@boyernick/standard-ui-react 0.1.1-canary.2 → 0.1.1-canary.22
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/package.json +5 -3
- package/src/accordion.tsx +1 -1
- package/src/alert-dialog.tsx +1 -1
- package/src/autocomplete.tsx +12 -11
- package/src/badge.tsx +73 -9
- package/src/brand.tsx +2 -2
- package/src/breadcrumb.tsx +38 -20
- package/src/button.tsx +2 -2
- package/src/calendar.tsx +22 -11
- package/src/card.tsx +57 -14
- package/src/carousel.tsx +163 -6
- package/src/checkbox.tsx +35 -13
- package/src/collapsible.tsx +4 -2
- package/src/combobox.tsx +13 -12
- package/src/command.tsx +38 -14
- package/src/context-menu.tsx +6 -3
- package/src/date-picker.tsx +174 -0
- package/src/dialog.tsx +33 -10
- package/src/drawer.tsx +1 -1
- package/src/empty.tsx +4 -4
- package/src/field.tsx +1 -1
- package/src/filter-group.tsx +139 -0
- package/src/icons.tsx +39 -0
- package/src/illustrations.tsx +219 -141
- package/src/image-modal.tsx +440 -49
- package/src/index.ts +188 -0
- package/src/input.tsx +1 -1
- package/src/kbd.tsx +49 -0
- package/src/lib/motion.ts +128 -18
- package/src/lib/popup.ts +45 -0
- package/src/menu.tsx +7 -4
- package/src/menubar.tsx +5 -0
- package/src/meter.tsx +1 -1
- package/src/minimap.tsx +267 -0
- package/src/navigation-menu.tsx +336 -67
- package/src/number-field.tsx +327 -61
- package/src/pagination.tsx +258 -42
- package/src/popover.tsx +3 -1
- package/src/preview-card.tsx +3 -1
- package/src/progress.tsx +6 -1
- package/src/questionnaire.tsx +279 -0
- package/src/scroll-area.tsx +1 -1
- package/src/select.tsx +8 -6
- package/src/sidebar.tsx +109 -28
- package/src/slider.tsx +64 -6
- package/src/sounds.tsx +6 -10
- package/src/spinner.tsx +105 -32
- package/src/switch.tsx +2 -2
- package/src/table.tsx +82 -15
- package/src/tabs.tsx +184 -38
- package/src/text-animate.tsx +71 -28
- package/src/textarea.tsx +1 -1
- package/src/timeline.tsx +321 -0
- package/src/toast.tsx +156 -23
- package/src/tooltip.tsx +43 -3
- package/src/video-player.tsx +296 -120
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@boyernick/standard-ui-react",
|
|
3
|
-
"version": "0.1.1-canary.
|
|
3
|
+
"version": "0.1.1-canary.22",
|
|
4
4
|
"description": "React components for StandardUI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -21,12 +21,14 @@
|
|
|
21
21
|
"test": "node --test --experimental-strip-types \"src/**/*.test.ts\""
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {
|
|
24
|
-
"react": "^
|
|
25
|
-
"react-dom": "^
|
|
24
|
+
"react": "^19.0.0",
|
|
25
|
+
"react-dom": "^19.0.0"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@base-ui/react": "^1.7.0",
|
|
29
|
+
"@central-icons-react/round-filled-radius-2-stroke-2": "^1.1.315",
|
|
29
30
|
"@central-icons-react/round-outlined-radius-2-stroke-2": "^1.1.312",
|
|
31
|
+
"@shadcn/react": "^0.3.0",
|
|
30
32
|
"class-variance-authority": "^0.7.1",
|
|
31
33
|
"clsx": "^2.1.1",
|
|
32
34
|
"date-fns": "^4.4.0",
|
package/src/accordion.tsx
CHANGED
package/src/alert-dialog.tsx
CHANGED
|
@@ -58,7 +58,7 @@ export const AlertDialogPopup = ({
|
|
|
58
58
|
}: AlertDialogPopupProps) => (
|
|
59
59
|
<BaseAlertDialog.Popup
|
|
60
60
|
className={cn(
|
|
61
|
-
"fixed top-1/2 left-1/2 z-50 flex w-full max-w-md -translate-x-1/2 -translate-y-1/2 flex-col gap-6 rounded-xl border border-border-primary bg-surface p-5 shadow-md outline-none max-sm:max-w-[calc(100vw-2rem)]",
|
|
61
|
+
"fixed top-1/2 left-1/2 z-50 flex w-full max-w-md -translate-x-1/2 -translate-y-1/2 flex-col gap-6 rounded-xl border border-border-primary bg-surface p-5 shadow-md outline-none max-h-[calc(100dvh-2rem)] overflow-y-auto max-sm:max-w-[calc(100vw-2rem)]",
|
|
62
62
|
motion.popupCenter,
|
|
63
63
|
className,
|
|
64
64
|
)}
|
package/src/autocomplete.tsx
CHANGED
|
@@ -5,6 +5,7 @@ import type { ComponentProps, ReactElement } from "react"
|
|
|
5
5
|
import { IconChevronDownSmall, IconCrossSmall } from "./icons"
|
|
6
6
|
import { cn } from "./lib/cn"
|
|
7
7
|
import { motion } from "./lib/motion"
|
|
8
|
+
import { popupInset, popupItem, popupLabel, popupMessage, popupSurface } from "./lib/popup"
|
|
8
9
|
|
|
9
10
|
export type AutocompleteProps = ComponentProps<typeof BaseAutocomplete.Root>
|
|
10
11
|
export type AutocompleteValueProps = ComponentProps<typeof BaseAutocomplete.Value>
|
|
@@ -66,8 +67,7 @@ export const AutocompleteInputGroup = ({
|
|
|
66
67
|
}: AutocompleteInputGroupProps) => (
|
|
67
68
|
<BaseAutocomplete.InputGroup
|
|
68
69
|
className={cn(
|
|
69
|
-
"relative flex min-h-9 w-full items-center rounded-
|
|
70
|
-
"has-[[data-popup-open]]:bg-background-tertiary/60",
|
|
70
|
+
"relative flex min-h-9 w-full items-center rounded-xl border border-border-secondary bg-surface inset-shadow-outline-top outline-none transition-[color,box-shadow]",
|
|
71
71
|
"focus-within:border-ring focus-within:ring-[3px] focus-within:ring-offset-1 focus-within:ring-offset-background-primary focus-within:ring-ring/20",
|
|
72
72
|
"aria-invalid:border-destructive aria-invalid:focus-within:border-destructive aria-invalid:focus-within:ring-destructive/20",
|
|
73
73
|
"has-[[aria-invalid=true]]:border-destructive has-[[aria-invalid=true]]:focus-within:border-destructive has-[[aria-invalid=true]]:focus-within:ring-destructive/20",
|
|
@@ -84,7 +84,7 @@ export const AutocompleteInput = ({
|
|
|
84
84
|
}: AutocompleteInputProps) => (
|
|
85
85
|
<BaseAutocomplete.Input
|
|
86
86
|
className={cn(
|
|
87
|
-
"h-9 min-w-0 flex-1 cursor-text rounded-
|
|
87
|
+
"h-9 min-w-0 flex-1 cursor-text rounded-xl bg-transparent px-3 text-sm text-fg-primary outline-none placeholder:text-fg-quaternary focus-visible:ring-0",
|
|
88
88
|
className,
|
|
89
89
|
)}
|
|
90
90
|
{...props}
|
|
@@ -134,7 +134,7 @@ export const AutocompleteClear = ({
|
|
|
134
134
|
{...props}
|
|
135
135
|
>
|
|
136
136
|
{children ?? (
|
|
137
|
-
<IconCrossSmall size={
|
|
137
|
+
<IconCrossSmall size={16} className="size-4" aria-hidden />
|
|
138
138
|
)}
|
|
139
139
|
</BaseAutocomplete.Clear>
|
|
140
140
|
)
|
|
@@ -151,7 +151,7 @@ export const AutocompleteBackdrop = ({
|
|
|
151
151
|
)
|
|
152
152
|
|
|
153
153
|
export const AutocompletePositioner = ({
|
|
154
|
-
sideOffset =
|
|
154
|
+
sideOffset = 6,
|
|
155
155
|
className,
|
|
156
156
|
...props
|
|
157
157
|
}: AutocompletePositionerProps) => (
|
|
@@ -168,7 +168,8 @@ export const AutocompletePopup = ({
|
|
|
168
168
|
}: AutocompletePopupProps) => (
|
|
169
169
|
<BaseAutocomplete.Popup
|
|
170
170
|
className={cn(
|
|
171
|
-
"z-50 max-h-[min(24rem,var(--available-height))] w-[var(--anchor-width)] overflow-hidden
|
|
171
|
+
"z-50 max-h-[min(24rem,var(--available-height))] w-[var(--anchor-width)] overflow-hidden",
|
|
172
|
+
popupSurface,
|
|
172
173
|
motion.popupAnchor,
|
|
173
174
|
className,
|
|
174
175
|
)}
|
|
@@ -199,7 +200,7 @@ export const AutocompleteList = ({
|
|
|
199
200
|
...props
|
|
200
201
|
}: AutocompleteListProps) => (
|
|
201
202
|
<BaseAutocomplete.List
|
|
202
|
-
className={cn("max-h-[inherit] overflow-y-auto
|
|
203
|
+
className={cn("max-h-[inherit] overflow-y-auto outline-none", popupInset, className)}
|
|
203
204
|
{...props}
|
|
204
205
|
/>
|
|
205
206
|
)
|
|
@@ -210,7 +211,7 @@ export const AutocompleteItem = ({
|
|
|
210
211
|
}: AutocompleteItemProps) => (
|
|
211
212
|
<BaseAutocomplete.Item
|
|
212
213
|
className={cn(
|
|
213
|
-
|
|
214
|
+
popupItem,
|
|
214
215
|
motion.colors,
|
|
215
216
|
"data-disabled:cursor-not-allowed data-disabled:opacity-50 data-highlighted:bg-background-tertiary data-highlighted:text-fg-primary",
|
|
216
217
|
className,
|
|
@@ -224,7 +225,7 @@ export const AutocompleteEmpty = ({
|
|
|
224
225
|
...props
|
|
225
226
|
}: AutocompleteEmptyProps) => (
|
|
226
227
|
<BaseAutocomplete.Empty
|
|
227
|
-
className={cn("
|
|
228
|
+
className={cn(cn(popupMessage, "empty:hidden"), className)}
|
|
228
229
|
{...props}
|
|
229
230
|
/>
|
|
230
231
|
)
|
|
@@ -234,7 +235,7 @@ export const AutocompleteStatus = ({
|
|
|
234
235
|
...props
|
|
235
236
|
}: AutocompleteStatusProps) => (
|
|
236
237
|
<BaseAutocomplete.Status
|
|
237
|
-
className={cn(
|
|
238
|
+
className={cn(popupMessage, className)}
|
|
238
239
|
{...props}
|
|
239
240
|
/>
|
|
240
241
|
)
|
|
@@ -251,7 +252,7 @@ export const AutocompleteGroupLabel = ({
|
|
|
251
252
|
...props
|
|
252
253
|
}: AutocompleteGroupLabelProps) => (
|
|
253
254
|
<BaseAutocomplete.GroupLabel
|
|
254
|
-
className={cn(
|
|
255
|
+
className={cn(popupLabel, className)}
|
|
255
256
|
{...props}
|
|
256
257
|
/>
|
|
257
258
|
)
|
package/src/badge.tsx
CHANGED
|
@@ -1,28 +1,92 @@
|
|
|
1
1
|
import { cva, type VariantProps } from "class-variance-authority"
|
|
2
|
-
import type { HTMLAttributes } from "react"
|
|
2
|
+
import type { HTMLAttributes, ReactNode } from "react"
|
|
3
3
|
import { cn } from "./lib/cn"
|
|
4
4
|
|
|
5
5
|
const badgeVariants = cva(
|
|
6
|
-
"
|
|
6
|
+
"inline-flex shrink-0 items-center justify-center whitespace-nowrap align-middle [&>[data-badge-label]]:min-w-0 [&>[data-badge-label]]:truncate [&>[data-badge-slot]]:inline-flex [&>[data-badge-slot]]:shrink-0 [&>[data-badge-slot]]:items-center [&>[data-badge-slot]]:justify-center [&>[data-badge-slot]>svg]:size-full",
|
|
7
7
|
{
|
|
8
8
|
variants: {
|
|
9
9
|
variant: {
|
|
10
|
-
default: "bg-background-tertiary
|
|
11
|
-
outline: "border border-border-primary
|
|
12
|
-
|
|
10
|
+
default: "bg-background-tertiary text-fg-primary",
|
|
11
|
+
outline: "border border-border-primary text-fg-secondary",
|
|
12
|
+
info: "bg-status-info-background text-status-info",
|
|
13
|
+
success: "bg-status-success-background text-status-success",
|
|
14
|
+
warning: "bg-status-warning-background text-status-warning",
|
|
15
|
+
critical: "bg-status-critical-background text-status-critical",
|
|
16
|
+
destructive: "bg-status-critical-background text-status-critical",
|
|
17
|
+
},
|
|
18
|
+
size: {
|
|
19
|
+
xxs: "text-2xs-strong h-4 gap-0.5 px-1.5 [&>[data-badge-slot]]:size-2.5",
|
|
20
|
+
xs: "text-2xs-strong h-5 gap-1 px-1.5 [&>[data-badge-slot]]:size-3",
|
|
21
|
+
sm: "text-xs-strong h-6 gap-1 px-2 [&>[data-badge-slot]]:size-3.5",
|
|
22
|
+
md: "text-xs-strong h-7 gap-1.5 px-2.5 [&>[data-badge-slot]]:size-3.5",
|
|
23
|
+
lg: "text-sm-strong h-8 gap-1.5 px-3 [&>[data-badge-slot]]:size-4",
|
|
24
|
+
},
|
|
25
|
+
rounded: {
|
|
26
|
+
true: "rounded-full",
|
|
27
|
+
false: "rounded-sm",
|
|
28
|
+
},
|
|
29
|
+
iconOnly: {
|
|
30
|
+
true: "p-0",
|
|
31
|
+
false: "",
|
|
13
32
|
},
|
|
14
33
|
},
|
|
34
|
+
compoundVariants: [
|
|
35
|
+
{ iconOnly: true, size: "xxs", class: "size-4" },
|
|
36
|
+
{ iconOnly: true, size: "xs", class: "size-5" },
|
|
37
|
+
{ iconOnly: true, size: "sm", class: "size-6" },
|
|
38
|
+
{ iconOnly: true, size: "md", class: "size-7" },
|
|
39
|
+
{ iconOnly: true, size: "lg", class: "size-8" },
|
|
40
|
+
],
|
|
15
41
|
defaultVariants: {
|
|
16
42
|
variant: "default",
|
|
43
|
+
size: "sm",
|
|
44
|
+
rounded: false,
|
|
45
|
+
iconOnly: false,
|
|
17
46
|
},
|
|
18
47
|
},
|
|
19
48
|
)
|
|
20
49
|
|
|
21
|
-
export type BadgeProps = HTMLAttributes<HTMLSpanElement> &
|
|
22
|
-
VariantProps<typeof badgeVariants>
|
|
50
|
+
export type BadgeProps = Omit<HTMLAttributes<HTMLSpanElement>, "prefix"> &
|
|
51
|
+
VariantProps<typeof badgeVariants> & {
|
|
52
|
+
/** Square badge sized to the height of `size`. */
|
|
53
|
+
iconOnly?: boolean
|
|
54
|
+
/** Pill shape (`rounded-full`) instead of the default light radius. */
|
|
55
|
+
rounded?: boolean
|
|
56
|
+
/** Icon or element before the label. */
|
|
57
|
+
prefix?: ReactNode
|
|
58
|
+
/** Icon or element after the label. */
|
|
59
|
+
suffix?: ReactNode
|
|
60
|
+
}
|
|
23
61
|
|
|
24
|
-
export const Badge = ({
|
|
25
|
-
|
|
62
|
+
export const Badge = ({
|
|
63
|
+
className,
|
|
64
|
+
variant,
|
|
65
|
+
size,
|
|
66
|
+
rounded,
|
|
67
|
+
iconOnly,
|
|
68
|
+
prefix,
|
|
69
|
+
suffix,
|
|
70
|
+
children,
|
|
71
|
+
...props
|
|
72
|
+
}: BadgeProps) => (
|
|
73
|
+
<span
|
|
74
|
+
className={cn(
|
|
75
|
+
badgeVariants({ variant, size, rounded, iconOnly }),
|
|
76
|
+
className,
|
|
77
|
+
)}
|
|
78
|
+
{...props}
|
|
79
|
+
>
|
|
80
|
+
{iconOnly ? (
|
|
81
|
+
<span data-badge-slot="icon">{children}</span>
|
|
82
|
+
) : (
|
|
83
|
+
<>
|
|
84
|
+
{prefix ? <span data-badge-slot="prefix">{prefix}</span> : null}
|
|
85
|
+
{children != null ? <span data-badge-label>{children}</span> : null}
|
|
86
|
+
{suffix ? <span data-badge-slot="suffix">{suffix}</span> : null}
|
|
87
|
+
</>
|
|
88
|
+
)}
|
|
89
|
+
</span>
|
|
26
90
|
)
|
|
27
91
|
|
|
28
92
|
export { badgeVariants }
|
package/src/brand.tsx
CHANGED
|
@@ -45,13 +45,13 @@ export const BrandWordmark = ({
|
|
|
45
45
|
compact = false,
|
|
46
46
|
size = "md",
|
|
47
47
|
}: BrandWordmarkProps) => {
|
|
48
|
-
const resolvedMarkSize = markSize ?? (size === "sm" ? 16 :
|
|
48
|
+
const resolvedMarkSize = markSize ?? (size === "sm" ? 16 : 32)
|
|
49
49
|
|
|
50
50
|
return (
|
|
51
51
|
<span
|
|
52
52
|
className={cn(
|
|
53
53
|
"inline-flex items-center",
|
|
54
|
-
size === "sm" ? "gap-1" : "gap-
|
|
54
|
+
size === "sm" ? "gap-1" : "gap-2",
|
|
55
55
|
className,
|
|
56
56
|
)}
|
|
57
57
|
aria-label="StandardUI"
|
package/src/breadcrumb.tsx
CHANGED
|
@@ -1,16 +1,30 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
|
2
|
+
import type { ComponentProps, ReactNode } from "react"
|
|
3
|
+
import { IconChevronRightSmall } from "./icons"
|
|
4
|
+
import { cn } from "./lib/cn"
|
|
5
|
+
import { motion } from "./lib/motion"
|
|
6
|
+
|
|
7
|
+
export type BreadcrumbProps = ComponentProps<"nav">
|
|
8
|
+
export type BreadcrumbListProps = ComponentProps<"ol">
|
|
9
|
+
export type BreadcrumbItemProps = ComponentProps<"li">
|
|
10
|
+
export type BreadcrumbLinkProps = ComponentProps<"a">
|
|
11
|
+
export type BreadcrumbPageProps = ComponentProps<"span">
|
|
12
|
+
|
|
13
|
+
const breadcrumbSeparatorVariants = cva("text-fg-tertiary", {
|
|
14
|
+
variants: {
|
|
15
|
+
variant: {
|
|
16
|
+
chevron: "[&_svg]:size-3.5",
|
|
17
|
+
slash: "",
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
defaultVariants: {
|
|
21
|
+
variant: "chevron",
|
|
22
|
+
},
|
|
23
|
+
})
|
|
5
24
|
|
|
6
|
-
export type BreadcrumbProps = ComponentProps<"nav">;
|
|
7
|
-
export type BreadcrumbListProps = ComponentProps<"ol">;
|
|
8
|
-
export type BreadcrumbItemProps = ComponentProps<"li">;
|
|
9
|
-
export type BreadcrumbLinkProps = ComponentProps<"a">;
|
|
10
|
-
export type BreadcrumbPageProps = ComponentProps<"span">;
|
|
11
25
|
export type BreadcrumbSeparatorProps = ComponentProps<"li"> & {
|
|
12
|
-
children?: ReactNode
|
|
13
|
-
}
|
|
26
|
+
children?: ReactNode
|
|
27
|
+
} & VariantProps<typeof breadcrumbSeparatorVariants>
|
|
14
28
|
|
|
15
29
|
export const Breadcrumb = ({ className, ...props }: BreadcrumbProps) => (
|
|
16
30
|
<nav
|
|
@@ -18,17 +32,17 @@ export const Breadcrumb = ({ className, ...props }: BreadcrumbProps) => (
|
|
|
18
32
|
className={cn("text-sm text-fg-secondary", className)}
|
|
19
33
|
{...props}
|
|
20
34
|
/>
|
|
21
|
-
)
|
|
35
|
+
)
|
|
22
36
|
|
|
23
37
|
export const BreadcrumbList = ({
|
|
24
38
|
className,
|
|
25
39
|
...props
|
|
26
40
|
}: BreadcrumbListProps) => (
|
|
27
41
|
<ol
|
|
28
|
-
className={cn("flex flex-wrap items-center gap-1.5", className)}
|
|
42
|
+
className={cn("flex flex-wrap items-center gap-x-2 gap-y-1.5", className)}
|
|
29
43
|
{...props}
|
|
30
44
|
/>
|
|
31
|
-
)
|
|
45
|
+
)
|
|
32
46
|
|
|
33
47
|
export const BreadcrumbItem = ({
|
|
34
48
|
className,
|
|
@@ -38,7 +52,7 @@ export const BreadcrumbItem = ({
|
|
|
38
52
|
className={cn("inline-flex items-center gap-1.5", className)}
|
|
39
53
|
{...props}
|
|
40
54
|
/>
|
|
41
|
-
)
|
|
55
|
+
)
|
|
42
56
|
|
|
43
57
|
export const BreadcrumbLink = ({
|
|
44
58
|
className,
|
|
@@ -52,7 +66,7 @@ export const BreadcrumbLink = ({
|
|
|
52
66
|
)}
|
|
53
67
|
{...props}
|
|
54
68
|
/>
|
|
55
|
-
)
|
|
69
|
+
)
|
|
56
70
|
|
|
57
71
|
export const BreadcrumbPage = ({
|
|
58
72
|
className,
|
|
@@ -63,19 +77,23 @@ export const BreadcrumbPage = ({
|
|
|
63
77
|
className={cn("font-medium text-fg-primary", className)}
|
|
64
78
|
{...props}
|
|
65
79
|
/>
|
|
66
|
-
)
|
|
80
|
+
)
|
|
67
81
|
|
|
68
82
|
export const BreadcrumbSeparator = ({
|
|
69
83
|
className,
|
|
70
84
|
children,
|
|
85
|
+
variant,
|
|
71
86
|
...props
|
|
72
87
|
}: BreadcrumbSeparatorProps) => (
|
|
73
88
|
<li
|
|
74
89
|
role="presentation"
|
|
75
90
|
aria-hidden
|
|
76
|
-
className={cn(
|
|
91
|
+
className={cn(breadcrumbSeparatorVariants({ variant }), className)}
|
|
77
92
|
{...props}
|
|
78
93
|
>
|
|
79
|
-
{children ??
|
|
94
|
+
{children ??
|
|
95
|
+
(variant === "slash" ? "/" : <IconChevronRightSmall aria-hidden />)}
|
|
80
96
|
</li>
|
|
81
|
-
)
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
export { breadcrumbSeparatorVariants }
|
package/src/button.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import type { ButtonHTMLAttributes, ReactNode } from "react"
|
|
|
3
3
|
import { cn } from "./lib/cn"
|
|
4
4
|
|
|
5
5
|
const buttonVariants = cva(
|
|
6
|
-
"text-sm inline-flex cursor-pointer items-center justify-center gap-1.5 whitespace-nowrap transition-all duration-
|
|
6
|
+
"text-sm inline-flex cursor-pointer items-center justify-center gap-1.5 whitespace-nowrap transition-all duration-[var(--duration-sm)] ease-enter outline-none focus-visible:ring-[3px] focus-visible:ring-offset-1 focus-visible:ring-offset-background-primary disabled:cursor-not-allowed disabled:opacity-50 disabled:active:translate-y-0 active:translate-y-px [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
7
7
|
{
|
|
8
8
|
variants: {
|
|
9
9
|
variant: {
|
|
@@ -25,7 +25,7 @@ const buttonVariants = cva(
|
|
|
25
25
|
},
|
|
26
26
|
rounded: {
|
|
27
27
|
true: "rounded-full",
|
|
28
|
-
false: "rounded-
|
|
28
|
+
false: "rounded-lg",
|
|
29
29
|
},
|
|
30
30
|
iconOnly: {
|
|
31
31
|
true: "px-0",
|
package/src/calendar.tsx
CHANGED
|
@@ -8,9 +8,9 @@ import { motion } from "./lib/motion"
|
|
|
8
8
|
export type CalendarProps = DayPickerProps
|
|
9
9
|
|
|
10
10
|
const navButtonClassName = cn(
|
|
11
|
-
"inline-flex size-
|
|
11
|
+
"inline-flex size-6 items-center justify-center rounded-md border border-transparent text-fg-tertiary",
|
|
12
12
|
motion.colors,
|
|
13
|
-
"hover:bg-background-tertiary hover:text-fg-primary outline-none focus-visible:border-ring focus-visible:
|
|
13
|
+
"hover:bg-background-tertiary hover:text-fg-primary outline-none focus-visible:border-ring focus-visible:bg-background-tertiary focus-visible:text-fg-primary focus-visible:ring-2 focus-visible:ring-ring/20 disabled:cursor-not-allowed disabled:opacity-50",
|
|
14
14
|
)
|
|
15
15
|
|
|
16
16
|
const CalendarChevron = ({
|
|
@@ -40,34 +40,45 @@ export const Calendar = ({
|
|
|
40
40
|
className,
|
|
41
41
|
classNames,
|
|
42
42
|
showOutsideDays = true,
|
|
43
|
+
weekStartsOn = 1,
|
|
43
44
|
components,
|
|
44
45
|
...props
|
|
45
46
|
}: CalendarProps) => (
|
|
46
47
|
<DayPicker
|
|
47
48
|
showOutsideDays={showOutsideDays}
|
|
48
|
-
|
|
49
|
+
weekStartsOn={weekStartsOn}
|
|
50
|
+
className={cn(
|
|
51
|
+
"w-64 rounded-xl border border-border-primary bg-surface p-3",
|
|
52
|
+
className,
|
|
53
|
+
)}
|
|
49
54
|
classNames={{
|
|
50
55
|
months: "relative flex flex-col gap-4 sm:flex-row",
|
|
51
|
-
month: "flex w-full flex-col
|
|
52
|
-
month_caption: "
|
|
56
|
+
month: "flex w-full flex-col",
|
|
57
|
+
month_caption: "flex h-8 items-start justify-start",
|
|
53
58
|
caption_label: "text-sm-strong text-fg-primary",
|
|
54
|
-
nav: "absolute
|
|
59
|
+
nav: "absolute top-0 right-0 flex items-center",
|
|
55
60
|
button_previous: navButtonClassName,
|
|
56
61
|
button_next: navButtonClassName,
|
|
57
62
|
month_grid: "w-full border-collapse",
|
|
58
63
|
weekdays: "flex",
|
|
59
64
|
weekday:
|
|
60
|
-
"flex
|
|
61
|
-
weeks: "flex flex-col",
|
|
62
|
-
week: "
|
|
65
|
+
"flex w-8 items-center justify-center pb-1 text-xs font-normal text-fg-tertiary select-none",
|
|
66
|
+
weeks: "flex flex-col gap-1",
|
|
67
|
+
week: "flex w-full",
|
|
63
68
|
day: "relative p-0 text-center",
|
|
64
69
|
day_button: cn(
|
|
65
|
-
"inline-flex size-8 items-center justify-center rounded-
|
|
70
|
+
"inline-flex size-8 items-center justify-center rounded-lg text-sm text-fg-primary tabular-nums",
|
|
66
71
|
motion.colors,
|
|
67
|
-
"hover:bg-background-tertiary outline-none focus-visible:
|
|
72
|
+
"hover:bg-background-tertiary outline-none focus-visible:z-10 focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 aria-selected:opacity-100",
|
|
68
73
|
),
|
|
69
74
|
selected:
|
|
70
75
|
"[&>button]:bg-brand-primary [&>button]:text-brand-foreground [&>button]:ring-0 [&>button]:hover:bg-brand-primary-hover [&>button]:hover:text-brand-foreground",
|
|
76
|
+
range_start:
|
|
77
|
+
"rounded-l-lg bg-brand-primary/10 last:rounded-r-lg [&>button]:relative [&>button]:z-[1]",
|
|
78
|
+
range_middle:
|
|
79
|
+
"bg-brand-primary/10 first:rounded-l-lg last:rounded-r-lg [&>button]:!rounded-none [&>button]:!bg-transparent [&>button]:!text-fg-primary [&>button]:hover:!bg-brand-primary/15",
|
|
80
|
+
range_end:
|
|
81
|
+
"rounded-r-lg bg-brand-primary/10 first:rounded-l-lg [&>button]:relative [&>button]:z-[1]",
|
|
71
82
|
today:
|
|
72
83
|
"[&>button]:font-medium [&>button]:ring-1 [&>button]:ring-inset [&>button]:ring-border-secondary",
|
|
73
84
|
outside: "[&>button]:text-fg-quaternary",
|
package/src/card.tsx
CHANGED
|
@@ -1,32 +1,59 @@
|
|
|
1
|
+
import { cva, type VariantProps } from "class-variance-authority"
|
|
1
2
|
import type { HTMLAttributes } from "react"
|
|
2
3
|
import { cn } from "./lib/cn"
|
|
3
4
|
|
|
4
|
-
|
|
5
|
+
const cardVariants = cva("flex flex-col rounded-xl bg-surface text-fg-primary", {
|
|
6
|
+
variants: {
|
|
7
|
+
variant: {
|
|
8
|
+
elevated: "shadow-lg",
|
|
9
|
+
outline: "border border-border-primary",
|
|
10
|
+
ghost: "",
|
|
11
|
+
},
|
|
12
|
+
padding: {
|
|
13
|
+
md: "gap-6 py-6",
|
|
14
|
+
none: "",
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
defaultVariants: {
|
|
18
|
+
variant: "elevated",
|
|
19
|
+
padding: "md",
|
|
20
|
+
},
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
export type CardProps = HTMLAttributes<HTMLDivElement> &
|
|
24
|
+
VariantProps<typeof cardVariants>
|
|
5
25
|
export type CardHeaderProps = HTMLAttributes<HTMLDivElement>
|
|
6
26
|
export type CardTitleProps = HTMLAttributes<HTMLHeadingElement>
|
|
7
27
|
export type CardDescriptionProps = HTMLAttributes<HTMLParagraphElement>
|
|
28
|
+
export type CardActionProps = HTMLAttributes<HTMLDivElement>
|
|
8
29
|
export type CardContentProps = HTMLAttributes<HTMLDivElement>
|
|
9
30
|
export type CardFooterProps = HTMLAttributes<HTMLDivElement>
|
|
10
31
|
|
|
11
|
-
export const Card = ({ className, ...props }: CardProps) => (
|
|
32
|
+
export const Card = ({ className, variant, padding, ...props }: CardProps) => (
|
|
12
33
|
<div
|
|
13
|
-
className={cn(
|
|
14
|
-
"flex flex-col overflow-hidden rounded-xl border border-border-primary bg-surface",
|
|
15
|
-
className,
|
|
16
|
-
)}
|
|
17
34
|
{...props}
|
|
35
|
+
data-slot="card"
|
|
36
|
+
className={cn(cardVariants({ variant, padding }), className)}
|
|
18
37
|
/>
|
|
19
38
|
)
|
|
20
39
|
|
|
21
40
|
export const CardHeader = ({ className, ...props }: CardHeaderProps) => (
|
|
22
41
|
<div
|
|
23
|
-
className={cn("flex flex-col gap-1 px-5 pt-5 pb-3", className)}
|
|
24
42
|
{...props}
|
|
43
|
+
data-slot="card-header"
|
|
44
|
+
className={cn(
|
|
45
|
+
"grid auto-rows-min items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto]",
|
|
46
|
+
className,
|
|
47
|
+
)}
|
|
25
48
|
/>
|
|
26
49
|
)
|
|
27
50
|
|
|
28
51
|
export const CardTitle = ({ className, ...props }: CardTitleProps) => (
|
|
29
|
-
<h3
|
|
52
|
+
<h3
|
|
53
|
+
{...props}
|
|
54
|
+
data-slot="card-title"
|
|
55
|
+
className={cn("text-sm-strong leading-none text-fg-primary", className)}
|
|
56
|
+
/>
|
|
30
57
|
)
|
|
31
58
|
|
|
32
59
|
export const CardDescription = ({
|
|
@@ -34,21 +61,37 @@ export const CardDescription = ({
|
|
|
34
61
|
...props
|
|
35
62
|
}: CardDescriptionProps) => (
|
|
36
63
|
<p
|
|
37
|
-
className={cn("text-sm leading-relaxed text-fg-secondary", className)}
|
|
38
64
|
{...props}
|
|
65
|
+
data-slot="card-description"
|
|
66
|
+
className={cn("text-sm text-fg-secondary", className)}
|
|
67
|
+
/>
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
export const CardAction = ({ className, ...props }: CardActionProps) => (
|
|
71
|
+
<div
|
|
72
|
+
{...props}
|
|
73
|
+
data-slot="card-action"
|
|
74
|
+
className={cn(
|
|
75
|
+
"col-start-2 row-span-2 row-start-1 self-start justify-self-end",
|
|
76
|
+
className,
|
|
77
|
+
)}
|
|
39
78
|
/>
|
|
40
79
|
)
|
|
41
80
|
|
|
42
81
|
export const CardContent = ({ className, ...props }: CardContentProps) => (
|
|
43
|
-
<div
|
|
82
|
+
<div
|
|
83
|
+
{...props}
|
|
84
|
+
data-slot="card-content"
|
|
85
|
+
className={cn("px-6", className)}
|
|
86
|
+
/>
|
|
44
87
|
)
|
|
45
88
|
|
|
46
89
|
export const CardFooter = ({ className, ...props }: CardFooterProps) => (
|
|
47
90
|
<div
|
|
48
|
-
className={cn(
|
|
49
|
-
"flex items-center gap-2 border-t border-border-primary px-5 py-4",
|
|
50
|
-
className,
|
|
51
|
-
)}
|
|
52
91
|
{...props}
|
|
92
|
+
data-slot="card-footer"
|
|
93
|
+
className={cn("flex items-center gap-2 px-6", className)}
|
|
53
94
|
/>
|
|
54
95
|
)
|
|
96
|
+
|
|
97
|
+
export { cardVariants }
|