@ratio-ui/core 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/catalogue.json +887 -27
  2. package/dist/components/accordion/Accordion.d.ts +19 -0
  3. package/dist/components/accordion/Accordion.js +52 -0
  4. package/dist/components/accordion/index.d.ts +2 -0
  5. package/dist/components/accordion/index.js +1 -0
  6. package/dist/components/breadcrumb/Breadcrumb.d.ts +19 -0
  7. package/dist/components/breadcrumb/Breadcrumb.js +50 -0
  8. package/dist/components/breadcrumb/index.d.ts +2 -0
  9. package/dist/components/breadcrumb/index.js +1 -0
  10. package/dist/components/chart/Chart.d.ts +137 -0
  11. package/dist/components/chart/Chart.js +238 -0
  12. package/dist/components/chart/index.d.ts +2 -0
  13. package/dist/components/chart/index.js +1 -0
  14. package/dist/components/combobox/Combobox.d.ts +52 -0
  15. package/dist/components/combobox/Combobox.js +92 -0
  16. package/dist/components/combobox/index.d.ts +2 -0
  17. package/dist/components/combobox/index.js +1 -0
  18. package/dist/components/data-table/DataTable.js +1 -1
  19. package/dist/components/date-picker/DatePicker.d.ts +3 -2
  20. package/dist/components/date-picker/DatePicker.js +7 -3
  21. package/dist/components/date-range-picker/DateRangePicker.d.ts +3 -2
  22. package/dist/components/date-range-picker/DateRangePicker.js +7 -3
  23. package/dist/components/drawer/Drawer.d.ts +52 -0
  24. package/dist/components/drawer/Drawer.js +120 -0
  25. package/dist/components/drawer/index.d.ts +2 -0
  26. package/dist/components/drawer/index.js +1 -0
  27. package/dist/components/field/Field.d.ts +8 -5
  28. package/dist/components/field/Field.js +9 -3
  29. package/dist/components/input-otp/InputOtp.d.ts +43 -0
  30. package/dist/components/input-otp/InputOtp.js +45 -0
  31. package/dist/components/input-otp/index.d.ts +2 -0
  32. package/dist/components/input-otp/index.js +1 -0
  33. package/dist/components/key-value-list/KeyValueList.d.ts +25 -0
  34. package/dist/components/key-value-list/KeyValueList.js +40 -0
  35. package/dist/components/key-value-list/index.d.ts +2 -0
  36. package/dist/components/key-value-list/index.js +1 -0
  37. package/dist/components/link/Link.js +1 -1
  38. package/dist/components/page-header/PageHeader.js +8 -8
  39. package/dist/components/progress/Progress.d.ts +25 -0
  40. package/dist/components/progress/Progress.js +38 -0
  41. package/dist/components/progress/index.d.ts +2 -0
  42. package/dist/components/progress/index.js +1 -0
  43. package/dist/components/radio-group/RadioGroup.d.ts +18 -0
  44. package/dist/components/radio-group/RadioGroup.js +32 -0
  45. package/dist/components/radio-group/index.d.ts +2 -0
  46. package/dist/components/radio-group/index.js +1 -0
  47. package/dist/components/scroll-area/ScrollArea.d.ts +12 -0
  48. package/dist/components/scroll-area/ScrollArea.js +34 -0
  49. package/dist/components/scroll-area/index.d.ts +2 -0
  50. package/dist/components/scroll-area/index.js +1 -0
  51. package/dist/components/separator/Separator.d.ts +15 -0
  52. package/dist/components/separator/Separator.js +25 -0
  53. package/dist/components/separator/index.d.ts +2 -0
  54. package/dist/components/separator/index.js +1 -0
  55. package/dist/components/sheet/Sheet.d.ts +52 -0
  56. package/dist/components/sheet/Sheet.js +89 -0
  57. package/dist/components/sheet/index.d.ts +2 -0
  58. package/dist/components/sheet/index.js +1 -0
  59. package/dist/components/summary-chips/SummaryChips.js +1 -1
  60. package/dist/components/tag-input/TagInput.js +1 -1
  61. package/dist/index.d.ts +28 -4
  62. package/dist/index.js +13 -1
  63. package/dist/lib/cn.js +2 -1
  64. package/dist/styles.css +1 -1
  65. package/package.json +52 -1
