@dirstack/ui 1.1.0 → 1.3.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 +17 -1
- package/dist/components/animated-number.d.ts +1 -1
- package/dist/components/animated-number.js +1 -1
- package/dist/components/badge.d.ts +1 -1
- package/dist/components/bar-list.d.ts +57 -0
- package/dist/components/bar-list.d.ts.map +1 -0
- package/dist/components/bar-list.js +117 -0
- package/dist/components/bar-list.js.map +1 -0
- package/dist/components/breakdown-card.d.ts +31 -0
- package/dist/components/breakdown-card.d.ts.map +1 -0
- package/dist/components/breakdown-card.js +41 -0
- package/dist/components/breakdown-card.js.map +1 -0
- package/dist/components/button.d.ts +1 -1
- package/dist/components/button.js +3 -3
- package/dist/components/card.d.ts +1 -1
- package/dist/components/detail-row.d.ts +1 -1
- package/dist/components/detail-row.js +2 -2
- package/dist/components/dialog.d.ts +1 -1
- package/dist/components/dialog.js +2 -2
- package/dist/components/empty-state.js +1 -1
- package/dist/components/form-section.d.ts +1 -1
- package/dist/components/form.d.ts +1 -1
- package/dist/components/form.js +2 -2
- package/dist/components/heading.d.ts +1 -1
- package/dist/components/input.js +1 -1
- package/dist/components/menu.js +1 -1
- package/dist/components/nav-button.js +1 -1
- package/dist/components/nav.js +1 -1
- package/dist/components/pagination.js +1 -1
- package/dist/components/ping.d.ts +38 -0
- package/dist/components/ping.d.ts.map +1 -0
- package/dist/components/ping.js +30 -0
- package/dist/components/ping.js.map +1 -0
- package/dist/components/popover.js +1 -1
- package/dist/components/search-input.js +1 -1
- package/dist/components/section-header.d.ts +2 -2
- package/dist/components/section-header.js +3 -3
- package/dist/components/select.d.ts.map +1 -1
- package/dist/components/select.js +2 -2
- package/dist/components/select.js.map +1 -1
- package/dist/components/stat-strip.d.ts +6 -2
- package/dist/components/stat-strip.d.ts.map +1 -1
- package/dist/components/stat-strip.js +4 -3
- package/dist/components/stat-strip.js.map +1 -1
- package/dist/components/tabs.js +1 -1
- package/dist/components/theme.d.ts +25 -0
- package/dist/components/theme.d.ts.map +1 -0
- package/dist/components/theme.js +128 -0
- package/dist/components/theme.js.map +1 -0
- package/dist/components/toaster.js +1 -1
- package/dist/components/tooltip.js +1 -1
- package/dist/components/view-tabs.d.ts +26 -0
- package/dist/components/view-tabs.d.ts.map +1 -0
- package/dist/components/view-tabs.js +27 -0
- package/dist/components/view-tabs.js.map +1 -0
- package/dist/lib/icons.d.ts +2 -1
- package/dist/lib/icons.d.ts.map +1 -1
- package/dist/lib/icons.js +4 -3
- package/dist/lib/icons.js.map +1 -1
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -23,7 +23,17 @@ export function Example() {
|
|
|
23
23
|
}
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
The shared helpers live at fixed subpaths: `@dirstack/ui/variants` (`cn`, `variants`, `VariantProps`), `@dirstack/ui/classes` (shared class strings), `@dirstack/ui/slot`,
|
|
26
|
+
The shared helpers live at fixed subpaths: `@dirstack/ui/variants` (`cn`, `variants`, `VariantProps`), `@dirstack/ui/classes` (shared class strings), `@dirstack/ui/slot`, `@dirstack/ui/interactive` (`interactiveVariants`), and `@dirstack/ui/animation` (`ANIMATION_DURATION`, `ANIMATION_EASING` — the shared motion timing, for syncing your own transitions with the library's).
|
|
27
|
+
|
|
28
|
+
## Components
|
|
29
|
+
|
|
30
|
+
Every file in `src/components` is its own subpath (`@dirstack/ui/<name>`):
|
|
31
|
+
|
|
32
|
+
- **Layout**: `page`, `stack`, `heading`, `section-header`, `card`, `detail-row`, `steps`, `nav`, `nav-button`
|
|
33
|
+
- **Forms**: `form`, `form-section`, `form-row`, `label`, `input`, `number-input`, `search-input`, `textarea`, `select`, `switch`, `copy-input`
|
|
34
|
+
- **Actions & overlays**: `button`, `copy-button`, `menu`, `popover`, `dialog`, `tooltip`, `tabs`, `toaster`, `kbd`
|
|
35
|
+
- **Display & feedback**: `badge`, `callout`, `empty-state`, `skeleton`, `ping` (status dot with optional pulse), `avatar`, `entity-avatar`, `pagination`
|
|
36
|
+
- **Dashboard**: `animated-number`, `chart`, `stat-strip`, `bar-list` (ranked share bars, `BarList.Row` / `BarList.Skeleton`), `breakdown-card` (titled panel with optional tabs and footer), `view-tabs` (tab switcher bound to a `?view=` param), `theme` (`useTheme` + `ThemeSelect`)
|
|
27
37
|
|
|
28
38
|
## Styles
|
|
29
39
|
|
|
@@ -38,6 +48,12 @@ That stylesheet carries the full design-token set (`--color-*` mirroring the sha
|
|
|
38
48
|
|
|
39
49
|
Every color is a `light-dark()` pair driven by `color-scheme`: left alone it follows the OS, and `data-theme="dark"` or `data-theme="light"` on `<html>` forces one. The theme expects the consumer to load the "Inter Variable" font; without it, type falls back to the system stack.
|
|
40
50
|
|
|
51
|
+
`@dirstack/ui/theme` manages that attribute for you: `useTheme()` returns `[theme, setTheme]` (`"system" | "light" | "dark"`), persists the choice in `localStorage.theme`, keeps tabs in sync, and `ThemeSelect` is a ready-made segmented System / Light / Dark control. The hook applies the stored theme once it mounts; to avoid a flash of the wrong scheme, apply it before first paint with this inline script in `<head>`:
|
|
52
|
+
|
|
53
|
+
```html
|
|
54
|
+
<script>try{var t=localStorage.theme;if(t==="light"||t==="dark")document.documentElement.dataset.theme=t}catch(e){}</script>
|
|
55
|
+
```
|
|
56
|
+
|
|
41
57
|
Override any token in your own CSS to re-theme:
|
|
42
58
|
|
|
43
59
|
```css
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { ANIMATION_EASING } from "../lib/animation.js";
|
|
3
|
-
import NumberFlow, { continuous } from "@number-flow/react";
|
|
4
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
import NumberFlow, { continuous } from "@number-flow/react";
|
|
5
5
|
//#region src/components/animated-number.tsx
|
|
6
6
|
const timing = {
|
|
7
7
|
duration: 500,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { VariantProps } from "../lib/variants.js";
|
|
2
|
-
import { useRender } from "@base-ui/react/use-render";
|
|
3
2
|
import { ReactNode } from "react";
|
|
3
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
4
4
|
//#region src/components/badge.d.ts
|
|
5
5
|
declare const badgeVariants: import("tailwind-variants").TVReturnType<{
|
|
6
6
|
variant: {
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { ComponentProps, ReactNode } from "react";
|
|
2
|
+
import { Format } from "@number-flow/react";
|
|
3
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
4
|
+
//#region src/components/bar-list.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Ranked breakdown list: each row is a label sitting on a soft bar whose width is the row's
|
|
7
|
+
* share of the largest value, measured across the label column, with the value right-aligned
|
|
8
|
+
* beside it. Rows are plain divs by default — a row that links out carries its `href` on the
|
|
9
|
+
* arrow beside the label. Pass `render={<button type="button" />}` (or a link) to make the
|
|
10
|
+
* whole row a click target, e.g. click-to-filter.
|
|
11
|
+
*/
|
|
12
|
+
declare function BarListRoot({ className, ...props }: ComponentProps<"div">): import("react").JSX.Element;
|
|
13
|
+
export type BarListRowProps = Omit<useRender.ComponentProps<"div">, "children"> & {
|
|
14
|
+
/**
|
|
15
|
+
* Row text; string labels truncate.
|
|
16
|
+
*/
|
|
17
|
+
label: ReactNode;
|
|
18
|
+
/**
|
|
19
|
+
* Leading visual (favicon, flag, icon tile), 16px.
|
|
20
|
+
*/
|
|
21
|
+
icon?: ReactNode;
|
|
22
|
+
value: number;
|
|
23
|
+
/**
|
|
24
|
+
* The largest value in the list; the bar spans `value / max` of the row.
|
|
25
|
+
*/
|
|
26
|
+
max: number;
|
|
27
|
+
format?: Format;
|
|
28
|
+
/**
|
|
29
|
+
* An extra figure (revenue, conversion rate) in its own muted column before the value.
|
|
30
|
+
*/
|
|
31
|
+
secondaryValue?: number | string;
|
|
32
|
+
secondaryFormat?: Format;
|
|
33
|
+
/**
|
|
34
|
+
* External URL, shown as an arrow beside the label that opens in a new tab. Don't combine
|
|
35
|
+
* with a `render` that makes the row itself a button or link — nested interactive content.
|
|
36
|
+
*/
|
|
37
|
+
href?: string;
|
|
38
|
+
};
|
|
39
|
+
declare function BarListRow({ label, icon, value, max, format, secondaryValue, secondaryFormat, href, render, className, style, ...props }: BarListRowProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
|
|
40
|
+
export type BarListSkeletonProps = ComponentProps<"div"> & {
|
|
41
|
+
/**
|
|
42
|
+
* Rows to draw, matching the list that replaces it.
|
|
43
|
+
*/
|
|
44
|
+
rows?: number;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Loading stand-in at the exact row height of `BarList.Row`, so swapping in data causes no
|
|
48
|
+
* layout shift.
|
|
49
|
+
*/
|
|
50
|
+
declare function BarListSkeleton({ rows, className, ...props }: BarListSkeletonProps): import("react").JSX.Element;
|
|
51
|
+
declare const BarList: typeof BarListRoot & {
|
|
52
|
+
Row: typeof BarListRow;
|
|
53
|
+
Skeleton: typeof BarListSkeleton;
|
|
54
|
+
};
|
|
55
|
+
//#endregion
|
|
56
|
+
export { BarList };
|
|
57
|
+
//# sourceMappingURL=bar-list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bar-list.d.ts","names":[],"sources":["../../src/components/bar-list.tsx"],"mappings":";;;;;;;;;;;iBAeS,cAAc,cAAc,SAAS,wCAAqB,IAAA;YAMvD,kBAAkB,KAAK,UAAU;;;;EAI3C,OAAO;;;;EAIP,OAAO;EACP;;;;EAIA;EACA,SAAS;;;;EAIT;EACA,kBAAkB;;;;;EAKlB;;iBAGO,aACP,OACA,MACA,OACA,KACA,QACA,gBACA,iBACA,MACA,QACA,WACA,UACG,SACF,kCAAe,+CAAA;YAqEN,uBAAuB;;;;EAIjC;;;;;;iBAOO,kBAAkB,MAAU,cAAc,SAAS,uCAAoB,IAAA;cAmB1E,gBAAO"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { ArrowUpRightIcon } from "../lib/icons.js";
|
|
2
|
+
import { cn } from "../lib/variants.js";
|
|
3
|
+
import { AnimatedNumber } from "./animated-number.js";
|
|
4
|
+
import { Skeleton } from "./skeleton.js";
|
|
5
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
7
|
+
//#region src/components/bar-list.tsx
|
|
8
|
+
/**
|
|
9
|
+
* Ranked breakdown list: each row is a label sitting on a soft bar whose width is the row's
|
|
10
|
+
* share of the largest value, measured across the label column, with the value right-aligned
|
|
11
|
+
* beside it. Rows are plain divs by default — a row that links out carries its `href` on the
|
|
12
|
+
* arrow beside the label. Pass `render={<button type="button" />}` (or a link) to make the
|
|
13
|
+
* whole row a click target, e.g. click-to-filter.
|
|
14
|
+
*/
|
|
15
|
+
function BarListRoot({ className, ...props }) {
|
|
16
|
+
return /* @__PURE__ */ jsx("div", {
|
|
17
|
+
className: cn("flex flex-col gap-1", className),
|
|
18
|
+
...props
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
const rowClasses = "flex h-7.5 w-full items-center gap-3 pr-2.5";
|
|
22
|
+
function BarListRow({ label, icon, value, max, format, secondaryValue, secondaryFormat, href, render, className, style, ...props }) {
|
|
23
|
+
const share = max > 0 ? Math.max(value / max, 0) : 0;
|
|
24
|
+
return useRender({
|
|
25
|
+
render,
|
|
26
|
+
defaultTagName: "div",
|
|
27
|
+
props: {
|
|
28
|
+
className: cn(rowClasses, "group/bar rounded-md text-start text-sm", "[&:is(button,a)]:cursor-pointer [&:is(button,a)]:hover:bg-foreground/3", "focus-visible:outline-[3px] focus-visible:outline-border/50", className),
|
|
29
|
+
style: {
|
|
30
|
+
"--bar-share": share,
|
|
31
|
+
...style
|
|
32
|
+
},
|
|
33
|
+
children: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
34
|
+
/* @__PURE__ */ jsxs("div", {
|
|
35
|
+
className: "relative flex h-full min-w-0 flex-1 items-center gap-2 pl-2.5",
|
|
36
|
+
children: [
|
|
37
|
+
/* @__PURE__ */ jsx("div", {
|
|
38
|
+
"aria-hidden": true,
|
|
39
|
+
className: "absolute inset-y-0 left-0 w-[calc(var(--bar-share)*100%)] min-w-1.5 origin-left animate-fill-bar rounded-md bg-muted transition-[width] duration-500 ease-out-expo"
|
|
40
|
+
}),
|
|
41
|
+
icon && /* @__PURE__ */ jsx("span", {
|
|
42
|
+
className: "relative flex size-4 shrink-0 items-center justify-center",
|
|
43
|
+
children: icon
|
|
44
|
+
}),
|
|
45
|
+
/* @__PURE__ */ jsx("span", {
|
|
46
|
+
className: "relative min-w-0 truncate",
|
|
47
|
+
children: label
|
|
48
|
+
}),
|
|
49
|
+
href && /* @__PURE__ */ jsx("a", {
|
|
50
|
+
href,
|
|
51
|
+
target: "_blank",
|
|
52
|
+
rel: "noreferrer",
|
|
53
|
+
"aria-label": typeof label === "string" ? `Open ${label} website` : "Open website",
|
|
54
|
+
className: "relative flex size-5 shrink-0 items-center justify-center rounded text-muted-foreground hover:text-foreground",
|
|
55
|
+
children: /* @__PURE__ */ jsx(ArrowUpRightIcon, { className: "size-3.5" })
|
|
56
|
+
})
|
|
57
|
+
]
|
|
58
|
+
}),
|
|
59
|
+
secondaryValue !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
60
|
+
className: "min-w-16 shrink-0 text-right text-muted-foreground tabular-nums",
|
|
61
|
+
children: /* @__PURE__ */ jsx(AnimatedNumber, {
|
|
62
|
+
value: secondaryValue,
|
|
63
|
+
format: secondaryFormat
|
|
64
|
+
})
|
|
65
|
+
}),
|
|
66
|
+
/* @__PURE__ */ jsx("span", {
|
|
67
|
+
className: "min-w-12 shrink-0 text-right text-muted-foreground tabular-nums",
|
|
68
|
+
children: /* @__PURE__ */ jsx(AnimatedNumber, {
|
|
69
|
+
value,
|
|
70
|
+
format
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
] }),
|
|
74
|
+
...props
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Label bars step down like a ranked list would, so the swap to data reads as a fill-in
|
|
80
|
+
* rather than a reflow.
|
|
81
|
+
*/
|
|
82
|
+
const skeletonShares = [
|
|
83
|
+
"70%",
|
|
84
|
+
"55%",
|
|
85
|
+
"45%",
|
|
86
|
+
"35%",
|
|
87
|
+
"30%"
|
|
88
|
+
];
|
|
89
|
+
/**
|
|
90
|
+
* Loading stand-in at the exact row height of `BarList.Row`, so swapping in data causes no
|
|
91
|
+
* layout shift.
|
|
92
|
+
*/
|
|
93
|
+
function BarListSkeleton({ rows = 5, className, ...props }) {
|
|
94
|
+
return /* @__PURE__ */ jsx(BarListRoot, {
|
|
95
|
+
"aria-hidden": true,
|
|
96
|
+
className,
|
|
97
|
+
...props,
|
|
98
|
+
children: Array.from({ length: rows }, (_, index) => /* @__PURE__ */ jsxs("div", {
|
|
99
|
+
className: rowClasses,
|
|
100
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
101
|
+
className: "relative h-full min-w-0 flex-1",
|
|
102
|
+
children: /* @__PURE__ */ jsx(Skeleton, {
|
|
103
|
+
className: "absolute inset-y-0 left-0",
|
|
104
|
+
style: { width: skeletonShares[index % skeletonShares.length] }
|
|
105
|
+
})
|
|
106
|
+
}), /* @__PURE__ */ jsx(Skeleton, { className: "h-3.5 w-8 shrink-0" })]
|
|
107
|
+
}, index))
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
const BarList = Object.assign(BarListRoot, {
|
|
111
|
+
Row: BarListRow,
|
|
112
|
+
Skeleton: BarListSkeleton
|
|
113
|
+
});
|
|
114
|
+
//#endregion
|
|
115
|
+
export { BarList };
|
|
116
|
+
|
|
117
|
+
//# sourceMappingURL=bar-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bar-list.js","names":[],"sources":["../../src/components/bar-list.tsx"],"sourcesContent":["import { useRender } from \"@base-ui/react/use-render\"\nimport type { Format } from \"@number-flow/react\"\nimport type { ComponentProps, CSSProperties, ReactNode } from \"react\"\nimport { AnimatedNumber } from \"~/components/animated-number\"\nimport { Skeleton } from \"~/components/skeleton\"\nimport { ArrowUpRightIcon } from \"~/lib/icons\"\nimport { cn } from \"~/lib/variants\"\n\n/**\n * Ranked breakdown list: each row is a label sitting on a soft bar whose width is the row's\n * share of the largest value, measured across the label column, with the value right-aligned\n * beside it. Rows are plain divs by default — a row that links out carries its `href` on the\n * arrow beside the label. Pass `render={<button type=\"button\" />}` (or a link) to make the\n * whole row a click target, e.g. click-to-filter.\n */\nfunction BarListRoot({ className, ...props }: ComponentProps<\"div\">) {\n return <div className={cn(\"flex flex-col gap-1\", className)} {...props} />\n}\n\nconst rowClasses = \"flex h-7.5 w-full items-center gap-3 pr-2.5\"\n\nexport type BarListRowProps = Omit<useRender.ComponentProps<\"div\">, \"children\"> & {\n /**\n * Row text; string labels truncate.\n */\n label: ReactNode\n /**\n * Leading visual (favicon, flag, icon tile), 16px.\n */\n icon?: ReactNode\n value: number\n /**\n * The largest value in the list; the bar spans `value / max` of the row.\n */\n max: number\n format?: Format\n /**\n * An extra figure (revenue, conversion rate) in its own muted column before the value.\n */\n secondaryValue?: number | string\n secondaryFormat?: Format\n /**\n * External URL, shown as an arrow beside the label that opens in a new tab. Don't combine\n * with a `render` that makes the row itself a button or link — nested interactive content.\n */\n href?: string\n}\n\nfunction BarListRow({\n label,\n icon,\n value,\n max,\n format,\n secondaryValue,\n secondaryFormat,\n href,\n render,\n className,\n style,\n ...props\n}: BarListRowProps) {\n const share = max > 0 ? Math.max(value / max, 0) : 0\n\n return useRender({\n render,\n defaultTagName: \"div\",\n props: {\n className: cn(\n rowClasses,\n \"group/bar rounded-md text-start text-sm\",\n // Rendered as a button or link, the row reads as a target: pointer, soft hover fill\n // and the shared focus outline.\n \"[&:is(button,a)]:cursor-pointer [&:is(button,a)]:hover:bg-foreground/3\",\n \"focus-visible:outline-[3px] focus-visible:outline-border/50\",\n className,\n ),\n style: { \"--bar-share\": share, ...style } as CSSProperties,\n children: (\n <>\n {/* The bar lives in the label column only: a 100% share reaches the gap before the\n value, never under it, so the numbers always sit on clean ground. */}\n <div className=\"relative flex h-full min-w-0 flex-1 items-center gap-2 pl-2.5\">\n <div\n aria-hidden\n className=\"absolute inset-y-0 left-0 w-[calc(var(--bar-share)*100%)] min-w-1.5 origin-left animate-fill-bar rounded-md bg-muted transition-[width] duration-500 ease-out-expo\"\n />\n\n {icon && (\n <span className=\"relative flex size-4 shrink-0 items-center justify-center\">\n {icon}\n </span>\n )}\n <span className=\"relative min-w-0 truncate\">{label}</span>\n\n {href && (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noreferrer\"\n aria-label={typeof label === \"string\" ? `Open ${label} website` : \"Open website\"}\n className=\"relative flex size-5 shrink-0 items-center justify-center rounded text-muted-foreground hover:text-foreground\"\n >\n <ArrowUpRightIcon className=\"size-3.5\" />\n </a>\n )}\n </div>\n\n {secondaryValue !== undefined && (\n <span className=\"min-w-16 shrink-0 text-right text-muted-foreground tabular-nums\">\n <AnimatedNumber value={secondaryValue} format={secondaryFormat} />\n </span>\n )}\n\n <span className=\"min-w-12 shrink-0 text-right text-muted-foreground tabular-nums\">\n <AnimatedNumber value={value} format={format} />\n </span>\n </>\n ),\n ...props,\n },\n })\n}\n\n/**\n * Label bars step down like a ranked list would, so the swap to data reads as a fill-in\n * rather than a reflow.\n */\nconst skeletonShares = [\"70%\", \"55%\", \"45%\", \"35%\", \"30%\"] as const\n\nexport type BarListSkeletonProps = ComponentProps<\"div\"> & {\n /**\n * Rows to draw, matching the list that replaces it.\n */\n rows?: number\n}\n\n/**\n * Loading stand-in at the exact row height of `BarList.Row`, so swapping in data causes no\n * layout shift.\n */\nfunction BarListSkeleton({ rows = 5, className, ...props }: BarListSkeletonProps) {\n return (\n <BarListRoot aria-hidden className={className} {...props}>\n {Array.from({ length: rows }, (_, index) => (\n <div key={index} className={rowClasses}>\n <div className=\"relative h-full min-w-0 flex-1\">\n <Skeleton\n className=\"absolute inset-y-0 left-0\"\n style={{ width: skeletonShares[index % skeletonShares.length] }}\n />\n </div>\n\n <Skeleton className=\"h-3.5 w-8 shrink-0\" />\n </div>\n ))}\n </BarListRoot>\n )\n}\n\nconst BarList = Object.assign(BarListRoot, { Row: BarListRow, Skeleton: BarListSkeleton })\n\nexport { BarList }\n"],"mappings":";;;;;;;;;;;;;;AAeA,SAAS,YAAY,EAAE,WAAW,GAAG,SAAgC;CACnE,OAAO,oBAAC,OAAD;EAAK,WAAW,GAAG,uBAAuB,SAAS;EAAG,GAAI;CAAQ,CAAA;AAC3E;AAEA,MAAM,aAAa;AA6BnB,SAAS,WAAW,EAClB,OACA,MACA,OACA,KACA,QACA,gBACA,iBACA,MACA,QACA,WACA,OACA,GAAG,SACe;CAClB,MAAM,QAAQ,MAAM,IAAI,KAAK,IAAI,QAAQ,KAAK,CAAC,IAAI;CAEnD,OAAO,UAAU;EACf;EACA,gBAAgB;EAChB,OAAO;GACL,WAAW,GACT,YACA,2CAGA,0EACA,+DACA,SACF;GACA,OAAO;IAAE,eAAe;IAAO,GAAG;GAAM;GACxC,UACE,qBAAA,UAAA,EAAA,UAAA;IAGE,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA;MACE,oBAAC,OAAD;OACE,eAAA;OACA,WAAU;MACX,CAAA;MAEA,QACC,oBAAC,QAAD;OAAM,WAAU;OACb,UAAA;MACG,CAAA;MAER,oBAAC,QAAD;OAAM,WAAU;OAA6B,UAAA;MAAY,CAAA;MAExD,QACC,oBAAC,KAAD;OACQ;OACN,QAAO;OACP,KAAI;OACJ,cAAY,OAAO,UAAU,WAAW,QAAQ,MAAM,YAAY;OAClE,WAAU;OAEV,UAAA,oBAAC,kBAAD,EAAkB,WAAU,WAAY,CAAA;MACvC,CAAA;KAEF;;IAEJ,mBAAmB,KAAA,KAClB,oBAAC,QAAD;KAAM,WAAU;KACd,UAAA,oBAAC,gBAAD;MAAgB,OAAO;MAAgB,QAAQ;KAAkB,CAAA;IAC7D,CAAA;IAGR,oBAAC,QAAD;KAAM,WAAU;KACd,UAAA,oBAAC,gBAAD;MAAuB;MAAe;KAAS,CAAA;IAC3C,CAAA;GACN,EAAA,CAAA;GAEJ,GAAG;EACL;CACF,CAAC;AACH;;;;;AAMA,MAAM,iBAAiB;CAAC;CAAO;CAAO;CAAO;CAAO;AAAK;;;;;AAazD,SAAS,gBAAgB,EAAE,OAAO,GAAG,WAAW,GAAG,SAA+B;CAChF,OACE,oBAAC,aAAD;EAAa,eAAA;EAAuB;EAAW,GAAI;EAChD,UAAA,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAG,UAChC,qBAAC,OAAD;GAAiB,WAAW;GAA5B,UAAA,CACE,oBAAC,OAAD;IAAK,WAAU;IACb,UAAA,oBAAC,UAAD;KACE,WAAU;KACV,OAAO,EAAE,OAAO,eAAe,QAAQ,eAAe,QAAQ;IAC/D,CAAA;GACE,CAAA,GAEL,oBAAC,UAAD,EAAU,WAAU,qBAAsB,CAAA,CACvC;EATK,GAAA,KASL,CACN;CACU,CAAA;AAEjB;AAEA,MAAM,UAAU,OAAO,OAAO,aAAa;CAAE,KAAK;CAAY,UAAU;AAAgB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Card } from "./card.js";
|
|
2
|
+
import { ComponentProps, ReactNode } from "react";
|
|
3
|
+
//#region src/components/breakdown-card.d.ts
|
|
4
|
+
export type BreakdownCardProps = ComponentProps<typeof Card> & {
|
|
5
|
+
title: ReactNode;
|
|
6
|
+
description?: ReactNode;
|
|
7
|
+
/**
|
|
8
|
+
* Header actions, right-aligned beside the title (a menu, a time-range control).
|
|
9
|
+
*/
|
|
10
|
+
actions?: ReactNode;
|
|
11
|
+
/**
|
|
12
|
+
* A view switcher (e.g. `ViewTabs`) pinned to the top of the body, above the children.
|
|
13
|
+
*/
|
|
14
|
+
tabs?: ReactNode;
|
|
15
|
+
/**
|
|
16
|
+
* A compact hairline-topped strip under the body, for a "Details" link or a total.
|
|
17
|
+
*/
|
|
18
|
+
footer?: ReactNode;
|
|
19
|
+
/**
|
|
20
|
+
* Drop the body panel's padding, for a body that draws its own edges (a divided row list).
|
|
21
|
+
*/
|
|
22
|
+
flush?: boolean;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* A dashboard panel: a titled header panel above a flex body panel, hairline-divided, with an
|
|
26
|
+
* optional footer strip. The body grows to fill the card so panels in the same row keep an
|
|
27
|
+
* even height.
|
|
28
|
+
*/
|
|
29
|
+
export declare function BreakdownCard({ title, description, actions, tabs, footer, flush, children, ...props }: BreakdownCardProps): import("react").JSX.Element;
|
|
30
|
+
//#endregion
|
|
31
|
+
//# sourceMappingURL=breakdown-card.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"breakdown-card.d.ts","names":[],"sources":["../../src/components/breakdown-card.tsx"],"mappings":";;;YAIY,qBAAqB,sBAAsB;EACrD,OAAO;EACP,cAAc;;;;EAId,UAAU;;;;EAIV,OAAO;;;;EAIP,SAAS;;;;EAIT;;;;;;;wBAQc,gBACd,OACA,aACA,SACA,MACA,QACA,OACA,aACG,SACF,qCAAkB,IAAA"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { cn } from "../lib/variants.js";
|
|
2
|
+
import { Card, CardHeader, CardPanel } from "./card.js";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
//#region src/components/breakdown-card.tsx
|
|
5
|
+
/**
|
|
6
|
+
* A dashboard panel: a titled header panel above a flex body panel, hairline-divided, with an
|
|
7
|
+
* optional footer strip. The body grows to fill the card so panels in the same row keep an
|
|
8
|
+
* even height.
|
|
9
|
+
*/
|
|
10
|
+
function BreakdownCard({ title, description, actions, tabs, footer, flush, children, ...props }) {
|
|
11
|
+
return /* @__PURE__ */ jsxs(Card, {
|
|
12
|
+
...props,
|
|
13
|
+
children: [
|
|
14
|
+
/* @__PURE__ */ jsx(CardPanel, {
|
|
15
|
+
className: "p-4 md:p-4",
|
|
16
|
+
children: /* @__PURE__ */ jsx(CardHeader, {
|
|
17
|
+
size: "panel",
|
|
18
|
+
className: "gap-y-0.5",
|
|
19
|
+
title,
|
|
20
|
+
description,
|
|
21
|
+
actions
|
|
22
|
+
})
|
|
23
|
+
}),
|
|
24
|
+
/* @__PURE__ */ jsxs(CardPanel, {
|
|
25
|
+
className: cn("flex flex-1 flex-col gap-3 p-4 md:p-4", flush && "p-0 md:p-0"),
|
|
26
|
+
children: [tabs && /* @__PURE__ */ jsx("div", {
|
|
27
|
+
className: cn("flex", flush && "px-4 pt-4"),
|
|
28
|
+
children: tabs
|
|
29
|
+
}), children]
|
|
30
|
+
}),
|
|
31
|
+
footer && /* @__PURE__ */ jsx(CardPanel, {
|
|
32
|
+
className: "px-4 py-2.5 text-sm md:px-4 md:py-2.5",
|
|
33
|
+
children: footer
|
|
34
|
+
})
|
|
35
|
+
]
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
//#endregion
|
|
39
|
+
export { BreakdownCard };
|
|
40
|
+
|
|
41
|
+
//# sourceMappingURL=breakdown-card.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"breakdown-card.js","names":[],"sources":["../../src/components/breakdown-card.tsx"],"sourcesContent":["import type { ComponentProps, ReactNode } from \"react\"\nimport { Card, CardHeader, CardPanel } from \"~/components/card\"\nimport { cn } from \"~/lib/variants\"\n\nexport type BreakdownCardProps = ComponentProps<typeof Card> & {\n title: ReactNode\n description?: ReactNode\n /**\n * Header actions, right-aligned beside the title (a menu, a time-range control).\n */\n actions?: ReactNode\n /**\n * A view switcher (e.g. `ViewTabs`) pinned to the top of the body, above the children.\n */\n tabs?: ReactNode\n /**\n * A compact hairline-topped strip under the body, for a \"Details\" link or a total.\n */\n footer?: ReactNode\n /**\n * Drop the body panel's padding, for a body that draws its own edges (a divided row list).\n */\n flush?: boolean\n}\n\n/**\n * A dashboard panel: a titled header panel above a flex body panel, hairline-divided, with an\n * optional footer strip. The body grows to fill the card so panels in the same row keep an\n * even height.\n */\nexport function BreakdownCard({\n title,\n description,\n actions,\n tabs,\n footer,\n flush,\n children,\n ...props\n}: BreakdownCardProps) {\n return (\n <Card {...props}>\n <CardPanel className=\"p-4 md:p-4\">\n <CardHeader\n size=\"panel\"\n className=\"gap-y-0.5\"\n title={title}\n description={description}\n actions={actions}\n />\n </CardPanel>\n\n <CardPanel className={cn(\"flex flex-1 flex-col gap-3 p-4 md:p-4\", flush && \"p-0 md:p-0\")}>\n {tabs && <div className={cn(\"flex\", flush && \"px-4 pt-4\")}>{tabs}</div>}\n {children}\n </CardPanel>\n\n {footer && <CardPanel className=\"px-4 py-2.5 text-sm md:px-4 md:py-2.5\">{footer}</CardPanel>}\n </Card>\n )\n}\n"],"mappings":";;;;;;;;;AA8BA,SAAgB,cAAc,EAC5B,OACA,aACA,SACA,MACA,QACA,OACA,UACA,GAAG,SACkB;CACrB,OACE,qBAAC,MAAD;EAAM,GAAI;EAAV,UAAA;GACE,oBAAC,WAAD;IAAW,WAAU;IACnB,UAAA,oBAAC,YAAD;KACE,MAAK;KACL,WAAU;KACH;KACM;KACJ;IACV,CAAA;GACQ,CAAA;GAEX,qBAAC,WAAD;IAAW,WAAW,GAAG,yCAAyC,SAAS,YAAY;IAAvF,UAAA,CACG,QAAQ,oBAAC,OAAD;KAAK,WAAW,GAAG,QAAQ,SAAS,WAAW;KAAI,UAAA;IAAU,CAAA,GACrE,QACQ;;GAEV,UAAU,oBAAC,WAAD;IAAW,WAAU;IAAyC,UAAA;GAAkB,CAAA;EACvF;;AAEV"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { VariantProps } from "../lib/variants.js";
|
|
2
2
|
import { interactiveVariants } from "../lib/interactive.js";
|
|
3
|
-
import { useRender } from "@base-ui/react/use-render";
|
|
4
3
|
import { ReactNode } from "react";
|
|
4
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
5
5
|
//#region src/components/button.d.ts
|
|
6
6
|
declare const buttonVariants: import("tailwind-variants").TVReturnType<{
|
|
7
7
|
variant: {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { cn, variants } from "../lib/variants.js";
|
|
2
|
-
import { slot } from "../lib/slot.js";
|
|
3
1
|
import { controlTextClasses } from "../lib/classes.js";
|
|
4
2
|
import { LoaderIcon } from "../lib/icons.js";
|
|
3
|
+
import { cn, variants } from "../lib/variants.js";
|
|
5
4
|
import { interactiveVariants } from "../lib/interactive.js";
|
|
5
|
+
import { slot } from "../lib/slot.js";
|
|
6
6
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import { mergeProps } from "@base-ui/react";
|
|
8
|
-
import { useRender } from "@base-ui/react/use-render";
|
|
9
8
|
import { Children, isValidElement } from "react";
|
|
9
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
10
10
|
//#region src/components/button.tsx
|
|
11
11
|
const buttonVariants = variants({
|
|
12
12
|
base: [`group/button inline-flex items-center justify-center font-medium ${controlTextClasses} text-start rounded-md overflow-clip select-none hover:z-10`, "disabled:opacity-60 disabled:pointer-events-none aria-disabled:opacity-60 aria-disabled:pointer-events-none"],
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { VariantProps } from "../lib/variants.js";
|
|
2
2
|
import { SectionHeader } from "./section-header.js";
|
|
3
|
-
import { useRender } from "@base-ui/react/use-render";
|
|
4
3
|
import { ComponentProps } from "react";
|
|
4
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
5
5
|
//#region src/components/card.d.ts
|
|
6
6
|
/**
|
|
7
7
|
* The one raised surface in the app: a white panel on the canvas, hairline border, 12px radius
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { VariantProps } from "../lib/variants.js";
|
|
2
|
-
import { useRender } from "@base-ui/react/use-render";
|
|
3
2
|
import { ReactNode } from "react";
|
|
3
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
4
4
|
//#region src/components/detail-row.d.ts
|
|
5
5
|
declare const detailRowVariants: import("tailwind-variants").TVReturnType<{
|
|
6
6
|
density: {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import "../lib/classes.js";
|
|
1
2
|
import { variants } from "../lib/variants.js";
|
|
2
3
|
import { slot } from "../lib/slot.js";
|
|
3
|
-
import "../lib/classes.js";
|
|
4
4
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
-
import { useRender } from "@base-ui/react/use-render";
|
|
6
5
|
import { isValidElement } from "react";
|
|
6
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
7
7
|
//#region src/components/detail-row.tsx
|
|
8
8
|
const detailRowVariants = variants({
|
|
9
9
|
slots: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { VariantProps } from "../lib/variants.js";
|
|
2
|
-
import { Button } from "./button.js";
|
|
3
2
|
import { SectionHeader } from "./section-header.js";
|
|
3
|
+
import { Button } from "./button.js";
|
|
4
4
|
import { ComponentProps, ReactNode } from "react";
|
|
5
5
|
import { Dialog as Dialog$1 } from "@base-ui/react/dialog";
|
|
6
6
|
//#region src/components/dialog.d.ts
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { cn, variants } from "../lib/variants.js";
|
|
3
2
|
import { XIcon } from "../lib/icons.js";
|
|
4
|
-
import {
|
|
3
|
+
import { cn, variants } from "../lib/variants.js";
|
|
5
4
|
import { SectionHeader, SectionHeaderBody, SectionHeaderDescription, SectionHeaderTitle } from "./section-header.js";
|
|
5
|
+
import { Button } from "./button.js";
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import { Dialog as Dialog$1 } from "@base-ui/react/dialog";
|
|
8
8
|
//#region src/components/dialog.tsx
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { cn, variants } from "../lib/variants.js";
|
|
2
1
|
import { descriptionClasses } from "../lib/classes.js";
|
|
2
|
+
import { cn, variants } from "../lib/variants.js";
|
|
3
3
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
4
|
//#region src/components/empty-state.tsx
|
|
5
5
|
const emptyStateVariants = variants({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useRender } from "@base-ui/react/use-render";
|
|
2
1
|
import { ReactNode } from "react";
|
|
2
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
3
3
|
//#region src/components/form-section.d.ts
|
|
4
4
|
type FormSectionProps = Omit<useRender.ComponentProps<"section">, "title"> & {
|
|
5
5
|
id?: string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Stack } from "./stack.js";
|
|
2
2
|
import { Label } from "./label.js";
|
|
3
|
-
import { useRender } from "@base-ui/react/use-render";
|
|
4
3
|
import { ComponentProps } from "react";
|
|
4
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
5
5
|
import { ControllerProps, FieldPath, FieldValues } from "react-hook-form";
|
|
6
6
|
//#region src/components/form.d.ts
|
|
7
7
|
declare const Form: <TFieldValues extends FieldValues, TContext = any, TTransformedValues = TFieldValues>({ children, watch, getValues, getErrors, getFieldState, setError, clearErrors, setValue, setValues, trigger, formState, resetField, reset, resetDefaultValues, handleSubmit, unregister, control, register, setFocus, subscribe }: import("react-hook-form").FormProviderProps<TFieldValues, TContext, TTransformedValues>) => React.JSX.Element;
|
package/dist/components/form.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { cn } from "../lib/variants.js";
|
|
3
2
|
import { controlTextClasses, descriptionClasses } from "../lib/classes.js";
|
|
3
|
+
import { cn } from "../lib/variants.js";
|
|
4
4
|
import { Stack } from "./stack.js";
|
|
5
5
|
import { Label } from "./label.js";
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
7
|
-
import { useRender } from "@base-ui/react/use-render";
|
|
8
7
|
import { createContext, useContext, useId } from "react";
|
|
8
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
9
9
|
import { Controller, FormProvider, useFormContext } from "react-hook-form";
|
|
10
10
|
//#region src/components/form.tsx
|
|
11
11
|
const Form = FormProvider;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { VariantProps } from "../lib/variants.js";
|
|
2
|
-
import { useRender } from "@base-ui/react/use-render";
|
|
3
2
|
import { ElementType, JSX } from "react";
|
|
3
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
4
4
|
//#region src/components/heading.d.ts
|
|
5
5
|
declare const headingVariants: import("tailwind-variants").TVReturnType<{
|
|
6
6
|
size: {
|
package/dist/components/input.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { cn, variants } from "../lib/variants.js";
|
|
2
1
|
import { controlTextClasses } from "../lib/classes.js";
|
|
2
|
+
import { cn, variants } from "../lib/variants.js";
|
|
3
3
|
import { interactiveVariants } from "../lib/interactive.js";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
//#region src/components/input.tsx
|
package/dist/components/menu.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { cn } from "../lib/variants.js";
|
|
3
2
|
import { controlTextClasses, eyebrowClasses, popoverAnimationClasses } from "../lib/classes.js";
|
|
4
3
|
import { CheckIcon, CircleIcon } from "../lib/icons.js";
|
|
4
|
+
import { cn } from "../lib/variants.js";
|
|
5
5
|
import { Kbd } from "./kbd.js";
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import { Menu as Menu$1 } from "@base-ui/react/menu";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { cn } from "../lib/variants.js";
|
|
2
|
+
import { Skeleton } from "./skeleton.js";
|
|
2
3
|
import { Button } from "./button.js";
|
|
3
4
|
import { EntityAvatar } from "./entity-avatar.js";
|
|
4
5
|
import { navItem } from "./nav.js";
|
|
5
|
-
import { Skeleton } from "./skeleton.js";
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
//#region src/components/nav-button.tsx
|
|
8
8
|
function NavButtonShell({ leading, variant = "flat", children, className, ...props }) {
|
package/dist/components/nav.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { cn, variants } from "../lib/variants.js";
|
|
2
1
|
import { eyebrowClasses } from "../lib/classes.js";
|
|
2
|
+
import { cn, variants } from "../lib/variants.js";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
//#region src/components/nav.tsx
|
|
5
5
|
function Nav({ className, ...props }) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { cn } from "../lib/variants.js";
|
|
2
1
|
import { ChevronLeftIcon, ChevronRightIcon } from "../lib/icons.js";
|
|
2
|
+
import { cn } from "../lib/variants.js";
|
|
3
3
|
import { Button } from "./button.js";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
//#region src/components/pagination.tsx
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { VariantProps } from "../lib/variants.js";
|
|
2
|
+
import { ComponentProps } from "react";
|
|
3
|
+
//#region src/components/ping.d.ts
|
|
4
|
+
declare const pingVariants: import("tailwind-variants").TVReturnType<{
|
|
5
|
+
tone: {
|
|
6
|
+
success: "text-success";
|
|
7
|
+
warning: "text-warning";
|
|
8
|
+
danger: "text-danger";
|
|
9
|
+
neutral: "text-muted-foreground";
|
|
10
|
+
};
|
|
11
|
+
}, undefined, "relative flex shrink-0 size-2 rounded-full", {
|
|
12
|
+
tone: {
|
|
13
|
+
success: "text-success";
|
|
14
|
+
warning: "text-warning";
|
|
15
|
+
danger: "text-danger";
|
|
16
|
+
neutral: "text-muted-foreground";
|
|
17
|
+
};
|
|
18
|
+
}, undefined, import("tailwind-variants").TVReturnTypeLike<{
|
|
19
|
+
tone: {
|
|
20
|
+
success: "text-success";
|
|
21
|
+
warning: "text-warning";
|
|
22
|
+
danger: "text-danger";
|
|
23
|
+
neutral: "text-muted-foreground";
|
|
24
|
+
};
|
|
25
|
+
}, undefined>>;
|
|
26
|
+
type PingProps = ComponentProps<"span"> & VariantProps<typeof pingVariants> & {
|
|
27
|
+
/**
|
|
28
|
+
* Pulse the dot. The glow overflows the box by half the dot size, so layout
|
|
29
|
+
* stays the size of the dot itself.
|
|
30
|
+
*/
|
|
31
|
+
animate?: boolean;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* A status dot: solid fill with an optional soft, slow pulse. Size it with `size-*`.
|
|
35
|
+
*/
|
|
36
|
+
export declare function Ping({ className, tone, animate, ...props }: PingProps): import("react").JSX.Element;
|
|
37
|
+
//#endregion
|
|
38
|
+
//# sourceMappingURL=ping.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ping.d.ts","names":[],"sources":["../../src/components/ping.tsx"],"mappings":";;;cAGM,0CAAY;;;;;;;;;;;;;;;;;;;;;;KAiBb,YAAY,yBACf,oBAAoB;;;;;EAKlB;;;;;wBAMY,OAAO,WAAW,MAAM,YAAmB,SAAS,4BAAS,IAAA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { cn, variants } from "../lib/variants.js";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
//#region src/components/ping.tsx
|
|
4
|
+
const pingVariants = variants({
|
|
5
|
+
base: "relative flex shrink-0 size-2 rounded-full",
|
|
6
|
+
variants: { tone: {
|
|
7
|
+
success: "text-success",
|
|
8
|
+
warning: "text-warning",
|
|
9
|
+
danger: "text-danger",
|
|
10
|
+
neutral: "text-muted-foreground"
|
|
11
|
+
} },
|
|
12
|
+
defaultVariants: { tone: "neutral" }
|
|
13
|
+
});
|
|
14
|
+
/**
|
|
15
|
+
* A status dot: solid fill with an optional soft, slow pulse. Size it with `size-*`.
|
|
16
|
+
*/
|
|
17
|
+
function Ping({ className, tone, animate = true, ...props }) {
|
|
18
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
19
|
+
className: cn(pingVariants({
|
|
20
|
+
tone,
|
|
21
|
+
className
|
|
22
|
+
})),
|
|
23
|
+
...props,
|
|
24
|
+
children: [animate && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute -inset-1/2 animate-ping rounded-full bg-current opacity-30 blur-[1px] [animation-duration:2s] motion-reduce:animate-none" }), /* @__PURE__ */ jsx("span", { className: "pointer-events-none absolute -inset-1/2 animate-pulse rounded-full bg-current opacity-30 motion-reduce:animate-none" })] }), /* @__PURE__ */ jsx("span", { className: "absolute inset-0 rounded-full bg-current" })]
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
export { Ping };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=ping.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ping.js","names":[],"sources":["../../src/components/ping.tsx"],"sourcesContent":["import type { ComponentProps } from \"react\"\nimport { variants, cn, type VariantProps } from \"~/lib/variants\"\n\nconst pingVariants = variants({\n base: \"relative flex shrink-0 size-2 rounded-full\",\n\n variants: {\n tone: {\n success: \"text-success\",\n warning: \"text-warning\",\n danger: \"text-danger\",\n neutral: \"text-muted-foreground\",\n },\n },\n\n defaultVariants: {\n tone: \"neutral\",\n },\n})\n\ntype PingProps = ComponentProps<\"span\"> &\n VariantProps<typeof pingVariants> & {\n /**\n * Pulse the dot. The glow overflows the box by half the dot size, so layout\n * stays the size of the dot itself.\n */\n animate?: boolean\n }\n\n/**\n * A status dot: solid fill with an optional soft, slow pulse. Size it with `size-*`.\n */\nexport function Ping({ className, tone, animate = true, ...props }: PingProps) {\n return (\n <span className={cn(pingVariants({ tone, className }))} {...props}>\n {animate && (\n <>\n <span className=\"pointer-events-none absolute -inset-1/2 animate-ping rounded-full bg-current opacity-30 blur-[1px] [animation-duration:2s] motion-reduce:animate-none\" />\n <span className=\"pointer-events-none absolute -inset-1/2 animate-pulse rounded-full bg-current opacity-30 motion-reduce:animate-none\" />\n </>\n )}\n <span className=\"absolute inset-0 rounded-full bg-current\" />\n </span>\n )\n}\n"],"mappings":";;;AAGA,MAAM,eAAe,SAAS;CAC5B,MAAM;CAEN,UAAU,EACR,MAAM;EACJ,SAAS;EACT,SAAS;EACT,QAAQ;EACR,SAAS;CACX,EACF;CAEA,iBAAiB,EACf,MAAM,UACR;AACF,CAAC;;;;AAcD,SAAgB,KAAK,EAAE,WAAW,MAAM,UAAU,MAAM,GAAG,SAAoB;CAC7E,OACE,qBAAC,QAAD;EAAM,WAAW,GAAG,aAAa;GAAE;GAAM;EAAU,CAAC,CAAC;EAAG,GAAI;EAA5D,UAAA,CACG,WACC,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,QAAD,EAAM,WAAU,wJAAyJ,CAAA,GACzK,oBAAC,QAAD,EAAM,WAAU,sHAAuH,CAAA,CACvI,EAAA,CAAA,GAEJ,oBAAC,QAAD,EAAM,WAAU,2CAA4C,CAAA,CACxD;;AAEV"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { cn } from "../lib/variants.js";
|
|
3
2
|
import { popoverAnimationClasses } from "../lib/classes.js";
|
|
3
|
+
import { cn } from "../lib/variants.js";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
import { Popover as Popover$1 } from "@base-ui/react/popover";
|
|
6
6
|
//#region src/components/popover.tsx
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { VariantProps } from "../lib/variants.js";
|
|
2
|
-
import { Stack } from "./stack.js";
|
|
3
2
|
import { HeadingProps } from "./heading.js";
|
|
4
|
-
import {
|
|
3
|
+
import { Stack } from "./stack.js";
|
|
5
4
|
import { ComponentProps, ReactNode } from "react";
|
|
5
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
6
6
|
//#region src/components/section-header.d.ts
|
|
7
7
|
declare const sectionHeaderVariants: import("tailwind-variants").TVReturnType<{
|
|
8
8
|
alignment: {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { cn, variants } from "../lib/variants.js";
|
|
2
1
|
import { descriptionClasses } from "../lib/classes.js";
|
|
3
|
-
import {
|
|
2
|
+
import { cn, variants } from "../lib/variants.js";
|
|
4
3
|
import { Heading } from "./heading.js";
|
|
4
|
+
import { Stack } from "./stack.js";
|
|
5
5
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
-
import { useRender } from "@base-ui/react/use-render";
|
|
7
6
|
import { createContext, use } from "react";
|
|
7
|
+
import { useRender } from "@base-ui/react/use-render";
|
|
8
8
|
//#region src/components/section-header.tsx
|
|
9
9
|
const sectionHeaderVariants = variants({
|
|
10
10
|
base: "flex items-center w-full min-w-0",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.d.ts","names":[],"sources":["../../src/components/select.tsx"],"mappings":";;;;cAQM,eAAM,SAAA;cACN,6BAAW,0BAAA,8BAAA,2CAAA,cAAA;cACX,6BAAW,0BAAA,8BAAA,2CAAA,cAAA;iBAER,gBACP,UACA,WACA,OACA,OACA,SACG,SACF,SAAgB,QAAQ,QAAQ,oBAAoB,iCAAc,IAAA;iBAmB5D,uBAAuB,cAAc,SAAS,SAAgB,cAAc,wBAAK,IAAA;iBAWjF,yBAAyB,cAAc,SAAS,SAAgB,gBAAgB,wBAAK,IAAA;iBAqBrF,gBACP,WACA,UACA,OACA,MACA,YACA,yBACG,SACF,SAAgB,MAAM,QACvB,KACE,SAAgB,WAAW,mFAE5B,IAAA;
|
|
1
|
+
{"version":3,"file":"select.d.ts","names":[],"sources":["../../src/components/select.tsx"],"mappings":";;;;cAQM,eAAM,SAAA;cACN,6BAAW,0BAAA,8BAAA,2CAAA,cAAA;cACX,6BAAW,0BAAA,8BAAA,2CAAA,cAAA;iBAER,gBACP,UACA,WACA,OACA,OACA,SACG,SACF,SAAgB,QAAQ,QAAQ,oBAAoB,iCAAc,IAAA;iBAmB5D,uBAAuB,cAAc,SAAS,SAAgB,cAAc,wBAAK,IAAA;iBAWjF,yBAAyB,cAAc,SAAS,SAAgB,gBAAgB,wBAAK,IAAA;iBAqBrF,gBACP,WACA,UACA,OACA,MACA,YACA,yBACG,SACF,SAAgB,MAAM,QACvB,KACE,SAAgB,WAAW,mFAE5B,IAAA;iBA8BM,cAAc,cAAc,SAAS,SAAgB,WAAW,wBAAK,IAAA;iBASrE,aAAa,WAAW,UAAU,UAAU,SAAS,SAAgB,KAAK,wBAAK,IAAA;iBAoB/E,kBAAkB,cAAc,SAAS,SAAgB,UAAU,wBAAK,IAAA"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { cn, variants } from "../lib/variants.js";
|
|
3
2
|
import { controlTextClasses, popoverAnimationClasses } from "../lib/classes.js";
|
|
4
3
|
import { CheckIcon, ChevronDownIcon, ChevronUpIcon, ChevronsUpDownIcon } from "../lib/icons.js";
|
|
4
|
+
import { cn, variants } from "../lib/variants.js";
|
|
5
5
|
import { inputVariants } from "./input.js";
|
|
6
6
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
import { Select as Select$1 } from "@base-ui/react/select";
|
|
@@ -57,7 +57,7 @@ function SelectContent({ className, children, align, side, sideOffset = 4, align
|
|
|
57
57
|
children: [
|
|
58
58
|
/* @__PURE__ */ jsx(SelectScrollUpButton, { className: selectScrollButtonVariants({ position: "top" }) }),
|
|
59
59
|
/* @__PURE__ */ jsx(Select$1.List, {
|
|
60
|
-
className: "p-1",
|
|
60
|
+
className: "max-h-(--available-height) overflow-y-auto p-1",
|
|
61
61
|
children
|
|
62
62
|
}),
|
|
63
63
|
/* @__PURE__ */ jsx(SelectScrollDownButton, { className: selectScrollButtonVariants({ position: "bottom" }) })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.js","names":["SelectPrimitive"],"sources":["../../src/components/select.tsx"],"sourcesContent":["\"use client\"\n\nimport { Select as SelectPrimitive } from \"@base-ui/react/select\"\nimport { inputVariants } from \"~/components/input\"\nimport { controlTextClasses, popoverAnimationClasses } from \"~/lib/classes\"\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon, ChevronsUpDownIcon } from \"~/lib/icons\"\nimport { variants, cn, type VariantProps } from \"~/lib/variants\"\n\nconst Select = SelectPrimitive.Root\nconst SelectGroup = SelectPrimitive.Group\nconst SelectValue = SelectPrimitive.Value\n\nfunction SelectTrigger({\n children,\n className,\n hover = true,\n focus = true,\n size,\n ...props\n}: SelectPrimitive.Trigger.Props & VariantProps<typeof inputVariants>) {\n return (\n <SelectPrimitive.Trigger\n className={cn(\n inputVariants({ hover, focus, size }),\n \"flex items-center justify-between\",\n className,\n )}\n {...props}\n >\n <span className=\"truncate\">{children}</span>\n\n <SelectPrimitive.Icon\n render={<ChevronsUpDownIcon className=\"ml-1 size-4 shrink-0 opacity-50\" />}\n />\n </SelectPrimitive.Trigger>\n )\n}\n\nfunction SelectScrollUpButton({ className, ...props }: SelectPrimitive.ScrollUpArrow.Props) {\n return (\n <SelectPrimitive.ScrollUpArrow\n className={cn(\"flex cursor-pointer items-center justify-center py-1\", className)}\n {...props}\n >\n <ChevronUpIcon />\n </SelectPrimitive.ScrollUpArrow>\n )\n}\n\nfunction SelectScrollDownButton({ className, ...props }: SelectPrimitive.ScrollDownArrow.Props) {\n return (\n <SelectPrimitive.ScrollDownArrow\n className={cn(\"flex cursor-pointer items-center justify-center py-1\", className)}\n {...props}\n >\n <ChevronDownIcon />\n </SelectPrimitive.ScrollDownArrow>\n )\n}\n\nconst selectScrollButtonVariants = variants({\n base: \"absolute inset-x-0 z-10 bg-background animate-in fade-in-0 duration-300\",\n variants: {\n position: {\n top: \"top-0 mask-b-from-0\",\n bottom: \"bottom-0 mask-t-from-0\",\n },\n },\n})\n\nfunction SelectContent({\n className,\n children,\n align,\n side,\n sideOffset = 4,\n alignItemWithTrigger = false,\n ...props\n}: SelectPrimitive.Popup.Props &\n Pick<\n SelectPrimitive.Positioner.Props,\n \"align\" | \"side\" | \"sideOffset\" | \"alignItemWithTrigger\"\n >) {\n return (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Positioner\n sideOffset={sideOffset}\n align={align}\n side={side}\n alignItemWithTrigger={alignItemWithTrigger}\n className=\"isolate z-50\"\n >\n <SelectPrimitive.Popup\n className={cn(\n \"relative z-50 isolate max-h-(--available-height) min-w-(--anchor-width) overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md backdrop-blur-xs\",\n !alignItemWithTrigger && popoverAnimationClasses,\n className,\n )}\n {...props}\n >\n <SelectScrollUpButton className={selectScrollButtonVariants({ position: \"top\" })} />\n <SelectPrimitive.List className=\"p-1\"
|
|
1
|
+
{"version":3,"file":"select.js","names":["SelectPrimitive"],"sources":["../../src/components/select.tsx"],"sourcesContent":["\"use client\"\n\nimport { Select as SelectPrimitive } from \"@base-ui/react/select\"\nimport { inputVariants } from \"~/components/input\"\nimport { controlTextClasses, popoverAnimationClasses } from \"~/lib/classes\"\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon, ChevronsUpDownIcon } from \"~/lib/icons\"\nimport { variants, cn, type VariantProps } from \"~/lib/variants\"\n\nconst Select = SelectPrimitive.Root\nconst SelectGroup = SelectPrimitive.Group\nconst SelectValue = SelectPrimitive.Value\n\nfunction SelectTrigger({\n children,\n className,\n hover = true,\n focus = true,\n size,\n ...props\n}: SelectPrimitive.Trigger.Props & VariantProps<typeof inputVariants>) {\n return (\n <SelectPrimitive.Trigger\n className={cn(\n inputVariants({ hover, focus, size }),\n \"flex items-center justify-between\",\n className,\n )}\n {...props}\n >\n <span className=\"truncate\">{children}</span>\n\n <SelectPrimitive.Icon\n render={<ChevronsUpDownIcon className=\"ml-1 size-4 shrink-0 opacity-50\" />}\n />\n </SelectPrimitive.Trigger>\n )\n}\n\nfunction SelectScrollUpButton({ className, ...props }: SelectPrimitive.ScrollUpArrow.Props) {\n return (\n <SelectPrimitive.ScrollUpArrow\n className={cn(\"flex cursor-pointer items-center justify-center py-1\", className)}\n {...props}\n >\n <ChevronUpIcon />\n </SelectPrimitive.ScrollUpArrow>\n )\n}\n\nfunction SelectScrollDownButton({ className, ...props }: SelectPrimitive.ScrollDownArrow.Props) {\n return (\n <SelectPrimitive.ScrollDownArrow\n className={cn(\"flex cursor-pointer items-center justify-center py-1\", className)}\n {...props}\n >\n <ChevronDownIcon />\n </SelectPrimitive.ScrollDownArrow>\n )\n}\n\nconst selectScrollButtonVariants = variants({\n base: \"absolute inset-x-0 z-10 bg-background animate-in fade-in-0 duration-300\",\n variants: {\n position: {\n top: \"top-0 mask-b-from-0\",\n bottom: \"bottom-0 mask-t-from-0\",\n },\n },\n})\n\nfunction SelectContent({\n className,\n children,\n align,\n side,\n sideOffset = 4,\n alignItemWithTrigger = false,\n ...props\n}: SelectPrimitive.Popup.Props &\n Pick<\n SelectPrimitive.Positioner.Props,\n \"align\" | \"side\" | \"sideOffset\" | \"alignItemWithTrigger\"\n >) {\n return (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Positioner\n sideOffset={sideOffset}\n align={align}\n side={side}\n alignItemWithTrigger={alignItemWithTrigger}\n className=\"isolate z-50\"\n >\n <SelectPrimitive.Popup\n className={cn(\n \"relative z-50 isolate max-h-(--available-height) min-w-(--anchor-width) overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md backdrop-blur-xs\",\n !alignItemWithTrigger && popoverAnimationClasses,\n className,\n )}\n {...props}\n >\n <SelectScrollUpButton className={selectScrollButtonVariants({ position: \"top\" })} />\n {/* The list is the scroller (not the popup), so the scroll arrows can overlay it. */}\n <SelectPrimitive.List className=\"max-h-(--available-height) overflow-y-auto p-1\">\n {children}\n </SelectPrimitive.List>\n <SelectScrollDownButton className={selectScrollButtonVariants({ position: \"bottom\" })} />\n </SelectPrimitive.Popup>\n </SelectPrimitive.Positioner>\n </SelectPrimitive.Portal>\n )\n}\n\nfunction SelectLabel({ className, ...props }: SelectPrimitive.GroupLabel.Props) {\n return (\n <SelectPrimitive.GroupLabel\n className={cn(\"px-2 py-1.5 text-sm font-medium\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectItem({ className, children, label, ...props }: SelectPrimitive.Item.Props) {\n return (\n <SelectPrimitive.Item\n label={label ?? (typeof children === \"string\" ? children : undefined)}\n className={cn(\n `relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 pl-8 pr-2 pointer-coarse:min-h-10 ${controlTextClasses} text-secondary-foreground outline-none focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50`,\n className,\n )}\n {...props}\n >\n <span className=\"absolute left-2 flex size-3.5 items-center justify-center\">\n <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n )\n}\n\nfunction SelectSeparator({ className, ...props }: SelectPrimitive.Separator.Props) {\n return (\n <SelectPrimitive.Separator className={cn(\"-mx-1 my-1 h-px bg-border\", className)} {...props} />\n )\n}\n\nexport {\n Select,\n SelectGroup,\n SelectValue,\n SelectTrigger,\n SelectContent,\n SelectLabel,\n SelectItem,\n SelectSeparator,\n SelectScrollUpButton,\n SelectScrollDownButton,\n}\n"],"mappings":";;;;;;;;AAQA,MAAM,SAASA,SAAgB;AAC/B,MAAM,cAAcA,SAAgB;AACpC,MAAM,cAAcA,SAAgB;AAEpC,SAAS,cAAc,EACrB,UACA,WACA,QAAQ,MACR,QAAQ,MACR,MACA,GAAG,SACkE;CACrE,OACE,qBAACA,SAAgB,SAAjB;EACE,WAAW,GACT,cAAc;GAAE;GAAO;GAAO;EAAK,CAAC,GACpC,qCACA,SACF;EACA,GAAI;EANN,UAAA,CAQE,oBAAC,QAAD;GAAM,WAAU;GAAY;EAAe,CAAA,GAE3C,oBAACA,SAAgB,MAAjB,EACE,QAAQ,oBAAC,oBAAD,EAAoB,WAAU,kCAAmC,CAAA,EAC1E,CAAA,CACsB;;AAE7B;AAEA,SAAS,qBAAqB,EAAE,WAAW,GAAG,SAA8C;CAC1F,OACE,oBAACA,SAAgB,eAAjB;EACE,WAAW,GAAG,wDAAwD,SAAS;EAC/E,GAAI;EAEJ,UAAA,oBAAC,eAAD,CAAgB,CAAA;CACa,CAAA;AAEnC;AAEA,SAAS,uBAAuB,EAAE,WAAW,GAAG,SAAgD;CAC9F,OACE,oBAACA,SAAgB,iBAAjB;EACE,WAAW,GAAG,wDAAwD,SAAS;EAC/E,GAAI;EAEJ,UAAA,oBAAC,iBAAD,CAAkB,CAAA;CACa,CAAA;AAErC;AAEA,MAAM,6BAA6B,SAAS;CAC1C,MAAM;CACN,UAAU,EACR,UAAU;EACR,KAAK;EACL,QAAQ;CACV,EACF;AACF,CAAC;AAED,SAAS,cAAc,EACrB,WACA,UACA,OACA,MACA,aAAa,GACb,uBAAuB,OACvB,GAAG,SAKA;CACH,OACE,oBAACA,SAAgB,QAAjB,EAAA,UACE,oBAACA,SAAgB,YAAjB;EACc;EACL;EACD;EACgB;EACtB,WAAU;EAEV,UAAA,qBAACA,SAAgB,OAAjB;GACE,WAAW,GACT,2KACA,CAAC,wBAAwB,yBACzB,SACF;GACA,GAAI;GANN,UAAA;IAQE,oBAAC,sBAAD,EAAsB,WAAW,2BAA2B,EAAE,UAAU,MAAM,CAAC,EAAI,CAAA;IAEnF,oBAACA,SAAgB,MAAjB;KAAsB,WAAU;KAC7B;IACmB,CAAA;IACtB,oBAAC,wBAAD,EAAwB,WAAW,2BAA2B,EAAE,UAAU,SAAS,CAAC,EAAI,CAAA;GACnE;;CACG,CAAA,EACN,CAAA;AAE5B;AAEA,SAAS,YAAY,EAAE,WAAW,GAAG,SAA2C;CAC9E,OACE,oBAACA,SAAgB,YAAjB;EACE,WAAW,GAAG,mCAAmC,SAAS;EAC1D,GAAI;CACL,CAAA;AAEL;AAEA,SAAS,WAAW,EAAE,WAAW,UAAU,OAAO,GAAG,SAAqC;CACxF,OACE,qBAACA,SAAgB,MAAjB;EACE,OAAO,UAAU,OAAO,aAAa,WAAW,WAAW,KAAA;EAC3D,WAAW,GACT,oHAAoH,mBAAmB,kJACvI,SACF;EACA,GAAI;EANN,UAAA,CAQE,oBAAC,QAAD;GAAM,WAAU;GACd,UAAA,oBAACA,SAAgB,eAAjB,EAAA,UACE,oBAAC,WAAD,EAAW,WAAU,SAAU,CAAA,EACF,CAAA;EAC3B,CAAA,GACN,oBAACA,SAAgB,UAAjB,EAA2B,SAAmC,CAAA,CAC1C;;AAE1B;AAEA,SAAS,gBAAgB,EAAE,WAAW,GAAG,SAA0C;CACjF,OACE,oBAACA,SAAgB,WAAjB;EAA2B,WAAW,GAAG,6BAA6B,SAAS;EAAG,GAAI;CAAQ,CAAA;AAElG"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { VariantProps } from "../lib/variants.js";
|
|
2
|
+
import { ComponentProps, ReactNode } from "react";
|
|
2
3
|
import { Format } from "@number-flow/react";
|
|
3
4
|
import { useRender } from "@base-ui/react/use-render";
|
|
4
|
-
import { ComponentProps } from "react";
|
|
5
5
|
//#region src/components/stat-strip.d.ts
|
|
6
6
|
declare const stripVariants: import("tailwind-variants").TVReturnType<{
|
|
7
7
|
variant: {
|
|
@@ -23,7 +23,11 @@ type StatStripProps = ComponentProps<"div"> & VariantProps<typeof stripVariants>
|
|
|
23
23
|
declare function StatStrip({ className, variant, ...props }: StatStripProps): import("react").JSX.Element;
|
|
24
24
|
type StatStripItemProps = Omit<useRender.ComponentProps<"div">, "children"> & {
|
|
25
25
|
label: string;
|
|
26
|
-
|
|
26
|
+
/**
|
|
27
|
+
* A number (or a string with a `format`) spins through `AnimatedNumber`; any other node,
|
|
28
|
+
* e.g. two `AnimatedNumber`s composing "1m 38s", renders as is.
|
|
29
|
+
*/
|
|
30
|
+
value: ReactNode;
|
|
27
31
|
format?: Format;
|
|
28
32
|
hint?: string;
|
|
29
33
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stat-strip.d.ts","names":[],"sources":["../../src/components/stat-strip.tsx"],"mappings":";;;;;cAOM,2CAAa;;;;;;;;;;;;;;;;KAmBd,iBAAiB,wBAAwB,oBAAoB;iBAEzD,YAAY,WAAW,YAAY,SAAS,iCAAc,IAAA;KAU9D,qBAAqB,KAAK,UAAU;EACvC;
|
|
1
|
+
{"version":3,"file":"stat-strip.d.ts","names":[],"sources":["../../src/components/stat-strip.tsx"],"mappings":";;;;;cAOM,2CAAa;;;;;;;;;;;;;;;;KAmBd,iBAAiB,wBAAwB,oBAAoB;iBAEzD,YAAY,WAAW,YAAY,SAAS,iCAAc,IAAA;KAU9D,qBAAqB,KAAK,UAAU;EACvC;;;;;EAKA,OAAO;EACP,SAAS;EACT;;;;;EAKA;;iBAGO,gBACP,OACA,OACA,QACA,MACA,UACA,QACA,cACG,SACF,qCAAkB,+CAAA"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { AnimatedNumber } from "./animated-number.js";
|
|
2
1
|
import { cn, variants } from "../lib/variants.js";
|
|
2
|
+
import { AnimatedNumber } from "./animated-number.js";
|
|
3
3
|
import { cardSurfaceClasses } from "./card.js";
|
|
4
4
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { isValidElement } from "react";
|
|
5
6
|
import { useRender } from "@base-ui/react/use-render";
|
|
6
7
|
//#region src/components/stat-strip.tsx
|
|
7
8
|
const stripVariants = variants({
|
|
@@ -36,8 +37,8 @@ function StatStripItem({ label, value, format, hint, selected, render, className
|
|
|
36
37
|
}),
|
|
37
38
|
/* @__PURE__ */ jsx("p", {
|
|
38
39
|
"data-value": true,
|
|
39
|
-
className: "mt-0.5 truncate font-display font-semibold text-xl tabular-nums sm:text-2xl",
|
|
40
|
-
children: /* @__PURE__ */ jsx(AnimatedNumber, {
|
|
40
|
+
className: "mt-0.5 truncate font-display font-semibold text-xl leading-8 tabular-nums sm:text-2xl sm:leading-9",
|
|
41
|
+
children: isValidElement(value) || typeof value !== "number" && typeof value !== "string" ? value : /* @__PURE__ */ jsx(AnimatedNumber, {
|
|
41
42
|
value,
|
|
42
43
|
format
|
|
43
44
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stat-strip.js","names":[],"sources":["../../src/components/stat-strip.tsx"],"sourcesContent":["import { useRender } from \"@base-ui/react/use-render\"\nimport type { Format } from \"@number-flow/react\"\nimport type
|
|
1
|
+
{"version":3,"file":"stat-strip.js","names":[],"sources":["../../src/components/stat-strip.tsx"],"sourcesContent":["import { useRender } from \"@base-ui/react/use-render\"\nimport type { Format } from \"@number-flow/react\"\nimport { type ComponentProps, isValidElement, type ReactNode } from \"react\"\nimport { AnimatedNumber } from \"~/components/animated-number\"\nimport { cardSurfaceClasses } from \"~/components/card\"\nimport { cn, variants, type VariantProps } from \"~/lib/variants\"\n\nconst stripVariants = variants({\n base: \"group/strip grid grid-cols-2 gap-y-1 max-sm:[&>*:last-child:nth-child(odd)]:col-span-2 sm:flex sm:flex-wrap sm:gap-y-0\",\n\n variants: {\n variant: {\n // A white card of figures, divided by full-height hairlines.\n plain: cardSurfaceClasses,\n // A canvas-toned track where the selected figure sits on a raised card, like a\n // segmented control; for strips that drive the panel beside them.\n // 13px gap: a 1px divider then sits 6px from the card on either side, matching the 6px inset.\n track: \"rounded-xl bg-background p-1.5 sm:gap-x-[13px]\",\n },\n },\n\n defaultVariants: {\n variant: \"plain\",\n },\n})\n\ntype StatStripProps = ComponentProps<\"div\"> & VariantProps<typeof stripVariants>\n\nfunction StatStrip({ className, variant, ...props }: StatStripProps) {\n return (\n <div\n data-variant={variant ?? \"plain\"}\n className={cn(stripVariants({ variant, className }))}\n {...props}\n />\n )\n}\n\ntype StatStripItemProps = Omit<useRender.ComponentProps<\"div\">, \"children\"> & {\n label: string\n /**\n * A number (or a string with a `format`) spins through `AnimatedNumber`; any other node,\n * e.g. two `AnimatedNumber`s composing \"1m 38s\", renders as is.\n */\n value: ReactNode\n format?: Format\n hint?: string\n /**\n * Marks the item as the one driving the panel beside it. Pass `render={<button ... />}`\n * to make it selectable.\n */\n selected?: boolean\n}\n\nfunction StatStripItem({\n label,\n value,\n format,\n hint,\n selected,\n render,\n className,\n ...props\n}: StatStripItemProps) {\n return useRender({\n render,\n defaultTagName: \"div\",\n props: {\n \"data-selected\": selected || undefined,\n className: cn(\n // The border is always laid out and only colored when selected, so toggling\n // never shifts the row.\n \"relative min-w-0 flex-1 rounded-lg border border-transparent px-4 py-3 text-start\",\n // Hairline divider between neighbours. The plain strip hides it around the\n // selected fill; the track keeps it, centered in the gap between cards.\n \"before:absolute before:inset-y-2 before:-left-px before:w-px before:bg-border first:before:hidden max-sm:before:hidden\",\n \"group-data-[variant=plain]/strip:data-selected:before:hidden group-data-[variant=plain]/strip:[[data-selected]+&]:before:hidden\",\n // Offsets are measured from the padding box, so the 1px border is added to land\n // exactly halfway across the 13px gap.\n \"group-data-[variant=track]/strip:before:-left-[8px]\",\n \"[&:is(button)]:hover:bg-foreground/3\",\n // Plain card: roomier cells, full-height dividers, selected item on a soft fill.\n \"group-data-[variant=plain]/strip:rounded-none group-data-[variant=plain]/strip:px-5 group-data-[variant=plain]/strip:py-4 group-data-[variant=plain]/strip:before:inset-y-0 group-data-[variant=plain]/strip:before:left-0\",\n \"group-data-[variant=plain]/strip:data-selected:bg-muted\",\n // Track: the selected item is a raised card; unselected figures recede.\n \"group-data-[variant=track]/strip:data-selected:border-border group-data-[variant=track]/strip:data-selected:bg-card group-data-[variant=track]/strip:data-selected:shadow-xs\",\n \"group-data-[variant=track]/strip:not-data-selected:[&_[data-value]]:text-muted-foreground\",\n \"group-data-[variant=track]/strip:[&:is(button)]:hover:not-data-selected:bg-card/60\",\n className,\n ),\n children: (\n <>\n <p className=\"text-muted-foreground text-sm sm:truncate\">{label}</p>\n\n {/* Fixed line heights (32px / 36px) equal NumberFlow's rendered box at text-xl / text-2xl,\n so a string value (\"—\", \"0:00\") sits at exactly the same height as an animated one. */}\n <p\n data-value\n className=\"mt-0.5 truncate font-display font-semibold text-xl leading-8 tabular-nums sm:text-2xl sm:leading-9\"\n >\n {isValidElement(value) || (typeof value !== \"number\" && typeof value !== \"string\") ? (\n value\n ) : (\n <AnimatedNumber value={value} format={format} />\n )}\n </p>\n\n {hint && <p className=\"text-muted-foreground text-xs sm:truncate\">{hint}</p>}\n </>\n ),\n ...props,\n },\n })\n}\n\nexport { StatStrip, StatStripItem }\n"],"mappings":";;;;;;;AAOA,MAAM,gBAAgB,SAAS;CAC7B,MAAM;CAEN,UAAU,EACR,SAAS;EAEP,OAAO;EAIP,OAAO;CACT,EACF;CAEA,iBAAiB,EACf,SAAS,QACX;AACF,CAAC;AAID,SAAS,UAAU,EAAE,WAAW,SAAS,GAAG,SAAyB;CACnE,OACE,oBAAC,OAAD;EACE,gBAAc,WAAW;EACzB,WAAW,GAAG,cAAc;GAAE;GAAS;EAAU,CAAC,CAAC;EACnD,GAAI;CACL,CAAA;AAEL;AAkBA,SAAS,cAAc,EACrB,OACA,OACA,QACA,MACA,UACA,QACA,WACA,GAAG,SACkB;CACrB,OAAO,UAAU;EACf;EACA,gBAAgB;EAChB,OAAO;GACL,iBAAiB,YAAY,KAAA;GAC7B,WAAW,GAGT,qFAGA,0HACA,mIAGA,uDACA,wCAEA,8NACA,2DAEA,gLACA,6FACA,sFACA,SACF;GACA,UACE,qBAAA,UAAA,EAAA,UAAA;IACE,oBAAC,KAAD;KAAG,WAAU;KAA6C,UAAA;IAAS,CAAA;IAInE,oBAAC,KAAD;KACE,cAAA;KACA,WAAU;KAET,UAAA,eAAe,KAAK,KAAM,OAAO,UAAU,YAAY,OAAO,UAAU,WACvE,QAEA,oBAAC,gBAAD;MAAuB;MAAe;KAAS,CAAA;IAEhD,CAAA;IAEF,QAAQ,oBAAC,KAAD;KAAG,WAAU;KAA6C,UAAA;IAAQ,CAAA;GAC3E,EAAA,CAAA;GAEJ,GAAG;EACL;CACF,CAAC;AACH"}
|
package/dist/components/tabs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { cn, variants } from "../lib/variants.js";
|
|
3
2
|
import { controlTextClasses } from "../lib/classes.js";
|
|
3
|
+
import { cn, variants } from "../lib/variants.js";
|
|
4
4
|
import { interactiveVariants } from "../lib/interactive.js";
|
|
5
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import { createContext, useContext } from "react";
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Tabs } from "./tabs.js";
|
|
2
|
+
import { ComponentProps } from "react";
|
|
3
|
+
//#region src/components/theme.d.ts
|
|
4
|
+
export type Theme = "system" | "light" | "dark";
|
|
5
|
+
/**
|
|
6
|
+
* The current theme and its setter. Persists to `localStorage["theme"]`, stays in sync across
|
|
7
|
+
* tabs, and drives the stylesheet's `light-dark()` tokens by setting `data-theme` on `<html>`
|
|
8
|
+
* (`system` removes it so the OS decides). SSR-safe: the server renders `system`.
|
|
9
|
+
*
|
|
10
|
+
* The hook only applies the stored theme once the first subscriber mounts. To avoid a flash of
|
|
11
|
+
* the wrong scheme, apply it before first paint with this inline script in `<head>`:
|
|
12
|
+
*
|
|
13
|
+
* ```html
|
|
14
|
+
* <script>try{var t=localStorage.theme;if(t==="light"||t==="dark")document.documentElement.dataset.theme=t}catch(e){}</script>
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function useTheme(): [Theme, (theme: Theme) => void];
|
|
18
|
+
type ThemeSelectProps = Omit<ComponentProps<typeof Tabs>, "value" | "defaultValue" | "onValueChange">;
|
|
19
|
+
/**
|
|
20
|
+
* Segmented System / Light / Dark control bound to `useTheme`, for a settings page or an
|
|
21
|
+
* account menu.
|
|
22
|
+
*/
|
|
23
|
+
export declare function ThemeSelect({ className, ...props }: ThemeSelectProps): import("react").JSX.Element;
|
|
24
|
+
//#endregion
|
|
25
|
+
//# sourceMappingURL=theme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.d.ts","names":[],"sources":["../../src/components/theme.tsx"],"mappings":";;;YAKY;;;;;;;;;;;;;wBAyGI,aAAa,QAAQ,OAAO;KAMvC,mBAAmB,KACtB,sBAAsB;;;;;wBAQR,cAAc,cAAc,SAAS,mCAAgB,IAAA"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Tabs, TabsList, TabsTrigger } from "./tabs.js";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
import { useSyncExternalStore } from "react";
|
|
5
|
+
//#region src/components/theme.tsx
|
|
6
|
+
const STORAGE_KEY = "theme";
|
|
7
|
+
const THEMES = [
|
|
8
|
+
"system",
|
|
9
|
+
"light",
|
|
10
|
+
"dark"
|
|
11
|
+
];
|
|
12
|
+
/**
|
|
13
|
+
* Tiny module store behind `useTheme`. One value shared by every subscriber, kept in step with
|
|
14
|
+
* `localStorage` (and with other tabs through the `storage` event) and mirrored onto
|
|
15
|
+
* `<html data-theme>`, which is what the stylesheet's `color-scheme` rules key on.
|
|
16
|
+
*/
|
|
17
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
18
|
+
let current;
|
|
19
|
+
function isTheme(value) {
|
|
20
|
+
return typeof value === "string" && THEMES.includes(value);
|
|
21
|
+
}
|
|
22
|
+
function readStored() {
|
|
23
|
+
try {
|
|
24
|
+
const stored = localStorage.getItem(STORAGE_KEY);
|
|
25
|
+
return isTheme(stored) ? stored : "system";
|
|
26
|
+
} catch {
|
|
27
|
+
return "system";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function writeStored(theme) {
|
|
31
|
+
try {
|
|
32
|
+
if (theme === "system") localStorage.removeItem(STORAGE_KEY);
|
|
33
|
+
else localStorage.setItem(STORAGE_KEY, theme);
|
|
34
|
+
} catch {}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* `system` clears the attribute so `color-scheme: light dark` follows the OS; anything else
|
|
38
|
+
* pins it.
|
|
39
|
+
*/
|
|
40
|
+
function applyTheme(theme) {
|
|
41
|
+
const root = document.documentElement;
|
|
42
|
+
if (theme === "system") delete root.dataset.theme;
|
|
43
|
+
else root.dataset.theme = theme;
|
|
44
|
+
}
|
|
45
|
+
function emit() {
|
|
46
|
+
for (const listener of listeners) listener();
|
|
47
|
+
}
|
|
48
|
+
function onStorage(event) {
|
|
49
|
+
if (event.key !== null && event.key !== STORAGE_KEY) return;
|
|
50
|
+
current = readStored();
|
|
51
|
+
applyTheme(current);
|
|
52
|
+
emit();
|
|
53
|
+
}
|
|
54
|
+
function getSnapshot() {
|
|
55
|
+
current ??= readStored();
|
|
56
|
+
return current;
|
|
57
|
+
}
|
|
58
|
+
function getServerSnapshot() {
|
|
59
|
+
return "system";
|
|
60
|
+
}
|
|
61
|
+
function subscribe(listener) {
|
|
62
|
+
if (listeners.size === 0) {
|
|
63
|
+
window.addEventListener("storage", onStorage);
|
|
64
|
+
applyTheme(getSnapshot());
|
|
65
|
+
}
|
|
66
|
+
listeners.add(listener);
|
|
67
|
+
return () => {
|
|
68
|
+
listeners.delete(listener);
|
|
69
|
+
if (listeners.size === 0) window.removeEventListener("storage", onStorage);
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function setTheme(theme) {
|
|
73
|
+
if (theme === current) return;
|
|
74
|
+
current = theme;
|
|
75
|
+
writeStored(theme);
|
|
76
|
+
applyTheme(theme);
|
|
77
|
+
emit();
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The current theme and its setter. Persists to `localStorage["theme"]`, stays in sync across
|
|
81
|
+
* tabs, and drives the stylesheet's `light-dark()` tokens by setting `data-theme` on `<html>`
|
|
82
|
+
* (`system` removes it so the OS decides). SSR-safe: the server renders `system`.
|
|
83
|
+
*
|
|
84
|
+
* The hook only applies the stored theme once the first subscriber mounts. To avoid a flash of
|
|
85
|
+
* the wrong scheme, apply it before first paint with this inline script in `<head>`:
|
|
86
|
+
*
|
|
87
|
+
* ```html
|
|
88
|
+
* <script>try{var t=localStorage.theme;if(t==="light"||t==="dark")document.documentElement.dataset.theme=t}catch(e){}<\/script>
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
function useTheme() {
|
|
92
|
+
return [useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot), setTheme];
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Segmented System / Light / Dark control bound to `useTheme`, for a settings page or an
|
|
96
|
+
* account menu.
|
|
97
|
+
*/
|
|
98
|
+
function ThemeSelect({ className, ...props }) {
|
|
99
|
+
const [theme, setTheme] = useTheme();
|
|
100
|
+
return /* @__PURE__ */ jsx(Tabs, {
|
|
101
|
+
value: theme,
|
|
102
|
+
onValueChange: (next) => setTheme(next),
|
|
103
|
+
className,
|
|
104
|
+
...props,
|
|
105
|
+
children: /* @__PURE__ */ jsxs(TabsList, {
|
|
106
|
+
variant: "segmented",
|
|
107
|
+
"aria-label": "Theme",
|
|
108
|
+
children: [
|
|
109
|
+
/* @__PURE__ */ jsx(TabsTrigger, {
|
|
110
|
+
value: "system",
|
|
111
|
+
children: "System"
|
|
112
|
+
}),
|
|
113
|
+
/* @__PURE__ */ jsx(TabsTrigger, {
|
|
114
|
+
value: "light",
|
|
115
|
+
children: "Light"
|
|
116
|
+
}),
|
|
117
|
+
/* @__PURE__ */ jsx(TabsTrigger, {
|
|
118
|
+
value: "dark",
|
|
119
|
+
children: "Dark"
|
|
120
|
+
})
|
|
121
|
+
]
|
|
122
|
+
})
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
//#endregion
|
|
126
|
+
export { ThemeSelect, useTheme };
|
|
127
|
+
|
|
128
|
+
//# sourceMappingURL=theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.js","names":[],"sources":["../../src/components/theme.tsx"],"sourcesContent":["\"use client\"\n\nimport { type ComponentProps, useSyncExternalStore } from \"react\"\nimport { Tabs, TabsList, TabsTrigger } from \"~/components/tabs\"\n\nexport type Theme = \"system\" | \"light\" | \"dark\"\n\nconst STORAGE_KEY = \"theme\"\nconst THEMES: readonly Theme[] = [\"system\", \"light\", \"dark\"]\n\n/**\n * Tiny module store behind `useTheme`. One value shared by every subscriber, kept in step with\n * `localStorage` (and with other tabs through the `storage` event) and mirrored onto\n * `<html data-theme>`, which is what the stylesheet's `color-scheme` rules key on.\n */\nconst listeners = new Set<() => void>()\nlet current: Theme | undefined\n\nfunction isTheme(value: unknown): value is Theme {\n return typeof value === \"string\" && THEMES.includes(value as Theme)\n}\n\nfunction readStored(): Theme {\n try {\n const stored = localStorage.getItem(STORAGE_KEY)\n return isTheme(stored) ? stored : \"system\"\n } catch {\n // Storage can be unavailable (privacy mode, sandboxed iframe) — fall back to the OS.\n return \"system\"\n }\n}\n\nfunction writeStored(theme: Theme) {\n try {\n if (theme === \"system\") localStorage.removeItem(STORAGE_KEY)\n else localStorage.setItem(STORAGE_KEY, theme)\n } catch {\n // Storage being unavailable only costs persistence; the in-memory value still applies.\n }\n}\n\n/**\n * `system` clears the attribute so `color-scheme: light dark` follows the OS; anything else\n * pins it.\n */\nfunction applyTheme(theme: Theme) {\n const root = document.documentElement\n\n if (theme === \"system\") delete root.dataset.theme\n else root.dataset.theme = theme\n}\n\nfunction emit() {\n for (const listener of listeners) listener()\n}\n\nfunction onStorage(event: StorageEvent) {\n // `key === null` is a `clear()` from another tab; treat it as a reset.\n if (event.key !== null && event.key !== STORAGE_KEY) return\n\n current = readStored()\n applyTheme(current)\n emit()\n}\n\nfunction getSnapshot(): Theme {\n current ??= readStored()\n return current\n}\n\nfunction getServerSnapshot(): Theme {\n return \"system\"\n}\n\nfunction subscribe(listener: () => void) {\n if (listeners.size === 0) {\n window.addEventListener(\"storage\", onStorage)\n // Apps that skip the inline script still land on the stored theme, one paint late.\n applyTheme(getSnapshot())\n }\n\n listeners.add(listener)\n\n return () => {\n listeners.delete(listener)\n if (listeners.size === 0) window.removeEventListener(\"storage\", onStorage)\n }\n}\n\nfunction setTheme(theme: Theme) {\n if (theme === current) return\n\n current = theme\n writeStored(theme)\n applyTheme(theme)\n emit()\n}\n\n/**\n * The current theme and its setter. Persists to `localStorage[\"theme\"]`, stays in sync across\n * tabs, and drives the stylesheet's `light-dark()` tokens by setting `data-theme` on `<html>`\n * (`system` removes it so the OS decides). SSR-safe: the server renders `system`.\n *\n * The hook only applies the stored theme once the first subscriber mounts. To avoid a flash of\n * the wrong scheme, apply it before first paint with this inline script in `<head>`:\n *\n * ```html\n * <script>try{var t=localStorage.theme;if(t===\"light\"||t===\"dark\")document.documentElement.dataset.theme=t}catch(e){}</script>\n * ```\n */\nexport function useTheme(): [Theme, (theme: Theme) => void] {\n const theme = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)\n\n return [theme, setTheme]\n}\n\ntype ThemeSelectProps = Omit<\n ComponentProps<typeof Tabs>,\n \"value\" | \"defaultValue\" | \"onValueChange\"\n>\n\n/**\n * Segmented System / Light / Dark control bound to `useTheme`, for a settings page or an\n * account menu.\n */\nexport function ThemeSelect({ className, ...props }: ThemeSelectProps) {\n const [theme, setTheme] = useTheme()\n\n return (\n <Tabs\n value={theme}\n onValueChange={(next: Theme) => setTheme(next)}\n className={className}\n {...props}\n >\n <TabsList variant=\"segmented\" aria-label=\"Theme\">\n <TabsTrigger value=\"system\">System</TabsTrigger>\n <TabsTrigger value=\"light\">Light</TabsTrigger>\n <TabsTrigger value=\"dark\">Dark</TabsTrigger>\n </TabsList>\n </Tabs>\n )\n}\n"],"mappings":";;;;;AAOA,MAAM,cAAc;AACpB,MAAM,SAA2B;CAAC;CAAU;CAAS;AAAM;;;;;;AAO3D,MAAM,4BAAY,IAAI,IAAgB;AACtC,IAAI;AAEJ,SAAS,QAAQ,OAAgC;CAC/C,OAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAc;AACpE;AAEA,SAAS,aAAoB;CAC3B,IAAI;EACF,MAAM,SAAS,aAAa,QAAQ,WAAW;EAC/C,OAAO,QAAQ,MAAM,IAAI,SAAS;CACpC,QAAQ;EAEN,OAAO;CACT;AACF;AAEA,SAAS,YAAY,OAAc;CACjC,IAAI;EACF,IAAI,UAAU,UAAU,aAAa,WAAW,WAAW;OACtD,aAAa,QAAQ,aAAa,KAAK;CAC9C,QAAQ,CAER;AACF;;;;;AAMA,SAAS,WAAW,OAAc;CAChC,MAAM,OAAO,SAAS;CAEtB,IAAI,UAAU,UAAU,OAAO,KAAK,QAAQ;MACvC,KAAK,QAAQ,QAAQ;AAC5B;AAEA,SAAS,OAAO;CACd,KAAK,MAAM,YAAY,WAAW,SAAS;AAC7C;AAEA,SAAS,UAAU,OAAqB;CAEtC,IAAI,MAAM,QAAQ,QAAQ,MAAM,QAAQ,aAAa;CAErD,UAAU,WAAW;CACrB,WAAW,OAAO;CAClB,KAAK;AACP;AAEA,SAAS,cAAqB;CAC5B,YAAY,WAAW;CACvB,OAAO;AACT;AAEA,SAAS,oBAA2B;CAClC,OAAO;AACT;AAEA,SAAS,UAAU,UAAsB;CACvC,IAAI,UAAU,SAAS,GAAG;EACxB,OAAO,iBAAiB,WAAW,SAAS;EAE5C,WAAW,YAAY,CAAC;CAC1B;CAEA,UAAU,IAAI,QAAQ;CAEtB,aAAa;EACX,UAAU,OAAO,QAAQ;EACzB,IAAI,UAAU,SAAS,GAAG,OAAO,oBAAoB,WAAW,SAAS;CAC3E;AACF;AAEA,SAAS,SAAS,OAAc;CAC9B,IAAI,UAAU,SAAS;CAEvB,UAAU;CACV,YAAY,KAAK;CACjB,WAAW,KAAK;CAChB,KAAK;AACP;;;;;;;;;;;;;AAcA,SAAgB,WAA4C;CAG1D,OAAO,CAFO,qBAAqB,WAAW,aAAa,iBAE/C,GAAG,QAAQ;AACzB;;;;;AAWA,SAAgB,YAAY,EAAE,WAAW,GAAG,SAA2B;CACrE,MAAM,CAAC,OAAO,YAAY,SAAS;CAEnC,OACE,oBAAC,MAAD;EACE,OAAO;EACP,gBAAgB,SAAgB,SAAS,IAAI;EAClC;EACX,GAAI;EAEJ,UAAA,qBAAC,UAAD;GAAU,SAAQ;GAAY,cAAW;GAAzC,UAAA;IACE,oBAAC,aAAD;KAAa,OAAM;KAAS,UAAA;IAAmB,CAAA;IAC/C,oBAAC,aAAD;KAAa,OAAM;KAAQ,UAAA;IAAkB,CAAA;IAC7C,oBAAC,aAAD;KAAa,OAAM;KAAO,UAAA;IAAiB,CAAA;GACnC;;CACN,CAAA;AAEV"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { cn } from "../lib/variants.js";
|
|
2
1
|
import { controlTextClasses } from "../lib/classes.js";
|
|
3
2
|
import { CircleCheckIcon, CircleHelpIcon, CircleXIcon, LoaderIcon } from "../lib/icons.js";
|
|
3
|
+
import { cn } from "../lib/variants.js";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
import { Toaster as Toaster$1 } from "sonner";
|
|
6
6
|
//#region src/components/toaster.tsx
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { cn } from "../lib/variants.js";
|
|
3
2
|
import { popoverAnimationClasses } from "../lib/classes.js";
|
|
3
|
+
import { cn } from "../lib/variants.js";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
import { Tooltip as Tooltip$1 } from "@base-ui/react/tooltip";
|
|
6
6
|
//#region src/components/tooltip.tsx
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Tabs, TabsList } from "./tabs.js";
|
|
2
|
+
import { ComponentProps } from "react";
|
|
3
|
+
//#region src/components/view-tabs.d.ts
|
|
4
|
+
export type ViewTabsProps<T extends string> = Omit<ComponentProps<typeof Tabs>, "value" | "defaultValue" | "onValueChange" | "onChange"> & {
|
|
5
|
+
value: T;
|
|
6
|
+
/**
|
|
7
|
+
* The view that maps to no `?view=` param, so the URL stays clean on the default tab.
|
|
8
|
+
*/
|
|
9
|
+
defaultValue: T;
|
|
10
|
+
options: {
|
|
11
|
+
value: T;
|
|
12
|
+
label: string;
|
|
13
|
+
}[];
|
|
14
|
+
onChange: (view: T | undefined) => void;
|
|
15
|
+
/**
|
|
16
|
+
* Forwarded to `TabsList`: `segmented` (default) for a header, `plain` inside a card.
|
|
17
|
+
*/
|
|
18
|
+
variant?: ComponentProps<typeof TabsList>["variant"];
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Tab switcher bound to a route's `view` search param. Emits `undefined` for the default view
|
|
22
|
+
* so the route can drop it from the URL instead of writing `?view=<default>`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function ViewTabs<T extends string>({ value, defaultValue, options, onChange, variant, className, ...props }: ViewTabsProps<T>): import("react").JSX.Element;
|
|
25
|
+
//#endregion
|
|
26
|
+
//# sourceMappingURL=view-tabs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view-tabs.d.ts","names":[],"sources":["../../src/components/view-tabs.tsx"],"mappings":";;;YAKY,cAAc,oBAAoB,KAC5C,sBAAsB;EAGtB,OAAO;;;;EAIP,cAAc;EACd;IAAW,OAAO;IAAG;;EACrB,WAAW,MAAM;;;;EAIjB,UAAU,sBAAsB;;;;;;wBAOlB,SAAS,oBACvB,OACA,cACA,SACA,UACA,SACA,cACG,SACF,cAAc,qBAAE,IAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Tabs, TabsList, TabsTrigger } from "./tabs.js";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
//#region src/components/view-tabs.tsx
|
|
5
|
+
/**
|
|
6
|
+
* Tab switcher bound to a route's `view` search param. Emits `undefined` for the default view
|
|
7
|
+
* so the route can drop it from the URL instead of writing `?view=<default>`.
|
|
8
|
+
*/
|
|
9
|
+
function ViewTabs({ value, defaultValue, options, onChange, variant, className, ...props }) {
|
|
10
|
+
return /* @__PURE__ */ jsx(Tabs, {
|
|
11
|
+
value,
|
|
12
|
+
onValueChange: (next) => onChange(next === defaultValue ? void 0 : next),
|
|
13
|
+
className,
|
|
14
|
+
...props,
|
|
15
|
+
children: /* @__PURE__ */ jsx(TabsList, {
|
|
16
|
+
variant,
|
|
17
|
+
children: options.map((option) => /* @__PURE__ */ jsx(TabsTrigger, {
|
|
18
|
+
value: option.value,
|
|
19
|
+
children: option.label
|
|
20
|
+
}, option.value))
|
|
21
|
+
})
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { ViewTabs };
|
|
26
|
+
|
|
27
|
+
//# sourceMappingURL=view-tabs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"view-tabs.js","names":[],"sources":["../../src/components/view-tabs.tsx"],"sourcesContent":["\"use client\"\n\nimport type { ComponentProps } from \"react\"\nimport { Tabs, TabsList, TabsTrigger } from \"~/components/tabs\"\n\nexport type ViewTabsProps<T extends string> = Omit<\n ComponentProps<typeof Tabs>,\n \"value\" | \"defaultValue\" | \"onValueChange\" | \"onChange\"\n> & {\n value: T\n /**\n * The view that maps to no `?view=` param, so the URL stays clean on the default tab.\n */\n defaultValue: T\n options: { value: T; label: string }[]\n onChange: (view: T | undefined) => void\n /**\n * Forwarded to `TabsList`: `segmented` (default) for a header, `plain` inside a card.\n */\n variant?: ComponentProps<typeof TabsList>[\"variant\"]\n}\n\n/**\n * Tab switcher bound to a route's `view` search param. Emits `undefined` for the default view\n * so the route can drop it from the URL instead of writing `?view=<default>`.\n */\nexport function ViewTabs<T extends string>({\n value,\n defaultValue,\n options,\n onChange,\n variant,\n className,\n ...props\n}: ViewTabsProps<T>) {\n return (\n <Tabs\n value={value}\n onValueChange={(next: T) => onChange(next === defaultValue ? undefined : next)}\n className={className}\n {...props}\n >\n <TabsList variant={variant}>\n {options.map(option => (\n <TabsTrigger key={option.value} value={option.value}>\n {option.label}\n </TabsTrigger>\n ))}\n </TabsList>\n </Tabs>\n )\n}\n"],"mappings":";;;;;;;;AA0BA,SAAgB,SAA2B,EACzC,OACA,cACA,SACA,UACA,SACA,WACA,GAAG,SACgB;CACnB,OACE,oBAAC,MAAD;EACS;EACP,gBAAgB,SAAY,SAAS,SAAS,eAAe,KAAA,IAAY,IAAI;EAClE;EACX,GAAI;EAEJ,UAAA,oBAAC,UAAD;GAAmB;GAChB,UAAA,QAAQ,KAAI,WACX,oBAAC,aAAD;IAAgC,OAAO,OAAO;IAC3C,UAAA,OAAO;GACG,GAFK,OAAO,KAEZ,CACd;EACO,CAAA;CACN,CAAA;AAEV"}
|
package/dist/lib/icons.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { ComponentType } from "react";
|
|
2
1
|
import { HugeiconsProps } from "@hugeicons/react";
|
|
2
|
+
import { ComponentType } from "react";
|
|
3
3
|
//#region src/lib/icons.d.ts
|
|
4
4
|
export type IconProps = Omit<HugeiconsProps, "icon" | "altIcon" | "showAlt">;
|
|
5
5
|
export type IconComponent = ComponentType<IconProps>;
|
|
6
|
+
export declare const ArrowUpRightIcon: IconComponent;
|
|
6
7
|
export declare const CheckIcon: IconComponent;
|
|
7
8
|
export declare const ChevronDownIcon: IconComponent;
|
|
8
9
|
export declare const ChevronLeftIcon: IconComponent;
|
package/dist/lib/icons.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icons.d.ts","names":[],"sources":["../../src/lib/icons.tsx"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"icons.d.ts","names":[],"sources":["../../src/lib/icons.tsx"],"mappings":";;;YAoBY,YAAY,KAAK;YACjB,gBAAgB,cAAc;qBAqB7B,kBAAgB;qBAChB,WAAS;qBACT,iBAAe;qBACf,iBAAe;qBACf,kBAAgB;qBAChB,eAAa;qBACb,oBAAkB;qBAClB,iBAAe;qBACf,gBAAc;qBACd,YAAU;qBACV,aAAW;qBACX,UAAQ;qBACR,YAAU;qBACV,YAAU;qBACV,OAAK"}
|
package/dist/lib/icons.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ArrowDown01Icon, ArrowLeft01Icon, ArrowRight01Icon, ArrowUp01Icon, Cancel01Icon, CancelCircleIcon, CheckmarkCircle02Icon, CircleIcon as CircleIcon$1, Copy01Icon, HelpCircleIcon, Loading03Icon, Search01Icon, Tick02Icon, UnfoldMoreIcon } from "@hugeicons/core-free-icons";
|
|
1
|
+
import { ArrowDown01Icon, ArrowLeft01Icon, ArrowRight01Icon, ArrowUp01Icon, ArrowUpRight01Icon, Cancel01Icon, CancelCircleIcon, CheckmarkCircle02Icon, CircleIcon as CircleIcon$1, Copy01Icon, HelpCircleIcon, Loading03Icon, Search01Icon, Tick02Icon, UnfoldMoreIcon } from "@hugeicons/core-free-icons";
|
|
3
2
|
import { HugeiconsIcon } from "@hugeicons/react";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
//#region src/lib/icons.tsx
|
|
5
5
|
/**
|
|
6
6
|
* Internal, non-exported icon helper. The package deliberately ships no public icon registry
|
|
@@ -23,6 +23,7 @@ function icon(def, name) {
|
|
|
23
23
|
Icon.displayName = name;
|
|
24
24
|
return Icon;
|
|
25
25
|
}
|
|
26
|
+
const ArrowUpRightIcon = icon(ArrowUpRight01Icon, "ArrowUpRightIcon");
|
|
26
27
|
const CheckIcon = icon(Tick02Icon, "CheckIcon");
|
|
27
28
|
const ChevronDownIcon = icon(ArrowDown01Icon, "ChevronDownIcon");
|
|
28
29
|
const ChevronLeftIcon = icon(ArrowLeft01Icon, "ChevronLeftIcon");
|
|
@@ -38,6 +39,6 @@ const LoaderIcon = icon(Loading03Icon, "LoaderIcon");
|
|
|
38
39
|
const SearchIcon = icon(Search01Icon, "SearchIcon");
|
|
39
40
|
const XIcon = icon(Cancel01Icon, "XIcon");
|
|
40
41
|
//#endregion
|
|
41
|
-
export { CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ChevronsUpDownIcon, CircleCheckIcon, CircleHelpIcon, CircleIcon, CircleXIcon, CopyIcon, LoaderIcon, SearchIcon, XIcon };
|
|
42
|
+
export { ArrowUpRightIcon, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, ChevronsUpDownIcon, CircleCheckIcon, CircleHelpIcon, CircleIcon, CircleXIcon, CopyIcon, LoaderIcon, SearchIcon, XIcon };
|
|
42
43
|
|
|
43
44
|
//# sourceMappingURL=icons.js.map
|
package/dist/lib/icons.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icons.js","names":["CircleDef"],"sources":["../../src/lib/icons.tsx"],"sourcesContent":["import {\n ArrowDown01Icon,\n ArrowLeft01Icon,\n ArrowRight01Icon,\n ArrowUp01Icon,\n Cancel01Icon,\n CancelCircleIcon,\n CheckmarkCircle02Icon,\n CircleIcon as CircleDef,\n Copy01Icon,\n HelpCircleIcon,\n Loading03Icon,\n Search01Icon,\n Tick02Icon,\n UnfoldMoreIcon,\n} from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon, type HugeiconsProps, type IconSvgElement } from \"@hugeicons/react\"\nimport type { ComponentType } from \"react\"\n\nexport type IconProps = Omit<HugeiconsProps, \"icon\" | \"altIcon\" | \"showAlt\">\nexport type IconComponent = ComponentType<IconProps>\n\n/**\n * Internal, non-exported icon helper. The package deliberately ships no public icon registry\n * (icon choice is product-specific and lives in each consuming app); this file only carries the\n * handful of structural glyphs the package's own components render. It lives in `lib/` rather\n * than `components/` so the `\"./*\": \"./dist/components/*\"` wildcard export never exposes it.\n *\n * Wraps a Hugeicons definition as a plain icon component, so call sites render `<CheckIcon />`.\n * Sizes to `1em` so a `size-*` class or the surrounding font size drives it.\n */\nfunction icon(def: IconSvgElement, name: string): IconComponent {\n function Icon(props: IconProps) {\n return <HugeiconsIcon icon={def} size=\"1em\" strokeWidth={1.75} {...props} />\n }\n\n Icon.displayName = name\n\n return Icon\n}\n\nexport const CheckIcon = icon(Tick02Icon, \"CheckIcon\")\nexport const ChevronDownIcon = icon(ArrowDown01Icon, \"ChevronDownIcon\")\nexport const ChevronLeftIcon = icon(ArrowLeft01Icon, \"ChevronLeftIcon\")\nexport const ChevronRightIcon = icon(ArrowRight01Icon, \"ChevronRightIcon\")\nexport const ChevronUpIcon = icon(ArrowUp01Icon, \"ChevronUpIcon\")\nexport const ChevronsUpDownIcon = icon(UnfoldMoreIcon, \"ChevronsUpDownIcon\")\nexport const CircleCheckIcon = icon(CheckmarkCircle02Icon, \"CircleCheckIcon\")\nexport const CircleHelpIcon = icon(HelpCircleIcon, \"CircleHelpIcon\")\nexport const CircleIcon = icon(CircleDef, \"CircleIcon\")\nexport const CircleXIcon = icon(CancelCircleIcon, \"CircleXIcon\")\nexport const CopyIcon = icon(Copy01Icon, \"CopyIcon\")\nexport const LoaderIcon = icon(Loading03Icon, \"LoaderIcon\")\nexport const SearchIcon = icon(Search01Icon, \"SearchIcon\")\nexport const XIcon = icon(Cancel01Icon, \"XIcon\")\n"],"mappings":";;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"icons.js","names":["CircleDef"],"sources":["../../src/lib/icons.tsx"],"sourcesContent":["import {\n ArrowDown01Icon,\n ArrowLeft01Icon,\n ArrowRight01Icon,\n ArrowUp01Icon,\n ArrowUpRight01Icon,\n Cancel01Icon,\n CancelCircleIcon,\n CheckmarkCircle02Icon,\n CircleIcon as CircleDef,\n Copy01Icon,\n HelpCircleIcon,\n Loading03Icon,\n Search01Icon,\n Tick02Icon,\n UnfoldMoreIcon,\n} from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon, type HugeiconsProps, type IconSvgElement } from \"@hugeicons/react\"\nimport type { ComponentType } from \"react\"\n\nexport type IconProps = Omit<HugeiconsProps, \"icon\" | \"altIcon\" | \"showAlt\">\nexport type IconComponent = ComponentType<IconProps>\n\n/**\n * Internal, non-exported icon helper. The package deliberately ships no public icon registry\n * (icon choice is product-specific and lives in each consuming app); this file only carries the\n * handful of structural glyphs the package's own components render. It lives in `lib/` rather\n * than `components/` so the `\"./*\": \"./dist/components/*\"` wildcard export never exposes it.\n *\n * Wraps a Hugeicons definition as a plain icon component, so call sites render `<CheckIcon />`.\n * Sizes to `1em` so a `size-*` class or the surrounding font size drives it.\n */\nfunction icon(def: IconSvgElement, name: string): IconComponent {\n function Icon(props: IconProps) {\n return <HugeiconsIcon icon={def} size=\"1em\" strokeWidth={1.75} {...props} />\n }\n\n Icon.displayName = name\n\n return Icon\n}\n\nexport const ArrowUpRightIcon = icon(ArrowUpRight01Icon, \"ArrowUpRightIcon\")\nexport const CheckIcon = icon(Tick02Icon, \"CheckIcon\")\nexport const ChevronDownIcon = icon(ArrowDown01Icon, \"ChevronDownIcon\")\nexport const ChevronLeftIcon = icon(ArrowLeft01Icon, \"ChevronLeftIcon\")\nexport const ChevronRightIcon = icon(ArrowRight01Icon, \"ChevronRightIcon\")\nexport const ChevronUpIcon = icon(ArrowUp01Icon, \"ChevronUpIcon\")\nexport const ChevronsUpDownIcon = icon(UnfoldMoreIcon, \"ChevronsUpDownIcon\")\nexport const CircleCheckIcon = icon(CheckmarkCircle02Icon, \"CircleCheckIcon\")\nexport const CircleHelpIcon = icon(HelpCircleIcon, \"CircleHelpIcon\")\nexport const CircleIcon = icon(CircleDef, \"CircleIcon\")\nexport const CircleXIcon = icon(CancelCircleIcon, \"CircleXIcon\")\nexport const CopyIcon = icon(Copy01Icon, \"CopyIcon\")\nexport const LoaderIcon = icon(Loading03Icon, \"LoaderIcon\")\nexport const SearchIcon = icon(Search01Icon, \"SearchIcon\")\nexport const XIcon = icon(Cancel01Icon, \"XIcon\")\n"],"mappings":";;;;;;;;;;;;;AAgCA,SAAS,KAAK,KAAqB,MAA6B;CAC9D,SAAS,KAAK,OAAkB;EAC9B,OAAO,oBAAC,eAAD;GAAe,MAAM;GAAK,MAAK;GAAM,aAAa;GAAM,GAAI;EAAQ,CAAA;CAC7E;CAEA,KAAK,cAAc;CAEnB,OAAO;AACT;AAEA,MAAa,mBAAmB,KAAK,oBAAoB,kBAAkB;AAC3E,MAAa,YAAY,KAAK,YAAY,WAAW;AACrD,MAAa,kBAAkB,KAAK,iBAAiB,iBAAiB;AACtE,MAAa,kBAAkB,KAAK,iBAAiB,iBAAiB;AACtE,MAAa,mBAAmB,KAAK,kBAAkB,kBAAkB;AACzE,MAAa,gBAAgB,KAAK,eAAe,eAAe;AAChE,MAAa,qBAAqB,KAAK,gBAAgB,oBAAoB;AAC3E,MAAa,kBAAkB,KAAK,uBAAuB,iBAAiB;AAC5E,MAAa,iBAAiB,KAAK,gBAAgB,gBAAgB;AACnE,MAAa,aAAa,KAAKA,cAAW,YAAY;AACtD,MAAa,cAAc,KAAK,kBAAkB,aAAa;AAC/D,MAAa,WAAW,KAAK,YAAY,UAAU;AACnD,MAAa,aAAa,KAAK,eAAe,YAAY;AAC1D,MAAa,aAAa,KAAK,cAAc,YAAY;AACzD,MAAa,QAAQ,KAAK,cAAc,OAAO"}
|
package/package.json
CHANGED
|
@@ -40,6 +40,10 @@
|
|
|
40
40
|
"types": "./dist/lib/slot.d.ts",
|
|
41
41
|
"default": "./dist/lib/slot.js"
|
|
42
42
|
},
|
|
43
|
+
"./animation": {
|
|
44
|
+
"types": "./dist/lib/animation.d.ts",
|
|
45
|
+
"default": "./dist/lib/animation.js"
|
|
46
|
+
},
|
|
43
47
|
"./*": {
|
|
44
48
|
"types": "./dist/components/*.d.ts",
|
|
45
49
|
"default": "./dist/components/*.js"
|
|
@@ -108,5 +112,5 @@
|
|
|
108
112
|
"engines": {
|
|
109
113
|
"node": ">=18"
|
|
110
114
|
},
|
|
111
|
-
"version": "1.
|
|
115
|
+
"version": "1.3.0"
|
|
112
116
|
}
|