Skip to content

Commit

Permalink
Fixed #480
Browse files Browse the repository at this point in the history
  • Loading branch information
Çağatay Çivici authored and Çağatay Çivici committed Jul 2, 2018
1 parent 9bb9aa5 commit 29f3d4f
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 61 deletions.
3 changes: 2 additions & 1 deletion src/components/fieldset/Fieldset.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ interface FieldsetProps {
style?: object;
toggleable?: boolean;
collapsed?: boolean;
onExpand?(): void;
onExpand?(event: Event): void;
onCollapse?(event: Event): void;
onToggle?(e:{event: originalEvent, value: boolean}): void;
}

export class Fieldset extends React.Component<FieldsetProps,any> {}
128 changes: 83 additions & 45 deletions src/components/fieldset/Fieldset.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ export class Fieldset extends Component {
toggleable: null,
collapsed: null,
onExpand: null,
onCollapse: null
onCollapse: null,
onToggle: null
};

static propTypes = {
Expand All @@ -25,19 +26,26 @@ export class Fieldset extends Component {
toggleable: PropTypes.bool,
collapsed: PropTypes.bool,
onExpand: PropTypes.func,
onCollapse: PropTypes.func
onCollapse: PropTypes.func,
onToggle: PropTypes.func
};

constructor(props) {
super(props);
this.state = {collapsed: this.props.collapsed};
this.toggle = this.toggle.bind(this);
if (!this.props.onToggle) {
this.state = {
collapsed: this.props.collapsed
};
}

this.toggle = this.toggle.bind(this);
this.id = this.props.id || UniqueComponentId();
}

componentDidUpdate() {
if(this.props.toggleable && !this.state.collapsed && this.expanding) {
const collapsed = this.props.onToggle ? this.props.collapsed : this.state.collapsed;

if(this.props.toggleable && !collapsed && this.expanding) {
DomHandler.addClass(this.contentWrapper, 'ui-fieldset-content-wrapper-expanding');

setTimeout(() => {
Expand All @@ -47,61 +55,67 @@ export class Fieldset extends Component {
}
}

static getDerivedStateFromProps(nextProps, prevState) {
if(nextProps.collapsed != null && nextProps.collapsed !== prevState.collapsed) {
return {
collapsed: nextProps.collapsed
};
}
toggle(event) {
if (this.props.toggleable) {
const collapsed = this.props.onToggle ? this.props.collapsed : this.state.collapsed;

return null;
}

toggle(e) {
if(this.props.toggleable) {
if(this.state.collapsed)
this.expand(e);
if(collapsed)
this.expand(event);
else
this.collapse(e);
this.collapse(event);

if (this.props.onToggle) {
this.props.onToggle({
originalEvent: event,
value: !collapsed
});
}
}

e.preventDefault();
event.preventDefault();
}

expand(event) {
this.setState({collapsed: false});
if (!this.props.onToggle) {
this.setState({collapsed: false});
}

this.expanding = true;
if(this.props.onCollapse) {
this.props.onCollapse(event);

if (this.props.onExpand) {
this.props.onExpand(event);
}
}

collapse(event) {
this.setState({collapsed: true});
if(this.props.onCollapse) {
if (!this.props.onToggle) {
this.setState({collapsed: true});
}

if (this.props.onCollapse) {
this.props.onCollapse(event);
}
}

renderContent() {
let className = classNames('ui-fieldset-content-wrapper', {
'ui-fieldset-content-wrapper-collapsed': (this.state.collapsed && this.props.toggleable),
'ui-fieldset-content-wrapper-expanded': (!this.state.collapsed && this.props.toggleable)
renderContent(collapsed) {
const className = classNames('ui-fieldset-content-wrapper', {
'ui-fieldset-content-wrapper-collapsed': (this.props.toggleable && collapsed),
'ui-fieldset-content-wrapper-expanded': (this.props.toggleable && !collapsed)
});
let id = this.id + '_content';
const id = this.id + '_content';

return (
<div ref={(el) => this.contentWrapper = el} className={className} id={id} aria-hidden={this.state.collapsed} role="region">
<div ref={(el) => this.contentWrapper = el} className={className} id={id} aria-hidden={collapsed} role="region">
<div className="ui-fieldset-content">
{this.props.children}
</div>
</div>
);
}

renderToggleIcon() {
if(this.props.toggleable) {
let className = classNames('ui-fieldset-toggler pi ', { 'pi-plus': this.state.collapsed, 'pi-minus': !this.state.collapsed });
renderToggleIcon(collapsed) {
if (this.props.toggleable) {
const className = classNames('ui-fieldset-toggler pi', {'pi-plus': collapsed, 'pi-minus': !collapsed});

return (
<span className={className}></span>
Expand All @@ -112,20 +126,44 @@ export class Fieldset extends Component {
}
}

renderLegendContent(collapsed) {
if (this.props.toggleable) {
const toggleIcon = this.renderToggleIcon(collapsed);
const ariaControls = this.id + '_content';

return (
<a href={'#' + ariaControls} aria-controls={ariaControls} aria-expanded={!collapsed} tabIndex={this.props.toggleable ? null : -1}>
{toggleIcon}
<span className="ui-fieldset-legend-text">{this.props.legend}</span>
</a>
);
}
else {
return (
<span className="ui-fieldset-legend-text">{this.props.legend}</span>
);
}
}

renderLegend(collapsed) {
const legendContent = this.renderLegendContent(collapsed);

return (
<legend className="ui-fieldset-legend ui-corner-all ui-state-default ui-unselectable-text" onClick={this.toggle}>
{legendContent}
</legend>
);
}

render() {
let content = this.renderContent();
let className = classNames('ui-fieldset ui-widget ui-widget-content ui-corner-all', this.props.className, {'ui-fieldset-toggleable': this.props.toggleable});
let toggleIcon = this.renderToggleIcon();
let ariaControls = this.id + '_content';
const className = classNames('ui-fieldset ui-widget ui-widget-content ui-corner-all', this.props.className, {'ui-fieldset-toggleable': this.props.toggleable});
const collapsed = this.props.toggleable ? (this.props.onToggle ? this.props.collapsed : this.state.collapsed) : false;
const legend = this.renderLegend(collapsed);
const content = this.renderContent(collapsed);

return (
<fieldset id={this.props.id} className={className} style={this.props.style}>
<legend className="ui-fieldset-legend ui-corner-all ui-state-default ui-unselectable-text" onClick={this.toggle}>
<a href={'#' + ariaControls} aria-controls={ariaControls} aria-expanded={!this.state.collapsed} tabIndex={this.props.toggleable ? null : -1}>
{toggleIcon}
<span className="ui-fieldset-legend-text">{this.props.legend}</span>
</a>
</legend>
{legend}
{content}
</fieldset>
);
Expand Down
5 changes: 5 additions & 0 deletions src/sass/App.scss
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,11 @@ body {
}
}

i {
background-color: #e5f9fc;
font-style: normal;
}

/* Demo Tabs Source */
.ui-tabview {
background: none;
Expand Down
57 changes: 42 additions & 15 deletions src/showcase/fieldset/FieldsetDemo.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ import {Fieldset} from 'primereact/fieldset';
</CodeHighlight>

<h3>Getting Started</h3>
<p>Fieldset is defined with Fieldset element.</p>
<p>Panel is a container component that accepts content as its children.</p>
<CodeHighlight className="language-jsx">
{`
<Fieldset legend="Godfather I">
Expand All @@ -72,11 +72,30 @@ import {Fieldset} from 'primereact/fieldset';
`}
</CodeHighlight>

<p>Instead of simple strings, <i>legend</i> propery also can be used to provide custom content as JSX.</p>

<h3>Toggleable</h3>
<p>Content of the fieldset can be expanded and collapsed using toggleable option, default state is defined with collapsed option.</p>
<p>Content of the fieldset can be expanded and collapsed using <i>toggleable</i> option. A toggleable fieldset can either be used as a Controlled or Uncontrolled component.</p>

<p>In controlled mode, <i>collapsed</i> and <i>onToggle</i> properties needs to be defined to control the collapsed state.</p>
<CodeHighlight className="language-jsx">
{`
<Fieldset legend="Godfather I" toggleable={true}>
<Fieldset legend="Godfather I" toggleable={true} collapsed={this.state.panelCollapsed} onToggle={(e) => this.setState({panelCollapsed: e.value})}>
The story begins as Don Vito Corleone, the head of a New York Mafia family, oversees his daughter's wedding.
His beloved son Michael has just come home from the war, but does not intend to become part of his father's business.
Through Michael's life the nature of the family business becomes clear. The business of the family is just like the head of the family,
kind and benevolent to those who give respect, but given to ruthless violence whenever anything stands against the good of the family.
</Fieldset>
`}
</CodeHighlight>

<p>In uncontrolled mode, only <i>toggleable</i> property needs to be enabled. Initial state can be still be provided using the <i>collapsed</i> property in uncontrolled mode however
it is evaluated at initial rendering and ignored in further updates. If you programmatically need to update the collapsed state, prefer to use the component as controlled.</p>

<CodeHighlight className="language-jsx">
{`
<Fieldset legend="Godfather I" toggleable={true} >
The story begins as Don Vito Corleone, the head of a New York Mafia family, oversees his daughter's wedding.
His beloved son Michael has just come home from the war, but does not intend to become part of his father's business.
Through Michael's life the nature of the family business becomes clear. The business of the family is just like the head of the family,
Expand Down Expand Up @@ -118,7 +137,7 @@ import {Fieldset} from 'primereact/fieldset';
</tr>
<tr>
<td>style</td>
<td>string</td>
<td>object</td>
<td>null</td>
<td>Inline style of the element.</td>
</tr>
Expand All @@ -142,24 +161,29 @@ import {Fieldset} from 'primereact/fieldset';
<div className="doc-tablewrapper">
<table className="doc-table">
<thead>
<tr>
<th>Name</th>
<th>Parameters</th>
<th>Description</th>
</tr>
<tr>
<th>Name</th>
<th>Parameters</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>onCollapse</td>
<td>event.originalEvent: browser event </td>
<td>Callback to invoke when an active tab is collapsed by clicking on the header.</td>
</tr>
<tr>
<td>onExpand</td>
<td>event.originalEvent: browser event
</td>
<td>event.originalEvent: browser event </td>
<td>Callback to invoke when a tab gets expanded.</td>
</tr>
<tr>
<td>onCollapse</td>
<td>event.originalEvent: browser event
<td>onToggle</td>
<td>event.originalEvent: browser event <br />
event.value: collapsed state as a boolean
</td>
<td>Callback to invoke when an active tab is collapsed by clicking on the header.</td>
<td>Callback to invoke when a tab gets expanded.</td>
</tr>
</tbody>
</table>
Expand Down Expand Up @@ -208,12 +232,15 @@ import {Fieldset} from 'primereact/fieldset';
</a>
<CodeHighlight className="language-javascript">
{`
import React, {Component} from 'react';
import {Fieldset} from 'primereact/fieldset';
export class FieldsetDemo extends Component {
render() {
return (
<div>
<div className="content-section">
<div className="content-section introduction">
<div className="feature-intro">
<h1>Fieldset</h1>
<p>Fieldset is a grouping component with a content toggle feature.</p>
Expand Down

0 comments on commit 29f3d4f

Please sign in to comment.