@bigtablet/design-system 3.16.0 → 3.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.css +2222 -1347
- package/dist/index.d.ts +1028 -197
- package/dist/index.js +1983 -782
- package/dist/styles/layout/_index.scss +18 -0
- package/dist/styles/typography/_index.scss +23 -0
- package/dist/vanilla/bigtablet.min.css +1 -1
- package/dist/vanilla/bigtablet.min.js +3 -3
- package/docs/AGENT_GUIDE.md +591 -0
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import './index.css';
|
|
3
3
|
import * as React11 from 'react';
|
|
4
|
-
import { createContext,
|
|
4
|
+
import { createContext, useState, useRef, useCallback, useEffect, useMemo, useContext, useId, Fragment, useImperativeHandle, useLayoutEffect } from 'react';
|
|
5
5
|
import { useSpring, animated } from '@react-spring/web';
|
|
6
|
-
import { ChevronDown, ChevronRight, Globe, ChevronLeft, ArrowUp, ArrowDown, ArrowUpDown, XCircle, AlertTriangle, CheckCircle2, Info, Bell,
|
|
6
|
+
import { ChevronDown, ChevronRight, Globe, ChevronLeft, EyeOff, Eye, ArrowUp, ArrowDown, ArrowUpDown, Search, XCircle, AlertTriangle, CheckCircle2, Info, Bell, Check, Image, X, TriangleAlert } from 'lucide-react';
|
|
7
7
|
import { jsx, jsxs, Fragment as Fragment$1 } from 'react/jsx-runtime';
|
|
8
8
|
import { createPortal } from 'react-dom';
|
|
9
9
|
|
|
@@ -409,6 +409,168 @@ function useSpringPresence({
|
|
|
409
409
|
}
|
|
410
410
|
});
|
|
411
411
|
}
|
|
412
|
+
var MIN_SPACE_BELOW = 120;
|
|
413
|
+
function useListboxPopup({
|
|
414
|
+
items,
|
|
415
|
+
onCommit,
|
|
416
|
+
disabled = false,
|
|
417
|
+
returnFocusOnClose = false,
|
|
418
|
+
initialActiveIndex
|
|
419
|
+
}) {
|
|
420
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
421
|
+
const [activeIndex, setActiveIndex] = useState(-1);
|
|
422
|
+
const [dropUp, setDropUp] = useState(false);
|
|
423
|
+
const wrapperRef = useRef(null);
|
|
424
|
+
const triggerRef = useRef(null);
|
|
425
|
+
const listRef = useRef(null);
|
|
426
|
+
const close = useCallback(() => {
|
|
427
|
+
setIsOpen(false);
|
|
428
|
+
if (returnFocusOnClose) triggerRef.current?.focus();
|
|
429
|
+
}, [returnFocusOnClose]);
|
|
430
|
+
useEffect(() => {
|
|
431
|
+
const handleOutsideClick = (event) => {
|
|
432
|
+
if (!wrapperRef.current?.contains(event.target)) setIsOpen(false);
|
|
433
|
+
};
|
|
434
|
+
document.addEventListener("mousedown", handleOutsideClick);
|
|
435
|
+
return () => document.removeEventListener("mousedown", handleOutsideClick);
|
|
436
|
+
}, []);
|
|
437
|
+
const moveActive = useCallback(
|
|
438
|
+
(dir) => {
|
|
439
|
+
if (items.length === 0) return;
|
|
440
|
+
if (!isOpen) {
|
|
441
|
+
setIsOpen(true);
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
let i = activeIndex;
|
|
445
|
+
if (i === -1) {
|
|
446
|
+
i = dir === 1 ? -1 : 0;
|
|
447
|
+
}
|
|
448
|
+
const len = items.length;
|
|
449
|
+
for (let step = 0; step < len; step++) {
|
|
450
|
+
i = (i + dir + len) % len;
|
|
451
|
+
if (!items[i].disabled) {
|
|
452
|
+
setActiveIndex(i);
|
|
453
|
+
break;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
},
|
|
457
|
+
[items, isOpen, activeIndex]
|
|
458
|
+
);
|
|
459
|
+
const commitActive = useCallback(() => {
|
|
460
|
+
if (activeIndex < 0 || activeIndex >= items.length) return;
|
|
461
|
+
const item = items[activeIndex];
|
|
462
|
+
if (item.disabled) return;
|
|
463
|
+
onCommit(item);
|
|
464
|
+
}, [activeIndex, items, onCommit]);
|
|
465
|
+
const firstEnabled = useCallback(() => items.findIndex((o) => !o.disabled), [items]);
|
|
466
|
+
const lastEnabled = useCallback(() => {
|
|
467
|
+
for (let i = items.length - 1; i >= 0; i--) {
|
|
468
|
+
if (!items[i].disabled) return i;
|
|
469
|
+
}
|
|
470
|
+
return -1;
|
|
471
|
+
}, [items]);
|
|
472
|
+
const onTriggerKeyDown = useCallback(
|
|
473
|
+
(event) => {
|
|
474
|
+
if (disabled) return;
|
|
475
|
+
switch (event.key) {
|
|
476
|
+
case " ":
|
|
477
|
+
case "Enter":
|
|
478
|
+
event.preventDefault();
|
|
479
|
+
if (!isOpen) setIsOpen(true);
|
|
480
|
+
else commitActive();
|
|
481
|
+
break;
|
|
482
|
+
case "ArrowDown":
|
|
483
|
+
event.preventDefault();
|
|
484
|
+
moveActive(1);
|
|
485
|
+
break;
|
|
486
|
+
case "ArrowUp":
|
|
487
|
+
event.preventDefault();
|
|
488
|
+
moveActive(-1);
|
|
489
|
+
break;
|
|
490
|
+
case "Home":
|
|
491
|
+
event.preventDefault();
|
|
492
|
+
setIsOpen(true);
|
|
493
|
+
setActiveIndex(firstEnabled());
|
|
494
|
+
break;
|
|
495
|
+
case "End":
|
|
496
|
+
event.preventDefault();
|
|
497
|
+
setIsOpen(true);
|
|
498
|
+
setActiveIndex(lastEnabled());
|
|
499
|
+
break;
|
|
500
|
+
case "Escape":
|
|
501
|
+
event.preventDefault();
|
|
502
|
+
setIsOpen(false);
|
|
503
|
+
break;
|
|
504
|
+
case "Tab":
|
|
505
|
+
setIsOpen(false);
|
|
506
|
+
break;
|
|
507
|
+
}
|
|
508
|
+
},
|
|
509
|
+
[disabled, isOpen, commitActive, moveActive, firstEnabled, lastEnabled]
|
|
510
|
+
);
|
|
511
|
+
const onInputKeyDown = useCallback(
|
|
512
|
+
(event) => {
|
|
513
|
+
if (disabled) return;
|
|
514
|
+
if (event.nativeEvent.isComposing) return;
|
|
515
|
+
switch (event.key) {
|
|
516
|
+
case "ArrowDown":
|
|
517
|
+
event.preventDefault();
|
|
518
|
+
moveActive(1);
|
|
519
|
+
break;
|
|
520
|
+
case "ArrowUp":
|
|
521
|
+
event.preventDefault();
|
|
522
|
+
moveActive(-1);
|
|
523
|
+
break;
|
|
524
|
+
case "Enter":
|
|
525
|
+
event.preventDefault();
|
|
526
|
+
commitActive();
|
|
527
|
+
break;
|
|
528
|
+
case "Escape":
|
|
529
|
+
event.preventDefault();
|
|
530
|
+
close();
|
|
531
|
+
break;
|
|
532
|
+
case "Tab":
|
|
533
|
+
close();
|
|
534
|
+
break;
|
|
535
|
+
}
|
|
536
|
+
},
|
|
537
|
+
[disabled, moveActive, commitActive, close]
|
|
538
|
+
);
|
|
539
|
+
useEffect(() => {
|
|
540
|
+
if (!isOpen) return;
|
|
541
|
+
const preferred = initialActiveIndex?.(items) ?? -1;
|
|
542
|
+
setActiveIndex(preferred >= 0 ? preferred : items.findIndex((o) => !o.disabled));
|
|
543
|
+
}, [isOpen, items]);
|
|
544
|
+
useEffect(() => {
|
|
545
|
+
if (!isOpen || activeIndex < 0) return;
|
|
546
|
+
const list = listRef.current;
|
|
547
|
+
if (!list) return;
|
|
548
|
+
const option = list.querySelectorAll('[role="option"]')[activeIndex];
|
|
549
|
+
option?.scrollIntoView?.({ block: "nearest" });
|
|
550
|
+
}, [isOpen, activeIndex, items]);
|
|
551
|
+
useEffect(() => {
|
|
552
|
+
if (!isOpen || !triggerRef.current) return;
|
|
553
|
+
const rect = triggerRef.current.getBoundingClientRect();
|
|
554
|
+
const spaceBelow = window.innerHeight - rect.bottom;
|
|
555
|
+
const spaceAbove = rect.top;
|
|
556
|
+
setDropUp(spaceBelow < MIN_SPACE_BELOW && spaceAbove > spaceBelow);
|
|
557
|
+
}, [isOpen]);
|
|
558
|
+
return {
|
|
559
|
+
isOpen,
|
|
560
|
+
setIsOpen,
|
|
561
|
+
dropUp,
|
|
562
|
+
activeIndex,
|
|
563
|
+
setActiveIndex,
|
|
564
|
+
wrapperRef,
|
|
565
|
+
triggerRef,
|
|
566
|
+
listRef,
|
|
567
|
+
close,
|
|
568
|
+
moveActive,
|
|
569
|
+
commitActive,
|
|
570
|
+
onTriggerKeyDown,
|
|
571
|
+
onInputKeyDown
|
|
572
|
+
};
|
|
573
|
+
}
|
|
412
574
|
|
|
413
575
|
// src/styles/icon/index.ts
|
|
414
576
|
var iconSize = {
|
|
@@ -550,6 +712,90 @@ var Badge = ({
|
|
|
550
712
|
}
|
|
551
713
|
);
|
|
552
714
|
};
|
|
715
|
+
var DescriptionList = ({
|
|
716
|
+
items,
|
|
717
|
+
layout = "row",
|
|
718
|
+
divided = false,
|
|
719
|
+
className,
|
|
720
|
+
ref,
|
|
721
|
+
...props
|
|
722
|
+
}) => /* @__PURE__ */ jsx(
|
|
723
|
+
"dl",
|
|
724
|
+
{
|
|
725
|
+
ref,
|
|
726
|
+
className: cn(
|
|
727
|
+
"description_list",
|
|
728
|
+
`description_list_layout_${layout}`,
|
|
729
|
+
{ description_list_divided: divided },
|
|
730
|
+
className
|
|
731
|
+
),
|
|
732
|
+
...props,
|
|
733
|
+
children: items.map((item, index) => /* @__PURE__ */ jsxs(
|
|
734
|
+
"div",
|
|
735
|
+
{
|
|
736
|
+
className: cn("description_list_item", { description_list_item_full: item.full }),
|
|
737
|
+
children: [
|
|
738
|
+
/* @__PURE__ */ jsx("dt", { className: "description_list_label", children: item.label }),
|
|
739
|
+
/* @__PURE__ */ jsx("dd", { className: "description_list_value", children: item.value })
|
|
740
|
+
]
|
|
741
|
+
},
|
|
742
|
+
index
|
|
743
|
+
))
|
|
744
|
+
}
|
|
745
|
+
);
|
|
746
|
+
var isPresent = (value) => value !== void 0 && value !== null && value !== "";
|
|
747
|
+
var Stat = ({
|
|
748
|
+
label,
|
|
749
|
+
value,
|
|
750
|
+
delta,
|
|
751
|
+
deltaTone = "neutral",
|
|
752
|
+
icon,
|
|
753
|
+
className,
|
|
754
|
+
ref,
|
|
755
|
+
...props
|
|
756
|
+
}) => /* @__PURE__ */ jsxs("div", { ref, className: cn("stat", className), ...props, children: [
|
|
757
|
+
/* @__PURE__ */ jsxs("div", { className: "stat_label", children: [
|
|
758
|
+
icon && /* @__PURE__ */ jsx("span", { className: "stat_icon", "aria-hidden": "true", children: icon }),
|
|
759
|
+
label
|
|
760
|
+
] }),
|
|
761
|
+
/* @__PURE__ */ jsx("div", { className: "stat_value", children: value }),
|
|
762
|
+
isPresent(delta) && /* @__PURE__ */ jsx("div", { className: cn("stat_delta", `stat_delta_${deltaTone}`), children: delta })
|
|
763
|
+
] });
|
|
764
|
+
var CheckGlyph = () => /* @__PURE__ */ jsx(
|
|
765
|
+
"svg",
|
|
766
|
+
{
|
|
767
|
+
viewBox: "0 0 20 20",
|
|
768
|
+
fill: "none",
|
|
769
|
+
stroke: "currentColor",
|
|
770
|
+
strokeWidth: 2,
|
|
771
|
+
strokeLinecap: "round",
|
|
772
|
+
strokeLinejoin: "round",
|
|
773
|
+
"aria-hidden": "true",
|
|
774
|
+
focusable: "false",
|
|
775
|
+
className: "timeline_glyph",
|
|
776
|
+
children: /* @__PURE__ */ jsx("polyline", { points: "4 10 8 14 16 6" })
|
|
777
|
+
}
|
|
778
|
+
);
|
|
779
|
+
var isPresent2 = (value) => value !== void 0 && value !== null && value !== "";
|
|
780
|
+
var Timeline = ({ items, className, ref, ...props }) => /* @__PURE__ */ jsx("ol", { ref, className: cn("timeline", className), ...props, children: items.map((item) => {
|
|
781
|
+
const status = item.status ?? "pending";
|
|
782
|
+
return /* @__PURE__ */ jsxs("li", { className: cn("timeline_item", `timeline_item_${status}`), children: [
|
|
783
|
+
/* @__PURE__ */ jsx("span", { className: "timeline_indicator", "aria-hidden": "true", children: item.icon ?? (status === "done" ? /* @__PURE__ */ jsx(CheckGlyph, {}) : /* @__PURE__ */ jsx(
|
|
784
|
+
"span",
|
|
785
|
+
{
|
|
786
|
+
className: cn("timeline_dot", { timeline_dot_hollow: status === "pending" })
|
|
787
|
+
}
|
|
788
|
+
)) }),
|
|
789
|
+
/* @__PURE__ */ jsxs("div", { className: "timeline_body", children: [
|
|
790
|
+
/* @__PURE__ */ jsxs("div", { className: "timeline_head", children: [
|
|
791
|
+
/* @__PURE__ */ jsx("div", { className: "timeline_title", children: item.title }),
|
|
792
|
+
isPresent2(item.time) && /* @__PURE__ */ jsx("div", { className: "timeline_time", children: item.time })
|
|
793
|
+
] }),
|
|
794
|
+
isPresent2(item.description) && /* @__PURE__ */ jsx("div", { className: "timeline_description", children: item.description }),
|
|
795
|
+
item.children
|
|
796
|
+
] })
|
|
797
|
+
] }, item.id);
|
|
798
|
+
}) });
|
|
553
799
|
var EmptyState = ({
|
|
554
800
|
illustration,
|
|
555
801
|
title,
|
|
@@ -579,12 +825,181 @@ var EmptyState = ({
|
|
|
579
825
|
}
|
|
580
826
|
);
|
|
581
827
|
};
|
|
828
|
+
|
|
829
|
+
// src/ui/system/locale-provider/messages.ts
|
|
830
|
+
var ko = {
|
|
831
|
+
"chip.remove": "{label} \uC81C\uAC70",
|
|
832
|
+
"dataView.clearSelection": "\uC120\uD0DD \uD574\uC81C",
|
|
833
|
+
"dataView.empty": "\uB370\uC774\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4",
|
|
834
|
+
"dataView.errorTitle": "\uBD88\uB7EC\uC624\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4",
|
|
835
|
+
"dataView.retry": "\uB2E4\uC2DC \uC2DC\uB3C4",
|
|
836
|
+
"dataView.search": "\uAC80\uC0C9",
|
|
837
|
+
"dataView.selectionSummary": "{count}\uAC1C \uC120\uD0DD\uB428",
|
|
838
|
+
"table.empty": "\uB370\uC774\uD130\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4",
|
|
839
|
+
"table.rowClickHint": "\uD074\uB9AD \uAC00\uB2A5\uD55C \uD589",
|
|
840
|
+
"table.selectAll": "\uC804\uCCB4 \uC120\uD0DD",
|
|
841
|
+
"table.selectRow": "{index}\uBC88\uC9F8 \uD589 \uC120\uD0DD",
|
|
842
|
+
"alert.cancel": "\uCDE8\uC18C",
|
|
843
|
+
"alert.confirm": "\uD655\uC778",
|
|
844
|
+
"errorState.title": "\uBB38\uC81C\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4",
|
|
845
|
+
"spinner.label": "\uB85C\uB529 \uC911",
|
|
846
|
+
"toast.close": "\uB2EB\uAE30",
|
|
847
|
+
"toast.region": "\uC54C\uB9BC",
|
|
848
|
+
"topLoading.label": "\uD398\uC774\uC9C0 \uB85C\uB529 \uC911",
|
|
849
|
+
"combobox.empty": "\uC77C\uCE58\uD558\uB294 \uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4",
|
|
850
|
+
"combobox.idle": "\uAC80\uC0C9\uC5B4\uB97C \uC785\uB825\uD558\uC138\uC694",
|
|
851
|
+
"combobox.loading": "\uAC80\uC0C9 \uC911",
|
|
852
|
+
"combobox.placeholder": "\uAC80\uC0C9\uD574\uC11C \uC120\uD0DD",
|
|
853
|
+
"datePicker.day": "\uC77C",
|
|
854
|
+
"datePicker.minDateSr": "\uCD5C\uC18C \uB0A0\uC9DC: {date}",
|
|
855
|
+
"datePicker.month": "\uC6D4",
|
|
856
|
+
"datePicker.rangeUntilTodaySr": "\uC624\uB298\uAE4C\uC9C0 \uC120\uD0DD \uAC00\uB2A5",
|
|
857
|
+
"datePicker.year": "\uB144",
|
|
858
|
+
"dateRange.end": "\uC885\uB8CC\uC77C",
|
|
859
|
+
"dateRange.start": "\uC2DC\uC791\uC77C",
|
|
860
|
+
"dropdown.empty": "\uACB0\uACFC \uC5C6\uC74C",
|
|
861
|
+
"dropdown.placeholder": "\uC120\uD0DD\u2026",
|
|
862
|
+
"dropdown.searchPlaceholder": "\uAC80\uC0C9\u2026",
|
|
863
|
+
"dropdown.selectedSummary": "{count}\uAC1C \uC120\uD0DD",
|
|
864
|
+
"fileInput.label": "\uD30C\uC77C \uC120\uD0DD",
|
|
865
|
+
"fileInput.removeImage": "\uC774\uBBF8\uC9C0 \uC81C\uAC70",
|
|
866
|
+
"imageCropper.hint": "\uB4DC\uB798\uADF8(\uB610\uB294 \uBC29\uD5A5\uD0A4)\uB85C \uC704\uCE58, \uD720\xB7\uC2AC\uB77C\uC774\uB354\uB85C \uBC30\uC728\uC744 \uB9DE\uCD94\uC138\uC694.",
|
|
867
|
+
"imageCropper.label": "\uC774\uBBF8\uC9C0 \uC704\uCE58\uC640 \uBC30\uC728 \uC870\uC815",
|
|
868
|
+
"imageCropper.noPanHint": "\uC774\uBBF8\uC9C0\uAC00 \uBDF0\uD3EC\uD2B8\uB97C \uB531 \uCC44\uC6CC \uC774\uB3D9 \uC5EC\uC720\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.",
|
|
869
|
+
"imageCropper.zoom": "\uBC30\uC728",
|
|
870
|
+
"imageCropper.zoomIn": "\uD655\uB300",
|
|
871
|
+
"imageCropper.zoomOut": "\uCD95\uC18C",
|
|
872
|
+
"otpInput.digit": "{index}\uBC88\uC9F8 \uC790\uB9AC",
|
|
873
|
+
"otpInput.label": "OTP \uC785\uB825",
|
|
874
|
+
"tagInput.added": "{names} \uCD94\uAC00\uB428",
|
|
875
|
+
"tagInput.addedWithNotes": "{names} \uCD94\uAC00\uB428 ({notes})",
|
|
876
|
+
"tagInput.atCap": "\uCD5C\uB300 {max}\uAC1C\uAE4C\uC9C0 \uCD94\uAC00\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4",
|
|
877
|
+
"tagInput.duplicate": "{names} \uC774\uBBF8 \uC788\uC74C",
|
|
878
|
+
"tagInput.placeholder": "\uC785\uB825 \uD6C4 Enter",
|
|
879
|
+
"tagInput.removed": "{name} \uC81C\uAC70\uB428",
|
|
880
|
+
"textField.clear": "\uC9C0\uC6B0\uAE30",
|
|
881
|
+
"textField.passwordHide": "\uBE44\uBC00\uBC88\uD638 \uC228\uAE30\uAE30",
|
|
882
|
+
"textField.passwordShow": "\uBE44\uBC00\uBC88\uD638 \uD45C\uC2DC",
|
|
883
|
+
"timePicker.hour": "\uC2DC",
|
|
884
|
+
"timePicker.minute": "\uBD84",
|
|
885
|
+
"timePicker.rangeSr": "{min} \uBD80\uD130 {max} \uAE4C\uC9C0 \uC120\uD0DD \uAC00\uB2A5",
|
|
886
|
+
"bottomNav.label": "\uC8FC\uC694 \uBA54\uB274",
|
|
887
|
+
"breadcrumb.label": "\uD604\uC7AC \uC704\uCE58",
|
|
888
|
+
"pagination.label": "\uD398\uC774\uC9C0 \uC774\uB3D9",
|
|
889
|
+
"pagination.next": "\uB2E4\uC74C \uD398\uC774\uC9C0",
|
|
890
|
+
"pagination.prev": "\uC774\uC804 \uD398\uC774\uC9C0",
|
|
891
|
+
"sidebar.toggle": "\uC0AC\uC774\uB4DC\uBC14 \uD1A0\uAE00",
|
|
892
|
+
"drawer.close": "\uB2EB\uAE30",
|
|
893
|
+
"modal.close": "\uB2EB\uAE30"
|
|
894
|
+
};
|
|
895
|
+
var en = {
|
|
896
|
+
"chip.remove": "Remove {label}",
|
|
897
|
+
"dataView.clearSelection": "Clear selection",
|
|
898
|
+
"dataView.empty": "No data",
|
|
899
|
+
"dataView.errorTitle": "Could not load",
|
|
900
|
+
"dataView.retry": "Try again",
|
|
901
|
+
"dataView.search": "Search",
|
|
902
|
+
"dataView.selectionSummary": "{count} selected",
|
|
903
|
+
"table.empty": "No data",
|
|
904
|
+
"table.rowClickHint": "Clickable row",
|
|
905
|
+
"table.selectAll": "Select all",
|
|
906
|
+
"table.selectRow": "Select row {index}",
|
|
907
|
+
"alert.cancel": "Cancel",
|
|
908
|
+
"alert.confirm": "OK",
|
|
909
|
+
"errorState.title": "Something went wrong",
|
|
910
|
+
"spinner.label": "Loading",
|
|
911
|
+
"toast.close": "Close",
|
|
912
|
+
"toast.region": "Notifications",
|
|
913
|
+
"topLoading.label": "Loading page",
|
|
914
|
+
"combobox.empty": "No matches",
|
|
915
|
+
"combobox.idle": "Type to search",
|
|
916
|
+
"combobox.loading": "Searching",
|
|
917
|
+
"combobox.placeholder": "Search to select",
|
|
918
|
+
"datePicker.day": "Day",
|
|
919
|
+
"datePicker.minDateSr": "Earliest date: {date}",
|
|
920
|
+
"datePicker.month": "Month",
|
|
921
|
+
"datePicker.rangeUntilTodaySr": "Selectable up to today",
|
|
922
|
+
"datePicker.year": "Year",
|
|
923
|
+
"dateRange.end": "End date",
|
|
924
|
+
"dateRange.start": "Start date",
|
|
925
|
+
"dropdown.empty": "No results",
|
|
926
|
+
"dropdown.placeholder": "Select\u2026",
|
|
927
|
+
"dropdown.searchPlaceholder": "Search\u2026",
|
|
928
|
+
"dropdown.selectedSummary": "{count} selected",
|
|
929
|
+
"fileInput.label": "Choose file",
|
|
930
|
+
"fileInput.removeImage": "Remove image",
|
|
931
|
+
"imageCropper.hint": "Drag (or use arrow keys) to move, wheel or slider to zoom.",
|
|
932
|
+
"imageCropper.label": "Adjust image position and zoom",
|
|
933
|
+
"imageCropper.noPanHint": "The image fills the viewport exactly, so there is no room to move it.",
|
|
934
|
+
"imageCropper.zoom": "Zoom",
|
|
935
|
+
"imageCropper.zoomIn": "Zoom in",
|
|
936
|
+
"imageCropper.zoomOut": "Zoom out",
|
|
937
|
+
"otpInput.digit": "Digit {index}",
|
|
938
|
+
"otpInput.label": "One-time code",
|
|
939
|
+
"tagInput.added": "{names} added",
|
|
940
|
+
"tagInput.addedWithNotes": "{names} added ({notes})",
|
|
941
|
+
"tagInput.atCap": "You can add up to {max}",
|
|
942
|
+
"tagInput.duplicate": "{names} already added",
|
|
943
|
+
"tagInput.placeholder": "Type and press Enter",
|
|
944
|
+
"tagInput.removed": "{name} removed",
|
|
945
|
+
"textField.clear": "Clear",
|
|
946
|
+
"textField.passwordHide": "Hide password",
|
|
947
|
+
"textField.passwordShow": "Show password",
|
|
948
|
+
"timePicker.hour": "Hour",
|
|
949
|
+
"timePicker.minute": "Minute",
|
|
950
|
+
"timePicker.rangeSr": "Selectable from {min} to {max}",
|
|
951
|
+
"bottomNav.label": "Main menu",
|
|
952
|
+
"breadcrumb.label": "Breadcrumb",
|
|
953
|
+
"pagination.label": "Pagination",
|
|
954
|
+
"pagination.next": "Next page",
|
|
955
|
+
"pagination.prev": "Previous page",
|
|
956
|
+
"sidebar.toggle": "Toggle sidebar",
|
|
957
|
+
"drawer.close": "Close",
|
|
958
|
+
"modal.close": "Close"
|
|
959
|
+
};
|
|
960
|
+
var catalogs = { ko, en };
|
|
961
|
+
function format(template, vars) {
|
|
962
|
+
if (!vars) return template;
|
|
963
|
+
return template.replace(
|
|
964
|
+
/\{(\w+)\}/g,
|
|
965
|
+
(whole, name) => name in vars ? String(vars[name]) : whole
|
|
966
|
+
);
|
|
967
|
+
}
|
|
968
|
+
function makeText(messages) {
|
|
969
|
+
return (key, vars) => format(messages[key], vars);
|
|
970
|
+
}
|
|
971
|
+
var FALLBACK = { locale: "ko", t: makeText(ko) };
|
|
972
|
+
var LocaleContext = createContext(void 0);
|
|
973
|
+
var LocaleProvider = ({ locale = "ko", messages, children }) => {
|
|
974
|
+
const stableMessages = useStableMessages(messages);
|
|
975
|
+
const value = useMemo(() => {
|
|
976
|
+
const base = catalogs[locale];
|
|
977
|
+
const merged = stableMessages ? { ...base, ...stableMessages } : base;
|
|
978
|
+
return { locale, t: makeText(merged) };
|
|
979
|
+
}, [locale, stableMessages]);
|
|
980
|
+
return /* @__PURE__ */ jsx(LocaleContext.Provider, { value, children });
|
|
981
|
+
};
|
|
982
|
+
function useStableMessages(messages) {
|
|
983
|
+
const ref = useRef(messages);
|
|
984
|
+
const previous = ref.current;
|
|
985
|
+
const same = previous === messages || !!previous && !!messages && Object.keys(previous).length === Object.keys(messages).length && Object.keys(messages).every((key) => previous[key] === messages[key]);
|
|
986
|
+
useEffect(() => {
|
|
987
|
+
if (!same) ref.current = messages;
|
|
988
|
+
}, [same, messages]);
|
|
989
|
+
return same ? previous : messages;
|
|
990
|
+
}
|
|
991
|
+
function useLocaleText() {
|
|
992
|
+
return (useContext(LocaleContext) ?? FALLBACK).t;
|
|
993
|
+
}
|
|
994
|
+
function useLocaleName() {
|
|
995
|
+
return (useContext(LocaleContext) ?? FALLBACK).locale;
|
|
996
|
+
}
|
|
582
997
|
var DEFAULT_ICON_SIZE = {
|
|
583
998
|
page: 48,
|
|
584
999
|
widget: 28
|
|
585
1000
|
};
|
|
586
1001
|
var ErrorState = ({
|
|
587
|
-
title
|
|
1002
|
+
title: titleProp,
|
|
588
1003
|
description,
|
|
589
1004
|
icon,
|
|
590
1005
|
action,
|
|
@@ -592,6 +1007,8 @@ var ErrorState = ({
|
|
|
592
1007
|
className,
|
|
593
1008
|
...props
|
|
594
1009
|
}) => {
|
|
1010
|
+
const t = useLocaleText();
|
|
1011
|
+
const title = titleProp === void 0 ? t("errorState.title") : titleProp;
|
|
595
1012
|
const resolvedIcon = icon === null ? null : icon ?? /* @__PURE__ */ jsx(TriangleAlert, { size: DEFAULT_ICON_SIZE[variant], strokeWidth: 1.5 });
|
|
596
1013
|
return /* @__PURE__ */ jsxs(
|
|
597
1014
|
"div",
|
|
@@ -609,15 +1026,17 @@ var ErrorState = ({
|
|
|
609
1026
|
);
|
|
610
1027
|
};
|
|
611
1028
|
var BottomNav = ({
|
|
612
|
-
ariaLabel
|
|
1029
|
+
ariaLabel: ariaLabelProp,
|
|
613
1030
|
className,
|
|
614
1031
|
children,
|
|
615
1032
|
...props
|
|
616
1033
|
}) => {
|
|
1034
|
+
const t = useLocaleText();
|
|
1035
|
+
const ariaLabel = ariaLabelProp ?? t("bottomNav.label");
|
|
617
1036
|
return /* @__PURE__ */ jsx("nav", { className: cn("bottom_nav", className), "aria-label": ariaLabel, ...props, children });
|
|
618
1037
|
};
|
|
619
1038
|
var BottomNavItem = (props) => {
|
|
620
|
-
const { icon, label, active, badge, as
|
|
1039
|
+
const { icon, label, active, badge, as, className, disabled, ref, ...rest } = props;
|
|
621
1040
|
const classes = cn(
|
|
622
1041
|
"bottom_nav_item",
|
|
623
1042
|
active && "bottom_nav_item_active",
|
|
@@ -625,6 +1044,8 @@ var BottomNavItem = (props) => {
|
|
|
625
1044
|
className
|
|
626
1045
|
);
|
|
627
1046
|
const ariaCurrent = active ? "page" : void 0;
|
|
1047
|
+
const anchorRest = rest;
|
|
1048
|
+
const Tag = as ?? (anchorRest.href != null ? "a" : "button");
|
|
628
1049
|
const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
629
1050
|
/* @__PURE__ */ jsxs("span", { className: "bottom_nav_item_icon", "aria-hidden": "true", children: [
|
|
630
1051
|
icon,
|
|
@@ -632,38 +1053,45 @@ var BottomNavItem = (props) => {
|
|
|
632
1053
|
] }),
|
|
633
1054
|
/* @__PURE__ */ jsx("span", { className: "bottom_nav_item_label", children: label })
|
|
634
1055
|
] });
|
|
635
|
-
if (
|
|
636
|
-
const {
|
|
1056
|
+
if (Tag === "button") {
|
|
1057
|
+
const {
|
|
1058
|
+
type,
|
|
1059
|
+
onClick: onClick2,
|
|
1060
|
+
href: _href,
|
|
1061
|
+
...buttonRest
|
|
1062
|
+
} = rest;
|
|
637
1063
|
return /* @__PURE__ */ jsx(
|
|
638
|
-
"
|
|
1064
|
+
"button",
|
|
639
1065
|
{
|
|
1066
|
+
ref,
|
|
1067
|
+
type: type ?? "button",
|
|
640
1068
|
className: classes,
|
|
641
|
-
|
|
1069
|
+
disabled,
|
|
642
1070
|
"aria-current": ariaCurrent,
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
onClick: (e) => {
|
|
646
|
-
if (disabled) {
|
|
647
|
-
e.preventDefault();
|
|
648
|
-
return;
|
|
649
|
-
}
|
|
650
|
-
onClick2?.(e);
|
|
651
|
-
},
|
|
652
|
-
...anchorRest,
|
|
1071
|
+
onClick: onClick2,
|
|
1072
|
+
...buttonRest,
|
|
653
1073
|
children: content
|
|
654
1074
|
}
|
|
655
1075
|
);
|
|
656
1076
|
}
|
|
657
|
-
const {
|
|
1077
|
+
const { onClick, tabIndex, ...tagProps } = anchorRest;
|
|
658
1078
|
return /* @__PURE__ */ jsx(
|
|
659
|
-
|
|
1079
|
+
Tag,
|
|
660
1080
|
{
|
|
661
|
-
|
|
1081
|
+
...tagProps,
|
|
1082
|
+
ref,
|
|
662
1083
|
className: classes,
|
|
663
|
-
disabled,
|
|
664
1084
|
"aria-current": ariaCurrent,
|
|
665
|
-
|
|
666
|
-
|
|
1085
|
+
"aria-disabled": disabled ? "true" : void 0,
|
|
1086
|
+
tabIndex: disabled ? -1 : tabIndex,
|
|
1087
|
+
onClick: (event) => {
|
|
1088
|
+
if (disabled) {
|
|
1089
|
+
event.preventDefault();
|
|
1090
|
+
event.stopPropagation();
|
|
1091
|
+
return;
|
|
1092
|
+
}
|
|
1093
|
+
onClick?.(event);
|
|
1094
|
+
},
|
|
667
1095
|
children: content
|
|
668
1096
|
}
|
|
669
1097
|
);
|
|
@@ -674,10 +1102,12 @@ var BottomNavSpacer = ({ className, ...props }) => {
|
|
|
674
1102
|
var Breadcrumb = ({
|
|
675
1103
|
items,
|
|
676
1104
|
separator,
|
|
677
|
-
navLabel
|
|
1105
|
+
navLabel: navLabelProp,
|
|
678
1106
|
className,
|
|
679
1107
|
...props
|
|
680
1108
|
}) => {
|
|
1109
|
+
const t = useLocaleText();
|
|
1110
|
+
const navLabel = navLabelProp ?? t("breadcrumb.label");
|
|
681
1111
|
const sep = separator ?? /* @__PURE__ */ jsx(ChevronRight, { size: iconSize.xs, "aria-hidden": "true" });
|
|
682
1112
|
return /* @__PURE__ */ jsx("nav", { "aria-label": navLabel, className: cn("breadcrumb", className), ...props, children: /* @__PURE__ */ jsx("ol", { className: "breadcrumb_list", children: items.map((item, idx) => {
|
|
683
1113
|
const isLast = idx === items.length - 1;
|
|
@@ -1018,7 +1448,7 @@ var Sidebar = ({
|
|
|
1018
1448
|
defaultCollapsed = false,
|
|
1019
1449
|
onCollapsedChange,
|
|
1020
1450
|
collapsible = true,
|
|
1021
|
-
toggleLabel
|
|
1451
|
+
toggleLabel: toggleLabelProp,
|
|
1022
1452
|
width = 240,
|
|
1023
1453
|
collapsedWidth = 64,
|
|
1024
1454
|
mode = "auto",
|
|
@@ -1027,6 +1457,8 @@ var Sidebar = ({
|
|
|
1027
1457
|
style,
|
|
1028
1458
|
...props
|
|
1029
1459
|
}) => {
|
|
1460
|
+
const t = useLocaleText();
|
|
1461
|
+
const toggleLabel = toggleLabelProp ?? t("sidebar.toggle");
|
|
1030
1462
|
const isControlled = collapsedProp !== void 0;
|
|
1031
1463
|
const [internalCollapsed, setInternalCollapsed] = React11.useState(defaultCollapsed);
|
|
1032
1464
|
const collapsed = isControlled ? collapsedProp : internalCollapsed;
|
|
@@ -1070,20 +1502,61 @@ var Sidebar = ({
|
|
|
1070
1502
|
);
|
|
1071
1503
|
};
|
|
1072
1504
|
var SidebarItem = (props) => {
|
|
1073
|
-
const { icon, active, trailing, as
|
|
1074
|
-
const classes = cn(
|
|
1505
|
+
const { icon, active, trailing, as, className, children, disabled, ref, ...rest } = props;
|
|
1506
|
+
const classes = cn(
|
|
1507
|
+
"sidebar_item",
|
|
1508
|
+
active && "sidebar_item_active",
|
|
1509
|
+
disabled && "sidebar_item_disabled",
|
|
1510
|
+
className
|
|
1511
|
+
);
|
|
1075
1512
|
const ariaCurrent = active ? "page" : void 0;
|
|
1513
|
+
const anchorRest = rest;
|
|
1514
|
+
const Tag = as ?? (anchorRest.href != null ? "a" : "button");
|
|
1076
1515
|
const inner = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
1077
1516
|
icon && /* @__PURE__ */ jsx("span", { className: "sidebar_item_icon", "aria-hidden": "true", children: icon }),
|
|
1078
1517
|
/* @__PURE__ */ jsx("span", { className: "sidebar_item_label", children }),
|
|
1079
1518
|
trailing && /* @__PURE__ */ jsx("span", { className: "sidebar_item_trailing", children: trailing })
|
|
1080
1519
|
] });
|
|
1081
|
-
if (
|
|
1082
|
-
const {
|
|
1083
|
-
|
|
1520
|
+
if (Tag === "button") {
|
|
1521
|
+
const {
|
|
1522
|
+
type,
|
|
1523
|
+
href: _href,
|
|
1524
|
+
...buttonRest
|
|
1525
|
+
} = rest;
|
|
1526
|
+
return /* @__PURE__ */ jsx(
|
|
1527
|
+
"button",
|
|
1528
|
+
{
|
|
1529
|
+
ref,
|
|
1530
|
+
type: type ?? "button",
|
|
1531
|
+
className: classes,
|
|
1532
|
+
disabled,
|
|
1533
|
+
"aria-current": ariaCurrent,
|
|
1534
|
+
...buttonRest,
|
|
1535
|
+
children: inner
|
|
1536
|
+
}
|
|
1537
|
+
);
|
|
1084
1538
|
}
|
|
1085
|
-
const {
|
|
1086
|
-
return /* @__PURE__ */ jsx(
|
|
1539
|
+
const { onClick, tabIndex, ...tagProps } = anchorRest;
|
|
1540
|
+
return /* @__PURE__ */ jsx(
|
|
1541
|
+
Tag,
|
|
1542
|
+
{
|
|
1543
|
+
...tagProps,
|
|
1544
|
+
ref,
|
|
1545
|
+
className: classes,
|
|
1546
|
+
"aria-current": ariaCurrent,
|
|
1547
|
+
"aria-disabled": disabled || void 0,
|
|
1548
|
+
tabIndex: disabled ? -1 : tabIndex,
|
|
1549
|
+
onClick: (event) => {
|
|
1550
|
+
if (disabled) {
|
|
1551
|
+
event.preventDefault();
|
|
1552
|
+
event.stopPropagation();
|
|
1553
|
+
return;
|
|
1554
|
+
}
|
|
1555
|
+
onClick?.(event);
|
|
1556
|
+
},
|
|
1557
|
+
children: inner
|
|
1558
|
+
}
|
|
1559
|
+
);
|
|
1087
1560
|
};
|
|
1088
1561
|
var SidebarSection = ({ label, className, children, ...props }) => {
|
|
1089
1562
|
return /* @__PURE__ */ jsxs("div", { className: cn("sidebar_section", className), ...props, children: [
|
|
@@ -2103,7 +2576,8 @@ var Chip = ({
|
|
|
2103
2576
|
className,
|
|
2104
2577
|
...props
|
|
2105
2578
|
}) => {
|
|
2106
|
-
const
|
|
2579
|
+
const t = useLocaleText();
|
|
2580
|
+
const removeAriaLabel = removeLabel ?? t("chip.remove", { label: String(label) });
|
|
2107
2581
|
const [iconHovered, setIconHovered] = useState(false);
|
|
2108
2582
|
const isStatic = type === "static";
|
|
2109
2583
|
const hasLeading = !isStatic && selected;
|
|
@@ -2200,252 +2674,382 @@ var Chip = ({
|
|
|
2200
2674
|
)
|
|
2201
2675
|
] });
|
|
2202
2676
|
};
|
|
2203
|
-
var
|
|
2204
|
-
|
|
2205
|
-
return
|
|
2206
|
-
}
|
|
2207
|
-
var
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
as,
|
|
2218
|
-
className,
|
|
2219
|
-
children,
|
|
2220
|
-
ref,
|
|
2221
|
-
...rest
|
|
2222
|
-
} = props;
|
|
2223
|
-
const buttonClassName = cn(
|
|
2224
|
-
"button",
|
|
2225
|
-
`button_variant_${variant}`,
|
|
2226
|
-
`button_size_${size}`,
|
|
2227
|
-
fullWidth && "button_full_width",
|
|
2228
|
-
radius2 && `button_radius_${radius2}`,
|
|
2229
|
-
danger && "button_danger",
|
|
2230
|
-
// anchor 엔 native :disabled 가 안 먹으므로 클래스로 비활성 스타일 적용 (button 도 무해)
|
|
2231
|
-
disabled && "button_disabled",
|
|
2232
|
-
className
|
|
2233
|
-
);
|
|
2234
|
-
const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
2235
|
-
leadingIcon && /* @__PURE__ */ jsx("span", { className: "button_icon", "aria-hidden": "true", children: leadingIcon }),
|
|
2236
|
-
children && /* @__PURE__ */ jsx("span", { className: "button_label", children }),
|
|
2237
|
-
trailingIcon && /* @__PURE__ */ jsx("span", { className: "button_icon", "aria-hidden": "true", children: trailingIcon })
|
|
2238
|
-
] });
|
|
2239
|
-
const anchorRest = rest;
|
|
2240
|
-
const renderAnchor = as === "a" || as === void 0 && anchorRest.href != null;
|
|
2241
|
-
if (renderAnchor) {
|
|
2242
|
-
const { onClick, tabIndex, ...anchorProps } = anchorRest;
|
|
2243
|
-
return /* @__PURE__ */ jsx(
|
|
2244
|
-
"a",
|
|
2245
|
-
{
|
|
2246
|
-
...anchorProps,
|
|
2247
|
-
ref,
|
|
2248
|
-
className: buttonClassName,
|
|
2249
|
-
"aria-disabled": disabled || void 0,
|
|
2250
|
-
tabIndex: disabled ? -1 : tabIndex,
|
|
2251
|
-
onClick: disabled ? (e) => e.preventDefault() : onClick,
|
|
2252
|
-
children: content
|
|
2253
|
-
}
|
|
2254
|
-
);
|
|
2677
|
+
var FormContext = createContext(void 0);
|
|
2678
|
+
function useFormError(name) {
|
|
2679
|
+
return useContext(FormContext)?.errors?.[name];
|
|
2680
|
+
}
|
|
2681
|
+
var Form = ({ errors, onSubmit, children, className, ...props }) => /* @__PURE__ */ jsx(FormContext.Provider, { value: { errors }, children: /* @__PURE__ */ jsx(
|
|
2682
|
+
"form",
|
|
2683
|
+
{
|
|
2684
|
+
className: cn("form", className),
|
|
2685
|
+
onSubmit: (event) => {
|
|
2686
|
+
event.preventDefault();
|
|
2687
|
+
onSubmit?.(event);
|
|
2688
|
+
},
|
|
2689
|
+
...props,
|
|
2690
|
+
children
|
|
2255
2691
|
}
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
action,
|
|
2271
|
-
variant
|
|
2272
|
-
}) => action.href ? /* @__PURE__ */ jsx(Button, { as: "a", href: action.href, size: "lg", variant, onClick: action.onClick, children: action.label }) : /* @__PURE__ */ jsx(Button, { size: "lg", variant, onClick: action.onClick, children: action.label });
|
|
2273
|
-
var Hero = ({
|
|
2274
|
-
height = "md",
|
|
2275
|
-
align = "left",
|
|
2276
|
-
backgroundImage,
|
|
2277
|
-
backgroundColor,
|
|
2278
|
-
overlay,
|
|
2279
|
-
title,
|
|
2280
|
-
subtitle,
|
|
2281
|
-
eyebrow,
|
|
2282
|
-
textColor = "auto",
|
|
2283
|
-
primaryAction,
|
|
2284
|
-
secondaryAction,
|
|
2692
|
+
) });
|
|
2693
|
+
var FormActions = ({ align = "end", children, className, ...props }) => /* @__PURE__ */ jsx("div", { className: cn("form_actions", `form_actions_${align}`, className), ...props, children });
|
|
2694
|
+
FormActions.displayName = "Form.Actions";
|
|
2695
|
+
Form.Actions = FormActions;
|
|
2696
|
+
var FieldContext = createContext(void 0);
|
|
2697
|
+
function useFieldControl() {
|
|
2698
|
+
return useContext(FieldContext);
|
|
2699
|
+
}
|
|
2700
|
+
var Field = ({
|
|
2701
|
+
name,
|
|
2702
|
+
label,
|
|
2703
|
+
required = false,
|
|
2704
|
+
help,
|
|
2705
|
+
error: errorProp,
|
|
2285
2706
|
children,
|
|
2286
2707
|
className,
|
|
2287
|
-
style,
|
|
2288
2708
|
...props
|
|
2289
2709
|
}) => {
|
|
2290
|
-
const
|
|
2291
|
-
const
|
|
2292
|
-
const
|
|
2293
|
-
const
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
/* @__PURE__ */ jsxs("
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
children
|
|
2314
|
-
] })
|
|
2315
|
-
] })
|
|
2710
|
+
const generatedId = useId();
|
|
2711
|
+
const inputId = `${name}-${generatedId}`;
|
|
2712
|
+
const formError = useFormError(name);
|
|
2713
|
+
const error = errorProp ?? formError;
|
|
2714
|
+
const labelId = label ? `${inputId}-label` : void 0;
|
|
2715
|
+
const helpId = help ? `${inputId}-help` : void 0;
|
|
2716
|
+
const errorId = error ? `${inputId}-error` : void 0;
|
|
2717
|
+
const showHelp = !error && !!help;
|
|
2718
|
+
const control = {
|
|
2719
|
+
inputId,
|
|
2720
|
+
labelId,
|
|
2721
|
+
describedBy: [errorId, showHelp ? helpId : void 0].filter(Boolean).join(" ") || void 0,
|
|
2722
|
+
invalid: !!error,
|
|
2723
|
+
required
|
|
2724
|
+
};
|
|
2725
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("field", !!error && "field_error", className), ...props, children: [
|
|
2726
|
+
label && /* @__PURE__ */ jsxs("label", { id: labelId, htmlFor: inputId, className: "field_label", children: [
|
|
2727
|
+
label,
|
|
2728
|
+
required && /* @__PURE__ */ jsx("span", { className: "field_required", "aria-hidden": "true", children: "*" })
|
|
2729
|
+
] }),
|
|
2730
|
+
/* @__PURE__ */ jsx(FieldContext.Provider, { value: control, children }),
|
|
2731
|
+
showHelp && /* @__PURE__ */ jsx("div", { id: helpId, className: "field_help", children: help }),
|
|
2732
|
+
error && /* @__PURE__ */ jsx("div", { id: errorId, className: "field_message", children: error })
|
|
2316
2733
|
] });
|
|
2317
2734
|
};
|
|
2318
|
-
var
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
IconComponent,
|
|
2322
|
-
{
|
|
2323
|
-
"aria-hidden": hasLabel ? void 0 : true,
|
|
2324
|
-
focusable: hasLabel ? void 0 : false,
|
|
2325
|
-
...props
|
|
2326
|
-
}
|
|
2327
|
-
);
|
|
2328
|
-
};
|
|
2329
|
-
Icon.displayName = "Icon";
|
|
2330
|
-
var ListItem = ({
|
|
2331
|
-
overline,
|
|
2735
|
+
var ClearIcon = () => /* @__PURE__ */ jsx(X, { size: iconSize.lg, "aria-hidden": "true" });
|
|
2736
|
+
var TextField = ({
|
|
2737
|
+
id,
|
|
2332
2738
|
label,
|
|
2739
|
+
showLabel = true,
|
|
2333
2740
|
supportingText,
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2741
|
+
error,
|
|
2742
|
+
success,
|
|
2743
|
+
identifier,
|
|
2744
|
+
leadingIcon,
|
|
2745
|
+
trailingIcon,
|
|
2746
|
+
leadingAction,
|
|
2747
|
+
trailingAction,
|
|
2748
|
+
showPasswordToggle,
|
|
2749
|
+
passwordToggleLabels,
|
|
2750
|
+
clearable,
|
|
2751
|
+
clearLabel: clearLabelProp,
|
|
2752
|
+
type,
|
|
2753
|
+
fullWidth,
|
|
2754
|
+
size = "md",
|
|
2755
|
+
variant = "outline",
|
|
2341
2756
|
className,
|
|
2757
|
+
onValueChange,
|
|
2758
|
+
onChangeAction,
|
|
2759
|
+
imeStrategy = "delayed",
|
|
2760
|
+
value,
|
|
2761
|
+
defaultValue,
|
|
2762
|
+
transformValue,
|
|
2763
|
+
ref,
|
|
2342
2764
|
...props
|
|
2343
2765
|
}) => {
|
|
2344
|
-
const
|
|
2345
|
-
const
|
|
2766
|
+
const t = useLocaleText();
|
|
2767
|
+
const clearLabel = clearLabelProp ?? t("textField.clear");
|
|
2768
|
+
const generatedId = useId();
|
|
2769
|
+
const field = useFieldControl();
|
|
2770
|
+
const inputId = id ?? field?.inputId ?? generatedId;
|
|
2771
|
+
const helperId = supportingText ? `${inputId}-help` : void 0;
|
|
2772
|
+
const describedBy = field?.describedBy ?? helperId;
|
|
2773
|
+
const isControlled = value !== void 0;
|
|
2774
|
+
const applyTransform = (nextValue) => transformValue ? transformValue(nextValue) : nextValue;
|
|
2775
|
+
const [innerValue, setInnerValue] = useState(() => applyTransform(value ?? defaultValue ?? ""));
|
|
2776
|
+
const isComposingRef = useRef(false);
|
|
2777
|
+
const lastEmittedValueRef = useRef(innerValue);
|
|
2778
|
+
const [prevValue, setPrevValue] = useState(value);
|
|
2779
|
+
if (isControlled && value !== prevValue && !isComposingRef.current) {
|
|
2780
|
+
setPrevValue(value);
|
|
2781
|
+
const nextValue = applyTransform(value ?? "");
|
|
2782
|
+
setInnerValue(nextValue);
|
|
2783
|
+
lastEmittedValueRef.current = nextValue;
|
|
2784
|
+
}
|
|
2785
|
+
const emit = useCallback(
|
|
2786
|
+
(nextValue) => {
|
|
2787
|
+
setInnerValue(nextValue);
|
|
2788
|
+
if (nextValue !== lastEmittedValueRef.current) {
|
|
2789
|
+
lastEmittedValueRef.current = nextValue;
|
|
2790
|
+
(onValueChange ?? onChangeAction)?.(nextValue);
|
|
2791
|
+
}
|
|
2792
|
+
},
|
|
2793
|
+
[onValueChange, onChangeAction]
|
|
2794
|
+
);
|
|
2795
|
+
const handleClear = useCallback(() => {
|
|
2796
|
+
emit("");
|
|
2797
|
+
}, [emit]);
|
|
2798
|
+
const [passwordRevealed, setPasswordRevealed] = useState(false);
|
|
2799
|
+
const togglePassword = useCallback(() => {
|
|
2800
|
+
setPasswordRevealed((revealed) => !revealed);
|
|
2801
|
+
}, []);
|
|
2802
|
+
let resolvedType = type;
|
|
2803
|
+
if (showPasswordToggle) {
|
|
2804
|
+
resolvedType = passwordRevealed ? "text" : type ?? "password";
|
|
2805
|
+
}
|
|
2806
|
+
const isError = !!error || !!field?.invalid;
|
|
2807
|
+
const isSuccess = !!success && !isError;
|
|
2346
2808
|
const rootClassName = cn(
|
|
2347
|
-
"
|
|
2348
|
-
`
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2809
|
+
"text_field",
|
|
2810
|
+
`text_field_variant_${variant}`,
|
|
2811
|
+
size === "sm" && "text_field_size_sm",
|
|
2812
|
+
size === "lg" && "text_field_size_lg",
|
|
2813
|
+
fullWidth && "text_field_full_width",
|
|
2814
|
+
isError && "text_field_error",
|
|
2815
|
+
isSuccess && "text_field_success",
|
|
2816
|
+
props.disabled && "text_field_disabled",
|
|
2352
2817
|
className
|
|
2353
2818
|
);
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2819
|
+
const passwordToggleLabel = passwordRevealed ? passwordToggleLabels?.hide ?? t("textField.passwordHide") : passwordToggleLabels?.show ?? t("textField.passwordShow");
|
|
2820
|
+
const resolvedTrailing = showPasswordToggle ? /* @__PURE__ */ jsx("span", { className: "text_field_icon text_field_action", children: /* @__PURE__ */ jsx(
|
|
2821
|
+
"button",
|
|
2822
|
+
{
|
|
2823
|
+
type: "button",
|
|
2824
|
+
onClick: togglePassword,
|
|
2825
|
+
"aria-label": passwordToggleLabel,
|
|
2826
|
+
disabled: props.disabled,
|
|
2827
|
+
children: passwordRevealed ? /* @__PURE__ */ jsx(EyeOff, { size: iconSize.lg, "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Eye, { size: iconSize.lg, "aria-hidden": "true" })
|
|
2828
|
+
}
|
|
2829
|
+
) }) : clearable && innerValue ? /* @__PURE__ */ jsx(
|
|
2830
|
+
"button",
|
|
2831
|
+
{
|
|
2832
|
+
type: "button",
|
|
2833
|
+
className: "text_field_clear",
|
|
2834
|
+
onClick: handleClear,
|
|
2835
|
+
"aria-label": clearLabel,
|
|
2836
|
+
disabled: props.disabled,
|
|
2837
|
+
children: /* @__PURE__ */ jsx(ClearIcon, {})
|
|
2838
|
+
}
|
|
2839
|
+
) : trailingAction ? /* @__PURE__ */ jsx("span", { className: "text_field_icon text_field_action", children: trailingAction }) : trailingIcon ? /* @__PURE__ */ jsx("span", { className: "text_field_icon", "aria-hidden": "true", children: trailingIcon }) : null;
|
|
2840
|
+
const resolvedLeading = leadingAction ? /* @__PURE__ */ jsx("span", { className: "text_field_icon text_field_action", children: leadingAction }) : leadingIcon ? /* @__PURE__ */ jsx("span", { className: "text_field_icon", "aria-hidden": "true", children: leadingIcon }) : null;
|
|
2841
|
+
return /* @__PURE__ */ jsxs("div", { className: rootClassName, children: [
|
|
2842
|
+
label && showLabel && /* @__PURE__ */ jsx("label", { htmlFor: inputId, className: "text_field_label", children: label }),
|
|
2843
|
+
/* @__PURE__ */ jsx("div", { className: "text_field_container", children: /* @__PURE__ */ jsxs("div", { className: "text_field_inner", children: [
|
|
2844
|
+
resolvedLeading,
|
|
2845
|
+
/* @__PURE__ */ jsx(
|
|
2846
|
+
"div",
|
|
2847
|
+
{
|
|
2848
|
+
className: cn(
|
|
2849
|
+
"text_field_input_wrap",
|
|
2850
|
+
resolvedTrailing && "text_field_input_wrap_no_pad_right"
|
|
2851
|
+
),
|
|
2852
|
+
children: /* @__PURE__ */ jsx(
|
|
2853
|
+
"input",
|
|
2854
|
+
{
|
|
2855
|
+
id: inputId,
|
|
2856
|
+
ref,
|
|
2857
|
+
className: cn("text_field_input", identifier && "text_field_input_identifier"),
|
|
2858
|
+
"aria-invalid": isError,
|
|
2859
|
+
"aria-describedby": describedBy,
|
|
2860
|
+
"aria-required": field?.required || void 0,
|
|
2861
|
+
"aria-label": !showLabel ? label : void 0,
|
|
2862
|
+
...props,
|
|
2863
|
+
type: resolvedType,
|
|
2864
|
+
value: innerValue,
|
|
2865
|
+
onCompositionStart: () => {
|
|
2866
|
+
isComposingRef.current = true;
|
|
2867
|
+
},
|
|
2868
|
+
onCompositionEnd: (event) => {
|
|
2869
|
+
isComposingRef.current = false;
|
|
2870
|
+
emit(applyTransform(event.currentTarget.value));
|
|
2871
|
+
},
|
|
2872
|
+
onChange: (event) => {
|
|
2873
|
+
const rawValue = event.target.value;
|
|
2874
|
+
if (isComposingRef.current) {
|
|
2875
|
+
setInnerValue(rawValue);
|
|
2876
|
+
if (imeStrategy === "immediate" && rawValue !== lastEmittedValueRef.current) {
|
|
2877
|
+
lastEmittedValueRef.current = rawValue;
|
|
2878
|
+
(onValueChange ?? onChangeAction)?.(rawValue);
|
|
2879
|
+
}
|
|
2880
|
+
return;
|
|
2881
|
+
}
|
|
2882
|
+
emit(applyTransform(rawValue));
|
|
2883
|
+
}
|
|
2884
|
+
}
|
|
2885
|
+
)
|
|
2886
|
+
}
|
|
2887
|
+
),
|
|
2888
|
+
resolvedTrailing
|
|
2889
|
+
] }) }),
|
|
2890
|
+
supportingText && /* @__PURE__ */ jsx("div", { id: helperId, className: "text_field_helper", children: supportingText })
|
|
2891
|
+
] });
|
|
2386
2892
|
};
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2893
|
+
TextField.displayName = "TextField";
|
|
2894
|
+
var Button = (props) => {
|
|
2895
|
+
const {
|
|
2896
|
+
variant = "filled",
|
|
2897
|
+
size = "md",
|
|
2898
|
+
leadingIcon,
|
|
2899
|
+
trailingIcon,
|
|
2900
|
+
fullWidth = false,
|
|
2901
|
+
radius: radius2,
|
|
2902
|
+
danger = false,
|
|
2903
|
+
disabled = false,
|
|
2904
|
+
as,
|
|
2905
|
+
className,
|
|
2906
|
+
children,
|
|
2907
|
+
ref,
|
|
2908
|
+
...rest
|
|
2909
|
+
} = props;
|
|
2910
|
+
const buttonClassName = cn(
|
|
2911
|
+
"button",
|
|
2912
|
+
`button_variant_${variant}`,
|
|
2913
|
+
`button_size_${size}`,
|
|
2914
|
+
fullWidth && "button_full_width",
|
|
2915
|
+
radius2 && `button_radius_${radius2}`,
|
|
2916
|
+
danger && "button_danger",
|
|
2917
|
+
// anchor 엔 native :disabled 가 안 먹으므로 클래스로 비활성 스타일 적용 (button 도 무해)
|
|
2918
|
+
disabled && "button_disabled",
|
|
2408
2919
|
className
|
|
2409
2920
|
);
|
|
2410
|
-
const
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
/* @__PURE__ */ jsxs("div", { className: "media_card_image_wrap", style: wrapStyle, children: [
|
|
2415
|
-
/* @__PURE__ */ jsx("img", { className: "media_card_image", src: image.src, alt: image.alt, loading: "lazy" }),
|
|
2416
|
-
isOverlay && /* @__PURE__ */ jsx("div", { className: "media_card_overlay", "aria-hidden": "true" })
|
|
2417
|
-
] }),
|
|
2418
|
-
/* @__PURE__ */ jsxs("div", { className: "media_card_body", children: [
|
|
2419
|
-
eyebrow && /* @__PURE__ */ jsx("div", { className: "media_card_eyebrow", children: eyebrow }),
|
|
2420
|
-
heading && /* @__PURE__ */ jsx(HeadingTag, { className: "media_card_heading", children: heading }),
|
|
2421
|
-
children && /* @__PURE__ */ jsx("div", { className: "media_card_content", children }),
|
|
2422
|
-
meta && /* @__PURE__ */ jsx("div", { className: "media_card_meta", children: meta })
|
|
2423
|
-
] })
|
|
2921
|
+
const content = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
2922
|
+
leadingIcon && /* @__PURE__ */ jsx("span", { className: "button_icon", "aria-hidden": "true", children: leadingIcon }),
|
|
2923
|
+
children && /* @__PURE__ */ jsx("span", { className: "button_label", children }),
|
|
2924
|
+
trailingIcon && /* @__PURE__ */ jsx("span", { className: "button_icon", "aria-hidden": "true", children: trailingIcon })
|
|
2424
2925
|
] });
|
|
2926
|
+
const anchorRest = rest;
|
|
2927
|
+
const Tag = as ?? (anchorRest.href != null ? "a" : "button");
|
|
2928
|
+
if (Tag === "button") {
|
|
2929
|
+
const {
|
|
2930
|
+
type = "button",
|
|
2931
|
+
href: _href,
|
|
2932
|
+
...buttonRest
|
|
2933
|
+
} = rest;
|
|
2934
|
+
return /* @__PURE__ */ jsx(
|
|
2935
|
+
"button",
|
|
2936
|
+
{
|
|
2937
|
+
ref,
|
|
2938
|
+
type,
|
|
2939
|
+
disabled,
|
|
2940
|
+
className: buttonClassName,
|
|
2941
|
+
...buttonRest,
|
|
2942
|
+
children: content
|
|
2943
|
+
}
|
|
2944
|
+
);
|
|
2945
|
+
}
|
|
2946
|
+
const { onClick, tabIndex, ...tagProps } = anchorRest;
|
|
2947
|
+
return /* @__PURE__ */ jsx(
|
|
2948
|
+
Tag,
|
|
2949
|
+
{
|
|
2950
|
+
...tagProps,
|
|
2951
|
+
ref,
|
|
2952
|
+
className: buttonClassName,
|
|
2953
|
+
"aria-disabled": disabled || void 0,
|
|
2954
|
+
tabIndex: disabled ? -1 : tabIndex,
|
|
2955
|
+
onClick: disabled ? (event) => {
|
|
2956
|
+
event.preventDefault();
|
|
2957
|
+
event.stopPropagation();
|
|
2958
|
+
} : onClick,
|
|
2959
|
+
children: content
|
|
2960
|
+
}
|
|
2961
|
+
);
|
|
2425
2962
|
};
|
|
2426
|
-
var
|
|
2427
|
-
const
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2963
|
+
var range = (start, end) => {
|
|
2964
|
+
const out = [];
|
|
2965
|
+
for (let i = start; i <= end; i += 1) out.push(i);
|
|
2966
|
+
return out;
|
|
2967
|
+
};
|
|
2968
|
+
var getPaginationItems = (page, totalPages) => {
|
|
2969
|
+
if (totalPages <= 7) return range(1, totalPages);
|
|
2970
|
+
const items = [];
|
|
2971
|
+
const last = totalPages;
|
|
2972
|
+
const sibling = 2;
|
|
2973
|
+
if (page <= sibling + 2) {
|
|
2974
|
+
for (const p of range(1, sibling + 3)) items.push(p);
|
|
2975
|
+
items.push("ellipsis");
|
|
2976
|
+
items.push(last);
|
|
2977
|
+
return items;
|
|
2978
|
+
}
|
|
2979
|
+
if (page >= last - sibling - 1) {
|
|
2980
|
+
items.push(1);
|
|
2981
|
+
items.push("ellipsis");
|
|
2982
|
+
for (const p of range(last - sibling - 2, last)) items.push(p);
|
|
2983
|
+
return items;
|
|
2984
|
+
}
|
|
2985
|
+
items.push(1);
|
|
2986
|
+
items.push("ellipsis");
|
|
2987
|
+
for (const p of range(page - sibling, page + sibling)) items.push(p);
|
|
2988
|
+
items.push("ellipsis");
|
|
2989
|
+
items.push(last);
|
|
2990
|
+
return items;
|
|
2991
|
+
};
|
|
2992
|
+
var Pagination = ({
|
|
2993
|
+
page,
|
|
2994
|
+
totalPages,
|
|
2995
|
+
onPageChange,
|
|
2996
|
+
onChange,
|
|
2997
|
+
prevLabel: prevLabelProp,
|
|
2998
|
+
nextLabel: nextLabelProp,
|
|
2999
|
+
navLabel: navLabelProp
|
|
3000
|
+
}) => {
|
|
3001
|
+
const t = useLocaleText();
|
|
3002
|
+
const prevLabel = prevLabelProp ?? t("pagination.prev");
|
|
3003
|
+
const nextLabel = nextLabelProp ?? t("pagination.next");
|
|
3004
|
+
const navLabel = navLabelProp ?? t("pagination.label");
|
|
3005
|
+
const emit = onPageChange ?? onChange;
|
|
3006
|
+
const prevDisabled = page <= 1;
|
|
3007
|
+
const nextDisabled = page >= totalPages;
|
|
3008
|
+
const items = React11.useMemo(() => getPaginationItems(page, totalPages), [page, totalPages]);
|
|
3009
|
+
return /* @__PURE__ */ jsxs("nav", { className: "pagination", "aria-label": navLabel, children: [
|
|
3010
|
+
/* @__PURE__ */ jsx(
|
|
3011
|
+
"button",
|
|
3012
|
+
{
|
|
3013
|
+
type: "button",
|
|
3014
|
+
className: "pagination_item",
|
|
3015
|
+
onClick: () => emit?.(page - 1),
|
|
3016
|
+
disabled: prevDisabled,
|
|
3017
|
+
"aria-label": prevLabel,
|
|
3018
|
+
children: "\u2039"
|
|
2437
3019
|
}
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
3020
|
+
),
|
|
3021
|
+
/* @__PURE__ */ jsx("ul", { className: "pagination_pages", children: items.map((it, idx) => {
|
|
3022
|
+
if (it === "ellipsis") {
|
|
3023
|
+
const prev = items[idx - 1];
|
|
3024
|
+
const next = items[idx + 1];
|
|
3025
|
+
return /* @__PURE__ */ jsx("li", { className: "pagination_ellipsis", "aria-hidden": "true", children: "\u2026" }, `e-${prev}-${next}`);
|
|
3026
|
+
}
|
|
3027
|
+
const isActive = it === page;
|
|
3028
|
+
const buttonClassName = cn("pagination_page_button", { pagination_active: isActive });
|
|
3029
|
+
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
3030
|
+
"button",
|
|
3031
|
+
{
|
|
3032
|
+
type: "button",
|
|
3033
|
+
className: buttonClassName,
|
|
3034
|
+
onClick: () => emit?.(it),
|
|
3035
|
+
"aria-current": isActive ? "page" : void 0,
|
|
3036
|
+
children: it
|
|
3037
|
+
}
|
|
3038
|
+
) }, it);
|
|
3039
|
+
}) }),
|
|
3040
|
+
/* @__PURE__ */ jsx(
|
|
3041
|
+
"button",
|
|
3042
|
+
{
|
|
3043
|
+
type: "button",
|
|
3044
|
+
className: "pagination_item",
|
|
3045
|
+
onClick: () => emit?.(page + 1),
|
|
3046
|
+
disabled: nextDisabled,
|
|
3047
|
+
"aria-label": nextLabel,
|
|
3048
|
+
children: "\u203A"
|
|
3049
|
+
}
|
|
3050
|
+
)
|
|
3051
|
+
] });
|
|
2447
3052
|
};
|
|
2448
|
-
Prose.displayName = "Prose";
|
|
2449
3053
|
var Skeleton = ({
|
|
2450
3054
|
variant = "text",
|
|
2451
3055
|
width,
|
|
@@ -2496,6 +3100,7 @@ var Checkbox = ({
|
|
|
2496
3100
|
props.disabled && "checkbox_disabled",
|
|
2497
3101
|
className
|
|
2498
3102
|
);
|
|
3103
|
+
const field = useFieldControl();
|
|
2499
3104
|
return /* @__PURE__ */ jsxs("label", { className: rootClassName, children: [
|
|
2500
3105
|
/* @__PURE__ */ jsx(
|
|
2501
3106
|
"input",
|
|
@@ -2504,6 +3109,9 @@ var Checkbox = ({
|
|
|
2504
3109
|
ref: inputRef,
|
|
2505
3110
|
type: "checkbox",
|
|
2506
3111
|
className: "checkbox_input",
|
|
3112
|
+
id: field?.inputId ?? props.id,
|
|
3113
|
+
"aria-describedby": field?.describedBy ?? props["aria-describedby"],
|
|
3114
|
+
"aria-required": field?.required || void 0,
|
|
2507
3115
|
"aria-invalid": error || void 0
|
|
2508
3116
|
}
|
|
2509
3117
|
),
|
|
@@ -2516,7 +3124,7 @@ var Table = ({
|
|
|
2516
3124
|
columns,
|
|
2517
3125
|
data,
|
|
2518
3126
|
keyExtractor,
|
|
2519
|
-
emptyMessage
|
|
3127
|
+
emptyMessage: emptyMessageProp,
|
|
2520
3128
|
isLoading = false,
|
|
2521
3129
|
skeletonRows = 5,
|
|
2522
3130
|
size = "md",
|
|
@@ -2525,16 +3133,21 @@ var Table = ({
|
|
|
2525
3133
|
ariaLabel,
|
|
2526
3134
|
className,
|
|
2527
3135
|
onRowClick,
|
|
2528
|
-
rowClickHint
|
|
3136
|
+
rowClickHint: rowClickHintProp,
|
|
2529
3137
|
sort,
|
|
2530
3138
|
onSortChange,
|
|
2531
|
-
selectAllAriaLabel
|
|
2532
|
-
selectRowAriaLabel
|
|
3139
|
+
selectAllAriaLabel: selectAllAriaLabelProp,
|
|
3140
|
+
selectRowAriaLabel: selectRowAriaLabelProp,
|
|
2533
3141
|
selectable = false,
|
|
2534
3142
|
rowKey,
|
|
2535
3143
|
selectedKeys,
|
|
2536
3144
|
onSelectionChange
|
|
2537
3145
|
}) => {
|
|
3146
|
+
const t = useLocaleText();
|
|
3147
|
+
const rowClickHint = rowClickHintProp ?? t("table.rowClickHint");
|
|
3148
|
+
const emptyMessage = emptyMessageProp === void 0 ? t("table.empty") : emptyMessageProp;
|
|
3149
|
+
const selectAllAriaLabel = selectAllAriaLabelProp ?? t("table.selectAll");
|
|
3150
|
+
const selectRowAriaLabel = selectRowAriaLabelProp ?? ((index) => t("table.selectRow", { index: index + 1 }));
|
|
2538
3151
|
const wrapperClassName = cn(
|
|
2539
3152
|
"table_wrapper",
|
|
2540
3153
|
`table_size_${size}`,
|
|
@@ -2702,10 +3315,312 @@ var Table = ({
|
|
|
2702
3315
|
);
|
|
2703
3316
|
}) })
|
|
2704
3317
|
] }),
|
|
2705
|
-
onRowClick && rowClickHint && /* @__PURE__ */ jsx("span", { id: rowClickHintId, className: "table_sr_only", children: rowClickHint }),
|
|
2706
|
-
isEmpty && /* @__PURE__ */ jsx("div", { className: "table_empty", role: "status", children: emptyMessage })
|
|
3318
|
+
onRowClick && rowClickHint && /* @__PURE__ */ jsx("span", { id: rowClickHintId, className: "table_sr_only", children: rowClickHint }),
|
|
3319
|
+
isEmpty && /* @__PURE__ */ jsx("div", { className: "table_empty", role: "status", children: emptyMessage })
|
|
3320
|
+
] });
|
|
3321
|
+
};
|
|
3322
|
+
var DataView = ({
|
|
3323
|
+
query,
|
|
3324
|
+
columns,
|
|
3325
|
+
rowKey,
|
|
3326
|
+
toolbar,
|
|
3327
|
+
selectionActions,
|
|
3328
|
+
pagination,
|
|
3329
|
+
empty,
|
|
3330
|
+
sort,
|
|
3331
|
+
onSortChange,
|
|
3332
|
+
onRowClick,
|
|
3333
|
+
ariaLabel,
|
|
3334
|
+
selectionSummary: selectionSummaryProp,
|
|
3335
|
+
clearSelectionLabel: clearSelectionLabelProp,
|
|
3336
|
+
errorTitle: errorTitleProp,
|
|
3337
|
+
retryLabel: retryLabelProp,
|
|
3338
|
+
className,
|
|
3339
|
+
...props
|
|
3340
|
+
}) => {
|
|
3341
|
+
const t = useLocaleText();
|
|
3342
|
+
const selectionSummary = selectionSummaryProp ?? ((count) => t("dataView.selectionSummary", { count }));
|
|
3343
|
+
const clearSelectionLabel = clearSelectionLabelProp ?? t("dataView.clearSelection");
|
|
3344
|
+
const errorTitle = errorTitleProp ?? t("dataView.errorTitle");
|
|
3345
|
+
const retryLabel = retryLabelProp ?? t("dataView.retry");
|
|
3346
|
+
const searchLabel = toolbar?.searchPlaceholder ?? t("dataView.search");
|
|
3347
|
+
const [selectedKeys, setSelectedKeys] = useState([]);
|
|
3348
|
+
const selectionBarId = useId();
|
|
3349
|
+
const selectable = !!selectionActions?.length;
|
|
3350
|
+
const rows = query.data ?? [];
|
|
3351
|
+
const showEmpty = !query.isLoading && !query.error && rows.length === 0;
|
|
3352
|
+
if (query.error) {
|
|
3353
|
+
return /* @__PURE__ */ jsx("div", { className: cn("data_view", className), ...props, children: /* @__PURE__ */ jsx(
|
|
3354
|
+
ErrorState,
|
|
3355
|
+
{
|
|
3356
|
+
variant: "widget",
|
|
3357
|
+
title: errorTitle,
|
|
3358
|
+
action: query.refetch ? /* @__PURE__ */ jsx(Button, { size: "sm", variant: "outline", onClick: query.refetch, children: retryLabel }) : void 0
|
|
3359
|
+
}
|
|
3360
|
+
) });
|
|
3361
|
+
}
|
|
3362
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("data_view", className), ...props, children: [
|
|
3363
|
+
toolbar && /* @__PURE__ */ jsxs("div", { className: "data_view_toolbar", children: [
|
|
3364
|
+
toolbar.search && /* @__PURE__ */ jsx("div", { className: "data_view_search", children: /* @__PURE__ */ jsx(
|
|
3365
|
+
TextField,
|
|
3366
|
+
{
|
|
3367
|
+
fullWidth: true,
|
|
3368
|
+
size: "sm",
|
|
3369
|
+
type: "search",
|
|
3370
|
+
value: toolbar.searchValue,
|
|
3371
|
+
onValueChange: toolbar.onSearchChange,
|
|
3372
|
+
placeholder: searchLabel,
|
|
3373
|
+
"aria-label": searchLabel,
|
|
3374
|
+
leadingIcon: /* @__PURE__ */ jsx(Search, { size: iconSize.sm })
|
|
3375
|
+
}
|
|
3376
|
+
) }),
|
|
3377
|
+
toolbar.filters && /* @__PURE__ */ jsx("div", { className: "data_view_filters", children: toolbar.filters })
|
|
3378
|
+
] }),
|
|
3379
|
+
selectable && selectedKeys.length > 0 && // `role="status"` - 선택이 바뀔 때마다 스크린리더가 개수를 읽는다. 액션 줄이
|
|
3380
|
+
// 시각적으로만 나타나면 키보드 사용자는 무엇이 가능해졌는지 알 수 없다.
|
|
3381
|
+
/* @__PURE__ */ jsxs("div", { id: selectionBarId, className: "data_view_selection", role: "status", children: [
|
|
3382
|
+
/* @__PURE__ */ jsx("span", { className: "data_view_selection_count", children: selectionSummary(selectedKeys.length) }),
|
|
3383
|
+
/* @__PURE__ */ jsxs("div", { className: "data_view_selection_actions", children: [
|
|
3384
|
+
selectionActions?.map((action) => /* @__PURE__ */ jsx(
|
|
3385
|
+
Button,
|
|
3386
|
+
{
|
|
3387
|
+
size: "sm",
|
|
3388
|
+
variant: "outline",
|
|
3389
|
+
danger: action.danger,
|
|
3390
|
+
onClick: () => action.onRun(selectedKeys),
|
|
3391
|
+
children: action.label
|
|
3392
|
+
},
|
|
3393
|
+
action.label
|
|
3394
|
+
)),
|
|
3395
|
+
/* @__PURE__ */ jsx(Button, { size: "sm", variant: "text", onClick: () => setSelectedKeys([]), children: clearSelectionLabel })
|
|
3396
|
+
] })
|
|
3397
|
+
] }),
|
|
3398
|
+
showEmpty ? empty ?? /* @__PURE__ */ jsx(EmptyState, { title: t("dataView.empty") }) : selectable ? (
|
|
3399
|
+
// 판별 union 이라 조건부 스프레드로는 좁혀지지 않는다 - 분기를 명시한다.
|
|
3400
|
+
/* @__PURE__ */ jsx(
|
|
3401
|
+
Table,
|
|
3402
|
+
{
|
|
3403
|
+
columns,
|
|
3404
|
+
data: rows,
|
|
3405
|
+
keyExtractor: rowKey,
|
|
3406
|
+
isLoading: query.isLoading,
|
|
3407
|
+
sort,
|
|
3408
|
+
onSortChange,
|
|
3409
|
+
onRowClick,
|
|
3410
|
+
ariaLabel,
|
|
3411
|
+
selectable: true,
|
|
3412
|
+
rowKey,
|
|
3413
|
+
selectedKeys,
|
|
3414
|
+
onSelectionChange: setSelectedKeys
|
|
3415
|
+
}
|
|
3416
|
+
)
|
|
3417
|
+
) : /* @__PURE__ */ jsx(
|
|
3418
|
+
Table,
|
|
3419
|
+
{
|
|
3420
|
+
columns,
|
|
3421
|
+
data: rows,
|
|
3422
|
+
keyExtractor: rowKey,
|
|
3423
|
+
isLoading: query.isLoading,
|
|
3424
|
+
sort,
|
|
3425
|
+
onSortChange,
|
|
3426
|
+
onRowClick,
|
|
3427
|
+
ariaLabel
|
|
3428
|
+
}
|
|
3429
|
+
),
|
|
3430
|
+
pagination && pagination.totalPages > 1 && /* @__PURE__ */ jsx("div", { className: "data_view_pagination", children: /* @__PURE__ */ jsx(
|
|
3431
|
+
Pagination,
|
|
3432
|
+
{
|
|
3433
|
+
page: pagination.page,
|
|
3434
|
+
totalPages: pagination.totalPages,
|
|
3435
|
+
onPageChange: pagination.onPageChange
|
|
3436
|
+
}
|
|
3437
|
+
) })
|
|
3438
|
+
] });
|
|
3439
|
+
};
|
|
3440
|
+
var Divider = ({ weight = "standard", className, ...props }) => {
|
|
3441
|
+
const dividerClassName = cn("divider", `divider_weight_${weight}`, className);
|
|
3442
|
+
return /* @__PURE__ */ jsx("hr", { className: dividerClassName, ...props });
|
|
3443
|
+
};
|
|
3444
|
+
var HeroActionButton = ({
|
|
3445
|
+
action,
|
|
3446
|
+
variant
|
|
3447
|
+
}) => action.href ? /* @__PURE__ */ jsx(Button, { as: "a", href: action.href, size: "lg", variant, onClick: action.onClick, children: action.label }) : /* @__PURE__ */ jsx(Button, { size: "lg", variant, onClick: action.onClick, children: action.label });
|
|
3448
|
+
var Hero = ({
|
|
3449
|
+
height = "md",
|
|
3450
|
+
align = "left",
|
|
3451
|
+
backgroundImage,
|
|
3452
|
+
backgroundColor,
|
|
3453
|
+
overlay,
|
|
3454
|
+
title,
|
|
3455
|
+
subtitle,
|
|
3456
|
+
eyebrow,
|
|
3457
|
+
textColor = "auto",
|
|
3458
|
+
primaryAction,
|
|
3459
|
+
secondaryAction,
|
|
3460
|
+
children,
|
|
3461
|
+
className,
|
|
3462
|
+
style,
|
|
3463
|
+
...props
|
|
3464
|
+
}) => {
|
|
3465
|
+
const resolvedOverlay = overlay === true ? "dark" : overlay;
|
|
3466
|
+
const isDarkOverlay = resolvedOverlay === "dark";
|
|
3467
|
+
const resolvedTextColor = textColor === "auto" ? isDarkOverlay || backgroundImage && !resolvedOverlay ? "inverse" : "default" : textColor;
|
|
3468
|
+
const heroClassName = cn(
|
|
3469
|
+
"hero",
|
|
3470
|
+
`hero_height_${height}`,
|
|
3471
|
+
`hero_align_${align}`,
|
|
3472
|
+
resolvedOverlay && `hero_overlay_${resolvedOverlay}`,
|
|
3473
|
+
`hero_text_${resolvedTextColor}`,
|
|
3474
|
+
className
|
|
3475
|
+
);
|
|
3476
|
+
const inlineStyle = { ...style };
|
|
3477
|
+
if (backgroundImage) inlineStyle.backgroundImage = `url("${backgroundImage}")`;
|
|
3478
|
+
if (backgroundColor) inlineStyle.backgroundColor = backgroundColor;
|
|
3479
|
+
return /* @__PURE__ */ jsxs("section", { className: heroClassName, style: inlineStyle, ...props, children: [
|
|
3480
|
+
resolvedOverlay && /* @__PURE__ */ jsx("div", { className: "hero_overlay", "aria-hidden": "true" }),
|
|
3481
|
+
/* @__PURE__ */ jsxs("div", { className: "hero_content", children: [
|
|
3482
|
+
eyebrow && /* @__PURE__ */ jsx("div", { className: "hero_eyebrow", children: eyebrow }),
|
|
3483
|
+
title && /* @__PURE__ */ jsx("h1", { className: "hero_title", children: title }),
|
|
3484
|
+
subtitle && /* @__PURE__ */ jsx("p", { className: "hero_subtitle", children: subtitle }),
|
|
3485
|
+
(primaryAction || secondaryAction || children) && /* @__PURE__ */ jsxs("div", { className: "hero_actions", children: [
|
|
3486
|
+
primaryAction && /* @__PURE__ */ jsx(HeroActionButton, { action: primaryAction, variant: "filled" }),
|
|
3487
|
+
secondaryAction && /* @__PURE__ */ jsx(HeroActionButton, { action: secondaryAction, variant: "outline" }),
|
|
3488
|
+
children
|
|
3489
|
+
] })
|
|
3490
|
+
] })
|
|
3491
|
+
] });
|
|
3492
|
+
};
|
|
3493
|
+
var Icon = ({ icon: IconComponent, ...props }) => {
|
|
3494
|
+
const hasLabel = !!props["aria-label"];
|
|
3495
|
+
return /* @__PURE__ */ jsx(
|
|
3496
|
+
IconComponent,
|
|
3497
|
+
{
|
|
3498
|
+
"aria-hidden": hasLabel ? void 0 : true,
|
|
3499
|
+
focusable: hasLabel ? void 0 : false,
|
|
3500
|
+
...props
|
|
3501
|
+
}
|
|
3502
|
+
);
|
|
3503
|
+
};
|
|
3504
|
+
Icon.displayName = "Icon";
|
|
3505
|
+
var ListItem = ({
|
|
3506
|
+
overline,
|
|
3507
|
+
label,
|
|
3508
|
+
supportingText,
|
|
3509
|
+
metadata,
|
|
3510
|
+
leadingElement,
|
|
3511
|
+
trailingElement,
|
|
3512
|
+
alignment,
|
|
3513
|
+
disabled,
|
|
3514
|
+
selected,
|
|
3515
|
+
onClick,
|
|
3516
|
+
className,
|
|
3517
|
+
...props
|
|
3518
|
+
}) => {
|
|
3519
|
+
const isOneLine = !overline && !supportingText && !metadata;
|
|
3520
|
+
const effectiveAlignment = alignment ?? (isOneLine ? "middle" : "top");
|
|
3521
|
+
const rootClassName = cn(
|
|
3522
|
+
"list_item",
|
|
3523
|
+
`list_item_align_${effectiveAlignment}`,
|
|
3524
|
+
disabled && "list_item_disabled",
|
|
3525
|
+
selected && "list_item_selected",
|
|
3526
|
+
onClick && "list_item_interactive",
|
|
3527
|
+
className
|
|
3528
|
+
);
|
|
3529
|
+
return (
|
|
3530
|
+
// biome-ignore lint/a11y/noStaticElementInteractions: optional interactive list item - role=button + tabIndex set conditionally based on onClick
|
|
3531
|
+
/* @__PURE__ */ jsx(
|
|
3532
|
+
"div",
|
|
3533
|
+
{
|
|
3534
|
+
className: rootClassName,
|
|
3535
|
+
onClick: disabled ? void 0 : onClick,
|
|
3536
|
+
onKeyDown: (e) => {
|
|
3537
|
+
if (disabled || !onClick) return;
|
|
3538
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
3539
|
+
e.preventDefault();
|
|
3540
|
+
e.currentTarget.click();
|
|
3541
|
+
}
|
|
3542
|
+
},
|
|
3543
|
+
role: onClick ? "button" : void 0,
|
|
3544
|
+
tabIndex: onClick && !disabled ? 0 : void 0,
|
|
3545
|
+
"aria-disabled": disabled || void 0,
|
|
3546
|
+
"aria-pressed": onClick && selected !== void 0 ? selected : void 0,
|
|
3547
|
+
...props,
|
|
3548
|
+
children: /* @__PURE__ */ jsxs("div", { className: "list_item_state_layer", children: [
|
|
3549
|
+
leadingElement && /* @__PURE__ */ jsx("div", { className: "list_item_leading", children: leadingElement }),
|
|
3550
|
+
/* @__PURE__ */ jsxs("div", { className: "list_item_content", children: [
|
|
3551
|
+
overline && /* @__PURE__ */ jsx("div", { className: "list_item_overline", children: overline }),
|
|
3552
|
+
/* @__PURE__ */ jsx("div", { className: "list_item_label", children: label }),
|
|
3553
|
+
supportingText && /* @__PURE__ */ jsx("div", { className: "list_item_supporting", children: supportingText }),
|
|
3554
|
+
metadata && /* @__PURE__ */ jsx("div", { className: "list_item_metadata", children: metadata })
|
|
3555
|
+
] }),
|
|
3556
|
+
trailingElement && /* @__PURE__ */ jsx("div", { className: "list_item_trailing", children: trailingElement })
|
|
3557
|
+
] })
|
|
3558
|
+
}
|
|
3559
|
+
)
|
|
3560
|
+
);
|
|
3561
|
+
};
|
|
3562
|
+
var MediaCard = ({
|
|
3563
|
+
image,
|
|
3564
|
+
imagePosition = "top",
|
|
3565
|
+
aspectRatio,
|
|
3566
|
+
heading,
|
|
3567
|
+
headingAs: HeadingTag = "h3",
|
|
3568
|
+
eyebrow,
|
|
3569
|
+
shadow = "sm",
|
|
3570
|
+
bordered = false,
|
|
3571
|
+
clickable = false,
|
|
3572
|
+
meta,
|
|
3573
|
+
children,
|
|
3574
|
+
className,
|
|
3575
|
+
...props
|
|
3576
|
+
}) => {
|
|
3577
|
+
const cardClassName = cn(
|
|
3578
|
+
"media_card",
|
|
3579
|
+
`media_card_image_${imagePosition}`,
|
|
3580
|
+
`media_card_shadow_${shadow}`,
|
|
3581
|
+
bordered && "media_card_bordered",
|
|
3582
|
+
clickable && "media_card_clickable",
|
|
3583
|
+
className
|
|
3584
|
+
);
|
|
3585
|
+
const isOverlay = imagePosition === "overlay";
|
|
3586
|
+
const cardStyle = isOverlay && aspectRatio ? { aspectRatio } : void 0;
|
|
3587
|
+
const wrapStyle = !isOverlay && aspectRatio ? { aspectRatio } : void 0;
|
|
3588
|
+
return /* @__PURE__ */ jsxs("div", { className: cardClassName, style: cardStyle, ...props, children: [
|
|
3589
|
+
/* @__PURE__ */ jsxs("div", { className: "media_card_image_wrap", style: wrapStyle, children: [
|
|
3590
|
+
/* @__PURE__ */ jsx("img", { className: "media_card_image", src: image.src, alt: image.alt, loading: "lazy" }),
|
|
3591
|
+
isOverlay && /* @__PURE__ */ jsx("div", { className: "media_card_overlay", "aria-hidden": "true" })
|
|
3592
|
+
] }),
|
|
3593
|
+
/* @__PURE__ */ jsxs("div", { className: "media_card_body", children: [
|
|
3594
|
+
eyebrow && /* @__PURE__ */ jsx("div", { className: "media_card_eyebrow", children: eyebrow }),
|
|
3595
|
+
heading && /* @__PURE__ */ jsx(HeadingTag, { className: "media_card_heading", children: heading }),
|
|
3596
|
+
children && /* @__PURE__ */ jsx("div", { className: "media_card_content", children }),
|
|
3597
|
+
meta && /* @__PURE__ */ jsx("div", { className: "media_card_meta", children: meta })
|
|
3598
|
+
] })
|
|
2707
3599
|
] });
|
|
2708
3600
|
};
|
|
3601
|
+
var Prose = ({ size = "md", className, children, ref, ...props }) => {
|
|
3602
|
+
const rootRef = React11.useRef(null);
|
|
3603
|
+
React11.useImperativeHandle(ref, () => rootRef.current, []);
|
|
3604
|
+
useSafeLayoutEffect(() => {
|
|
3605
|
+
const root = rootRef.current;
|
|
3606
|
+
if (!root) return;
|
|
3607
|
+
const targets = Array.from(root.querySelectorAll("pre, table"));
|
|
3608
|
+
const sync = () => {
|
|
3609
|
+
for (const el of targets) {
|
|
3610
|
+
if (el.scrollWidth > el.clientWidth) el.setAttribute("tabindex", "0");
|
|
3611
|
+
else el.removeAttribute("tabindex");
|
|
3612
|
+
}
|
|
3613
|
+
};
|
|
3614
|
+
sync();
|
|
3615
|
+
if (typeof ResizeObserver === "undefined") return;
|
|
3616
|
+
const observer = new ResizeObserver(sync);
|
|
3617
|
+
observer.observe(root);
|
|
3618
|
+
for (const el of targets) observer.observe(el);
|
|
3619
|
+
return () => observer.disconnect();
|
|
3620
|
+
}, [children]);
|
|
3621
|
+
return /* @__PURE__ */ jsx("div", { ref: rootRef, className: cn("prose", `prose_size_${size}`, className), ...props, children });
|
|
3622
|
+
};
|
|
3623
|
+
Prose.displayName = "Prose";
|
|
2709
3624
|
var ICONS = {
|
|
2710
3625
|
info: /* @__PURE__ */ jsx(Info, { size: iconSize.lg, "aria-hidden": "true" }),
|
|
2711
3626
|
success: /* @__PURE__ */ jsx(CheckCircle2, { size: iconSize.lg, "aria-hidden": "true" }),
|
|
@@ -2756,8 +3671,8 @@ var AlertModal = ({
|
|
|
2756
3671
|
variant = "info",
|
|
2757
3672
|
title,
|
|
2758
3673
|
message,
|
|
2759
|
-
confirmText
|
|
2760
|
-
cancelText
|
|
3674
|
+
confirmText: confirmTextProp,
|
|
3675
|
+
cancelText: cancelTextProp,
|
|
2761
3676
|
showCancel = false,
|
|
2762
3677
|
destructive = false,
|
|
2763
3678
|
actionsAlign = "right",
|
|
@@ -2767,6 +3682,9 @@ var AlertModal = ({
|
|
|
2767
3682
|
onCancel,
|
|
2768
3683
|
onClose
|
|
2769
3684
|
}) => {
|
|
3685
|
+
const t = useLocaleText();
|
|
3686
|
+
const confirmText = confirmTextProp ?? t("alert.confirm");
|
|
3687
|
+
const cancelText = cancelTextProp ?? t("alert.cancel");
|
|
2770
3688
|
const dismiss = onCancel ?? onClose;
|
|
2771
3689
|
const panelRef = React11.useRef(null);
|
|
2772
3690
|
const titleId = React11.useId();
|
|
@@ -2886,7 +3804,9 @@ var LinearProgress = ({
|
|
|
2886
3804
|
}
|
|
2887
3805
|
);
|
|
2888
3806
|
};
|
|
2889
|
-
var Spinner = ({ size = 24, ariaLabel
|
|
3807
|
+
var Spinner = ({ size = 24, ariaLabel: ariaLabelProp }) => {
|
|
3808
|
+
const t = useLocaleText();
|
|
3809
|
+
const ariaLabel = ariaLabelProp ?? t("spinner.label");
|
|
2890
3810
|
return /* @__PURE__ */ jsx(
|
|
2891
3811
|
"span",
|
|
2892
3812
|
{
|
|
@@ -2964,9 +3884,12 @@ var ToastItemComponent = ({ item, onRemove, closeAriaLabel }) => {
|
|
|
2964
3884
|
var ToastProvider = ({
|
|
2965
3885
|
children,
|
|
2966
3886
|
maxCount = 5,
|
|
2967
|
-
closeAriaLabel
|
|
2968
|
-
regionLabel
|
|
3887
|
+
closeAriaLabel: closeAriaLabelProp,
|
|
3888
|
+
regionLabel: regionLabelProp
|
|
2969
3889
|
}) => {
|
|
3890
|
+
const t = useLocaleText();
|
|
3891
|
+
const closeAriaLabel = closeAriaLabelProp ?? t("toast.close");
|
|
3892
|
+
const regionLabel = regionLabelProp ?? t("toast.region");
|
|
2970
3893
|
const [toasts, setToasts] = React11.useState([]);
|
|
2971
3894
|
const isMounted = useIsMounted();
|
|
2972
3895
|
const addToast = React11.useCallback(
|
|
@@ -2977,7 +3900,7 @@ var ToastProvider = ({
|
|
|
2977
3900
|
[maxCount]
|
|
2978
3901
|
);
|
|
2979
3902
|
const removeToast = React11.useCallback((id) => {
|
|
2980
|
-
setToasts((prev) => prev.filter((
|
|
3903
|
+
setToasts((prev) => prev.filter((t2) => t2.id !== id));
|
|
2981
3904
|
}, []);
|
|
2982
3905
|
const contextValue = React11.useMemo(() => ({ addToast }), [addToast]);
|
|
2983
3906
|
return /* @__PURE__ */ jsxs(ToastContext.Provider, { value: contextValue, children: [
|
|
@@ -3032,8 +3955,10 @@ var TopLoading = ({
|
|
|
3032
3955
|
color,
|
|
3033
3956
|
height = 3,
|
|
3034
3957
|
isLoading = true,
|
|
3035
|
-
ariaLabel
|
|
3958
|
+
ariaLabel: ariaLabelProp
|
|
3036
3959
|
}) => {
|
|
3960
|
+
const t = useLocaleText();
|
|
3961
|
+
const ariaLabel = ariaLabelProp ?? t("topLoading.label");
|
|
3037
3962
|
if (!isLoading) return null;
|
|
3038
3963
|
const isIndeterminate = progress === void 0;
|
|
3039
3964
|
return /* @__PURE__ */ jsx(
|
|
@@ -3059,26 +3984,212 @@ var TopLoading = ({
|
|
|
3059
3984
|
}
|
|
3060
3985
|
);
|
|
3061
3986
|
};
|
|
3987
|
+
var Combobox = ({
|
|
3988
|
+
value = null,
|
|
3989
|
+
onValueChange,
|
|
3990
|
+
onSearch,
|
|
3991
|
+
defaultOptions = [],
|
|
3992
|
+
debounceMs = 250,
|
|
3993
|
+
placeholder: placeholderProp,
|
|
3994
|
+
emptyMessage: emptyMessageProp,
|
|
3995
|
+
idleMessage: idleMessageProp,
|
|
3996
|
+
size = "md",
|
|
3997
|
+
disabled = false,
|
|
3998
|
+
fullWidth = false,
|
|
3999
|
+
renderOption,
|
|
4000
|
+
ariaLabel,
|
|
4001
|
+
loadingLabel: loadingLabelProp,
|
|
4002
|
+
className,
|
|
4003
|
+
...props
|
|
4004
|
+
}) => {
|
|
4005
|
+
const t = useLocaleText();
|
|
4006
|
+
const placeholder = placeholderProp ?? t("combobox.placeholder");
|
|
4007
|
+
const emptyMessage = emptyMessageProp ?? t("combobox.empty");
|
|
4008
|
+
const idleMessage = idleMessageProp ?? t("combobox.idle");
|
|
4009
|
+
const loadingLabel = loadingLabelProp ?? t("combobox.loading");
|
|
4010
|
+
const generatedId = useId();
|
|
4011
|
+
const field = useFieldControl();
|
|
4012
|
+
const inputId = field?.inputId ?? generatedId;
|
|
4013
|
+
const listId = `${inputId}-listbox`;
|
|
4014
|
+
const [query, setQuery] = useState("");
|
|
4015
|
+
const [options, setOptions] = useState(defaultOptions);
|
|
4016
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
4017
|
+
const [hasSearched, setHasSearched] = useState(false);
|
|
4018
|
+
const requestSeq = useRef(0);
|
|
4019
|
+
const defaultOptionsRef = useRef(defaultOptions);
|
|
4020
|
+
useEffect(() => {
|
|
4021
|
+
defaultOptionsRef.current = defaultOptions;
|
|
4022
|
+
}, [defaultOptions]);
|
|
4023
|
+
const closeRef = useRef(() => {
|
|
4024
|
+
});
|
|
4025
|
+
const commit = useCallback(
|
|
4026
|
+
(option) => {
|
|
4027
|
+
onValueChange?.(option);
|
|
4028
|
+
setQuery("");
|
|
4029
|
+
closeRef.current();
|
|
4030
|
+
},
|
|
4031
|
+
[onValueChange]
|
|
4032
|
+
);
|
|
4033
|
+
const popup = useListboxPopup({
|
|
4034
|
+
items: options,
|
|
4035
|
+
onCommit: commit,
|
|
4036
|
+
disabled,
|
|
4037
|
+
// 상시 컨트롤이 입력창이라 포커스를 되돌릴 필요가 없다. triggerRef 는 장식용
|
|
4038
|
+
// chevron 버튼(tabIndex=-1)에 붙어 있어, 켜면 Escape 가 포커스를 그 숨은 버튼으로 던진다.
|
|
4039
|
+
returnFocusOnClose: false
|
|
4040
|
+
});
|
|
4041
|
+
const { isOpen, setIsOpen, close, activeIndex, setActiveIndex } = popup;
|
|
4042
|
+
closeRef.current = close;
|
|
4043
|
+
useEffect(() => {
|
|
4044
|
+
if (!isOpen) return;
|
|
4045
|
+
if (query === "") {
|
|
4046
|
+
requestSeq.current++;
|
|
4047
|
+
setOptions(defaultOptionsRef.current);
|
|
4048
|
+
setHasSearched(false);
|
|
4049
|
+
setIsLoading(false);
|
|
4050
|
+
return;
|
|
4051
|
+
}
|
|
4052
|
+
const seq = ++requestSeq.current;
|
|
4053
|
+
setIsLoading(true);
|
|
4054
|
+
const timer = setTimeout(() => {
|
|
4055
|
+
onSearch(query).then((result) => {
|
|
4056
|
+
if (seq !== requestSeq.current) return;
|
|
4057
|
+
setOptions(result);
|
|
4058
|
+
setHasSearched(true);
|
|
4059
|
+
}).catch(() => {
|
|
4060
|
+
if (seq !== requestSeq.current) return;
|
|
4061
|
+
setOptions([]);
|
|
4062
|
+
setHasSearched(true);
|
|
4063
|
+
}).finally(() => {
|
|
4064
|
+
if (seq !== requestSeq.current) return;
|
|
4065
|
+
setIsLoading(false);
|
|
4066
|
+
});
|
|
4067
|
+
}, debounceMs);
|
|
4068
|
+
return () => clearTimeout(timer);
|
|
4069
|
+
}, [query, isOpen, debounceMs, onSearch]);
|
|
4070
|
+
const rootClassName = cn(
|
|
4071
|
+
"combobox",
|
|
4072
|
+
`combobox_size_${size}`,
|
|
4073
|
+
{ combobox_full_width: fullWidth, combobox_disabled: disabled },
|
|
4074
|
+
className
|
|
4075
|
+
);
|
|
4076
|
+
const showIdle = !isLoading && !hasSearched && options.length === 0;
|
|
4077
|
+
const showEmpty = !isLoading && hasSearched && options.length === 0;
|
|
4078
|
+
const hasList = !showIdle && !showEmpty;
|
|
4079
|
+
const panelStyle = useSpringPresence({
|
|
4080
|
+
visible: isOpen,
|
|
4081
|
+
from: popup.dropUp ? "translateY(4px)" : "translateY(-4px)"
|
|
4082
|
+
});
|
|
4083
|
+
return /* @__PURE__ */ jsxs("div", { ref: popup.wrapperRef, className: rootClassName, ...props, children: [
|
|
4084
|
+
/* @__PURE__ */ jsxs("div", { className: "combobox_control", children: [
|
|
4085
|
+
/* @__PURE__ */ jsx(
|
|
4086
|
+
"input",
|
|
4087
|
+
{
|
|
4088
|
+
id: inputId,
|
|
4089
|
+
className: "combobox_input",
|
|
4090
|
+
role: "combobox",
|
|
4091
|
+
type: "text",
|
|
4092
|
+
autoComplete: "off",
|
|
4093
|
+
disabled,
|
|
4094
|
+
value: isOpen ? query : value?.label ?? "",
|
|
4095
|
+
placeholder: value ? value.label : placeholder,
|
|
4096
|
+
"aria-expanded": isOpen,
|
|
4097
|
+
"aria-controls": isOpen && hasList ? listId : void 0,
|
|
4098
|
+
"aria-autocomplete": "list",
|
|
4099
|
+
"aria-activedescendant": isOpen && activeIndex >= 0 && options[activeIndex] ? `${listId}-${options[activeIndex].value}` : void 0,
|
|
4100
|
+
"aria-labelledby": field?.labelId,
|
|
4101
|
+
"aria-label": field?.labelId ? void 0 : ariaLabel,
|
|
4102
|
+
"aria-describedby": field?.describedBy,
|
|
4103
|
+
"aria-invalid": field?.invalid || void 0,
|
|
4104
|
+
"aria-required": field?.required || void 0,
|
|
4105
|
+
onChange: (event) => {
|
|
4106
|
+
setQuery(event.target.value);
|
|
4107
|
+
if (!isOpen) setIsOpen(true);
|
|
4108
|
+
},
|
|
4109
|
+
onFocus: () => !disabled && setIsOpen(true),
|
|
4110
|
+
onKeyDown: popup.onInputKeyDown
|
|
4111
|
+
}
|
|
4112
|
+
),
|
|
4113
|
+
isLoading && /* @__PURE__ */ jsx("span", { className: "combobox_spinner", children: /* @__PURE__ */ jsx(Spinner, { size: iconSize.sm, ariaLabel: loadingLabel }) }),
|
|
4114
|
+
/* @__PURE__ */ jsx(
|
|
4115
|
+
"button",
|
|
4116
|
+
{
|
|
4117
|
+
type: "button",
|
|
4118
|
+
ref: popup.triggerRef,
|
|
4119
|
+
className: "combobox_toggle",
|
|
4120
|
+
tabIndex: -1,
|
|
4121
|
+
disabled,
|
|
4122
|
+
"aria-hidden": "true",
|
|
4123
|
+
onClick: () => isOpen ? close() : setIsOpen(true),
|
|
4124
|
+
children: /* @__PURE__ */ jsx(ChevronDown, { size: iconSize.lg })
|
|
4125
|
+
}
|
|
4126
|
+
)
|
|
4127
|
+
] }),
|
|
4128
|
+
isOpen && /* @__PURE__ */ jsx(
|
|
4129
|
+
animated.div,
|
|
4130
|
+
{
|
|
4131
|
+
className: cn("combobox_panel", { combobox_panel_up: popup.dropUp }),
|
|
4132
|
+
style: panelStyle,
|
|
4133
|
+
children: !hasList ? /* @__PURE__ */ jsx("p", { className: "combobox_message", role: "status", children: showIdle ? idleMessage : emptyMessage }) : /* @__PURE__ */ jsx(
|
|
4134
|
+
"div",
|
|
4135
|
+
{
|
|
4136
|
+
ref: popup.listRef,
|
|
4137
|
+
id: listId,
|
|
4138
|
+
className: "combobox_list",
|
|
4139
|
+
role: "listbox",
|
|
4140
|
+
children: options.map((option, index) => (
|
|
4141
|
+
/* biome-ignore lint/a11y/useKeyWithClickEvents: 키보드는 입력의 onKeyDown 이 담당한다 - option 은 aria-activedescendant 로 가리키는 비포커스 요소다 (APG Combobox) */
|
|
4142
|
+
/* @__PURE__ */ jsx(
|
|
4143
|
+
"div",
|
|
4144
|
+
{
|
|
4145
|
+
id: `${listId}-${option.value}`,
|
|
4146
|
+
role: "option",
|
|
4147
|
+
tabIndex: -1,
|
|
4148
|
+
"aria-selected": value?.value === option.value,
|
|
4149
|
+
"aria-disabled": option.disabled || void 0,
|
|
4150
|
+
className: cn("combobox_option", {
|
|
4151
|
+
is_active: index === activeIndex,
|
|
4152
|
+
is_disabled: option.disabled
|
|
4153
|
+
}),
|
|
4154
|
+
onMouseEnter: () => !option.disabled && setActiveIndex(index),
|
|
4155
|
+
onClick: () => !option.disabled && commit(option),
|
|
4156
|
+
children: renderOption ? renderOption(option) : option.label
|
|
4157
|
+
},
|
|
4158
|
+
option.value
|
|
4159
|
+
)
|
|
4160
|
+
))
|
|
4161
|
+
}
|
|
4162
|
+
)
|
|
4163
|
+
}
|
|
4164
|
+
)
|
|
4165
|
+
] });
|
|
4166
|
+
};
|
|
3062
4167
|
var normalizeForSearch = (s) => s.toLowerCase().replace(/\s+/g, "");
|
|
3063
4168
|
var Dropdown = (props) => {
|
|
4169
|
+
const t = useLocaleText();
|
|
3064
4170
|
const {
|
|
3065
4171
|
id,
|
|
3066
4172
|
label,
|
|
3067
|
-
placeholder
|
|
4173
|
+
placeholder: placeholderProp,
|
|
3068
4174
|
options,
|
|
3069
4175
|
disabled,
|
|
3070
4176
|
size = "md",
|
|
3071
4177
|
variant = "outline",
|
|
3072
4178
|
className,
|
|
3073
4179
|
searchable = false,
|
|
3074
|
-
searchPlaceholder
|
|
3075
|
-
emptyText
|
|
3076
|
-
selectedSummary
|
|
4180
|
+
searchPlaceholder: searchPlaceholderProp,
|
|
4181
|
+
emptyText: emptyTextProp,
|
|
4182
|
+
selectedSummary: selectedSummaryProp,
|
|
3077
4183
|
name
|
|
3078
4184
|
} = props;
|
|
4185
|
+
const placeholder = placeholderProp ?? t("dropdown.placeholder");
|
|
4186
|
+
const searchPlaceholder = searchPlaceholderProp ?? t("dropdown.searchPlaceholder");
|
|
4187
|
+
const emptyText = emptyTextProp ?? t("dropdown.empty");
|
|
4188
|
+
const selectedSummary = selectedSummaryProp ?? ((count) => t("dropdown.selectedSummary", { count }));
|
|
3079
4189
|
const multiple = props.multiple === true;
|
|
3080
4190
|
const internalId = useId();
|
|
3081
|
-
const
|
|
4191
|
+
const field = useFieldControl();
|
|
4192
|
+
const dropdownId = id ?? field?.inputId ?? internalId;
|
|
3082
4193
|
const isControlled = props.value !== void 0;
|
|
3083
4194
|
const [internalSingle, setInternalSingle] = useState(
|
|
3084
4195
|
() => props.multiple === true ? null : props.defaultValue ?? null
|
|
@@ -3086,14 +4197,9 @@ var Dropdown = (props) => {
|
|
|
3086
4197
|
const [internalMulti, setInternalMulti] = useState(
|
|
3087
4198
|
() => props.multiple === true ? props.defaultValue ?? [] : []
|
|
3088
4199
|
);
|
|
3089
|
-
const [isOpen, setIsOpen] = useState(false);
|
|
3090
|
-
const [activeIndex, setActiveIndex] = useState(-1);
|
|
3091
|
-
const [dropUp, setDropUp] = useState(false);
|
|
3092
4200
|
const [searchText, setSearchText] = useState("");
|
|
3093
4201
|
const [committedQuery, setCommittedQuery] = useState("");
|
|
3094
4202
|
const isComposingRef = useRef(false);
|
|
3095
|
-
const wrapperRef = useRef(null);
|
|
3096
|
-
const controlRef = useRef(null);
|
|
3097
4203
|
const searchRef = useRef(null);
|
|
3098
4204
|
const selectedValues = useMemo(() => {
|
|
3099
4205
|
if (multiple) {
|
|
@@ -3131,129 +4237,41 @@ var Dropdown = (props) => {
|
|
|
3131
4237
|
},
|
|
3132
4238
|
[selectedValues, options, isControlled, props.multiple, props.onValueChange, props.onChange]
|
|
3133
4239
|
);
|
|
3134
|
-
const closePanel = useCallback(() => {
|
|
3135
|
-
setIsOpen(false);
|
|
3136
|
-
if (searchable) controlRef.current?.focus();
|
|
3137
|
-
}, [searchable]);
|
|
3138
4240
|
const selectOption = useCallback(
|
|
3139
|
-
(opt) => {
|
|
3140
|
-
if (opt.disabled) return;
|
|
3141
|
-
if (multiple) {
|
|
3142
|
-
toggleMultiple(opt);
|
|
3143
|
-
} else {
|
|
3144
|
-
selectSingle(opt.value);
|
|
3145
|
-
closePanel();
|
|
3146
|
-
}
|
|
3147
|
-
},
|
|
3148
|
-
[multiple, toggleMultiple, selectSingle, closePanel]
|
|
3149
|
-
);
|
|
3150
|
-
useEffect(() => {
|
|
3151
|
-
const handleOutsideClick = (e) => {
|
|
3152
|
-
if (!wrapperRef.current?.contains(e.target)) {
|
|
3153
|
-
setIsOpen(false);
|
|
3154
|
-
}
|
|
3155
|
-
};
|
|
3156
|
-
document.addEventListener("mousedown", handleOutsideClick);
|
|
3157
|
-
return () => document.removeEventListener("mousedown", handleOutsideClick);
|
|
3158
|
-
}, []);
|
|
3159
|
-
const moveActive = useCallback(
|
|
3160
|
-
(dir) => {
|
|
3161
|
-
if (visibleOptions.length === 0) return;
|
|
3162
|
-
if (!isOpen) {
|
|
3163
|
-
setIsOpen(true);
|
|
3164
|
-
return;
|
|
3165
|
-
}
|
|
3166
|
-
let i = activeIndex;
|
|
3167
|
-
if (i === -1) {
|
|
3168
|
-
i = dir === 1 ? -1 : 0;
|
|
3169
|
-
}
|
|
3170
|
-
const len = visibleOptions.length;
|
|
3171
|
-
for (let step = 0; step < len; step++) {
|
|
3172
|
-
i = (i + dir + len) % len;
|
|
3173
|
-
if (!visibleOptions[i].disabled) {
|
|
3174
|
-
setActiveIndex(i);
|
|
3175
|
-
break;
|
|
3176
|
-
}
|
|
3177
|
-
}
|
|
3178
|
-
},
|
|
3179
|
-
[visibleOptions, isOpen, activeIndex]
|
|
3180
|
-
);
|
|
3181
|
-
const commitActive = useCallback(() => {
|
|
3182
|
-
if (activeIndex < 0 || activeIndex >= visibleOptions.length) return;
|
|
3183
|
-
selectOption(visibleOptions[activeIndex]);
|
|
3184
|
-
}, [activeIndex, visibleOptions, selectOption]);
|
|
3185
|
-
const onControlKeyDown = (e) => {
|
|
3186
|
-
if (disabled) return;
|
|
3187
|
-
switch (e.key) {
|
|
3188
|
-
case " ":
|
|
3189
|
-
case "Enter":
|
|
3190
|
-
e.preventDefault();
|
|
3191
|
-
if (!isOpen) setIsOpen(true);
|
|
3192
|
-
else commitActive();
|
|
3193
|
-
break;
|
|
3194
|
-
case "ArrowDown":
|
|
3195
|
-
e.preventDefault();
|
|
3196
|
-
moveActive(1);
|
|
3197
|
-
break;
|
|
3198
|
-
case "ArrowUp":
|
|
3199
|
-
e.preventDefault();
|
|
3200
|
-
moveActive(-1);
|
|
3201
|
-
break;
|
|
3202
|
-
case "Home":
|
|
3203
|
-
e.preventDefault();
|
|
3204
|
-
setIsOpen(true);
|
|
3205
|
-
setActiveIndex(visibleOptions.findIndex((o) => !o.disabled));
|
|
3206
|
-
break;
|
|
3207
|
-
case "End":
|
|
3208
|
-
e.preventDefault();
|
|
3209
|
-
setIsOpen(true);
|
|
3210
|
-
for (let i = visibleOptions.length - 1; i >= 0; i--) {
|
|
3211
|
-
if (!visibleOptions[i].disabled) {
|
|
3212
|
-
setActiveIndex(i);
|
|
3213
|
-
break;
|
|
3214
|
-
}
|
|
3215
|
-
}
|
|
3216
|
-
break;
|
|
3217
|
-
case "Escape":
|
|
3218
|
-
e.preventDefault();
|
|
3219
|
-
setIsOpen(false);
|
|
3220
|
-
break;
|
|
3221
|
-
case "Tab":
|
|
3222
|
-
setIsOpen(false);
|
|
3223
|
-
break;
|
|
3224
|
-
}
|
|
3225
|
-
};
|
|
3226
|
-
const onSearchKeyDown = (e) => {
|
|
3227
|
-
if (e.nativeEvent.isComposing) return;
|
|
3228
|
-
switch (e.key) {
|
|
3229
|
-
case "ArrowDown":
|
|
3230
|
-
e.preventDefault();
|
|
3231
|
-
moveActive(1);
|
|
3232
|
-
break;
|
|
3233
|
-
case "ArrowUp":
|
|
3234
|
-
e.preventDefault();
|
|
3235
|
-
moveActive(-1);
|
|
3236
|
-
break;
|
|
3237
|
-
case "Enter":
|
|
3238
|
-
e.preventDefault();
|
|
3239
|
-
commitActive();
|
|
3240
|
-
break;
|
|
3241
|
-
case "Escape":
|
|
3242
|
-
e.preventDefault();
|
|
3243
|
-
closePanel();
|
|
3244
|
-
break;
|
|
3245
|
-
case "Tab":
|
|
4241
|
+
(opt) => {
|
|
4242
|
+
if (opt.disabled) return;
|
|
4243
|
+
if (multiple) {
|
|
4244
|
+
toggleMultiple(opt);
|
|
4245
|
+
} else {
|
|
4246
|
+
selectSingle(opt.value);
|
|
3246
4247
|
closePanel();
|
|
3247
|
-
|
|
3248
|
-
}
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
4248
|
+
}
|
|
4249
|
+
},
|
|
4250
|
+
// closePanel 은 아래 훅에서 오므로 선언 순서상 참조만 한다 (렌더마다 동일 참조).
|
|
4251
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: closePanel 은 훅 결과라 아래에서 정의된다
|
|
4252
|
+
[multiple, toggleMultiple, selectSingle]
|
|
4253
|
+
);
|
|
4254
|
+
const {
|
|
4255
|
+
isOpen,
|
|
4256
|
+
setIsOpen,
|
|
4257
|
+
dropUp,
|
|
4258
|
+
activeIndex,
|
|
4259
|
+
setActiveIndex,
|
|
4260
|
+
wrapperRef,
|
|
4261
|
+
triggerRef: controlRef,
|
|
4262
|
+
listRef,
|
|
4263
|
+
close: closePanel,
|
|
4264
|
+
onTriggerKeyDown: onControlKeyDown,
|
|
4265
|
+
onInputKeyDown: onSearchKeyDown
|
|
4266
|
+
} = useListboxPopup({
|
|
4267
|
+
items: visibleOptions,
|
|
4268
|
+
onCommit: selectOption,
|
|
4269
|
+
disabled,
|
|
4270
|
+
// searchable 은 포커스가 검색 입력에 있으므로 닫을 때 트리거로 되돌린다.
|
|
4271
|
+
returnFocusOnClose: searchable,
|
|
4272
|
+
// 열릴 때는 선택된 항목을 활성으로. 없으면 훅이 첫 활성 항목을 고른다.
|
|
4273
|
+
initialActiveIndex: (opts) => opts.findIndex((o) => selectedValues.includes(o.value) && !o.disabled)
|
|
4274
|
+
});
|
|
3257
4275
|
useEffect(() => {
|
|
3258
4276
|
if (!isOpen) {
|
|
3259
4277
|
setSearchText("");
|
|
@@ -3266,14 +4284,6 @@ var Dropdown = (props) => {
|
|
|
3266
4284
|
searchRef.current?.focus();
|
|
3267
4285
|
}
|
|
3268
4286
|
}, [isOpen, searchable]);
|
|
3269
|
-
useEffect(() => {
|
|
3270
|
-
if (!isOpen || !controlRef.current) return;
|
|
3271
|
-
const rect = controlRef.current.getBoundingClientRect();
|
|
3272
|
-
const spaceBelow = window.innerHeight - rect.bottom;
|
|
3273
|
-
const spaceAbove = rect.top;
|
|
3274
|
-
const MIN_BELOW = 120;
|
|
3275
|
-
setDropUp(spaceBelow < MIN_BELOW && spaceAbove > spaceBelow);
|
|
3276
|
-
}, [isOpen]);
|
|
3277
4287
|
const currentOption = useMemo(
|
|
3278
4288
|
() => multiple ? null : options.find((o) => o.value === selectedValues[0]) ?? null,
|
|
3279
4289
|
[multiple, options, selectedValues]
|
|
@@ -3304,6 +4314,8 @@ var Dropdown = (props) => {
|
|
|
3304
4314
|
className: cn("dropdown_control", { is_disabled: disabled }),
|
|
3305
4315
|
"aria-haspopup": "listbox",
|
|
3306
4316
|
"aria-expanded": isOpen,
|
|
4317
|
+
"aria-describedby": field?.describedBy,
|
|
4318
|
+
"aria-invalid": field?.invalid || void 0,
|
|
3307
4319
|
"aria-controls": isOpen ? `${dropdownId}_listbox` : void 0,
|
|
3308
4320
|
onClick: () => !disabled && setIsOpen((o) => !o),
|
|
3309
4321
|
onKeyDown: onControlKeyDown,
|
|
@@ -3354,6 +4366,7 @@ var Dropdown = (props) => {
|
|
|
3354
4366
|
/* @__PURE__ */ jsx(
|
|
3355
4367
|
"div",
|
|
3356
4368
|
{
|
|
4369
|
+
ref: listRef,
|
|
3357
4370
|
id: `${dropdownId}_listbox`,
|
|
3358
4371
|
role: "listbox",
|
|
3359
4372
|
className: "dropdown_options",
|
|
@@ -3399,7 +4412,7 @@ var Dropdown = (props) => {
|
|
|
3399
4412
|
var pad = (n) => String(n).padStart(2, "0");
|
|
3400
4413
|
var getDaysInMonth = (year, month) => new Date(year, month, 0).getDate();
|
|
3401
4414
|
var normalizeWidth = (v) => typeof v === "number" ? `${v}px` : v;
|
|
3402
|
-
var
|
|
4415
|
+
var range2 = (start, end) => Array.from({ length: end - start + 1 }, (_, i) => start + i);
|
|
3403
4416
|
var DatePicker = ({
|
|
3404
4417
|
label,
|
|
3405
4418
|
value,
|
|
@@ -3413,12 +4426,19 @@ var DatePicker = ({
|
|
|
3413
4426
|
disabled,
|
|
3414
4427
|
fullWidth = true,
|
|
3415
4428
|
width,
|
|
3416
|
-
yearLabel
|
|
3417
|
-
monthLabel
|
|
3418
|
-
dayLabel
|
|
3419
|
-
minDateSrFormat
|
|
3420
|
-
selectableRangeUntilTodaySrText
|
|
4429
|
+
yearLabel: yearLabelProp,
|
|
4430
|
+
monthLabel: monthLabelProp,
|
|
4431
|
+
dayLabel: dayLabelProp,
|
|
4432
|
+
minDateSrFormat: minDateSrFormatProp,
|
|
4433
|
+
selectableRangeUntilTodaySrText: selectableRangeUntilTodaySrTextProp
|
|
3421
4434
|
}) => {
|
|
4435
|
+
const t = useLocaleText();
|
|
4436
|
+
const yearLabel = yearLabelProp ?? t("datePicker.year");
|
|
4437
|
+
const monthLabel = monthLabelProp ?? t("datePicker.month");
|
|
4438
|
+
const dayLabel = dayLabelProp ?? t("datePicker.day");
|
|
4439
|
+
const minDateSrFormat = minDateSrFormatProp ?? t("datePicker.minDateSr");
|
|
4440
|
+
const selectableRangeUntilTodaySrText = selectableRangeUntilTodaySrTextProp ?? t("datePicker.rangeUntilTodaySr");
|
|
4441
|
+
const field = useFieldControl();
|
|
3422
4442
|
const groupId = React11.useId();
|
|
3423
4443
|
const constraintId = React11.useId();
|
|
3424
4444
|
const { todayYear, todayMonth, todayDay } = React11.useMemo(() => {
|
|
@@ -3467,22 +4487,23 @@ var DatePicker = ({
|
|
|
3467
4487
|
}
|
|
3468
4488
|
return daysInMonth;
|
|
3469
4489
|
}, [year, month, selectableRange, todayYear, todayMonth, todayDay]);
|
|
4490
|
+
const minYear = min.year > 0 ? Math.max(startYear, min.year) : startYear;
|
|
3470
4491
|
const yearOptions = React11.useMemo(
|
|
3471
|
-
() =>
|
|
4492
|
+
() => range2(minYear, Math.max(minYear, maxYear)).map((y) => ({
|
|
3472
4493
|
value: String(y),
|
|
3473
4494
|
label: String(y)
|
|
3474
4495
|
})),
|
|
3475
|
-
[
|
|
4496
|
+
[minYear, maxYear]
|
|
3476
4497
|
);
|
|
3477
4498
|
const monthOptions = React11.useMemo(
|
|
3478
|
-
() =>
|
|
4499
|
+
() => range2(minMonth, Math.max(minMonth, maxMonth)).map((m) => ({
|
|
3479
4500
|
value: String(m),
|
|
3480
4501
|
label: pad(m)
|
|
3481
4502
|
})),
|
|
3482
4503
|
[minMonth, maxMonth]
|
|
3483
4504
|
);
|
|
3484
4505
|
const dayOptions = React11.useMemo(
|
|
3485
|
-
() =>
|
|
4506
|
+
() => range2(minDay, Math.max(minDay, maxDay)).map((d) => ({
|
|
3486
4507
|
value: String(d),
|
|
3487
4508
|
label: pad(d)
|
|
3488
4509
|
})),
|
|
@@ -3548,8 +4569,9 @@ var DatePicker = ({
|
|
|
3548
4569
|
{
|
|
3549
4570
|
className: "date_picker_fields",
|
|
3550
4571
|
role: "group",
|
|
3551
|
-
"aria-labelledby": label ? groupId : void 0,
|
|
3552
|
-
"aria-describedby": constraintDesc ? constraintId : void 0,
|
|
4572
|
+
"aria-labelledby": field?.labelId ?? (label ? groupId : void 0),
|
|
4573
|
+
"aria-describedby": [field?.describedBy, constraintDesc ? constraintId : void 0].filter(Boolean).join(" ") || void 0,
|
|
4574
|
+
"aria-invalid": field?.invalid || void 0,
|
|
3553
4575
|
children: [
|
|
3554
4576
|
/* @__PURE__ */ jsx(
|
|
3555
4577
|
Dropdown,
|
|
@@ -3595,8 +4617,83 @@ var DatePicker = ({
|
|
|
3595
4617
|
)
|
|
3596
4618
|
] });
|
|
3597
4619
|
};
|
|
4620
|
+
var DateRangePicker = ({
|
|
4621
|
+
value,
|
|
4622
|
+
onValueChange,
|
|
4623
|
+
startLabel: startLabelProp,
|
|
4624
|
+
endLabel: endLabelProp,
|
|
4625
|
+
startYear,
|
|
4626
|
+
endYear,
|
|
4627
|
+
minDate,
|
|
4628
|
+
selectableRange = "all",
|
|
4629
|
+
disabled,
|
|
4630
|
+
fullWidth = true
|
|
4631
|
+
}) => {
|
|
4632
|
+
const t = useLocaleText();
|
|
4633
|
+
const startLabel = startLabelProp ?? t("dateRange.start");
|
|
4634
|
+
const endLabel = endLabelProp ?? t("dateRange.end");
|
|
4635
|
+
const field = useFieldControl();
|
|
4636
|
+
const start = value?.start;
|
|
4637
|
+
const end = value?.end;
|
|
4638
|
+
const handleStartChange = (next) => {
|
|
4639
|
+
onValueChange({ start: next, end: end && end < next ? void 0 : end });
|
|
4640
|
+
};
|
|
4641
|
+
const handleEndChange = (next) => {
|
|
4642
|
+
onValueChange({ start, end: next });
|
|
4643
|
+
};
|
|
4644
|
+
const endMinDate = start ?? minDate;
|
|
4645
|
+
return /* @__PURE__ */ jsx(
|
|
4646
|
+
"div",
|
|
4647
|
+
{
|
|
4648
|
+
className: cn("date_range_picker", {
|
|
4649
|
+
date_range_picker_full_width: fullWidth,
|
|
4650
|
+
date_range_picker_disabled: disabled
|
|
4651
|
+
}),
|
|
4652
|
+
children: /* @__PURE__ */ jsxs(
|
|
4653
|
+
"div",
|
|
4654
|
+
{
|
|
4655
|
+
className: "date_range_picker_fields",
|
|
4656
|
+
role: "group",
|
|
4657
|
+
"aria-labelledby": field?.labelId,
|
|
4658
|
+
"aria-describedby": field?.describedBy,
|
|
4659
|
+
"aria-invalid": field?.invalid || void 0,
|
|
4660
|
+
children: [
|
|
4661
|
+
/* @__PURE__ */ jsx(
|
|
4662
|
+
DatePicker,
|
|
4663
|
+
{
|
|
4664
|
+
label: startLabel,
|
|
4665
|
+
value: start,
|
|
4666
|
+
onValueChange: handleStartChange,
|
|
4667
|
+
startYear,
|
|
4668
|
+
endYear,
|
|
4669
|
+
minDate,
|
|
4670
|
+
selectableRange,
|
|
4671
|
+
disabled,
|
|
4672
|
+
fullWidth: true
|
|
4673
|
+
}
|
|
4674
|
+
),
|
|
4675
|
+
/* @__PURE__ */ jsx(
|
|
4676
|
+
DatePicker,
|
|
4677
|
+
{
|
|
4678
|
+
label: endLabel,
|
|
4679
|
+
value: end,
|
|
4680
|
+
onValueChange: handleEndChange,
|
|
4681
|
+
startYear,
|
|
4682
|
+
endYear,
|
|
4683
|
+
minDate: endMinDate,
|
|
4684
|
+
selectableRange,
|
|
4685
|
+
disabled: disabled || !start,
|
|
4686
|
+
fullWidth: true
|
|
4687
|
+
}
|
|
4688
|
+
)
|
|
4689
|
+
]
|
|
4690
|
+
}
|
|
4691
|
+
)
|
|
4692
|
+
}
|
|
4693
|
+
);
|
|
4694
|
+
};
|
|
3598
4695
|
var FileInput = ({
|
|
3599
|
-
label
|
|
4696
|
+
label: labelProp,
|
|
3600
4697
|
onFiles,
|
|
3601
4698
|
supportingText,
|
|
3602
4699
|
preview = false,
|
|
@@ -3608,8 +4705,12 @@ var FileInput = ({
|
|
|
3608
4705
|
onChange,
|
|
3609
4706
|
...props
|
|
3610
4707
|
}) => {
|
|
3611
|
-
const
|
|
4708
|
+
const t = useLocaleText();
|
|
4709
|
+
const label = labelProp ?? t("fileInput.label");
|
|
4710
|
+
const generatedInputId = React11.useId();
|
|
3612
4711
|
const helperId = React11.useId();
|
|
4712
|
+
const field = useFieldControl();
|
|
4713
|
+
const inputId = field?.inputId ?? generatedInputId;
|
|
3613
4714
|
const inputRef = React11.useRef(null);
|
|
3614
4715
|
const [previewUrls, setPreviewUrls] = React11.useState([]);
|
|
3615
4716
|
const previewUrlsRef = React11.useRef([]);
|
|
@@ -3679,7 +4780,8 @@ var FileInput = ({
|
|
|
3679
4780
|
className: "file_input_control",
|
|
3680
4781
|
disabled,
|
|
3681
4782
|
accept: isPreviewVariant ? accept ?? "image/*" : accept,
|
|
3682
|
-
"aria-describedby": supportingText ? helperId : void 0,
|
|
4783
|
+
"aria-describedby": field?.describedBy ?? (supportingText ? helperId : void 0),
|
|
4784
|
+
"aria-invalid": field?.invalid || void 0,
|
|
3683
4785
|
onChange: handleChange
|
|
3684
4786
|
}
|
|
3685
4787
|
),
|
|
@@ -3704,7 +4806,7 @@ var FileInput = ({
|
|
|
3704
4806
|
type: "button",
|
|
3705
4807
|
className: "file_input_preview_remove",
|
|
3706
4808
|
onClick: handleRemove,
|
|
3707
|
-
"aria-label": "
|
|
4809
|
+
"aria-label": t("fileInput.removeImage"),
|
|
3708
4810
|
children: /* @__PURE__ */ jsx(X, { size: iconSize.xs, "aria-hidden": "true" })
|
|
3709
4811
|
}
|
|
3710
4812
|
),
|
|
@@ -3767,20 +4869,28 @@ function ImageCropper({
|
|
|
3767
4869
|
onReady,
|
|
3768
4870
|
onError,
|
|
3769
4871
|
className,
|
|
3770
|
-
label
|
|
3771
|
-
hint
|
|
3772
|
-
zoomOutLabel
|
|
3773
|
-
zoomLabel
|
|
3774
|
-
zoomInLabel
|
|
3775
|
-
noPanHint
|
|
4872
|
+
label: labelProp,
|
|
4873
|
+
hint: hintProp,
|
|
4874
|
+
zoomOutLabel: zoomOutLabelProp,
|
|
4875
|
+
zoomLabel: zoomLabelProp,
|
|
4876
|
+
zoomInLabel: zoomInLabelProp,
|
|
4877
|
+
noPanHint: noPanHintProp,
|
|
3776
4878
|
...rest
|
|
3777
4879
|
}) {
|
|
4880
|
+
const t = useLocaleText();
|
|
4881
|
+
const hint = hintProp ?? t("imageCropper.hint");
|
|
4882
|
+
const noPanHint = noPanHintProp ?? t("imageCropper.noPanHint");
|
|
4883
|
+
const label = labelProp ?? t("imageCropper.label");
|
|
4884
|
+
const zoomOutLabel = zoomOutLabelProp ?? t("imageCropper.zoomOut");
|
|
4885
|
+
const zoomLabel = zoomLabelProp ?? t("imageCropper.zoom");
|
|
4886
|
+
const zoomInLabel = zoomInLabelProp ?? t("imageCropper.zoomIn");
|
|
3778
4887
|
const imageRef = useRef(null);
|
|
3779
4888
|
const viewportRef = useRef(null);
|
|
3780
4889
|
const dragRef = useRef(
|
|
3781
4890
|
null
|
|
3782
4891
|
);
|
|
3783
4892
|
const hintId = useId();
|
|
4893
|
+
const field = useFieldControl();
|
|
3784
4894
|
const [previewUrl, setPreviewUrl] = useState("");
|
|
3785
4895
|
const [srcType, setSrcType] = useState("");
|
|
3786
4896
|
useEffect(() => {
|
|
@@ -3955,8 +5065,9 @@ function ImageCropper({
|
|
|
3955
5065
|
className: cn("image_cropper_viewport", dragging && "image_cropper_viewport_dragging"),
|
|
3956
5066
|
style: viewportStyle,
|
|
3957
5067
|
role: "group",
|
|
3958
|
-
"aria-
|
|
3959
|
-
"aria-
|
|
5068
|
+
"aria-labelledby": field?.labelId,
|
|
5069
|
+
"aria-label": field?.labelId ? void 0 : label,
|
|
5070
|
+
"aria-describedby": [field?.describedBy, hintId].filter(Boolean).join(" "),
|
|
3960
5071
|
tabIndex: imageSize ? 0 : -1,
|
|
3961
5072
|
onPointerDown: handlePointerDown,
|
|
3962
5073
|
onPointerMove: handlePointerMove,
|
|
@@ -4044,9 +5155,11 @@ var OtpInput = ({
|
|
|
4044
5155
|
disabled = false,
|
|
4045
5156
|
supportingText,
|
|
4046
5157
|
autoFocus = false,
|
|
4047
|
-
ariaLabel
|
|
5158
|
+
ariaLabel: ariaLabelProp,
|
|
4048
5159
|
className
|
|
4049
5160
|
}) => {
|
|
5161
|
+
const t = useLocaleText();
|
|
5162
|
+
const ariaLabel = ariaLabelProp ?? t("otpInput.label");
|
|
4050
5163
|
const inputsRef = React11.useRef([]);
|
|
4051
5164
|
const isTypingRef = React11.useRef(false);
|
|
4052
5165
|
React11.useEffect(() => {
|
|
@@ -4130,46 +5243,56 @@ var OtpInput = ({
|
|
|
4130
5243
|
};
|
|
4131
5244
|
const rootClassName = cn("otp_input", className);
|
|
4132
5245
|
const supportingId = React11.useId();
|
|
5246
|
+
const field = useFieldControl();
|
|
4133
5247
|
return (
|
|
4134
5248
|
// biome-ignore lint/a11y/useSemanticElements: <fieldset> would force border/legend styles; role=group is the WAI-ARIA equivalent for OTP grouping
|
|
4135
|
-
/* @__PURE__ */ jsxs(
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
5249
|
+
/* @__PURE__ */ jsxs(
|
|
5250
|
+
"div",
|
|
5251
|
+
{
|
|
5252
|
+
className: rootClassName,
|
|
5253
|
+
role: "group",
|
|
5254
|
+
"aria-labelledby": field?.labelId,
|
|
5255
|
+
"aria-label": field?.labelId ? void 0 : ariaLabel,
|
|
5256
|
+
children: [
|
|
5257
|
+
/* @__PURE__ */ jsx("div", { className: "otp_input_boxes", children: digits.map((digit, i) => /* @__PURE__ */ jsx(
|
|
5258
|
+
"input",
|
|
5259
|
+
{
|
|
5260
|
+
ref: (el) => {
|
|
5261
|
+
inputsRef.current[i] = el;
|
|
5262
|
+
},
|
|
5263
|
+
type: "text",
|
|
5264
|
+
inputMode: "numeric",
|
|
5265
|
+
pattern: "\\d*",
|
|
5266
|
+
maxLength: 1,
|
|
5267
|
+
autoComplete: i === 0 ? "one-time-code" : "off",
|
|
5268
|
+
value: digit,
|
|
5269
|
+
onChange: (e) => handleChange(i, e),
|
|
5270
|
+
onFocus: () => handleFocus(i),
|
|
5271
|
+
onKeyDown: (e) => handleKeyDown2(i, e),
|
|
5272
|
+
onPaste: handlePaste,
|
|
5273
|
+
disabled,
|
|
5274
|
+
"aria-label": t("otpInput.digit", { index: i + 1 }),
|
|
5275
|
+
"aria-invalid": error || field?.invalid || void 0,
|
|
5276
|
+
"aria-describedby": field?.describedBy ?? (supportingText ? supportingId : void 0),
|
|
5277
|
+
className: cn(
|
|
5278
|
+
"otp_input_box",
|
|
5279
|
+
error && "otp_input_box_error",
|
|
5280
|
+
disabled && "otp_input_box_disabled"
|
|
5281
|
+
)
|
|
5282
|
+
},
|
|
5283
|
+
i
|
|
5284
|
+
)) }),
|
|
5285
|
+
supportingText && /* @__PURE__ */ jsx(
|
|
5286
|
+
"span",
|
|
5287
|
+
{
|
|
5288
|
+
id: supportingId,
|
|
5289
|
+
className: cn("otp_input_supporting", error && "otp_input_supporting_error"),
|
|
5290
|
+
children: supportingText
|
|
5291
|
+
}
|
|
4160
5292
|
)
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
supportingText && /* @__PURE__ */ jsx(
|
|
4165
|
-
"span",
|
|
4166
|
-
{
|
|
4167
|
-
id: supportingId,
|
|
4168
|
-
className: cn("otp_input_supporting", error && "otp_input_supporting_error"),
|
|
4169
|
-
children: supportingText
|
|
4170
|
-
}
|
|
4171
|
-
)
|
|
4172
|
-
] })
|
|
5293
|
+
]
|
|
5294
|
+
}
|
|
5295
|
+
)
|
|
4173
5296
|
);
|
|
4174
5297
|
};
|
|
4175
5298
|
OtpInput.displayName = "OtpInput";
|
|
@@ -4198,6 +5321,7 @@ var RadioGroup = ({
|
|
|
4198
5321
|
const generatedName = React11.useId();
|
|
4199
5322
|
const name = nameProp ?? generatedName;
|
|
4200
5323
|
const idPrefix = React11.useId();
|
|
5324
|
+
const field = useFieldControl();
|
|
4201
5325
|
const labelId = label ? `${idPrefix}-label` : void 0;
|
|
4202
5326
|
const helperId = supportingText ? `${idPrefix}-help` : void 0;
|
|
4203
5327
|
const onChange = React11.useCallback(
|
|
@@ -4227,9 +5351,10 @@ var RadioGroup = ({
|
|
|
4227
5351
|
"div",
|
|
4228
5352
|
{
|
|
4229
5353
|
role: "radiogroup",
|
|
4230
|
-
"aria-labelledby": labelId,
|
|
4231
|
-
"aria-describedby": helperId,
|
|
4232
|
-
"aria-invalid": error || void 0,
|
|
5354
|
+
"aria-labelledby": field?.labelId ?? labelId,
|
|
5355
|
+
"aria-describedby": field?.describedBy ?? helperId,
|
|
5356
|
+
"aria-invalid": error || field?.invalid || void 0,
|
|
5357
|
+
"aria-required": field?.required || void 0,
|
|
4233
5358
|
className: "radio_group_options",
|
|
4234
5359
|
children
|
|
4235
5360
|
}
|
|
@@ -4262,6 +5387,7 @@ var Radio = ({
|
|
|
4262
5387
|
onChange?.(event);
|
|
4263
5388
|
};
|
|
4264
5389
|
const rootClassName = cn("radio", `radio_size_${size}`, disabled && "radio_disabled", className);
|
|
5390
|
+
const field = useFieldControl();
|
|
4265
5391
|
return /* @__PURE__ */ jsxs("label", { className: rootClassName, children: [
|
|
4266
5392
|
/* @__PURE__ */ jsx(
|
|
4267
5393
|
"input",
|
|
@@ -4269,6 +5395,8 @@ var Radio = ({
|
|
|
4269
5395
|
ref,
|
|
4270
5396
|
type: "radio",
|
|
4271
5397
|
className: "radio_input",
|
|
5398
|
+
id: field?.inputId ?? props.id,
|
|
5399
|
+
"aria-describedby": field?.describedBy ?? props["aria-describedby"],
|
|
4272
5400
|
value,
|
|
4273
5401
|
name,
|
|
4274
5402
|
disabled,
|
|
@@ -4282,6 +5410,149 @@ var Radio = ({
|
|
|
4282
5410
|
] });
|
|
4283
5411
|
};
|
|
4284
5412
|
Radio.displayName = "Radio";
|
|
5413
|
+
var SEPARATORS = /[,\t\n\r]+/;
|
|
5414
|
+
var splitTags = (text) => text.split(SEPARATORS).map((part) => part.trim()).filter(Boolean);
|
|
5415
|
+
var TagInput = ({
|
|
5416
|
+
value,
|
|
5417
|
+
defaultValue = [],
|
|
5418
|
+
onValueChange,
|
|
5419
|
+
placeholder: placeholderProp,
|
|
5420
|
+
maxTags,
|
|
5421
|
+
allowDuplicates = false,
|
|
5422
|
+
size = "md",
|
|
5423
|
+
disabled = false,
|
|
5424
|
+
fullWidth = false,
|
|
5425
|
+
ariaLabel,
|
|
5426
|
+
className,
|
|
5427
|
+
...props
|
|
5428
|
+
}) => {
|
|
5429
|
+
const t = useLocaleText();
|
|
5430
|
+
const placeholder = placeholderProp ?? t("tagInput.placeholder");
|
|
5431
|
+
const generatedId = useId();
|
|
5432
|
+
const field = useFieldControl();
|
|
5433
|
+
const inputId = field?.inputId ?? generatedId;
|
|
5434
|
+
const isControlled = value !== void 0;
|
|
5435
|
+
const [innerTags, setInnerTags] = useState(defaultValue);
|
|
5436
|
+
const tags = isControlled ? value : innerTags;
|
|
5437
|
+
const [draft, setDraft] = useState("");
|
|
5438
|
+
const [announcement, setAnnouncement] = useState("");
|
|
5439
|
+
const inputRef = useRef(null);
|
|
5440
|
+
const isFull = maxTags !== void 0 && tags.length >= maxTags;
|
|
5441
|
+
const setTags = (next) => {
|
|
5442
|
+
if (!isControlled) setInnerTags(next);
|
|
5443
|
+
onValueChange?.(next);
|
|
5444
|
+
};
|
|
5445
|
+
const addTags = (text) => {
|
|
5446
|
+
const candidates = splitTags(text);
|
|
5447
|
+
if (candidates.length === 0) return 0;
|
|
5448
|
+
const next = [...tags];
|
|
5449
|
+
const added = [];
|
|
5450
|
+
const duplicates = [];
|
|
5451
|
+
for (const candidate of candidates) {
|
|
5452
|
+
if (maxTags !== void 0 && next.length >= maxTags) break;
|
|
5453
|
+
if (!allowDuplicates && next.includes(candidate)) {
|
|
5454
|
+
duplicates.push(candidate);
|
|
5455
|
+
continue;
|
|
5456
|
+
}
|
|
5457
|
+
next.push(candidate);
|
|
5458
|
+
added.push(candidate);
|
|
5459
|
+
}
|
|
5460
|
+
const isAtCap = maxTags !== void 0 && next.length >= maxTags;
|
|
5461
|
+
if (added.length === 0) {
|
|
5462
|
+
if (isAtCap) {
|
|
5463
|
+
setAnnouncement(t("tagInput.atCap", { max: maxTags }));
|
|
5464
|
+
} else if (duplicates.length > 0) {
|
|
5465
|
+
setAnnouncement(t("tagInput.duplicate", { names: duplicates.join(", ") }));
|
|
5466
|
+
}
|
|
5467
|
+
return 0;
|
|
5468
|
+
}
|
|
5469
|
+
setTags(next);
|
|
5470
|
+
const notes = [
|
|
5471
|
+
duplicates.length > 0 ? t("tagInput.duplicate", { names: duplicates.join(", ") }) : "",
|
|
5472
|
+
isAtCap && maxTags !== void 0 ? t("tagInput.atCap", { max: maxTags }) : ""
|
|
5473
|
+
].filter(Boolean);
|
|
5474
|
+
setAnnouncement(
|
|
5475
|
+
notes.length > 0 ? t("tagInput.addedWithNotes", { names: added.join(", "), notes: notes.join(", ") }) : t("tagInput.added", { names: added.join(", ") })
|
|
5476
|
+
);
|
|
5477
|
+
return added.length;
|
|
5478
|
+
};
|
|
5479
|
+
const removeAt = (index) => {
|
|
5480
|
+
const removed = tags[index];
|
|
5481
|
+
setTags(tags.filter((_, i) => i !== index));
|
|
5482
|
+
setAnnouncement(t("tagInput.removed", { name: removed }));
|
|
5483
|
+
};
|
|
5484
|
+
const onKeyDown = (event) => {
|
|
5485
|
+
if (event.nativeEvent.isComposing) return;
|
|
5486
|
+
if (event.key === "Enter" || event.key === ",") {
|
|
5487
|
+
event.preventDefault();
|
|
5488
|
+
if (addTags(draft) > 0) setDraft("");
|
|
5489
|
+
return;
|
|
5490
|
+
}
|
|
5491
|
+
if (event.key === "Backspace" && draft === "" && tags.length > 0) {
|
|
5492
|
+
event.preventDefault();
|
|
5493
|
+
removeAt(tags.length - 1);
|
|
5494
|
+
}
|
|
5495
|
+
};
|
|
5496
|
+
const onPaste = (event) => {
|
|
5497
|
+
const text = event.clipboardData.getData("text");
|
|
5498
|
+
if (!SEPARATORS.test(text)) return;
|
|
5499
|
+
event.preventDefault();
|
|
5500
|
+
const input = event.currentTarget;
|
|
5501
|
+
const start = input.selectionStart ?? draft.length;
|
|
5502
|
+
const end = input.selectionEnd ?? draft.length;
|
|
5503
|
+
const merged = `${draft.slice(0, start)}${text}${draft.slice(end)}`;
|
|
5504
|
+
if (addTags(merged) > 0) setDraft("");
|
|
5505
|
+
};
|
|
5506
|
+
const rootClassName = cn(
|
|
5507
|
+
"tag_input",
|
|
5508
|
+
`tag_input_size_${size}`,
|
|
5509
|
+
{ tag_input_full_width: fullWidth, tag_input_disabled: disabled },
|
|
5510
|
+
className
|
|
5511
|
+
);
|
|
5512
|
+
return /* @__PURE__ */ jsxs("div", { className: rootClassName, ...props, children: [
|
|
5513
|
+
/* @__PURE__ */ jsxs("div", { className: "tag_input_control", onClick: () => inputRef.current?.focus(), children: [
|
|
5514
|
+
tags.length > 0 && /* @__PURE__ */ jsx("ul", { className: "tag_input_tags", children: tags.map((tag, index) => (
|
|
5515
|
+
/* biome-ignore lint/suspicious/noArrayIndexKey: allowDuplicates 면 같은 라벨이 여러 개라 값만으로는 구분되지 않는다 */
|
|
5516
|
+
/* @__PURE__ */ jsx("li", { className: "tag_input_tag", children: /* @__PURE__ */ jsx(
|
|
5517
|
+
Chip,
|
|
5518
|
+
{
|
|
5519
|
+
type: "static",
|
|
5520
|
+
size: "sm",
|
|
5521
|
+
label: tag,
|
|
5522
|
+
removable: !disabled,
|
|
5523
|
+
onRemove: () => removeAt(index)
|
|
5524
|
+
}
|
|
5525
|
+
) }, `${tag}-${index}`)
|
|
5526
|
+
)) }),
|
|
5527
|
+
/* @__PURE__ */ jsx(
|
|
5528
|
+
"input",
|
|
5529
|
+
{
|
|
5530
|
+
ref: inputRef,
|
|
5531
|
+
id: inputId,
|
|
5532
|
+
className: "tag_input_field",
|
|
5533
|
+
type: "text",
|
|
5534
|
+
autoComplete: "off",
|
|
5535
|
+
value: draft,
|
|
5536
|
+
disabled,
|
|
5537
|
+
readOnly: isFull,
|
|
5538
|
+
placeholder: isFull ? "" : placeholder,
|
|
5539
|
+
"aria-labelledby": field?.labelId,
|
|
5540
|
+
"aria-label": field?.labelId ? void 0 : ariaLabel,
|
|
5541
|
+
"aria-describedby": field?.describedBy,
|
|
5542
|
+
"aria-invalid": field?.invalid || void 0,
|
|
5543
|
+
"aria-required": field?.required || void 0,
|
|
5544
|
+
onChange: (event) => setDraft(event.target.value),
|
|
5545
|
+
onKeyDown,
|
|
5546
|
+
onPaste,
|
|
5547
|
+
onBlur: () => {
|
|
5548
|
+
if (addTags(draft) > 0) setDraft("");
|
|
5549
|
+
}
|
|
5550
|
+
}
|
|
5551
|
+
)
|
|
5552
|
+
] }),
|
|
5553
|
+
/* @__PURE__ */ jsx("span", { className: "tag_input_live", role: "status", children: announcement })
|
|
5554
|
+
] });
|
|
5555
|
+
};
|
|
4285
5556
|
var LINE_HEIGHT_PX = {
|
|
4286
5557
|
sm: 20,
|
|
4287
5558
|
md: 20,
|
|
@@ -4313,8 +5584,10 @@ var Textarea = ({
|
|
|
4313
5584
|
...props
|
|
4314
5585
|
}) => {
|
|
4315
5586
|
const generatedId = useId();
|
|
4316
|
-
const
|
|
5587
|
+
const field = useFieldControl();
|
|
5588
|
+
const inputId = id ?? field?.inputId ?? generatedId;
|
|
4317
5589
|
const helperId = supportingText ? `${inputId}-help` : void 0;
|
|
5590
|
+
const describedBy = field?.describedBy ?? helperId;
|
|
4318
5591
|
const isControlled = value !== void 0;
|
|
4319
5592
|
const applyTransform = (nextValue) => transformValue ? transformValue(nextValue) : nextValue;
|
|
4320
5593
|
const [innerValue, setInnerValue] = useState(() => applyTransform(value ?? defaultValue ?? ""));
|
|
@@ -4346,228 +5619,187 @@ var Textarea = ({
|
|
|
4346
5619
|
const maxH = maxRows ? maxRows * lh2 : Number.POSITIVE_INFINITY;
|
|
4347
5620
|
el.style.height = "auto";
|
|
4348
5621
|
const next = Math.min(Math.max(el.scrollHeight, minH), maxH);
|
|
4349
|
-
el.style.height = `${next}px`;
|
|
4350
|
-
el.style.overflowY = el.scrollHeight > maxH ? "auto" : "hidden";
|
|
4351
|
-
}, [innerValue, autoGrow, size, minRows, maxRows]);
|
|
4352
|
-
const rootClassName = cn(
|
|
4353
|
-
"textarea",
|
|
4354
|
-
size === "sm" && "textarea_size_sm",
|
|
4355
|
-
size === "lg" && "textarea_size_lg",
|
|
4356
|
-
fullWidth && "textarea_full_width",
|
|
4357
|
-
error && "textarea_error",
|
|
4358
|
-
props.disabled && "textarea_disabled",
|
|
4359
|
-
className
|
|
4360
|
-
);
|
|
4361
|
-
const counterText = showCounter && maxLength !== void 0 ? `${innerValue.length}/${maxLength}` : showCounter ? String(innerValue.length) : null;
|
|
4362
|
-
const emit = (nextValue) => {
|
|
4363
|
-
setInnerValue(nextValue);
|
|
4364
|
-
if (nextValue !== lastEmittedValueRef.current) {
|
|
4365
|
-
lastEmittedValueRef.current = nextValue;
|
|
4366
|
-
(onValueChange ?? onChangeAction)?.(nextValue);
|
|
4367
|
-
}
|
|
4368
|
-
};
|
|
4369
|
-
return /* @__PURE__ */ jsxs("div", { className: rootClassName, children: [
|
|
4370
|
-
label && showLabel && /* @__PURE__ */ jsx("label", { htmlFor: inputId, className: "textarea_label", children: label }),
|
|
4371
|
-
/* @__PURE__ */ jsxs("div", { className: "textarea_container", children: [
|
|
4372
|
-
toolbar && /* @__PURE__ */ jsx("div", { className: "textarea_toolbar", inert: props.disabled || void 0, children: toolbar }),
|
|
4373
|
-
/* @__PURE__ */ jsx("div", { className: "textarea_input_wrap", children: /* @__PURE__ */ jsx(
|
|
4374
|
-
"textarea",
|
|
4375
|
-
{
|
|
4376
|
-
id: inputId,
|
|
4377
|
-
ref: setRefs,
|
|
4378
|
-
className: "textarea_input",
|
|
4379
|
-
style: { resize: autoGrow ? "none" : resize },
|
|
4380
|
-
rows: autoGrow ? minRows ?? rows : rows,
|
|
4381
|
-
maxLength,
|
|
4382
|
-
"aria-invalid": !!error,
|
|
4383
|
-
"aria-describedby": helperId,
|
|
4384
|
-
"aria-label": !showLabel ? label : void 0,
|
|
4385
|
-
...props,
|
|
4386
|
-
value: innerValue,
|
|
4387
|
-
onCompositionStart: () => {
|
|
4388
|
-
isComposingRef.current = true;
|
|
4389
|
-
},
|
|
4390
|
-
onCompositionEnd: (event) => {
|
|
4391
|
-
isComposingRef.current = false;
|
|
4392
|
-
emit(applyTransform(event.currentTarget.value));
|
|
4393
|
-
},
|
|
4394
|
-
onChange: (event) => {
|
|
4395
|
-
const rawValue = event.target.value;
|
|
4396
|
-
if (isComposingRef.current) {
|
|
4397
|
-
setInnerValue(rawValue);
|
|
4398
|
-
if (imeStrategy === "immediate" && rawValue !== lastEmittedValueRef.current) {
|
|
4399
|
-
lastEmittedValueRef.current = rawValue;
|
|
4400
|
-
(onValueChange ?? onChangeAction)?.(rawValue);
|
|
4401
|
-
}
|
|
4402
|
-
return;
|
|
4403
|
-
}
|
|
4404
|
-
emit(applyTransform(rawValue));
|
|
4405
|
-
}
|
|
4406
|
-
}
|
|
4407
|
-
) })
|
|
4408
|
-
] }),
|
|
4409
|
-
(supportingText || counterText) && /* @__PURE__ */ jsxs("div", { className: "textarea_footer", children: [
|
|
4410
|
-
supportingText ? /* @__PURE__ */ jsx("div", { id: helperId, className: "textarea_helper", children: supportingText }) : /* @__PURE__ */ jsx("span", {}),
|
|
4411
|
-
counterText && /* @__PURE__ */ jsx("div", { className: "textarea_counter", "aria-hidden": "true", children: counterText })
|
|
4412
|
-
] })
|
|
4413
|
-
] });
|
|
4414
|
-
};
|
|
4415
|
-
Textarea.displayName = "Textarea";
|
|
4416
|
-
var ClearIcon = () => /* @__PURE__ */ jsx(X, { size: iconSize.lg, "aria-hidden": "true" });
|
|
4417
|
-
var DEFAULT_PASSWORD_TOGGLE_LABELS = { show: "\uBE44\uBC00\uBC88\uD638 \uD45C\uC2DC", hide: "\uBE44\uBC00\uBC88\uD638 \uC228\uAE30\uAE30" };
|
|
4418
|
-
var TextField = ({
|
|
4419
|
-
id,
|
|
4420
|
-
label,
|
|
4421
|
-
showLabel = true,
|
|
4422
|
-
supportingText,
|
|
4423
|
-
error,
|
|
4424
|
-
success,
|
|
4425
|
-
identifier,
|
|
4426
|
-
leadingIcon,
|
|
4427
|
-
trailingIcon,
|
|
4428
|
-
leadingAction,
|
|
4429
|
-
trailingAction,
|
|
4430
|
-
showPasswordToggle,
|
|
4431
|
-
passwordToggleLabels,
|
|
4432
|
-
clearable,
|
|
4433
|
-
clearLabel = "\uC9C0\uC6B0\uAE30",
|
|
4434
|
-
type,
|
|
4435
|
-
fullWidth,
|
|
4436
|
-
size = "md",
|
|
4437
|
-
variant = "outline",
|
|
4438
|
-
className,
|
|
4439
|
-
onValueChange,
|
|
4440
|
-
onChangeAction,
|
|
4441
|
-
imeStrategy = "delayed",
|
|
4442
|
-
value,
|
|
4443
|
-
defaultValue,
|
|
4444
|
-
transformValue,
|
|
4445
|
-
ref,
|
|
4446
|
-
...props
|
|
4447
|
-
}) => {
|
|
4448
|
-
const generatedId = useId();
|
|
4449
|
-
const inputId = id ?? generatedId;
|
|
4450
|
-
const helperId = supportingText ? `${inputId}-help` : void 0;
|
|
4451
|
-
const isControlled = value !== void 0;
|
|
4452
|
-
const applyTransform = (nextValue) => transformValue ? transformValue(nextValue) : nextValue;
|
|
4453
|
-
const [innerValue, setInnerValue] = useState(() => applyTransform(value ?? defaultValue ?? ""));
|
|
4454
|
-
const isComposingRef = useRef(false);
|
|
4455
|
-
const lastEmittedValueRef = useRef(innerValue);
|
|
4456
|
-
const [prevValue, setPrevValue] = useState(value);
|
|
4457
|
-
if (isControlled && value !== prevValue && !isComposingRef.current) {
|
|
4458
|
-
setPrevValue(value);
|
|
4459
|
-
const nextValue = applyTransform(value ?? "");
|
|
4460
|
-
setInnerValue(nextValue);
|
|
4461
|
-
lastEmittedValueRef.current = nextValue;
|
|
4462
|
-
}
|
|
4463
|
-
const emit = useCallback(
|
|
4464
|
-
(nextValue) => {
|
|
4465
|
-
setInnerValue(nextValue);
|
|
4466
|
-
if (nextValue !== lastEmittedValueRef.current) {
|
|
4467
|
-
lastEmittedValueRef.current = nextValue;
|
|
4468
|
-
(onValueChange ?? onChangeAction)?.(nextValue);
|
|
4469
|
-
}
|
|
4470
|
-
},
|
|
4471
|
-
[onValueChange, onChangeAction]
|
|
4472
|
-
);
|
|
4473
|
-
const handleClear = useCallback(() => {
|
|
4474
|
-
emit("");
|
|
4475
|
-
}, [emit]);
|
|
4476
|
-
const [passwordRevealed, setPasswordRevealed] = useState(false);
|
|
4477
|
-
const togglePassword = useCallback(() => {
|
|
4478
|
-
setPasswordRevealed((revealed) => !revealed);
|
|
4479
|
-
}, []);
|
|
4480
|
-
let resolvedType = type;
|
|
4481
|
-
if (showPasswordToggle) {
|
|
4482
|
-
resolvedType = passwordRevealed ? "text" : type ?? "password";
|
|
4483
|
-
}
|
|
4484
|
-
const isError = !!error;
|
|
4485
|
-
const isSuccess = !!success && !isError;
|
|
5622
|
+
el.style.height = `${next}px`;
|
|
5623
|
+
el.style.overflowY = el.scrollHeight > maxH ? "auto" : "hidden";
|
|
5624
|
+
}, [innerValue, autoGrow, size, minRows, maxRows]);
|
|
4486
5625
|
const rootClassName = cn(
|
|
4487
|
-
"
|
|
4488
|
-
|
|
4489
|
-
size === "
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
isSuccess && "text_field_success",
|
|
4494
|
-
props.disabled && "text_field_disabled",
|
|
5626
|
+
"textarea",
|
|
5627
|
+
size === "sm" && "textarea_size_sm",
|
|
5628
|
+
size === "lg" && "textarea_size_lg",
|
|
5629
|
+
fullWidth && "textarea_full_width",
|
|
5630
|
+
error && "textarea_error",
|
|
5631
|
+
props.disabled && "textarea_disabled",
|
|
4495
5632
|
className
|
|
4496
5633
|
);
|
|
4497
|
-
const
|
|
4498
|
-
const
|
|
4499
|
-
|
|
4500
|
-
{
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
"aria-label": passwordToggleLabel,
|
|
4504
|
-
disabled: props.disabled,
|
|
4505
|
-
children: passwordRevealed ? /* @__PURE__ */ jsx(EyeOff, { size: iconSize.lg, "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Eye, { size: iconSize.lg, "aria-hidden": "true" })
|
|
4506
|
-
}
|
|
4507
|
-
) }) : clearable && innerValue ? /* @__PURE__ */ jsx(
|
|
4508
|
-
"button",
|
|
4509
|
-
{
|
|
4510
|
-
type: "button",
|
|
4511
|
-
className: "text_field_clear",
|
|
4512
|
-
onClick: handleClear,
|
|
4513
|
-
"aria-label": clearLabel,
|
|
4514
|
-
disabled: props.disabled,
|
|
4515
|
-
children: /* @__PURE__ */ jsx(ClearIcon, {})
|
|
5634
|
+
const counterText = showCounter && maxLength !== void 0 ? `${innerValue.length}/${maxLength}` : showCounter ? String(innerValue.length) : null;
|
|
5635
|
+
const emit = (nextValue) => {
|
|
5636
|
+
setInnerValue(nextValue);
|
|
5637
|
+
if (nextValue !== lastEmittedValueRef.current) {
|
|
5638
|
+
lastEmittedValueRef.current = nextValue;
|
|
5639
|
+
(onValueChange ?? onChangeAction)?.(nextValue);
|
|
4516
5640
|
}
|
|
4517
|
-
|
|
4518
|
-
const resolvedLeading = leadingAction ? /* @__PURE__ */ jsx("span", { className: "text_field_icon text_field_action", children: leadingAction }) : leadingIcon ? /* @__PURE__ */ jsx("span", { className: "text_field_icon", "aria-hidden": "true", children: leadingIcon }) : null;
|
|
5641
|
+
};
|
|
4519
5642
|
return /* @__PURE__ */ jsxs("div", { className: rootClassName, children: [
|
|
4520
|
-
label && showLabel && /* @__PURE__ */ jsx("label", { htmlFor: inputId, className: "
|
|
4521
|
-
/* @__PURE__ */
|
|
4522
|
-
|
|
4523
|
-
/* @__PURE__ */ jsx(
|
|
4524
|
-
"
|
|
5643
|
+
label && showLabel && /* @__PURE__ */ jsx("label", { htmlFor: inputId, className: "textarea_label", children: label }),
|
|
5644
|
+
/* @__PURE__ */ jsxs("div", { className: "textarea_container", children: [
|
|
5645
|
+
toolbar && /* @__PURE__ */ jsx("div", { className: "textarea_toolbar", inert: props.disabled || void 0, children: toolbar }),
|
|
5646
|
+
/* @__PURE__ */ jsx("div", { className: "textarea_input_wrap", children: /* @__PURE__ */ jsx(
|
|
5647
|
+
"textarea",
|
|
4525
5648
|
{
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
setInnerValue(rawValue);
|
|
4553
|
-
if (imeStrategy === "immediate" && rawValue !== lastEmittedValueRef.current) {
|
|
4554
|
-
lastEmittedValueRef.current = rawValue;
|
|
4555
|
-
(onValueChange ?? onChangeAction)?.(rawValue);
|
|
4556
|
-
}
|
|
4557
|
-
return;
|
|
4558
|
-
}
|
|
4559
|
-
emit(applyTransform(rawValue));
|
|
5649
|
+
id: inputId,
|
|
5650
|
+
ref: setRefs,
|
|
5651
|
+
className: "textarea_input",
|
|
5652
|
+
style: { resize: autoGrow ? "none" : resize },
|
|
5653
|
+
rows: autoGrow ? minRows ?? rows : rows,
|
|
5654
|
+
maxLength,
|
|
5655
|
+
"aria-invalid": !!error || !!field?.invalid,
|
|
5656
|
+
"aria-describedby": describedBy,
|
|
5657
|
+
"aria-required": field?.required || void 0,
|
|
5658
|
+
"aria-label": !showLabel ? label : void 0,
|
|
5659
|
+
...props,
|
|
5660
|
+
value: innerValue,
|
|
5661
|
+
onCompositionStart: () => {
|
|
5662
|
+
isComposingRef.current = true;
|
|
5663
|
+
},
|
|
5664
|
+
onCompositionEnd: (event) => {
|
|
5665
|
+
isComposingRef.current = false;
|
|
5666
|
+
emit(applyTransform(event.currentTarget.value));
|
|
5667
|
+
},
|
|
5668
|
+
onChange: (event) => {
|
|
5669
|
+
const rawValue = event.target.value;
|
|
5670
|
+
if (isComposingRef.current) {
|
|
5671
|
+
setInnerValue(rawValue);
|
|
5672
|
+
if (imeStrategy === "immediate" && rawValue !== lastEmittedValueRef.current) {
|
|
5673
|
+
lastEmittedValueRef.current = rawValue;
|
|
5674
|
+
(onValueChange ?? onChangeAction)?.(rawValue);
|
|
4560
5675
|
}
|
|
5676
|
+
return;
|
|
4561
5677
|
}
|
|
4562
|
-
|
|
5678
|
+
emit(applyTransform(rawValue));
|
|
5679
|
+
}
|
|
4563
5680
|
}
|
|
4564
|
-
)
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
5681
|
+
) })
|
|
5682
|
+
] }),
|
|
5683
|
+
(supportingText || counterText) && /* @__PURE__ */ jsxs("div", { className: "textarea_footer", children: [
|
|
5684
|
+
supportingText ? /* @__PURE__ */ jsx("div", { id: helperId, className: "textarea_helper", children: supportingText }) : /* @__PURE__ */ jsx("span", {}),
|
|
5685
|
+
counterText && /* @__PURE__ */ jsx("div", { className: "textarea_counter", "aria-hidden": "true", children: counterText })
|
|
5686
|
+
] })
|
|
4568
5687
|
] });
|
|
4569
5688
|
};
|
|
4570
|
-
|
|
5689
|
+
Textarea.displayName = "Textarea";
|
|
5690
|
+
var toMinutes = (value) => {
|
|
5691
|
+
if (!value) return null;
|
|
5692
|
+
const [h, m] = value.split(":").map(Number);
|
|
5693
|
+
if (!Number.isInteger(h) || !Number.isInteger(m)) return null;
|
|
5694
|
+
if (h < 0 || h > 23 || m < 0 || m > 59) return null;
|
|
5695
|
+
return h * 60 + m;
|
|
5696
|
+
};
|
|
5697
|
+
var pad2 = (n) => String(n).padStart(2, "0");
|
|
5698
|
+
var TimePicker = ({
|
|
5699
|
+
label,
|
|
5700
|
+
value,
|
|
5701
|
+
onValueChange,
|
|
5702
|
+
minuteStep = 5,
|
|
5703
|
+
minTime,
|
|
5704
|
+
maxTime,
|
|
5705
|
+
disabled,
|
|
5706
|
+
fullWidth = true,
|
|
5707
|
+
hourLabel: hourLabelProp,
|
|
5708
|
+
minuteLabel: minuteLabelProp
|
|
5709
|
+
}) => {
|
|
5710
|
+
const t = useLocaleText();
|
|
5711
|
+
const hourLabel = hourLabelProp ?? t("timePicker.hour");
|
|
5712
|
+
const minuteLabel = minuteLabelProp ?? t("timePicker.minute");
|
|
5713
|
+
const field = useFieldControl();
|
|
5714
|
+
const groupId = React11.useId();
|
|
5715
|
+
const constraintId = React11.useId();
|
|
5716
|
+
const min = toMinutes(minTime) ?? 0;
|
|
5717
|
+
const max = toMinutes(maxTime) ?? 23 * 60 + 59;
|
|
5718
|
+
const parsed = toMinutes(value);
|
|
5719
|
+
const hour = parsed === null ? null : Math.floor(parsed / 60);
|
|
5720
|
+
const minute = parsed === null ? null : parsed % 60;
|
|
5721
|
+
const hourOptions = React11.useMemo(() => {
|
|
5722
|
+
const first = Math.floor(min / 60);
|
|
5723
|
+
const last = Math.floor(max / 60);
|
|
5724
|
+
return Array.from({ length: Math.max(0, last - first + 1) }, (_, i) => {
|
|
5725
|
+
const h = first + i;
|
|
5726
|
+
return { value: String(h), label: pad2(h) };
|
|
5727
|
+
});
|
|
5728
|
+
}, [min, max]);
|
|
5729
|
+
const minuteOptions = React11.useMemo(() => {
|
|
5730
|
+
if (hour === null) return [];
|
|
5731
|
+
const step = Math.max(1, Math.floor(minuteStep));
|
|
5732
|
+
return Array.from({ length: Math.ceil(60 / step) }, (_, i) => i * step).filter((m) => m < 60).filter((m) => hour * 60 + m >= min && hour * 60 + m <= max).map((m) => ({ value: String(m), label: pad2(m) }));
|
|
5733
|
+
}, [hour, minuteStep, min, max]);
|
|
5734
|
+
const emit = (h, m) => onValueChange(`${pad2(h)}:${pad2(m)}`);
|
|
5735
|
+
const handleHourChange = (raw) => {
|
|
5736
|
+
if (!raw) return;
|
|
5737
|
+
const h = Number(raw);
|
|
5738
|
+
const step = Math.max(1, Math.floor(minuteStep));
|
|
5739
|
+
const candidates = Array.from({ length: Math.ceil(60 / step) }, (_, i) => i * step).filter(
|
|
5740
|
+
(m) => m < 60 && h * 60 + m >= min && h * 60 + m <= max
|
|
5741
|
+
);
|
|
5742
|
+
if (candidates.length === 0) return;
|
|
5743
|
+
const keep = minute !== null && candidates.includes(minute) ? minute : candidates[0];
|
|
5744
|
+
emit(h, keep);
|
|
5745
|
+
};
|
|
5746
|
+
const handleMinuteChange = (raw) => {
|
|
5747
|
+
if (!raw || hour === null) return;
|
|
5748
|
+
emit(hour, Number(raw));
|
|
5749
|
+
};
|
|
5750
|
+
const constraint = minTime || maxTime ? t("timePicker.rangeSr", { min: minTime ?? "00:00", max: maxTime ?? "23:59" }) : "";
|
|
5751
|
+
return /* @__PURE__ */ jsxs(
|
|
5752
|
+
"div",
|
|
5753
|
+
{
|
|
5754
|
+
className: cn("time_picker", {
|
|
5755
|
+
time_picker_full_width: fullWidth,
|
|
5756
|
+
time_picker_disabled: disabled
|
|
5757
|
+
}),
|
|
5758
|
+
children: [
|
|
5759
|
+
label && /* @__PURE__ */ jsx("span", { className: "time_picker_label", id: groupId, children: label }),
|
|
5760
|
+
constraint && /* @__PURE__ */ jsx("span", { id: constraintId, className: "time_picker_sr_only", children: constraint }),
|
|
5761
|
+
/* @__PURE__ */ jsxs(
|
|
5762
|
+
"div",
|
|
5763
|
+
{
|
|
5764
|
+
className: "time_picker_fields",
|
|
5765
|
+
role: "group",
|
|
5766
|
+
"aria-labelledby": field?.labelId ?? (label ? groupId : void 0),
|
|
5767
|
+
"aria-describedby": [field?.describedBy, constraint ? constraintId : void 0].filter(Boolean).join(" ") || void 0,
|
|
5768
|
+
"aria-invalid": field?.invalid || void 0,
|
|
5769
|
+
children: [
|
|
5770
|
+
/* @__PURE__ */ jsx(
|
|
5771
|
+
Dropdown,
|
|
5772
|
+
{
|
|
5773
|
+
size: "sm",
|
|
5774
|
+
fullWidth: true,
|
|
5775
|
+
label: hourLabel,
|
|
5776
|
+
placeholder: hourLabel,
|
|
5777
|
+
options: hourOptions,
|
|
5778
|
+
value: hour === null ? null : String(hour),
|
|
5779
|
+
onValueChange: handleHourChange,
|
|
5780
|
+
disabled
|
|
5781
|
+
}
|
|
5782
|
+
),
|
|
5783
|
+
/* @__PURE__ */ jsx(
|
|
5784
|
+
Dropdown,
|
|
5785
|
+
{
|
|
5786
|
+
size: "sm",
|
|
5787
|
+
fullWidth: true,
|
|
5788
|
+
label: minuteLabel,
|
|
5789
|
+
placeholder: minuteLabel,
|
|
5790
|
+
options: minuteOptions,
|
|
5791
|
+
value: minute === null ? null : String(minute),
|
|
5792
|
+
onValueChange: handleMinuteChange,
|
|
5793
|
+
disabled: disabled || hour === null
|
|
5794
|
+
}
|
|
5795
|
+
)
|
|
5796
|
+
]
|
|
5797
|
+
}
|
|
5798
|
+
)
|
|
5799
|
+
]
|
|
5800
|
+
}
|
|
5801
|
+
);
|
|
5802
|
+
};
|
|
4571
5803
|
var Toggle = ({
|
|
4572
5804
|
checked,
|
|
4573
5805
|
defaultChecked,
|
|
@@ -4590,6 +5822,7 @@ var Toggle = ({
|
|
|
4590
5822
|
if (!isControlled) setInnerChecked(next);
|
|
4591
5823
|
(onCheckedChange ?? onChange)?.(next);
|
|
4592
5824
|
};
|
|
5825
|
+
const field = useFieldControl();
|
|
4593
5826
|
const rootClassName = cn(
|
|
4594
5827
|
"toggle",
|
|
4595
5828
|
`toggle_size_${size}`,
|
|
@@ -4604,7 +5837,10 @@ var Toggle = ({
|
|
|
4604
5837
|
type: "button",
|
|
4605
5838
|
role: "switch",
|
|
4606
5839
|
"aria-checked": isOn,
|
|
4607
|
-
|
|
5840
|
+
id: field?.inputId ?? props.id,
|
|
5841
|
+
"aria-describedby": field?.describedBy ?? props["aria-describedby"],
|
|
5842
|
+
"aria-labelledby": field?.labelId,
|
|
5843
|
+
"aria-label": field?.labelId ? void 0 : ariaLabel,
|
|
4608
5844
|
disabled,
|
|
4609
5845
|
onClick: handleToggle,
|
|
4610
5846
|
className: rootClassName,
|
|
@@ -4630,92 +5866,6 @@ var IconButton = ({
|
|
|
4630
5866
|
);
|
|
4631
5867
|
return /* @__PURE__ */ jsx("button", { ref, type, className: buttonClassName, ...props, children: /* @__PURE__ */ jsx("span", { className: "icon_button_icon", "aria-hidden": "true", children: icon }) });
|
|
4632
5868
|
};
|
|
4633
|
-
var range2 = (start, end) => {
|
|
4634
|
-
const out = [];
|
|
4635
|
-
for (let i = start; i <= end; i += 1) out.push(i);
|
|
4636
|
-
return out;
|
|
4637
|
-
};
|
|
4638
|
-
var getPaginationItems = (page, totalPages) => {
|
|
4639
|
-
if (totalPages <= 7) return range2(1, totalPages);
|
|
4640
|
-
const items = [];
|
|
4641
|
-
const last = totalPages;
|
|
4642
|
-
const sibling = 2;
|
|
4643
|
-
if (page <= sibling + 2) {
|
|
4644
|
-
for (const p of range2(1, sibling + 3)) items.push(p);
|
|
4645
|
-
items.push("ellipsis");
|
|
4646
|
-
items.push(last);
|
|
4647
|
-
return items;
|
|
4648
|
-
}
|
|
4649
|
-
if (page >= last - sibling - 1) {
|
|
4650
|
-
items.push(1);
|
|
4651
|
-
items.push("ellipsis");
|
|
4652
|
-
for (const p of range2(last - sibling - 2, last)) items.push(p);
|
|
4653
|
-
return items;
|
|
4654
|
-
}
|
|
4655
|
-
items.push(1);
|
|
4656
|
-
items.push("ellipsis");
|
|
4657
|
-
for (const p of range2(page - sibling, page + sibling)) items.push(p);
|
|
4658
|
-
items.push("ellipsis");
|
|
4659
|
-
items.push(last);
|
|
4660
|
-
return items;
|
|
4661
|
-
};
|
|
4662
|
-
var Pagination = ({
|
|
4663
|
-
page,
|
|
4664
|
-
totalPages,
|
|
4665
|
-
onPageChange,
|
|
4666
|
-
onChange,
|
|
4667
|
-
prevLabel = "\uC774\uC804 \uD398\uC774\uC9C0",
|
|
4668
|
-
nextLabel = "\uB2E4\uC74C \uD398\uC774\uC9C0",
|
|
4669
|
-
navLabel = "\uD398\uC774\uC9C0 \uC774\uB3D9"
|
|
4670
|
-
}) => {
|
|
4671
|
-
const emit = onPageChange ?? onChange;
|
|
4672
|
-
const prevDisabled = page <= 1;
|
|
4673
|
-
const nextDisabled = page >= totalPages;
|
|
4674
|
-
const items = React11.useMemo(() => getPaginationItems(page, totalPages), [page, totalPages]);
|
|
4675
|
-
return /* @__PURE__ */ jsxs("nav", { className: "pagination", "aria-label": navLabel, children: [
|
|
4676
|
-
/* @__PURE__ */ jsx(
|
|
4677
|
-
"button",
|
|
4678
|
-
{
|
|
4679
|
-
type: "button",
|
|
4680
|
-
className: "pagination_item",
|
|
4681
|
-
onClick: () => emit?.(page - 1),
|
|
4682
|
-
disabled: prevDisabled,
|
|
4683
|
-
"aria-label": prevLabel,
|
|
4684
|
-
children: "\u2039"
|
|
4685
|
-
}
|
|
4686
|
-
),
|
|
4687
|
-
/* @__PURE__ */ jsx("ul", { className: "pagination_pages", children: items.map((it, idx) => {
|
|
4688
|
-
if (it === "ellipsis") {
|
|
4689
|
-
const prev = items[idx - 1];
|
|
4690
|
-
const next = items[idx + 1];
|
|
4691
|
-
return /* @__PURE__ */ jsx("li", { className: "pagination_ellipsis", "aria-hidden": "true", children: "\u2026" }, `e-${prev}-${next}`);
|
|
4692
|
-
}
|
|
4693
|
-
const isActive = it === page;
|
|
4694
|
-
const buttonClassName = cn("pagination_page_button", { pagination_active: isActive });
|
|
4695
|
-
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
4696
|
-
"button",
|
|
4697
|
-
{
|
|
4698
|
-
type: "button",
|
|
4699
|
-
className: buttonClassName,
|
|
4700
|
-
onClick: () => emit?.(it),
|
|
4701
|
-
"aria-current": isActive ? "page" : void 0,
|
|
4702
|
-
children: it
|
|
4703
|
-
}
|
|
4704
|
-
) }, it);
|
|
4705
|
-
}) }),
|
|
4706
|
-
/* @__PURE__ */ jsx(
|
|
4707
|
-
"button",
|
|
4708
|
-
{
|
|
4709
|
-
type: "button",
|
|
4710
|
-
className: "pagination_item",
|
|
4711
|
-
onClick: () => emit?.(page + 1),
|
|
4712
|
-
disabled: nextDisabled,
|
|
4713
|
-
"aria-label": nextLabel,
|
|
4714
|
-
children: "\u203A"
|
|
4715
|
-
}
|
|
4716
|
-
)
|
|
4717
|
-
] });
|
|
4718
|
-
};
|
|
4719
5869
|
var SLIDE_FROM = {
|
|
4720
5870
|
left: "translateX(-100%)",
|
|
4721
5871
|
right: "translateX(100%)",
|
|
@@ -4731,13 +5881,15 @@ var Drawer = ({
|
|
|
4731
5881
|
closeOnOverlay = true,
|
|
4732
5882
|
dismissible,
|
|
4733
5883
|
showCloseIcon = true,
|
|
4734
|
-
closeLabel
|
|
5884
|
+
closeLabel: closeLabelProp,
|
|
4735
5885
|
ariaLabel,
|
|
4736
5886
|
onExited,
|
|
4737
5887
|
children,
|
|
4738
5888
|
className,
|
|
4739
5889
|
...props
|
|
4740
5890
|
}) => {
|
|
5891
|
+
const t = useLocaleText();
|
|
5892
|
+
const closeLabel = closeLabelProp ?? t("drawer.close");
|
|
4741
5893
|
const lastContentRef = React11.useRef({ children, title, footer });
|
|
4742
5894
|
if (open) lastContentRef.current = { children, title, footer };
|
|
4743
5895
|
const content = open ? { children, title, footer } : lastContentRef.current;
|
|
@@ -4837,13 +5989,15 @@ var Modal = ({
|
|
|
4837
5989
|
footer,
|
|
4838
5990
|
footerAlign = "end",
|
|
4839
5991
|
showCloseIcon = true,
|
|
4840
|
-
closeLabel
|
|
5992
|
+
closeLabel: closeLabelProp,
|
|
4841
5993
|
children,
|
|
4842
5994
|
className,
|
|
4843
5995
|
ariaLabel,
|
|
4844
5996
|
onExited,
|
|
4845
5997
|
...props
|
|
4846
5998
|
}) => {
|
|
5999
|
+
const t = useLocaleText();
|
|
6000
|
+
const closeLabel = closeLabelProp ?? t("modal.close");
|
|
4847
6001
|
const lastContentRef = React11.useRef({ children, title, description, footer });
|
|
4848
6002
|
if (open) lastContentRef.current = { children, title, description, footer };
|
|
4849
6003
|
const content = open ? { children, title, description, footer } : lastContentRef.current;
|
|
@@ -5010,15 +6164,39 @@ var ThemeProvider = ({
|
|
|
5010
6164
|
);
|
|
5011
6165
|
return /* @__PURE__ */ jsx(ThemeContext.Provider, { value, children });
|
|
5012
6166
|
};
|
|
6167
|
+
var AppShell = ({
|
|
6168
|
+
sidebar,
|
|
6169
|
+
header,
|
|
6170
|
+
padded = true,
|
|
6171
|
+
className,
|
|
6172
|
+
children,
|
|
6173
|
+
ref,
|
|
6174
|
+
...props
|
|
6175
|
+
}) => /* @__PURE__ */ jsxs(
|
|
6176
|
+
"div",
|
|
6177
|
+
{
|
|
6178
|
+
ref,
|
|
6179
|
+
className: cn("app_shell", { app_shell_with_sidebar: !!sidebar }, className),
|
|
6180
|
+
...props,
|
|
6181
|
+
children: [
|
|
6182
|
+
sidebar && /* @__PURE__ */ jsx("div", { className: "app_shell_sidebar", children: sidebar }),
|
|
6183
|
+
/* @__PURE__ */ jsxs("div", { className: "app_shell_body", children: [
|
|
6184
|
+
header && /* @__PURE__ */ jsx("div", { className: "app_shell_header", children: header }),
|
|
6185
|
+
/* @__PURE__ */ jsx("main", { className: cn("app_shell_main", { app_shell_main_padded: padded }), children })
|
|
6186
|
+
] })
|
|
6187
|
+
]
|
|
6188
|
+
}
|
|
6189
|
+
);
|
|
5013
6190
|
var Container = ({
|
|
5014
6191
|
size = "xl",
|
|
5015
6192
|
center = true,
|
|
5016
|
-
as
|
|
6193
|
+
as,
|
|
5017
6194
|
ref,
|
|
5018
6195
|
className,
|
|
5019
6196
|
children,
|
|
5020
6197
|
...props
|
|
5021
6198
|
}) => {
|
|
6199
|
+
const Tag = as ?? "div";
|
|
5022
6200
|
return /* @__PURE__ */ jsx(
|
|
5023
6201
|
Tag,
|
|
5024
6202
|
{
|
|
@@ -5036,7 +6214,7 @@ var Grid = ({
|
|
|
5036
6214
|
rowGap,
|
|
5037
6215
|
colGap,
|
|
5038
6216
|
singleColOnMobile = true,
|
|
5039
|
-
as
|
|
6217
|
+
as,
|
|
5040
6218
|
ref,
|
|
5041
6219
|
className,
|
|
5042
6220
|
children,
|
|
@@ -5044,6 +6222,7 @@ var Grid = ({
|
|
|
5044
6222
|
...props
|
|
5045
6223
|
}) => {
|
|
5046
6224
|
const gridTemplateColumns = cols === "auto" ? `repeat(auto-fill, minmax(${minColWidth}, 1fr))` : `repeat(${cols}, 1fr)`;
|
|
6225
|
+
const Tag = as ?? "div";
|
|
5047
6226
|
return /* @__PURE__ */ jsx(
|
|
5048
6227
|
Tag,
|
|
5049
6228
|
{
|
|
@@ -5061,15 +6240,36 @@ var Grid = ({
|
|
|
5061
6240
|
}
|
|
5062
6241
|
);
|
|
5063
6242
|
};
|
|
6243
|
+
var PageHeader = ({
|
|
6244
|
+
title,
|
|
6245
|
+
description,
|
|
6246
|
+
breadcrumb,
|
|
6247
|
+
actions,
|
|
6248
|
+
tabs,
|
|
6249
|
+
className,
|
|
6250
|
+
ref,
|
|
6251
|
+
...props
|
|
6252
|
+
}) => /* @__PURE__ */ jsxs("div", { ref, className: cn("page_header", className), ...props, children: [
|
|
6253
|
+
breadcrumb && /* @__PURE__ */ jsx("div", { className: "page_header_breadcrumb", children: breadcrumb }),
|
|
6254
|
+
/* @__PURE__ */ jsxs("div", { className: "page_header_bar", children: [
|
|
6255
|
+
/* @__PURE__ */ jsxs("div", { className: "page_header_titles", children: [
|
|
6256
|
+
/* @__PURE__ */ jsx("h1", { className: "page_header_title", children: title }),
|
|
6257
|
+
description && /* @__PURE__ */ jsx("p", { className: "page_header_description", children: description })
|
|
6258
|
+
] }),
|
|
6259
|
+
actions && /* @__PURE__ */ jsx("div", { className: "page_header_actions", children: actions })
|
|
6260
|
+
] }),
|
|
6261
|
+
tabs && /* @__PURE__ */ jsx("div", { className: "page_header_tabs", children: tabs })
|
|
6262
|
+
] });
|
|
5064
6263
|
var Section = ({
|
|
5065
6264
|
spacing: spacing2 = "md",
|
|
5066
6265
|
bg = "default",
|
|
5067
|
-
as
|
|
6266
|
+
as,
|
|
5068
6267
|
ref,
|
|
5069
6268
|
className,
|
|
5070
6269
|
children,
|
|
5071
6270
|
...props
|
|
5072
6271
|
}) => {
|
|
6272
|
+
const Tag = as ?? "section";
|
|
5073
6273
|
return /* @__PURE__ */ jsx(
|
|
5074
6274
|
Tag,
|
|
5075
6275
|
{
|
|
@@ -5086,13 +6286,14 @@ var Stack = ({
|
|
|
5086
6286
|
align,
|
|
5087
6287
|
justify,
|
|
5088
6288
|
wrap,
|
|
5089
|
-
as
|
|
6289
|
+
as,
|
|
5090
6290
|
ref,
|
|
5091
6291
|
className,
|
|
5092
6292
|
children,
|
|
5093
6293
|
style,
|
|
5094
6294
|
...props
|
|
5095
6295
|
}) => {
|
|
6296
|
+
const Tag = as ?? "div";
|
|
5096
6297
|
return /* @__PURE__ */ jsx(
|
|
5097
6298
|
Tag,
|
|
5098
6299
|
{
|
|
@@ -5112,4 +6313,4 @@ var Stack = ({
|
|
|
5112
6313
|
);
|
|
5113
6314
|
};
|
|
5114
6315
|
|
|
5115
|
-
export { Accordion, AlertProvider, Avatar, Badge, BottomNav, BottomNavItem, BottomNavSpacer, Breadcrumb, Button, Card, Checkbox, Chip, Container, DatePicker, Divider, Drawer, Dropdown, EmptyState, ErrorState, FileInput, Grid, Hero, Icon, IconButton, ImageCropper, LinearProgress, ListItem, MediaCard, Menu, Modal, NavBar, NavLink, OtpInput, Pagination, Popover, Prose, Radio, RadioGroup, Section, Sidebar, SidebarItem, SidebarSection, Skeleton, Spinner, Stack, Tab, TabList, TabPanel, Table, Tabs, TextField, Textarea, ThemeProvider, ToastProvider, Toggle, Tooltip, TopLoading, a11y, baseBorderWidth, baseColors, baseTypography, borderWidth, breakpoints, cn, colors, elevation, iconSize, motion, opacity, radius, skeleton, spacing, typography, useAlert, useFocusTrap, useRadioGroupContext, useReducedMotion, useSpringHover, useSpringPresence, useTheme, useToast, zIndex };
|
|
6316
|
+
export { Accordion, AlertProvider, AppShell, Avatar, Badge, BottomNav, BottomNavItem, BottomNavSpacer, Breadcrumb, Button, Card, Checkbox, Chip, Combobox, Container, DataView, DatePicker, DateRangePicker, DescriptionList, Divider, Drawer, Dropdown, EmptyState, ErrorState, Field, FileInput, Form, Grid, Hero, Icon, IconButton, ImageCropper, LinearProgress, ListItem, LocaleProvider, MediaCard, Menu, Modal, NavBar, NavLink, OtpInput, PageHeader, Pagination, Popover, Prose, Radio, RadioGroup, Section, Sidebar, SidebarItem, SidebarSection, Skeleton, Spinner, Stack, Stat, Tab, TabList, TabPanel, Table, Tabs, TagInput, TextField, Textarea, ThemeProvider, TimePicker, Timeline, ToastProvider, Toggle, Tooltip, TopLoading, a11y, baseBorderWidth, baseColors, baseTypography, borderWidth, breakpoints, catalogs, cn, colors, elevation, en, iconSize, ko, motion, opacity, radius, skeleton, spacing, typography, useAlert, useFieldControl, useFocusTrap, useListboxPopup, useLocaleName, useLocaleText, useRadioGroupContext, useReducedMotion, useSpringHover, useSpringPresence, useTheme, useToast, zIndex };
|