cortena-ui 1.3.0 → 1.4.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 +74 -3
- package/dist/a2ui/catalogue-doc.d.ts +44 -0
- package/dist/a2ui/catalogue-doc.js +169 -0
- package/dist/a2ui/catalogue-doc.js.map +1 -0
- package/dist/a2ui/catalogue.d.ts +44 -0
- package/dist/a2ui/catalogue.js +942 -0
- package/dist/a2ui/catalogue.js.map +1 -0
- package/dist/a2ui/index.d.ts +7 -0
- package/dist/a2ui/message.d.ts +232 -0
- package/dist/a2ui/message.js +365 -0
- package/dist/a2ui/message.js.map +1 -0
- package/dist/a2ui/renderer.d.ts +46 -0
- package/dist/a2ui/renderer.js +252 -0
- package/dist/a2ui/renderer.js.map +1 -0
- package/dist/a2ui/views.d.ts +80 -0
- package/dist/a2ui/views.js +596 -0
- package/dist/a2ui/views.js.map +1 -0
- package/dist/a2ui.d.ts +8 -0
- package/dist/a2ui.js +7 -0
- package/dist/chart.d.ts +9 -0
- package/dist/chart.js +9 -0
- package/dist/components/accordion.d.ts +22 -0
- package/dist/components/accordion.js +63 -0
- package/dist/components/accordion.js.map +1 -0
- package/dist/components/alert.d.ts +15 -0
- package/dist/components/alert.js +64 -0
- package/dist/components/alert.js.map +1 -0
- package/dist/components/avatar.d.ts +18 -0
- package/dist/components/avatar.js +40 -0
- package/dist/components/avatar.js.map +1 -0
- package/dist/components/badge.d.ts +12 -0
- package/dist/components/badge.js +47 -0
- package/dist/components/badge.js.map +1 -0
- package/dist/components/breadcrumb.d.ts +71 -0
- package/dist/components/breadcrumb.js +123 -0
- package/dist/components/breadcrumb.js.map +1 -0
- package/dist/components/button-link.d.ts +28 -0
- package/dist/components/button-link.js +24 -0
- package/dist/components/button-link.js.map +1 -0
- package/dist/components/button.d.ts +24 -0
- package/dist/components/button.js +65 -0
- package/dist/components/button.js.map +1 -0
- package/dist/components/calendar.d.ts +28 -0
- package/dist/components/calendar.js +123 -0
- package/dist/components/calendar.js.map +1 -0
- package/dist/components/card.d.ts +32 -0
- package/dist/components/card.js +57 -0
- package/dist/components/card.js.map +1 -0
- package/dist/components/chart/chart.d.ts +71 -0
- package/dist/components/chart/chart.js +167 -0
- package/dist/components/chart/chart.js.map +1 -0
- package/dist/components/chart/container.d.ts +88 -0
- package/dist/components/chart/container.js +189 -0
- package/dist/components/chart/container.js.map +1 -0
- package/dist/components/chart/data.js +128 -0
- package/dist/components/chart/data.js.map +1 -0
- package/dist/components/chart/index.d.ts +9 -0
- package/dist/components/chart/index.js +10 -0
- package/dist/components/chart/nivo-charts.js +225 -0
- package/dist/components/chart/nivo-charts.js.map +1 -0
- package/dist/components/chart/nivo-lazy.js +50 -0
- package/dist/components/chart/nivo-lazy.js.map +1 -0
- package/dist/components/chart/nivo-theme.d.ts +156 -0
- package/dist/components/chart/nivo-theme.js +161 -0
- package/dist/components/chart/nivo-theme.js.map +1 -0
- package/dist/components/chart/recharts-charts.js +276 -0
- package/dist/components/chart/recharts-charts.js.map +1 -0
- package/dist/components/chart/recharts-lazy.js +58 -0
- package/dist/components/chart/recharts-lazy.js.map +1 -0
- package/dist/components/chart/recharts-parts.d.ts +10 -0
- package/dist/components/chart/recharts-parts.js +25 -0
- package/dist/components/chart/recharts-parts.js.map +1 -0
- package/dist/components/chart/tokens.d.ts +62 -0
- package/dist/components/chart/tokens.js +192 -0
- package/dist/components/chart/tokens.js.map +1 -0
- package/dist/components/chart/types.d.ts +114 -0
- package/dist/components/chart/types.js +27 -0
- package/dist/components/chart/types.js.map +1 -0
- package/dist/components/checkbox.d.ts +20 -0
- package/dist/components/checkbox.js +24 -0
- package/dist/components/checkbox.js.map +1 -0
- package/dist/components/chip.d.ts +17 -0
- package/dist/components/chip.js +47 -0
- package/dist/components/chip.js.map +1 -0
- package/dist/components/combobox.d.ts +76 -0
- package/dist/components/combobox.js +201 -0
- package/dist/components/combobox.js.map +1 -0
- package/dist/components/command.d.ts +50 -0
- package/dist/components/command.js +117 -0
- package/dist/components/command.js.map +1 -0
- package/dist/components/data-table/data-table.d.ts +65 -0
- package/dist/components/data-table/data-table.js +588 -0
- package/dist/components/data-table/data-table.js.map +1 -0
- package/dist/components/data-table/export.d.ts +23 -0
- package/dist/components/data-table/export.js +95 -0
- package/dist/components/data-table/export.js.map +1 -0
- package/dist/components/data-table/features.d.ts +66 -0
- package/dist/components/data-table/features.js +103 -0
- package/dist/components/data-table/features.js.map +1 -0
- package/dist/components/data-table/index.d.ts +8 -0
- package/dist/components/data-table/parts.d.ts +79 -0
- package/dist/components/data-table/parts.js +400 -0
- package/dist/components/data-table/parts.js.map +1 -0
- package/dist/components/data-table/system-columns.js +84 -0
- package/dist/components/data-table/system-columns.js.map +1 -0
- package/dist/components/data-table/types.d.ts +172 -0
- package/dist/components/data-table/use-data-table.d.ts +19 -0
- package/dist/components/data-table/use-data-table.js +171 -0
- package/dist/components/data-table/use-data-table.js.map +1 -0
- package/dist/components/data-table/use-server-source.js +200 -0
- package/dist/components/data-table/use-server-source.js.map +1 -0
- package/dist/components/date-field.d.ts +54 -0
- package/dist/components/date-field.js +235 -0
- package/dist/components/date-field.js.map +1 -0
- package/dist/components/date-picker.d.ts +42 -0
- package/dist/components/date-picker.js +125 -0
- package/dist/components/date-picker.js.map +1 -0
- package/dist/components/dialog.d.ts +36 -0
- package/dist/components/dialog.js +97 -0
- package/dist/components/dialog.js.map +1 -0
- package/dist/components/dropdown-menu.d.ts +54 -0
- package/dist/components/dropdown-menu.js +191 -0
- package/dist/components/dropdown-menu.js.map +1 -0
- package/dist/components/dropzone.d.ts +48 -0
- package/dist/components/dropzone.js +185 -0
- package/dist/components/dropzone.js.map +1 -0
- package/dist/components/empty-state.d.ts +22 -0
- package/dist/components/empty-state.js +46 -0
- package/dist/components/empty-state.js.map +1 -0
- package/dist/components/error-banner.d.ts +17 -0
- package/dist/components/error-banner.js +52 -0
- package/dist/components/error-banner.js.map +1 -0
- package/dist/components/field.d.ts +64 -0
- package/dist/components/field.js +133 -0
- package/dist/components/field.js.map +1 -0
- package/dist/components/form.d.ts +37 -0
- package/dist/components/form.js +103 -0
- package/dist/components/form.js.map +1 -0
- package/dist/components/input.d.ts +17 -0
- package/dist/components/input.js +26 -0
- package/dist/components/input.js.map +1 -0
- package/dist/components/kbd.d.ts +11 -0
- package/dist/components/kbd.js +20 -0
- package/dist/components/kbd.js.map +1 -0
- package/dist/components/label.d.ts +14 -0
- package/dist/components/label.js +28 -0
- package/dist/components/label.js.map +1 -0
- package/dist/components/loading-skeleton.d.ts +22 -0
- package/dist/components/loading-skeleton.js +123 -0
- package/dist/components/loading-skeleton.js.map +1 -0
- package/dist/components/markdown.d.ts +44 -0
- package/dist/components/markdown.js +231 -0
- package/dist/components/markdown.js.map +1 -0
- package/dist/components/page-header.d.ts +26 -0
- package/dist/components/page-header.js +53 -0
- package/dist/components/page-header.js.map +1 -0
- package/dist/components/popover.d.ts +29 -0
- package/dist/components/popover.js +74 -0
- package/dist/components/popover.js.map +1 -0
- package/dist/components/progress.d.ts +22 -0
- package/dist/components/progress.js +49 -0
- package/dist/components/progress.js.map +1 -0
- package/dist/components/radio-group.d.ts +20 -0
- package/dist/components/radio-group.js +29 -0
- package/dist/components/radio-group.js.map +1 -0
- package/dist/components/scroll-area.d.ts +25 -0
- package/dist/components/scroll-area.js +39 -0
- package/dist/components/scroll-area.js.map +1 -0
- package/dist/components/section-card.d.ts +29 -0
- package/dist/components/section-card.js +55 -0
- package/dist/components/section-card.js.map +1 -0
- package/dist/components/segmented.d.ts +27 -0
- package/dist/components/segmented.js +32 -0
- package/dist/components/segmented.js.map +1 -0
- package/dist/components/select.d.ts +62 -0
- package/dist/components/select.js +97 -0
- package/dist/components/select.js.map +1 -0
- package/dist/components/separator.d.ts +19 -0
- package/dist/components/separator.js +23 -0
- package/dist/components/separator.js.map +1 -0
- package/dist/components/sheet.d.ts +35 -0
- package/dist/components/sheet.js +131 -0
- package/dist/components/sheet.js.map +1 -0
- package/dist/components/skeleton.d.ts +12 -0
- package/dist/components/skeleton.js +22 -0
- package/dist/components/skeleton.js.map +1 -0
- package/dist/components/sortable-list.d.ts +67 -0
- package/dist/components/sortable-list.js +206 -0
- package/dist/components/sortable-list.js.map +1 -0
- package/dist/components/spinner.d.ts +29 -0
- package/dist/components/spinner.js +34 -0
- package/dist/components/spinner.js.map +1 -0
- package/dist/components/status-dot.d.ts +26 -0
- package/dist/components/status-dot.js +47 -0
- package/dist/components/status-dot.js.map +1 -0
- package/dist/components/switch.d.ts +21 -0
- package/dist/components/switch.js +21 -0
- package/dist/components/switch.js.map +1 -0
- package/dist/components/tabs.d.ts +24 -0
- package/dist/components/tabs.js +60 -0
- package/dist/components/tabs.js.map +1 -0
- package/dist/components/textarea.d.ts +19 -0
- package/dist/components/textarea.js +47 -0
- package/dist/components/textarea.js.map +1 -0
- package/dist/components/toast.d.ts +47 -0
- package/dist/components/toast.js +106 -0
- package/dist/components/toast.js.map +1 -0
- package/dist/components/toolbar.d.ts +19 -0
- package/dist/components/toolbar.js +45 -0
- package/dist/components/toolbar.js.map +1 -0
- package/dist/components/tooltip.d.ts +28 -0
- package/dist/components/tooltip.js +59 -0
- package/dist/components/tooltip.js.map +1 -0
- package/dist/core.d.ts +44 -0
- package/dist/core.js +44 -0
- package/dist/data-table.d.ts +9 -0
- package/dist/data-table.js +7 -0
- package/dist/form.d.ts +7 -0
- package/dist/form.js +7 -0
- package/dist/hooks/use-cortena-theme.d.ts +98 -0
- package/dist/hooks/use-cortena-theme.js +145 -0
- package/dist/hooks/use-cortena-theme.js.map +1 -0
- package/dist/index.d.ts +75 -2678
- package/dist/index.js +66 -8598
- package/dist/lib/cn.d.ts +10 -0
- package/dist/lib/cn.js +15 -0
- package/dist/lib/cn.js.map +1 -0
- package/dist/lib/render.d.ts +23 -0
- package/dist/lib/render.js +20 -0
- package/dist/lib/render.js.map +1 -0
- package/dist/lib/shakeable.js +39 -0
- package/dist/lib/shakeable.js.map +1 -0
- package/dist/markdown.d.ts +3 -0
- package/dist/markdown.js +3 -0
- package/dist/sortable-list.d.ts +3 -0
- package/dist/sortable-list.js +3 -0
- package/package.json +37 -14
- package/src/a2ui/catalogue.ts +140 -103
- package/src/a2ui/views.tsx +5 -2
- package/src/components/alert.tsx +1 -1
- package/src/components/badge.tsx +1 -1
- package/src/components/button.tsx +1 -1
- package/src/components/chart/chart.tsx +72 -25
- package/src/components/chart/container.tsx +24 -39
- package/src/components/chart/index.tsx +4 -2
- package/src/components/chart/nivo-charts.tsx +41 -13
- package/src/components/chart/nivo-lazy.tsx +52 -0
- package/src/components/chart/recharts-charts.tsx +98 -3
- package/src/components/chart/recharts-lazy.tsx +72 -0
- package/src/components/chart/recharts-parts.tsx +34 -0
- package/src/components/chart/tokens.ts +1 -1
- package/src/components/chart/types.ts +14 -0
- package/src/components/chip.tsx +1 -1
- package/src/components/combobox.tsx +2 -2
- package/src/components/data-table/export.ts +18 -2
- package/src/components/data-table/features.ts +77 -45
- package/src/components/data-table/parts.tsx +15 -0
- package/src/components/data-table/use-data-table.ts +7 -2
- package/src/components/data-table/use-server-source.ts +17 -4
- package/src/components/date-field.tsx +1 -1
- package/src/components/error-banner.tsx +1 -1
- package/src/components/field.tsx +2 -2
- package/src/components/form.tsx +2 -2
- package/src/components/input.tsx +1 -1
- package/src/components/label.tsx +1 -1
- package/src/components/markdown.tsx +5 -4
- package/src/components/sheet.tsx +2 -2
- package/src/components/sortable-list.tsx +2 -2
- package/src/components/textarea.tsx +1 -1
- package/src/components/toast.tsx +1 -1
- package/src/entries/a2ui.ts +11 -0
- package/src/entries/chart.ts +10 -0
- package/src/entries/core.ts +91 -0
- package/src/entries/data-table.ts +9 -0
- package/src/entries/form.ts +24 -0
- package/src/entries/markdown.ts +9 -0
- package/src/entries/sortable-list.ts +13 -0
- package/src/index.ts +32 -98
- package/src/lib/shakeable.ts +33 -0
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
import { cn } from "../lib/cn.js";
|
|
4
|
+
import { renderWith } from "../lib/render.js";
|
|
5
|
+
import { ChevronRight, MoreHorizontal } from "lucide-react";
|
|
6
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
|
+
//#region src/components/breadcrumb.tsx
|
|
8
|
+
/**
|
|
9
|
+
* Breadcrumb — the trail above a page title.
|
|
10
|
+
*
|
|
11
|
+
* A `<nav aria-label="Breadcrumb">` around an ordered list, which is what
|
|
12
|
+
* assistive technology expects: the list order is the hierarchy, so a screen
|
|
13
|
+
* reader announces "list, 4 items" and reads the path in order. Separators are
|
|
14
|
+
* decorative list items, not text inside the links, so a link's accessible
|
|
15
|
+
* name is the crumb and nothing else.
|
|
16
|
+
*
|
|
17
|
+
* The last crumb is `BreadcrumbPage`, not a link: it is the page you are on,
|
|
18
|
+
* so it carries `aria-current="page"` and is not focusable. Everything before
|
|
19
|
+
* it is a `BreadcrumbLink`.
|
|
20
|
+
*
|
|
21
|
+
* ```tsx
|
|
22
|
+
* <Breadcrumb>
|
|
23
|
+
* <BreadcrumbList>
|
|
24
|
+
* <BreadcrumbItem>
|
|
25
|
+
* <BreadcrumbLink href="/">Home</BreadcrumbLink>
|
|
26
|
+
* </BreadcrumbItem>
|
|
27
|
+
* <BreadcrumbSeparator />
|
|
28
|
+
* <BreadcrumbItem>
|
|
29
|
+
* <BreadcrumbEllipsis />
|
|
30
|
+
* </BreadcrumbItem>
|
|
31
|
+
* <BreadcrumbSeparator />
|
|
32
|
+
* <BreadcrumbItem>
|
|
33
|
+
* <BreadcrumbPage>Invoice 4021</BreadcrumbPage>
|
|
34
|
+
* </BreadcrumbItem>
|
|
35
|
+
* </BreadcrumbList>
|
|
36
|
+
* </Breadcrumb>
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* **Router links.** `BreadcrumbLink` renders an `<a>` by default. Pass
|
|
40
|
+
* `render` with the router's link component and the class name, `href` and
|
|
41
|
+
* handlers are merged onto it, the same contract as `ButtonLink`:
|
|
42
|
+
* `render={<NextLink href="/projects" />}` or
|
|
43
|
+
* `render={<Link to="/projects" />}`. This is deliberately not Base UI's
|
|
44
|
+
* `render` — a breadcrumb is markup, not a Base UI primitive — but it takes
|
|
45
|
+
* the same shape so there is one thing to remember.
|
|
46
|
+
*/
|
|
47
|
+
function Breadcrumb({ className, ...props }) {
|
|
48
|
+
return /* @__PURE__ */ jsx("nav", {
|
|
49
|
+
"data-slot": "breadcrumb",
|
|
50
|
+
"aria-label": "Breadcrumb",
|
|
51
|
+
className: cn("min-w-0", className),
|
|
52
|
+
...props
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
function BreadcrumbList({ className, ...props }) {
|
|
56
|
+
return /* @__PURE__ */ jsx("ol", {
|
|
57
|
+
"data-slot": "breadcrumb-list",
|
|
58
|
+
className: cn("flex flex-wrap items-center gap-1.5 break-words p-0 sm:gap-2", "list-none text-[length:var(--ds-text-caption-lg)]", "leading-[var(--ds-text-caption-lg--line-height)] text-[color:var(--ds-muted-foreground)]", className),
|
|
59
|
+
...props
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function BreadcrumbItem({ className, ...props }) {
|
|
63
|
+
return /* @__PURE__ */ jsx("li", {
|
|
64
|
+
"data-slot": "breadcrumb-item",
|
|
65
|
+
className: cn("inline-flex min-w-0 items-center gap-1.5", className),
|
|
66
|
+
...props
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
function BreadcrumbLink({ className, render, children, ...props }) {
|
|
70
|
+
const merged = {
|
|
71
|
+
...props,
|
|
72
|
+
"data-slot": "breadcrumb-link",
|
|
73
|
+
className: cn("truncate rounded-[var(--ds-radius-sm)] text-[color:var(--ds-muted-foreground)] no-underline", "transition-colors duration-[var(--ds-duration-fast)] ease-[var(--ds-ease-out)]", "hover:text-[color:var(--ds-foreground)] hover:underline underline-offset-4", "outline-none focus-visible:ring-[3px] focus-visible:ring-[var(--ds-ring)]/40", "[&_svg]:size-3.5 [&_svg]:shrink-0", className)
|
|
74
|
+
};
|
|
75
|
+
return renderWith(render, merged, children, "a");
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The current page: the last crumb, which is not a link.
|
|
79
|
+
*
|
|
80
|
+
* A plain `<span aria-current="page">`, deliberately not `role="link"` with
|
|
81
|
+
* `aria-disabled` — a disabled link that cannot be focused is a fiction, and
|
|
82
|
+
* it makes `getByRole("link")` return a crumb that navigates nowhere. With a
|
|
83
|
+
* span, the roles in the trail are exactly the crumbs you can travel to.
|
|
84
|
+
*/
|
|
85
|
+
function BreadcrumbPage({ className, ...props }) {
|
|
86
|
+
return /* @__PURE__ */ jsx("span", {
|
|
87
|
+
"data-slot": "breadcrumb-page",
|
|
88
|
+
"aria-current": "page",
|
|
89
|
+
className: cn("truncate font-medium text-[color:var(--ds-foreground)]", className),
|
|
90
|
+
...props
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
/** Decorative divider between two crumbs; a chevron unless children replace it. */
|
|
94
|
+
function BreadcrumbSeparator({ className, children, ...props }) {
|
|
95
|
+
return /* @__PURE__ */ jsx("li", {
|
|
96
|
+
"data-slot": "breadcrumb-separator",
|
|
97
|
+
role: "presentation",
|
|
98
|
+
"aria-hidden": "true",
|
|
99
|
+
className: cn("inline-flex shrink-0 items-center text-[color:var(--ds-text-tertiary)] [&_svg]:size-3.5", className),
|
|
100
|
+
...props,
|
|
101
|
+
children: children ?? /* @__PURE__ */ jsx(ChevronRight, {})
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Stands in for the crumbs a long trail collapses; put it inside a
|
|
106
|
+
* BreadcrumbItem. The glyph is hidden and the label is not: an ellipsis that
|
|
107
|
+
* announces nothing leaves a screen-reader user with a gap in the path.
|
|
108
|
+
*/
|
|
109
|
+
function BreadcrumbEllipsis({ className, children, ...props }) {
|
|
110
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
111
|
+
"data-slot": "breadcrumb-ellipsis",
|
|
112
|
+
className: cn("inline-flex size-5 items-center justify-center text-[color:var(--ds-text-tertiary)]", "[&_svg]:size-3.5", className),
|
|
113
|
+
...props,
|
|
114
|
+
children: [/* @__PURE__ */ jsx(MoreHorizontal, { "aria-hidden": true }), /* @__PURE__ */ jsx("span", {
|
|
115
|
+
className: "sr-only",
|
|
116
|
+
children: children ?? "More levels"
|
|
117
|
+
})]
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
//#endregion
|
|
121
|
+
export { Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator };
|
|
122
|
+
|
|
123
|
+
//# sourceMappingURL=breadcrumb.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"breadcrumb.js","names":[],"sources":["../../src/components/breadcrumb.tsx"],"sourcesContent":["\"use client\";\n\nimport { ChevronRight, MoreHorizontal } from \"lucide-react\";\nimport type * as React from \"react\";\nimport { cn } from \"@/lib/cn\";\nimport { renderWith, type RenderProp } from \"@/lib/render\";\n\n/**\n * Breadcrumb — the trail above a page title.\n *\n * A `<nav aria-label=\"Breadcrumb\">` around an ordered list, which is what\n * assistive technology expects: the list order is the hierarchy, so a screen\n * reader announces \"list, 4 items\" and reads the path in order. Separators are\n * decorative list items, not text inside the links, so a link's accessible\n * name is the crumb and nothing else.\n *\n * The last crumb is `BreadcrumbPage`, not a link: it is the page you are on,\n * so it carries `aria-current=\"page\"` and is not focusable. Everything before\n * it is a `BreadcrumbLink`.\n *\n * ```tsx\n * <Breadcrumb>\n * <BreadcrumbList>\n * <BreadcrumbItem>\n * <BreadcrumbLink href=\"/\">Home</BreadcrumbLink>\n * </BreadcrumbItem>\n * <BreadcrumbSeparator />\n * <BreadcrumbItem>\n * <BreadcrumbEllipsis />\n * </BreadcrumbItem>\n * <BreadcrumbSeparator />\n * <BreadcrumbItem>\n * <BreadcrumbPage>Invoice 4021</BreadcrumbPage>\n * </BreadcrumbItem>\n * </BreadcrumbList>\n * </Breadcrumb>\n * ```\n *\n * **Router links.** `BreadcrumbLink` renders an `<a>` by default. Pass\n * `render` with the router's link component and the class name, `href` and\n * handlers are merged onto it, the same contract as `ButtonLink`:\n * `render={<NextLink href=\"/projects\" />}` or\n * `render={<Link to=\"/projects\" />}`. This is deliberately not Base UI's\n * `render` — a breadcrumb is markup, not a Base UI primitive — but it takes\n * the same shape so there is one thing to remember.\n */\nfunction Breadcrumb({ className, ...props }: React.ComponentProps<\"nav\">) {\n return (\n <nav\n data-slot=\"breadcrumb\"\n aria-label=\"Breadcrumb\"\n className={cn(\"min-w-0\", className)}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbList({ className, ...props }: React.ComponentProps<\"ol\">) {\n return (\n <ol\n data-slot=\"breadcrumb-list\"\n className={cn(\n \"flex flex-wrap items-center gap-1.5 break-words p-0 sm:gap-2\",\n \"list-none text-[length:var(--ds-text-caption-lg)]\",\n \"leading-[var(--ds-text-caption-lg--line-height)] text-[color:var(--ds-muted-foreground)]\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction BreadcrumbItem({ className, ...props }: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"breadcrumb-item\"\n className={cn(\"inline-flex min-w-0 items-center gap-1.5\", className)}\n {...props}\n />\n );\n}\n\nexport interface BreadcrumbLinkProps extends React.ComponentProps<\"a\"> {\n /** Replace the rendered `<a>` with a router link; props are merged onto it. */\n render?: RenderProp;\n}\n\nfunction BreadcrumbLink({ className, render, children, ...props }: BreadcrumbLinkProps) {\n const merged = {\n ...props,\n \"data-slot\": \"breadcrumb-link\",\n className: cn(\n \"truncate rounded-[var(--ds-radius-sm)] text-[color:var(--ds-muted-foreground)] no-underline\",\n \"transition-colors duration-[var(--ds-duration-fast)] ease-[var(--ds-ease-out)]\",\n \"hover:text-[color:var(--ds-foreground)] hover:underline underline-offset-4\",\n \"outline-none focus-visible:ring-[3px] focus-visible:ring-[var(--ds-ring)]/40\",\n \"[&_svg]:size-3.5 [&_svg]:shrink-0\",\n className,\n ),\n };\n return renderWith(render, merged, children, \"a\");\n}\n\n/**\n * The current page: the last crumb, which is not a link.\n *\n * A plain `<span aria-current=\"page\">`, deliberately not `role=\"link\"` with\n * `aria-disabled` — a disabled link that cannot be focused is a fiction, and\n * it makes `getByRole(\"link\")` return a crumb that navigates nowhere. With a\n * span, the roles in the trail are exactly the crumbs you can travel to.\n */\nfunction BreadcrumbPage({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"breadcrumb-page\"\n aria-current=\"page\"\n className={cn(\"truncate font-medium text-[color:var(--ds-foreground)]\", className)}\n {...props}\n />\n );\n}\n\n/** Decorative divider between two crumbs; a chevron unless children replace it. */\nfunction BreadcrumbSeparator({ className, children, ...props }: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"breadcrumb-separator\"\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn(\n \"inline-flex shrink-0 items-center text-[color:var(--ds-text-tertiary)] [&_svg]:size-3.5\",\n className,\n )}\n {...props}\n >\n {children ?? <ChevronRight />}\n </li>\n );\n}\n\n/**\n * Stands in for the crumbs a long trail collapses; put it inside a\n * BreadcrumbItem. The glyph is hidden and the label is not: an ellipsis that\n * announces nothing leaves a screen-reader user with a gap in the path.\n */\nfunction BreadcrumbEllipsis({ className, children, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"breadcrumb-ellipsis\"\n className={cn(\n \"inline-flex size-5 items-center justify-center text-[color:var(--ds-text-tertiary)]\",\n \"[&_svg]:size-3.5\",\n className,\n )}\n {...props}\n >\n <MoreHorizontal aria-hidden />\n <span className=\"sr-only\">{children ?? \"More levels\"}</span>\n </span>\n );\n}\n\nexport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbPage,\n BreadcrumbSeparator,\n BreadcrumbEllipsis,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8CA,SAAS,WAAW,EAAE,WAAW,GAAG,SAAsC;CACxE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,cAAW;EACX,WAAW,GAAG,WAAW,SAAS;EAClC,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,SAAqC;CAC3E,OACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GACT,gEACA,qDACA,4FACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,eAAe,EAAE,WAAW,GAAG,SAAqC;CAC3E,OACE,oBAAC,MAAD;EACE,aAAU;EACV,WAAW,GAAG,4CAA4C,SAAS;EACnE,GAAI;CACL,CAAA;AAEL;AAOA,SAAS,eAAe,EAAE,WAAW,QAAQ,UAAU,GAAG,SAA8B;CACtF,MAAM,SAAS;EACb,GAAG;EACH,aAAa;EACb,WAAW,GACT,+FACA,kFACA,8EACA,gFACA,qCACA,SACF;CACF;CACA,OAAO,WAAW,QAAQ,QAAQ,UAAU,GAAG;AACjD;;;;;;;;;AAUA,SAAS,eAAe,EAAE,WAAW,GAAG,SAAuC;CAC7E,OACE,oBAAC,QAAD;EACE,aAAU;EACV,gBAAa;EACb,WAAW,GAAG,0DAA0D,SAAS;EACjF,GAAI;CACL,CAAA;AAEL;;AAGA,SAAS,oBAAoB,EAAE,WAAW,UAAU,GAAG,SAAqC;CAC1F,OACE,oBAAC,MAAD;EACE,aAAU;EACV,MAAK;EACL,eAAY;EACZ,WAAW,GACT,2FACA,SACF;EACA,GAAI;EAEH,UAAA,YAAY,oBAAC,cAAD,CAAe,CAAA;CAC1B,CAAA;AAER;;;;;;AAOA,SAAS,mBAAmB,EAAE,WAAW,UAAU,GAAG,SAAuC;CAC3F,OACE,qBAAC,QAAD;EACE,aAAU;EACV,WAAW,GACT,uFACA,oBACA,SACF;EACA,GAAI;EAPN,UAAA,CASE,oBAAC,gBAAD,EAAgB,eAAA,KAAa,CAAA,GAC7B,oBAAC,QAAD;GAAM,WAAU;GAAW,UAAA,YAAY;EAAoB,CAAA,CACvD;;AAEV"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { RenderProp } from "../lib/render.js";
|
|
3
|
+
import { ButtonProps } from "./button.js";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
//#region src/components/button-link.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* An anchor that looks like a Button and keeps link semantics.
|
|
8
|
+
*
|
|
9
|
+
* `Button render={<a />}` makes Base UI treat the anchor as a button (role,
|
|
10
|
+
* tabindex, its `nativeButton` warning), which demotes real navigation for
|
|
11
|
+
* assistive technology and breaks `getByRole("link")`. Navigation should stay
|
|
12
|
+
* an anchor. This is the migration target for every Radix-era
|
|
13
|
+
* `<Button asChild><Link /></Button>`.
|
|
14
|
+
*
|
|
15
|
+
* Framework routers: pass `render` with the router's link so the styling and
|
|
16
|
+
* `href` land on it, e.g. `render={<NextLink href="/x" />}`; otherwise it
|
|
17
|
+
* renders a plain `<a>`.
|
|
18
|
+
*/
|
|
19
|
+
export interface ButtonLinkProps extends Omit<React.ComponentProps<"a">, "children">, Pick<ButtonProps, "variant" | "size"> {
|
|
20
|
+
children?: React.ReactNode;
|
|
21
|
+
/** Replace the rendered `<a>` with a router link; props are merged onto it. */
|
|
22
|
+
render?: RenderProp;
|
|
23
|
+
disabled?: boolean;
|
|
24
|
+
}
|
|
25
|
+
declare function ButtonLink({ className, variant, size, render, disabled, children, ...props }: ButtonLinkProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>;
|
|
26
|
+
//#endregion
|
|
27
|
+
export { ButtonLink };
|
|
28
|
+
//# sourceMappingURL=button-link.d.ts.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
import { cn } from "../lib/cn.js";
|
|
4
|
+
import { renderWith } from "../lib/render.js";
|
|
5
|
+
import { buttonVariants } from "./button.js";
|
|
6
|
+
//#region src/components/button-link.tsx
|
|
7
|
+
function ButtonLink({ className, variant, size, render, disabled, children, ...props }) {
|
|
8
|
+
const classes = cn(buttonVariants({
|
|
9
|
+
variant,
|
|
10
|
+
size
|
|
11
|
+
}), disabled && "pointer-events-none opacity-50", className);
|
|
12
|
+
const merged = {
|
|
13
|
+
...props,
|
|
14
|
+
"data-slot": "button-link",
|
|
15
|
+
className: classes,
|
|
16
|
+
"aria-disabled": disabled || void 0,
|
|
17
|
+
tabIndex: disabled ? -1 : props.tabIndex
|
|
18
|
+
};
|
|
19
|
+
return renderWith(render, merged, children, "a");
|
|
20
|
+
}
|
|
21
|
+
//#endregion
|
|
22
|
+
export { ButtonLink };
|
|
23
|
+
|
|
24
|
+
//# sourceMappingURL=button-link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"button-link.js","names":[],"sources":["../../src/components/button-link.tsx"],"sourcesContent":["\"use client\";\n\nimport type * as React from \"react\";\nimport { cn } from \"@/lib/cn\";\nimport { renderWith, type RenderProp } from \"@/lib/render\";\nimport { buttonVariants, type ButtonProps } from \"@/components/button\";\n\n/**\n * An anchor that looks like a Button and keeps link semantics.\n *\n * `Button render={<a />}` makes Base UI treat the anchor as a button (role,\n * tabindex, its `nativeButton` warning), which demotes real navigation for\n * assistive technology and breaks `getByRole(\"link\")`. Navigation should stay\n * an anchor. This is the migration target for every Radix-era\n * `<Button asChild><Link /></Button>`.\n *\n * Framework routers: pass `render` with the router's link so the styling and\n * `href` land on it, e.g. `render={<NextLink href=\"/x\" />}`; otherwise it\n * renders a plain `<a>`.\n */\nexport interface ButtonLinkProps\n extends Omit<React.ComponentProps<\"a\">, \"children\">,\n Pick<ButtonProps, \"variant\" | \"size\"> {\n children?: React.ReactNode;\n /** Replace the rendered `<a>` with a router link; props are merged onto it. */\n render?: RenderProp;\n disabled?: boolean;\n}\n\nfunction ButtonLink({ className, variant, size, render, disabled, children, ...props }: ButtonLinkProps) {\n const classes = cn(buttonVariants({ variant, size }), disabled && \"pointer-events-none opacity-50\", className);\n const merged = {\n ...props,\n \"data-slot\": \"button-link\",\n className: classes,\n \"aria-disabled\": disabled || undefined,\n tabIndex: disabled ? -1 : props.tabIndex,\n };\n return renderWith(render, merged, children, \"a\");\n}\n\nexport { ButtonLink };\n"],"mappings":";;;;;;AA6BA,SAAS,WAAW,EAAE,WAAW,SAAS,MAAM,QAAQ,UAAU,UAAU,GAAG,SAA0B;CACvG,MAAM,UAAU,GAAG,eAAe;EAAE;EAAS;CAAK,CAAC,GAAG,YAAY,kCAAkC,SAAS;CAC7G,MAAM,SAAS;EACb,GAAG;EACH,aAAa;EACb,WAAW;EACX,iBAAiB,YAAY,KAAA;EAC7B,UAAU,WAAW,KAAK,MAAM;CAClC;CACA,OAAO,WAAW,QAAQ,QAAQ,UAAU,GAAG;AACjD"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { VariantProps } from "class-variance-authority";
|
|
3
|
+
import { Button } from "@base-ui/react/button";
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
//#region src/components/button.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Button.
|
|
8
|
+
*
|
|
9
|
+
* Base UI supplies the behaviour (native button semantics, `focusableWhenDisabled`,
|
|
10
|
+
* keyboard activation on non-button elements through `render`). Every visual
|
|
11
|
+
* value is a cortena-design token; nothing here is a literal the lint would flag.
|
|
12
|
+
*
|
|
13
|
+
* Radix users: `asChild` is gone. Pass `render={<a href=... />}` to change the
|
|
14
|
+
* rendered element, which is Base UI's equivalent.
|
|
15
|
+
*/
|
|
16
|
+
declare const buttonVariants: (props?: ({
|
|
17
|
+
variant?: "link" | "destructive" | "secondary" | "outline" | "primary" | "ghost" | "soft" | null | undefined;
|
|
18
|
+
size?: "sm" | "md" | "lg" | "icon" | "icon-sm" | null | undefined;
|
|
19
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
20
|
+
export interface ButtonProps extends React.ComponentProps<typeof Button>, VariantProps<typeof buttonVariants> {}
|
|
21
|
+
declare function Button$1({ className, variant, size, ...props }: ButtonProps): React.JSX.Element;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { Button$1 as Button, buttonVariants };
|
|
24
|
+
//# sourceMappingURL=button.d.ts.map
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
import { cn } from "../lib/cn.js";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
import { cva } from "class-variance-authority";
|
|
6
|
+
import { Button } from "@base-ui/react/button";
|
|
7
|
+
//#region src/components/button.tsx
|
|
8
|
+
/**
|
|
9
|
+
* Button.
|
|
10
|
+
*
|
|
11
|
+
* Base UI supplies the behaviour (native button semantics, `focusableWhenDisabled`,
|
|
12
|
+
* keyboard activation on non-button elements through `render`). Every visual
|
|
13
|
+
* value is a cortena-design token; nothing here is a literal the lint would flag.
|
|
14
|
+
*
|
|
15
|
+
* Radix users: `asChild` is gone. Pass `render={<a href=... />}` to change the
|
|
16
|
+
* rendered element, which is Base UI's equivalent.
|
|
17
|
+
*/
|
|
18
|
+
const buttonVariants = /* @__PURE__ */ cva([
|
|
19
|
+
"inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap",
|
|
20
|
+
"font-medium",
|
|
21
|
+
"rounded-[var(--ds-radius-md)]",
|
|
22
|
+
"border",
|
|
23
|
+
"transition-[background-color,border-color,color,box-shadow,filter]",
|
|
24
|
+
"duration-[var(--ds-duration-fast)] ease-[var(--ds-ease-out)]",
|
|
25
|
+
"outline-none focus-visible:ring-[3px] focus-visible:ring-[var(--ds-ring)]/40",
|
|
26
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
27
|
+
"[&_svg]:pointer-events-none [&_svg]:shrink-0"
|
|
28
|
+
], {
|
|
29
|
+
variants: {
|
|
30
|
+
variant: {
|
|
31
|
+
primary: "border-[var(--ds-primary)] bg-[var(--ds-primary)] text-[color:var(--ds-primary-foreground)] hover:border-[var(--ds-primary-hover)] hover:bg-[var(--ds-primary-hover)]",
|
|
32
|
+
secondary: "border-[var(--ds-border)] bg-[var(--ds-secondary)] text-[color:var(--ds-secondary-foreground)] hover:border-[var(--ds-border-strong)] hover:bg-[var(--ds-hover)]",
|
|
33
|
+
outline: "border-[var(--ds-border-strong)] bg-transparent text-[color:var(--ds-foreground)] hover:bg-[var(--ds-hover)]",
|
|
34
|
+
ghost: "border-transparent bg-transparent text-[color:var(--ds-muted-foreground)] hover:bg-[var(--ds-hover)] hover:text-[color:var(--ds-foreground)]",
|
|
35
|
+
soft: "border-transparent bg-[var(--ds-primary-soft)] text-[color:var(--ds-primary-soft-foreground)] hover:bg-[var(--ds-primary-soft)] hover:brightness-95",
|
|
36
|
+
destructive: "border-[var(--ds-destructive)] bg-[var(--ds-destructive)] text-[color:var(--ds-destructive-foreground)] hover:brightness-110",
|
|
37
|
+
link: "border-transparent bg-transparent text-[color:var(--ds-primary)] underline-offset-4 hover:underline"
|
|
38
|
+
},
|
|
39
|
+
size: {
|
|
40
|
+
sm: "h-8 px-3 text-[length:var(--ds-text-caption)] rounded-[var(--ds-radius-sm)] [&_svg]:size-3.5",
|
|
41
|
+
md: "h-9 px-4 text-[length:var(--ds-text-caption-lg)] [&_svg]:size-4",
|
|
42
|
+
lg: "h-10 px-5 text-[length:var(--ds-text-body-sm)] [&_svg]:size-4",
|
|
43
|
+
icon: "size-9 [&_svg]:size-4",
|
|
44
|
+
"icon-sm": "size-8 rounded-[var(--ds-radius-sm)] [&_svg]:size-3.5"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
defaultVariants: {
|
|
48
|
+
variant: "primary",
|
|
49
|
+
size: "md"
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
function Button$1({ className, variant, size, ...props }) {
|
|
53
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
54
|
+
"data-slot": "button",
|
|
55
|
+
className: cn(buttonVariants({
|
|
56
|
+
variant,
|
|
57
|
+
size
|
|
58
|
+
}), className),
|
|
59
|
+
...props
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
export { Button$1 as Button, buttonVariants };
|
|
64
|
+
|
|
65
|
+
//# sourceMappingURL=button.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"button.js","names":["Button","BaseButton"],"sources":["../../src/components/button.tsx"],"sourcesContent":["\"use client\";\n\nimport { Button as BaseButton } from \"@base-ui/react/button\";\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport type * as React from \"react\";\nimport { cn } from \"@/lib/cn\";\n\n/**\n * Button.\n *\n * Base UI supplies the behaviour (native button semantics, `focusableWhenDisabled`,\n * keyboard activation on non-button elements through `render`). Every visual\n * value is a cortena-design token; nothing here is a literal the lint would flag.\n *\n * Radix users: `asChild` is gone. Pass `render={<a href=... />}` to change the\n * rendered element, which is Base UI's equivalent.\n */\nconst buttonVariants = /* @__PURE__ */ cva(\n [\n \"inline-flex shrink-0 select-none items-center justify-center gap-2 whitespace-nowrap\",\n \"font-medium\",\n \"rounded-[var(--ds-radius-md)]\",\n \"border\",\n \"transition-[background-color,border-color,color,box-shadow,filter]\",\n \"duration-[var(--ds-duration-fast)] ease-[var(--ds-ease-out)]\",\n \"outline-none focus-visible:ring-[3px] focus-visible:ring-[var(--ds-ring)]/40\",\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 \"border-[var(--ds-primary)] bg-[var(--ds-primary)] text-[color:var(--ds-primary-foreground)] hover:border-[var(--ds-primary-hover)] hover:bg-[var(--ds-primary-hover)]\",\n secondary:\n \"border-[var(--ds-border)] bg-[var(--ds-secondary)] text-[color:var(--ds-secondary-foreground)] hover:border-[var(--ds-border-strong)] hover:bg-[var(--ds-hover)]\",\n outline:\n \"border-[var(--ds-border-strong)] bg-transparent text-[color:var(--ds-foreground)] hover:bg-[var(--ds-hover)]\",\n ghost:\n \"border-transparent bg-transparent text-[color:var(--ds-muted-foreground)] hover:bg-[var(--ds-hover)] hover:text-[color:var(--ds-foreground)]\",\n soft:\n \"border-transparent bg-[var(--ds-primary-soft)] text-[color:var(--ds-primary-soft-foreground)] hover:bg-[var(--ds-primary-soft)] hover:brightness-95\",\n destructive:\n \"border-[var(--ds-destructive)] bg-[var(--ds-destructive)] text-[color:var(--ds-destructive-foreground)] hover:brightness-110\",\n link: \"border-transparent bg-transparent text-[color:var(--ds-primary)] underline-offset-4 hover:underline\",\n },\n size: {\n sm: \"h-8 px-3 text-[length:var(--ds-text-caption)] rounded-[var(--ds-radius-sm)] [&_svg]:size-3.5\",\n md: \"h-9 px-4 text-[length:var(--ds-text-caption-lg)] [&_svg]:size-4\",\n lg: \"h-10 px-5 text-[length:var(--ds-text-body-sm)] [&_svg]:size-4\",\n icon: \"size-9 [&_svg]:size-4\",\n \"icon-sm\": \"size-8 rounded-[var(--ds-radius-sm)] [&_svg]:size-3.5\",\n },\n },\n defaultVariants: {\n variant: \"primary\",\n size: \"md\",\n },\n },\n);\n\nexport interface ButtonProps\n extends React.ComponentProps<typeof BaseButton>, VariantProps<typeof buttonVariants> {}\n\nfunction Button({ className, variant, size, ...props }: ButtonProps) {\n return (\n <BaseButton\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n />\n );\n}\n\nexport { Button, buttonVariants };\n"],"mappings":";;;;;;;;;;;;;;;;;AAiBA,MAAM,iBAAiC,oBACrC;CACE;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,GACA;CACE,UAAU;EACR,SAAS;GACP,SACE;GACF,WACE;GACF,SACE;GACF,OACE;GACF,MACE;GACF,aACE;GACF,MAAM;EACR;EACA,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,MAAM;GACN,WAAW;EACb;CACF;CACA,iBAAiB;EACf,SAAS;EACT,MAAM;CACR;AACF,CACF;AAKA,SAASA,SAAO,EAAE,WAAW,SAAS,MAAM,GAAG,SAAsB;CACnE,OACE,oBAACC,QAAD;EACE,aAAU;EACV,WAAW,GAAG,eAAe;GAAE;GAAS;EAAK,CAAC,GAAG,SAAS;EAC1D,GAAI;CACL,CAAA;AAEL"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { DayButtonProps, DayPickerProps } from "react-day-picker";
|
|
4
|
+
//#region src/components/calendar.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Calendar.
|
|
7
|
+
*
|
|
8
|
+
* The shadcn Calendar shape over react-day-picker 10. The library's stylesheet
|
|
9
|
+
* is not imported; every class comes from the `classNames` map below and every
|
|
10
|
+
* visual value in it is a cortena-design token. Structure (nav, caption, grid,
|
|
11
|
+
* dropdown caption) is DayPicker's; the day cells, nav buttons and chevrons are
|
|
12
|
+
* swapped for our Button and lucide icons through `components`.
|
|
13
|
+
*
|
|
14
|
+
* `showOutsideDays` defaults to true and `captionLayout` to `"label"`; pass
|
|
15
|
+
* `captionLayout="dropdown"` for native month/year selects in the caption.
|
|
16
|
+
*/
|
|
17
|
+
export type CalendarProps = DayPickerProps;
|
|
18
|
+
/**
|
|
19
|
+
* One day cell's button. Selection and range state are exposed as data
|
|
20
|
+
* attributes so the classes below (and a consumer's) can paint them; the
|
|
21
|
+
* `today` attribute is only set when the day is not selected, so the soft
|
|
22
|
+
* fill never competes with the selected fill.
|
|
23
|
+
*/
|
|
24
|
+
declare function CalendarDayButton({ className, day, modifiers, ...props }: DayButtonProps): React.JSX.Element;
|
|
25
|
+
declare function Calendar({ className, classNames, components, showOutsideDays, captionLayout, formatters, ...props }: CalendarProps): React.JSX.Element;
|
|
26
|
+
//#endregion
|
|
27
|
+
export { Calendar, CalendarDayButton };
|
|
28
|
+
//# sourceMappingURL=calendar.d.ts.map
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
import { cn } from "../lib/cn.js";
|
|
4
|
+
import { Button } from "./button.js";
|
|
5
|
+
import { ChevronDown, ChevronLeft, ChevronRight, ChevronUp } from "lucide-react";
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
import * as React from "react";
|
|
8
|
+
import { DayPicker, getDefaultClassNames } from "react-day-picker";
|
|
9
|
+
//#region src/components/calendar.tsx
|
|
10
|
+
function CalendarRoot({ className, rootRef, ...props }) {
|
|
11
|
+
return /* @__PURE__ */ jsx("div", {
|
|
12
|
+
"data-slot": "calendar",
|
|
13
|
+
ref: rootRef,
|
|
14
|
+
className,
|
|
15
|
+
...props
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
function CalendarChevron({ className, orientation, size: _size, disabled, ...props }) {
|
|
19
|
+
return /* @__PURE__ */ jsx(orientation === "left" ? ChevronLeft : orientation === "right" ? ChevronRight : orientation === "up" ? ChevronUp : ChevronDown, {
|
|
20
|
+
"data-slot": "calendar-chevron",
|
|
21
|
+
"aria-hidden": true,
|
|
22
|
+
className: cn("size-4", disabled && "opacity-50", className),
|
|
23
|
+
...props
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function CalendarPreviousMonthButton(props) {
|
|
27
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
28
|
+
"data-slot": "calendar-previous-month",
|
|
29
|
+
variant: "outline",
|
|
30
|
+
size: "icon-sm",
|
|
31
|
+
...props
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function CalendarNextMonthButton(props) {
|
|
35
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
36
|
+
"data-slot": "calendar-next-month",
|
|
37
|
+
variant: "outline",
|
|
38
|
+
size: "icon-sm",
|
|
39
|
+
...props
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* One day cell's button. Selection and range state are exposed as data
|
|
44
|
+
* attributes so the classes below (and a consumer's) can paint them; the
|
|
45
|
+
* `today` attribute is only set when the day is not selected, so the soft
|
|
46
|
+
* fill never competes with the selected fill.
|
|
47
|
+
*/
|
|
48
|
+
function CalendarDayButton({ className, day, modifiers, ...props }) {
|
|
49
|
+
const ref = React.useRef(null);
|
|
50
|
+
React.useEffect(() => {
|
|
51
|
+
if (modifiers.focused) ref.current?.focus();
|
|
52
|
+
}, [modifiers.focused]);
|
|
53
|
+
const inRange = modifiers.range_start || modifiers.range_end || modifiers.range_middle;
|
|
54
|
+
const selectedSingle = modifiers.selected && !inRange;
|
|
55
|
+
const filled = selectedSingle || modifiers.range_start || modifiers.range_end;
|
|
56
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
57
|
+
ref,
|
|
58
|
+
"data-slot": "calendar-day-button",
|
|
59
|
+
"data-day": day.isoDate,
|
|
60
|
+
"data-selected-single": selectedSingle || void 0,
|
|
61
|
+
"data-range-start": modifiers.range_start || void 0,
|
|
62
|
+
"data-range-end": modifiers.range_end || void 0,
|
|
63
|
+
"data-range-middle": modifiers.range_middle && !filled || void 0,
|
|
64
|
+
"data-today": modifiers.today && !modifiers.selected || void 0,
|
|
65
|
+
variant: "ghost",
|
|
66
|
+
size: "icon-sm",
|
|
67
|
+
className: cn("size-8 font-normal text-[length:var(--ds-text-caption-lg)] text-[color:var(--ds-foreground)]", "rounded-[var(--ds-radius-sm)] leading-none", "data-[today]:bg-[var(--ds-primary-soft)] data-[today]:text-[color:var(--ds-primary-soft-foreground)]", "data-[range-middle]:rounded-none data-[range-middle]:bg-[var(--ds-primary-soft)] data-[range-middle]:text-[color:var(--ds-primary-soft-foreground)] data-[range-middle]:hover:bg-[var(--ds-primary-soft)] data-[range-middle]:hover:brightness-95", "data-[selected-single]:bg-[var(--ds-primary)] data-[selected-single]:text-[color:var(--ds-primary-foreground)] data-[selected-single]:hover:bg-[var(--ds-primary-hover)] data-[selected-single]:hover:text-[color:var(--ds-primary-foreground)]", "data-[range-start]:bg-[var(--ds-primary)] data-[range-start]:text-[color:var(--ds-primary-foreground)] data-[range-start]:hover:bg-[var(--ds-primary-hover)] data-[range-start]:hover:text-[color:var(--ds-primary-foreground)]", "data-[range-end]:bg-[var(--ds-primary)] data-[range-end]:text-[color:var(--ds-primary-foreground)] data-[range-end]:hover:bg-[var(--ds-primary-hover)] data-[range-end]:hover:text-[color:var(--ds-primary-foreground)]", "group-data-[outside]/day:text-[color:var(--ds-text-tertiary)]", "group-data-[disabled]/day:text-[color:var(--ds-text-disabled)] group-data-[disabled]/day:opacity-50", className),
|
|
68
|
+
...props
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
function Calendar({ className, classNames, components, showOutsideDays = true, captionLayout = "label", formatters, ...props }) {
|
|
72
|
+
const defaults = getDefaultClassNames();
|
|
73
|
+
return /* @__PURE__ */ jsx(DayPicker, {
|
|
74
|
+
showOutsideDays,
|
|
75
|
+
captionLayout,
|
|
76
|
+
className: cn("w-fit p-3 text-[color:var(--ds-foreground)]", className),
|
|
77
|
+
formatters: {
|
|
78
|
+
formatMonthDropdown: (date) => date.toLocaleString("default", { month: "short" }),
|
|
79
|
+
...formatters
|
|
80
|
+
},
|
|
81
|
+
classNames: {
|
|
82
|
+
root: cn("w-fit", defaults.root),
|
|
83
|
+
months: cn("relative flex flex-col gap-4 md:flex-row", defaults.months),
|
|
84
|
+
month: cn("flex w-full flex-col gap-3", defaults.month),
|
|
85
|
+
nav: cn("absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1", defaults.nav),
|
|
86
|
+
button_previous: cn("aria-disabled:pointer-events-none aria-disabled:opacity-50", defaults.button_previous),
|
|
87
|
+
button_next: cn("aria-disabled:pointer-events-none aria-disabled:opacity-50", defaults.button_next),
|
|
88
|
+
month_caption: cn("flex h-8 w-full items-center justify-center px-9", defaults.month_caption),
|
|
89
|
+
caption_label: cn("select-none font-medium text-[length:var(--ds-text-body-sm)] text-[color:var(--ds-foreground)]", captionLayout !== "label" && "flex h-8 items-center gap-1 rounded-[var(--ds-radius-sm)] pl-2 pr-1 [&>svg]:size-3.5 [&>svg]:text-[color:var(--ds-muted-foreground)]", defaults.caption_label),
|
|
90
|
+
dropdowns: cn("flex h-8 w-full items-center justify-center gap-1.5 font-medium text-[length:var(--ds-text-body-sm)]", defaults.dropdowns),
|
|
91
|
+
dropdown_root: cn("relative rounded-[var(--ds-radius-sm)] border border-[var(--ds-border)] bg-[var(--ds-muted)]", "has-focus-visible:border-[var(--ds-ring)] has-focus-visible:ring-[3px] has-focus-visible:ring-[var(--ds-ring)]/40", defaults.dropdown_root),
|
|
92
|
+
dropdown: cn("absolute inset-0 cursor-pointer opacity-0", defaults.dropdown),
|
|
93
|
+
month_grid: cn("w-full border-collapse", defaults.month_grid),
|
|
94
|
+
weekdays: cn("flex", defaults.weekdays),
|
|
95
|
+
weekday: cn("flex-1 select-none font-normal text-[length:var(--ds-text-caption)] text-[color:var(--ds-muted-foreground)]", defaults.weekday),
|
|
96
|
+
week: cn("mt-1 flex w-full", defaults.week),
|
|
97
|
+
week_number_header: cn("w-8 select-none", defaults.week_number_header),
|
|
98
|
+
week_number: cn("select-none text-[length:var(--ds-text-caption)] text-[color:var(--ds-muted-foreground)]", defaults.week_number),
|
|
99
|
+
day: cn("group/day relative aspect-square size-8 select-none p-0 text-center", defaults.day),
|
|
100
|
+
range_start: cn("rounded-l-[var(--ds-radius-sm)] bg-[var(--ds-primary-soft)]", defaults.range_start),
|
|
101
|
+
range_middle: cn("rounded-none bg-[var(--ds-primary-soft)]", defaults.range_middle),
|
|
102
|
+
range_end: cn("rounded-r-[var(--ds-radius-sm)] bg-[var(--ds-primary-soft)]", defaults.range_end),
|
|
103
|
+
today: defaults.today,
|
|
104
|
+
outside: defaults.outside,
|
|
105
|
+
disabled: defaults.disabled,
|
|
106
|
+
hidden: cn("invisible", defaults.hidden),
|
|
107
|
+
...classNames
|
|
108
|
+
},
|
|
109
|
+
components: {
|
|
110
|
+
Root: CalendarRoot,
|
|
111
|
+
Chevron: CalendarChevron,
|
|
112
|
+
PreviousMonthButton: CalendarPreviousMonthButton,
|
|
113
|
+
NextMonthButton: CalendarNextMonthButton,
|
|
114
|
+
DayButton: CalendarDayButton,
|
|
115
|
+
...components
|
|
116
|
+
},
|
|
117
|
+
...props
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
//#endregion
|
|
121
|
+
export { Calendar, CalendarDayButton };
|
|
122
|
+
|
|
123
|
+
//# sourceMappingURL=calendar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar.js","names":[],"sources":["../../src/components/calendar.tsx"],"sourcesContent":["\"use client\";\n\nimport { ChevronDown, ChevronLeft, ChevronRight, ChevronUp } from \"lucide-react\";\nimport * as React from \"react\";\nimport {\n DayPicker,\n getDefaultClassNames,\n type ChevronProps,\n type DayButtonProps,\n type DayPickerProps,\n type NextMonthButtonProps,\n type PreviousMonthButtonProps,\n type RootProps,\n} from \"react-day-picker\";\nimport { Button } from \"@/components/button\";\nimport { cn } from \"@/lib/cn\";\n\n/**\n * Calendar.\n *\n * The shadcn Calendar shape over react-day-picker 10. The library's stylesheet\n * is not imported; every class comes from the `classNames` map below and every\n * visual value in it is a cortena-design token. Structure (nav, caption, grid,\n * dropdown caption) is DayPicker's; the day cells, nav buttons and chevrons are\n * swapped for our Button and lucide icons through `components`.\n *\n * `showOutsideDays` defaults to true and `captionLayout` to `\"label\"`; pass\n * `captionLayout=\"dropdown\"` for native month/year selects in the caption.\n */\nexport type CalendarProps = DayPickerProps;\n\nfunction CalendarRoot({ className, rootRef, ...props }: RootProps) {\n return <div data-slot=\"calendar\" ref={rootRef} className={className} {...props} />;\n}\n\nfunction CalendarChevron({ className, orientation, size: _size, disabled, ...props }: ChevronProps) {\n const Icon =\n orientation === \"left\"\n ? ChevronLeft\n : orientation === \"right\"\n ? ChevronRight\n : orientation === \"up\"\n ? ChevronUp\n : ChevronDown;\n return (\n <Icon\n data-slot=\"calendar-chevron\"\n aria-hidden\n className={cn(\"size-4\", disabled && \"opacity-50\", className)}\n {...props}\n />\n );\n}\n\nfunction CalendarPreviousMonthButton(props: PreviousMonthButtonProps) {\n return <Button data-slot=\"calendar-previous-month\" variant=\"outline\" size=\"icon-sm\" {...props} />;\n}\n\nfunction CalendarNextMonthButton(props: NextMonthButtonProps) {\n return <Button data-slot=\"calendar-next-month\" variant=\"outline\" size=\"icon-sm\" {...props} />;\n}\n\n/**\n * One day cell's button. Selection and range state are exposed as data\n * attributes so the classes below (and a consumer's) can paint them; the\n * `today` attribute is only set when the day is not selected, so the soft\n * fill never competes with the selected fill.\n */\nfunction CalendarDayButton({ className, day, modifiers, ...props }: DayButtonProps) {\n const ref = React.useRef<HTMLButtonElement>(null);\n React.useEffect(() => {\n if (modifiers.focused) ref.current?.focus();\n }, [modifiers.focused]);\n\n const inRange = modifiers.range_start || modifiers.range_end || modifiers.range_middle;\n const selectedSingle = modifiers.selected && !inRange;\n const filled = selectedSingle || modifiers.range_start || modifiers.range_end;\n\n return (\n <Button\n ref={ref}\n data-slot=\"calendar-day-button\"\n data-day={day.isoDate}\n data-selected-single={selectedSingle || undefined}\n data-range-start={modifiers.range_start || undefined}\n data-range-end={modifiers.range_end || undefined}\n data-range-middle={(modifiers.range_middle && !filled) || undefined}\n data-today={(modifiers.today && !modifiers.selected) || undefined}\n variant=\"ghost\"\n size=\"icon-sm\"\n className={cn(\n \"size-8 font-normal text-[length:var(--ds-text-caption-lg)] text-[color:var(--ds-foreground)]\",\n \"rounded-[var(--ds-radius-sm)] leading-none\",\n // today: soft fill from the primary tint\n \"data-[today]:bg-[var(--ds-primary-soft)] data-[today]:text-[color:var(--ds-primary-soft-foreground)]\",\n // range interior: soft fill, square so the run reads as one band\n \"data-[range-middle]:rounded-none data-[range-middle]:bg-[var(--ds-primary-soft)] data-[range-middle]:text-[color:var(--ds-primary-soft-foreground)] data-[range-middle]:hover:bg-[var(--ds-primary-soft)] data-[range-middle]:hover:brightness-95\",\n // selected day and range ends: solid primary\n \"data-[selected-single]:bg-[var(--ds-primary)] data-[selected-single]:text-[color:var(--ds-primary-foreground)] data-[selected-single]:hover:bg-[var(--ds-primary-hover)] data-[selected-single]:hover:text-[color:var(--ds-primary-foreground)]\",\n \"data-[range-start]:bg-[var(--ds-primary)] data-[range-start]:text-[color:var(--ds-primary-foreground)] data-[range-start]:hover:bg-[var(--ds-primary-hover)] data-[range-start]:hover:text-[color:var(--ds-primary-foreground)]\",\n \"data-[range-end]:bg-[var(--ds-primary)] data-[range-end]:text-[color:var(--ds-primary-foreground)] data-[range-end]:hover:bg-[var(--ds-primary-hover)] data-[range-end]:hover:text-[color:var(--ds-primary-foreground)]\",\n // the cell's own flags, read from the parent <td>\n \"group-data-[outside]/day:text-[color:var(--ds-text-tertiary)]\",\n \"group-data-[disabled]/day:text-[color:var(--ds-text-disabled)] group-data-[disabled]/day:opacity-50\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction Calendar({\n className,\n classNames,\n components,\n showOutsideDays = true,\n captionLayout = \"label\",\n formatters,\n ...props\n}: CalendarProps) {\n const defaults = getDefaultClassNames();\n return (\n <DayPicker\n showOutsideDays={showOutsideDays}\n captionLayout={captionLayout}\n className={cn(\"w-fit p-3 text-[color:var(--ds-foreground)]\", className)}\n formatters={{\n formatMonthDropdown: (date) => date.toLocaleString(\"default\", { month: \"short\" }),\n ...formatters,\n }}\n classNames={{\n root: cn(\"w-fit\", defaults.root),\n months: cn(\"relative flex flex-col gap-4 md:flex-row\", defaults.months),\n month: cn(\"flex w-full flex-col gap-3\", defaults.month),\n nav: cn(\"absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1\", defaults.nav),\n button_previous: cn(\"aria-disabled:pointer-events-none aria-disabled:opacity-50\", defaults.button_previous),\n button_next: cn(\"aria-disabled:pointer-events-none aria-disabled:opacity-50\", defaults.button_next),\n month_caption: cn(\"flex h-8 w-full items-center justify-center px-9\", defaults.month_caption),\n caption_label: cn(\n \"select-none font-medium text-[length:var(--ds-text-body-sm)] text-[color:var(--ds-foreground)]\",\n captionLayout !== \"label\" &&\n \"flex h-8 items-center gap-1 rounded-[var(--ds-radius-sm)] pl-2 pr-1 [&>svg]:size-3.5 [&>svg]:text-[color:var(--ds-muted-foreground)]\",\n defaults.caption_label,\n ),\n dropdowns: cn(\n \"flex h-8 w-full items-center justify-center gap-1.5 font-medium text-[length:var(--ds-text-body-sm)]\",\n defaults.dropdowns,\n ),\n dropdown_root: cn(\n \"relative rounded-[var(--ds-radius-sm)] border border-[var(--ds-border)] bg-[var(--ds-muted)]\",\n \"has-focus-visible:border-[var(--ds-ring)] has-focus-visible:ring-[3px] has-focus-visible:ring-[var(--ds-ring)]/40\",\n defaults.dropdown_root,\n ),\n dropdown: cn(\"absolute inset-0 cursor-pointer opacity-0\", defaults.dropdown),\n month_grid: cn(\"w-full border-collapse\", defaults.month_grid),\n weekdays: cn(\"flex\", defaults.weekdays),\n weekday: cn(\n \"flex-1 select-none font-normal text-[length:var(--ds-text-caption)] text-[color:var(--ds-muted-foreground)]\",\n defaults.weekday,\n ),\n week: cn(\"mt-1 flex w-full\", defaults.week),\n week_number_header: cn(\"w-8 select-none\", defaults.week_number_header),\n week_number: cn(\n \"select-none text-[length:var(--ds-text-caption)] text-[color:var(--ds-muted-foreground)]\",\n defaults.week_number,\n ),\n day: cn(\n \"group/day relative aspect-square size-8 select-none p-0 text-center\",\n defaults.day,\n ),\n range_start: cn(\"rounded-l-[var(--ds-radius-sm)] bg-[var(--ds-primary-soft)]\", defaults.range_start),\n range_middle: cn(\"rounded-none bg-[var(--ds-primary-soft)]\", defaults.range_middle),\n range_end: cn(\"rounded-r-[var(--ds-radius-sm)] bg-[var(--ds-primary-soft)]\", defaults.range_end),\n today: defaults.today,\n outside: defaults.outside,\n disabled: defaults.disabled,\n hidden: cn(\"invisible\", defaults.hidden),\n ...classNames,\n }}\n components={{\n Root: CalendarRoot,\n Chevron: CalendarChevron,\n PreviousMonthButton: CalendarPreviousMonthButton,\n NextMonthButton: CalendarNextMonthButton,\n DayButton: CalendarDayButton,\n ...components,\n }}\n {...props}\n />\n );\n}\n\nexport { Calendar, CalendarDayButton };\n"],"mappings":";;;;;;;;;AA+BA,SAAS,aAAa,EAAE,WAAW,SAAS,GAAG,SAAoB;CACjE,OAAO,oBAAC,OAAD;EAAK,aAAU;EAAW,KAAK;EAAoB;EAAW,GAAI;CAAQ,CAAA;AACnF;AAEA,SAAS,gBAAgB,EAAE,WAAW,aAAa,MAAM,OAAO,UAAU,GAAG,SAAuB;CASlG,OACE,oBARA,gBAAgB,SACZ,cACA,gBAAgB,UACd,eACA,gBAAgB,OACd,YACA,aAER;EACE,aAAU;EACV,eAAA;EACA,WAAW,GAAG,UAAU,YAAY,cAAc,SAAS;EAC3D,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,4BAA4B,OAAiC;CACpE,OAAO,oBAAC,QAAD;EAAQ,aAAU;EAA0B,SAAQ;EAAU,MAAK;EAAU,GAAI;CAAQ,CAAA;AAClG;AAEA,SAAS,wBAAwB,OAA6B;CAC5D,OAAO,oBAAC,QAAD;EAAQ,aAAU;EAAsB,SAAQ;EAAU,MAAK;EAAU,GAAI;CAAQ,CAAA;AAC9F;;;;;;;AAQA,SAAS,kBAAkB,EAAE,WAAW,KAAK,WAAW,GAAG,SAAyB;CAClF,MAAM,MAAM,MAAM,OAA0B,IAAI;CAChD,MAAM,gBAAgB;EACpB,IAAI,UAAU,SAAS,IAAI,SAAS,MAAM;CAC5C,GAAG,CAAC,UAAU,OAAO,CAAC;CAEtB,MAAM,UAAU,UAAU,eAAe,UAAU,aAAa,UAAU;CAC1E,MAAM,iBAAiB,UAAU,YAAY,CAAC;CAC9C,MAAM,SAAS,kBAAkB,UAAU,eAAe,UAAU;CAEpE,OACE,oBAAC,QAAD;EACO;EACL,aAAU;EACV,YAAU,IAAI;EACd,wBAAsB,kBAAkB,KAAA;EACxC,oBAAkB,UAAU,eAAe,KAAA;EAC3C,kBAAgB,UAAU,aAAa,KAAA;EACvC,qBAAoB,UAAU,gBAAgB,CAAC,UAAW,KAAA;EAC1D,cAAa,UAAU,SAAS,CAAC,UAAU,YAAa,KAAA;EACxD,SAAQ;EACR,MAAK;EACL,WAAW,GACT,gGACA,8CAEA,wGAEA,qPAEA,mPACA,mOACA,2NAEA,iEACA,uGACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,SAAS,EAChB,WACA,YACA,YACA,kBAAkB,MAClB,gBAAgB,SAChB,YACA,GAAG,SACa;CAChB,MAAM,WAAW,qBAAqB;CACtC,OACE,oBAAC,WAAD;EACmB;EACF;EACf,WAAW,GAAG,+CAA+C,SAAS;EACtE,YAAY;GACV,sBAAsB,SAAS,KAAK,eAAe,WAAW,EAAE,OAAO,QAAQ,CAAC;GAChF,GAAG;EACL;EACA,YAAY;GACV,MAAM,GAAG,SAAS,SAAS,IAAI;GAC/B,QAAQ,GAAG,4CAA4C,SAAS,MAAM;GACtE,OAAO,GAAG,8BAA8B,SAAS,KAAK;GACtD,KAAK,GAAG,2EAA2E,SAAS,GAAG;GAC/F,iBAAiB,GAAG,8DAA8D,SAAS,eAAe;GAC1G,aAAa,GAAG,8DAA8D,SAAS,WAAW;GAClG,eAAe,GAAG,oDAAoD,SAAS,aAAa;GAC5F,eAAe,GACb,kGACA,kBAAkB,WAChB,wIACF,SAAS,aACX;GACA,WAAW,GACT,wGACA,SAAS,SACX;GACA,eAAe,GACb,gGACA,qHACA,SAAS,aACX;GACA,UAAU,GAAG,6CAA6C,SAAS,QAAQ;GAC3E,YAAY,GAAG,0BAA0B,SAAS,UAAU;GAC5D,UAAU,GAAG,QAAQ,SAAS,QAAQ;GACtC,SAAS,GACP,+GACA,SAAS,OACX;GACA,MAAM,GAAG,oBAAoB,SAAS,IAAI;GAC1C,oBAAoB,GAAG,mBAAmB,SAAS,kBAAkB;GACrE,aAAa,GACX,4FACA,SAAS,WACX;GACA,KAAK,GACH,uEACA,SAAS,GACX;GACA,aAAa,GAAG,+DAA+D,SAAS,WAAW;GACnG,cAAc,GAAG,4CAA4C,SAAS,YAAY;GAClF,WAAW,GAAG,+DAA+D,SAAS,SAAS;GAC/F,OAAO,SAAS;GAChB,SAAS,SAAS;GAClB,UAAU,SAAS;GACnB,QAAQ,GAAG,aAAa,SAAS,MAAM;GACvC,GAAG;EACL;EACA,YAAY;GACV,MAAM;GACN,SAAS;GACT,qBAAqB;GACrB,iBAAiB;GACjB,WAAW;GACX,GAAG;EACL;EACA,GAAI;CACL,CAAA;AAEL"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { RenderProp } from "../lib/render.js";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
//#region src/components/card.d.ts
|
|
5
|
+
export interface CardProps extends React.ComponentProps<"div"> {
|
|
6
|
+
/** Lift the border and surface on hover, for clickable cards. */
|
|
7
|
+
hover?: boolean;
|
|
8
|
+
/** Draw the border in the ring colour, for a selected or highlighted card. */
|
|
9
|
+
accent?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Replace the rendered `<div>` with another element, so a card can *be* the
|
|
12
|
+
* landmark rather than sit inside a wrapper that is one:
|
|
13
|
+
* `render={<aside />}` for a sidebar panel, `render={<section />}` (with an
|
|
14
|
+
* `aria-labelledby` pointing at its title) for a labelled region,
|
|
15
|
+
* `render={<article />}` for a self-contained item in a feed. Props set on
|
|
16
|
+
* the passed element come through; the card's own styling wins.
|
|
17
|
+
*/
|
|
18
|
+
render?: RenderProp;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Card — the bordered surface everything else sits on. `render` changes the
|
|
22
|
+
* element without changing the look, which is how a card becomes a landmark.
|
|
23
|
+
*/
|
|
24
|
+
declare function Card({ className, hover, accent, render, children, ...props }: CardProps): React.ReactElement<unknown, string | React.JSXElementConstructor<any>>;
|
|
25
|
+
declare function CardHeader({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
26
|
+
declare function CardTitle({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
27
|
+
declare function CardDescription({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
28
|
+
declare function CardContent({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
29
|
+
declare function CardFooter({ className, ...props }: React.ComponentProps<"div">): React.JSX.Element;
|
|
30
|
+
//#endregion
|
|
31
|
+
export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle };
|
|
32
|
+
//# sourceMappingURL=card.d.ts.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
import { cn } from "../lib/cn.js";
|
|
4
|
+
import { renderWith } from "../lib/render.js";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
//#region src/components/card.tsx
|
|
7
|
+
/**
|
|
8
|
+
* Card — the bordered surface everything else sits on. `render` changes the
|
|
9
|
+
* element without changing the look, which is how a card becomes a landmark.
|
|
10
|
+
*/
|
|
11
|
+
function Card({ className, hover, accent, render, children, ...props }) {
|
|
12
|
+
return renderWith(render, {
|
|
13
|
+
"data-slot": "card",
|
|
14
|
+
"data-accent": accent ? "" : void 0,
|
|
15
|
+
...props,
|
|
16
|
+
className: cn("flex flex-col rounded-[var(--ds-radius-lg)] border bg-[var(--ds-card)] text-[color:var(--ds-foreground)]", "transition-[border-color,background-color] duration-[var(--ds-duration-fast)] ease-[var(--ds-ease-out)]", accent ? "border-[var(--ds-ring)]" : "border-[var(--ds-border-subtle)]", hover && "hover:border-[var(--ds-border)] hover:bg-[var(--ds-popover)]", className)
|
|
17
|
+
}, children, "div");
|
|
18
|
+
}
|
|
19
|
+
function CardHeader({ className, ...props }) {
|
|
20
|
+
return /* @__PURE__ */ jsx("div", {
|
|
21
|
+
"data-slot": "card-header",
|
|
22
|
+
className: cn("flex flex-col gap-1.5 p-5 pb-3", className),
|
|
23
|
+
...props
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function CardTitle({ className, ...props }) {
|
|
27
|
+
return /* @__PURE__ */ jsx("div", {
|
|
28
|
+
"data-slot": "card-title",
|
|
29
|
+
className: cn("text-[length:var(--ds-text-body-md)] font-semibold", "leading-[var(--ds-text-h1--line-height)] tracking-[var(--ds-text-h1--letter-spacing)]", "text-[color:var(--ds-foreground)]", className),
|
|
30
|
+
...props
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function CardDescription({ className, ...props }) {
|
|
34
|
+
return /* @__PURE__ */ jsx("div", {
|
|
35
|
+
"data-slot": "card-description",
|
|
36
|
+
className: cn("text-[length:var(--ds-text-caption-lg)] text-[color:var(--ds-muted-foreground)]", className),
|
|
37
|
+
...props
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function CardContent({ className, ...props }) {
|
|
41
|
+
return /* @__PURE__ */ jsx("div", {
|
|
42
|
+
"data-slot": "card-content",
|
|
43
|
+
className: cn("p-5 pt-0", className),
|
|
44
|
+
...props
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function CardFooter({ className, ...props }) {
|
|
48
|
+
return /* @__PURE__ */ jsx("div", {
|
|
49
|
+
"data-slot": "card-footer",
|
|
50
|
+
className: cn("flex items-center gap-2 border-t border-[var(--ds-border-subtle)] p-4", className),
|
|
51
|
+
...props
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
export { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle };
|
|
56
|
+
|
|
57
|
+
//# sourceMappingURL=card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"card.js","names":[],"sources":["../../src/components/card.tsx"],"sourcesContent":["\"use client\";\n\nimport type * as React from \"react\";\nimport { cn } from \"@/lib/cn\";\nimport { renderWith, type RenderProp } from \"@/lib/render\";\n\nexport interface CardProps extends React.ComponentProps<\"div\"> {\n /** Lift the border and surface on hover, for clickable cards. */\n hover?: boolean;\n /** Draw the border in the ring colour, for a selected or highlighted card. */\n accent?: boolean;\n /**\n * Replace the rendered `<div>` with another element, so a card can *be* the\n * landmark rather than sit inside a wrapper that is one:\n * `render={<aside />}` for a sidebar panel, `render={<section />}` (with an\n * `aria-labelledby` pointing at its title) for a labelled region,\n * `render={<article />}` for a self-contained item in a feed. Props set on\n * the passed element come through; the card's own styling wins.\n */\n render?: RenderProp;\n}\n\n/**\n * Card — the bordered surface everything else sits on. `render` changes the\n * element without changing the look, which is how a card becomes a landmark.\n */\nfunction Card({ className, hover, accent, render, children, ...props }: CardProps) {\n return renderWith(\n render,\n {\n // data-slot first: SectionCard (and any other composer) overrides it.\n \"data-slot\": \"card\",\n \"data-accent\": accent ? \"\" : undefined,\n ...props,\n className: cn(\n \"flex flex-col rounded-[var(--ds-radius-lg)] border bg-[var(--ds-card)] text-[color:var(--ds-foreground)]\",\n \"transition-[border-color,background-color] duration-[var(--ds-duration-fast)] ease-[var(--ds-ease-out)]\",\n accent ? \"border-[var(--ds-ring)]\" : \"border-[var(--ds-border-subtle)]\",\n hover && \"hover:border-[var(--ds-border)] hover:bg-[var(--ds-popover)]\",\n className,\n ),\n },\n children,\n \"div\",\n );\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\"flex flex-col gap-1.5 p-5 pb-3\", className)}\n {...props}\n />\n );\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn(\n \"text-[length:var(--ds-text-body-md)] font-semibold\",\n \"leading-[var(--ds-text-h1--line-height)] tracking-[var(--ds-text-h1--letter-spacing)]\",\n \"text-[color:var(--ds-foreground)]\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn(\n \"text-[length:var(--ds-text-caption-lg)] text-[color:var(--ds-muted-foreground)]\",\n className,\n )}\n {...props}\n />\n );\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return <div data-slot=\"card-content\" className={cn(\"p-5 pt-0\", className)} {...props} />;\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn(\n \"flex items-center gap-2 border-t border-[var(--ds-border-subtle)] p-4\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter };\n"],"mappings":";;;;;;;;;;AA0BA,SAAS,KAAK,EAAE,WAAW,OAAO,QAAQ,QAAQ,UAAU,GAAG,SAAoB;CACjF,OAAO,WACL,QACA;EAEE,aAAa;EACb,eAAe,SAAS,KAAK,KAAA;EAC7B,GAAG;EACH,WAAW,GACT,4GACA,2GACA,SAAS,4BAA4B,oCACrC,SAAS,gEACT,SACF;CACF,GACA,UACA,KACF;AACF;AAEA,SAAS,WAAW,EAAE,WAAW,GAAG,SAAsC;CACxE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GAAG,kCAAkC,SAAS;EACzD,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,UAAU,EAAE,WAAW,GAAG,SAAsC;CACvE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GACT,sDACA,yFACA,qCACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,gBAAgB,EAAE,WAAW,GAAG,SAAsC;CAC7E,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GACT,mFACA,SACF;EACA,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAsC;CACzE,OAAO,oBAAC,OAAD;EAAK,aAAU;EAAe,WAAW,GAAG,YAAY,SAAS;EAAG,GAAI;CAAQ,CAAA;AACzF;AAEA,SAAS,WAAW,EAAE,WAAW,GAAG,SAAsC;CACxE,OACE,oBAAC,OAAD;EACE,aAAU;EACV,WAAW,GACT,yEACA,SACF;EACA,GAAI;CACL,CAAA;AAEL"}
|