Skip to content

Commit 30d473a

Browse files
authored
feat: Add AccordionItem alias for Disclosure (#9212)
* feat: Add AccordionItem so we can change Disclosure in the future without a breaking change * copy * small typo * whoops lint * update docs and story * get rid of accordion context
1 parent 8aaa70a commit 30d473a

File tree

6 files changed

+272
-178
lines changed

6 files changed

+272
-178
lines changed

packages/@react-spectrum/s2/chromatic/Accordion.stories.tsx

Lines changed: 61 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* governing permissions and limitations under the License.
1111
*/
1212

13-
import {Accordion, ActionButton, Disclosure, DisclosureHeader, DisclosurePanel, DisclosureTitle, TextField} from '../src';
13+
import {Accordion, AccordionItem, AccordionItemHeader, AccordionItemPanel, AccordionItemTitle, ActionButton, TextField} from '../src';
1414
import type {Meta, StoryObj} from '@storybook/react';
1515
import NewIcon from '../s2wf-icons/S2_Icon_New_20_N.svg';
1616
import React from 'react';
@@ -32,22 +32,22 @@ export const Example: Story = {
3232
return (
3333
<div className={style({minHeight: 240})}>
3434
<Accordion {...args}>
35-
<Disclosure id="files">
36-
<DisclosureTitle>
35+
<AccordionItem id="files">
36+
<AccordionItemTitle>
3737
Files
38-
</DisclosureTitle>
39-
<DisclosurePanel>
38+
</AccordionItemTitle>
39+
<AccordionItemPanel>
4040
Files content
41-
</DisclosurePanel>
42-
</Disclosure>
43-
<Disclosure id="people">
44-
<DisclosureTitle>
41+
</AccordionItemPanel>
42+
</AccordionItem>
43+
<AccordionItem id="people">
44+
<AccordionItemTitle>
4545
People
46-
</DisclosureTitle>
47-
<DisclosurePanel>
46+
</AccordionItemTitle>
47+
<AccordionItemPanel>
4848
<TextField label="Name" styles={style({maxWidth: 176})} placeholder="Enter your name" />
49-
</DisclosurePanel>
50-
</Disclosure>
49+
</AccordionItemPanel>
50+
</AccordionItem>
5151
</Accordion>
5252
</div>
5353
);
@@ -59,57 +59,57 @@ export const WithLongTitle: Story = {
5959
return (
6060
<div className={style({minHeight: 224})}>
6161
<Accordion styles={style({maxWidth: 224})} {...args}>
62-
<Disclosure>
63-
<DisclosureTitle>
62+
<AccordionItem>
63+
<AccordionItemTitle>
6464
Files
65-
</DisclosureTitle>
66-
<DisclosurePanel>
65+
</AccordionItemTitle>
66+
<AccordionItemPanel>
6767
Files content
68-
</DisclosurePanel>
69-
</Disclosure>
70-
<Disclosure>
71-
<DisclosureTitle>
68+
</AccordionItemPanel>
69+
</AccordionItem>
70+
<AccordionItem>
71+
<AccordionItemTitle>
7272
People
73-
</DisclosureTitle>
74-
<DisclosurePanel>
73+
</AccordionItemTitle>
74+
<AccordionItemPanel>
7575
People content
76-
</DisclosurePanel>
77-
</Disclosure>
78-
<Disclosure>
79-
<DisclosureTitle>
76+
</AccordionItemPanel>
77+
</AccordionItem>
78+
<AccordionItem>
79+
<AccordionItemTitle>
8080
Very very very very very long title that wraps
81-
</DisclosureTitle>
82-
<DisclosurePanel>
81+
</AccordionItemTitle>
82+
<AccordionItemPanel>
8383
Accordion content
84-
</DisclosurePanel>
85-
</Disclosure>
84+
</AccordionItemPanel>
85+
</AccordionItem>
8686
</Accordion>
8787
</div>
8888
);
8989
}
9090
};
9191

92-
export const WithDisabledDisclosure: Story = {
92+
export const WithDisabledItem: Story = {
9393
render: (args) => {
9494
return (
9595
<div className={style({minHeight: 240})}>
9696
<Accordion {...args}>
97-
<Disclosure>
98-
<DisclosureTitle>
97+
<AccordionItem>
98+
<AccordionItemTitle>
9999
Files
100-
</DisclosureTitle>
101-
<DisclosurePanel>
100+
</AccordionItemTitle>
101+
<AccordionItemPanel>
102102
Files content
103-
</DisclosurePanel>
104-
</Disclosure>
105-
<Disclosure isDisabled>
106-
<DisclosureTitle>
103+
</AccordionItemPanel>
104+
</AccordionItem>
105+
<AccordionItem isDisabled>
106+
<AccordionItemTitle>
107107
People
108-
</DisclosureTitle>
109-
<DisclosurePanel>
108+
</AccordionItemTitle>
109+
<AccordionItemPanel>
110110
<TextField label="Name" placeholder="Enter your name" />
111-
</DisclosurePanel>
112-
</Disclosure>
111+
</AccordionItemPanel>
112+
</AccordionItem>
113113
</Accordion>
114114
</div>
115115
);
@@ -122,7 +122,7 @@ WithLongTitle.parameters = {
122122
}
123123
};
124124

125-
WithDisabledDisclosure.parameters = {
125+
WithDisabledItem.parameters = {
126126
docs: {
127127
disable: true
128128
}
@@ -133,28 +133,28 @@ export const WithActionButton: Story = {
133133
return (
134134
<div className={style({minHeight: 240})}>
135135
<Accordion {...args}>
136-
<Disclosure id="files">
137-
<DisclosureHeader>
138-
<DisclosureTitle>
136+
<AccordionItem id="files">
137+
<AccordionItemHeader>
138+
<AccordionItemTitle>
139139
Files
140-
</DisclosureTitle>
140+
</AccordionItemTitle>
141141
<ActionButton><NewIcon aria-label="new icon" /></ActionButton>
142-
</DisclosureHeader>
143-
<DisclosurePanel>
142+
</AccordionItemHeader>
143+
<AccordionItemPanel>
144144
Files content
145-
</DisclosurePanel>
146-
</Disclosure>
147-
<Disclosure id="people">
148-
<DisclosureHeader>
149-
<DisclosureTitle>
145+
</AccordionItemPanel>
146+
</AccordionItem>
147+
<AccordionItem id="people">
148+
<AccordionItemHeader>
149+
<AccordionItemTitle>
150150
People
151-
</DisclosureTitle>
151+
</AccordionItemTitle>
152152
<ActionButton><NewIcon aria-label="new icon" /></ActionButton>
153-
</DisclosureHeader>
154-
<DisclosurePanel>
153+
</AccordionItemHeader>
154+
<AccordionItemPanel>
155155
<TextField label="Name" styles={style({maxWidth: 176})} placeholder="Enter your name" />
156-
</DisclosurePanel>
157-
</Disclosure>
156+
</AccordionItemPanel>
157+
</AccordionItem>
158158
</Accordion>
159159
</div>
160160
);

packages/@react-spectrum/s2/src/Accordion.tsx

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,19 @@
1111
*/
1212

1313
import {ContextValue, DisclosureGroup, DisclosureGroupProps, SlotProps} from 'react-aria-components';
14-
import {DisclosureContext} from './Disclosure';
14+
import {
15+
Disclosure,
16+
DisclosureContext,
17+
DisclosureHeader,
18+
DisclosurePanel,
19+
DisclosurePanelProps,
20+
DisclosureProps,
21+
DisclosureTitle,
22+
DisclosureTitleProps
23+
} from './Disclosure';
1524
import {DOMProps, DOMRef, DOMRefValue, GlobalDOMAttributes} from '@react-types/shared';
1625
import {getAllowedOverrides, StylesPropWithHeight, UnsafeStyles} from './style-utils' with { type: 'macro' };
17-
import React, {createContext, forwardRef} from 'react';
26+
import React, {createContext, forwardRef, ReactNode} from 'react';
1827
import {style} from '../style' with { type: 'macro' };
1928
import {useDOMRef} from '@react-spectrum/utils';
2029
import {useSpectrumContextProps} from './useSpectrumContextProps';
@@ -70,3 +79,40 @@ export const Accordion = forwardRef(function Accordion(props: AccordionProps, re
7079
</DisclosureContext.Provider>
7180
);
7281
});
82+
83+
export interface AccordionItemProps extends DisclosureProps {
84+
/** The contents of the accordion, consisting of a AccordionItemTitle and AccordionItemPanel. */
85+
children: ReactNode
86+
}
87+
/**
88+
* A accordion item is a collapsible section of content. It is composed of a header with a heading and trigger button, and a panel that contains the content.
89+
*/
90+
export const AccordionItem = forwardRef(function AccordionItem(props: AccordionItemProps, ref: DOMRef<HTMLDivElement>) {
91+
return <Disclosure {...props} ref={ref} />;
92+
});
93+
94+
export interface AccordionItemTitleProps extends DisclosureTitleProps {}
95+
/**
96+
* An accordion item title consisting of a heading and a trigger button to expand/collapse the panel.
97+
*/
98+
export const AccordionItemTitle = forwardRef(function AccordionItemTitle(props: AccordionItemTitleProps, ref: DOMRef<HTMLDivElement>) {
99+
return <DisclosureTitle {...props} ref={ref} />;
100+
});
101+
102+
export interface AccordionItemHeaderProps extends UnsafeStyles, DOMProps {
103+
children: React.ReactNode
104+
}
105+
/**
106+
* A wrapper element for the accordion item title that can contain other elements not part of the trigger.
107+
*/
108+
export const AccordionItemHeader = forwardRef(function AccordionItemHeader(props: AccordionItemHeaderProps, ref: DOMRef<HTMLDivElement>) {
109+
return <DisclosureHeader {...props} ref={ref} />;
110+
});
111+
112+
export interface AccordionItemPanelProps extends DisclosurePanelProps {}
113+
/**
114+
* An accordion item panel is a collapsible section of content that is hidden until the accordion item is expanded.
115+
*/
116+
export const AccordionItemPanel = forwardRef(function AccordionItemPanel(props: AccordionItemPanelProps, ref: DOMRef<HTMLDivElement>) {
117+
return <DisclosurePanel {...props} ref={ref} />;
118+
});

packages/@react-spectrum/s2/src/Disclosure.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ const disclosure = style({
6666
}, getAllowedOverrides());
6767

6868
/**
69-
* A disclosure is a collapsible section of content. It is composed of a a header with a heading and trigger button, and a panel that contains the content.
69+
* A disclosure is a collapsible section of content. It is composed of a header with a heading and trigger button, and a panel that contains the content.
7070
*/
7171
export const Disclosure = forwardRef(function Disclosure(props: DisclosureProps, ref: DOMRef<HTMLDivElement>) {
7272
[props, ref] = useSpectrumContextProps(props, ref, DisclosureContext);
@@ -99,7 +99,7 @@ export const Disclosure = forwardRef(function Disclosure(props: DisclosureProps,
9999

100100
export interface DisclosureTitleProps extends UnsafeStyles, DOMProps {
101101
/** The heading level of the disclosure header.
102-
*
102+
*
103103
* @default 3
104104
*/
105105
level?: number,
@@ -342,4 +342,3 @@ export const DisclosurePanel = forwardRef(function DisclosurePanel(props: Disclo
342342
</RACDisclosurePanel>
343343
);
344344
});
345-

packages/@react-spectrum/s2/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
'use client';
1414

15-
export {Accordion, AccordionContext} from './Accordion';
15+
export {Accordion, AccordionContext, AccordionItem, AccordionItemHeader, AccordionItemTitle, AccordionItemPanel} from './Accordion';
1616
export {ActionBar, ActionBarContext} from './ActionBar';
1717
export {ActionButton, ActionButtonContext} from './ActionButton';
1818
export {ActionButtonGroup, ActionButtonGroupContext} from './ActionButtonGroup';
@@ -96,7 +96,7 @@ export {Collection} from 'react-aria-components';
9696
export {FileTrigger} from 'react-aria-components';
9797
export {parseColor} from 'react-aria-components';
9898

99-
export type {AccordionProps} from './Accordion';
99+
export type {AccordionProps, AccordionItemProps, AccordionItemHeaderProps, AccordionItemTitleProps, AccordionItemPanelProps} from './Accordion';
100100
export type {ActionBarProps} from './ActionBar';
101101
export type {ActionButtonProps} from './ActionButton';
102102
export type {ActionButtonGroupProps} from './ActionButtonGroup';

0 commit comments

Comments
 (0)