Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Single accordion #25

Merged
merged 7 commits into from
Feb 28, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 62 additions & 9 deletions docs/components/accordion.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,50 +6,102 @@ A Twofold is an expandable component with two parts: a summary and details. Init

A Twofold is the inner element in an Accordion.

Use the Accordion's `single` variant to have only one Twofold open at a time. Use the `multi` (default) variant to have multiple elements open at the same time.
Use the Accordion's `single` variant to have only one Twofold open at a time. Use the `multiple` (default) variant to have multiple elements open at the same time.

## Example

```javascript
class SampleAccordion extends React.Component {
const data = {
'title1': 'some short summary',
'title2': 'a short title/summary with subheading left blank',
'title3': 'pick me',
'summary1': 'you can put a subheading here, or leave it blank',
'summary3': 'you can add more info here, after the title',
'details1': 'Lorem ipsum dolor sit amet, tortor dolor sit et eros, adipiscing mi lobortis lorem condimentum mi velit, dui posuere malesuada rutrum, dui morbi neque morbi suscipit. Inceptos quis in quisque eget, auctor imperdiet nam id in sed est. A fringilla, dictum quo mi. Massa mauris diam, sed integer libero erat, auctor nunc interdum posuere enim. Nisl viverra nascetur nec integer elit mauris, lectus scelerisque libero eleifend id dignissim et, ultricies lacus felis pretium, vel euismod molestie, ut nam integer tincidunt quis elit. Architecto varius at quis mi nec viverra, et vehicula, congue sapien est cras suspendisse, conubia pede nulla morbi imperdiet.',
'details2': 'Augue justo nibh magna bibendum. Interdum maecenas dignissim consequatur egestas neque, mi in neque, eu adipiscing accumsan libero lacus luctus. Facilisis aenean adipiscing suscipit, aliquam vivamus quam a sem. Sit dui montes sit, mauris velit morbi, in aliquam et vestibulum wisi nisl ipsum, turpis platea suspendisse vivamus interdum pellentesque donec, sed nullam. Volutpat sit in convallis lorem, risus ut turpis nulla, adipiscing ut mi. Nec mauris dui sit sed, donec dictum, sem nibh. Aliquam ad nec commodo pellentesque, in nisl fermentum rhoncus, ullamcorper porta pulvinar, et tincidunt lobortis, quis ipsum. Quam wisi id, amet mauris metus at egestas aliquet odio, posuere potenti orci gravida in.',
'details3': 'Erat nulla lectus mauris tempus nam ultricies, quam sollicitudin, scelerisque ac, tortor ipsum tristique aliquam, lectus ligula turpis urna vel. Mus quae ut, vel ac. Dolor vel nulla et, wisi sit, autem sem sociis consectetuer. Aenean est pellentesque vestibulum vulputate, dignissim ultricies ipsum laoreet, tellus ultrices elit eget mus viverra magna. Felis phasellus amet malesuada, a adipiscing mollis suspendisse varius tincidunt, at mi. Varius scelerisque quis diam vitae erat pellentesque, metus morbi mus ea sed sit nec, tortor id nunc scelerisque purus, quis pede id sem est inceptos, velit quam posuere ipsum nulla. Turpis reiciendis nec molestie aliquam, interdum odio vel nibh ligula sed, posuere etiam ac odio. Ligula sodales placerat lacus cum augue.',
};

class SampleAccordions extends React.Component {
constructor(props) {
super();
this.state = {
active1: false,
active2: false,
active3: false
active3: false,
multi1: false,
multi2: false,
multi3: false,
singleActive: '',
};
}

handleSingle(key) {
this.setState({
[key]: !(this.state.singleActive === key), // add extra criteria here for true state
singleActive: key, // keep track of active item
});
}

handleToggle(key) {
this.setState({
[key]: !this.state[key],
});
}

render() {
return (
<div>
<h2>Accordion</h2>
<Accordion>
<h3>single variant (one panel open at a time)</h3>
<Accordion variant='single' singleActive={this.state.singleActive}>
<Twofold
key='active1'
heading={data.title1}
subheading={data.summary1}
onChange={() => this.setState({ active1: !this.state.active1 })}
onChange={() => this.handleSingle('active1')}
active={this.state.active1}
>{data.details1}</Twofold>
<Twofold
key='active2'
heading={data.title2}
subheading={data.summary2}
onChange={() => this.setState({ active2: !this.state.active2 })}
onChange={() => this.handleSingle('active2')}
active={this.state.active2}
>{data.details2}</Twofold>
<Twofold
key='active3'
heading={data.title3}
subheading={data.summary3}
onChange={() => this.setState({ active3: !this.state.active3 })}
onChange={() => this.handleSingle('active3')}
active={this.state.active3}
>{data.details3}</Twofold>
</Accordion>
<h3>multiple variant (multiple panels open at a time)</h3>
<Accordion>
<Twofold
heading={data.title1}
subheading={data.summary1}
onChange={() => this.handleToggle('multi1')}
active={this.state.multi1}
>{data.details1}</Twofold>
<Twofold
heading={data.title2}
subheading={data.summary2}
onChange={() => this.handleToggle('multi2')}
active={this.state.multi2}
>{data.details2}</Twofold>
<Twofold
heading={data.title3}
subheading={data.summary3}
onChange={() => this.handleToggle('multi3')}
active={this.state.multi3}
>{data.details3}</Twofold>
</Accordion>
</div>
);
}
}

```

## Try it
Expand All @@ -59,7 +111,8 @@ _an embedded Codepen here_

