@geomak/ui 6.28.0 → 6.29.1
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 +340 -293
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +63 -44
- package/dist/index.d.ts +63 -44
- package/dist/index.js +341 -294
- package/dist/index.js.map +1 -1
- package/dist/styles.css +48 -6
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -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
|
})();
|
|
@@ -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 = React28.useRef(null);
|
|
2325
|
+
const atBottomRef = React28.useRef(true);
|
|
2326
|
+
const [showJump, setShowJump] = React28.useState(false);
|
|
2327
|
+
const [draft, setDraft] = React28.useState("");
|
|
2328
|
+
const taRef = React28.useRef(null);
|
|
2329
|
+
const hasHeader = title != null || subtitle != null || avatar != null || headerActions != null;
|
|
2330
|
+
const isTyping = typingNames.length > 0;
|
|
2331
|
+
const scrollToBottom = React28.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
|
+
React28.useEffect(() => {
|
|
2345
|
+
if (atBottomRef.current) scrollToBottom(messages.length > 0);
|
|
2346
|
+
}, [messages.length, isTyping]);
|
|
2347
|
+
React28.useEffect(() => {
|
|
2348
|
+
scrollToBottom(false);
|
|
2349
|
+
}, [scrollToBottom]);
|
|
2350
|
+
React28.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
|
] }),
|
|
@@ -2529,253 +2823,6 @@ function LogoutTimer({
|
|
|
2529
2823
|
] })
|
|
2530
2824
|
] }) });
|
|
2531
2825
|
}
|
|
2532
|
-
var WEEKDAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
2533
|
-
var MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
2534
|
-
var startOfDay = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
2535
|
-
var sameDay = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
2536
|
-
var addMonths = (d, n) => new Date(d.getFullYear(), d.getMonth() + n, 1);
|
|
2537
|
-
function buildGrid(month, weekStartsOn) {
|
|
2538
|
-
const first = new Date(month.getFullYear(), month.getMonth(), 1);
|
|
2539
|
-
const offset = (first.getDay() - weekStartsOn + 7) % 7;
|
|
2540
|
-
const start = new Date(first);
|
|
2541
|
-
start.setDate(first.getDate() - offset);
|
|
2542
|
-
return Array.from({ length: 42 }, (_, i) => {
|
|
2543
|
-
const d = new Date(start);
|
|
2544
|
-
d.setDate(start.getDate() + i);
|
|
2545
|
-
return d;
|
|
2546
|
-
});
|
|
2547
|
-
}
|
|
2548
|
-
var NavIcon = ({ dir }) => /* @__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: dir === "left" ? "M15 19l-7-7 7-7" : "M9 5l7 7-7 7" }) });
|
|
2549
|
-
function Calendar2({
|
|
2550
|
-
value,
|
|
2551
|
-
onChange,
|
|
2552
|
-
month,
|
|
2553
|
-
defaultMonth,
|
|
2554
|
-
onMonthChange,
|
|
2555
|
-
events,
|
|
2556
|
-
min,
|
|
2557
|
-
max,
|
|
2558
|
-
weekStartsOn = 0,
|
|
2559
|
-
className = "",
|
|
2560
|
-
style
|
|
2561
|
-
}) {
|
|
2562
|
-
const today = React28.useMemo(() => startOfDay(/* @__PURE__ */ new Date()), []);
|
|
2563
|
-
const [internalMonth, setInternalMonth] = React28.useState(() => month ?? defaultMonth ?? value ?? today);
|
|
2564
|
-
const visible = month ?? internalMonth;
|
|
2565
|
-
const setMonth = (next) => {
|
|
2566
|
-
onMonthChange?.(next);
|
|
2567
|
-
if (month === void 0) setInternalMonth(next);
|
|
2568
|
-
};
|
|
2569
|
-
const grid = React28.useMemo(() => buildGrid(visible, weekStartsOn), [visible, weekStartsOn]);
|
|
2570
|
-
const weekdays = React28.useMemo(() => Array.from({ length: 7 }, (_, i) => WEEKDAYS[(i + weekStartsOn) % 7]), [weekStartsOn]);
|
|
2571
|
-
const eventsByDay = React28.useMemo(() => {
|
|
2572
|
-
const map = /* @__PURE__ */ new Map();
|
|
2573
|
-
for (const ev of events ?? []) {
|
|
2574
|
-
const key = startOfDay(ev.date).toDateString();
|
|
2575
|
-
const arr = map.get(key) ?? [];
|
|
2576
|
-
arr.push(ev);
|
|
2577
|
-
map.set(key, arr);
|
|
2578
|
-
}
|
|
2579
|
-
return map;
|
|
2580
|
-
}, [events]);
|
|
2581
|
-
const disabled = (d) => min && d < startOfDay(min) || max && d > startOfDay(max);
|
|
2582
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: ["inline-block rounded-lg border border-border bg-surface p-3 select-none", className].filter(Boolean).join(" "), style, children: [
|
|
2583
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-2 flex items-center justify-between px-1", children: [
|
|
2584
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2585
|
-
"button",
|
|
2586
|
-
{
|
|
2587
|
-
type: "button",
|
|
2588
|
-
"aria-label": "Previous month",
|
|
2589
|
-
onClick: () => setMonth(addMonths(visible, -1)),
|
|
2590
|
-
className: "flex h-7 w-7 items-center justify-center rounded-md text-foreground-secondary hover:bg-surface-raised hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
2591
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(NavIcon, { dir: "left" })
|
|
2592
|
-
}
|
|
2593
|
-
),
|
|
2594
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm font-semibold text-foreground", "aria-live": "polite", children: [
|
|
2595
|
-
MONTHS[visible.getMonth()],
|
|
2596
|
-
" ",
|
|
2597
|
-
visible.getFullYear()
|
|
2598
|
-
] }),
|
|
2599
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2600
|
-
"button",
|
|
2601
|
-
{
|
|
2602
|
-
type: "button",
|
|
2603
|
-
"aria-label": "Next month",
|
|
2604
|
-
onClick: () => setMonth(addMonths(visible, 1)),
|
|
2605
|
-
className: "flex h-7 w-7 items-center justify-center rounded-md text-foreground-secondary hover:bg-surface-raised hover:text-foreground focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
2606
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(NavIcon, { dir: "right" })
|
|
2607
|
-
}
|
|
2608
|
-
)
|
|
2609
|
-
] }),
|
|
2610
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-7 mb-1", children: weekdays.map((w) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-center text-[11px] font-medium uppercase tracking-wide text-foreground-muted py-1", children: w }, w)) }),
|
|
2611
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-7 gap-0.5", role: "grid", children: grid.map((d, i) => {
|
|
2612
|
-
const inMonth = d.getMonth() === visible.getMonth();
|
|
2613
|
-
const isSelected = value != null && sameDay(d, value);
|
|
2614
|
-
const isToday2 = sameDay(d, today);
|
|
2615
|
-
const isDisabled = disabled(d);
|
|
2616
|
-
const dayEvents = eventsByDay.get(d.toDateString()) ?? [];
|
|
2617
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2618
|
-
"button",
|
|
2619
|
-
{
|
|
2620
|
-
type: "button",
|
|
2621
|
-
role: "gridcell",
|
|
2622
|
-
"aria-selected": isSelected,
|
|
2623
|
-
"aria-current": isToday2 ? "date" : void 0,
|
|
2624
|
-
disabled: isDisabled,
|
|
2625
|
-
onClick: () => onChange?.(startOfDay(d)),
|
|
2626
|
-
className: [
|
|
2627
|
-
"relative flex h-9 w-9 flex-col items-center justify-center rounded-md text-sm transition-colors",
|
|
2628
|
-
"focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
2629
|
-
isSelected ? "bg-accent text-accent-fg font-semibold" : inMonth ? "text-foreground hover:bg-surface-raised" : "text-foreground-muted hover:bg-surface-raised",
|
|
2630
|
-
isDisabled ? "opacity-40 cursor-not-allowed hover:bg-transparent" : "",
|
|
2631
|
-
!isSelected && isToday2 ? "ring-1 ring-inset ring-accent/60" : ""
|
|
2632
|
-
].filter(Boolean).join(" "),
|
|
2633
|
-
children: [
|
|
2634
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "leading-none", children: d.getDate() }),
|
|
2635
|
-
dayEvents.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute bottom-1 flex gap-0.5", children: dayEvents.slice(0, 3).map((ev, j) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
2636
|
-
"span",
|
|
2637
|
-
{
|
|
2638
|
-
title: ev.label,
|
|
2639
|
-
className: "h-1 w-1 rounded-full",
|
|
2640
|
-
style: { backgroundColor: ev.color ?? (isSelected ? "var(--color-accent-fg)" : "var(--color-accent)") }
|
|
2641
|
-
},
|
|
2642
|
-
j
|
|
2643
|
-
)) })
|
|
2644
|
-
]
|
|
2645
|
-
},
|
|
2646
|
-
i
|
|
2647
|
-
);
|
|
2648
|
-
}) })
|
|
2649
|
-
] });
|
|
2650
|
-
}
|
|
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
2826
|
var SIZE5 = {
|
|
2780
2827
|
sm: { h: "h-control-sm", text: "text-xs", pad: "px-2.5" },
|
|
2781
2828
|
md: { h: "h-control-md", text: "text-sm", pad: "px-3.5" },
|
|
@@ -2874,7 +2921,7 @@ function SegmentedControl({
|
|
|
2874
2921
|
}
|
|
2875
2922
|
|
|
2876
2923
|
// src/components/core/scheduler.utils.ts
|
|
2877
|
-
var
|
|
2924
|
+
var MONTHS = [
|
|
2878
2925
|
"January",
|
|
2879
2926
|
"February",
|
|
2880
2927
|
"March",
|
|
@@ -2888,23 +2935,23 @@ var MONTHS2 = [
|
|
|
2888
2935
|
"November",
|
|
2889
2936
|
"December"
|
|
2890
2937
|
];
|
|
2891
|
-
var MONTHS_SHORT =
|
|
2892
|
-
var
|
|
2893
|
-
var
|
|
2894
|
-
var
|
|
2938
|
+
var MONTHS_SHORT = MONTHS.map((m) => m.slice(0, 3));
|
|
2939
|
+
var WEEKDAYS = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
2940
|
+
var toDate2 = (d) => d instanceof Date ? d : new Date(d);
|
|
2941
|
+
var startOfDay = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
2895
2942
|
var addDays = (d, n) => {
|
|
2896
2943
|
const x = new Date(d);
|
|
2897
2944
|
x.setDate(x.getDate() + n);
|
|
2898
2945
|
return x;
|
|
2899
2946
|
};
|
|
2900
|
-
var
|
|
2901
|
-
var
|
|
2902
|
-
var isToday = (d) =>
|
|
2947
|
+
var addMonths = (d, n) => new Date(d.getFullYear(), d.getMonth() + n, 1);
|
|
2948
|
+
var sameDay = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
2949
|
+
var isToday = (d) => sameDay(d, /* @__PURE__ */ new Date());
|
|
2903
2950
|
var isSameMonth = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth();
|
|
2904
2951
|
var startOfMonth = (d) => new Date(d.getFullYear(), d.getMonth(), 1);
|
|
2905
2952
|
var endOfMonth = (d) => new Date(d.getFullYear(), d.getMonth() + 1, 0);
|
|
2906
2953
|
var startOfWeek = (d, weekStartsOn) => {
|
|
2907
|
-
const x =
|
|
2954
|
+
const x = startOfDay(d);
|
|
2908
2955
|
const diff = (x.getDay() - weekStartsOn + 7) % 7;
|
|
2909
2956
|
return addDays(x, -diff);
|
|
2910
2957
|
};
|
|
@@ -2924,12 +2971,12 @@ var weekRange = (cursor, weekStartsOn) => {
|
|
|
2924
2971
|
const from = startOfWeek(cursor, weekStartsOn);
|
|
2925
2972
|
return { from, to: addDays(from, 6) };
|
|
2926
2973
|
};
|
|
2927
|
-
var weekdayLabels = (weekStartsOn) => Array.from({ length: 7 }, (_, i) =>
|
|
2928
|
-
var monthYearLabel = (d) => `${
|
|
2974
|
+
var weekdayLabels = (weekStartsOn) => Array.from({ length: 7 }, (_, i) => WEEKDAYS[(i + weekStartsOn) % 7]);
|
|
2975
|
+
var monthYearLabel = (d) => `${MONTHS[d.getMonth()]} ${d.getFullYear()}`;
|
|
2929
2976
|
var weekLabel = (cursor, weekStartsOn) => {
|
|
2930
2977
|
const from = startOfWeek(cursor, weekStartsOn);
|
|
2931
2978
|
const to = addDays(from, 6);
|
|
2932
|
-
const m = (d) =>
|
|
2979
|
+
const m = (d) => MONTHS[d.getMonth()].slice(0, 3);
|
|
2933
2980
|
if (from.getMonth() === to.getMonth()) {
|
|
2934
2981
|
return `${m(from)} ${from.getDate()} \u2013 ${to.getDate()}, ${to.getFullYear()}`;
|
|
2935
2982
|
}
|
|
@@ -2938,10 +2985,10 @@ var weekLabel = (cursor, weekStartsOn) => {
|
|
|
2938
2985
|
};
|
|
2939
2986
|
var minutesIntoDay = (d) => d.getHours() * 60 + d.getMinutes();
|
|
2940
2987
|
var hourLabel = (hour) => `${String(hour).padStart(2, "0")}:00`;
|
|
2941
|
-
var
|
|
2988
|
+
var timeLabel2 = (d) => `${String(d.getHours()).padStart(2, "0")}:${String(d.getMinutes()).padStart(2, "0")}`;
|
|
2942
2989
|
var normalize = (e) => {
|
|
2943
|
-
const start =
|
|
2944
|
-
const end = e.end ?
|
|
2990
|
+
const start = toDate2(e.start);
|
|
2991
|
+
const end = e.end ? toDate2(e.end) : new Date(start.getTime() + 36e5);
|
|
2945
2992
|
return { ...e, start, end };
|
|
2946
2993
|
};
|
|
2947
2994
|
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" }) });
|
|
@@ -3005,7 +3052,7 @@ function Scheduler({
|
|
|
3005
3052
|
);
|
|
3006
3053
|
const go = React28.useCallback((delta) => {
|
|
3007
3054
|
setDir(delta);
|
|
3008
|
-
setCursor((c) => view === "month" ?
|
|
3055
|
+
setCursor((c) => view === "month" ? addMonths(c, delta) : addDays(c, delta * 7));
|
|
3009
3056
|
}, [view]);
|
|
3010
3057
|
const goToday = React28.useCallback(() => {
|
|
3011
3058
|
setDir(0);
|
|
@@ -3188,7 +3235,7 @@ function MonthView({
|
|
|
3188
3235
|
/* @__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)) }),
|
|
3189
3236
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid flex-1 grid-cols-7 grid-rows-6", children: grid.map((day, i) => {
|
|
3190
3237
|
const inMonth = isSameMonth(day, cursor);
|
|
3191
|
-
const dayEvents = events.filter((e) =>
|
|
3238
|
+
const dayEvents = events.filter((e) => sameDay(e.start, day));
|
|
3192
3239
|
const today = isToday(day);
|
|
3193
3240
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3194
3241
|
"button",
|
|
@@ -3238,7 +3285,7 @@ function EventChip({ event, onSelect }) {
|
|
|
3238
3285
|
e.stopPropagation();
|
|
3239
3286
|
onSelect?.(event);
|
|
3240
3287
|
},
|
|
3241
|
-
title: `${event.title} \xB7 ${
|
|
3288
|
+
title: `${event.title} \xB7 ${timeLabel2(event.start)}`,
|
|
3242
3289
|
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
3290
|
children: [
|
|
3244
3291
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-2 w-2 flex-shrink-0 rounded-full", style: { backgroundColor: color } }),
|
|
@@ -3277,7 +3324,7 @@ function WeekView({
|
|
|
3277
3324
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 overflow-y-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid", style: { gridTemplateColumns: `3.5rem repeat(7, 1fr)`, height: gridHeight }, children: [
|
|
3278
3325
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative border-r border-border", children: hours.map((h, i) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute right-1 -translate-y-1/2 text-[10px] tabular-nums text-foreground-muted", style: { top: i * hourHeight }, children: i === 0 ? "" : hourLabel(h) }, h)) }),
|
|
3279
3326
|
days.map((day) => {
|
|
3280
|
-
const dayEvents = events.filter((e) =>
|
|
3327
|
+
const dayEvents = events.filter((e) => sameDay(e.start, day) && !e.allDay);
|
|
3281
3328
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative border-r border-border last:border-r-0", children: [
|
|
3282
3329
|
hours.map((h, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
3283
3330
|
"button",
|
|
@@ -3303,7 +3350,7 @@ function WeekView({
|
|
|
3303
3350
|
ev.stopPropagation();
|
|
3304
3351
|
onSelectEvent?.(e);
|
|
3305
3352
|
},
|
|
3306
|
-
title: `${e.title} \xB7 ${
|
|
3353
|
+
title: `${e.title} \xB7 ${timeLabel2(e.start)}\u2013${timeLabel2(e.end)}`,
|
|
3307
3354
|
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
3355
|
style: {
|
|
3309
3356
|
top: Math.max(0, top),
|
|
@@ -3313,7 +3360,7 @@ function WeekView({
|
|
|
3313
3360
|
},
|
|
3314
3361
|
children: [
|
|
3315
3362
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate font-medium", children: e.title }),
|
|
3316
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate", style: { color }, children:
|
|
3363
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate", style: { color }, children: timeLabel2(e.start) })
|
|
3317
3364
|
]
|
|
3318
3365
|
},
|
|
3319
3366
|
e.id
|
|
@@ -5515,7 +5562,7 @@ function Pagination({
|
|
|
5515
5562
|
}, [serverSide, options.perPage, picker]);
|
|
5516
5563
|
const currentOpt = picker.find((o) => o.key === displayPerPageKey);
|
|
5517
5564
|
const currentPerPageLabel = currentOpt?.label ?? currentOpt?.value ?? options.perPage ?? "";
|
|
5518
|
-
const navBtn = (icon, disabled, onClick, title) => /* @__PURE__ */ jsxRuntime.jsx(Button_default, { variant: "outline", size: "sm", disabled, onClick, icon, className: "w-7 !px-0 focus-visible:!ring-offset-0", "aria-label": title, title });
|
|
5565
|
+
const navBtn = (icon, disabled, onClick, title) => /* @__PURE__ */ jsxRuntime.jsx(Button_default, { variant: "outline", size: "sm", disabled, onClick, icon, className: "w-7 !px-0 focus-visible:!ring-[3px] focus-visible:!ring-focus-ring focus-visible:!ring-offset-0", "aria-label": title, title });
|
|
5519
5566
|
const chevronRight = /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) });
|
|
5520
5567
|
const doubleChevronRight = /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "h-4 w-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M13 5l7 7-7 7M5 5l7 7-7 7" }) });
|
|
5521
5568
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center justify-end gap-x-4 gap-y-3", children: [
|
|
@@ -5527,7 +5574,7 @@ function Pagination({
|
|
|
5527
5574
|
variant: "outline",
|
|
5528
5575
|
size: "sm",
|
|
5529
5576
|
side: "top",
|
|
5530
|
-
className: "focus-visible:!ring-offset-0",
|
|
5577
|
+
className: "focus-visible:!ring-[3px] focus-visible:!ring-focus-ring focus-visible:!ring-offset-0",
|
|
5531
5578
|
label: String(currentPerPageLabel),
|
|
5532
5579
|
items: picker.map((o) => ({
|
|
5533
5580
|
key: o.key,
|
|
@@ -7862,7 +7909,7 @@ function addDays2(d, n) {
|
|
|
7862
7909
|
c.setDate(c.getDate() + n);
|
|
7863
7910
|
return c;
|
|
7864
7911
|
}
|
|
7865
|
-
function
|
|
7912
|
+
function addMonths2(d, n) {
|
|
7866
7913
|
const c = new Date(d);
|
|
7867
7914
|
c.setMonth(c.getMonth() + n);
|
|
7868
7915
|
return c;
|
|
@@ -7873,7 +7920,7 @@ function defaultFormat3(d) {
|
|
|
7873
7920
|
const day = d.getDate().toString().padStart(2, "0");
|
|
7874
7921
|
return `${y}-${m}-${day}`;
|
|
7875
7922
|
}
|
|
7876
|
-
function
|
|
7923
|
+
function buildGrid(viewMonth, weekStartsOn) {
|
|
7877
7924
|
const first = startOfMonth2(viewMonth);
|
|
7878
7925
|
const startOffset = (first.getDay() - weekStartsOn + 7) % 7;
|
|
7879
7926
|
const gridStart = addDays2(first, -startOffset);
|
|
@@ -7930,7 +7977,7 @@ function DatePicker({
|
|
|
7930
7977
|
const ordered = WEEKDAY_SHORT.slice(weekStartsOn).concat(WEEKDAY_SHORT.slice(0, weekStartsOn));
|
|
7931
7978
|
return ordered;
|
|
7932
7979
|
}, [weekStartsOn]);
|
|
7933
|
-
const grid = React28.useMemo(() =>
|
|
7980
|
+
const grid = React28.useMemo(() => buildGrid(viewMonth, weekStartsOn), [viewMonth, weekStartsOn]);
|
|
7934
7981
|
const isDisabled = (d) => {
|
|
7935
7982
|
if (min && d < min) return true;
|
|
7936
7983
|
if (max && d > max) return true;
|
|
@@ -7961,14 +8008,14 @@ function DatePicker({
|
|
|
7961
8008
|
next(7);
|
|
7962
8009
|
} else if (e.key === "PageUp") {
|
|
7963
8010
|
e.preventDefault();
|
|
7964
|
-
const nm =
|
|
8011
|
+
const nm = addMonths2(viewMonth, -1);
|
|
7965
8012
|
setViewMonth(nm);
|
|
7966
|
-
setFocusDate((d) =>
|
|
8013
|
+
setFocusDate((d) => addMonths2(d, -1));
|
|
7967
8014
|
} else if (e.key === "PageDown") {
|
|
7968
8015
|
e.preventDefault();
|
|
7969
|
-
const nm =
|
|
8016
|
+
const nm = addMonths2(viewMonth, 1);
|
|
7970
8017
|
setViewMonth(nm);
|
|
7971
|
-
setFocusDate((d) =>
|
|
8018
|
+
setFocusDate((d) => addMonths2(d, 1));
|
|
7972
8019
|
} else if (e.key === "Home") {
|
|
7973
8020
|
e.preventDefault();
|
|
7974
8021
|
const dow = (focusDate.getDay() - weekStartsOn + 7) % 7;
|
|
@@ -8033,7 +8080,7 @@ function DatePicker({
|
|
|
8033
8080
|
{
|
|
8034
8081
|
type: "button",
|
|
8035
8082
|
onClick: () => {
|
|
8036
|
-
if (view === "days") setViewMonth(
|
|
8083
|
+
if (view === "days") setViewMonth(addMonths2(viewMonth, -1));
|
|
8037
8084
|
else if (view === "months") setViewMonth(new Date(viewMonth.getFullYear() - 1, viewMonth.getMonth(), 1));
|
|
8038
8085
|
else setViewMonth(new Date(viewMonth.getFullYear() - 10, viewMonth.getMonth(), 1));
|
|
8039
8086
|
},
|
|
@@ -8068,7 +8115,7 @@ function DatePicker({
|
|
|
8068
8115
|
{
|
|
8069
8116
|
type: "button",
|
|
8070
8117
|
onClick: () => {
|
|
8071
|
-
if (view === "days") setViewMonth(
|
|
8118
|
+
if (view === "days") setViewMonth(addMonths2(viewMonth, 1));
|
|
8072
8119
|
else if (view === "months") setViewMonth(new Date(viewMonth.getFullYear() + 1, viewMonth.getMonth(), 1));
|
|
8073
8120
|
else setViewMonth(new Date(viewMonth.getFullYear() + 10, viewMonth.getMonth(), 1));
|
|
8074
8121
|
},
|
|
@@ -8854,16 +8901,16 @@ function TimePicker({
|
|
|
8854
8901
|
var MONTH_NAMES2 = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
8855
8902
|
var WEEKDAY = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
8856
8903
|
var startOfMonth3 = (d) => new Date(d.getFullYear(), d.getMonth(), 1);
|
|
8857
|
-
var
|
|
8904
|
+
var addMonths3 = (d, n) => new Date(d.getFullYear(), d.getMonth() + n, 1);
|
|
8858
8905
|
var addDays3 = (d, n) => {
|
|
8859
8906
|
const c = new Date(d);
|
|
8860
8907
|
c.setDate(c.getDate() + n);
|
|
8861
8908
|
return c;
|
|
8862
8909
|
};
|
|
8863
8910
|
var isSameDay2 = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
8864
|
-
var
|
|
8911
|
+
var startOfDay2 = (d) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
8865
8912
|
var defaultFmt = (d) => `${d.getFullYear()}-${`${d.getMonth() + 1}`.padStart(2, "0")}-${`${d.getDate()}`.padStart(2, "0")}`;
|
|
8866
|
-
function
|
|
8913
|
+
function buildGrid2(viewMonth, weekStartsOn) {
|
|
8867
8914
|
const first = startOfMonth3(viewMonth);
|
|
8868
8915
|
const offset = (first.getDay() - weekStartsOn + 7) % 7;
|
|
8869
8916
|
const gridStart = addDays3(first, -offset);
|
|
@@ -8902,13 +8949,13 @@ function DateRangePicker({
|
|
|
8902
8949
|
() => WEEKDAY.slice(weekStartsOn).concat(WEEKDAY.slice(0, weekStartsOn)),
|
|
8903
8950
|
[weekStartsOn]
|
|
8904
8951
|
);
|
|
8905
|
-
const isDisabled = (d) => min && d <
|
|
8952
|
+
const isDisabled = (d) => min && d < startOfDay2(min) || max && d > startOfDay2(max);
|
|
8906
8953
|
const effective = pendingStart ? { start: pendingStart, end: hoverDate } : value;
|
|
8907
8954
|
const inRange = (d) => {
|
|
8908
8955
|
const { start, end } = effective;
|
|
8909
8956
|
if (!start || !end) return false;
|
|
8910
8957
|
const [a, b] = start <= end ? [start, end] : [end, start];
|
|
8911
|
-
return d >=
|
|
8958
|
+
return d >= startOfDay2(a) && d <= startOfDay2(b);
|
|
8912
8959
|
};
|
|
8913
8960
|
const onDayClick = (d) => {
|
|
8914
8961
|
if (isDisabled(d)) return;
|
|
@@ -8926,7 +8973,7 @@ function DateRangePicker({
|
|
|
8926
8973
|
};
|
|
8927
8974
|
const triggerText = value.start && value.end ? `${format(value.start)} \u2013 ${format(value.end)}` : value.start ? `${format(value.start)} \u2013 \u2026` : "";
|
|
8928
8975
|
const renderMonth = (viewMonth) => {
|
|
8929
|
-
const cells =
|
|
8976
|
+
const cells = buildGrid2(viewMonth, weekStartsOn);
|
|
8930
8977
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
8931
8978
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm font-semibold text-center mb-2 select-none", children: [
|
|
8932
8979
|
MONTH_NAMES2[viewMonth.getMonth()],
|
|
@@ -9015,7 +9062,7 @@ function DateRangePicker({
|
|
|
9015
9062
|
"button",
|
|
9016
9063
|
{
|
|
9017
9064
|
type: "button",
|
|
9018
|
-
onClick: () => setLeftMonth(
|
|
9065
|
+
onClick: () => setLeftMonth(addMonths3(leftMonth, -1)),
|
|
9019
9066
|
"aria-label": "Previous month",
|
|
9020
9067
|
className: "absolute -top-1 left-0 w-7 h-7 inline-flex items-center justify-center rounded-md hover:bg-surface-raised focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
9021
9068
|
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "w-4 h-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M15 19l-7-7 7-7" }) })
|
|
@@ -9028,13 +9075,13 @@ function DateRangePicker({
|
|
|
9028
9075
|
"button",
|
|
9029
9076
|
{
|
|
9030
9077
|
type: "button",
|
|
9031
|
-
onClick: () => setLeftMonth(
|
|
9078
|
+
onClick: () => setLeftMonth(addMonths3(leftMonth, 1)),
|
|
9032
9079
|
"aria-label": "Next month",
|
|
9033
9080
|
className: "absolute -top-1 right-0 w-7 h-7 inline-flex items-center justify-center rounded-md hover:bg-surface-raised focus:outline-none focus-visible:ring-2 focus-visible:ring-accent",
|
|
9034
9081
|
children: /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, className: "w-4 h-4", children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M9 5l7 7-7 7" }) })
|
|
9035
9082
|
}
|
|
9036
9083
|
),
|
|
9037
|
-
renderMonth(
|
|
9084
|
+
renderMonth(addMonths3(leftMonth, 1))
|
|
9038
9085
|
] })
|
|
9039
9086
|
] })
|
|
9040
9087
|
]
|
|
@@ -9298,7 +9345,6 @@ exports.Box = Box;
|
|
|
9298
9345
|
exports.Breadcrumbs = Breadcrumbs;
|
|
9299
9346
|
exports.Button = Button_default;
|
|
9300
9347
|
exports.CARD_BRANDS = CARD_BRANDS;
|
|
9301
|
-
exports.Calendar = Calendar2;
|
|
9302
9348
|
exports.Card = Card_default;
|
|
9303
9349
|
exports.CardCarousel = CardCarousel;
|
|
9304
9350
|
exports.Cart = Cart;
|
|
@@ -9307,6 +9353,7 @@ exports.CartProvider = CartProvider;
|
|
|
9307
9353
|
exports.Catalog = Catalog;
|
|
9308
9354
|
exports.CatalogCarousel = CatalogCarousel;
|
|
9309
9355
|
exports.CatalogGrid = CatalogGrid;
|
|
9356
|
+
exports.Chat = Chat;
|
|
9310
9357
|
exports.Checkbox = Checkbox;
|
|
9311
9358
|
exports.Checkout = Checkout;
|
|
9312
9359
|
exports.ColorPicker = ColorPicker;
|