@@ -0,0 +1,19 @@
1
+ import { Accordion } from "@base-ui/react/accordion";
2
+ import { JSX } from "react";
3
+ /** The props of Accordion: Base UI's accordion props, except className, style and render. */
4
+ export type AccordionProps = Omit<Accordion.Root.Props, 'className' | 'style' | 'render'>;
5
+ /** The props of AccordionItem: Base UI's item props, except className, style and render. Give each a value. */
6
+ export type AccordionItemProps = Omit<Accordion.Item.Props, 'className' | 'style' | 'render'>;
7
+ /** The props of AccordionTrigger: Base UI's trigger props, except className, style and render. */
8
+ export type AccordionTriggerProps = Omit<Accordion.Trigger.Props, 'className' | 'style' | 'render'>;
9
+ /** The props of AccordionContent: Base UI's panel props, except className, style and render. */
10
+ export type AccordionContentProps = Omit<Accordion.Panel.Props, 'className' | 'style' | 'render'>;
11
+ /** A stack of sections that open and close. One section is open at a time unless multiple is set. */
12
+ declare function Accordion$1({ ...props }: AccordionProps): JSX.Element;
13
+ /** One section: a trigger and its content, separated from the next by a hairline. */
14
+ export declare function AccordionItem({ ...props }: AccordionItemProps): JSX.Element;
15
+ /** The heading row of a section, with a chevron that turns when it is open. */
16
+ export declare function AccordionTrigger({ children, ...props }: AccordionTriggerProps): JSX.Element;
17
+ /** The body of a section. It appears and disappears at once, with no height animation. */
18
+ export declare function AccordionContent({ children, ...props }: AccordionContentProps): JSX.Element;
19
+ export { Accordion$1 as Accordion };
@@ -0,0 +1,52 @@
1
+ import { cn } from "../../lib/cn.js";
2
+ import { Icon } from "../icon/Icon.js";
3
+ import { Accordion } from "@base-ui/react/accordion";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ // src/components/accordion/Accordion.tsx
6
+ /** A stack of sections that open and close. One section is open at a time unless multiple is set. */
7
+ function Accordion$1({ ...props }) {
8
+ return /* @__PURE__ */ jsx(Accordion.Root, {
9
+ "data-slot": "accordion",
10
+ className: "rt:flex rt:w-full rt:flex-col",
11
+ ...props
12
+ });
13
+ }
14
+ /** One section: a trigger and its content, separated from the next by a hairline. */
15
+ function AccordionItem({ ...props }) {
16
+ return /* @__PURE__ */ jsx(Accordion.Item, {
17
+ "data-slot": "accordion-item",
18
+ className: "rt:not-last:border-b rt:not-last:border-divider",
19
+ ...props
20
+ });
21
+ }
22
+ /** The heading row of a section, with a chevron that turns when it is open. */
23
+ function AccordionTrigger({ children, ...props }) {
24
+ return /* @__PURE__ */ jsx(Accordion.Header, {
25
+ className: "rt:flex",
26
+ children: /* @__PURE__ */ jsxs(Accordion.Trigger, {
27
+ "data-slot": "accordion-trigger",
28
+ className: cn("rt:group/accordion-trigger rt:flex rt:flex-1 rt:cursor-pointer rt:items-center rt:justify-between rt:gap-2 rt:rounded-lg rt:bg-transparent rt:py-2.75 rt:text-left rt:text-b4 rt:text-foreground rt:outline-none", "rt:focus-visible:focus-ring rt:forced-outline", "rt:disabled:cursor-not-allowed rt:disabled:opacity-50 rt:data-disabled:cursor-not-allowed rt:data-disabled:opacity-50"),
29
+ ...props,
30
+ children: [children, /* @__PURE__ */ jsx("span", {
31
+ className: "rt:flex rt:shrink-0 rt:rotate-0 rt:text-muted-foreground rt:group-aria-expanded/accordion-trigger:rotate-180",
32
+ children: /* @__PURE__ */ jsx(Icon, {
33
+ name: "nav-chevron",
34
+ size: 12
35
+ })
36
+ })]
37
+ })
38
+ });
39
+ }
40
+ /** The body of a section. It appears and disappears at once, with no height animation. */
41
+ function AccordionContent({ children, ...props }) {
42
+ return /* @__PURE__ */ jsx(Accordion.Panel, {
43
+ "data-slot": "accordion-content",
44
+ className: "rt:overflow-hidden rt:text-b3 rt:text-foreground",
45
+ ...props,
46
+ children: /* @__PURE__ */ jsx("div", {
47
+ className: "rt:pb-2.75",
48
+ children
49
+ })
50
+ });
51
+ }
52
+ export { Accordion$1 as Accordion, AccordionContent, AccordionItem, AccordionTrigger };
@@ -0,0 +1,2 @@
1
+ import { Accordion, AccordionContent, AccordionContentProps, AccordionItem, AccordionItemProps, AccordionProps, AccordionTrigger, AccordionTriggerProps } from "./Accordion.js";
2
+ export { Accordion, AccordionContent, type AccordionContentProps, AccordionItem, type AccordionItemProps, type AccordionProps, AccordionTrigger, type AccordionTriggerProps };
@@ -0,0 +1 @@
1
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "./Accordion.js";
@@ -0,0 +1,19 @@
1
+ import { JSX, Ref } from "react";
2
+ /** One step of the trail. The last item, or any item without an href, is shown as plain text; the last is the current page. */
3
+ export type BreadcrumbItem = {
4
+ /** The text of the step. */
5
+ label: string;
6
+ /** Where the step goes. Leave out for the current page. */
7
+ href?: string;
8
+ };
9
+ /** The props of Breadcrumb. */
10
+ export type BreadcrumbProps = {
11
+ /** The trail, from the root to the current page. */
12
+ items: BreadcrumbItem[];
13
+ /** Past this many items the middle ones collapse behind an ellipsis, keeping the first and the last two. */
14
+ maxItems?: number;
15
+ /** Receives the rendered nav. */
16
+ ref?: Ref<HTMLElement>;
17
+ };
18
+ /** The trail to the current page: links, chevron separators, the current page as text and an overflow ellipsis. */
19
+ export declare function Breadcrumb({ items, maxItems, ref }: BreadcrumbProps): JSX.Element;
@@ -0,0 +1,50 @@
1
+ import { cn } from "../../lib/cn.js";
2
+ import { Icon } from "../icon/Icon.js";
3
+ import { RatioLink } from "../link-provider/RatioLink.js";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { useState } from "react";
6
+ // src/components/breadcrumb/Breadcrumb.tsx
7
+ const STEP = "rt:text-b3 rt:rounded-sm rt:focus-visible:focus-ring";
8
+ /** The trail to the current page: links, chevron separators, the current page as text and an overflow ellipsis. */
9
+ function Breadcrumb({ items, maxItems, ref }) {
10
+ const [expanded, setExpanded] = useState(false);
11
+ const shown = !expanded && maxItems !== void 0 && items.length > maxItems && items.length > 3 ? [
12
+ items[0],
13
+ "ellipsis",
14
+ ...items.slice(items.length - 2)
15
+ ] : items;
16
+ return /* @__PURE__ */ jsx("nav", {
17
+ ref,
18
+ "aria-label": "Breadcrumb",
19
+ "data-slot": "breadcrumb",
20
+ children: /* @__PURE__ */ jsx("ol", {
21
+ className: "rt:flex rt:flex-wrap rt:items-center rt:gap-2 rt:text-foreground-subdued",
22
+ children: shown.map((item, i) => {
23
+ const isLast = i === shown.length - 1;
24
+ return /* @__PURE__ */ jsxs("li", {
25
+ className: "rt:inline-flex rt:items-center rt:gap-2",
26
+ children: [item === "ellipsis" ? /* @__PURE__ */ jsx("button", {
27
+ type: "button",
28
+ "aria-label": "Show hidden pages",
29
+ onClick: () => setExpanded(true),
30
+ className: cn(STEP, "rt:px-1 rt:transition-colors rt:hover:text-foreground"),
31
+ children: "…"
32
+ }) : isLast || !item.href ? /* @__PURE__ */ jsx("span", {
33
+ ...isLast ? { "aria-current": "page" } : {},
34
+ className: cn(STEP, isLast ? "rt:text-foreground" : ""),
35
+ children: item.label
36
+ }) : /* @__PURE__ */ jsx(RatioLink, {
37
+ href: item.href,
38
+ className: cn(STEP, "rt:transition-colors rt:hover:text-foreground"),
39
+ children: item.label
40
+ }), !isLast && /* @__PURE__ */ jsx(Icon, {
41
+ name: "chevron-right",
42
+ size: 8,
43
+ tone: "icon"
44
+ })]
45
+ }, item === "ellipsis" ? "ellipsis" : `${item.label}|${item.href ?? ""}`);
46
+ })
47
+ })
48
+ });
49
+ }
50
+ export { Breadcrumb };
@@ -0,0 +1,2 @@
1
+ import { Breadcrumb, BreadcrumbItem, BreadcrumbProps } from "./Breadcrumb.js";
2
+ export { Breadcrumb, type BreadcrumbItem, type BreadcrumbProps };
@@ -0,0 +1 @@
1
+ export { Breadcrumb } from "./Breadcrumb.js";
@@ -0,0 +1,137 @@
1
+ import { IconName } from "../icon/registry.js";
2
+ import "../icon/index.js";
3
+ import { HTMLAttributes, JSX, ReactElement, ReactNode } from "react";
4
+ import * as RechartsPrimitive from "recharts";
5
+ import { DefaultLegendContentProps, DefaultTooltipContentProps, TooltipValueType } from "recharts";
6
+ type TooltipNameType = number | string;
7
+ type TooltipContent = DefaultTooltipContentProps<TooltipValueType, TooltipNameType>;
8
+ /**
9
+ * A chart colour token, in series order: chart-1 the accent blue, chart-2 the body ink, chart-3 the placeholder grey,
10
+ * chart-4 the accent tint and chart-5 the line grey. chart-4 and chart-5 sit below 3:1 on white, so draw them only
11
+ * beside a darker series or with a stroke.
12
+ */
13
+ export type ChartColor = 'chart-1' | 'chart-2' | 'chart-3' | 'chart-4' | 'chart-5';
14
+ /** How one series or category of a chart is named and coloured. */
15
+ export interface ChartSeriesConfig {
16
+ /** The name the tooltip, the legend and the data table show for it. */
17
+ label?: ReactNode;
18
+ /** An icon drawn in place of its colour swatch in the tooltip and the legend. */
19
+ icon?: IconName;
20
+ /** The chart token it is drawn in. Pass the same token to the series with chartColor. */
21
+ color?: ChartColor;
22
+ }
23
+ /** The series and categories of a chart, by data key. */
24
+ export type ChartConfig = Record<string, ChartSeriesConfig>;
25
+ /**
26
+ * The value a Recharts fill or stroke takes for a chart token, such as var(--rt-chart-1). Series are coloured only from
27
+ * these tokens.
28
+ */
29
+ export declare function chartColor(color: ChartColor): string;
30
+ /** The rows a chart offers assistive technology as a table, beside the drawing. */
31
+ export interface ChartTable {
32
+ /** The rows of the chart, as passed to its data prop. */
33
+ data: ReadonlyArray<Record<string, unknown>>;
34
+ /** The key of each row's label, such as the day on the x axis: the table's first column. A Date is written as a date. */
35
+ labelKey: string;
36
+ /** Writes each number of the series, such as formatMoney for sales. Defaults to a count. */
37
+ formatValue?: (value: number) => string;
38
+ }
39
+ /** A chart needs a summary: a description, a data table, or both. */
40
+ type ChartSummary = {
41
+ /** One sentence on what the chart shows, read after its name, such as "Sales peak on Tuesday". */
42
+ description: string;
43
+ /** The chart's rows as a visually hidden table, for assistive technology. */
44
+ table?: ChartTable;
45
+ } | {
46
+ /** One sentence on what the chart shows, read after its name, such as "Sales peak on Tuesday". */
47
+ description?: string;
48
+ /** The chart's rows as a visually hidden table, for assistive technology. */
49
+ table: ChartTable;
50
+ };
51
+ /** How a chart takes its size: 16:9 or square at the full width, or the full size of its parent. */
52
+ export type ChartAspect = 'video' | 'square' | 'fill';
53
+ /**
54
+ * The props of Chart: the HTML attributes of its div, except className, style and children, with the config, the
55
+ * accessible name and summary, and one Recharts chart.
56
+ */
57
+ export type ChartProps = Omit<HTMLAttributes<HTMLDivElement>, 'className' | 'style' | 'children'> & ChartSummary & {
58
+ /** The series and categories, by data key: their labels, icons and chart tokens. */
59
+ config: ChartConfig;
60
+ /** The chart's accessible name, such as "Sales by day". */
61
+ label: string;
62
+ /** The size: video (16:9, the default) or square at the full width, or fill to take the parent's size. */
63
+ aspect?: ChartAspect;
64
+ /** The size the chart is drawn at before it measures its box. Defaults to 320 by 200. */
65
+ initialDimension?: {
66
+ width: number;
67
+ height: number;
68
+ };
69
+ /** One Recharts chart, such as a BarChart or a LineChart, whose series pass isAnimationActive false. */
70
+ children: ReactElement;
71
+ };
72
+ /**
73
+ * A chart on Recharts, drawn with the chart tokens. It holds the config the tooltip and legend read, styles Recharts'
74
+ * ticks, grid and cursor with the tokens, and is a figure named by its label and summarised by a description, a visually
75
+ * hidden data table, or both. Motion is colour fades only, so every series passes isAnimationActive false.
76
+ */
77
+ export declare function Chart({ config, label, description, table, aspect, initialDimension, children, ...rest }: ChartProps): JSX.Element;
78
+ /**
79
+ * The props of ChartTooltip: Recharts' Tooltip props, except its style and class name props. Its content defaults to
80
+ * ChartTooltipContent; it never animates.
81
+ */
82
+ export type ChartTooltipProps = Omit<RechartsPrimitive.TooltipProps<TooltipValueType, TooltipNameType>, 'wrapperStyle' | 'contentStyle' | 'itemStyle' | 'labelStyle' | 'wrapperClassName' | 'labelClassName' | 'cursor'> & {
83
+ /** Shows the cursor line or band under the pointer. On or off: Recharts' SVG props would carry a class name and a style. */
84
+ cursor?: boolean;
85
+ };
86
+ /** The chart's tooltip: Recharts' Tooltip, still (no movement), drawing ChartTooltipContent unless given other content. */
87
+ export declare function ChartTooltip({ content, ...props }: ChartTooltipProps): JSX.Element;
88
+ /** The props of ChartTooltipContent. The tooltip sets active, payload and label; the rest choose what it shows. */
89
+ export interface ChartTooltipContentProps {
90
+ /** Set by the tooltip: whether a point is active. */
91
+ active?: boolean;
92
+ /** Set by the tooltip: the values of the series at the active point. */
93
+ payload?: TooltipContent['payload'];
94
+ /** Set by the tooltip: the active point's label, such as its x-axis category. */
95
+ label?: TooltipContent['label'];
96
+ /** Writes the label from it and the payload. */
97
+ labelFormatter?: TooltipContent['labelFormatter'];
98
+ /** Draws a whole row, in place of the swatch, name and value, from the value, name, item, index and payload. */
99
+ formatter?: TooltipContent['formatter'];
100
+ /** The swatch: a dot (the default), a line or a dashed line. */
101
+ indicator?: 'dot' | 'line' | 'dashed';
102
+ /** Leaves out the label. */
103
+ hideLabel?: boolean;
104
+ /** Leaves out the swatches. */
105
+ hideIndicator?: boolean;
106
+ /** The key of the item, or its data row, whose value names the config entry of a row. */
107
+ nameKey?: string;
108
+ /** The key whose config entry labels the tooltip, in place of the active point's label. */
109
+ labelKey?: string;
110
+ /** One chart token for every swatch, in place of each series' own. */
111
+ color?: ChartColor;
112
+ /** Writes a number for its series, such as formatMoney for sales. Defaults to a count. */
113
+ formatValue?: (value: number) => string;
114
+ }
115
+ /**
116
+ * The box a chart tooltip draws: the active point's label, then a row per series with its swatch, its config label and
117
+ * its value, a count unless formatValue writes it. A 1px border on white, no shadow.
118
+ */
119
+ export declare function ChartTooltipContent({ active, payload, label, labelFormatter, formatter, indicator, hideLabel, hideIndicator, nameKey, labelKey, color, formatValue }: ChartTooltipContentProps): JSX.Element | null;
120
+ /** The props of ChartLegend: Recharts' Legend props, except its style props. Its content defaults to ChartLegendContent. */
121
+ export type ChartLegendProps = Omit<RechartsPrimitive.LegendProps, 'wrapperStyle' | 'labelStyle'>;
122
+ /** The chart's legend: Recharts' Legend, drawing ChartLegendContent unless given other content. */
123
+ export declare function ChartLegend({ content, ...props }: ChartLegendProps): JSX.Element;
124
+ /** The props of ChartLegendContent. The legend sets payload and verticalAlign; the rest choose what it shows. */
125
+ export interface ChartLegendContentProps {
126
+ /** Set by the legend: its series. */
127
+ payload?: DefaultLegendContentProps['payload'];
128
+ /** Set by the legend: whether it sits above or below the chart, which sets the side of its gap. */
129
+ verticalAlign?: DefaultLegendContentProps['verticalAlign'];
130
+ /** Draws the swatch even where the config gives an icon. */
131
+ hideIcon?: boolean;
132
+ /** The key of the item whose value names the config entry of a series. */
133
+ nameKey?: string;
134
+ }
135
+ /** The row a chart legend draws: a swatch in each series' chart token, or its icon, and its config label. */
136
+ export declare function ChartLegendContent({ payload, verticalAlign, hideIcon, nameKey }: ChartLegendContentProps): JSX.Element | null;
137
+ export {};
@@ -0,0 +1,238 @@
1
+ import { cn } from "../../lib/cn.js";
2
+ import { Icon } from "../icon/Icon.js";
3
+ import { formatCount, formatDate } from "../../lib/format.js";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+ import { createContext, use, useId, useMemo } from "react";
6
+ import * as RechartsPrimitive from "recharts";
7
+ // src/components/chart/Chart.tsx
8
+ /**
9
+ * The value a Recharts fill or stroke takes for a chart token, such as var(--rt-chart-1). Series are coloured only from
10
+ * these tokens.
11
+ */
12
+ function chartColor(color) {
13
+ return `var(--rt-${color})`;
14
+ }
15
+ /** The swatch classes of each token: a fill for the dot and line indicators, a border for the dashed one. */
16
+ const SWATCH = {
17
+ "chart-1": {
18
+ fill: "rt:bg-chart-1",
19
+ border: "rt:border-chart-1"
20
+ },
21
+ "chart-2": {
22
+ fill: "rt:bg-chart-2",
23
+ border: "rt:border-chart-2"
24
+ },
25
+ "chart-3": {
26
+ fill: "rt:bg-chart-3",
27
+ border: "rt:border-chart-3"
28
+ },
29
+ "chart-4": {
30
+ fill: "rt:bg-chart-4",
31
+ border: "rt:border-chart-4"
32
+ },
33
+ "chart-5": {
34
+ fill: "rt:bg-chart-5",
35
+ border: "rt:border-chart-5"
36
+ }
37
+ };
38
+ /** The swatch classes of a series whose token is not known: the muted ink. */
39
+ const UNKNOWN_SWATCH = {
40
+ fill: "rt:bg-muted-foreground",
41
+ border: "rt:border-muted-foreground"
42
+ };
43
+ const TOKEN_VALUE = /var\(--rt-(chart-[1-5])\)/;
44
+ /** The chart token a Recharts colour names, when it was written with chartColor. */
45
+ function tokenOf(value) {
46
+ const match = typeof value === "string" ? TOKEN_VALUE.exec(value) : null;
47
+ return match ? match[1] : void 0;
48
+ }
49
+ const ChartContext = createContext(null);
50
+ function useChart() {
51
+ const context = use(ChartContext);
52
+ if (!context) throw new Error("useChart must be used within a <Chart />");
53
+ return context;
54
+ }
55
+ const INITIAL_DIMENSION = {
56
+ width: 320,
57
+ height: 200
58
+ };
59
+ const ASPECT = {
60
+ video: "rt:aspect-video rt:w-full",
61
+ square: "rt:aspect-square rt:w-full",
62
+ fill: "rt:size-full"
63
+ };
64
+ function cellText(value, formatValue = formatCount) {
65
+ if (typeof value === "number") return formatValue(value);
66
+ if (value instanceof Date) return formatDate(value);
67
+ return typeof value === "string" ? value : "";
68
+ }
69
+ function ChartDataTable({ label, config, table }) {
70
+ const { data, labelKey, formatValue } = table;
71
+ const keys = Object.keys(config).filter((key) => key !== labelKey && data.some((row) => key in row));
72
+ return /* @__PURE__ */ jsx("div", {
73
+ "data-slot": "chart-table",
74
+ className: "rt:sr-only",
75
+ children: /* @__PURE__ */ jsxs("table", { children: [
76
+ /* @__PURE__ */ jsx("caption", { children: label }),
77
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [/* @__PURE__ */ jsx("th", {
78
+ scope: "col",
79
+ children: config[labelKey]?.label ?? labelKey
80
+ }), keys.map((key) => /* @__PURE__ */ jsx("th", {
81
+ scope: "col",
82
+ children: config[key]?.label ?? key
83
+ }, key))] }) }),
84
+ /* @__PURE__ */ jsx("tbody", { children: data.map((row) => /* @__PURE__ */ jsxs("tr", { children: [/* @__PURE__ */ jsx("th", {
85
+ scope: "row",
86
+ children: cellText(row[labelKey])
87
+ }), keys.map((key) => /* @__PURE__ */ jsx("td", { children: cellText(row[key], formatValue) }, key))] }, cellText(row[labelKey]))) })
88
+ ] })
89
+ });
90
+ }
91
+ /**
92
+ * A chart on Recharts, drawn with the chart tokens. It holds the config the tooltip and legend read, styles Recharts'
93
+ * ticks, grid and cursor with the tokens, and is a figure named by its label and summarised by a description, a visually
94
+ * hidden data table, or both. Motion is colour fades only, so every series passes isAnimationActive false.
95
+ */
96
+ function Chart({ config, label, description, table, aspect = "video", initialDimension = INITIAL_DIMENSION, children, ...rest }) {
97
+ const descriptionId = `${useId()}-description`;
98
+ const value = useMemo(() => ({ config }), [config]);
99
+ return /* @__PURE__ */ jsx(ChartContext, {
100
+ value,
101
+ children: /* @__PURE__ */ jsxs("div", {
102
+ ...rest,
103
+ "data-slot": "chart",
104
+ role: "figure",
105
+ "aria-label": label,
106
+ "aria-describedby": description ? descriptionId : void 0,
107
+ className: cn("rt:recharts rt:relative rt:flex rt:justify-center rt:text-c1 rt:text-foreground", ASPECT[aspect]),
108
+ children: [
109
+ description ? /* @__PURE__ */ jsx("p", {
110
+ id: descriptionId,
111
+ hidden: true,
112
+ children: description
113
+ }) : null,
114
+ table ? /* @__PURE__ */ jsx(ChartDataTable, {
115
+ label,
116
+ config,
117
+ table
118
+ }) : null,
119
+ /* @__PURE__ */ jsx(RechartsPrimitive.ResponsiveContainer, {
120
+ initialDimension,
121
+ children
122
+ })
123
+ ]
124
+ })
125
+ });
126
+ }
127
+ /** The config entry of a tooltip or legend item: by the item's name key, else by the key itself. */
128
+ function configOf(config, payload, key) {
129
+ if (typeof payload !== "object" || payload === null) return;
130
+ const row = "payload" in payload && typeof payload.payload === "object" && payload.payload !== null ? payload.payload : void 0;
131
+ let configKey = key;
132
+ if (key in payload && typeof payload[key] === "string") configKey = payload[key];
133
+ else if (row && key in row && typeof row[key] === "string") configKey = row[key];
134
+ return configKey in config ? config[configKey] : config[key];
135
+ }
136
+ /** The chart's tooltip: Recharts' Tooltip, still (no movement), drawing ChartTooltipContent unless given other content. */
137
+ function ChartTooltip({ content = /* @__PURE__ */ jsx(ChartTooltipContent, {}), ...props }) {
138
+ return /* @__PURE__ */ jsx(RechartsPrimitive.Tooltip, {
139
+ content,
140
+ ...props,
141
+ isAnimationActive: false
142
+ });
143
+ }
144
+ /** The swatch of a tooltip or legend item, in its chart token. */
145
+ function Swatch({ color, indicator, nested }) {
146
+ const tone = color ? SWATCH[color] : UNKNOWN_SWATCH;
147
+ return /* @__PURE__ */ jsx("div", {
148
+ "data-slot": "chart-swatch",
149
+ className: cn("rt:shrink-0 rt:rounded-sm", indicator === "dot" && cn("rt:size-2.5", tone.fill), indicator === "line" && cn("rt:w-1", tone.fill), indicator === "dashed" && cn("rt:w-0 rt:border-2 rt:border-dashed rt:bg-transparent", tone.border), nested && indicator === "dashed" && "rt:my-0.5")
150
+ });
151
+ }
152
+ /**
153
+ * The box a chart tooltip draws: the active point's label, then a row per series with its swatch, its config label and
154
+ * its value, a count unless formatValue writes it. A 1px border on white, no shadow.
155
+ */
156
+ function ChartTooltipContent({ active, payload, label, labelFormatter, formatter, indicator = "dot", hideLabel = false, hideIndicator = false, nameKey, labelKey, color, formatValue = formatCount }) {
157
+ const { config } = useChart();
158
+ if (!active || !payload?.length) return null;
159
+ const tooltipLabel = (() => {
160
+ if (hideLabel) return null;
161
+ const [item] = payload;
162
+ const key = `${labelKey ?? item?.dataKey ?? item?.name ?? "value"}`;
163
+ const itemConfig = configOf(config, item, key);
164
+ const value = !labelKey && typeof label === "string" ? config[label]?.label ?? label : itemConfig?.label;
165
+ const text = labelFormatter ? labelFormatter(value, payload) : value;
166
+ return text ? /* @__PURE__ */ jsx("div", {
167
+ className: "rt:text-c2",
168
+ children: text
169
+ }) : null;
170
+ })();
171
+ const nestLabel = payload.length === 1 && indicator !== "dot";
172
+ return /* @__PURE__ */ jsxs("div", {
173
+ "data-slot": "chart-tooltip",
174
+ className: "rt:grid rt:min-w-32 rt:items-start rt:gap-1.5 rt:rounded-lg rt:border rt:border-border rt:bg-background rt:px-3 rt:py-1.5 rt:text-c1 rt:text-foreground",
175
+ children: [nestLabel ? null : tooltipLabel, /* @__PURE__ */ jsx("div", {
176
+ className: "rt:grid rt:gap-1.5",
177
+ children: payload.filter((item) => item.type !== "none").map((item, index) => {
178
+ const key = `${nameKey ?? item.name ?? item.dataKey ?? "value"}`;
179
+ const itemConfig = configOf(config, item, key);
180
+ const tone = color ?? itemConfig?.color ?? tokenOf(item.payload?.fill) ?? tokenOf(item.color);
181
+ return /* @__PURE__ */ jsx("div", {
182
+ className: cn("rt:flex rt:w-full rt:flex-wrap rt:items-stretch rt:gap-2", indicator === "dot" && "rt:items-center"),
183
+ children: formatter && item.value !== void 0 && item.name ? formatter(item.value, item.name, item, index, payload) : /* @__PURE__ */ jsxs(Fragment, { children: [itemConfig?.icon ? /* @__PURE__ */ jsx(Icon, {
184
+ name: itemConfig.icon,
185
+ tone: "subdued"
186
+ }) : hideIndicator ? null : /* @__PURE__ */ jsx(Swatch, {
187
+ color: tone,
188
+ indicator,
189
+ nested: nestLabel
190
+ }), /* @__PURE__ */ jsxs("div", {
191
+ className: cn("rt:flex rt:flex-1 rt:justify-between rt:gap-2", nestLabel ? "rt:items-end" : "rt:items-center"),
192
+ children: [/* @__PURE__ */ jsxs("div", {
193
+ className: "rt:grid rt:gap-1.5",
194
+ children: [nestLabel ? tooltipLabel : null, /* @__PURE__ */ jsx("span", {
195
+ className: "rt:text-muted-foreground",
196
+ children: itemConfig?.label ?? item.name
197
+ })]
198
+ }), item.value != null ? /* @__PURE__ */ jsx("span", {
199
+ className: "rt:text-c2 rt:text-foreground rt:tabular-nums",
200
+ children: typeof item.value === "number" ? formatValue(item.value) : String(item.value)
201
+ }) : null]
202
+ })] })
203
+ }, key);
204
+ })
205
+ })]
206
+ });
207
+ }
208
+ /** The chart's legend: Recharts' Legend, drawing ChartLegendContent unless given other content. */
209
+ function ChartLegend({ content = /* @__PURE__ */ jsx(ChartLegendContent, {}), ...props }) {
210
+ return /* @__PURE__ */ jsx(RechartsPrimitive.Legend, {
211
+ content,
212
+ ...props
213
+ });
214
+ }
215
+ /** The row a chart legend draws: a swatch in each series' chart token, or its icon, and its config label. */
216
+ function ChartLegendContent({ payload, verticalAlign = "bottom", hideIcon = false, nameKey }) {
217
+ const { config } = useChart();
218
+ if (!payload?.length) return null;
219
+ return /* @__PURE__ */ jsx("div", {
220
+ "data-slot": "chart-legend",
221
+ className: cn("rt:flex rt:items-center rt:justify-center rt:gap-3", verticalAlign === "top" ? "rt:pb-3" : "rt:pt-3"),
222
+ children: payload.filter((item) => item.type !== "none").map((item) => {
223
+ const key = `${nameKey ?? item.dataKey ?? "value"}`;
224
+ const itemConfig = configOf(config, item, key);
225
+ return /* @__PURE__ */ jsxs("div", {
226
+ className: "rt:flex rt:items-center rt:gap-1.5",
227
+ children: [itemConfig?.icon && !hideIcon ? /* @__PURE__ */ jsx(Icon, {
228
+ name: itemConfig.icon,
229
+ tone: "subdued"
230
+ }) : /* @__PURE__ */ jsx("div", {
231
+ "data-slot": "chart-swatch",
232
+ className: cn("rt:size-2 rt:shrink-0 rt:rounded-sm", (SWATCH[itemConfig?.color ?? tokenOf(item.color) ?? "none"] ?? UNKNOWN_SWATCH).fill)
233
+ }), itemConfig?.label ?? item.value]
234
+ }, key);
235
+ })
236
+ });
237
+ }
238
+ export { Chart, ChartLegend, ChartLegendContent, ChartTooltip, ChartTooltipContent, chartColor };
@@ -0,0 +1,2 @@
1
+ import { Chart, ChartAspect, ChartColor, ChartConfig, ChartLegend, ChartLegendContent, ChartLegendContentProps, ChartLegendProps, ChartProps, ChartSeriesConfig, ChartTable, ChartTooltip, ChartTooltipContent, ChartTooltipContentProps, ChartTooltipProps, chartColor } from "./Chart.js";
2
+ export { Chart, type ChartAspect, type ChartColor, type ChartConfig, ChartLegend, ChartLegendContent, type ChartLegendContentProps, type ChartLegendProps, type ChartProps, type ChartSeriesConfig, type ChartTable, ChartTooltip, ChartTooltipContent, type ChartTooltipContentProps, type ChartTooltipProps, chartColor };
@@ -0,0 +1 @@
1
+ export { Chart, ChartLegend, ChartLegendContent, ChartTooltip, ChartTooltipContent, chartColor } from "./Chart.js";
@@ -0,0 +1,52 @@
1
+ import { JSX, Ref } from "react";
2
+ import { Combobox } from "@base-ui/react/combobox";
3
+ /** One option: the value that is stored and the text people see. A plain string stands for both. */
4
+ export type ComboboxItem = string | {
5
+ value: string;
6
+ label: string;
7
+ };
8
+ /** The props of Combobox: one choice from a list, with a search field. */
9
+ export type ComboboxProps = {
10
+ /** The options. Strings or { value, label } objects. */
11
+ items: readonly ComboboxItem[];
12
+ /** The chosen value for a controlled combobox, or null for none. */
13
+ value?: string | null;
14
+ /** The value to start with when the combobox keeps its own state. */
15
+ defaultValue?: string | null;
16
+ /** Called with the new value, or null when the choice is cleared. */
17
+ onValueChange?: (value: string | null, eventDetails: Combobox.Root.ChangeEventDetails) => void;
18
+ /** The text shown while nothing is chosen. */
19
+ placeholder?: string;
20
+ /** The text shown when the search matches no option. Defaults to "No results found". */
21
+ emptyText?: string;
22
+ /** Marks the field invalid and draws the error ring, as on every form control. Field sets it when it shows an error. */
23
+ 'aria-invalid'?: boolean | 'true' | 'false';
24
+ /** The same as aria-invalid, kept as its alias. */
25
+ invalid?: boolean;
26
+ /** Shows a button that clears the choice while one is made. Defaults to true. */
27
+ clearable?: boolean;
28
+ /** Stops people from changing the choice. */
29
+ disabled?: boolean;
30
+ /** The name of the field in a form. */
31
+ name?: string;
32
+ /** The accessible name when no label is wired to the field. */
33
+ 'aria-label'?: string;
34
+ /** The ids of the elements that name the field. Field sets it to its label. */
35
+ 'aria-labelledby'?: string;
36
+ /** The ids of the elements that describe the field, such as its hint or error. Field sets it. */
37
+ 'aria-describedby'?: string;
38
+ /** Tells assistive technology that the field must be filled. Field sets it for a required field. */
39
+ 'aria-required'?: boolean | 'true' | 'false';
40
+ /** The id of the input, for a label's htmlFor. */
41
+ id?: string;
42
+ /** Receives the input element. */
43
+ ref?: Ref<HTMLInputElement>;
44
+ };
45
+ /**
46
+ * A field to choose one option from a list, with a search: type to narrow the list, pick with the mouse or Enter.
47
+ * The field looks like an Input and the list like a Popover panel. For several choices shown as chips, use TagInput.
48
+ * Mark it invalid with aria-invalid; give the list an empty text with emptyText. Inside a Field, the label, hint, error
49
+ * and required mark reach the input.
50
+ */
51
+ declare function Combobox$1({ items, value, defaultValue, onValueChange, placeholder, emptyText, 'aria-invalid': ariaInvalid, invalid, clearable, disabled, name, id, ref, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, 'aria-describedby': ariaDescribedBy, 'aria-required': ariaRequired }: ComboboxProps): JSX.Element;
52
+ export { Combobox$1 as Combobox };