Skip to content

Commit f40faa2

Browse files
Added a new accordion component
1 parent 331b464 commit f40faa2

File tree

5 files changed

+142
-10
lines changed

5 files changed

+142
-10
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import {
2+
Accordion,
3+
AccordionContent,
4+
AccordionItem,
5+
AccordionTrigger,
6+
} from "@/components/ui/accordion";
7+
8+
export function AccordionDemo() {
9+
return (
10+
<Accordion type="single" collapsible className="w-4/5">
11+
<AccordionItem value="item-1">
12+
<AccordionTrigger>Is it accessible?</AccordionTrigger>
13+
<AccordionContent>
14+
Yes. It adheres to the WAI-ARIA design pattern.
15+
</AccordionContent>
16+
</AccordionItem>
17+
<AccordionItem value="item-2">
18+
<AccordionTrigger>Is it styled?</AccordionTrigger>
19+
<AccordionContent>
20+
Yes. It comes with default styles that matches the other
21+
components&apos; aesthetic.
22+
</AccordionContent>
23+
</AccordionItem>
24+
<AccordionItem value="item-3">
25+
<AccordionTrigger>Is it animated?</AccordionTrigger>
26+
<AccordionContent>
27+
Yes. Its animated by default, but you can disable it if you prefer.
28+
</AccordionContent>
29+
</AccordionItem>
30+
</Accordion>
31+
);
32+
}

app/(docs)/docs/accordion/page.tsx

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import React from "react";
2+
import {
3+
PageSubTitle,
4+
PageTemplate,
5+
} from "@/app/(docs)/docs/components/page-template";
6+
import { Steppers } from "@/components/ui/steppers";
7+
import PreviewCodeCard from "@/app/(docs)/docs/components/preview-code-card";
8+
import { Metadata } from "next";
9+
import { baseMetadata } from "@/app/(docs)/layout-parts/base-metadata";
10+
import { AccordionDemo } from "./accordion-demo";
11+
12+
const tailwindConfigCode = ` extend: {
13+
keyframes: {
14+
"accordion-down": {
15+
from: { height: "0" },
16+
to: { height: "var(--radix-accordion-content-height)" },
17+
},
18+
"accordion-up": {
19+
from: { height: "var(--radix-accordion-content-height)" },
20+
to: { height: "0" },
21+
},
22+
},
23+
animation: {
24+
"accordion-down": "accordion-down 0.2s ease-out",
25+
"accordion-up": "accordion-up 0.2s ease-out",
26+
},
27+
},`;
28+
29+
export const metadata: Metadata = baseMetadata({
30+
title: "Accordion",
31+
description:
32+
"A vertically stacked set of interactive headings that each reveal a section of content.",
33+
});
34+
35+
const SkeletonLoadingPage = () => {
36+
return (
37+
<PageTemplate
38+
title="Accordion"
39+
description="A vertically stacked set of interactive headings that each reveal a section of content."
40+
>
41+
<PreviewCodeCard path="app/(docs)/docs/accordion/accordion-demo.tsx">
42+
{<AccordionDemo />}
43+
</PreviewCodeCard>
44+
45+
<PageSubTitle>Installation</PageSubTitle>
46+
<Steppers
47+
withInstall
48+
tailwindConfig={{
49+
tailwindConfig: true,
50+
code: tailwindConfigCode,
51+
}}
52+
codePath="components/ui/accordion.tsx"
53+
withEnd
54+
/>
55+
</PageTemplate>
56+
);
57+
};
58+
59+
export default SkeletonLoadingPage;

app/(docs)/layout-parts/documentation.constant.ts

+6
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,12 @@ export const DOCS: Documentation[] = [
138138
url: "/docs/skeleton",
139139
new: true,
140140
},
141+
{
142+
label: "Accordion",
143+
value: "accordion",
144+
url: "/docs/accordion",
145+
new: true,
146+
},
141147
],
142148
},
143149
];

components/ui/steppers.tsx

+44-10
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,30 @@ import { H4 } from "@/components/ui/heading-with-anchor";
33
import { cn } from "@/lib/utils";
44
import CodeHighlight from "@/app/(docs)/docs/components/code-card/parts/code-highlight";
55
import fs from "fs/promises";
6+
import { InlineCode } from "./inline-code";
67

