@geomak/ui 6.28.0 → 6.29.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/dist/index.cjs +582 -415
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +62 -1
- package/dist/index.d.ts +62 -1
- package/dist/index.js +320 -154
- package/dist/index.js.map +1 -1
- package/dist/styles.css +40 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var chunkOAV4TA4B_cjs = require('./chunk-OAV4TA4B.cjs');
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
-
var
|
|
5
|
+
var React29 = require('react');
|
|
6
6
|
var reactDom = require('react-dom');
|
|
7
7
|
var AvatarPrimitive = require('@radix-ui/react-avatar');
|
|
8
8
|
var DropdownMenu = require('@radix-ui/react-dropdown-menu');
|
|
@@ -40,7 +40,7 @@ function _interopNamespace(e) {
|
|
|
40
40
|
return Object.freeze(n);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
var
|
|
43
|
+
var React29__default = /*#__PURE__*/_interopDefault(React29);
|
|
44
44
|
var AvatarPrimitive__namespace = /*#__PURE__*/_interopNamespace(AvatarPrimitive);
|
|
45
45
|
var DropdownMenu__namespace = /*#__PURE__*/_interopNamespace(DropdownMenu);
|
|
46
46
|
var Dialog__namespace = /*#__PURE__*/_interopNamespace(Dialog);
|
|
@@ -216,8 +216,8 @@ Icon.Copy = Copy;
|
|
|
216
216
|
Icon.CircleStack = CircleStack;
|
|
217
217
|
var icons_default = Icon;
|
|
218
218
|
function Portal({ children, target }) {
|
|
219
|
-
const [resolved, setResolved] =
|
|
220
|
-
|
|
219
|
+
const [resolved, setResolved] = React29.useState(null);
|
|
220
|
+
React29.useEffect(() => {
|
|
221
221
|
if (target === null) {
|
|
222
222
|
setResolved(null);
|
|
223
223
|
return;
|
|
@@ -507,8 +507,8 @@ function Avatar({
|
|
|
507
507
|
if (fallback) return fallback;
|
|
508
508
|
if (alt) {
|
|
509
509
|
const parts = alt.trim().split(/\s+/).slice(0, 2);
|
|
510
|
-
const
|
|
511
|
-
if (
|
|
510
|
+
const initials2 = parts.map((p) => p[0]?.toUpperCase() ?? "").join("");
|
|
511
|
+
if (initials2) return initials2;
|
|
512
512
|
}
|
|
513
513
|
return /* @__PURE__ */ jsxRuntime.jsx(PersonSilhouette, {});
|
|
514
514
|
})();
|
|
@@ -651,7 +651,7 @@ function IconButton({
|
|
|
651
651
|
className = "",
|
|
652
652
|
style
|
|
653
653
|
}) {
|
|
654
|
-
const colorScheme =
|
|
654
|
+
const colorScheme = React29.useMemo(() => {
|
|
655
655
|
if (type === "primary") {
|
|
656
656
|
return "bg-accent text-accent-fg hover:bg-accent-hover";
|
|
657
657
|
}
|
|
@@ -741,7 +741,7 @@ var SIZE_CLASSES = {
|
|
|
741
741
|
md: "h-9 px-4 text-sm gap-1.5 rounded-lg",
|
|
742
742
|
lg: "h-11 px-5 text-sm gap-2 rounded-xl"
|
|
743
743
|
};
|
|
744
|
-
var Button =
|
|
744
|
+
var Button = React29__default.default.forwardRef(function Button2({
|
|
745
745
|
content,
|
|
746
746
|
variant = "primary",
|
|
747
747
|
size = "md",
|
|
@@ -849,7 +849,7 @@ function MenuButton({
|
|
|
849
849
|
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95",
|
|
850
850
|
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95"
|
|
851
851
|
].join(" "),
|
|
852
|
-
children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
852
|
+
children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(React29__default.default.Fragment, { children: [
|
|
853
853
|
item.separatorBefore && /* @__PURE__ */ jsxRuntime.jsx(DropdownMenu__namespace.Separator, { className: "my-1 h-px bg-border" }),
|
|
854
854
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
855
855
|
DropdownMenu__namespace.Item,
|
|
@@ -1092,9 +1092,9 @@ function Tooltip({
|
|
|
1092
1092
|
] }) });
|
|
1093
1093
|
}
|
|
1094
1094
|
var TooltipProvider = TooltipPrimitive__namespace.Provider;
|
|
1095
|
-
var TabsContext =
|
|
1095
|
+
var TabsContext = React29.createContext(null);
|
|
1096
1096
|
function useTabsContext() {
|
|
1097
|
-
const ctx =
|
|
1097
|
+
const ctx = React29.useContext(TabsContext);
|
|
1098
1098
|
if (!ctx) throw new Error("Tabs.List / Tabs.Trigger / Tabs.Panel must be rendered inside <Tabs>.");
|
|
1099
1099
|
return ctx;
|
|
1100
1100
|
}
|
|
@@ -1116,26 +1116,26 @@ function Tabs({
|
|
|
1116
1116
|
children
|
|
1117
1117
|
}) {
|
|
1118
1118
|
const isControlled = value !== void 0;
|
|
1119
|
-
const [internal, setInternal] =
|
|
1119
|
+
const [internal, setInternal] = React29.useState(defaultValue);
|
|
1120
1120
|
const current = isControlled ? value : internal;
|
|
1121
1121
|
const reduced = !!framerMotion.useReducedMotion();
|
|
1122
|
-
const indicatorId =
|
|
1123
|
-
const select =
|
|
1122
|
+
const indicatorId = React29.useId();
|
|
1123
|
+
const select = React29.useCallback((next) => {
|
|
1124
1124
|
if (!isControlled) setInternal(next);
|
|
1125
1125
|
onValueChange?.(next);
|
|
1126
1126
|
}, [isControlled, onValueChange]);
|
|
1127
|
-
const registry =
|
|
1128
|
-
const orderRef =
|
|
1129
|
-
const [, bump] =
|
|
1130
|
-
const registerTab =
|
|
1127
|
+
const registry = React29.useRef(/* @__PURE__ */ new Map());
|
|
1128
|
+
const orderRef = React29.useRef(0);
|
|
1129
|
+
const [, bump] = React29.useState(0);
|
|
1130
|
+
const registerTab = React29.useCallback((val, meta) => {
|
|
1131
1131
|
const existing = registry.current.get(val);
|
|
1132
1132
|
registry.current.set(val, { ...meta, order: existing?.order ?? orderRef.current++ });
|
|
1133
1133
|
if (!existing) bump((v) => v + 1);
|
|
1134
1134
|
}, []);
|
|
1135
|
-
const unregisterTab =
|
|
1135
|
+
const unregisterTab = React29.useCallback((val) => {
|
|
1136
1136
|
if (registry.current.delete(val)) bump((v) => v + 1);
|
|
1137
1137
|
}, []);
|
|
1138
|
-
const getTabs =
|
|
1138
|
+
const getTabs = React29.useCallback(() => [...registry.current.entries()].sort((a, b) => a[1].order - b[1].order).map(([val, m]) => ({ value: val, label: m.label, icon: m.icon, disabled: m.disabled })), []);
|
|
1139
1139
|
return /* @__PURE__ */ jsxRuntime.jsx(TabsContext.Provider, { value: { value: current, variant, size, orientation, indicatorId, reduced, select, registerTab, unregisterTab, getTabs }, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1140
1140
|
TabsPrimitive__namespace.Root,
|
|
1141
1141
|
{
|
|
@@ -1155,10 +1155,10 @@ function Tabs({
|
|
|
1155
1155
|
function TabsList({ children, "aria-label": ariaLabel, className = "" }) {
|
|
1156
1156
|
const { variant, orientation, reduced, value } = useTabsContext();
|
|
1157
1157
|
const horizontal = orientation === "horizontal";
|
|
1158
|
-
const scrollRef =
|
|
1159
|
-
const [edges, setEdges] =
|
|
1158
|
+
const scrollRef = React29.useRef(null);
|
|
1159
|
+
const [edges, setEdges] = React29.useState({ start: false, end: false });
|
|
1160
1160
|
const scrollable = variant !== "segmented";
|
|
1161
|
-
|
|
1161
|
+
React29.useLayoutEffect(() => {
|
|
1162
1162
|
const el = scrollRef.current;
|
|
1163
1163
|
if (!el || !scrollable) return;
|
|
1164
1164
|
const update = () => {
|
|
@@ -1183,13 +1183,13 @@ function TabsList({ children, "aria-label": ariaLabel, className = "" }) {
|
|
|
1183
1183
|
ro.disconnect();
|
|
1184
1184
|
};
|
|
1185
1185
|
}, [horizontal, scrollable, children]);
|
|
1186
|
-
const nudge =
|
|
1186
|
+
const nudge = React29.useCallback((dir) => {
|
|
1187
1187
|
const el = scrollRef.current;
|
|
1188
1188
|
if (!el) return;
|
|
1189
1189
|
const amount = (horizontal ? el.clientWidth : el.clientHeight) * 0.7 * dir;
|
|
1190
1190
|
el.scrollBy({ [horizontal ? "left" : "top"]: amount, behavior: reduced ? "auto" : "smooth" });
|
|
1191
1191
|
}, [horizontal, reduced]);
|
|
1192
|
-
|
|
1192
|
+
React29.useLayoutEffect(() => {
|
|
1193
1193
|
const el = scrollRef.current;
|
|
1194
1194
|
if (!el || !scrollable) return;
|
|
1195
1195
|
const active = el.querySelector("[role=tab][data-state=active]");
|
|
@@ -1247,9 +1247,9 @@ function Chevron2({ side, orientation, onClick }) {
|
|
|
1247
1247
|
function OverflowMenu() {
|
|
1248
1248
|
const { getTabs, value, select, orientation } = useTabsContext();
|
|
1249
1249
|
const horizontal = orientation === "horizontal";
|
|
1250
|
-
const [open, setOpen] =
|
|
1251
|
-
const wrapRef =
|
|
1252
|
-
const timer =
|
|
1250
|
+
const [open, setOpen] = React29.useState(false);
|
|
1251
|
+
const wrapRef = React29.useRef(null);
|
|
1252
|
+
const timer = React29.useRef(null);
|
|
1253
1253
|
const openNow = () => {
|
|
1254
1254
|
if (timer.current) clearTimeout(timer.current);
|
|
1255
1255
|
setOpen(true);
|
|
@@ -1257,7 +1257,7 @@ function OverflowMenu() {
|
|
|
1257
1257
|
const closeSoon = () => {
|
|
1258
1258
|
timer.current = setTimeout(() => setOpen(false), 160);
|
|
1259
1259
|
};
|
|
1260
|
-
|
|
1260
|
+
React29.useLayoutEffect(() => {
|
|
1261
1261
|
if (!open) return;
|
|
1262
1262
|
const onDoc = (e) => {
|
|
1263
1263
|
if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
|
|
@@ -1338,7 +1338,7 @@ function TabsTrigger({ value, icon, badge, closeable, onClose, disabled, classNa
|
|
|
1338
1338
|
const isActive = active === value;
|
|
1339
1339
|
const horizontal = orientation === "horizontal";
|
|
1340
1340
|
const sz = SIZE[size];
|
|
1341
|
-
|
|
1341
|
+
React29.useLayoutEffect(() => {
|
|
1342
1342
|
registerTab(value, { label: children, icon, disabled });
|
|
1343
1343
|
return () => unregisterTab(value);
|
|
1344
1344
|
}, [value, children, icon, disabled, registerTab, unregisterTab]);
|
|
@@ -1536,7 +1536,7 @@ function Tree({
|
|
|
1536
1536
|
item.key
|
|
1537
1537
|
)) });
|
|
1538
1538
|
}
|
|
1539
|
-
var AccordionCtx =
|
|
1539
|
+
var AccordionCtx = React29.createContext({ variant: "separated" });
|
|
1540
1540
|
function Accordion2({
|
|
1541
1541
|
children,
|
|
1542
1542
|
type = "single",
|
|
@@ -1595,7 +1595,7 @@ var Chevron3 = /* @__PURE__ */ jsxRuntime.jsx(
|
|
|
1595
1595
|
}
|
|
1596
1596
|
);
|
|
1597
1597
|
function AccordionItem({ value, title, icon, children, disabled, className = "" }) {
|
|
1598
|
-
const { variant } =
|
|
1598
|
+
const { variant } = React29.useContext(AccordionCtx);
|
|
1599
1599
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1600
1600
|
AccordionPrimitive__namespace.Item,
|
|
1601
1601
|
{
|
|
@@ -1654,7 +1654,7 @@ function Breadcrumbs({
|
|
|
1654
1654
|
className = "",
|
|
1655
1655
|
style
|
|
1656
1656
|
}) {
|
|
1657
|
-
const [expanded, setExpanded] =
|
|
1657
|
+
const [expanded, setExpanded] = React29.useState(false);
|
|
1658
1658
|
const shouldCollapse = maxItems > 0 && items.length > maxItems && !expanded;
|
|
1659
1659
|
const visible = [];
|
|
1660
1660
|
if (shouldCollapse) {
|
|
@@ -1838,8 +1838,8 @@ function Stepper({
|
|
|
1838
1838
|
className = ""
|
|
1839
1839
|
}) {
|
|
1840
1840
|
const reduced = framerMotion.useReducedMotion();
|
|
1841
|
-
const [forcedVertical, setForcedVertical] =
|
|
1842
|
-
|
|
1841
|
+
const [forcedVertical, setForcedVertical] = React29.useState(false);
|
|
1842
|
+
React29.useEffect(() => {
|
|
1843
1843
|
if (!responsive || orientation === "vertical") return;
|
|
1844
1844
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
1845
1845
|
const mq = window.matchMedia("(max-width: 767px)");
|
|
@@ -1948,7 +1948,7 @@ function Kbd({
|
|
|
1948
1948
|
style
|
|
1949
1949
|
}) {
|
|
1950
1950
|
if (keys && keys.length > 0) {
|
|
1951
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: ["inline-flex items-center gap-1", className].filter(Boolean).join(" "), style, children: keys.map((k, i) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1951
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: ["inline-flex items-center gap-1", className].filter(Boolean).join(" "), style, children: keys.map((k, i) => /* @__PURE__ */ jsxRuntime.jsxs(React29__default.default.Fragment, { children: [
|
|
1952
1952
|
i > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground-muted text-xs select-none", children: separator }),
|
|
1953
1953
|
/* @__PURE__ */ jsxRuntime.jsx("kbd", { className: [cap, SIZE3[size]].join(" "), children: k })
|
|
1954
1954
|
] }, `${k}-${i}`)) });
|
|
@@ -2039,13 +2039,13 @@ function FlatCarousel({
|
|
|
2039
2039
|
className = "",
|
|
2040
2040
|
style
|
|
2041
2041
|
}) {
|
|
2042
|
-
const scrollerRef =
|
|
2043
|
-
const slides =
|
|
2044
|
-
const [active, setActive] =
|
|
2045
|
-
const [atStart, setAtStart] =
|
|
2046
|
-
const [atEnd, setAtEnd] =
|
|
2042
|
+
const scrollerRef = React29.useRef(null);
|
|
2043
|
+
const slides = React29__default.default.Children.toArray(children);
|
|
2044
|
+
const [active, setActive] = React29.useState(0);
|
|
2045
|
+
const [atStart, setAtStart] = React29.useState(true);
|
|
2046
|
+
const [atEnd, setAtEnd] = React29.useState(false);
|
|
2047
2047
|
const width = typeof itemWidth === "number" ? `${itemWidth}px` : itemWidth;
|
|
2048
|
-
const update =
|
|
2048
|
+
const update = React29.useCallback(() => {
|
|
2049
2049
|
const el = scrollerRef.current;
|
|
2050
2050
|
if (!el) return;
|
|
2051
2051
|
setAtStart(el.scrollLeft <= 1);
|
|
@@ -2054,7 +2054,7 @@ function FlatCarousel({
|
|
|
2054
2054
|
const slideW = first ? first.getBoundingClientRect().width + gap : el.clientWidth;
|
|
2055
2055
|
setActive(Math.round(el.scrollLeft / slideW));
|
|
2056
2056
|
}, [gap]);
|
|
2057
|
-
|
|
2057
|
+
React29.useEffect(() => {
|
|
2058
2058
|
update();
|
|
2059
2059
|
const el = scrollerRef.current;
|
|
2060
2060
|
if (!el) return;
|
|
@@ -2095,9 +2095,9 @@ function RotatingCarousel({
|
|
|
2095
2095
|
className = "",
|
|
2096
2096
|
style
|
|
2097
2097
|
}) {
|
|
2098
|
-
const slides =
|
|
2098
|
+
const slides = React29__default.default.Children.toArray(children);
|
|
2099
2099
|
const count = slides.length;
|
|
2100
|
-
const [active, setActive] =
|
|
2100
|
+
const [active, setActive] = React29.useState(0);
|
|
2101
2101
|
const reduced = framerMotion.useReducedMotion();
|
|
2102
2102
|
const wrap = (n) => count > 0 ? (n % count + count) % count : 0;
|
|
2103
2103
|
const idx = wrap(active);
|
|
@@ -2168,6 +2168,300 @@ function RotatingCarousel({
|
|
|
2168
2168
|
}
|
|
2169
2169
|
);
|
|
2170
2170
|
}
|
|
2171
|
+
var FIELD_SIZE = {
|
|
2172
|
+
sm: { control: "h-control-sm", text: "text-xs", padX: "px-2.5", gap: "gap-1.5" },
|
|
2173
|
+
md: { control: "h-control-md", text: "text-sm", padX: "px-3", gap: "gap-2" },
|
|
2174
|
+
lg: { control: "h-control-lg", text: "text-sm", padX: "px-3.5", gap: "gap-2.5" }
|
|
2175
|
+
};
|
|
2176
|
+
var FOCUS_WITHIN = "focus-within:outline-none focus-within:border-accent";
|
|
2177
|
+
var FOCUS_ELEMENT = "focus:outline-none focus:border-accent data-[state=open]:border-accent";
|
|
2178
|
+
var FOCUS_WITHIN_ERROR = "focus-within:border-status-error";
|
|
2179
|
+
var FOCUS_ELEMENT_ERROR = "focus:border-status-error data-[state=open]:border-status-error";
|
|
2180
|
+
function fieldShell({
|
|
2181
|
+
size = "md",
|
|
2182
|
+
hasError = false,
|
|
2183
|
+
disabled = false,
|
|
2184
|
+
focusWithin = false,
|
|
2185
|
+
sized = true
|
|
2186
|
+
} = {}) {
|
|
2187
|
+
const s = FIELD_SIZE[size];
|
|
2188
|
+
return [
|
|
2189
|
+
"w-full rounded-lg border bg-surface text-foreground",
|
|
2190
|
+
"transition-[color,box-shadow,border-color] duration-150",
|
|
2191
|
+
s.text,
|
|
2192
|
+
sized ? `${s.control} ${s.padX}` : "",
|
|
2193
|
+
// resting border
|
|
2194
|
+
hasError ? "border-status-error" : "border-border",
|
|
2195
|
+
// hover (only when interactive + no error)
|
|
2196
|
+
disabled ? "bg-surface-raised text-foreground-muted cursor-not-allowed" : hasError ? "" : "hover:border-border-strong",
|
|
2197
|
+
// focus
|
|
2198
|
+
focusWithin ? FOCUS_WITHIN : FOCUS_ELEMENT,
|
|
2199
|
+
hasError ? focusWithin ? FOCUS_WITHIN_ERROR : FOCUS_ELEMENT_ERROR : "",
|
|
2200
|
+
// placeholder colour for native inputs
|
|
2201
|
+
"placeholder:text-foreground-muted"
|
|
2202
|
+
].filter(Boolean).join(" ");
|
|
2203
|
+
}
|
|
2204
|
+
function FieldHelpIcon({ text }) {
|
|
2205
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Tooltip, { title: text, placement: "top", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2206
|
+
"button",
|
|
2207
|
+
{
|
|
2208
|
+
type: "button",
|
|
2209
|
+
"aria-label": "More information",
|
|
2210
|
+
className: "inline-flex items-center justify-center rounded-full text-foreground-muted transition-colors hover:text-foreground focus:outline-none focus-visible:text-accent",
|
|
2211
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 16 16", className: "h-3.5 w-3.5", fill: "none", stroke: "currentColor", strokeWidth: 1.5, "aria-hidden": "true", children: [
|
|
2212
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "8", cy: "8", r: "6.25" }),
|
|
2213
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", d: "M8 7.4v3.4" }),
|
|
2214
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "8", cy: "5.1", r: "0.65", fill: "currentColor", stroke: "none" })
|
|
2215
|
+
] })
|
|
2216
|
+
}
|
|
2217
|
+
) });
|
|
2218
|
+
}
|
|
2219
|
+
function FieldLabel({
|
|
2220
|
+
label,
|
|
2221
|
+
htmlFor,
|
|
2222
|
+
required,
|
|
2223
|
+
helperText,
|
|
2224
|
+
horizontal = false,
|
|
2225
|
+
align = "start",
|
|
2226
|
+
style,
|
|
2227
|
+
width,
|
|
2228
|
+
className = ""
|
|
2229
|
+
}) {
|
|
2230
|
+
if (label == null && helperText == null) return null;
|
|
2231
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2232
|
+
"div",
|
|
2233
|
+
{
|
|
2234
|
+
style: { width: horizontal ? width : void 0, ...style },
|
|
2235
|
+
className: [
|
|
2236
|
+
"flex items-center gap-1",
|
|
2237
|
+
horizontal ? "flex-shrink-0 whitespace-nowrap" : "",
|
|
2238
|
+
// Only the 'start' alignment needs the top nudge; 'center' relies
|
|
2239
|
+
// on the row's items-center to line up with a short control.
|
|
2240
|
+
horizontal && align === "start" ? "mt-2" : "",
|
|
2241
|
+
className
|
|
2242
|
+
].filter(Boolean).join(" "),
|
|
2243
|
+
children: [
|
|
2244
|
+
label != null && /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor, className: "text-sm font-medium text-foreground select-none", children: [
|
|
2245
|
+
label,
|
|
2246
|
+
required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-status-error ml-0.5", "aria-hidden": "true", children: "*" })
|
|
2247
|
+
] }),
|
|
2248
|
+
helperText != null && /* @__PURE__ */ jsxRuntime.jsx(FieldHelpIcon, { text: helperText })
|
|
2249
|
+
]
|
|
2250
|
+
}
|
|
2251
|
+
);
|
|
2252
|
+
}
|
|
2253
|
+
function Field({
|
|
2254
|
+
label,
|
|
2255
|
+
htmlFor,
|
|
2256
|
+
errorId,
|
|
2257
|
+
errorMessage,
|
|
2258
|
+
layout = "vertical",
|
|
2259
|
+
required,
|
|
2260
|
+
helperText,
|
|
2261
|
+
labelAlign = "start",
|
|
2262
|
+
labelStyle,
|
|
2263
|
+
labelWidth,
|
|
2264
|
+
className = "",
|
|
2265
|
+
children
|
|
2266
|
+
}) {
|
|
2267
|
+
const hasError = errorMessage != null;
|
|
2268
|
+
const horizontal = layout === "horizontal";
|
|
2269
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2270
|
+
"div",
|
|
2271
|
+
{
|
|
2272
|
+
className: [
|
|
2273
|
+
"flex",
|
|
2274
|
+
horizontal ? `flex-row gap-3 ${labelAlign === "center" ? "items-center" : "items-start"}` : "flex-col gap-1.5",
|
|
2275
|
+
className
|
|
2276
|
+
].filter(Boolean).join(" "),
|
|
2277
|
+
children: [
|
|
2278
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2279
|
+
FieldLabel,
|
|
2280
|
+
{
|
|
2281
|
+
label,
|
|
2282
|
+
htmlFor,
|
|
2283
|
+
required,
|
|
2284
|
+
helperText,
|
|
2285
|
+
horizontal,
|
|
2286
|
+
align: labelAlign,
|
|
2287
|
+
style: labelStyle,
|
|
2288
|
+
width: labelWidth
|
|
2289
|
+
}
|
|
2290
|
+
),
|
|
2291
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
|
|
2292
|
+
children,
|
|
2293
|
+
hasError && /* @__PURE__ */ jsxRuntime.jsx("div", { id: errorId, className: "text-status-error text-xs mt-1", children: errorMessage })
|
|
2294
|
+
] })
|
|
2295
|
+
]
|
|
2296
|
+
}
|
|
2297
|
+
);
|
|
2298
|
+
}
|
|
2299
|
+
var toDate = (d) => d instanceof Date ? d : new Date(d);
|
|
2300
|
+
var timeLabel = (d) => `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
|
|
2301
|
+
var initials = (name) => (name ?? "").trim().split(/\s+/).slice(0, 2).map((w) => w[0]?.toUpperCase() ?? "").join("") || void 0;
|
|
2302
|
+
var SendIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", className: "h-4 w-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M22 2 11 13M22 2l-7 20-4-9-9-4 20-7z" }) });
|
|
2303
|
+
var ArrowDown = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, "aria-hidden": "true", className: "h-4 w-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 5v14M5 12l7 7 7-7" }) });
|
|
2304
|
+
function TypingDots() {
|
|
2305
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex items-center gap-1", "aria-hidden": "true", children: [0, 1, 2].map((i) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-1.5 w-1.5 animate-bounce rounded-full bg-foreground-muted", style: { animationDelay: `${i * 0.15}s` } }, i)) });
|
|
2306
|
+
}
|
|
2307
|
+
function Chat({
|
|
2308
|
+
messages,
|
|
2309
|
+
currentUserId,
|
|
2310
|
+
onSend,
|
|
2311
|
+
typingNames = [],
|
|
2312
|
+
title,
|
|
2313
|
+
subtitle,
|
|
2314
|
+
avatar,
|
|
2315
|
+
headerActions,
|
|
2316
|
+
placeholder = "Write a message\u2026",
|
|
2317
|
+
disabled = false,
|
|
2318
|
+
hideComposer = false,
|
|
2319
|
+
emptyState,
|
|
2320
|
+
height = 480,
|
|
2321
|
+
className = "",
|
|
2322
|
+
style
|
|
2323
|
+
}) {
|
|
2324
|
+
const listRef = React29.useRef(null);
|
|
2325
|
+
const atBottomRef = React29.useRef(true);
|
|
2326
|
+
const [showJump, setShowJump] = React29.useState(false);
|
|
2327
|
+
const [draft, setDraft] = React29.useState("");
|
|
2328
|
+
const taRef = React29.useRef(null);
|
|
2329
|
+
const hasHeader = title != null || subtitle != null || avatar != null || headerActions != null;
|
|
2330
|
+
const isTyping = typingNames.length > 0;
|
|
2331
|
+
const scrollToBottom = React29.useCallback((smooth = true) => {
|
|
2332
|
+
const el = listRef.current;
|
|
2333
|
+
if (!el) return;
|
|
2334
|
+
if (typeof el.scrollTo === "function") el.scrollTo({ top: el.scrollHeight, behavior: smooth ? "smooth" : "auto" });
|
|
2335
|
+
else el.scrollTop = el.scrollHeight;
|
|
2336
|
+
}, []);
|
|
2337
|
+
const onScroll = () => {
|
|
2338
|
+
const el = listRef.current;
|
|
2339
|
+
if (!el) return;
|
|
2340
|
+
const near = el.scrollHeight - el.scrollTop - el.clientHeight < 80;
|
|
2341
|
+
atBottomRef.current = near;
|
|
2342
|
+
setShowJump(!near);
|
|
2343
|
+
};
|
|
2344
|
+
React29.useEffect(() => {
|
|
2345
|
+
if (atBottomRef.current) scrollToBottom(messages.length > 0);
|
|
2346
|
+
}, [messages.length, isTyping]);
|
|
2347
|
+
React29.useEffect(() => {
|
|
2348
|
+
scrollToBottom(false);
|
|
2349
|
+
}, [scrollToBottom]);
|
|
2350
|
+
React29.useLayoutEffect(() => {
|
|
2351
|
+
const ta = taRef.current;
|
|
2352
|
+
if (!ta) return;
|
|
2353
|
+
ta.style.height = "auto";
|
|
2354
|
+
ta.style.height = `${Math.min(ta.scrollHeight, 120)}px`;
|
|
2355
|
+
}, [draft]);
|
|
2356
|
+
const send = () => {
|
|
2357
|
+
const text = draft.trim();
|
|
2358
|
+
if (!text || disabled) return;
|
|
2359
|
+
onSend?.(text);
|
|
2360
|
+
setDraft("");
|
|
2361
|
+
};
|
|
2362
|
+
const onKeyDown = (e) => {
|
|
2363
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
2364
|
+
e.preventDefault();
|
|
2365
|
+
send();
|
|
2366
|
+
}
|
|
2367
|
+
};
|
|
2368
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2369
|
+
"div",
|
|
2370
|
+
{
|
|
2371
|
+
className: ["flex flex-col overflow-hidden rounded-xl border border-border bg-surface", className].filter(Boolean).join(" "),
|
|
2372
|
+
style: { height, ...style },
|
|
2373
|
+
children: [
|
|
2374
|
+
hasHeader && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-shrink-0 items-center gap-3 border-b border-border px-4 py-3", children: [
|
|
2375
|
+
avatar != null && /* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: avatar, alt: typeof title === "string" ? title : "Conversation", size: "sm" }),
|
|
2376
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
2377
|
+
title != null && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-sm font-semibold text-foreground", children: title }),
|
|
2378
|
+
subtitle != null && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-xs text-foreground-muted", children: subtitle })
|
|
2379
|
+
] }),
|
|
2380
|
+
headerActions != null && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-shrink-0 items-center gap-1", children: headerActions })
|
|
2381
|
+
] }),
|
|
2382
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 overflow-hidden", children: [
|
|
2383
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { ref: listRef, onScroll, className: "flex h-full flex-col gap-1 overflow-y-auto bg-background px-4 py-3", children: [
|
|
2384
|
+
messages.length === 0 && !isTyping ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 items-center justify-center text-center text-sm text-foreground-muted", children: emptyState ?? "No messages yet. Say hello \u{1F44B}" }) : messages.map((m, i) => {
|
|
2385
|
+
const own = m.authorId === currentUserId;
|
|
2386
|
+
const prev = messages[i - 1];
|
|
2387
|
+
const next = messages[i + 1];
|
|
2388
|
+
const firstOfGroup = !prev || prev.authorId !== m.authorId;
|
|
2389
|
+
const lastOfGroup = !next || next.authorId !== m.authorId;
|
|
2390
|
+
const ts = m.timestamp ? toDate(m.timestamp) : null;
|
|
2391
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ["flex items-end gap-2", own ? "flex-row-reverse" : "", firstOfGroup ? "mt-2 first:mt-0" : ""].filter(Boolean).join(" "), children: [
|
|
2392
|
+
!own && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-7 flex-shrink-0", children: lastOfGroup && /* @__PURE__ */ jsxRuntime.jsx(Avatar, { src: m.avatar, alt: m.authorName ?? "User", fallback: initials(m.authorName), size: "xs" }) }),
|
|
2393
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: ["flex max-w-[78%] flex-col", own ? "items-end" : "items-start"].join(" "), children: [
|
|
2394
|
+
firstOfGroup && !own && m.authorName && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mb-0.5 px-1 text-[11px] font-medium text-foreground-muted", children: m.authorName }),
|
|
2395
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2396
|
+
"div",
|
|
2397
|
+
{
|
|
2398
|
+
className: [
|
|
2399
|
+
"whitespace-pre-wrap break-words px-3 py-1.5 text-sm leading-snug",
|
|
2400
|
+
own ? "rounded-2xl bg-accent text-accent-fg" : "rounded-2xl border border-border bg-surface text-foreground",
|
|
2401
|
+
lastOfGroup ? own ? "rounded-br-md" : "rounded-bl-md" : ""
|
|
2402
|
+
].filter(Boolean).join(" "),
|
|
2403
|
+
children: m.text
|
|
2404
|
+
}
|
|
2405
|
+
),
|
|
2406
|
+
lastOfGroup && (ts || own && m.status) && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "mt-0.5 px-1 text-[10px] text-foreground-muted", children: [
|
|
2407
|
+
ts && timeLabel(ts),
|
|
2408
|
+
own && m.status && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-1 capitalize", children: [
|
|
2409
|
+
"\xB7 ",
|
|
2410
|
+
m.status
|
|
2411
|
+
] })
|
|
2412
|
+
] })
|
|
2413
|
+
] })
|
|
2414
|
+
] }, m.id);
|
|
2415
|
+
}),
|
|
2416
|
+
isTyping && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-2 flex items-end gap-2", children: [
|
|
2417
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-7 flex-shrink-0" }),
|
|
2418
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 rounded-2xl rounded-bl-md border border-border bg-surface px-3 py-2", children: [
|
|
2419
|
+
/* @__PURE__ */ jsxRuntime.jsx(TypingDots, {}),
|
|
2420
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[11px] text-foreground-muted", children: typingNames.length === 1 ? `${typingNames[0]} is typing` : `${typingNames.length} people are typing` })
|
|
2421
|
+
] })
|
|
2422
|
+
] })
|
|
2423
|
+
] }),
|
|
2424
|
+
showJump && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2425
|
+
"button",
|
|
2426
|
+
{
|
|
2427
|
+
type: "button",
|
|
2428
|
+
onClick: () => scrollToBottom(true),
|
|
2429
|
+
"aria-label": "Jump to latest",
|
|
2430
|
+
className: "absolute bottom-3 left-1/2 flex h-8 w-8 -translate-x-1/2 items-center justify-center rounded-full border border-border bg-surface text-foreground-secondary shadow-md transition-colors hover:bg-surface-raised hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
2431
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ArrowDown, {})
|
|
2432
|
+
}
|
|
2433
|
+
)
|
|
2434
|
+
] }),
|
|
2435
|
+
!hideComposer && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-shrink-0 items-end gap-2 border-t border-border p-3", children: [
|
|
2436
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2437
|
+
"textarea",
|
|
2438
|
+
{
|
|
2439
|
+
ref: taRef,
|
|
2440
|
+
rows: 1,
|
|
2441
|
+
value: draft,
|
|
2442
|
+
disabled,
|
|
2443
|
+
placeholder,
|
|
2444
|
+
onChange: (e) => setDraft(e.target.value),
|
|
2445
|
+
onKeyDown,
|
|
2446
|
+
"aria-label": "Message",
|
|
2447
|
+
className: `${fieldShell({ size: "md", hasError: false, disabled, sized: false })} max-h-[120px] flex-1 resize-none px-3 py-2 leading-snug`
|
|
2448
|
+
}
|
|
2449
|
+
),
|
|
2450
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2451
|
+
IconButton,
|
|
2452
|
+
{
|
|
2453
|
+
type: "primary",
|
|
2454
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(SendIcon, {}),
|
|
2455
|
+
title: "Send",
|
|
2456
|
+
disabled: disabled || draft.trim().length === 0,
|
|
2457
|
+
onClick: send
|
|
2458
|
+
}
|
|
2459
|
+
)
|
|
2460
|
+
] })
|
|
2461
|
+
]
|
|
2462
|
+
}
|
|
2463
|
+
);
|
|
2464
|
+
}
|
|
2171
2465
|
var VALUE_SIZE = {
|
|
2172
2466
|
sm: "text-xl",
|
|
2173
2467
|
md: "text-3xl",
|
|
@@ -2179,7 +2473,7 @@ var TONE2 = {
|
|
|
2179
2473
|
neutral: "text-foreground-muted"
|
|
2180
2474
|
};
|
|
2181
2475
|
var ArrowUp = /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.2, "aria-hidden": "true", className: "h-3.5 w-3.5", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 19V5M5 12l7-7 7 7" }) });
|
|
2182
|
-
var
|
|
2476
|
+
var ArrowDown2 = /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.2, "aria-hidden": "true", className: "h-3.5 w-3.5", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M12 5v14M5 12l7 7 7-7" }) });
|
|
2183
2477
|
function Statistic({
|
|
2184
2478
|
label,
|
|
2185
2479
|
value,
|
|
@@ -2211,7 +2505,7 @@ function Statistic({
|
|
|
2211
2505
|
suffix && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground-muted text-[0.5em] font-medium self-center", children: suffix })
|
|
2212
2506
|
] }),
|
|
2213
2507
|
delta && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `mt-1.5 flex items-center gap-1 text-sm font-medium ${align === "center" ? "justify-center" : ""} ${TONE2[deltaTone]}`, children: [
|
|
2214
|
-
dir === "up" ? ArrowUp : dir === "down" ?
|
|
2508
|
+
dir === "up" ? ArrowUp : dir === "down" ? ArrowDown2 : null,
|
|
2215
2509
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: delta.value }),
|
|
2216
2510
|
delta.label && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground-muted font-normal", children: delta.label })
|
|
2217
2511
|
] }),
|
|
@@ -2247,7 +2541,7 @@ function FAB({
|
|
|
2247
2541
|
className = "",
|
|
2248
2542
|
style
|
|
2249
2543
|
}) {
|
|
2250
|
-
const [open, setOpen] =
|
|
2544
|
+
const [open, setOpen] = React29.useState(false);
|
|
2251
2545
|
const reduced = framerMotion.useReducedMotion();
|
|
2252
2546
|
const hasDial = !!actions && actions.length > 0;
|
|
2253
2547
|
const bottom = position.startsWith("bottom");
|
|
@@ -2349,8 +2643,8 @@ function PopConfirm({
|
|
|
2349
2643
|
onOpenChange,
|
|
2350
2644
|
className = ""
|
|
2351
2645
|
}) {
|
|
2352
|
-
const [uncontrolledOpen, setUncontrolledOpen] =
|
|
2353
|
-
const [loading, setLoading] =
|
|
2646
|
+
const [uncontrolledOpen, setUncontrolledOpen] = React29.useState(false);
|
|
2647
|
+
const [loading, setLoading] = React29.useState(false);
|
|
2354
2648
|
const isOpen = open ?? uncontrolledOpen;
|
|
2355
2649
|
const setOpen = (next) => {
|
|
2356
2650
|
onOpenChange?.(next);
|
|
@@ -2437,16 +2731,16 @@ function LogoutTimer({
|
|
|
2437
2731
|
logoutLabel = "Sign out now"
|
|
2438
2732
|
}) {
|
|
2439
2733
|
const reduced = framerMotion.useReducedMotion();
|
|
2440
|
-
const [warning, setWarning] =
|
|
2441
|
-
const [remaining, setRemaining] =
|
|
2442
|
-
const idleTimer =
|
|
2443
|
-
const tick =
|
|
2444
|
-
const deadline =
|
|
2445
|
-
const warningRef =
|
|
2446
|
-
const lastReset =
|
|
2447
|
-
const cbs =
|
|
2734
|
+
const [warning, setWarning] = React29.useState(false);
|
|
2735
|
+
const [remaining, setRemaining] = React29.useState(countdown);
|
|
2736
|
+
const idleTimer = React29.useRef(null);
|
|
2737
|
+
const tick = React29.useRef(null);
|
|
2738
|
+
const deadline = React29.useRef(0);
|
|
2739
|
+
const warningRef = React29.useRef(false);
|
|
2740
|
+
const lastReset = React29.useRef(0);
|
|
2741
|
+
const cbs = React29.useRef({ onLogout, onContinue, onWarning });
|
|
2448
2742
|
cbs.current = { onLogout, onContinue, onWarning };
|
|
2449
|
-
const clearTimers =
|
|
2743
|
+
const clearTimers = React29.useCallback(() => {
|
|
2450
2744
|
if (idleTimer.current) {
|
|
2451
2745
|
clearTimeout(idleTimer.current);
|
|
2452
2746
|
idleTimer.current = null;
|
|
@@ -2456,13 +2750,13 @@ function LogoutTimer({
|
|
|
2456
2750
|
tick.current = null;
|
|
2457
2751
|
}
|
|
2458
2752
|
}, []);
|
|
2459
|
-
const logout =
|
|
2753
|
+
const logout = React29.useCallback(() => {
|
|
2460
2754
|
clearTimers();
|
|
2461
2755
|
warningRef.current = false;
|
|
2462
2756
|
setWarning(false);
|
|
2463
2757
|
cbs.current.onLogout();
|
|
2464
2758
|
}, [clearTimers]);
|
|
2465
|
-
const startIdle =
|
|
2759
|
+
const startIdle = React29.useCallback(() => {
|
|
2466
2760
|
if (idleTimer.current) clearTimeout(idleTimer.current);
|
|
2467
2761
|
idleTimer.current = setTimeout(() => {
|
|
2468
2762
|
warningRef.current = true;
|
|
@@ -2477,7 +2771,7 @@ function LogoutTimer({
|
|
|
2477
2771
|
}, 250);
|
|
2478
2772
|
}, timeout);
|
|
2479
2773
|
}, [timeout, countdown, logout]);
|
|
2480
|
-
const stay =
|
|
2774
|
+
const stay = React29.useCallback(() => {
|
|
2481
2775
|
if (tick.current) {
|
|
2482
2776
|
clearInterval(tick.current);
|
|
2483
2777
|
tick.current = null;
|
|
@@ -2487,7 +2781,7 @@ function LogoutTimer({
|
|
|
2487
2781
|
cbs.current.onContinue?.();
|
|
2488
2782
|
startIdle();
|
|
2489
2783
|
}, [startIdle]);
|
|
2490
|
-
|
|
2784
|
+
React29.useEffect(() => {
|
|
2491
2785
|
if (!enabled) {
|
|
2492
2786
|
clearTimers();
|
|
2493
2787
|
warningRef.current = false;
|
|
@@ -2559,16 +2853,16 @@ function Calendar2({
|
|
|
2559
2853
|
className = "",
|
|
2560
2854
|
style
|
|
2561
2855
|
}) {
|
|
2562
|
-
const today =
|
|
2563
|
-
const [internalMonth, setInternalMonth] =
|
|
2856
|
+
const today = React29.useMemo(() => startOfDay(/* @__PURE__ */ new Date()), []);
|
|
2857
|
+
const [internalMonth, setInternalMonth] = React29.useState(() => month ?? defaultMonth ?? value ?? today);
|
|
2564
2858
|
const visible = month ?? internalMonth;
|
|
2565
2859
|
const setMonth = (next) => {
|
|
2566
2860
|
onMonthChange?.(next);
|
|
2567
2861
|
if (month === void 0) setInternalMonth(next);
|
|
2568
2862
|
};
|
|
2569
|
-
const grid =
|
|
2570
|
-
const weekdays =
|
|
2571
|
-
const eventsByDay =
|
|
2863
|
+
const grid = React29.useMemo(() => buildGrid(visible, weekStartsOn), [visible, weekStartsOn]);
|
|
2864
|
+
const weekdays = React29.useMemo(() => Array.from({ length: 7 }, (_, i) => WEEKDAYS[(i + weekStartsOn) % 7]), [weekStartsOn]);
|
|
2865
|
+
const eventsByDay = React29.useMemo(() => {
|
|
2572
2866
|
const map = /* @__PURE__ */ new Map();
|
|
2573
2867
|
for (const ev of events ?? []) {
|
|
2574
2868
|
const key = startOfDay(ev.date).toDateString();
|
|
@@ -2648,134 +2942,6 @@ function Calendar2({
|
|
|
2648
2942
|
}) })
|
|
2649
2943
|
] });
|
|
2650
2944
|
}
|
|
2651
|
-
var FIELD_SIZE = {
|
|
2652
|
-
sm: { control: "h-control-sm", text: "text-xs", padX: "px-2.5", gap: "gap-1.5" },
|
|
2653
|
-
md: { control: "h-control-md", text: "text-sm", padX: "px-3", gap: "gap-2" },
|
|
2654
|
-
lg: { control: "h-control-lg", text: "text-sm", padX: "px-3.5", gap: "gap-2.5" }
|
|
2655
|
-
};
|
|
2656
|
-
var FOCUS_WITHIN = "focus-within:outline-none focus-within:border-accent";
|
|
2657
|
-
var FOCUS_ELEMENT = "focus:outline-none focus:border-accent data-[state=open]:border-accent";
|
|
2658
|
-
var FOCUS_WITHIN_ERROR = "focus-within:border-status-error";
|
|
2659
|
-
var FOCUS_ELEMENT_ERROR = "focus:border-status-error data-[state=open]:border-status-error";
|
|
2660
|
-
function fieldShell({
|
|
2661
|
-
size = "md",
|
|
2662
|
-
hasError = false,
|
|
2663
|
-
disabled = false,
|
|
2664
|
-
focusWithin = false,
|
|
2665
|
-
sized = true
|
|
2666
|
-
} = {}) {
|
|
2667
|
-
const s = FIELD_SIZE[size];
|
|
2668
|
-
return [
|
|
2669
|
-
"w-full rounded-lg border bg-surface text-foreground",
|
|
2670
|
-
"transition-[color,box-shadow,border-color] duration-150",
|
|
2671
|
-
s.text,
|
|
2672
|
-
sized ? `${s.control} ${s.padX}` : "",
|
|
2673
|
-
// resting border
|
|
2674
|
-
hasError ? "border-status-error" : "border-border",
|
|
2675
|
-
// hover (only when interactive + no error)
|
|
2676
|
-
disabled ? "bg-surface-raised text-foreground-muted cursor-not-allowed" : hasError ? "" : "hover:border-border-strong",
|
|
2677
|
-
// focus
|
|
2678
|
-
focusWithin ? FOCUS_WITHIN : FOCUS_ELEMENT,
|
|
2679
|
-
hasError ? focusWithin ? FOCUS_WITHIN_ERROR : FOCUS_ELEMENT_ERROR : "",
|
|
2680
|
-
// placeholder colour for native inputs
|
|
2681
|
-
"placeholder:text-foreground-muted"
|
|
2682
|
-
].filter(Boolean).join(" ");
|
|
2683
|
-
}
|
|
2684
|
-
function FieldHelpIcon({ text }) {
|
|
2685
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Tooltip, { title: text, placement: "top", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2686
|
-
"button",
|
|
2687
|
-
{
|
|
2688
|
-
type: "button",
|
|
2689
|
-
"aria-label": "More information",
|
|
2690
|
-
className: "inline-flex items-center justify-center rounded-full text-foreground-muted transition-colors hover:text-foreground focus:outline-none focus-visible:text-accent",
|
|
2691
|
-
children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { viewBox: "0 0 16 16", className: "h-3.5 w-3.5", fill: "none", stroke: "currentColor", strokeWidth: 1.5, "aria-hidden": "true", children: [
|
|
2692
|
-
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "8", cy: "8", r: "6.25" }),
|
|
2693
|
-
/* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", d: "M8 7.4v3.4" }),
|
|
2694
|
-
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "8", cy: "5.1", r: "0.65", fill: "currentColor", stroke: "none" })
|
|
2695
|
-
] })
|
|
2696
|
-
}
|
|
2697
|
-
) });
|
|
2698
|
-
}
|
|
2699
|
-
function FieldLabel({
|
|
2700
|
-
label,
|
|
2701
|
-
htmlFor,
|
|
2702
|
-
required,
|
|
2703
|
-
helperText,
|
|
2704
|
-
horizontal = false,
|
|
2705
|
-
align = "start",
|
|
2706
|
-
style,
|
|
2707
|
-
width,
|
|
2708
|
-
className = ""
|
|
2709
|
-
}) {
|
|
2710
|
-
if (label == null && helperText == null) return null;
|
|
2711
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2712
|
-
"div",
|
|
2713
|
-
{
|
|
2714
|
-
style: { width: horizontal ? width : void 0, ...style },
|
|
2715
|
-
className: [
|
|
2716
|
-
"flex items-center gap-1",
|
|
2717
|
-
horizontal ? "flex-shrink-0 whitespace-nowrap" : "",
|
|
2718
|
-
// Only the 'start' alignment needs the top nudge; 'center' relies
|
|
2719
|
-
// on the row's items-center to line up with a short control.
|
|
2720
|
-
horizontal && align === "start" ? "mt-2" : "",
|
|
2721
|
-
className
|
|
2722
|
-
].filter(Boolean).join(" "),
|
|
2723
|
-
children: [
|
|
2724
|
-
label != null && /* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor, className: "text-sm font-medium text-foreground select-none", children: [
|
|
2725
|
-
label,
|
|
2726
|
-
required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-status-error ml-0.5", "aria-hidden": "true", children: "*" })
|
|
2727
|
-
] }),
|
|
2728
|
-
helperText != null && /* @__PURE__ */ jsxRuntime.jsx(FieldHelpIcon, { text: helperText })
|
|
2729
|
-
]
|
|
2730
|
-
}
|
|
2731
|
-
);
|
|
2732
|
-
}
|
|
2733
|
-
function Field({
|
|
2734
|
-
label,
|
|
2735
|
-
htmlFor,
|
|
2736
|
-
errorId,
|
|
2737
|
-
errorMessage,
|
|
2738
|
-
layout = "vertical",
|
|
2739
|
-
required,
|
|
2740
|
-
helperText,
|
|
2741
|
-
labelAlign = "start",
|
|
2742
|
-
labelStyle,
|
|
2743
|
-
labelWidth,
|
|
2744
|
-
className = "",
|
|
2745
|
-
children
|
|
2746
|
-
}) {
|
|
2747
|
-
const hasError = errorMessage != null;
|
|
2748
|
-
const horizontal = layout === "horizontal";
|
|
2749
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2750
|
-
"div",
|
|
2751
|
-
{
|
|
2752
|
-
className: [
|
|
2753
|
-
"flex",
|
|
2754
|
-
horizontal ? `flex-row gap-3 ${labelAlign === "center" ? "items-center" : "items-start"}` : "flex-col gap-1.5",
|
|
2755
|
-
className
|
|
2756
|
-
].filter(Boolean).join(" "),
|
|
2757
|
-
children: [
|
|
2758
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2759
|
-
FieldLabel,
|
|
2760
|
-
{
|
|
2761
|
-
label,
|
|
2762
|
-
htmlFor,
|
|
2763
|
-
required,
|
|
2764
|
-
helperText,
|
|
2765
|
-
horizontal,
|
|
2766
|
-
align: labelAlign,
|
|
2767
|
-
style: labelStyle,
|
|
2768
|
-
width: labelWidth
|
|
2769
|
-
}
|
|
2770
|
-
),
|
|
2771
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col min-w-0 flex-1", children: [
|
|
2772
|
-
children,
|
|
2773
|
-
hasError && /* @__PURE__ */ jsxRuntime.jsx("div", { id: errorId, className: "text-status-error text-xs mt-1", children: errorMessage })
|
|
2774
|
-
] })
|
|
2775
|
-
]
|
|
2776
|
-
}
|
|
2777
|
-
);
|
|
2778
|
-
}
|
|
2779
2945
|
var SIZE5 = {
|
|
2780
2946
|
sm: { h: "h-control-sm", text: "text-xs", pad: "px-2.5" },
|
|
2781
2947
|
md: { h: "h-control-md", text: "text-sm", pad: "px-3.5" },
|
|
@@ -2799,11 +2965,11 @@ function SegmentedControl({
|
|
|
2799
2965
|
"aria-label": ariaLabel
|
|
2800
2966
|
}) {
|
|
2801
2967
|
const sz = SIZE5[size];
|
|
2802
|
-
const groupId =
|
|
2803
|
-
const errorId =
|
|
2968
|
+
const groupId = React29.useId();
|
|
2969
|
+
const errorId = React29.useId();
|
|
2804
2970
|
const hasError = errorMessage != null;
|
|
2805
2971
|
const isControlled = value !== void 0;
|
|
2806
|
-
const [internal, setInternal] =
|
|
2972
|
+
const [internal, setInternal] = React29.useState(defaultValue);
|
|
2807
2973
|
const current = isControlled ? value : internal;
|
|
2808
2974
|
const handle = (v) => {
|
|
2809
2975
|
if (!v) return;
|
|
@@ -2890,7 +3056,7 @@ var MONTHS2 = [
|
|
|
2890
3056
|
];
|
|
2891
3057
|
var MONTHS_SHORT = MONTHS2.map((m) => m.slice(0, 3));
|
|
2892
3058
|
var WEEKDAYS2 = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
2893
|
-
var
|
|
3059
|
+
var toDate2 = (d) => d instanceof Date ? d : new Date(d);
|
|
2894
3060
|
var startOfDay2 = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
2895
3061
|
var addDays = (d, n) => {
|
|
2896
3062
|
const x = new Date(d);
|
|
@@ -2938,10 +3104,10 @@ var weekLabel = (cursor, weekStartsOn) => {
|
|
|
2938
3104
|
};
|
|
2939
3105
|
var minutesIntoDay = (d) => d.getHours() * 60 + d.getMinutes();
|
|
2940
3106
|
var hourLabel = (hour) => `${String(hour).padStart(2, "0")}:00`;
|
|
2941
|
-
var
|
|
3107
|
+
var timeLabel2 = (d) => `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
|
|
2942
3108
|
var normalize = (e) => {
|
|
2943
|
-
const start =
|
|
2944
|
-
const end = e.end ?
|
|
3109
|
+
const start = toDate2(e.start);
|
|
3110
|
+
const end = e.end ? toDate2(e.end) : new Date(start.getTime() + 36e5);
|
|
2945
3111
|
return { ...e, start, end };
|
|
2946
3112
|
};
|
|
2947
3113
|
var Spinner2 = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "currentColor", "aria-hidden": "true", className: "h-5 w-5 animate-spin text-accent", children: /* @__PURE__ */ jsxRuntime.jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M4.755 10.059a7.5 7.5 0 0112.548-3.364l1.903 1.903h-3.183a.75.75 0 100 1.5h4.992a.75.75 0 00.75-.75V4.356a.75.75 0 00-1.5 0v3.18l-1.9-1.9A9 9 0 003.306 9.67a.75.75 0 101.45.388zm15.408 3.352a.75.75 0 00-.919.53 7.5 7.5 0 01-12.548 3.364l-1.902-1.903h3.183a.75.75 0 000-1.5H2.984a.75.75 0 00-.75.75v4.992a.75.75 0 001.5 0v-3.18l1.9 1.9a9 9 0 0015.059-4.035.75.75 0 00-.53-.918z" }) });
|
|
@@ -2963,22 +3129,22 @@ function Scheduler({
|
|
|
2963
3129
|
style
|
|
2964
3130
|
}) {
|
|
2965
3131
|
const reduced = framerMotion.useReducedMotion();
|
|
2966
|
-
const [view, setView] =
|
|
2967
|
-
const [cursor, setCursor] =
|
|
2968
|
-
const [loaded, setLoaded] =
|
|
2969
|
-
const [loading, setLoading] =
|
|
2970
|
-
const [error, setError] =
|
|
2971
|
-
const [reloadKey, setReloadKey] =
|
|
2972
|
-
const [dir, setDir] =
|
|
2973
|
-
const cbRef =
|
|
3132
|
+
const [view, setView] = React29.useState(defaultView);
|
|
3133
|
+
const [cursor, setCursor] = React29.useState(() => defaultDate ?? /* @__PURE__ */ new Date());
|
|
3134
|
+
const [loaded, setLoaded] = React29.useState([]);
|
|
3135
|
+
const [loading, setLoading] = React29.useState(false);
|
|
3136
|
+
const [error, setError] = React29.useState(null);
|
|
3137
|
+
const [reloadKey, setReloadKey] = React29.useState(0);
|
|
3138
|
+
const [dir, setDir] = React29.useState(0);
|
|
3139
|
+
const cbRef = React29.useRef({ loadEvents, onError });
|
|
2974
3140
|
cbRef.current = { loadEvents, onError };
|
|
2975
|
-
const range =
|
|
3141
|
+
const range = React29.useMemo(
|
|
2976
3142
|
() => view === "month" ? monthRange(cursor) : weekRange(cursor, weekStartsOn),
|
|
2977
3143
|
[view, cursor, weekStartsOn]
|
|
2978
3144
|
);
|
|
2979
3145
|
const fromKey = range.from.getTime();
|
|
2980
3146
|
const toKey = range.to.getTime();
|
|
2981
|
-
|
|
3147
|
+
React29.useEffect(() => {
|
|
2982
3148
|
const { loadEvents: loader, onError: onErr } = cbRef.current;
|
|
2983
3149
|
if (!loader) return;
|
|
2984
3150
|
let cancelled = false;
|
|
@@ -2998,16 +3164,16 @@ function Scheduler({
|
|
|
2998
3164
|
cancelled = true;
|
|
2999
3165
|
};
|
|
3000
3166
|
}, [fromKey, toKey, view, reloadKey]);
|
|
3001
|
-
const retry =
|
|
3002
|
-
const events =
|
|
3167
|
+
const retry = React29.useCallback(() => setReloadKey((k) => k + 1), []);
|
|
3168
|
+
const events = React29.useMemo(
|
|
3003
3169
|
() => (controlledEvents ?? loaded).map(normalize),
|
|
3004
3170
|
[controlledEvents, loaded]
|
|
3005
3171
|
);
|
|
3006
|
-
const go =
|
|
3172
|
+
const go = React29.useCallback((delta) => {
|
|
3007
3173
|
setDir(delta);
|
|
3008
3174
|
setCursor((c) => view === "month" ? addMonths2(c, delta) : addDays(c, delta * 7));
|
|
3009
3175
|
}, [view]);
|
|
3010
|
-
const goToday =
|
|
3176
|
+
const goToday = React29.useCallback(() => {
|
|
3011
3177
|
setDir(0);
|
|
3012
3178
|
setCursor(/* @__PURE__ */ new Date());
|
|
3013
3179
|
}, []);
|
|
@@ -3117,9 +3283,9 @@ function SchedulerError({ onRetry }) {
|
|
|
3117
3283
|
] });
|
|
3118
3284
|
}
|
|
3119
3285
|
function MonthYearPicker({ label, cursor, onPick }) {
|
|
3120
|
-
const [open, setOpen] =
|
|
3121
|
-
const [viewYear, setViewYear] =
|
|
3122
|
-
|
|
3286
|
+
const [open, setOpen] = React29.useState(false);
|
|
3287
|
+
const [viewYear, setViewYear] = React29.useState(cursor.getFullYear());
|
|
3288
|
+
React29.useEffect(() => {
|
|
3123
3289
|
if (open) setViewYear(cursor.getFullYear());
|
|
3124
3290
|
}, [open, cursor]);
|
|
3125
3291
|
return /* @__PURE__ */ jsxRuntime.jsxs(Popover__namespace.Root, { open, onOpenChange: setOpen, children: [
|
|
@@ -3182,7 +3348,7 @@ function MonthView({
|
|
|
3182
3348
|
onSelectSlot,
|
|
3183
3349
|
onSelectEvent
|
|
3184
3350
|
}) {
|
|
3185
|
-
const grid =
|
|
3351
|
+
const grid = React29.useMemo(() => buildMonthGrid(cursor, weekStartsOn), [cursor, weekStartsOn]);
|
|
3186
3352
|
const labels = weekdayLabels(weekStartsOn);
|
|
3187
3353
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full flex-col", children: [
|
|
3188
3354
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-7 border-b border-border", children: labels.map((l) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 py-1.5 text-center text-[11px] font-medium uppercase tracking-wide text-foreground-muted", children: l }, l)) }),
|
|
@@ -3238,7 +3404,7 @@ function EventChip({ event, onSelect }) {
|
|
|
3238
3404
|
e.stopPropagation();
|
|
3239
3405
|
onSelect?.(event);
|
|
3240
3406
|
},
|
|
3241
|
-
title: `${event.title} \xB7 ${
|
|
3407
|
+
title: `${event.title} \xB7 ${timeLabel2(event.start)}`,
|
|
3242
3408
|
className: "flex items-center gap-1.5 truncate rounded px-1 py-0.5 text-left text-[11px] font-medium text-foreground hover:opacity-80 focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
3243
3409
|
children: [
|
|
3244
3410
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-2 w-2 flex-shrink-0 rounded-full", style: { backgroundColor: color } }),
|
|
@@ -3256,11 +3422,11 @@ function WeekView({
|
|
|
3256
3422
|
onSelectSlot,
|
|
3257
3423
|
onSelectEvent
|
|
3258
3424
|
}) {
|
|
3259
|
-
const days =
|
|
3260
|
-
const labels =
|
|
3425
|
+
const days = React29.useMemo(() => getWeekDays(cursor, weekStartsOn), [cursor, weekStartsOn]);
|
|
3426
|
+
const labels = React29.useMemo(() => weekdayLabels(weekStartsOn), [weekStartsOn]);
|
|
3261
3427
|
const dow = (d) => labels[(d.getDay() - weekStartsOn + 7) % 7];
|
|
3262
3428
|
const [startHour, endHour] = dayHours;
|
|
3263
|
-
const hours =
|
|
3429
|
+
const hours = React29.useMemo(
|
|
3264
3430
|
() => Array.from({ length: endHour - startHour }, (_, i) => startHour + i),
|
|
3265
3431
|
[startHour, endHour]
|
|
3266
3432
|
);
|
|
@@ -3303,7 +3469,7 @@ function WeekView({
|
|
|
3303
3469
|
ev.stopPropagation();
|
|
3304
3470
|
onSelectEvent?.(e);
|
|
3305
3471
|
},
|
|
3306
|
-
title: `${e.title} \xB7 ${
|
|
3472
|
+
title: `${e.title} \xB7 ${timeLabel2(e.start)}\u2013${timeLabel2(e.end)}`,
|
|
3307
3473
|
className: "absolute left-0.5 right-0.5 overflow-hidden rounded-md border px-1.5 py-0.5 text-left text-[11px] leading-tight text-foreground shadow-sm transition-shadow hover:shadow-md focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
3308
3474
|
style: {
|
|
3309
3475
|
top: Math.max(0, top),
|
|
@@ -3313,7 +3479,7 @@ function WeekView({
|
|
|
3313
3479
|
},
|
|
3314
3480
|
children: [
|
|
3315
3481
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate font-medium", children: e.title }),
|
|
3316
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate", style: { color }, children:
|
|
3482
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate", style: { color }, children: timeLabel2(e.start) })
|
|
3317
3483
|
]
|
|
3318
3484
|
},
|
|
3319
3485
|
e.id
|
|
@@ -3451,17 +3617,17 @@ function Cart({
|
|
|
3451
3617
|
] })
|
|
3452
3618
|
] });
|
|
3453
3619
|
}
|
|
3454
|
-
var CartContext =
|
|
3620
|
+
var CartContext = React29.createContext(null);
|
|
3455
3621
|
var clampQty = (qty, max) => {
|
|
3456
3622
|
const lower = Math.max(1, Math.round(qty));
|
|
3457
3623
|
return max != null ? Math.min(lower, max) : lower;
|
|
3458
3624
|
};
|
|
3459
3625
|
function CartProvider({ children, initialItems = [], onChange }) {
|
|
3460
|
-
const [items, setItems] =
|
|
3461
|
-
|
|
3626
|
+
const [items, setItems] = React29.useState(initialItems);
|
|
3627
|
+
React29.useEffect(() => {
|
|
3462
3628
|
onChange?.(items);
|
|
3463
3629
|
}, [items]);
|
|
3464
|
-
const addToCart =
|
|
3630
|
+
const addToCart = React29.useCallback((item, quantity) => {
|
|
3465
3631
|
const addQty = quantity ?? item.quantity ?? 1;
|
|
3466
3632
|
setItems((prev) => {
|
|
3467
3633
|
const existing = prev.find((it) => it.id === item.id);
|
|
@@ -3474,29 +3640,29 @@ function CartProvider({ children, initialItems = [], onChange }) {
|
|
|
3474
3640
|
return [...prev, { ...rest, quantity: clampQty(addQty, item.max) }];
|
|
3475
3641
|
});
|
|
3476
3642
|
}, []);
|
|
3477
|
-
const removeFromCart =
|
|
3643
|
+
const removeFromCart = React29.useCallback((id) => {
|
|
3478
3644
|
setItems((prev) => prev.filter((it) => it.id !== id));
|
|
3479
3645
|
}, []);
|
|
3480
|
-
const updateQuantity =
|
|
3646
|
+
const updateQuantity = React29.useCallback((id, quantity) => {
|
|
3481
3647
|
setItems(
|
|
3482
3648
|
(prev) => prev.map((it) => it.id === id ? { ...it, quantity: clampQty(quantity, it.max) } : it)
|
|
3483
3649
|
);
|
|
3484
3650
|
}, []);
|
|
3485
|
-
const clearCart =
|
|
3486
|
-
const isInCart =
|
|
3487
|
-
const getItemCount =
|
|
3488
|
-
const getCartTotal =
|
|
3651
|
+
const clearCart = React29.useCallback(() => setItems([]), []);
|
|
3652
|
+
const isInCart = React29.useCallback((id) => items.some((it) => it.id === id), [items]);
|
|
3653
|
+
const getItemCount = React29.useCallback(() => items.reduce((sum, it) => sum + it.quantity, 0), [items]);
|
|
3654
|
+
const getCartTotal = React29.useCallback(
|
|
3489
3655
|
() => items.reduce((sum, it) => sum + it.price * it.quantity, 0),
|
|
3490
3656
|
[items]
|
|
3491
3657
|
);
|
|
3492
|
-
const value =
|
|
3658
|
+
const value = React29.useMemo(
|
|
3493
3659
|
() => ({ items, addToCart, removeFromCart, updateQuantity, clearCart, isInCart, getItemCount, getCartTotal }),
|
|
3494
3660
|
[items, addToCart, removeFromCart, updateQuantity, clearCart, isInCart, getItemCount, getCartTotal]
|
|
3495
3661
|
);
|
|
3496
3662
|
return /* @__PURE__ */ jsxRuntime.jsx(CartContext.Provider, { value, children });
|
|
3497
3663
|
}
|
|
3498
3664
|
function useCart() {
|
|
3499
|
-
const ctx =
|
|
3665
|
+
const ctx = React29.useContext(CartContext);
|
|
3500
3666
|
if (!ctx) {
|
|
3501
3667
|
throw new Error("useCart must be used within a <CartProvider>.");
|
|
3502
3668
|
}
|
|
@@ -3830,11 +3996,11 @@ function buildBindings(store, name, kind, snap) {
|
|
|
3830
3996
|
|
|
3831
3997
|
// src/form/useForm.ts
|
|
3832
3998
|
function useForm(options = {}) {
|
|
3833
|
-
const ref =
|
|
3999
|
+
const ref = React29.useRef(null);
|
|
3834
4000
|
if (ref.current === null) ref.current = new FormStore(options);
|
|
3835
4001
|
const store = ref.current;
|
|
3836
|
-
|
|
3837
|
-
const make =
|
|
4002
|
+
React29.useSyncExternalStore(store.subscribe, store.getRootSnapshot, store.getRootSnapshot);
|
|
4003
|
+
const make = React29.useCallback(
|
|
3838
4004
|
(kind) => (name, rules) => {
|
|
3839
4005
|
if (rules !== void 0) store.setRule(name, rules);
|
|
3840
4006
|
return buildBindings(store, name, kind, store.getFieldSnapshot(name));
|
|
@@ -3863,9 +4029,9 @@ function useForm(options = {}) {
|
|
|
3863
4029
|
fieldTarget: make("target")
|
|
3864
4030
|
};
|
|
3865
4031
|
}
|
|
3866
|
-
var FormContext =
|
|
4032
|
+
var FormContext = React29.createContext(null);
|
|
3867
4033
|
function useFormStore() {
|
|
3868
|
-
const store =
|
|
4034
|
+
const store = React29.useContext(FormContext);
|
|
3869
4035
|
if (!store) {
|
|
3870
4036
|
throw new Error("useFormStore must be used within a <Form>. Did you forget to wrap your fields?");
|
|
3871
4037
|
}
|
|
@@ -3879,8 +4045,8 @@ function Form({
|
|
|
3879
4045
|
children,
|
|
3880
4046
|
...rest
|
|
3881
4047
|
}) {
|
|
3882
|
-
const ref =
|
|
3883
|
-
const bypass =
|
|
4048
|
+
const ref = React29.useRef(null);
|
|
4049
|
+
const bypass = React29.useRef(false);
|
|
3884
4050
|
const handleSubmit = async (e) => {
|
|
3885
4051
|
if (bypass.current) {
|
|
3886
4052
|
bypass.current = false;
|
|
@@ -3932,12 +4098,12 @@ function useFormField(name, options = {}) {
|
|
|
3932
4098
|
const store = useFormStore();
|
|
3933
4099
|
const { kind = "value", rules } = options;
|
|
3934
4100
|
if (rules !== void 0 && store.getRule(name) !== rules) store.setRule(name, rules);
|
|
3935
|
-
|
|
4101
|
+
React29.useEffect(() => {
|
|
3936
4102
|
return () => {
|
|
3937
4103
|
if (rules !== void 0) store.removeRule(name);
|
|
3938
4104
|
};
|
|
3939
4105
|
}, [store, name]);
|
|
3940
|
-
const snap =
|
|
4106
|
+
const snap = React29.useSyncExternalStore(
|
|
3941
4107
|
store.subscribe,
|
|
3942
4108
|
() => store.getFieldSnapshot(name)
|
|
3943
4109
|
);
|
|
@@ -3949,7 +4115,7 @@ function FormField({ name, kind, rules, children }) {
|
|
|
3949
4115
|
}
|
|
3950
4116
|
function useFieldArray(name) {
|
|
3951
4117
|
const store = useFormStore();
|
|
3952
|
-
|
|
4118
|
+
React29.useSyncExternalStore(store.subscribe, store.getRootSnapshot, store.getRootSnapshot);
|
|
3953
4119
|
const arr = store.getValue(name) ?? [];
|
|
3954
4120
|
const keys = store.getKeys(name);
|
|
3955
4121
|
return {
|
|
@@ -3982,7 +4148,7 @@ function TextInput({
|
|
|
3982
4148
|
suffix,
|
|
3983
4149
|
id
|
|
3984
4150
|
}) {
|
|
3985
|
-
const errorId =
|
|
4151
|
+
const errorId = React29.useId();
|
|
3986
4152
|
const hasError = errorMessage != null;
|
|
3987
4153
|
const hasAdornment = prefix != null || suffix != null;
|
|
3988
4154
|
const inputId = htmlFor ?? id;
|
|
@@ -4143,7 +4309,7 @@ function CreditCardForm({
|
|
|
4143
4309
|
className = "",
|
|
4144
4310
|
style
|
|
4145
4311
|
}) {
|
|
4146
|
-
const initial =
|
|
4312
|
+
const initial = React29.useRef({
|
|
4147
4313
|
number: formatCardNumber(defaultValue?.number ?? ""),
|
|
4148
4314
|
name: defaultValue?.name ?? "",
|
|
4149
4315
|
expiry: formatExpiry(defaultValue?.expiry ?? ""),
|
|
@@ -4152,7 +4318,7 @@ function CreditCardForm({
|
|
|
4152
4318
|
const form = useForm({ initialValues: initial });
|
|
4153
4319
|
const numberStr = String(form.values.number ?? "");
|
|
4154
4320
|
const brand = detectBrand(numberStr);
|
|
4155
|
-
|
|
4321
|
+
React29.useEffect(() => {
|
|
4156
4322
|
onChange?.(toCard(form.values));
|
|
4157
4323
|
}, [form.values.number, form.values.name, form.values.expiry, form.values.cvv]);
|
|
4158
4324
|
const numberBind = form.fieldNative("number", {
|
|
@@ -4275,7 +4441,7 @@ function Checkout({
|
|
|
4275
4441
|
] })
|
|
4276
4442
|
] });
|
|
4277
4443
|
}
|
|
4278
|
-
var NotificationContext =
|
|
4444
|
+
var NotificationContext = React29.createContext({
|
|
4279
4445
|
open: () => void 0,
|
|
4280
4446
|
close: () => void 0
|
|
4281
4447
|
});
|
|
@@ -4333,26 +4499,26 @@ function NotificationItem({
|
|
|
4333
4499
|
onClose,
|
|
4334
4500
|
reduced
|
|
4335
4501
|
}) {
|
|
4336
|
-
const [paused, setPaused] =
|
|
4502
|
+
const [paused, setPaused] = React29.useState(false);
|
|
4337
4503
|
const duration = n.duration ?? 4e3;
|
|
4338
4504
|
const isAutoDismissing = isFinite(duration) && duration > 0;
|
|
4339
4505
|
const showProgress = !reduced && isAutoDismissing;
|
|
4340
|
-
const timerRef =
|
|
4341
|
-
const startTimeRef =
|
|
4342
|
-
const remainingRef =
|
|
4343
|
-
const clearTimer =
|
|
4506
|
+
const timerRef = React29.useRef(null);
|
|
4507
|
+
const startTimeRef = React29.useRef(0);
|
|
4508
|
+
const remainingRef = React29.useRef(duration);
|
|
4509
|
+
const clearTimer = React29.useCallback(() => {
|
|
4344
4510
|
if (timerRef.current !== null) {
|
|
4345
4511
|
clearTimeout(timerRef.current);
|
|
4346
4512
|
timerRef.current = null;
|
|
4347
4513
|
}
|
|
4348
4514
|
}, []);
|
|
4349
|
-
const scheduleDismiss =
|
|
4515
|
+
const scheduleDismiss = React29.useCallback((ms) => {
|
|
4350
4516
|
clearTimer();
|
|
4351
4517
|
if (!isAutoDismissing) return;
|
|
4352
4518
|
startTimeRef.current = Date.now();
|
|
4353
4519
|
timerRef.current = setTimeout(() => onClose(n.id), ms);
|
|
4354
4520
|
}, [clearTimer, isAutoDismissing, n.id, onClose]);
|
|
4355
|
-
|
|
4521
|
+
React29.useEffect(() => {
|
|
4356
4522
|
if (paused || !isAutoDismissing) return;
|
|
4357
4523
|
scheduleDismiss(remainingRef.current);
|
|
4358
4524
|
return clearTimer;
|
|
@@ -4435,15 +4601,15 @@ function NotificationProvider({
|
|
|
4435
4601
|
children,
|
|
4436
4602
|
position = "top-right"
|
|
4437
4603
|
}) {
|
|
4438
|
-
const [notifications, setNotifications] =
|
|
4604
|
+
const [notifications, setNotifications] = React29.useState([]);
|
|
4439
4605
|
const reduced = framerMotion.useReducedMotion();
|
|
4440
|
-
const open =
|
|
4606
|
+
const open = React29.useCallback((payload) => {
|
|
4441
4607
|
setNotifications((prev) => [
|
|
4442
4608
|
...prev,
|
|
4443
4609
|
{ duration: 4e3, ...payload, id: Date.now() + Math.random() }
|
|
4444
4610
|
]);
|
|
4445
4611
|
}, []);
|
|
4446
|
-
const close =
|
|
4612
|
+
const close = React29.useCallback((id) => {
|
|
4447
4613
|
setNotifications((prev) => prev.filter((n) => n.id !== id));
|
|
4448
4614
|
}, []);
|
|
4449
4615
|
return /* @__PURE__ */ jsxRuntime.jsxs(NotificationContext.Provider, { value: { open, close }, children: [
|
|
@@ -4472,7 +4638,7 @@ function NotificationProvider({
|
|
|
4472
4638
|
] });
|
|
4473
4639
|
}
|
|
4474
4640
|
function useNotification() {
|
|
4475
|
-
const { open } =
|
|
4641
|
+
const { open } = React29.useContext(NotificationContext);
|
|
4476
4642
|
return {
|
|
4477
4643
|
info: (props) => open({ type: "info", ...props }),
|
|
4478
4644
|
success: (props) => open({ type: "success", ...props }),
|
|
@@ -4589,10 +4755,10 @@ function FadingBase({
|
|
|
4589
4755
|
isMounted = false,
|
|
4590
4756
|
children
|
|
4591
4757
|
}) {
|
|
4592
|
-
const [shouldRender, setShouldRender] =
|
|
4593
|
-
const [visible, setVisible] =
|
|
4594
|
-
const timerRef =
|
|
4595
|
-
|
|
4758
|
+
const [shouldRender, setShouldRender] = React29.useState(isMounted);
|
|
4759
|
+
const [visible, setVisible] = React29.useState(false);
|
|
4760
|
+
const timerRef = React29.useRef(null);
|
|
4761
|
+
React29.useEffect(() => {
|
|
4596
4762
|
if (isMounted) {
|
|
4597
4763
|
setShouldRender(true);
|
|
4598
4764
|
const rafId = requestAnimationFrame(() => setVisible(true));
|
|
@@ -4690,8 +4856,8 @@ function ScalableContainer({
|
|
|
4690
4856
|
togglePosition = "top-right",
|
|
4691
4857
|
className = ""
|
|
4692
4858
|
}) {
|
|
4693
|
-
const containerRef =
|
|
4694
|
-
const [internalScaled, setInternalScaled] =
|
|
4859
|
+
const containerRef = React29.useRef(null);
|
|
4860
|
+
const [internalScaled, setInternalScaled] = React29.useState(false);
|
|
4695
4861
|
const isScaled = expanded ?? internalScaled;
|
|
4696
4862
|
const reduced = framerMotion.useReducedMotion();
|
|
4697
4863
|
const onToggle = () => {
|
|
@@ -4829,17 +4995,17 @@ function CatalogGrid({ items, buttonText, onOpen, className = "" }) {
|
|
|
4829
4995
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex flex-wrap gap-2 ${className}`.trim(), children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsx(GridCard, { item, buttonText, onOpen }, item.key)) });
|
|
4830
4996
|
}
|
|
4831
4997
|
function CatalogCarousel({ items, buttonText, onOpen, className = "" }) {
|
|
4832
|
-
const [activeIndex, setActiveIndex] =
|
|
4833
|
-
const [indexPool, setIndexPool] =
|
|
4834
|
-
const cardRefs =
|
|
4835
|
-
const getIndexes =
|
|
4998
|
+
const [activeIndex, setActiveIndex] = React29.useState(0);
|
|
4999
|
+
const [indexPool, setIndexPool] = React29.useState([]);
|
|
5000
|
+
const cardRefs = React29.useRef([]);
|
|
5001
|
+
const getIndexes = React29.useMemo(() => {
|
|
4836
5002
|
let nextIndex = activeIndex + 1;
|
|
4837
5003
|
let previousIndex = activeIndex - 1;
|
|
4838
5004
|
if (activeIndex === 0) previousIndex = items.length - 1;
|
|
4839
5005
|
if (activeIndex === items.length - 1) nextIndex = 0;
|
|
4840
5006
|
return { previousIndex, nextIndex };
|
|
4841
5007
|
}, [activeIndex, items.length]);
|
|
4842
|
-
|
|
5008
|
+
React29.useEffect(() => {
|
|
4843
5009
|
const { nextIndex, previousIndex } = getIndexes;
|
|
4844
5010
|
let indexes = [previousIndex, activeIndex, nextIndex];
|
|
4845
5011
|
if (activeIndex !== 0 && activeIndex !== items.length - 1) {
|
|
@@ -5012,8 +5178,8 @@ function writeDismissed(key) {
|
|
|
5012
5178
|
}
|
|
5013
5179
|
}
|
|
5014
5180
|
function useTargetBbox(ref) {
|
|
5015
|
-
const [bbox, setBbox] =
|
|
5016
|
-
|
|
5181
|
+
const [bbox, setBbox] = React29.useState(null);
|
|
5182
|
+
React29.useLayoutEffect(() => {
|
|
5017
5183
|
const el = ref?.current;
|
|
5018
5184
|
if (!el) {
|
|
5019
5185
|
setBbox(null);
|
|
@@ -5043,7 +5209,7 @@ function tooltipStyleFor(bbox, placement) {
|
|
|
5043
5209
|
return { left: bbox.left + bbox.width / 2, top: bbox.top - TOOLTIP_GAP, transform: "translate(-50%, -100%)", width: TOOLTIP_WIDTH };
|
|
5044
5210
|
}
|
|
5045
5211
|
function useFocusTrap(containerRef, active) {
|
|
5046
|
-
|
|
5212
|
+
React29.useEffect(() => {
|
|
5047
5213
|
if (!active) return;
|
|
5048
5214
|
const el = containerRef.current;
|
|
5049
5215
|
if (!el) return;
|
|
@@ -5082,16 +5248,16 @@ function Wizard({
|
|
|
5082
5248
|
onComplete,
|
|
5083
5249
|
onSkip
|
|
5084
5250
|
}) {
|
|
5085
|
-
const tooltipRef =
|
|
5086
|
-
const tooltipTitleId =
|
|
5087
|
-
const tooltipBodyId =
|
|
5251
|
+
const tooltipRef = React29.useRef(null);
|
|
5252
|
+
const tooltipTitleId = React29.useId();
|
|
5253
|
+
const tooltipBodyId = React29.useId();
|
|
5088
5254
|
const reduced = framerMotion.useReducedMotion();
|
|
5089
|
-
const [open, setOpen] =
|
|
5090
|
-
const [activeIndex, setActiveIndex] =
|
|
5255
|
+
const [open, setOpen] = React29.useState(() => steps.length > 0 && !readDismissed(storageKey));
|
|
5256
|
+
const [activeIndex, setActiveIndex] = React29.useState(0);
|
|
5091
5257
|
const step = steps[activeIndex];
|
|
5092
5258
|
const bbox = useTargetBbox(step?.stepRef);
|
|
5093
5259
|
useFocusTrap(tooltipRef, open);
|
|
5094
|
-
|
|
5260
|
+
React29.useEffect(() => {
|
|
5095
5261
|
if (!open || !dismissible) return;
|
|
5096
5262
|
const onKey = (e) => {
|
|
5097
5263
|
if (e.key === "Escape") {
|
|
@@ -5102,12 +5268,12 @@ function Wizard({
|
|
|
5102
5268
|
document.addEventListener("keydown", onKey);
|
|
5103
5269
|
return () => document.removeEventListener("keydown", onKey);
|
|
5104
5270
|
}, [open, dismissible]);
|
|
5105
|
-
const handleSkip =
|
|
5271
|
+
const handleSkip = React29.useCallback(() => {
|
|
5106
5272
|
writeDismissed(storageKey);
|
|
5107
5273
|
setOpen(false);
|
|
5108
5274
|
onSkip?.();
|
|
5109
5275
|
}, [storageKey, onSkip]);
|
|
5110
|
-
const handleComplete =
|
|
5276
|
+
const handleComplete = React29.useCallback(() => {
|
|
5111
5277
|
writeDismissed(storageKey);
|
|
5112
5278
|
setOpen(false);
|
|
5113
5279
|
onComplete?.();
|
|
@@ -5250,7 +5416,7 @@ function Wizard({
|
|
|
5250
5416
|
] });
|
|
5251
5417
|
}
|
|
5252
5418
|
var SearchIcon = /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "currentColor", className: "w-4 h-4", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("path", { fillRule: "evenodd", d: "M10.5 3.75a6.75 6.75 0 100 13.5 6.75 6.75 0 000-13.5zM2.25 10.5a8.25 8.25 0 1114.59 5.28l4.69 4.69a.75.75 0 11-1.06 1.06l-4.69-4.69A8.25 8.25 0 012.25 10.5z", clipRule: "evenodd" }) });
|
|
5253
|
-
var SearchInput =
|
|
5419
|
+
var SearchInput = React29__default.default.forwardRef(function SearchInput2({ value, onChange, disabled, label, htmlFor, placeholder, name, inputStyle, style, layout = "vertical", size = "md", icon, helperText, className }, ref) {
|
|
5254
5420
|
return /* @__PURE__ */ jsxRuntime.jsx(Field, { className, label, htmlFor, layout, helperText, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5255
5421
|
"div",
|
|
5256
5422
|
{
|
|
@@ -5434,7 +5600,7 @@ function TableBody({
|
|
|
5434
5600
|
expandRow,
|
|
5435
5601
|
getRowKey
|
|
5436
5602
|
}) {
|
|
5437
|
-
const [expanded, setExpanded] =
|
|
5603
|
+
const [expanded, setExpanded] = React29.useState(() => /* @__PURE__ */ new Set());
|
|
5438
5604
|
const reduced = framerMotion.useReducedMotion();
|
|
5439
5605
|
const toggleRow = (rowKey) => {
|
|
5440
5606
|
setExpanded((prev) => {
|
|
@@ -5449,7 +5615,7 @@ function TableBody({
|
|
|
5449
5615
|
return /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: rows.map((row, i) => {
|
|
5450
5616
|
const rowKey = getRowKey(row, i);
|
|
5451
5617
|
const isExpanded = expanded.has(rowKey);
|
|
5452
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
5618
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(React29__default.default.Fragment, { children: [
|
|
5453
5619
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5454
5620
|
"tr",
|
|
5455
5621
|
{
|
|
@@ -5505,9 +5671,9 @@ function Pagination({
|
|
|
5505
5671
|
const matchedOption = picker.find(
|
|
5506
5672
|
(o) => o.label === options.perPage || o.value === options.perPage
|
|
5507
5673
|
);
|
|
5508
|
-
const [perPageKey, setPerPageKey] =
|
|
5674
|
+
const [perPageKey, setPerPageKey] = React29.useState(() => matchedOption?.key ?? picker[0]?.key);
|
|
5509
5675
|
const displayPerPageKey = serverSide ? matchedOption?.key ?? perPageKey : perPageKey;
|
|
5510
|
-
|
|
5676
|
+
React29.useEffect(() => {
|
|
5511
5677
|
if (serverSide && options.perPage != null) {
|
|
5512
5678
|
const next = picker.find((o) => o.label === options.perPage || o.value === options.perPage);
|
|
5513
5679
|
if (next) setPerPageKey(next.key);
|
|
@@ -5570,14 +5736,14 @@ function Table({
|
|
|
5570
5736
|
className = "",
|
|
5571
5737
|
style
|
|
5572
5738
|
}) {
|
|
5573
|
-
const searchRef =
|
|
5574
|
-
const [searchTerm, setSearchTerm] =
|
|
5575
|
-
const [perPage, setPerPage] =
|
|
5739
|
+
const searchRef = React29.useRef(null);
|
|
5740
|
+
const [searchTerm, setSearchTerm] = React29.useState("");
|
|
5741
|
+
const [perPage, setPerPage] = React29.useState(
|
|
5576
5742
|
typeof pagination.perPage === "number" ? pagination.perPage : 15
|
|
5577
5743
|
);
|
|
5578
|
-
const [activePage, setActivePage] =
|
|
5744
|
+
const [activePage, setActivePage] = React29.useState(0);
|
|
5579
5745
|
const isServerSide = !!(pagination.enabled && pagination.serverSide);
|
|
5580
|
-
const filteredRows =
|
|
5746
|
+
const filteredRows = React29.useMemo(() => {
|
|
5581
5747
|
if (isServerSide || !searchTerm) return rows;
|
|
5582
5748
|
const term = searchTerm.toLowerCase();
|
|
5583
5749
|
return rows.filter(
|
|
@@ -5586,29 +5752,29 @@ function Table({
|
|
|
5586
5752
|
)
|
|
5587
5753
|
);
|
|
5588
5754
|
}, [rows, searchTerm, isServerSide]);
|
|
5589
|
-
const datasets =
|
|
5755
|
+
const datasets = React29.useMemo(() => {
|
|
5590
5756
|
if (isServerSide) return [rows];
|
|
5591
5757
|
return createDatasets(filteredRows, pagination.enabled ? perPage : null);
|
|
5592
5758
|
}, [filteredRows, perPage, pagination.enabled, isServerSide, rows]);
|
|
5593
|
-
const MAX_PAGE =
|
|
5759
|
+
const MAX_PAGE = React29.useMemo(() => {
|
|
5594
5760
|
if (isServerSide && typeof pagination.maxPage === "number") return Math.max(0, pagination.maxPage);
|
|
5595
5761
|
if (isServerSide && typeof pagination.totalCount === "number")
|
|
5596
5762
|
return Math.max(0, Math.ceil(pagination.totalCount / perPage) - 1);
|
|
5597
5763
|
return datasets.length ? datasets.length - 1 : 0;
|
|
5598
5764
|
}, [isServerSide, pagination.maxPage, pagination.totalCount, perPage, datasets.length]);
|
|
5599
|
-
const currentPageRows =
|
|
5765
|
+
const currentPageRows = React29.useMemo(() => {
|
|
5600
5766
|
if (isServerSide) return rows;
|
|
5601
5767
|
return datasets[activePage] ?? [];
|
|
5602
5768
|
}, [isServerSide, rows, datasets, activePage]);
|
|
5603
|
-
|
|
5769
|
+
React29.useEffect(() => {
|
|
5604
5770
|
if (pagination.enabled && !isServerSide && typeof pagination.perPage === "number") {
|
|
5605
5771
|
setPerPage(pagination.perPage);
|
|
5606
5772
|
}
|
|
5607
5773
|
}, [pagination.enabled, pagination.perPage, isServerSide]);
|
|
5608
|
-
|
|
5774
|
+
React29.useEffect(() => {
|
|
5609
5775
|
if (isServerSide && typeof pagination.perPage === "number") setPerPage(pagination.perPage);
|
|
5610
5776
|
}, [isServerSide, pagination.perPage]);
|
|
5611
|
-
|
|
5777
|
+
React29.useEffect(() => {
|
|
5612
5778
|
if (isServerSide && typeof pagination.page === "number" && pagination.page >= 1)
|
|
5613
5779
|
setActivePage(pagination.page - 1);
|
|
5614
5780
|
}, [isServerSide, pagination.page]);
|
|
@@ -5692,7 +5858,7 @@ function TableSkeletonBody({
|
|
|
5692
5858
|
)) });
|
|
5693
5859
|
}
|
|
5694
5860
|
function ThemeSwitch({ checked, onChange, label = "Toggle dark mode", className = "" }) {
|
|
5695
|
-
const id =
|
|
5861
|
+
const id = React29.useId();
|
|
5696
5862
|
return /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: id, className: `flex items-center gap-2 cursor-pointer select-none ${className}`.trim(), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5697
5863
|
SwitchPrimitive__namespace.Root,
|
|
5698
5864
|
{
|
|
@@ -5876,7 +6042,7 @@ function Sidebar({
|
|
|
5876
6042
|
}
|
|
5877
6043
|
) });
|
|
5878
6044
|
}
|
|
5879
|
-
var MegaMenuContext =
|
|
6045
|
+
var MegaMenuContext = React29.createContext({ align: "start" });
|
|
5880
6046
|
function MegaMenu({
|
|
5881
6047
|
children,
|
|
5882
6048
|
align = "start",
|
|
@@ -5907,7 +6073,7 @@ function MegaMenu({
|
|
|
5907
6073
|
}
|
|
5908
6074
|
var TOP_ITEM = "group/top inline-flex items-center gap-1.5 h-10 px-3 rounded-md text-sm font-medium select-none text-foreground-secondary hover:text-foreground hover:bg-surface-raised data-[state=open]:text-accent data-[active]:text-accent transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-accent";
|
|
5909
6075
|
function MegaMenuItem({ label, icon, href, children, className = "" }) {
|
|
5910
|
-
const { align } =
|
|
6076
|
+
const { align } = React29.useContext(MegaMenuContext);
|
|
5911
6077
|
const pos = align === "center" ? "left-1/2 -translate-x-1/2" : align === "end" ? "right-0" : "left-0";
|
|
5912
6078
|
if (!children) {
|
|
5913
6079
|
return /* @__PURE__ */ jsxRuntime.jsx(NavigationMenu__namespace.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs(NavigationMenu__namespace.Link, { href, className: [TOP_ITEM, className].filter(Boolean).join(" "), children: [
|
|
@@ -5992,8 +6158,8 @@ function MegaMenuLink({ href, icon, description, active, onClick, children, clas
|
|
|
5992
6158
|
function MegaMenuFeatured({ children, className = "" }) {
|
|
5993
6159
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: ["min-w-0 rounded-lg bg-surface-raised border border-border p-4 flex flex-col", className].filter(Boolean).join(" "), children });
|
|
5994
6160
|
}
|
|
5995
|
-
var elementsOfType = (children, type) =>
|
|
5996
|
-
(c) =>
|
|
6161
|
+
var elementsOfType = (children, type) => React29__default.default.Children.toArray(children).filter(
|
|
6162
|
+
(c) => React29__default.default.isValidElement(c) && c.type === type
|
|
5997
6163
|
);
|
|
5998
6164
|
var MOBILE_CHEVRON = /* @__PURE__ */ jsxRuntime.jsx(
|
|
5999
6165
|
"svg",
|
|
@@ -6030,9 +6196,9 @@ function MobileLinkRow({ link, onNavigate }) {
|
|
|
6030
6196
|
);
|
|
6031
6197
|
}
|
|
6032
6198
|
function MobilePanel({ panel, onNavigate }) {
|
|
6033
|
-
const nodes =
|
|
6199
|
+
const nodes = React29__default.default.Children.toArray(panel.props.children);
|
|
6034
6200
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-4 px-2 pb-3 pt-1", children: nodes.map((node, i) => {
|
|
6035
|
-
if (!
|
|
6201
|
+
if (!React29__default.default.isValidElement(node)) return null;
|
|
6036
6202
|
const el = node;
|
|
6037
6203
|
if (el.type === MegaMenuSection) {
|
|
6038
6204
|
const { title, children } = el.props;
|
|
@@ -6051,8 +6217,8 @@ function MegaMenuMobile({
|
|
|
6051
6217
|
children,
|
|
6052
6218
|
label
|
|
6053
6219
|
}) {
|
|
6054
|
-
const [open, setOpen] =
|
|
6055
|
-
const [expanded, setExpanded] =
|
|
6220
|
+
const [open, setOpen] = React29.useState(false);
|
|
6221
|
+
const [expanded, setExpanded] = React29.useState(null);
|
|
6056
6222
|
const items = elementsOfType(children, MegaMenuItem);
|
|
6057
6223
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "md:hidden w-full", children: [
|
|
6058
6224
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -6125,17 +6291,17 @@ function AppShell({
|
|
|
6125
6291
|
children,
|
|
6126
6292
|
className = ""
|
|
6127
6293
|
}) {
|
|
6128
|
-
const [expanded, setExpanded] =
|
|
6129
|
-
const [isMobile, setIsMobile] =
|
|
6130
|
-
const [mobileOpen, setMobileOpen] =
|
|
6131
|
-
|
|
6294
|
+
const [expanded, setExpanded] = React29.useState(sidebarDefaultExpanded);
|
|
6295
|
+
const [isMobile, setIsMobile] = React29.useState(false);
|
|
6296
|
+
const [mobileOpen, setMobileOpen] = React29.useState(false);
|
|
6297
|
+
React29.useEffect(() => {
|
|
6132
6298
|
const mq = window.matchMedia("(max-width: 767px)");
|
|
6133
6299
|
const update = (e) => setIsMobile(e.matches);
|
|
6134
6300
|
update(mq);
|
|
6135
6301
|
mq.addEventListener("change", update);
|
|
6136
6302
|
return () => mq.removeEventListener("change", update);
|
|
6137
6303
|
}, []);
|
|
6138
|
-
|
|
6304
|
+
React29.useEffect(() => {
|
|
6139
6305
|
if (!isMobile) setMobileOpen(false);
|
|
6140
6306
|
}, [isMobile]);
|
|
6141
6307
|
const hasSidebar = sidebarSections.length > 0;
|
|
@@ -6262,7 +6428,7 @@ function SecureLayout({
|
|
|
6262
6428
|
className = ""
|
|
6263
6429
|
}) {
|
|
6264
6430
|
const reduced = framerMotion.useReducedMotion();
|
|
6265
|
-
const cbs =
|
|
6431
|
+
const cbs = React29.useRef({ canAccess, onGranted, onDeny });
|
|
6266
6432
|
cbs.current = { canAccess, onGranted, onDeny };
|
|
6267
6433
|
const rolesKey = JSON.stringify(roles);
|
|
6268
6434
|
const requiredRolesKey = JSON.stringify(requiredRoles);
|
|
@@ -6277,10 +6443,10 @@ function SecureLayout({
|
|
|
6277
6443
|
if (requiredPermissions?.length && !has(permissions, requiredPermissions, requireAllPermissions)) return false;
|
|
6278
6444
|
return true;
|
|
6279
6445
|
};
|
|
6280
|
-
const [state, setState] =
|
|
6446
|
+
const [state, setState] = React29.useState(
|
|
6281
6447
|
() => !passesSync() ? "denied" : canAccess ? "checking" : "granted"
|
|
6282
6448
|
);
|
|
6283
|
-
|
|
6449
|
+
React29.useEffect(() => {
|
|
6284
6450
|
let cancelled = false;
|
|
6285
6451
|
const { canAccess: check, onGranted: granted, onDeny: deny } = cbs.current;
|
|
6286
6452
|
const finish = (ok) => {
|
|
@@ -6441,10 +6607,10 @@ function ThemeProvider({
|
|
|
6441
6607
|
className = "",
|
|
6442
6608
|
style
|
|
6443
6609
|
}) {
|
|
6444
|
-
const id =
|
|
6610
|
+
const id = React29__default.default.useId().replace(/:/g, "");
|
|
6445
6611
|
const scopeClass = `geo-th-${id}`;
|
|
6446
|
-
const divRef =
|
|
6447
|
-
|
|
6612
|
+
const divRef = React29.useRef(null);
|
|
6613
|
+
React29.useEffect(() => {
|
|
6448
6614
|
const el = divRef.current;
|
|
6449
6615
|
if (!el) return;
|
|
6450
6616
|
if (colorScheme === "auto") return;
|
|
@@ -6459,8 +6625,8 @@ function ThemeProvider({
|
|
|
6459
6625
|
}
|
|
6460
6626
|
el.classList.toggle("dark", colorScheme === "dark");
|
|
6461
6627
|
}, [colorScheme]);
|
|
6462
|
-
const lightVars =
|
|
6463
|
-
const darkVarStr =
|
|
6628
|
+
const lightVars = React29.useMemo(() => toCssVars(theme), [theme]);
|
|
6629
|
+
const darkVarStr = React29.useMemo(() => {
|
|
6464
6630
|
if (!darkTheme) return "";
|
|
6465
6631
|
const dvars = toCssVars(darkTheme);
|
|
6466
6632
|
if (!Object.keys(dvars).length) return "";
|
|
@@ -6502,7 +6668,7 @@ function NumberInput({
|
|
|
6502
6668
|
readOnly = false,
|
|
6503
6669
|
precision
|
|
6504
6670
|
}) {
|
|
6505
|
-
const errorId =
|
|
6671
|
+
const errorId = React29.useId();
|
|
6506
6672
|
const hasError = errorMessage != null;
|
|
6507
6673
|
const inferredPrecision = precision ?? (Number.isInteger(step) ? 0 : String(step).split(".")[1]?.length ?? 0);
|
|
6508
6674
|
const round = (n) => {
|
|
@@ -6633,8 +6799,8 @@ function Password({
|
|
|
6633
6799
|
showIcon,
|
|
6634
6800
|
hideIcon
|
|
6635
6801
|
}) {
|
|
6636
|
-
const [visible, setVisible] =
|
|
6637
|
-
const errorId =
|
|
6802
|
+
const [visible, setVisible] = React29.useState(false);
|
|
6803
|
+
const errorId = React29.useId();
|
|
6638
6804
|
const hasError = errorMessage != null;
|
|
6639
6805
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
6640
6806
|
Field,
|
|
@@ -6707,7 +6873,7 @@ function Checkbox({
|
|
|
6707
6873
|
}) {
|
|
6708
6874
|
const isChecked = checked ?? value ?? false;
|
|
6709
6875
|
const labelFirst = labelPosition === "left";
|
|
6710
|
-
const errorId =
|
|
6876
|
+
const errorId = React29.useId();
|
|
6711
6877
|
const hasError = errorMessage != null;
|
|
6712
6878
|
const box = /* @__PURE__ */ jsxRuntime.jsx(
|
|
6713
6879
|
CheckboxPrimitive__namespace.Root,
|
|
@@ -6815,8 +6981,8 @@ function RadioGroup({
|
|
|
6815
6981
|
className,
|
|
6816
6982
|
errorMessage
|
|
6817
6983
|
}) {
|
|
6818
|
-
const errorId =
|
|
6819
|
-
const groupId =
|
|
6984
|
+
const errorId = React29.useId();
|
|
6985
|
+
const groupId = React29.useId();
|
|
6820
6986
|
const hasError = errorMessage != null;
|
|
6821
6987
|
const labelFirst = labelPosition === "left";
|
|
6822
6988
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -6916,11 +7082,11 @@ function Switch({
|
|
|
6916
7082
|
disabled,
|
|
6917
7083
|
errorMessage
|
|
6918
7084
|
}) {
|
|
6919
|
-
const id =
|
|
6920
|
-
const errorId =
|
|
7085
|
+
const id = React29.useId();
|
|
7086
|
+
const errorId = React29.useId();
|
|
6921
7087
|
const hasError = errorMessage != null;
|
|
6922
7088
|
const isControlled = checked !== void 0;
|
|
6923
|
-
const [internal, setInternal] =
|
|
7089
|
+
const [internal, setInternal] = React29.useState(defaultChecked);
|
|
6924
7090
|
const isOn = isControlled ? checked : internal;
|
|
6925
7091
|
const handle = (c) => {
|
|
6926
7092
|
if (!isControlled) setInternal(c);
|
|
@@ -6996,11 +7162,11 @@ function MultiTagRow({
|
|
|
6996
7162
|
labelFor,
|
|
6997
7163
|
onRemove
|
|
6998
7164
|
}) {
|
|
6999
|
-
const wrapRef =
|
|
7000
|
-
const measureRef =
|
|
7001
|
-
const [visibleCount, setVisibleCount] =
|
|
7165
|
+
const wrapRef = React29.useRef(null);
|
|
7166
|
+
const measureRef = React29.useRef(null);
|
|
7167
|
+
const [visibleCount, setVisibleCount] = React29.useState(values.length);
|
|
7002
7168
|
const key = values.map(String).join("|");
|
|
7003
|
-
|
|
7169
|
+
React29.useLayoutEffect(() => {
|
|
7004
7170
|
const wrap = wrapRef.current;
|
|
7005
7171
|
const measure = measureRef.current;
|
|
7006
7172
|
if (!wrap || !measure) return;
|
|
@@ -7094,16 +7260,16 @@ function Dropdown({
|
|
|
7094
7260
|
size = "md",
|
|
7095
7261
|
className = ""
|
|
7096
7262
|
}) {
|
|
7097
|
-
const [open, setOpen] =
|
|
7098
|
-
const [selectedItems, setSelectedItems] =
|
|
7099
|
-
const [searchTerm, setSearchTerm] =
|
|
7100
|
-
const [innerItems, setInnerItems] =
|
|
7101
|
-
const errorId =
|
|
7263
|
+
const [open, setOpen] = React29.useState(false);
|
|
7264
|
+
const [selectedItems, setSelectedItems] = React29.useState([]);
|
|
7265
|
+
const [searchTerm, setSearchTerm] = React29.useState("");
|
|
7266
|
+
const [innerItems, setInnerItems] = React29.useState([]);
|
|
7267
|
+
const errorId = React29.useId();
|
|
7102
7268
|
const hasError = errorMessage != null;
|
|
7103
|
-
|
|
7269
|
+
React29.useEffect(() => {
|
|
7104
7270
|
setInnerItems(items);
|
|
7105
7271
|
}, [items]);
|
|
7106
|
-
|
|
7272
|
+
React29.useEffect(() => {
|
|
7107
7273
|
if (isMultiselect && Array.isArray(value)) {
|
|
7108
7274
|
setSelectedItems(value);
|
|
7109
7275
|
}
|
|
@@ -7295,19 +7461,19 @@ function AutoComplete({
|
|
|
7295
7461
|
required,
|
|
7296
7462
|
htmlFor
|
|
7297
7463
|
}) {
|
|
7298
|
-
const errorId =
|
|
7464
|
+
const errorId = React29.useId();
|
|
7299
7465
|
const hasError = errorMessage != null;
|
|
7300
|
-
const [term, setTerm] =
|
|
7301
|
-
const [open, setOpen] =
|
|
7302
|
-
const [asyncItems, setAsyncItems] =
|
|
7303
|
-
const [loading, setLoading] =
|
|
7466
|
+
const [term, setTerm] = React29.useState("");
|
|
7467
|
+
const [open, setOpen] = React29.useState(false);
|
|
7468
|
+
const [asyncItems, setAsyncItems] = React29.useState([]);
|
|
7469
|
+
const [loading, setLoading] = React29.useState(false);
|
|
7304
7470
|
const isAsync = typeof onSearch === "function";
|
|
7305
|
-
const debounceRef =
|
|
7306
|
-
const requestIdRef =
|
|
7471
|
+
const debounceRef = React29.useRef(null);
|
|
7472
|
+
const requestIdRef = React29.useRef(0);
|
|
7307
7473
|
const staticFiltered = isAsync || !items ? [] : term.trim() ? items.filter(
|
|
7308
7474
|
({ key, label: label2 }) => label2.toLowerCase().includes(term.toLowerCase()) || key.toLowerCase().includes(term.toLowerCase())
|
|
7309
7475
|
) : [];
|
|
7310
|
-
|
|
7476
|
+
React29.useEffect(() => {
|
|
7311
7477
|
if (!isAsync) return;
|
|
7312
7478
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
7313
7479
|
if (!term.trim()) {
|
|
@@ -7463,15 +7629,15 @@ function TreeSelect({
|
|
|
7463
7629
|
defaultExpandedKeys = [],
|
|
7464
7630
|
size = "md"
|
|
7465
7631
|
}) {
|
|
7466
|
-
const errorId =
|
|
7632
|
+
const errorId = React29.useId();
|
|
7467
7633
|
const hasError = errorMessage != null;
|
|
7468
|
-
const [open, setOpen] =
|
|
7469
|
-
const [expanded, setExpanded] =
|
|
7470
|
-
const [activeIndex, setActiveIndex] =
|
|
7471
|
-
const listRef =
|
|
7472
|
-
const visible =
|
|
7473
|
-
const didSyncOnOpenRef =
|
|
7474
|
-
|
|
7634
|
+
const [open, setOpen] = React29.useState(false);
|
|
7635
|
+
const [expanded, setExpanded] = React29.useState(() => new Set(defaultExpandedKeys));
|
|
7636
|
+
const [activeIndex, setActiveIndex] = React29.useState(0);
|
|
7637
|
+
const listRef = React29.useRef(null);
|
|
7638
|
+
const visible = React29.useMemo(() => flattenVisible(items, expanded), [items, expanded]);
|
|
7639
|
+
const didSyncOnOpenRef = React29.useRef(false);
|
|
7640
|
+
React29.useEffect(() => {
|
|
7475
7641
|
if (!open) {
|
|
7476
7642
|
didSyncOnOpenRef.current = false;
|
|
7477
7643
|
return;
|
|
@@ -7481,7 +7647,7 @@ function TreeSelect({
|
|
|
7481
7647
|
setActiveIndex(selectedIdx >= 0 ? selectedIdx : 0);
|
|
7482
7648
|
didSyncOnOpenRef.current = true;
|
|
7483
7649
|
}, [open, value]);
|
|
7484
|
-
const selectedNode =
|
|
7650
|
+
const selectedNode = React29.useMemo(
|
|
7485
7651
|
() => value != null ? findNodeByKey(items, value) : null,
|
|
7486
7652
|
[items, value]
|
|
7487
7653
|
);
|
|
@@ -7712,11 +7878,11 @@ function FileInput({
|
|
|
7712
7878
|
required,
|
|
7713
7879
|
icon
|
|
7714
7880
|
}) {
|
|
7715
|
-
const inputRef =
|
|
7716
|
-
const errorId =
|
|
7717
|
-
const [files, setFiles] =
|
|
7718
|
-
const [dragging, setDragging] =
|
|
7719
|
-
const [sizeError, setSizeError] =
|
|
7881
|
+
const inputRef = React29.useRef(null);
|
|
7882
|
+
const errorId = React29.useId();
|
|
7883
|
+
const [files, setFiles] = React29.useState([]);
|
|
7884
|
+
const [dragging, setDragging] = React29.useState(false);
|
|
7885
|
+
const [sizeError, setSizeError] = React29.useState(null);
|
|
7720
7886
|
const effectiveError = errorMessage ?? sizeError ?? void 0;
|
|
7721
7887
|
const openPicker = () => {
|
|
7722
7888
|
if (!disabled) inputRef.current?.click();
|
|
@@ -7907,30 +8073,30 @@ function DatePicker({
|
|
|
7907
8073
|
size = "md",
|
|
7908
8074
|
className = ""
|
|
7909
8075
|
}) {
|
|
7910
|
-
const errorId =
|
|
8076
|
+
const errorId = React29.useId();
|
|
7911
8077
|
const hasError = errorMessage != null;
|
|
7912
|
-
const [open, setOpen] =
|
|
7913
|
-
const [viewMonth, setViewMonth] =
|
|
7914
|
-
const [focusDate, setFocusDate] =
|
|
7915
|
-
const [view, setView] =
|
|
7916
|
-
const gridRef =
|
|
7917
|
-
|
|
8078
|
+
const [open, setOpen] = React29.useState(false);
|
|
8079
|
+
const [viewMonth, setViewMonth] = React29.useState(() => startOfMonth2(value ?? /* @__PURE__ */ new Date()));
|
|
8080
|
+
const [focusDate, setFocusDate] = React29.useState(() => value ?? /* @__PURE__ */ new Date());
|
|
8081
|
+
const [view, setView] = React29.useState("days");
|
|
8082
|
+
const gridRef = React29.useRef(null);
|
|
8083
|
+
React29.useEffect(() => {
|
|
7918
8084
|
if (!open) return;
|
|
7919
8085
|
const target = value ?? /* @__PURE__ */ new Date();
|
|
7920
8086
|
setViewMonth(startOfMonth2(target));
|
|
7921
8087
|
setFocusDate(target);
|
|
7922
8088
|
setView("days");
|
|
7923
8089
|
}, [open, value]);
|
|
7924
|
-
|
|
8090
|
+
React29.useEffect(() => {
|
|
7925
8091
|
if (!open) return;
|
|
7926
8092
|
const cell = gridRef.current?.querySelector(`[data-day="${defaultFormat3(focusDate)}"]`);
|
|
7927
8093
|
cell?.focus();
|
|
7928
8094
|
}, [open, focusDate]);
|
|
7929
|
-
const weekdays =
|
|
8095
|
+
const weekdays = React29.useMemo(() => {
|
|
7930
8096
|
const ordered = WEEKDAY_SHORT.slice(weekStartsOn).concat(WEEKDAY_SHORT.slice(0, weekStartsOn));
|
|
7931
8097
|
return ordered;
|
|
7932
8098
|
}, [weekStartsOn]);
|
|
7933
|
-
const grid =
|
|
8099
|
+
const grid = React29.useMemo(() => buildGrid2(viewMonth, weekStartsOn), [viewMonth, weekStartsOn]);
|
|
7934
8100
|
const isDisabled = (d) => {
|
|
7935
8101
|
if (min && d < min) return true;
|
|
7936
8102
|
if (max && d > max) return true;
|
|
@@ -8220,10 +8386,10 @@ function TextArea({
|
|
|
8220
8386
|
style,
|
|
8221
8387
|
inputStyle
|
|
8222
8388
|
}) {
|
|
8223
|
-
const errorId =
|
|
8389
|
+
const errorId = React29.useId();
|
|
8224
8390
|
const hasError = errorMessage != null;
|
|
8225
|
-
const ref =
|
|
8226
|
-
|
|
8391
|
+
const ref = React29.useRef(null);
|
|
8392
|
+
React29.useLayoutEffect(() => {
|
|
8227
8393
|
if (!autoGrow) return;
|
|
8228
8394
|
const el = ref.current;
|
|
8229
8395
|
if (!el) return;
|
|
@@ -8295,14 +8461,14 @@ function Slider({
|
|
|
8295
8461
|
name,
|
|
8296
8462
|
htmlFor
|
|
8297
8463
|
}) {
|
|
8298
|
-
const errorId =
|
|
8464
|
+
const errorId = React29.useId();
|
|
8299
8465
|
const hasError = errorMessage != null;
|
|
8300
8466
|
const isRange = Array.isArray(value ?? defaultValue);
|
|
8301
|
-
const [internal, setInternal] =
|
|
8467
|
+
const [internal, setInternal] = React29.useState(
|
|
8302
8468
|
() => toArray(value) ?? toArray(defaultValue) ?? [min]
|
|
8303
8469
|
);
|
|
8304
8470
|
const current = toArray(value) ?? internal;
|
|
8305
|
-
const [dragging, setDragging] =
|
|
8471
|
+
const [dragging, setDragging] = React29.useState(false);
|
|
8306
8472
|
const emit = (arr) => {
|
|
8307
8473
|
setInternal(arr);
|
|
8308
8474
|
const next = isRange ? [arr[0], arr[1]] : arr[0];
|
|
@@ -8397,11 +8563,11 @@ function TagsInput({
|
|
|
8397
8563
|
validate,
|
|
8398
8564
|
separators = ["Enter", ","]
|
|
8399
8565
|
}) {
|
|
8400
|
-
const errorId =
|
|
8401
|
-
const inputRef =
|
|
8402
|
-
const [internal, setInternal] =
|
|
8403
|
-
const [draft, setDraft] =
|
|
8404
|
-
const [localError, setLocalError] =
|
|
8566
|
+
const errorId = React29.useId();
|
|
8567
|
+
const inputRef = React29.useRef(null);
|
|
8568
|
+
const [internal, setInternal] = React29.useState(defaultValue ?? []);
|
|
8569
|
+
const [draft, setDraft] = React29.useState("");
|
|
8570
|
+
const [localError, setLocalError] = React29.useState(null);
|
|
8405
8571
|
const tags = value ?? internal;
|
|
8406
8572
|
const hasError = errorMessage != null || localError != null;
|
|
8407
8573
|
const errorText = errorMessage ?? localError ?? void 0;
|
|
@@ -8532,9 +8698,9 @@ function OtpInput({
|
|
|
8532
8698
|
className,
|
|
8533
8699
|
groupAfter
|
|
8534
8700
|
}) {
|
|
8535
|
-
const errorId =
|
|
8701
|
+
const errorId = React29.useId();
|
|
8536
8702
|
const hasError = errorMessage != null;
|
|
8537
|
-
const refs =
|
|
8703
|
+
const refs = React29.useRef([]);
|
|
8538
8704
|
const chars = Array.from({ length }, (_, i) => value[i] ?? "");
|
|
8539
8705
|
const pattern = mode === "numeric" ? /[0-9]/ : /[a-zA-Z0-9]/;
|
|
8540
8706
|
const emit = (next) => {
|
|
@@ -8583,7 +8749,7 @@ function OtpInput({
|
|
|
8583
8749
|
emit(valid.join(""));
|
|
8584
8750
|
focusBox(valid.length);
|
|
8585
8751
|
};
|
|
8586
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Field, { className, label, htmlFor, errorId, errorMessage, required, layout, helperText, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": typeof label === "string" ? label : "One-time code", children: chars.map((char, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8752
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Field, { className, label, htmlFor, errorId, errorMessage, required, layout, helperText, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap items-center gap-2", role: "group", "aria-label": typeof label === "string" ? label : "One-time code", children: chars.map((char, idx) => /* @__PURE__ */ jsxRuntime.jsxs(React29__default.default.Fragment, { children: [
|
|
8587
8753
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8588
8754
|
"input",
|
|
8589
8755
|
{
|
|
@@ -8641,9 +8807,9 @@ function Rating({
|
|
|
8641
8807
|
className,
|
|
8642
8808
|
required
|
|
8643
8809
|
}) {
|
|
8644
|
-
const errorId =
|
|
8645
|
-
const [internal, setInternal] =
|
|
8646
|
-
const [hover, setHover] =
|
|
8810
|
+
const errorId = React29.useId();
|
|
8811
|
+
const [internal, setInternal] = React29.useState(defaultValue);
|
|
8812
|
+
const [hover, setHover] = React29.useState(null);
|
|
8647
8813
|
const current = value ?? internal;
|
|
8648
8814
|
const display2 = hover ?? current;
|
|
8649
8815
|
const interactive = !readOnly && !disabled;
|
|
@@ -8766,9 +8932,9 @@ function TimePicker({
|
|
|
8766
8932
|
required,
|
|
8767
8933
|
style
|
|
8768
8934
|
}) {
|
|
8769
|
-
const errorId =
|
|
8935
|
+
const errorId = React29.useId();
|
|
8770
8936
|
const hasError = errorMessage != null;
|
|
8771
|
-
const [open, setOpen] =
|
|
8937
|
+
const [open, setOpen] = React29.useState(false);
|
|
8772
8938
|
const parsed = parse(value) ?? { h: 0, m: 0, s: 0 };
|
|
8773
8939
|
const update = (next) => {
|
|
8774
8940
|
const merged = { ...parsed, ...next };
|
|
@@ -8892,13 +9058,13 @@ function DateRangePicker({
|
|
|
8892
9058
|
required,
|
|
8893
9059
|
style
|
|
8894
9060
|
}) {
|
|
8895
|
-
const errorId =
|
|
9061
|
+
const errorId = React29.useId();
|
|
8896
9062
|
const hasError = errorMessage != null;
|
|
8897
|
-
const [open, setOpen] =
|
|
8898
|
-
const [leftMonth, setLeftMonth] =
|
|
8899
|
-
const [pendingStart, setPendingStart] =
|
|
8900
|
-
const [hoverDate, setHoverDate] =
|
|
8901
|
-
const weekdays =
|
|
9063
|
+
const [open, setOpen] = React29.useState(false);
|
|
9064
|
+
const [leftMonth, setLeftMonth] = React29.useState(() => startOfMonth3(value.start ?? /* @__PURE__ */ new Date()));
|
|
9065
|
+
const [pendingStart, setPendingStart] = React29.useState(null);
|
|
9066
|
+
const [hoverDate, setHoverDate] = React29.useState(null);
|
|
9067
|
+
const weekdays = React29.useMemo(
|
|
8902
9068
|
() => WEEKDAY.slice(weekStartsOn).concat(WEEKDAY.slice(0, weekStartsOn)),
|
|
8903
9069
|
[weekStartsOn]
|
|
8904
9070
|
);
|
|
@@ -9074,10 +9240,10 @@ function ColorPicker({
|
|
|
9074
9240
|
required,
|
|
9075
9241
|
placeholder = "Pick a colour\u2026"
|
|
9076
9242
|
}) {
|
|
9077
|
-
const errorId =
|
|
9243
|
+
const errorId = React29.useId();
|
|
9078
9244
|
const hasError = errorMessage != null;
|
|
9079
|
-
const [open, setOpen] =
|
|
9080
|
-
const [draft, setDraft] =
|
|
9245
|
+
const [open, setOpen] = React29.useState(false);
|
|
9246
|
+
const [draft, setDraft] = React29.useState(value);
|
|
9081
9247
|
const valid = HEX_RE.test(value);
|
|
9082
9248
|
const pick = (hex) => {
|
|
9083
9249
|
onChange?.(hex);
|
|
@@ -9164,7 +9330,7 @@ function ColorPicker({
|
|
|
9164
9330
|
}
|
|
9165
9331
|
var CUSTOM_EVENT = "oxy-local-storage";
|
|
9166
9332
|
function useLocalStorage(key, initialValue) {
|
|
9167
|
-
const read =
|
|
9333
|
+
const read = React29.useCallback(() => {
|
|
9168
9334
|
if (typeof window === "undefined") return initialValue;
|
|
9169
9335
|
try {
|
|
9170
9336
|
const item = window.localStorage.getItem(key);
|
|
@@ -9173,8 +9339,8 @@ function useLocalStorage(key, initialValue) {
|
|
|
9173
9339
|
return initialValue;
|
|
9174
9340
|
}
|
|
9175
9341
|
}, [key]);
|
|
9176
|
-
const [stored, setStored] =
|
|
9177
|
-
const setValue =
|
|
9342
|
+
const [stored, setStored] = React29.useState(read);
|
|
9343
|
+
const setValue = React29.useCallback((value) => {
|
|
9178
9344
|
setStored((prev) => {
|
|
9179
9345
|
const next = value instanceof Function ? value(prev) : value;
|
|
9180
9346
|
try {
|
|
@@ -9187,7 +9353,7 @@ function useLocalStorage(key, initialValue) {
|
|
|
9187
9353
|
return next;
|
|
9188
9354
|
});
|
|
9189
9355
|
}, [key]);
|
|
9190
|
-
const remove =
|
|
9356
|
+
const remove = React29.useCallback(() => {
|
|
9191
9357
|
try {
|
|
9192
9358
|
if (typeof window !== "undefined") {
|
|
9193
9359
|
window.localStorage.removeItem(key);
|
|
@@ -9197,10 +9363,10 @@ function useLocalStorage(key, initialValue) {
|
|
|
9197
9363
|
}
|
|
9198
9364
|
setStored(initialValue);
|
|
9199
9365
|
}, [key]);
|
|
9200
|
-
|
|
9366
|
+
React29.useEffect(() => {
|
|
9201
9367
|
setStored(read());
|
|
9202
9368
|
}, [key, read]);
|
|
9203
|
-
|
|
9369
|
+
React29.useEffect(() => {
|
|
9204
9370
|
if (typeof window === "undefined") return;
|
|
9205
9371
|
const onStorage = (e) => {
|
|
9206
9372
|
if (e.key === null || e.key === key) setStored(read());
|
|
@@ -9219,8 +9385,8 @@ function useLocalStorage(key, initialValue) {
|
|
|
9219
9385
|
}
|
|
9220
9386
|
function useMediaQuery(query) {
|
|
9221
9387
|
const get = () => typeof window !== "undefined" && typeof window.matchMedia === "function" ? window.matchMedia(query).matches : false;
|
|
9222
|
-
const [matches, setMatches] =
|
|
9223
|
-
|
|
9388
|
+
const [matches, setMatches] = React29.useState(get);
|
|
9389
|
+
React29.useEffect(() => {
|
|
9224
9390
|
if (typeof window === "undefined" || typeof window.matchMedia !== "function") return;
|
|
9225
9391
|
const mql = window.matchMedia(query);
|
|
9226
9392
|
const onChange = () => setMatches(mql.matches);
|
|
@@ -9251,8 +9417,8 @@ function decodeSegment(seg) {
|
|
|
9251
9417
|
}
|
|
9252
9418
|
}
|
|
9253
9419
|
function useJwt(token) {
|
|
9254
|
-
const [, tick] =
|
|
9255
|
-
const decoded =
|
|
9420
|
+
const [, tick] = React29.useState(0);
|
|
9421
|
+
const decoded = React29.useMemo(() => {
|
|
9256
9422
|
if (!token) return { payload: null, header: null, exp: null };
|
|
9257
9423
|
const [h, p] = token.split(".");
|
|
9258
9424
|
const header = decodeSegment(h);
|
|
@@ -9260,7 +9426,7 @@ function useJwt(token) {
|
|
|
9260
9426
|
const exp = payload && typeof payload.exp === "number" ? payload.exp : null;
|
|
9261
9427
|
return { payload, header, exp };
|
|
9262
9428
|
}, [token]);
|
|
9263
|
-
|
|
9429
|
+
React29.useEffect(() => {
|
|
9264
9430
|
if (decoded.exp == null) return;
|
|
9265
9431
|
const ms = decoded.exp * 1e3 - Date.now();
|
|
9266
9432
|
if (ms <= 0) return;
|
|
@@ -9307,6 +9473,7 @@ exports.CartProvider = CartProvider;
|
|
|
9307
9473
|
exports.Catalog = Catalog;
|
|
9308
9474
|
exports.CatalogCarousel = CatalogCarousel;
|
|
9309
9475
|
exports.CatalogGrid = CatalogGrid;
|
|
9476
|
+
exports.Chat = Chat;
|
|
9310
9477
|
exports.Checkbox = Checkbox;
|
|
9311
9478
|
exports.Checkout = Checkout;
|
|
9312
9479
|
exports.ColorPicker = ColorPicker;
|