@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,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AlertDialog — WealthX DS overrides (shadcn / \@base-ui alert-dialog)
|
|
3
|
+
*
|
|
4
|
+
* Changes from shadcn default:
|
|
5
|
+
* - AlertDialogOverlay: `bg-black/50` → `bg-foreground/50` — DS foreground token (matches Figma)
|
|
6
|
+
* - AlertDialogContent: `rounded-lg` removed — sharp corners per Figma
|
|
7
|
+
* - AlertDialogContent: `shadow-lg` removed — flat panels per Figma
|
|
8
|
+
* - AlertDialogFooter: always row, right-aligned; `border-t border-border pt-4` separator
|
|
9
|
+
* - AlertDialogMedia: borderless icon slot — `size-10` default, `size-8` sm
|
|
10
|
+
*/
|
|
11
|
+
import { type ReactElement } from "react"
|
|
12
|
+
import * as React from "react"
|
|
13
|
+
import { AlertDialog as AlertDialogPrimitive } from "@base-ui/react/alert-dialog"
|
|
14
|
+
import { cn } from "@/lib/utils"
|
|
15
|
+
import { useThemeVars } from "@/lib/theme-provider"
|
|
16
|
+
import { buttonVariants } from "@/components/ui/button"
|
|
17
|
+
|
|
18
|
+
export type AlertDialogProps = React.ComponentProps<typeof AlertDialogPrimitive.Root>
|
|
19
|
+
|
|
20
|
+
function AlertDialog({
|
|
21
|
+
...props
|
|
22
|
+
}: AlertDialogProps): ReactElement {
|
|
23
|
+
return <AlertDialogPrimitive.Root data-slot="alert-dialog" {...props} />
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export type AlertDialogTriggerProps = React.ComponentProps<typeof AlertDialogPrimitive.Trigger>
|
|
27
|
+
|
|
28
|
+
function AlertDialogTrigger({
|
|
29
|
+
...props
|
|
30
|
+
}: AlertDialogTriggerProps): ReactElement {
|
|
31
|
+
return (
|
|
32
|
+
<AlertDialogPrimitive.Trigger data-slot="alert-dialog-trigger" {...props} />
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type AlertDialogPortalProps = React.ComponentProps<typeof AlertDialogPrimitive.Portal>
|
|
37
|
+
|
|
38
|
+
function AlertDialogPortal({
|
|
39
|
+
...props
|
|
40
|
+
}: AlertDialogPortalProps): ReactElement {
|
|
41
|
+
return (
|
|
42
|
+
<AlertDialogPrimitive.Portal data-slot="alert-dialog-portal" {...props} />
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export type AlertDialogOverlayProps = React.ComponentProps<typeof AlertDialogPrimitive.Backdrop>
|
|
47
|
+
|
|
48
|
+
function AlertDialogOverlay({
|
|
49
|
+
className,
|
|
50
|
+
...props
|
|
51
|
+
}: AlertDialogOverlayProps): ReactElement {
|
|
52
|
+
return (
|
|
53
|
+
<AlertDialogPrimitive.Backdrop
|
|
54
|
+
className={cn(
|
|
55
|
+
// WealthX: foreground/50 scrim — matches Figma foreground token at 50% opacity
|
|
56
|
+
"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",
|
|
57
|
+
className
|
|
58
|
+
)}
|
|
59
|
+
data-slot="alert-dialog-overlay"
|
|
60
|
+
{...props}
|
|
61
|
+
/>
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export type AlertDialogContentProps = React.ComponentProps<typeof AlertDialogPrimitive.Popup> & {
|
|
66
|
+
size?: "default" | "sm"
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function AlertDialogContent({
|
|
70
|
+
className,
|
|
71
|
+
size = "default",
|
|
72
|
+
style,
|
|
73
|
+
...props
|
|
74
|
+
}: AlertDialogContentProps): ReactElement {
|
|
75
|
+
const themeVars = useThemeVars();
|
|
76
|
+
return (
|
|
77
|
+
<AlertDialogPortal>
|
|
78
|
+
<AlertDialogOverlay />
|
|
79
|
+
<AlertDialogPrimitive.Popup
|
|
80
|
+
className={cn(
|
|
81
|
+
// WealthX: removed rounded-lg (sharp corners), shadow-lg (flat panels)
|
|
82
|
+
"group/alert-dialog-content fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 duration-200 data-[size=sm]:max-w-xs data-ending-style:animate-out data-ending-style:fade-out-0 data-ending-style:zoom-out-95 data-ending-style:fill-mode-forwards data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-[size=default]:sm:max-w-lg",
|
|
83
|
+
className
|
|
84
|
+
)}
|
|
85
|
+
data-size={size}
|
|
86
|
+
data-slot="alert-dialog-content"
|
|
87
|
+
style={{ ...themeVars, ...style } as React.CSSProperties}
|
|
88
|
+
{...props}
|
|
89
|
+
/>
|
|
90
|
+
</AlertDialogPortal>
|
|
91
|
+
)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export type AlertDialogHeaderProps = React.ComponentProps<"div">
|
|
95
|
+
|
|
96
|
+
function AlertDialogHeader({
|
|
97
|
+
className,
|
|
98
|
+
...props
|
|
99
|
+
}: AlertDialogHeaderProps): ReactElement {
|
|
100
|
+
return (
|
|
101
|
+
<div
|
|
102
|
+
className={cn(
|
|
103
|
+
"grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-6 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]",
|
|
104
|
+
className
|
|
105
|
+
)}
|
|
106
|
+
data-slot="alert-dialog-header"
|
|
107
|
+
{...props}
|
|
108
|
+
/>
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export type AlertDialogFooterProps = React.ComponentProps<"div">
|
|
113
|
+
|
|
114
|
+
function AlertDialogFooter({
|
|
115
|
+
className,
|
|
116
|
+
...props
|
|
117
|
+
}: AlertDialogFooterProps): ReactElement {
|
|
118
|
+
return (
|
|
119
|
+
<div
|
|
120
|
+
className={cn(
|
|
121
|
+
// WealthX: always row, right-aligned, separator above footer (matches Figma)
|
|
122
|
+
"flex flex-row justify-end gap-2 border-t border-border pt-4",
|
|
123
|
+
className
|
|
124
|
+
)}
|
|
125
|
+
data-slot="alert-dialog-footer"
|
|
126
|
+
{...props}
|
|
127
|
+
/>
|
|
128
|
+
)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export type AlertDialogTitleProps = React.ComponentProps<typeof AlertDialogPrimitive.Title>
|
|
132
|
+
|
|
133
|
+
function AlertDialogTitle({
|
|
134
|
+
className,
|
|
135
|
+
...props
|
|
136
|
+
}: AlertDialogTitleProps): ReactElement {
|
|
137
|
+
return (
|
|
138
|
+
<AlertDialogPrimitive.Title
|
|
139
|
+
className={cn(
|
|
140
|
+
"text-lg font-semibold sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2",
|
|
141
|
+
className
|
|
142
|
+
)}
|
|
143
|
+
data-slot="alert-dialog-title"
|
|
144
|
+
{...props}
|
|
145
|
+
/>
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export type AlertDialogDescriptionProps = React.ComponentProps<typeof AlertDialogPrimitive.Description>
|
|
150
|
+
|
|
151
|
+
function AlertDialogDescription({
|
|
152
|
+
className,
|
|
153
|
+
...props
|
|
154
|
+
}: AlertDialogDescriptionProps): ReactElement {
|
|
155
|
+
return (
|
|
156
|
+
<AlertDialogPrimitive.Description
|
|
157
|
+
className={cn(
|
|
158
|
+
"text-sm text-muted-foreground sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2",
|
|
159
|
+
className
|
|
160
|
+
)}
|
|
161
|
+
data-slot="alert-dialog-description"
|
|
162
|
+
{...props}
|
|
163
|
+
/>
|
|
164
|
+
)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export type AlertDialogMediaProps = React.ComponentProps<"div">
|
|
168
|
+
|
|
169
|
+
function AlertDialogMedia({
|
|
170
|
+
className,
|
|
171
|
+
...props
|
|
172
|
+
}: AlertDialogMediaProps): ReactElement {
|
|
173
|
+
return (
|
|
174
|
+
<div
|
|
175
|
+
className={cn(
|
|
176
|
+
// WealthX: borderless icon slot — size-10 default, size-8 sm
|
|
177
|
+
"mb-2 inline-flex size-10 items-center justify-center group-data-[size=sm]/alert-dialog-content:size-8 sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-5",
|
|
178
|
+
className
|
|
179
|
+
)}
|
|
180
|
+
data-slot="alert-dialog-media"
|
|
181
|
+
{...props}
|
|
182
|
+
/>
|
|
183
|
+
)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export type AlertDialogActionProps = React.ComponentProps<typeof AlertDialogPrimitive.Close> & {
|
|
187
|
+
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link"
|
|
188
|
+
size?: "default" | "sm" | "lg" | "xs" | "icon"
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function AlertDialogAction({
|
|
192
|
+
className,
|
|
193
|
+
variant = "default",
|
|
194
|
+
size = "default",
|
|
195
|
+
...props
|
|
196
|
+
}: AlertDialogActionProps): ReactElement {
|
|
197
|
+
return (
|
|
198
|
+
<AlertDialogPrimitive.Close
|
|
199
|
+
className={cn(buttonVariants({ variant, size }), className)}
|
|
200
|
+
data-slot="alert-dialog-action"
|
|
201
|
+
{...props}
|
|
202
|
+
/>
|
|
203
|
+
)
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export type AlertDialogCancelProps = React.ComponentProps<typeof AlertDialogPrimitive.Close> & {
|
|
207
|
+
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link"
|
|
208
|
+
size?: "default" | "sm" | "lg" | "xs" | "icon"
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function AlertDialogCancel({
|
|
212
|
+
className,
|
|
213
|
+
variant = "outline",
|
|
214
|
+
size = "default",
|
|
215
|
+
...props
|
|
216
|
+
}: AlertDialogCancelProps): ReactElement {
|
|
217
|
+
return (
|
|
218
|
+
<AlertDialogPrimitive.Close
|
|
219
|
+
className={cn(buttonVariants({ variant, size }), className)}
|
|
220
|
+
data-slot="alert-dialog-cancel"
|
|
221
|
+
{...props}
|
|
222
|
+
/>
|
|
223
|
+
)
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export {
|
|
227
|
+
AlertDialog,
|
|
228
|
+
AlertDialogAction,
|
|
229
|
+
AlertDialogCancel,
|
|
230
|
+
AlertDialogContent,
|
|
231
|
+
AlertDialogDescription,
|
|
232
|
+
AlertDialogFooter,
|
|
233
|
+
AlertDialogHeader,
|
|
234
|
+
AlertDialogMedia,
|
|
235
|
+
AlertDialogOverlay,
|
|
236
|
+
AlertDialogPortal,
|
|
237
|
+
AlertDialogTitle,
|
|
238
|
+
AlertDialogTrigger,
|
|
239
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { type ReactElement } from "react"
|
|
2
|
+
import * as React from "react"
|
|
3
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
|
4
|
+
import { cn } from "@/lib/utils"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Alert — WealthX Design System
|
|
8
|
+
* Figma: https://www.figma.com/design/9V9F0NGVsif8LGmEhVjOcT/Design-System---shadcn?node-id=72-2633
|
|
9
|
+
*
|
|
10
|
+
* Base: official shadcn alert (npx shadcn\@latest add alert)
|
|
11
|
+
* WealthX overrides: sharp corners (no rounded-lg), added warning/success/info variants
|
|
12
|
+
*/
|
|
13
|
+
const alertVariants = cva(
|
|
14
|
+
"relative grid w-full grid-cols-[0_1fr] items-start gap-y-0.5 border px-4 py-3 text-sm has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] has-[>svg]:gap-x-3 [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current",
|
|
15
|
+
{
|
|
16
|
+
variants: {
|
|
17
|
+
variant: {
|
|
18
|
+
default: "border-border bg-card text-card-foreground",
|
|
19
|
+
destructive: "border-destructive/40 bg-destructive/10 text-destructive *:data-[slot=alert-description]:text-destructive/90 [&>svg]:text-destructive",
|
|
20
|
+
warning: "border-warning/40 bg-warning/10 text-warning *:data-[slot=alert-description]:text-warning/90 [&>svg]:text-warning",
|
|
21
|
+
success: "border-success/40 bg-success/10 text-success *:data-[slot=alert-description]:text-success/90 [&>svg]:text-success",
|
|
22
|
+
info: "border-info/40 bg-info/10 text-info *:data-[slot=alert-description]:text-info/90 [&>svg]:text-info",
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
defaultVariants: {
|
|
26
|
+
variant: "default",
|
|
27
|
+
},
|
|
28
|
+
}
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
export type AlertProps = React.ComponentProps<"div"> & VariantProps<typeof alertVariants>
|
|
32
|
+
|
|
33
|
+
function Alert({
|
|
34
|
+
className,
|
|
35
|
+
variant,
|
|
36
|
+
...props
|
|
37
|
+
}: AlertProps): ReactElement {
|
|
38
|
+
return (
|
|
39
|
+
<div
|
|
40
|
+
className={cn(alertVariants({ variant }), className)}
|
|
41
|
+
data-slot="alert"
|
|
42
|
+
role="alert"
|
|
43
|
+
{...props}
|
|
44
|
+
/>
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export type AlertTitleProps = React.ComponentProps<"div">
|
|
49
|
+
|
|
50
|
+
function AlertTitle({ className, ...props }: AlertTitleProps): ReactElement {
|
|
51
|
+
return (
|
|
52
|
+
<div
|
|
53
|
+
className={cn(
|
|
54
|
+
"col-start-2 line-clamp-1 min-h-4 font-medium tracking-tight",
|
|
55
|
+
className
|
|
56
|
+
)}
|
|
57
|
+
data-slot="alert-title"
|
|
58
|
+
{...props}
|
|
59
|
+
/>
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export type AlertDescriptionProps = React.ComponentProps<"div">
|
|
64
|
+
|
|
65
|
+
function AlertDescription({
|
|
66
|
+
className,
|
|
67
|
+
...props
|
|
68
|
+
}: AlertDescriptionProps): ReactElement {
|
|
69
|
+
return (
|
|
70
|
+
<div
|
|
71
|
+
className={cn(
|
|
72
|
+
"col-start-2 grid justify-items-start gap-1 text-sm text-muted-foreground [&_p]:leading-relaxed",
|
|
73
|
+
className
|
|
74
|
+
)}
|
|
75
|
+
data-slot="alert-description"
|
|
76
|
+
{...props}
|
|
77
|
+
/>
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export { Alert, AlertTitle, AlertDescription }
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { type ReactElement } from "react"
|
|
2
|
+
import * as React from "react"
|
|
3
|
+
import { Avatar as AvatarPrimitive } from "@base-ui/react/avatar"
|
|
4
|
+
import { cn } from "@/lib/utils"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Avatar — shadcn/WealthX
|
|
8
|
+
* Base: npx shadcn\@latest add avatar (latest)
|
|
9
|
+
* Figma: Design-System---shadcn?node-id=72-2717
|
|
10
|
+
*
|
|
11
|
+
* WealthX:
|
|
12
|
+
* - Removed overflow-hidden from Avatar root → moved to AvatarImage/AvatarFallback
|
|
13
|
+
* so AvatarBadge (absolute positioned) is not clipped by the parent.
|
|
14
|
+
* - Added font-sans to AvatarFallback for consistent typography.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export type AvatarProps = React.ComponentProps<typeof AvatarPrimitive.Root> & {
|
|
18
|
+
size?: "default" | "sm" | "lg"
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function Avatar({
|
|
22
|
+
className,
|
|
23
|
+
size = "default",
|
|
24
|
+
...props
|
|
25
|
+
}: AvatarProps): ReactElement {
|
|
26
|
+
return (
|
|
27
|
+
<AvatarPrimitive.Root
|
|
28
|
+
className={cn(
|
|
29
|
+
"group/avatar relative flex size-8 shrink-0 rounded-full select-none data-[size=lg]:size-10 data-[size=sm]:size-6",
|
|
30
|
+
className
|
|
31
|
+
)}
|
|
32
|
+
data-size={size}
|
|
33
|
+
data-slot="avatar"
|
|
34
|
+
{...props}
|
|
35
|
+
/>
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export type AvatarImageProps = React.ComponentProps<typeof AvatarPrimitive.Image>
|
|
40
|
+
|
|
41
|
+
function AvatarImage({
|
|
42
|
+
className,
|
|
43
|
+
...props
|
|
44
|
+
}: AvatarImageProps): ReactElement {
|
|
45
|
+
return (
|
|
46
|
+
<AvatarPrimitive.Image
|
|
47
|
+
className={cn("aspect-square size-full rounded-full", className)}
|
|
48
|
+
data-slot="avatar-image"
|
|
49
|
+
{...props}
|
|
50
|
+
/>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export type AvatarFallbackProps = React.ComponentProps<typeof AvatarPrimitive.Fallback>
|
|
55
|
+
|
|
56
|
+
function AvatarFallback({
|
|
57
|
+
className,
|
|
58
|
+
...props
|
|
59
|
+
}: AvatarFallbackProps): ReactElement {
|
|
60
|
+
return (
|
|
61
|
+
<AvatarPrimitive.Fallback
|
|
62
|
+
className={cn(
|
|
63
|
+
"flex size-full items-center justify-center rounded-full overflow-hidden bg-muted text-sm font-sans text-muted-foreground group-data-[size=sm]/avatar:text-xs",
|
|
64
|
+
className
|
|
65
|
+
)}
|
|
66
|
+
data-slot="avatar-fallback"
|
|
67
|
+
{...props}
|
|
68
|
+
/>
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export type AvatarBadgeProps = React.ComponentProps<"span">
|
|
73
|
+
|
|
74
|
+
function AvatarBadge({ className, ...props }: AvatarBadgeProps): ReactElement {
|
|
75
|
+
return (
|
|
76
|
+
<span
|
|
77
|
+
className={cn(
|
|
78
|
+
"absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-primary text-primary-foreground ring-2 ring-background select-none",
|
|
79
|
+
"group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden",
|
|
80
|
+
"group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2",
|
|
81
|
+
"group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2",
|
|
82
|
+
className
|
|
83
|
+
)}
|
|
84
|
+
data-slot="avatar-badge"
|
|
85
|
+
{...props}
|
|
86
|
+
/>
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export type AvatarGroupProps = React.ComponentProps<"div">
|
|
91
|
+
|
|
92
|
+
function AvatarGroup({ className, ...props }: AvatarGroupProps): ReactElement {
|
|
93
|
+
return (
|
|
94
|
+
<div
|
|
95
|
+
className={cn(
|
|
96
|
+
"group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background",
|
|
97
|
+
className
|
|
98
|
+
)}
|
|
99
|
+
data-slot="avatar-group"
|
|
100
|
+
{...props}
|
|
101
|
+
/>
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export type AvatarGroupCountProps = React.ComponentProps<"div">
|
|
106
|
+
|
|
107
|
+
function AvatarGroupCount({
|
|
108
|
+
className,
|
|
109
|
+
...props
|
|
110
|
+
}: AvatarGroupCountProps): ReactElement {
|
|
111
|
+
return (
|
|
112
|
+
<div
|
|
113
|
+
className={cn(
|
|
114
|
+
"relative flex size-8 shrink-0 items-center justify-center rounded-full bg-muted text-sm text-muted-foreground ring-2 ring-background group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3",
|
|
115
|
+
className
|
|
116
|
+
)}
|
|
117
|
+
data-slot="avatar-group-count"
|
|
118
|
+
{...props}
|
|
119
|
+
/>
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export {
|
|
124
|
+
Avatar,
|
|
125
|
+
AvatarImage,
|
|
126
|
+
AvatarFallback,
|
|
127
|
+
AvatarBadge,
|
|
128
|
+
AvatarGroup,
|
|
129
|
+
AvatarGroupCount,
|
|
130
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type ReactElement } from "react"
|
|
2
|
+
import * as React from "react"
|
|
3
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
|
4
|
+
import { cn } from "@/lib/utils"
|
|
5
|
+
import { Slot } from "@/lib/slot"
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Badge — shadcn/WealthX
|
|
9
|
+
* Base: npx shadcn\@latest add badge (latest)
|
|
10
|
+
* Figma: Design-System---shadcn?node-id=665-2024
|
|
11
|
+
*
|
|
12
|
+
* WealthX: added font-sans. All 6 shadcn variants preserved.
|
|
13
|
+
*/
|
|
14
|
+
const badgeVariants = cva(
|
|
15
|
+
"inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2 py-0.5 text-xs font-medium font-sans whitespace-nowrap transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3",
|
|
16
|
+
{
|
|
17
|
+
variants: {
|
|
18
|
+
variant: {
|
|
19
|
+
default: "bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
|
|
20
|
+
secondary:
|
|
21
|
+
"bg-muted text-muted-foreground [a&]:hover:bg-muted/80",
|
|
22
|
+
destructive:
|
|
23
|
+
"bg-destructive text-destructive-foreground focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40 [a&]:hover:bg-destructive/90",
|
|
24
|
+
outline:
|
|
25
|
+
"border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
|
|
26
|
+
ghost: "[a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
|
|
27
|
+
link: "text-primary underline-offset-4 [a&]:hover:underline",
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
defaultVariants: {
|
|
31
|
+
variant: "default",
|
|
32
|
+
},
|
|
33
|
+
}
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
export type BadgeProps = React.ComponentProps<"span"> &
|
|
37
|
+
VariantProps<typeof badgeVariants> & { asChild?: boolean }
|
|
38
|
+
|
|
39
|
+
function Badge({
|
|
40
|
+
className,
|
|
41
|
+
variant = "default",
|
|
42
|
+
asChild = false,
|
|
43
|
+
...props
|
|
44
|
+
}: BadgeProps): ReactElement {
|
|
45
|
+
const Comp = asChild ? Slot : "span"
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<Comp
|
|
49
|
+
className={cn(badgeVariants({ variant }), className)}
|
|
50
|
+
data-slot="badge"
|
|
51
|
+
data-variant={variant}
|
|
52
|
+
{...props}
|
|
53
|
+
/>
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export { Badge, badgeVariants }
|
|
@@ -1,37 +1,47 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { type ReactElement, type ComponentProps, forwardRef } from "react"
|
|
2
2
|
import { cva, type VariantProps } from "class-variance-authority"
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
import {
|
|
3
|
+
import { Loader2 } from "lucide-react"
|
|
4
|
+
import { cn } from "@/lib/utils"
|
|
5
|
+
import { Slot } from "@/lib/slot"
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Button — WealthX Design System
|
|
9
|
+
* Figma: https://www.figma.com/design/9V9F0NGVsif8LGmEhVjOcT/Design-System---shadcn?node-id=72-2719
|
|
10
|
+
*
|
|
11
|
+
* Base: official shadcn new-york button (npx shadcn\@latest add button)
|
|
12
|
+
* WealthX overrides: variants, square corners, font-sans, loading state
|
|
13
|
+
*/
|
|
7
14
|
const buttonVariants = cva(
|
|
8
|
-
"
|
|
15
|
+
"inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 font-sans text-sm font-medium whitespace-nowrap transition-all active:scale-[0.98] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
9
16
|
{
|
|
10
17
|
variants: {
|
|
11
18
|
variant: {
|
|
12
|
-
default:
|
|
13
|
-
|
|
14
|
-
"border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
|
|
19
|
+
default:
|
|
20
|
+
"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
|
|
15
21
|
secondary:
|
|
16
|
-
"bg-secondary text-secondary-foreground hover:bg-secondary/80
|
|
17
|
-
ghost:
|
|
18
|
-
"hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50",
|
|
22
|
+
"bg-brand-secondary text-brand-secondary-foreground shadow-xs hover:bg-brand-secondary/80 focus-visible:ring-brand-secondary/30",
|
|
19
23
|
destructive:
|
|
20
|
-
"bg-destructive
|
|
21
|
-
|
|
24
|
+
"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
|
|
25
|
+
outline:
|
|
26
|
+
"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
|
|
27
|
+
"outline-primary":
|
|
28
|
+
"border border-primary text-foreground bg-transparent shadow-xs hover:bg-primary/5 focus-visible:ring-primary/50",
|
|
29
|
+
"outline-secondary":
|
|
30
|
+
"border border-brand-secondary text-brand-secondary bg-transparent shadow-xs hover:bg-brand-secondary/10 focus-visible:ring-brand-secondary/30",
|
|
31
|
+
ghost:
|
|
32
|
+
"hover:bg-accent hover:text-accent-foreground hover:shadow-xs dark:hover:bg-accent/50",
|
|
33
|
+
link:
|
|
34
|
+
"text-primary underline-offset-4 hover:underline",
|
|
22
35
|
},
|
|
23
36
|
size: {
|
|
24
|
-
default:
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
icon:
|
|
30
|
-
"icon-
|
|
31
|
-
|
|
32
|
-
"icon-sm":
|
|
33
|
-
"size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
|
|
34
|
-
"icon-lg": "size-9",
|
|
37
|
+
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
|
38
|
+
xs: "h-6 gap-1 px-2 text-xs has-[>svg]:px-1.5 [&_svg:not([class*='size-'])]:size-3",
|
|
39
|
+
sm: "h-8 gap-1.5 px-3 has-[>svg]:px-2.5",
|
|
40
|
+
lg: "h-10 px-6 has-[>svg]:px-4",
|
|
41
|
+
icon: "size-9",
|
|
42
|
+
"icon-xs": "size-6 [&_svg:not([class*='size-'])]:size-3",
|
|
43
|
+
"icon-sm": "size-8",
|
|
44
|
+
"icon-lg": "size-10",
|
|
35
45
|
},
|
|
36
46
|
},
|
|
37
47
|
defaultVariants: {
|
|
@@ -41,27 +51,49 @@ const buttonVariants = cva(
|
|
|
41
51
|
}
|
|
42
52
|
)
|
|
43
53
|
|
|
44
|
-
|
|
45
|
-
className,
|
|
46
|
-
variant = "default",
|
|
47
|
-
size = "default",
|
|
48
|
-
asChild = false,
|
|
49
|
-
...props
|
|
50
|
-
}: React.ComponentProps<"button"> &
|
|
54
|
+
export type ButtonProps = ComponentProps<"button"> &
|
|
51
55
|
VariantProps<typeof buttonVariants> & {
|
|
52
56
|
asChild?: boolean
|
|
53
|
-
|
|
54
|
-
|
|
57
|
+
/** Shows spinner and disables the button. Icon-only sizes hide the icon. */
|
|
58
|
+
loading?: boolean
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(
|
|
62
|
+
{
|
|
63
|
+
className,
|
|
64
|
+
variant,
|
|
65
|
+
size,
|
|
66
|
+
asChild = false,
|
|
67
|
+
loading = false,
|
|
68
|
+
disabled,
|
|
69
|
+
children,
|
|
70
|
+
...props
|
|
71
|
+
},
|
|
72
|
+
ref
|
|
73
|
+
): ReactElement {
|
|
74
|
+
const Comp = asChild ? Slot : "button"
|
|
75
|
+
const isIconOnly = size === "icon" || size === "icon-xs" || size === "icon-sm" || size === "icon-lg"
|
|
55
76
|
|
|
56
77
|
return (
|
|
57
78
|
<Comp
|
|
79
|
+
className={cn(buttonVariants({ variant, size, className }))}
|
|
80
|
+
data-size={size}
|
|
58
81
|
data-slot="button"
|
|
59
82
|
data-variant={variant}
|
|
60
|
-
|
|
61
|
-
|
|
83
|
+
disabled={loading || disabled}
|
|
84
|
+
ref={ref}
|
|
62
85
|
{...props}
|
|
63
|
-
|
|
86
|
+
>
|
|
87
|
+
{loading ? (
|
|
88
|
+
<>
|
|
89
|
+
<Loader2 aria-hidden="true" className="animate-spin" />
|
|
90
|
+
{!isIconOnly && children}
|
|
91
|
+
</>
|
|
92
|
+
) : (
|
|
93
|
+
children
|
|
94
|
+
)}
|
|
95
|
+
</Comp>
|
|
64
96
|
)
|
|
65
|
-
}
|
|
97
|
+
})
|
|
66
98
|
|
|
67
99
|
export { Button, buttonVariants }
|