@craftzbay/ui 0.9.0 → 0.10.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/README.md +72 -6
- package/dist-lib/components/ui/Accordion.js +60 -0
- package/dist-lib/components/ui/Accordion.js.map +1 -0
- package/dist-lib/components/ui/Alert.d.ts +1 -1
- package/dist-lib/components/ui/Alert.js +66 -0
- package/dist-lib/components/ui/Alert.js.map +1 -0
- package/dist-lib/components/ui/Avatar.d.ts +2 -2
- package/dist-lib/components/ui/Avatar.js +96 -0
- package/dist-lib/components/ui/Avatar.js.map +1 -0
- package/dist-lib/components/ui/Badge.d.ts +1 -1
- package/dist-lib/components/ui/Badge.js +67 -0
- package/dist-lib/components/ui/Badge.js.map +1 -0
- package/dist-lib/components/ui/Breadcrumbs.js +34 -0
- package/dist-lib/components/ui/Breadcrumbs.js.map +1 -0
- package/dist-lib/components/ui/Button.d.ts +1 -1
- package/dist-lib/components/ui/Button.js +117 -0
- package/dist-lib/components/ui/Button.js.map +1 -0
- package/dist-lib/components/ui/Calendar.d.ts +7 -1
- package/dist-lib/components/ui/Calendar.js +111 -0
- package/dist-lib/components/ui/Calendar.js.map +1 -0
- package/dist-lib/components/ui/Card.d.ts +1 -1
- package/dist-lib/components/ui/Card.js +116 -0
- package/dist-lib/components/ui/Card.js.map +1 -0
- package/dist-lib/components/ui/Carousel.d.ts +5 -1
- package/dist-lib/components/ui/Carousel.js +143 -0
- package/dist-lib/components/ui/Carousel.js.map +1 -0
- package/dist-lib/components/ui/Chart.d.ts +26 -4
- package/dist-lib/components/ui/Chart.js +253 -0
- package/dist-lib/components/ui/Chart.js.map +1 -0
- package/dist-lib/components/ui/Checkbox.js +56 -0
- package/dist-lib/components/ui/Checkbox.js.map +1 -0
- package/dist-lib/components/ui/Combobox.d.ts +7 -0
- package/dist-lib/components/ui/Combobox.js +164 -0
- package/dist-lib/components/ui/Combobox.js.map +1 -0
- package/dist-lib/components/ui/CommandPalette.d.ts +3 -3
- package/dist-lib/components/ui/CommandPalette.js +174 -0
- package/dist-lib/components/ui/CommandPalette.js.map +1 -0
- package/dist-lib/components/ui/ContextMenu.js +150 -0
- package/dist-lib/components/ui/ContextMenu.js.map +1 -0
- package/dist-lib/components/ui/DataGrid.js +84 -0
- package/dist-lib/components/ui/DataGrid.js.map +1 -0
- package/dist-lib/components/ui/DatePicker.d.ts +16 -13
- package/dist-lib/components/ui/DatePicker.js +174 -0
- package/dist-lib/components/ui/DatePicker.js.map +1 -0
- package/dist-lib/components/ui/DesignSystemProvider.d.ts +8 -1
- package/dist-lib/components/ui/DesignSystemProvider.js +79 -0
- package/dist-lib/components/ui/DesignSystemProvider.js.map +1 -0
- package/dist-lib/components/ui/Dialog.d.ts +1 -1
- package/dist-lib/components/ui/Dialog.js +140 -0
- package/dist-lib/components/ui/Dialog.js.map +1 -0
- package/dist-lib/components/ui/Drawer.d.ts +6 -0
- package/dist-lib/components/ui/Drawer.js +98 -0
- package/dist-lib/components/ui/Drawer.js.map +1 -0
- package/dist-lib/components/ui/DropdownMenu.js +164 -0
- package/dist-lib/components/ui/DropdownMenu.js.map +1 -0
- package/dist-lib/components/ui/EmptyState.js +32 -0
- package/dist-lib/components/ui/EmptyState.js.map +1 -0
- package/dist-lib/components/ui/ErrorState.js +48 -0
- package/dist-lib/components/ui/ErrorState.js.map +1 -0
- package/dist-lib/components/ui/FileUpload.d.ts +3 -0
- package/dist-lib/components/ui/FileUpload.js +108 -0
- package/dist-lib/components/ui/FileUpload.js.map +1 -0
- package/dist-lib/components/ui/Form.d.ts +1 -0
- package/dist-lib/components/ui/Form.js +105 -0
- package/dist-lib/components/ui/Form.js.map +1 -0
- package/dist-lib/components/ui/Icon.js +26 -0
- package/dist-lib/components/ui/Icon.js.map +1 -0
- package/dist-lib/components/ui/IconButton.d.ts +1 -1
- package/dist-lib/components/ui/IconButton.js +56 -0
- package/dist-lib/components/ui/IconButton.js.map +1 -0
- package/dist-lib/components/ui/Input.d.ts +6 -3
- package/dist-lib/components/ui/Input.js +135 -0
- package/dist-lib/components/ui/Input.js.map +1 -0
- package/dist-lib/components/ui/Kbd.js +24 -0
- package/dist-lib/components/ui/Kbd.js.map +1 -0
- package/dist-lib/components/ui/MultiSelect.d.ts +3 -1
- package/dist-lib/components/ui/MultiSelect.js +196 -0
- package/dist-lib/components/ui/MultiSelect.js.map +1 -0
- package/dist-lib/components/ui/Pagination.d.ts +23 -0
- package/dist-lib/components/ui/Pagination.js +148 -0
- package/dist-lib/components/ui/Pagination.js.map +1 -0
- package/dist-lib/components/ui/Popover.js +35 -0
- package/dist-lib/components/ui/Popover.js.map +1 -0
- package/dist-lib/components/ui/Progress.js +95 -0
- package/dist-lib/components/ui/Progress.js.map +1 -0
- package/dist-lib/components/ui/RadioGroup.js +64 -0
- package/dist-lib/components/ui/RadioGroup.js.map +1 -0
- package/dist-lib/components/ui/ScrollArea.js +44 -0
- package/dist-lib/components/ui/ScrollArea.js.map +1 -0
- package/dist-lib/components/ui/Select.js +131 -0
- package/dist-lib/components/ui/Select.js.map +1 -0
- package/dist-lib/components/ui/Separator.js +26 -0
- package/dist-lib/components/ui/Separator.js.map +1 -0
- package/dist-lib/components/ui/Sheet.d.ts +1 -1
- package/dist-lib/components/ui/Sheet.js +113 -0
- package/dist-lib/components/ui/Sheet.js.map +1 -0
- package/dist-lib/components/ui/Sidebar.d.ts +18 -6
- package/dist-lib/components/ui/Sidebar.js +169 -0
- package/dist-lib/components/ui/Sidebar.js.map +1 -0
- package/dist-lib/components/ui/Skeleton.js +28 -0
- package/dist-lib/components/ui/Skeleton.js.map +1 -0
- package/dist-lib/components/ui/Slider.js +52 -0
- package/dist-lib/components/ui/Slider.js.map +1 -0
- package/dist-lib/components/ui/Snackbar.d.ts +1 -1
- package/dist-lib/components/ui/Snackbar.js +56 -0
- package/dist-lib/components/ui/Snackbar.js.map +1 -0
- package/dist-lib/components/ui/Spinner.js +42 -0
- package/dist-lib/components/ui/Spinner.js.map +1 -0
- package/dist-lib/components/ui/Stepper.js +88 -0
- package/dist-lib/components/ui/Stepper.js.map +1 -0
- package/dist-lib/components/ui/Switch.js +77 -0
- package/dist-lib/components/ui/Switch.js.map +1 -0
- package/dist-lib/components/ui/Table.d.ts +9 -1
- package/dist-lib/components/ui/Table.js +157 -0
- package/dist-lib/components/ui/Table.js.map +1 -0
- package/dist-lib/components/ui/Tabs.d.ts +1 -1
- package/dist-lib/components/ui/Tabs.js +89 -0
- package/dist-lib/components/ui/Tabs.js.map +1 -0
- package/dist-lib/components/ui/TagInput.d.ts +17 -2
- package/dist-lib/components/ui/TagInput.js +111 -0
- package/dist-lib/components/ui/TagInput.js.map +1 -0
- package/dist-lib/components/ui/Textarea.js +77 -0
- package/dist-lib/components/ui/Textarea.js.map +1 -0
- package/dist-lib/components/ui/Timeline.d.ts +16 -6
- package/dist-lib/components/ui/Timeline.js +52 -0
- package/dist-lib/components/ui/Timeline.js.map +1 -0
- package/dist-lib/components/ui/Toast.d.ts +1 -1
- package/dist-lib/components/ui/Toast.js +171 -0
- package/dist-lib/components/ui/Toast.js.map +1 -0
- package/dist-lib/components/ui/Tooltip.js +58 -0
- package/dist-lib/components/ui/Tooltip.js.map +1 -0
- package/dist-lib/components/ui/TopNav.js +52 -0
- package/dist-lib/components/ui/TopNav.js.map +1 -0
- package/dist-lib/components/ui/Tree.d.ts +27 -5
- package/dist-lib/components/ui/Tree.js +167 -0
- package/dist-lib/components/ui/Tree.js.map +1 -0
- package/dist-lib/hooks/use-field-ids.d.ts +29 -0
- package/dist-lib/hooks/use-field-ids.js +18 -0
- package/dist-lib/hooks/use-field-ids.js.map +1 -0
- package/dist-lib/hooks/use-media-query.js +18 -0
- package/dist-lib/hooks/use-media-query.js.map +1 -0
- package/dist-lib/hooks/use-strings.d.ts +5 -0
- package/dist-lib/hooks/use-strings.js +12 -0
- package/dist-lib/hooks/use-strings.js.map +1 -0
- package/dist-lib/hooks/use-toast.js +36 -0
- package/dist-lib/hooks/use-toast.js.map +1 -0
- package/dist-lib/icon.d.ts +8 -0
- package/dist-lib/icon.js +7 -0
- package/dist-lib/icon.js.map +1 -0
- package/dist-lib/icons/index.d.ts +71 -88
- package/dist-lib/icons/index.js +145 -0
- package/dist-lib/icons/index.js.map +1 -0
- package/dist-lib/illustrations/index.js +105 -0
- package/dist-lib/illustrations/index.js.map +1 -0
- package/dist-lib/index.d.ts +62 -59
- package/dist-lib/index.js +267 -4529
- package/dist-lib/index.js.map +1 -1
- package/dist-lib/lib/strings.d.ts +129 -0
- package/dist-lib/lib/strings.js +85 -0
- package/dist-lib/lib/strings.js.map +1 -0
- package/dist-lib/lib/strings.mn.d.ts +3 -0
- package/dist-lib/lib/strings.mn.js +70 -0
- package/dist-lib/lib/strings.mn.js.map +1 -0
- package/dist-lib/lib/utils.d.ts +0 -1
- package/dist-lib/lib/utils.js +10 -0
- package/dist-lib/lib/utils.js.map +1 -0
- package/dist-lib/styles.css +1 -1
- package/dist-lib/theme.css +777 -0
- package/package.json +31 -8
- package/dist-lib/index.cjs +0 -8
- package/dist-lib/index.cjs.map +0 -1
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as s, jsxs as l } from "react/jsx-runtime";
|
|
3
|
+
import { forwardRef as f } from "react";
|
|
4
|
+
import { Slot as p } from "@radix-ui/react-slot";
|
|
5
|
+
import { Loader2 as x } from "../../icons/index.js";
|
|
6
|
+
import { cn as h } from "../../lib/utils.js";
|
|
7
|
+
import { cva as k } from "class-variance-authority";
|
|
8
|
+
const z = k(
|
|
9
|
+
[
|
|
10
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap",
|
|
11
|
+
"rounded-md text-sm font-medium",
|
|
12
|
+
"transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]",
|
|
13
|
+
"outline-none",
|
|
14
|
+
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
15
|
+
"focus-visible:ring-offset-background",
|
|
16
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
17
|
+
"[&_svg]:pointer-events-none [&_svg]:shrink-0"
|
|
18
|
+
],
|
|
19
|
+
{
|
|
20
|
+
variants: {
|
|
21
|
+
variant: {
|
|
22
|
+
primary: [
|
|
23
|
+
"bg-accent text-on-accent",
|
|
24
|
+
"hover:bg-accent-hover",
|
|
25
|
+
"active:bg-accent-active"
|
|
26
|
+
],
|
|
27
|
+
secondary: [
|
|
28
|
+
"bg-background-muted text-foreground border border-border",
|
|
29
|
+
"hover:bg-surface-hover",
|
|
30
|
+
"active:bg-surface-active"
|
|
31
|
+
],
|
|
32
|
+
outline: [
|
|
33
|
+
"border border-border bg-transparent text-foreground",
|
|
34
|
+
"hover:bg-background-muted",
|
|
35
|
+
"active:bg-background-subtle"
|
|
36
|
+
],
|
|
37
|
+
ghost: [
|
|
38
|
+
"bg-transparent text-foreground",
|
|
39
|
+
"hover:bg-background-muted",
|
|
40
|
+
"active:bg-background-subtle"
|
|
41
|
+
],
|
|
42
|
+
destructive: [
|
|
43
|
+
"bg-danger text-on-danger",
|
|
44
|
+
"hover:bg-danger-hover",
|
|
45
|
+
"active:bg-danger-active"
|
|
46
|
+
],
|
|
47
|
+
link: [
|
|
48
|
+
"bg-transparent text-accent underline-offset-4 px-0",
|
|
49
|
+
"hover:underline",
|
|
50
|
+
"active:text-accent-hover"
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
size: {
|
|
54
|
+
sm: "h-8 px-3 text-xs [&_svg]:size-4",
|
|
55
|
+
md: "h-9 px-3.5 text-sm [&_svg]:size-4",
|
|
56
|
+
lg: "h-10 px-4 text-sm [&_svg]:size-5",
|
|
57
|
+
icon: "h-9 w-9 [&_svg]:size-4"
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
compoundVariants: [
|
|
61
|
+
// The `link` variant ignores horizontal padding from the size variant.
|
|
62
|
+
{ variant: "link", size: "sm", class: "h-auto px-0" },
|
|
63
|
+
{ variant: "link", size: "md", class: "h-auto px-0" },
|
|
64
|
+
{ variant: "link", size: "lg", class: "h-auto px-0" }
|
|
65
|
+
],
|
|
66
|
+
defaultVariants: {
|
|
67
|
+
variant: "primary",
|
|
68
|
+
size: "md"
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
), y = f(function({
|
|
72
|
+
className: o,
|
|
73
|
+
variant: i,
|
|
74
|
+
size: c,
|
|
75
|
+
asChild: d = !1,
|
|
76
|
+
loading: e = !1,
|
|
77
|
+
leadingIcon: u,
|
|
78
|
+
trailingIcon: v,
|
|
79
|
+
disabled: b,
|
|
80
|
+
children: t,
|
|
81
|
+
type: g = "button",
|
|
82
|
+
...r
|
|
83
|
+
}, a) {
|
|
84
|
+
const m = b || e, n = h(z({ variant: i, size: c }), o);
|
|
85
|
+
return d ? /* @__PURE__ */ s(
|
|
86
|
+
p,
|
|
87
|
+
{
|
|
88
|
+
ref: a,
|
|
89
|
+
"aria-busy": e || void 0,
|
|
90
|
+
"data-loading": e || void 0,
|
|
91
|
+
className: n,
|
|
92
|
+
...r,
|
|
93
|
+
children: t
|
|
94
|
+
}
|
|
95
|
+
) : /* @__PURE__ */ l(
|
|
96
|
+
"button",
|
|
97
|
+
{
|
|
98
|
+
ref: a,
|
|
99
|
+
type: g,
|
|
100
|
+
"aria-busy": e || void 0,
|
|
101
|
+
disabled: m,
|
|
102
|
+
"data-loading": e || void 0,
|
|
103
|
+
className: n,
|
|
104
|
+
...r,
|
|
105
|
+
children: [
|
|
106
|
+
e ? /* @__PURE__ */ s(x, { className: "animate-spin", "aria-hidden": "true" }) : u,
|
|
107
|
+
t,
|
|
108
|
+
!e && v
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
);
|
|
112
|
+
});
|
|
113
|
+
y.displayName = "Button";
|
|
114
|
+
export {
|
|
115
|
+
y as Button
|
|
116
|
+
};
|
|
117
|
+
//# sourceMappingURL=Button.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Button.js","sources":["../../../src/components/ui/Button.tsx"],"sourcesContent":["'use client';\n\nimport { forwardRef, type ButtonHTMLAttributes, type ReactNode } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { Loader2 } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { cva, type VariantProps } from '@/lib/cva';\n\n/* -----------------------------------------------------------------------------\n * Variants — the entire visual surface of the Button.\n *\n * All sizes share the same border radius (md = 6px) per the refined-minimal\n * rules. Focus state is the standardised 2px-ring + 2px-offset on every\n * variant, including `link`.\n * --------------------------------------------------------------------------- */\nconst button = cva(\n [\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap',\n 'rounded-md text-sm font-medium',\n 'transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]',\n 'outline-none',\n 'focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n 'focus-visible:ring-offset-background',\n 'disabled:pointer-events-none disabled:opacity-50',\n '[&_svg]:pointer-events-none [&_svg]:shrink-0',\n ],\n {\n variants: {\n variant: {\n primary: [\n 'bg-accent text-on-accent',\n 'hover:bg-accent-hover',\n 'active:bg-accent-active',\n ],\n secondary: [\n 'bg-background-muted text-foreground border border-border',\n 'hover:bg-surface-hover',\n 'active:bg-surface-active',\n ],\n outline: [\n 'border border-border bg-transparent text-foreground',\n 'hover:bg-background-muted',\n 'active:bg-background-subtle',\n ],\n ghost: [\n 'bg-transparent text-foreground',\n 'hover:bg-background-muted',\n 'active:bg-background-subtle',\n ],\n destructive: [\n 'bg-danger text-on-danger',\n 'hover:bg-danger-hover',\n 'active:bg-danger-active',\n ],\n link: [\n 'bg-transparent text-accent underline-offset-4 px-0',\n 'hover:underline',\n 'active:text-accent-hover',\n ],\n },\n size: {\n sm: 'h-8 px-3 text-xs [&_svg]:size-4',\n md: 'h-9 px-3.5 text-sm [&_svg]:size-4',\n lg: 'h-10 px-4 text-sm [&_svg]:size-5',\n icon: 'h-9 w-9 [&_svg]:size-4',\n },\n },\n compoundVariants: [\n // The `link` variant ignores horizontal padding from the size variant.\n { variant: 'link', size: 'sm', class: 'h-auto px-0' },\n { variant: 'link', size: 'md', class: 'h-auto px-0' },\n { variant: 'link', size: 'lg', class: 'h-auto px-0' },\n ],\n defaultVariants: {\n variant: 'primary',\n size: 'md',\n },\n },\n);\n\nexport interface ButtonProps\n extends ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof button> {\n /**\n * Render as a different element via Radix Slot. Useful when wrapping a\n * link: `<Button asChild><a href=\"…\">…</a></Button>`.\n * @default false\n */\n asChild?: boolean;\n /**\n * Show a spinner in place of the leading icon and disable the button.\n * Use for async actions where the user must wait.\n * @default false\n */\n loading?: boolean;\n /** Icon rendered before the label. Replaced by a spinner when loading. */\n leadingIcon?: ReactNode;\n /** Icon rendered after the label. Hidden while loading. */\n trailingIcon?: ReactNode;\n}\n\n/**\n * Primary interactive element. Variants:\n *\n * - `primary` — accent fill, the single most prominent action on a screen.\n * - `secondary` — neutral fill, sits next to a primary or stands alone for\n * secondary actions.\n * - `outline` — border only, transparent fill. Use when next to a primary.\n * - `ghost` — no border, hover background. Use in dense toolbars and tables.\n * - `destructive` — danger fill, reserved for irreversible actions.\n * - `link` — text styled as a link.\n *\n * @example Two-button row\n * <div className=\"flex gap-2 justify-end\">\n * <Button variant=\"outline\">Cancel</Button>\n * <Button>Save changes</Button>\n * </div>\n *\n * @example Loading state\n * <Button loading leadingIcon={<Mail />}>Sending…</Button>\n *\n * @do Use one primary button per major surface. Verb-first labels.\n * @dont Stack three primary buttons in a row — only the most important\n * action gets the primary variant.\n */\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(\n {\n className,\n variant,\n size,\n asChild = false,\n loading = false,\n leadingIcon,\n trailingIcon,\n disabled,\n children,\n type = 'button',\n ...props\n },\n ref,\n) {\n const isDisabled = disabled || loading;\n const classes = cn(button({ variant, size }), className);\n\n if (asChild) {\n // Slot requires exactly one element child — pass the consumer's element\n // through untouched. The consumer is responsible for any leading/trailing\n // icons inside that element.\n return (\n <Slot\n ref={ref}\n aria-busy={loading || undefined}\n data-loading={loading || undefined}\n className={classes}\n {...props}\n >\n {children}\n </Slot>\n );\n }\n\n return (\n <button\n ref={ref}\n type={type}\n aria-busy={loading || undefined}\n disabled={isDisabled}\n data-loading={loading || undefined}\n className={classes}\n {...props}\n >\n {loading ? (\n <Loader2 className=\"animate-spin\" aria-hidden=\"true\" />\n ) : (\n leadingIcon\n )}\n {children}\n {!loading && trailingIcon}\n </button>\n );\n});\n\nButton.displayName = 'Button';\n"],"names":["button","cva","Button","forwardRef","className","variant","size","asChild","loading","leadingIcon","trailingIcon","disabled","children","type","props","ref","isDisabled","classes","cn","jsx","Slot","jsxs","Loader2"],"mappings":";;;;;;;AAeA,MAAMA,IAASC;AAAA,EACb;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAAA,EAEF;AAAA,IACE,UAAU;AAAA,MACR,SAAS;AAAA,QACP,SAAS;AAAA,UACP;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,SAAS;AAAA,UACP;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,OAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,aAAa;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,QAEF,MAAM;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,MACF;AAAA,MAEF,MAAM;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,MAAM;AAAA,MAAA;AAAA,IACR;AAAA,IAEF,kBAAkB;AAAA;AAAA,MAEhB,EAAE,SAAS,QAAQ,MAAM,MAAM,OAAO,cAAA;AAAA,MACtC,EAAE,SAAS,QAAQ,MAAM,MAAM,OAAO,cAAA;AAAA,MACtC,EAAE,SAAS,QAAQ,MAAM,MAAM,OAAO,cAAA;AAAA,IAAc;AAAA,IAEtD,iBAAiB;AAAA,MACf,SAAS;AAAA,MACT,MAAM;AAAA,IAAA;AAAA,EACR;AAEJ,GA+CaC,IAASC,EAA2C,SAC/D;AAAA,EACE,WAAAC;AAAA,EACA,SAAAC;AAAA,EACA,MAAAC;AAAA,EACA,SAAAC,IAAU;AAAA,EACV,SAAAC,IAAU;AAAA,EACV,aAAAC;AAAA,EACA,cAAAC;AAAA,EACA,UAAAC;AAAA,EACA,UAAAC;AAAA,EACA,MAAAC,IAAO;AAAA,EACP,GAAGC;AACL,GACAC,GACA;AACA,QAAMC,IAAaL,KAAYH,GACzBS,IAAUC,EAAGlB,EAAO,EAAE,SAAAK,GAAS,MAAAC,EAAA,CAAM,GAAGF,CAAS;AAEvD,SAAIG,IAKA,gBAAAY;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,KAAAL;AAAA,MACA,aAAWP,KAAW;AAAA,MACtB,gBAAcA,KAAW;AAAA,MACzB,WAAWS;AAAA,MACV,GAAGH;AAAA,MAEH,UAAAF;AAAA,IAAA;AAAA,EAAA,IAML,gBAAAS;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,KAAAN;AAAA,MACA,MAAAF;AAAA,MACA,aAAWL,KAAW;AAAA,MACtB,UAAUQ;AAAA,MACV,gBAAcR,KAAW;AAAA,MACzB,WAAWS;AAAA,MACV,GAAGH;AAAA,MAEH,UAAA;AAAA,QAAAN,sBACEc,GAAA,EAAQ,WAAU,gBAAe,eAAY,QAAO,IAErDb;AAAA,QAEDG;AAAA,QACA,CAACJ,KAAWE;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGnB,CAAC;AAEDR,EAAO,cAAc;"}
|
|
@@ -5,5 +5,11 @@ export type CalendarProps = DayPickerProps & {
|
|
|
5
5
|
/**
|
|
6
6
|
* Standalone calendar surface. Used by DatePicker, but can also be embedded
|
|
7
7
|
* directly in popovers, sheets, or inline forms. Wraps `react-day-picker` v9.
|
|
8
|
+
*
|
|
9
|
+
* Not a forwardRef: RDP v9's `DayPicker` is a plain function component and
|
|
10
|
+
* exposes no root ref, so a forwarded ref would silently be dropped.
|
|
8
11
|
*/
|
|
9
|
-
export declare
|
|
12
|
+
export declare function Calendar({ className, classNames, captionLayout, startMonth, endMonth, ...props }: CalendarProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export declare namespace Calendar {
|
|
14
|
+
var displayName: string;
|
|
15
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as t, jsxs as c } from "react/jsx-runtime";
|
|
3
|
+
import { useMemo as g } from "react";
|
|
4
|
+
import { DayPicker as f } from "react-day-picker";
|
|
5
|
+
import * as l from "@radix-ui/react-select";
|
|
6
|
+
import { ChevronLeft as p, ChevronRight as v, ChevronDown as u } from "../../icons/index.js";
|
|
7
|
+
/* empty css */
|
|
8
|
+
import { Select as x, SelectContent as h, SelectItem as w } from "./Select.js";
|
|
9
|
+
import { cn as b } from "../../lib/utils.js";
|
|
10
|
+
function y({
|
|
11
|
+
options: d = [],
|
|
12
|
+
value: n,
|
|
13
|
+
onChange: r,
|
|
14
|
+
disabled: a,
|
|
15
|
+
"aria-label": s
|
|
16
|
+
}) {
|
|
17
|
+
const o = d.find((e) => e.value === Number(n));
|
|
18
|
+
return /* @__PURE__ */ c(
|
|
19
|
+
x,
|
|
20
|
+
{
|
|
21
|
+
value: n === void 0 ? void 0 : String(n),
|
|
22
|
+
onValueChange: (e) => {
|
|
23
|
+
r == null || r({ target: { value: e } });
|
|
24
|
+
},
|
|
25
|
+
disabled: a,
|
|
26
|
+
children: [
|
|
27
|
+
/* @__PURE__ */ c(
|
|
28
|
+
l.Trigger,
|
|
29
|
+
{
|
|
30
|
+
"aria-label": s,
|
|
31
|
+
className: b(
|
|
32
|
+
"border-border bg-card text-foreground inline-flex h-7 items-center gap-1 rounded-md border px-2 text-sm font-medium",
|
|
33
|
+
"hover:bg-background-muted focus-visible:ring-ring outline-none focus-visible:ring-2",
|
|
34
|
+
"disabled:pointer-events-none disabled:opacity-50"
|
|
35
|
+
),
|
|
36
|
+
children: [
|
|
37
|
+
/* @__PURE__ */ t(l.Value, { children: o == null ? void 0 : o.label }),
|
|
38
|
+
/* @__PURE__ */ t(l.Icon, { asChild: !0, children: /* @__PURE__ */ t(u, { className: "size-3.5 opacity-60", "aria-hidden": !0 }) })
|
|
39
|
+
]
|
|
40
|
+
}
|
|
41
|
+
),
|
|
42
|
+
/* @__PURE__ */ t(h, { className: "max-h-64", children: d.map((e) => /* @__PURE__ */ t(w, { value: String(e.value), disabled: e.disabled, children: e.label }, e.value)) })
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
function _({
|
|
48
|
+
className: d,
|
|
49
|
+
classNames: n,
|
|
50
|
+
captionLayout: r = "dropdown",
|
|
51
|
+
startMonth: a,
|
|
52
|
+
endMonth: s,
|
|
53
|
+
...o
|
|
54
|
+
}) {
|
|
55
|
+
const { start: e, end: m } = g(() => {
|
|
56
|
+
const i = /* @__PURE__ */ new Date();
|
|
57
|
+
return {
|
|
58
|
+
start: a ?? new Date(i.getFullYear() - 100, 0, 1),
|
|
59
|
+
end: s ?? new Date(i.getFullYear() + 10, 11, 31)
|
|
60
|
+
};
|
|
61
|
+
}, [a, s]);
|
|
62
|
+
return /* @__PURE__ */ t(
|
|
63
|
+
f,
|
|
64
|
+
{
|
|
65
|
+
showOutsideDays: !0,
|
|
66
|
+
captionLayout: r,
|
|
67
|
+
startMonth: e,
|
|
68
|
+
endMonth: m,
|
|
69
|
+
className: b("border-border bg-card inline-block rounded-lg border p-3", d),
|
|
70
|
+
classNames: {
|
|
71
|
+
root: "rdp",
|
|
72
|
+
months: "relative flex flex-col gap-4 sm:flex-row sm:gap-6",
|
|
73
|
+
month: "flex flex-col gap-3",
|
|
74
|
+
month_caption: "relative flex h-8 items-center justify-center px-8",
|
|
75
|
+
dropdowns: "flex items-center justify-center gap-2",
|
|
76
|
+
caption_label: "flex items-center gap-1 text-sm font-medium",
|
|
77
|
+
// The caption is positioned and painted after the nav, so the nav must
|
|
78
|
+
// sit above it (z-10) for its buttons to receive clicks. The container
|
|
79
|
+
// itself ignores pointer events so the centred dropdowns underneath
|
|
80
|
+
// stay clickable — only the buttons opt back in.
|
|
81
|
+
nav: "pointer-events-none absolute inset-x-0 top-0 z-10 flex h-8 items-center justify-between",
|
|
82
|
+
button_previous: "pointer-events-auto inline-flex h-7 w-7 items-center justify-center rounded-md text-foreground-muted hover:bg-background-muted focus-visible:ring-2 focus-visible:ring-ring outline-none disabled:opacity-40 disabled:pointer-events-none",
|
|
83
|
+
button_next: "pointer-events-auto inline-flex h-7 w-7 items-center justify-center rounded-md text-foreground-muted hover:bg-background-muted focus-visible:ring-2 focus-visible:ring-ring outline-none disabled:opacity-40 disabled:pointer-events-none",
|
|
84
|
+
month_grid: "w-full border-collapse",
|
|
85
|
+
weekdays: "grid grid-cols-7",
|
|
86
|
+
weekday: "h-8 w-9 text-center text-[11px] font-medium uppercase tracking-wide text-foreground-subtle",
|
|
87
|
+
week: "mt-0.5 grid grid-cols-7",
|
|
88
|
+
day: "relative h-9 w-9 p-0 text-center",
|
|
89
|
+
day_button: "inline-flex h-9 w-9 items-center justify-center rounded-md text-sm hover:bg-background-muted focus-visible:ring-2 focus-visible:ring-ring outline-none aria-selected:bg-accent aria-selected:text-on-accent aria-selected:hover:bg-accent-700",
|
|
90
|
+
today: "[&_button]:border [&_button]:border-border",
|
|
91
|
+
outside: "text-foreground-subtle",
|
|
92
|
+
disabled: "opacity-40 pointer-events-none",
|
|
93
|
+
range_start: "[&_button]:bg-accent [&_button]:text-on-accent [&_button]:rounded-r-none",
|
|
94
|
+
range_end: "[&_button]:bg-accent [&_button]:text-on-accent [&_button]:rounded-l-none",
|
|
95
|
+
range_middle: "[&_button]:bg-accent-soft [&_button]:text-foreground [&_button]:rounded-none",
|
|
96
|
+
hidden: "invisible",
|
|
97
|
+
...n
|
|
98
|
+
},
|
|
99
|
+
components: {
|
|
100
|
+
Dropdown: y,
|
|
101
|
+
Chevron: ({ orientation: i }) => i === "left" ? /* @__PURE__ */ t(p, { className: "size-4" }) : i === "right" ? /* @__PURE__ */ t(v, { className: "size-4" }) : /* @__PURE__ */ t(u, { className: "size-3.5 opacity-60" })
|
|
102
|
+
},
|
|
103
|
+
...o
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
_.displayName = "Calendar";
|
|
108
|
+
export {
|
|
109
|
+
_ as Calendar
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=Calendar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Calendar.js","sources":["../../../src/components/ui/Calendar.tsx"],"sourcesContent":["'use client';\n\nimport { useMemo, type ChangeEvent } from 'react';\nimport { DayPicker, type DayPickerProps, type DropdownProps } from 'react-day-picker';\nimport * as SelectPrimitive from '@radix-ui/react-select';\nimport { ChevronDown, ChevronLeft, ChevronRight } from '@/icons';\nimport 'react-day-picker/style.css';\nimport { Select, SelectContent, SelectItem } from './Select';\nimport { cn } from '@/lib/utils';\n\nexport type CalendarProps = DayPickerProps & { className?: string };\n\n/**\n * Month / year dropdown rendered with the design-system Select instead of a\n * native `<select>` — the native popup is unbounded (a century of years fills\n * the screen on macOS) and can't be styled. Radix gives us a max-height,\n * internal scrolling, and auto-scroll to the selected year.\n */\nfunction CalendarDropdown({\n options = [],\n value,\n onChange,\n disabled,\n 'aria-label': ariaLabel,\n}: DropdownProps) {\n const selected = options.find((opt) => opt.value === Number(value));\n\n return (\n <Select\n value={value === undefined ? undefined : String(value)}\n onValueChange={(v) => {\n // RDP's handler expects a native select change event — fake the shape.\n onChange?.({ target: { value: v } } as unknown as ChangeEvent<HTMLSelectElement>);\n }}\n disabled={disabled}\n >\n <SelectPrimitive.Trigger\n aria-label={ariaLabel}\n className={cn(\n 'border-border bg-card text-foreground inline-flex h-7 items-center gap-1 rounded-md border px-2 text-sm font-medium',\n 'hover:bg-background-muted focus-visible:ring-ring outline-none focus-visible:ring-2',\n 'disabled:pointer-events-none disabled:opacity-50',\n )}\n >\n <SelectPrimitive.Value>{selected?.label}</SelectPrimitive.Value>\n <SelectPrimitive.Icon asChild>\n <ChevronDown className=\"size-3.5 opacity-60\" aria-hidden />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n <SelectContent className=\"max-h-64\">\n {options.map((opt) => (\n <SelectItem key={opt.value} value={String(opt.value)} disabled={opt.disabled}>\n {opt.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n}\n\n/**\n * Standalone calendar surface. Used by DatePicker, but can also be embedded\n * directly in popovers, sheets, or inline forms. Wraps `react-day-picker` v9.\n *\n * Not a forwardRef: RDP v9's `DayPicker` is a plain function component and\n * exposes no root ref, so a forwarded ref would silently be dropped.\n */\nexport function Calendar({\n className,\n classNames,\n captionLayout = 'dropdown',\n startMonth,\n endMonth,\n ...props\n}: CalendarProps) {\n // Bound the month/year dropdowns. Consumers can narrow this with\n // startMonth / endMonth; the default spans a century back to a decade ahead\n // so the year dropdown is useful for both birthdays and future scheduling.\n // Memoised — fresh Date identities every render defeat RDP's internal\n // memoisation and re-derive the navigable range on each paint.\n const { start, end } = useMemo(() => {\n const now = new Date();\n return {\n start: startMonth ?? new Date(now.getFullYear() - 100, 0, 1),\n end: endMonth ?? new Date(now.getFullYear() + 10, 11, 31),\n };\n }, [startMonth, endMonth]);\n\n return (\n <DayPicker\n showOutsideDays\n captionLayout={captionLayout}\n startMonth={start}\n endMonth={end}\n className={cn('border-border bg-card inline-block rounded-lg border p-3', className)}\n classNames={{\n root: 'rdp',\n months: 'relative flex flex-col gap-4 sm:flex-row sm:gap-6',\n month: 'flex flex-col gap-3',\n month_caption: 'relative flex h-8 items-center justify-center px-8',\n dropdowns: 'flex items-center justify-center gap-2',\n caption_label: 'flex items-center gap-1 text-sm font-medium',\n // The caption is positioned and painted after the nav, so the nav must\n // sit above it (z-10) for its buttons to receive clicks. The container\n // itself ignores pointer events so the centred dropdowns underneath\n // stay clickable — only the buttons opt back in.\n nav: 'pointer-events-none absolute inset-x-0 top-0 z-10 flex h-8 items-center justify-between',\n button_previous:\n 'pointer-events-auto inline-flex h-7 w-7 items-center justify-center rounded-md text-foreground-muted hover:bg-background-muted focus-visible:ring-2 focus-visible:ring-ring outline-none disabled:opacity-40 disabled:pointer-events-none',\n button_next:\n 'pointer-events-auto inline-flex h-7 w-7 items-center justify-center rounded-md text-foreground-muted hover:bg-background-muted focus-visible:ring-2 focus-visible:ring-ring outline-none disabled:opacity-40 disabled:pointer-events-none',\n month_grid: 'w-full border-collapse',\n weekdays: 'grid grid-cols-7',\n weekday:\n 'h-8 w-9 text-center text-[11px] font-medium uppercase tracking-wide text-foreground-subtle',\n week: 'mt-0.5 grid grid-cols-7',\n day: 'relative h-9 w-9 p-0 text-center',\n day_button:\n 'inline-flex h-9 w-9 items-center justify-center rounded-md text-sm hover:bg-background-muted focus-visible:ring-2 focus-visible:ring-ring outline-none aria-selected:bg-accent aria-selected:text-on-accent aria-selected:hover:bg-accent-700',\n today: '[&_button]:border [&_button]:border-border',\n outside: 'text-foreground-subtle',\n disabled: 'opacity-40 pointer-events-none',\n range_start: '[&_button]:bg-accent [&_button]:text-on-accent [&_button]:rounded-r-none',\n range_end: '[&_button]:bg-accent [&_button]:text-on-accent [&_button]:rounded-l-none',\n range_middle:\n '[&_button]:bg-accent-soft [&_button]:text-foreground [&_button]:rounded-none',\n hidden: 'invisible',\n ...classNames,\n }}\n components={{\n Dropdown: CalendarDropdown,\n Chevron: ({ orientation }) => {\n if (orientation === 'left') return <ChevronLeft className=\"size-4\" />;\n if (orientation === 'right') return <ChevronRight className=\"size-4\" />;\n // up/down — used for the month/year dropdown carets\n return <ChevronDown className=\"size-3.5 opacity-60\" />;\n },\n }}\n {...props}\n />\n );\n}\nCalendar.displayName = 'Calendar';\n"],"names":["CalendarDropdown","options","value","onChange","disabled","ariaLabel","selected","opt","jsxs","Select","v","SelectPrimitive","cn","jsx","ChevronDown","SelectContent","SelectItem","Calendar","className","classNames","captionLayout","startMonth","endMonth","props","start","end","useMemo","now","DayPicker","orientation","ChevronLeft","ChevronRight"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HTMLAttributes } from 'react';
|
|
2
|
-
import { VariantProps } from '../../lib/cva';
|
|
2
|
+
import { VariantProps } from '../../lib/cva.js';
|
|
3
3
|
declare const card: (props?: ({
|
|
4
4
|
variant?: "default" | "interactive" | null | undefined;
|
|
5
5
|
padding?: "none" | "md" | "sm" | "lg" | null | undefined;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as d } from "react/jsx-runtime";
|
|
3
|
+
import { forwardRef as n } from "react";
|
|
4
|
+
import { cn as i } from "../../lib/utils.js";
|
|
5
|
+
import { cva as g } from "class-variance-authority";
|
|
6
|
+
const b = g(
|
|
7
|
+
[
|
|
8
|
+
"rounded-lg border bg-card text-card-foreground",
|
|
9
|
+
"transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]"
|
|
10
|
+
],
|
|
11
|
+
{
|
|
12
|
+
variants: {
|
|
13
|
+
variant: {
|
|
14
|
+
default: "border-border",
|
|
15
|
+
interactive: [
|
|
16
|
+
"border-border hover:border-border-strong hover:bg-background-subtle cursor-pointer",
|
|
17
|
+
"outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
18
|
+
"focus-visible:ring-offset-background"
|
|
19
|
+
]
|
|
20
|
+
},
|
|
21
|
+
padding: {
|
|
22
|
+
none: "",
|
|
23
|
+
sm: "p-4",
|
|
24
|
+
md: "p-5",
|
|
25
|
+
lg: "p-6"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
defaultVariants: {
|
|
29
|
+
variant: "default",
|
|
30
|
+
padding: "md"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
), v = n(function({ className: e, variant: r, padding: t, onClick: a, onKeyDown: u, role: c, tabIndex: l, ...m }, p) {
|
|
34
|
+
const f = r === "interactive" && typeof a == "function";
|
|
35
|
+
return /* @__PURE__ */ d(
|
|
36
|
+
"div",
|
|
37
|
+
{
|
|
38
|
+
ref: p,
|
|
39
|
+
role: c ?? (f ? "button" : void 0),
|
|
40
|
+
tabIndex: l ?? (f ? 0 : void 0),
|
|
41
|
+
onClick: a,
|
|
42
|
+
onKeyDown: f || u ? (o) => {
|
|
43
|
+
u == null || u(o), !(o.defaultPrevented || !f) && (o.key === "Enter" || o.key === " ") && (o.preventDefault(), a == null || a(o));
|
|
44
|
+
} : void 0,
|
|
45
|
+
className: i(b({ variant: r, padding: t }), e),
|
|
46
|
+
...m
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
v.displayName = "Card";
|
|
51
|
+
const C = n(
|
|
52
|
+
function({ className: e, ...r }, t) {
|
|
53
|
+
return /* @__PURE__ */ d(
|
|
54
|
+
"div",
|
|
55
|
+
{
|
|
56
|
+
ref: t,
|
|
57
|
+
className: i("flex flex-col gap-1 pb-4", e),
|
|
58
|
+
...r
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
C.displayName = "CardHeader";
|
|
64
|
+
const x = n(
|
|
65
|
+
function({ className: e, children: r, ...t }, a) {
|
|
66
|
+
return /* @__PURE__ */ d(
|
|
67
|
+
"h3",
|
|
68
|
+
{
|
|
69
|
+
ref: a,
|
|
70
|
+
className: i("text-base font-semibold text-foreground leading-tight", e),
|
|
71
|
+
...t,
|
|
72
|
+
children: r
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
x.displayName = "CardTitle";
|
|
78
|
+
const N = n(function({ className: e, ...r }, t) {
|
|
79
|
+
return /* @__PURE__ */ d(
|
|
80
|
+
"p",
|
|
81
|
+
{
|
|
82
|
+
ref: t,
|
|
83
|
+
className: i("text-sm text-foreground-muted", e),
|
|
84
|
+
...r
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
});
|
|
88
|
+
N.displayName = "CardDescription";
|
|
89
|
+
const y = n(
|
|
90
|
+
function({ className: e, ...r }, t) {
|
|
91
|
+
return /* @__PURE__ */ d("div", { ref: t, className: i("text-sm text-foreground", e), ...r });
|
|
92
|
+
}
|
|
93
|
+
);
|
|
94
|
+
y.displayName = "CardContent";
|
|
95
|
+
const h = n(
|
|
96
|
+
function({ className: e, ...r }, t) {
|
|
97
|
+
return /* @__PURE__ */ d(
|
|
98
|
+
"div",
|
|
99
|
+
{
|
|
100
|
+
ref: t,
|
|
101
|
+
className: i("flex items-center gap-2 pt-4", e),
|
|
102
|
+
...r
|
|
103
|
+
}
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
h.displayName = "CardFooter";
|
|
108
|
+
export {
|
|
109
|
+
v as Card,
|
|
110
|
+
y as CardContent,
|
|
111
|
+
N as CardDescription,
|
|
112
|
+
h as CardFooter,
|
|
113
|
+
C as CardHeader,
|
|
114
|
+
x as CardTitle
|
|
115
|
+
};
|
|
116
|
+
//# sourceMappingURL=Card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Card.js","sources":["../../../src/components/ui/Card.tsx"],"sourcesContent":["'use client';\n\nimport { forwardRef, type HTMLAttributes, type KeyboardEvent, type MouseEvent } from 'react';\nimport { cn } from '@/lib/utils';\nimport { cva, type VariantProps } from '@/lib/cva';\n\nconst card = cva(\n [\n 'rounded-lg border bg-card text-card-foreground',\n 'transition-colors duration-[var(--duration-fast)] ease-[var(--ease-out)]',\n ],\n {\n variants: {\n variant: {\n default: 'border-border',\n interactive: [\n 'border-border hover:border-border-strong hover:bg-background-subtle cursor-pointer',\n 'outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n 'focus-visible:ring-offset-background',\n ],\n },\n padding: {\n none: '',\n sm: 'p-4',\n md: 'p-5',\n lg: 'p-6',\n },\n },\n defaultVariants: {\n variant: 'default',\n padding: 'md',\n },\n },\n);\n\nexport interface CardProps\n extends HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof card> {}\n\n/**\n * Bounded surface used to group related content. Per the refined-minimal\n * rules, cards on the page have a hairline border and no shadow.\n *\n * @example Header + content + footer\n * <Card>\n * <CardHeader>\n * <CardTitle>Storage</CardTitle>\n * <CardDescription>Usage across all projects.</CardDescription>\n * </CardHeader>\n * <CardContent>…</CardContent>\n * <CardFooter><Button>Upgrade</Button></CardFooter>\n * </Card>\n *\n * @example Clickable list row\n * <Card variant=\"interactive\" onClick={open}>…</Card>\n *\n * @do Use the `border` style. If a card needs to \"float\" (modal, dropdown),\n * it isn't a Card — it's a Popover/Dialog.\n * @dont Add `shadow-lg` to Cards. Shadows on inline surfaces violate the\n * refined-minimal direction.\n */\nexport const Card = forwardRef<HTMLDivElement, CardProps>(function Card(\n { className, variant, padding, onClick, onKeyDown, role, tabIndex, ...props },\n ref,\n) {\n // An interactive card with a click handler must be reachable and operable\n // from the keyboard: expose it as a button and map Enter/Space to click.\n const isButtonLike = variant === 'interactive' && typeof onClick === 'function';\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n onKeyDown?.(event);\n if (event.defaultPrevented || !isButtonLike) return;\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n onClick?.(event as unknown as MouseEvent<HTMLDivElement>);\n }\n };\n return (\n <div\n ref={ref}\n role={role ?? (isButtonLike ? 'button' : undefined)}\n tabIndex={tabIndex ?? (isButtonLike ? 0 : undefined)}\n onClick={onClick}\n onKeyDown={isButtonLike || onKeyDown ? handleKeyDown : undefined}\n className={cn(card({ variant, padding }), className)}\n {...props}\n />\n );\n});\nCard.displayName = 'Card';\n\nexport const CardHeader = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n function CardHeader({ className, ...props }, ref) {\n return (\n <div\n ref={ref}\n className={cn('flex flex-col gap-1 pb-4', className)}\n {...props}\n />\n );\n },\n);\nCardHeader.displayName = 'CardHeader';\n\nexport const CardTitle = forwardRef<HTMLHeadingElement, HTMLAttributes<HTMLHeadingElement>>(\n function CardTitle({ className, children, ...props }, ref) {\n return (\n <h3\n ref={ref}\n className={cn('text-base font-semibold text-foreground leading-tight', className)}\n {...props}\n >\n {children}\n </h3>\n );\n },\n);\nCardTitle.displayName = 'CardTitle';\n\nexport const CardDescription = forwardRef<\n HTMLParagraphElement,\n HTMLAttributes<HTMLParagraphElement>\n>(function CardDescription({ className, ...props }, ref) {\n return (\n <p\n ref={ref}\n className={cn('text-sm text-foreground-muted', className)}\n {...props}\n />\n );\n});\nCardDescription.displayName = 'CardDescription';\n\nexport const CardContent = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n function CardContent({ className, ...props }, ref) {\n return <div ref={ref} className={cn('text-sm text-foreground', className)} {...props} />;\n },\n);\nCardContent.displayName = 'CardContent';\n\nexport const CardFooter = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n function CardFooter({ className, ...props }, ref) {\n return (\n <div\n ref={ref}\n className={cn('flex items-center gap-2 pt-4', className)}\n {...props}\n />\n );\n },\n);\nCardFooter.displayName = 'CardFooter';\n"],"names":["card","cva","Card","forwardRef","className","variant","padding","onClick","onKeyDown","role","tabIndex","props","ref","isButtonLike","jsx","event","cn","CardHeader","CardTitle","children","CardDescription","CardContent","CardFooter"],"mappings":"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"}
|
|
@@ -13,7 +13,11 @@ export interface CarouselProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
13
13
|
*/
|
|
14
14
|
export declare const Carousel: import('react').ForwardRefExoticComponent<CarouselProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
15
15
|
export declare const CarouselContent: import('react').ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & import('react').RefAttributes<HTMLDivElement>>;
|
|
16
|
-
export
|
|
16
|
+
export interface CarouselItemProps extends HTMLAttributes<HTMLDivElement> {
|
|
17
|
+
/** 0-based position, used for the default "{i+1} of {n}" label. */
|
|
18
|
+
index?: number;
|
|
19
|
+
}
|
|
20
|
+
export declare const CarouselItem: import('react').ForwardRefExoticComponent<CarouselItemProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
17
21
|
export declare function CarouselPrevious({ className }: {
|
|
18
22
|
className?: string;
|
|
19
23
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as a } from "react/jsx-runtime";
|
|
3
|
+
import { forwardRef as b, useState as x, useCallback as k, useEffect as N, createContext as R, useContext as E } from "react";
|
|
4
|
+
import L from "embla-carousel-react";
|
|
5
|
+
import { ChevronRight as j, ChevronLeft as B } from "../../icons/index.js";
|
|
6
|
+
import { cn as f } from "../../lib/utils.js";
|
|
7
|
+
import { useStrings as d } from "../../hooks/use-strings.js";
|
|
8
|
+
import { formatString as q } from "../../lib/strings.js";
|
|
9
|
+
import { IconButton as h } from "./IconButton.js";
|
|
10
|
+
const g = R(null);
|
|
11
|
+
function C() {
|
|
12
|
+
const r = E(g);
|
|
13
|
+
if (!r) throw new Error("Carousel components must be used inside <Carousel>");
|
|
14
|
+
return r;
|
|
15
|
+
}
|
|
16
|
+
const D = b(function({ opts: n, orientation: t = "horizontal", setApi: o, className: l, children: c, ...u }, m) {
|
|
17
|
+
const v = d(), [P, e] = L({
|
|
18
|
+
...n,
|
|
19
|
+
axis: t === "horizontal" ? "x" : "y"
|
|
20
|
+
}), [z, I] = x(!1), [y, S] = x(!1), [p, w] = x(0), i = k((s) => {
|
|
21
|
+
s && (I(s.canScrollPrev()), S(s.canScrollNext()));
|
|
22
|
+
}, []);
|
|
23
|
+
return N(() => {
|
|
24
|
+
if (e)
|
|
25
|
+
return o == null || o(e), i(e), e.on("reInit", i).on("select", i), () => {
|
|
26
|
+
e.off("reInit", i).off("select", i);
|
|
27
|
+
};
|
|
28
|
+
}, [e, i, o]), N(() => {
|
|
29
|
+
if (!e) return;
|
|
30
|
+
const s = () => w(e.slideNodes().length);
|
|
31
|
+
return s(), e.on("reInit", s), () => {
|
|
32
|
+
e.off("reInit", s);
|
|
33
|
+
};
|
|
34
|
+
}, [e]), /* @__PURE__ */ a(
|
|
35
|
+
g.Provider,
|
|
36
|
+
{
|
|
37
|
+
value: {
|
|
38
|
+
carouselRef: P,
|
|
39
|
+
api: e,
|
|
40
|
+
canPrev: z,
|
|
41
|
+
canNext: y,
|
|
42
|
+
scrollPrev: () => e == null ? void 0 : e.scrollPrev(),
|
|
43
|
+
scrollNext: () => e == null ? void 0 : e.scrollNext(),
|
|
44
|
+
orientation: t,
|
|
45
|
+
slideCount: p
|
|
46
|
+
},
|
|
47
|
+
children: /* @__PURE__ */ a(
|
|
48
|
+
"div",
|
|
49
|
+
{
|
|
50
|
+
ref: m,
|
|
51
|
+
className: f("relative", l),
|
|
52
|
+
role: "region",
|
|
53
|
+
"aria-roledescription": "carousel",
|
|
54
|
+
"aria-label": u["aria-label"] ?? (u["aria-labelledby"] ? void 0 : v.carousel.label),
|
|
55
|
+
...u,
|
|
56
|
+
children: c
|
|
57
|
+
}
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
});
|
|
62
|
+
D.displayName = "Carousel";
|
|
63
|
+
const F = b(
|
|
64
|
+
function({ className: n, ...t }, o) {
|
|
65
|
+
const { carouselRef: l, orientation: c } = C();
|
|
66
|
+
return /* @__PURE__ */ a("div", { ref: l, className: "overflow-hidden", children: /* @__PURE__ */ a(
|
|
67
|
+
"div",
|
|
68
|
+
{
|
|
69
|
+
ref: o,
|
|
70
|
+
className: f(
|
|
71
|
+
"flex",
|
|
72
|
+
c === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
|
|
73
|
+
n
|
|
74
|
+
),
|
|
75
|
+
...t
|
|
76
|
+
}
|
|
77
|
+
) });
|
|
78
|
+
}
|
|
79
|
+
);
|
|
80
|
+
F.displayName = "CarouselContent";
|
|
81
|
+
const G = b(function({ className: n, index: t, ...o }, l) {
|
|
82
|
+
const c = d(), { orientation: u, slideCount: m } = C(), v = t !== void 0 && m > 0 ? q(c.carousel.slide, { index: t + 1, count: m }) : void 0;
|
|
83
|
+
return /* @__PURE__ */ a(
|
|
84
|
+
"div",
|
|
85
|
+
{
|
|
86
|
+
ref: l,
|
|
87
|
+
role: "group",
|
|
88
|
+
"aria-roledescription": "slide",
|
|
89
|
+
"aria-label": o["aria-label"] ?? v,
|
|
90
|
+
className: f(
|
|
91
|
+
"min-w-0 shrink-0 grow-0 basis-full",
|
|
92
|
+
u === "horizontal" ? "pl-4" : "pt-4",
|
|
93
|
+
n
|
|
94
|
+
),
|
|
95
|
+
...o
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
});
|
|
99
|
+
G.displayName = "CarouselItem";
|
|
100
|
+
function V({ className: r }) {
|
|
101
|
+
const { canPrev: n, scrollPrev: t, orientation: o } = C(), l = d();
|
|
102
|
+
return /* @__PURE__ */ a(
|
|
103
|
+
h,
|
|
104
|
+
{
|
|
105
|
+
"aria-label": l.carousel.previous,
|
|
106
|
+
variant: "outline",
|
|
107
|
+
disabled: !n,
|
|
108
|
+
onClick: t,
|
|
109
|
+
icon: /* @__PURE__ */ a(B, {}),
|
|
110
|
+
className: f(
|
|
111
|
+
"absolute z-10",
|
|
112
|
+
o === "horizontal" ? "top-1/2 -left-12 -translate-y-1/2" : "-top-12 left-1/2 -translate-x-1/2 rotate-90",
|
|
113
|
+
r
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
function W({ className: r }) {
|
|
119
|
+
const { canNext: n, scrollNext: t, orientation: o } = C(), l = d();
|
|
120
|
+
return /* @__PURE__ */ a(
|
|
121
|
+
h,
|
|
122
|
+
{
|
|
123
|
+
"aria-label": l.carousel.next,
|
|
124
|
+
variant: "outline",
|
|
125
|
+
disabled: !n,
|
|
126
|
+
onClick: t,
|
|
127
|
+
icon: /* @__PURE__ */ a(j, {}),
|
|
128
|
+
className: f(
|
|
129
|
+
"absolute z-10",
|
|
130
|
+
o === "horizontal" ? "top-1/2 -right-12 -translate-y-1/2" : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
|
|
131
|
+
r
|
|
132
|
+
)
|
|
133
|
+
}
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
export {
|
|
137
|
+
D as Carousel,
|
|
138
|
+
F as CarouselContent,
|
|
139
|
+
G as CarouselItem,
|
|
140
|
+
W as CarouselNext,
|
|
141
|
+
V as CarouselPrevious
|
|
142
|
+
};
|
|
143
|
+
//# sourceMappingURL=Carousel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Carousel.js","sources":["../../../src/components/ui/Carousel.tsx"],"sourcesContent":["'use client';\n\nimport {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useState,\n type HTMLAttributes,\n} from 'react';\nimport useEmblaCarousel, { type UseEmblaCarouselType } from 'embla-carousel-react';\nimport { ChevronLeft, ChevronRight } from '@/icons';\nimport { cn } from '@/lib/utils';\nimport { useStrings } from '@/hooks/use-strings';\nimport { formatString } from '@/lib/strings';\nimport { IconButton } from './IconButton';\n\ntype CarouselApi = UseEmblaCarouselType[1];\ntype CarouselOptions = Parameters<typeof useEmblaCarousel>[0];\n\ninterface CarouselContextValue {\n carouselRef: ReturnType<typeof useEmblaCarousel>[0];\n api: CarouselApi;\n canPrev: boolean;\n canNext: boolean;\n scrollPrev: () => void;\n scrollNext: () => void;\n orientation: 'horizontal' | 'vertical';\n slideCount: number;\n}\n\nconst CarouselContext = createContext<CarouselContextValue | null>(null);\n\nfunction useCarousel() {\n const ctx = useContext(CarouselContext);\n if (!ctx) throw new Error('Carousel components must be used inside <Carousel>');\n return ctx;\n}\n\nexport interface CarouselProps extends HTMLAttributes<HTMLDivElement> {\n opts?: CarouselOptions;\n orientation?: 'horizontal' | 'vertical';\n setApi?: (api: CarouselApi) => void;\n}\n\n/**\n * Embla-backed carousel. Compose with `<CarouselContent>`, `<CarouselItem>`,\n * `<CarouselPrevious>`, and `<CarouselNext>`.\n */\nexport const Carousel = forwardRef<HTMLDivElement, CarouselProps>(function Carousel(\n { opts, orientation = 'horizontal', setApi, className, children, ...props },\n ref,\n) {\n const strings = useStrings();\n const [carouselRef, api] = useEmblaCarousel({\n ...opts,\n axis: orientation === 'horizontal' ? 'x' : 'y',\n });\n const [canPrev, setCanPrev] = useState(false);\n const [canNext, setCanNext] = useState(false);\n const [slideCount, setSlideCount] = useState(0);\n\n const onSelect = useCallback((api: CarouselApi) => {\n if (!api) return;\n setCanPrev(api.canScrollPrev());\n setCanNext(api.canScrollNext());\n }, []);\n\n useEffect(() => {\n if (!api) return;\n setApi?.(api);\n onSelect(api);\n api.on('reInit', onSelect).on('select', onSelect);\n return () => {\n api.off('reInit', onSelect).off('select', onSelect);\n };\n }, [api, onSelect, setApi]);\n\n useEffect(() => {\n if (!api) return;\n const count = () => setSlideCount(api.slideNodes().length);\n count();\n api.on('reInit', count);\n return () => {\n api.off('reInit', count);\n };\n }, [api]);\n\n return (\n <CarouselContext.Provider\n value={{\n carouselRef,\n api,\n canPrev,\n canNext,\n scrollPrev: () => api?.scrollPrev(),\n scrollNext: () => api?.scrollNext(),\n orientation,\n slideCount,\n }}\n >\n <div\n ref={ref}\n className={cn('relative', className)}\n role=\"region\"\n aria-roledescription=\"carousel\"\n aria-label={props['aria-label'] ?? (props['aria-labelledby'] ? undefined : strings.carousel.label)}\n {...props}\n >\n {children}\n </div>\n </CarouselContext.Provider>\n );\n});\nCarousel.displayName = 'Carousel';\n\nexport const CarouselContent = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n function CarouselContent({ className, ...props }, ref) {\n const { carouselRef, orientation } = useCarousel();\n return (\n <div ref={carouselRef} className=\"overflow-hidden\">\n <div\n ref={ref}\n className={cn(\n 'flex',\n orientation === 'horizontal' ? '-ml-4' : '-mt-4 flex-col',\n className,\n )}\n {...props}\n />\n </div>\n );\n },\n);\nCarouselContent.displayName = 'CarouselContent';\n\nexport interface CarouselItemProps extends HTMLAttributes<HTMLDivElement> {\n /** 0-based position, used for the default \"{i+1} of {n}\" label. */\n index?: number;\n}\n\nexport const CarouselItem = forwardRef<HTMLDivElement, CarouselItemProps>(function CarouselItem(\n { className, index, ...props },\n ref,\n) {\n const strings = useStrings();\n const { orientation, slideCount } = useCarousel();\n const defaultLabel =\n index !== undefined && slideCount > 0\n ? formatString(strings.carousel.slide, { index: index + 1, count: slideCount })\n : undefined;\n return (\n <div\n ref={ref}\n role=\"group\"\n aria-roledescription=\"slide\"\n aria-label={props['aria-label'] ?? defaultLabel}\n className={cn(\n 'min-w-0 shrink-0 grow-0 basis-full',\n orientation === 'horizontal' ? 'pl-4' : 'pt-4',\n className,\n )}\n {...props}\n />\n );\n});\nCarouselItem.displayName = 'CarouselItem';\n\nexport function CarouselPrevious({ className }: { className?: string }) {\n const { canPrev, scrollPrev, orientation } = useCarousel();\n const strings = useStrings();\n return (\n <IconButton\n aria-label={strings.carousel.previous}\n variant=\"outline\"\n disabled={!canPrev}\n onClick={scrollPrev}\n icon={<ChevronLeft />}\n className={cn(\n 'absolute z-10',\n orientation === 'horizontal'\n ? 'top-1/2 -left-12 -translate-y-1/2'\n : '-top-12 left-1/2 -translate-x-1/2 rotate-90',\n className,\n )}\n />\n );\n}\n\nexport function CarouselNext({ className }: { className?: string }) {\n const { canNext, scrollNext, orientation } = useCarousel();\n const strings = useStrings();\n return (\n <IconButton\n aria-label={strings.carousel.next}\n variant=\"outline\"\n disabled={!canNext}\n onClick={scrollNext}\n icon={<ChevronRight />}\n className={cn(\n 'absolute z-10',\n orientation === 'horizontal'\n ? 'top-1/2 -right-12 -translate-y-1/2'\n : '-bottom-12 left-1/2 -translate-x-1/2 rotate-90',\n className,\n )}\n />\n );\n}\n"],"names":["CarouselContext","createContext","useCarousel","ctx","useContext","Carousel","forwardRef","opts","orientation","setApi","className","children","props","ref","strings","useStrings","carouselRef","api","useEmblaCarousel","canPrev","setCanPrev","useState","canNext","setCanNext","slideCount","setSlideCount","onSelect","useCallback","useEffect","count","jsx","cn","CarouselContent","CarouselItem","index","defaultLabel","formatString","CarouselPrevious","scrollPrev","IconButton","ChevronLeft","CarouselNext","scrollNext","ChevronRight"],"mappings":"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"}
|
|
@@ -9,18 +9,40 @@ export interface ChartPoint {
|
|
|
9
9
|
x: string | number;
|
|
10
10
|
y: number;
|
|
11
11
|
}
|
|
12
|
-
export interface
|
|
12
|
+
export interface ChartSeries {
|
|
13
|
+
/** Name used in the accessible summary and tooltips. */
|
|
14
|
+
name?: string;
|
|
13
15
|
data: ChartPoint[];
|
|
16
|
+
}
|
|
17
|
+
export interface ChartProps {
|
|
18
|
+
/** Primary series. Ignored when `series` is provided. */
|
|
19
|
+
data?: ChartPoint[];
|
|
20
|
+
/** Multiple series drawn on the same scale. */
|
|
21
|
+
series?: ChartSeries[];
|
|
22
|
+
/**
|
|
23
|
+
* Per-series colours. Defaults to the categorical token list below.
|
|
24
|
+
* TODO(globals.css): add `--chart-1..6` tokens and switch the defaults.
|
|
25
|
+
*/
|
|
26
|
+
colors?: string[];
|
|
14
27
|
/** Drawing height in px. */
|
|
15
28
|
height?: number;
|
|
16
29
|
/** Defaults to fluid 100%. */
|
|
17
30
|
width?: number | string;
|
|
18
|
-
/**
|
|
31
|
+
/** Visible caption rendered above the chart. Doubles as the accessible name. */
|
|
19
32
|
caption?: ReactNode;
|
|
33
|
+
/** Accessible name when there is no `caption`. */
|
|
34
|
+
'aria-label'?: string;
|
|
35
|
+
/** Alias of `aria-label` (SVG `<title>`). */
|
|
36
|
+
title?: string;
|
|
20
37
|
/** Faint horizontal gridlines. Default true. */
|
|
21
38
|
grid?: boolean;
|
|
39
|
+
/** Y-axis tick labels + first/last x labels. Default true. */
|
|
40
|
+
showAxis?: boolean;
|
|
22
41
|
className?: string;
|
|
23
42
|
}
|
|
24
|
-
export declare
|
|
43
|
+
export declare const DEFAULT_CHART_COLORS: string[];
|
|
44
|
+
/** 1234 → "1.2K", 3_400_000 → "3.4M". */
|
|
45
|
+
export declare function abbreviateNumber(n: number): string;
|
|
46
|
+
export declare function LineChart({ data, series, colors, height, width, caption, 'aria-label': ariaLabel, title, grid, showAxis, className, }: ChartProps): import("react/jsx-runtime").JSX.Element;
|
|
25
47
|
export declare function AreaChart(props: ChartProps): import("react/jsx-runtime").JSX.Element;
|
|
26
|
-
export declare function BarChart({ data, height, width, caption, grid, className }: ChartProps): import("react/jsx-runtime").JSX.Element;
|
|
48
|
+
export declare function BarChart({ data, series, colors, height, width, caption, 'aria-label': ariaLabel, title, grid, showAxis, className, }: ChartProps): import("react/jsx-runtime").JSX.Element;
|