@wealthx/shadcn 0.0.2 → 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 +135 -11
- package/CHANGELOG.md +6 -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 +4312 -90
- package/dist/index.mjs +459 -158
- 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 +1 -1
- 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/dist/index.d.mts +0 -27
- package/dist/index.d.ts +0 -27
- package/src/provider/ShadcnProvider.tsx +0 -89
- package/src/provider/index.ts +0 -2
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type ReactElement } from "react"
|
|
2
|
+
import * as React from "react"
|
|
3
|
+
import { cn } from "@/lib/utils"
|
|
4
|
+
|
|
5
|
+
export type LabelProps = React.ComponentProps<"label">
|
|
6
|
+
|
|
7
|
+
function Label({
|
|
8
|
+
className,
|
|
9
|
+
...props
|
|
10
|
+
}: LabelProps): ReactElement {
|
|
11
|
+
return (
|
|
12
|
+
// eslint-disable-next-line jsx-a11y/label-has-associated-control -- htmlFor is passed by the consumer
|
|
13
|
+
<label
|
|
14
|
+
className={cn(
|
|
15
|
+
"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
|
|
16
|
+
className
|
|
17
|
+
)}
|
|
18
|
+
data-slot="label"
|
|
19
|
+
{...props}
|
|
20
|
+
/>
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { Label }
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { type ReactElement } from "react"
|
|
2
|
+
import * as React from "react"
|
|
3
|
+
import {
|
|
4
|
+
ChevronLeftIcon,
|
|
5
|
+
ChevronRightIcon,
|
|
6
|
+
MoreHorizontalIcon,
|
|
7
|
+
} from "lucide-react"
|
|
8
|
+
import { cn } from "@/lib/utils"
|
|
9
|
+
import { buttonVariants, type Button } from "@/components/ui/button"
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Pagination — WealthX Design System
|
|
13
|
+
* Figma: https://www.figma.com/design/9V9F0NGVsif8LGmEhVjOcT/Design-System---shadcn?node-id=73-1981
|
|
14
|
+
*
|
|
15
|
+
* Base: official shadcn pagination (npx shadcn\@latest add pagination)
|
|
16
|
+
* WealthX overrides: none — ghost/outline variants match design system
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
export type PaginationProps = React.ComponentProps<"nav">
|
|
20
|
+
|
|
21
|
+
function Pagination({ className, ...props }: PaginationProps): ReactElement {
|
|
22
|
+
return (
|
|
23
|
+
<nav
|
|
24
|
+
aria-label="pagination"
|
|
25
|
+
className={cn("mx-auto flex w-full justify-center", className)}
|
|
26
|
+
data-slot="pagination"
|
|
27
|
+
role="navigation"
|
|
28
|
+
{...props}
|
|
29
|
+
/>
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type PaginationContentProps = React.ComponentProps<"ul">
|
|
34
|
+
|
|
35
|
+
function PaginationContent({
|
|
36
|
+
className,
|
|
37
|
+
...props
|
|
38
|
+
}: PaginationContentProps): ReactElement {
|
|
39
|
+
return (
|
|
40
|
+
<ul
|
|
41
|
+
className={cn("flex flex-row items-center gap-1", className)}
|
|
42
|
+
data-slot="pagination-content"
|
|
43
|
+
{...props}
|
|
44
|
+
/>
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export type PaginationItemProps = React.ComponentProps<"li">
|
|
49
|
+
|
|
50
|
+
function PaginationItem({ ...props }: PaginationItemProps): ReactElement {
|
|
51
|
+
return <li data-slot="pagination-item" {...props} />
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export type PaginationLinkProps = {
|
|
55
|
+
isActive?: boolean
|
|
56
|
+
} & Pick<React.ComponentProps<typeof Button>, "size"> &
|
|
57
|
+
React.ComponentProps<"a">
|
|
58
|
+
|
|
59
|
+
function PaginationLink({
|
|
60
|
+
className,
|
|
61
|
+
isActive,
|
|
62
|
+
size = "icon",
|
|
63
|
+
...props
|
|
64
|
+
}: PaginationLinkProps): ReactElement {
|
|
65
|
+
return (
|
|
66
|
+
// eslint-disable-next-line jsx-a11y/anchor-has-content -- children passed via props spread
|
|
67
|
+
<a
|
|
68
|
+
aria-current={isActive ? "page" : undefined}
|
|
69
|
+
className={cn(
|
|
70
|
+
buttonVariants({
|
|
71
|
+
variant: isActive ? "outline" : "ghost",
|
|
72
|
+
size,
|
|
73
|
+
}),
|
|
74
|
+
className
|
|
75
|
+
)}
|
|
76
|
+
data-active={isActive}
|
|
77
|
+
data-slot="pagination-link"
|
|
78
|
+
{...props}
|
|
79
|
+
/>
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export type PaginationPreviousProps = React.ComponentProps<typeof PaginationLink>
|
|
84
|
+
|
|
85
|
+
function PaginationPrevious({
|
|
86
|
+
className,
|
|
87
|
+
...props
|
|
88
|
+
}: PaginationPreviousProps): ReactElement {
|
|
89
|
+
return (
|
|
90
|
+
<PaginationLink
|
|
91
|
+
aria-label="Go to previous page"
|
|
92
|
+
className={cn("gap-1 px-2.5 sm:pl-2.5", className)}
|
|
93
|
+
size="default"
|
|
94
|
+
{...props}
|
|
95
|
+
>
|
|
96
|
+
<ChevronLeftIcon />
|
|
97
|
+
<span className="hidden sm:block">Previous</span>
|
|
98
|
+
</PaginationLink>
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export type PaginationNextProps = React.ComponentProps<typeof PaginationLink>
|
|
103
|
+
|
|
104
|
+
function PaginationNext({
|
|
105
|
+
className,
|
|
106
|
+
...props
|
|
107
|
+
}: PaginationNextProps): ReactElement {
|
|
108
|
+
return (
|
|
109
|
+
<PaginationLink
|
|
110
|
+
aria-label="Go to next page"
|
|
111
|
+
className={cn("gap-1 px-2.5 sm:pr-2.5", className)}
|
|
112
|
+
size="default"
|
|
113
|
+
{...props}
|
|
114
|
+
>
|
|
115
|
+
<span className="hidden sm:block">Next</span>
|
|
116
|
+
<ChevronRightIcon />
|
|
117
|
+
</PaginationLink>
|
|
118
|
+
)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export type PaginationEllipsisProps = React.ComponentProps<"span">
|
|
122
|
+
|
|
123
|
+
function PaginationEllipsis({
|
|
124
|
+
className,
|
|
125
|
+
...props
|
|
126
|
+
}: PaginationEllipsisProps): ReactElement {
|
|
127
|
+
return (
|
|
128
|
+
<span
|
|
129
|
+
aria-hidden
|
|
130
|
+
className={cn("flex size-9 items-center justify-center", className)}
|
|
131
|
+
data-slot="pagination-ellipsis"
|
|
132
|
+
{...props}
|
|
133
|
+
>
|
|
134
|
+
<MoreHorizontalIcon className="size-4" />
|
|
135
|
+
<span className="sr-only">More pages</span>
|
|
136
|
+
</span>
|
|
137
|
+
)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export {
|
|
141
|
+
Pagination,
|
|
142
|
+
PaginationContent,
|
|
143
|
+
PaginationLink,
|
|
144
|
+
PaginationItem,
|
|
145
|
+
PaginationPrevious,
|
|
146
|
+
PaginationNext,
|
|
147
|
+
PaginationEllipsis,
|
|
148
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { type ReactElement } from "react"
|
|
2
|
+
import * as React from "react"
|
|
3
|
+
import { Popover as PopoverPrimitive } from "@base-ui/react/popover"
|
|
4
|
+
import { cn } from "@/lib/utils"
|
|
5
|
+
import { useThemeVars } from "@/lib/theme-provider"
|
|
6
|
+
|
|
7
|
+
export type PopoverProps = React.ComponentProps<typeof PopoverPrimitive.Root>
|
|
8
|
+
|
|
9
|
+
function Popover({
|
|
10
|
+
...props
|
|
11
|
+
}: PopoverProps): ReactElement {
|
|
12
|
+
return <PopoverPrimitive.Root data-slot="popover" {...props} />
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type PopoverTriggerProps = React.ComponentProps<typeof PopoverPrimitive.Trigger>
|
|
16
|
+
|
|
17
|
+
function PopoverTrigger({
|
|
18
|
+
...props
|
|
19
|
+
}: PopoverTriggerProps): ReactElement {
|
|
20
|
+
return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type PopoverContentProps = React.ComponentProps<typeof PopoverPrimitive.Popup> & {
|
|
24
|
+
align?: "start" | "center" | "end"
|
|
25
|
+
sideOffset?: number
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function PopoverContent({
|
|
29
|
+
className,
|
|
30
|
+
align = "center",
|
|
31
|
+
sideOffset = 4,
|
|
32
|
+
style,
|
|
33
|
+
...props
|
|
34
|
+
}: PopoverContentProps): ReactElement {
|
|
35
|
+
const themeVars = useThemeVars();
|
|
36
|
+
return (
|
|
37
|
+
<PopoverPrimitive.Portal>
|
|
38
|
+
<PopoverPrimitive.Positioner
|
|
39
|
+
align={align}
|
|
40
|
+
sideOffset={sideOffset}
|
|
41
|
+
>
|
|
42
|
+
<PopoverPrimitive.Popup
|
|
43
|
+
className={cn(
|
|
44
|
+
"z-50 w-72 border border-border bg-popover p-4 text-popover-foreground shadow-md outline-hidden data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 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",
|
|
45
|
+
className
|
|
46
|
+
)}
|
|
47
|
+
data-slot="popover-content"
|
|
48
|
+
style={{ ...themeVars, ...style } as React.CSSProperties}
|
|
49
|
+
{...props}
|
|
50
|
+
/>
|
|
51
|
+
</PopoverPrimitive.Positioner>
|
|
52
|
+
</PopoverPrimitive.Portal>
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export type PopoverAnchorProps = React.ComponentProps<"div">
|
|
57
|
+
|
|
58
|
+
function PopoverAnchor({
|
|
59
|
+
...props
|
|
60
|
+
}: PopoverAnchorProps): ReactElement {
|
|
61
|
+
return <div data-slot="popover-anchor" {...props} />
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export type PopoverHeaderProps = React.ComponentProps<"div">
|
|
65
|
+
|
|
66
|
+
function PopoverHeader({ className, ...props }: PopoverHeaderProps): ReactElement {
|
|
67
|
+
return (
|
|
68
|
+
<div
|
|
69
|
+
className={cn("flex flex-col gap-1 text-sm", className)}
|
|
70
|
+
data-slot="popover-header"
|
|
71
|
+
{...props}
|
|
72
|
+
/>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export type PopoverTitleProps = React.ComponentProps<"h2">
|
|
77
|
+
|
|
78
|
+
function PopoverTitle({ className, ...props }: PopoverTitleProps): ReactElement {
|
|
79
|
+
return (
|
|
80
|
+
// eslint-disable-next-line jsx-a11y/heading-has-content -- children passed via props spread
|
|
81
|
+
<h2
|
|
82
|
+
className={cn("font-medium", className)}
|
|
83
|
+
data-slot="popover-title"
|
|
84
|
+
{...props}
|
|
85
|
+
/>
|
|
86
|
+
)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export type PopoverDescriptionProps = React.ComponentProps<"p">
|
|
90
|
+
|
|
91
|
+
function PopoverDescription({
|
|
92
|
+
className,
|
|
93
|
+
...props
|
|
94
|
+
}: PopoverDescriptionProps): ReactElement {
|
|
95
|
+
return (
|
|
96
|
+
<p
|
|
97
|
+
className={cn("text-muted-foreground", className)}
|
|
98
|
+
data-slot="popover-description"
|
|
99
|
+
{...props}
|
|
100
|
+
/>
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export {
|
|
105
|
+
Popover,
|
|
106
|
+
PopoverTrigger,
|
|
107
|
+
PopoverContent,
|
|
108
|
+
PopoverAnchor,
|
|
109
|
+
PopoverHeader,
|
|
110
|
+
PopoverTitle,
|
|
111
|
+
PopoverDescription,
|
|
112
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { type ReactElement } from "react"
|
|
2
|
+
import * as React from "react"
|
|
3
|
+
import { Progress as ProgressPrimitive } from "@base-ui/react/progress"
|
|
4
|
+
import { cn } from "@/lib/utils"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Progress — WealthX Design System
|
|
8
|
+
* Figma: https://www.figma.com/design/9V9F0NGVsif8LGmEhVjOcT/Design-System---shadcn?node-id=73-1983
|
|
9
|
+
*
|
|
10
|
+
* Base: official shadcn progress (npx shadcn\@latest add progress)
|
|
11
|
+
* WealthX overrides: sharp corners (no rounded-full), track bg-muted instead of bg-primary/20
|
|
12
|
+
*/
|
|
13
|
+
export type ProgressProps = React.ComponentProps<typeof ProgressPrimitive.Root>
|
|
14
|
+
|
|
15
|
+
function Progress({
|
|
16
|
+
className,
|
|
17
|
+
value,
|
|
18
|
+
...props
|
|
19
|
+
}: ProgressProps): ReactElement {
|
|
20
|
+
return (
|
|
21
|
+
<ProgressPrimitive.Root
|
|
22
|
+
className={cn(
|
|
23
|
+
"relative h-2 w-full overflow-hidden bg-muted",
|
|
24
|
+
className
|
|
25
|
+
)}
|
|
26
|
+
data-slot="progress"
|
|
27
|
+
value={value}
|
|
28
|
+
{...props}
|
|
29
|
+
>
|
|
30
|
+
<ProgressPrimitive.Track className="h-full">
|
|
31
|
+
<ProgressPrimitive.Indicator
|
|
32
|
+
className="h-full bg-primary transition-all"
|
|
33
|
+
data-slot="progress-indicator"
|
|
34
|
+
/>
|
|
35
|
+
</ProgressPrimitive.Track>
|
|
36
|
+
</ProgressPrimitive.Root>
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { Progress }
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { type ReactElement, type ComponentProps } from "react"
|
|
2
|
+
import { CircleIcon } from "lucide-react"
|
|
3
|
+
import { RadioGroup as RadioGroupPrimitive } from "@base-ui/react/radio-group"
|
|
4
|
+
import { Radio as RadioPrimitive } from "@base-ui/react/radio"
|
|
5
|
+
import { cn } from "@/lib/utils"
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* RadioGroup — WealthX Design System (shadcn base)
|
|
9
|
+
* Figma: https://www.figma.com/design/9V9F0NGVsif8LGmEhVjOcT/Design-System---shadcn?node-id=76-8893
|
|
10
|
+
*
|
|
11
|
+
* Base: official shadcn radio-group (npx shadcn\@latest add radio-group)
|
|
12
|
+
* WealthX additions: RadioGroupCard (card with radio + label/description)
|
|
13
|
+
*
|
|
14
|
+
* Tokens: circle fill=background (white), stroke=primary, checked fill=primary,
|
|
15
|
+
* indicator=background. Error overrides primary-destructive.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/* Shared radio circle base classes -- single source for Item & Card */
|
|
19
|
+
const CIRCLE_BASE =
|
|
20
|
+
"inline-flex items-center justify-center aspect-square size-4 shrink-0 rounded-full border border-primary bg-background"
|
|
21
|
+
|
|
22
|
+
/* Shared indicator dot */
|
|
23
|
+
const INDICATOR_DOT = "size-2 fill-background text-background"
|
|
24
|
+
|
|
25
|
+
export type RadioGroupProps = ComponentProps<typeof RadioGroupPrimitive>
|
|
26
|
+
|
|
27
|
+
function RadioGroup({
|
|
28
|
+
className,
|
|
29
|
+
...props
|
|
30
|
+
}: RadioGroupProps): ReactElement {
|
|
31
|
+
return (
|
|
32
|
+
<RadioGroupPrimitive
|
|
33
|
+
className={cn("grid gap-3", className)}
|
|
34
|
+
data-slot="radio-group"
|
|
35
|
+
{...props}
|
|
36
|
+
/>
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export type RadioGroupItemProps = ComponentProps<typeof RadioPrimitive.Root>
|
|
41
|
+
|
|
42
|
+
function RadioGroupItem({
|
|
43
|
+
className,
|
|
44
|
+
...props
|
|
45
|
+
}: RadioGroupItemProps): ReactElement {
|
|
46
|
+
return (
|
|
47
|
+
<RadioPrimitive.Root
|
|
48
|
+
className={cn(
|
|
49
|
+
CIRCLE_BASE,
|
|
50
|
+
"transition-all outline-none",
|
|
51
|
+
"focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50",
|
|
52
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
53
|
+
"data-checked:bg-primary",
|
|
54
|
+
"aria-invalid:border-destructive aria-invalid:ring-destructive/20",
|
|
55
|
+
"aria-invalid:data-checked:border-destructive aria-invalid:data-checked:bg-destructive",
|
|
56
|
+
"dark:bg-input/30 dark:aria-invalid:ring-destructive/40",
|
|
57
|
+
className
|
|
58
|
+
)}
|
|
59
|
+
data-slot="radio-group-item"
|
|
60
|
+
{...props}
|
|
61
|
+
>
|
|
62
|
+
<RadioPrimitive.Indicator
|
|
63
|
+
data-slot="radio-group-indicator"
|
|
64
|
+
>
|
|
65
|
+
<CircleIcon className={INDICATOR_DOT} />
|
|
66
|
+
</RadioPrimitive.Indicator>
|
|
67
|
+
</RadioPrimitive.Root>
|
|
68
|
+
)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* RadioGroupCard -- card with radio left, label+description right.
|
|
73
|
+
* Figma: CardRadio (3039:5971)
|
|
74
|
+
* Checked: border-primary + bg-primary/5. Error: destructive variant.
|
|
75
|
+
*/
|
|
76
|
+
export type RadioGroupCardProps = Omit<ComponentProps<typeof RadioPrimitive.Root>, "children"> & {
|
|
77
|
+
label: string
|
|
78
|
+
description?: string
|
|
79
|
+
error?: boolean
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function RadioGroupCard({
|
|
83
|
+
className,
|
|
84
|
+
value,
|
|
85
|
+
disabled,
|
|
86
|
+
error,
|
|
87
|
+
label,
|
|
88
|
+
description,
|
|
89
|
+
...props
|
|
90
|
+
}: RadioGroupCardProps): ReactElement {
|
|
91
|
+
return (
|
|
92
|
+
<RadioPrimitive.Root
|
|
93
|
+
aria-invalid={error || undefined}
|
|
94
|
+
className={cn(
|
|
95
|
+
"group/card flex items-center gap-3 border border-border p-4 font-sans transition-colors text-left cursor-pointer outline-none",
|
|
96
|
+
"focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50",
|
|
97
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
98
|
+
"data-checked:border-primary data-checked:bg-primary/5",
|
|
99
|
+
"aria-invalid:border-destructive",
|
|
100
|
+
"aria-invalid:data-checked:border-destructive aria-invalid:data-checked:bg-destructive/5",
|
|
101
|
+
className
|
|
102
|
+
)}
|
|
103
|
+
data-slot="radio-group-card"
|
|
104
|
+
disabled={disabled}
|
|
105
|
+
value={value}
|
|
106
|
+
{...props}
|
|
107
|
+
>
|
|
108
|
+
<div
|
|
109
|
+
className={cn(
|
|
110
|
+
CIRCLE_BASE,
|
|
111
|
+
"transition-colors",
|
|
112
|
+
"group-data-[checked]/card:bg-primary",
|
|
113
|
+
"group-aria-invalid/card:border-destructive",
|
|
114
|
+
"group-aria-invalid/card:group-data-[checked]/card:border-destructive group-aria-invalid/card:group-data-[checked]/card:bg-destructive",
|
|
115
|
+
)}
|
|
116
|
+
>
|
|
117
|
+
<RadioPrimitive.Indicator>
|
|
118
|
+
<CircleIcon className={INDICATOR_DOT} />
|
|
119
|
+
</RadioPrimitive.Indicator>
|
|
120
|
+
</div>
|
|
121
|
+
<div className="flex flex-col gap-1">
|
|
122
|
+
<span className="text-sm font-medium leading-none">{label}</span>
|
|
123
|
+
{description ? <span className="text-sm text-muted-foreground">{description}</span> : null}
|
|
124
|
+
</div>
|
|
125
|
+
</RadioPrimitive.Root>
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export { RadioGroup, RadioGroupItem, RadioGroupCard }
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { type ReactElement } from "react"
|
|
2
|
+
import * as React from "react"
|
|
3
|
+
import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "lucide-react"
|
|
4
|
+
import { Select as SelectPrimitive } from "@base-ui/react/select"
|
|
5
|
+
import { cn } from "@/lib/utils"
|
|
6
|
+
import { useThemeVars } from "@/lib/theme-provider"
|
|
7
|
+
|
|
8
|
+
export type SelectProps = React.ComponentProps<typeof SelectPrimitive.Root>
|
|
9
|
+
|
|
10
|
+
function Select({
|
|
11
|
+
...props
|
|
12
|
+
}: SelectProps): ReactElement {
|
|
13
|
+
return <SelectPrimitive.Root data-slot="select" {...props} />
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type SelectGroupProps = React.ComponentProps<typeof SelectPrimitive.Group>
|
|
17
|
+
|
|
18
|
+
function SelectGroup({
|
|
19
|
+
...props
|
|
20
|
+
}: SelectGroupProps): ReactElement {
|
|
21
|
+
return <SelectPrimitive.Group data-slot="select-group" {...props} />
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type SelectValueProps = React.ComponentProps<typeof SelectPrimitive.Value>
|
|
25
|
+
|
|
26
|
+
function SelectValue({
|
|
27
|
+
...props
|
|
28
|
+
}: SelectValueProps): ReactElement {
|
|
29
|
+
return <SelectPrimitive.Value data-slot="select-value" {...props} />
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type SelectTriggerProps = React.ComponentProps<typeof SelectPrimitive.Trigger> & {
|
|
33
|
+
size?: "sm" | "default"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function SelectTrigger({
|
|
37
|
+
className,
|
|
38
|
+
size = "default",
|
|
39
|
+
children,
|
|
40
|
+
...props
|
|
41
|
+
}: SelectTriggerProps): ReactElement {
|
|
42
|
+
return (
|
|
43
|
+
<SelectPrimitive.Trigger
|
|
44
|
+
className={cn(
|
|
45
|
+
"flex w-fit items-center justify-between gap-2 border border-input bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-primary focus-visible:ring-[3px] focus-visible:ring-primary/20 data-popup-open:border-primary data-popup-open:ring-[3px] data-popup-open:ring-primary/20 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground",
|
|
46
|
+
className
|
|
47
|
+
)}
|
|
48
|
+
data-size={size}
|
|
49
|
+
data-slot="select-trigger"
|
|
50
|
+
{...props}
|
|
51
|
+
>
|
|
52
|
+
{children}
|
|
53
|
+
<SelectPrimitive.Icon className="transition-transform duration-200 data-popup-open:rotate-180">
|
|
54
|
+
<ChevronDownIcon className="size-4 opacity-50" />
|
|
55
|
+
</SelectPrimitive.Icon>
|
|
56
|
+
</SelectPrimitive.Trigger>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export type SelectContentProps = React.ComponentProps<typeof SelectPrimitive.Popup>
|
|
61
|
+
|
|
62
|
+
function SelectContent({
|
|
63
|
+
className,
|
|
64
|
+
children,
|
|
65
|
+
style,
|
|
66
|
+
...props
|
|
67
|
+
}: SelectContentProps): ReactElement {
|
|
68
|
+
const themeVars = useThemeVars();
|
|
69
|
+
return (
|
|
70
|
+
<SelectPrimitive.Portal>
|
|
71
|
+
<SelectPrimitive.Positioner align="start" alignItemWithTrigger={false} sideOffset={4}>
|
|
72
|
+
<SelectPrimitive.Popup
|
|
73
|
+
className={cn(
|
|
74
|
+
"relative z-50 max-h-[var(--available-height)] min-w-[8rem] overflow-x-hidden overflow-y-auto border bg-popover p-1 text-popover-foreground shadow-md data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 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",
|
|
75
|
+
className
|
|
76
|
+
)}
|
|
77
|
+
data-slot="select-content"
|
|
78
|
+
style={{ ...themeVars, ...style } as React.CSSProperties}
|
|
79
|
+
{...props}
|
|
80
|
+
>
|
|
81
|
+
<SelectScrollUpButton />
|
|
82
|
+
{children}
|
|
83
|
+
<SelectScrollDownButton />
|
|
84
|
+
</SelectPrimitive.Popup>
|
|
85
|
+
</SelectPrimitive.Positioner>
|
|
86
|
+
</SelectPrimitive.Portal>
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export type SelectLabelProps = React.ComponentProps<typeof SelectPrimitive.GroupLabel>
|
|
91
|
+
|
|
92
|
+
function SelectLabel({
|
|
93
|
+
className,
|
|
94
|
+
...props
|
|
95
|
+
}: SelectLabelProps): ReactElement {
|
|
96
|
+
return (
|
|
97
|
+
<SelectPrimitive.GroupLabel
|
|
98
|
+
className={cn("px-2 py-1.5 text-xs font-semibold text-muted-foreground", className)}
|
|
99
|
+
data-slot="select-label"
|
|
100
|
+
{...props}
|
|
101
|
+
/>
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export type SelectItemProps = React.ComponentProps<typeof SelectPrimitive.Item>
|
|
106
|
+
|
|
107
|
+
function SelectItem({
|
|
108
|
+
className,
|
|
109
|
+
children,
|
|
110
|
+
...props
|
|
111
|
+
}: SelectItemProps): ReactElement {
|
|
112
|
+
return (
|
|
113
|
+
<SelectPrimitive.Item
|
|
114
|
+
className={cn(
|
|
115
|
+
"relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-highlighted:bg-primary/5 data-highlighted:text-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2",
|
|
116
|
+
className
|
|
117
|
+
)}
|
|
118
|
+
data-slot="select-item"
|
|
119
|
+
{...props}
|
|
120
|
+
>
|
|
121
|
+
<span
|
|
122
|
+
className="absolute right-2 flex size-3.5 items-center justify-center"
|
|
123
|
+
data-slot="select-item-indicator"
|
|
124
|
+
>
|
|
125
|
+
<SelectPrimitive.ItemIndicator>
|
|
126
|
+
<CheckIcon className="size-4" />
|
|
127
|
+
</SelectPrimitive.ItemIndicator>
|
|
128
|
+
</span>
|
|
129
|
+
<SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>
|
|
130
|
+
</SelectPrimitive.Item>
|
|
131
|
+
)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export type SelectSeparatorProps = React.ComponentProps<"div">
|
|
135
|
+
|
|
136
|
+
function SelectSeparator({
|
|
137
|
+
className,
|
|
138
|
+
...props
|
|
139
|
+
}: SelectSeparatorProps): ReactElement {
|
|
140
|
+
return (
|
|
141
|
+
<div
|
|
142
|
+
className={cn("pointer-events-none -mx-1 my-1 h-px bg-border", className)}
|
|
143
|
+
data-slot="select-separator"
|
|
144
|
+
role="separator"
|
|
145
|
+
{...props}
|
|
146
|
+
/>
|
|
147
|
+
)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export type SelectScrollUpButtonProps = React.ComponentProps<typeof SelectPrimitive.ScrollUpArrow>
|
|
151
|
+
|
|
152
|
+
function SelectScrollUpButton({
|
|
153
|
+
className,
|
|
154
|
+
...props
|
|
155
|
+
}: SelectScrollUpButtonProps): ReactElement {
|
|
156
|
+
return (
|
|
157
|
+
<SelectPrimitive.ScrollUpArrow
|
|
158
|
+
className={cn(
|
|
159
|
+
"flex cursor-default items-center justify-center py-1",
|
|
160
|
+
className
|
|
161
|
+
)}
|
|
162
|
+
data-slot="select-scroll-up-button"
|
|
163
|
+
{...props}
|
|
164
|
+
>
|
|
165
|
+
<ChevronUpIcon className="size-4" />
|
|
166
|
+
</SelectPrimitive.ScrollUpArrow>
|
|
167
|
+
)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export type SelectScrollDownButtonProps = React.ComponentProps<typeof SelectPrimitive.ScrollDownArrow>
|
|
171
|
+
|
|
172
|
+
function SelectScrollDownButton({
|
|
173
|
+
className,
|
|
174
|
+
...props
|
|
175
|
+
}: SelectScrollDownButtonProps): ReactElement {
|
|
176
|
+
return (
|
|
177
|
+
<SelectPrimitive.ScrollDownArrow
|
|
178
|
+
className={cn(
|
|
179
|
+
"flex cursor-default items-center justify-center py-1",
|
|
180
|
+
className
|
|
181
|
+
)}
|
|
182
|
+
data-slot="select-scroll-down-button"
|
|
183
|
+
{...props}
|
|
184
|
+
>
|
|
185
|
+
<ChevronDownIcon className="size-4" />
|
|
186
|
+
</SelectPrimitive.ScrollDownArrow>
|
|
187
|
+
)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export {
|
|
191
|
+
Select,
|
|
192
|
+
SelectContent,
|
|
193
|
+
SelectGroup,
|
|
194
|
+
SelectItem,
|
|
195
|
+
SelectLabel,
|
|
196
|
+
SelectScrollDownButton,
|
|
197
|
+
SelectScrollUpButton,
|
|
198
|
+
SelectSeparator,
|
|
199
|
+
SelectTrigger,
|
|
200
|
+
SelectValue,
|
|
201
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type ReactElement } from "react"
|
|
2
|
+
import * as React from "react"
|
|
3
|
+
import { Separator as SeparatorPrimitive } from "@base-ui/react/separator"
|
|
4
|
+
import { cn } from "@/lib/utils"
|
|
5
|
+
|
|
6
|
+
export type SeparatorProps = React.ComponentProps<typeof SeparatorPrimitive>
|
|
7
|
+
|
|
8
|
+
function Separator({
|
|
9
|
+
className,
|
|
10
|
+
orientation = "horizontal",
|
|
11
|
+
...props
|
|
12
|
+
}: SeparatorProps): ReactElement {
|
|
13
|
+
return (
|
|
14
|
+
<SeparatorPrimitive
|
|
15
|
+
className={cn(
|
|
16
|
+
"shrink-0 bg-border data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-px",
|
|
17
|
+
className
|
|
18
|
+
)}
|
|
19
|
+
data-orientation={orientation}
|
|
20
|
+
data-slot="separator"
|
|
21
|
+
{...props}
|
|
22
|
+
/>
|
|
23
|
+
)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { Separator }
|