Skip to content

Commit 69109f0

Browse files
reidbarbersnowystingerLFDanLu
authored
docs(RAC): add tailwind starter for Disclosure and DisclosureGroup (#7166)
* add tailwind starter for Disclosure and DisclosureGroup * fix focus ring border radius * update disabled chevron style * fix focus ring in group * cleanup variants and styles * fix text color * fix padding * move DisclosureGroup to it's own story --------- Co-authored-by: Robert Snow <[email protected]> Co-authored-by: Daniel Lu <[email protected]>
1 parent 72a85cc commit 69109f0

File tree

3 files changed

+175
-0
lines changed

3 files changed

+175
-0
lines changed

starters/tailwind/src/Disclosure.tsx

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import React, { useContext } from "react";
2+
import {
3+
UNSTABLE_Disclosure as AriaDisclosure,
4+
UNSTABLE_DisclosureGroup as AriaDisclosureGroup,
5+
DisclosureProps as AriaDisclosureProps,
6+
DisclosureGroupProps as AriaDisclosureGroupProps,
7+
UNSTABLE_DisclosurePanel as AriaDisclosurePanel,
8+
DisclosurePanelProps as AriaDisclosurePanelProps,
9+
composeRenderProps,
10+
Heading,
11+
Button,
12+
DisclosureStateContext,
13+
} from "react-aria-components";
14+
import { tv } from "tailwind-variants";
15+
import { ChevronRight } from "lucide-react";
16+
import { composeTailwindRenderProps, focusRing } from "./utils";
17+
import { DisclosureGroupStateContext } from "react-aria-components";
18+
19+
const disclosure = tv({
20+
base: "group min-w-64 border dark:border-zinc-600 rounded-lg text-gray-900 dark:text-zinc-200",
21+
variants: {
22+
isInGroup: {
23+
true: "border-0 border-b last:border-b-0 rounded-b-none last:rounded-b-lg",
24+
}
25+
}
26+
});
27+
28+
const disclosureButton = tv({
29+
extend: focusRing,
30+
base: "rounded-lg flex gap-2 items-center w-full text-start p-2 cursor-default",
31+
variants: {
32+
isDisabled: {
33+
true: 'text-gray-300 dark:text-zinc-600 forced-colors:text-[GrayText]'
34+
},
35+
isInGroup: {
36+
true: "-outline-offset-2 rounded-none group-first:rounded-t-lg group-last:rounded-b-lg",
37+
}
38+
}
39+
});
40+
41+
const chevron = tv({
42+
base: "w-5 h-5 text-gray-500 dark:text-gray-400 transition-transform duration-200 ease-in-out",
43+
variants: {
44+
isExpanded: {
45+
true: "transform rotate-90",
46+
},
47+
isDisabled: {
48+
true: 'text-gray-300 dark:text-zinc-600 forced-colors:text-[GrayText]'
49+
}
50+
}
51+
});
52+
53+
export interface DisclosureProps extends AriaDisclosureProps {
54+
children: React.ReactNode;
55+
}
56+
57+
export function Disclosure({ children, ...props }: DisclosureProps) {
58+
let isInGroup = useContext(DisclosureGroupStateContext) !== null;
59+
return (
60+
<AriaDisclosure
61+
{...props}
62+
className={composeRenderProps(props.className, (className, renderProps) => disclosure({ ...renderProps, isInGroup, className }))}
63+
>
64+
{children}
65+
</AriaDisclosure>
66+
);
67+
}
68+
69+
export interface DisclosureHeaderProps {
70+
children: React.ReactNode;
71+
}
72+
73+
export function DisclosureHeader({ children }: DisclosureHeaderProps) {
74+
let { isExpanded } = useContext(DisclosureStateContext)!;
75+
let isInGroup = useContext(DisclosureGroupStateContext) !== null;
76+
return (
77+
<Heading className="text-lg font-semibold">
78+
<Button
79+
slot="trigger"
80+
className={(renderProps) => disclosureButton({ ...renderProps, isInGroup })}
81+
>
82+
{({isDisabled}) => (
83+
<>
84+
<ChevronRight aria-hidden className={chevron({ isExpanded, isDisabled })} />
85+
{children}
86+
</>
87+
)}
88+
</Button>
89+
</Heading>
90+
);
91+
}
92+
93+
export interface DisclosurePanelProps extends AriaDisclosurePanelProps {
94+
children: React.ReactNode;
95+
}
96+
97+
export function DisclosurePanel({ children, ...props }: DisclosurePanelProps) {
98+
return (
99+
<AriaDisclosurePanel {...props} className={composeTailwindRenderProps(props.className, 'group-data-[expanded]:px-4 group-data-[expanded]:py-2')}>
100+
{children}
101+
</AriaDisclosurePanel>
102+
);
103+
}
104+
105+
export interface DisclosureGroupProps extends AriaDisclosureGroupProps {
106+
children: React.ReactNode;
107+
}
108+
109+
export function DisclosureGroup({ children, ...props }: DisclosureGroupProps) {
110+
return (
111+
<AriaDisclosureGroup {...props} className={composeTailwindRenderProps(props.className, 'border dark:border-zinc-600 rounded-lg')}>
112+
{children}
113+
</AriaDisclosureGroup>
114+
);
115+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import type { Meta } from "@storybook/react";
2+
import React from "react";
3+
import {
4+
Disclosure,
5+
DisclosureHeader,
6+
DisclosurePanel,
7+
} from "../src/Disclosure";
8+
9+
const meta: Meta<typeof Disclosure> = {
10+
component: Disclosure,
11+
parameters: {
12+
layout: 'centered'
13+
},
14+
tags: ['autodocs']
15+
};
16+
17+
export default meta;
18+
19+
export const Example = (args: any) => (
20+
<Disclosure {...args}>
21+
<DisclosureHeader>Files</DisclosureHeader>
22+
<DisclosurePanel>Files content</DisclosurePanel>
23+
</Disclosure>
24+
);
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import type { Meta } from "@storybook/react";
2+
import React from "react";
3+
import {
4+
Disclosure,
5+
DisclosureHeader,
6+
DisclosurePanel,
7+
DisclosureGroup,
8+
} from "../src/Disclosure";
9+
10+
const meta: Meta<typeof DisclosureGroup> = {
11+
component: DisclosureGroup,
12+
parameters: {
13+
layout: 'centered'
14+
},
15+
tags: ['autodocs']
16+
};
17+
18+
export default meta;
19+
20+
export const Example = (args: any) => (
21+
<DisclosureGroup {...args}>
22+
<Disclosure>
23+
<DisclosureHeader>Files</DisclosureHeader>
24+
<DisclosurePanel>Files content</DisclosurePanel>
25+
</Disclosure>
26+
<Disclosure>
27+
<DisclosureHeader>Images</DisclosureHeader>
28+
<DisclosurePanel>Images content</DisclosurePanel>
29+
</Disclosure>
30+
<Disclosure>
31+
<DisclosureHeader>Documents</DisclosureHeader>
32+
<DisclosurePanel>Documents content</DisclosurePanel>
33+
</Disclosure>
34+
</DisclosureGroup>
35+
);
36+

0 commit comments

Comments
 (0)