| Name | Type | Description |
| --- | --- | --- | --- |
| `variant` | <code>'single'&#124;'multi'</code> | Determines whether only one Twofold can be expanded at a time, or whether multiple Twofolds can be open simultaneously. Default is `multi`.
| `variant` | <code>'single'&#124;'multiple'</code> | Determines whether only one Twofold can be expanded at a time, or whether multiple Twofolds can be open simultaneously. Default is `multiple`.
| `singleActive` | 'string' | For the `single` accordion variant, contains the `key` of the single active Twofold.
| `mod` | <code>string&#124;Array<string></code> | Apply custom mods from the theme on the Accordion.

## Theme
Expand Down
5 changes: 3 additions & 2 deletions docs/components/twofold.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,12 @@ _an embedded Codepen here_

| Name | Type | Description |
| --- | --- | --- | --- |
| `active` | `boolean` | Required. If true, Twofold is open. Handled by Accordion component if wrapped inside an Accordion.
| `active` | `boolean` | Required. If true, Twofold is open.
| `key` | `string` | The unique id of the Twofold. Can be the same as the Twofold's key in its container's state. Required for Twofolds used in an Accordion with the `single` variant.
| `heading` | `string` | The contents of the heading. Text only(?).
| `subheading` | `string` | The contents of the subheading. Text only(?).
| `icon` | `element` | Defines the icon element. If not defined, defaults to a chevron.
| `onChange` | `function` | Function to handle open and close logic. Handled by Accordion component if wrapped inside an Accordion.
| `onChange` | `function` | Function to handle open and close logic.
| `mod` | <code>string&#124;Array<string></code> | Apply custom mods from the theme on the Twofold.

##Theme
Expand Down
31 changes: 25 additions & 6 deletions src/components/accordion/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,42 @@ A Twofold is an expandable component with two parts: a summary and details. Init

A Twofold is the inner element in an Accordion.

Use the Accordion's `single` variant to have only one Twofold open at a time. Use the `multi` (default) variant to have multiple elements open at the same time.
Use the Accordion's `single` variant to have only one Twofold open at a time. Use the `multiple` (default) variant to have multiple elements open at the same time.

## Example

```javascript
<Accordion variant="multi">
<Twofold heading="some short summary" subheading="more short summary">details here</Twofold>
<Twofold heading="pithy title" subheading="I have more info" active>details here</Twofold>
<Twofold heading="pick me" subheading="the skinny" active>details here</Twofold>
<Accordion variant='single' singleActive={this.state.singleActive}>
<Twofold
key='active1'
heading={data.title1}
subheading={data.summary1}
onChange={() => this.handleSingleClick('active1')}
active={this.state.active1}
>{data.details1}</Twofold>
<Twofold
key='active2'
heading={data.title2}
subheading={data.summary2}
onChange={() => this.handleSingleClick('active2')}
active={this.state.active2}
>{data.details2}</Twofold>
<Twofold
key='active3'
heading={data.title3}
subheading={data.summary3}
onChange={() => this.handleSingleClick('active3')}
active={this.state.active3}
>{data.details3}</Twofold>
</Accordion>
```

## Properties

| Name | Type | Description |
| --- | --- | --- | --- |
| `variant` | <code>'single'&#124;'multi'</code> | Determines whether only one Twofold can be expanded at a time, or whether multiple Twofolds can be open simultaneously. Default is `multi`.
| `variant` | <code>'single'&#124;'multiple'</code> | Determines whether only one Twofold can be expanded at a time, or whether multiple Twofolds can be open simultaneously. Default is `multiple`.
| `singleActive` | 'string' | For the `single` accordion variant, contains the `key` of the single active Twofold.
| `mod` | <code>string&#124;Array<string></code> | Apply custom mods from the theme on the Accordion.

## Theme
Expand Down
20 changes: 16 additions & 4 deletions src/components/accordion/accordion.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,33 @@ const Accordion = (props: *) => {
className: propsClassName,
theme,
variant,
singleActive,
children,
mod,
...rest
} = props;

// function to adjust the active classes on the children as appropriate
const clonedChildren = children.map((child) => {
const makeActive = child.key === singleActive ? child.props.active : false;
return React.cloneElement(child, {
active: makeActive,
});
},
);

const variantChildren = variant === 'single' ? clonedChildren : children;

const className = classNames(
theme.accordion,
!!variant && theme[variant],
resolveMods(theme, mod),
theme[propsClassName],
...rest,
);

return (
<div className={className}>
{children}
{variantChildren}
</div>
);
};
Expand All @@ -35,8 +46,9 @@ Accordion.propTypes = {

variant: PropTypes.oneOf([
'single',
'multi',
'multiple',
]),
singleActive: PropTypes.string,

children: PropTypes.node,

Expand All @@ -51,7 +63,7 @@ Accordion.propTypes = {

// Variants
single: PropTypes.string,
multi: PropTypes.string,
multiple: PropTypes.string,

}).isRequired,
};
Expand Down
5 changes: 3 additions & 2 deletions src/components/twofold/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,12 @@ class SampleTwofold extends React.Component {

| Name | Type | Description |
| --- | --- | --- | --- |
| `active` | `boolean` | Required. If true, Twofold is open. Handled by Accordion component if wrapped inside an Accordion.
| `active` | `boolean` | Required. If true, Twofold is open.
| `key` | `string` | The unique id of the Twofold. Can be the same as the Twofold's key in its container's state. Required for Twofolds used in an Accordion with the `single` variant.
| `heading` | `string` | The contents of the heading. Text only(?).
| `subheading` | `string` | The contents of the subheading. Text only(?).
| `icon` | `element` | Defines the icon element. If not defined, defaults to a chevron.
| `onChange` | `function` | Function to handle open and close logic. Handled by Accordion component if wrapped inside an Accordion.
| `onChange` | `function` | Function to handle open and close logic.
| `mod` | <code>string&#124;Array<string></code> | Apply custom mods from the theme on the Twofold.

##Theme
Expand Down