78
interface StepperProps {
89
children?: React.ReactNode;
910
title?: string;
1011
step?: number;
1112
}
13+
1214
const Stepper = ({ title, children, step }: StepperProps) => {
1315
return (
1416
<div>
1517
<div className="flex items-center gap-3">
16-
<span className="flex h-10 w-10 items-center justify-center rounded-full bg-zinc-800 text-white p-3 ">
18+
<span className="flex h-10 w-10 items-center justify-center rounded-full bg-zinc-800 text-white p-3">
1719
{step}
1820
</span>
19-
<H4>{title}</H4>
21+
<H4>
22+
{title === "Extend tailwind.config.js" ? (
23+
<span>
24+
Extend <InlineCode>tailwind.config.js</InlineCode>
25+
</span>
26+
) : (
27+
title
28+
)}
29+
</H4>
2030
</div>
2131
<div className="my-3 ml-5 border-l-2 border-l-gray-200 pl-8">
2232
{children}
@@ -31,28 +41,38 @@ interface SteppersBaseProps {
3141
withEnd?: boolean;
3242
}
3343

44+
interface TailwindConfigStep {
45+
tailwindConfig?: boolean;
46+
code?: string;
47+
}
48+
3449
interface SteppersWithInstallProps extends SteppersBaseProps {
3550
withInstall?: true;
36-
/** 要複製的程式碼 */
3751
codePath?: string;
38-
/** npm install script */
3952
installScript?: string;
53+
tailwindConfig?: TailwindConfigStep;
4054
}
4155

4256
interface SteppersWithoutInstallProps extends SteppersBaseProps {
4357
withInstall?: false;
58+
tailwindConfig?: TailwindConfigStep;
4459
}
4560

4661
type SteppersProps = SteppersWithInstallProps | SteppersWithoutInstallProps;
4762

4863
export const Steppers = async (props: SteppersProps) => {
49-
const { steps, className, withEnd, withInstall } = props;
64+
const { steps, className, withEnd, withInstall, tailwindConfig } = props;
5065

5166
let installCode = "";
5267
if (withInstall && props.codePath) {
5368
installCode = await fs.readFile(props.codePath, "utf8");
5469
}
55-
const withInstallOffset = withInstall ? (props.installScript ? 2 : 1) : 0;
70+
71+
// Calculate the offset based on install steps and tailwind config
72+
const installStepsCount = withInstall ? (props.installScript ? 2 : 1) : 0;
73+
const tailwindStepCount = tailwindConfig?.tailwindConfig ? 1 : 0;
74+
const totalOffset = installStepsCount + tailwindStepCount;
75+
5676
return (
5777
<>
5878
<div className={cn(className)}>
@@ -61,30 +81,44 @@ export const Steppers = async (props: SteppersProps) => {
6181
{props.installScript && (
6282
<Stepper
6383
title="Install the package if you do not have it."
64-
step={withInstallOffset - 1}
84+
step={1}
6585
>
6686
<CodeHighlight lang="shell" code={props.installScript} />
6787
</Stepper>
6888
)}
6989
<Stepper
7090
title="Copy and paste the following code into your project."
71-
step={withInstallOffset}
91+
step={props.installScript ? 2 : 1}
7292
>
7393
<CodeHighlight code={installCode} withExpand={false} />
7494
</Stepper>
7595
</>
7696
)}
97+
98+
{tailwindConfig?.tailwindConfig && (
99+
<Stepper
100+
title="Extend tailwind.config.js"
101+
step={installStepsCount + 1}
102+
>
103+
<CodeHighlight
104+
code={tailwindConfig.code || ""}
105+
withExpand={false}
106+
/>
107+
</Stepper>
108+
)}
109+
77110
{steps?.map((props, index) => (
78111
<Stepper
79112
key={props.title}
80113
{...props}
81-
step={index + 1 + withInstallOffset}
114+
step={index + 1 + totalOffset}
82115
/>
83116
))}
117+
84118
{withEnd && (
85119
<Stepper
86120
title="Update the import paths to match your project setup."
87-
step={(steps?.length || 0) + 1 + withInstallOffset}
121+
step={(steps?.length || 0) + 1 + totalOffset}
88122
/>
89123
)}
90124
</div>

lib/routes-config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export const ROUTES = [
6565
},
6666
{ label: "Spinner", value: "spinner", url: `${BASE_PATH}/spinner` },
6767
{ label: "Skeleton", value: "skeleton", url: `${BASE_PATH}/skeleton` },
68+
{ label: "Accordion", value: "accordion", url: `${BASE_PATH}/accordion` },
6869
],
6970
},
7071
];

0 commit comments

Comments
 (0)