@bigtablet/design-system 1.24.1 → 1.25.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/README.md +10 -32
- package/dist/index.css +1466 -811
- package/dist/index.d.ts +330 -215
- package/dist/index.js +872 -584
- package/dist/styles/{scss/_a11y.scss → a11y/_index.scss} +1 -1
- package/dist/styles/border-width/_index.scss +11 -0
- package/dist/styles/{scss/_colors.scss → colors/_index.scss} +8 -0
- package/dist/styles/elevation/_index.scss +5 -0
- package/dist/styles/opacity/_index.scss +12 -0
- package/dist/styles/{scss/token.scss → token.scss} +3 -1
- package/dist/styles/{scss/_typography.scss → typography/_index.scss} +9 -2
- package/dist/vanilla/bigtablet.min.css +1 -1
- package/package.json +8 -14
- package/dist/next.css +0 -133
- package/dist/next.d.ts +0 -53
- package/dist/next.js +0 -148
- package/dist/styles/scss/_shadows.scss +0 -5
- /package/dist/styles/{scss/_breakpoints.scss → breakpoints/_index.scss} +0 -0
- /package/dist/styles/{scss/_layout.scss → layout/_index.scss} +0 -0
- /package/dist/styles/{scss/_motion.scss → motion/_index.scss} +0 -0
- /package/dist/styles/{scss/_radius.scss → radius/_index.scss} +0 -0
- /package/dist/styles/{scss/_skeleton.scss → skeleton/_index.scss} +0 -0
- /package/dist/styles/{scss/_spacing.scss → spacing/_index.scss} +0 -0
- /package/dist/styles/{scss/_z-index.scss → z-index/_index.scss} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
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
|
-
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
6
5
|
import { createPortal } from 'react-dom';
|
|
6
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
7
7
|
import { ChevronDown, Check, X, Bell, Info, AlertTriangle, XCircle, CheckCircle2 } from 'lucide-react';
|
|
8
8
|
|
|
9
|
-
// src/styles/
|
|
9
|
+
// src/styles/a11y/index.ts
|
|
10
10
|
var a11y = {
|
|
11
11
|
focusRing: "0 0 0 3px rgba(0, 0, 0, 0.15)",
|
|
12
12
|
focusRingError: "0 0 0 3px rgba(239, 68, 68, 0.15)",
|
|
@@ -14,7 +14,7 @@ var a11y = {
|
|
|
14
14
|
tapMinSize: "44px"
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
// src/styles/
|
|
17
|
+
// src/styles/border-width/index.ts
|
|
18
18
|
var baseBorderWidth = {
|
|
19
19
|
"0": "0px",
|
|
20
20
|
"1": "1px",
|
|
@@ -26,7 +26,7 @@ var borderWidth = {
|
|
|
26
26
|
indicator: baseBorderWidth["2"]
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
// src/styles/
|
|
29
|
+
// src/styles/breakpoints/index.ts
|
|
30
30
|
var breakpoints = {
|
|
31
31
|
compact: 0,
|
|
32
32
|
// mobile
|
|
@@ -38,7 +38,7 @@ var breakpoints = {
|
|
|
38
38
|
// desktop
|
|
39
39
|
};
|
|
40
40
|
|
|
41
|
-
// src/styles/
|
|
41
|
+
// src/styles/colors/index.ts
|
|
42
42
|
var baseColors = {
|
|
43
43
|
brandPrimary: "#121212",
|
|
44
44
|
blue600: "#1A73E8",
|
|
@@ -48,6 +48,7 @@ var baseColors = {
|
|
|
48
48
|
neutral300: "#999999",
|
|
49
49
|
neutral400: "#B3B3B3",
|
|
50
50
|
neutral500: "#888888",
|
|
51
|
+
neutral600: "#6B6B6B",
|
|
51
52
|
neutral700: "#666666",
|
|
52
53
|
neutral900: "#121212",
|
|
53
54
|
statusError: "#EF4444",
|
|
@@ -104,7 +105,7 @@ var colors = {
|
|
|
104
105
|
}
|
|
105
106
|
};
|
|
106
107
|
|
|
107
|
-
// src/styles/
|
|
108
|
+
// src/styles/motion/index.ts
|
|
108
109
|
var motion = {
|
|
109
110
|
transition: {
|
|
110
111
|
fast: "0.1s ease-in-out",
|
|
@@ -119,7 +120,7 @@ var motion = {
|
|
|
119
120
|
}
|
|
120
121
|
};
|
|
121
122
|
|
|
122
|
-
// src/styles/
|
|
123
|
+
// src/styles/opacity/index.ts
|
|
123
124
|
var opacity = {
|
|
124
125
|
"0": 0,
|
|
125
126
|
"5": 0.05,
|
|
@@ -133,7 +134,7 @@ var opacity = {
|
|
|
133
134
|
"100": 1
|
|
134
135
|
};
|
|
135
136
|
|
|
136
|
-
// src/styles/
|
|
137
|
+
// src/styles/radius/index.ts
|
|
137
138
|
var radius = {
|
|
138
139
|
none: "0px",
|
|
139
140
|
xs: "4px",
|
|
@@ -144,8 +145,8 @@ var radius = {
|
|
|
144
145
|
full: "9999px"
|
|
145
146
|
};
|
|
146
147
|
|
|
147
|
-
// src/styles/
|
|
148
|
-
var
|
|
148
|
+
// src/styles/elevation/index.ts
|
|
149
|
+
var elevation = {
|
|
149
150
|
level1: "0 1px 1px -1px rgba(0, 0, 0, 0.20), 0 3px 3px 0px rgba(0, 0, 0, 0.12)",
|
|
150
151
|
level2: "0 2px 2px -2px rgba(0, 0, 0, 0.20), 0 6px 6px 0px rgba(0, 0, 0, 0.12)",
|
|
151
152
|
level3: "0 3px 3px -3px rgba(0, 0, 0, 0.20), 0 9px 9px 0px rgba(0, 0, 0, 0.12)",
|
|
@@ -153,7 +154,7 @@ var shadows = {
|
|
|
153
154
|
level5: "0 8px 10px -5px rgba(0, 0, 0, 0.20), 0 20px 20px 0px rgba(0, 0, 0, 0.12)"
|
|
154
155
|
};
|
|
155
156
|
|
|
156
|
-
// src/styles/
|
|
157
|
+
// src/styles/spacing/index.ts
|
|
157
158
|
var spacing = {
|
|
158
159
|
"0": "0px",
|
|
159
160
|
"1": "1px",
|
|
@@ -171,7 +172,7 @@ var spacing = {
|
|
|
171
172
|
"48": "48px"
|
|
172
173
|
};
|
|
173
174
|
|
|
174
|
-
// src/styles/
|
|
175
|
+
// src/styles/skeleton/index.ts
|
|
175
176
|
var skeleton = {
|
|
176
177
|
color: {
|
|
177
178
|
base: baseColors.neutral50,
|
|
@@ -197,7 +198,7 @@ var skeleton = {
|
|
|
197
198
|
}
|
|
198
199
|
};
|
|
199
200
|
|
|
200
|
-
// src/styles/
|
|
201
|
+
// src/styles/typography/index.ts
|
|
201
202
|
var baseTypography = {
|
|
202
203
|
fontFamily: {
|
|
203
204
|
primary: "Pretendard"
|
|
@@ -217,8 +218,15 @@ var baseTypography = {
|
|
|
217
218
|
"48": "48px"
|
|
218
219
|
},
|
|
219
220
|
fontWeight: {
|
|
221
|
+
thin: "Thin",
|
|
222
|
+
extraLight: "ExtraLight",
|
|
223
|
+
light: "Light",
|
|
220
224
|
regular: "Regular",
|
|
221
|
-
medium: "Medium"
|
|
225
|
+
medium: "Medium",
|
|
226
|
+
semiBold: "SemiBold",
|
|
227
|
+
bold: "Bold",
|
|
228
|
+
extraBold: "ExtraBold",
|
|
229
|
+
black: "Black"
|
|
222
230
|
},
|
|
223
231
|
lineHeight: {
|
|
224
232
|
"16": "16px",
|
|
@@ -434,7 +442,7 @@ var typography = {
|
|
|
434
442
|
}
|
|
435
443
|
};
|
|
436
444
|
|
|
437
|
-
// src/styles/
|
|
445
|
+
// src/styles/z-index/index.ts
|
|
438
446
|
var zIndex = {
|
|
439
447
|
level0: 0,
|
|
440
448
|
level1: 10,
|
|
@@ -475,8 +483,8 @@ var FOCUSABLE_SELECTORS = [
|
|
|
475
483
|
'[tabindex]:not([tabindex="-1"])'
|
|
476
484
|
].join(", ");
|
|
477
485
|
function useFocusTrap(containerRef, isActive) {
|
|
478
|
-
const previousActiveElement =
|
|
479
|
-
|
|
486
|
+
const previousActiveElement = React4.useRef(null);
|
|
487
|
+
React4.useEffect(() => {
|
|
480
488
|
if (!isActive) return;
|
|
481
489
|
const container = containerRef.current;
|
|
482
490
|
if (!container) return;
|
|
@@ -524,28 +532,6 @@ function useFocusTrap(containerRef, isActive) {
|
|
|
524
532
|
};
|
|
525
533
|
}, [isActive, containerRef]);
|
|
526
534
|
}
|
|
527
|
-
var Card = ({
|
|
528
|
-
heading,
|
|
529
|
-
headingAs: HeadingTag = "h3",
|
|
530
|
-
shadow = "sm",
|
|
531
|
-
padding = "md",
|
|
532
|
-
bordered = false,
|
|
533
|
-
className,
|
|
534
|
-
children,
|
|
535
|
-
...props
|
|
536
|
-
}) => {
|
|
537
|
-
const cardClassName = cn(
|
|
538
|
-
"card",
|
|
539
|
-
`card_shadow_${shadow}`,
|
|
540
|
-
`card_p_${padding}`,
|
|
541
|
-
{ card_bordered: bordered },
|
|
542
|
-
className
|
|
543
|
-
);
|
|
544
|
-
return /* @__PURE__ */ jsxs("div", { className: cardClassName, ...props, children: [
|
|
545
|
-
heading ? /* @__PURE__ */ jsx(HeadingTag, { className: "card_title", children: heading }) : null,
|
|
546
|
-
/* @__PURE__ */ jsx("div", { className: "card_body", children })
|
|
547
|
-
] });
|
|
548
|
-
};
|
|
549
535
|
var AlertContext = createContext(null);
|
|
550
536
|
var useAlert = () => {
|
|
551
537
|
const context = useContext(AlertContext);
|
|
@@ -603,10 +589,12 @@ var AlertModal = ({
|
|
|
603
589
|
onCancel,
|
|
604
590
|
onClose
|
|
605
591
|
}) => {
|
|
606
|
-
const panelRef =
|
|
592
|
+
const panelRef = React4.useRef(null);
|
|
593
|
+
const titleId = React4.useId();
|
|
594
|
+
const messageId = React4.useId();
|
|
607
595
|
useFocusTrap(panelRef, true);
|
|
608
|
-
const modalClassName =
|
|
609
|
-
const actionsClassName =
|
|
596
|
+
const modalClassName = cn("alert_modal", `alert_variant_${variant}`);
|
|
597
|
+
const actionsClassName = cn("alert_actions", `alert_actions_${actionsAlign}`);
|
|
610
598
|
return /* @__PURE__ */ jsx(
|
|
611
599
|
"div",
|
|
612
600
|
{
|
|
@@ -625,11 +613,11 @@ var AlertModal = ({
|
|
|
625
613
|
},
|
|
626
614
|
role: "alertdialog",
|
|
627
615
|
"aria-modal": "true",
|
|
628
|
-
"aria-labelledby":
|
|
629
|
-
"aria-describedby":
|
|
616
|
+
"aria-labelledby": titleId,
|
|
617
|
+
"aria-describedby": messageId,
|
|
630
618
|
children: [
|
|
631
|
-
title && /* @__PURE__ */ jsx("div", { className: "alert_title", id:
|
|
632
|
-
message && /* @__PURE__ */ jsx("div", { className: "alert_message", id:
|
|
619
|
+
title && /* @__PURE__ */ jsx("div", { className: "alert_title", id: titleId, children: title }),
|
|
620
|
+
message && /* @__PURE__ */ jsx("div", { className: "alert_message", id: messageId, children: message }),
|
|
633
621
|
/* @__PURE__ */ jsxs("div", { className: actionsClassName, children: [
|
|
634
622
|
showCancel && /* @__PURE__ */ jsx("button", { type: "button", className: "alert_button alert_button_cancel", onClick: onCancel, children: cancelText }),
|
|
635
623
|
/* @__PURE__ */ jsx("button", { type: "button", className: "alert_button alert_button_confirm", onClick: onConfirm, children: confirmText })
|
|
@@ -640,178 +628,156 @@ var AlertModal = ({
|
|
|
640
628
|
}
|
|
641
629
|
);
|
|
642
630
|
};
|
|
643
|
-
var
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
}
|
|
652
|
-
);
|
|
653
|
-
};
|
|
654
|
-
var ToastContext = React9.createContext(null);
|
|
655
|
-
var VARIANT_ICONS = {
|
|
656
|
-
success: /* @__PURE__ */ jsx(CheckCircle2, { size: 18 }),
|
|
657
|
-
error: /* @__PURE__ */ jsx(XCircle, { size: 18 }),
|
|
658
|
-
warning: /* @__PURE__ */ jsx(AlertTriangle, { size: 18 }),
|
|
659
|
-
info: /* @__PURE__ */ jsx(Info, { size: 18 }),
|
|
660
|
-
default: /* @__PURE__ */ jsx(Bell, { size: 18 })
|
|
661
|
-
};
|
|
662
|
-
var ToastItemComponent = ({ item, onRemove, closeAriaLabel }) => {
|
|
663
|
-
const [exiting, setExiting] = React9.useState(false);
|
|
664
|
-
const closingRef = React9.useRef(false);
|
|
665
|
-
const close = React9.useCallback(() => {
|
|
666
|
-
if (closingRef.current) return;
|
|
667
|
-
closingRef.current = true;
|
|
668
|
-
setExiting(true);
|
|
669
|
-
setTimeout(() => onRemove(item.id), 260);
|
|
670
|
-
}, [item.id, onRemove]);
|
|
671
|
-
const itemClassName = ["toast_item", exiting && "toast_item_exiting"].filter(Boolean).join(" ");
|
|
672
|
-
return /* @__PURE__ */ jsxs("div", { className: itemClassName, role: item.variant === "error" ? "alert" : "status", children: [
|
|
673
|
-
/* @__PURE__ */ jsx("span", { className: `toast_icon toast_icon_${item.variant}`, "aria-hidden": "true", children: VARIANT_ICONS[item.variant] }),
|
|
674
|
-
/* @__PURE__ */ jsx("span", { className: "toast_message", children: item.message }),
|
|
675
|
-
/* @__PURE__ */ jsx("button", { type: "button", className: "toast_close", onClick: close, "aria-label": closeAriaLabel, children: /* @__PURE__ */ jsx(X, { size: 14 }) }),
|
|
676
|
-
/* @__PURE__ */ jsx(
|
|
677
|
-
"div",
|
|
678
|
-
{
|
|
679
|
-
className: `toast_progress toast_progress_${item.variant}`,
|
|
680
|
-
style: { "--toast-duration": `${item.duration}ms` },
|
|
681
|
-
onAnimationEnd: close,
|
|
682
|
-
"aria-hidden": "true"
|
|
683
|
-
}
|
|
684
|
-
)
|
|
685
|
-
] });
|
|
686
|
-
};
|
|
687
|
-
var ToastProvider = ({
|
|
631
|
+
var Button = ({
|
|
632
|
+
variant = "filled",
|
|
633
|
+
size = "md",
|
|
634
|
+
leadingIcon,
|
|
635
|
+
trailingIcon,
|
|
636
|
+
fullWidth = false,
|
|
637
|
+
radius: radius2,
|
|
638
|
+
className,
|
|
688
639
|
children,
|
|
689
|
-
|
|
690
|
-
closeAriaLabel = "Close"
|
|
640
|
+
...props
|
|
691
641
|
}) => {
|
|
692
|
-
const
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
const id = crypto.randomUUID();
|
|
700
|
-
setToasts((prev) => [{ id, message, variant, duration }, ...prev].slice(0, maxCount));
|
|
701
|
-
},
|
|
702
|
-
[maxCount]
|
|
642
|
+
const buttonClassName = cn(
|
|
643
|
+
"button",
|
|
644
|
+
`button_variant_${variant}`,
|
|
645
|
+
`button_size_${size}`,
|
|
646
|
+
fullWidth && "button_full_width",
|
|
647
|
+
radius2 && `button_radius_${radius2}`,
|
|
648
|
+
className
|
|
703
649
|
);
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
children,
|
|
709
|
-
isMounted && createPortal(
|
|
710
|
-
/* @__PURE__ */ jsx(
|
|
711
|
-
"div",
|
|
712
|
-
{
|
|
713
|
-
className: "toast_container",
|
|
714
|
-
role: "region",
|
|
715
|
-
"aria-live": "polite",
|
|
716
|
-
"aria-atomic": "false",
|
|
717
|
-
"aria-label": "Notifications",
|
|
718
|
-
children: toasts.map((item) => /* @__PURE__ */ jsx(
|
|
719
|
-
ToastItemComponent,
|
|
720
|
-
{
|
|
721
|
-
item,
|
|
722
|
-
onRemove: removeToast,
|
|
723
|
-
closeAriaLabel
|
|
724
|
-
},
|
|
725
|
-
item.id
|
|
726
|
-
))
|
|
727
|
-
}
|
|
728
|
-
),
|
|
729
|
-
document.body
|
|
730
|
-
)
|
|
650
|
+
return /* @__PURE__ */ jsxs("button", { className: buttonClassName, ...props, children: [
|
|
651
|
+
leadingIcon && /* @__PURE__ */ jsx("span", { className: "button_icon", "aria-hidden": "true", children: leadingIcon }),
|
|
652
|
+
children && /* @__PURE__ */ jsx("span", { className: "button_label", children }),
|
|
653
|
+
trailingIcon && /* @__PURE__ */ jsx("span", { className: "button_icon", "aria-hidden": "true", children: trailingIcon })
|
|
731
654
|
] });
|
|
732
655
|
};
|
|
733
|
-
var
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
error: (message, duration) => ctx.addToast(message, "error", duration),
|
|
743
|
-
/** 경고 메시지를 표시한다 */
|
|
744
|
-
warning: (message, duration) => ctx.addToast(message, "warning", duration),
|
|
745
|
-
/** 정보 메시지를 표시한다 */
|
|
746
|
-
info: (message, duration) => ctx.addToast(message, "info", duration),
|
|
747
|
-
/** 기본 메시지를 표시한다 */
|
|
748
|
-
message: (message, duration) => ctx.addToast(message, "default", duration)
|
|
749
|
-
};
|
|
750
|
-
};
|
|
751
|
-
var TopLoading = ({
|
|
752
|
-
progress,
|
|
753
|
-
color,
|
|
754
|
-
height = 3,
|
|
755
|
-
isLoading = true,
|
|
756
|
-
ariaLabel = "Page loading"
|
|
656
|
+
var Card = ({
|
|
657
|
+
heading,
|
|
658
|
+
headingAs: HeadingTag = "h3",
|
|
659
|
+
shadow = "sm",
|
|
660
|
+
padding = "md",
|
|
661
|
+
bordered = false,
|
|
662
|
+
className,
|
|
663
|
+
children,
|
|
664
|
+
...props
|
|
757
665
|
}) => {
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
{
|
|
763
|
-
|
|
764
|
-
style: { height },
|
|
765
|
-
role: "progressbar",
|
|
766
|
-
"aria-valuemin": 0,
|
|
767
|
-
"aria-valuemax": 100,
|
|
768
|
-
"aria-valuenow": isIndeterminate ? void 0 : progress,
|
|
769
|
-
"aria-label": ariaLabel,
|
|
770
|
-
children: /* @__PURE__ */ jsx(
|
|
771
|
-
"div",
|
|
772
|
-
{
|
|
773
|
-
className: ["top_loading_bar", isIndeterminate && "top_loading_indeterminate"].filter(Boolean).join(" "),
|
|
774
|
-
style: {
|
|
775
|
-
width: isIndeterminate ? void 0 : `${progress}%`,
|
|
776
|
-
backgroundColor: color
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
)
|
|
780
|
-
}
|
|
666
|
+
const cardClassName = cn(
|
|
667
|
+
"card",
|
|
668
|
+
`card_shadow_${shadow}`,
|
|
669
|
+
`card_p_${padding}`,
|
|
670
|
+
{ card_bordered: bordered },
|
|
671
|
+
className
|
|
781
672
|
);
|
|
673
|
+
return /* @__PURE__ */ jsxs("div", { className: cardClassName, ...props, children: [
|
|
674
|
+
heading ? /* @__PURE__ */ jsx(HeadingTag, { className: "card_title", children: heading }) : null,
|
|
675
|
+
/* @__PURE__ */ jsx("div", { className: "card_body", children })
|
|
676
|
+
] });
|
|
782
677
|
};
|
|
783
678
|
var Checkbox = ({
|
|
784
679
|
label,
|
|
785
|
-
size = "md",
|
|
786
680
|
indeterminate,
|
|
681
|
+
error,
|
|
787
682
|
className,
|
|
788
683
|
ref,
|
|
789
684
|
...props
|
|
790
685
|
}) => {
|
|
791
|
-
const inputRef =
|
|
792
|
-
|
|
793
|
-
|
|
686
|
+
const inputRef = React4.useRef(null);
|
|
687
|
+
React4.useImperativeHandle(
|
|
688
|
+
ref,
|
|
689
|
+
() => inputRef.current
|
|
690
|
+
);
|
|
691
|
+
React4.useEffect(() => {
|
|
794
692
|
if (!inputRef.current) return;
|
|
795
693
|
inputRef.current.indeterminate = Boolean(indeterminate);
|
|
796
694
|
}, [indeterminate]);
|
|
797
|
-
const rootClassName = cn(
|
|
695
|
+
const rootClassName = cn(
|
|
696
|
+
"checkbox",
|
|
697
|
+
error && "checkbox_error",
|
|
698
|
+
className
|
|
699
|
+
);
|
|
798
700
|
return /* @__PURE__ */ jsxs("label", { className: rootClassName, children: [
|
|
799
|
-
/* @__PURE__ */ jsx(
|
|
800
|
-
|
|
701
|
+
/* @__PURE__ */ jsx(
|
|
702
|
+
"input",
|
|
703
|
+
{
|
|
704
|
+
ref: inputRef,
|
|
705
|
+
type: "checkbox",
|
|
706
|
+
className: "checkbox_input",
|
|
707
|
+
...props
|
|
708
|
+
}
|
|
709
|
+
),
|
|
710
|
+
/* @__PURE__ */ jsx("span", { className: "checkbox_state_layer", "aria-hidden": "true", children: /* @__PURE__ */ jsx("span", { className: "checkbox_icon" }) }),
|
|
801
711
|
label ? /* @__PURE__ */ jsx("span", { className: "checkbox_label", children: label }) : null
|
|
802
712
|
] });
|
|
803
713
|
};
|
|
804
714
|
Checkbox.displayName = "Checkbox";
|
|
715
|
+
var CheckIcon = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 20 20", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("polyline", { points: "4 10 8 14 16 6" }) });
|
|
716
|
+
var CloseIcon = () => /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 20 20", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
717
|
+
/* @__PURE__ */ jsx("line", { x1: "6", y1: "6", x2: "14", y2: "14" }),
|
|
718
|
+
/* @__PURE__ */ jsx("line", { x1: "14", y1: "6", x2: "6", y2: "14" })
|
|
719
|
+
] });
|
|
720
|
+
var ChevronDownIcon = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 20 20", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx("polyline", { points: "5 8 10 13 15 8" }) });
|
|
721
|
+
var Chip = ({
|
|
722
|
+
type = "basic",
|
|
723
|
+
label,
|
|
724
|
+
selected,
|
|
725
|
+
removable,
|
|
726
|
+
disabled,
|
|
727
|
+
onClick,
|
|
728
|
+
onRemove,
|
|
729
|
+
className,
|
|
730
|
+
...props
|
|
731
|
+
}) => {
|
|
732
|
+
const hasLeading = selected;
|
|
733
|
+
const hasTrailing = type === "input" && removable || type === "filter";
|
|
734
|
+
const chipClassName = cn(
|
|
735
|
+
"chip",
|
|
736
|
+
`chip_type_${type}`,
|
|
737
|
+
selected && "chip_selected",
|
|
738
|
+
hasLeading && "chip_has_leading",
|
|
739
|
+
hasTrailing && "chip_has_trailing",
|
|
740
|
+
disabled && "chip_disabled",
|
|
741
|
+
className
|
|
742
|
+
);
|
|
743
|
+
return /* @__PURE__ */ jsxs("div", { className: chipClassName, ...props, children: [
|
|
744
|
+
/* @__PURE__ */ jsxs(
|
|
745
|
+
"button",
|
|
746
|
+
{
|
|
747
|
+
type: "button",
|
|
748
|
+
className: "chip_content",
|
|
749
|
+
disabled,
|
|
750
|
+
onClick,
|
|
751
|
+
children: [
|
|
752
|
+
hasLeading && /* @__PURE__ */ jsx("span", { className: "chip_icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx(CheckIcon, {}) }),
|
|
753
|
+
/* @__PURE__ */ jsx("span", { className: "chip_label", children: label })
|
|
754
|
+
]
|
|
755
|
+
}
|
|
756
|
+
),
|
|
757
|
+
hasTrailing && /* @__PURE__ */ jsx(
|
|
758
|
+
"button",
|
|
759
|
+
{
|
|
760
|
+
type: "button",
|
|
761
|
+
className: "chip_trailing",
|
|
762
|
+
disabled,
|
|
763
|
+
onClick: type === "input" && removable ? onRemove : onClick,
|
|
764
|
+
"aria-label": type === "input" && removable ? "Remove" : "Toggle dropdown",
|
|
765
|
+
children: /* @__PURE__ */ jsx("span", { className: "chip_icon", "aria-hidden": "true", children: type === "input" && removable ? /* @__PURE__ */ jsx(CloseIcon, {}) : /* @__PURE__ */ jsx(ChevronDownIcon, {}) })
|
|
766
|
+
}
|
|
767
|
+
)
|
|
768
|
+
] });
|
|
769
|
+
};
|
|
805
770
|
var pad = (n) => String(n).padStart(2, "0");
|
|
806
771
|
var getDaysInMonth = (year, month) => new Date(year, month, 0).getDate();
|
|
807
772
|
var normalizeWidth = (v) => typeof v === "number" ? `${v}px` : v;
|
|
773
|
+
var range = (start, end) => Array.from({ length: end - start + 1 }, (_, i) => start + i);
|
|
808
774
|
var DatePicker = ({
|
|
809
775
|
label,
|
|
810
776
|
value,
|
|
811
777
|
onChange,
|
|
812
778
|
mode = "year-month-day",
|
|
813
779
|
startYear = 1950,
|
|
814
|
-
endYear
|
|
780
|
+
endYear: endYearProp,
|
|
815
781
|
minDate,
|
|
816
782
|
selectableRange = "all",
|
|
817
783
|
disabled,
|
|
@@ -823,37 +789,108 @@ var DatePicker = ({
|
|
|
823
789
|
minDateSrFormat = "Minimum date: {date}",
|
|
824
790
|
selectableRangeUntilTodaySrText = "Selectable up to today"
|
|
825
791
|
}) => {
|
|
826
|
-
const groupId =
|
|
827
|
-
const constraintId =
|
|
828
|
-
const
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
const
|
|
792
|
+
const groupId = React4.useId();
|
|
793
|
+
const constraintId = React4.useId();
|
|
794
|
+
const { todayYear, todayMonth, todayDay } = React4.useMemo(() => {
|
|
795
|
+
const now = /* @__PURE__ */ new Date();
|
|
796
|
+
return {
|
|
797
|
+
todayYear: now.getFullYear(),
|
|
798
|
+
todayMonth: now.getMonth() + 1,
|
|
799
|
+
todayDay: now.getDate()
|
|
800
|
+
};
|
|
801
|
+
}, []);
|
|
802
|
+
const endYear = endYearProp ?? todayYear + 10;
|
|
803
|
+
const parsed = React4.useMemo(() => {
|
|
804
|
+
if (!value) return { year: 0, month: 0, day: 0 };
|
|
805
|
+
const [y, m, d] = value.split("-").map(Number);
|
|
806
|
+
return {
|
|
807
|
+
year: y || 0,
|
|
808
|
+
month: m || 0,
|
|
809
|
+
day: d || 0
|
|
810
|
+
};
|
|
811
|
+
}, [value]);
|
|
812
|
+
const min = React4.useMemo(() => {
|
|
813
|
+
if (!minDate) return { year: 0, month: 0, day: 0 };
|
|
814
|
+
const [y, m, d] = minDate.split("-").map(Number);
|
|
815
|
+
return {
|
|
816
|
+
year: y || 0,
|
|
817
|
+
month: m || 0,
|
|
818
|
+
day: d || 0
|
|
819
|
+
};
|
|
820
|
+
}, [minDate]);
|
|
821
|
+
const { year, month, day } = parsed;
|
|
837
822
|
const maxYear = selectableRange === "until-today" ? todayYear : endYear;
|
|
838
|
-
const minMonth =
|
|
823
|
+
const minMonth = min.year > 0 && year === min.year ? min.month : 1;
|
|
839
824
|
const maxMonth = selectableRange === "until-today" && year === todayYear ? todayMonth : 12;
|
|
840
|
-
const minDay =
|
|
841
|
-
const maxDay =
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
onChange(`${yy}-${pad(mm)}`);
|
|
847
|
-
return;
|
|
825
|
+
const minDay = min.year > 0 && min.month > 0 && year === min.year && month === min.month ? min.day : 1;
|
|
826
|
+
const maxDay = React4.useMemo(() => {
|
|
827
|
+
if (!year || !month) return 31;
|
|
828
|
+
const daysInMonth = getDaysInMonth(year, month);
|
|
829
|
+
if (selectableRange === "until-today" && year === todayYear && month === todayMonth) {
|
|
830
|
+
return Math.min(daysInMonth, todayDay);
|
|
848
831
|
}
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
832
|
+
return daysInMonth;
|
|
833
|
+
}, [year, month, selectableRange, todayYear, todayMonth, todayDay]);
|
|
834
|
+
const yearOptions = React4.useMemo(
|
|
835
|
+
() => range(startYear, maxYear),
|
|
836
|
+
[startYear, maxYear]
|
|
837
|
+
);
|
|
838
|
+
const monthOptions = React4.useMemo(
|
|
839
|
+
() => range(minMonth, Math.max(minMonth, maxMonth)),
|
|
840
|
+
[minMonth, maxMonth]
|
|
841
|
+
);
|
|
842
|
+
const dayOptions = React4.useMemo(
|
|
843
|
+
() => range(minDay, Math.max(minDay, maxDay)),
|
|
844
|
+
[minDay, maxDay]
|
|
845
|
+
);
|
|
846
|
+
const emit = React4.useCallback(
|
|
847
|
+
(yy, mm, dd) => {
|
|
848
|
+
if (mode === "year-month") {
|
|
849
|
+
onChange(`${yy}-${pad(mm)}`);
|
|
850
|
+
return;
|
|
851
|
+
}
|
|
852
|
+
const safeDay = Math.min(dd ?? 1, getDaysInMonth(yy, mm));
|
|
853
|
+
onChange(`${yy}-${pad(mm)}-${pad(safeDay)}`);
|
|
854
|
+
},
|
|
855
|
+
[mode, onChange]
|
|
856
|
+
);
|
|
857
|
+
const handleYearChange = React4.useCallback(
|
|
858
|
+
(newYear) => {
|
|
859
|
+
let newMonth = month;
|
|
860
|
+
const newMinMonth = min.year > 0 && newYear === min.year ? min.month : 1;
|
|
861
|
+
const newMaxMonth = selectableRange === "until-today" && newYear === todayYear ? todayMonth : 12;
|
|
862
|
+
if (newMonth > 0 && newMonth < newMinMonth) newMonth = newMinMonth;
|
|
863
|
+
if (newMonth > newMaxMonth) newMonth = newMaxMonth;
|
|
864
|
+
if (newMonth > 0) {
|
|
865
|
+
emit(newYear, newMonth, day || void 0);
|
|
866
|
+
} else {
|
|
867
|
+
emit(newYear, newMinMonth, day || void 0);
|
|
868
|
+
}
|
|
869
|
+
},
|
|
870
|
+
[month, day, min.year, min.month, selectableRange, todayYear, todayMonth, emit]
|
|
871
|
+
);
|
|
872
|
+
const handleMonthChange = React4.useCallback(
|
|
873
|
+
(newMonth) => {
|
|
874
|
+
if (!year) return;
|
|
875
|
+
emit(year, newMonth, day || void 0);
|
|
876
|
+
},
|
|
877
|
+
[year, day, emit]
|
|
878
|
+
);
|
|
879
|
+
const handleDayChange = React4.useCallback(
|
|
880
|
+
(newDay) => {
|
|
881
|
+
if (!year || !month) return;
|
|
882
|
+
emit(year, month, newDay);
|
|
883
|
+
},
|
|
884
|
+
[year, month, emit]
|
|
885
|
+
);
|
|
852
886
|
const containerStyle = width ? { width: normalizeWidth(width) } : void 0;
|
|
853
|
-
const rootClassName = cn("date_picker", {
|
|
887
|
+
const rootClassName = cn("date_picker", {
|
|
888
|
+
date_picker_full_width: fullWidth && !width
|
|
889
|
+
});
|
|
854
890
|
const constraintParts = [];
|
|
855
891
|
if (minDate) constraintParts.push(minDateSrFormat.replace("{date}", minDate));
|
|
856
|
-
if (selectableRange === "until-today")
|
|
892
|
+
if (selectableRange === "until-today")
|
|
893
|
+
constraintParts.push(selectableRangeUntilTodaySrText);
|
|
857
894
|
const constraintDesc = constraintParts.join(". ");
|
|
858
895
|
return /* @__PURE__ */ jsxs("div", { className: rootClassName, style: containerStyle, children: [
|
|
859
896
|
label && /* @__PURE__ */ jsx("span", { className: "date_picker_label", id: groupId, children: label }),
|
|
@@ -870,12 +907,12 @@ var DatePicker = ({
|
|
|
870
907
|
"select",
|
|
871
908
|
{
|
|
872
909
|
"aria-label": yearLabel,
|
|
873
|
-
value: year,
|
|
910
|
+
value: year || "",
|
|
874
911
|
disabled,
|
|
875
|
-
onChange: (e) =>
|
|
912
|
+
onChange: (e) => handleYearChange(Number(e.target.value)),
|
|
876
913
|
children: [
|
|
877
914
|
/* @__PURE__ */ jsx("option", { value: "", children: yearLabel }),
|
|
878
|
-
|
|
915
|
+
yearOptions.map((y) => /* @__PURE__ */ jsx("option", { value: y, children: y }, y))
|
|
879
916
|
]
|
|
880
917
|
}
|
|
881
918
|
),
|
|
@@ -883,12 +920,12 @@ var DatePicker = ({
|
|
|
883
920
|
"select",
|
|
884
921
|
{
|
|
885
922
|
"aria-label": monthLabel,
|
|
886
|
-
value: month,
|
|
923
|
+
value: month || "",
|
|
887
924
|
disabled: disabled || !year,
|
|
888
|
-
onChange: (e) =>
|
|
925
|
+
onChange: (e) => handleMonthChange(Number(e.target.value)),
|
|
889
926
|
children: [
|
|
890
927
|
/* @__PURE__ */ jsx("option", { value: "", children: monthLabel }),
|
|
891
|
-
|
|
928
|
+
monthOptions.map((m) => /* @__PURE__ */ jsx("option", { value: m, children: pad(m) }, m))
|
|
892
929
|
]
|
|
893
930
|
}
|
|
894
931
|
),
|
|
@@ -896,12 +933,12 @@ var DatePicker = ({
|
|
|
896
933
|
"select",
|
|
897
934
|
{
|
|
898
935
|
"aria-label": dayLabel,
|
|
899
|
-
value: day,
|
|
936
|
+
value: day || "",
|
|
900
937
|
disabled: disabled || !month,
|
|
901
|
-
onChange: (e) =>
|
|
938
|
+
onChange: (e) => handleDayChange(Number(e.target.value)),
|
|
902
939
|
children: [
|
|
903
940
|
/* @__PURE__ */ jsx("option", { value: "", children: dayLabel }),
|
|
904
|
-
|
|
941
|
+
dayOptions.map((d) => /* @__PURE__ */ jsx("option", { value: d, children: pad(d) }, d))
|
|
905
942
|
]
|
|
906
943
|
}
|
|
907
944
|
)
|
|
@@ -910,17 +947,66 @@ var DatePicker = ({
|
|
|
910
947
|
)
|
|
911
948
|
] });
|
|
912
949
|
};
|
|
950
|
+
var Divider = ({
|
|
951
|
+
weight = "standard",
|
|
952
|
+
className,
|
|
953
|
+
...props
|
|
954
|
+
}) => {
|
|
955
|
+
const dividerClassName = cn(
|
|
956
|
+
"divider",
|
|
957
|
+
`divider_weight_${weight}`,
|
|
958
|
+
className
|
|
959
|
+
);
|
|
960
|
+
return /* @__PURE__ */ jsx("hr", { className: dividerClassName, ...props });
|
|
961
|
+
};
|
|
962
|
+
var FAB = ({
|
|
963
|
+
variant = "primary",
|
|
964
|
+
icon,
|
|
965
|
+
className,
|
|
966
|
+
...props
|
|
967
|
+
}) => {
|
|
968
|
+
const fabClassName = cn(
|
|
969
|
+
"fab",
|
|
970
|
+
`fab_variant_${variant}`,
|
|
971
|
+
className
|
|
972
|
+
);
|
|
973
|
+
return /* @__PURE__ */ jsx("button", { className: fabClassName, ...props, children: /* @__PURE__ */ jsx("span", { className: "fab_icon", "aria-hidden": "true", children: icon }) });
|
|
974
|
+
};
|
|
913
975
|
var FileInput = ({
|
|
914
976
|
label = "Choose file",
|
|
915
977
|
onFiles,
|
|
916
|
-
|
|
978
|
+
supportingText,
|
|
979
|
+
preview = false,
|
|
917
980
|
className,
|
|
918
981
|
disabled,
|
|
919
982
|
...props
|
|
920
983
|
}) => {
|
|
921
|
-
const inputId =
|
|
922
|
-
const helperId =
|
|
923
|
-
const
|
|
984
|
+
const inputId = React4.useId();
|
|
985
|
+
const helperId = React4.useId();
|
|
986
|
+
const [previewUrls, setPreviewUrls] = React4.useState([]);
|
|
987
|
+
const handleChange = (e) => {
|
|
988
|
+
const files = e.currentTarget.files;
|
|
989
|
+
onFiles?.(files);
|
|
990
|
+
if (preview && files) {
|
|
991
|
+
previewUrls.forEach((url) => URL.revokeObjectURL(url));
|
|
992
|
+
const urls = [];
|
|
993
|
+
for (let i = 0; i < files.length; i++) {
|
|
994
|
+
if (files[i].type.startsWith("image/")) {
|
|
995
|
+
urls.push(URL.createObjectURL(files[i]));
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
setPreviewUrls(urls);
|
|
999
|
+
} else {
|
|
1000
|
+
previewUrls.forEach((url) => URL.revokeObjectURL(url));
|
|
1001
|
+
setPreviewUrls([]);
|
|
1002
|
+
}
|
|
1003
|
+
};
|
|
1004
|
+
React4.useEffect(() => {
|
|
1005
|
+
return () => {
|
|
1006
|
+
previewUrls.forEach((url) => URL.revokeObjectURL(url));
|
|
1007
|
+
};
|
|
1008
|
+
}, [previewUrls]);
|
|
1009
|
+
const rootClassName = cn("file_input", disabled && "file_input_disabled", className);
|
|
924
1010
|
return /* @__PURE__ */ jsxs("div", { className: rootClassName, children: [
|
|
925
1011
|
/* @__PURE__ */ jsx(
|
|
926
1012
|
"input",
|
|
@@ -929,259 +1015,357 @@ var FileInput = ({
|
|
|
929
1015
|
type: "file",
|
|
930
1016
|
className: "file_input_control",
|
|
931
1017
|
disabled,
|
|
932
|
-
"aria-describedby":
|
|
933
|
-
onChange:
|
|
1018
|
+
"aria-describedby": supportingText ? helperId : void 0,
|
|
1019
|
+
onChange: handleChange,
|
|
934
1020
|
...props
|
|
935
1021
|
}
|
|
936
1022
|
),
|
|
937
1023
|
/* @__PURE__ */ jsx("label", { htmlFor: inputId, className: "file_input_label", children: label }),
|
|
938
|
-
|
|
1024
|
+
supportingText && /* @__PURE__ */ jsx("span", { id: helperId, className: "file_input_helper", children: supportingText }),
|
|
1025
|
+
previewUrls.length > 0 && /* @__PURE__ */ jsx("div", { className: "file_input_preview", children: previewUrls.map((url) => /* @__PURE__ */ jsx("img", { src: url, alt: "", className: "file_input_preview_img" }, url)) })
|
|
939
1026
|
] });
|
|
940
1027
|
};
|
|
941
|
-
var
|
|
942
|
-
|
|
943
|
-
return /* @__PURE__ */ jsxs("label", { className: rootClassName, children: [
|
|
944
|
-
/* @__PURE__ */ jsx("input", { ref, type: "radio", className: "radio_input", ...props }),
|
|
945
|
-
/* @__PURE__ */ jsx("span", { className: "radio_dot", "aria-hidden": "true" }),
|
|
946
|
-
label ? /* @__PURE__ */ jsx("span", { className: "radio_label", children: label }) : null
|
|
947
|
-
] });
|
|
948
|
-
};
|
|
949
|
-
Radio.displayName = "Radio";
|
|
950
|
-
var Switch = ({
|
|
951
|
-
checked,
|
|
952
|
-
defaultChecked,
|
|
953
|
-
onChange,
|
|
1028
|
+
var IconButton = ({
|
|
1029
|
+
variant = "standard",
|
|
954
1030
|
size = "md",
|
|
955
|
-
|
|
1031
|
+
icon,
|
|
956
1032
|
className,
|
|
957
|
-
ariaLabel,
|
|
958
|
-
ref,
|
|
959
1033
|
...props
|
|
960
1034
|
}) => {
|
|
961
|
-
const
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
if (disabled) return;
|
|
966
|
-
const next = !isOn;
|
|
967
|
-
if (!isControlled) setInnerChecked(next);
|
|
968
|
-
onChange?.(next);
|
|
969
|
-
};
|
|
970
|
-
const rootClassName = cn(
|
|
971
|
-
"switch",
|
|
972
|
-
`switch_size_${size}`,
|
|
973
|
-
{ switch_on: isOn, switch_disabled: disabled },
|
|
1035
|
+
const buttonClassName = cn(
|
|
1036
|
+
"icon_button",
|
|
1037
|
+
`icon_button_variant_${variant}`,
|
|
1038
|
+
`icon_button_size_${size}`,
|
|
974
1039
|
className
|
|
975
1040
|
);
|
|
1041
|
+
return /* @__PURE__ */ jsx("button", { className: buttonClassName, ...props, children: /* @__PURE__ */ jsx("span", { className: "icon_button_icon", "aria-hidden": "true", children: icon }) });
|
|
1042
|
+
};
|
|
1043
|
+
var LinearProgress = ({
|
|
1044
|
+
totalSteps,
|
|
1045
|
+
currentStep,
|
|
1046
|
+
className,
|
|
1047
|
+
...props
|
|
1048
|
+
}) => {
|
|
1049
|
+
const percent = totalSteps > 0 ? Math.min(Math.max(currentStep / totalSteps, 0), 1) * 100 : 0;
|
|
976
1050
|
return /* @__PURE__ */ jsx(
|
|
977
|
-
"
|
|
1051
|
+
"div",
|
|
978
1052
|
{
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
"aria-
|
|
983
|
-
"aria-
|
|
984
|
-
disabled,
|
|
985
|
-
onClick: handleToggle,
|
|
986
|
-
className: rootClassName,
|
|
1053
|
+
className: cn("linear_progress", className),
|
|
1054
|
+
role: "progressbar",
|
|
1055
|
+
"aria-valuenow": currentStep,
|
|
1056
|
+
"aria-valuemin": 0,
|
|
1057
|
+
"aria-valuemax": totalSteps,
|
|
987
1058
|
...props,
|
|
988
|
-
children: /* @__PURE__ */ jsx(
|
|
1059
|
+
children: /* @__PURE__ */ jsx(
|
|
1060
|
+
"div",
|
|
1061
|
+
{
|
|
1062
|
+
className: "linear_progress_indicator",
|
|
1063
|
+
style: { width: `${percent}%` }
|
|
1064
|
+
}
|
|
1065
|
+
)
|
|
989
1066
|
}
|
|
990
1067
|
);
|
|
991
1068
|
};
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
id,
|
|
1069
|
+
var ListItem = ({
|
|
1070
|
+
overline,
|
|
995
1071
|
label,
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
fullWidth,
|
|
1072
|
+
supportingText,
|
|
1073
|
+
metadata,
|
|
1074
|
+
leadingElement,
|
|
1075
|
+
trailingElement,
|
|
1076
|
+
alignment = "top",
|
|
1077
|
+
disabled,
|
|
1078
|
+
onClick,
|
|
1004
1079
|
className,
|
|
1005
|
-
onChangeAction,
|
|
1006
|
-
value,
|
|
1007
|
-
defaultValue,
|
|
1008
|
-
transformValue,
|
|
1009
|
-
ref,
|
|
1010
1080
|
...props
|
|
1011
1081
|
}) => {
|
|
1012
|
-
const
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
() => applyTransform(value ?? defaultValue ?? "")
|
|
1082
|
+
const rootClassName = cn(
|
|
1083
|
+
"list_item",
|
|
1084
|
+
`list_item_align_${alignment}`,
|
|
1085
|
+
disabled && "list_item_disabled",
|
|
1086
|
+
onClick && "list_item_interactive",
|
|
1087
|
+
className
|
|
1019
1088
|
);
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
if (!isControlled) return;
|
|
1023
|
-
const nextValue = value ?? "";
|
|
1024
|
-
setInnerValue(transformValue ? transformValue(nextValue) : nextValue);
|
|
1025
|
-
}, [isControlled, value, transformValue]);
|
|
1026
|
-
const rootClassName = cn("text_field", { text_field_full_width: fullWidth }, className);
|
|
1027
|
-
const inputClassName = cn(
|
|
1028
|
-
"text_field_input",
|
|
1029
|
-
`text_field_variant_${variant}`,
|
|
1030
|
-
`text_field_size_${size}`,
|
|
1089
|
+
return /* @__PURE__ */ jsx(
|
|
1090
|
+
"div",
|
|
1031
1091
|
{
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1092
|
+
className: rootClassName,
|
|
1093
|
+
onClick: disabled ? void 0 : onClick,
|
|
1094
|
+
onKeyDown: (e) => {
|
|
1095
|
+
if (disabled || !onClick) return;
|
|
1096
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
1097
|
+
e.preventDefault();
|
|
1098
|
+
onClick(e);
|
|
1099
|
+
}
|
|
1100
|
+
},
|
|
1101
|
+
role: onClick ? "button" : void 0,
|
|
1102
|
+
tabIndex: onClick && !disabled ? 0 : void 0,
|
|
1103
|
+
"aria-disabled": disabled || void 0,
|
|
1104
|
+
...props,
|
|
1105
|
+
children: /* @__PURE__ */ jsxs("div", { className: "list_item_state_layer", children: [
|
|
1106
|
+
leadingElement && /* @__PURE__ */ jsx("div", { className: "list_item_leading", children: leadingElement }),
|
|
1107
|
+
/* @__PURE__ */ jsxs("div", { className: "list_item_content", children: [
|
|
1108
|
+
overline && /* @__PURE__ */ jsx("span", { className: "list_item_overline", children: overline }),
|
|
1109
|
+
/* @__PURE__ */ jsx("span", { className: "list_item_label", children: label }),
|
|
1110
|
+
supportingText && /* @__PURE__ */ jsx("span", { className: "list_item_supporting", children: supportingText }),
|
|
1111
|
+
metadata && /* @__PURE__ */ jsx("span", { className: "list_item_metadata", children: metadata })
|
|
1112
|
+
] }),
|
|
1113
|
+
trailingElement && /* @__PURE__ */ jsx("div", { className: "list_item_trailing", children: trailingElement })
|
|
1114
|
+
] })
|
|
1036
1115
|
}
|
|
1037
1116
|
);
|
|
1038
|
-
const helperClassName = cn("text_field_helper", {
|
|
1039
|
-
text_field_helper_error: error,
|
|
1040
|
-
text_field_helper_success: success
|
|
1041
|
-
});
|
|
1042
|
-
return /* @__PURE__ */ jsxs("div", { className: rootClassName, children: [
|
|
1043
|
-
label ? /* @__PURE__ */ jsx("label", { className: "text_field_label", htmlFor: inputId, children: label }) : null,
|
|
1044
|
-
/* @__PURE__ */ jsxs("div", { className: "text_field_wrap", children: [
|
|
1045
|
-
leftIcon ? /* @__PURE__ */ jsx("span", { className: "text_field_icon text_field_icon_left", "aria-hidden": "true", children: leftIcon }) : null,
|
|
1046
|
-
/* @__PURE__ */ jsx(
|
|
1047
|
-
"input",
|
|
1048
|
-
{
|
|
1049
|
-
id: inputId,
|
|
1050
|
-
ref,
|
|
1051
|
-
className: inputClassName,
|
|
1052
|
-
"aria-invalid": !!error,
|
|
1053
|
-
"aria-describedby": helperId,
|
|
1054
|
-
...props,
|
|
1055
|
-
value: innerValue,
|
|
1056
|
-
onCompositionStart: () => {
|
|
1057
|
-
isComposingRef.current = true;
|
|
1058
|
-
},
|
|
1059
|
-
onCompositionEnd: (event) => {
|
|
1060
|
-
isComposingRef.current = false;
|
|
1061
|
-
const rawValue = event.currentTarget.value;
|
|
1062
|
-
const nextValue = applyTransform(rawValue);
|
|
1063
|
-
setInnerValue(nextValue);
|
|
1064
|
-
onChangeAction?.(nextValue);
|
|
1065
|
-
},
|
|
1066
|
-
onChange: (event) => {
|
|
1067
|
-
const rawValue = event.target.value;
|
|
1068
|
-
if (isComposingRef.current) {
|
|
1069
|
-
setInnerValue(rawValue);
|
|
1070
|
-
return;
|
|
1071
|
-
}
|
|
1072
|
-
const nextValue = applyTransform(rawValue);
|
|
1073
|
-
setInnerValue(nextValue);
|
|
1074
|
-
onChangeAction?.(nextValue);
|
|
1075
|
-
}
|
|
1076
|
-
}
|
|
1077
|
-
),
|
|
1078
|
-
rightIcon ? /* @__PURE__ */ jsx("span", { className: "text_field_icon text_field_icon_right", "aria-hidden": "true", children: rightIcon }) : null
|
|
1079
|
-
] }),
|
|
1080
|
-
helperText ? /* @__PURE__ */ jsx("div", { id: helperId, className: helperClassName, children: helperText }) : null
|
|
1081
|
-
] });
|
|
1082
1117
|
};
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1118
|
+
var Modal = ({
|
|
1119
|
+
open,
|
|
1120
|
+
onClose,
|
|
1121
|
+
closeOnOverlay = true,
|
|
1122
|
+
width = 520,
|
|
1123
|
+
title,
|
|
1124
|
+
children,
|
|
1089
1125
|
className,
|
|
1090
|
-
|
|
1126
|
+
ariaLabel,
|
|
1091
1127
|
...props
|
|
1092
1128
|
}) => {
|
|
1093
|
-
const
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
className
|
|
1099
|
-
);
|
|
1100
|
-
const buttonStyle = width ? { ...style, width } : style;
|
|
1101
|
-
return /* @__PURE__ */ jsx("button", { className: buttonClassName, style: buttonStyle, ...props });
|
|
1102
|
-
};
|
|
1103
|
-
var Select = ({
|
|
1104
|
-
id,
|
|
1105
|
-
label,
|
|
1106
|
-
placeholder = "Select\u2026",
|
|
1107
|
-
options,
|
|
1108
|
-
value,
|
|
1109
|
-
onChange,
|
|
1110
|
-
defaultValue = null,
|
|
1111
|
-
disabled,
|
|
1112
|
-
size = "md",
|
|
1113
|
-
variant = "outline",
|
|
1114
|
-
fullWidth,
|
|
1115
|
-
className,
|
|
1116
|
-
textAlign = "left"
|
|
1117
|
-
}) => {
|
|
1118
|
-
const internalId = React9.useId();
|
|
1119
|
-
const selectId = id ?? internalId;
|
|
1120
|
-
const isControlled = value !== void 0;
|
|
1121
|
-
const [internalValue, setInternalValue] = React9.useState(defaultValue);
|
|
1122
|
-
const currentValue = isControlled ? value ?? null : internalValue;
|
|
1123
|
-
const [isOpen, setIsOpen] = React9.useState(false);
|
|
1124
|
-
const [activeIndex, setActiveIndex] = React9.useState(-1);
|
|
1125
|
-
const [dropUp, setDropUp] = React9.useState(false);
|
|
1126
|
-
const wrapperRef = React9.useRef(null);
|
|
1127
|
-
const controlRef = React9.useRef(null);
|
|
1128
|
-
const currentOption = React9.useMemo(
|
|
1129
|
-
() => options.find((o) => o.value === currentValue) ?? null,
|
|
1130
|
-
[options, currentValue]
|
|
1131
|
-
);
|
|
1132
|
-
const setValue = React9.useCallback(
|
|
1133
|
-
(next) => {
|
|
1134
|
-
const option = options.find((o) => o.value === next) ?? null;
|
|
1135
|
-
if (!isControlled) setInternalValue(next);
|
|
1136
|
-
onChange?.(next, option);
|
|
1137
|
-
},
|
|
1138
|
-
[isControlled, onChange, options]
|
|
1139
|
-
);
|
|
1140
|
-
const handleOutsideClick = React9.useEffectEvent((e) => {
|
|
1141
|
-
if (!wrapperRef.current?.contains(e.target)) {
|
|
1142
|
-
setIsOpen(false);
|
|
1143
|
-
}
|
|
1129
|
+
const panelRef = React4.useRef(null);
|
|
1130
|
+
const titleId = React4.useId();
|
|
1131
|
+
useFocusTrap(panelRef, open);
|
|
1132
|
+
const handleEscape = React4.useEffectEvent((e) => {
|
|
1133
|
+
if (e.key === "Escape") onClose?.();
|
|
1144
1134
|
});
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1135
|
+
React4.useEffect(() => {
|
|
1136
|
+
if (!open) return;
|
|
1137
|
+
document.addEventListener("keydown", handleEscape);
|
|
1138
|
+
return () => document.removeEventListener("keydown", handleEscape);
|
|
1139
|
+
}, [open]);
|
|
1140
|
+
React4.useEffect(() => {
|
|
1141
|
+
if (!open) return;
|
|
1142
|
+
const body = document.body;
|
|
1143
|
+
const openModals = parseInt(body.dataset.openModals || "0", 10);
|
|
1144
|
+
if (openModals === 0) {
|
|
1145
|
+
body.dataset.originalOverflow = window.getComputedStyle(body).overflow;
|
|
1146
|
+
body.style.overflow = "hidden";
|
|
1153
1147
|
}
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
if (
|
|
1159
|
-
|
|
1160
|
-
|
|
1148
|
+
body.dataset.openModals = String(openModals + 1);
|
|
1149
|
+
return () => {
|
|
1150
|
+
const currentOpenModals = parseInt(body.dataset.openModals || "1", 10);
|
|
1151
|
+
const nextOpenModals = currentOpenModals - 1;
|
|
1152
|
+
if (nextOpenModals === 0) {
|
|
1153
|
+
body.style.overflow = body.dataset.originalOverflow || "";
|
|
1154
|
+
delete body.dataset.openModals;
|
|
1155
|
+
delete body.dataset.originalOverflow;
|
|
1156
|
+
} else {
|
|
1157
|
+
body.dataset.openModals = String(nextOpenModals);
|
|
1161
1158
|
}
|
|
1159
|
+
};
|
|
1160
|
+
}, [open]);
|
|
1161
|
+
if (!open) return null;
|
|
1162
|
+
const panelClassName = cn("modal_panel", className);
|
|
1163
|
+
const hasTitle = !!title;
|
|
1164
|
+
return /* @__PURE__ */ jsx(
|
|
1165
|
+
"div",
|
|
1166
|
+
{
|
|
1167
|
+
className: "modal",
|
|
1168
|
+
role: "dialog",
|
|
1169
|
+
"aria-modal": "true",
|
|
1170
|
+
"aria-labelledby": hasTitle && !ariaLabel ? titleId : void 0,
|
|
1171
|
+
"aria-label": !hasTitle ? ariaLabel ?? "Dialog" : ariaLabel,
|
|
1172
|
+
onClick: () => closeOnOverlay && onClose?.(),
|
|
1173
|
+
onKeyDown: (e) => {
|
|
1174
|
+
if (e.key === "Escape") onClose?.();
|
|
1175
|
+
},
|
|
1176
|
+
children: /* @__PURE__ */ jsxs(
|
|
1177
|
+
"div",
|
|
1178
|
+
{
|
|
1179
|
+
ref: panelRef,
|
|
1180
|
+
className: panelClassName,
|
|
1181
|
+
style: { width },
|
|
1182
|
+
role: "document",
|
|
1183
|
+
onClick: (e) => e.stopPropagation(),
|
|
1184
|
+
onKeyDown: (e) => {
|
|
1185
|
+
if (e.key !== "Escape") e.stopPropagation();
|
|
1186
|
+
},
|
|
1187
|
+
...props,
|
|
1188
|
+
children: [
|
|
1189
|
+
title && /* @__PURE__ */ jsx("div", { id: titleId, className: "modal_header", children: title }),
|
|
1190
|
+
/* @__PURE__ */ jsx("div", { className: "modal_body", children })
|
|
1191
|
+
]
|
|
1192
|
+
}
|
|
1193
|
+
)
|
|
1162
1194
|
}
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
const
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1195
|
+
);
|
|
1196
|
+
};
|
|
1197
|
+
var range2 = (start, end) => {
|
|
1198
|
+
const out = [];
|
|
1199
|
+
for (let i = start; i <= end; i += 1) out.push(i);
|
|
1200
|
+
return out;
|
|
1201
|
+
};
|
|
1202
|
+
var getPaginationItems = (page, totalPages) => {
|
|
1203
|
+
if (totalPages <= 7) return range2(1, totalPages);
|
|
1204
|
+
const items = [];
|
|
1205
|
+
const last = totalPages;
|
|
1206
|
+
const sibling = 2;
|
|
1207
|
+
if (page <= sibling + 2) {
|
|
1208
|
+
for (const p of range2(1, sibling + 3)) items.push(p);
|
|
1209
|
+
items.push("ellipsis");
|
|
1210
|
+
items.push(last);
|
|
1211
|
+
return items;
|
|
1212
|
+
}
|
|
1213
|
+
if (page >= last - sibling - 1) {
|
|
1214
|
+
items.push(1);
|
|
1215
|
+
items.push("ellipsis");
|
|
1216
|
+
for (const p of range2(last - sibling - 2, last)) items.push(p);
|
|
1217
|
+
return items;
|
|
1218
|
+
}
|
|
1219
|
+
items.push(1);
|
|
1220
|
+
items.push("ellipsis");
|
|
1221
|
+
for (const p of range2(page - sibling, page + sibling)) items.push(p);
|
|
1222
|
+
items.push("ellipsis");
|
|
1223
|
+
items.push(last);
|
|
1224
|
+
return items;
|
|
1225
|
+
};
|
|
1226
|
+
var Pagination = ({
|
|
1227
|
+
page,
|
|
1228
|
+
totalPages,
|
|
1229
|
+
onChange,
|
|
1230
|
+
prevLabel = "Previous page",
|
|
1231
|
+
nextLabel = "Next page"
|
|
1232
|
+
}) => {
|
|
1233
|
+
const prevDisabled = page <= 1;
|
|
1234
|
+
const nextDisabled = page >= totalPages;
|
|
1235
|
+
const items = React4.useMemo(() => getPaginationItems(page, totalPages), [page, totalPages]);
|
|
1236
|
+
return /* @__PURE__ */ jsxs("nav", { className: "pagination", "aria-label": "Pagination", children: [
|
|
1237
|
+
/* @__PURE__ */ jsx(
|
|
1238
|
+
"button",
|
|
1239
|
+
{
|
|
1240
|
+
type: "button",
|
|
1241
|
+
className: "pagination_item",
|
|
1242
|
+
onClick: () => onChange(page - 1),
|
|
1243
|
+
disabled: prevDisabled,
|
|
1244
|
+
"aria-label": prevLabel,
|
|
1245
|
+
children: "\u2039"
|
|
1246
|
+
}
|
|
1247
|
+
),
|
|
1248
|
+
/* @__PURE__ */ jsx("ul", { className: "pagination_pages", children: items.map((it, idx) => {
|
|
1249
|
+
if (it === "ellipsis") {
|
|
1250
|
+
return /* @__PURE__ */ jsx("li", { className: "pagination_ellipsis", "aria-hidden": "true", children: "\u2026" }, `e-${idx}`);
|
|
1251
|
+
}
|
|
1252
|
+
const isActive = it === page;
|
|
1253
|
+
const buttonClassName = cn("pagination_page_button", { pagination_active: isActive });
|
|
1254
|
+
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(
|
|
1255
|
+
"button",
|
|
1256
|
+
{
|
|
1257
|
+
type: "button",
|
|
1258
|
+
className: buttonClassName,
|
|
1259
|
+
onClick: () => onChange(it),
|
|
1260
|
+
"aria-current": isActive ? "page" : void 0,
|
|
1261
|
+
children: it
|
|
1262
|
+
}
|
|
1263
|
+
) }, it);
|
|
1264
|
+
}) }),
|
|
1265
|
+
/* @__PURE__ */ jsx(
|
|
1266
|
+
"button",
|
|
1267
|
+
{
|
|
1268
|
+
type: "button",
|
|
1269
|
+
className: "pagination_item",
|
|
1270
|
+
onClick: () => onChange(page + 1),
|
|
1271
|
+
disabled: nextDisabled,
|
|
1272
|
+
"aria-label": nextLabel,
|
|
1273
|
+
children: "\u203A"
|
|
1274
|
+
}
|
|
1275
|
+
)
|
|
1276
|
+
] });
|
|
1277
|
+
};
|
|
1278
|
+
var Radio = ({ label, size = "md", className, ref, ...props }) => {
|
|
1279
|
+
const rootClassName = cn("radio", `radio_size_${size}`, className);
|
|
1280
|
+
return /* @__PURE__ */ jsxs("label", { className: rootClassName, children: [
|
|
1281
|
+
/* @__PURE__ */ jsx("input", { ref, type: "radio", className: "radio_input", ...props }),
|
|
1282
|
+
/* @__PURE__ */ jsx("span", { className: "radio_state_layer", "aria-hidden": "true", children: /* @__PURE__ */ jsx("span", { className: "radio_dot" }) }),
|
|
1283
|
+
label ? /* @__PURE__ */ jsx("span", { className: "radio_label", children: label }) : null
|
|
1284
|
+
] });
|
|
1285
|
+
};
|
|
1286
|
+
Radio.displayName = "Radio";
|
|
1287
|
+
var Select = ({
|
|
1288
|
+
id,
|
|
1289
|
+
label,
|
|
1290
|
+
placeholder = "Select\u2026",
|
|
1291
|
+
options,
|
|
1292
|
+
value,
|
|
1293
|
+
onChange,
|
|
1294
|
+
defaultValue = null,
|
|
1295
|
+
disabled,
|
|
1296
|
+
size = "md",
|
|
1297
|
+
variant = "outline",
|
|
1298
|
+
fullWidth,
|
|
1299
|
+
className,
|
|
1300
|
+
textAlign = "left"
|
|
1301
|
+
}) => {
|
|
1302
|
+
const internalId = React4.useId();
|
|
1303
|
+
const selectId = id ?? internalId;
|
|
1304
|
+
const isControlled = value !== void 0;
|
|
1305
|
+
const [internalValue, setInternalValue] = React4.useState(defaultValue);
|
|
1306
|
+
const currentValue = isControlled ? value ?? null : internalValue;
|
|
1307
|
+
const [isOpen, setIsOpen] = React4.useState(false);
|
|
1308
|
+
const [activeIndex, setActiveIndex] = React4.useState(-1);
|
|
1309
|
+
const [dropUp, setDropUp] = React4.useState(false);
|
|
1310
|
+
const wrapperRef = React4.useRef(null);
|
|
1311
|
+
const controlRef = React4.useRef(null);
|
|
1312
|
+
const currentOption = React4.useMemo(
|
|
1313
|
+
() => options.find((o) => o.value === currentValue) ?? null,
|
|
1314
|
+
[options, currentValue]
|
|
1315
|
+
);
|
|
1316
|
+
const setValue = React4.useCallback(
|
|
1317
|
+
(next) => {
|
|
1318
|
+
const option = options.find((o) => o.value === next) ?? null;
|
|
1319
|
+
if (!isControlled) setInternalValue(next);
|
|
1320
|
+
onChange?.(next, option);
|
|
1321
|
+
},
|
|
1322
|
+
[isControlled, onChange, options]
|
|
1323
|
+
);
|
|
1324
|
+
const handleOutsideClick = React4.useEffectEvent((e) => {
|
|
1325
|
+
if (!wrapperRef.current?.contains(e.target)) {
|
|
1326
|
+
setIsOpen(false);
|
|
1327
|
+
}
|
|
1328
|
+
});
|
|
1329
|
+
React4.useEffect(() => {
|
|
1330
|
+
document.addEventListener("mousedown", handleOutsideClick);
|
|
1331
|
+
return () => document.removeEventListener("mousedown", handleOutsideClick);
|
|
1332
|
+
}, []);
|
|
1333
|
+
const moveActive = (dir) => {
|
|
1334
|
+
if (!isOpen) {
|
|
1335
|
+
setIsOpen(true);
|
|
1336
|
+
return;
|
|
1337
|
+
}
|
|
1338
|
+
let i = activeIndex;
|
|
1339
|
+
const len = options.length;
|
|
1340
|
+
for (let step = 0; step < len; step++) {
|
|
1341
|
+
i = (i + dir + len) % len;
|
|
1342
|
+
if (!options[i].disabled) {
|
|
1343
|
+
setActiveIndex(i);
|
|
1344
|
+
break;
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
};
|
|
1348
|
+
const commitActive = () => {
|
|
1349
|
+
if (activeIndex < 0 || activeIndex >= options.length) return;
|
|
1350
|
+
const opt = options[activeIndex];
|
|
1351
|
+
if (!opt.disabled) {
|
|
1352
|
+
setValue(opt.value);
|
|
1353
|
+
setIsOpen(false);
|
|
1354
|
+
}
|
|
1355
|
+
};
|
|
1356
|
+
const onKeyDown = (e) => {
|
|
1357
|
+
if (disabled) return;
|
|
1358
|
+
switch (e.key) {
|
|
1359
|
+
case " ":
|
|
1360
|
+
case "Enter":
|
|
1361
|
+
e.preventDefault();
|
|
1362
|
+
if (!isOpen) setIsOpen(true);
|
|
1363
|
+
else commitActive();
|
|
1364
|
+
break;
|
|
1365
|
+
case "ArrowDown":
|
|
1366
|
+
e.preventDefault();
|
|
1367
|
+
moveActive(1);
|
|
1368
|
+
break;
|
|
1185
1369
|
case "ArrowUp":
|
|
1186
1370
|
e.preventDefault();
|
|
1187
1371
|
moveActive(-1);
|
|
@@ -1207,7 +1391,7 @@ var Select = ({
|
|
|
1207
1391
|
break;
|
|
1208
1392
|
}
|
|
1209
1393
|
};
|
|
1210
|
-
|
|
1394
|
+
React4.useEffect(() => {
|
|
1211
1395
|
if (!isOpen) return;
|
|
1212
1396
|
const idx = options.findIndex((o) => o.value === currentValue && !o.disabled);
|
|
1213
1397
|
setActiveIndex(
|
|
@@ -1217,7 +1401,7 @@ var Select = ({
|
|
|
1217
1401
|
)
|
|
1218
1402
|
);
|
|
1219
1403
|
}, [isOpen, options, currentValue]);
|
|
1220
|
-
|
|
1404
|
+
React4.useLayoutEffect(() => {
|
|
1221
1405
|
if (!isOpen || !controlRef.current) return;
|
|
1222
1406
|
const rect = controlRef.current.getBoundingClientRect();
|
|
1223
1407
|
const listHeight = Math.min(options.length * 40, 288);
|
|
@@ -1309,165 +1493,269 @@ var Select = ({
|
|
|
1309
1493
|
}
|
|
1310
1494
|
);
|
|
1311
1495
|
};
|
|
1312
|
-
var
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
if (page <= sibling + 2) {
|
|
1323
|
-
for (const p of range(1, sibling + 3)) items.push(p);
|
|
1324
|
-
items.push("ellipsis");
|
|
1325
|
-
items.push(last);
|
|
1326
|
-
return items;
|
|
1327
|
-
}
|
|
1328
|
-
if (page >= last - sibling - 1) {
|
|
1329
|
-
items.push(1);
|
|
1330
|
-
items.push("ellipsis");
|
|
1331
|
-
for (const p of range(last - sibling - 2, last)) items.push(p);
|
|
1332
|
-
return items;
|
|
1333
|
-
}
|
|
1334
|
-
items.push(1);
|
|
1335
|
-
items.push("ellipsis");
|
|
1336
|
-
for (const p of range(page - sibling, page + sibling)) items.push(p);
|
|
1337
|
-
items.push("ellipsis");
|
|
1338
|
-
items.push(last);
|
|
1339
|
-
return items;
|
|
1496
|
+
var Spinner = ({ size = 24, ariaLabel = "Loading" }) => {
|
|
1497
|
+
return /* @__PURE__ */ jsx(
|
|
1498
|
+
"span",
|
|
1499
|
+
{
|
|
1500
|
+
className: "spinner",
|
|
1501
|
+
style: { width: size, height: size },
|
|
1502
|
+
role: "status",
|
|
1503
|
+
"aria-label": ariaLabel
|
|
1504
|
+
}
|
|
1505
|
+
);
|
|
1340
1506
|
};
|
|
1341
|
-
var
|
|
1342
|
-
|
|
1343
|
-
|
|
1507
|
+
var Switch = ({
|
|
1508
|
+
checked,
|
|
1509
|
+
defaultChecked,
|
|
1344
1510
|
onChange,
|
|
1345
|
-
|
|
1346
|
-
|
|
1511
|
+
size = "md",
|
|
1512
|
+
disabled,
|
|
1513
|
+
className,
|
|
1514
|
+
ariaLabel,
|
|
1515
|
+
ref,
|
|
1516
|
+
...props
|
|
1347
1517
|
}) => {
|
|
1348
|
-
const
|
|
1349
|
-
const
|
|
1350
|
-
const
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1518
|
+
const isControlled = checked !== void 0;
|
|
1519
|
+
const [innerChecked, setInnerChecked] = React4.useState(!!defaultChecked);
|
|
1520
|
+
const isOn = isControlled ? !!checked : innerChecked;
|
|
1521
|
+
const handleToggle = () => {
|
|
1522
|
+
if (disabled) return;
|
|
1523
|
+
const next = !isOn;
|
|
1524
|
+
if (!isControlled) setInnerChecked(next);
|
|
1525
|
+
onChange?.(next);
|
|
1526
|
+
};
|
|
1527
|
+
const rootClassName = cn(
|
|
1528
|
+
"switch",
|
|
1529
|
+
`switch_size_${size}`,
|
|
1530
|
+
{ switch_on: isOn, switch_disabled: disabled },
|
|
1531
|
+
className
|
|
1532
|
+
);
|
|
1533
|
+
return /* @__PURE__ */ jsx(
|
|
1534
|
+
"button",
|
|
1535
|
+
{
|
|
1536
|
+
ref,
|
|
1537
|
+
type: "button",
|
|
1538
|
+
role: "switch",
|
|
1539
|
+
"aria-checked": isOn,
|
|
1540
|
+
"aria-label": ariaLabel,
|
|
1541
|
+
disabled,
|
|
1542
|
+
onClick: handleToggle,
|
|
1543
|
+
className: rootClassName,
|
|
1544
|
+
...props,
|
|
1545
|
+
children: /* @__PURE__ */ jsx("span", { className: "switch_thumb" })
|
|
1546
|
+
}
|
|
1547
|
+
);
|
|
1548
|
+
};
|
|
1549
|
+
Switch.displayName = "Switch";
|
|
1550
|
+
var TextField = ({
|
|
1551
|
+
id,
|
|
1552
|
+
label,
|
|
1553
|
+
showLabel = true,
|
|
1554
|
+
supportingText,
|
|
1555
|
+
error,
|
|
1556
|
+
leadingIcon,
|
|
1557
|
+
trailingIcon,
|
|
1558
|
+
fullWidth,
|
|
1559
|
+
className,
|
|
1560
|
+
onChangeAction,
|
|
1561
|
+
value,
|
|
1562
|
+
defaultValue,
|
|
1563
|
+
transformValue,
|
|
1564
|
+
ref,
|
|
1565
|
+
...props
|
|
1566
|
+
}) => {
|
|
1567
|
+
const generatedId = React4.useId();
|
|
1568
|
+
const inputId = id ?? generatedId;
|
|
1569
|
+
const helperId = supportingText ? `${inputId}-help` : void 0;
|
|
1570
|
+
const isControlled = value !== void 0;
|
|
1571
|
+
const applyTransform = (nextValue) => transformValue ? transformValue(nextValue) : nextValue;
|
|
1572
|
+
const [innerValue, setInnerValue] = React4.useState(
|
|
1573
|
+
() => applyTransform(value ?? defaultValue ?? "")
|
|
1574
|
+
);
|
|
1575
|
+
const isComposingRef = React4.useRef(false);
|
|
1576
|
+
React4.useEffect(() => {
|
|
1577
|
+
if (!isControlled) return;
|
|
1578
|
+
const nextValue = value ?? "";
|
|
1579
|
+
setInnerValue(transformValue ? transformValue(nextValue) : nextValue);
|
|
1580
|
+
}, [isControlled, value, transformValue]);
|
|
1581
|
+
const rootClassName = cn(
|
|
1582
|
+
"text_field",
|
|
1583
|
+
fullWidth && "text_field_full_width",
|
|
1584
|
+
error && "text_field_error",
|
|
1585
|
+
props.disabled && "text_field_disabled",
|
|
1586
|
+
className
|
|
1587
|
+
);
|
|
1588
|
+
return /* @__PURE__ */ jsxs("div", { className: rootClassName, children: [
|
|
1589
|
+
/* @__PURE__ */ jsxs("div", { className: "text_field_container", children: [
|
|
1590
|
+
leadingIcon && /* @__PURE__ */ jsx("span", { className: "text_field_icon", "aria-hidden": "true", children: leadingIcon }),
|
|
1591
|
+
/* @__PURE__ */ jsx("div", { className: "text_field_input_wrap", children: /* @__PURE__ */ jsx(
|
|
1592
|
+
"input",
|
|
1371
1593
|
{
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
"aria-
|
|
1376
|
-
|
|
1594
|
+
id: inputId,
|
|
1595
|
+
ref,
|
|
1596
|
+
className: "text_field_input",
|
|
1597
|
+
"aria-invalid": !!error,
|
|
1598
|
+
"aria-describedby": helperId,
|
|
1599
|
+
"aria-label": !showLabel ? label : void 0,
|
|
1600
|
+
...props,
|
|
1601
|
+
value: innerValue,
|
|
1602
|
+
onCompositionStart: () => {
|
|
1603
|
+
isComposingRef.current = true;
|
|
1604
|
+
},
|
|
1605
|
+
onCompositionEnd: (event) => {
|
|
1606
|
+
isComposingRef.current = false;
|
|
1607
|
+
const rawValue = event.currentTarget.value;
|
|
1608
|
+
const nextValue = applyTransform(rawValue);
|
|
1609
|
+
setInnerValue(nextValue);
|
|
1610
|
+
onChangeAction?.(nextValue);
|
|
1611
|
+
},
|
|
1612
|
+
onChange: (event) => {
|
|
1613
|
+
const rawValue = event.target.value;
|
|
1614
|
+
if (isComposingRef.current) {
|
|
1615
|
+
setInnerValue(rawValue);
|
|
1616
|
+
return;
|
|
1617
|
+
}
|
|
1618
|
+
const nextValue = applyTransform(rawValue);
|
|
1619
|
+
setInnerValue(nextValue);
|
|
1620
|
+
onChangeAction?.(nextValue);
|
|
1621
|
+
}
|
|
1377
1622
|
}
|
|
1378
|
-
) },
|
|
1379
|
-
|
|
1623
|
+
) }),
|
|
1624
|
+
trailingIcon && /* @__PURE__ */ jsx("span", { className: "text_field_icon", "aria-hidden": "true", children: trailingIcon }),
|
|
1625
|
+
label && showLabel && /* @__PURE__ */ jsx("label", { className: "text_field_label", htmlFor: inputId, children: label })
|
|
1626
|
+
] }),
|
|
1627
|
+
supportingText && /* @__PURE__ */ jsx("div", { id: helperId, className: "text_field_helper", children: supportingText })
|
|
1628
|
+
] });
|
|
1629
|
+
};
|
|
1630
|
+
TextField.displayName = "TextField";
|
|
1631
|
+
var ToastContext = React4.createContext(null);
|
|
1632
|
+
var VARIANT_ICONS = {
|
|
1633
|
+
success: /* @__PURE__ */ jsx(CheckCircle2, { size: 18 }),
|
|
1634
|
+
error: /* @__PURE__ */ jsx(XCircle, { size: 18 }),
|
|
1635
|
+
warning: /* @__PURE__ */ jsx(AlertTriangle, { size: 18 }),
|
|
1636
|
+
info: /* @__PURE__ */ jsx(Info, { size: 18 }),
|
|
1637
|
+
default: /* @__PURE__ */ jsx(Bell, { size: 18 })
|
|
1638
|
+
};
|
|
1639
|
+
var ToastItemComponent = ({ item, onRemove, closeAriaLabel }) => {
|
|
1640
|
+
const [exiting, setExiting] = React4.useState(false);
|
|
1641
|
+
const closingRef = React4.useRef(false);
|
|
1642
|
+
const close = React4.useCallback(() => {
|
|
1643
|
+
if (closingRef.current) return;
|
|
1644
|
+
closingRef.current = true;
|
|
1645
|
+
setExiting(true);
|
|
1646
|
+
setTimeout(() => onRemove(item.id), 260);
|
|
1647
|
+
}, [item.id, onRemove]);
|
|
1648
|
+
const itemClassName = cn("toast_item", exiting && "toast_item_exiting");
|
|
1649
|
+
return /* @__PURE__ */ jsxs("div", { className: itemClassName, role: item.variant === "error" ? "alert" : "status", children: [
|
|
1650
|
+
/* @__PURE__ */ jsx("span", { className: `toast_icon toast_icon_${item.variant}`, "aria-hidden": "true", children: VARIANT_ICONS[item.variant] }),
|
|
1651
|
+
/* @__PURE__ */ jsx("span", { className: "toast_message", children: item.message }),
|
|
1652
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "toast_close", onClick: close, "aria-label": closeAriaLabel, children: /* @__PURE__ */ jsx(X, { size: 14 }) }),
|
|
1380
1653
|
/* @__PURE__ */ jsx(
|
|
1381
|
-
"
|
|
1654
|
+
"div",
|
|
1382
1655
|
{
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
"aria-label": nextLabel,
|
|
1388
|
-
children: "\u203A"
|
|
1656
|
+
className: `toast_progress toast_progress_${item.variant}`,
|
|
1657
|
+
style: { "--toast-duration": `${item.duration}ms` },
|
|
1658
|
+
onAnimationEnd: close,
|
|
1659
|
+
"aria-hidden": "true"
|
|
1389
1660
|
}
|
|
1390
1661
|
)
|
|
1391
1662
|
] });
|
|
1392
1663
|
};
|
|
1393
|
-
var
|
|
1394
|
-
open,
|
|
1395
|
-
onClose,
|
|
1396
|
-
closeOnOverlay = true,
|
|
1397
|
-
width = 520,
|
|
1398
|
-
title,
|
|
1664
|
+
var ToastProvider = ({
|
|
1399
1665
|
children,
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
...props
|
|
1666
|
+
maxCount = 5,
|
|
1667
|
+
closeAriaLabel = "Close"
|
|
1403
1668
|
}) => {
|
|
1404
|
-
const
|
|
1405
|
-
const
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1669
|
+
const [toasts, setToasts] = React4.useState([]);
|
|
1670
|
+
const [isMounted, setIsMounted] = React4.useState(false);
|
|
1671
|
+
React4.useEffect(() => {
|
|
1672
|
+
setIsMounted(true);
|
|
1673
|
+
}, []);
|
|
1674
|
+
const addToast = React4.useCallback(
|
|
1675
|
+
(message, variant, duration = 3e3) => {
|
|
1676
|
+
const id = crypto.randomUUID();
|
|
1677
|
+
setToasts((prev) => [{ id, message, variant, duration }, ...prev].slice(0, maxCount));
|
|
1678
|
+
},
|
|
1679
|
+
[maxCount]
|
|
1680
|
+
);
|
|
1681
|
+
const removeToast = React4.useCallback((id) => {
|
|
1682
|
+
setToasts((prev) => prev.filter((t) => t.id !== id));
|
|
1683
|
+
}, []);
|
|
1684
|
+
return /* @__PURE__ */ jsxs(ToastContext.Provider, { value: { addToast }, children: [
|
|
1685
|
+
children,
|
|
1686
|
+
isMounted && createPortal(
|
|
1687
|
+
/* @__PURE__ */ jsx(
|
|
1688
|
+
"div",
|
|
1689
|
+
{
|
|
1690
|
+
className: "toast_container",
|
|
1691
|
+
role: "region",
|
|
1692
|
+
"aria-live": "polite",
|
|
1693
|
+
"aria-atomic": "false",
|
|
1694
|
+
"aria-label": "Notifications",
|
|
1695
|
+
children: toasts.map((item) => /* @__PURE__ */ jsx(
|
|
1696
|
+
ToastItemComponent,
|
|
1697
|
+
{
|
|
1698
|
+
item,
|
|
1699
|
+
onRemove: removeToast,
|
|
1700
|
+
closeAriaLabel
|
|
1701
|
+
},
|
|
1702
|
+
item.id
|
|
1703
|
+
))
|
|
1704
|
+
}
|
|
1705
|
+
),
|
|
1706
|
+
document.body
|
|
1707
|
+
)
|
|
1708
|
+
] });
|
|
1709
|
+
};
|
|
1710
|
+
var useToast = () => {
|
|
1711
|
+
const ctx = useContext(ToastContext);
|
|
1712
|
+
if (!ctx) {
|
|
1713
|
+
throw new Error("useToast must be used within ToastProvider");
|
|
1714
|
+
}
|
|
1715
|
+
return {
|
|
1716
|
+
/** 성공 메시지를 표시한다 */
|
|
1717
|
+
success: (message, duration) => ctx.addToast(message, "success", duration),
|
|
1718
|
+
/** 오류 메시지를 표시한다 */
|
|
1719
|
+
error: (message, duration) => ctx.addToast(message, "error", duration),
|
|
1720
|
+
/** 경고 메시지를 표시한다 */
|
|
1721
|
+
warning: (message, duration) => ctx.addToast(message, "warning", duration),
|
|
1722
|
+
/** 정보 메시지를 표시한다 */
|
|
1723
|
+
info: (message, duration) => ctx.addToast(message, "info", duration),
|
|
1724
|
+
/** 기본 메시지를 표시한다 */
|
|
1725
|
+
message: (message, duration) => ctx.addToast(message, "default", duration)
|
|
1726
|
+
};
|
|
1727
|
+
};
|
|
1728
|
+
var TopLoading = ({
|
|
1729
|
+
progress,
|
|
1730
|
+
color,
|
|
1731
|
+
height = 3,
|
|
1732
|
+
isLoading = true,
|
|
1733
|
+
ariaLabel = "Page loading"
|
|
1734
|
+
}) => {
|
|
1735
|
+
if (!isLoading) return null;
|
|
1736
|
+
const isIndeterminate = progress === void 0;
|
|
1439
1737
|
return /* @__PURE__ */ jsx(
|
|
1440
1738
|
"div",
|
|
1441
1739
|
{
|
|
1442
|
-
className: "
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
"aria-
|
|
1446
|
-
"aria-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
},
|
|
1451
|
-
children: /* @__PURE__ */ jsxs(
|
|
1740
|
+
className: "top_loading",
|
|
1741
|
+
style: { height },
|
|
1742
|
+
role: "progressbar",
|
|
1743
|
+
"aria-valuemin": 0,
|
|
1744
|
+
"aria-valuemax": 100,
|
|
1745
|
+
"aria-valuenow": isIndeterminate ? void 0 : progress,
|
|
1746
|
+
"aria-label": ariaLabel,
|
|
1747
|
+
children: /* @__PURE__ */ jsx(
|
|
1452
1748
|
"div",
|
|
1453
1749
|
{
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
onKeyDown: (e) => {
|
|
1460
|
-
if (e.key !== "Escape") e.stopPropagation();
|
|
1461
|
-
},
|
|
1462
|
-
...props,
|
|
1463
|
-
children: [
|
|
1464
|
-
title && /* @__PURE__ */ jsx("div", { id: titleId, className: "modal_header", children: title }),
|
|
1465
|
-
/* @__PURE__ */ jsx("div", { className: "modal_body", children })
|
|
1466
|
-
]
|
|
1750
|
+
className: cn("top_loading_bar", isIndeterminate && "top_loading_indeterminate"),
|
|
1751
|
+
style: {
|
|
1752
|
+
width: isIndeterminate ? void 0 : `${progress}%`,
|
|
1753
|
+
backgroundColor: color
|
|
1754
|
+
}
|
|
1467
1755
|
}
|
|
1468
1756
|
)
|
|
1469
1757
|
}
|
|
1470
1758
|
);
|
|
1471
1759
|
};
|
|
1472
1760
|
|
|
1473
|
-
export { AlertProvider, Button, Card, Checkbox, DatePicker, FileInput, Modal, Pagination, Radio, Select, Spinner, Switch, TextField, ToastProvider, TopLoading, a11y, baseBorderWidth, baseColors, baseTypography, borderWidth, breakpoints, colors, motion, opacity, radius,
|
|
1761
|
+
export { AlertProvider, Button, Card, Checkbox, Chip, DatePicker, Divider, FAB, FileInput, IconButton, LinearProgress, ListItem, Modal, Pagination, Radio, Select, Spinner, Switch, TextField, ToastProvider, TopLoading, a11y, baseBorderWidth, baseColors, baseTypography, borderWidth, breakpoints, colors, elevation, motion, opacity, radius, skeleton, spacing, typography, useAlert, useToast, zIndex };
|