@fiestaboard/ui 5.3.0 → 5.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -0
- package/dist/components/chrome/nav-list.d.ts +53 -0
- package/dist/components/chrome/nav-list.js +84 -0
- package/dist/components/chrome/nav-list.js.map +1 -0
- package/dist/components/containment/icon-tile.d.ts +67 -0
- package/dist/components/containment/icon-tile.js +44 -0
- package/dist/components/containment/icon-tile.js.map +1 -0
- package/dist/components/containment/json-tree.js +1 -1
- package/dist/components/containment/json-tree.js.map +1 -1
- package/dist/components/containment/scroll-area.d.ts +17 -0
- package/dist/components/containment/scroll-area.js +2 -2
- package/dist/components/containment/scroll-area.js.map +1 -1
- package/dist/components/containment/tabs.js +2 -2
- package/dist/components/containment/tabs.js.map +1 -1
- package/dist/components/editor/formula/formula-editor-panel.js +2 -2
- package/dist/components/editor/formula/formula-editor-panel.js.map +1 -1
- package/dist/components/editor/template-editor-toolbar.d.ts +27 -3
- package/dist/components/editor/template-editor-toolbar.js +99 -96
- package/dist/components/editor/template-editor-toolbar.js.map +1 -1
- package/dist/components/forms/button.d.ts +1 -1
- package/dist/components/forms/button.js +2 -0
- package/dist/components/forms/button.js.map +1 -1
- package/dist/components/forms/selection-group.d.ts +82 -0
- package/dist/components/forms/selection-group.js +51 -0
- package/dist/components/forms/selection-group.js.map +1 -0
- package/dist/components/forms/swatch.d.ts +81 -0
- package/dist/components/forms/swatch.js +91 -0
- package/dist/components/forms/swatch.js.map +1 -0
- package/dist/components/forms/timezone-picker.d.ts +163 -0
- package/dist/components/forms/timezone-picker.js +158 -0
- package/dist/components/forms/timezone-picker.js.map +1 -0
- package/dist/components/forms/toggle-card.d.ts +45 -35
- package/dist/components/forms/toggle-card.js +187 -122
- package/dist/components/forms/toggle-card.js.map +1 -1
- package/dist/components/forms/toggle.d.ts +1 -1
- package/dist/components/layout/flex.d.ts +1 -1
- package/dist/components/layout/grid.d.ts +1 -1
- package/dist/components/layout/stack.d.ts +1 -1
- package/dist/components/overlays/lightbox.js +1 -1
- package/dist/components/overlays/lightbox.js.map +1 -1
- package/dist/components/overlays/overlay-close.js +1 -1
- package/dist/components/overlays/overlay-close.js.map +1 -1
- package/dist/components/plugin/board-showcase.js +1 -1
- package/dist/components/plugin/board-showcase.js.map +1 -1
- package/dist/components/typography/heading.d.ts +1 -1
- package/dist/components/typography/text-link.d.ts +27 -3
- package/dist/components/typography/text-link.js +1 -1
- package/dist/components/typography/text-link.js.map +1 -1
- package/dist/components/typography/text.d.ts +1 -1
- package/dist/components/wizard/wizard-shell.d.ts +6 -1
- package/dist/components/wizard/wizard-shell.js +38 -35
- package/dist/components/wizard/wizard-shell.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +104 -100
- package/dist/theme.css +85 -4
- package/package.json +9 -2
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import "react";
|
|
3
|
+
import { jsx as e } from "react/jsx-runtime";
|
|
4
|
+
import { Radio as t } from "@base-ui/react/radio";
|
|
5
|
+
import { RadioGroup as n } from "@base-ui/react/radio-group";
|
|
6
|
+
//#region src/components/forms/selection-group.tsx
|
|
7
|
+
function r({ slot: t, onValueChange: r, onKeyDown: i, className: a, children: o, ...s }) {
|
|
8
|
+
return /* @__PURE__ */ e(n, {
|
|
9
|
+
"data-slot": t,
|
|
10
|
+
className: a,
|
|
11
|
+
onValueChange: (e) => r?.(e),
|
|
12
|
+
onKeyDown: (e) => {
|
|
13
|
+
if (i?.(e), e.defaultPrevented || e.key !== "Home" && e.key !== "End" || e.altKey || e.ctrlKey || e.metaKey || e.shiftKey || e.target?.getAttribute("role") !== "radio") return;
|
|
14
|
+
let t = Array.from(e.currentTarget.querySelectorAll("[role=\"radio\"]")).filter((e) => !e.hasAttribute("disabled") && e.getAttribute("aria-disabled") !== "true"), n = e.key === "Home" ? t[0] : t[t.length - 1];
|
|
15
|
+
n !== void 0 && (e.preventDefault(), n.focus(), n.click());
|
|
16
|
+
},
|
|
17
|
+
...s,
|
|
18
|
+
children: o
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function i({ grouped: n, value: r, pressed: i, onPressedChange: a, onClick: o, disabled: s, ref: c, children: l, ...u }) {
|
|
22
|
+
if (n) return /* @__PURE__ */ e(t.Root, {
|
|
23
|
+
value: r,
|
|
24
|
+
render: /* @__PURE__ */ e("button", { type: "button" }),
|
|
25
|
+
nativeButton: !0,
|
|
26
|
+
disabled: s,
|
|
27
|
+
onClick: o,
|
|
28
|
+
ref: c,
|
|
29
|
+
...u,
|
|
30
|
+
children: l
|
|
31
|
+
});
|
|
32
|
+
let d = (e) => {
|
|
33
|
+
o?.(e), !e.defaultPrevented && a?.(!i);
|
|
34
|
+
};
|
|
35
|
+
return /* @__PURE__ */ e("button", {
|
|
36
|
+
type: "button",
|
|
37
|
+
disabled: s,
|
|
38
|
+
ref: c,
|
|
39
|
+
...i === void 0 ? {} : {
|
|
40
|
+
"aria-pressed": i,
|
|
41
|
+
...i ? { "data-checked": "" } : { "data-unchecked": "" }
|
|
42
|
+
},
|
|
43
|
+
onClick: d,
|
|
44
|
+
...u,
|
|
45
|
+
children: l
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
export { i as SelectableItemRoot, r as SelectionGroupRoot };
|
|
50
|
+
|
|
51
|
+
//# sourceMappingURL=selection-group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selection-group.js","names":[],"sources":["../../../src/components/forms/selection-group.tsx"],"mappings":";;;;;;AAuEA,SAAS,EAAmB,EAC1B,SACA,kBACA,cACA,cACA,aACA,GAAG,KACuB;CAwB1B,OACE,kBAAC,GAAD;EACE,aAAW;EACA;EACX,gBAAgB,MAAS,IAAgB,CAAc;EACvD,YA5BmB,MAA+C;GAMpE,IALA,IAAY,CAAK,GACb,EAAM,oBACN,EAAM,QAAQ,UAAU,EAAM,QAAQ,SAEtC,EAAM,UAAU,EAAM,WAAW,EAAM,WAAW,EAAM,YACvD,EAAM,QAA+B,aAAa,MAAM,MAAM,SAAS;GAE5E,IAAM,IAAU,MAAM,KAAK,EAAM,cAAc,iBAA8B,kBAAgB,CAAC,CAAC,CAAC,QAC7F,MAAW,CAAC,EAAO,aAAa,UAAU,KAAK,EAAO,aAAa,eAAe,MAAM,MAC3F,GACM,IAAS,EAAM,QAAQ,SAAS,EAAQ,KAAK,EAAQ,EAAQ,SAAS;GACxE,MAAW,KAAA,MAGf,EAAM,eAAe,GACrB,EAAO,MAAM,GAIb,EAAO,MAAM;EACf;EAQI,GAAI;EAEH;CACkB,CAAA;AAEzB;AA+BA,SAAS,EAAmB,EAC1B,YACA,UACA,YACA,oBACA,YACA,aACA,QACA,aACA,GAAG,KACuB;CAC1B,IAAI,GACF,OAGE,kBAAC,EAAe,MAAhB;EACS;EACP,QAAQ,kBAAC,UAAD,EAAQ,MAAK,SAAU,CAAA;EAC/B,cAAA;EACU;EACD;EACJ;EACL,GAAI;EAEH;CACkB,CAAA;CAIzB,IAAM,KAAe,MAAyC;EAC5D,IAAU,CAAK,GACX,GAAM,oBACV,IAAkB,CAAC,CAAO;CAC5B;CAEA,OACE,kBAAC,UAAD;EACE,MAAK;EACK;EACL;EAIL,GAAK,MAAY,KAAA,IACb,CAAC,IACD;GAAE,gBAAgB;GAAS,GAAI,IAAU,EAAE,gBAAgB,GAAG,IAAI,EAAE,kBAAkB,GAAG;EAAG;EAChG,SAAS;EACT,GAAI;EAEH;CACK,CAAA;AAEZ"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { type VariantProps } from "class-variance-authority";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { type SelectionGroupBaseProps, type SelectionGroupNameProps } from "./selection-group";
|
|
4
|
+
declare const swatchGroupVariants: (props?: ({
|
|
5
|
+
wrap?: boolean | null | undefined;
|
|
6
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
|
+
declare const swatchVariants: (props?: ({
|
|
8
|
+
size?: "sm" | "md" | "lg" | null | undefined;
|
|
9
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
10
|
+
declare const swatchFillVariants: (props?: ({
|
|
11
|
+
size?: "sm" | "md" | "lg" | null | undefined;
|
|
12
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
13
|
+
declare const swatchIndicatorVariants: (props?: ({
|
|
14
|
+
size?: "sm" | "md" | "lg" | null | undefined;
|
|
15
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
16
|
+
type SwatchSize = NonNullable<VariantProps<typeof swatchVariants>["size"]>;
|
|
17
|
+
export type SwatchGroupProps = SelectionGroupBaseProps & SelectionGroupNameProps & VariantProps<typeof swatchGroupVariants> & {
|
|
18
|
+
/** Diameter applied to every swatch in the group; a swatch may override it. */
|
|
19
|
+
size?: SwatchSize;
|
|
20
|
+
className?: string;
|
|
21
|
+
children?: React.ReactNode;
|
|
22
|
+
} & Omit<React.ComponentProps<"div">, "defaultValue" | "onChange">;
|
|
23
|
+
/**
|
|
24
|
+
* Single-select group of {@link Swatch}es — a real `radiogroup`.
|
|
25
|
+
*
|
|
26
|
+
* One tab stop for the whole group; arrow keys move the selection and wrap,
|
|
27
|
+
* Home/End jump to the ends, and the selection can never be emptied (a board
|
|
28
|
+
* always has a colour). Swatches inside it take their state from the group's
|
|
29
|
+
* `value`, so they need a `value` of their own and must NOT be given
|
|
30
|
+
* `pressed`.
|
|
31
|
+
*
|
|
32
|
+
* The group needs its own accessible name ("Board colour") and the type
|
|
33
|
+
* requires it: swatch labels do not compose into one, and a nameless
|
|
34
|
+
* radiogroup fails axe.
|
|
35
|
+
*
|
|
36
|
+
* A wrapped group keeps Base UI's LINEAR arrow-key order — Up/Down step by
|
|
37
|
+
* one, not by the column count. Row-aware movement is only correct with a
|
|
38
|
+
* fixed column count, which a `flex-wrap` palette does not have; a ±1
|
|
39
|
+
* Up/Down that pretends otherwise is the half-measure `editor/color-picker-
|
|
40
|
+
* content.tsx` already regretted. Use a fixed-column grid via `className`
|
|
41
|
+
* only if you are prepared to own that arithmetic.
|
|
42
|
+
*/
|
|
43
|
+
declare function SwatchGroup({ className, size, wrap, children, ...props }: SwatchGroupProps): React.JSX.Element;
|
|
44
|
+
export type SwatchProps = Omit<React.ComponentProps<"button">, "aria-label" | "children" | "color" | "value"> & VariantProps<typeof swatchVariants> & {
|
|
45
|
+
/**
|
|
46
|
+
* The colour being picked, as ANY CSS colour — a board-surface token
|
|
47
|
+
* (`var(--color-board-surface-dark)`), a plugin colour-rule hue, or a
|
|
48
|
+
* raw hex. It is applied as an inline `background-color`, which is the
|
|
49
|
+
* only way an arbitrary runtime value can reach the DOM; Tailwind cannot
|
|
50
|
+
* compile a class for a value it never sees.
|
|
51
|
+
*/
|
|
52
|
+
color: string;
|
|
53
|
+
/**
|
|
54
|
+
* Localized accessible name — e.g. "Black", "Board white". REQUIRED: the
|
|
55
|
+
* swatch renders no text, so this is its only name. Name the colour, not
|
|
56
|
+
* its value; "#0d0d0d" is not a name.
|
|
57
|
+
*/
|
|
58
|
+
label: string;
|
|
59
|
+
/** Identifies the swatch inside a {@link SwatchGroup}. */
|
|
60
|
+
value?: string;
|
|
61
|
+
/**
|
|
62
|
+
* Standalone toggle state — only outside a group. Pair with
|
|
63
|
+
* `onPressedChange`. Leave undefined for a swatch that merely opens a
|
|
64
|
+
* picker: it then gets no `aria-pressed` at all.
|
|
65
|
+
*/
|
|
66
|
+
pressed?: boolean;
|
|
67
|
+
onPressedChange?: (pressed: boolean) => void;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* One colour circle. Inside a {@link SwatchGroup} it is a `radio`
|
|
71
|
+
* (`aria-checked`, roving tabindex, arrow keys). On its own with `pressed`
|
|
72
|
+
* it is an `aria-pressed` toggle button.
|
|
73
|
+
*
|
|
74
|
+
* Fill diameters are 20 / 24 / 32px at `sm` / `md` / `lg`; the button around
|
|
75
|
+
* them is 28 / 32 / 40px, so every target clears WCAG 2.2 SC 2.5.8's 24×24
|
|
76
|
+
* minimum. Selection shows as a `--foreground` ring outside the fill plus a
|
|
77
|
+
* `--primary` check disc over it — never as a change to the fill, which is
|
|
78
|
+
* the thing being picked.
|
|
79
|
+
*/
|
|
80
|
+
declare function Swatch({ className, size, value, color, label, pressed, onPressedChange, ...props }: SwatchProps): React.JSX.Element;
|
|
81
|
+
export { Swatch, swatchFillVariants, SwatchGroup, swatchGroupVariants, swatchIndicatorVariants, swatchVariants };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/utils.js";
|
|
3
|
+
import { SelectableItemRoot as t, SelectionGroupRoot as n } from "./selection-group.js";
|
|
4
|
+
import { Check as r } from "lucide-react";
|
|
5
|
+
import * as i from "react";
|
|
6
|
+
import { jsx as a } from "react/jsx-runtime";
|
|
7
|
+
import { cva as o } from "class-variance-authority";
|
|
8
|
+
//#region src/components/forms/swatch.tsx
|
|
9
|
+
var s = o(["flex items-center gap-2"], {
|
|
10
|
+
variants: { wrap: {
|
|
11
|
+
true: "flex-wrap",
|
|
12
|
+
false: "flex-nowrap"
|
|
13
|
+
} },
|
|
14
|
+
defaultVariants: { wrap: !0 }
|
|
15
|
+
}), c = o([
|
|
16
|
+
"group/swatch inline-flex shrink-0 cursor-pointer items-center justify-center rounded-full",
|
|
17
|
+
"bg-transparent p-1",
|
|
18
|
+
"focus-ring transition-[box-shadow,opacity] duration-control",
|
|
19
|
+
"disabled:pointer-events-none disabled:opacity-50"
|
|
20
|
+
], {
|
|
21
|
+
variants: { size: {
|
|
22
|
+
sm: "size-7",
|
|
23
|
+
md: "size-8",
|
|
24
|
+
lg: "size-10"
|
|
25
|
+
} },
|
|
26
|
+
defaultVariants: { size: "md" }
|
|
27
|
+
}), l = o([
|
|
28
|
+
"pointer-events-none flex items-center justify-center rounded-full",
|
|
29
|
+
"border border-input",
|
|
30
|
+
"ring-offset-2 ring-offset-background transition-[box-shadow] duration-control",
|
|
31
|
+
"group-data-[checked]/swatch:ring-2 group-data-[checked]/swatch:ring-foreground"
|
|
32
|
+
], {
|
|
33
|
+
variants: { size: {
|
|
34
|
+
sm: "size-5",
|
|
35
|
+
md: "size-6",
|
|
36
|
+
lg: "size-8"
|
|
37
|
+
} },
|
|
38
|
+
defaultVariants: { size: "md" }
|
|
39
|
+
}), u = o([
|
|
40
|
+
"pointer-events-none flex items-center justify-center rounded-full bg-primary text-primary-foreground",
|
|
41
|
+
"ring-1 ring-background opacity-0 transition-opacity duration-control",
|
|
42
|
+
"group-data-[checked]/swatch:opacity-100"
|
|
43
|
+
], {
|
|
44
|
+
variants: { size: {
|
|
45
|
+
sm: "size-3 [&_svg]:size-2",
|
|
46
|
+
md: "size-3.5 [&_svg]:size-2.5",
|
|
47
|
+
lg: "size-4 [&_svg]:size-3"
|
|
48
|
+
} },
|
|
49
|
+
defaultVariants: { size: "md" }
|
|
50
|
+
}), d = i.createContext(null);
|
|
51
|
+
function f({ className: t, size: r, wrap: o, children: c, ...l }) {
|
|
52
|
+
let u = i.useMemo(() => ({ size: r }), [r]);
|
|
53
|
+
return /* @__PURE__ */ a(d.Provider, {
|
|
54
|
+
value: u,
|
|
55
|
+
children: /* @__PURE__ */ a(n, {
|
|
56
|
+
slot: "swatch-group",
|
|
57
|
+
className: e(s({ wrap: o }), t),
|
|
58
|
+
...l,
|
|
59
|
+
children: c
|
|
60
|
+
})
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
function p({ className: n, size: o, value: s, color: f, label: p, pressed: m, onPressedChange: h, ...g }) {
|
|
64
|
+
let _ = i.useContext(d), v = o ?? _?.size ?? "md";
|
|
65
|
+
return /* @__PURE__ */ a(t, {
|
|
66
|
+
grouped: _ !== null,
|
|
67
|
+
value: s,
|
|
68
|
+
pressed: m,
|
|
69
|
+
onPressedChange: h,
|
|
70
|
+
"aria-label": p,
|
|
71
|
+
"data-slot": "swatch",
|
|
72
|
+
"data-size": v,
|
|
73
|
+
className: e(c({ size: v }), n),
|
|
74
|
+
...g,
|
|
75
|
+
children: /* @__PURE__ */ a("span", {
|
|
76
|
+
"data-slot": "swatch-fill",
|
|
77
|
+
"aria-hidden": "true",
|
|
78
|
+
style: { backgroundColor: f },
|
|
79
|
+
className: l({ size: v }),
|
|
80
|
+
children: /* @__PURE__ */ a("span", {
|
|
81
|
+
"data-slot": "swatch-indicator",
|
|
82
|
+
className: u({ size: v }),
|
|
83
|
+
children: /* @__PURE__ */ a(r, {})
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
export { p as Swatch, f as SwatchGroup, l as swatchFillVariants, s as swatchGroupVariants, u as swatchIndicatorVariants, c as swatchVariants };
|
|
90
|
+
|
|
91
|
+
//# sourceMappingURL=swatch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swatch.js","names":[],"sources":["../../../src/components/forms/swatch.tsx"],"mappings":";;;;;;;;AAkGA,IAAM,IAAsB,EAC1B,CAIE,yBACF,GACA;CACE,UAAU,EACR,MAAM;EACJ,MAAM;EACN,OAAO;CACT,EACF;CACA,iBAAiB,EACf,MAAM,GACR;AACF,CACF,GAEM,IAAiB,EACrB;CAIE;CAIA;CAGA;CACA;AACF,GACA;CACE,UAAU,EACR,MAAM;EAEJ,IAAI;EACJ,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CACF,GAEM,IAAqB,EACzB;CACE;CAGA;CAGA;CACA;AACF,GACA;CACE,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CACF,GAEM,IAA0B,EAC9B;CAIE;CACA;CACA;AACF,GACA;CACE,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EACf,MAAM,KACR;AACF,CACF,GAQM,IAAqB,EAAM,cAA8C,IAAI;AA+BnF,SAAS,EAAY,EAAE,cAAW,SAAM,SAAM,aAAU,GAAG,KAA2B;CACpF,IAAM,IAAU,EAAM,eAAwC,EAAE,QAAK,IAAI,CAAC,CAAI,CAAC;CAE/E,OACE,kBAAC,EAAmB,UAApB;EAA6B,OAAO;EAClC,UAAA,kBAAC,GAAD;GAAoB,MAAK;GAAe,WAAW,EAAG,EAAoB,EAAE,QAAK,CAAC,GAAG,CAAS;GAAG,GAAI;GAClG;EACiB,CAAA;CACO,CAAA;AAEjC;AAwCA,SAAS,EAAO,EAAE,cAAW,SAAM,UAAO,UAAO,UAAO,YAAS,oBAAiB,GAAG,KAAsB;CACzG,IAAM,IAAQ,EAAM,WAAW,CAAkB,GAC3C,IAAe,KAAQ,GAAO,QAAQ;CAE5C,OACE,kBAAC,GAAD;EACE,SAAS,MAAU;EACZ;EACE;EACQ;EACjB,cAAY;EACZ,aAAU;EACV,aAAW;EACX,WAAW,EAAG,EAAe,EAAE,MAAM,EAAa,CAAC,GAAG,CAAS;EAC/D,GAAI;EAEJ,UAAA,kBAAC,QAAD;GACE,aAAU;GAGV,eAAY;GACZ,OAAO,EAAE,iBAAiB,EAAM;GAChC,WAAW,EAAmB,EAAE,MAAM,EAAa,CAAC;GAEpD,UAAA,kBAAC,QAAD;IAAM,aAAU;IAAmB,WAAW,EAAwB,EAAE,MAAM,EAAa,CAAC;IAC1F,UAAA,kBAAC,GAAD,CAAQ,CAAA;GACJ,CAAA;EACF,CAAA;CACY,CAAA;AAExB"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Searchable IANA time-zone combobox: a text input that filters ~400 zones and
|
|
4
|
+
* a portalled listbox of matches.
|
|
5
|
+
*
|
|
6
|
+
* WHAT IT IS NOT.
|
|
7
|
+
* `Select` is a listbox with no text entry — usable at 10 options, unusable at
|
|
8
|
+
* 400, which is why the consuming app hand-rolled 336 lines of this and
|
|
9
|
+
* rendered it from three places. `TimePicker` picks an instant *within* a day
|
|
10
|
+
* (hour + minute + presets); this picks the zone that instant is read in. They
|
|
11
|
+
* compose — a schedule row is a `TimePicker` next to a `TimezonePicker` — so
|
|
12
|
+
* they deliberately share a controlled/uncontrolled shape: `value` +
|
|
13
|
+
* `defaultValue` + `onValueChange`, all optional, resolved with `??` so a
|
|
14
|
+
* controlled `""` still means "unset" instead of falling through to internal
|
|
15
|
+
* state.
|
|
16
|
+
*
|
|
17
|
+
* VALUE vs TEXT. `value` is the IANA id (`"Europe/Berlin"`), never the display
|
|
18
|
+
* label — the label is presentation and a consumer may localize it through
|
|
19
|
+
* `timezones`. The input's *text* is a separate thing the user can type
|
|
20
|
+
* anything into, so the component reports whether that text currently names a
|
|
21
|
+
* known zone via {@link TimezonePickerProps.onValidityChange}, which is what
|
|
22
|
+
* lets a form block "Europe/Berlim" from being saved.
|
|
23
|
+
*
|
|
24
|
+
* ACCESSIBILITY CONTRACT (all of it from Base UI's Combobox, none hand-rolled):
|
|
25
|
+
* the input is `role="combobox"` with `aria-expanded` / `aria-haspopup` /
|
|
26
|
+
* `aria-controls`; the panel is `role="listbox"` with `role="option"` rows;
|
|
27
|
+
* ArrowUp/ArrowDown move the highlight as `aria-activedescendant` while DOM
|
|
28
|
+
* focus stays on the input (the combobox pattern — unlike TimePicker's
|
|
29
|
+
* roving-tabindex listbox, where focus really moves); Enter commits, Escape
|
|
30
|
+
* closes, an outside press dismisses. The panel is portalled, so a picker
|
|
31
|
+
* inside a card or a scroll box with `overflow: hidden` is not clipped, and
|
|
32
|
+
* the positioner anchors it to the input.
|
|
33
|
+
*
|
|
34
|
+
* `aria-invalid` is NOT set from the validity check, deliberately. It would
|
|
35
|
+
* flip to "invalid" on every keystroke of a zone the user is halfway through
|
|
36
|
+
* typing, and a live combobox announcing an error mid-word is worse than no
|
|
37
|
+
* error at all. The unknown-text state is published as `data-unknown-zone` (a
|
|
38
|
+
* silent styling hook) and as `onValidityChange`; *when* to escalate it to
|
|
39
|
+
* `aria-invalid` — on blur, on submit — is the form's call, not the kit's.
|
|
40
|
+
*
|
|
41
|
+
* Rows are 32px tall (py-1.5 over a 20px line box), clearing WCAG 2.2 SC 2.5.8's
|
|
42
|
+
* 24×24 minimum target. The offset column is `text-muted-foreground`, which is
|
|
43
|
+
* text and therefore held to SC 1.4.3's 4.5:1 by the token, not to 3:1.
|
|
44
|
+
*/
|
|
45
|
+
/** A zone as this component consumes it. See {@link listTimezones}. */
|
|
46
|
+
export interface TimezoneOption {
|
|
47
|
+
/** IANA identifier, e.g. `"Europe/Berlin"`. This is what `value` carries. */
|
|
48
|
+
id: string;
|
|
49
|
+
/**
|
|
50
|
+
* Localized display name shown in the input and the list (the app resolves
|
|
51
|
+
* i18n). Defaults to the id with underscores turned into spaces, so
|
|
52
|
+
* `"America/New_York"` reads `"America/New York"` and the visible text stays
|
|
53
|
+
* the identifier the user probably has in mind.
|
|
54
|
+
*/
|
|
55
|
+
label?: string;
|
|
56
|
+
/**
|
|
57
|
+
* UTC offset as a bare signed string, `"+02:00"`. Derived from the zone for
|
|
58
|
+
* the current instant when omitted. Pass it explicitly when the rendering
|
|
59
|
+
* must not move with DST — a Storybook story or a VRT baseline.
|
|
60
|
+
*/
|
|
61
|
+
offset?: string;
|
|
62
|
+
}
|
|
63
|
+
/** {@link TimezoneOption} after defaults are filled in. */
|
|
64
|
+
type ResolvedZone = Required<TimezoneOption>;
|
|
65
|
+
/**
|
|
66
|
+
* Every user-visible string the picker renders on its own. All optional with
|
|
67
|
+
* English defaults, the same shape TimePicker uses — the package never
|
|
68
|
+
* resolves i18n, the app passes copy in.
|
|
69
|
+
*/
|
|
70
|
+
export interface TimezonePickerLabels {
|
|
71
|
+
/** Input placeholder while no zone is chosen. Default `"Search time zones"`. */
|
|
72
|
+
placeholder?: string;
|
|
73
|
+
/** Shown and announced politely when the query matches nothing. Default `"No matching time zone"`. */
|
|
74
|
+
empty?: string;
|
|
75
|
+
/** Accessible name of the results listbox. Default `"Time zones"`. */
|
|
76
|
+
list?: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The runtime's IANA zone table, each entry carrying its UTC offset at
|
|
80
|
+
* `referenceDate` (default: now).
|
|
81
|
+
*
|
|
82
|
+
* A zone's offset is a function of the date — Europe/Berlin is `+01:00` in
|
|
83
|
+
* January and `+02:00` in July — so this cannot be a constant. It is cached at
|
|
84
|
+
* hour granularity: deriving 418 offsets costs ~35 ms of `Intl.DateTimeFormat`
|
|
85
|
+
* construction, which must not run once per render per picker, and an hourly
|
|
86
|
+
* key means a DST transition corrects itself without anyone reloading the tab.
|
|
87
|
+
*
|
|
88
|
+
* Defensive by design, because `Intl.supportedValuesOf` is absent from thin
|
|
89
|
+
* ICU builds (and from some jsdom setups): if the zone table cannot be read at
|
|
90
|
+
* all it degrades to the single resolved local zone, and if that fails too it
|
|
91
|
+
* returns `[]`. Either way the escape hatch is the same — pass `timezones`.
|
|
92
|
+
*/
|
|
93
|
+
export declare function listTimezones(referenceDate?: Date): ResolvedZone[];
|
|
94
|
+
export interface TimezonePickerProps {
|
|
95
|
+
/**
|
|
96
|
+
* Selected IANA id, controlled. `""` means unset. Pair with
|
|
97
|
+
* {@link TimezonePickerProps.onValueChange}; omit both for the uncontrolled
|
|
98
|
+
* form seeded by `defaultValue`.
|
|
99
|
+
*/
|
|
100
|
+
value?: string;
|
|
101
|
+
/** Initial IANA id (uncontrolled). Default `""` — unset. */
|
|
102
|
+
defaultValue?: string;
|
|
103
|
+
/** Fired with the new IANA id when a zone is chosen. One argument, never Base UI's event-details pair. */
|
|
104
|
+
onValueChange?: (value: string) => void;
|
|
105
|
+
/**
|
|
106
|
+
* The zones to offer. Defaults to {@link listTimezones}, i.e. everything this
|
|
107
|
+
* runtime's ICU build knows about, labelled by id. Pass a list to shorten it
|
|
108
|
+
* to the zones your product supports, to localize the labels, or to pin the
|
|
109
|
+
* offsets so a story or a VRT baseline does not move at the next DST change.
|
|
110
|
+
*/
|
|
111
|
+
timezones?: readonly TimezoneOption[];
|
|
112
|
+
/**
|
|
113
|
+
* The instant zone offsets are computed for, when they are derived rather
|
|
114
|
+
* than supplied. Defaults to now; pass a fixed date to make rendering
|
|
115
|
+
* deterministic.
|
|
116
|
+
*/
|
|
117
|
+
referenceDate?: Date;
|
|
118
|
+
/**
|
|
119
|
+
* Called when the answer to "does the text in the input name a known zone?"
|
|
120
|
+
* flips, and once on mount so a form can gate its submit before any typing.
|
|
121
|
+
*
|
|
122
|
+
* An EMPTY input reports `true`. Emptiness is required-ness, which the form
|
|
123
|
+
* already models — it can see `value === ""` — and reporting it as invalid
|
|
124
|
+
* would make every untouched optional zone field shout on mount. `false`
|
|
125
|
+
* means the user typed something that is not a zone, which is the typo this
|
|
126
|
+
* callback exists to catch.
|
|
127
|
+
*/
|
|
128
|
+
onValidityChange?: (valid: boolean) => void;
|
|
129
|
+
/**
|
|
130
|
+
* Maximum number of matches rendered at once. Default `100`: an unfiltered
|
|
131
|
+
* open would otherwise mount ~400 option rows, and nobody scrolls past the
|
|
132
|
+
* first screen — they type. `-1` renders every match.
|
|
133
|
+
*/
|
|
134
|
+
limit?: number;
|
|
135
|
+
labels?: TimezonePickerLabels;
|
|
136
|
+
disabled?: boolean;
|
|
137
|
+
readOnly?: boolean;
|
|
138
|
+
required?: boolean;
|
|
139
|
+
/** Submits the selected IANA id under this name when inside a form. */
|
|
140
|
+
name?: string;
|
|
141
|
+
/** Forwarded to the input so an external `<Label htmlFor>` can name it. */
|
|
142
|
+
id?: string;
|
|
143
|
+
"aria-label"?: string;
|
|
144
|
+
"aria-labelledby"?: string;
|
|
145
|
+
"aria-describedby"?: string;
|
|
146
|
+
/**
|
|
147
|
+
* Passed straight through. The picker never derives this from the validity
|
|
148
|
+
* check — see the file header for why mid-word "invalid" is the wrong call.
|
|
149
|
+
*/
|
|
150
|
+
"aria-invalid"?: React.AriaAttributes["aria-invalid"];
|
|
151
|
+
/** Classes for the input. */
|
|
152
|
+
className?: string;
|
|
153
|
+
/** Classes for the popup surface. */
|
|
154
|
+
contentClassName?: string;
|
|
155
|
+
/** Open the list on first render (uncontrolled). */
|
|
156
|
+
defaultOpen?: boolean;
|
|
157
|
+
/** Controlled open state; pair with `onOpenChange`. */
|
|
158
|
+
open?: boolean;
|
|
159
|
+
onOpenChange?: (open: boolean) => void;
|
|
160
|
+
ref?: React.Ref<HTMLInputElement>;
|
|
161
|
+
}
|
|
162
|
+
declare function TimezonePicker({ value: valueProp, defaultValue, onValueChange, timezones, referenceDate, onValidityChange, limit, labels, disabled, readOnly, required, name, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, className, contentClassName, defaultOpen, open, onOpenChange, ref, }: TimezonePickerProps): React.JSX.Element;
|
|
163
|
+
export { TimezonePicker };
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { cn as e } from "../../lib/utils.js";
|
|
3
|
+
import { Globe as t } from "lucide-react";
|
|
4
|
+
import * as n from "react";
|
|
5
|
+
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
6
|
+
import { Combobox as a } from "@base-ui/react/combobox";
|
|
7
|
+
//#region src/components/forms/timezone-picker.tsx
|
|
8
|
+
var o = {
|
|
9
|
+
placeholder: "Search time zones",
|
|
10
|
+
empty: "No matching time zone",
|
|
11
|
+
list: "Time zones"
|
|
12
|
+
}, s = /GMT([+-]\d{2}:\d{2})/;
|
|
13
|
+
function c(e, t) {
|
|
14
|
+
try {
|
|
15
|
+
let n = new Intl.DateTimeFormat("en-US", {
|
|
16
|
+
timeZone: e,
|
|
17
|
+
timeZoneName: "longOffset"
|
|
18
|
+
}).formatToParts(t).find((e) => e.type === "timeZoneName")?.value ?? "";
|
|
19
|
+
return n === "GMT" ? "+00:00" : s.exec(n)?.[1] ?? "";
|
|
20
|
+
} catch {
|
|
21
|
+
return "";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
var l = null;
|
|
25
|
+
function u(e = /* @__PURE__ */ new Date()) {
|
|
26
|
+
let t = e.toISOString().slice(0, 13);
|
|
27
|
+
if (l?.key === t) return l.zones;
|
|
28
|
+
let n = [];
|
|
29
|
+
try {
|
|
30
|
+
n = Intl.supportedValuesOf?.("timeZone") ?? [];
|
|
31
|
+
} catch {
|
|
32
|
+
n = [];
|
|
33
|
+
}
|
|
34
|
+
if (n.length === 0) try {
|
|
35
|
+
let e = new Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
36
|
+
n = e ? [e] : [];
|
|
37
|
+
} catch {
|
|
38
|
+
n = [];
|
|
39
|
+
}
|
|
40
|
+
let r = n.map((t) => ({
|
|
41
|
+
id: t,
|
|
42
|
+
label: d(t),
|
|
43
|
+
offset: c(t, e)
|
|
44
|
+
})).filter((e) => e.offset !== "");
|
|
45
|
+
return l = {
|
|
46
|
+
key: t,
|
|
47
|
+
zones: r
|
|
48
|
+
}, r;
|
|
49
|
+
}
|
|
50
|
+
function d(e) {
|
|
51
|
+
return e.replace(/_/g, " ");
|
|
52
|
+
}
|
|
53
|
+
function f(e, t) {
|
|
54
|
+
return e ? e.map((e) => ({
|
|
55
|
+
id: e.id,
|
|
56
|
+
label: e.label ?? d(e.id),
|
|
57
|
+
offset: e.offset ?? c(e.id, t)
|
|
58
|
+
})) : u(t);
|
|
59
|
+
}
|
|
60
|
+
function p(e) {
|
|
61
|
+
return `${e.id} ${d(e.id)} ${e.label} ${e.offset} utc${e.offset} gmt${e.offset}`.toLowerCase();
|
|
62
|
+
}
|
|
63
|
+
function m(e, t) {
|
|
64
|
+
let n = t.trim().toLowerCase().split(/\s+/).filter(Boolean);
|
|
65
|
+
if (n.length === 0) return !0;
|
|
66
|
+
let r = p(e);
|
|
67
|
+
return n.every((e) => r.includes(e));
|
|
68
|
+
}
|
|
69
|
+
function h({ value: s, defaultValue: c = "", onValueChange: l, timezones: u, referenceDate: d, onValidityChange: p, limit: h = 100, labels: g, disabled: _, readOnly: v, required: y, name: b, id: x, "aria-label": S, "aria-labelledby": C, "aria-describedby": w, "aria-invalid": T, className: E, contentClassName: D, defaultOpen: O, open: k, onOpenChange: A, ref: j }) {
|
|
70
|
+
let M = {
|
|
71
|
+
...o,
|
|
72
|
+
...g
|
|
73
|
+
}, N = n.useMemo(() => f(u, d ?? /* @__PURE__ */ new Date()), [u, d]), [P, F] = n.useState(c), I = s ?? P, L = n.useMemo(() => N.find((e) => e.id === I) ?? null, [N, I]), [R, z] = n.useState(() => L?.label ?? ""), [B, V] = n.useState(I);
|
|
74
|
+
B !== I && (V(I), z(L?.label ?? ""));
|
|
75
|
+
let H = n.useMemo(() => {
|
|
76
|
+
let e = R.trim().toLowerCase();
|
|
77
|
+
return e === "" || N.some((t) => t.id.toLowerCase() === e || t.label.toLowerCase() === e);
|
|
78
|
+
}, [R, N]), U = n.useRef(null);
|
|
79
|
+
return n.useEffect(() => {
|
|
80
|
+
U.current !== H && (U.current = H, p?.(H));
|
|
81
|
+
}, [H, p]), /* @__PURE__ */ i(a.Root, {
|
|
82
|
+
items: N,
|
|
83
|
+
value: L,
|
|
84
|
+
onValueChange: (e) => {
|
|
85
|
+
let t = e?.id ?? "";
|
|
86
|
+
s === void 0 && F(t), l?.(t);
|
|
87
|
+
},
|
|
88
|
+
inputValue: R,
|
|
89
|
+
onInputValueChange: (e) => z(e),
|
|
90
|
+
filter: m,
|
|
91
|
+
limit: h,
|
|
92
|
+
itemToStringLabel: (e) => e.label,
|
|
93
|
+
itemToStringValue: (e) => e.id,
|
|
94
|
+
isItemEqualToValue: (e, t) => e.id === t.id,
|
|
95
|
+
disabled: _,
|
|
96
|
+
readOnly: v,
|
|
97
|
+
required: y,
|
|
98
|
+
name: b,
|
|
99
|
+
defaultOpen: O,
|
|
100
|
+
open: k,
|
|
101
|
+
onOpenChange: (e) => A?.(e),
|
|
102
|
+
children: [/* @__PURE__ */ i("div", {
|
|
103
|
+
"data-slot": "timezone-picker",
|
|
104
|
+
className: "relative w-full",
|
|
105
|
+
children: [/* @__PURE__ */ r(t, {
|
|
106
|
+
"data-slot": "timezone-picker-icon",
|
|
107
|
+
"aria-hidden": "true",
|
|
108
|
+
className: "pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted-foreground"
|
|
109
|
+
}), /* @__PURE__ */ r(a.Input, {
|
|
110
|
+
ref: j,
|
|
111
|
+
id: x,
|
|
112
|
+
"data-slot": "timezone-picker-input",
|
|
113
|
+
"data-unknown-zone": H ? void 0 : "",
|
|
114
|
+
placeholder: M.placeholder,
|
|
115
|
+
"aria-label": S,
|
|
116
|
+
"aria-labelledby": C,
|
|
117
|
+
"aria-describedby": w,
|
|
118
|
+
"aria-invalid": T,
|
|
119
|
+
className: e("flex h-9 w-full rounded-md border border-input bg-transparent py-1 pl-9 pr-3 text-sm shadow-sm", "transition-[color,background-color,border-color,box-shadow] duration-control", "placeholder:text-muted-foreground hover:border-ring/60", "focus-ring", "aria-invalid:border-destructive", "disabled:cursor-not-allowed disabled:opacity-50", E)
|
|
120
|
+
})]
|
|
121
|
+
}), /* @__PURE__ */ r(a.Portal, { children: /* @__PURE__ */ r(a.Positioner, {
|
|
122
|
+
side: "bottom",
|
|
123
|
+
align: "start",
|
|
124
|
+
sideOffset: 4,
|
|
125
|
+
className: "z-[var(--z-select)]",
|
|
126
|
+
children: /* @__PURE__ */ i(a.Popup, {
|
|
127
|
+
"data-slot": "timezone-picker-popup",
|
|
128
|
+
className: e("max-h-[min(18rem,var(--available-height))] w-[var(--anchor-width)] min-w-[12rem] overflow-y-auto", "rounded-md border bg-popover p-1 text-popover-foreground shadow-md outline-hidden", "origin-[var(--transform-origin)] data-[ending-style]:animate-out data-[ending-style]:fade-out-0 data-[open]:animate-in data-[open]:fade-in-0", D),
|
|
129
|
+
children: [/* @__PURE__ */ r(a.Empty, {
|
|
130
|
+
"data-slot": "timezone-picker-empty",
|
|
131
|
+
className: "px-2 py-1.5 text-sm text-muted-foreground empty:hidden",
|
|
132
|
+
children: M.empty
|
|
133
|
+
}), /* @__PURE__ */ r(a.List, {
|
|
134
|
+
"data-slot": "timezone-picker-list",
|
|
135
|
+
"aria-label": M.list,
|
|
136
|
+
children: (t) => /* @__PURE__ */ i(a.Item, {
|
|
137
|
+
value: t,
|
|
138
|
+
"data-slot": "timezone-picker-item",
|
|
139
|
+
className: e("flex w-full cursor-default select-none items-center gap-3 rounded-sm px-2 py-1.5 text-sm outline-none", "data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground", "data-[selected]:font-medium"),
|
|
140
|
+
children: [/* @__PURE__ */ r("span", {
|
|
141
|
+
"data-slot": "timezone-picker-item-label",
|
|
142
|
+
className: "truncate",
|
|
143
|
+
children: t.label
|
|
144
|
+
}), /* @__PURE__ */ r("span", {
|
|
145
|
+
"data-slot": "timezone-picker-item-offset",
|
|
146
|
+
className: "ml-auto shrink-0 text-xs tabular-nums text-muted-foreground",
|
|
147
|
+
children: t.offset
|
|
148
|
+
})]
|
|
149
|
+
}, t.id)
|
|
150
|
+
})]
|
|
151
|
+
})
|
|
152
|
+
}) })]
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
//#endregion
|
|
156
|
+
export { h as TimezonePicker, u as listTimezones };
|
|
157
|
+
|
|
158
|
+
//# sourceMappingURL=timezone-picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"timezone-picker.js","names":[],"sources":["../../../src/components/forms/timezone-picker.tsx"],"mappings":"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"}
|