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

feat(accordion): add content and toggle container props #2713

Merged
merged 7 commits into from Sep 6, 2019
Merged
Changes from 6 commits
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

@@ -4,7 +4,6 @@ import { Accordion } from './Accordion';
import { AccordionToggle } from './AccordionToggle';
import { AccordionContent } from './AccordionContent';
import { AccordionItem } from './AccordionItem';
import { AccordionContext } from './AccordionContext';

describe('Accordion', () => {
test('Accordion default', () => {
@@ -26,10 +25,9 @@ describe('Accordion', () => {

test('It should pass optional aria props', () => {
const view = mount(
<AccordionContext.Provider value={{ asDefinitionList: true }}>
<Accordion asDefinitionList>
<AccordionToggle aria-label="Toggle details for" aria-labelledby="ex-toggle2 ex-item2" id="ex-toggle2" />
</AccordionContext.Provider>,
{}
</Accordion>
);
const button = view.find('button[id="ex-toggle2"]').getElement();
expect(button.props['aria-label']).toBe('Toggle details for');
@@ -39,12 +37,26 @@ describe('Accordion', () => {

test('Toggle expanded', () => {
const view = mount(
<AccordionContext.Provider value={{ asDefinitionList: true }}>
<Accordion asDefinitionList>
<AccordionToggle aria-label="Toggle details for" id="ex-toggle2" isExpanded />
</AccordionContext.Provider>
</Accordion>
);
const button = view.find('button[id="ex-toggle2"]').getElement();
expect(button.props['aria-expanded']).toBe(true);
expect(button.props.className).toContain('pf-m-expanded');
});

test('Custom containers', () => {
const container = 'a';
const view = mount(
<Accordion headingLevel="h2">
<AccordionItem>
<AccordionToggle id="item-1" component={container}>Item One</AccordionToggle>
<AccordionContent component={container}>Item One Content</AccordionContent>
</AccordionItem>
</Accordion>
);
expect(view.find(AccordionToggle).getDOMNode().tagName).toBe(container.toLocaleUpperCase());
expect(view.find(AccordionContent).getDOMNode().tagName).toBe(container.toLocaleUpperCase());
});
});
@@ -27,7 +27,10 @@ export const Accordion: React.FunctionComponent<AccordionProps> = ({
const AccordionList: any = asDefinitionList ? 'dl' : 'div';
return (
<AccordionList className={css(styles.accordion, className)} aria-label={ariaLabel} {...props}>
<AccordionContext.Provider value={{ AccordionHeadingLevel: headingLevel, asDefinitionList }}>
<AccordionContext.Provider value={{
ContentContainer: asDefinitionList ? 'dd' : 'div',
ToggleContainer: asDefinitionList ? 'dt' : headingLevel
}}>
{children}
</AccordionContext.Provider>
</AccordionList>
@@ -16,6 +16,8 @@ export interface AccordionContentProps extends React.HTMLProps<HTMLDivElement> {
isFixed?: boolean;
/** Adds accessible text to the Accordion content */
'aria-label'?: string;
/** Container to override the default for content */

This comment has been minimized.

Copy link
@tlabaj

tlabaj Sep 6, 2019

Contributor

Maybe say Component to use as content container?

This comment has been minimized.

Copy link
@redallen

redallen Sep 6, 2019

Author Contributor

Sure, done!

component?: React.ElementType;
}

export const AccordionContent: React.FunctionComponent<AccordionContentProps> = ({
@@ -25,13 +27,14 @@ export const AccordionContent: React.FunctionComponent<AccordionContentProps> =
isHidden = false,
isFixed = false,
'aria-label': ariaLabel = '',
component,
...props
}: AccordionContentProps) => (
<AccordionContext.Consumer>
{({ asDefinitionList }) => {
const AccordionContentContainer = asDefinitionList ? 'dd' : 'div';
{({ ContentContainer }) => {
const Container = component || ContentContainer;
return (
<AccordionContentContainer
<Container
id={id}
className={css(
styles.accordionExpandedContent,
@@ -44,7 +47,7 @@ export const AccordionContent: React.FunctionComponent<AccordionContentProps> =
{...props}
>
<div className={css(styles.accordionExpandedContentBody)}>{children}</div>
</AccordionContentContainer>
</Container>
);
}}
</AccordionContext.Consumer>
@@ -1,8 +1,8 @@
import * as React from 'react';

interface AccordionContextProps {
AccordionHeadingLevel: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
asDefinitionList: boolean;
ContentContainer: React.ElementType;
ToggleContainer: React.ElementType;
}

export const AccordionContext = React.createContext<Partial<AccordionContextProps>>({});
@@ -14,20 +14,23 @@ export interface AccordionToggleProps extends Omit<React.HTMLProps<HTMLButtonEle
isExpanded?: boolean;
/** Identify the Accordion toggle number */
id: string;
/** Container to override the default for toggle */
component?: React.ElementType;
}

export const AccordionToggle: React.FunctionComponent<AccordionToggleProps> = ({
className = '',
id,
isExpanded = false,
children = null,
component,
...props
}: AccordionToggleProps) => (
<AccordionContext.Consumer>
{({ asDefinitionList, AccordionHeadingLevel }) => {
const AccordionToggleContainer = asDefinitionList ? 'dt' : AccordionHeadingLevel;
{({ ToggleContainer }) => {
const Container = component || ToggleContainer;
return (
<AccordionToggleContainer>
<Container>
<button
id={id}
className={css(styles.accordionToggle, isExpanded && styles.modifiers.expanded, className)}
@@ -37,7 +40,7 @@ export const AccordionToggle: React.FunctionComponent<AccordionToggleProps> = ({
<span className={css(styles.accordionToggleText)}>{children}</span>
<AngleRightIcon className={css(styles.accordionToggleIcon)} />
</button>
</AccordionToggleContainer>
</Container>
);
}}
</AccordionContext.Consumer>
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.