@wealthx/shadcn 0.0.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +160 -0
- package/CHANGELOG.md +13 -0
- package/CHANGES.md +345 -0
- package/dist/chunk-2WZVSBAY.mjs +232 -0
- package/dist/chunk-2Y7YJKPE.mjs +47 -0
- package/dist/chunk-3U7SD3MS.mjs +55 -0
- package/dist/chunk-3VQNJ235.mjs +114 -0
- package/dist/chunk-55CEW76V.mjs +35 -0
- package/dist/chunk-6AFMNC42.mjs +146 -0
- package/dist/chunk-6OJF6XRN.mjs +117 -0
- package/dist/chunk-7LDIMXGM.mjs +181 -0
- package/dist/chunk-AMJ23O53.mjs +122 -0
- package/dist/chunk-BBJBJSXQ.mjs +44 -0
- package/dist/chunk-BGP2N52Z.mjs +126 -0
- package/dist/chunk-BMFN37JH.mjs +41 -0
- package/dist/chunk-CGOKTPXU.mjs +79 -0
- package/dist/chunk-CZ3BW5GL.mjs +81 -0
- package/dist/chunk-DBHJ5KC3.mjs +55 -0
- package/dist/chunk-DDPA2XXS.mjs +97 -0
- package/dist/chunk-DS2AMHN2.mjs +30 -0
- package/dist/chunk-E3K6O4FZ.mjs +57 -0
- package/dist/chunk-FWCSY2DS.mjs +37 -0
- package/dist/chunk-GPRJQ24C.mjs +28 -0
- package/dist/chunk-HS7TFG7V.mjs +24 -0
- package/dist/chunk-HUVTPUV2.mjs +256 -0
- package/dist/chunk-IAOOZCUY.mjs +90 -0
- package/dist/chunk-JF4PHPD5.mjs +111 -0
- package/dist/chunk-JU2RUWHF.mjs +123 -0
- package/dist/chunk-KKHTJNMM.mjs +86 -0
- package/dist/chunk-MJIEMGRD.mjs +266 -0
- package/dist/chunk-MKFL5MNH.mjs +372 -0
- package/dist/chunk-MQ72DIBH.mjs +105 -0
- package/dist/chunk-NGYG2EA6.mjs +148 -0
- package/dist/chunk-NWZ46DJL.mjs +213 -0
- package/dist/chunk-OXQQNQZI.mjs +75 -0
- package/dist/chunk-PMKODV6M.mjs +161 -0
- package/dist/chunk-QOJ2DQD6.mjs +57 -0
- package/dist/chunk-RL772EH7.mjs +126 -0
- package/dist/chunk-SLWCCURD.mjs +99 -0
- package/dist/chunk-V7CNWJT3.mjs +10 -0
- package/dist/chunk-VG6UF6UT.mjs +68 -0
- package/dist/chunk-VYMHBV6D.mjs +123 -0
- package/dist/chunk-VZ2NR7L3.mjs +195 -0
- package/dist/chunk-YN5SYTOO.mjs +117 -0
- package/dist/chunk-Z3MK2KKZ.mjs +83 -0
- package/dist/chunk-ZN2QKLF6.mjs +187 -0
- package/dist/chunk-ZZV5JVNW.mjs +34 -0
- package/dist/components/ui/accordion.js +142 -0
- package/dist/components/ui/accordion.mjs +14 -0
- package/dist/components/ui/alert-dialog.js +413 -0
- package/dist/components/ui/alert-dialog.mjs +34 -0
- package/dist/components/ui/alert.js +134 -0
- package/dist/components/ui/alert.mjs +12 -0
- package/dist/components/ui/avatar.js +173 -0
- package/dist/components/ui/avatar.mjs +18 -0
- package/dist/components/ui/badge.js +163 -0
- package/dist/components/ui/badge.mjs +11 -0
- package/dist/components/ui/button.js +198 -0
- package/dist/components/ui/button.mjs +11 -0
- package/dist/components/ui/calendar.js +408 -0
- package/dist/components/ui/calendar.mjs +12 -0
- package/dist/components/ui/card.js +156 -0
- package/dist/components/ui/card.mjs +20 -0
- package/dist/components/ui/checkbox.js +166 -0
- package/dist/components/ui/checkbox.mjs +11 -0
- package/dist/components/ui/chip.js +199 -0
- package/dist/components/ui/chip.mjs +10 -0
- package/dist/components/ui/data-table.js +925 -0
- package/dist/components/ui/data-table.mjs +29 -0
- package/dist/components/ui/date-picker.js +561 -0
- package/dist/components/ui/date-picker.mjs +15 -0
- package/dist/components/ui/dialog.js +378 -0
- package/dist/components/ui/dialog.mjs +30 -0
- package/dist/components/ui/drawer.js +213 -0
- package/dist/components/ui/drawer.mjs +28 -0
- package/dist/components/ui/dropdown-menu.js +338 -0
- package/dist/components/ui/dropdown-menu.mjs +38 -0
- package/dist/components/ui/empty.js +173 -0
- package/dist/components/ui/empty.mjs +18 -0
- package/dist/components/ui/field.js +359 -0
- package/dist/components/ui/field.mjs +28 -0
- package/dist/components/ui/input-group.js +406 -0
- package/dist/components/ui/input-group.mjs +22 -0
- package/dist/components/ui/input-otp.js +149 -0
- package/dist/components/ui/input-otp.mjs +14 -0
- package/dist/components/ui/input.js +81 -0
- package/dist/components/ui/input.mjs +8 -0
- package/dist/components/ui/label.js +85 -0
- package/dist/components/ui/label.mjs +8 -0
- package/dist/components/ui/pagination.js +333 -0
- package/dist/components/ui/pagination.mjs +22 -0
- package/dist/components/ui/popover.js +167 -0
- package/dist/components/ui/popover.mjs +22 -0
- package/dist/components/ui/progress.js +97 -0
- package/dist/components/ui/progress.mjs +8 -0
- package/dist/components/ui/radio-group.js +178 -0
- package/dist/components/ui/radio-group.mjs +12 -0
- package/dist/components/ui/select.js +262 -0
- package/dist/components/ui/select.mjs +28 -0
- package/dist/components/ui/separator.js +86 -0
- package/dist/components/ui/separator.mjs +8 -0
- package/dist/components/ui/sheet.js +227 -0
- package/dist/components/ui/sheet.mjs +26 -0
- package/dist/components/ui/skeleton.js +75 -0
- package/dist/components/ui/skeleton.mjs +8 -0
- package/dist/components/ui/sonner.js +86 -0
- package/dist/components/ui/sonner.mjs +7 -0
- package/dist/components/ui/spinner.js +93 -0
- package/dist/components/ui/spinner.mjs +10 -0
- package/dist/components/ui/switch.js +178 -0
- package/dist/components/ui/switch.mjs +11 -0
- package/dist/components/ui/table.js +184 -0
- package/dist/components/ui/table.mjs +22 -0
- package/dist/components/ui/tabs.js +181 -0
- package/dist/components/ui/tabs.mjs +16 -0
- package/dist/components/ui/textarea.js +79 -0
- package/dist/components/ui/textarea.mjs +8 -0
- package/dist/components/ui/toggle-group.js +184 -0
- package/dist/components/ui/toggle-group.mjs +12 -0
- package/dist/components/ui/toggle.js +108 -0
- package/dist/components/ui/toggle.mjs +11 -0
- package/dist/components/ui/tooltip.js +140 -0
- package/dist/components/ui/tooltip.mjs +16 -0
- package/dist/index.js +4409 -0
- package/dist/index.mjs +462 -0
- package/dist/lib/colors.js +84 -0
- package/dist/lib/colors.mjs +13 -0
- package/dist/lib/theme-provider.js +150 -0
- package/dist/lib/theme-provider.mjs +13 -0
- package/dist/lib/typography.js +157 -0
- package/dist/lib/typography.mjs +25 -0
- package/dist/lib/utils.js +34 -0
- package/dist/lib/utils.mjs +7 -0
- package/dist/styles.css +2 -0
- package/package.json +228 -11
- package/scripts/build-css.ts +15 -9
- package/src/components/index.tsx +443 -0
- package/src/components/ui/accordion.tsx +99 -0
- package/src/components/ui/alert-dialog.tsx +239 -0
- package/src/components/ui/alert.tsx +81 -0
- package/src/components/ui/avatar.tsx +130 -0
- package/src/components/ui/badge.tsx +57 -0
- package/src/components/ui/button.tsx +69 -37
- package/src/components/ui/calendar.tsx +252 -0
- package/src/components/ui/card.tsx +106 -0
- package/src/components/ui/checkbox.tsx +111 -0
- package/src/components/ui/chip.tsx +65 -0
- package/src/components/ui/data-table.tsx +490 -0
- package/src/components/ui/date-picker.tsx +133 -0
- package/src/components/ui/dialog.tsx +195 -0
- package/src/components/ui/drawer.tsx +169 -0
- package/src/components/ui/dropdown-menu.tsx +315 -0
- package/src/components/ui/empty.tsx +128 -0
- package/src/components/ui/field.tsx +273 -0
- package/src/components/ui/input-group.tsx +190 -0
- package/src/components/ui/input-otp.tsx +90 -0
- package/src/components/ui/input.tsx +28 -0
- package/src/components/ui/label.tsx +24 -0
- package/src/components/ui/pagination.tsx +148 -0
- package/src/components/ui/popover.tsx +112 -0
- package/src/components/ui/progress.tsx +40 -0
- package/src/components/ui/radio-group.tsx +129 -0
- package/src/components/ui/select.tsx +201 -0
- package/src/components/ui/separator.tsx +26 -0
- package/src/components/ui/sheet.tsx +182 -0
- package/src/components/ui/skeleton.tsx +22 -0
- package/src/components/ui/sonner.tsx +48 -0
- package/src/components/ui/spinner.tsx +41 -0
- package/src/components/ui/switch.tsx +126 -0
- package/src/components/ui/table.tsx +143 -0
- package/src/components/ui/tabs.tsx +119 -0
- package/src/components/ui/textarea.tsx +28 -0
- package/src/components/ui/toggle-group.tsx +94 -0
- package/src/components/ui/toggle.tsx +59 -0
- package/src/components/ui/tooltip.tsx +80 -0
- package/src/index.ts +15 -3
- package/src/lib/colors.ts +74 -0
- package/src/lib/slot.tsx +68 -0
- package/src/lib/theme-provider.tsx +134 -0
- package/src/lib/typography.ts +153 -0
- package/src/lib/utils.ts +1 -1
- package/src/styles/globals.css +377 -107
- package/src/styles/styles-css.ts +1 -1
- package/tsup.config.ts +48 -2
- package/src/provider/ShadcnProvider.tsx +0 -89
- package/src/provider/index.ts +0 -2
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sheet — WealthX DS overrides (shadcn / base-ui dialog)
|
|
3
|
+
*
|
|
4
|
+
* Changes from shadcn default:
|
|
5
|
+
* - SheetOverlay: `bg-black/50` -- `bg-foreground/50` — DS foreground token (matches Figma)
|
|
6
|
+
* - SheetContent: `shadow-lg` removed — flat panels per Figma
|
|
7
|
+
* - SheetTitle: added `text-lg` — matches Figma Text-lg/Semibold
|
|
8
|
+
* - Close button: matches DialogClose — no radius, `hover:bg-foreground/5`, `focus:ring-border`
|
|
9
|
+
*/
|
|
10
|
+
import { type ReactElement } from "react"
|
|
11
|
+
import * as React from "react"
|
|
12
|
+
import { XIcon } from "lucide-react"
|
|
13
|
+
import { Dialog as SheetPrimitive } from "@base-ui/react/dialog"
|
|
14
|
+
import { cn } from "@/lib/utils"
|
|
15
|
+
import { useThemeVars } from "@/lib/theme-provider"
|
|
16
|
+
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// Side-specific panel classes
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
const SIDE_CLASSES = {
|
|
22
|
+
right: "inset-y-0 right-0 h-full w-3/4 border-l data-ending-style:slide-out-to-right data-open:slide-in-from-right sm:max-w-sm",
|
|
23
|
+
left: "inset-y-0 left-0 h-full w-3/4 border-r data-ending-style:slide-out-to-left data-open:slide-in-from-left sm:max-w-sm",
|
|
24
|
+
top: "inset-x-0 top-0 h-auto border-b data-ending-style:slide-out-to-top data-open:slide-in-from-top",
|
|
25
|
+
bottom: "inset-x-0 bottom-0 h-auto border-t data-ending-style:slide-out-to-bottom data-open:slide-in-from-bottom",
|
|
26
|
+
} satisfies Record<string, string>
|
|
27
|
+
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Components
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
export type SheetProps = React.ComponentProps<typeof SheetPrimitive.Root>
|
|
33
|
+
|
|
34
|
+
function Sheet({ ...props }: SheetProps): ReactElement {
|
|
35
|
+
return <SheetPrimitive.Root data-slot="sheet" {...props} />
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type SheetTriggerProps = React.ComponentProps<typeof SheetPrimitive.Trigger>
|
|
39
|
+
|
|
40
|
+
function SheetTrigger({
|
|
41
|
+
...props
|
|
42
|
+
}: SheetTriggerProps): ReactElement {
|
|
43
|
+
return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type SheetCloseProps = React.ComponentProps<typeof SheetPrimitive.Close>
|
|
47
|
+
|
|
48
|
+
function SheetClose({
|
|
49
|
+
...props
|
|
50
|
+
}: SheetCloseProps): ReactElement {
|
|
51
|
+
return <SheetPrimitive.Close data-slot="sheet-close" {...props} />
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export type SheetPortalProps = React.ComponentProps<typeof SheetPrimitive.Portal>
|
|
55
|
+
|
|
56
|
+
function SheetPortal({
|
|
57
|
+
...props
|
|
58
|
+
}: SheetPortalProps): ReactElement {
|
|
59
|
+
return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function SheetOverlay({
|
|
63
|
+
className,
|
|
64
|
+
...props
|
|
65
|
+
}: React.ComponentProps<typeof SheetPrimitive.Backdrop>): ReactElement {
|
|
66
|
+
return (
|
|
67
|
+
<SheetPrimitive.Backdrop
|
|
68
|
+
className={cn(
|
|
69
|
+
"fixed inset-0 z-50 bg-foreground/50 data-ending-style:animate-out data-ending-style:fade-out-0 data-ending-style:fill-mode-forwards data-open:animate-in data-open:fade-in-0",
|
|
70
|
+
className
|
|
71
|
+
)}
|
|
72
|
+
data-slot="sheet-overlay"
|
|
73
|
+
{...props}
|
|
74
|
+
/>
|
|
75
|
+
)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export type SheetContentProps = React.ComponentProps<typeof SheetPrimitive.Popup> & {
|
|
79
|
+
side?: keyof typeof SIDE_CLASSES
|
|
80
|
+
showCloseButton?: boolean
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function SheetContent({
|
|
84
|
+
className,
|
|
85
|
+
children,
|
|
86
|
+
side = "right",
|
|
87
|
+
showCloseButton = true,
|
|
88
|
+
style,
|
|
89
|
+
...props
|
|
90
|
+
}: SheetContentProps): ReactElement {
|
|
91
|
+
const themeVars = useThemeVars();
|
|
92
|
+
return (
|
|
93
|
+
<SheetPortal>
|
|
94
|
+
<SheetOverlay />
|
|
95
|
+
<SheetPrimitive.Popup
|
|
96
|
+
className={cn(
|
|
97
|
+
"fixed z-50 flex flex-col gap-4 bg-background transition ease-in-out data-ending-style:animate-out data-ending-style:duration-300 data-ending-style:fill-mode-forwards data-open:animate-in data-open:duration-500",
|
|
98
|
+
SIDE_CLASSES[side],
|
|
99
|
+
className
|
|
100
|
+
)}
|
|
101
|
+
data-slot="sheet-content"
|
|
102
|
+
style={{ ...themeVars, ...style } as React.CSSProperties}
|
|
103
|
+
{...props}
|
|
104
|
+
>
|
|
105
|
+
{children}
|
|
106
|
+
{showCloseButton ? <SheetPrimitive.Close
|
|
107
|
+
className="absolute top-4 right-4 transition-colors hover:bg-foreground/5 focus:outline-hidden focus:ring-2 focus:ring-border focus:ring-offset-0 disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4"
|
|
108
|
+
data-slot="sheet-icon-close"
|
|
109
|
+
>
|
|
110
|
+
<XIcon />
|
|
111
|
+
<span className="sr-only">Close</span>
|
|
112
|
+
</SheetPrimitive.Close> : null}
|
|
113
|
+
</SheetPrimitive.Popup>
|
|
114
|
+
</SheetPortal>
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export type SheetHeaderProps = React.ComponentProps<"div">
|
|
119
|
+
|
|
120
|
+
function SheetHeader({ className, ...props }: SheetHeaderProps): ReactElement {
|
|
121
|
+
return (
|
|
122
|
+
<div
|
|
123
|
+
className={cn("flex flex-col gap-1.5 p-4", className)}
|
|
124
|
+
data-slot="sheet-header"
|
|
125
|
+
{...props}
|
|
126
|
+
/>
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export type SheetFooterProps = React.ComponentProps<"div">
|
|
131
|
+
|
|
132
|
+
function SheetFooter({ className, ...props }: SheetFooterProps): ReactElement {
|
|
133
|
+
return (
|
|
134
|
+
<div
|
|
135
|
+
className={cn("mt-auto flex flex-col gap-2 p-4", className)}
|
|
136
|
+
data-slot="sheet-footer"
|
|
137
|
+
{...props}
|
|
138
|
+
/>
|
|
139
|
+
)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export type SheetTitleProps = React.ComponentProps<typeof SheetPrimitive.Title>
|
|
143
|
+
|
|
144
|
+
function SheetTitle({
|
|
145
|
+
className,
|
|
146
|
+
...props
|
|
147
|
+
}: SheetTitleProps): ReactElement {
|
|
148
|
+
return (
|
|
149
|
+
<SheetPrimitive.Title
|
|
150
|
+
className={cn("text-lg font-semibold text-foreground", className)}
|
|
151
|
+
data-slot="sheet-title"
|
|
152
|
+
{...props}
|
|
153
|
+
/>
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export type SheetDescriptionProps = React.ComponentProps<typeof SheetPrimitive.Description>
|
|
158
|
+
|
|
159
|
+
function SheetDescription({
|
|
160
|
+
className,
|
|
161
|
+
...props
|
|
162
|
+
}: SheetDescriptionProps): ReactElement {
|
|
163
|
+
return (
|
|
164
|
+
<SheetPrimitive.Description
|
|
165
|
+
className={cn("text-sm text-muted-foreground", className)}
|
|
166
|
+
data-slot="sheet-description"
|
|
167
|
+
{...props}
|
|
168
|
+
/>
|
|
169
|
+
)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export {
|
|
173
|
+
Sheet,
|
|
174
|
+
SheetClose,
|
|
175
|
+
SheetContent,
|
|
176
|
+
SheetDescription,
|
|
177
|
+
SheetFooter,
|
|
178
|
+
SheetHeader,
|
|
179
|
+
SheetPortal,
|
|
180
|
+
SheetTitle,
|
|
181
|
+
SheetTrigger,
|
|
182
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type ReactElement, type ComponentProps } from "react"
|
|
2
|
+
import { cn } from "@/lib/utils"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Skeleton — WealthX Design System (shadcn base)
|
|
6
|
+
*
|
|
7
|
+
* Base: official shadcn skeleton (npx shadcn\@latest add skeleton)
|
|
8
|
+
* WealthX override: removed rounded-md (sharp corners per design system)
|
|
9
|
+
*/
|
|
10
|
+
export type SkeletonProps = ComponentProps<"div">
|
|
11
|
+
|
|
12
|
+
function Skeleton({ className, ...props }: SkeletonProps): ReactElement {
|
|
13
|
+
return (
|
|
14
|
+
<div
|
|
15
|
+
className={cn("animate-pulse bg-muted", className)}
|
|
16
|
+
data-slot="skeleton"
|
|
17
|
+
{...props}
|
|
18
|
+
/>
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { Skeleton }
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type ReactElement } from "react"
|
|
2
|
+
import React from "react"
|
|
3
|
+
import {
|
|
4
|
+
CircleCheckIcon,
|
|
5
|
+
InfoIcon,
|
|
6
|
+
Loader2Icon,
|
|
7
|
+
OctagonXIcon,
|
|
8
|
+
TriangleAlertIcon,
|
|
9
|
+
} from "lucide-react"
|
|
10
|
+
import { Toaster as Sonner, type ToasterProps } from "sonner"
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Toaster — WealthX Design System (shadcn base)
|
|
14
|
+
* Figma: https://www.figma.com/design/9V9F0NGVsif8LGmEhVjOcT/Design-System---shadcn?node-id=3094-7557
|
|
15
|
+
*
|
|
16
|
+
* Variants: Default | Success | Info | Warning | Error | Loading
|
|
17
|
+
* Left accent strip (4px) applied to all status types via globals.css data-type selectors.
|
|
18
|
+
* WealthX uses a custom ThemeProvider (not next-themes), so `theme` defaults to "light".
|
|
19
|
+
*/
|
|
20
|
+
function Toaster({ theme = "light", ...props }: ToasterProps): ReactElement {
|
|
21
|
+
return <Sonner
|
|
22
|
+
className="toaster group"
|
|
23
|
+
icons={{
|
|
24
|
+
success: <CircleCheckIcon className="size-4" />,
|
|
25
|
+
info: <InfoIcon className="size-4" />,
|
|
26
|
+
warning: <TriangleAlertIcon className="size-4" />,
|
|
27
|
+
error: <OctagonXIcon className="size-4" />,
|
|
28
|
+
loading: <Loader2Icon className="size-4 animate-spin" />,
|
|
29
|
+
}}
|
|
30
|
+
style={
|
|
31
|
+
{
|
|
32
|
+
"--normal-bg": "var(--popover)",
|
|
33
|
+
"--normal-text": "var(--popover-foreground)",
|
|
34
|
+
"--normal-border": "var(--border)",
|
|
35
|
+
"--border-radius": "var(--radius)",
|
|
36
|
+
} as React.CSSProperties
|
|
37
|
+
}
|
|
38
|
+
theme={theme}
|
|
39
|
+
toastOptions={{
|
|
40
|
+
classNames: {
|
|
41
|
+
toast: "font-sans",
|
|
42
|
+
},
|
|
43
|
+
}}
|
|
44
|
+
{...props}
|
|
45
|
+
/>
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { Toaster }
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type ReactElement, type ComponentProps } from "react"
|
|
2
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
|
3
|
+
import { LoaderCircle } from "lucide-react"
|
|
4
|
+
import { cn } from "@/lib/utils"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Spinner — WealthX Design System
|
|
8
|
+
* Figma: https://www.figma.com/design/9V9F0NGVsif8LGmEhVjOcT/Design-System---shadcn?node-id=1196-1174
|
|
9
|
+
*
|
|
10
|
+
* Built on lucide-react LoaderCircle + animate-spin.
|
|
11
|
+
* Color inherits from parent via currentColor — use text-* to style.
|
|
12
|
+
* Sizes: sm (12px) | default (16px) | lg (24px) | xl (32px)
|
|
13
|
+
*/
|
|
14
|
+
const spinnerVariants = cva("animate-spin shrink-0", {
|
|
15
|
+
variants: {
|
|
16
|
+
size: {
|
|
17
|
+
sm: "size-3",
|
|
18
|
+
default: "size-4",
|
|
19
|
+
lg: "size-6",
|
|
20
|
+
xl: "size-8",
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
defaultVariants: {
|
|
24
|
+
size: "default",
|
|
25
|
+
},
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
export type SpinnerProps = ComponentProps<"svg"> & VariantProps<typeof spinnerVariants>
|
|
29
|
+
|
|
30
|
+
function Spinner({ className, size, ...props }: SpinnerProps): ReactElement {
|
|
31
|
+
return (
|
|
32
|
+
<LoaderCircle
|
|
33
|
+
aria-hidden="true"
|
|
34
|
+
className={cn(spinnerVariants({ size }), className)}
|
|
35
|
+
data-slot="spinner"
|
|
36
|
+
{...props}
|
|
37
|
+
/>
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { Spinner, spinnerVariants }
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
|
|
3
|
+
import { type ReactElement, useState, type ComponentProps } from "react"
|
|
4
|
+
import { Switch as SwitchPrimitive } from "@base-ui/react/switch"
|
|
5
|
+
import { cn } from "@/lib/utils"
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Switch — shadcn/WealthX
|
|
9
|
+
* Base: npx shadcn\@latest add switch (latest)
|
|
10
|
+
* Figma: Design-System---shadcn?node-id=3041-6197
|
|
11
|
+
*
|
|
12
|
+
* WealthX additions: aria-invalid error state, SwitchCard with position variants.
|
|
13
|
+
* Tokens: unchecked=input, checked=primary, error=destructive, thumb=background.
|
|
14
|
+
*/
|
|
15
|
+
export type SwitchProps = ComponentProps<typeof SwitchPrimitive.Root> & {
|
|
16
|
+
size?: "sm" | "default"
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function Switch({
|
|
20
|
+
className,
|
|
21
|
+
size = "default",
|
|
22
|
+
...props
|
|
23
|
+
}: SwitchProps): ReactElement {
|
|
24
|
+
return (
|
|
25
|
+
<SwitchPrimitive.Root
|
|
26
|
+
className={cn(
|
|
27
|
+
"peer group/switch inline-flex shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none",
|
|
28
|
+
"focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50",
|
|
29
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
30
|
+
"data-[size=default]:h-[1.15rem] data-[size=default]:w-8",
|
|
31
|
+
"data-[size=sm]:h-3.5 data-[size=sm]:w-6",
|
|
32
|
+
"data-checked:bg-primary data-unchecked:bg-input",
|
|
33
|
+
"aria-invalid:data-checked:bg-destructive aria-invalid:border-destructive",
|
|
34
|
+
"dark:data-unchecked:bg-input/80",
|
|
35
|
+
className
|
|
36
|
+
)}
|
|
37
|
+
data-size={size}
|
|
38
|
+
data-slot="switch"
|
|
39
|
+
{...props}
|
|
40
|
+
>
|
|
41
|
+
<SwitchPrimitive.Thumb
|
|
42
|
+
className={cn(
|
|
43
|
+
"pointer-events-none block rounded-full bg-background ring-0 transition-transform",
|
|
44
|
+
"group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3",
|
|
45
|
+
"data-checked:translate-x-[calc(100%-2px)] data-unchecked:translate-x-0",
|
|
46
|
+
"dark:data-checked:bg-primary-foreground dark:data-unchecked:bg-foreground"
|
|
47
|
+
)}
|
|
48
|
+
data-slot="switch-thumb"
|
|
49
|
+
/>
|
|
50
|
+
</SwitchPrimitive.Root>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* SwitchCard -- card wrapper with label + description + switch toggle.
|
|
56
|
+
* Figma: SwitchCard (3041:6237)
|
|
57
|
+
*/
|
|
58
|
+
export type SwitchCardProps = Omit<ComponentProps<typeof SwitchPrimitive.Root>, "children"> & {
|
|
59
|
+
label: string
|
|
60
|
+
description?: string
|
|
61
|
+
error?: boolean
|
|
62
|
+
switchPosition?: "left" | "right"
|
|
63
|
+
size?: "sm" | "default"
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function SwitchCard({
|
|
67
|
+
className,
|
|
68
|
+
checked,
|
|
69
|
+
defaultChecked,
|
|
70
|
+
onCheckedChange,
|
|
71
|
+
disabled,
|
|
72
|
+
error,
|
|
73
|
+
label,
|
|
74
|
+
description,
|
|
75
|
+
switchPosition = "right",
|
|
76
|
+
size,
|
|
77
|
+
...props
|
|
78
|
+
}: SwitchCardProps): ReactElement {
|
|
79
|
+
const [internalChecked, setInternalChecked] = useState(defaultChecked ?? false)
|
|
80
|
+
const isChecked = checked ?? internalChecked
|
|
81
|
+
|
|
82
|
+
const switchElement = (
|
|
83
|
+
<Switch
|
|
84
|
+
aria-invalid={error || undefined}
|
|
85
|
+
checked={isChecked as boolean}
|
|
86
|
+
className="shrink-0"
|
|
87
|
+
disabled={disabled}
|
|
88
|
+
onCheckedChange={(value, event) => {
|
|
89
|
+
setInternalChecked(value)
|
|
90
|
+
onCheckedChange?.(value, event)
|
|
91
|
+
}}
|
|
92
|
+
size={size}
|
|
93
|
+
{...props}
|
|
94
|
+
/>
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
const contentElement = (
|
|
98
|
+
<div className="flex flex-col gap-1">
|
|
99
|
+
<span className="text-sm font-medium leading-none">{label}</span>
|
|
100
|
+
{description ? <span className="text-sm text-muted-foreground">{description}</span> : null}
|
|
101
|
+
</div>
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<label
|
|
106
|
+
className={cn(
|
|
107
|
+
"flex items-center gap-3 border border-border p-4 font-sans transition-colors cursor-pointer",
|
|
108
|
+
switchPosition === "right" && "justify-between",
|
|
109
|
+
disabled && "cursor-not-allowed opacity-50",
|
|
110
|
+
error
|
|
111
|
+
? ["border-destructive", isChecked && "bg-destructive/5"]
|
|
112
|
+
: isChecked && "border-primary bg-primary/5",
|
|
113
|
+
className
|
|
114
|
+
)}
|
|
115
|
+
data-slot="switch-card"
|
|
116
|
+
>
|
|
117
|
+
{switchPosition === "left" ? (
|
|
118
|
+
<>{switchElement}{contentElement}</>
|
|
119
|
+
) : (
|
|
120
|
+
<>{contentElement}{switchElement}</>
|
|
121
|
+
)}
|
|
122
|
+
</label>
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export { Switch, SwitchCard }
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table — WealthX DS overrides (shadcn base)
|
|
3
|
+
*
|
|
4
|
+
* Changes from shadcn default:
|
|
5
|
+
* - TableHead: `text-foreground` -- `text-muted-foreground` — header labels are secondary text
|
|
6
|
+
* - TableHead: `px-2` -- `px-4` — wider horizontal padding per Figma spacing
|
|
7
|
+
* - TableCell: `p-2` -- `px-4 py-3` — consistent cell padding per Figma
|
|
8
|
+
* - TableRow: `transition-colors` -- `transition-[background-color,opacity]` — scoped animation
|
|
9
|
+
* - TableRow: `data-[state=selected]:bg-muted` -- `data-[state=selected]:bg-primary/10` — selected tint matches Figma (primary + 10% opacity)
|
|
10
|
+
* - TableFooter: inherits same cell padding via className
|
|
11
|
+
*/
|
|
12
|
+
import { type ReactElement } from "react"
|
|
13
|
+
import * as React from "react"
|
|
14
|
+
import { cn } from "@/lib/utils"
|
|
15
|
+
|
|
16
|
+
export type TableProps = React.ComponentProps<"table">
|
|
17
|
+
|
|
18
|
+
function Table({ className, ...props }: TableProps): ReactElement {
|
|
19
|
+
return (
|
|
20
|
+
<div
|
|
21
|
+
className="relative w-full overflow-x-auto"
|
|
22
|
+
data-slot="table-container"
|
|
23
|
+
>
|
|
24
|
+
<table
|
|
25
|
+
className={cn("w-full caption-bottom text-sm", className)}
|
|
26
|
+
data-slot="table"
|
|
27
|
+
{...props}
|
|
28
|
+
/>
|
|
29
|
+
</div>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type TableHeaderProps = React.ComponentProps<"thead">
|
|
34
|
+
|
|
35
|
+
function TableHeader({ className, ...props }: TableHeaderProps): ReactElement {
|
|
36
|
+
return (
|
|
37
|
+
<thead
|
|
38
|
+
className={cn("[&_tr]:border-b", className)}
|
|
39
|
+
data-slot="table-header"
|
|
40
|
+
{...props}
|
|
41
|
+
/>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export type TableBodyProps = React.ComponentProps<"tbody">
|
|
46
|
+
|
|
47
|
+
function TableBody({ className, ...props }: TableBodyProps): ReactElement {
|
|
48
|
+
return (
|
|
49
|
+
<tbody
|
|
50
|
+
className={cn("[&_tr:last-child]:border-0", className)}
|
|
51
|
+
data-slot="table-body"
|
|
52
|
+
{...props}
|
|
53
|
+
/>
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export type TableFooterProps = React.ComponentProps<"tfoot">
|
|
58
|
+
|
|
59
|
+
function TableFooter({ className, ...props }: TableFooterProps): ReactElement {
|
|
60
|
+
return (
|
|
61
|
+
<tfoot
|
|
62
|
+
className={cn(
|
|
63
|
+
"border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
|
|
64
|
+
className
|
|
65
|
+
)}
|
|
66
|
+
data-slot="table-footer"
|
|
67
|
+
{...props}
|
|
68
|
+
/>
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export type TableRowProps = React.ComponentProps<"tr">
|
|
73
|
+
|
|
74
|
+
function TableRow({ className, ...props }: TableRowProps): ReactElement {
|
|
75
|
+
return (
|
|
76
|
+
<tr
|
|
77
|
+
className={cn(
|
|
78
|
+
"border-b transition-[background-color,opacity] hover:bg-muted/50 data-[state=selected]:bg-primary/10",
|
|
79
|
+
className
|
|
80
|
+
)}
|
|
81
|
+
data-slot="table-row"
|
|
82
|
+
{...props}
|
|
83
|
+
/>
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export type TableHeadProps = React.ComponentProps<"th">
|
|
88
|
+
|
|
89
|
+
function TableHead({ className, ...props }: TableHeadProps): ReactElement {
|
|
90
|
+
return (
|
|
91
|
+
<th
|
|
92
|
+
className={cn(
|
|
93
|
+
"h-10 px-4 text-left align-middle font-medium whitespace-nowrap text-muted-foreground",
|
|
94
|
+
"[&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
|
|
95
|
+
className
|
|
96
|
+
)}
|
|
97
|
+
data-slot="table-head"
|
|
98
|
+
{...props}
|
|
99
|
+
/>
|
|
100
|
+
)
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export type TableCellProps = React.ComponentProps<"td">
|
|
104
|
+
|
|
105
|
+
function TableCell({ className, ...props }: TableCellProps): ReactElement {
|
|
106
|
+
return (
|
|
107
|
+
<td
|
|
108
|
+
className={cn(
|
|
109
|
+
"px-4 py-3 align-middle whitespace-nowrap",
|
|
110
|
+
"[&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
|
|
111
|
+
className
|
|
112
|
+
)}
|
|
113
|
+
data-slot="table-cell"
|
|
114
|
+
{...props}
|
|
115
|
+
/>
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export type TableCaptionProps = React.ComponentProps<"caption">
|
|
120
|
+
|
|
121
|
+
function TableCaption({
|
|
122
|
+
className,
|
|
123
|
+
...props
|
|
124
|
+
}: TableCaptionProps): ReactElement {
|
|
125
|
+
return (
|
|
126
|
+
<caption
|
|
127
|
+
className={cn("mt-4 text-sm text-muted-foreground", className)}
|
|
128
|
+
data-slot="table-caption"
|
|
129
|
+
{...props}
|
|
130
|
+
/>
|
|
131
|
+
)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export {
|
|
135
|
+
Table,
|
|
136
|
+
TableHeader,
|
|
137
|
+
TableBody,
|
|
138
|
+
TableFooter,
|
|
139
|
+
TableHead,
|
|
140
|
+
TableRow,
|
|
141
|
+
TableCell,
|
|
142
|
+
TableCaption,
|
|
143
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { type ReactElement } from "react"
|
|
2
|
+
import * as React from "react"
|
|
3
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
|
4
|
+
import { Tabs as TabsPrimitive } from "@base-ui/react/tabs"
|
|
5
|
+
import { cn } from "@/lib/utils"
|
|
6
|
+
|
|
7
|
+
export type TabsProps = React.ComponentProps<typeof TabsPrimitive.Root> & {
|
|
8
|
+
orientation?: "horizontal" | "vertical"
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function Tabs({
|
|
12
|
+
className,
|
|
13
|
+
orientation = "horizontal",
|
|
14
|
+
...props
|
|
15
|
+
}: TabsProps): ReactElement {
|
|
16
|
+
return (
|
|
17
|
+
<TabsPrimitive.Root
|
|
18
|
+
className={cn(
|
|
19
|
+
"group/tabs flex gap-2 data-[orientation=horizontal]:flex-col",
|
|
20
|
+
className
|
|
21
|
+
)}
|
|
22
|
+
data-orientation={orientation}
|
|
23
|
+
data-slot="tabs"
|
|
24
|
+
{...props}
|
|
25
|
+
/>
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const tabsListVariants = cva(
|
|
30
|
+
"group/tabs-list inline-flex w-fit items-center justify-center gap-1 rounded-none p-[3px] text-muted-foreground group-data-[orientation=horizontal]/tabs:h-9 group-data-[orientation=vertical]/tabs:h-fit group-data-[orientation=vertical]/tabs:flex-col",
|
|
31
|
+
{
|
|
32
|
+
variants: {
|
|
33
|
+
variant: {
|
|
34
|
+
default: "bg-muted",
|
|
35
|
+
line: "bg-transparent p-0",
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
defaultVariants: {
|
|
39
|
+
variant: "default",
|
|
40
|
+
},
|
|
41
|
+
}
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
export type TabsListProps = React.ComponentProps<typeof TabsPrimitive.List> &
|
|
45
|
+
VariantProps<typeof tabsListVariants>
|
|
46
|
+
|
|
47
|
+
function TabsList({
|
|
48
|
+
className,
|
|
49
|
+
variant = "default",
|
|
50
|
+
...props
|
|
51
|
+
}: TabsListProps): ReactElement {
|
|
52
|
+
return (
|
|
53
|
+
<TabsPrimitive.List
|
|
54
|
+
className={cn(tabsListVariants({ variant }), className)}
|
|
55
|
+
data-slot="tabs-list"
|
|
56
|
+
data-variant={variant}
|
|
57
|
+
{...props}
|
|
58
|
+
/>
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export type TabsTriggerProps = React.ComponentProps<typeof TabsPrimitive.Tab>
|
|
63
|
+
|
|
64
|
+
function TabsTrigger({
|
|
65
|
+
className,
|
|
66
|
+
...props
|
|
67
|
+
}: TabsTriggerProps): ReactElement {
|
|
68
|
+
return (
|
|
69
|
+
<TabsPrimitive.Tab
|
|
70
|
+
className={cn(
|
|
71
|
+
// Base layout & typography
|
|
72
|
+
"relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 whitespace-nowrap",
|
|
73
|
+
"rounded-none border border-transparent px-1.5 py-1 text-sm font-medium",
|
|
74
|
+
"text-muted-foreground transition-all",
|
|
75
|
+
// Vertical orientation
|
|
76
|
+
"group-data-[orientation=vertical]/tabs:w-full group-data-[orientation=vertical]/tabs:justify-start",
|
|
77
|
+
// Hover & focus
|
|
78
|
+
"hover:text-foreground",
|
|
79
|
+
"focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring",
|
|
80
|
+
// Disabled
|
|
81
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
82
|
+
// Active state — Default variant: primary/10 bg + subtle shadow
|
|
83
|
+
// Base UI uses data-active attribute for the active/selected tab
|
|
84
|
+
"data-active:bg-primary/10 data-active:text-foreground",
|
|
85
|
+
"group-data-[variant=default]/tabs-list:data-active:shadow-sm",
|
|
86
|
+
// Active state — Line variant: suppress bg & shadow
|
|
87
|
+
"group-data-[variant=line]/tabs-list:data-active:bg-transparent",
|
|
88
|
+
"group-data-[variant=line]/tabs-list:data-active:shadow-none",
|
|
89
|
+
// Indicator pseudo-element (visible only for Line variant, active state)
|
|
90
|
+
"after:absolute after:bg-primary after:opacity-0 after:transition-opacity",
|
|
91
|
+
"group-data-[orientation=horizontal]/tabs:after:inset-x-0 group-data-[orientation=horizontal]/tabs:after:bottom-[-5px] group-data-[orientation=horizontal]/tabs:after:h-0.5",
|
|
92
|
+
"group-data-[orientation=vertical]/tabs:after:inset-y-0 group-data-[orientation=vertical]/tabs:after:-right-1 group-data-[orientation=vertical]/tabs:after:w-0.5",
|
|
93
|
+
"group-data-[variant=line]/tabs-list:data-active:after:opacity-100",
|
|
94
|
+
// SVG icons
|
|
95
|
+
"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
96
|
+
className
|
|
97
|
+
)}
|
|
98
|
+
data-slot="tabs-trigger"
|
|
99
|
+
{...props}
|
|
100
|
+
/>
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export type TabsContentProps = React.ComponentProps<typeof TabsPrimitive.Panel>
|
|
105
|
+
|
|
106
|
+
function TabsContent({
|
|
107
|
+
className,
|
|
108
|
+
...props
|
|
109
|
+
}: TabsContentProps): ReactElement {
|
|
110
|
+
return (
|
|
111
|
+
<TabsPrimitive.Panel
|
|
112
|
+
className={cn("flex-1 outline-none", className)}
|
|
113
|
+
data-slot="tabs-content"
|
|
114
|
+
{...props}
|
|
115
|
+
/>
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants }
|