orynn 0.2.0 → 0.5.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/LICENSE +1 -1
- package/README.md +47 -54
- package/dist/index.cjs +2666 -494
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +836 -104
- package/dist/index.d.ts +836 -104
- package/dist/index.js +2599 -495
- package/dist/index.js.map +1 -1
- package/dist/styles.css +2028 -392
- package/package.json +18 -9
package/dist/index.cjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var react = require('react');
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var reactDom = require('react-dom');
|
|
6
|
+
var radixUi = require('radix-ui');
|
|
6
7
|
|
|
7
8
|
var __typeError = (msg) => {
|
|
8
9
|
throw TypeError(msg);
|
|
@@ -30,8 +31,8 @@ var base = (props) => ({
|
|
|
30
31
|
});
|
|
31
32
|
var CheckIcon = (p) => /* @__PURE__ */ jsxRuntime.jsx("svg", { ...base(p), children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 6 9 17l-5-5" }) });
|
|
32
33
|
var MinusIcon = (p) => /* @__PURE__ */ jsxRuntime.jsx("svg", { ...base(p), children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 12h14" }) });
|
|
33
|
-
var PlusIcon = (p) => /* @__PURE__ */ jsxRuntime.jsx("svg", { ...base(p), children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 5v14M5 12h14" }) });
|
|
34
34
|
var ChevronDownIcon = (p) => /* @__PURE__ */ jsxRuntime.jsx("svg", { ...base(p), children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m6 9 6 6 6-6" }) });
|
|
35
|
+
var ChevronUpIcon = (p) => /* @__PURE__ */ jsxRuntime.jsx("svg", { ...base(p), children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m6 15 6-6 6 6" }) });
|
|
35
36
|
var ChevronLeftIcon = (p) => /* @__PURE__ */ jsxRuntime.jsx("svg", { ...base(p), children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m15 18-6-6 6-6" }) });
|
|
36
37
|
var ChevronRightIcon = (p) => /* @__PURE__ */ jsxRuntime.jsx("svg", { ...base(p), children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m9 18 6-6-6-6" }) });
|
|
37
38
|
var XIcon = (p) => /* @__PURE__ */ jsxRuntime.jsx("svg", { ...base(p), children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6 6 18M6 6l12 12" }) });
|
|
@@ -48,11 +49,15 @@ var CalendarIcon = (p) => /* @__PURE__ */ jsxRuntime.jsxs("svg", { ...base(p), c
|
|
|
48
49
|
/* @__PURE__ */ jsxRuntime.jsx("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2" }),
|
|
49
50
|
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M16 2v4M8 2v4M3 10h18" })
|
|
50
51
|
] });
|
|
52
|
+
var CircleIcon = (p) => /* @__PURE__ */ jsxRuntime.jsx("svg", { ...base({ strokeWidth: 0, fill: "currentColor", ...p }), children: /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "6" }) });
|
|
51
53
|
var CheckboxGroupContext = react.createContext(null);
|
|
52
54
|
var sizePx = {
|
|
53
|
-
sm: "0.
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
sm: "0.875rem",
|
|
56
|
+
// 14px
|
|
57
|
+
md: "1rem",
|
|
58
|
+
// 16px — shadcn size-4
|
|
59
|
+
lg: "1.125rem"
|
|
60
|
+
// 18px
|
|
56
61
|
};
|
|
57
62
|
var Checkbox = /* @__PURE__ */ react.forwardRef(
|
|
58
63
|
function Checkbox2(props, ref) {
|
|
@@ -210,15 +215,7 @@ function Field(props) {
|
|
|
210
215
|
description != null && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "orynn-field__description", id: descriptionId, children: description }),
|
|
211
216
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "orynn-field__control", children: typeof children === "function" ? children(ctx) : children }),
|
|
212
217
|
invalid && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "orynn-field__error", id: errorId, role: "alert", children: messages.length === 1 ? messages[0] : messages.map((m) => /* @__PURE__ */ jsxRuntime.jsx("span", { children: m }, m)) }),
|
|
213
|
-
successMsg && /* @__PURE__ */ jsxRuntime.jsx(
|
|
214
|
-
"p",
|
|
215
|
-
{
|
|
216
|
-
className: "orynn-field__error",
|
|
217
|
-
id: successId,
|
|
218
|
-
style: { color: "var(--orynn-color-success)" },
|
|
219
|
-
children: successMsg
|
|
220
|
-
}
|
|
221
|
-
)
|
|
218
|
+
successMsg && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "orynn-field__success", id: successId, children: successMsg })
|
|
222
219
|
]
|
|
223
220
|
}
|
|
224
221
|
);
|
|
@@ -237,8 +234,11 @@ function CheckboxGroup(props) {
|
|
|
237
234
|
defaultValue,
|
|
238
235
|
onChange,
|
|
239
236
|
orientation = "vertical",
|
|
237
|
+
columns,
|
|
240
238
|
min,
|
|
241
239
|
max,
|
|
240
|
+
showSelectAll = false,
|
|
241
|
+
selectAllLabel = "Select all",
|
|
242
242
|
options,
|
|
243
243
|
children,
|
|
244
244
|
className,
|
|
@@ -263,6 +263,19 @@ function CheckboxGroup(props) {
|
|
|
263
263
|
},
|
|
264
264
|
[value, setValue, onChange]
|
|
265
265
|
);
|
|
266
|
+
const selectableValues = (options ?? []).filter((o) => !o.disabled).map((o) => o.value);
|
|
267
|
+
const allSelected = selectableValues.length > 0 && selectableValues.every((v) => value.includes(v));
|
|
268
|
+
const someSelected = selectableValues.some((v) => value.includes(v));
|
|
269
|
+
const toggleAll = () => {
|
|
270
|
+
if (allSelected) {
|
|
271
|
+
setValue([]);
|
|
272
|
+
onChange?.([]);
|
|
273
|
+
} else {
|
|
274
|
+
const next = max != null ? selectableValues.slice(0, max) : selectableValues;
|
|
275
|
+
setValue(next);
|
|
276
|
+
onChange?.(next);
|
|
277
|
+
}
|
|
278
|
+
};
|
|
266
279
|
const ctx = react.useMemo(
|
|
267
280
|
() => ({
|
|
268
281
|
name,
|
|
@@ -286,23 +299,40 @@ function CheckboxGroup(props) {
|
|
|
286
299
|
disabled,
|
|
287
300
|
id,
|
|
288
301
|
className,
|
|
289
|
-
children: () => /* @__PURE__ */ jsxRuntime.jsx(CheckboxGroupContext.Provider, { value: ctx, children: /* @__PURE__ */ jsxRuntime.
|
|
302
|
+
children: () => /* @__PURE__ */ jsxRuntime.jsx(CheckboxGroupContext.Provider, { value: ctx, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
290
303
|
"div",
|
|
291
304
|
{
|
|
292
305
|
role: "group",
|
|
293
306
|
"aria-labelledby": label != null ? `${id}-label` : void 0,
|
|
294
307
|
className: cx("orynn-choice-group"),
|
|
295
|
-
"data-orientation": orientation,
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
308
|
+
"data-orientation": columns ? void 0 : orientation,
|
|
309
|
+
"data-columns": columns ? "" : void 0,
|
|
310
|
+
style: columns ? { "--orynn-choice-columns": columns } : void 0,
|
|
311
|
+
children: [
|
|
312
|
+
showSelectAll && selectableValues.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "orynn-choice-group__selectall", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
313
|
+
Checkbox,
|
|
314
|
+
{
|
|
315
|
+
checked: allSelected,
|
|
316
|
+
indeterminate: !allSelected && someSelected,
|
|
317
|
+
disabled,
|
|
318
|
+
label: selectAllLabel,
|
|
319
|
+
onChange: toggleAll
|
|
320
|
+
}
|
|
321
|
+
) }),
|
|
322
|
+
options ? options.map((o) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
323
|
+
Checkbox,
|
|
324
|
+
{
|
|
325
|
+
value: o.value,
|
|
326
|
+
label: o.icon != null ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
327
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-choice__icon", children: o.icon }),
|
|
328
|
+
o.label
|
|
329
|
+
] }) : o.label,
|
|
330
|
+
description: o.description,
|
|
331
|
+
disabled: o.disabled
|
|
332
|
+
},
|
|
333
|
+
o.value
|
|
334
|
+
)) : children
|
|
335
|
+
]
|
|
306
336
|
}
|
|
307
337
|
) })
|
|
308
338
|
}
|
|
@@ -323,6 +353,8 @@ var FieldBox = /* @__PURE__ */ react.forwardRef(
|
|
|
323
353
|
floatingLabel,
|
|
324
354
|
left,
|
|
325
355
|
right,
|
|
356
|
+
addonBefore,
|
|
357
|
+
addonAfter,
|
|
326
358
|
textarea,
|
|
327
359
|
className,
|
|
328
360
|
children,
|
|
@@ -342,7 +374,8 @@ var FieldBox = /* @__PURE__ */ react.forwardRef(
|
|
|
342
374
|
}
|
|
343
375
|
onBlur?.(e);
|
|
344
376
|
};
|
|
345
|
-
|
|
377
|
+
const hasAddon = addonBefore != null || addonAfter != null;
|
|
378
|
+
const box = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
346
379
|
"div",
|
|
347
380
|
{
|
|
348
381
|
ref,
|
|
@@ -361,6 +394,8 @@ var FieldBox = /* @__PURE__ */ react.forwardRef(
|
|
|
361
394
|
"data-focused": isFocused || void 0,
|
|
362
395
|
"data-active": active || isFocused || void 0,
|
|
363
396
|
"data-open": open || void 0,
|
|
397
|
+
"data-addon-before": addonBefore != null || void 0,
|
|
398
|
+
"data-addon-after": addonAfter != null || void 0,
|
|
364
399
|
onFocus: handleFocus,
|
|
365
400
|
onBlur: handleBlur,
|
|
366
401
|
...rest,
|
|
@@ -372,8 +407,137 @@ var FieldBox = /* @__PURE__ */ react.forwardRef(
|
|
|
372
407
|
]
|
|
373
408
|
}
|
|
374
409
|
);
|
|
410
|
+
if (!hasAddon) return box;
|
|
411
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "orynn-box__group", "data-size": size, "data-disabled": disabled || void 0, children: [
|
|
412
|
+
addonBefore != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-box__addon", "data-side": "before", children: addonBefore }),
|
|
413
|
+
box,
|
|
414
|
+
addonAfter != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-box__addon", "data-side": "after", children: addonAfter })
|
|
415
|
+
] });
|
|
375
416
|
}
|
|
376
417
|
);
|
|
418
|
+
|
|
419
|
+
// src/theme/theme.ts
|
|
420
|
+
var len = (v) => typeof v === "number" ? `${v}px` : v;
|
|
421
|
+
var RADIUS_KEYWORDS = {
|
|
422
|
+
none: "0px",
|
|
423
|
+
sm: "0.375rem",
|
|
424
|
+
md: "0.5rem",
|
|
425
|
+
lg: "0.625rem",
|
|
426
|
+
xl: "0.875rem",
|
|
427
|
+
pill: "9999px"
|
|
428
|
+
};
|
|
429
|
+
var DARK_FG = "#0b0d12";
|
|
430
|
+
var LIGHT_FG = "#ffffff";
|
|
431
|
+
function contrastFor(color) {
|
|
432
|
+
const c = color.trim().toLowerCase();
|
|
433
|
+
const hex = /^#?([\da-f]{3}|[\da-f]{6})$/.exec(c)?.[1];
|
|
434
|
+
if (hex) {
|
|
435
|
+
const full = hex.length === 3 ? hex.replace(/./g, "$&$&") : hex;
|
|
436
|
+
const n = Number.parseInt(full, 16);
|
|
437
|
+
const toLin = (v) => {
|
|
438
|
+
const x = v / 255;
|
|
439
|
+
return x <= 0.03928 ? x / 12.92 : ((x + 0.055) / 1.055) ** 2.4;
|
|
440
|
+
};
|
|
441
|
+
const lum = 0.2126 * toLin(n >> 16 & 255) + 0.7152 * toLin(n >> 8 & 255) + 0.0722 * toLin(n & 255);
|
|
442
|
+
return lum > 0.42 ? DARK_FG : LIGHT_FG;
|
|
443
|
+
}
|
|
444
|
+
const okl = /^oklch\(\s*([\d.]+)(%?)/.exec(c);
|
|
445
|
+
if (okl) {
|
|
446
|
+
const l = Number.parseFloat(okl[1]) / (okl[2] ? 100 : 1);
|
|
447
|
+
return l >= 0.62 ? DARK_FG : LIGHT_FG;
|
|
448
|
+
}
|
|
449
|
+
const hsl = /^hsla?\(\s*[\d.]+(?:deg)?\s*[, ]\s*[\d.]+%\s*[, ]\s*([\d.]+)%/.exec(c)?.[1];
|
|
450
|
+
if (hsl) return Number.parseFloat(hsl) >= 60 ? DARK_FG : LIGHT_FG;
|
|
451
|
+
if (c === "white") return DARK_FG;
|
|
452
|
+
if (c === "black") return LIGHT_FG;
|
|
453
|
+
return LIGHT_FG;
|
|
454
|
+
}
|
|
455
|
+
function normalizeTheme(input) {
|
|
456
|
+
return typeof input === "string" ? { preset: input } : input ?? {};
|
|
457
|
+
}
|
|
458
|
+
function resolveThemeVars(config) {
|
|
459
|
+
const vars = {};
|
|
460
|
+
const primary = config.primary ?? config.accent;
|
|
461
|
+
if (primary) {
|
|
462
|
+
const p = primary;
|
|
463
|
+
vars["--orynn-color-primary"] = p;
|
|
464
|
+
vars["--orynn-color-primary-foreground"] = config.primaryForeground ?? config.accentContrast ?? contrastFor(p);
|
|
465
|
+
if (!config.ring) vars["--orynn-color-ring"] = p;
|
|
466
|
+
}
|
|
467
|
+
if (config.ring) vars["--orynn-color-ring"] = config.ring;
|
|
468
|
+
if (config.font) vars["--orynn-font-family"] = config.font;
|
|
469
|
+
if (config.fontSize != null) vars["--orynn-font-size"] = len(config.fontSize);
|
|
470
|
+
if (config.controlWidth != null) {
|
|
471
|
+
vars["--orynn-control-width"] = len(config.controlWidth);
|
|
472
|
+
vars["--orynn-control-max-width"] = "none";
|
|
473
|
+
}
|
|
474
|
+
if (config.controlMaxWidth != null)
|
|
475
|
+
vars["--orynn-control-max-width"] = len(config.controlMaxWidth);
|
|
476
|
+
if (config.radius != null) {
|
|
477
|
+
const r = config.radius;
|
|
478
|
+
vars["--orynn-radius"] = typeof r === "string" && r in RADIUS_KEYWORDS ? RADIUS_KEYWORDS[r] : len(r);
|
|
479
|
+
}
|
|
480
|
+
Object.assign(vars, config.vars ?? {});
|
|
481
|
+
return vars;
|
|
482
|
+
}
|
|
483
|
+
var OrynnContext = react.createContext({
|
|
484
|
+
preset: "default",
|
|
485
|
+
density: "comfortable",
|
|
486
|
+
config: {},
|
|
487
|
+
portalContainer: null
|
|
488
|
+
});
|
|
489
|
+
function syncThemeEl(el, preset, density, config, style) {
|
|
490
|
+
const attr = (name, value) => value == null ? el.removeAttribute(name) : el.setAttribute(name, value);
|
|
491
|
+
attr("data-orynn-theme", preset === "default" ? null : preset);
|
|
492
|
+
attr("data-orynn-density", density === "comfortable" ? null : density);
|
|
493
|
+
attr("data-orynn-color-scheme", config.colorScheme ?? null);
|
|
494
|
+
el.classList.toggle("dark", config.colorScheme === "dark");
|
|
495
|
+
el.removeAttribute("style");
|
|
496
|
+
for (const [k, v] of Object.entries(style)) {
|
|
497
|
+
if (v != null) el.style.setProperty(k, String(v));
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
function OrynnProvider({ theme, as = "div", className, children }) {
|
|
501
|
+
const config = react.useMemo(() => normalizeTheme(theme), [theme]);
|
|
502
|
+
const preset = config.preset ?? "default";
|
|
503
|
+
const density = config.density ?? "comfortable";
|
|
504
|
+
const style = react.useMemo(() => resolveThemeVars(config), [config]);
|
|
505
|
+
const [portalContainer, setPortalContainer] = react.useState(null);
|
|
506
|
+
react.useEffect(() => {
|
|
507
|
+
if (typeof document === "undefined") return;
|
|
508
|
+
const el = document.createElement("div");
|
|
509
|
+
el.className = "orynn-portal";
|
|
510
|
+
document.body.appendChild(el);
|
|
511
|
+
setPortalContainer(el);
|
|
512
|
+
return () => {
|
|
513
|
+
el.remove();
|
|
514
|
+
setPortalContainer(null);
|
|
515
|
+
};
|
|
516
|
+
}, []);
|
|
517
|
+
react.useEffect(() => {
|
|
518
|
+
if (portalContainer)
|
|
519
|
+
syncThemeEl(portalContainer, preset, density, config, style);
|
|
520
|
+
}, [portalContainer, preset, density, config, style]);
|
|
521
|
+
const ctx = react.useMemo(
|
|
522
|
+
() => ({ preset, density, config, portalContainer }),
|
|
523
|
+
[preset, density, config, portalContainer]
|
|
524
|
+
);
|
|
525
|
+
const dataProps = {
|
|
526
|
+
"data-orynn-theme": preset === "default" ? void 0 : preset,
|
|
527
|
+
"data-orynn-density": density === "comfortable" ? void 0 : density,
|
|
528
|
+
"data-orynn-color-scheme": config.colorScheme
|
|
529
|
+
};
|
|
530
|
+
const darkClass = config.colorScheme === "dark" ? "dark" : void 0;
|
|
531
|
+
return /* @__PURE__ */ jsxRuntime.jsx(OrynnContext.Provider, { value: ctx, children: as === "contents" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: darkClass, style: { display: "contents", ...style }, ...dataProps, children }) : as === "span" ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx("orynn-root", className, darkClass), style, ...dataProps, children }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: cx("orynn-root", className, darkClass), style, ...dataProps, children }) });
|
|
532
|
+
}
|
|
533
|
+
function useOrynnTheme() {
|
|
534
|
+
return react.useContext(OrynnContext);
|
|
535
|
+
}
|
|
536
|
+
function usePortalContainer() {
|
|
537
|
+
const { portalContainer } = react.useContext(OrynnContext);
|
|
538
|
+
if (portalContainer) return portalContainer;
|
|
539
|
+
return typeof document === "undefined" ? null : document.body;
|
|
540
|
+
}
|
|
377
541
|
var useIsoLayoutEffect = typeof window === "undefined" ? react.useEffect : react.useLayoutEffect;
|
|
378
542
|
function Popover({
|
|
379
543
|
open,
|
|
@@ -382,6 +546,7 @@ function Popover({
|
|
|
382
546
|
children,
|
|
383
547
|
matchWidth = true,
|
|
384
548
|
offset = 6,
|
|
549
|
+
maxHeight,
|
|
385
550
|
className,
|
|
386
551
|
popoverRef,
|
|
387
552
|
role,
|
|
@@ -393,6 +558,7 @@ function Popover({
|
|
|
393
558
|
if (popoverRef) popoverRef.current = el;
|
|
394
559
|
};
|
|
395
560
|
const [pos, setPos] = react.useState(null);
|
|
561
|
+
const container = usePortalContainer();
|
|
396
562
|
useIsoLayoutEffect(() => {
|
|
397
563
|
if (!open) return;
|
|
398
564
|
const anchor = anchorRef.current;
|
|
@@ -404,12 +570,13 @@ function Popover({
|
|
|
404
570
|
const above = r.top - offset;
|
|
405
571
|
const wanted = innerRef.current?.scrollHeight ?? 280;
|
|
406
572
|
const placeTop = below < Math.min(wanted, 240) && above > below;
|
|
573
|
+
const avail = Math.max(140, (placeTop ? above : below) - 4);
|
|
407
574
|
setPos({
|
|
408
575
|
left: r.left,
|
|
409
576
|
top: placeTop ? r.top - offset : r.bottom + offset,
|
|
410
577
|
width: r.width,
|
|
411
578
|
placement: placeTop ? "top" : "bottom",
|
|
412
|
-
maxHeight: Math.
|
|
579
|
+
maxHeight: maxHeight != null ? Math.min(maxHeight, avail) : avail
|
|
413
580
|
});
|
|
414
581
|
};
|
|
415
582
|
update();
|
|
@@ -422,7 +589,7 @@ function Popover({
|
|
|
422
589
|
window.removeEventListener("scroll", update, true);
|
|
423
590
|
window.removeEventListener("resize", update);
|
|
424
591
|
};
|
|
425
|
-
}, [open, anchorRef, offset]);
|
|
592
|
+
}, [open, anchorRef, offset, maxHeight]);
|
|
426
593
|
react.useEffect(() => {
|
|
427
594
|
if (!open) return;
|
|
428
595
|
const onPointerDown = (e) => {
|
|
@@ -443,7 +610,7 @@ function Popover({
|
|
|
443
610
|
document.removeEventListener("keydown", onKey, true);
|
|
444
611
|
};
|
|
445
612
|
}, [open, anchorRef, onClose]);
|
|
446
|
-
if (!open ||
|
|
613
|
+
if (!open || !pos || !container) return null;
|
|
447
614
|
return reactDom.createPortal(
|
|
448
615
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
449
616
|
"div",
|
|
@@ -463,7 +630,7 @@ function Popover({
|
|
|
463
630
|
children
|
|
464
631
|
}
|
|
465
632
|
),
|
|
466
|
-
|
|
633
|
+
container
|
|
467
634
|
);
|
|
468
635
|
}
|
|
469
636
|
|
|
@@ -488,27 +655,82 @@ var clampDate = (d, min, max) => {
|
|
|
488
655
|
return d;
|
|
489
656
|
};
|
|
490
657
|
var pad = (n, len2 = 2) => String(n).padStart(len2, "0");
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
658
|
+
var FORMAT_TOKENS = /(?<![A-Za-z])(yyyy|yy|MMMM|MMM|MM|M|dd|d|EEEE|EEE|HH|H|hh|h|mm|m|ss|s|aa|a|A)(?![A-Za-z])/g;
|
|
659
|
+
function formatDate(d, fmt = "yyyy-MM-dd", locale) {
|
|
660
|
+
if (typeof fmt !== "string") return new Intl.DateTimeFormat(locale, fmt).format(d);
|
|
661
|
+
const h12 = d.getHours() % 12 || 12;
|
|
662
|
+
const map = {
|
|
663
|
+
yyyy: String(d.getFullYear()),
|
|
664
|
+
yy: pad(d.getFullYear() % 100),
|
|
665
|
+
MMMM: new Intl.DateTimeFormat(locale, { month: "long" }).format(d),
|
|
666
|
+
MMM: new Intl.DateTimeFormat(locale, { month: "short" }).format(d),
|
|
667
|
+
MM: pad(d.getMonth() + 1),
|
|
668
|
+
M: String(d.getMonth() + 1),
|
|
669
|
+
dd: pad(d.getDate()),
|
|
670
|
+
d: String(d.getDate()),
|
|
671
|
+
EEEE: new Intl.DateTimeFormat(locale, { weekday: "long" }).format(d),
|
|
672
|
+
EEE: new Intl.DateTimeFormat(locale, { weekday: "short" }).format(d),
|
|
673
|
+
HH: pad(d.getHours()),
|
|
674
|
+
H: String(d.getHours()),
|
|
675
|
+
hh: pad(h12),
|
|
676
|
+
h: String(h12),
|
|
677
|
+
mm: pad(d.getMinutes()),
|
|
678
|
+
m: String(d.getMinutes()),
|
|
679
|
+
ss: pad(d.getSeconds()),
|
|
680
|
+
s: String(d.getSeconds()),
|
|
681
|
+
aa: d.getHours() < 12 ? "am" : "pm",
|
|
682
|
+
a: d.getHours() < 12 ? "am" : "pm",
|
|
683
|
+
A: d.getHours() < 12 ? "AM" : "PM"
|
|
684
|
+
};
|
|
685
|
+
return fmt.replace(FORMAT_TOKENS, (t) => map[t] ?? t);
|
|
686
|
+
}
|
|
687
|
+
function matchMonthName(input, locale) {
|
|
688
|
+
for (let m = 0; m < 12; m += 1) {
|
|
689
|
+
for (const style of ["long", "short"]) {
|
|
690
|
+
const name = new Intl.DateTimeFormat(locale, { month: style }).format(new Date(2021, m, 1));
|
|
691
|
+
const i = input.toLowerCase().indexOf(name.toLowerCase());
|
|
692
|
+
if (i !== -1) return { month: m, rest: input.slice(0, i) + input.slice(i + name.length) };
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
return null;
|
|
696
|
+
}
|
|
697
|
+
function parseDate(input, fmt = "yyyy-MM-dd", locale) {
|
|
698
|
+
const pattern = typeof fmt === "string" ? fmt : "yyyy-MM-dd";
|
|
699
|
+
let text = input;
|
|
700
|
+
let monthFromName;
|
|
701
|
+
if (/MMM/.test(pattern)) {
|
|
702
|
+
const hit = matchMonthName(text, locale);
|
|
703
|
+
if (hit) {
|
|
704
|
+
monthFromName = hit.month;
|
|
705
|
+
text = hit.rest;
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
const nums = text.match(/\d+/g);
|
|
709
|
+
if (!nums && monthFromName === void 0) return null;
|
|
710
|
+
const order = (pattern.match(/yyyy|yy|MM|dd|HH|hh|mm|ss|M|d|H|h|m|s/g) ?? ["yyyy", "MM", "dd"]).map((t) => t.length === 2 ? t.charAt(0) + t.charAt(0) : t);
|
|
500
711
|
let y;
|
|
501
|
-
let
|
|
502
|
-
let
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
712
|
+
let mo = monthFromName;
|
|
713
|
+
let day;
|
|
714
|
+
let hh = 0;
|
|
715
|
+
let mm = 0;
|
|
716
|
+
let ss = 0;
|
|
717
|
+
let ni = 0;
|
|
718
|
+
for (const tok of order) {
|
|
719
|
+
if ((tok === "MM" || tok === "M") && monthFromName !== void 0) continue;
|
|
720
|
+
const n = Number((nums ?? [])[ni]);
|
|
721
|
+
ni += 1;
|
|
722
|
+
if (Number.isNaN(n)) continue;
|
|
723
|
+
if (tok === "yyyy" || tok === "yy") y = n < 100 ? 2e3 + n : n;
|
|
724
|
+
else if (tok === "MM" || tok === "M") mo = n - 1;
|
|
725
|
+
else if (tok === "dd" || tok === "d") day = n;
|
|
726
|
+
else if (tok === "HH" || tok === "H" || tok === "hh" || tok === "h") hh = n;
|
|
727
|
+
else if (tok === "mm" || tok === "m") mm = n;
|
|
728
|
+
else if (tok === "ss" || tok === "s") ss = n;
|
|
729
|
+
}
|
|
730
|
+
if (/pm/i.test(input) && hh < 12) hh += 12;
|
|
731
|
+
if (/am/i.test(input) && hh === 12) hh = 0;
|
|
732
|
+
if (y == null && day == null && mo == null) return null;
|
|
733
|
+
const d = new Date(y ?? (/* @__PURE__ */ new Date()).getFullYear(), mo ?? 0, day ?? 1, hh, mm, ss);
|
|
512
734
|
return Number.isNaN(d.getTime()) ? null : d;
|
|
513
735
|
}
|
|
514
736
|
function toDate(v) {
|
|
@@ -517,11 +739,14 @@ function toDate(v) {
|
|
|
517
739
|
const d = new Date(v);
|
|
518
740
|
return Number.isNaN(d.getTime()) ? null : startOfDay(d);
|
|
519
741
|
}
|
|
520
|
-
function monthMatrix(viewYear, viewMonth, firstDayOfWeek) {
|
|
742
|
+
function monthMatrix(viewYear, viewMonth, firstDayOfWeek, fixedWeeks = true) {
|
|
521
743
|
const first = new Date(viewYear, viewMonth, 1);
|
|
522
744
|
const offset = (first.getDay() - firstDayOfWeek + 7) % 7;
|
|
523
745
|
const start = addDays(first, -offset);
|
|
524
|
-
return Array.from({ length: 42 }, (_, i) => addDays(start, i));
|
|
746
|
+
if (fixedWeeks) return Array.from({ length: 42 }, (_, i) => addDays(start, i));
|
|
747
|
+
const last = new Date(viewYear, viewMonth + 1, 0);
|
|
748
|
+
const used = Math.ceil((offset + last.getDate()) / 7);
|
|
749
|
+
return Array.from({ length: used * 7 }, (_, i) => addDays(start, i));
|
|
525
750
|
}
|
|
526
751
|
function weekdayLabels(firstDayOfWeek, locale) {
|
|
527
752
|
const fmt = new Intl.DateTimeFormat(locale, { weekday: "short" });
|
|
@@ -530,6 +755,10 @@ function weekdayLabels(firstDayOfWeek, locale) {
|
|
|
530
755
|
(_, i) => fmt.format(new Date(2023, 0, 1 + (firstDayOfWeek + i) % 7))
|
|
531
756
|
);
|
|
532
757
|
}
|
|
758
|
+
function decadeGrid(year) {
|
|
759
|
+
const start = Math.floor(year / 10) * 10;
|
|
760
|
+
return { start, years: Array.from({ length: 12 }, (_, i) => start - 1 + i) };
|
|
761
|
+
}
|
|
533
762
|
function isoWeek(d) {
|
|
534
763
|
const date = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
|
|
535
764
|
const dayNum = (date.getUTCDay() + 6) % 7;
|
|
@@ -538,9 +767,40 @@ function isoWeek(d) {
|
|
|
538
767
|
const diff = date.getTime() - firstThursday.getTime();
|
|
539
768
|
return 1 + Math.round(diff / (7 * 24 * 3600 * 1e3));
|
|
540
769
|
}
|
|
770
|
+
|
|
771
|
+
// src/controls/DatePicker/calendar-range.ts
|
|
772
|
+
function normalizeRange(r) {
|
|
773
|
+
if (r.start && r.end && startOfDay(r.start) > startOfDay(r.end)) {
|
|
774
|
+
return { start: r.end, end: r.start };
|
|
775
|
+
}
|
|
776
|
+
return r;
|
|
777
|
+
}
|
|
778
|
+
function isRangeComplete(r) {
|
|
779
|
+
return !!r && !!r.start && !!r.end;
|
|
780
|
+
}
|
|
781
|
+
function isWithinRange(d, r) {
|
|
782
|
+
if (!isRangeComplete(r)) return false;
|
|
783
|
+
const t = startOfDay(d).getTime();
|
|
784
|
+
return t > startOfDay(r.start).getTime() && t < startOfDay(r.end).getTime();
|
|
785
|
+
}
|
|
786
|
+
var isRangeStart = (d, r) => !!r && isSameDay(d, r.start);
|
|
787
|
+
var isRangeEnd = (d, r) => !!r && isSameDay(d, r.end);
|
|
788
|
+
function previewRange(anchor, hover) {
|
|
789
|
+
if (!anchor || !hover) return null;
|
|
790
|
+
return normalizeRange({ start: anchor, end: hover });
|
|
791
|
+
}
|
|
792
|
+
function nextRange(current, d) {
|
|
793
|
+
if (!current.start || current.start && current.end) return { start: startOfDay(d), end: null };
|
|
794
|
+
return normalizeRange({ start: current.start, end: startOfDay(d) });
|
|
795
|
+
}
|
|
541
796
|
function Calendar({
|
|
542
797
|
value,
|
|
543
798
|
onSelect,
|
|
799
|
+
mode = "single",
|
|
800
|
+
selectedDates,
|
|
801
|
+
range,
|
|
802
|
+
previewRange: previewRange2,
|
|
803
|
+
onHoverDate,
|
|
544
804
|
minDate,
|
|
545
805
|
maxDate,
|
|
546
806
|
isDisabled,
|
|
@@ -550,16 +810,33 @@ function Calendar({
|
|
|
550
810
|
showToday,
|
|
551
811
|
showClear,
|
|
552
812
|
onClear,
|
|
553
|
-
autoFocus
|
|
813
|
+
autoFocus,
|
|
814
|
+
view: viewProp,
|
|
815
|
+
defaultView,
|
|
816
|
+
onViewChange,
|
|
817
|
+
precision = "day",
|
|
818
|
+
fixedWeeks = true,
|
|
819
|
+
defaultMonth,
|
|
820
|
+
numberOfMonths = 1
|
|
554
821
|
}) {
|
|
822
|
+
const panels = Math.max(1, Math.floor(numberOfMonths));
|
|
555
823
|
const today = startOfDay(/* @__PURE__ */ new Date());
|
|
556
|
-
const
|
|
557
|
-
const
|
|
824
|
+
const anchor = value ?? (mode === "range" ? range?.start ?? range?.end ?? null : null) ?? (mode === "multiple" ? selectedDates?.[0] ?? null : null) ?? defaultMonth ?? null;
|
|
825
|
+
const initial = anchor ?? clampDate(today, minDate, maxDate);
|
|
826
|
+
const [nav, setNav] = react.useState({ y: initial.getFullYear(), m: initial.getMonth() });
|
|
558
827
|
const [focused, setFocused] = react.useState(initial);
|
|
828
|
+
const [innerView, setInnerView] = react.useState(
|
|
829
|
+
defaultView ?? (precision === "day" ? "day" : precision)
|
|
830
|
+
);
|
|
831
|
+
const view = viewProp ?? innerView;
|
|
832
|
+
const setView = (v) => {
|
|
833
|
+
if (viewProp === void 0) setInnerView(v);
|
|
834
|
+
onViewChange?.(v);
|
|
835
|
+
};
|
|
559
836
|
const gridRef = react.useRef(null);
|
|
560
837
|
react.useEffect(() => {
|
|
561
838
|
if (value) {
|
|
562
|
-
|
|
839
|
+
setNav({ y: value.getFullYear(), m: value.getMonth() });
|
|
563
840
|
setFocused(value);
|
|
564
841
|
}
|
|
565
842
|
}, [value]);
|
|
@@ -568,94 +845,118 @@ function Calendar({
|
|
|
568
845
|
gridRef.current?.querySelector('[data-focused="true"]')?.focus();
|
|
569
846
|
}
|
|
570
847
|
}, [autoFocus]);
|
|
571
|
-
const cells = monthMatrix(view.y, view.m, firstDayOfWeek);
|
|
572
|
-
const weekdays = weekdayLabels(firstDayOfWeek, locale);
|
|
573
|
-
const monthName = new Intl.DateTimeFormat(locale, { month: "long", year: "numeric" }).format(
|
|
574
|
-
new Date(view.y, view.m, 1)
|
|
575
|
-
);
|
|
576
848
|
const outOfRange = (d) => minDate != null && d < startOfDay(minDate) || maxDate != null && d > startOfDay(maxDate) || Boolean(isDisabled?.(d));
|
|
577
|
-
const
|
|
578
|
-
const
|
|
579
|
-
|
|
580
|
-
|
|
849
|
+
const monthOutOfRange = (y, m) => {
|
|
850
|
+
const first = new Date(y, m, 1);
|
|
851
|
+
const last = new Date(y, m + 1, 0);
|
|
852
|
+
return maxDate != null && first > startOfDay(maxDate) || minDate != null && last < startOfDay(minDate);
|
|
853
|
+
};
|
|
854
|
+
const yearOutOfRange = (y) => maxDate != null && new Date(y, 0, 1) > startOfDay(maxDate) || minDate != null && new Date(y, 11, 31) < startOfDay(minDate);
|
|
855
|
+
const focusGrid = () => {
|
|
581
856
|
requestAnimationFrame(() => {
|
|
582
857
|
gridRef.current?.querySelector('[data-focused="true"]')?.focus();
|
|
583
858
|
});
|
|
584
859
|
};
|
|
585
|
-
const
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
next = addDays(focused, 6 - (focused.getDay() - firstDayOfWeek + 7) % 7);
|
|
595
|
-
else if (k === "PageUp") next = addMonths(focused, e.shiftKey ? -12 : -1);
|
|
596
|
-
else if (k === "PageDown") next = addMonths(focused, e.shiftKey ? 12 : 1);
|
|
597
|
-
else if (k === "Enter" || k === " ") {
|
|
598
|
-
e.preventDefault();
|
|
599
|
-
if (!outOfRange(focused)) onSelect(focused);
|
|
600
|
-
return;
|
|
601
|
-
} else return;
|
|
602
|
-
e.preventDefault();
|
|
603
|
-
goto(next);
|
|
860
|
+
const navIndex = nav.y * 12 + nav.m;
|
|
861
|
+
const goto = (d) => {
|
|
862
|
+
const c = clampDate(d, minDate, maxDate);
|
|
863
|
+
setFocused(c);
|
|
864
|
+
const ci = c.getFullYear() * 12 + c.getMonth();
|
|
865
|
+
if (ci < navIndex || ci > navIndex + panels - 1) {
|
|
866
|
+
setNav({ y: c.getFullYear(), m: c.getMonth() });
|
|
867
|
+
}
|
|
868
|
+
focusGrid();
|
|
604
869
|
};
|
|
605
|
-
const
|
|
606
|
-
const
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
870
|
+
const canDrillUp = view !== "year";
|
|
871
|
+
const dayTitle = () => {
|
|
872
|
+
const first = new Date(nav.y, nav.m, 1);
|
|
873
|
+
if (panels <= 1) {
|
|
874
|
+
return new Intl.DateTimeFormat(locale, { month: "long", year: "numeric" }).format(first);
|
|
875
|
+
}
|
|
876
|
+
const last = new Date(nav.y, nav.m + panels - 1, 1);
|
|
877
|
+
const f = new Intl.DateTimeFormat(locale, { month: "short" }).format(first);
|
|
878
|
+
const l = new Intl.DateTimeFormat(locale, { month: "short", year: "numeric" }).format(last);
|
|
879
|
+
return first.getFullYear() === last.getFullYear() ? `${f} \u2013 ${l}` : `${f} ${first.getFullYear()} \u2013 ${l}`;
|
|
880
|
+
};
|
|
881
|
+
const titleText = view === "day" ? dayTitle() : view === "month" ? String(nav.y) : (() => {
|
|
882
|
+
const g = decadeGrid(nav.y);
|
|
883
|
+
return `${g.start} \u2013 ${g.start + 9}`;
|
|
884
|
+
})();
|
|
885
|
+
const step = (dir) => {
|
|
886
|
+
if (view === "day") setNav((v) => ({ ...addMonthNav(v, dir) }));
|
|
887
|
+
else if (view === "month") setNav((v) => ({ ...v, y: v.y + dir }));
|
|
888
|
+
else setNav((v) => ({ ...v, y: v.y + dir * 10 }));
|
|
889
|
+
};
|
|
890
|
+
const header = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "orynn-calendar__header", children: [
|
|
891
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
892
|
+
"button",
|
|
893
|
+
{
|
|
894
|
+
type: "button",
|
|
895
|
+
className: "orynn-calendar__nav",
|
|
896
|
+
"aria-label": view === "day" ? "Previous month" : view === "month" ? "Previous year" : "Previous decade",
|
|
897
|
+
onClick: () => step(-1),
|
|
898
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronLeftIcon, {})
|
|
899
|
+
}
|
|
900
|
+
),
|
|
901
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
902
|
+
"button",
|
|
903
|
+
{
|
|
904
|
+
type: "button",
|
|
905
|
+
className: "orynn-calendar__title",
|
|
906
|
+
"aria-live": "polite",
|
|
907
|
+
disabled: !canDrillUp,
|
|
908
|
+
onClick: () => {
|
|
909
|
+
if (!canDrillUp) return;
|
|
910
|
+
setView(view === "day" ? "month" : "year");
|
|
911
|
+
},
|
|
912
|
+
children: titleText
|
|
913
|
+
}
|
|
914
|
+
),
|
|
915
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
916
|
+
"button",
|
|
917
|
+
{
|
|
918
|
+
type: "button",
|
|
919
|
+
className: "orynn-calendar__nav",
|
|
920
|
+
"aria-label": view === "day" ? "Next month" : view === "month" ? "Next year" : "Next decade",
|
|
921
|
+
onClick: () => step(1),
|
|
922
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronRightIcon, {})
|
|
923
|
+
}
|
|
924
|
+
)
|
|
925
|
+
] });
|
|
926
|
+
const dayGrid = (monthOffset = 0) => {
|
|
927
|
+
const panelMonth = new Date(nav.y, nav.m + monthOffset, 1);
|
|
928
|
+
const py = panelMonth.getFullYear();
|
|
929
|
+
const pm = panelMonth.getMonth();
|
|
930
|
+
const cells = monthMatrix(py, pm, firstDayOfWeek, fixedWeeks);
|
|
931
|
+
const weeks = cells.length / 7;
|
|
932
|
+
const weekdays = weekdayLabels(firstDayOfWeek, locale);
|
|
933
|
+
const monthName = new Intl.DateTimeFormat(locale, { month: "long", year: "numeric" }).format(
|
|
934
|
+
panelMonth
|
|
935
|
+
);
|
|
936
|
+
const onKeyDown = (e) => {
|
|
937
|
+
const k = e.key;
|
|
938
|
+
let next = null;
|
|
939
|
+
if (k === "ArrowLeft") next = addDays(focused, -1);
|
|
940
|
+
else if (k === "ArrowRight") next = addDays(focused, 1);
|
|
941
|
+
else if (k === "ArrowUp") next = addDays(focused, -7);
|
|
942
|
+
else if (k === "ArrowDown") next = addDays(focused, 7);
|
|
943
|
+
else if (k === "Home")
|
|
944
|
+
next = addDays(focused, -((focused.getDay() - firstDayOfWeek + 7) % 7));
|
|
945
|
+
else if (k === "End")
|
|
946
|
+
next = addDays(focused, 6 - (focused.getDay() - firstDayOfWeek + 7) % 7);
|
|
947
|
+
else if (k === "PageUp") next = addMonths(focused, e.shiftKey ? -12 : -1);
|
|
948
|
+
else if (k === "PageDown") next = addMonths(focused, e.shiftKey ? 12 : 1);
|
|
949
|
+
else if (k === "Enter" || k === " ") {
|
|
950
|
+
e.preventDefault();
|
|
951
|
+
if (!outOfRange(focused)) onSelect(focused);
|
|
952
|
+
return;
|
|
953
|
+
} else return;
|
|
954
|
+
e.preventDefault();
|
|
955
|
+
goto(next);
|
|
956
|
+
};
|
|
957
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
656
958
|
"table",
|
|
657
959
|
{
|
|
658
|
-
ref: gridRef,
|
|
659
960
|
className: "orynn-calendar__grid",
|
|
660
961
|
role: "grid",
|
|
661
962
|
"aria-label": monthName,
|
|
@@ -665,16 +966,29 @@ function Calendar({
|
|
|
665
966
|
showWeekNumbers && /* @__PURE__ */ jsxRuntime.jsx("th", { "aria-hidden": "true" }),
|
|
666
967
|
weekdays.map((w) => /* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", children: w }, w))
|
|
667
968
|
] }) }),
|
|
668
|
-
/* @__PURE__ */ jsxRuntime.jsx("tbody", { children: Array.from({ length:
|
|
969
|
+
/* @__PURE__ */ jsxRuntime.jsx("tbody", { onMouseLeave: onHoverDate ? () => onHoverDate(null) : void 0, children: Array.from({ length: weeks }, (_, week) => {
|
|
669
970
|
const row = cells.slice(week * 7, week * 7 + 7);
|
|
670
971
|
const firstOfRow = row[0];
|
|
671
972
|
return /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
|
|
672
973
|
showWeekNumbers && /* @__PURE__ */ jsxRuntime.jsx("td", { className: "orynn-calendar__weeknum", children: isoWeek(firstOfRow) }),
|
|
673
974
|
row.map((d) => {
|
|
674
|
-
const inMonth = d.getMonth() ===
|
|
975
|
+
const inMonth = d.getMonth() === pm;
|
|
675
976
|
const disabled = outOfRange(d);
|
|
676
|
-
const selected = isSameDay(d, value);
|
|
677
977
|
const isFocused = isSameDay(d, focused);
|
|
978
|
+
let selected;
|
|
979
|
+
let rangeStart = false;
|
|
980
|
+
let rangeEnd = false;
|
|
981
|
+
let inRange = false;
|
|
982
|
+
if (mode === "multiple") {
|
|
983
|
+
selected = (selectedDates ?? []).some((x) => isSameDay(x, d));
|
|
984
|
+
} else if (mode === "range") {
|
|
985
|
+
rangeStart = isRangeStart(d, range) || !!previewRange2 && isRangeStart(d, previewRange2);
|
|
986
|
+
rangeEnd = isRangeEnd(d, range) || !!previewRange2 && isRangeEnd(d, previewRange2);
|
|
987
|
+
inRange = isWithinRange(d, range) || !!previewRange2 && isWithinRange(d, previewRange2);
|
|
988
|
+
selected = rangeStart || rangeEnd;
|
|
989
|
+
} else {
|
|
990
|
+
selected = isSameDay(d, value);
|
|
991
|
+
}
|
|
678
992
|
return /* @__PURE__ */ jsxRuntime.jsx("td", { role: "gridcell", "aria-selected": selected, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
679
993
|
"button",
|
|
680
994
|
{
|
|
@@ -685,10 +999,15 @@ function Calendar({
|
|
|
685
999
|
"data-outside": !inMonth || void 0,
|
|
686
1000
|
"data-today": isSameDay(d, today) || void 0,
|
|
687
1001
|
"data-selected": selected || void 0,
|
|
1002
|
+
"data-range-start": rangeStart || void 0,
|
|
1003
|
+
"data-range-end": rangeEnd || void 0,
|
|
1004
|
+
"data-in-range": inRange || void 0,
|
|
688
1005
|
disabled,
|
|
689
1006
|
"aria-label": new Intl.DateTimeFormat(locale, { dateStyle: "full" }).format(
|
|
690
1007
|
d
|
|
691
1008
|
),
|
|
1009
|
+
onMouseEnter: onHoverDate ? () => onHoverDate(d) : void 0,
|
|
1010
|
+
onFocus: onHoverDate ? () => onHoverDate(d) : void 0,
|
|
692
1011
|
onClick: () => {
|
|
693
1012
|
setFocused(d);
|
|
694
1013
|
onSelect(d);
|
|
@@ -700,25 +1019,187 @@ function Calendar({
|
|
|
700
1019
|
] }, firstOfRow.toISOString());
|
|
701
1020
|
}) })
|
|
702
1021
|
]
|
|
1022
|
+
},
|
|
1023
|
+
`${py}-${pm}`
|
|
1024
|
+
);
|
|
1025
|
+
};
|
|
1026
|
+
const monthGrid = () => {
|
|
1027
|
+
const names = Array.from(
|
|
1028
|
+
{ length: 12 },
|
|
1029
|
+
(_, i) => new Intl.DateTimeFormat(locale, { month: "short" }).format(new Date(2021, i, 1))
|
|
1030
|
+
);
|
|
1031
|
+
const onKeyDown = (e) => {
|
|
1032
|
+
let m = nav.m;
|
|
1033
|
+
if (e.key === "ArrowLeft") m -= 1;
|
|
1034
|
+
else if (e.key === "ArrowRight") m += 1;
|
|
1035
|
+
else if (e.key === "ArrowUp") m -= 3;
|
|
1036
|
+
else if (e.key === "ArrowDown") m += 3;
|
|
1037
|
+
else if (e.key === "Enter" || e.key === " ") {
|
|
1038
|
+
e.preventDefault();
|
|
1039
|
+
pickMonth(nav.m);
|
|
1040
|
+
return;
|
|
1041
|
+
} else return;
|
|
1042
|
+
e.preventDefault();
|
|
1043
|
+
const d = addMonths(new Date(nav.y, nav.m, 1), m - nav.m);
|
|
1044
|
+
setNav({ y: d.getFullYear(), m: d.getMonth() });
|
|
1045
|
+
focusGrid();
|
|
1046
|
+
};
|
|
1047
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1048
|
+
"div",
|
|
1049
|
+
{
|
|
1050
|
+
className: "orynn-calendar__pickgrid",
|
|
1051
|
+
role: "grid",
|
|
1052
|
+
"aria-label": `Months of ${nav.y}`,
|
|
1053
|
+
onKeyDown,
|
|
1054
|
+
children: [0, 3, 6, 9].map((rowStart) => /* @__PURE__ */ jsxRuntime.jsx("div", { role: "row", className: "orynn-calendar__pickrow", children: names.slice(rowStart, rowStart + 3).map((name, j) => {
|
|
1055
|
+
const i = rowStart + j;
|
|
1056
|
+
const isFocused = i === nav.m;
|
|
1057
|
+
const selected = value != null && value.getFullYear() === nav.y && value.getMonth() === i;
|
|
1058
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1059
|
+
"button",
|
|
1060
|
+
{
|
|
1061
|
+
type: "button",
|
|
1062
|
+
className: "orynn-calendar__cell",
|
|
1063
|
+
tabIndex: isFocused ? 0 : -1,
|
|
1064
|
+
"data-focused": isFocused || void 0,
|
|
1065
|
+
"data-selected": selected || void 0,
|
|
1066
|
+
disabled: monthOutOfRange(nav.y, i),
|
|
1067
|
+
onClick: () => pickMonth(i),
|
|
1068
|
+
children: name
|
|
1069
|
+
},
|
|
1070
|
+
name
|
|
1071
|
+
);
|
|
1072
|
+
}) }, rowStart))
|
|
703
1073
|
}
|
|
704
|
-
)
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
1074
|
+
);
|
|
1075
|
+
};
|
|
1076
|
+
const pickMonth = (m) => {
|
|
1077
|
+
if (monthOutOfRange(nav.y, m)) return;
|
|
1078
|
+
setNav((v) => ({ ...v, m }));
|
|
1079
|
+
if (precision === "month") {
|
|
1080
|
+
onSelect(new Date(nav.y, m, 1));
|
|
1081
|
+
} else {
|
|
1082
|
+
setView("day");
|
|
1083
|
+
setFocused(clampDate(new Date(nav.y, m, 1), minDate, maxDate));
|
|
1084
|
+
focusGrid();
|
|
1085
|
+
}
|
|
1086
|
+
};
|
|
1087
|
+
const yearGrid = () => {
|
|
1088
|
+
const g = decadeGrid(nav.y);
|
|
1089
|
+
const onKeyDown = (e) => {
|
|
1090
|
+
let y = nav.y;
|
|
1091
|
+
if (e.key === "ArrowLeft") y -= 1;
|
|
1092
|
+
else if (e.key === "ArrowRight") y += 1;
|
|
1093
|
+
else if (e.key === "ArrowUp") y -= 3;
|
|
1094
|
+
else if (e.key === "ArrowDown") y += 3;
|
|
1095
|
+
else if (e.key === "Enter" || e.key === " ") {
|
|
1096
|
+
e.preventDefault();
|
|
1097
|
+
pickYear(nav.y);
|
|
1098
|
+
return;
|
|
1099
|
+
} else return;
|
|
1100
|
+
e.preventDefault();
|
|
1101
|
+
setNav((v) => ({ ...v, y }));
|
|
1102
|
+
focusGrid();
|
|
1103
|
+
};
|
|
1104
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1105
|
+
"div",
|
|
1106
|
+
{
|
|
1107
|
+
className: "orynn-calendar__pickgrid",
|
|
1108
|
+
role: "grid",
|
|
1109
|
+
"aria-label": `Years ${g.start}\u2013${g.start + 9}`,
|
|
1110
|
+
onKeyDown,
|
|
1111
|
+
children: [0, 3, 6, 9].map((rowStart) => /* @__PURE__ */ jsxRuntime.jsx("div", { role: "row", className: "orynn-calendar__pickrow", children: g.years.slice(rowStart, rowStart + 3).map((y) => {
|
|
1112
|
+
const isFocused = y === nav.y;
|
|
1113
|
+
const selected = value != null && value.getFullYear() === y;
|
|
1114
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1115
|
+
"button",
|
|
1116
|
+
{
|
|
1117
|
+
type: "button",
|
|
1118
|
+
className: "orynn-calendar__cell",
|
|
1119
|
+
tabIndex: isFocused ? 0 : -1,
|
|
1120
|
+
"data-focused": isFocused || void 0,
|
|
1121
|
+
"data-outside": y < g.start || y > g.start + 9 || void 0,
|
|
1122
|
+
"data-selected": selected || void 0,
|
|
1123
|
+
disabled: yearOutOfRange(y),
|
|
1124
|
+
onClick: () => pickYear(y),
|
|
1125
|
+
children: y
|
|
1126
|
+
},
|
|
1127
|
+
y
|
|
1128
|
+
);
|
|
1129
|
+
}) }, rowStart))
|
|
1130
|
+
}
|
|
1131
|
+
);
|
|
1132
|
+
};
|
|
1133
|
+
const pickYear = (y) => {
|
|
1134
|
+
if (yearOutOfRange(y)) return;
|
|
1135
|
+
setNav((v) => ({ ...v, y }));
|
|
1136
|
+
if (precision === "year") {
|
|
1137
|
+
onSelect(new Date(y, 0, 1));
|
|
1138
|
+
} else {
|
|
1139
|
+
setView("month");
|
|
1140
|
+
focusGrid();
|
|
1141
|
+
}
|
|
1142
|
+
};
|
|
1143
|
+
const dayView = panels <= 1 ? dayGrid() : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "orynn-calendar__panels", children: Array.from({ length: panels }, (_, i) => dayGrid(i)) });
|
|
1144
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1145
|
+
"div",
|
|
1146
|
+
{
|
|
1147
|
+
className: "orynn-calendar",
|
|
1148
|
+
ref: gridRef,
|
|
1149
|
+
"data-view": view,
|
|
1150
|
+
"data-months": panels > 1 ? panels : void 0,
|
|
1151
|
+
children: [
|
|
1152
|
+
header,
|
|
1153
|
+
" ",
|
|
1154
|
+
view === "day" ? dayView : view === "month" ? monthGrid() : yearGrid(),
|
|
1155
|
+
(showToday || showClear) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "orynn-calendar__footer", children: [
|
|
1156
|
+
showToday ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1157
|
+
"button",
|
|
1158
|
+
{
|
|
1159
|
+
type: "button",
|
|
1160
|
+
className: "orynn-calendar__action",
|
|
1161
|
+
disabled: outOfRange(today),
|
|
1162
|
+
onClick: () => onSelect(today),
|
|
1163
|
+
children: "Today"
|
|
1164
|
+
}
|
|
1165
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("span", {}),
|
|
1166
|
+
showClear && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "orynn-calendar__action", onClick: onClear, children: "Clear" })
|
|
1167
|
+
] })
|
|
1168
|
+
]
|
|
1169
|
+
}
|
|
1170
|
+
);
|
|
1171
|
+
}
|
|
1172
|
+
function addMonthNav(v, dir) {
|
|
1173
|
+
const total = v.y * 12 + v.m + dir;
|
|
1174
|
+
return { y: Math.floor(total / 12), m: (total % 12 + 12) % 12 };
|
|
719
1175
|
}
|
|
1176
|
+
|
|
1177
|
+
// src/controls/DatePicker/time-utils.ts
|
|
1178
|
+
var timeParts = (d) => ({
|
|
1179
|
+
h: d.getHours(),
|
|
1180
|
+
m: d.getMinutes(),
|
|
1181
|
+
s: d.getSeconds()
|
|
1182
|
+
});
|
|
1183
|
+
function withTime(date, time) {
|
|
1184
|
+
const r = new Date(date);
|
|
1185
|
+
r.setHours(time.h, time.m, time.s, 0);
|
|
1186
|
+
return r;
|
|
1187
|
+
}
|
|
1188
|
+
function minuteOptions(step) {
|
|
1189
|
+
const s = Math.max(1, Math.min(30, Math.floor(step)));
|
|
1190
|
+
const out = [];
|
|
1191
|
+
for (let m = 0; m < 60; m += s) out.push(m);
|
|
1192
|
+
return out;
|
|
1193
|
+
}
|
|
1194
|
+
var pad2 = (n) => String(n).padStart(2, "0");
|
|
1195
|
+
var normDates = (v) => Array.isArray(v) ? v.map((x) => toDate(x)).filter(Boolean) : [];
|
|
1196
|
+
var normRange = (v) => {
|
|
1197
|
+
const r = v ?? {};
|
|
1198
|
+
return { start: toDate(r.start ?? null), end: toDate(r.end ?? null) };
|
|
1199
|
+
};
|
|
720
1200
|
var DatePicker = /* @__PURE__ */ react.forwardRef(
|
|
721
|
-
function DatePicker2(
|
|
1201
|
+
function DatePicker2(propsIn, ref) {
|
|
1202
|
+
const props = propsIn;
|
|
722
1203
|
const {
|
|
723
1204
|
label,
|
|
724
1205
|
description,
|
|
@@ -736,6 +1217,7 @@ var DatePicker = /* @__PURE__ */ react.forwardRef(
|
|
|
736
1217
|
id: idProp,
|
|
737
1218
|
name,
|
|
738
1219
|
className,
|
|
1220
|
+
mode = "single",
|
|
739
1221
|
value: valueProp,
|
|
740
1222
|
defaultValue,
|
|
741
1223
|
onChange,
|
|
@@ -743,46 +1225,123 @@ var DatePicker = /* @__PURE__ */ react.forwardRef(
|
|
|
743
1225
|
minDate,
|
|
744
1226
|
maxDate,
|
|
745
1227
|
disabledDates,
|
|
1228
|
+
isDateUnavailable,
|
|
746
1229
|
firstDayOfWeek = 0,
|
|
747
1230
|
locale,
|
|
748
1231
|
showWeekNumbers,
|
|
749
1232
|
showToday = true,
|
|
750
1233
|
showClear,
|
|
1234
|
+
defaultView,
|
|
1235
|
+
precision = "day",
|
|
1236
|
+
fixedWeeks = true,
|
|
1237
|
+
numberOfMonths,
|
|
1238
|
+
showTime = false,
|
|
1239
|
+
timeStep = 5,
|
|
1240
|
+
defaultMonth,
|
|
1241
|
+
presets,
|
|
751
1242
|
inline = false,
|
|
752
1243
|
allowInput = true,
|
|
753
|
-
closeOnSelect
|
|
1244
|
+
closeOnSelect: closeOnSelectProp,
|
|
1245
|
+
open: openProp,
|
|
1246
|
+
defaultOpen = false,
|
|
1247
|
+
onOpenChange,
|
|
754
1248
|
placeholder
|
|
755
1249
|
} = props;
|
|
756
1250
|
const reactId = react.useId();
|
|
757
1251
|
const id = idProp ?? reactId;
|
|
758
1252
|
const panelId = `${id}-cal`;
|
|
1253
|
+
const withTimePicker = showTime && mode === "single";
|
|
1254
|
+
const closeOnSelect = closeOnSelectProp ?? !withTimePicker;
|
|
1255
|
+
const fmt = withTimePicker && format === "yyyy-MM-dd" ? "yyyy-MM-dd HH:mm" : format;
|
|
759
1256
|
const isControlled = valueProp !== void 0;
|
|
760
|
-
const [
|
|
761
|
-
const
|
|
762
|
-
const
|
|
1257
|
+
const [innerRaw, setInnerRaw] = react.useState(() => defaultValue ?? null);
|
|
1258
|
+
const raw = isControlled ? valueProp : innerRaw;
|
|
1259
|
+
const toDateKeepTime = (v) => {
|
|
1260
|
+
if (v == null) return null;
|
|
1261
|
+
const d = new Date(v);
|
|
1262
|
+
return Number.isNaN(d.getTime()) ? null : d;
|
|
1263
|
+
};
|
|
1264
|
+
const curDate = mode === "single" ? withTimePicker ? toDateKeepTime(raw) : toDate(raw) : null;
|
|
1265
|
+
const curRange = mode === "range" ? normRange(raw) : { start: null, end: null };
|
|
1266
|
+
const curDates = mode === "multiple" ? normDates(raw) : [];
|
|
1267
|
+
const commit = (next) => {
|
|
1268
|
+
if (!isControlled) {
|
|
1269
|
+
setInnerRaw(next);
|
|
1270
|
+
}
|
|
1271
|
+
onChange?.(next);
|
|
1272
|
+
};
|
|
1273
|
+
const openIsControlled = openProp !== void 0;
|
|
1274
|
+
const [innerOpen, setInnerOpen] = react.useState(defaultOpen);
|
|
1275
|
+
const open = openIsControlled ? openProp : innerOpen;
|
|
1276
|
+
const setOpen = (next) => {
|
|
1277
|
+
if (!openIsControlled) setInnerOpen(next);
|
|
1278
|
+
onOpenChange?.(next);
|
|
1279
|
+
};
|
|
763
1280
|
const [gridFocus, setGridFocus] = react.useState(false);
|
|
764
|
-
const [
|
|
1281
|
+
const [hoverDate, setHoverDate] = react.useState(null);
|
|
1282
|
+
const displayText = () => {
|
|
1283
|
+
if (mode === "single") return curDate ? formatDate(curDate, fmt, locale) : "";
|
|
1284
|
+
if (mode === "multiple") {
|
|
1285
|
+
if (curDates.length === 0) return "";
|
|
1286
|
+
if (curDates.length === 1) return formatDate(curDates[0], fmt, locale);
|
|
1287
|
+
return `${curDates.length} selected`;
|
|
1288
|
+
}
|
|
1289
|
+
if (!curRange.start && !curRange.end) return "";
|
|
1290
|
+
const s = curRange.start ? formatDate(curRange.start, fmt, locale) : "\u2026";
|
|
1291
|
+
const e = curRange.end ? formatDate(curRange.end, fmt, locale) : "\u2026";
|
|
1292
|
+
return `${s} \u2013 ${e}`;
|
|
1293
|
+
};
|
|
1294
|
+
const [text, setText] = react.useState(displayText);
|
|
765
1295
|
const boxRef = react.useRef(null);
|
|
766
1296
|
const inputRef = react.useRef(null);
|
|
1297
|
+
const skipFocusOpen = react.useRef(false);
|
|
1298
|
+
const valueKey = [
|
|
1299
|
+
mode,
|
|
1300
|
+
typeof fmt === "string" ? fmt : JSON.stringify(fmt),
|
|
1301
|
+
locale ?? "",
|
|
1302
|
+
curDate?.getTime() ?? "",
|
|
1303
|
+
curRange.start?.getTime() ?? "",
|
|
1304
|
+
curRange.end?.getTime() ?? "",
|
|
1305
|
+
curDates.map((d) => d.getTime()).join(",")
|
|
1306
|
+
].join("|");
|
|
767
1307
|
react.useEffect(() => {
|
|
768
|
-
setText(
|
|
769
|
-
}, [
|
|
1308
|
+
setText(displayText());
|
|
1309
|
+
}, [valueKey]);
|
|
770
1310
|
const isDisabledDate = (d) => {
|
|
1311
|
+
if (isDateUnavailable?.(d)) return true;
|
|
771
1312
|
if (Array.isArray(disabledDates))
|
|
772
1313
|
return disabledDates.some((x) => isSameDay(startOfDay(x), d));
|
|
773
1314
|
return Boolean(disabledDates?.(d));
|
|
774
1315
|
};
|
|
775
|
-
const
|
|
776
|
-
|
|
777
|
-
|
|
1316
|
+
const closeAndRefocus = () => {
|
|
1317
|
+
setOpen(false);
|
|
1318
|
+
setGridFocus(false);
|
|
1319
|
+
skipFocusOpen.current = true;
|
|
1320
|
+
inputRef.current?.focus();
|
|
778
1321
|
};
|
|
779
1322
|
const select = (d) => {
|
|
780
1323
|
if (isDisabledDate(d)) return;
|
|
781
|
-
|
|
782
|
-
if (
|
|
783
|
-
|
|
784
|
-
|
|
1324
|
+
const day = startOfDay(d);
|
|
1325
|
+
if (mode === "single") {
|
|
1326
|
+
const picked = withTimePicker ? withTime(day, curDate ? timeParts(curDate) : { h: 0, m: 0, s: 0 }) : day;
|
|
1327
|
+
commit(picked);
|
|
1328
|
+
if (closeOnSelect) closeAndRefocus();
|
|
1329
|
+
return;
|
|
1330
|
+
}
|
|
1331
|
+
if (mode === "multiple") {
|
|
1332
|
+
const has = curDates.some((x) => isSameDay(x, day));
|
|
1333
|
+
commit(has ? curDates.filter((x) => !isSameDay(x, day)) : [...curDates, day]);
|
|
1334
|
+
return;
|
|
785
1335
|
}
|
|
1336
|
+
const next = nextRange(curRange, day);
|
|
1337
|
+
commit(next);
|
|
1338
|
+
if (isRangeComplete(next) && closeOnSelect) closeAndRefocus();
|
|
1339
|
+
};
|
|
1340
|
+
const clearValue = () => {
|
|
1341
|
+
if (mode === "single") commit(null);
|
|
1342
|
+
else if (mode === "multiple") commit([]);
|
|
1343
|
+
else commit({ start: null, end: null });
|
|
1344
|
+
onClear?.();
|
|
786
1345
|
};
|
|
787
1346
|
const onKeyDown = (e) => {
|
|
788
1347
|
if (disabled || readOnly) return;
|
|
@@ -793,31 +1352,96 @@ var DatePicker = /* @__PURE__ */ react.forwardRef(
|
|
|
793
1352
|
} else if (e.key === "Escape" && open) {
|
|
794
1353
|
e.preventDefault();
|
|
795
1354
|
setOpen(false);
|
|
796
|
-
} else if (e.key === "Enter") {
|
|
797
|
-
const parsed = parseDate(text,
|
|
1355
|
+
} else if (e.key === "Enter" && mode === "single") {
|
|
1356
|
+
const parsed = parseDate(text, fmt, locale);
|
|
798
1357
|
if (parsed && !isDisabledDate(startOfDay(parsed))) select(parsed);
|
|
799
1358
|
}
|
|
800
1359
|
};
|
|
801
|
-
const
|
|
1360
|
+
const preview = mode === "range" && curRange.start && !curRange.end ? previewRange(curRange.start, hoverDate) : null;
|
|
1361
|
+
const applyPreset = (p) => {
|
|
1362
|
+
const resolved = p.getValue ? p.getValue() : p.value;
|
|
1363
|
+
if (resolved == null) return;
|
|
1364
|
+
commit(resolved);
|
|
1365
|
+
if (closeOnSelect && !inline) closeAndRefocus();
|
|
1366
|
+
};
|
|
1367
|
+
const setTimeField = (part, n) => {
|
|
1368
|
+
const base2 = curDate ?? startOfDay(/* @__PURE__ */ new Date());
|
|
1369
|
+
const t = timeParts(base2);
|
|
1370
|
+
commit(withTime(base2, { ...t, [part]: n, s: 0 }));
|
|
1371
|
+
};
|
|
1372
|
+
const timeColumn = withTimePicker ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "orynn-datepicker__time", children: [
|
|
1373
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-datepicker__time-label", children: "Time" }),
|
|
1374
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "orynn-datepicker__time-fields", children: [
|
|
1375
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1376
|
+
"select",
|
|
1377
|
+
{
|
|
1378
|
+
"aria-label": "Hour",
|
|
1379
|
+
className: "orynn-datepicker__time-select",
|
|
1380
|
+
value: curDate ? curDate.getHours() : 0,
|
|
1381
|
+
onChange: (e) => setTimeField("h", Number(e.target.value)),
|
|
1382
|
+
children: Array.from({ length: 24 }, (_, h) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: h, children: pad2(h) }, h))
|
|
1383
|
+
}
|
|
1384
|
+
),
|
|
1385
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: ":" }),
|
|
1386
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1387
|
+
"select",
|
|
1388
|
+
{
|
|
1389
|
+
"aria-label": "Minute",
|
|
1390
|
+
className: "orynn-datepicker__time-select",
|
|
1391
|
+
value: curDate ? curDate.getMinutes() - curDate.getMinutes() % timeStep : 0,
|
|
1392
|
+
onChange: (e) => setTimeField("m", Number(e.target.value)),
|
|
1393
|
+
children: minuteOptions(timeStep).map((m) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: m, children: pad2(m) }, m))
|
|
1394
|
+
}
|
|
1395
|
+
)
|
|
1396
|
+
] })
|
|
1397
|
+
] }) : null;
|
|
1398
|
+
const calendar = /* @__PURE__ */ jsxRuntime.jsx(
|
|
802
1399
|
Calendar,
|
|
803
1400
|
{
|
|
804
|
-
value,
|
|
1401
|
+
value: curDate,
|
|
805
1402
|
onSelect: select,
|
|
1403
|
+
mode,
|
|
1404
|
+
selectedDates: mode === "multiple" ? curDates : void 0,
|
|
1405
|
+
range: mode === "range" ? curRange : void 0,
|
|
1406
|
+
previewRange: preview,
|
|
1407
|
+
onHoverDate: mode === "range" ? setHoverDate : void 0,
|
|
806
1408
|
minDate,
|
|
807
1409
|
maxDate,
|
|
808
1410
|
isDisabled: isDisabledDate,
|
|
809
1411
|
firstDayOfWeek,
|
|
810
1412
|
locale,
|
|
811
1413
|
showWeekNumbers,
|
|
812
|
-
showToday,
|
|
1414
|
+
showToday: showToday && mode === "single",
|
|
813
1415
|
showClear,
|
|
1416
|
+
defaultView,
|
|
1417
|
+
precision,
|
|
1418
|
+
fixedWeeks,
|
|
1419
|
+
numberOfMonths,
|
|
1420
|
+
defaultMonth,
|
|
814
1421
|
onClear: () => {
|
|
815
|
-
|
|
1422
|
+
clearValue();
|
|
816
1423
|
setOpen(false);
|
|
817
1424
|
},
|
|
818
1425
|
autoFocus: open && gridFocus || inline
|
|
819
1426
|
}
|
|
820
1427
|
);
|
|
1428
|
+
const body = timeColumn ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "orynn-datepicker__withtime", children: [
|
|
1429
|
+
calendar,
|
|
1430
|
+
timeColumn
|
|
1431
|
+
] }) : calendar;
|
|
1432
|
+
const cal = presets && presets.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "orynn-datepicker__panel", children: [
|
|
1433
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "orynn-datepicker__presets", children: presets.map((p) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1434
|
+
"button",
|
|
1435
|
+
{
|
|
1436
|
+
type: "button",
|
|
1437
|
+
className: "orynn-datepicker__preset",
|
|
1438
|
+
onClick: () => applyPreset(p),
|
|
1439
|
+
children: p.label
|
|
1440
|
+
},
|
|
1441
|
+
p.label
|
|
1442
|
+
)) }),
|
|
1443
|
+
body
|
|
1444
|
+
] }) : body;
|
|
821
1445
|
if (inline) {
|
|
822
1446
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
823
1447
|
Field,
|
|
@@ -834,7 +1458,8 @@ var DatePicker = /* @__PURE__ */ react.forwardRef(
|
|
|
834
1458
|
}
|
|
835
1459
|
);
|
|
836
1460
|
}
|
|
837
|
-
const hasValue =
|
|
1461
|
+
const hasValue = mode === "single" ? curDate != null : mode === "multiple" ? curDates.length > 0 : Boolean(curRange.start || curRange.end);
|
|
1462
|
+
const typingAllowed = mode === "single" && allowInput && !readOnly;
|
|
838
1463
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
839
1464
|
Field,
|
|
840
1465
|
{
|
|
@@ -869,10 +1494,7 @@ var DatePicker = /* @__PURE__ */ react.forwardRef(
|
|
|
869
1494
|
className: "orynn-box__iconbtn",
|
|
870
1495
|
"aria-label": "Clear",
|
|
871
1496
|
tabIndex: -1,
|
|
872
|
-
onClick:
|
|
873
|
-
commit(null);
|
|
874
|
-
onClear?.();
|
|
875
|
-
},
|
|
1497
|
+
onClick: clearValue,
|
|
876
1498
|
children: /* @__PURE__ */ jsxRuntime.jsx(XIcon, {})
|
|
877
1499
|
}
|
|
878
1500
|
),
|
|
@@ -888,7 +1510,7 @@ var DatePicker = /* @__PURE__ */ react.forwardRef(
|
|
|
888
1510
|
onClick: () => {
|
|
889
1511
|
if (disabled || readOnly) return;
|
|
890
1512
|
setGridFocus(true);
|
|
891
|
-
setOpen(
|
|
1513
|
+
setOpen(!open);
|
|
892
1514
|
},
|
|
893
1515
|
children: /* @__PURE__ */ jsxRuntime.jsx(CalendarIcon, {})
|
|
894
1516
|
}
|
|
@@ -907,7 +1529,7 @@ var DatePicker = /* @__PURE__ */ react.forwardRef(
|
|
|
907
1529
|
name,
|
|
908
1530
|
className: "orynn-box__field",
|
|
909
1531
|
type: "text",
|
|
910
|
-
inputMode: "numeric",
|
|
1532
|
+
inputMode: typingAllowed ? "numeric" : void 0,
|
|
911
1533
|
autoComplete: "off",
|
|
912
1534
|
role: "combobox",
|
|
913
1535
|
"aria-expanded": open,
|
|
@@ -917,19 +1539,26 @@ var DatePicker = /* @__PURE__ */ react.forwardRef(
|
|
|
917
1539
|
"aria-describedby": describedById,
|
|
918
1540
|
value: text,
|
|
919
1541
|
disabled,
|
|
920
|
-
readOnly: !
|
|
1542
|
+
readOnly: !typingAllowed,
|
|
921
1543
|
required,
|
|
922
|
-
placeholder: floatingLabel ? void 0 : placeholder ??
|
|
1544
|
+
placeholder: floatingLabel ? void 0 : placeholder ?? (typeof fmt === "string" ? fmt.toLowerCase() : void 0),
|
|
923
1545
|
onChange: (e) => setText(e.target.value),
|
|
924
1546
|
onKeyDown,
|
|
925
|
-
onFocus: () =>
|
|
1547
|
+
onFocus: () => {
|
|
1548
|
+
if (skipFocusOpen.current) {
|
|
1549
|
+
skipFocusOpen.current = false;
|
|
1550
|
+
return;
|
|
1551
|
+
}
|
|
1552
|
+
setOpen(true);
|
|
1553
|
+
},
|
|
926
1554
|
onBlur: () => {
|
|
927
|
-
|
|
1555
|
+
if (mode !== "single") return;
|
|
1556
|
+
const parsed = parseDate(text, fmt, locale);
|
|
928
1557
|
if (parsed && !isDisabledDate(startOfDay(parsed))) {
|
|
929
1558
|
commit(startOfDay(parsed));
|
|
930
|
-
setText(formatDate(startOfDay(parsed),
|
|
1559
|
+
setText(formatDate(startOfDay(parsed), fmt, locale));
|
|
931
1560
|
} else {
|
|
932
|
-
setText(
|
|
1561
|
+
setText(curDate ? formatDate(curDate, fmt, locale) : "");
|
|
933
1562
|
}
|
|
934
1563
|
}
|
|
935
1564
|
}
|
|
@@ -956,7 +1585,13 @@ var DatePicker = /* @__PURE__ */ react.forwardRef(
|
|
|
956
1585
|
);
|
|
957
1586
|
}
|
|
958
1587
|
);
|
|
1588
|
+
var CREATE_VALUE = "\0orynn-create";
|
|
959
1589
|
var toArray = (v) => v == null ? [] : Array.isArray(v) ? v : [v];
|
|
1590
|
+
var isGrouped = (o) => {
|
|
1591
|
+
const first = o[0];
|
|
1592
|
+
return first != null && "items" in first && Array.isArray(first.items);
|
|
1593
|
+
};
|
|
1594
|
+
var flattenOptions = (o) => isGrouped(o) ? o.flatMap((g) => g.items.map((it) => ({ ...it, group: it.group ?? g.group }))) : o;
|
|
960
1595
|
function Highlight({ text, query }) {
|
|
961
1596
|
if (!query) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: text });
|
|
962
1597
|
const i = text.toLowerCase().indexOf(query.toLowerCase());
|
|
@@ -998,52 +1633,103 @@ var Dropdown = /* @__PURE__ */ react.forwardRef(
|
|
|
998
1633
|
highlightMatch,
|
|
999
1634
|
renderOption,
|
|
1000
1635
|
renderValue,
|
|
1636
|
+
renderGroupLabel,
|
|
1001
1637
|
placeholder,
|
|
1002
1638
|
emptyMessage = "No results",
|
|
1639
|
+
loadingMessage = "Loading\u2026",
|
|
1003
1640
|
closeOnSelect = !multiple,
|
|
1004
1641
|
maxSelectedLabels,
|
|
1642
|
+
maxValues,
|
|
1643
|
+
hidePickedOptions = false,
|
|
1644
|
+
showSelectAll = false,
|
|
1005
1645
|
native = false,
|
|
1006
|
-
startContent
|
|
1646
|
+
startContent,
|
|
1647
|
+
creatable = false,
|
|
1648
|
+
onCreate,
|
|
1649
|
+
isValidNewOption,
|
|
1650
|
+
formatCreateLabel,
|
|
1651
|
+
createPosition = "last",
|
|
1652
|
+
onSearch,
|
|
1653
|
+
searchDebounce = 0,
|
|
1654
|
+
open: openProp,
|
|
1655
|
+
defaultOpen = false,
|
|
1656
|
+
onOpenChange,
|
|
1657
|
+
maxHeight
|
|
1007
1658
|
} = props;
|
|
1008
1659
|
const reactId = react.useId();
|
|
1009
1660
|
const id = idProp ?? reactId;
|
|
1010
1661
|
const listId = `${id}-listbox`;
|
|
1011
|
-
const
|
|
1012
|
-
const [
|
|
1013
|
-
const
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1662
|
+
const baseOptions = react.useMemo(() => flattenOptions(options), [options]);
|
|
1663
|
+
const [createdOptions, setCreatedOptions] = react.useState([]);
|
|
1664
|
+
const allOptions = react.useMemo(
|
|
1665
|
+
() => [...baseOptions, ...createdOptions],
|
|
1666
|
+
[baseOptions, createdOptions]
|
|
1667
|
+
);
|
|
1668
|
+
const [selectedValues, setSelectedValues] = useControllableState({
|
|
1669
|
+
value: valueProp === void 0 ? void 0 : toArray(valueProp),
|
|
1670
|
+
defaultValue: toArray(defaultValue),
|
|
1671
|
+
onChange: void 0
|
|
1672
|
+
});
|
|
1673
|
+
const commit = (next) => {
|
|
1674
|
+
setSelectedValues(next);
|
|
1675
|
+
onChange?.(multiple ? next : next[0] ?? null);
|
|
1676
|
+
};
|
|
1677
|
+
const openIsControlled = openProp !== void 0;
|
|
1678
|
+
const [innerOpen, setInnerOpen] = react.useState(defaultOpen);
|
|
1679
|
+
const open = openIsControlled ? openProp : innerOpen;
|
|
1680
|
+
const setOpen = (next) => {
|
|
1681
|
+
if (!openIsControlled) setInnerOpen(next);
|
|
1682
|
+
onOpenChange?.(next);
|
|
1017
1683
|
};
|
|
1018
|
-
const [open, setOpen] = react.useState(false);
|
|
1019
1684
|
const [query, setQuery] = react.useState("");
|
|
1020
1685
|
const [activeIndex, setActiveIndex] = react.useState(0);
|
|
1021
1686
|
const boxRef = react.useRef(null);
|
|
1022
1687
|
const inputRef = react.useRef(null);
|
|
1023
1688
|
const listRef = react.useRef(null);
|
|
1024
|
-
const byValue = react.useMemo(() => new Map(
|
|
1025
|
-
const selectedOptions = selectedValues.map((v) => byValue.get(v)).filter(Boolean);
|
|
1689
|
+
const byValue = react.useMemo(() => new Map(allOptions.map((o) => [o.value, o])), [allOptions]);
|
|
1690
|
+
const selectedOptions = selectedValues.map((v) => byValue.get(v) ?? { label: v, value: v }).filter(Boolean);
|
|
1691
|
+
react.useEffect(() => {
|
|
1692
|
+
if (!onSearch) return;
|
|
1693
|
+
const t = setTimeout(() => onSearch(query), searchDebounce);
|
|
1694
|
+
return () => clearTimeout(t);
|
|
1695
|
+
}, [query, onSearch, searchDebounce]);
|
|
1026
1696
|
const filtered = react.useMemo(() => {
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1697
|
+
let list = allOptions;
|
|
1698
|
+
if (searchable && query && !onSearch) {
|
|
1699
|
+
const q = query.toLowerCase();
|
|
1700
|
+
const match = filterFn ?? ((o) => filterMode === "startsWith" ? o.label.toLowerCase().startsWith(q) : o.label.toLowerCase().includes(q));
|
|
1701
|
+
list = list.filter((o) => match(o, query));
|
|
1702
|
+
}
|
|
1703
|
+
if (multiple && hidePickedOptions) {
|
|
1704
|
+
list = list.filter((o) => !selectedValues.includes(o.value));
|
|
1705
|
+
}
|
|
1706
|
+
return list;
|
|
1707
|
+
}, [
|
|
1708
|
+
allOptions,
|
|
1709
|
+
searchable,
|
|
1710
|
+
query,
|
|
1711
|
+
onSearch,
|
|
1712
|
+
filterMode,
|
|
1713
|
+
filterFn,
|
|
1714
|
+
multiple,
|
|
1715
|
+
hidePickedOptions,
|
|
1716
|
+
selectedValues
|
|
1717
|
+
]);
|
|
1718
|
+
const showCreateRow = creatable && searchable && query.trim().length > 0 && (isValidNewOption ? isValidNewOption(query.trim(), allOptions) : !allOptions.some((o) => o.label.toLowerCase() === query.trim().toLowerCase()));
|
|
1719
|
+
const createRow = { value: CREATE_VALUE, label: query.trim() };
|
|
1720
|
+
const selectableOptions = showCreateRow ? createPosition === "first" ? [createRow, ...filtered] : [...filtered, createRow] : filtered;
|
|
1032
1721
|
const rows = react.useMemo(() => {
|
|
1033
1722
|
const out = [];
|
|
1034
1723
|
let seenGroup;
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
if (o.group && o.group !== seenGroup) {
|
|
1724
|
+
selectableOptions.forEach((o, optionIndex) => {
|
|
1725
|
+
if (o.value !== CREATE_VALUE && o.group && o.group !== seenGroup) {
|
|
1038
1726
|
seenGroup = o.group;
|
|
1039
1727
|
out.push({ type: "group", label: o.group });
|
|
1040
1728
|
}
|
|
1041
1729
|
out.push({ type: "option", option: o, optionIndex });
|
|
1042
|
-
|
|
1043
|
-
}
|
|
1730
|
+
});
|
|
1044
1731
|
return out;
|
|
1045
|
-
}, [
|
|
1046
|
-
const selectableOptions = filtered;
|
|
1732
|
+
}, [selectableOptions]);
|
|
1047
1733
|
react.useEffect(() => {
|
|
1048
1734
|
setActiveIndex((i) => Math.min(Math.max(0, i), Math.max(0, selectableOptions.length - 1)));
|
|
1049
1735
|
}, [selectableOptions.length]);
|
|
@@ -1064,10 +1750,34 @@ var Dropdown = /* @__PURE__ */ react.forwardRef(
|
|
|
1064
1750
|
setActiveIndex(firstRelevantIndex());
|
|
1065
1751
|
setOpen(true);
|
|
1066
1752
|
};
|
|
1753
|
+
const handleCreate = (raw) => {
|
|
1754
|
+
const input = raw.trim();
|
|
1755
|
+
if (!input) return;
|
|
1756
|
+
onCreate?.(input);
|
|
1757
|
+
setCreatedOptions(
|
|
1758
|
+
(prev) => prev.some((o) => o.value === input) || baseOptions.some((o) => o.value === input) ? prev : [...prev, { label: input, value: input }]
|
|
1759
|
+
);
|
|
1760
|
+
if (multiple) {
|
|
1761
|
+
if (maxValues != null && selectedValues.length >= maxValues) return;
|
|
1762
|
+
commit([...selectedValues, input]);
|
|
1763
|
+
} else {
|
|
1764
|
+
commit([input]);
|
|
1765
|
+
}
|
|
1766
|
+
setQuery("");
|
|
1767
|
+
if (closeOnSelect) {
|
|
1768
|
+
setOpen(false);
|
|
1769
|
+
inputRef.current?.focus();
|
|
1770
|
+
}
|
|
1771
|
+
};
|
|
1067
1772
|
const pick = (opt) => {
|
|
1773
|
+
if (opt.value === CREATE_VALUE) {
|
|
1774
|
+
handleCreate(opt.label);
|
|
1775
|
+
return;
|
|
1776
|
+
}
|
|
1068
1777
|
if (opt.disabled) return;
|
|
1069
1778
|
if (multiple) {
|
|
1070
1779
|
const has = selectedValues.includes(opt.value);
|
|
1780
|
+
if (!has && maxValues != null && selectedValues.length >= maxValues) return;
|
|
1071
1781
|
commit(
|
|
1072
1782
|
has ? selectedValues.filter((v) => v !== opt.value) : [...selectedValues, opt.value]
|
|
1073
1783
|
);
|
|
@@ -1085,6 +1795,16 @@ var Dropdown = /* @__PURE__ */ react.forwardRef(
|
|
|
1085
1795
|
onClear?.();
|
|
1086
1796
|
setQuery("");
|
|
1087
1797
|
};
|
|
1798
|
+
const selectAllTargets = filtered.filter((o) => !o.disabled).map((o) => o.value);
|
|
1799
|
+
const allSelected = selectAllTargets.length > 0 && selectAllTargets.every((v) => selectedValues.includes(v));
|
|
1800
|
+
const toggleSelectAll = () => {
|
|
1801
|
+
if (allSelected) {
|
|
1802
|
+
commit(selectedValues.filter((v) => !selectAllTargets.includes(v)));
|
|
1803
|
+
} else {
|
|
1804
|
+
const merged = Array.from(/* @__PURE__ */ new Set([...selectedValues, ...selectAllTargets]));
|
|
1805
|
+
commit(maxValues != null ? merged.slice(0, maxValues) : merged);
|
|
1806
|
+
}
|
|
1807
|
+
};
|
|
1088
1808
|
const onKeyDown = (e) => {
|
|
1089
1809
|
if (disabled || readOnly) return;
|
|
1090
1810
|
switch (e.key) {
|
|
@@ -1149,6 +1869,7 @@ var Dropdown = /* @__PURE__ */ react.forwardRef(
|
|
|
1149
1869
|
};
|
|
1150
1870
|
const hasValue = selectedValues.length > 0;
|
|
1151
1871
|
const doHighlight = highlightMatch ?? searchable;
|
|
1872
|
+
const isLoadingEmpty = Boolean(loading) && selectableOptions.length === 0;
|
|
1152
1873
|
if (native && !multiple && !searchable) {
|
|
1153
1874
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1154
1875
|
Field,
|
|
@@ -1175,7 +1896,7 @@ var Dropdown = /* @__PURE__ */ react.forwardRef(
|
|
|
1175
1896
|
onChange: (e) => commit(e.target.value ? [e.target.value] : []),
|
|
1176
1897
|
children: [
|
|
1177
1898
|
placeholder != null && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: required, children: placeholder }),
|
|
1178
|
-
|
|
1899
|
+
baseOptions.map((o) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: o.value, disabled: o.disabled, children: o.label }, o.value))
|
|
1179
1900
|
]
|
|
1180
1901
|
}
|
|
1181
1902
|
)
|
|
@@ -1262,7 +1983,6 @@ var Dropdown = /* @__PURE__ */ react.forwardRef(
|
|
|
1262
1983
|
{
|
|
1263
1984
|
...ref ? { ref: setRefs(ref, inputRef) } : { ref: inputRef },
|
|
1264
1985
|
id,
|
|
1265
|
-
name,
|
|
1266
1986
|
className: "orynn-select__search",
|
|
1267
1987
|
role: "combobox",
|
|
1268
1988
|
"aria-expanded": open,
|
|
@@ -1274,7 +1994,11 @@ var Dropdown = /* @__PURE__ */ react.forwardRef(
|
|
|
1274
1994
|
autoComplete: "off",
|
|
1275
1995
|
readOnly: !searchable || readOnly,
|
|
1276
1996
|
disabled,
|
|
1277
|
-
placeholder:
|
|
1997
|
+
placeholder: (
|
|
1998
|
+
// only the search input shows the placeholder; when not
|
|
1999
|
+
// searchable the sibling span owns it (avoids a double render)
|
|
2000
|
+
!hasValue && searchable ? placeholder : void 0
|
|
2001
|
+
),
|
|
1278
2002
|
value: query,
|
|
1279
2003
|
size: 1,
|
|
1280
2004
|
onChange: (e) => {
|
|
@@ -1284,7 +2008,8 @@ var Dropdown = /* @__PURE__ */ react.forwardRef(
|
|
|
1284
2008
|
onKeyDown,
|
|
1285
2009
|
onFocus: openPanel
|
|
1286
2010
|
}
|
|
1287
|
-
)
|
|
2011
|
+
),
|
|
2012
|
+
name != null && (multiple ? selectedValues.map((v) => /* @__PURE__ */ jsxRuntime.jsx("input", { type: "hidden", name, value: v }, v)) : /* @__PURE__ */ jsxRuntime.jsx("input", { type: "hidden", name, value: selectedValues[0] ?? "" }))
|
|
1288
2013
|
] })
|
|
1289
2014
|
}
|
|
1290
2015
|
),
|
|
@@ -1295,44 +2020,61 @@ var Dropdown = /* @__PURE__ */ react.forwardRef(
|
|
|
1295
2020
|
anchorRef: boxRef,
|
|
1296
2021
|
onClose: () => setOpen(false),
|
|
1297
2022
|
popoverRef: listRef,
|
|
1298
|
-
|
|
2023
|
+
maxHeight,
|
|
2024
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1299
2025
|
"div",
|
|
1300
2026
|
{
|
|
1301
2027
|
className: "orynn-listbox",
|
|
1302
2028
|
id: listId,
|
|
1303
2029
|
role: "listbox",
|
|
1304
2030
|
"aria-multiselectable": multiple || void 0,
|
|
1305
|
-
children:
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
{
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
selectedValues.includes(row.option.value)
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
2031
|
+
children: [
|
|
2032
|
+
multiple && showSelectAll && selectAllTargets.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "orynn-listbox__action", onClick: toggleSelectAll, children: allSelected ? "Clear all" : "Select all" }),
|
|
2033
|
+
isLoadingEmpty ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "orynn-listbox__empty", children: loadingMessage }) : selectableOptions.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "orynn-listbox__empty", children: emptyMessage }) : rows.map(
|
|
2034
|
+
(row) => row.type === "group" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "orynn-listbox__group", children: renderGroupLabel ? renderGroupLabel(row.label) : row.label }, `g-${row.label}`) : row.option.value === CREATE_VALUE ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
2035
|
+
"div",
|
|
2036
|
+
{
|
|
2037
|
+
id: `${id}-opt-${CREATE_VALUE}`,
|
|
2038
|
+
role: "option",
|
|
2039
|
+
"aria-selected": false,
|
|
2040
|
+
className: "orynn-option orynn-option--create",
|
|
2041
|
+
"data-active": row.optionIndex === activeIndex || void 0,
|
|
2042
|
+
onMouseEnter: () => setActiveIndex(row.optionIndex),
|
|
2043
|
+
onClick: () => pick(row.option),
|
|
2044
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-option__body", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-option__label", children: formatCreateLabel ? formatCreateLabel(row.option.label) : `Create "${row.option.label}"` }) })
|
|
2045
|
+
},
|
|
2046
|
+
CREATE_VALUE
|
|
2047
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
2048
|
+
"div",
|
|
2049
|
+
{
|
|
2050
|
+
id: `${id}-opt-${row.option.value}`,
|
|
2051
|
+
role: "option",
|
|
2052
|
+
"aria-selected": selectedValues.includes(row.option.value),
|
|
2053
|
+
"aria-disabled": row.option.disabled || void 0,
|
|
2054
|
+
className: "orynn-option",
|
|
2055
|
+
"data-active": row.optionIndex === activeIndex || void 0,
|
|
2056
|
+
"data-selected": selectedValues.includes(row.option.value) || void 0,
|
|
2057
|
+
"data-disabled": row.option.disabled || void 0,
|
|
2058
|
+
onMouseEnter: () => setActiveIndex(row.optionIndex),
|
|
2059
|
+
onClick: () => pick(row.option),
|
|
2060
|
+
children: renderOption ? renderOption(row.option, {
|
|
2061
|
+
selected: selectedValues.includes(row.option.value),
|
|
2062
|
+
active: row.optionIndex === activeIndex,
|
|
2063
|
+
disabled: Boolean(row.option.disabled),
|
|
2064
|
+
query
|
|
2065
|
+
}) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2066
|
+
row.option.icon,
|
|
2067
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "orynn-option__body", children: [
|
|
2068
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-option__label", children: doHighlight ? /* @__PURE__ */ jsxRuntime.jsx(Highlight, { text: row.option.label, query }) : row.option.label }),
|
|
2069
|
+
row.option.description != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-option__desc", children: row.option.description })
|
|
2070
|
+
] }),
|
|
2071
|
+
selectedValues.includes(row.option.value) && /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, { className: "orynn-option__check" })
|
|
2072
|
+
] })
|
|
2073
|
+
},
|
|
2074
|
+
row.option.value
|
|
2075
|
+
)
|
|
1334
2076
|
)
|
|
1335
|
-
|
|
2077
|
+
]
|
|
1336
2078
|
}
|
|
1337
2079
|
)
|
|
1338
2080
|
}
|
|
@@ -1380,8 +2122,14 @@ var Input = /* @__PURE__ */ react.forwardRef(
|
|
|
1380
2122
|
type = "text",
|
|
1381
2123
|
prefix,
|
|
1382
2124
|
suffix,
|
|
2125
|
+
addonBefore,
|
|
2126
|
+
addonAfter,
|
|
1383
2127
|
passwordToggle,
|
|
2128
|
+
passwordVisible,
|
|
2129
|
+
onPasswordVisibleChange,
|
|
2130
|
+
visibilityToggleIcon,
|
|
1384
2131
|
showCount,
|
|
2132
|
+
debounce,
|
|
1385
2133
|
maxLength,
|
|
1386
2134
|
placeholder,
|
|
1387
2135
|
...rest
|
|
@@ -1393,14 +2141,32 @@ var Input = /* @__PURE__ */ react.forwardRef(
|
|
|
1393
2141
|
defaultValue: defaultValue ?? "",
|
|
1394
2142
|
onChange: void 0
|
|
1395
2143
|
});
|
|
1396
|
-
const
|
|
2144
|
+
const revealIsControlled = passwordVisible !== void 0;
|
|
2145
|
+
const [innerReveal, setInnerReveal] = react.useState(false);
|
|
2146
|
+
const reveal = revealIsControlled ? passwordVisible : innerReveal;
|
|
2147
|
+
const setReveal = (next) => {
|
|
2148
|
+
if (!revealIsControlled) setInnerReveal(next);
|
|
2149
|
+
onPasswordVisibleChange?.(next);
|
|
2150
|
+
};
|
|
2151
|
+
const debounceTimer = react.useRef();
|
|
2152
|
+
react.useEffect(() => () => clearTimeout(debounceTimer.current), []);
|
|
2153
|
+
const emitChange = (v, e) => {
|
|
2154
|
+
if (debounce && debounce > 0) {
|
|
2155
|
+
clearTimeout(debounceTimer.current);
|
|
2156
|
+
debounceTimer.current = setTimeout(() => onChange?.(v, e), debounce);
|
|
2157
|
+
} else {
|
|
2158
|
+
onChange?.(v, e);
|
|
2159
|
+
}
|
|
2160
|
+
};
|
|
1397
2161
|
const showToggle = (passwordToggle ?? type === "password") && !disabled && !readOnly;
|
|
1398
2162
|
const effectiveType = type === "password" && reveal ? "text" : type;
|
|
1399
2163
|
const hasValue = value.length > 0;
|
|
1400
2164
|
const showClear = clearable && hasValue && !disabled && !readOnly;
|
|
2165
|
+
const countMax = showCount && typeof showCount === "object" ? showCount.max ?? maxLength : maxLength;
|
|
2166
|
+
const countNode = showCount && typeof showCount === "object" && showCount.formatter ? showCount.formatter(value.length, countMax) : `${value.length}${countMax ? `/${countMax}` : ""}`;
|
|
1401
2167
|
const handleChange = (e) => {
|
|
1402
2168
|
setValue(e.target.value);
|
|
1403
|
-
|
|
2169
|
+
emitChange(e.target.value, e);
|
|
1404
2170
|
};
|
|
1405
2171
|
const handleKeyDown = (e) => {
|
|
1406
2172
|
if (e.key === "Enter") onEnter?.(value);
|
|
@@ -1432,16 +2198,15 @@ var Input = /* @__PURE__ */ react.forwardRef(
|
|
|
1432
2198
|
invalid,
|
|
1433
2199
|
valid,
|
|
1434
2200
|
active: hasValue,
|
|
2201
|
+
addonBefore,
|
|
2202
|
+
addonAfter,
|
|
1435
2203
|
left: startContent != null || prefix != null ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1436
2204
|
startContent,
|
|
1437
2205
|
prefix != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-box__adornment--affix", children: prefix })
|
|
1438
2206
|
] }) : void 0,
|
|
1439
2207
|
right: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1440
2208
|
suffix != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-box__adornment--affix", children: suffix }),
|
|
1441
|
-
showCount && /* @__PURE__ */ jsxRuntime.
|
|
1442
|
-
value.length,
|
|
1443
|
-
maxLength ? `/${maxLength}` : ""
|
|
1444
|
-
] }),
|
|
2209
|
+
showCount && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-box__adornment--affix", children: countNode }),
|
|
1445
2210
|
showClear && /* @__PURE__ */ jsxRuntime.jsx(
|
|
1446
2211
|
"button",
|
|
1447
2212
|
{
|
|
@@ -1461,8 +2226,8 @@ var Input = /* @__PURE__ */ react.forwardRef(
|
|
|
1461
2226
|
"aria-label": reveal ? "Hide" : "Show",
|
|
1462
2227
|
"aria-pressed": reveal,
|
|
1463
2228
|
tabIndex: -1,
|
|
1464
|
-
onClick: () => setReveal(
|
|
1465
|
-
children: reveal ? /* @__PURE__ */ jsxRuntime.jsx(EyeOffIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(EyeIcon, {})
|
|
2229
|
+
onClick: () => setReveal(!reveal),
|
|
2230
|
+
children: visibilityToggleIcon ? visibilityToggleIcon(reveal) : reveal ? /* @__PURE__ */ jsxRuntime.jsx(EyeOffIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(EyeIcon, {})
|
|
1466
2231
|
}
|
|
1467
2232
|
),
|
|
1468
2233
|
loading && /* @__PURE__ */ jsxRuntime.jsx(SpinnerIcon, {}),
|
|
@@ -1499,6 +2264,11 @@ var Input = /* @__PURE__ */ react.forwardRef(
|
|
|
1499
2264
|
);
|
|
1500
2265
|
var clamp = (n, min, max) => Math.min(max ?? Number.POSITIVE_INFINITY, Math.max(min ?? Number.NEGATIVE_INFINITY, n));
|
|
1501
2266
|
var round = (n, p) => p == null ? n : Math.round(n * 10 ** p) / 10 ** p;
|
|
2267
|
+
var SENTINEL_GROUP = "[[g]]";
|
|
2268
|
+
var SENTINEL_DECIMAL = "[[d]]";
|
|
2269
|
+
function swapSeparators(out, seps, thousandSeparator, decimalSeparator) {
|
|
2270
|
+
return out.split(seps.group).join(SENTINEL_GROUP).split(seps.decimal).join(SENTINEL_DECIMAL).split(SENTINEL_GROUP).join(thousandSeparator ?? seps.group).split(SENTINEL_DECIMAL).join(decimalSeparator ?? seps.decimal);
|
|
2271
|
+
}
|
|
1502
2272
|
var NumberField = /* @__PURE__ */ react.forwardRef(
|
|
1503
2273
|
function NumberField2(props, ref) {
|
|
1504
2274
|
const {
|
|
@@ -1521,19 +2291,37 @@ var NumberField = /* @__PURE__ */ react.forwardRef(
|
|
|
1521
2291
|
value: valueProp,
|
|
1522
2292
|
defaultValue = null,
|
|
1523
2293
|
onChange,
|
|
2294
|
+
onValueChange,
|
|
1524
2295
|
min,
|
|
1525
2296
|
max,
|
|
1526
2297
|
step = 1,
|
|
1527
2298
|
shiftStep,
|
|
2299
|
+
smallStep,
|
|
1528
2300
|
precision,
|
|
2301
|
+
decimalScale,
|
|
2302
|
+
fixedDecimalScale,
|
|
1529
2303
|
buttons = "stacked",
|
|
2304
|
+
hideControls,
|
|
1530
2305
|
grouping,
|
|
2306
|
+
thousandSeparator,
|
|
2307
|
+
decimalSeparator,
|
|
1531
2308
|
locale,
|
|
2309
|
+
style,
|
|
1532
2310
|
currency,
|
|
2311
|
+
unit,
|
|
2312
|
+
formatOptions,
|
|
2313
|
+
format: formatFn,
|
|
2314
|
+
parse: parseFn,
|
|
1533
2315
|
prefix,
|
|
1534
2316
|
suffix,
|
|
1535
|
-
|
|
2317
|
+
allowNegative = true,
|
|
2318
|
+
clampBehavior,
|
|
2319
|
+
clampOnBlur,
|
|
2320
|
+
emptyValue = null,
|
|
1536
2321
|
allowMouseWheel,
|
|
2322
|
+
isWheelDisabled,
|
|
2323
|
+
stepHoldDelay = 300,
|
|
2324
|
+
stepHoldInterval = 60,
|
|
1537
2325
|
placeholder,
|
|
1538
2326
|
...rest
|
|
1539
2327
|
} = props;
|
|
@@ -1544,15 +2332,45 @@ var NumberField = /* @__PURE__ */ react.forwardRef(
|
|
|
1544
2332
|
defaultValue,
|
|
1545
2333
|
onChange: void 0
|
|
1546
2334
|
});
|
|
1547
|
-
const
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
2335
|
+
const resolvedStyle = style ?? (currency ? "currency" : "decimal");
|
|
2336
|
+
const scale = decimalScale ?? precision;
|
|
2337
|
+
const clampMode = clampBehavior ?? (clampOnBlur === false ? "none" : "blur");
|
|
2338
|
+
const effMin = allowNegative ? min : Math.max(0, min ?? 0);
|
|
2339
|
+
const showButtons = hideControls ? false : buttons;
|
|
2340
|
+
const wheelEnabled = isWheelDisabled != null ? !isWheelDisabled : Boolean(allowMouseWheel);
|
|
2341
|
+
const fmt = react.useMemo(() => {
|
|
2342
|
+
if (formatOptions) return new Intl.NumberFormat(locale, formatOptions);
|
|
2343
|
+
const opts = {
|
|
2344
|
+
useGrouping: grouping ?? (thousandSeparator != null || resolvedStyle === "currency")
|
|
2345
|
+
};
|
|
2346
|
+
if (resolvedStyle === "currency") {
|
|
2347
|
+
opts.style = "currency";
|
|
2348
|
+
opts.currency = currency ?? "USD";
|
|
2349
|
+
} else if (resolvedStyle === "percent") {
|
|
2350
|
+
opts.style = "percent";
|
|
2351
|
+
} else if (resolvedStyle === "unit" && unit) {
|
|
2352
|
+
opts.style = "unit";
|
|
2353
|
+
opts.unit = unit;
|
|
2354
|
+
}
|
|
2355
|
+
if (scale != null) {
|
|
2356
|
+
opts.maximumFractionDigits = scale;
|
|
2357
|
+
if (fixedDecimalScale) opts.minimumFractionDigits = scale;
|
|
2358
|
+
} else {
|
|
2359
|
+
opts.maximumFractionDigits = resolvedStyle === "currency" ? 2 : 20;
|
|
2360
|
+
opts.minimumFractionDigits = resolvedStyle === "currency" ? 2 : 0;
|
|
2361
|
+
}
|
|
2362
|
+
return new Intl.NumberFormat(locale, opts);
|
|
2363
|
+
}, [
|
|
2364
|
+
locale,
|
|
2365
|
+
formatOptions,
|
|
2366
|
+
grouping,
|
|
2367
|
+
thousandSeparator,
|
|
2368
|
+
resolvedStyle,
|
|
2369
|
+
currency,
|
|
2370
|
+
unit,
|
|
2371
|
+
scale,
|
|
2372
|
+
fixedDecimalScale
|
|
2373
|
+
]);
|
|
1556
2374
|
const seps = react.useMemo(() => {
|
|
1557
2375
|
const parts = new Intl.NumberFormat(locale).formatToParts(11111.1);
|
|
1558
2376
|
return {
|
|
@@ -1561,23 +2379,47 @@ var NumberField = /* @__PURE__ */ react.forwardRef(
|
|
|
1561
2379
|
};
|
|
1562
2380
|
}, [locale]);
|
|
1563
2381
|
const display = react.useCallback(
|
|
1564
|
-
(n) =>
|
|
1565
|
-
|
|
2382
|
+
(n) => {
|
|
2383
|
+
if (n == null || Number.isNaN(n)) return "";
|
|
2384
|
+
if (formatFn) return formatFn(n);
|
|
2385
|
+
let out = fmt.format(n);
|
|
2386
|
+
if (thousandSeparator != null || decimalSeparator != null) {
|
|
2387
|
+
out = swapSeparators(out, seps, thousandSeparator, decimalSeparator);
|
|
2388
|
+
}
|
|
2389
|
+
return `${prefix ?? ""}${out}${suffix ?? ""}`;
|
|
2390
|
+
},
|
|
2391
|
+
[fmt, formatFn, prefix, suffix, seps, thousandSeparator, decimalSeparator]
|
|
1566
2392
|
);
|
|
1567
2393
|
const parse = react.useCallback(
|
|
1568
2394
|
(raw) => {
|
|
2395
|
+
if (parseFn) return parseFn(raw);
|
|
1569
2396
|
let s = raw;
|
|
1570
2397
|
if (prefix) s = s.split(prefix).join("");
|
|
1571
2398
|
if (suffix) s = s.split(suffix).join("");
|
|
1572
|
-
|
|
2399
|
+
const grp = thousandSeparator ?? seps.group;
|
|
2400
|
+
const dec = decimalSeparator ?? seps.decimal;
|
|
2401
|
+
s = s.split(grp).join("").split(dec).join(".");
|
|
1573
2402
|
s = s.replace(/[^\d.\-]/g, "");
|
|
2403
|
+
if (!allowNegative) s = s.replace(/-/g, "");
|
|
1574
2404
|
if (s === "" || s === "-" || s === ".") return null;
|
|
1575
2405
|
const first = s.indexOf(".");
|
|
1576
2406
|
if (first !== -1) s = s.slice(0, first + 1) + s.slice(first + 1).replace(/\./g, "");
|
|
1577
|
-
|
|
1578
|
-
|
|
2407
|
+
let n = Number(s);
|
|
2408
|
+
if (Number.isNaN(n)) return null;
|
|
2409
|
+
if (resolvedStyle === "percent" && !formatFn) n = n / 100;
|
|
2410
|
+
return n;
|
|
1579
2411
|
},
|
|
1580
|
-
[
|
|
2412
|
+
[
|
|
2413
|
+
parseFn,
|
|
2414
|
+
prefix,
|
|
2415
|
+
suffix,
|
|
2416
|
+
seps,
|
|
2417
|
+
thousandSeparator,
|
|
2418
|
+
decimalSeparator,
|
|
2419
|
+
allowNegative,
|
|
2420
|
+
resolvedStyle,
|
|
2421
|
+
formatFn
|
|
2422
|
+
]
|
|
1581
2423
|
);
|
|
1582
2424
|
const [text, setText] = react.useState(() => display(value));
|
|
1583
2425
|
const [editing, setEditing] = react.useState(false);
|
|
@@ -1587,65 +2429,76 @@ var NumberField = /* @__PURE__ */ react.forwardRef(
|
|
|
1587
2429
|
const commit = (n) => {
|
|
1588
2430
|
setValue(n);
|
|
1589
2431
|
onChange?.(n);
|
|
2432
|
+
onValueChange?.({ value: n, formatted: display(n) });
|
|
1590
2433
|
};
|
|
1591
2434
|
const setNumber = (n) => {
|
|
1592
2435
|
commit(n);
|
|
1593
2436
|
setText(display(n));
|
|
1594
2437
|
};
|
|
1595
|
-
const bump = (dir,
|
|
1596
|
-
const
|
|
1597
|
-
const base2 = value ?? (dir > 0 ?
|
|
1598
|
-
|
|
2438
|
+
const bump = (dir, mode = "n") => {
|
|
2439
|
+
const amount = mode === "l" ? shiftStep ?? step * 10 : mode === "s" ? smallStep ?? step / 10 : step;
|
|
2440
|
+
const base2 = value ?? (dir > 0 ? effMin ?? 0 : max ?? 0);
|
|
2441
|
+
let next = round(base2 + amount * dir, scale);
|
|
2442
|
+
if (clampMode !== "none") next = clamp(next, effMin, max);
|
|
2443
|
+
else if (!allowNegative && next < 0) next = 0;
|
|
2444
|
+
setNumber(next);
|
|
1599
2445
|
};
|
|
1600
2446
|
const innerRef = react.useRef(null);
|
|
1601
2447
|
react.useEffect(() => {
|
|
1602
2448
|
const el = innerRef.current;
|
|
1603
|
-
if (!el || !
|
|
2449
|
+
if (!el || !wheelEnabled) return;
|
|
1604
2450
|
const onWheel = (e) => {
|
|
1605
2451
|
if (document.activeElement !== el) return;
|
|
1606
2452
|
e.preventDefault();
|
|
1607
|
-
bump(e.deltaY < 0 ? 1 : -1, e.shiftKey);
|
|
2453
|
+
bump(e.deltaY < 0 ? 1 : -1, e.shiftKey ? "l" : e.altKey ? "s" : "n");
|
|
1608
2454
|
};
|
|
1609
2455
|
el.addEventListener("wheel", onWheel, { passive: false });
|
|
1610
2456
|
return () => el.removeEventListener("wheel", onWheel);
|
|
1611
2457
|
});
|
|
1612
2458
|
const onKeyDown = (e) => {
|
|
1613
2459
|
if (disabled || readOnly) return;
|
|
2460
|
+
const mode = e.shiftKey ? "l" : e.altKey ? "s" : "n";
|
|
1614
2461
|
if (e.key === "ArrowUp") {
|
|
1615
2462
|
e.preventDefault();
|
|
1616
|
-
bump(1,
|
|
2463
|
+
bump(1, mode);
|
|
1617
2464
|
} else if (e.key === "ArrowDown") {
|
|
1618
2465
|
e.preventDefault();
|
|
1619
|
-
bump(-1,
|
|
2466
|
+
bump(-1, mode);
|
|
1620
2467
|
} else if (e.key === "PageUp") {
|
|
1621
2468
|
e.preventDefault();
|
|
1622
|
-
bump(1,
|
|
2469
|
+
bump(1, "l");
|
|
1623
2470
|
} else if (e.key === "PageDown") {
|
|
1624
2471
|
e.preventDefault();
|
|
1625
|
-
bump(-1,
|
|
1626
|
-
} else if (e.key === "Home" &&
|
|
2472
|
+
bump(-1, "l");
|
|
2473
|
+
} else if (e.key === "Home" && effMin != null) {
|
|
1627
2474
|
e.preventDefault();
|
|
1628
|
-
setNumber(
|
|
2475
|
+
setNumber(effMin);
|
|
1629
2476
|
} else if (e.key === "End" && max != null) {
|
|
1630
2477
|
e.preventDefault();
|
|
1631
2478
|
setNumber(max);
|
|
1632
2479
|
}
|
|
1633
2480
|
};
|
|
1634
2481
|
const holdTimer = react.useRef();
|
|
2482
|
+
const holdDelay = react.useRef();
|
|
1635
2483
|
const startHold = (dir) => {
|
|
1636
2484
|
bump(dir);
|
|
1637
2485
|
let count = 0;
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
2486
|
+
holdDelay.current = setTimeout(() => {
|
|
2487
|
+
holdTimer.current = setInterval(() => {
|
|
2488
|
+
count += 1;
|
|
2489
|
+
bump(dir, count > 6 ? "l" : "n");
|
|
2490
|
+
}, stepHoldInterval);
|
|
2491
|
+
}, stepHoldDelay);
|
|
1642
2492
|
};
|
|
1643
|
-
const stopHold = () =>
|
|
1644
|
-
|
|
1645
|
-
|
|
2493
|
+
const stopHold = () => {
|
|
2494
|
+
clearTimeout(holdDelay.current);
|
|
2495
|
+
clearInterval(holdTimer.current);
|
|
2496
|
+
};
|
|
2497
|
+
react.useEffect(() => stopHold, []);
|
|
2498
|
+
const StepButtons = showButtons && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1646
2499
|
"div",
|
|
1647
2500
|
{
|
|
1648
|
-
className: `orynn-number__buttons${
|
|
2501
|
+
className: `orynn-number__buttons${showButtons === "horizontal" ? " orynn-number__buttons--horizontal" : ""}`,
|
|
1649
2502
|
children: [
|
|
1650
2503
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1651
2504
|
"button",
|
|
@@ -1658,7 +2511,7 @@ var NumberField = /* @__PURE__ */ react.forwardRef(
|
|
|
1658
2511
|
onPointerDown: () => startHold(1),
|
|
1659
2512
|
onPointerUp: stopHold,
|
|
1660
2513
|
onPointerLeave: stopHold,
|
|
1661
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2514
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronUpIcon, { className: "orynn-number__caret" })
|
|
1662
2515
|
}
|
|
1663
2516
|
),
|
|
1664
2517
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1668,11 +2521,11 @@ var NumberField = /* @__PURE__ */ react.forwardRef(
|
|
|
1668
2521
|
className: "orynn-number__btn",
|
|
1669
2522
|
"aria-label": "Decrement",
|
|
1670
2523
|
tabIndex: -1,
|
|
1671
|
-
disabled: disabled || readOnly ||
|
|
2524
|
+
disabled: disabled || readOnly || effMin != null && (value ?? 0) <= effMin,
|
|
1672
2525
|
onPointerDown: () => startHold(-1),
|
|
1673
2526
|
onPointerUp: stopHold,
|
|
1674
2527
|
onPointerLeave: stopHold,
|
|
1675
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2528
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ChevronDownIcon, { className: "orynn-number__caret" })
|
|
1676
2529
|
}
|
|
1677
2530
|
)
|
|
1678
2531
|
]
|
|
@@ -1723,7 +2576,7 @@ var NumberField = /* @__PURE__ */ react.forwardRef(
|
|
|
1723
2576
|
inputMode: "decimal",
|
|
1724
2577
|
role: "spinbutton",
|
|
1725
2578
|
"aria-valuenow": value ?? void 0,
|
|
1726
|
-
"aria-valuemin":
|
|
2579
|
+
"aria-valuemin": effMin,
|
|
1727
2580
|
"aria-valuemax": max,
|
|
1728
2581
|
value: text,
|
|
1729
2582
|
disabled,
|
|
@@ -1735,13 +2588,16 @@ var NumberField = /* @__PURE__ */ react.forwardRef(
|
|
|
1735
2588
|
onFocus: () => setEditing(true),
|
|
1736
2589
|
onChange: (e) => {
|
|
1737
2590
|
setText(e.target.value);
|
|
1738
|
-
|
|
2591
|
+
const parsed = parse(e.target.value);
|
|
2592
|
+
commit(
|
|
2593
|
+
parsed == null ? null : clampMode === "strict" ? clamp(parsed, effMin, max) : parsed
|
|
2594
|
+
);
|
|
1739
2595
|
},
|
|
1740
2596
|
onKeyDown,
|
|
1741
2597
|
onBlur: () => {
|
|
1742
2598
|
setEditing(false);
|
|
1743
2599
|
const parsed = parse(text);
|
|
1744
|
-
const final = parsed == null ?
|
|
2600
|
+
const final = parsed == null ? emptyValue : round(clampMode !== "none" ? clamp(parsed, effMin, max) : parsed, scale);
|
|
1745
2601
|
if (final !== value) commit(final);
|
|
1746
2602
|
setText(display(final));
|
|
1747
2603
|
}
|
|
@@ -1754,7 +2610,7 @@ var NumberField = /* @__PURE__ */ react.forwardRef(
|
|
|
1754
2610
|
}
|
|
1755
2611
|
);
|
|
1756
2612
|
var RadioGroupContext = react.createContext(null);
|
|
1757
|
-
var sizePx2 = { sm: "0.
|
|
2613
|
+
var sizePx2 = { sm: "0.875rem", md: "1rem", lg: "1.125rem" };
|
|
1758
2614
|
var Radio = /* @__PURE__ */ react.forwardRef(
|
|
1759
2615
|
function Radio2(props, ref) {
|
|
1760
2616
|
const group = react.useContext(RadioGroupContext);
|
|
@@ -1831,6 +2687,7 @@ function RadioGroup(props) {
|
|
|
1831
2687
|
defaultValue = null,
|
|
1832
2688
|
onChange,
|
|
1833
2689
|
orientation = "vertical",
|
|
2690
|
+
columns,
|
|
1834
2691
|
options,
|
|
1835
2692
|
children,
|
|
1836
2693
|
className,
|
|
@@ -1866,12 +2723,17 @@ function RadioGroup(props) {
|
|
|
1866
2723
|
"aria-labelledby": label != null ? `${id}-label` : void 0,
|
|
1867
2724
|
"aria-required": required || void 0,
|
|
1868
2725
|
className: "orynn-choice-group",
|
|
1869
|
-
"data-orientation": orientation,
|
|
2726
|
+
"data-orientation": columns ? void 0 : orientation,
|
|
2727
|
+
"data-columns": columns ? "" : void 0,
|
|
2728
|
+
style: columns ? { "--orynn-choice-columns": columns } : void 0,
|
|
1870
2729
|
children: options ? options.map((o) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1871
2730
|
Radio,
|
|
1872
2731
|
{
|
|
1873
2732
|
value: o.value,
|
|
1874
|
-
label: o.
|
|
2733
|
+
label: o.icon != null ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2734
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-choice__icon", children: o.icon }),
|
|
2735
|
+
o.label
|
|
2736
|
+
] }) : o.label,
|
|
1875
2737
|
description: o.description,
|
|
1876
2738
|
disabled: o.disabled
|
|
1877
2739
|
},
|
|
@@ -1898,12 +2760,17 @@ var Textarea = /* @__PURE__ */ react.forwardRef(
|
|
|
1898
2760
|
floatingLabel,
|
|
1899
2761
|
clearable,
|
|
1900
2762
|
onClear,
|
|
2763
|
+
loading,
|
|
2764
|
+
endContent,
|
|
1901
2765
|
id: idProp,
|
|
1902
2766
|
name,
|
|
1903
2767
|
className,
|
|
1904
2768
|
value: valueProp,
|
|
1905
2769
|
defaultValue,
|
|
1906
2770
|
onChange,
|
|
2771
|
+
onEnter,
|
|
2772
|
+
submitOnEnter,
|
|
2773
|
+
onKeyDown,
|
|
1907
2774
|
autoResize,
|
|
1908
2775
|
minRows = 3,
|
|
1909
2776
|
maxRows = 10,
|
|
@@ -1928,9 +2795,9 @@ var Textarea = /* @__PURE__ */ react.forwardRef(
|
|
|
1928
2795
|
el.style.height = "auto";
|
|
1929
2796
|
const cs = getComputedStyle(el);
|
|
1930
2797
|
const line = Number.parseFloat(cs.lineHeight) || 20;
|
|
1931
|
-
const
|
|
1932
|
-
const min = line * minRows +
|
|
1933
|
-
const max = line * maxRows +
|
|
2798
|
+
const pad3 = Number.parseFloat(cs.paddingTop) + Number.parseFloat(cs.paddingBottom);
|
|
2799
|
+
const min = line * minRows + pad3;
|
|
2800
|
+
const max = line * maxRows + pad3;
|
|
1934
2801
|
el.style.height = `${Math.min(Math.max(el.scrollHeight, min), max)}px`;
|
|
1935
2802
|
el.style.overflowY = el.scrollHeight > max ? "auto" : "hidden";
|
|
1936
2803
|
}, [autoResize, minRows, maxRows]);
|
|
@@ -1939,7 +2806,16 @@ var Textarea = /* @__PURE__ */ react.forwardRef(
|
|
|
1939
2806
|
setValue(e.target.value);
|
|
1940
2807
|
onChange?.(e.target.value, e);
|
|
1941
2808
|
};
|
|
2809
|
+
const handleKeyDown = (e) => {
|
|
2810
|
+
if (e.key === "Enter" && !e.shiftKey && (onEnter || submitOnEnter)) {
|
|
2811
|
+
if (submitOnEnter) e.preventDefault();
|
|
2812
|
+
onEnter?.(value);
|
|
2813
|
+
}
|
|
2814
|
+
onKeyDown?.(e);
|
|
2815
|
+
};
|
|
1942
2816
|
const hasValue = value.length > 0;
|
|
2817
|
+
const countMax = showCount && typeof showCount === "object" ? showCount.max ?? maxLength : maxLength;
|
|
2818
|
+
const countNode = showCount && typeof showCount === "object" && showCount.formatter ? showCount.formatter(value.length, countMax) : `${value.length}${countMax ? `/${countMax}` : ""}`;
|
|
1943
2819
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
1944
2820
|
Field,
|
|
1945
2821
|
{
|
|
@@ -1964,20 +2840,24 @@ var Textarea = /* @__PURE__ */ react.forwardRef(
|
|
|
1964
2840
|
valid,
|
|
1965
2841
|
active: hasValue,
|
|
1966
2842
|
floatingLabel: floatingLabel ? /* @__PURE__ */ jsxRuntime.jsx("label", { className: "orynn-box__label", htmlFor: id, children: label }) : void 0,
|
|
1967
|
-
right: clearable && hasValue
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
2843
|
+
right: clearable && hasValue || loading || endContent != null ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2844
|
+
clearable && hasValue && !disabled && !readOnly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2845
|
+
"button",
|
|
2846
|
+
{
|
|
2847
|
+
type: "button",
|
|
2848
|
+
className: "orynn-box__iconbtn",
|
|
2849
|
+
"aria-label": "Clear",
|
|
2850
|
+
tabIndex: -1,
|
|
2851
|
+
onClick: () => {
|
|
2852
|
+
setValue("");
|
|
2853
|
+
onClear?.();
|
|
2854
|
+
},
|
|
2855
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(XIcon, {})
|
|
2856
|
+
}
|
|
2857
|
+
),
|
|
2858
|
+
loading && /* @__PURE__ */ jsxRuntime.jsx(SpinnerIcon, {}),
|
|
2859
|
+
endContent
|
|
2860
|
+
] }) : void 0,
|
|
1981
2861
|
children: [
|
|
1982
2862
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1983
2863
|
"textarea",
|
|
@@ -1997,13 +2877,11 @@ var Textarea = /* @__PURE__ */ react.forwardRef(
|
|
|
1997
2877
|
placeholder: floatingLabel ? void 0 : placeholder,
|
|
1998
2878
|
"aria-invalid": invalid || void 0,
|
|
1999
2879
|
"aria-describedby": describedById,
|
|
2000
|
-
onChange: handleChange
|
|
2880
|
+
onChange: handleChange,
|
|
2881
|
+
onKeyDown: handleKeyDown
|
|
2001
2882
|
}
|
|
2002
2883
|
),
|
|
2003
|
-
showCount && /* @__PURE__ */ jsxRuntime.
|
|
2004
|
-
value.length,
|
|
2005
|
-
maxLength ? `/${maxLength}` : ""
|
|
2006
|
-
] })
|
|
2884
|
+
showCount && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-box__footer", children: countNode })
|
|
2007
2885
|
]
|
|
2008
2886
|
}
|
|
2009
2887
|
)
|
|
@@ -2060,24 +2938,63 @@ function registerField(type, registration) {
|
|
|
2060
2938
|
|
|
2061
2939
|
// src/layout/resolve-columns.ts
|
|
2062
2940
|
var DEFAULT_COLUMNS = { desktop: 3, tablet: 2, mobile: 1 };
|
|
2941
|
+
var DEFAULT_MIN_COL = 192;
|
|
2063
2942
|
var clampCount = (n, fallback) => typeof n === "number" && Number.isFinite(n) && n >= 1 ? Math.floor(n) : fallback;
|
|
2064
|
-
function resolveColumns(
|
|
2943
|
+
function resolveColumns(input) {
|
|
2944
|
+
if (typeof input === "number") {
|
|
2945
|
+
const n = clampCount(input, DEFAULT_COLUMNS.desktop);
|
|
2946
|
+
return { desktop: n, tablet: n, mobile: n };
|
|
2947
|
+
}
|
|
2065
2948
|
return {
|
|
2066
|
-
desktop: clampCount(
|
|
2067
|
-
tablet: clampCount(
|
|
2068
|
-
mobile: clampCount(
|
|
2949
|
+
desktop: clampCount(input?.desktop, DEFAULT_COLUMNS.desktop),
|
|
2950
|
+
tablet: clampCount(input?.tablet, DEFAULT_COLUMNS.tablet),
|
|
2951
|
+
mobile: clampCount(input?.mobile, DEFAULT_COLUMNS.mobile)
|
|
2069
2952
|
};
|
|
2070
2953
|
}
|
|
2954
|
+
function resolveGrid(width, cols, minColWidth = DEFAULT_MIN_COL) {
|
|
2955
|
+
const { desktop: d, tablet: t, mobile: m } = cols;
|
|
2956
|
+
if (!width || !Number.isFinite(width) || width <= 0) {
|
|
2957
|
+
return { count: d, tier: "desktop" };
|
|
2958
|
+
}
|
|
2959
|
+
const per = minColWidth > 0 ? minColWidth : DEFAULT_MIN_COL;
|
|
2960
|
+
const maxFit = Math.max(1, Math.floor(width / per));
|
|
2961
|
+
if (d === t && t === m) {
|
|
2962
|
+
const count = Math.min(d, maxFit);
|
|
2963
|
+
return { count, tier: count >= d ? "desktop" : count > 1 ? "tablet" : "mobile" };
|
|
2964
|
+
}
|
|
2965
|
+
if (maxFit >= d) return { count: d, tier: "desktop" };
|
|
2966
|
+
if (t < d && maxFit >= t) return { count: t, tier: "tablet" };
|
|
2967
|
+
if (maxFit >= m) return { count: m, tier: "mobile" };
|
|
2968
|
+
return { count: Math.min(m, maxFit), tier: "mobile" };
|
|
2969
|
+
}
|
|
2071
2970
|
function clampSpan(span, columnCount) {
|
|
2072
2971
|
const n = clampCount(span, 1);
|
|
2073
2972
|
return Math.min(n, Math.max(columnCount, 1));
|
|
2074
2973
|
}
|
|
2974
|
+
function pickSpan(layout, tier) {
|
|
2975
|
+
if (!layout) return 1;
|
|
2976
|
+
const v = layout[tier] ?? layout.desktop ?? layout.tablet ?? layout.mobile;
|
|
2977
|
+
return typeof v === "number" && Number.isFinite(v) && v >= 1 ? Math.floor(v) : 1;
|
|
2978
|
+
}
|
|
2075
2979
|
|
|
2076
2980
|
// src/core/config/normalize.ts
|
|
2077
2981
|
function normalizeGap(gap) {
|
|
2078
2982
|
if (gap == null) return void 0;
|
|
2079
2983
|
return typeof gap === "number" ? `${gap}px` : gap;
|
|
2080
2984
|
}
|
|
2985
|
+
function normalizeMinColWidth(value) {
|
|
2986
|
+
if (typeof value === "number") return value > 0 ? value : DEFAULT_MIN_COL;
|
|
2987
|
+
if (typeof value === "string") {
|
|
2988
|
+
const n = Number.parseFloat(value);
|
|
2989
|
+
if (!Number.isFinite(n) || n <= 0) return DEFAULT_MIN_COL;
|
|
2990
|
+
if (/rem|em/i.test(value)) {
|
|
2991
|
+
const root = typeof document !== "undefined" ? Number.parseFloat(getComputedStyle(document.documentElement).fontSize) || 16 : 16;
|
|
2992
|
+
return n * root;
|
|
2993
|
+
}
|
|
2994
|
+
return n;
|
|
2995
|
+
}
|
|
2996
|
+
return DEFAULT_MIN_COL;
|
|
2997
|
+
}
|
|
2081
2998
|
function normalizeConfig(config, registry2) {
|
|
2082
2999
|
invariant(
|
|
2083
3000
|
config != null && typeof config === "object" && Array.isArray(config.fields),
|
|
@@ -2111,18 +3028,52 @@ function normalizeConfig(config, registry2) {
|
|
|
2111
3028
|
return {
|
|
2112
3029
|
fields: config.fields,
|
|
2113
3030
|
columns: resolveColumns(config.columns),
|
|
3031
|
+
minColWidth: normalizeMinColWidth(config.minColumnWidth),
|
|
2114
3032
|
gap: normalizeGap(config.gap),
|
|
2115
3033
|
legend: config.legend,
|
|
2116
3034
|
id: config.id
|
|
2117
3035
|
};
|
|
2118
3036
|
}
|
|
2119
3037
|
|
|
3038
|
+
// src/core/config/conditions.ts
|
|
3039
|
+
function evalCondition(when, values) {
|
|
3040
|
+
if (when == null) return true;
|
|
3041
|
+
if (typeof when === "function") return Boolean(when(values));
|
|
3042
|
+
const actual = values[when.field];
|
|
3043
|
+
if ("eq" in when) return actual === when.eq;
|
|
3044
|
+
if ("ne" in when) return actual !== when.ne;
|
|
3045
|
+
if ("in" in when) return Array.isArray(when.in) && when.in.includes(actual);
|
|
3046
|
+
if ("notIn" in when) return Array.isArray(when.notIn) && !when.notIn.includes(actual);
|
|
3047
|
+
if ("truthy" in when) return Boolean(actual) === Boolean(when.truthy);
|
|
3048
|
+
return Boolean(actual);
|
|
3049
|
+
}
|
|
3050
|
+
|
|
2120
3051
|
// src/core/validation/messages.ts
|
|
2121
3052
|
var plural = (n, word) => `${n} ${word}${n === 1 ? "" : "s"}`;
|
|
3053
|
+
var dateStr = (p) => {
|
|
3054
|
+
const d = p instanceof Date ? p : new Date(String(p));
|
|
3055
|
+
return Number.isNaN(d.getTime()) ? String(p) : d.toLocaleDateString();
|
|
3056
|
+
};
|
|
2122
3057
|
var defaultMessages = {
|
|
2123
3058
|
required: ({ label }) => `${label} is required`,
|
|
2124
3059
|
minLength: ({ param, label }) => `${label} must be at least ${plural(param, "character")}`,
|
|
2125
|
-
maxLength: ({ param, label }) => `${label} must be at most ${plural(param, "character")}
|
|
3060
|
+
maxLength: ({ param, label }) => `${label} must be at most ${plural(param, "character")}`,
|
|
3061
|
+
minItems: ({ param, label }) => `Select at least ${plural(param, "option")} for ${label}`,
|
|
3062
|
+
maxItems: ({ param, label }) => `Select at most ${plural(param, "option")} for ${label}`,
|
|
3063
|
+
min: ({ param, label }) => `${label} must be at least ${param}`,
|
|
3064
|
+
max: ({ param, label }) => `${label} must be at most ${param}`,
|
|
3065
|
+
integer: ({ label }) => `${label} must be a whole number`,
|
|
3066
|
+
minDate: ({ param, label }) => `${label} must be on or after ${dateStr(param)}`,
|
|
3067
|
+
maxDate: ({ param, label }) => `${label} must be on or before ${dateStr(param)}`,
|
|
3068
|
+
minRangeDays: ({ param, label }) => `${label} must span at least ${plural(param, "day")}`,
|
|
3069
|
+
maxRangeDays: ({ param, label }) => `${label} must span at most ${plural(param, "day")}`,
|
|
3070
|
+
email: ({ label }) => `${label} must be a valid email address`,
|
|
3071
|
+
url: ({ label }) => `${label} must be a valid URL`,
|
|
3072
|
+
pattern: ({ label }) => `${label} is not in the expected format`,
|
|
3073
|
+
oneOf: ({ label }) => `${label} is not an allowed value`,
|
|
3074
|
+
equals: ({ label }) => `${label} does not match`,
|
|
3075
|
+
validate: ({ label }) => `${label} is invalid`,
|
|
3076
|
+
schema: ({ label }) => `${label} is invalid`
|
|
2126
3077
|
};
|
|
2127
3078
|
var FALLBACK_LABEL = "This field";
|
|
2128
3079
|
function resolveMessage(token, param, label, overrides) {
|
|
@@ -2136,6 +3087,50 @@ function resolveMessage(token, param, label, overrides) {
|
|
|
2136
3087
|
// src/core/validation/rules.ts
|
|
2137
3088
|
var isEmpty = (value) => value == null || value === "" || Array.isArray(value) && value.length === 0;
|
|
2138
3089
|
var asLength = (value) => typeof value === "string" || Array.isArray(value) ? value.length : String(value ?? "").length;
|
|
3090
|
+
var toNumber = (value) => {
|
|
3091
|
+
if (typeof value === "number") return Number.isNaN(value) ? null : value;
|
|
3092
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
3093
|
+
const n = Number(value);
|
|
3094
|
+
return Number.isNaN(n) ? null : n;
|
|
3095
|
+
}
|
|
3096
|
+
return null;
|
|
3097
|
+
};
|
|
3098
|
+
var toTime = (value) => {
|
|
3099
|
+
if (value == null || value === "") return null;
|
|
3100
|
+
const d = value instanceof Date ? value : new Date(value);
|
|
3101
|
+
const t = d.getTime();
|
|
3102
|
+
return Number.isNaN(t) ? null : t;
|
|
3103
|
+
};
|
|
3104
|
+
var rangeSpanDays = (value) => {
|
|
3105
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
3106
|
+
const { start, end } = value;
|
|
3107
|
+
const s = toTime(start);
|
|
3108
|
+
const e = toTime(end);
|
|
3109
|
+
if (s == null || e == null) return null;
|
|
3110
|
+
return Math.abs(Math.round((e - s) / 864e5)) + 1;
|
|
3111
|
+
};
|
|
3112
|
+
var EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
3113
|
+
var URL_RE = /^(https?:\/\/)[^\s.]+\.\S{2,}$/i;
|
|
3114
|
+
function toRegExp(param) {
|
|
3115
|
+
if (param instanceof RegExp) return param;
|
|
3116
|
+
if (typeof param === "string") {
|
|
3117
|
+
try {
|
|
3118
|
+
return new RegExp(param);
|
|
3119
|
+
} catch {
|
|
3120
|
+
return null;
|
|
3121
|
+
}
|
|
3122
|
+
}
|
|
3123
|
+
if (param && typeof param === "object" && "value" in param) {
|
|
3124
|
+
const { value, flags } = param;
|
|
3125
|
+
if (value instanceof RegExp) return value;
|
|
3126
|
+
try {
|
|
3127
|
+
return new RegExp(value, flags);
|
|
3128
|
+
} catch {
|
|
3129
|
+
return null;
|
|
3130
|
+
}
|
|
3131
|
+
}
|
|
3132
|
+
return null;
|
|
3133
|
+
}
|
|
2139
3134
|
var builtInRules = {
|
|
2140
3135
|
required: (value, param) => {
|
|
2141
3136
|
if (param === false) return null;
|
|
@@ -2148,6 +3143,84 @@ var builtInRules = {
|
|
|
2148
3143
|
maxLength: (value, param) => {
|
|
2149
3144
|
if (typeof param !== "number" || isEmpty(value)) return null;
|
|
2150
3145
|
return asLength(value) > param ? "maxLength" : null;
|
|
3146
|
+
},
|
|
3147
|
+
minItems: (value, param) => {
|
|
3148
|
+
if (typeof param !== "number" || !Array.isArray(value)) return null;
|
|
3149
|
+
return value.length < param ? "minItems" : null;
|
|
3150
|
+
},
|
|
3151
|
+
maxItems: (value, param) => {
|
|
3152
|
+
if (typeof param !== "number" || !Array.isArray(value)) return null;
|
|
3153
|
+
return value.length > param ? "maxItems" : null;
|
|
3154
|
+
},
|
|
3155
|
+
email: (value, param) => {
|
|
3156
|
+
if (param === false || isEmpty(value)) return null;
|
|
3157
|
+
return EMAIL_RE.test(String(value)) ? null : "email";
|
|
3158
|
+
},
|
|
3159
|
+
url: (value, param) => {
|
|
3160
|
+
if (param === false || isEmpty(value)) return null;
|
|
3161
|
+
return URL_RE.test(String(value)) ? null : "url";
|
|
3162
|
+
},
|
|
3163
|
+
pattern: (value, param) => {
|
|
3164
|
+
if (isEmpty(value)) return null;
|
|
3165
|
+
const re = toRegExp(param);
|
|
3166
|
+
if (!re) return null;
|
|
3167
|
+
return re.test(String(value)) ? null : "pattern";
|
|
3168
|
+
},
|
|
3169
|
+
integer: (value, param) => {
|
|
3170
|
+
if (param === false || isEmpty(value)) return null;
|
|
3171
|
+
const n = toNumber(value);
|
|
3172
|
+
return n != null && Number.isInteger(n) ? null : "integer";
|
|
3173
|
+
},
|
|
3174
|
+
min: (value, param) => {
|
|
3175
|
+
if (typeof param !== "number" || isEmpty(value)) return null;
|
|
3176
|
+
const n = toNumber(value);
|
|
3177
|
+
return n != null && n < param ? "min" : null;
|
|
3178
|
+
},
|
|
3179
|
+
max: (value, param) => {
|
|
3180
|
+
if (typeof param !== "number" || isEmpty(value)) return null;
|
|
3181
|
+
const n = toNumber(value);
|
|
3182
|
+
return n != null && n > param ? "max" : null;
|
|
3183
|
+
},
|
|
3184
|
+
minDate: (value, param) => {
|
|
3185
|
+
if (isEmpty(value)) return null;
|
|
3186
|
+
const v = toTime(value);
|
|
3187
|
+
const p = toTime(param);
|
|
3188
|
+
return v != null && p != null && v < p ? "minDate" : null;
|
|
3189
|
+
},
|
|
3190
|
+
maxDate: (value, param) => {
|
|
3191
|
+
if (isEmpty(value)) return null;
|
|
3192
|
+
const v = toTime(value);
|
|
3193
|
+
const p = toTime(param);
|
|
3194
|
+
return v != null && p != null && v > p ? "maxDate" : null;
|
|
3195
|
+
},
|
|
3196
|
+
minRangeDays: (value, param) => {
|
|
3197
|
+
if (typeof param !== "number") return null;
|
|
3198
|
+
const span = rangeSpanDays(value);
|
|
3199
|
+
return span != null && span < param ? "minRangeDays" : null;
|
|
3200
|
+
},
|
|
3201
|
+
maxRangeDays: (value, param) => {
|
|
3202
|
+
if (typeof param !== "number") return null;
|
|
3203
|
+
const span = rangeSpanDays(value);
|
|
3204
|
+
return span != null && span > param ? "maxRangeDays" : null;
|
|
3205
|
+
},
|
|
3206
|
+
oneOf: (value, param) => {
|
|
3207
|
+
if (isEmpty(value) || !Array.isArray(param)) return null;
|
|
3208
|
+
return param.includes(value) ? null : "oneOf";
|
|
3209
|
+
},
|
|
3210
|
+
equals: (value, param, allValues) => {
|
|
3211
|
+
if (isEmpty(value)) return null;
|
|
3212
|
+
const target = param && typeof param === "object" && "field" in param ? allValues[param.field] : param;
|
|
3213
|
+
return value == target ? null : "equals";
|
|
3214
|
+
},
|
|
3215
|
+
validate: (value, param, allValues) => {
|
|
3216
|
+
if (typeof param !== "function") return null;
|
|
3217
|
+
const out = param(value, allValues);
|
|
3218
|
+
if (out instanceof Promise) {
|
|
3219
|
+
return out.then(
|
|
3220
|
+
(r) => typeof r === "string" ? r : r === false ? "validate" : null
|
|
3221
|
+
);
|
|
3222
|
+
}
|
|
3223
|
+
return typeof out === "string" ? out : out === false ? "validate" : null;
|
|
2151
3224
|
}
|
|
2152
3225
|
};
|
|
2153
3226
|
var registry = new Map(Object.entries(builtInRules));
|
|
@@ -2161,12 +3234,12 @@ function getRule(name) {
|
|
|
2161
3234
|
// src/core/validation/resolver.ts
|
|
2162
3235
|
function createRuleResolver() {
|
|
2163
3236
|
return (values, config) => {
|
|
2164
|
-
const
|
|
3237
|
+
const pending = [];
|
|
2165
3238
|
for (const field of config.fields) {
|
|
2166
3239
|
const validation = field.validation;
|
|
2167
3240
|
if (!validation) continue;
|
|
3241
|
+
if (!evalCondition(field.when, values)) continue;
|
|
2168
3242
|
const value = values[field.name];
|
|
2169
|
-
const errors = [];
|
|
2170
3243
|
for (const key of Object.keys(validation)) {
|
|
2171
3244
|
if (key === "messages") continue;
|
|
2172
3245
|
const param = validation[key];
|
|
@@ -2178,16 +3251,34 @@ function createRuleResolver() {
|
|
|
2178
3251
|
}
|
|
2179
3252
|
continue;
|
|
2180
3253
|
}
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
errors.push({
|
|
3254
|
+
pending.push({
|
|
3255
|
+
field: field.name,
|
|
2184
3256
|
rule: key,
|
|
2185
|
-
|
|
3257
|
+
param,
|
|
3258
|
+
label: field.label,
|
|
3259
|
+
overrides: validation.messages,
|
|
3260
|
+
token: rule(value, param, values)
|
|
2186
3261
|
});
|
|
2187
3262
|
}
|
|
2188
|
-
if (errors.length > 0) result[field.name] = errors;
|
|
2189
3263
|
}
|
|
2190
|
-
|
|
3264
|
+
const collect = (settled) => {
|
|
3265
|
+
const result = {};
|
|
3266
|
+
pending.forEach((p, i) => {
|
|
3267
|
+
const token = settled[i];
|
|
3268
|
+
if (token == null) return;
|
|
3269
|
+
const bucket = result[p.field] ?? [];
|
|
3270
|
+
bucket.push({
|
|
3271
|
+
rule: p.rule,
|
|
3272
|
+
message: resolveMessage(token, p.param, p.label, p.overrides)
|
|
3273
|
+
});
|
|
3274
|
+
result[p.field] = bucket;
|
|
3275
|
+
});
|
|
3276
|
+
return result;
|
|
3277
|
+
};
|
|
3278
|
+
if (pending.some((p) => p.token instanceof Promise)) {
|
|
3279
|
+
return Promise.all(pending.map((p) => Promise.resolve(p.token))).then(collect);
|
|
3280
|
+
}
|
|
3281
|
+
return collect(pending.map((p) => p.token));
|
|
2191
3282
|
};
|
|
2192
3283
|
}
|
|
2193
3284
|
var defaultResolver = /* @__PURE__ */ createRuleResolver();
|
|
@@ -2419,23 +3510,43 @@ function useFieldsetState(config, options = {}) {
|
|
|
2419
3510
|
getFieldProps
|
|
2420
3511
|
};
|
|
2421
3512
|
}
|
|
2422
|
-
|
|
3513
|
+
var useBrowserLayoutEffect = typeof window !== "undefined" ? react.useLayoutEffect : react.useEffect;
|
|
3514
|
+
var GridContext = react.createContext({ count: 1, tier: "desktop" });
|
|
3515
|
+
function FieldGrid({ columns, minColWidth, gap, className, children }) {
|
|
3516
|
+
const ref = react.useRef(null);
|
|
3517
|
+
const per = minColWidth && minColWidth > 0 ? minColWidth : DEFAULT_MIN_COL;
|
|
3518
|
+
const { desktop, tablet, mobile } = columns;
|
|
3519
|
+
const [grid, setGrid] = react.useState(() => resolveGrid(0, columns, per));
|
|
3520
|
+
useBrowserLayoutEffect(() => {
|
|
3521
|
+
const el = ref.current;
|
|
3522
|
+
if (!el) return;
|
|
3523
|
+
const cols = { desktop, tablet, mobile };
|
|
3524
|
+
const apply = (width) => {
|
|
3525
|
+
const next = resolveGrid(width, cols, per);
|
|
3526
|
+
setGrid((cur) => cur.count === next.count && cur.tier === next.tier ? cur : next);
|
|
3527
|
+
};
|
|
3528
|
+
apply(el.getBoundingClientRect().width);
|
|
3529
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
3530
|
+
const ro = new ResizeObserver((entries) => {
|
|
3531
|
+
for (const entry of entries) {
|
|
3532
|
+
const box = entry.contentBoxSize?.[0];
|
|
3533
|
+
apply(box ? box.inlineSize : entry.contentRect.width);
|
|
3534
|
+
}
|
|
3535
|
+
});
|
|
3536
|
+
ro.observe(el);
|
|
3537
|
+
return () => ro.disconnect();
|
|
3538
|
+
}, [desktop, tablet, mobile, per]);
|
|
2423
3539
|
const style = {
|
|
2424
|
-
"--orynn-cols
|
|
2425
|
-
"--orynn-cols-tablet": columns.tablet,
|
|
2426
|
-
"--orynn-cols-mobile": columns.mobile,
|
|
3540
|
+
"--orynn-cols": grid.count,
|
|
2427
3541
|
...gap ? { "--orynn-grid-gap": gap } : {}
|
|
2428
3542
|
};
|
|
2429
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cx("orynn-grid", className), style, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "orynn-grid__track", children }) });
|
|
3543
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { ref, className: cx("orynn-grid", className), style, children: /* @__PURE__ */ jsxRuntime.jsx(GridContext.Provider, { value: grid, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "orynn-grid__track", children }) }) });
|
|
2430
3544
|
}
|
|
2431
|
-
function FieldGridItem({ span,
|
|
2432
|
-
|
|
2433
|
-
const
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
"--orynn-span-mobile": clampSpan(span.mobile, columns.mobile)
|
|
2437
|
-
};
|
|
2438
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "orynn-grid__item", style, children });
|
|
3545
|
+
function FieldGridItem({ span, children }) {
|
|
3546
|
+
const { count, tier } = react.useContext(GridContext);
|
|
3547
|
+
const effective = span ? clampSpan(pickSpan(span, tier), count) : 1;
|
|
3548
|
+
if (effective <= 1) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
|
|
3549
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "orynn-grid__item", style: { "--orynn-span": effective }, children });
|
|
2439
3550
|
}
|
|
2440
3551
|
var noop = () => {
|
|
2441
3552
|
};
|
|
@@ -2445,6 +3556,7 @@ function FieldRendererImpl({ field, registry: registry2, slice, disabled }) {
|
|
|
2445
3556
|
registration,
|
|
2446
3557
|
`No control registered for field type "${field.type}" (field "${field.name}").`
|
|
2447
3558
|
);
|
|
3559
|
+
const fallbackId = react.useId();
|
|
2448
3560
|
if (!registration) return null;
|
|
2449
3561
|
const Control = registration.component;
|
|
2450
3562
|
const required = field.validation?.required === true;
|
|
@@ -2454,6 +3566,36 @@ function FieldRendererImpl({ field, registry: registry2, slice, disabled }) {
|
|
|
2454
3566
|
const handleChange = (next) => {
|
|
2455
3567
|
slice.setValue(registration.formatValue ? registration.formatValue(next) : next);
|
|
2456
3568
|
};
|
|
3569
|
+
if (registration.selfContained) {
|
|
3570
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3571
|
+
"div",
|
|
3572
|
+
{
|
|
3573
|
+
style: { display: "contents" },
|
|
3574
|
+
onBlur: (e) => {
|
|
3575
|
+
if (!e.currentTarget.contains(e.relatedTarget)) slice.markTouched();
|
|
3576
|
+
},
|
|
3577
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3578
|
+
Control,
|
|
3579
|
+
{
|
|
3580
|
+
id: fallbackId,
|
|
3581
|
+
name: field.name,
|
|
3582
|
+
value,
|
|
3583
|
+
onChange: handleChange,
|
|
3584
|
+
onBlur: slice.markTouched,
|
|
3585
|
+
onFocus: noop,
|
|
3586
|
+
disabled: isDisabled,
|
|
3587
|
+
readOnly: field.readOnly === true,
|
|
3588
|
+
required,
|
|
3589
|
+
invalid: messages.length > 0,
|
|
3590
|
+
label: field.label,
|
|
3591
|
+
description: field.description,
|
|
3592
|
+
errors: messages,
|
|
3593
|
+
config: field
|
|
3594
|
+
}
|
|
3595
|
+
)
|
|
3596
|
+
}
|
|
3597
|
+
);
|
|
3598
|
+
}
|
|
2457
3599
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2458
3600
|
Field,
|
|
2459
3601
|
{
|
|
@@ -2486,90 +3628,290 @@ var FieldRenderer = /* @__PURE__ */ react.memo(
|
|
|
2486
3628
|
FieldRendererImpl,
|
|
2487
3629
|
(prev, next) => prev.field === next.field && prev.registry === next.registry && prev.disabled === next.disabled && prev.slice.value === next.slice.value && prev.slice.touched === next.slice.touched && prev.slice.errors === next.slice.errors && prev.slice.setValue === next.slice.setValue && prev.slice.markTouched === next.slice.markTouched
|
|
2488
3630
|
);
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
id
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
3631
|
+
function FieldsetView({ state, registry: registry2, disabled, className, id }) {
|
|
3632
|
+
const activeRegistry = registry2 ?? defaultRegistry;
|
|
3633
|
+
const { columns, minColWidth, gap, legend, fields, id: configId } = state.config;
|
|
3634
|
+
const visible = fields.filter((f) => evalCondition(f.when, state.values));
|
|
3635
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3636
|
+
"fieldset",
|
|
3637
|
+
{
|
|
3638
|
+
className: cx("orynn-fieldset", className),
|
|
3639
|
+
id: id ?? configId,
|
|
3640
|
+
disabled: disabled || void 0,
|
|
3641
|
+
children: [
|
|
3642
|
+
legend != null && /* @__PURE__ */ jsxRuntime.jsx("legend", { className: "orynn-fieldset__legend", children: legend }),
|
|
3643
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldGrid, { columns, minColWidth, gap, children: visible.map((field) => /* @__PURE__ */ jsxRuntime.jsx(FieldGridItem, { span: field.layout, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
3644
|
+
FieldRenderer,
|
|
3645
|
+
{
|
|
3646
|
+
field,
|
|
3647
|
+
registry: activeRegistry,
|
|
3648
|
+
slice: state.getFieldProps(field.name),
|
|
3649
|
+
disabled: disabled === true
|
|
3650
|
+
}
|
|
3651
|
+
) }, field.name)) })
|
|
3652
|
+
]
|
|
3653
|
+
}
|
|
3654
|
+
);
|
|
3655
|
+
}
|
|
3656
|
+
var str = (v) => typeof v === "string" ? v : v == null ? "" : String(v);
|
|
3657
|
+
var toISO = (d) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
|
|
3658
|
+
function shell(p) {
|
|
3659
|
+
const c = p.config;
|
|
3660
|
+
return {
|
|
3661
|
+
id: p.id,
|
|
3662
|
+
name: p.name,
|
|
3663
|
+
label: p.label,
|
|
3664
|
+
description: p.description,
|
|
3665
|
+
error: p.errors,
|
|
3666
|
+
required: p.required,
|
|
3667
|
+
disabled: p.disabled,
|
|
3668
|
+
readOnly: p.readOnly,
|
|
3669
|
+
size: c.size,
|
|
3670
|
+
variant: c.variant,
|
|
3671
|
+
floatingLabel: c.floatingLabel
|
|
3672
|
+
};
|
|
3673
|
+
}
|
|
3674
|
+
var InputControl = (p) => {
|
|
3675
|
+
const c = p.config;
|
|
2505
3676
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2506
|
-
|
|
3677
|
+
Input,
|
|
2507
3678
|
{
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
3679
|
+
...shell(p),
|
|
3680
|
+
type: c.inputType ?? "text",
|
|
3681
|
+
prefix: c.prefix,
|
|
3682
|
+
suffix: c.suffix,
|
|
3683
|
+
addonBefore: c.addonBefore,
|
|
3684
|
+
addonAfter: c.addonAfter,
|
|
3685
|
+
clearable: c.clearable,
|
|
3686
|
+
maxLength: c.maxLength,
|
|
3687
|
+
showCount: c.showCount,
|
|
3688
|
+
debounce: c.debounce,
|
|
3689
|
+
inputMode: c.inputMode,
|
|
3690
|
+
pattern: c.pattern,
|
|
3691
|
+
placeholder: c.placeholder,
|
|
3692
|
+
value: str(p.value),
|
|
3693
|
+
onChange: (v) => p.onChange(v),
|
|
3694
|
+
...c.props
|
|
2523
3695
|
}
|
|
2524
3696
|
);
|
|
2525
3697
|
};
|
|
2526
|
-
var
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
onChange,
|
|
2531
|
-
onBlur,
|
|
2532
|
-
onFocus,
|
|
2533
|
-
disabled,
|
|
2534
|
-
required,
|
|
2535
|
-
invalid,
|
|
2536
|
-
describedById,
|
|
2537
|
-
config
|
|
2538
|
-
}) => {
|
|
2539
|
-
const field = config;
|
|
2540
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2541
|
-
"select",
|
|
3698
|
+
var TextareaControl = (p) => {
|
|
3699
|
+
const c = p.config;
|
|
3700
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3701
|
+
Textarea,
|
|
2542
3702
|
{
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
...
|
|
2555
|
-
children: [
|
|
2556
|
-
field.placeholder != null && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", disabled: required, children: field.placeholder }),
|
|
2557
|
-
field.options.map((option) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: option.value, disabled: option.disabled, children: option.label }, option.value))
|
|
2558
|
-
]
|
|
3703
|
+
...shell(p),
|
|
3704
|
+
minRows: c.rows,
|
|
3705
|
+
maxRows: c.maxRows,
|
|
3706
|
+
autoResize: c.autoResize,
|
|
3707
|
+
resize: c.resize,
|
|
3708
|
+
submitOnEnter: c.submitOnEnter,
|
|
3709
|
+
maxLength: c.maxLength,
|
|
3710
|
+
showCount: c.showCount,
|
|
3711
|
+
placeholder: c.placeholder,
|
|
3712
|
+
value: str(p.value),
|
|
3713
|
+
onChange: (v) => p.onChange(v),
|
|
3714
|
+
...c.props
|
|
2559
3715
|
}
|
|
2560
3716
|
);
|
|
2561
3717
|
};
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
3718
|
+
var NumberFieldControl = (p) => {
|
|
3719
|
+
const c = p.config;
|
|
3720
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3721
|
+
NumberField,
|
|
3722
|
+
{
|
|
3723
|
+
...shell(p),
|
|
3724
|
+
min: c.min,
|
|
3725
|
+
max: c.max,
|
|
3726
|
+
step: c.step,
|
|
3727
|
+
precision: c.precision,
|
|
3728
|
+
decimalScale: c.decimalScale,
|
|
3729
|
+
currency: c.currency,
|
|
3730
|
+
style: c.style,
|
|
3731
|
+
locale: c.locale,
|
|
3732
|
+
prefix: c.prefix,
|
|
3733
|
+
suffix: c.suffix,
|
|
3734
|
+
thousandSeparator: c.thousandSeparator,
|
|
3735
|
+
allowNegative: c.allowNegative,
|
|
3736
|
+
clampBehavior: c.clampBehavior,
|
|
3737
|
+
hideControls: c.hideControls,
|
|
3738
|
+
placeholder: c.placeholder,
|
|
3739
|
+
value: typeof p.value === "number" ? p.value : null,
|
|
3740
|
+
onChange: (v) => p.onChange(v),
|
|
3741
|
+
...c.props
|
|
3742
|
+
}
|
|
3743
|
+
);
|
|
3744
|
+
};
|
|
3745
|
+
var DropdownControl = (p) => {
|
|
3746
|
+
const c = p.config;
|
|
3747
|
+
const value = c.multiple ? Array.isArray(p.value) ? p.value : [] : Array.isArray(p.value) ? p.value[0] ?? "" : str(p.value);
|
|
3748
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3749
|
+
Dropdown,
|
|
3750
|
+
{
|
|
3751
|
+
...shell(p),
|
|
3752
|
+
options: c.options,
|
|
3753
|
+
searchable: c.searchable,
|
|
3754
|
+
multiple: c.multiple,
|
|
3755
|
+
clearable: c.clearable,
|
|
3756
|
+
creatable: c.creatable,
|
|
3757
|
+
maxValues: c.maxValues,
|
|
3758
|
+
hidePickedOptions: c.hidePickedOptions,
|
|
3759
|
+
showSelectAll: c.showSelectAll,
|
|
3760
|
+
searchDebounce: c.searchDebounce,
|
|
3761
|
+
placeholder: c.placeholder,
|
|
3762
|
+
value,
|
|
3763
|
+
onChange: (v) => p.onChange(v ?? (c.multiple ? [] : "")),
|
|
3764
|
+
...c.props
|
|
3765
|
+
}
|
|
3766
|
+
);
|
|
3767
|
+
};
|
|
3768
|
+
var DateControl = (p) => {
|
|
3769
|
+
const c = p.config;
|
|
3770
|
+
const toDate2 = (x) => x == null ? void 0 : x instanceof Date ? x : new Date(x);
|
|
3771
|
+
const mode = c.mode ?? "single";
|
|
3772
|
+
const common = {
|
|
3773
|
+
...shell(p),
|
|
3774
|
+
format: c.format,
|
|
3775
|
+
precision: c.precision,
|
|
3776
|
+
minDate: toDate2(c.minDate),
|
|
3777
|
+
maxDate: toDate2(c.maxDate),
|
|
3778
|
+
showToday: c.showToday,
|
|
3779
|
+
clearable: c.clearable,
|
|
3780
|
+
placeholder: c.placeholder,
|
|
3781
|
+
presets: c.presets,
|
|
3782
|
+
...c.props
|
|
3783
|
+
};
|
|
3784
|
+
if (mode === "range") {
|
|
3785
|
+
const v = p.value ?? {};
|
|
3786
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3787
|
+
DatePicker,
|
|
3788
|
+
{
|
|
3789
|
+
...common,
|
|
3790
|
+
mode: "range",
|
|
3791
|
+
value: { start: v.start ?? null, end: v.end ?? null },
|
|
3792
|
+
onChange: (r) => p.onChange({
|
|
3793
|
+
start: r.start ? toISO(r.start) : "",
|
|
3794
|
+
end: r.end ? toISO(r.end) : ""
|
|
3795
|
+
})
|
|
3796
|
+
}
|
|
3797
|
+
);
|
|
2565
3798
|
}
|
|
2566
|
-
if (
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
3799
|
+
if (mode === "multiple") {
|
|
3800
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3801
|
+
DatePicker,
|
|
3802
|
+
{
|
|
3803
|
+
...common,
|
|
3804
|
+
mode: "multiple",
|
|
3805
|
+
value: Array.isArray(p.value) ? p.value : [],
|
|
3806
|
+
onChange: (arr) => p.onChange(arr.map(toISO))
|
|
3807
|
+
}
|
|
3808
|
+
);
|
|
2572
3809
|
}
|
|
3810
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3811
|
+
DatePicker,
|
|
3812
|
+
{
|
|
3813
|
+
...common,
|
|
3814
|
+
value: typeof p.value === "string" && p.value ? p.value : null,
|
|
3815
|
+
onChange: (d) => p.onChange(d instanceof Date ? toISO(d) : "")
|
|
3816
|
+
}
|
|
3817
|
+
);
|
|
3818
|
+
};
|
|
3819
|
+
var CheckboxControl = (p) => {
|
|
3820
|
+
const c = p.config;
|
|
3821
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "orynn-field", children: [
|
|
3822
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3823
|
+
Checkbox,
|
|
3824
|
+
{
|
|
3825
|
+
id: p.id,
|
|
3826
|
+
name: p.name,
|
|
3827
|
+
label: c.checkboxLabel ?? c.label,
|
|
3828
|
+
description: c.description,
|
|
3829
|
+
checked: Boolean(p.value),
|
|
3830
|
+
onChange: (v) => p.onChange(v),
|
|
3831
|
+
disabled: p.disabled,
|
|
3832
|
+
required: p.required,
|
|
3833
|
+
invalid: (p.errors?.length ?? 0) > 0,
|
|
3834
|
+
...c.props
|
|
3835
|
+
}
|
|
3836
|
+
),
|
|
3837
|
+
p.errors?.[0] && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "orynn-field__error", role: "alert", children: p.errors[0] })
|
|
3838
|
+
] });
|
|
3839
|
+
};
|
|
3840
|
+
var CheckboxGroupControl = (p) => {
|
|
3841
|
+
const c = p.config;
|
|
3842
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3843
|
+
CheckboxGroup,
|
|
3844
|
+
{
|
|
3845
|
+
id: p.id,
|
|
3846
|
+
name: p.name,
|
|
3847
|
+
label: p.label,
|
|
3848
|
+
description: p.description,
|
|
3849
|
+
error: p.errors,
|
|
3850
|
+
required: p.required,
|
|
3851
|
+
disabled: p.disabled,
|
|
3852
|
+
options: c.options.map((o) => ({
|
|
3853
|
+
label: o.label,
|
|
3854
|
+
value: o.value,
|
|
3855
|
+
description: o.description,
|
|
3856
|
+
icon: o.icon,
|
|
3857
|
+
disabled: o.disabled
|
|
3858
|
+
})),
|
|
3859
|
+
orientation: c.orientation,
|
|
3860
|
+
columns: c.columns,
|
|
3861
|
+
showSelectAll: c.showSelectAll,
|
|
3862
|
+
min: c.min,
|
|
3863
|
+
max: c.max,
|
|
3864
|
+
value: Array.isArray(p.value) ? p.value : [],
|
|
3865
|
+
onChange: (v) => p.onChange(v),
|
|
3866
|
+
...c.props
|
|
3867
|
+
}
|
|
3868
|
+
);
|
|
3869
|
+
};
|
|
3870
|
+
var RadioControl = (p) => {
|
|
3871
|
+
const c = p.config;
|
|
3872
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3873
|
+
RadioGroup,
|
|
3874
|
+
{
|
|
3875
|
+
id: p.id,
|
|
3876
|
+
name: p.name,
|
|
3877
|
+
label: p.label,
|
|
3878
|
+
description: p.description,
|
|
3879
|
+
error: p.errors,
|
|
3880
|
+
required: p.required,
|
|
3881
|
+
disabled: p.disabled,
|
|
3882
|
+
options: c.options.map((o) => ({
|
|
3883
|
+
label: o.label,
|
|
3884
|
+
value: o.value,
|
|
3885
|
+
description: o.description,
|
|
3886
|
+
icon: o.icon,
|
|
3887
|
+
disabled: o.disabled
|
|
3888
|
+
})),
|
|
3889
|
+
orientation: c.orientation,
|
|
3890
|
+
columns: c.columns,
|
|
3891
|
+
variant: c.radioVariant,
|
|
3892
|
+
value: typeof p.value === "string" && p.value ? p.value : null,
|
|
3893
|
+
onChange: (v) => p.onChange(v),
|
|
3894
|
+
...c.props
|
|
3895
|
+
}
|
|
3896
|
+
);
|
|
3897
|
+
};
|
|
3898
|
+
var needsOptions = (config) => Array.isArray(config.options) ? null : "requires an `options` array";
|
|
3899
|
+
function registerBuiltins(registry2) {
|
|
3900
|
+
const add = (type, component, extra = {}) => {
|
|
3901
|
+
if (!registry2.has(type)) {
|
|
3902
|
+
registry2.register(type, { component, selfContained: true, defaultValue: "", ...extra });
|
|
3903
|
+
}
|
|
3904
|
+
};
|
|
3905
|
+
add("input", InputControl);
|
|
3906
|
+
add("textarea", TextareaControl);
|
|
3907
|
+
add("number", NumberFieldControl, {
|
|
3908
|
+
parseValue: (raw) => typeof raw === "number" ? raw : raw === "" || raw == null ? null : Number(raw)
|
|
3909
|
+
});
|
|
3910
|
+
add("dropdown", DropdownControl, { validateConfig: needsOptions });
|
|
3911
|
+
add("date", DateControl);
|
|
3912
|
+
add("checkbox", CheckboxControl, { defaultValue: false });
|
|
3913
|
+
add("checkbox-group", CheckboxGroupControl, { defaultValue: [], validateConfig: needsOptions });
|
|
3914
|
+
add("radio", RadioControl, { validateConfig: needsOptions });
|
|
2573
3915
|
}
|
|
2574
3916
|
var seeded = false;
|
|
2575
3917
|
function ensureBuiltins(defaultRegistry2) {
|
|
@@ -2603,110 +3945,938 @@ function Fieldset(props) {
|
|
|
2603
3945
|
...validateOn ? { validateOn } : {}
|
|
2604
3946
|
};
|
|
2605
3947
|
const fs = useFieldsetState(config, options);
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
"fieldset",
|
|
3948
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
3949
|
+
FieldsetView,
|
|
2609
3950
|
{
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
disabled: disabled
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
/* @__PURE__ */ jsxRuntime.jsx(FieldGrid, { columns, gap, children: fields.map((field) => /* @__PURE__ */ jsxRuntime.jsx(FieldGridItem, { span: field.layout, columns, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
2616
|
-
FieldRenderer,
|
|
2617
|
-
{
|
|
2618
|
-
field,
|
|
2619
|
-
registry: activeRegistry,
|
|
2620
|
-
slice: fs.getFieldProps(field.name),
|
|
2621
|
-
disabled: disabled === true
|
|
2622
|
-
}
|
|
2623
|
-
) }, field.name)) })
|
|
2624
|
-
]
|
|
3951
|
+
state: fs,
|
|
3952
|
+
registry: activeRegistry,
|
|
3953
|
+
disabled: disabled === true,
|
|
3954
|
+
className,
|
|
3955
|
+
id
|
|
2625
3956
|
}
|
|
2626
3957
|
);
|
|
2627
3958
|
}
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
}
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
3959
|
+
function Form(props) {
|
|
3960
|
+
const {
|
|
3961
|
+
config,
|
|
3962
|
+
value,
|
|
3963
|
+
defaultValue,
|
|
3964
|
+
onChange,
|
|
3965
|
+
onSubmit,
|
|
3966
|
+
onInvalid,
|
|
3967
|
+
resolver,
|
|
3968
|
+
validateOn,
|
|
3969
|
+
disabled,
|
|
3970
|
+
children,
|
|
3971
|
+
className,
|
|
3972
|
+
...rest
|
|
3973
|
+
} = props;
|
|
3974
|
+
ensureBuiltins(defaultRegistry);
|
|
3975
|
+
const fs = useFieldsetState(config, {
|
|
3976
|
+
registry: defaultRegistry,
|
|
3977
|
+
...value !== void 0 ? { value } : {},
|
|
3978
|
+
...defaultValue !== void 0 ? { defaultValue } : {},
|
|
3979
|
+
...onChange ? { onChange } : {},
|
|
3980
|
+
...resolver ? { resolver } : {},
|
|
3981
|
+
...validateOn ? { validateOn } : {}
|
|
3982
|
+
});
|
|
3983
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3984
|
+
"form",
|
|
3985
|
+
{
|
|
3986
|
+
...rest,
|
|
3987
|
+
className: cx("orynn-form", className),
|
|
3988
|
+
noValidate: true,
|
|
3989
|
+
onSubmit: fs.handleSubmit(
|
|
3990
|
+
(values) => onSubmit(values, fs),
|
|
3991
|
+
(errors) => onInvalid?.(errors)
|
|
3992
|
+
),
|
|
3993
|
+
children: [
|
|
3994
|
+
/* @__PURE__ */ jsxRuntime.jsx(FieldsetView, { state: fs, disabled }),
|
|
3995
|
+
typeof children === "function" ? children(fs) : children
|
|
3996
|
+
]
|
|
3997
|
+
}
|
|
3998
|
+
);
|
|
2667
3999
|
}
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
4000
|
+
|
|
4001
|
+
// src/primitives/shared/classes.ts
|
|
4002
|
+
var mod = (base2, key, fallback) => key === fallback ? void 0 : `${base2}--${key}`;
|
|
4003
|
+
function buttonClasses(variant = "default", size = "default") {
|
|
4004
|
+
return cx(
|
|
4005
|
+
"orynn-button",
|
|
4006
|
+
mod("orynn-button", variant, "default"),
|
|
4007
|
+
mod("orynn-button", size, "default")
|
|
4008
|
+
);
|
|
4009
|
+
}
|
|
4010
|
+
function badgeClasses(variant = "default") {
|
|
4011
|
+
return cx("orynn-badge", mod("orynn-badge", variant, "default"));
|
|
4012
|
+
}
|
|
4013
|
+
var Button = /* @__PURE__ */ react.forwardRef(function Button2({
|
|
4014
|
+
className,
|
|
4015
|
+
variant = "default",
|
|
4016
|
+
size = "default",
|
|
4017
|
+
asChild = false,
|
|
4018
|
+
type,
|
|
4019
|
+
loading = false,
|
|
4020
|
+
loadingText,
|
|
4021
|
+
leftIcon,
|
|
4022
|
+
rightIcon,
|
|
4023
|
+
fullWidth = false,
|
|
4024
|
+
disabled,
|
|
4025
|
+
children,
|
|
4026
|
+
...props
|
|
4027
|
+
}, ref) {
|
|
4028
|
+
const shared = {
|
|
4029
|
+
"data-slot": "button",
|
|
4030
|
+
"data-variant": variant,
|
|
4031
|
+
"data-size": size,
|
|
4032
|
+
"data-loading": loading || void 0,
|
|
4033
|
+
"data-full-width": fullWidth || void 0,
|
|
4034
|
+
className: cx(buttonClasses(variant, size), className),
|
|
4035
|
+
...props
|
|
4036
|
+
};
|
|
4037
|
+
if (asChild) {
|
|
4038
|
+
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Slot.Root, { ref, "aria-busy": loading || void 0, ...shared, children });
|
|
4039
|
+
}
|
|
4040
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4041
|
+
"button",
|
|
4042
|
+
{
|
|
4043
|
+
ref,
|
|
4044
|
+
type: type ?? "button",
|
|
4045
|
+
disabled: disabled || loading,
|
|
4046
|
+
"aria-busy": loading || void 0,
|
|
4047
|
+
...shared,
|
|
4048
|
+
children: [
|
|
4049
|
+
loading ? /* @__PURE__ */ jsxRuntime.jsx(SpinnerIcon, { className: "orynn-button__spinner" }) : leftIcon,
|
|
4050
|
+
loading && loadingText != null ? loadingText : children,
|
|
4051
|
+
!loading && rightIcon
|
|
4052
|
+
]
|
|
4053
|
+
}
|
|
4054
|
+
);
|
|
2672
4055
|
});
|
|
2673
|
-
function
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
4056
|
+
var Label = /* @__PURE__ */ react.forwardRef(function Label2({ className, required, optional, children, ...props }, ref) {
|
|
4057
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4058
|
+
radixUi.Label.Root,
|
|
4059
|
+
{
|
|
4060
|
+
ref,
|
|
4061
|
+
"data-slot": "label",
|
|
4062
|
+
className: cx("orynn-label", className),
|
|
4063
|
+
...props,
|
|
4064
|
+
children: [
|
|
4065
|
+
children,
|
|
4066
|
+
required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-label__required", "aria-hidden": "true", children: "*" }),
|
|
4067
|
+
!required && optional && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-label__optional", children: optional === true ? "(optional)" : optional })
|
|
4068
|
+
]
|
|
4069
|
+
}
|
|
2681
4070
|
);
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
4071
|
+
});
|
|
4072
|
+
var Card = /* @__PURE__ */ react.forwardRef(function Card2({ className, asChild = false, interactive = false, ...props }, ref) {
|
|
4073
|
+
const shared = {
|
|
4074
|
+
"data-slot": "card",
|
|
4075
|
+
"data-interactive": interactive || void 0,
|
|
4076
|
+
className: cx("orynn-card", className),
|
|
4077
|
+
...props
|
|
4078
|
+
};
|
|
4079
|
+
return asChild ? /* @__PURE__ */ jsxRuntime.jsx(radixUi.Slot.Root, { ref, ...shared }) : /* @__PURE__ */ jsxRuntime.jsx("div", { ref, ...shared });
|
|
4080
|
+
});
|
|
4081
|
+
var CardHeader = /* @__PURE__ */ react.forwardRef(function CardHeader2({ className, ...props }, ref) {
|
|
4082
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4083
|
+
"div",
|
|
4084
|
+
{
|
|
4085
|
+
ref,
|
|
4086
|
+
"data-slot": "card-header",
|
|
4087
|
+
className: cx("orynn-card__header", className),
|
|
4088
|
+
...props
|
|
4089
|
+
}
|
|
4090
|
+
);
|
|
4091
|
+
});
|
|
4092
|
+
var CardTitle = /* @__PURE__ */ react.forwardRef(function CardTitle2({ className, ...props }, ref) {
|
|
4093
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4094
|
+
"div",
|
|
4095
|
+
{
|
|
4096
|
+
ref,
|
|
4097
|
+
"data-slot": "card-title",
|
|
4098
|
+
className: cx("orynn-card__title", className),
|
|
4099
|
+
...props
|
|
4100
|
+
}
|
|
4101
|
+
);
|
|
4102
|
+
});
|
|
4103
|
+
var CardDescription = /* @__PURE__ */ react.forwardRef(
|
|
4104
|
+
function CardDescription2({ className, ...props }, ref) {
|
|
4105
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4106
|
+
"div",
|
|
4107
|
+
{
|
|
4108
|
+
ref,
|
|
4109
|
+
"data-slot": "card-description",
|
|
4110
|
+
className: cx("orynn-card__description", className),
|
|
4111
|
+
...props
|
|
4112
|
+
}
|
|
4113
|
+
);
|
|
4114
|
+
}
|
|
4115
|
+
);
|
|
4116
|
+
var CardAction = /* @__PURE__ */ react.forwardRef(function CardAction2({ className, ...props }, ref) {
|
|
4117
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4118
|
+
"div",
|
|
4119
|
+
{
|
|
4120
|
+
ref,
|
|
4121
|
+
"data-slot": "card-action",
|
|
4122
|
+
className: cx("orynn-card__action", className),
|
|
4123
|
+
...props
|
|
4124
|
+
}
|
|
4125
|
+
);
|
|
4126
|
+
});
|
|
4127
|
+
var CardContent = /* @__PURE__ */ react.forwardRef(
|
|
4128
|
+
function CardContent2({ className, ...props }, ref) {
|
|
4129
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4130
|
+
"div",
|
|
4131
|
+
{
|
|
4132
|
+
ref,
|
|
4133
|
+
"data-slot": "card-content",
|
|
4134
|
+
className: cx("orynn-card__content", className),
|
|
4135
|
+
...props
|
|
4136
|
+
}
|
|
4137
|
+
);
|
|
4138
|
+
}
|
|
4139
|
+
);
|
|
4140
|
+
var CardFooter = /* @__PURE__ */ react.forwardRef(function CardFooter2({ className, ...props }, ref) {
|
|
4141
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4142
|
+
"div",
|
|
4143
|
+
{
|
|
4144
|
+
ref,
|
|
4145
|
+
"data-slot": "card-footer",
|
|
4146
|
+
className: cx("orynn-card__footer", className),
|
|
4147
|
+
...props
|
|
4148
|
+
}
|
|
4149
|
+
);
|
|
4150
|
+
});
|
|
4151
|
+
var Badge = /* @__PURE__ */ react.forwardRef(function Badge2({
|
|
4152
|
+
className,
|
|
4153
|
+
variant = "default",
|
|
4154
|
+
size = "md",
|
|
4155
|
+
dot = false,
|
|
4156
|
+
icon,
|
|
4157
|
+
removable = false,
|
|
4158
|
+
onRemove,
|
|
4159
|
+
asChild = false,
|
|
4160
|
+
children,
|
|
4161
|
+
...props
|
|
4162
|
+
}, ref) {
|
|
4163
|
+
const shared = {
|
|
4164
|
+
"data-slot": "badge",
|
|
4165
|
+
"data-variant": variant,
|
|
4166
|
+
"data-size": size,
|
|
4167
|
+
className: cx(badgeClasses(variant), className),
|
|
4168
|
+
...props
|
|
2685
4169
|
};
|
|
2686
|
-
|
|
4170
|
+
if (asChild) {
|
|
4171
|
+
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Slot.Root, { ref, ...shared, children });
|
|
4172
|
+
}
|
|
4173
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("span", { ref, ...shared, children: [
|
|
4174
|
+
dot && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-badge__dot", "aria-hidden": "true" }),
|
|
4175
|
+
icon,
|
|
4176
|
+
children,
|
|
4177
|
+
removable && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4178
|
+
"button",
|
|
4179
|
+
{
|
|
4180
|
+
type: "button",
|
|
4181
|
+
className: "orynn-badge__remove",
|
|
4182
|
+
"aria-label": "Remove",
|
|
4183
|
+
onClick: onRemove,
|
|
4184
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(XIcon, {})
|
|
4185
|
+
}
|
|
4186
|
+
)
|
|
4187
|
+
] });
|
|
4188
|
+
});
|
|
4189
|
+
var Alert = /* @__PURE__ */ react.forwardRef(function Alert2({ className, variant = "default", icon, title, dismissible, onDismiss, children, ...props }, ref) {
|
|
4190
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4191
|
+
"div",
|
|
4192
|
+
{
|
|
4193
|
+
ref,
|
|
4194
|
+
"data-slot": "alert",
|
|
4195
|
+
"data-variant": variant,
|
|
4196
|
+
"data-dismissible": dismissible || void 0,
|
|
4197
|
+
role: "alert",
|
|
4198
|
+
className: cx("orynn-alert", variant !== "default" && `orynn-alert--${variant}`, className),
|
|
4199
|
+
...props,
|
|
4200
|
+
children: [
|
|
4201
|
+
icon,
|
|
4202
|
+
title != null && /* @__PURE__ */ jsxRuntime.jsx(AlertTitle, { children: title }),
|
|
4203
|
+
children,
|
|
4204
|
+
dismissible && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4205
|
+
"button",
|
|
4206
|
+
{
|
|
4207
|
+
type: "button",
|
|
4208
|
+
className: "orynn-alert__dismiss",
|
|
4209
|
+
"aria-label": "Dismiss",
|
|
4210
|
+
onClick: onDismiss,
|
|
4211
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(XIcon, {})
|
|
4212
|
+
}
|
|
4213
|
+
)
|
|
4214
|
+
]
|
|
4215
|
+
}
|
|
4216
|
+
);
|
|
4217
|
+
});
|
|
4218
|
+
var AlertTitle = /* @__PURE__ */ react.forwardRef(
|
|
4219
|
+
function AlertTitle2({ className, ...props }, ref) {
|
|
4220
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4221
|
+
"div",
|
|
4222
|
+
{
|
|
4223
|
+
ref,
|
|
4224
|
+
"data-slot": "alert-title",
|
|
4225
|
+
className: cx("orynn-alert__title", className),
|
|
4226
|
+
...props
|
|
4227
|
+
}
|
|
4228
|
+
);
|
|
4229
|
+
}
|
|
4230
|
+
);
|
|
4231
|
+
var AlertDescription = /* @__PURE__ */ react.forwardRef(
|
|
4232
|
+
function AlertDescription2({ className, ...props }, ref) {
|
|
4233
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4234
|
+
"div",
|
|
4235
|
+
{
|
|
4236
|
+
ref,
|
|
4237
|
+
"data-slot": "alert-description",
|
|
4238
|
+
className: cx("orynn-alert__description", className),
|
|
4239
|
+
...props
|
|
4240
|
+
}
|
|
4241
|
+
);
|
|
4242
|
+
}
|
|
4243
|
+
);
|
|
4244
|
+
var Separator = /* @__PURE__ */ react.forwardRef(
|
|
4245
|
+
function Separator2({
|
|
4246
|
+
className,
|
|
4247
|
+
orientation = "horizontal",
|
|
4248
|
+
decorative = true,
|
|
4249
|
+
variant = "solid",
|
|
4250
|
+
children,
|
|
4251
|
+
...props
|
|
4252
|
+
}, ref) {
|
|
4253
|
+
if (children != null && orientation === "horizontal") {
|
|
4254
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4255
|
+
"div",
|
|
4256
|
+
{
|
|
4257
|
+
ref,
|
|
4258
|
+
role: "separator",
|
|
4259
|
+
"aria-orientation": "horizontal",
|
|
4260
|
+
"data-slot": "separator",
|
|
4261
|
+
"data-orientation": "horizontal",
|
|
4262
|
+
"data-variant": variant,
|
|
4263
|
+
className: cx("orynn-separator", "orynn-separator--labelled", className),
|
|
4264
|
+
...props,
|
|
4265
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-separator__label", children })
|
|
4266
|
+
}
|
|
4267
|
+
);
|
|
4268
|
+
}
|
|
4269
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4270
|
+
radixUi.Separator.Root,
|
|
4271
|
+
{
|
|
4272
|
+
ref,
|
|
4273
|
+
"data-slot": "separator",
|
|
4274
|
+
"data-variant": variant,
|
|
4275
|
+
orientation,
|
|
4276
|
+
decorative,
|
|
4277
|
+
className: cx("orynn-separator", className),
|
|
4278
|
+
...props
|
|
4279
|
+
}
|
|
4280
|
+
);
|
|
4281
|
+
}
|
|
4282
|
+
);
|
|
4283
|
+
var Table = /* @__PURE__ */ react.forwardRef(function Table2({ className, size, dense, ...props }, ref) {
|
|
4284
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-slot": "table-container", className: "orynn-table__wrap", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4285
|
+
"table",
|
|
4286
|
+
{
|
|
4287
|
+
ref,
|
|
4288
|
+
"data-slot": "table",
|
|
4289
|
+
"data-size": dense ? "sm" : size,
|
|
4290
|
+
className: cx("orynn-table", className),
|
|
4291
|
+
...props
|
|
4292
|
+
}
|
|
4293
|
+
) });
|
|
4294
|
+
});
|
|
4295
|
+
var TableHeader = /* @__PURE__ */ react.forwardRef(
|
|
4296
|
+
function TableHeader2({ className, sticky, ...props }, ref) {
|
|
4297
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4298
|
+
"thead",
|
|
4299
|
+
{
|
|
4300
|
+
ref,
|
|
4301
|
+
"data-slot": "table-header",
|
|
4302
|
+
"data-sticky": sticky || void 0,
|
|
4303
|
+
className: cx("orynn-table__header", className),
|
|
4304
|
+
...props
|
|
4305
|
+
}
|
|
4306
|
+
);
|
|
4307
|
+
}
|
|
4308
|
+
);
|
|
4309
|
+
var TableBody = /* @__PURE__ */ react.forwardRef(function TableBody2({ className, ...props }, ref) {
|
|
4310
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4311
|
+
"tbody",
|
|
4312
|
+
{
|
|
4313
|
+
ref,
|
|
4314
|
+
"data-slot": "table-body",
|
|
4315
|
+
className: cx("orynn-table__body", className),
|
|
4316
|
+
...props
|
|
4317
|
+
}
|
|
4318
|
+
);
|
|
4319
|
+
});
|
|
4320
|
+
var TableFooter = /* @__PURE__ */ react.forwardRef(function TableFooter2({ className, ...props }, ref) {
|
|
4321
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4322
|
+
"tfoot",
|
|
4323
|
+
{
|
|
4324
|
+
ref,
|
|
4325
|
+
"data-slot": "table-footer",
|
|
4326
|
+
className: cx("orynn-table__footer", className),
|
|
4327
|
+
...props
|
|
4328
|
+
}
|
|
4329
|
+
);
|
|
4330
|
+
});
|
|
4331
|
+
var TableRow = /* @__PURE__ */ react.forwardRef(
|
|
4332
|
+
function TableRow2({ className, selected, ...props }, ref) {
|
|
4333
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4334
|
+
"tr",
|
|
4335
|
+
{
|
|
4336
|
+
ref,
|
|
4337
|
+
"data-slot": "table-row",
|
|
4338
|
+
"data-state": selected ? "selected" : void 0,
|
|
4339
|
+
className: cx("orynn-table__row", className),
|
|
4340
|
+
...props
|
|
4341
|
+
}
|
|
4342
|
+
);
|
|
4343
|
+
}
|
|
4344
|
+
);
|
|
4345
|
+
var TableHead = /* @__PURE__ */ react.forwardRef(
|
|
4346
|
+
function TableHead2({ className, ...props }, ref) {
|
|
4347
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4348
|
+
"th",
|
|
4349
|
+
{
|
|
4350
|
+
ref,
|
|
4351
|
+
"data-slot": "table-head",
|
|
4352
|
+
className: cx("orynn-table__head", className),
|
|
4353
|
+
...props
|
|
4354
|
+
}
|
|
4355
|
+
);
|
|
4356
|
+
}
|
|
4357
|
+
);
|
|
4358
|
+
var TableCell = /* @__PURE__ */ react.forwardRef(
|
|
4359
|
+
function TableCell2({ className, ...props }, ref) {
|
|
4360
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4361
|
+
"td",
|
|
4362
|
+
{
|
|
4363
|
+
ref,
|
|
4364
|
+
"data-slot": "table-cell",
|
|
4365
|
+
className: cx("orynn-table__cell", className),
|
|
4366
|
+
...props
|
|
4367
|
+
}
|
|
4368
|
+
);
|
|
4369
|
+
}
|
|
4370
|
+
);
|
|
4371
|
+
var TableCaption = /* @__PURE__ */ react.forwardRef(function TableCaption2({ className, ...props }, ref) {
|
|
4372
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4373
|
+
"caption",
|
|
4374
|
+
{
|
|
4375
|
+
ref,
|
|
4376
|
+
"data-slot": "table-caption",
|
|
4377
|
+
className: cx("orynn-table__caption", className),
|
|
4378
|
+
...props
|
|
4379
|
+
}
|
|
4380
|
+
);
|
|
4381
|
+
});
|
|
4382
|
+
var Switch = /* @__PURE__ */ react.forwardRef(function Switch2({
|
|
4383
|
+
className,
|
|
4384
|
+
size = "default",
|
|
4385
|
+
label,
|
|
4386
|
+
description,
|
|
4387
|
+
labelPlacement = "end",
|
|
4388
|
+
onLabel,
|
|
4389
|
+
offLabel,
|
|
4390
|
+
thumbIcon,
|
|
4391
|
+
id: idProp,
|
|
4392
|
+
...props
|
|
4393
|
+
}, ref) {
|
|
4394
|
+
const reactId = react.useId();
|
|
4395
|
+
const id = idProp ?? reactId;
|
|
4396
|
+
const control = /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4397
|
+
radixUi.Switch.Root,
|
|
4398
|
+
{
|
|
4399
|
+
ref,
|
|
4400
|
+
id,
|
|
4401
|
+
"data-slot": "switch",
|
|
4402
|
+
"data-size": size,
|
|
4403
|
+
className: cx("orynn-switch", className),
|
|
4404
|
+
...props,
|
|
4405
|
+
children: [
|
|
4406
|
+
offLabel != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-switch__text orynn-switch__text--off", "aria-hidden": "true", children: offLabel }),
|
|
4407
|
+
onLabel != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-switch__text orynn-switch__text--on", "aria-hidden": "true", children: onLabel }),
|
|
4408
|
+
/* @__PURE__ */ jsxRuntime.jsx(radixUi.Switch.Thumb, { "data-slot": "switch-thumb", className: "orynn-switch__thumb", children: thumbIcon })
|
|
4409
|
+
]
|
|
4410
|
+
}
|
|
4411
|
+
);
|
|
4412
|
+
if (label == null && description == null) return control;
|
|
4413
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4414
|
+
"label",
|
|
4415
|
+
{
|
|
4416
|
+
className: "orynn-switch-field",
|
|
4417
|
+
"data-slot": "switch-field",
|
|
4418
|
+
"data-placement": labelPlacement,
|
|
4419
|
+
htmlFor: id,
|
|
4420
|
+
children: [
|
|
4421
|
+
control,
|
|
4422
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "orynn-switch-field__text", children: [
|
|
4423
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-switch-field__label", children: label }),
|
|
4424
|
+
description != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-switch-field__description", children: description })
|
|
4425
|
+
] })
|
|
4426
|
+
]
|
|
4427
|
+
}
|
|
4428
|
+
);
|
|
4429
|
+
});
|
|
4430
|
+
var Tabs = /* @__PURE__ */ react.forwardRef(function Tabs2({ className, variant = "pill", size = "md", fitted = false, ...props }, ref) {
|
|
4431
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4432
|
+
radixUi.Tabs.Root,
|
|
4433
|
+
{
|
|
4434
|
+
ref,
|
|
4435
|
+
"data-slot": "tabs",
|
|
4436
|
+
"data-variant": variant,
|
|
4437
|
+
"data-size": size,
|
|
4438
|
+
"data-fitted": fitted || void 0,
|
|
4439
|
+
className: cx("orynn-tabs", className),
|
|
4440
|
+
...props
|
|
4441
|
+
}
|
|
4442
|
+
);
|
|
4443
|
+
});
|
|
4444
|
+
var TabsList = /* @__PURE__ */ react.forwardRef(function TabsList2({ className, ...props }, ref) {
|
|
4445
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4446
|
+
radixUi.Tabs.List,
|
|
4447
|
+
{
|
|
4448
|
+
ref,
|
|
4449
|
+
"data-slot": "tabs-list",
|
|
4450
|
+
className: cx("orynn-tabs__list", className),
|
|
4451
|
+
...props
|
|
4452
|
+
}
|
|
4453
|
+
);
|
|
4454
|
+
});
|
|
4455
|
+
var TabsTrigger = /* @__PURE__ */ react.forwardRef(function TabsTrigger2({ className, ...props }, ref) {
|
|
4456
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4457
|
+
radixUi.Tabs.Trigger,
|
|
4458
|
+
{
|
|
4459
|
+
ref,
|
|
4460
|
+
"data-slot": "tabs-trigger",
|
|
4461
|
+
className: cx("orynn-tabs__trigger", className),
|
|
4462
|
+
...props
|
|
4463
|
+
}
|
|
4464
|
+
);
|
|
4465
|
+
});
|
|
4466
|
+
var TabsContent = /* @__PURE__ */ react.forwardRef(function TabsContent2({ className, ...props }, ref) {
|
|
4467
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4468
|
+
radixUi.Tabs.Content,
|
|
4469
|
+
{
|
|
4470
|
+
ref,
|
|
4471
|
+
"data-slot": "tabs-content",
|
|
4472
|
+
className: cx("orynn-tabs__content", className),
|
|
4473
|
+
...props
|
|
4474
|
+
}
|
|
4475
|
+
);
|
|
4476
|
+
});
|
|
4477
|
+
var Dialog = (props) => /* @__PURE__ */ jsxRuntime.jsx(radixUi.Dialog.Root, { "data-slot": "dialog", ...props });
|
|
4478
|
+
var DialogTrigger = (props) => /* @__PURE__ */ jsxRuntime.jsx(radixUi.Dialog.Trigger, { "data-slot": "dialog-trigger", ...props });
|
|
4479
|
+
var DialogClose = (props) => /* @__PURE__ */ jsxRuntime.jsx(radixUi.Dialog.Close, { "data-slot": "dialog-close", ...props });
|
|
4480
|
+
var DialogPortal = radixUi.Dialog.Portal;
|
|
4481
|
+
var DialogContent = /* @__PURE__ */ react.forwardRef(
|
|
4482
|
+
function DialogContent2({ className, children, showCloseButton = true, size = "lg", scrollable, container, ...props }, ref) {
|
|
4483
|
+
const themed = usePortalContainer();
|
|
4484
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(radixUi.Dialog.Portal, { container: container ?? themed ?? void 0, children: [
|
|
4485
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4486
|
+
radixUi.Dialog.Overlay,
|
|
4487
|
+
{
|
|
4488
|
+
"data-slot": "dialog-overlay",
|
|
4489
|
+
className: "orynn-overlay orynn-dialog__overlay"
|
|
4490
|
+
}
|
|
4491
|
+
),
|
|
4492
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4493
|
+
radixUi.Dialog.Content,
|
|
4494
|
+
{
|
|
4495
|
+
ref,
|
|
4496
|
+
"data-slot": "dialog-content",
|
|
4497
|
+
"data-size": size,
|
|
4498
|
+
"data-scrollable": scrollable || void 0,
|
|
4499
|
+
className: cx("orynn-dialog__content", className),
|
|
4500
|
+
...props,
|
|
4501
|
+
children: [
|
|
4502
|
+
children,
|
|
4503
|
+
showCloseButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4504
|
+
radixUi.Dialog.Close,
|
|
4505
|
+
{
|
|
4506
|
+
"data-slot": "dialog-close",
|
|
4507
|
+
className: "orynn-dialog__close",
|
|
4508
|
+
"aria-label": "Close",
|
|
4509
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(XIcon, {})
|
|
4510
|
+
}
|
|
4511
|
+
)
|
|
4512
|
+
]
|
|
4513
|
+
}
|
|
4514
|
+
)
|
|
4515
|
+
] });
|
|
4516
|
+
}
|
|
4517
|
+
);
|
|
4518
|
+
function DialogHeader({ className, ...props }) {
|
|
4519
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-slot": "dialog-header", className: cx("orynn-dialog__header", className), ...props });
|
|
2687
4520
|
}
|
|
2688
|
-
function
|
|
2689
|
-
return
|
|
4521
|
+
function DialogFooter({ className, ...props }) {
|
|
4522
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-slot": "dialog-footer", className: cx("orynn-dialog__footer", className), ...props });
|
|
4523
|
+
}
|
|
4524
|
+
var DialogTitle = /* @__PURE__ */ react.forwardRef(function DialogTitle2({ className, ...props }, ref) {
|
|
4525
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4526
|
+
radixUi.Dialog.Title,
|
|
4527
|
+
{
|
|
4528
|
+
ref,
|
|
4529
|
+
"data-slot": "dialog-title",
|
|
4530
|
+
className: cx("orynn-dialog__title", className),
|
|
4531
|
+
...props
|
|
4532
|
+
}
|
|
4533
|
+
);
|
|
4534
|
+
});
|
|
4535
|
+
var DialogDescription = /* @__PURE__ */ react.forwardRef(function DialogDescription2({ className, ...props }, ref) {
|
|
4536
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4537
|
+
radixUi.Dialog.Description,
|
|
4538
|
+
{
|
|
4539
|
+
ref,
|
|
4540
|
+
"data-slot": "dialog-description",
|
|
4541
|
+
className: cx("orynn-dialog__description", className),
|
|
4542
|
+
...props
|
|
4543
|
+
}
|
|
4544
|
+
);
|
|
4545
|
+
});
|
|
4546
|
+
var Popover2 = (props) => /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Root, { "data-slot": "popover", ...props });
|
|
4547
|
+
var PopoverTrigger = (props) => /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Trigger, { "data-slot": "popover-trigger", ...props });
|
|
4548
|
+
var PopoverAnchor = (props) => /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Anchor, { "data-slot": "popover-anchor", ...props });
|
|
4549
|
+
var PopoverClose = radixUi.Popover.Close;
|
|
4550
|
+
var PopoverArrow = (props) => /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Arrow, { "data-slot": "popover-arrow", className: "orynn-popover__arrow", ...props });
|
|
4551
|
+
var PopoverContent = /* @__PURE__ */ react.forwardRef(
|
|
4552
|
+
function PopoverContent2({ className, align = "center", sideOffset = 4, arrow = false, container, children, ...props }, ref) {
|
|
4553
|
+
const themed = usePortalContainer();
|
|
4554
|
+
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Popover.Portal, { container: container ?? themed ?? void 0, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4555
|
+
radixUi.Popover.Content,
|
|
4556
|
+
{
|
|
4557
|
+
ref,
|
|
4558
|
+
"data-slot": "popover-content",
|
|
4559
|
+
align,
|
|
4560
|
+
sideOffset,
|
|
4561
|
+
className: cx("orynn-content orynn-popover__content", className),
|
|
4562
|
+
...props,
|
|
4563
|
+
children: [
|
|
4564
|
+
children,
|
|
4565
|
+
arrow && /* @__PURE__ */ jsxRuntime.jsx(PopoverArrow, {})
|
|
4566
|
+
]
|
|
4567
|
+
}
|
|
4568
|
+
) });
|
|
4569
|
+
}
|
|
4570
|
+
);
|
|
4571
|
+
function TooltipProvider({
|
|
4572
|
+
delayDuration = 0,
|
|
4573
|
+
...props
|
|
4574
|
+
}) {
|
|
4575
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4576
|
+
radixUi.Tooltip.Provider,
|
|
4577
|
+
{
|
|
4578
|
+
"data-slot": "tooltip-provider",
|
|
4579
|
+
delayDuration,
|
|
4580
|
+
...props
|
|
4581
|
+
}
|
|
4582
|
+
);
|
|
4583
|
+
}
|
|
4584
|
+
function Tooltip({
|
|
4585
|
+
delayDuration = 0,
|
|
4586
|
+
skipDelayDuration,
|
|
4587
|
+
disableHoverableContent,
|
|
4588
|
+
disableProvider = false,
|
|
4589
|
+
...props
|
|
4590
|
+
}) {
|
|
4591
|
+
const root = /* @__PURE__ */ jsxRuntime.jsx(
|
|
4592
|
+
radixUi.Tooltip.Root,
|
|
4593
|
+
{
|
|
4594
|
+
"data-slot": "tooltip",
|
|
4595
|
+
delayDuration,
|
|
4596
|
+
disableHoverableContent,
|
|
4597
|
+
...props
|
|
4598
|
+
}
|
|
4599
|
+
);
|
|
4600
|
+
if (disableProvider) return root;
|
|
4601
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4602
|
+
TooltipProvider,
|
|
4603
|
+
{
|
|
4604
|
+
delayDuration,
|
|
4605
|
+
skipDelayDuration,
|
|
4606
|
+
disableHoverableContent,
|
|
4607
|
+
children: root
|
|
4608
|
+
}
|
|
4609
|
+
);
|
|
4610
|
+
}
|
|
4611
|
+
var TooltipTrigger = (props) => /* @__PURE__ */ jsxRuntime.jsx(radixUi.Tooltip.Trigger, { "data-slot": "tooltip-trigger", ...props });
|
|
4612
|
+
var TooltipContent = /* @__PURE__ */ react.forwardRef(
|
|
4613
|
+
function TooltipContent2({ className, sideOffset = 0, arrow = true, arrowSize = 11, container, children, ...props }, ref) {
|
|
4614
|
+
const themed = usePortalContainer();
|
|
4615
|
+
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.Tooltip.Portal, { container: container ?? themed ?? void 0, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4616
|
+
radixUi.Tooltip.Content,
|
|
4617
|
+
{
|
|
4618
|
+
ref,
|
|
4619
|
+
"data-slot": "tooltip-content",
|
|
4620
|
+
sideOffset,
|
|
4621
|
+
className: cx("orynn-content orynn-tooltip__content", className),
|
|
4622
|
+
...props,
|
|
4623
|
+
children: [
|
|
4624
|
+
children,
|
|
4625
|
+
arrow && /* @__PURE__ */ jsxRuntime.jsx(
|
|
4626
|
+
radixUi.Tooltip.Arrow,
|
|
4627
|
+
{
|
|
4628
|
+
width: arrowSize,
|
|
4629
|
+
height: Math.round(arrowSize / 2.2),
|
|
4630
|
+
className: "orynn-tooltip__arrow"
|
|
4631
|
+
}
|
|
4632
|
+
)
|
|
4633
|
+
]
|
|
4634
|
+
}
|
|
4635
|
+
) });
|
|
4636
|
+
}
|
|
4637
|
+
);
|
|
4638
|
+
var DropdownMenu = (props) => /* @__PURE__ */ jsxRuntime.jsx(radixUi.DropdownMenu.Root, { "data-slot": "dropdown-menu", ...props });
|
|
4639
|
+
var DropdownMenuTrigger = (props) => /* @__PURE__ */ jsxRuntime.jsx(radixUi.DropdownMenu.Trigger, { "data-slot": "dropdown-menu-trigger", ...props });
|
|
4640
|
+
var DropdownMenuGroup = radixUi.DropdownMenu.Group;
|
|
4641
|
+
var DropdownMenuPortal = radixUi.DropdownMenu.Portal;
|
|
4642
|
+
var DropdownMenuSub = radixUi.DropdownMenu.Sub;
|
|
4643
|
+
var DropdownMenuRadioGroup = radixUi.DropdownMenu.RadioGroup;
|
|
4644
|
+
var DropdownMenuContent = /* @__PURE__ */ react.forwardRef(function DropdownMenuContent2({ className, sideOffset = 4, container, ...props }, ref) {
|
|
4645
|
+
const themed = usePortalContainer();
|
|
4646
|
+
return /* @__PURE__ */ jsxRuntime.jsx(radixUi.DropdownMenu.Portal, { container: container ?? themed ?? void 0, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4647
|
+
radixUi.DropdownMenu.Content,
|
|
4648
|
+
{
|
|
4649
|
+
ref,
|
|
4650
|
+
"data-slot": "dropdown-menu-content",
|
|
4651
|
+
sideOffset,
|
|
4652
|
+
className: cx("orynn-content orynn-menu__content", className),
|
|
4653
|
+
...props
|
|
4654
|
+
}
|
|
4655
|
+
) });
|
|
4656
|
+
});
|
|
4657
|
+
var DropdownMenuItem = /* @__PURE__ */ react.forwardRef(
|
|
4658
|
+
function DropdownMenuItem2({ className, inset, variant = "default", icon, shortcut, children, ...props }, ref) {
|
|
4659
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4660
|
+
radixUi.DropdownMenu.Item,
|
|
4661
|
+
{
|
|
4662
|
+
ref,
|
|
4663
|
+
"data-slot": "dropdown-menu-item",
|
|
4664
|
+
"data-inset": inset || void 0,
|
|
4665
|
+
"data-variant": variant,
|
|
4666
|
+
className: cx("orynn-menu__item", className),
|
|
4667
|
+
...props,
|
|
4668
|
+
children: [
|
|
4669
|
+
icon,
|
|
4670
|
+
children,
|
|
4671
|
+
shortcut != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-menu__shortcut", children: shortcut })
|
|
4672
|
+
]
|
|
4673
|
+
}
|
|
4674
|
+
);
|
|
4675
|
+
}
|
|
4676
|
+
);
|
|
4677
|
+
var DropdownMenuCheckboxItem = /* @__PURE__ */ react.forwardRef(function DropdownMenuCheckboxItem2({ className, children, checked, ...props }, ref) {
|
|
4678
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4679
|
+
radixUi.DropdownMenu.CheckboxItem,
|
|
4680
|
+
{
|
|
4681
|
+
ref,
|
|
4682
|
+
"data-slot": "dropdown-menu-checkbox-item",
|
|
4683
|
+
className: cx("orynn-menu__item", "orynn-menu__item--check", className),
|
|
4684
|
+
checked,
|
|
4685
|
+
...props,
|
|
4686
|
+
children: [
|
|
4687
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-menu__indicator", children: /* @__PURE__ */ jsxRuntime.jsx(radixUi.DropdownMenu.ItemIndicator, { children: /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, {}) }) }),
|
|
4688
|
+
children
|
|
4689
|
+
]
|
|
4690
|
+
}
|
|
4691
|
+
);
|
|
4692
|
+
});
|
|
4693
|
+
var DropdownMenuRadioItem = /* @__PURE__ */ react.forwardRef(function DropdownMenuRadioItem2({ className, children, ...props }, ref) {
|
|
4694
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4695
|
+
radixUi.DropdownMenu.RadioItem,
|
|
4696
|
+
{
|
|
4697
|
+
ref,
|
|
4698
|
+
"data-slot": "dropdown-menu-radio-item",
|
|
4699
|
+
className: cx("orynn-menu__item", "orynn-menu__item--check", className),
|
|
4700
|
+
...props,
|
|
4701
|
+
children: [
|
|
4702
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "orynn-menu__indicator", children: /* @__PURE__ */ jsxRuntime.jsx(radixUi.DropdownMenu.ItemIndicator, { children: /* @__PURE__ */ jsxRuntime.jsx(CircleIcon, { className: "orynn-menu__dot" }) }) }),
|
|
4703
|
+
children
|
|
4704
|
+
]
|
|
4705
|
+
}
|
|
4706
|
+
);
|
|
4707
|
+
});
|
|
4708
|
+
var DropdownMenuLabel = /* @__PURE__ */ react.forwardRef(
|
|
4709
|
+
function DropdownMenuLabel2({ className, inset, ...props }, ref) {
|
|
4710
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4711
|
+
radixUi.DropdownMenu.Label,
|
|
4712
|
+
{
|
|
4713
|
+
ref,
|
|
4714
|
+
"data-slot": "dropdown-menu-label",
|
|
4715
|
+
"data-inset": inset || void 0,
|
|
4716
|
+
className: cx("orynn-menu__label", className),
|
|
4717
|
+
...props
|
|
4718
|
+
}
|
|
4719
|
+
);
|
|
4720
|
+
}
|
|
4721
|
+
);
|
|
4722
|
+
var DropdownMenuSeparator = /* @__PURE__ */ react.forwardRef(function DropdownMenuSeparator2({ className, ...props }, ref) {
|
|
4723
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4724
|
+
radixUi.DropdownMenu.Separator,
|
|
4725
|
+
{
|
|
4726
|
+
ref,
|
|
4727
|
+
"data-slot": "dropdown-menu-separator",
|
|
4728
|
+
className: cx("orynn-menu__separator", className),
|
|
4729
|
+
...props
|
|
4730
|
+
}
|
|
4731
|
+
);
|
|
4732
|
+
});
|
|
4733
|
+
function DropdownMenuShortcut({ className, ...props }) {
|
|
4734
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4735
|
+
"span",
|
|
4736
|
+
{
|
|
4737
|
+
"data-slot": "dropdown-menu-shortcut",
|
|
4738
|
+
className: cx("orynn-menu__shortcut", className),
|
|
4739
|
+
...props
|
|
4740
|
+
}
|
|
4741
|
+
);
|
|
2690
4742
|
}
|
|
4743
|
+
var DropdownMenuSubTrigger = /* @__PURE__ */ react.forwardRef(function DropdownMenuSubTrigger2({ className, inset, children, ...props }, ref) {
|
|
4744
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
4745
|
+
radixUi.DropdownMenu.SubTrigger,
|
|
4746
|
+
{
|
|
4747
|
+
ref,
|
|
4748
|
+
"data-slot": "dropdown-menu-sub-trigger",
|
|
4749
|
+
"data-inset": inset || void 0,
|
|
4750
|
+
className: cx("orynn-menu__item", "orynn-menu__sub-trigger", className),
|
|
4751
|
+
...props,
|
|
4752
|
+
children: [
|
|
4753
|
+
children,
|
|
4754
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChevronRightIcon, { className: "orynn-menu__sub-chevron" })
|
|
4755
|
+
]
|
|
4756
|
+
}
|
|
4757
|
+
);
|
|
4758
|
+
});
|
|
4759
|
+
var DropdownMenuSubContent = /* @__PURE__ */ react.forwardRef(function DropdownMenuSubContent2({ className, ...props }, ref) {
|
|
4760
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
4761
|
+
radixUi.DropdownMenu.SubContent,
|
|
4762
|
+
{
|
|
4763
|
+
ref,
|
|
4764
|
+
"data-slot": "dropdown-menu-sub-content",
|
|
4765
|
+
className: cx("orynn-content", "orynn-menu__content", "orynn-menu__sub-content", className),
|
|
4766
|
+
...props
|
|
4767
|
+
}
|
|
4768
|
+
);
|
|
4769
|
+
});
|
|
2691
4770
|
|
|
2692
4771
|
// src/types/validation.ts
|
|
2693
4772
|
var FORM_ERROR_KEY = "$form";
|
|
2694
4773
|
|
|
4774
|
+
// src/core/validation/standard-schema.ts
|
|
4775
|
+
function pathToField(path) {
|
|
4776
|
+
if (!path || path.length === 0) return { field: FORM_ERROR_KEY, rest: "" };
|
|
4777
|
+
const seg = (p) => String(typeof p === "object" && p !== null && "key" in p ? p.key : p);
|
|
4778
|
+
const parts = path.map(seg);
|
|
4779
|
+
return { field: parts[0] ?? FORM_ERROR_KEY, rest: parts.slice(1).join(".") };
|
|
4780
|
+
}
|
|
4781
|
+
function standardSchemaResolver(schema) {
|
|
4782
|
+
return (values) => {
|
|
4783
|
+
const out = schema["~standard"].validate(values);
|
|
4784
|
+
const toResult = (r) => {
|
|
4785
|
+
const result = {};
|
|
4786
|
+
if (!("issues" in r) || !r.issues) return result;
|
|
4787
|
+
for (const issue of r.issues) {
|
|
4788
|
+
const { field, rest } = pathToField(issue.path);
|
|
4789
|
+
const bucket = result[field] ?? [];
|
|
4790
|
+
bucket.push({ rule: "schema", message: issue.message, ...rest ? { path: rest } : {} });
|
|
4791
|
+
result[field] = bucket;
|
|
4792
|
+
}
|
|
4793
|
+
return result;
|
|
4794
|
+
};
|
|
4795
|
+
return out instanceof Promise ? out.then(toResult) : toResult(out);
|
|
4796
|
+
};
|
|
4797
|
+
}
|
|
4798
|
+
|
|
4799
|
+
exports.Alert = Alert;
|
|
4800
|
+
exports.AlertDescription = AlertDescription;
|
|
4801
|
+
exports.AlertTitle = AlertTitle;
|
|
4802
|
+
exports.Badge = Badge;
|
|
4803
|
+
exports.Button = Button;
|
|
4804
|
+
exports.Card = Card;
|
|
4805
|
+
exports.CardAction = CardAction;
|
|
4806
|
+
exports.CardContent = CardContent;
|
|
4807
|
+
exports.CardDescription = CardDescription;
|
|
4808
|
+
exports.CardFooter = CardFooter;
|
|
4809
|
+
exports.CardHeader = CardHeader;
|
|
4810
|
+
exports.CardTitle = CardTitle;
|
|
2695
4811
|
exports.Checkbox = Checkbox;
|
|
2696
4812
|
exports.CheckboxGroup = CheckboxGroup;
|
|
2697
4813
|
exports.DatePicker = DatePicker;
|
|
4814
|
+
exports.Dialog = Dialog;
|
|
4815
|
+
exports.DialogClose = DialogClose;
|
|
4816
|
+
exports.DialogContent = DialogContent;
|
|
4817
|
+
exports.DialogDescription = DialogDescription;
|
|
4818
|
+
exports.DialogFooter = DialogFooter;
|
|
4819
|
+
exports.DialogHeader = DialogHeader;
|
|
4820
|
+
exports.DialogPortal = DialogPortal;
|
|
4821
|
+
exports.DialogTitle = DialogTitle;
|
|
4822
|
+
exports.DialogTrigger = DialogTrigger;
|
|
2698
4823
|
exports.Dropdown = Dropdown;
|
|
4824
|
+
exports.DropdownMenu = DropdownMenu;
|
|
4825
|
+
exports.DropdownMenuCheckboxItem = DropdownMenuCheckboxItem;
|
|
4826
|
+
exports.DropdownMenuContent = DropdownMenuContent;
|
|
4827
|
+
exports.DropdownMenuGroup = DropdownMenuGroup;
|
|
4828
|
+
exports.DropdownMenuItem = DropdownMenuItem;
|
|
4829
|
+
exports.DropdownMenuLabel = DropdownMenuLabel;
|
|
4830
|
+
exports.DropdownMenuPortal = DropdownMenuPortal;
|
|
4831
|
+
exports.DropdownMenuRadioGroup = DropdownMenuRadioGroup;
|
|
4832
|
+
exports.DropdownMenuRadioItem = DropdownMenuRadioItem;
|
|
4833
|
+
exports.DropdownMenuSeparator = DropdownMenuSeparator;
|
|
4834
|
+
exports.DropdownMenuShortcut = DropdownMenuShortcut;
|
|
4835
|
+
exports.DropdownMenuSub = DropdownMenuSub;
|
|
4836
|
+
exports.DropdownMenuSubContent = DropdownMenuSubContent;
|
|
4837
|
+
exports.DropdownMenuSubTrigger = DropdownMenuSubTrigger;
|
|
4838
|
+
exports.DropdownMenuTrigger = DropdownMenuTrigger;
|
|
2699
4839
|
exports.FORM_ERROR_KEY = FORM_ERROR_KEY;
|
|
2700
4840
|
exports.Field = Field;
|
|
2701
4841
|
exports.FieldBox = FieldBox;
|
|
2702
4842
|
exports.Fieldset = Fieldset;
|
|
4843
|
+
exports.FieldsetView = FieldsetView;
|
|
4844
|
+
exports.Form = Form;
|
|
2703
4845
|
exports.Input = Input;
|
|
4846
|
+
exports.Label = Label;
|
|
2704
4847
|
exports.NumberField = NumberField;
|
|
2705
4848
|
exports.OrynnProvider = OrynnProvider;
|
|
4849
|
+
exports.Popover = Popover2;
|
|
4850
|
+
exports.PopoverAnchor = PopoverAnchor;
|
|
4851
|
+
exports.PopoverArrow = PopoverArrow;
|
|
4852
|
+
exports.PopoverClose = PopoverClose;
|
|
4853
|
+
exports.PopoverContent = PopoverContent;
|
|
4854
|
+
exports.PopoverTrigger = PopoverTrigger;
|
|
2706
4855
|
exports.Radio = Radio;
|
|
2707
4856
|
exports.RadioGroup = RadioGroup;
|
|
2708
4857
|
exports.Select = Dropdown;
|
|
4858
|
+
exports.Separator = Separator;
|
|
4859
|
+
exports.Switch = Switch;
|
|
4860
|
+
exports.Table = Table;
|
|
4861
|
+
exports.TableBody = TableBody;
|
|
4862
|
+
exports.TableCaption = TableCaption;
|
|
4863
|
+
exports.TableCell = TableCell;
|
|
4864
|
+
exports.TableFooter = TableFooter;
|
|
4865
|
+
exports.TableHead = TableHead;
|
|
4866
|
+
exports.TableHeader = TableHeader;
|
|
4867
|
+
exports.TableRow = TableRow;
|
|
4868
|
+
exports.Tabs = Tabs;
|
|
4869
|
+
exports.TabsContent = TabsContent;
|
|
4870
|
+
exports.TabsList = TabsList;
|
|
4871
|
+
exports.TabsTrigger = TabsTrigger;
|
|
2709
4872
|
exports.Textarea = Textarea;
|
|
4873
|
+
exports.Tooltip = Tooltip;
|
|
4874
|
+
exports.TooltipContent = TooltipContent;
|
|
4875
|
+
exports.TooltipProvider = TooltipProvider;
|
|
4876
|
+
exports.TooltipTrigger = TooltipTrigger;
|
|
4877
|
+
exports.badgeClasses = badgeClasses;
|
|
4878
|
+
exports.builtInRules = builtInRules;
|
|
4879
|
+
exports.buttonClasses = buttonClasses;
|
|
2710
4880
|
exports.createRegistry = createRegistry;
|
|
2711
4881
|
exports.createRuleResolver = createRuleResolver;
|
|
2712
4882
|
exports.defaultRegistry = defaultRegistry;
|
|
@@ -2715,7 +4885,9 @@ exports.normalizeConfig = normalizeConfig;
|
|
|
2715
4885
|
exports.registerField = registerField;
|
|
2716
4886
|
exports.registerRule = registerRule;
|
|
2717
4887
|
exports.resolveThemeVars = resolveThemeVars;
|
|
4888
|
+
exports.standardSchemaResolver = standardSchemaResolver;
|
|
2718
4889
|
exports.useFieldsetState = useFieldsetState;
|
|
2719
4890
|
exports.useOrynnTheme = useOrynnTheme;
|
|
4891
|
+
exports.usePortalContainer = usePortalContainer;
|
|
2720
4892
|
//# sourceMappingURL=index.cjs.map
|
|
2721
4893
|
//# sourceMappingURL=index.cjs.map
|