@bigtablet/design-system 2.4.0 → 2.4.2
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 +141 -141
- package/dist/index.d.ts +69 -69
- package/dist/index.js +439 -413
- package/package.json +24 -23
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import './index.css';
|
|
3
|
-
import * as
|
|
3
|
+
import * as React4 from 'react';
|
|
4
4
|
import { createContext, useContext, useState, useCallback } from 'react';
|
|
5
5
|
import { createPortal } from 'react-dom';
|
|
6
6
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
@@ -107,6 +107,15 @@ var colors = {
|
|
|
107
107
|
}
|
|
108
108
|
};
|
|
109
109
|
|
|
110
|
+
// src/styles/elevation/index.ts
|
|
111
|
+
var elevation = {
|
|
112
|
+
level1: "0 1px 1px -1px rgba(0, 0, 0, 0.20), 0 3px 3px 0px rgba(0, 0, 0, 0.12)",
|
|
113
|
+
level2: "0 2px 2px -2px rgba(0, 0, 0, 0.20), 0 6px 6px 0px rgba(0, 0, 0, 0.12)",
|
|
114
|
+
level3: "0 3px 3px -3px rgba(0, 0, 0, 0.20), 0 9px 9px 0px rgba(0, 0, 0, 0.12)",
|
|
115
|
+
level4: "0 5px 5px -5px rgba(0, 0, 0, 0.20), 0 15px 15px 0px rgba(0, 0, 0, 0.12)",
|
|
116
|
+
level5: "0 8px 10px -5px rgba(0, 0, 0, 0.20), 0 20px 20px 0px rgba(0, 0, 0, 0.12)"
|
|
117
|
+
};
|
|
118
|
+
|
|
110
119
|
// src/styles/motion/index.ts
|
|
111
120
|
var motion = {
|
|
112
121
|
transition: {
|
|
@@ -147,15 +156,6 @@ var radius = {
|
|
|
147
156
|
full: "9999px"
|
|
148
157
|
};
|
|
149
158
|
|
|
150
|
-
// src/styles/elevation/index.ts
|
|
151
|
-
var elevation = {
|
|
152
|
-
level1: "0 1px 1px -1px rgba(0, 0, 0, 0.20), 0 3px 3px 0px rgba(0, 0, 0, 0.12)",
|
|
153
|
-
level2: "0 2px 2px -2px rgba(0, 0, 0, 0.20), 0 6px 6px 0px rgba(0, 0, 0, 0.12)",
|
|
154
|
-
level3: "0 3px 3px -3px rgba(0, 0, 0, 0.20), 0 9px 9px 0px rgba(0, 0, 0, 0.12)",
|
|
155
|
-
level4: "0 5px 5px -5px rgba(0, 0, 0, 0.20), 0 15px 15px 0px rgba(0, 0, 0, 0.12)",
|
|
156
|
-
level5: "0 8px 10px -5px rgba(0, 0, 0, 0.20), 0 20px 20px 0px rgba(0, 0, 0, 0.12)"
|
|
157
|
-
};
|
|
158
|
-
|
|
159
159
|
// src/styles/spacing/index.ts
|
|
160
160
|
var spacing = {
|
|
161
161
|
"0": "0px",
|
|
@@ -485,8 +485,8 @@ var FOCUSABLE_SELECTORS = [
|
|
|
485
485
|
'[tabindex]:not([tabindex="-1"])'
|
|
486
486
|
].join(", ");
|
|
487
487
|
function useFocusTrap(containerRef, isActive) {
|
|
488
|
-
const previousActiveElement =
|
|
489
|
-
|
|
488
|
+
const previousActiveElement = React4.useRef(null);
|
|
489
|
+
React4.useEffect(() => {
|
|
490
490
|
if (!isActive) return;
|
|
491
491
|
const container = containerRef.current;
|
|
492
492
|
if (!container) return;
|
|
@@ -591,43 +591,46 @@ var AlertModal = ({
|
|
|
591
591
|
onCancel,
|
|
592
592
|
onClose
|
|
593
593
|
}) => {
|
|
594
|
-
const panelRef =
|
|
595
|
-
const titleId =
|
|
596
|
-
const messageId =
|
|
594
|
+
const panelRef = React4.useRef(null);
|
|
595
|
+
const titleId = React4.useId();
|
|
596
|
+
const messageId = React4.useId();
|
|
597
597
|
useFocusTrap(panelRef, true);
|
|
598
598
|
const modalClassName = cn("alert_modal", `alert_variant_${variant}`);
|
|
599
599
|
const actionsClassName = cn("alert_actions", `alert_actions_${actionsAlign}`);
|
|
600
|
-
return
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
"
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
/* @__PURE__ */
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
600
|
+
return (
|
|
601
|
+
// biome-ignore lint/a11y/noStaticElementInteractions: modal overlay pattern — clickable backdrop without role=button (focus is trapped on the panel inside)
|
|
602
|
+
/* @__PURE__ */ jsx(
|
|
603
|
+
"div",
|
|
604
|
+
{
|
|
605
|
+
className: "alert_overlay",
|
|
606
|
+
role: "presentation",
|
|
607
|
+
onClick: onClose,
|
|
608
|
+
onKeyDown: (e) => e.key === "Escape" && onClose(),
|
|
609
|
+
children: /* @__PURE__ */ jsxs(
|
|
610
|
+
"div",
|
|
611
|
+
{
|
|
612
|
+
ref: panelRef,
|
|
613
|
+
className: modalClassName,
|
|
614
|
+
onClick: (e) => e.stopPropagation(),
|
|
615
|
+
onKeyDown: (e) => {
|
|
616
|
+
if (e.key !== "Escape") e.stopPropagation();
|
|
617
|
+
},
|
|
618
|
+
role: "alertdialog",
|
|
619
|
+
"aria-modal": "true",
|
|
620
|
+
"aria-labelledby": titleId,
|
|
621
|
+
"aria-describedby": messageId,
|
|
622
|
+
children: [
|
|
623
|
+
title && /* @__PURE__ */ jsx("div", { className: "alert_title", id: titleId, children: title }),
|
|
624
|
+
message && /* @__PURE__ */ jsx("div", { className: "alert_message", id: messageId, children: message }),
|
|
625
|
+
/* @__PURE__ */ jsxs("div", { className: actionsClassName, children: [
|
|
626
|
+
showCancel && /* @__PURE__ */ jsx("button", { type: "button", className: "alert_button alert_button_cancel", onClick: onCancel, children: cancelText }),
|
|
627
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "alert_button alert_button_confirm", onClick: onConfirm, children: confirmText })
|
|
628
|
+
] })
|
|
629
|
+
]
|
|
630
|
+
}
|
|
631
|
+
)
|
|
632
|
+
}
|
|
633
|
+
)
|
|
631
634
|
);
|
|
632
635
|
};
|
|
633
636
|
var Button = ({
|
|
@@ -685,12 +688,12 @@ var Checkbox = ({
|
|
|
685
688
|
ref,
|
|
686
689
|
...props
|
|
687
690
|
}) => {
|
|
688
|
-
const inputRef =
|
|
689
|
-
|
|
691
|
+
const inputRef = React4.useRef(null);
|
|
692
|
+
React4.useImperativeHandle(
|
|
690
693
|
ref,
|
|
691
694
|
() => inputRef.current
|
|
692
695
|
);
|
|
693
|
-
|
|
696
|
+
React4.useEffect(() => {
|
|
694
697
|
if (!inputRef.current) return;
|
|
695
698
|
inputRef.current.indeterminate = Boolean(indeterminate);
|
|
696
699
|
}, [indeterminate]);
|
|
@@ -701,26 +704,57 @@ var Checkbox = ({
|
|
|
701
704
|
className
|
|
702
705
|
);
|
|
703
706
|
return /* @__PURE__ */ jsxs("label", { className: rootClassName, children: [
|
|
704
|
-
/* @__PURE__ */ jsx(
|
|
705
|
-
"input",
|
|
706
|
-
{
|
|
707
|
-
ref: inputRef,
|
|
708
|
-
type: "checkbox",
|
|
709
|
-
className: "checkbox_input",
|
|
710
|
-
...props
|
|
711
|
-
}
|
|
712
|
-
),
|
|
707
|
+
/* @__PURE__ */ jsx("input", { ref: inputRef, type: "checkbox", className: "checkbox_input", ...props }),
|
|
713
708
|
/* @__PURE__ */ jsx("span", { className: "checkbox_state_layer", "aria-hidden": "true", children: /* @__PURE__ */ jsx("span", { className: "checkbox_icon" }) }),
|
|
714
709
|
label ? /* @__PURE__ */ jsx("span", { className: "checkbox_label", children: label }) : null
|
|
715
710
|
] });
|
|
716
711
|
};
|
|
717
712
|
Checkbox.displayName = "Checkbox";
|
|
718
|
-
var CheckIcon = () => /* @__PURE__ */ jsx(
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
713
|
+
var CheckIcon = () => /* @__PURE__ */ jsx(
|
|
714
|
+
"svg",
|
|
715
|
+
{
|
|
716
|
+
viewBox: "0 0 20 20",
|
|
717
|
+
fill: "none",
|
|
718
|
+
stroke: "currentColor",
|
|
719
|
+
strokeWidth: 2,
|
|
720
|
+
strokeLinecap: "round",
|
|
721
|
+
strokeLinejoin: "round",
|
|
722
|
+
"aria-hidden": "true",
|
|
723
|
+
focusable: "false",
|
|
724
|
+
children: /* @__PURE__ */ jsx("polyline", { points: "4 10 8 14 16 6" })
|
|
725
|
+
}
|
|
726
|
+
);
|
|
727
|
+
var CloseIcon = () => /* @__PURE__ */ jsxs(
|
|
728
|
+
"svg",
|
|
729
|
+
{
|
|
730
|
+
viewBox: "0 0 20 20",
|
|
731
|
+
fill: "none",
|
|
732
|
+
stroke: "currentColor",
|
|
733
|
+
strokeWidth: 2,
|
|
734
|
+
strokeLinecap: "round",
|
|
735
|
+
strokeLinejoin: "round",
|
|
736
|
+
"aria-hidden": "true",
|
|
737
|
+
focusable: "false",
|
|
738
|
+
children: [
|
|
739
|
+
/* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "14", y2: "14" }),
|
|
740
|
+
/* @__PURE__ */ jsx("line", { x1: "14", y1: "6", x2: "6", y2: "14" })
|
|
741
|
+
]
|
|
742
|
+
}
|
|
743
|
+
);
|
|
744
|
+
var ChevronDownIcon = () => /* @__PURE__ */ jsx(
|
|
745
|
+
"svg",
|
|
746
|
+
{
|
|
747
|
+
viewBox: "0 0 20 20",
|
|
748
|
+
fill: "none",
|
|
749
|
+
stroke: "currentColor",
|
|
750
|
+
strokeWidth: 2,
|
|
751
|
+
strokeLinecap: "round",
|
|
752
|
+
strokeLinejoin: "round",
|
|
753
|
+
"aria-hidden": "true",
|
|
754
|
+
focusable: "false",
|
|
755
|
+
children: /* @__PURE__ */ jsx("polyline", { points: "5 8 10 13 15 8" })
|
|
756
|
+
}
|
|
757
|
+
);
|
|
724
758
|
var Chip = ({
|
|
725
759
|
type = "basic",
|
|
726
760
|
label,
|
|
@@ -818,22 +852,22 @@ var Dropdown = ({
|
|
|
818
852
|
fullWidth,
|
|
819
853
|
className
|
|
820
854
|
}) => {
|
|
821
|
-
const internalId =
|
|
855
|
+
const internalId = React4.useId();
|
|
822
856
|
const dropdownId = id ?? internalId;
|
|
823
857
|
const isControlled = value !== void 0;
|
|
824
|
-
const [internalValue, setInternalValue] =
|
|
858
|
+
const [internalValue, setInternalValue] = React4.useState(defaultValue);
|
|
825
859
|
const currentValue = isControlled ? value ?? null : internalValue;
|
|
826
|
-
const [isOpen, setIsOpen] =
|
|
827
|
-
const [activeIndex, setActiveIndex] =
|
|
828
|
-
const [dropUp, setDropUp] =
|
|
829
|
-
const wrapperRef =
|
|
830
|
-
const controlRef =
|
|
831
|
-
const currentOption =
|
|
860
|
+
const [isOpen, setIsOpen] = React4.useState(false);
|
|
861
|
+
const [activeIndex, setActiveIndex] = React4.useState(-1);
|
|
862
|
+
const [dropUp, setDropUp] = React4.useState(false);
|
|
863
|
+
const wrapperRef = React4.useRef(null);
|
|
864
|
+
const controlRef = React4.useRef(null);
|
|
865
|
+
const currentOption = React4.useMemo(
|
|
832
866
|
() => options.find((o) => o.value === currentValue) ?? null,
|
|
833
867
|
[options, currentValue]
|
|
834
868
|
);
|
|
835
869
|
const isLabelVisible = isOpen || !!currentOption;
|
|
836
|
-
const setValue =
|
|
870
|
+
const setValue = React4.useCallback(
|
|
837
871
|
(next) => {
|
|
838
872
|
const option = options.find((o) => o.value === next) ?? null;
|
|
839
873
|
if (!isControlled) setInternalValue(next);
|
|
@@ -841,7 +875,7 @@ var Dropdown = ({
|
|
|
841
875
|
},
|
|
842
876
|
[isControlled, onChange, options]
|
|
843
877
|
);
|
|
844
|
-
|
|
878
|
+
React4.useEffect(() => {
|
|
845
879
|
const handleOutsideClick = (e) => {
|
|
846
880
|
if (!wrapperRef.current?.contains(e.target)) {
|
|
847
881
|
setIsOpen(false);
|
|
@@ -912,14 +946,17 @@ var Dropdown = ({
|
|
|
912
946
|
break;
|
|
913
947
|
}
|
|
914
948
|
};
|
|
915
|
-
|
|
949
|
+
React4.useEffect(() => {
|
|
916
950
|
if (!isOpen) return;
|
|
917
951
|
const idx = options.findIndex((o) => o.value === currentValue && !o.disabled);
|
|
918
952
|
setActiveIndex(
|
|
919
|
-
idx >= 0 ? idx : Math.max(
|
|
953
|
+
idx >= 0 ? idx : Math.max(
|
|
954
|
+
0,
|
|
955
|
+
options.findIndex((o) => !o.disabled)
|
|
956
|
+
)
|
|
920
957
|
);
|
|
921
958
|
}, [isOpen, options, currentValue]);
|
|
922
|
-
|
|
959
|
+
React4.useLayoutEffect(() => {
|
|
923
960
|
if (!isOpen || !controlRef.current) return;
|
|
924
961
|
const rect = controlRef.current.getBoundingClientRect();
|
|
925
962
|
const listHeight = Math.min(options.length * 56, 288);
|
|
@@ -938,14 +975,7 @@ var Dropdown = ({
|
|
|
938
975
|
style: fullWidth ? { width: "100%" } : void 0,
|
|
939
976
|
children: [
|
|
940
977
|
/* @__PURE__ */ jsxs("div", { className: fieldsetClassName, children: [
|
|
941
|
-
label && /* @__PURE__ */ jsx(
|
|
942
|
-
"span",
|
|
943
|
-
{
|
|
944
|
-
className: cn("dropdown_label", { is_visible: isLabelVisible }),
|
|
945
|
-
"aria-hidden": "true",
|
|
946
|
-
children: label
|
|
947
|
-
}
|
|
948
|
-
),
|
|
978
|
+
label && /* @__PURE__ */ jsx("span", { className: cn("dropdown_label", { is_visible: isLabelVisible }), "aria-hidden": "true", children: label }),
|
|
949
979
|
/* @__PURE__ */ jsxs(
|
|
950
980
|
"button",
|
|
951
981
|
{
|
|
@@ -967,49 +997,41 @@ var Dropdown = ({
|
|
|
967
997
|
}
|
|
968
998
|
)
|
|
969
999
|
] }),
|
|
970
|
-
isOpen && /* @__PURE__ */ jsx(
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
]
|
|
1006
|
-
}
|
|
1007
|
-
),
|
|
1008
|
-
opt.showDivider && /* @__PURE__ */ jsx("div", { className: "dropdown_option_divider", role: "separator" })
|
|
1009
|
-
] }, opt.value);
|
|
1010
|
-
})
|
|
1011
|
-
}
|
|
1012
|
-
)
|
|
1000
|
+
isOpen && /* @__PURE__ */ jsx("div", { id: `${dropdownId}_listbox`, role: "listbox", className: listClassName, children: options.map((opt, i) => {
|
|
1001
|
+
const selected = currentValue === opt.value;
|
|
1002
|
+
const active = i === activeIndex;
|
|
1003
|
+
return /* @__PURE__ */ jsxs(React4.Fragment, { children: [
|
|
1004
|
+
/* @__PURE__ */ jsxs(
|
|
1005
|
+
"div",
|
|
1006
|
+
{
|
|
1007
|
+
role: "option",
|
|
1008
|
+
tabIndex: -1,
|
|
1009
|
+
"aria-selected": selected,
|
|
1010
|
+
"aria-disabled": opt.disabled ? true : void 0,
|
|
1011
|
+
className: cn("dropdown_option", {
|
|
1012
|
+
is_selected: selected,
|
|
1013
|
+
is_active: active,
|
|
1014
|
+
is_disabled: opt.disabled
|
|
1015
|
+
}),
|
|
1016
|
+
onMouseEnter: () => !opt.disabled && setActiveIndex(i),
|
|
1017
|
+
onClick: () => {
|
|
1018
|
+
if (opt.disabled) return;
|
|
1019
|
+
setValue(opt.value);
|
|
1020
|
+
setIsOpen(false);
|
|
1021
|
+
},
|
|
1022
|
+
children: [
|
|
1023
|
+
opt.leadingIcon && /* @__PURE__ */ jsx("span", { className: "dropdown_option_icon", children: opt.leadingIcon }),
|
|
1024
|
+
/* @__PURE__ */ jsxs("span", { className: "dropdown_option_content", children: [
|
|
1025
|
+
/* @__PURE__ */ jsx("span", { className: "dropdown_option_label", children: opt.label }),
|
|
1026
|
+
opt.supportingText && /* @__PURE__ */ jsx("span", { className: "dropdown_option_supporting", children: opt.supportingText })
|
|
1027
|
+
] }),
|
|
1028
|
+
(selected || opt.trailingIcon) && /* @__PURE__ */ jsx("span", { className: "dropdown_option_trailing", children: opt.trailingIcon ?? /* @__PURE__ */ jsx(Check, { size: 16, "aria-hidden": "true" }) })
|
|
1029
|
+
]
|
|
1030
|
+
}
|
|
1031
|
+
),
|
|
1032
|
+
opt.showDivider && /* @__PURE__ */ jsx("hr", { className: "dropdown_option_divider" })
|
|
1033
|
+
] }, opt.value);
|
|
1034
|
+
}) })
|
|
1013
1035
|
]
|
|
1014
1036
|
}
|
|
1015
1037
|
);
|
|
@@ -1036,9 +1058,9 @@ var DatePicker = ({
|
|
|
1036
1058
|
minDateSrFormat = "Minimum date: {date}",
|
|
1037
1059
|
selectableRangeUntilTodaySrText = "Selectable up to today"
|
|
1038
1060
|
}) => {
|
|
1039
|
-
const groupId =
|
|
1040
|
-
const constraintId =
|
|
1041
|
-
const { todayYear, todayMonth, todayDay } =
|
|
1061
|
+
const groupId = React4.useId();
|
|
1062
|
+
const constraintId = React4.useId();
|
|
1063
|
+
const { todayYear, todayMonth, todayDay } = React4.useMemo(() => {
|
|
1042
1064
|
const now = /* @__PURE__ */ new Date();
|
|
1043
1065
|
return {
|
|
1044
1066
|
todayYear: now.getFullYear(),
|
|
@@ -1047,7 +1069,7 @@ var DatePicker = ({
|
|
|
1047
1069
|
};
|
|
1048
1070
|
}, []);
|
|
1049
1071
|
const endYear = endYearProp ?? todayYear + 10;
|
|
1050
|
-
const parsed =
|
|
1072
|
+
const parsed = React4.useMemo(() => {
|
|
1051
1073
|
if (!value) return { year: 0, month: 0, day: 0 };
|
|
1052
1074
|
const [y, m, d] = value.split("-").map(Number);
|
|
1053
1075
|
return {
|
|
@@ -1056,7 +1078,7 @@ var DatePicker = ({
|
|
|
1056
1078
|
day: d || 0
|
|
1057
1079
|
};
|
|
1058
1080
|
}, [value]);
|
|
1059
|
-
const min =
|
|
1081
|
+
const min = React4.useMemo(() => {
|
|
1060
1082
|
if (!minDate) return { year: 0, month: 0, day: 0 };
|
|
1061
1083
|
const [y, m, d] = minDate.split("-").map(Number);
|
|
1062
1084
|
return {
|
|
@@ -1069,11 +1091,14 @@ var DatePicker = ({
|
|
|
1069
1091
|
const maxYear = selectableRange === "until-today" ? todayYear : endYear;
|
|
1070
1092
|
const minMonth = min.year > 0 && year === min.year ? Math.min(12, Math.max(1, min.month)) : 1;
|
|
1071
1093
|
const maxMonth = selectableRange === "until-today" && year === todayYear ? todayMonth : 12;
|
|
1072
|
-
const minDay = Math.min(
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1094
|
+
const minDay = Math.min(
|
|
1095
|
+
31,
|
|
1096
|
+
Math.max(
|
|
1097
|
+
1,
|
|
1098
|
+
min.year > 0 && min.month > 0 && year === min.year && month === min.month ? min.day : 1
|
|
1099
|
+
)
|
|
1100
|
+
);
|
|
1101
|
+
const maxDay = React4.useMemo(() => {
|
|
1077
1102
|
if (!year || !month) return 31;
|
|
1078
1103
|
const daysInMonth = getDaysInMonth(year, month);
|
|
1079
1104
|
if (selectableRange === "until-today" && year === todayYear && month === todayMonth) {
|
|
@@ -1081,28 +1106,28 @@ var DatePicker = ({
|
|
|
1081
1106
|
}
|
|
1082
1107
|
return daysInMonth;
|
|
1083
1108
|
}, [year, month, selectableRange, todayYear, todayMonth, todayDay]);
|
|
1084
|
-
const yearOptions =
|
|
1109
|
+
const yearOptions = React4.useMemo(
|
|
1085
1110
|
() => range(startYear, maxYear).map((y) => ({
|
|
1086
1111
|
value: String(y),
|
|
1087
1112
|
label: String(y)
|
|
1088
1113
|
})),
|
|
1089
1114
|
[startYear, maxYear]
|
|
1090
1115
|
);
|
|
1091
|
-
const monthOptions =
|
|
1116
|
+
const monthOptions = React4.useMemo(
|
|
1092
1117
|
() => range(minMonth, Math.max(minMonth, maxMonth)).map((m) => ({
|
|
1093
1118
|
value: String(m),
|
|
1094
1119
|
label: pad(m)
|
|
1095
1120
|
})),
|
|
1096
1121
|
[minMonth, maxMonth]
|
|
1097
1122
|
);
|
|
1098
|
-
const dayOptions =
|
|
1123
|
+
const dayOptions = React4.useMemo(
|
|
1099
1124
|
() => range(minDay, Math.max(minDay, maxDay)).map((d) => ({
|
|
1100
1125
|
value: String(d),
|
|
1101
1126
|
label: pad(d)
|
|
1102
1127
|
})),
|
|
1103
1128
|
[minDay, maxDay]
|
|
1104
1129
|
);
|
|
1105
|
-
const emit =
|
|
1130
|
+
const emit = React4.useCallback(
|
|
1106
1131
|
(yy, mm, dd) => {
|
|
1107
1132
|
if (mode === "year-month") {
|
|
1108
1133
|
onChange(`${yy}-${pad(mm)}`);
|
|
@@ -1113,7 +1138,7 @@ var DatePicker = ({
|
|
|
1113
1138
|
},
|
|
1114
1139
|
[mode, onChange]
|
|
1115
1140
|
);
|
|
1116
|
-
const handleYearChange =
|
|
1141
|
+
const handleYearChange = React4.useCallback(
|
|
1117
1142
|
(raw) => {
|
|
1118
1143
|
if (!raw) return;
|
|
1119
1144
|
const newYear = Number(raw);
|
|
@@ -1130,14 +1155,14 @@ var DatePicker = ({
|
|
|
1130
1155
|
},
|
|
1131
1156
|
[month, day, min.year, min.month, selectableRange, todayYear, todayMonth, emit]
|
|
1132
1157
|
);
|
|
1133
|
-
const handleMonthChange =
|
|
1158
|
+
const handleMonthChange = React4.useCallback(
|
|
1134
1159
|
(raw) => {
|
|
1135
1160
|
if (!raw || !year) return;
|
|
1136
1161
|
emit(year, Number(raw), day || void 0);
|
|
1137
1162
|
},
|
|
1138
1163
|
[year, day, emit]
|
|
1139
1164
|
);
|
|
1140
|
-
const handleDayChange =
|
|
1165
|
+
const handleDayChange = React4.useCallback(
|
|
1141
1166
|
(raw) => {
|
|
1142
1167
|
if (!raw || !year || !month) return;
|
|
1143
1168
|
emit(year, month, Number(raw));
|
|
@@ -1151,8 +1176,7 @@ var DatePicker = ({
|
|
|
1151
1176
|
});
|
|
1152
1177
|
const constraintParts = [];
|
|
1153
1178
|
if (minDate) constraintParts.push(minDateSrFormat.replace("{date}", minDate));
|
|
1154
|
-
if (selectableRange === "until-today")
|
|
1155
|
-
constraintParts.push(selectableRangeUntilTodaySrText);
|
|
1179
|
+
if (selectableRange === "until-today") constraintParts.push(selectableRangeUntilTodaySrText);
|
|
1156
1180
|
const constraintDesc = constraintParts.join(". ");
|
|
1157
1181
|
return /* @__PURE__ */ jsxs("div", { className: rootClassName, style: containerStyle, children: [
|
|
1158
1182
|
label && /* @__PURE__ */ jsx("span", { className: "date_picker_label", id: groupId, children: label }),
|
|
@@ -1209,29 +1233,12 @@ var DatePicker = ({
|
|
|
1209
1233
|
)
|
|
1210
1234
|
] });
|
|
1211
1235
|
};
|
|
1212
|
-
var Divider = ({
|
|
1213
|
-
|
|
1214
|
-
className,
|
|
1215
|
-
...props
|
|
1216
|
-
}) => {
|
|
1217
|
-
const dividerClassName = cn(
|
|
1218
|
-
"divider",
|
|
1219
|
-
`divider_weight_${weight}`,
|
|
1220
|
-
className
|
|
1221
|
-
);
|
|
1236
|
+
var Divider = ({ weight = "standard", className, ...props }) => {
|
|
1237
|
+
const dividerClassName = cn("divider", `divider_weight_${weight}`, className);
|
|
1222
1238
|
return /* @__PURE__ */ jsx("hr", { className: dividerClassName, ...props });
|
|
1223
1239
|
};
|
|
1224
|
-
var FAB = ({
|
|
1225
|
-
|
|
1226
|
-
icon,
|
|
1227
|
-
className,
|
|
1228
|
-
...props
|
|
1229
|
-
}) => {
|
|
1230
|
-
const fabClassName = cn(
|
|
1231
|
-
"fab",
|
|
1232
|
-
`fab_variant_${variant}`,
|
|
1233
|
-
className
|
|
1234
|
-
);
|
|
1240
|
+
var FAB = ({ variant = "primary", icon, className, ...props }) => {
|
|
1241
|
+
const fabClassName = cn("fab", `fab_variant_${variant}`, className);
|
|
1235
1242
|
return /* @__PURE__ */ jsx("button", { className: fabClassName, ...props, children: /* @__PURE__ */ jsx("span", { className: "fab_icon", "aria-hidden": "true", children: icon }) });
|
|
1236
1243
|
};
|
|
1237
1244
|
var FileInput = ({
|
|
@@ -1243,14 +1250,16 @@ var FileInput = ({
|
|
|
1243
1250
|
disabled,
|
|
1244
1251
|
...props
|
|
1245
1252
|
}) => {
|
|
1246
|
-
const inputId =
|
|
1247
|
-
const helperId =
|
|
1248
|
-
const [previewUrls, setPreviewUrls] =
|
|
1253
|
+
const inputId = React4.useId();
|
|
1254
|
+
const helperId = React4.useId();
|
|
1255
|
+
const [previewUrls, setPreviewUrls] = React4.useState([]);
|
|
1249
1256
|
const handleChange = (e) => {
|
|
1250
1257
|
const files = e.currentTarget.files;
|
|
1251
1258
|
onFiles?.(files);
|
|
1252
1259
|
if (preview && files) {
|
|
1253
|
-
|
|
1260
|
+
for (const url of previewUrls) {
|
|
1261
|
+
URL.revokeObjectURL(url);
|
|
1262
|
+
}
|
|
1254
1263
|
const urls = [];
|
|
1255
1264
|
for (let i = 0; i < files.length; i++) {
|
|
1256
1265
|
if (files[i].type.startsWith("image/")) {
|
|
@@ -1259,13 +1268,17 @@ var FileInput = ({
|
|
|
1259
1268
|
}
|
|
1260
1269
|
setPreviewUrls(urls);
|
|
1261
1270
|
} else {
|
|
1262
|
-
|
|
1271
|
+
for (const url of previewUrls) {
|
|
1272
|
+
URL.revokeObjectURL(url);
|
|
1273
|
+
}
|
|
1263
1274
|
setPreviewUrls([]);
|
|
1264
1275
|
}
|
|
1265
1276
|
};
|
|
1266
|
-
|
|
1277
|
+
React4.useEffect(() => {
|
|
1267
1278
|
return () => {
|
|
1268
|
-
|
|
1279
|
+
for (const url of previewUrls) {
|
|
1280
|
+
URL.revokeObjectURL(url);
|
|
1281
|
+
}
|
|
1269
1282
|
};
|
|
1270
1283
|
}, [previewUrls]);
|
|
1271
1284
|
const rootClassName = cn("file_input", disabled && "file_input_disabled", className);
|
|
@@ -1284,7 +1297,10 @@ var FileInput = ({
|
|
|
1284
1297
|
),
|
|
1285
1298
|
/* @__PURE__ */ jsx("label", { htmlFor: inputId, className: "file_input_label", children: label }),
|
|
1286
1299
|
supportingText && /* @__PURE__ */ jsx("span", { id: helperId, className: "file_input_helper", children: supportingText }),
|
|
1287
|
-
previewUrls.length > 0 && /* @__PURE__ */ jsx("div", { className: "file_input_preview", children: previewUrls.map((url) =>
|
|
1300
|
+
previewUrls.length > 0 && /* @__PURE__ */ jsx("div", { className: "file_input_preview", children: previewUrls.map((url) => (
|
|
1301
|
+
// biome-ignore lint/performance/noImgElement: framework-agnostic DS — host app should swap with next/image if needed
|
|
1302
|
+
/* @__PURE__ */ jsx("img", { src: url, alt: "", className: "file_input_preview_img" }, url)
|
|
1303
|
+
)) })
|
|
1288
1304
|
] });
|
|
1289
1305
|
};
|
|
1290
1306
|
|
|
@@ -1923,13 +1939,7 @@ var LinearProgress = ({
|
|
|
1923
1939
|
"aria-valuemin": 0,
|
|
1924
1940
|
"aria-valuemax": totalSteps,
|
|
1925
1941
|
...props,
|
|
1926
|
-
children: /* @__PURE__ */ jsx(
|
|
1927
|
-
"div",
|
|
1928
|
-
{
|
|
1929
|
-
className: "linear_progress_indicator",
|
|
1930
|
-
style: { width: `${percent}%` }
|
|
1931
|
-
}
|
|
1932
|
-
)
|
|
1942
|
+
children: /* @__PURE__ */ jsx("div", { className: "linear_progress_indicator", style: { width: `${percent}%` } })
|
|
1933
1943
|
}
|
|
1934
1944
|
);
|
|
1935
1945
|
};
|
|
@@ -1953,32 +1963,114 @@ var ListItem = ({
|
|
|
1953
1963
|
onClick && "list_item_interactive",
|
|
1954
1964
|
className
|
|
1955
1965
|
);
|
|
1966
|
+
return (
|
|
1967
|
+
// biome-ignore lint/a11y/noStaticElementInteractions: optional interactive list item — role=button + tabIndex set conditionally based on onClick
|
|
1968
|
+
/* @__PURE__ */ jsx(
|
|
1969
|
+
"div",
|
|
1970
|
+
{
|
|
1971
|
+
className: rootClassName,
|
|
1972
|
+
onClick: disabled ? void 0 : onClick,
|
|
1973
|
+
onKeyDown: (e) => {
|
|
1974
|
+
if (disabled || !onClick) return;
|
|
1975
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
1976
|
+
e.preventDefault();
|
|
1977
|
+
onClick(e);
|
|
1978
|
+
}
|
|
1979
|
+
},
|
|
1980
|
+
role: onClick ? "button" : void 0,
|
|
1981
|
+
tabIndex: onClick && !disabled ? 0 : void 0,
|
|
1982
|
+
"aria-disabled": disabled || void 0,
|
|
1983
|
+
...props,
|
|
1984
|
+
children: /* @__PURE__ */ jsxs("div", { className: "list_item_state_layer", children: [
|
|
1985
|
+
leadingElement && /* @__PURE__ */ jsx("div", { className: "list_item_leading", children: leadingElement }),
|
|
1986
|
+
/* @__PURE__ */ jsxs("div", { className: "list_item_content", children: [
|
|
1987
|
+
overline && /* @__PURE__ */ jsx("span", { className: "list_item_overline", children: overline }),
|
|
1988
|
+
/* @__PURE__ */ jsx("span", { className: "list_item_label", children: label }),
|
|
1989
|
+
supportingText && /* @__PURE__ */ jsx("span", { className: "list_item_supporting", children: supportingText }),
|
|
1990
|
+
metadata && /* @__PURE__ */ jsx("span", { className: "list_item_metadata", children: metadata })
|
|
1991
|
+
] }),
|
|
1992
|
+
trailingElement && /* @__PURE__ */ jsx("div", { className: "list_item_trailing", children: trailingElement })
|
|
1993
|
+
] })
|
|
1994
|
+
}
|
|
1995
|
+
)
|
|
1996
|
+
);
|
|
1997
|
+
};
|
|
1998
|
+
var Modal = ({
|
|
1999
|
+
open,
|
|
2000
|
+
onClose,
|
|
2001
|
+
closeOnOverlay = true,
|
|
2002
|
+
width = 520,
|
|
2003
|
+
title,
|
|
2004
|
+
children,
|
|
2005
|
+
className,
|
|
2006
|
+
ariaLabel,
|
|
2007
|
+
...props
|
|
2008
|
+
}) => {
|
|
2009
|
+
const panelRef = React4.useRef(null);
|
|
2010
|
+
const titleId = React4.useId();
|
|
2011
|
+
useFocusTrap(panelRef, open);
|
|
2012
|
+
const handleEscape = React4.useEffectEvent((e) => {
|
|
2013
|
+
if (e.key === "Escape") onClose?.();
|
|
2014
|
+
});
|
|
2015
|
+
React4.useEffect(() => {
|
|
2016
|
+
if (!open) return;
|
|
2017
|
+
document.addEventListener("keydown", handleEscape);
|
|
2018
|
+
return () => document.removeEventListener("keydown", handleEscape);
|
|
2019
|
+
}, [open]);
|
|
2020
|
+
React4.useEffect(() => {
|
|
2021
|
+
if (!open) return;
|
|
2022
|
+
const body = document.body;
|
|
2023
|
+
const openModals = parseInt(body.dataset.openModals || "0", 10);
|
|
2024
|
+
if (openModals === 0) {
|
|
2025
|
+
body.dataset.originalOverflow = window.getComputedStyle(body).overflow;
|
|
2026
|
+
body.style.overflow = "hidden";
|
|
2027
|
+
}
|
|
2028
|
+
body.dataset.openModals = String(openModals + 1);
|
|
2029
|
+
return () => {
|
|
2030
|
+
const currentOpenModals = parseInt(body.dataset.openModals || "1", 10);
|
|
2031
|
+
const nextOpenModals = currentOpenModals - 1;
|
|
2032
|
+
if (nextOpenModals === 0) {
|
|
2033
|
+
body.style.overflow = body.dataset.originalOverflow || "";
|
|
2034
|
+
delete body.dataset.openModals;
|
|
2035
|
+
delete body.dataset.originalOverflow;
|
|
2036
|
+
} else {
|
|
2037
|
+
body.dataset.openModals = String(nextOpenModals);
|
|
2038
|
+
}
|
|
2039
|
+
};
|
|
2040
|
+
}, [open]);
|
|
2041
|
+
if (!open) return null;
|
|
2042
|
+
const panelClassName = cn("modal_panel", className);
|
|
2043
|
+
const hasTitle = !!title;
|
|
1956
2044
|
return /* @__PURE__ */ jsx(
|
|
1957
2045
|
"div",
|
|
1958
2046
|
{
|
|
1959
|
-
className:
|
|
1960
|
-
|
|
2047
|
+
className: "modal",
|
|
2048
|
+
role: "dialog",
|
|
2049
|
+
"aria-modal": "true",
|
|
2050
|
+
"aria-labelledby": hasTitle && !ariaLabel ? titleId : void 0,
|
|
2051
|
+
"aria-label": !hasTitle ? ariaLabel ?? "Dialog" : ariaLabel,
|
|
2052
|
+
onClick: () => closeOnOverlay && onClose?.(),
|
|
1961
2053
|
onKeyDown: (e) => {
|
|
1962
|
-
if (
|
|
1963
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
1964
|
-
e.preventDefault();
|
|
1965
|
-
onClick(e);
|
|
1966
|
-
}
|
|
2054
|
+
if (e.key === "Escape") onClose?.();
|
|
1967
2055
|
},
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
2056
|
+
children: /* @__PURE__ */ jsxs(
|
|
2057
|
+
"div",
|
|
2058
|
+
{
|
|
2059
|
+
ref: panelRef,
|
|
2060
|
+
className: panelClassName,
|
|
2061
|
+
style: { width },
|
|
2062
|
+
role: "document",
|
|
2063
|
+
onClick: (e) => e.stopPropagation(),
|
|
2064
|
+
onKeyDown: (e) => {
|
|
2065
|
+
if (e.key !== "Escape") e.stopPropagation();
|
|
2066
|
+
},
|
|
2067
|
+
...props,
|
|
2068
|
+
children: [
|
|
2069
|
+
title && /* @__PURE__ */ jsx("div", { id: titleId, className: "modal_header", children: title }),
|
|
2070
|
+
/* @__PURE__ */ jsx("div", { className: "modal_body", children })
|
|
2071
|
+
]
|
|
2072
|
+
}
|
|
2073
|
+
)
|
|
1982
2074
|
}
|
|
1983
2075
|
);
|
|
1984
2076
|
};
|
|
@@ -1993,8 +2085,11 @@ var OtpInput = ({
|
|
|
1993
2085
|
ariaLabel = "OTP \uC785\uB825",
|
|
1994
2086
|
className
|
|
1995
2087
|
}) => {
|
|
1996
|
-
const inputsRef =
|
|
1997
|
-
|
|
2088
|
+
const inputsRef = React4.useRef([]);
|
|
2089
|
+
React4.useEffect(() => {
|
|
2090
|
+
if (autoFocus) inputsRef.current[0]?.focus();
|
|
2091
|
+
}, [autoFocus]);
|
|
2092
|
+
const digits = React4.useMemo(() => {
|
|
1998
2093
|
const arr = value.split("").slice(0, length);
|
|
1999
2094
|
while (arr.length < length) arr.push("");
|
|
2000
2095
|
return arr;
|
|
@@ -2016,7 +2111,7 @@ var OtpInput = ({
|
|
|
2016
2111
|
}
|
|
2017
2112
|
};
|
|
2018
2113
|
const handleFocus = (index) => {
|
|
2019
|
-
const firstEmpty = digits.
|
|
2114
|
+
const firstEmpty = digits.indexOf("");
|
|
2020
2115
|
if (firstEmpty !== -1 && firstEmpty < index) {
|
|
2021
2116
|
focusInput(firstEmpty);
|
|
2022
2117
|
}
|
|
@@ -2057,116 +2152,39 @@ var OtpInput = ({
|
|
|
2057
2152
|
focusInput(nextIndex);
|
|
2058
2153
|
};
|
|
2059
2154
|
const rootClassName = cn("otp_input", className);
|
|
2060
|
-
return
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
{
|
|
2064
|
-
|
|
2065
|
-
inputsRef.current[i] = el;
|
|
2066
|
-
},
|
|
2067
|
-
type: "text",
|
|
2068
|
-
inputMode: "numeric",
|
|
2069
|
-
pattern: "\\d*",
|
|
2070
|
-
maxLength: 1,
|
|
2071
|
-
value: digit,
|
|
2072
|
-
onChange: (e) => handleChange(i, e),
|
|
2073
|
-
onFocus: () => handleFocus(i),
|
|
2074
|
-
onKeyDown: (e) => handleKeyDown(i, e),
|
|
2075
|
-
onPaste: handlePaste,
|
|
2076
|
-
disabled,
|
|
2077
|
-
autoFocus: autoFocus && i === 0,
|
|
2078
|
-
"aria-label": `${i + 1}\uBC88\uC9F8 \uC790\uB9AC`,
|
|
2079
|
-
className: cn(
|
|
2080
|
-
"otp_input_box",
|
|
2081
|
-
error && "otp_input_box_error",
|
|
2082
|
-
disabled && "otp_input_box_disabled"
|
|
2083
|
-
)
|
|
2084
|
-
},
|
|
2085
|
-
i
|
|
2086
|
-
)) }),
|
|
2087
|
-
supportingText && /* @__PURE__ */ jsx("span", { className: cn("otp_input_supporting", error && "otp_input_supporting_error"), children: supportingText })
|
|
2088
|
-
] });
|
|
2089
|
-
};
|
|
2090
|
-
OtpInput.displayName = "OtpInput";
|
|
2091
|
-
var Modal = ({
|
|
2092
|
-
open,
|
|
2093
|
-
onClose,
|
|
2094
|
-
closeOnOverlay = true,
|
|
2095
|
-
width = 520,
|
|
2096
|
-
title,
|
|
2097
|
-
children,
|
|
2098
|
-
className,
|
|
2099
|
-
ariaLabel,
|
|
2100
|
-
...props
|
|
2101
|
-
}) => {
|
|
2102
|
-
const panelRef = React5.useRef(null);
|
|
2103
|
-
const titleId = React5.useId();
|
|
2104
|
-
useFocusTrap(panelRef, open);
|
|
2105
|
-
const handleEscape = React5.useEffectEvent((e) => {
|
|
2106
|
-
if (e.key === "Escape") onClose?.();
|
|
2107
|
-
});
|
|
2108
|
-
React5.useEffect(() => {
|
|
2109
|
-
if (!open) return;
|
|
2110
|
-
document.addEventListener("keydown", handleEscape);
|
|
2111
|
-
return () => document.removeEventListener("keydown", handleEscape);
|
|
2112
|
-
}, [open]);
|
|
2113
|
-
React5.useEffect(() => {
|
|
2114
|
-
if (!open) return;
|
|
2115
|
-
const body = document.body;
|
|
2116
|
-
const openModals = parseInt(body.dataset.openModals || "0", 10);
|
|
2117
|
-
if (openModals === 0) {
|
|
2118
|
-
body.dataset.originalOverflow = window.getComputedStyle(body).overflow;
|
|
2119
|
-
body.style.overflow = "hidden";
|
|
2120
|
-
}
|
|
2121
|
-
body.dataset.openModals = String(openModals + 1);
|
|
2122
|
-
return () => {
|
|
2123
|
-
const currentOpenModals = parseInt(body.dataset.openModals || "1", 10);
|
|
2124
|
-
const nextOpenModals = currentOpenModals - 1;
|
|
2125
|
-
if (nextOpenModals === 0) {
|
|
2126
|
-
body.style.overflow = body.dataset.originalOverflow || "";
|
|
2127
|
-
delete body.dataset.openModals;
|
|
2128
|
-
delete body.dataset.originalOverflow;
|
|
2129
|
-
} else {
|
|
2130
|
-
body.dataset.openModals = String(nextOpenModals);
|
|
2131
|
-
}
|
|
2132
|
-
};
|
|
2133
|
-
}, [open]);
|
|
2134
|
-
if (!open) return null;
|
|
2135
|
-
const panelClassName = cn("modal_panel", className);
|
|
2136
|
-
const hasTitle = !!title;
|
|
2137
|
-
return /* @__PURE__ */ jsx(
|
|
2138
|
-
"div",
|
|
2139
|
-
{
|
|
2140
|
-
className: "modal",
|
|
2141
|
-
role: "dialog",
|
|
2142
|
-
"aria-modal": "true",
|
|
2143
|
-
"aria-labelledby": hasTitle && !ariaLabel ? titleId : void 0,
|
|
2144
|
-
"aria-label": !hasTitle ? ariaLabel ?? "Dialog" : ariaLabel,
|
|
2145
|
-
onClick: () => closeOnOverlay && onClose?.(),
|
|
2146
|
-
onKeyDown: (e) => {
|
|
2147
|
-
if (e.key === "Escape") onClose?.();
|
|
2148
|
-
},
|
|
2149
|
-
children: /* @__PURE__ */ jsxs(
|
|
2150
|
-
"div",
|
|
2155
|
+
return (
|
|
2156
|
+
// biome-ignore lint/a11y/useSemanticElements: <fieldset> would force border/legend styles; role=group is the WAI-ARIA equivalent for OTP grouping
|
|
2157
|
+
/* @__PURE__ */ jsxs("div", { className: rootClassName, role: "group", "aria-label": ariaLabel, children: [
|
|
2158
|
+
/* @__PURE__ */ jsx("div", { className: "otp_input_boxes", children: digits.map((digit, i) => /* @__PURE__ */ jsx(
|
|
2159
|
+
"input",
|
|
2151
2160
|
{
|
|
2152
|
-
ref:
|
|
2153
|
-
|
|
2154
|
-
style: { width },
|
|
2155
|
-
role: "document",
|
|
2156
|
-
onClick: (e) => e.stopPropagation(),
|
|
2157
|
-
onKeyDown: (e) => {
|
|
2158
|
-
if (e.key !== "Escape") e.stopPropagation();
|
|
2161
|
+
ref: (el) => {
|
|
2162
|
+
inputsRef.current[i] = el;
|
|
2159
2163
|
},
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2164
|
+
type: "text",
|
|
2165
|
+
inputMode: "numeric",
|
|
2166
|
+
pattern: "\\d*",
|
|
2167
|
+
maxLength: 1,
|
|
2168
|
+
value: digit,
|
|
2169
|
+
onChange: (e) => handleChange(i, e),
|
|
2170
|
+
onFocus: () => handleFocus(i),
|
|
2171
|
+
onKeyDown: (e) => handleKeyDown(i, e),
|
|
2172
|
+
onPaste: handlePaste,
|
|
2173
|
+
disabled,
|
|
2174
|
+
"aria-label": `${i + 1}\uBC88\uC9F8 \uC790\uB9AC`,
|
|
2175
|
+
className: cn(
|
|
2176
|
+
"otp_input_box",
|
|
2177
|
+
error && "otp_input_box_error",
|
|
2178
|
+
disabled && "otp_input_box_disabled"
|
|
2179
|
+
)
|
|
2180
|
+
},
|
|
2181
|
+
i
|
|
2182
|
+
)) }),
|
|
2183
|
+
supportingText && /* @__PURE__ */ jsx("span", { className: cn("otp_input_supporting", error && "otp_input_supporting_error"), children: supportingText })
|
|
2184
|
+
] })
|
|
2168
2185
|
);
|
|
2169
2186
|
};
|
|
2187
|
+
OtpInput.displayName = "OtpInput";
|
|
2170
2188
|
var range2 = (start, end) => {
|
|
2171
2189
|
const out = [];
|
|
2172
2190
|
for (let i = start; i <= end; i += 1) out.push(i);
|
|
@@ -2205,7 +2223,7 @@ var Pagination = ({
|
|
|
2205
2223
|
}) => {
|
|
2206
2224
|
const prevDisabled = page <= 1;
|
|
2207
2225
|
const nextDisabled = page >= totalPages;
|
|
2208
|
-
const items =
|
|
2226
|
+
const items = React4.useMemo(() => getPaginationItems(page, totalPages), [page, totalPages]);
|
|
2209
2227
|
return /* @__PURE__ */ jsxs("nav", { className: "pagination", "aria-label": "Pagination", children: [
|
|
2210
2228
|
/* @__PURE__ */ jsx(
|
|
2211
2229
|
"button",
|
|
@@ -2220,7 +2238,9 @@ var Pagination = ({
|
|
|
2220
2238
|
),
|
|
2221
2239
|
/* @__PURE__ */ jsx("ul", { className: "pagination_pages", children: items.map((it, idx) => {
|
|
2222
2240
|
if (it === "ellipsis") {
|
|
2223
|
-
|
|
2241
|
+
const prev = items[idx - 1];
|
|
2242
|
+
const next = items[idx + 1];
|
|
2243
|
+
return /* @__PURE__ */ jsx("li", { className: "pagination_ellipsis", "aria-hidden": "true", children: "\u2026" }, `e-${prev}-${next}`);
|
|
2224
2244
|
}
|
|
2225
2245
|
const isActive = it === page;
|
|
2226
2246
|
const buttonClassName = cn("pagination_page_button", { pagination_active: isActive });
|
|
@@ -2249,7 +2269,12 @@ var Pagination = ({
|
|
|
2249
2269
|
] });
|
|
2250
2270
|
};
|
|
2251
2271
|
var Radio = ({ label, size = "md", className, ref, ...props }) => {
|
|
2252
|
-
const rootClassName = cn(
|
|
2272
|
+
const rootClassName = cn(
|
|
2273
|
+
"radio",
|
|
2274
|
+
`radio_size_${size}`,
|
|
2275
|
+
props.disabled && "radio_disabled",
|
|
2276
|
+
className
|
|
2277
|
+
);
|
|
2253
2278
|
return /* @__PURE__ */ jsxs("label", { className: rootClassName, children: [
|
|
2254
2279
|
/* @__PURE__ */ jsx("input", { ref, type: "radio", className: "radio_input", ...props }),
|
|
2255
2280
|
/* @__PURE__ */ jsx("span", { className: "radio_state_layer", "aria-hidden": "true", children: /* @__PURE__ */ jsx("span", { className: "radio_dot" }) }),
|
|
@@ -2268,49 +2293,6 @@ var Spinner = ({ size = 24, ariaLabel = "Loading" }) => {
|
|
|
2268
2293
|
}
|
|
2269
2294
|
);
|
|
2270
2295
|
};
|
|
2271
|
-
var Toggle = ({
|
|
2272
|
-
checked,
|
|
2273
|
-
defaultChecked,
|
|
2274
|
-
onChange,
|
|
2275
|
-
size = "sm",
|
|
2276
|
-
disabled,
|
|
2277
|
-
className,
|
|
2278
|
-
ariaLabel,
|
|
2279
|
-
ref,
|
|
2280
|
-
...props
|
|
2281
|
-
}) => {
|
|
2282
|
-
const isControlled = checked !== void 0;
|
|
2283
|
-
const [innerChecked, setInnerChecked] = React5.useState(!!defaultChecked);
|
|
2284
|
-
const isOn = isControlled ? !!checked : innerChecked;
|
|
2285
|
-
const handleToggle = () => {
|
|
2286
|
-
if (disabled) return;
|
|
2287
|
-
const next = !isOn;
|
|
2288
|
-
if (!isControlled) setInnerChecked(next);
|
|
2289
|
-
onChange?.(next);
|
|
2290
|
-
};
|
|
2291
|
-
const rootClassName = cn(
|
|
2292
|
-
"toggle",
|
|
2293
|
-
`toggle_size_${size}`,
|
|
2294
|
-
{ toggle_on: isOn, toggle_disabled: disabled },
|
|
2295
|
-
className
|
|
2296
|
-
);
|
|
2297
|
-
return /* @__PURE__ */ jsx(
|
|
2298
|
-
"button",
|
|
2299
|
-
{
|
|
2300
|
-
ref,
|
|
2301
|
-
type: "button",
|
|
2302
|
-
role: "switch",
|
|
2303
|
-
"aria-checked": isOn,
|
|
2304
|
-
"aria-label": ariaLabel,
|
|
2305
|
-
disabled,
|
|
2306
|
-
onClick: handleToggle,
|
|
2307
|
-
className: rootClassName,
|
|
2308
|
-
...props,
|
|
2309
|
-
children: /* @__PURE__ */ jsx("span", { className: "toggle_thumb" })
|
|
2310
|
-
}
|
|
2311
|
-
);
|
|
2312
|
-
};
|
|
2313
|
-
Toggle.displayName = "Toggle";
|
|
2314
2296
|
var ClearIcon = () => /* @__PURE__ */ jsx(Icon, { name: "close", size: 20 });
|
|
2315
2297
|
var TextField = ({
|
|
2316
2298
|
id,
|
|
@@ -2331,21 +2313,21 @@ var TextField = ({
|
|
|
2331
2313
|
ref,
|
|
2332
2314
|
...props
|
|
2333
2315
|
}) => {
|
|
2334
|
-
const generatedId =
|
|
2316
|
+
const generatedId = React4.useId();
|
|
2335
2317
|
const inputId = id ?? generatedId;
|
|
2336
2318
|
const helperId = supportingText ? `${inputId}-help` : void 0;
|
|
2337
2319
|
const isControlled = value !== void 0;
|
|
2338
2320
|
const applyTransform = (nextValue) => transformValue ? transformValue(nextValue) : nextValue;
|
|
2339
|
-
const [innerValue, setInnerValue] =
|
|
2321
|
+
const [innerValue, setInnerValue] = React4.useState(
|
|
2340
2322
|
() => applyTransform(value ?? defaultValue ?? "")
|
|
2341
2323
|
);
|
|
2342
|
-
const isComposingRef =
|
|
2343
|
-
|
|
2324
|
+
const isComposingRef = React4.useRef(false);
|
|
2325
|
+
React4.useEffect(() => {
|
|
2344
2326
|
if (!isControlled) return;
|
|
2345
2327
|
const nextValue = value ?? "";
|
|
2346
2328
|
setInnerValue(transformValue ? transformValue(nextValue) : nextValue);
|
|
2347
2329
|
}, [isControlled, value, transformValue]);
|
|
2348
|
-
const handleClear =
|
|
2330
|
+
const handleClear = React4.useCallback(() => {
|
|
2349
2331
|
setInnerValue("");
|
|
2350
2332
|
onChangeAction?.("");
|
|
2351
2333
|
}, [onChangeAction]);
|
|
@@ -2357,54 +2339,54 @@ var TextField = ({
|
|
|
2357
2339
|
props.disabled && "text_field_disabled",
|
|
2358
2340
|
className
|
|
2359
2341
|
);
|
|
2360
|
-
const resolvedTrailing = clearable && innerValue ? /* @__PURE__ */ jsx(
|
|
2361
|
-
"button",
|
|
2362
|
-
{
|
|
2363
|
-
type: "button",
|
|
2364
|
-
className: "text_field_clear",
|
|
2365
|
-
onClick: handleClear,
|
|
2366
|
-
"aria-label": "Clear",
|
|
2367
|
-
children: /* @__PURE__ */ jsx(ClearIcon, {})
|
|
2368
|
-
}
|
|
2369
|
-
) : trailingIcon ? /* @__PURE__ */ jsx("span", { className: "text_field_icon", "aria-hidden": "true", children: trailingIcon }) : null;
|
|
2342
|
+
const resolvedTrailing = clearable && innerValue ? /* @__PURE__ */ jsx("button", { type: "button", className: "text_field_clear", onClick: handleClear, "aria-label": "Clear", children: /* @__PURE__ */ jsx(ClearIcon, {}) }) : trailingIcon ? /* @__PURE__ */ jsx("span", { className: "text_field_icon", "aria-hidden": "true", children: trailingIcon }) : null;
|
|
2370
2343
|
return /* @__PURE__ */ jsxs("div", { className: rootClassName, children: [
|
|
2371
2344
|
/* @__PURE__ */ jsxs("fieldset", { className: "text_field_container", children: [
|
|
2372
2345
|
label && showLabel && /* @__PURE__ */ jsx("legend", { className: "text_field_label", children: /* @__PURE__ */ jsx("label", { htmlFor: inputId, children: label }) }),
|
|
2373
2346
|
/* @__PURE__ */ jsxs("div", { className: "text_field_inner", children: [
|
|
2374
2347
|
leadingIcon && /* @__PURE__ */ jsx("span", { className: "text_field_icon", "aria-hidden": "true", children: leadingIcon }),
|
|
2375
|
-
/* @__PURE__ */ jsx(
|
|
2376
|
-
"
|
|
2348
|
+
/* @__PURE__ */ jsx(
|
|
2349
|
+
"div",
|
|
2377
2350
|
{
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2351
|
+
className: cn(
|
|
2352
|
+
"text_field_input_wrap",
|
|
2353
|
+
resolvedTrailing && "text_field_input_wrap_no_pad_right"
|
|
2354
|
+
),
|
|
2355
|
+
children: /* @__PURE__ */ jsx(
|
|
2356
|
+
"input",
|
|
2357
|
+
{
|
|
2358
|
+
id: inputId,
|
|
2359
|
+
ref,
|
|
2360
|
+
className: "text_field_input",
|
|
2361
|
+
"aria-invalid": !!error,
|
|
2362
|
+
"aria-describedby": helperId,
|
|
2363
|
+
"aria-label": !showLabel ? label : void 0,
|
|
2364
|
+
...props,
|
|
2365
|
+
value: innerValue,
|
|
2366
|
+
onCompositionStart: () => {
|
|
2367
|
+
isComposingRef.current = true;
|
|
2368
|
+
},
|
|
2369
|
+
onCompositionEnd: (event) => {
|
|
2370
|
+
isComposingRef.current = false;
|
|
2371
|
+
const rawValue = event.currentTarget.value;
|
|
2372
|
+
const nextValue = applyTransform(rawValue);
|
|
2373
|
+
setInnerValue(nextValue);
|
|
2374
|
+
onChangeAction?.(nextValue);
|
|
2375
|
+
},
|
|
2376
|
+
onChange: (event) => {
|
|
2377
|
+
const rawValue = event.target.value;
|
|
2378
|
+
if (isComposingRef.current) {
|
|
2379
|
+
setInnerValue(rawValue);
|
|
2380
|
+
return;
|
|
2381
|
+
}
|
|
2382
|
+
const nextValue = applyTransform(rawValue);
|
|
2383
|
+
setInnerValue(nextValue);
|
|
2384
|
+
onChangeAction?.(nextValue);
|
|
2385
|
+
}
|
|
2401
2386
|
}
|
|
2402
|
-
|
|
2403
|
-
setInnerValue(nextValue);
|
|
2404
|
-
onChangeAction?.(nextValue);
|
|
2405
|
-
}
|
|
2387
|
+
)
|
|
2406
2388
|
}
|
|
2407
|
-
)
|
|
2389
|
+
),
|
|
2408
2390
|
resolvedTrailing
|
|
2409
2391
|
] })
|
|
2410
2392
|
] }),
|
|
@@ -2412,7 +2394,7 @@ var TextField = ({
|
|
|
2412
2394
|
] });
|
|
2413
2395
|
};
|
|
2414
2396
|
TextField.displayName = "TextField";
|
|
2415
|
-
var ToastContext =
|
|
2397
|
+
var ToastContext = React4.createContext(null);
|
|
2416
2398
|
var VARIANT_ICONS = {
|
|
2417
2399
|
success: /* @__PURE__ */ jsx(CheckCircle2, { size: 18 }),
|
|
2418
2400
|
error: /* @__PURE__ */ jsx(XCircle, { size: 18 }),
|
|
@@ -2421,9 +2403,9 @@ var VARIANT_ICONS = {
|
|
|
2421
2403
|
default: /* @__PURE__ */ jsx(Bell, { size: 18 })
|
|
2422
2404
|
};
|
|
2423
2405
|
var ToastItemComponent = ({ item, onRemove, closeAriaLabel }) => {
|
|
2424
|
-
const [exiting, setExiting] =
|
|
2425
|
-
const closingRef =
|
|
2426
|
-
const close =
|
|
2406
|
+
const [exiting, setExiting] = React4.useState(false);
|
|
2407
|
+
const closingRef = React4.useRef(false);
|
|
2408
|
+
const close = React4.useCallback(() => {
|
|
2427
2409
|
if (closingRef.current) return;
|
|
2428
2410
|
closingRef.current = true;
|
|
2429
2411
|
setExiting(true);
|
|
@@ -2450,24 +2432,25 @@ var ToastProvider = ({
|
|
|
2450
2432
|
maxCount = 5,
|
|
2451
2433
|
closeAriaLabel = "Close"
|
|
2452
2434
|
}) => {
|
|
2453
|
-
const [toasts, setToasts] =
|
|
2454
|
-
const [isMounted, setIsMounted] =
|
|
2455
|
-
|
|
2435
|
+
const [toasts, setToasts] = React4.useState([]);
|
|
2436
|
+
const [isMounted, setIsMounted] = React4.useState(false);
|
|
2437
|
+
React4.useEffect(() => {
|
|
2456
2438
|
setIsMounted(true);
|
|
2457
2439
|
}, []);
|
|
2458
|
-
const addToast =
|
|
2440
|
+
const addToast = React4.useCallback(
|
|
2459
2441
|
(message, variant, duration = 3e3) => {
|
|
2460
2442
|
const id = crypto.randomUUID();
|
|
2461
2443
|
setToasts((prev) => [{ id, message, variant, duration }, ...prev].slice(0, maxCount));
|
|
2462
2444
|
},
|
|
2463
2445
|
[maxCount]
|
|
2464
2446
|
);
|
|
2465
|
-
const removeToast =
|
|
2447
|
+
const removeToast = React4.useCallback((id) => {
|
|
2466
2448
|
setToasts((prev) => prev.filter((t) => t.id !== id));
|
|
2467
2449
|
}, []);
|
|
2468
2450
|
return /* @__PURE__ */ jsxs(ToastContext.Provider, { value: { addToast }, children: [
|
|
2469
2451
|
children,
|
|
2470
2452
|
isMounted && createPortal(
|
|
2453
|
+
// biome-ignore lint/a11y/useSemanticElements: <section> would create unwanted nesting in portal; role=region is the WAI-ARIA equivalent for live announcements
|
|
2471
2454
|
/* @__PURE__ */ jsx(
|
|
2472
2455
|
"div",
|
|
2473
2456
|
{
|
|
@@ -2509,6 +2492,49 @@ var useToast = () => {
|
|
|
2509
2492
|
message: (message, duration) => ctx.addToast(message, "default", duration)
|
|
2510
2493
|
};
|
|
2511
2494
|
};
|
|
2495
|
+
var Toggle = ({
|
|
2496
|
+
checked,
|
|
2497
|
+
defaultChecked,
|
|
2498
|
+
onChange,
|
|
2499
|
+
size = "sm",
|
|
2500
|
+
disabled,
|
|
2501
|
+
className,
|
|
2502
|
+
ariaLabel,
|
|
2503
|
+
ref,
|
|
2504
|
+
...props
|
|
2505
|
+
}) => {
|
|
2506
|
+
const isControlled = checked !== void 0;
|
|
2507
|
+
const [innerChecked, setInnerChecked] = React4.useState(!!defaultChecked);
|
|
2508
|
+
const isOn = isControlled ? !!checked : innerChecked;
|
|
2509
|
+
const handleToggle = () => {
|
|
2510
|
+
if (disabled) return;
|
|
2511
|
+
const next = !isOn;
|
|
2512
|
+
if (!isControlled) setInnerChecked(next);
|
|
2513
|
+
onChange?.(next);
|
|
2514
|
+
};
|
|
2515
|
+
const rootClassName = cn(
|
|
2516
|
+
"toggle",
|
|
2517
|
+
`toggle_size_${size}`,
|
|
2518
|
+
{ toggle_on: isOn, toggle_disabled: disabled },
|
|
2519
|
+
className
|
|
2520
|
+
);
|
|
2521
|
+
return /* @__PURE__ */ jsx(
|
|
2522
|
+
"button",
|
|
2523
|
+
{
|
|
2524
|
+
ref,
|
|
2525
|
+
type: "button",
|
|
2526
|
+
role: "switch",
|
|
2527
|
+
"aria-checked": isOn,
|
|
2528
|
+
"aria-label": ariaLabel,
|
|
2529
|
+
disabled,
|
|
2530
|
+
onClick: handleToggle,
|
|
2531
|
+
className: rootClassName,
|
|
2532
|
+
...props,
|
|
2533
|
+
children: /* @__PURE__ */ jsx("span", { className: "toggle_thumb" })
|
|
2534
|
+
}
|
|
2535
|
+
);
|
|
2536
|
+
};
|
|
2537
|
+
Toggle.displayName = "Toggle";
|
|
2512
2538
|
var TopLoading = ({
|
|
2513
2539
|
progress,
|
|
2514
2540
|
color,
|