Skip to content

Commit 257ef67

Browse files
authored
Merge pull request #28 from filecoin-project/bp/accordion-component
[UXIT-3442] Accordion component
2 parents 608637a + da4d4b7 commit 257ef67

File tree

14 files changed

+343
-267
lines changed

14 files changed

+343
-267
lines changed

components.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"$schema": "https://ui.shadcn.com/schema.json",
3+
"style": "new-york",
4+
"rsc": false,
5+
"tsx": true,
6+
"tailwind": {
7+
"config": "",
8+
"css": "src/index.css",
9+
"baseColor": "neutral",
10+
"cssVariables": true,
11+
"prefix": ""
12+
},
13+
"iconLibrary": "lucide",
14+
"aliases": {
15+
"components": "@/components",
16+
"utils": "@/lib/utils",
17+
"ui": "@/components/ui",
18+
"lib": "@/lib",
19+
"hooks": "@/hooks"
20+
},
21+
"registries": {}
22+
}

package-lock.json

Lines changed: 176 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@
1212
"typecheck": "tsc --noEmit"
1313
},
1414
"dependencies": {
15+
"@radix-ui/react-accordion": "^1.2.12",
1516
"@radix-ui/react-form": "^0.1.8",
1617
"@tailwindcss/vite": "^4.1.14",
1718
"class-variance-authority": "^0.7.1",
19+
"clsx": "^2.1.1",
1820
"filecoin-pin": "^0.7.3",
1921
"lucide-react": "^0.545.0",
2022
"pino": "^10.0.0",
@@ -34,6 +36,7 @@
3436
"buffer": "^6.0.3",
3537
"globals": "^16.4.0",
3638
"process": "^0.11.10",
39+
"tw-animate-css": "^1.4.0",
3740
"typescript": "~5.9.3",
3841
"vite": "^7.1.9"
3942
}

src/components/layout/content.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import DragNDrop from '../upload/drag-n-drop.tsx'
44
import UploadProgress from '../upload/upload-progress.tsx'
55
import './content.css'
66
import { PageTitle } from '../ui/page-title.tsx'
7+
import { Heading } from '../ui/heading.tsx'
78

89
export default function Content() {
910
const [uploadedFile, setUploadedFile] = useState<{ file: File; cid: string } | null>(null)
@@ -39,7 +40,8 @@ export default function Content() {
3940
<PageTitle />
4041

4142
{uploadedFile ? (
42-
<div className="upload-progress-section">
43+
<div className="space-y-6">
44+
<Heading tag="h2">Uploaded files</Heading>
4345
<UploadProgress
4446
fileName={uploadedFile.file.name}
4547
fileSize={formatFileSize(uploadedFile.file.size)}
@@ -78,7 +80,7 @@ export default function Content() {
7880
</div>
7981
) : (
8082
<div className="space-y-6">
81-
<h2 className="text-xl font-medium text-white">Upload a file</h2>
83+
<Heading tag="h2">Upload a file</Heading>
8284
<DragNDrop isUploading={uploadState.isUploading} onUpload={handleUpload} />
8385
</div>
8486
)}

src/components/ui/accordion.tsx

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import * as AccordionPrimitive from '@radix-ui/react-accordion'
2+
import { ChevronDownIcon } from 'lucide-react'
3+
4+
import { cn } from '../../utils/cn.ts'
5+
6+
function Accordion({ ...props }: React.ComponentProps<typeof AccordionPrimitive.Root>) {
7+
return <AccordionPrimitive.Root data-slot="accordion" {...props} />
8+
}
9+
10+
function AccordionItem({ className, ...props }: React.ComponentProps<typeof AccordionPrimitive.Item>) {
11+
return (
12+
<AccordionPrimitive.Item
13+
className={cn('border-b last:border-b-0', className)}
14+
data-slot="accordion-item"
15+
{...props}
16+
/>
17+
)
18+
}
19+
20+
function AccordionTrigger({ className, children, ...props }: React.ComponentProps<typeof AccordionPrimitive.Trigger>) {
21+
return (
22+
<AccordionPrimitive.Header className="flex">
23+
<AccordionPrimitive.Trigger
24+
className={cn(
25+
'focus-visible:border-ring focus-visible:ring-ring/50 flex flex-1 items-start justify-between gap-4 rounded-md py-4 text-left text-sm font-medium transition-all outline-none hover:underline focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&[data-state=open]>svg]:rotate-180',
26+
className
27+
)}
28+
data-slot="accordion-trigger"
29+
{...props}
30+
>
31+
{children}
32+
<ChevronDownIcon className="text-muted-foreground pointer-events-none size-5 shrink-0 translate-y-0.5 transition-transform duration-200" />
33+
</AccordionPrimitive.Trigger>
34+
</AccordionPrimitive.Header>
35+
)
36+
}
37+
38+
function AccordionContent({ className, children, ...props }: React.ComponentProps<typeof AccordionPrimitive.Content>) {
39+
return (
40+
<AccordionPrimitive.Content
41+
className="data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm"
42+
data-slot="accordion-content"
43+
{...props}
44+
>
45+
<div className={className}>{children}</div>
46+
</AccordionPrimitive.Content>
47+
)
48+
}
49+
50+
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }

src/components/ui/badge-status.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ const badgeVariants = cva('inline-flex items-center gap-1 pl-1.5 pr-2 py-0.5 rou
1313
variants: {
1414
status: {
1515
'in-progress': 'bg-badge-in-progress text-badge-in-progress-text border border-badge-in-progress-border',
16-
completed: 'bg-badge-success text-brand-50 border border-badge-success-border',
17-
pinned: 'bg-badge-success text-brand-50 border border-badge-success-border',
16+
completed: 'bg-brand-950 text-brand-700 border border-brand-900',
17+
pinned: 'bg-brand-950 text-brand-700 border border-brand-900',
1818
error: null,
1919
pending: 'bg-zinc-800 border border-zinc-700 text-zinc-300',
2020
},

src/components/ui/card.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ type CardWrapperProps = {
88
type CardHeaderProps = {
99
title: string
1010
status: UploadProgress['status']
11-
estimatedTime?: string
11+
estimatedTime?: number
1212
}
1313

1414
type CardContentProps = {
@@ -19,10 +19,11 @@ function CardWrapper({ children }: CardWrapperProps) {
1919
return <div className="bg-zinc-900 p-6 rounded-lg space-y-6">{children}</div>
2020
}
2121

22-
function CardHeader({ title, status }: CardHeaderProps) {
22+
function CardHeader({ title, status, estimatedTime }: CardHeaderProps) {
2323
return (
2424
<div className="flex items-center justify-between">
2525
<h3 className="font-medium">{title}</h3>
26+
{status === 'in-progress' && estimatedTime && <span className="text-sm text-zinc-400">{estimatedTime}%</span>}
2627
{status !== 'in-progress' && <BadgeStatus status={status} />}
2728
</div>
2829
)

0 commit comments

Comments
 (0)