@dragunio/fe-libs 0.1.7 → 0.1.9

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.js CHANGED
@@ -32,14 +32,25 @@ __export(index_exports, {
32
32
  CurrencyInput: () => CurrencyInput,
33
33
  DateTimePicker: () => DateTimePicker,
34
34
  Drawer: () => Drawer,
35
+ DrawerWidths: () => DrawerWidths,
36
+ EmailInput: () => EmailInput,
35
37
  ExpandableSection: () => ExpandableSection,
38
+ EyeIcon: () => EyeIcon,
39
+ EyeOffIcon: () => EyeOffIcon,
40
+ FILE_UPLOAD_ACCEPTS: () => FILE_UPLOAD_ACCEPTS,
41
+ FilePreview: () => FilePreview,
42
+ FileUpload: () => FileUpload,
36
43
  Loading: () => Loading,
44
+ MailboxIcon: () => MailboxIcon,
37
45
  Message: () => Message,
38
46
  Modal: () => Modal,
39
47
  MoreHorizontalIcon: () => MoreHorizontalIcon,
40
48
  MoreVerticalIcon: () => MoreVerticalIcon,
41
49
  NumberInput: () => NumberInput,
42
50
  Pagination: () => Pagination,
51
+ PasswordInput: () => PasswordInput,
52
+ PhoneIcon: () => PhoneIcon,
53
+ PhoneNumberInput: () => PhoneNumberInput,
43
54
  PlusIcon: () => PlusIcon,
44
55
  ProgressBar: () => ProgressBar,
45
56
  RadioButton: () => RadioButton,
@@ -59,6 +70,7 @@ __export(index_exports, {
59
70
  TableHead: () => TableHead,
60
71
  TableHeader: () => TableHeader,
61
72
  TableRow: () => TableRow,
73
+ Tabs: () => Tabs,
62
74
  TextArea: () => TextArea,
63
75
  TextInput: () => TextInput,
64
76
  Toggle: () => Toggle,
@@ -70,7 +82,9 @@ __export(index_exports, {
70
82
  chevron_right: () => chevron_right,
71
83
  chevron_up: () => chevron_up,
72
84
  copy: () => copy,
85
+ formatFileSize: () => formatFileSize,
73
86
  formatNumber: () => formatNumber,
87
+ getFilePreviewKind: () => getFilePreviewKind,
74
88
  getIconSize: () => getIconSize,
75
89
  key: () => key,
76
90
  lock: () => lock,
@@ -78,10 +92,14 @@ __export(index_exports, {
78
92
  log_out: () => log_out,
79
93
  message: () => message,
80
94
  minus_square: () => minus_square,
95
+ normalizePhoneNumber: () => normalizePhoneNumber,
81
96
  plus: () => plus,
82
97
  plus_square: () => plus_square,
83
98
  search: () => search,
84
99
  trash: () => trash,
100
+ validateEmail: () => validateEmail,
101
+ validatePassword: () => validatePassword,
102
+ validatePhoneNumber: () => validatePhoneNumber,
85
103
  x_close: () => x_close
86
104
  });
87
105
  module.exports = __toCommonJS(index_exports);
@@ -209,16 +227,16 @@ var iconProps2 = ({ size, ...props }) => ({
209
227
  ...props
210
228
  });
211
229
  var chevron_right = (props) => {
212
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { ...iconProps2(props), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { "fill-rule": "evenodd", "clip-rule": "evenodd", d: "M8.39898 5.39898C8.73093 5.06704 9.26912 5.06704 9.60107 5.39898L15.6011 11.399C15.933 11.7309 15.933 12.2691 15.6011 12.6011L9.60107 18.6011C9.26912 18.933 8.73093 18.933 8.39898 18.6011C8.06704 18.2691 8.06704 17.7309 8.39898 17.399L13.7979 12L8.39898 6.60107C8.06704 6.26912 8.06704 5.73093 8.39898 5.39898Z", fill: props.fill }) });
230
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { ...iconProps2(props), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M8.39898 5.39898C8.73093 5.06704 9.26912 5.06704 9.60107 5.39898L15.6011 11.399C15.933 11.7309 15.933 12.2691 15.6011 12.6011L9.60107 18.6011C9.26912 18.933 8.73093 18.933 8.39898 18.6011C8.06704 18.2691 8.06704 17.7309 8.39898 17.399L13.7979 12L8.39898 6.60107C8.06704 6.26912 8.06704 5.73093 8.39898 5.39898Z", fill: props.fill }) });
213
231
  };
214
232
  var chevron_up = (props) => {
215
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { ...iconProps2(props), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { "fill-rule": "evenodd", "clip-rule": "evenodd", d: "M11.399 8.39898C11.7309 8.06704 12.2691 8.06704 12.6011 8.39898L18.6011 14.399C18.933 14.7309 18.933 15.2691 18.6011 15.6011C18.2691 15.933 17.7309 15.933 17.399 15.6011L12 10.2021L6.60107 15.6011C6.26912 15.933 5.73093 15.933 5.39898 15.6011C5.06704 15.2691 5.06704 14.7309 5.39898 14.399L11.399 8.39898Z", fill: "#101828" }) });
233
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { ...iconProps2(props), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M11.399 8.39898C11.7309 8.06704 12.2691 8.06704 12.6011 8.39898L18.6011 14.399C18.933 14.7309 18.933 15.2691 18.6011 15.6011C18.2691 15.933 17.7309 15.933 17.399 15.6011L12 10.2021L6.60107 15.6011C6.26912 15.933 5.73093 15.933 5.39898 15.6011C5.06704 15.2691 5.06704 14.7309 5.39898 14.399L11.399 8.39898Z", fill: "#101828" }) });
216
234
  };
217
235
  var chevron_left = (props) => {
218
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { ...iconProps2(props), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { "fill-rule": "evenodd", "clip-rule": "evenodd", d: "M15.6011 5.39898C15.933 5.73093 15.933 6.26912 15.6011 6.60107L10.2021 12L15.6011 17.399C15.933 17.7309 15.933 18.2691 15.6011 18.6011C15.2691 18.933 14.7309 18.933 14.399 18.6011L8.39898 12.6011C8.06704 12.2691 8.06704 11.7309 8.39898 11.399L14.399 5.39898C14.7309 5.06704 15.2691 5.06704 15.6011 5.39898Z", fill: "#101828" }) });
236
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { ...iconProps2(props), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M15.6011 5.39898C15.933 5.73093 15.933 6.26912 15.6011 6.60107L10.2021 12L15.6011 17.399C15.933 17.7309 15.933 18.2691 15.6011 18.6011C15.2691 18.933 14.7309 18.933 14.399 18.6011L8.39898 12.6011C8.06704 12.2691 8.06704 11.7309 8.39898 11.399L14.399 5.39898C14.7309 5.06704 15.2691 5.06704 15.6011 5.39898Z", fill: "#101828" }) });
219
237
  };
220
238
  var chevron_down = (props) => {
221
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { ...iconProps2(props), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { "fill-rule": "evenodd", "clip-rule": "evenodd", d: "M5.39898 8.39898C5.73093 8.06704 6.26912 8.06704 6.60107 8.39898L12 13.7979L17.399 8.39898C17.7309 8.06704 18.2691 8.06704 18.6011 8.39898C18.933 8.73093 18.933 9.26912 18.6011 9.60107L12.6011 15.6011C12.2691 15.933 11.7309 15.933 11.399 15.6011L5.39898 9.60107C5.06704 9.26912 5.06704 8.73093 5.39898 8.39898Z", fill: "#101828" }) });
239
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("svg", { ...iconProps2(props), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M5.39898 8.39898C5.73093 8.06704 6.26912 8.06704 6.60107 8.39898L12 13.7979L17.399 8.39898C17.7309 8.06704 18.2691 8.06704 18.6011 8.39898C18.933 8.73093 18.933 9.26912 18.6011 9.60107L12.6011 15.6011C12.2691 15.933 11.7309 15.933 11.399 15.6011L5.39898 9.60107C5.06704 9.26912 5.06704 8.73093 5.39898 8.39898Z", fill: "#101828" }) });
222
240
  };
223
241
 
224
242
  // packages/icons/src/svgItems/security.tsx
@@ -326,6 +344,82 @@ function SearchIcon(props) {
326
344
  )
327
345
  ] });
328
346
  }
347
+ function MailboxIcon(props) {
348
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { ...iconProps4(props), children: [
349
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
350
+ "rect",
351
+ {
352
+ x: "3.5",
353
+ y: "5.5",
354
+ width: "17",
355
+ height: "13",
356
+ rx: "2",
357
+ stroke: "currentColor",
358
+ strokeWidth: "1.8"
359
+ }
360
+ ),
361
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
362
+ "path",
363
+ {
364
+ d: "m4.5 7 6.04 4.53a2.4 2.4 0 0 0 2.92 0L19.5 7",
365
+ stroke: "currentColor",
366
+ strokeWidth: "1.8",
367
+ strokeLinecap: "round",
368
+ strokeLinejoin: "round"
369
+ }
370
+ )
371
+ ] });
372
+ }
373
+ function PhoneIcon(props) {
374
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("svg", { ...iconProps4(props), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
375
+ "path",
376
+ {
377
+ d: "M8.05 3.75 5.84 4.8c-.76.36-1.15 1.2-.94 2.02 1.55 6.14 6.34 10.93 12.48 12.48.82.21 1.66-.18 2.02-.94l1.05-2.21a1.5 1.5 0 0 0-.57-1.91l-2.41-1.48a1.5 1.5 0 0 0-1.8.18l-1.23 1.06a10.38 10.38 0 0 1-4.45-4.45l1.06-1.23a1.5 1.5 0 0 0 .18-1.8L9.96 4.32a1.5 1.5 0 0 0-1.91-.57Z",
378
+ stroke: "currentColor",
379
+ strokeWidth: "1.8",
380
+ strokeLinecap: "round",
381
+ strokeLinejoin: "round"
382
+ }
383
+ ) });
384
+ }
385
+ function EyeIcon(props) {
386
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { ...iconProps4(props), children: [
387
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
388
+ "path",
389
+ {
390
+ d: "M2.9 12s3.1-5 9.1-5 9.1 5 9.1 5-3.1 5-9.1 5-9.1-5-9.1-5Z",
391
+ stroke: "currentColor",
392
+ strokeWidth: "1.8",
393
+ strokeLinecap: "round",
394
+ strokeLinejoin: "round"
395
+ }
396
+ ),
397
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { cx: "12", cy: "12", r: "2.4", stroke: "currentColor", strokeWidth: "1.8" })
398
+ ] });
399
+ }
400
+ function EyeOffIcon(props) {
401
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("svg", { ...iconProps4(props), children: [
402
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
403
+ "path",
404
+ {
405
+ d: "M10.58 7.16A6.1 6.1 0 0 1 12 7c6 0 9.1 5 9.1 5a16.1 16.1 0 0 1-2.54 2.84M13.28 16.83A6.1 6.1 0 0 1 12 17c-6 0-9.1-5-9.1-5a16.1 16.1 0 0 1 2.59-2.87",
406
+ stroke: "currentColor",
407
+ strokeWidth: "1.8",
408
+ strokeLinecap: "round",
409
+ strokeLinejoin: "round"
410
+ }
411
+ ),
412
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
413
+ "path",
414
+ {
415
+ d: "m3.5 3.5 17 17M10.1 10.1a2.7 2.7 0 0 0 3.8 3.8",
416
+ stroke: "currentColor",
417
+ strokeWidth: "1.8",
418
+ strokeLinecap: "round"
419
+ }
420
+ )
421
+ ] });
422
+ }
329
423
 
330
424
  // packages/button-bar/src/index.tsx
331
425
  var import_jsx_runtime6 = require("react/jsx-runtime");
@@ -342,9 +436,23 @@ function ButtonBar({
342
436
  const rootRef = (0, import_react2.useRef)(null);
343
437
  const moreMenuId = (0, import_react2.useId)();
344
438
  const visibleCount = Math.max(0, Math.floor(maxVisible));
345
- const visibleActions = actions.slice(0, visibleCount);
346
- const overflowActions = actions.slice(visibleCount);
347
- const hasOverflow = overflowActions.length > 0;
439
+ const actionCount = actions.filter(
440
+ (item) => item !== "|"
441
+ ).length;
442
+ const hasOverflow = actionCount > visibleCount;
443
+ let visibleActionEndIndex = actions.length;
444
+ if (hasOverflow) {
445
+ visibleActionEndIndex = 0;
446
+ let renderedActionCount = 0;
447
+ while (visibleActionEndIndex < actions.length && renderedActionCount < visibleCount) {
448
+ if (actions[visibleActionEndIndex] !== "|") renderedActionCount += 1;
449
+ visibleActionEndIndex += 1;
450
+ }
451
+ }
452
+ const visibleActions = actions.slice(0, visibleActionEndIndex).filter((item) => item !== "|");
453
+ const overflowItems = actions.slice(visibleActionEndIndex).filter(
454
+ (item, index, items) => item !== "|" || items.slice(0, index).some((candidate) => candidate !== "|") && items.slice(index + 1).some((candidate) => candidate !== "|") && items[index - 1] !== "|"
455
+ );
348
456
  const {
349
457
  onClick: onMoreClick,
350
458
  disabled: moreDisabled,
@@ -368,18 +476,20 @@ function ButtonBar({
368
476
  document.removeEventListener("keydown", onKeyDown);
369
477
  };
370
478
  }, [isMoreOpen]);
371
- const renderAction = (action, shouldCloseMore = false) => {
372
- const { id, onClick, disabled, ...buttonProps } = action;
479
+ const renderAction = (action, isOverflowAction = false) => {
480
+ const { id, className: className2, onClick, disabled, prefix, ...buttonProps } = action;
373
481
  return /* @__PURE__ */ (0, import_react3.createElement)(
374
482
  Button,
375
483
  {
376
484
  ...buttonProps,
485
+ className: [className2, isOverflowAction && "fe-button-bar__menu-action"].filter(Boolean).join(" ") || void 0,
377
486
  disabled,
378
487
  key: id,
379
488
  onClick: (event) => {
380
489
  onClick?.(event);
381
- if (shouldCloseMore && !disabled) setIsMoreOpen(false);
382
- }
490
+ if (isOverflowAction && !disabled) setIsMoreOpen(false);
491
+ },
492
+ prefix: isOverflowAction ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "fe-button-bar__menu-icon", children: prefix }) : prefix
383
493
  }
384
494
  );
385
495
  };
@@ -417,7 +527,17 @@ function ButtonBar({
417
527
  className: "fe-button-bar__menu",
418
528
  id: moreMenuId,
419
529
  role: "group",
420
- children: overflowActions.map((action) => renderAction(action, true))
530
+ children: overflowItems.map(
531
+ (item, index) => item === "|" ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
532
+ "div",
533
+ {
534
+ "aria-orientation": "horizontal",
535
+ className: "fe-button-bar__menu-divider",
536
+ role: "separator"
537
+ },
538
+ `divider-${index}`
539
+ ) : renderAction(item, true)
540
+ )
421
541
  }
422
542
  )
423
543
  ] })
@@ -426,12 +546,207 @@ function ButtonBar({
426
546
  );
427
547
  }
428
548
 
549
+ // packages/tabs/src/index.tsx
550
+ var import_react4 = require("react");
551
+ var import_jsx_runtime7 = require("react/jsx-runtime");
552
+ var hasPanel = (item) => Object.prototype.hasOwnProperty.call(item, "content");
553
+ function findSelectableTab(items, value) {
554
+ return items.find((item) => item.id === value && !item.disabled) ?? items.find((item) => !item.disabled);
555
+ }
556
+ function scrollBehavior() {
557
+ return typeof window !== "undefined" && window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ? "auto" : "smooth";
558
+ }
559
+ var Tabs = (0, import_react4.forwardRef)(function Tabs2({
560
+ items,
561
+ value,
562
+ defaultValue,
563
+ onChange,
564
+ variant = "tab",
565
+ scrollButtons = "auto",
566
+ previousScrollLabel = "Scroll tabs backward",
567
+ nextScrollLabel = "Scroll tabs forward",
568
+ className,
569
+ "aria-label": ariaLabel = "Tabs",
570
+ "aria-labelledby": ariaLabelledBy,
571
+ ...props
572
+ }, ref) {
573
+ const generatedId = (0, import_react4.useId)();
574
+ const listRef = (0, import_react4.useRef)(null);
575
+ const tabRefs = (0, import_react4.useRef)(/* @__PURE__ */ new Map());
576
+ const [uncontrolledValue, setUncontrolledValue] = (0, import_react4.useState)(
577
+ () => findSelectableTab(items, defaultValue)?.id
578
+ );
579
+ const [scrollState, setScrollState] = (0, import_react4.useState)({
580
+ hasOverflow: false,
581
+ canScrollBackward: false,
582
+ canScrollForward: false
583
+ });
584
+ const activeTab = findSelectableTab(items, value ?? uncontrolledValue);
585
+ const activeIndex = activeTab ? items.findIndex((item) => item.id === activeTab.id) : -1;
586
+ (0, import_react4.useEffect)(() => {
587
+ if (value === void 0 && activeTab?.id !== uncontrolledValue) {
588
+ setUncontrolledValue(activeTab?.id);
589
+ }
590
+ }, [activeTab?.id, uncontrolledValue, value]);
591
+ const updateScrollState = (0, import_react4.useCallback)(() => {
592
+ const list = listRef.current;
593
+ if (!list) return;
594
+ const maxScroll = Math.max(0, list.scrollWidth - list.clientWidth);
595
+ setScrollState({
596
+ hasOverflow: maxScroll > 1,
597
+ canScrollBackward: list.scrollLeft > 1,
598
+ canScrollForward: list.scrollLeft < maxScroll - 1
599
+ });
600
+ }, []);
601
+ (0, import_react4.useEffect)(() => {
602
+ const list = listRef.current;
603
+ if (!list) return;
604
+ updateScrollState();
605
+ list.addEventListener("scroll", updateScrollState, { passive: true });
606
+ const observer = typeof ResizeObserver === "undefined" ? void 0 : new ResizeObserver(updateScrollState);
607
+ observer?.observe(list);
608
+ window.addEventListener("resize", updateScrollState);
609
+ return () => {
610
+ list.removeEventListener("scroll", updateScrollState);
611
+ observer?.disconnect();
612
+ window.removeEventListener("resize", updateScrollState);
613
+ };
614
+ }, [items, updateScrollState]);
615
+ (0, import_react4.useEffect)(() => {
616
+ const tab = activeTab ? tabRefs.current.get(activeTab.id) : void 0;
617
+ tab?.scrollIntoView?.({
618
+ behavior: scrollBehavior(),
619
+ block: "nearest",
620
+ inline: "nearest"
621
+ });
622
+ }, [activeTab?.id]);
623
+ const selectTab = (item, event) => {
624
+ if (item.disabled || item.id === activeTab?.id) return;
625
+ if (value === void 0) setUncontrolledValue(item.id);
626
+ onChange?.(item.id, item, event);
627
+ };
628
+ const selectFromKeyboard = (item, event) => {
629
+ const enabledItems = items.filter((candidate) => !candidate.disabled);
630
+ const currentIndex = enabledItems.findIndex(
631
+ (candidate) => candidate.id === item.id
632
+ );
633
+ if (currentIndex === -1) return;
634
+ let nextIndex;
635
+ if (event.key === "ArrowRight" || event.key === "ArrowDown") {
636
+ nextIndex = (currentIndex + 1) % enabledItems.length;
637
+ } else if (event.key === "ArrowLeft" || event.key === "ArrowUp") {
638
+ nextIndex = (currentIndex - 1 + enabledItems.length) % enabledItems.length;
639
+ } else if (event.key === "Home") {
640
+ nextIndex = 0;
641
+ } else if (event.key === "End") {
642
+ nextIndex = enabledItems.length - 1;
643
+ }
644
+ if (nextIndex === void 0) return;
645
+ event.preventDefault();
646
+ const nextItem = enabledItems[nextIndex];
647
+ if (!nextItem) return;
648
+ tabRefs.current.get(nextItem.id)?.focus();
649
+ selectTab(nextItem, event);
650
+ };
651
+ const scrollTabs = (direction) => {
652
+ const list = listRef.current;
653
+ if (!list) return;
654
+ list.scrollBy({
655
+ left: direction * Math.max(160, Math.round(list.clientWidth * 0.75)),
656
+ behavior: scrollBehavior()
657
+ });
658
+ };
659
+ const showScrollButtons = scrollButtons === "always" || scrollButtons === "auto" && scrollState.hasOverflow;
660
+ const classes = ["fe-tabs", `fe-tabs--${variant}`, className].filter(Boolean).join(" ");
661
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { ...props, className: classes, ref, children: [
662
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "fe-tabs__navigation", children: [
663
+ showScrollButtons && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
664
+ Button,
665
+ {
666
+ "aria-label": previousScrollLabel,
667
+ className: "fe-tabs__scroll-button",
668
+ disabled: !scrollState.canScrollBackward,
669
+ hierarchy: "tertiary-gray",
670
+ icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(chevron_left, { size: 18 }),
671
+ iconOnly: true,
672
+ onClick: () => scrollTabs(-1),
673
+ size: "32"
674
+ }
675
+ ),
676
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "fe-tabs__scroller", ref: listRef, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
677
+ "div",
678
+ {
679
+ "aria-label": ariaLabelledBy ? void 0 : ariaLabel,
680
+ "aria-labelledby": ariaLabelledBy,
681
+ "aria-orientation": "horizontal",
682
+ className: "fe-tabs__list",
683
+ role: "tablist",
684
+ children: items.map((item, index) => {
685
+ const selected = item.id === activeTab?.id;
686
+ const panelId = `${generatedId}-panel-${index}`;
687
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
688
+ "button",
689
+ {
690
+ "aria-controls": hasPanel(item) ? panelId : void 0,
691
+ "aria-selected": selected,
692
+ className: "fe-tabs__tab",
693
+ disabled: item.disabled,
694
+ id: `${generatedId}-tab-${index}`,
695
+ onClick: (event) => selectTab(item, event),
696
+ onKeyDown: (event) => selectFromKeyboard(item, event),
697
+ ref: (node) => {
698
+ if (node) tabRefs.current.set(item.id, node);
699
+ else tabRefs.current.delete(item.id);
700
+ },
701
+ role: "tab",
702
+ tabIndex: selected ? 0 : -1,
703
+ type: "button",
704
+ children: item.label
705
+ },
706
+ item.id
707
+ );
708
+ })
709
+ }
710
+ ) }),
711
+ showScrollButtons && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
712
+ Button,
713
+ {
714
+ "aria-label": nextScrollLabel,
715
+ className: "fe-tabs__scroll-button",
716
+ disabled: !scrollState.canScrollForward,
717
+ hierarchy: "tertiary-gray",
718
+ icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(chevron_right, { size: 18 }),
719
+ iconOnly: true,
720
+ onClick: () => scrollTabs(1),
721
+ size: "32"
722
+ }
723
+ )
724
+ ] }),
725
+ items.map(
726
+ (item, index) => hasPanel(item) ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
727
+ "div",
728
+ {
729
+ "aria-labelledby": `${generatedId}-tab-${index}`,
730
+ className: "fe-tabs__panel",
731
+ hidden: item.id !== activeTab?.id,
732
+ id: `${generatedId}-panel-${index}`,
733
+ role: "tabpanel",
734
+ tabIndex: 0,
735
+ children: item.content
736
+ },
737
+ item.id
738
+ ) : null
739
+ )
740
+ ] });
741
+ });
742
+ Tabs.displayName = "Tabs";
743
+
429
744
  // packages/table/src/index.tsx
430
- var import_react5 = require("react");
745
+ var import_react6 = require("react");
431
746
 
432
747
  // packages/pagination/src/index.tsx
433
- var import_react4 = require("react");
434
- var import_jsx_runtime7 = require("react/jsx-runtime");
748
+ var import_react5 = require("react");
749
+ var import_jsx_runtime8 = require("react/jsx-runtime");
435
750
  var clamp = (value, min, max) => Math.min(Math.max(value, min), max);
436
751
  var range = (start, end) => Array.from({ length: Math.max(0, end - start + 1) }, (_, index) => start + index);
437
752
  function getItems(totalPages, page, siblingCount, boundaryCount) {
@@ -463,9 +778,9 @@ function Pagination({
463
778
  ...props
464
779
  }) {
465
780
  const safeTotalPages = Math.max(1, Math.floor(totalPages));
466
- const [uncontrolledPage, setUncontrolledPage] = (0, import_react4.useState)(() => clamp(defaultPage, 1, safeTotalPages));
781
+ const [uncontrolledPage, setUncontrolledPage] = (0, import_react5.useState)(() => clamp(defaultPage, 1, safeTotalPages));
467
782
  const currentPage = clamp(page ?? uncontrolledPage, 1, safeTotalPages);
468
- const items = (0, import_react4.useMemo)(
783
+ const items = (0, import_react5.useMemo)(
469
784
  () => getItems(safeTotalPages, currentPage, Math.max(0, siblingCount), Math.max(0, boundaryCount)),
470
785
  [safeTotalPages, currentPage, siblingCount, boundaryCount]
471
786
  );
@@ -474,9 +789,9 @@ function Pagination({
474
789
  if (page === void 0) setUncontrolledPage(resolvedPage);
475
790
  if (resolvedPage !== currentPage) onPageChange?.(resolvedPage);
476
791
  };
477
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("nav", { className: ["fe-pagination", className].filter(Boolean).join(" "), "aria-label": "Pagination", ...props, children: [
478
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Button, { className: "fe-pagination__button fe-pagination__button--control", hierarchy: "secondary-gray", size: "40", iconOnly: true, icon: "\u2039", "aria-label": previousLabel, disabled: disabled || currentPage === 1, onClick: () => selectPage(currentPage - 1) }),
479
- items.map((item, index) => item === "start-ellipsis" || item === "end-ellipsis" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "fe-pagination__ellipsis", "aria-hidden": "true", children: "\u2026" }, `${item}-${index}`) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
792
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("nav", { className: ["fe-pagination", className].filter(Boolean).join(" "), "aria-label": "Pagination", ...props, children: [
793
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { className: "fe-pagination__button fe-pagination__button--control", hierarchy: "secondary-gray", size: "40", iconOnly: true, icon: "\u2039", "aria-label": previousLabel, disabled: disabled || currentPage === 1, onClick: () => selectPage(currentPage - 1) }),
794
+ items.map((item, index) => item === "start-ellipsis" || item === "end-ellipsis" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "fe-pagination__ellipsis", "aria-hidden": "true", children: "\u2026" }, `${item}-${index}`) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
480
795
  Button,
481
796
  {
482
797
  className: "fe-pagination__button",
@@ -490,13 +805,13 @@ function Pagination({
490
805
  },
491
806
  item
492
807
  )),
493
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Button, { className: "fe-pagination__button fe-pagination__button--control", hierarchy: "secondary-gray", size: "40", iconOnly: true, icon: "\u203A", "aria-label": nextLabel, disabled: disabled || currentPage === safeTotalPages, onClick: () => selectPage(currentPage + 1) })
808
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { className: "fe-pagination__button fe-pagination__button--control", hierarchy: "secondary-gray", size: "40", iconOnly: true, icon: "\u203A", "aria-label": nextLabel, disabled: disabled || currentPage === safeTotalPages, onClick: () => selectPage(currentPage + 1) })
494
809
  ] });
495
810
  }
496
811
 
497
812
  // packages/table/src/index.tsx
498
- var import_jsx_runtime8 = require("react/jsx-runtime");
499
- var TableContext = (0, import_react5.createContext)({ striped: false });
813
+ var import_jsx_runtime9 = require("react/jsx-runtime");
814
+ var TableContext = (0, import_react6.createContext)({ striped: false });
500
815
  var MIN_COLUMN_WIDTH = 96;
501
816
  var MAX_COLUMN_WIDTH = 1200;
502
817
  function getColumnCount(headers, data) {
@@ -505,7 +820,7 @@ function getColumnCount(headers, data) {
505
820
  function getText(value) {
506
821
  if (typeof value === "string" || typeof value === "number") return String(value);
507
822
  if (Array.isArray(value)) return value.map(getText).join("");
508
- if ((0, import_react5.isValidElement)(value)) return getText(value.props.children);
823
+ if ((0, import_react6.isValidElement)(value)) return getText(value.props.children);
509
824
  return "";
510
825
  }
511
826
  function autoColumnSize(columnIndex, headers, data) {
@@ -541,37 +856,37 @@ function DataTable({
541
856
  }) {
542
857
  const columnCount = getColumnCount(headers, data);
543
858
  const safeMinWidth = Math.max(1, minColumnWidth);
544
- const generatedSizes = (0, import_react5.useMemo)(
859
+ const generatedSizes = (0, import_react6.useMemo)(
545
860
  () => getInitialColumnSizes(headers, data, defaultColumnSizes, safeMinWidth),
546
861
  [headers, data, defaultColumnSizes, safeMinWidth]
547
862
  );
548
- const [uncontrolledSizes, setUncontrolledSizes] = (0, import_react5.useState)(generatedSizes);
863
+ const [uncontrolledSizes, setUncontrolledSizes] = (0, import_react6.useState)(generatedSizes);
549
864
  const shouldPaginate = pagination ?? pageSize !== void 0;
550
865
  const safePageSize = Math.max(1, Math.floor(pageSize ?? 10));
551
866
  const totalPages = Math.max(1, Math.ceil(data.length / safePageSize));
552
- const [uncontrolledPage, setUncontrolledPage] = (0, import_react5.useState)(() => Math.min(Math.max(1, defaultPage), totalPages));
867
+ const [uncontrolledPage, setUncontrolledPage] = (0, import_react6.useState)(() => Math.min(Math.max(1, defaultPage), totalPages));
553
868
  const currentPage = Math.min(Math.max(1, page ?? uncontrolledPage), totalPages);
554
869
  const pagedData = shouldPaginate ? data.slice((currentPage - 1) * safePageSize, currentPage * safePageSize) : data;
555
- const resizeState = (0, import_react5.useRef)();
556
- const [isResizing, setIsResizing] = (0, import_react5.useState)(false);
870
+ const resizeState = (0, import_react6.useRef)();
871
+ const [isResizing, setIsResizing] = (0, import_react6.useState)(false);
557
872
  const sizes2 = columnSizes ? getInitialColumnSizes(headers, data, columnSizes, safeMinWidth).map((size) => Math.max(safeMinWidth, size)) : uncontrolledSizes.map((size) => Math.max(safeMinWidth, size));
558
- (0, import_react5.useEffect)(() => {
873
+ (0, import_react6.useEffect)(() => {
559
874
  if (columnSizes) return;
560
875
  setUncontrolledSizes((currentSizes) => {
561
876
  const nextSizes = generatedSizes.map((generatedSize, index) => currentSizes[index] ?? generatedSize);
562
877
  return sameSizes(currentSizes, nextSizes) ? currentSizes : nextSizes;
563
878
  });
564
879
  }, [columnSizes, generatedSizes]);
565
- (0, import_react5.useEffect)(() => {
880
+ (0, import_react6.useEffect)(() => {
566
881
  if (page === void 0 && uncontrolledPage > totalPages) setUncontrolledPage(totalPages);
567
882
  }, [page, totalPages, uncontrolledPage]);
568
- const updateColumnSize = (0, import_react5.useCallback)((columnIndex, nextSize) => {
883
+ const updateColumnSize = (0, import_react6.useCallback)((columnIndex, nextSize) => {
569
884
  const clampedSize = Math.min(MAX_COLUMN_WIDTH, Math.max(safeMinWidth, Math.round(nextSize)));
570
885
  const nextSizes = sizes2.map((size, index) => index === columnIndex ? clampedSize : size);
571
886
  if (!columnSizes) setUncontrolledSizes(nextSizes);
572
887
  onColumnResize?.(nextSizes, columnIndex);
573
888
  }, [columnSizes, onColumnResize, safeMinWidth, sizes2]);
574
- (0, import_react5.useEffect)(() => {
889
+ (0, import_react6.useEffect)(() => {
575
890
  const onPointerMove = (event) => {
576
891
  const activeResize = resizeState.current;
577
892
  if (!activeResize) return;
@@ -595,14 +910,14 @@ function DataTable({
595
910
  if (nextPage !== currentPage) onPageChange?.(nextPage);
596
911
  };
597
912
  const resolvedPaginationPosition = paginationPosition === "middle-bottom" ? "bottom-center" : paginationPosition;
598
- const paginationControl = shouldPaginate && totalPages > 1 ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: `fe-table__pagination fe-table__pagination--${resolvedPaginationPosition}`, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Pagination, { page: currentPage, totalPages, onPageChange: changePage }) }) : null;
599
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "fe-table", "data-resizing": isResizing || void 0, children: [
913
+ const paginationControl = shouldPaginate && totalPages > 1 ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: `fe-table__pagination fe-table__pagination--${resolvedPaginationPosition}`, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Pagination, { page: currentPage, totalPages, onPageChange: changePage }) }) : null;
914
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "fe-table", "data-resizing": isResizing || void 0, children: [
600
915
  resolvedPaginationPosition === "top-right" && paginationControl,
601
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("table", { className: ["fe-table__table", className].filter(Boolean).join(" "), "data-fe-table": true, "data-striped": striped || void 0, ...props, children: [
602
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("colgroup", { children: sizes2.map((size, index) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("col", { style: { width: `${size}px` } }, index)) }),
603
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("tr", { children: Array.from({ length: columnCount }, (_, columnIndex) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("th", { scope: "col", children: [
604
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "fe-table__header-content", children: headers[columnIndex] ?? `Column ${columnIndex + 1}` }),
605
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
916
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("table", { className: ["fe-table__table", className].filter(Boolean).join(" "), "data-fe-table": true, "data-striped": striped || void 0, ...props, children: [
917
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("colgroup", { children: sizes2.map((size, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("col", { style: { width: `${size}px` } }, index)) }),
918
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("tr", { children: Array.from({ length: columnCount }, (_, columnIndex) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("th", { scope: "col", children: [
919
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "fe-table__header-content", children: headers[columnIndex] ?? `Column ${columnIndex + 1}` }),
920
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
606
921
  "span",
607
922
  {
608
923
  className: "fe-table__resize-handle",
@@ -626,7 +941,7 @@ function DataTable({
626
941
  }
627
942
  )
628
943
  ] }, columnIndex)) }) }),
629
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("tbody", { children: pagedData.map((row, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("tr", { children: Array.from({ length: columnCount }, (_, columnIndex) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("td", { children: row[columnIndex] }, columnIndex)) }, shouldPaginate ? (currentPage - 1) * safePageSize + rowIndex : rowIndex)) })
944
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("tbody", { children: pagedData.map((row, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("tr", { children: Array.from({ length: columnCount }, (_, columnIndex) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("td", { children: row[columnIndex] }, columnIndex)) }, shouldPaginate ? (currentPage - 1) * safePageSize + rowIndex : rowIndex)) })
630
945
  ] }),
631
946
  resolvedPaginationPosition !== "top-right" && paginationControl
632
947
  ] });
@@ -644,33 +959,33 @@ function Table({
644
959
  paginationPosition,
645
960
  ...props
646
961
  }) {
647
- if (headers || data) return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(DataTable, { headers: headers ?? [], data: data ?? [], striped: striped ?? true, pagination, pageSize, page, defaultPage, onPageChange, paginationPosition, ...props });
648
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(TableContext.Provider, { value: { striped: striped ?? false }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("table", { "data-fe-table": true, "data-striped": striped || void 0, ...props, children }) });
962
+ if (headers || data) return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DataTable, { headers: headers ?? [], data: data ?? [], striped: striped ?? true, pagination, pageSize, page, defaultPage, onPageChange, paginationPosition, ...props });
963
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TableContext.Provider, { value: { striped: striped ?? false }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("table", { "data-fe-table": true, "data-striped": striped || void 0, ...props, children }) });
649
964
  }
650
965
  function TableHead(props) {
651
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("thead", { ...props });
966
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("thead", { ...props });
652
967
  }
653
968
  function TableBody(props) {
654
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("tbody", { ...props });
969
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("tbody", { ...props });
655
970
  }
656
971
  function TableRow({ children, ...props }) {
657
- const { striped } = (0, import_react5.useContext)(TableContext);
658
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("tr", { "data-striped": striped || void 0, ...props, children });
972
+ const { striped } = (0, import_react6.useContext)(TableContext);
973
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("tr", { "data-striped": striped || void 0, ...props, children });
659
974
  }
660
975
  function TableCell({ children, ...props }) {
661
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("td", { ...props, children });
976
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("td", { ...props, children });
662
977
  }
663
978
  function TableHeader({ children, ...props }) {
664
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("th", { scope: "col", ...props, children });
979
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("th", { scope: "col", ...props, children });
665
980
  }
666
981
  function TableCaption(props) {
667
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("caption", { ...props });
982
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("caption", { ...props });
668
983
  }
669
984
 
670
985
  // packages/toggle/src/index.tsx
671
- var import_react6 = require("react");
672
- var import_jsx_runtime9 = require("react/jsx-runtime");
673
- var Toggle = (0, import_react6.forwardRef)(function Toggle2({
986
+ var import_react7 = require("react");
987
+ var import_jsx_runtime10 = require("react/jsx-runtime");
988
+ var Toggle = (0, import_react7.forwardRef)(function Toggle2({
674
989
  color = "#16a34a",
675
990
  label,
676
991
  labelPosition = "right",
@@ -684,9 +999,9 @@ var Toggle = (0, import_react6.forwardRef)(function Toggle2({
684
999
  "--fe-toggle-color": color,
685
1000
  ...style
686
1001
  };
687
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("label", { className: classes, style: toggleStyle, children: [
688
- label && labelPosition === "top" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "fe-toggle__label", children: label }),
689
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1002
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("label", { className: classes, style: toggleStyle, children: [
1003
+ label && labelPosition === "top" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "fe-toggle__label", children: label }),
1004
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
690
1005
  "input",
691
1006
  {
692
1007
  ref,
@@ -697,49 +1012,269 @@ var Toggle = (0, import_react6.forwardRef)(function Toggle2({
697
1012
  ...props
698
1013
  }
699
1014
  ),
700
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "fe-toggle__control", "aria-hidden": "true" }),
701
- label && labelPosition === "right" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "fe-toggle__label", children: label })
1015
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "fe-toggle__control", "aria-hidden": "true" }),
1016
+ label && labelPosition === "right" && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "fe-toggle__label", children: label })
702
1017
  ] });
703
1018
  });
704
1019
  Toggle.displayName = "Toggle";
705
1020
 
706
1021
  // packages/drawer/src/index.tsx
707
- var import_react7 = require("react");
1022
+ var import_react9 = require("react");
708
1023
  var import_react_dom = require("react-dom");
709
- var import_jsx_runtime10 = require("react/jsx-runtime");
710
- function Drawer({ open, onClose, title, footer, side = "right", width = 400, fullScreen = false, children, closeOnBackdropClick = true, className, style, ...props }) {
711
- (0, import_react7.useEffect)(() => {
712
- if (!open) return;
1024
+
1025
+ // packages/overlay/src/useModalOverlay.ts
1026
+ var import_react8 = require("react");
1027
+ var FOCUSABLE_SELECTOR = [
1028
+ "a[href]",
1029
+ "area[href]",
1030
+ "input:not([disabled])",
1031
+ "select:not([disabled])",
1032
+ "textarea:not([disabled])",
1033
+ "button:not([disabled])",
1034
+ "iframe",
1035
+ "object",
1036
+ "embed",
1037
+ '[contenteditable="true"]',
1038
+ '[tabindex]:not([tabindex="-1"])'
1039
+ ].join(",");
1040
+ var overlayStack = [];
1041
+ var scrollLockCount = 0;
1042
+ var savedBodyStyles = null;
1043
+ var useIsomorphicLayoutEffect = typeof window === "undefined" ? import_react8.useEffect : import_react8.useLayoutEffect;
1044
+ function lockBodyScroll() {
1045
+ if (typeof document === "undefined" || scrollLockCount++ > 0) return;
1046
+ const { body, documentElement } = document;
1047
+ savedBodyStyles = {
1048
+ overflow: body.style.overflow,
1049
+ overscrollBehavior: body.style.overscrollBehavior,
1050
+ paddingRight: body.style.paddingRight
1051
+ };
1052
+ const scrollbarWidth = Math.max(
1053
+ 0,
1054
+ window.innerWidth - documentElement.clientWidth
1055
+ );
1056
+ const currentPadding = Number.parseFloat(window.getComputedStyle(body).paddingRight) || 0;
1057
+ body.style.overflow = "hidden";
1058
+ body.style.overscrollBehavior = "none";
1059
+ if (scrollbarWidth > 0)
1060
+ body.style.paddingRight = `${currentPadding + scrollbarWidth}px`;
1061
+ }
1062
+ function unlockBodyScroll() {
1063
+ if (typeof document === "undefined" || scrollLockCount === 0) return;
1064
+ scrollLockCount -= 1;
1065
+ if (scrollLockCount > 0 || !savedBodyStyles) return;
1066
+ const { body } = document;
1067
+ body.style.overflow = savedBodyStyles.overflow;
1068
+ body.style.overscrollBehavior = savedBodyStyles.overscrollBehavior;
1069
+ body.style.paddingRight = savedBodyStyles.paddingRight;
1070
+ savedBodyStyles = null;
1071
+ }
1072
+ function getFocusableElements(panel) {
1073
+ return Array.from(
1074
+ panel.querySelectorAll(FOCUSABLE_SELECTOR)
1075
+ ).filter(
1076
+ (element) => element.tabIndex >= 0 && !element.hasAttribute("disabled") && element.getAttribute("aria-hidden") !== "true"
1077
+ );
1078
+ }
1079
+ function getTopOverlay() {
1080
+ return overlayStack.reduce((top, candidate) => {
1081
+ if (!top || candidate.priority > top.priority) return candidate;
1082
+ if (candidate.priority < top.priority) return top;
1083
+ const topNode = top.panelRef.current?.parentElement;
1084
+ const candidateNode = candidate.panelRef.current?.parentElement;
1085
+ if (topNode && candidateNode) {
1086
+ const position = topNode.compareDocumentPosition(candidateNode);
1087
+ if (position & Node.DOCUMENT_POSITION_FOLLOWING) return candidate;
1088
+ if (position & Node.DOCUMENT_POSITION_PRECEDING) return top;
1089
+ }
1090
+ return candidate;
1091
+ }, void 0);
1092
+ }
1093
+ function useModalOverlay(options) {
1094
+ const overlayIdRef = (0, import_react8.useRef)();
1095
+ const previouslyFocusedRef = (0, import_react8.useRef)(null);
1096
+ const optionsRef = (0, import_react8.useRef)(options);
1097
+ optionsRef.current = options;
1098
+ if (!overlayIdRef.current) overlayIdRef.current = /* @__PURE__ */ Symbol("fe-overlay");
1099
+ useIsomorphicLayoutEffect(() => {
1100
+ if (!options.open || typeof document === "undefined") return;
1101
+ const overlayId = overlayIdRef.current;
1102
+ previouslyFocusedRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
1103
+ overlayStack.push({
1104
+ id: overlayId,
1105
+ panelRef: options.panelRef,
1106
+ priority: options.priority ?? 0
1107
+ });
1108
+ lockBodyScroll();
1109
+ const focusInitialElement = () => {
1110
+ const { initialFocusRef, panelRef } = optionsRef.current;
1111
+ const focusTarget = initialFocusRef?.current ?? panelRef.current;
1112
+ focusTarget?.focus();
1113
+ };
1114
+ let cancelled = false;
1115
+ queueMicrotask(() => {
1116
+ if (!cancelled && getTopOverlay()?.id === overlayId)
1117
+ focusInitialElement();
1118
+ });
713
1119
  const onKeyDown = (event) => {
714
- if (event.key === "Escape") onClose();
1120
+ if (getTopOverlay()?.id !== overlayId) return;
1121
+ if (event.key === "Escape") {
1122
+ if (optionsRef.current.closeOnEscape !== false) {
1123
+ event.preventDefault();
1124
+ optionsRef.current.onClose();
1125
+ }
1126
+ return;
1127
+ }
1128
+ if (event.key !== "Tab") return;
1129
+ const panel = optionsRef.current.panelRef.current;
1130
+ if (!panel) return;
1131
+ const focusable = getFocusableElements(panel);
1132
+ if (!focusable.length) {
1133
+ event.preventDefault();
1134
+ panel.focus();
1135
+ return;
1136
+ }
1137
+ const first = focusable[0];
1138
+ const last = focusable[focusable.length - 1];
1139
+ const activeElement = document.activeElement;
1140
+ if (event.shiftKey && (activeElement === first || !panel.contains(activeElement))) {
1141
+ event.preventDefault();
1142
+ last.focus();
1143
+ } else if (!event.shiftKey && (activeElement === last || !panel.contains(activeElement))) {
1144
+ event.preventDefault();
1145
+ first.focus();
1146
+ }
715
1147
  };
716
1148
  document.addEventListener("keydown", onKeyDown);
717
- return () => document.removeEventListener("keydown", onKeyDown);
718
- }, [onClose, open]);
1149
+ return () => {
1150
+ document.removeEventListener("keydown", onKeyDown);
1151
+ cancelled = true;
1152
+ const stackIndex = overlayStack.findIndex(
1153
+ (entry) => entry.id === overlayId
1154
+ );
1155
+ if (stackIndex !== -1) overlayStack.splice(stackIndex, 1);
1156
+ unlockBodyScroll();
1157
+ if (optionsRef.current.restoreFocus !== false) {
1158
+ const nextOverlay = getTopOverlay()?.panelRef.current;
1159
+ if (nextOverlay) nextOverlay.focus();
1160
+ else if (previouslyFocusedRef.current?.isConnected) {
1161
+ previouslyFocusedRef.current.focus();
1162
+ }
1163
+ }
1164
+ };
1165
+ }, [options.open, options.panelRef]);
1166
+ }
1167
+
1168
+ // packages/drawer/src/index.tsx
1169
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1170
+ var DrawerWidths = {
1171
+ small: 360,
1172
+ medium: 400,
1173
+ large: 480
1174
+ };
1175
+ function Drawer({
1176
+ open,
1177
+ onClose,
1178
+ title,
1179
+ description,
1180
+ footer,
1181
+ side = "right",
1182
+ width = DrawerWidths.medium,
1183
+ fullScreen = false,
1184
+ children,
1185
+ closeOnBackdropClick = true,
1186
+ closeOnEscape = true,
1187
+ closeLabel = "Close drawer",
1188
+ initialFocusRef,
1189
+ restoreFocus = true,
1190
+ className,
1191
+ style,
1192
+ "aria-label": ariaLabel,
1193
+ "aria-describedby": ariaDescribedBy,
1194
+ ...props
1195
+ }) {
1196
+ const titleId = (0, import_react9.useId)();
1197
+ const descriptionId = (0, import_react9.useId)();
1198
+ const panelRef = (0, import_react9.useRef)(null);
1199
+ useModalOverlay({
1200
+ open,
1201
+ onClose,
1202
+ panelRef,
1203
+ priority: 1e3,
1204
+ closeOnEscape,
1205
+ initialFocusRef,
1206
+ restoreFocus
1207
+ });
719
1208
  if (!open || typeof document === "undefined") return null;
720
1209
  const panelStyle = !fullScreen && (side === "left" || side === "right") ? { ...style, width: typeof width === "number" ? `${width}px` : width } : style;
721
- return (0, import_react_dom.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "fe-drawer-backdrop", role: "presentation", onMouseDown: (event) => {
722
- if (event.target === event.currentTarget && closeOnBackdropClick) onClose();
723
- }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("aside", { className: ["fe-drawer", `fe-drawer--${side}`, fullScreen && "fe-drawer--full-screen", className].filter(Boolean).join(" "), style: panelStyle, role: "dialog", "aria-modal": "true", "aria-label": typeof title === "string" ? title : "Drawer", ...props, children: [
724
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("header", { className: "fe-drawer__header", children: [
725
- title && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("h2", { children: title }),
726
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("button", { type: "button", "aria-label": "Close drawer", onClick: onClose, children: "\xD7" })
727
- ] }),
728
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: "fe-drawer__body", children }),
729
- footer && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("footer", { className: "fe-drawer__footer", children: footer })
730
- ] }) }), document.body);
1210
+ const describedBy = [description ? descriptionId : void 0, ariaDescribedBy].filter(Boolean).join(" ") || void 0;
1211
+ return (0, import_react_dom.createPortal)(
1212
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1213
+ "div",
1214
+ {
1215
+ className: "fe-drawer-backdrop",
1216
+ role: "presentation",
1217
+ onMouseDown: (event) => {
1218
+ if (event.target === event.currentTarget && closeOnBackdropClick)
1219
+ onClose();
1220
+ },
1221
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1222
+ "aside",
1223
+ {
1224
+ ref: panelRef,
1225
+ className: [
1226
+ "fe-drawer",
1227
+ `fe-drawer--${side}`,
1228
+ fullScreen && "fe-drawer--full-screen",
1229
+ className
1230
+ ].filter(Boolean).join(" "),
1231
+ style: panelStyle,
1232
+ role: "dialog",
1233
+ "aria-modal": "true",
1234
+ "aria-labelledby": title ? titleId : void 0,
1235
+ "aria-describedby": describedBy,
1236
+ "aria-label": ariaLabel ?? (title ? void 0 : "Drawer"),
1237
+ tabIndex: -1,
1238
+ ...props,
1239
+ children: [
1240
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("header", { className: "fe-drawer__header", children: [
1241
+ (title || description) && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "fe-drawer__heading", children: [
1242
+ title && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h2", { id: titleId, children: title }),
1243
+ description && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { id: descriptionId, children: description })
1244
+ ] }),
1245
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1246
+ Button,
1247
+ {
1248
+ hierarchy: "tertiary-gray",
1249
+ size: "32",
1250
+ iconOnly: true,
1251
+ icon: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(CloseIcon, {}),
1252
+ "aria-label": closeLabel,
1253
+ onClick: onClose
1254
+ }
1255
+ )
1256
+ ] }),
1257
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "fe-drawer__body", children }),
1258
+ footer && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("footer", { className: "fe-drawer__footer", children: footer })
1259
+ ]
1260
+ }
1261
+ )
1262
+ }
1263
+ ),
1264
+ document.body
1265
+ );
731
1266
  }
732
1267
 
733
1268
  // packages/form-controls/src/controls/TextInput/text-input.tsx
734
- var import_react9 = require("react");
1269
+ var import_react11 = require("react");
735
1270
 
736
1271
  // packages/tooltip/src/index.tsx
737
- var import_react8 = require("react");
738
- var import_jsx_runtime11 = require("react/jsx-runtime");
1272
+ var import_react10 = require("react");
1273
+ var import_jsx_runtime12 = require("react/jsx-runtime");
739
1274
  function Tooltip({ content, children, placement = "top", disabled, className, ...props }) {
740
- const [visible, setVisible] = (0, import_react8.useState)(false);
741
- const id = (0, import_react8.useId)();
742
- const trigger = (0, import_react8.cloneElement)(children, { "aria-describedby": visible ? id : void 0, onMouseEnter: (event) => {
1275
+ const [visible, setVisible] = (0, import_react10.useState)(false);
1276
+ const id = (0, import_react10.useId)();
1277
+ const trigger = (0, import_react10.cloneElement)(children, { "aria-describedby": visible ? id : void 0, onMouseEnter: (event) => {
743
1278
  children.props.onMouseEnter?.(event);
744
1279
  setVisible(true);
745
1280
  }, onMouseLeave: (event) => {
@@ -752,14 +1287,14 @@ function Tooltip({ content, children, placement = "top", disabled, className, ..
752
1287
  children.props.onBlur?.(event);
753
1288
  setVisible(false);
754
1289
  } });
755
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: ["fe-tooltip", `fe-tooltip--${placement}`, className].filter(Boolean).join(" "), ...props, children: [
1290
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: ["fe-tooltip", `fe-tooltip--${placement}`, className].filter(Boolean).join(" "), ...props, children: [
756
1291
  trigger,
757
- visible && !disabled && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { id, role: "tooltip", className: "fe-tooltip__content", children: content })
1292
+ visible && !disabled && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { id, role: "tooltip", className: "fe-tooltip__content", children: content })
758
1293
  ] });
759
1294
  }
760
1295
 
761
1296
  // packages/form-controls/src/controls/Field/field.tsx
762
- var import_jsx_runtime12 = require("react/jsx-runtime");
1297
+ var import_jsx_runtime13 = require("react/jsx-runtime");
763
1298
  function getFieldError(error, errorMessage) {
764
1299
  if (errorMessage !== void 0 && errorMessage !== null) return errorMessage;
765
1300
  if (typeof error !== "boolean") return error;
@@ -776,10 +1311,10 @@ function FieldLabel({
776
1311
  isRequired = false
777
1312
  }) {
778
1313
  if (!label) return null;
779
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: "fe-field__label", children: [
780
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { id, children: label }),
781
- isRequired && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "fe-field__required", "aria-hidden": "true", children: "*" }),
782
- description && descriptionDisplay === "tooltip" && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Tooltip, { content: description, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1314
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "fe-field__label", children: [
1315
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { id, children: label }),
1316
+ isRequired && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "fe-field__required", "aria-hidden": "true", children: "*" }),
1317
+ description && descriptionDisplay === "tooltip" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Tooltip, { content: description, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
783
1318
  "span",
784
1319
  {
785
1320
  className: "fe-field__info",
@@ -798,7 +1333,7 @@ function FieldMessage({
798
1333
  descriptionDisplay
799
1334
  }) {
800
1335
  if (error !== void 0 && error !== false && error !== null)
801
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1336
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
802
1337
  "span",
803
1338
  {
804
1339
  id,
@@ -808,13 +1343,13 @@ function FieldMessage({
808
1343
  }
809
1344
  );
810
1345
  if (description && descriptionDisplay === "inline")
811
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { id, className: "fe-field__message", children: description });
1346
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { id, className: "fe-field__message", children: description });
812
1347
  return null;
813
1348
  }
814
1349
 
815
1350
  // packages/form-controls/src/controls/TextInput/text-input.tsx
816
- var import_jsx_runtime13 = require("react/jsx-runtime");
817
- var TextInput = (0, import_react9.forwardRef)(
1351
+ var import_jsx_runtime14 = require("react/jsx-runtime");
1352
+ var TextInput = (0, import_react11.forwardRef)(
818
1353
  function TextInput2({
819
1354
  value,
820
1355
  defaultValue = "",
@@ -844,12 +1379,12 @@ var TextInput = (0, import_react9.forwardRef)(
844
1379
  "aria-labelledby": ariaLabelledBy,
845
1380
  ...props
846
1381
  }, ref) {
847
- const generatedId = (0, import_react9.useId)();
1382
+ const generatedId = (0, import_react11.useId)();
848
1383
  const inputId = id ?? generatedId + "-input";
849
1384
  const labelId = generatedId + "-label";
850
1385
  const messageId2 = generatedId + "-message";
851
1386
  const controlled = value !== void 0;
852
- const [internalValue, setInternalValue] = (0, import_react9.useState)(defaultValue);
1387
+ const [internalValue, setInternalValue] = (0, import_react11.useState)(defaultValue);
853
1388
  const currentValue = controlled ? value : internalValue;
854
1389
  const fieldError = getFieldError(error, errorMessage);
855
1390
  const hasError = fieldError !== void 0 && fieldError !== false && fieldError !== null;
@@ -870,7 +1405,7 @@ var TextInput = (0, import_react9.forwardRef)(
870
1405
  onValueChange?.("");
871
1406
  onClear?.();
872
1407
  };
873
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1408
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
874
1409
  "div",
875
1410
  {
876
1411
  className: [
@@ -879,7 +1414,7 @@ var TextInput = (0, import_react9.forwardRef)(
879
1414
  className
880
1415
  ].filter(Boolean).join(" "),
881
1416
  children: [
882
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1417
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
883
1418
  FieldLabel,
884
1419
  {
885
1420
  id: labelId,
@@ -889,10 +1424,10 @@ var TextInput = (0, import_react9.forwardRef)(
889
1424
  isRequired
890
1425
  }
891
1426
  ),
892
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "fe-text-input__control", children: [
893
- resolvedPrefix && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "fe-text-input__prefix", children: resolvedPrefix }),
894
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "fe-text-input__input-wrap", children: [
895
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1427
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "fe-text-input__control", children: [
1428
+ resolvedPrefix && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "fe-text-input__prefix", children: resolvedPrefix }),
1429
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "fe-text-input__input-wrap", children: [
1430
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
896
1431
  "input",
897
1432
  {
898
1433
  ref,
@@ -914,26 +1449,26 @@ var TextInput = (0, import_react9.forwardRef)(
914
1449
  ...props
915
1450
  }
916
1451
  ),
917
- isRequired && placeholder && !currentValue && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: "fe-text-input__placeholder", "aria-hidden": "true", children: [
918
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: placeholder }),
919
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "fe-field__required", children: "*" })
1452
+ isRequired && placeholder && !currentValue && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "fe-text-input__placeholder", "aria-hidden": "true", children: [
1453
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: placeholder }),
1454
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "fe-field__required", children: "*" })
920
1455
  ] })
921
1456
  ] }),
922
- resolvedSuffix && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "fe-text-input__suffix", children: resolvedSuffix }),
923
- clearable && currentValue && !disabled && !readOnly && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1457
+ resolvedSuffix && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "fe-text-input__suffix", children: resolvedSuffix }),
1458
+ clearable && currentValue && !disabled && !readOnly && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
924
1459
  Button,
925
1460
  {
926
1461
  hierarchy: "tertiary-gray",
927
1462
  size: "24",
928
1463
  iconOnly: true,
929
- icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(CloseIcon, { size: 14 }),
1464
+ icon: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CloseIcon, { size: 14 }),
930
1465
  "aria-label": clearLabel,
931
1466
  onClick: clear,
932
1467
  className: "fe-text-input__clear"
933
1468
  }
934
1469
  )
935
1470
  ] }),
936
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1471
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
937
1472
  FieldMessage,
938
1473
  {
939
1474
  id: messageId2,
@@ -949,10 +1484,257 @@ var TextInput = (0, import_react9.forwardRef)(
949
1484
  );
950
1485
  TextInput.displayName = "TextInput";
951
1486
 
1487
+ // packages/form-controls/src/controls/EmailInput/email-input.tsx
1488
+ var import_react13 = require("react");
1489
+
1490
+ // packages/form-controls/src/controls/ValidatedInput/validation.ts
1491
+ var import_react12 = require("react");
1492
+ var invalidValueMessage = "Invalid value.";
1493
+ function toValidationError(result) {
1494
+ if (typeof result === "string") return result || void 0;
1495
+ return result === false ? invalidValueMessage : void 0;
1496
+ }
1497
+ function validateEmail(value, required = false) {
1498
+ const email = value.trim();
1499
+ if (!email) return required ? "Email is required." : void 0;
1500
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email) ? void 0 : "Enter a valid email address.";
1501
+ }
1502
+ function validatePassword(value, required = false) {
1503
+ if (!value) return required ? "Password is required." : void 0;
1504
+ if (value.length < 8) return "Use at least 8 characters.";
1505
+ if (!/[a-z]/.test(value) || !/[A-Z]/.test(value) || !/\d/.test(value))
1506
+ return "Include uppercase, lowercase, and a number.";
1507
+ return void 0;
1508
+ }
1509
+ function validatePhoneNumber(value, required = false) {
1510
+ const phoneNumber = value.trim();
1511
+ if (!phoneNumber) return required ? "Phone number is required." : void 0;
1512
+ if (!/^\+?[\d() ]+$/.test(phoneNumber))
1513
+ return "Use only numbers, spaces, parentheses, and an optional leading +.";
1514
+ const digitCount = phoneNumber.replace(/\D/g, "").length;
1515
+ return digitCount >= 7 && digitCount <= 15 ? void 0 : "Enter a phone number with 7 to 15 digits.";
1516
+ }
1517
+ function normalizePhoneNumber(value) {
1518
+ return value.replace(/[^\d+() ]/g, "");
1519
+ }
1520
+ function useInputValidation({
1521
+ error,
1522
+ errorMessage,
1523
+ isRequired = false,
1524
+ required = false,
1525
+ validate,
1526
+ validateOn = "blur",
1527
+ builtInValidator
1528
+ }) {
1529
+ const [validationError, setValidationError] = (0, import_react12.useState)();
1530
+ const [hasValidated, setHasValidated] = (0, import_react12.useState)(false);
1531
+ const hasExternalError = error !== void 0 || errorMessage !== void 0;
1532
+ const validateValue = (value) => {
1533
+ const builtInError = builtInValidator(value, isRequired || required);
1534
+ const customError = builtInError ? void 0 : toValidationError(validate?.(value));
1535
+ const nextError = builtInError ?? customError;
1536
+ setHasValidated(true);
1537
+ setValidationError(nextError);
1538
+ return nextError;
1539
+ };
1540
+ return {
1541
+ error: hasExternalError ? getFieldError(error, errorMessage) : validationError,
1542
+ onValueChange(value) {
1543
+ if (validateOn === "change" || hasValidated) validateValue(value);
1544
+ },
1545
+ onBlur(value) {
1546
+ if (validateOn === "blur") validateValue(value);
1547
+ }
1548
+ };
1549
+ }
1550
+
1551
+ // packages/form-controls/src/controls/EmailInput/email-input.tsx
1552
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1553
+ var EmailInput = (0, import_react13.forwardRef)(
1554
+ function EmailInput2({
1555
+ error,
1556
+ errorMessage,
1557
+ isRequired,
1558
+ required,
1559
+ validate,
1560
+ validateOn,
1561
+ onBlur,
1562
+ onValueChange,
1563
+ autoComplete,
1564
+ className,
1565
+ ...props
1566
+ }, ref) {
1567
+ const validation = useInputValidation({
1568
+ error,
1569
+ errorMessage,
1570
+ isRequired,
1571
+ required,
1572
+ validate,
1573
+ validateOn,
1574
+ builtInValidator: validateEmail
1575
+ });
1576
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1577
+ TextInput,
1578
+ {
1579
+ ...props,
1580
+ ref,
1581
+ className: ["fe-email-input", className].filter(Boolean).join(" "),
1582
+ type: "email",
1583
+ inputMode: "email",
1584
+ autoComplete: autoComplete ?? "email",
1585
+ isRequired,
1586
+ required,
1587
+ prefix: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(MailboxIcon, { size: 18 }),
1588
+ error: validation.error,
1589
+ onValueChange: (value) => {
1590
+ validation.onValueChange(value);
1591
+ onValueChange?.(value);
1592
+ },
1593
+ onBlur: (event) => {
1594
+ validation.onBlur(event.currentTarget.value);
1595
+ onBlur?.(event);
1596
+ }
1597
+ }
1598
+ );
1599
+ }
1600
+ );
1601
+ EmailInput.displayName = "EmailInput";
1602
+
1603
+ // packages/form-controls/src/controls/PasswordInput/password-input.tsx
1604
+ var import_react14 = require("react");
1605
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1606
+ var PasswordInput = (0, import_react14.forwardRef)(
1607
+ function PasswordInput2({
1608
+ error,
1609
+ errorMessage,
1610
+ isRequired,
1611
+ required,
1612
+ validate,
1613
+ validateOn,
1614
+ onBlur,
1615
+ onValueChange,
1616
+ autoComplete,
1617
+ className,
1618
+ showPasswordLabel = "Show password",
1619
+ hidePasswordLabel = "Hide password",
1620
+ ...props
1621
+ }, ref) {
1622
+ const [visible, setVisible] = (0, import_react14.useState)(false);
1623
+ const validation = useInputValidation({
1624
+ error,
1625
+ errorMessage,
1626
+ isRequired,
1627
+ required,
1628
+ validate,
1629
+ validateOn,
1630
+ builtInValidator: validatePassword
1631
+ });
1632
+ const toggleLabel = visible ? hidePasswordLabel : showPasswordLabel;
1633
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1634
+ TextInput,
1635
+ {
1636
+ ...props,
1637
+ ref,
1638
+ className: ["fe-password-input", className].filter(Boolean).join(" "),
1639
+ type: visible ? "text" : "password",
1640
+ autoComplete: autoComplete ?? "current-password",
1641
+ isRequired,
1642
+ required,
1643
+ suffix: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1644
+ Button,
1645
+ {
1646
+ hierarchy: "tertiary-gray",
1647
+ size: "24",
1648
+ iconOnly: true,
1649
+ icon: visible ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(EyeOffIcon, { size: 16 }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(EyeIcon, { size: 16 }),
1650
+ "aria-label": toggleLabel,
1651
+ "aria-pressed": visible,
1652
+ className: "fe-password-input__toggle",
1653
+ onMouseDown: (event) => event.preventDefault(),
1654
+ onClick: () => setVisible((previous) => !previous)
1655
+ }
1656
+ ),
1657
+ error: validation.error,
1658
+ onValueChange: (value) => {
1659
+ validation.onValueChange(value);
1660
+ onValueChange?.(value);
1661
+ },
1662
+ onBlur: (event) => {
1663
+ validation.onBlur(event.currentTarget.value);
1664
+ onBlur?.(event);
1665
+ }
1666
+ }
1667
+ );
1668
+ }
1669
+ );
1670
+ PasswordInput.displayName = "PasswordInput";
1671
+
1672
+ // packages/form-controls/src/controls/PhoneNumberInput/phone-number-input.tsx
1673
+ var import_react15 = require("react");
1674
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1675
+ var PhoneNumberInput = (0, import_react15.forwardRef)(function PhoneNumberInput2({
1676
+ value,
1677
+ defaultValue = "",
1678
+ error,
1679
+ errorMessage,
1680
+ isRequired,
1681
+ required,
1682
+ validate,
1683
+ validateOn,
1684
+ onBlur,
1685
+ onValueChange,
1686
+ autoComplete,
1687
+ className,
1688
+ ...props
1689
+ }, ref) {
1690
+ const controlled = value !== void 0;
1691
+ const [uncontrolledValue, setUncontrolledValue] = (0, import_react15.useState)(
1692
+ () => normalizePhoneNumber(defaultValue)
1693
+ );
1694
+ const currentValue = controlled ? value : uncontrolledValue;
1695
+ const validation = useInputValidation({
1696
+ error,
1697
+ errorMessage,
1698
+ isRequired,
1699
+ required,
1700
+ validate,
1701
+ validateOn,
1702
+ builtInValidator: validatePhoneNumber
1703
+ });
1704
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1705
+ TextInput,
1706
+ {
1707
+ ...props,
1708
+ ref,
1709
+ className: ["fe-phone-number-input", className].filter(Boolean).join(" "),
1710
+ type: "tel",
1711
+ inputMode: "tel",
1712
+ autoComplete: autoComplete ?? "tel",
1713
+ value: currentValue,
1714
+ isRequired,
1715
+ required,
1716
+ prefix: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(PhoneIcon, { size: 18 }),
1717
+ error: validation.error,
1718
+ onValueChange: (nextValue) => {
1719
+ const normalizedValue = normalizePhoneNumber(nextValue);
1720
+ if (!controlled) setUncontrolledValue(normalizedValue);
1721
+ validation.onValueChange(normalizedValue);
1722
+ onValueChange?.(normalizedValue);
1723
+ },
1724
+ onBlur: (event) => {
1725
+ const normalizedValue = normalizePhoneNumber(event.currentTarget.value);
1726
+ validation.onBlur(normalizedValue);
1727
+ onBlur?.(event);
1728
+ }
1729
+ }
1730
+ );
1731
+ });
1732
+ PhoneNumberInput.displayName = "PhoneNumberInput";
1733
+
952
1734
  // packages/form-controls/src/controls/TextArea/text-area.tsx
953
- var import_react10 = require("react");
954
- var import_jsx_runtime14 = require("react/jsx-runtime");
955
- var TextArea = (0, import_react10.forwardRef)(
1735
+ var import_react16 = require("react");
1736
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1737
+ var TextArea = (0, import_react16.forwardRef)(
956
1738
  function TextArea2({
957
1739
  value,
958
1740
  defaultValue = "",
@@ -979,13 +1761,13 @@ var TextArea = (0, import_react10.forwardRef)(
979
1761
  "aria-labelledby": ariaLabelledBy,
980
1762
  ...props
981
1763
  }, ref) {
982
- const generatedId = (0, import_react10.useId)();
1764
+ const generatedId = (0, import_react16.useId)();
983
1765
  const inputId = id ?? generatedId + "-input";
984
1766
  const labelId = generatedId + "-label";
985
1767
  const messageId2 = generatedId + "-message";
986
1768
  const controlled = value !== void 0;
987
- const [internalValue, setInternalValue] = (0, import_react10.useState)(defaultValue);
988
- const textareaRef = (0, import_react10.useRef)(null);
1769
+ const [internalValue, setInternalValue] = (0, import_react16.useState)(defaultValue);
1770
+ const textareaRef = (0, import_react16.useRef)(null);
989
1771
  const currentValue = controlled ? value : internalValue;
990
1772
  const fieldError = getFieldError(error, errorMessage);
991
1773
  const hasError = fieldError !== void 0 && fieldError !== false && fieldError !== null;
@@ -1003,8 +1785,8 @@ var TextArea = (0, import_react10.forwardRef)(
1003
1785
  textarea.style.height = "auto";
1004
1786
  textarea.style.height = `${textarea.scrollHeight}px`;
1005
1787
  };
1006
- (0, import_react10.useImperativeHandle)(ref, () => textareaRef.current, []);
1007
- (0, import_react10.useLayoutEffect)(() => {
1788
+ (0, import_react16.useImperativeHandle)(ref, () => textareaRef.current, []);
1789
+ (0, import_react16.useLayoutEffect)(() => {
1008
1790
  if (autosize && textareaRef.current) {
1009
1791
  resizeToContent(textareaRef.current);
1010
1792
  }
@@ -1014,7 +1796,7 @@ var TextArea = (0, import_react10.forwardRef)(
1014
1796
  onValueChange?.("");
1015
1797
  onClear?.();
1016
1798
  };
1017
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1799
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1018
1800
  "div",
1019
1801
  {
1020
1802
  className: [
@@ -1024,7 +1806,7 @@ var TextArea = (0, import_react10.forwardRef)(
1024
1806
  className
1025
1807
  ].filter(Boolean).join(" "),
1026
1808
  children: [
1027
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1809
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1028
1810
  FieldLabel,
1029
1811
  {
1030
1812
  id: labelId,
@@ -1034,8 +1816,8 @@ var TextArea = (0, import_react10.forwardRef)(
1034
1816
  isRequired
1035
1817
  }
1036
1818
  ),
1037
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "fe-text-area__control", children: [
1038
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1819
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "fe-text-area__control", children: [
1820
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1039
1821
  "textarea",
1040
1822
  {
1041
1823
  ref: textareaRef,
@@ -1058,24 +1840,24 @@ var TextArea = (0, import_react10.forwardRef)(
1058
1840
  ...props
1059
1841
  }
1060
1842
  ),
1061
- isRequired && placeholder && !currentValue && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: "fe-text-area__placeholder", "aria-hidden": "true", children: [
1062
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: placeholder }),
1063
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: "fe-field__required", children: "*" })
1843
+ isRequired && placeholder && !currentValue && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "fe-text-area__placeholder", "aria-hidden": "true", children: [
1844
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: placeholder }),
1845
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "fe-field__required", children: "*" })
1064
1846
  ] }),
1065
- clearable && currentValue && !disabled && !readOnly && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1847
+ clearable && currentValue && !disabled && !readOnly && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1066
1848
  Button,
1067
1849
  {
1068
1850
  hierarchy: "tertiary-gray",
1069
1851
  size: "24",
1070
1852
  iconOnly: true,
1071
- icon: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CloseIcon, { size: 14 }),
1853
+ icon: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(CloseIcon, { size: 14 }),
1072
1854
  "aria-label": clearLabel,
1073
1855
  onClick: clear,
1074
1856
  className: "fe-text-area__clear"
1075
1857
  }
1076
1858
  )
1077
1859
  ] }),
1078
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1860
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1079
1861
  FieldMessage,
1080
1862
  {
1081
1863
  id: messageId2,
@@ -1092,10 +1874,25 @@ var TextArea = (0, import_react10.forwardRef)(
1092
1874
  TextArea.displayName = "TextArea";
1093
1875
 
1094
1876
  // packages/form-controls/src/controls/Selection/selection.tsx
1095
- var import_react11 = require("react");
1877
+ var import_react17 = require("react");
1096
1878
  var import_react_dom2 = require("react-dom");
1097
- var import_jsx_runtime15 = require("react/jsx-runtime");
1098
- var Selection = (0, import_react11.forwardRef)(
1879
+
1880
+ // packages/overlay/src/getPortalZIndex.ts
1881
+ var DEFAULT_PORTAL_Z_INDEX = 1e3;
1882
+ function getPortalZIndex(anchor) {
1883
+ if (!anchor || typeof window === "undefined") return DEFAULT_PORTAL_Z_INDEX;
1884
+ let highestAncestorZIndex = DEFAULT_PORTAL_Z_INDEX - 1;
1885
+ for (let element = anchor; element; element = element.parentElement) {
1886
+ const zIndex = Number.parseInt(window.getComputedStyle(element).zIndex, 10);
1887
+ if (Number.isFinite(zIndex))
1888
+ highestAncestorZIndex = Math.max(highestAncestorZIndex, zIndex);
1889
+ }
1890
+ return Math.max(DEFAULT_PORTAL_Z_INDEX, highestAncestorZIndex + 1);
1891
+ }
1892
+
1893
+ // packages/form-controls/src/controls/Selection/selection.tsx
1894
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1895
+ var Selection = (0, import_react17.forwardRef)(
1099
1896
  function Selection2({
1100
1897
  className,
1101
1898
  label,
@@ -1124,7 +1921,7 @@ var Selection = (0, import_react11.forwardRef)(
1124
1921
  "aria-labelledby": ariaLabelledBy,
1125
1922
  ...props
1126
1923
  }, ref) {
1127
- const generatedId = (0, import_react11.useId)();
1924
+ const generatedId = (0, import_react17.useId)();
1128
1925
  const triggerId = id ?? generatedId + "-trigger";
1129
1926
  const listboxId = triggerId + "-listbox";
1130
1927
  const labelId = generatedId + "-label";
@@ -1142,7 +1939,7 @@ var Selection = (0, import_react11.forwardRef)(
1142
1939
  label ? labelId : void 0
1143
1940
  );
1144
1941
  const isControlled = value !== void 0;
1145
- const [internalValue, setInternalValue] = (0, import_react11.useState)(
1942
+ const [internalValue, setInternalValue] = (0, import_react17.useState)(
1146
1943
  defaultValue ?? (multiple ? [] : "")
1147
1944
  );
1148
1945
  const selectedValue = isControlled ? value : internalValue;
@@ -1150,13 +1947,13 @@ var Selection = (0, import_react11.forwardRef)(
1150
1947
  const selectedOptions = options.filter(
1151
1948
  (option) => selectedValues.some((item) => String(item) === String(option.value))
1152
1949
  );
1153
- const [open, setOpen] = (0, import_react11.useState)(false);
1154
- const [query, setQuery] = (0, import_react11.useState)("");
1155
- const [activeIndex, setActiveIndex] = (0, import_react11.useState)(0);
1156
- const rootRef = (0, import_react11.useRef)(null);
1157
- const menuRef = (0, import_react11.useRef)(null);
1158
- const [menuPosition, setMenuPosition] = (0, import_react11.useState)(null);
1159
- (0, import_react11.useEffect)(() => {
1950
+ const [open, setOpen] = (0, import_react17.useState)(false);
1951
+ const [query, setQuery] = (0, import_react17.useState)("");
1952
+ const [activeIndex, setActiveIndex] = (0, import_react17.useState)(0);
1953
+ const rootRef = (0, import_react17.useRef)(null);
1954
+ const menuRef = (0, import_react17.useRef)(null);
1955
+ const [menuPosition, setMenuPosition] = (0, import_react17.useState)(null);
1956
+ (0, import_react17.useEffect)(() => {
1160
1957
  const close = (event) => {
1161
1958
  const target = event.target;
1162
1959
  if (!rootRef.current?.contains(target) && !menuRef.current?.contains(target))
@@ -1165,7 +1962,7 @@ var Selection = (0, import_react11.forwardRef)(
1165
1962
  document.addEventListener("mousedown", close);
1166
1963
  return () => document.removeEventListener("mousedown", close);
1167
1964
  }, []);
1168
- (0, import_react11.useLayoutEffect)(() => {
1965
+ (0, import_react17.useLayoutEffect)(() => {
1169
1966
  if (!open) return;
1170
1967
  const updateMenuPosition = () => {
1171
1968
  const rect = rootRef.current?.getBoundingClientRect();
@@ -1173,7 +1970,8 @@ var Selection = (0, import_react11.forwardRef)(
1173
1970
  setMenuPosition({
1174
1971
  top: rect.bottom + 7,
1175
1972
  left: rect.left,
1176
- width: rect.width
1973
+ width: rect.width,
1974
+ zIndex: getPortalZIndex(rootRef.current)
1177
1975
  });
1178
1976
  };
1179
1977
  updateMenuPosition();
@@ -1242,7 +2040,7 @@ var Selection = (0, import_react11.forwardRef)(
1242
2040
  }
1243
2041
  if (event.key === "Escape") setOpen(false);
1244
2042
  };
1245
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2043
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
1246
2044
  "div",
1247
2045
  {
1248
2046
  ref,
@@ -1257,7 +2055,7 @@ var Selection = (0, import_react11.forwardRef)(
1257
2055
  ].filter(Boolean).join(" "),
1258
2056
  ...props,
1259
2057
  children: [
1260
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2058
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1261
2059
  FieldLabel,
1262
2060
  {
1263
2061
  id: labelId,
@@ -1267,8 +2065,8 @@ var Selection = (0, import_react11.forwardRef)(
1267
2065
  isRequired
1268
2066
  }
1269
2067
  ),
1270
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { ref: rootRef, className: "fe-selection__control", children: [
1271
- name && selectedValues.map((item) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2068
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { ref: rootRef, className: "fe-selection__control", children: [
2069
+ name && selectedValues.map((item) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1272
2070
  "input",
1273
2071
  {
1274
2072
  type: "hidden",
@@ -1277,7 +2075,7 @@ var Selection = (0, import_react11.forwardRef)(
1277
2075
  },
1278
2076
  String(item)
1279
2077
  )),
1280
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2078
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
1281
2079
  "button",
1282
2080
  {
1283
2081
  id: triggerId,
@@ -1295,7 +2093,7 @@ var Selection = (0, import_react11.forwardRef)(
1295
2093
  onClick: () => setOpen((current) => !current),
1296
2094
  onKeyDown: onTriggerKeyDown,
1297
2095
  children: [
1298
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2096
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1299
2097
  "span",
1300
2098
  {
1301
2099
  className: [
@@ -1303,30 +2101,30 @@ var Selection = (0, import_react11.forwardRef)(
1303
2101
  !selectedOptions.length && "is-placeholder",
1304
2102
  tag && selectedOptions.length > 1 && "is-tags"
1305
2103
  ].filter(Boolean).join(" "),
1306
- children: displayLabel ? tag && multiple ? selectedOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2104
+ children: displayLabel ? tag && multiple ? selectedOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
1307
2105
  "span",
1308
2106
  {
1309
2107
  className: "fe-selection__tag",
1310
2108
  children: [
1311
2109
  option.label,
1312
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { "aria-hidden": "true", children: "\xD7" })
2110
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { "aria-hidden": "true", children: "\xD7" })
1313
2111
  ]
1314
2112
  },
1315
2113
  String(option.value)
1316
- )) : displayLabel.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { children: [
2114
+ )) : displayLabel.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { children: [
1317
2115
  item,
1318
2116
  index < displayLabel.length - 1 ? ", " : ""
1319
- ] }, index)) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
1320
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: placeholder }),
1321
- isRequired && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "fe-field__required", "aria-hidden": "true", children: "*" })
2117
+ ] }, index)) : /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
2118
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { children: placeholder }),
2119
+ isRequired && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "fe-field__required", "aria-hidden": "true", children: "*" })
1322
2120
  ] })
1323
2121
  }
1324
2122
  ),
1325
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "fe-selection__actions", children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "fe-selection__chevron", "aria-hidden": "true" }) })
2123
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "fe-selection__actions", children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "fe-selection__chevron", "aria-hidden": "true" }) })
1326
2124
  ]
1327
2125
  }
1328
2126
  ),
1329
- clearable && selectedOptions.length > 0 && !disabled && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2127
+ clearable && selectedOptions.length > 0 && !disabled && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1330
2128
  "button",
1331
2129
  {
1332
2130
  type: "button",
@@ -1336,7 +2134,7 @@ var Selection = (0, import_react11.forwardRef)(
1336
2134
  }
1337
2135
  ),
1338
2136
  open && menuPosition && (0, import_react_dom2.createPortal)(
1339
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2137
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
1340
2138
  "div",
1341
2139
  {
1342
2140
  ref: menuRef,
@@ -1346,14 +2144,15 @@ var Selection = (0, import_react11.forwardRef)(
1346
2144
  position: "fixed",
1347
2145
  top: menuPosition.top,
1348
2146
  left: menuPosition.left,
1349
- width: menuPosition.width
2147
+ width: menuPosition.width,
2148
+ zIndex: menuPosition.zIndex
1350
2149
  },
1351
2150
  role: "listbox",
1352
2151
  "aria-multiselectable": multiple || void 0,
1353
2152
  children: [
1354
- searchable && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "fe-selection__search", children: [
1355
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { "aria-hidden": "true", children: "\u2315" }),
1356
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2153
+ searchable && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "fe-selection__search", children: [
2154
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { "aria-hidden": "true", children: "\u2315" }),
2155
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1357
2156
  "input",
1358
2157
  {
1359
2158
  autoFocus: true,
@@ -1367,11 +2166,11 @@ var Selection = (0, import_react11.forwardRef)(
1367
2166
  }
1368
2167
  )
1369
2168
  ] }),
1370
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "fe-selection__options", children: filteredOptions.length ? filteredOptions.map((option, index) => {
2169
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "fe-selection__options", children: filteredOptions.length ? filteredOptions.map((option, index) => {
1371
2170
  const isSelected = selectedValues.some(
1372
2171
  (item) => String(item) === String(option.value)
1373
2172
  );
1374
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2173
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
1375
2174
  "button",
1376
2175
  {
1377
2176
  type: "button",
@@ -1385,8 +2184,8 @@ var Selection = (0, import_react11.forwardRef)(
1385
2184
  onMouseMove: () => setActiveIndex(index),
1386
2185
  onClick: () => choose(option),
1387
2186
  children: [
1388
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: option.label }),
1389
- isSelected && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2187
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { children: option.label }),
2188
+ isSelected && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1390
2189
  "span",
1391
2190
  {
1392
2191
  className: "fe-selection__check",
@@ -1398,14 +2197,14 @@ var Selection = (0, import_react11.forwardRef)(
1398
2197
  },
1399
2198
  String(option.value)
1400
2199
  );
1401
- }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("p", { className: "fe-selection__empty", children: "No matching options" }) })
2200
+ }) : /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "fe-selection__empty", children: "No matching options" }) })
1402
2201
  ]
1403
2202
  }
1404
2203
  ),
1405
2204
  document.body
1406
2205
  )
1407
2206
  ] }),
1408
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2207
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1409
2208
  FieldMessage,
1410
2209
  {
1411
2210
  id: messageId2,
@@ -1422,8 +2221,8 @@ var Selection = (0, import_react11.forwardRef)(
1422
2221
  Selection.displayName = "Selection";
1423
2222
 
1424
2223
  // packages/form-controls/src/controls/NumberInput/number-input.tsx
1425
- var import_react12 = require("react");
1426
- var import_jsx_runtime16 = require("react/jsx-runtime");
2224
+ var import_react18 = require("react");
2225
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1427
2226
  function formatNumber(value, decimals = 2, thousandSeparator = ",", decimalSeparator = ".") {
1428
2227
  return new Intl.NumberFormat("en-US", {
1429
2228
  minimumFractionDigits: 0,
@@ -1480,7 +2279,7 @@ function normalizeNumberInput(raw, options) {
1480
2279
  value
1481
2280
  };
1482
2281
  }
1483
- var NumberInput = (0, import_react12.forwardRef)(
2282
+ var NumberInput = (0, import_react18.forwardRef)(
1484
2283
  function NumberInput2({
1485
2284
  value,
1486
2285
  defaultValue = null,
@@ -1517,14 +2316,14 @@ var NumberInput = (0, import_react12.forwardRef)(
1517
2316
  onKeyDown,
1518
2317
  ...props
1519
2318
  }, ref) {
1520
- const inputRef = (0, import_react12.useRef)(null);
1521
- const generatedId = (0, import_react12.useId)();
2319
+ const inputRef = (0, import_react18.useRef)(null);
2320
+ const generatedId = (0, import_react18.useId)();
1522
2321
  const messageId2 = generatedId + "-message";
1523
2322
  const isControlled = value !== void 0;
1524
- const [internalValue, setInternalValue] = (0, import_react12.useState)(defaultValue);
1525
- const [focused, setFocused] = (0, import_react12.useState)(false);
2323
+ const [internalValue, setInternalValue] = (0, import_react18.useState)(defaultValue);
2324
+ const [focused, setFocused] = (0, import_react18.useState)(false);
1526
2325
  const actualValue = isControlled ? value ?? null : internalValue;
1527
- const [text, setText] = (0, import_react12.useState)(
2326
+ const [text, setText] = (0, import_react18.useState)(
1528
2327
  actualValue === null ? "" : formatNumber(
1529
2328
  actualValue,
1530
2329
  decimals,
@@ -1547,7 +2346,7 @@ var NumberInput = (0, import_react12.forwardRef)(
1547
2346
  );
1548
2347
  const resolvedPrefix = prefix ?? Prefix;
1549
2348
  const resolvedSuffix = suffix ?? Suffix;
1550
- (0, import_react12.useEffect)(() => {
2349
+ (0, import_react18.useEffect)(() => {
1551
2350
  if (!focused)
1552
2351
  setText(
1553
2352
  actualValue === null ? "" : formatNumber(
@@ -1601,7 +2400,7 @@ var NumberInput = (0, import_react12.forwardRef)(
1601
2400
  const stepIsUsable = Number.isFinite(step) && step > 0;
1602
2401
  const disableIncrement = Boolean(props.disabled || props.readOnly) || !stepIsUsable || max !== void 0 && actualValue !== null && actualValue >= max;
1603
2402
  const disableDecrement = Boolean(props.disabled || props.readOnly) || !stepIsUsable || min !== void 0 && actualValue !== null && actualValue <= min;
1604
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2403
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
1605
2404
  "div",
1606
2405
  {
1607
2406
  className: [
@@ -1610,7 +2409,7 @@ var NumberInput = (0, import_react12.forwardRef)(
1610
2409
  className
1611
2410
  ].filter(Boolean).join(" "),
1612
2411
  children: [
1613
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2412
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1614
2413
  FieldLabel,
1615
2414
  {
1616
2415
  id: labelId,
@@ -1620,10 +2419,10 @@ var NumberInput = (0, import_react12.forwardRef)(
1620
2419
  isRequired
1621
2420
  }
1622
2421
  ),
1623
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "fe-number-input__control", children: [
1624
- resolvedPrefix && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "fe-number-input__prefix", children: resolvedPrefix }),
1625
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "fe-number-input__input-wrap", children: [
1626
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2422
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "fe-number-input__control", children: [
2423
+ resolvedPrefix && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "fe-number-input__prefix", children: resolvedPrefix }),
2424
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "fe-number-input__input-wrap", children: [
2425
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1627
2426
  "input",
1628
2427
  {
1629
2428
  ref: (node) => {
@@ -1659,41 +2458,41 @@ var NumberInput = (0, import_react12.forwardRef)(
1659
2458
  "aria-describedby": describedBy
1660
2459
  }
1661
2460
  ),
1662
- isRequired && placeholder && !text && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2461
+ isRequired && placeholder && !text && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
1663
2462
  "span",
1664
2463
  {
1665
2464
  className: "fe-number-input__placeholder",
1666
2465
  "aria-hidden": "true",
1667
2466
  children: [
1668
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: placeholder }),
1669
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "fe-field__required", children: "*" })
2467
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { children: placeholder }),
2468
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "fe-field__required", children: "*" })
1670
2469
  ]
1671
2470
  }
1672
2471
  )
1673
2472
  ] }),
1674
- resolvedSuffix && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "fe-number-input__suffix", children: resolvedSuffix }),
2473
+ resolvedSuffix && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "fe-number-input__suffix", children: resolvedSuffix }),
1675
2474
  endAdornment,
1676
- showStepper && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: "fe-number-input__stepper", children: [
1677
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2475
+ showStepper && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "fe-number-input__stepper", children: [
2476
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1678
2477
  Button,
1679
2478
  {
1680
2479
  hierarchy: "tertiary-gray",
1681
2480
  size: "24",
1682
2481
  iconOnly: true,
1683
- icon: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ChevronUpIcon, { size: 12 }),
2482
+ icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ChevronUpIcon, { size: 12 }),
1684
2483
  "aria-label": incrementLabel,
1685
2484
  disabled: disableIncrement,
1686
2485
  onMouseDown: (event) => event.preventDefault(),
1687
2486
  onClick: () => adjustValue(1)
1688
2487
  }
1689
2488
  ),
1690
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2489
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1691
2490
  Button,
1692
2491
  {
1693
2492
  hierarchy: "tertiary-gray",
1694
2493
  size: "24",
1695
2494
  iconOnly: true,
1696
- icon: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(ChevronDownIcon, { size: 12 }),
2495
+ icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ChevronDownIcon, { size: 12 }),
1697
2496
  "aria-label": decrementLabel,
1698
2497
  disabled: disableDecrement,
1699
2498
  onMouseDown: (event) => event.preventDefault(),
@@ -1702,7 +2501,7 @@ var NumberInput = (0, import_react12.forwardRef)(
1702
2501
  )
1703
2502
  ] })
1704
2503
  ] }),
1705
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2504
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1706
2505
  FieldMessage,
1707
2506
  {
1708
2507
  id: messageId2,
@@ -1719,8 +2518,8 @@ var NumberInput = (0, import_react12.forwardRef)(
1719
2518
  NumberInput.displayName = "NumberInput";
1720
2519
 
1721
2520
  // packages/form-controls/src/controls/CurrencyInput/currency-input.tsx
1722
- var import_react13 = require("react");
1723
- var import_jsx_runtime17 = require("react/jsx-runtime");
2521
+ var import_react19 = require("react");
2522
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1724
2523
  function CurrencyInput({
1725
2524
  suffix = "VND",
1726
2525
  currencies,
@@ -1731,13 +2530,13 @@ function CurrencyInput({
1731
2530
  disabled,
1732
2531
  ...props
1733
2532
  }) {
1734
- const [internalCurrency, setInternalCurrency] = (0, import_react13.useState)(
2533
+ const [internalCurrency, setInternalCurrency] = (0, import_react19.useState)(
1735
2534
  defaultCurrency ?? currencies?.[0]?.code ?? ""
1736
2535
  );
1737
2536
  const selectedCurrency = currency ?? internalCurrency;
1738
2537
  const current = currencies?.find((item) => item.code === selectedCurrency);
1739
2538
  const currencySuffix = current?.suffix ?? current?.code ?? suffix;
1740
- const endAdornment = currencies?.length ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2539
+ const endAdornment = currencies?.length ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1741
2540
  Selection,
1742
2541
  {
1743
2542
  className: "fe-currency-input__currency",
@@ -1756,8 +2555,8 @@ function CurrencyInput({
1756
2555
  onCurrencyChange?.(next);
1757
2556
  }
1758
2557
  }
1759
- ) : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "fe-currency-input__suffix", children: currencySuffix });
1760
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2558
+ ) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "fe-currency-input__suffix", children: currencySuffix });
2559
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1761
2560
  NumberInput,
1762
2561
  {
1763
2562
  ...props,
@@ -1769,8 +2568,8 @@ function CurrencyInput({
1769
2568
  }
1770
2569
 
1771
2570
  // packages/form-controls/src/controls/DateTimePicker/date-time-picker.tsx
1772
- var import_react14 = require("react");
1773
- var import_jsx_runtime18 = require("react/jsx-runtime");
2571
+ var import_react20 = require("react");
2572
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1774
2573
  var pad = (value) => String(value).padStart(2, "0");
1775
2574
  function formatDate(date, format) {
1776
2575
  return format.replace(/yyyy/g, String(date.getFullYear())).replace(/MM/g, pad(date.getMonth() + 1)).replace(/dd/g, pad(date.getDate())).replace(/HH/g, pad(date.getHours())).replace(/mm/g, pad(date.getMinutes()));
@@ -1806,7 +2605,7 @@ function DateTimePicker(props) {
1806
2605
  "aria-describedby": ariaDescribedBy,
1807
2606
  "aria-labelledby": ariaLabelledBy
1808
2607
  } = props;
1809
- const generatedId = (0, import_react14.useId)();
2608
+ const generatedId = (0, import_react20.useId)();
1810
2609
  const triggerId = id ?? generatedId + "-trigger";
1811
2610
  const labelId = generatedId + "-label";
1812
2611
  const messageId2 = generatedId + "-message";
@@ -1824,28 +2623,28 @@ function DateTimePicker(props) {
1824
2623
  );
1825
2624
  const isRange = mode === "range";
1826
2625
  const controlled = props.value !== void 0;
1827
- const [singleInternal, setSingleInternal] = (0, import_react14.useState)(
2626
+ const [singleInternal, setSingleInternal] = (0, import_react20.useState)(
1828
2627
  (!isRange ? props.defaultValue : null) ?? null
1829
2628
  );
1830
- const [rangeInternal, setRangeInternal] = (0, import_react14.useState)(
2629
+ const [rangeInternal, setRangeInternal] = (0, import_react20.useState)(
1831
2630
  (isRange ? props.defaultValue : void 0) ?? [null, null]
1832
2631
  );
1833
2632
  const singleValue = !isRange ? props.value ?? singleInternal : null;
1834
2633
  const rangeValue = isRange ? props.value ?? rangeInternal : [null, null];
1835
- const [open, setOpen] = (0, import_react14.useState)(false);
1836
- const [month, setMonth] = (0, import_react14.useState)(
2634
+ const [open, setOpen] = (0, import_react20.useState)(false);
2635
+ const [month, setMonth] = (0, import_react20.useState)(
1837
2636
  () => new Date((isRange ? rangeValue[0] : singleValue) ?? /* @__PURE__ */ new Date())
1838
2637
  );
1839
- const [editingEnd, setEditingEnd] = (0, import_react14.useState)(false);
1840
- const rootRef = (0, import_react14.useRef)(null);
1841
- (0, import_react14.useEffect)(() => {
2638
+ const [editingEnd, setEditingEnd] = (0, import_react20.useState)(false);
2639
+ const rootRef = (0, import_react20.useRef)(null);
2640
+ (0, import_react20.useEffect)(() => {
1842
2641
  const onPointerDown = (event) => {
1843
2642
  if (!rootRef.current?.contains(event.target)) setOpen(false);
1844
2643
  };
1845
2644
  document.addEventListener("mousedown", onPointerDown);
1846
2645
  return () => document.removeEventListener("mousedown", onPointerDown);
1847
2646
  }, []);
1848
- (0, import_react14.useEffect)(() => {
2647
+ (0, import_react20.useEffect)(() => {
1849
2648
  if (disabled) setOpen(false);
1850
2649
  }, [disabled]);
1851
2650
  const setSingle = (next) => {
@@ -1901,7 +2700,7 @@ function DateTimePicker(props) {
1901
2700
  setRange(editingEnd ? [rangeValue[0], next] : [next, rangeValue[1]]);
1902
2701
  else setSingle(next);
1903
2702
  };
1904
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
2703
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
1905
2704
  "div",
1906
2705
  {
1907
2706
  ref: rootRef,
@@ -1911,7 +2710,7 @@ function DateTimePicker(props) {
1911
2710
  className
1912
2711
  ].filter(Boolean).join(" "),
1913
2712
  children: [
1914
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2713
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1915
2714
  FieldLabel,
1916
2715
  {
1917
2716
  id: labelId,
@@ -1921,7 +2720,7 @@ function DateTimePicker(props) {
1921
2720
  isRequired
1922
2721
  }
1923
2722
  ),
1924
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
2723
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
1925
2724
  "button",
1926
2725
  {
1927
2726
  id: triggerId,
@@ -1935,29 +2734,29 @@ function DateTimePicker(props) {
1935
2734
  "aria-expanded": open,
1936
2735
  onClick: () => setOpen((current) => !current),
1937
2736
  children: [
1938
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { "aria-hidden": "true", children: "\u25F7" }),
1939
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
2737
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { "aria-hidden": "true", children: "\u25F7" }),
2738
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
1940
2739
  "span",
1941
2740
  {
1942
2741
  className: !shownValue && placeholder ? "fe-datetime-picker__value is-placeholder" : "fe-datetime-picker__value",
1943
2742
  children: [
1944
2743
  shownValue || placeholder || (isRange ? "Select date range" : "Select date and time"),
1945
- isRequired && placeholder && !shownValue && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "fe-field__required", "aria-hidden": "true", children: "*" })
2744
+ isRequired && placeholder && !shownValue && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "fe-field__required", "aria-hidden": "true", children: "*" })
1946
2745
  ]
1947
2746
  }
1948
2747
  )
1949
2748
  ]
1950
2749
  }
1951
2750
  ),
1952
- open && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
2751
+ open && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
1953
2752
  "div",
1954
2753
  {
1955
2754
  className: "fe-datetime-picker__popper",
1956
2755
  role: "dialog",
1957
2756
  "aria-label": "Date and time picker",
1958
2757
  children: [
1959
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "fe-datetime-picker__month", children: [
1960
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2758
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "fe-datetime-picker__month", children: [
2759
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1961
2760
  "button",
1962
2761
  {
1963
2762
  type: "button",
@@ -1968,11 +2767,11 @@ function DateTimePicker(props) {
1968
2767
  children: "\u2039"
1969
2768
  }
1970
2769
  ),
1971
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("strong", { children: month.toLocaleDateString(locale, {
2770
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("strong", { children: month.toLocaleDateString(locale, {
1972
2771
  month: "long",
1973
2772
  year: "numeric"
1974
2773
  }) }),
1975
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2774
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1976
2775
  "button",
1977
2776
  {
1978
2777
  type: "button",
@@ -1984,12 +2783,12 @@ function DateTimePicker(props) {
1984
2783
  }
1985
2784
  )
1986
2785
  ] }),
1987
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "fe-datetime-picker__weekdays", children: ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"].map((day) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: day }, day)) }),
1988
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "fe-datetime-picker__days", children: days.map((day) => {
2786
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "fe-datetime-picker__weekdays", children: ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"].map((day) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: day }, day)) }),
2787
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "fe-datetime-picker__days", children: days.map((day) => {
1989
2788
  const inMonth = day.getMonth() === month.getMonth();
1990
2789
  const selected = isRange ? sameDay(day, rangeValue[0]) || sameDay(day, rangeValue[1]) : sameDay(day, singleValue);
1991
2790
  const inRange = isRange && rangeValue[0] && rangeValue[1] && day > startOfDay(rangeValue[0]) && day < startOfDay(rangeValue[1]);
1992
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2791
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1993
2792
  "button",
1994
2793
  {
1995
2794
  type: "button",
@@ -2004,8 +2803,8 @@ function DateTimePicker(props) {
2004
2803
  day.toISOString()
2005
2804
  );
2006
2805
  }) }),
2007
- isRange && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "fe-datetime-picker__range-tabs", children: [
2008
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2806
+ isRange && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "fe-datetime-picker__range-tabs", children: [
2807
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2009
2808
  "button",
2010
2809
  {
2011
2810
  type: "button",
@@ -2014,7 +2813,7 @@ function DateTimePicker(props) {
2014
2813
  children: "Start"
2015
2814
  }
2016
2815
  ),
2017
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2816
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2018
2817
  "button",
2019
2818
  {
2020
2819
  type: "button",
@@ -2024,9 +2823,9 @@ function DateTimePicker(props) {
2024
2823
  }
2025
2824
  )
2026
2825
  ] }),
2027
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("label", { className: "fe-datetime-picker__time", children: [
2826
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("label", { className: "fe-datetime-picker__time", children: [
2028
2827
  "Time",
2029
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2828
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2030
2829
  "input",
2031
2830
  {
2032
2831
  type: "time",
@@ -2039,7 +2838,7 @@ function DateTimePicker(props) {
2039
2838
  ]
2040
2839
  }
2041
2840
  ),
2042
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2841
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2043
2842
  FieldMessage,
2044
2843
  {
2045
2844
  id: messageId2,
@@ -2054,9 +2853,9 @@ function DateTimePicker(props) {
2054
2853
  }
2055
2854
 
2056
2855
  // packages/form-controls/src/controls/Checkbox/checkbox.tsx
2057
- var import_react15 = require("react");
2058
- var import_jsx_runtime19 = require("react/jsx-runtime");
2059
- var Checkbox = (0, import_react15.forwardRef)(
2856
+ var import_react21 = require("react");
2857
+ var import_jsx_runtime23 = require("react/jsx-runtime");
2858
+ var Checkbox = (0, import_react21.forwardRef)(
2060
2859
  function Checkbox2({
2061
2860
  label,
2062
2861
  labelPosition = "right",
@@ -2072,10 +2871,10 @@ var Checkbox = (0, import_react15.forwardRef)(
2072
2871
  disabled && "fe-checkbox--disabled",
2073
2872
  className
2074
2873
  ].filter(Boolean).join(" ");
2075
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("label", { className: classes, style, children: [
2076
- label && labelPosition === "top" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "fe-checkbox__label", children: label }),
2077
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { className: "fe-checkbox__content", children: [
2078
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2874
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { className: classes, style, children: [
2875
+ label && labelPosition === "top" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "fe-checkbox__label", children: label }),
2876
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: "fe-checkbox__content", children: [
2877
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2079
2878
  "input",
2080
2879
  {
2081
2880
  ref,
@@ -2086,8 +2885,8 @@ var Checkbox = (0, import_react15.forwardRef)(
2086
2885
  ...props
2087
2886
  }
2088
2887
  ),
2089
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "fe-checkbox__control", "aria-hidden": "true" }),
2090
- label && labelPosition === "right" && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "fe-checkbox__label", children: label })
2888
+ /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "fe-checkbox__control", "aria-hidden": "true" }),
2889
+ label && labelPosition === "right" && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "fe-checkbox__label", children: label })
2091
2890
  ] })
2092
2891
  ] });
2093
2892
  }
@@ -2095,9 +2894,9 @@ var Checkbox = (0, import_react15.forwardRef)(
2095
2894
  Checkbox.displayName = "Checkbox";
2096
2895
 
2097
2896
  // packages/form-controls/src/controls/RadioButton/radio-button.tsx
2098
- var import_react16 = require("react");
2099
- var import_jsx_runtime20 = require("react/jsx-runtime");
2100
- var RadioButton = (0, import_react16.forwardRef)(
2897
+ var import_react22 = require("react");
2898
+ var import_jsx_runtime24 = require("react/jsx-runtime");
2899
+ var RadioButton = (0, import_react22.forwardRef)(
2101
2900
  function RadioButton2({
2102
2901
  label,
2103
2902
  labelPosition = "right",
@@ -2113,10 +2912,10 @@ var RadioButton = (0, import_react16.forwardRef)(
2113
2912
  disabled && "fe-radio-button--disabled",
2114
2913
  className
2115
2914
  ].filter(Boolean).join(" ");
2116
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("label", { className: classes, style, children: [
2117
- label && labelPosition === "top" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "fe-radio-button__label", children: label }),
2118
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "fe-radio-button__content", children: [
2119
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2915
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("label", { className: classes, style, children: [
2916
+ label && labelPosition === "top" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "fe-radio-button__label", children: label }),
2917
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { className: "fe-radio-button__content", children: [
2918
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
2120
2919
  "input",
2121
2920
  {
2122
2921
  ref,
@@ -2127,8 +2926,8 @@ var RadioButton = (0, import_react16.forwardRef)(
2127
2926
  ...props
2128
2927
  }
2129
2928
  ),
2130
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "fe-radio-button__control", "aria-hidden": "true" }),
2131
- label && labelPosition === "right" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "fe-radio-button__label", children: label })
2929
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "fe-radio-button__control", "aria-hidden": "true" }),
2930
+ label && labelPosition === "right" && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "fe-radio-button__label", children: label })
2132
2931
  ] })
2133
2932
  ] });
2134
2933
  }
@@ -2136,9 +2935,9 @@ var RadioButton = (0, import_react16.forwardRef)(
2136
2935
  RadioButton.displayName = "RadioButton";
2137
2936
 
2138
2937
  // packages/form-controls/src/controls/RadioGroup/radio-group.tsx
2139
- var import_react17 = require("react");
2140
- var import_jsx_runtime21 = require("react/jsx-runtime");
2141
- var RadioGroup = (0, import_react17.forwardRef)(
2938
+ var import_react23 = require("react");
2939
+ var import_jsx_runtime25 = require("react/jsx-runtime");
2940
+ var RadioGroup = (0, import_react23.forwardRef)(
2142
2941
  function RadioGroup2({
2143
2942
  label,
2144
2943
  labelPosition = "top",
@@ -2156,7 +2955,7 @@ var RadioGroup = (0, import_react17.forwardRef)(
2156
2955
  "aria-labelledby": ariaLabelledBy,
2157
2956
  ...props
2158
2957
  }, ref) {
2159
- const generatedId = (0, import_react17.useId)();
2958
+ const generatedId = (0, import_react23.useId)();
2160
2959
  const groupName = name ?? `fe-radio-group-${generatedId}`;
2161
2960
  const labelId = `${id ?? generatedId}-label`;
2162
2961
  const isControlled = value !== void 0;
@@ -2170,12 +2969,12 @@ var RadioGroup = (0, import_react17.forwardRef)(
2170
2969
  const handleChange = (option, event) => {
2171
2970
  if (event.target.checked) onChange?.(option.value, option, event);
2172
2971
  };
2173
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { ref, className: classes, ...props, children: [
2174
- label && labelPosition === "top" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { id: labelId, className: "fe-radio-group__label", children: [
2972
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { ref, className: classes, ...props, children: [
2973
+ label && labelPosition === "top" && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { id: labelId, className: "fe-radio-group__label", children: [
2175
2974
  label,
2176
- isRequired && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "fe-radio-group__required", "aria-hidden": "true", children: "*" })
2975
+ isRequired && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "fe-radio-group__required", "aria-hidden": "true", children: "*" })
2177
2976
  ] }),
2178
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2977
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2179
2978
  "div",
2180
2979
  {
2181
2980
  id,
@@ -2187,7 +2986,7 @@ var RadioGroup = (0, import_react17.forwardRef)(
2187
2986
  children: options.map((option) => {
2188
2987
  const optionDisabled = disabled || option.disabled;
2189
2988
  const optionValue = String(option.value);
2190
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2989
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2191
2990
  RadioButton,
2192
2991
  {
2193
2992
  name: groupName,
@@ -2204,9 +3003,9 @@ var RadioGroup = (0, import_react17.forwardRef)(
2204
3003
  })
2205
3004
  }
2206
3005
  ),
2207
- label && labelPosition === "right" && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { id: labelId, className: "fe-radio-group__label", children: [
3006
+ label && labelPosition === "right" && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("span", { id: labelId, className: "fe-radio-group__label", children: [
2208
3007
  label,
2209
- isRequired && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "fe-radio-group__required", "aria-hidden": "true", children: "*" })
3008
+ isRequired && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "fe-radio-group__required", "aria-hidden": "true", children: "*" })
2210
3009
  ] })
2211
3010
  ] });
2212
3011
  }
@@ -2214,29 +3013,29 @@ var RadioGroup = (0, import_react17.forwardRef)(
2214
3013
  RadioGroup.displayName = "RadioGroup";
2215
3014
 
2216
3015
  // packages/expandable-section/src/index.tsx
2217
- var import_react18 = require("react");
2218
- var import_jsx_runtime22 = require("react/jsx-runtime");
3016
+ var import_react24 = require("react");
3017
+ var import_jsx_runtime26 = require("react/jsx-runtime");
2219
3018
  function ExpandableSection({ title, children, expanded, defaultExpanded = false, onExpandedChange, disabled, className, ...props }) {
2220
- const [internalExpanded, setInternalExpanded] = (0, import_react18.useState)(defaultExpanded);
3019
+ const [internalExpanded, setInternalExpanded] = (0, import_react24.useState)(defaultExpanded);
2221
3020
  const isExpanded = expanded ?? internalExpanded;
2222
- const id = (0, import_react18.useId)();
3021
+ const id = (0, import_react24.useId)();
2223
3022
  const toggle = () => {
2224
3023
  if (disabled) return;
2225
3024
  const next = !isExpanded;
2226
3025
  if (expanded === void 0) setInternalExpanded(next);
2227
3026
  onExpandedChange?.(next);
2228
3027
  };
2229
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("section", { className: ["fe-expandable-section", isExpanded && "fe-expandable-section--expanded", disabled && "fe-expandable-section--disabled", className].filter(Boolean).join(" "), ...props, children: [
2230
- /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("button", { className: "fe-expandable-section__trigger", type: "button", "aria-expanded": isExpanded, "aria-controls": id, disabled, onClick: toggle, children: [
2231
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { children: title }),
2232
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { className: "fe-expandable-section__chevron", "aria-hidden": "true" })
3028
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("section", { className: ["fe-expandable-section", isExpanded && "fe-expandable-section--expanded", disabled && "fe-expandable-section--disabled", className].filter(Boolean).join(" "), ...props, children: [
3029
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("button", { className: "fe-expandable-section__trigger", type: "button", "aria-expanded": isExpanded, "aria-controls": id, disabled, onClick: toggle, children: [
3030
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { children: title }),
3031
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "fe-expandable-section__chevron", "aria-hidden": "true" })
2233
3032
  ] }),
2234
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { id, className: "fe-expandable-section__content", "aria-hidden": !isExpanded, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "fe-expandable-section__content-inner", children }) })
3033
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { id, className: "fe-expandable-section__content", "aria-hidden": !isExpanded, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "fe-expandable-section__content-inner", children }) })
2235
3034
  ] });
2236
3035
  }
2237
3036
 
2238
3037
  // packages/loading/src/index.tsx
2239
- var import_jsx_runtime23 = require("react/jsx-runtime");
3038
+ var import_jsx_runtime27 = require("react/jsx-runtime");
2240
3039
  var sizes = {
2241
3040
  small: "16px",
2242
3041
  medium: "24px",
@@ -2249,15 +3048,15 @@ function Loading({ size = "medium", color = "#2878f0", label, className, style,
2249
3048
  "--fe-loading-color": color,
2250
3049
  ...style
2251
3050
  };
2252
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("span", { className: ["fe-loading", className].filter(Boolean).join(" "), style: loadingStyle, role: "status", ...props, children: [
2253
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "fe-loading__spinner", "aria-hidden": "true" }),
2254
- label && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "fe-loading__label", children: label }),
2255
- !label && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { className: "fe-loading__sr-only", children: "Loading" })
3051
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: ["fe-loading", className].filter(Boolean).join(" "), style: loadingStyle, role: "status", ...props, children: [
3052
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "fe-loading__spinner", "aria-hidden": "true" }),
3053
+ label && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "fe-loading__label", children: label }),
3054
+ !label && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "fe-loading__sr-only", children: "Loading" })
2256
3055
  ] });
2257
3056
  }
2258
3057
 
2259
3058
  // packages/skeleton/src/index.tsx
2260
- var import_jsx_runtime24 = require("react/jsx-runtime");
3059
+ var import_jsx_runtime28 = require("react/jsx-runtime");
2261
3060
  var pixels = (value) => typeof value === "number" ? `${value}px` : value;
2262
3061
  function SkeletonBase({ variant = "box", shape, width, height, count = 1, animated = true, className, style, ...props }) {
2263
3062
  const resolvedVariant = shape ?? variant;
@@ -2268,7 +3067,7 @@ function SkeletonBase({ variant = "box", shape, width, height, count = 1, animat
2268
3067
  "--fe-skeleton-height": resolvedHeight,
2269
3068
  ...style
2270
3069
  };
2271
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_jsx_runtime24.Fragment, { children: Array.from({ length: Math.max(1, count) }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3070
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_jsx_runtime28.Fragment, { children: Array.from({ length: Math.max(1, count) }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
2272
3071
  "div",
2273
3072
  {
2274
3073
  className: ["fe-skeleton", `fe-skeleton--${resolvedVariant}`, animated && "fe-skeleton--animated", className].filter(Boolean).join(" "),
@@ -2280,16 +3079,16 @@ function SkeletonBase({ variant = "box", shape, width, height, count = 1, animat
2280
3079
  )) });
2281
3080
  }
2282
3081
  function SkeletonCircle({ size = 40, ...props }) {
2283
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SkeletonBase, { variant: "circle", width: size, height: size, ...props });
3082
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SkeletonBase, { variant: "circle", width: size, height: size, ...props });
2284
3083
  }
2285
3084
  function SkeletonSquare({ size = 80, ...props }) {
2286
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SkeletonBase, { variant: "box", width: size, height: size, ...props });
3085
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SkeletonBase, { variant: "box", width: size, height: size, ...props });
2287
3086
  }
2288
3087
  function SkeletonBox({ width = "100%", height = 80, ...props }) {
2289
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SkeletonBase, { variant: "box", width, height, ...props });
3088
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SkeletonBase, { variant: "box", width, height, ...props });
2290
3089
  }
2291
3090
  function SkeletonLine({ width = "100%", height = 12, ...props }) {
2292
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(SkeletonBase, { variant: "line", width, height, ...props });
3091
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SkeletonBase, { variant: "line", width, height, ...props });
2293
3092
  }
2294
3093
  var Skeleton = Object.assign(SkeletonBase, {
2295
3094
  Circle: SkeletonCircle,
@@ -2299,9 +3098,9 @@ var Skeleton = Object.assign(SkeletonBase, {
2299
3098
  });
2300
3099
 
2301
3100
  // packages/modal/src/index.tsx
2302
- var import_react19 = require("react");
3101
+ var import_react25 = require("react");
2303
3102
  var import_react_dom3 = require("react-dom");
2304
- var import_jsx_runtime25 = require("react/jsx-runtime");
3103
+ var import_jsx_runtime29 = require("react/jsx-runtime");
2305
3104
  function Modal({
2306
3105
  open,
2307
3106
  onClose,
@@ -2312,60 +3111,87 @@ function Modal({
2312
3111
  actions = [],
2313
3112
  size = "medium",
2314
3113
  closeOnBackdropClick = true,
3114
+ closeOnEscape = true,
2315
3115
  closeButton = true,
2316
3116
  closeLabel = "Close modal",
3117
+ initialFocusRef,
3118
+ restoreFocus = true,
2317
3119
  className,
3120
+ "aria-label": ariaLabel,
3121
+ "aria-describedby": ariaDescribedBy,
2318
3122
  ...props
2319
3123
  }) {
2320
- const titleId = (0, import_react19.useId)();
2321
- const panelRef = (0, import_react19.useRef)(null);
2322
- (0, import_react19.useEffect)(() => {
2323
- if (!open) return;
2324
- const onKeyDown = (event) => {
2325
- if (event.key === "Escape") onClose();
2326
- };
2327
- document.addEventListener("keydown", onKeyDown);
2328
- panelRef.current?.focus();
2329
- return () => document.removeEventListener("keydown", onKeyDown);
2330
- }, [onClose, open]);
3124
+ const titleId = (0, import_react25.useId)();
3125
+ const descriptionId = (0, import_react25.useId)();
3126
+ const panelRef = (0, import_react25.useRef)(null);
3127
+ useModalOverlay({
3128
+ open,
3129
+ onClose,
3130
+ panelRef,
3131
+ priority: 1100,
3132
+ closeOnEscape,
3133
+ initialFocusRef,
3134
+ restoreFocus
3135
+ });
2331
3136
  if (!open || typeof document === "undefined") return null;
2332
3137
  const hasFooter = footer || actions.length > 0;
3138
+ const describedBy = [description ? descriptionId : void 0, ariaDescribedBy].filter(Boolean).join(" ") || void 0;
2333
3139
  return (0, import_react_dom3.createPortal)(
2334
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "fe-modal-backdrop", role: "presentation", onMouseDown: (event) => {
2335
- if (event.target === event.currentTarget && closeOnBackdropClick) onClose();
2336
- }, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
3140
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
2337
3141
  "div",
2338
3142
  {
2339
- ref: panelRef,
2340
- className: ["fe-modal", `fe-modal--${size}`, className].filter(Boolean).join(" "),
2341
- role: "dialog",
2342
- "aria-modal": "true",
2343
- "aria-labelledby": title ? titleId : void 0,
2344
- "aria-label": title ? void 0 : "Modal",
2345
- tabIndex: -1,
2346
- ...props,
2347
- children: [
2348
- (title || description || closeButton) && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("header", { className: "fe-modal__header", children: [
2349
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "fe-modal__heading", children: [
2350
- title && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("h2", { id: titleId, children: title }),
2351
- description && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("p", { children: description })
2352
- ] }),
2353
- closeButton && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Button, { hierarchy: "tertiary-gray", size: "32", iconOnly: true, icon: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(CloseIcon, {}), "aria-label": closeLabel, onClick: onClose })
2354
- ] }),
2355
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "fe-modal__body", children }),
2356
- hasFooter && /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("footer", { className: "fe-modal__footer", children: [
2357
- footer && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "fe-modal__footer-content", children: footer }),
2358
- actions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "fe-modal__actions", children: actions.map(({ label, ...action }, index) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Button, { ...action, children: label }, index)) })
2359
- ] })
2360
- ]
3143
+ className: "fe-modal-backdrop",
3144
+ role: "presentation",
3145
+ onMouseDown: (event) => {
3146
+ if (event.target === event.currentTarget && closeOnBackdropClick)
3147
+ onClose();
3148
+ },
3149
+ children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
3150
+ "div",
3151
+ {
3152
+ ref: panelRef,
3153
+ className: ["fe-modal", `fe-modal--${size}`, className].filter(Boolean).join(" "),
3154
+ role: "dialog",
3155
+ "aria-modal": "true",
3156
+ "aria-labelledby": title ? titleId : void 0,
3157
+ "aria-describedby": describedBy,
3158
+ "aria-label": ariaLabel ?? (title ? void 0 : "Modal"),
3159
+ tabIndex: -1,
3160
+ ...props,
3161
+ children: [
3162
+ (title || description || closeButton) && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("header", { className: "fe-modal__header", children: [
3163
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "fe-modal__heading", children: [
3164
+ title && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("h2", { id: titleId, children: title }),
3165
+ description && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { id: descriptionId, children: description })
3166
+ ] }),
3167
+ closeButton && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
3168
+ Button,
3169
+ {
3170
+ hierarchy: "tertiary-gray",
3171
+ size: "32",
3172
+ iconOnly: true,
3173
+ icon: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(CloseIcon, {}),
3174
+ "aria-label": closeLabel,
3175
+ onClick: onClose
3176
+ }
3177
+ )
3178
+ ] }),
3179
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "fe-modal__body", children }),
3180
+ hasFooter && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("footer", { className: "fe-modal__footer", children: [
3181
+ footer && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "fe-modal__footer-content", children: footer }),
3182
+ actions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "fe-modal__actions", children: actions.map(({ label, ...action }, index) => /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Button, { ...action, children: label }, index)) })
3183
+ ] })
3184
+ ]
3185
+ }
3186
+ )
2361
3187
  }
2362
- ) }),
3188
+ ),
2363
3189
  document.body
2364
3190
  );
2365
3191
  }
2366
3192
 
2367
3193
  // packages/progress/src/index.tsx
2368
- var import_jsx_runtime26 = require("react/jsx-runtime");
3194
+ var import_jsx_runtime30 = require("react/jsx-runtime");
2369
3195
  function ProgressBar({ value, max = 100, label, showValue = true, size = "medium", color = "#2878f0", className, style, "aria-label": ariaLabel, ...props }) {
2370
3196
  const indeterminate = value === null || value === void 0;
2371
3197
  const percentage = indeterminate ? 0 : Math.min(100, Math.max(0, Number(value) / Math.max(1, max) * 100));
@@ -2375,17 +3201,17 @@ function ProgressBar({ value, max = 100, label, showValue = true, size = "medium
2375
3201
  ...style
2376
3202
  };
2377
3203
  const visibleValue = `${Math.round(percentage)}%`;
2378
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: ["fe-progress", `fe-progress--${size}`, indeterminate && "fe-progress--indeterminate", className].filter(Boolean).join(" "), style: progressStyle, ...props, children: [
2379
- (label || !indeterminate && showValue) && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "fe-progress__meta", children: [
2380
- label && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "fe-progress__label", children: label }),
2381
- !indeterminate && showValue && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("output", { className: "fe-progress__value", children: visibleValue })
3204
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: ["fe-progress", `fe-progress--${size}`, indeterminate && "fe-progress--indeterminate", className].filter(Boolean).join(" "), style: progressStyle, ...props, children: [
3205
+ (label || !indeterminate && showValue) && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "fe-progress__meta", children: [
3206
+ label && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "fe-progress__label", children: label }),
3207
+ !indeterminate && showValue && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("output", { className: "fe-progress__value", children: visibleValue })
2382
3208
  ] }),
2383
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "fe-progress__track", role: "progressbar", "aria-label": ariaLabel ?? (typeof label === "string" ? label : "Progress"), "aria-valuemin": indeterminate ? void 0 : 0, "aria-valuemax": indeterminate ? void 0 : max, "aria-valuenow": indeterminate ? void 0 : Number(value), "aria-valuetext": indeterminate ? "Loading" : visibleValue, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "fe-progress__indicator" }) })
3209
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "fe-progress__track", role: "progressbar", "aria-label": ariaLabel ?? (typeof label === "string" ? label : "Progress"), "aria-valuemin": indeterminate ? void 0 : 0, "aria-valuemax": indeterminate ? void 0 : max, "aria-valuenow": indeterminate ? void 0 : Number(value), "aria-valuetext": indeterminate ? "Loading" : visibleValue, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "fe-progress__indicator" }) })
2384
3210
  ] });
2385
3211
  }
2386
3212
 
2387
3213
  // packages/chip/src/index.tsx
2388
- var import_jsx_runtime27 = require("react/jsx-runtime");
3214
+ var import_jsx_runtime31 = require("react/jsx-runtime");
2389
3215
  var statuses = ["default", "info", "success", "warning", "error", "neutral", "pending", "processing"];
2390
3216
  function Chip({ children, status = "default", color, variant = "subtle", dot = false, onRemove, removeLabel = "Remove", className, style, ...props }) {
2391
3217
  const usesCustomColor = Boolean(color);
@@ -2394,16 +3220,16 @@ function Chip({ children, status = "default", color, variant = "subtle", dot = f
2394
3220
  ...style
2395
3221
  };
2396
3222
  const resolvedStatus = statuses.includes(status) ? status : "default";
2397
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("span", { className: ["fe-chip", `fe-chip--${variant}`, `fe-chip--${usesCustomColor ? "custom" : resolvedStatus}`, className].filter(Boolean).join(" "), style: chipStyle, ...props, children: [
2398
- dot && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "fe-chip__dot", "aria-hidden": "true" }),
2399
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "fe-chip__content", children }),
2400
- onRemove && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(Button, { hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(CloseIcon, { size: 14 }), "aria-label": removeLabel, onClick: onRemove, className: "fe-chip__remove" })
3223
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: ["fe-chip", `fe-chip--${variant}`, `fe-chip--${usesCustomColor ? "custom" : resolvedStatus}`, className].filter(Boolean).join(" "), style: chipStyle, ...props, children: [
3224
+ dot && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "fe-chip__dot", "aria-hidden": "true" }),
3225
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "fe-chip__content", children }),
3226
+ onRemove && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Button, { hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(CloseIcon, { size: 14 }), "aria-label": removeLabel, onClick: onRemove, className: "fe-chip__remove" })
2401
3227
  ] });
2402
3228
  }
2403
3229
 
2404
3230
  // packages/message/src/index.tsx
2405
- var import_react20 = require("react");
2406
- var import_jsx_runtime28 = require("react/jsx-runtime");
3231
+ var import_react26 = require("react");
3232
+ var import_jsx_runtime32 = require("react/jsx-runtime");
2407
3233
  var messageId = 0;
2408
3234
  var entries = [];
2409
3235
  var listeners = /* @__PURE__ */ new Set();
@@ -2436,22 +3262,22 @@ var message = {
2436
3262
  };
2437
3263
  var icons = { success: "\u2713", info: "i", warning: "!", error: "\xD7" };
2438
3264
  function Message({ maxCount = 4, closeLabel = "Close notification", className, ...props }) {
2439
- const [visibleEntries, setVisibleEntries] = (0, import_react20.useState)(entries);
2440
- (0, import_react20.useEffect)(() => {
3265
+ const [visibleEntries, setVisibleEntries] = (0, import_react26.useState)(entries);
3266
+ (0, import_react26.useEffect)(() => {
2441
3267
  const listener = (nextEntries) => setVisibleEntries(nextEntries);
2442
3268
  listeners.add(listener);
2443
3269
  return () => {
2444
3270
  listeners.delete(listener);
2445
3271
  };
2446
3272
  }, []);
2447
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: ["fe-message-viewport", className].filter(Boolean).join(" "), "aria-live": "polite", ...props, children: visibleEntries.slice(-Math.max(1, maxCount)).map((entry) => /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: `fe-message fe-message--${entry.severity ?? "info"}`, role: entry.severity === "error" ? "alert" : "status", children: [
2448
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "fe-message__icon", "aria-hidden": "true", children: icons[entry.severity ?? "info"] }),
2449
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "fe-message__body", children: [
2450
- entry.title && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("strong", { className: "fe-message__title", children: entry.title }),
2451
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "fe-message__content", children: entry.content })
3273
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: ["fe-message-viewport", className].filter(Boolean).join(" "), "aria-live": "polite", ...props, children: visibleEntries.slice(-Math.max(1, maxCount)).map((entry) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: `fe-message fe-message--${entry.severity ?? "info"}`, role: entry.severity === "error" ? "alert" : "status", children: [
3274
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "fe-message__icon", "aria-hidden": "true", children: icons[entry.severity ?? "info"] }),
3275
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { className: "fe-message__body", children: [
3276
+ entry.title && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("strong", { className: "fe-message__title", children: entry.title }),
3277
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { className: "fe-message__content", children: entry.content })
2452
3278
  ] }),
2453
- entry.action && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "fe-message__action", children: entry.action }),
2454
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Button, { className: "fe-message__close", hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: "\xD7", "aria-label": closeLabel, onClick: () => dismiss(entry.id) })
3279
+ entry.action && /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "fe-message__action", children: entry.action }),
3280
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Button, { className: "fe-message__close", hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: "\xD7", "aria-label": closeLabel, onClick: () => dismiss(entry.id) })
2455
3281
  ] }, entry.id)) });
2456
3282
  }
2457
3283
  ((Message2) => {
@@ -2465,8 +3291,8 @@ function Message({ maxCount = 4, closeLabel = "Close notification", className, .
2465
3291
  })(Message || (Message = {}));
2466
3292
 
2467
3293
  // packages/snackbar/src/index.tsx
2468
- var import_react21 = require("react");
2469
- var import_jsx_runtime29 = require("react/jsx-runtime");
3294
+ var import_react27 = require("react");
3295
+ var import_jsx_runtime33 = require("react/jsx-runtime");
2470
3296
  function Snackbar({
2471
3297
  open,
2472
3298
  message: message2,
@@ -2480,12 +3306,12 @@ function Snackbar({
2480
3306
  }) {
2481
3307
  const vertical = anchorOrigin.vertical ?? "bottom";
2482
3308
  const horizontal = anchorOrigin.horizontal ?? "center";
2483
- (0, import_react21.useEffect)(() => {
3309
+ (0, import_react27.useEffect)(() => {
2484
3310
  if (!open || autoHideDuration === null) return void 0;
2485
3311
  const timer = window.setTimeout(() => onClose?.("timeout"), autoHideDuration);
2486
3312
  return () => window.clearTimeout(timer);
2487
3313
  }, [open, autoHideDuration, onClose]);
2488
- (0, import_react21.useEffect)(() => {
3314
+ (0, import_react27.useEffect)(() => {
2489
3315
  if (!open) return void 0;
2490
3316
  const onKeyDown = (event) => {
2491
3317
  if (event.key === "Escape") onClose?.("escapeKeyDown");
@@ -2494,16 +3320,16 @@ function Snackbar({
2494
3320
  return () => window.removeEventListener("keydown", onKeyDown);
2495
3321
  }, [open, onClose]);
2496
3322
  if (!open) return null;
2497
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: ["fe-snackbar", `fe-snackbar--${vertical}`, `fe-snackbar--${horizontal}`, className].filter(Boolean).join(" "), ...props, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "fe-snackbar__content", role: "status", "aria-live": "polite", children: [
2498
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "fe-snackbar__message", children: message2 }),
2499
- action && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "fe-snackbar__action", children: action }),
2500
- onClose && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Button, { className: "fe-snackbar__close", hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: "\xD7", "aria-label": closeLabel, onClick: () => onClose("closeButton") })
3323
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: ["fe-snackbar", `fe-snackbar--${vertical}`, `fe-snackbar--${horizontal}`, className].filter(Boolean).join(" "), ...props, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "fe-snackbar__content", role: "status", "aria-live": "polite", children: [
3324
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "fe-snackbar__message", children: message2 }),
3325
+ action && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "fe-snackbar__action", children: action }),
3326
+ onClose && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Button, { className: "fe-snackbar__close", hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: "\xD7", "aria-label": closeLabel, onClick: () => onClose("closeButton") })
2501
3327
  ] }) });
2502
3328
  }
2503
3329
 
2504
3330
  // packages/avatar/src/index.tsx
2505
- var import_react22 = require("react");
2506
- var import_jsx_runtime30 = require("react/jsx-runtime");
3331
+ var import_react28 = require("react");
3332
+ var import_jsx_runtime34 = require("react/jsx-runtime");
2507
3333
  var FALLBACK_AVATARS = [
2508
3334
  {
2509
3335
  background: "#E0E7FF",
@@ -2836,7 +3662,7 @@ function AvatarFallbackIcon({ avatar }) {
2836
3662
  shirt,
2837
3663
  skin
2838
3664
  } = avatar;
2839
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
3665
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
2840
3666
  "svg",
2841
3667
  {
2842
3668
  className: "fe-avatar__fallback-icon",
@@ -2844,15 +3670,15 @@ function AvatarFallbackIcon({ avatar }) {
2844
3670
  focusable: "false",
2845
3671
  "aria-hidden": "true",
2846
3672
  children: [
2847
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("rect", { width: "24", height: "24", fill: background }),
2848
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
3673
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("rect", { width: "24", height: "24", fill: background }),
3674
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2849
3675
  "path",
2850
3676
  {
2851
3677
  d: "M3 24c.52-3.79 3.58-6.25 9-6.25S20.48 20.21 21 24",
2852
3678
  fill: shirt
2853
3679
  }
2854
3680
  ),
2855
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
3681
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2856
3682
  "path",
2857
3683
  {
2858
3684
  d: "M8.1 17.65h7.8l1.05 2.05H7.05l1.05-2.05Z",
@@ -2860,38 +3686,38 @@ function AvatarFallbackIcon({ avatar }) {
2860
3686
  opacity: ".72"
2861
3687
  }
2862
3688
  ),
2863
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("circle", { cx: "12", cy: "10.25", r: "5.25", fill: skin }),
2864
- hairStyle === 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
3689
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("circle", { cx: "12", cy: "10.25", r: "5.25", fill: skin }),
3690
+ hairStyle === 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2865
3691
  "path",
2866
3692
  {
2867
3693
  d: "M6.75 10.25C6.75 6.34 9.02 4 12.15 4c3.22 0 5.1 2.33 5.1 5.54-1.6-1.41-3.46-2.1-5.59-2.1-1.63 0-3.27.56-4.91 1.68Z",
2868
3694
  fill: hair
2869
3695
  }
2870
3696
  ),
2871
- hairStyle === 1 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
3697
+ hairStyle === 1 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2872
3698
  "path",
2873
3699
  {
2874
3700
  d: "M6.6 10.1c.16-3.93 2.57-6.2 5.62-6.2 3.57 0 5.3 2.75 5.08 6.32-1.42-1.23-2.91-1.82-4.48-1.82-2.4 0-3.9.65-6.22 1.7Z",
2875
3701
  fill: hair
2876
3702
  }
2877
3703
  ),
2878
- hairStyle === 2 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
3704
+ hairStyle === 2 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2879
3705
  "path",
2880
3706
  {
2881
3707
  d: "M6.8 10.55C6.8 6.28 9.43 4 12.2 4c3.46 0 5.13 2.83 4.93 6.38-1.38-1.58-3.03-2.38-4.92-2.38-1.81 0-3.61.85-5.41 2.55Z",
2882
3708
  fill: hair
2883
3709
  }
2884
3710
  ),
2885
- hairStyle === 3 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
3711
+ hairStyle === 3 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2886
3712
  "path",
2887
3713
  {
2888
3714
  d: "M6.66 10.1C6.94 6.12 9.18 4 12.1 4c3.77 0 5.2 2.95 5.18 6.21-1.5-1.07-3.1-1.6-4.8-1.6-2.18 0-3.98.5-5.82 1.49Z",
2889
3715
  fill: hair
2890
3716
  }
2891
3717
  ),
2892
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("circle", { cx: "10.05", cy: "10.65", r: ".48", fill: "#3B2924" }),
2893
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("circle", { cx: "13.95", cy: "10.65", r: ".48", fill: "#3B2924" }),
2894
- expression === 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
3718
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("circle", { cx: "10.05", cy: "10.65", r: ".48", fill: "#3B2924" }),
3719
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("circle", { cx: "13.95", cy: "10.65", r: ".48", fill: "#3B2924" }),
3720
+ expression === 0 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2895
3721
  "path",
2896
3722
  {
2897
3723
  d: "M10.25 13.2c1.08.66 2.42.66 3.5 0",
@@ -2901,7 +3727,7 @@ function AvatarFallbackIcon({ avatar }) {
2901
3727
  strokeLinecap: "round"
2902
3728
  }
2903
3729
  ),
2904
- expression === 1 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
3730
+ expression === 1 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2905
3731
  "path",
2906
3732
  {
2907
3733
  d: "M10.5 13.2h3",
@@ -2911,7 +3737,7 @@ function AvatarFallbackIcon({ avatar }) {
2911
3737
  strokeLinecap: "round"
2912
3738
  }
2913
3739
  ),
2914
- expression === 2 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
3740
+ expression === 2 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2915
3741
  "path",
2916
3742
  {
2917
3743
  d: "M10.6 13.38c.84-.44 1.96-.44 2.8 0",
@@ -2921,11 +3747,11 @@ function AvatarFallbackIcon({ avatar }) {
2921
3747
  strokeLinecap: "round"
2922
3748
  }
2923
3749
  ),
2924
- expression === 3 && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("circle", { cx: "12", cy: "13.2", r: ".82", fill: "#B95A5A" }),
2925
- glasses && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("g", { fill: "none", stroke: "#3C4355", strokeWidth: ".65", children: [
2926
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("circle", { cx: "10", cy: "10.55", r: "1.45" }),
2927
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("circle", { cx: "14", cy: "10.55", r: "1.45" }),
2928
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("path", { d: "M11.45 10.55h1.1M8.55 10.55H7.5m9 0h-1.05" })
3750
+ expression === 3 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("circle", { cx: "12", cy: "13.2", r: ".82", fill: "#B95A5A" }),
3751
+ glasses && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("g", { fill: "none", stroke: "#3C4355", strokeWidth: ".65", children: [
3752
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("circle", { cx: "10", cy: "10.55", r: "1.45" }),
3753
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("circle", { cx: "14", cy: "10.55", r: "1.45" }),
3754
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("path", { d: "M11.45 10.55h1.1M8.55 10.55H7.5m9 0h-1.05" })
2929
3755
  ] })
2930
3756
  ]
2931
3757
  }
@@ -2944,10 +3770,10 @@ function Avatar({
2944
3770
  "aria-label": ariaLabel,
2945
3771
  ...props
2946
3772
  }) {
2947
- const [generatedFallbackIndex] = (0, import_react22.useState)(
3773
+ const [generatedFallbackIndex] = (0, import_react28.useState)(
2948
3774
  () => Math.floor(Math.random() * FALLBACK_AVATARS.length)
2949
3775
  );
2950
- const [failedImageSrc, setFailedImageSrc] = (0, import_react22.useState)();
3776
+ const [failedImageSrc, setFailedImageSrc] = (0, import_react28.useState)();
2951
3777
  const imageSrc = src?.trim();
2952
3778
  const trimmedContent = content?.trim() ?? "";
2953
3779
  const showImage = Boolean(imageSrc && failedImageSrc !== imageSrc);
@@ -2959,7 +3785,7 @@ function Avatar({
2959
3785
  ...style
2960
3786
  };
2961
3787
  const fallbackLabel = (alt ?? trimmedContent) || "Avatar";
2962
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
3788
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
2963
3789
  "span",
2964
3790
  {
2965
3791
  className: ["fe-avatar", `fe-avatar--${shape}`, className].filter(Boolean).join(" "),
@@ -2968,7 +3794,7 @@ function Avatar({
2968
3794
  "aria-label": showImage ? ariaLabel : ariaLabel ?? fallbackLabel,
2969
3795
  ...props,
2970
3796
  children: [
2971
- showImage && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
3797
+ showImage && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
2972
3798
  "img",
2973
3799
  {
2974
3800
  className: "fe-avatar__image",
@@ -2977,8 +3803,8 @@ function Avatar({
2977
3803
  onError: () => setFailedImageSrc(imageSrc)
2978
3804
  }
2979
3805
  ),
2980
- !showImage && initials && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "fe-avatar__initials", "aria-hidden": "true", children: initials }),
2981
- !showImage && !initials && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(AvatarFallbackIcon, { avatar: selectedFallback })
3806
+ !showImage && initials && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "fe-avatar__initials", "aria-hidden": "true", children: initials }),
3807
+ !showImage && !initials && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(AvatarFallbackIcon, { avatar: selectedFallback })
2982
3808
  ]
2983
3809
  }
2984
3810
  );
@@ -2991,7 +3817,7 @@ function AvatarGroup({
2991
3817
  role,
2992
3818
  ...props
2993
3819
  }) {
2994
- const avatars = import_react22.Children.toArray(children).filter(import_react22.isValidElement);
3820
+ const avatars = import_react28.Children.toArray(children).filter(import_react28.isValidElement);
2995
3821
  const hasMaxCount = typeof maxCount === "number" && Number.isFinite(maxCount) && maxCount > 0;
2996
3822
  const itemLimit = hasMaxCount ? Math.floor(maxCount) : avatars.length;
2997
3823
  const hasOverflow = avatars.length > itemLimit;
@@ -3004,7 +3830,7 @@ function AvatarGroup({
3004
3830
  "--fe-avatar-font-size": resolveFontSize(firstAvatarSize)
3005
3831
  };
3006
3832
  const singleContent = avatars.length === 1 ? avatars[0]?.props.content?.trim() ?? "" : "";
3007
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
3833
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
3008
3834
  "div",
3009
3835
  {
3010
3836
  className: ["fe-avatar-group", className].filter(Boolean).join(" "),
@@ -3012,8 +3838,8 @@ function AvatarGroup({
3012
3838
  role: role ?? "group",
3013
3839
  ...props,
3014
3840
  children: [
3015
- /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "fe-avatar-group__items", children: [
3016
- visibleAvatars.map((avatar, index) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
3841
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "fe-avatar-group__items", children: [
3842
+ visibleAvatars.map((avatar, index) => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
3017
3843
  "span",
3018
3844
  {
3019
3845
  className: "fe-avatar-group__item",
@@ -3022,7 +3848,7 @@ function AvatarGroup({
3022
3848
  },
3023
3849
  avatar.key ?? index
3024
3850
  )),
3025
- hasOverflow && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
3851
+ hasOverflow && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
3026
3852
  "span",
3027
3853
  {
3028
3854
  className: "fe-avatar-group__more",
@@ -3036,11 +3862,633 @@ function AvatarGroup({
3036
3862
  }
3037
3863
  )
3038
3864
  ] }),
3039
- singleContent && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "fe-avatar-group__content", children: singleContent })
3865
+ singleContent && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "fe-avatar-group__content", children: singleContent })
3040
3866
  ]
3041
3867
  }
3042
3868
  );
3043
3869
  }
3870
+
3871
+ // packages/file-upload/src/index.tsx
3872
+ var import_react29 = require("react");
3873
+ var import_jsx_runtime35 = require("react/jsx-runtime");
3874
+ var FILE_UPLOAD_ACCEPTS = {
3875
+ all: [],
3876
+ image: [
3877
+ "image/*",
3878
+ ".avif",
3879
+ ".bmp",
3880
+ ".gif",
3881
+ ".heic",
3882
+ ".heif",
3883
+ ".ico",
3884
+ ".jpeg",
3885
+ ".jpg",
3886
+ ".png",
3887
+ ".svg",
3888
+ ".tif",
3889
+ ".tiff",
3890
+ ".webp"
3891
+ ],
3892
+ pdf: [".pdf"],
3893
+ word: [".doc", ".docm", ".docx", ".dot", ".dotx", ".odt", ".rtf"],
3894
+ spreadsheet: [".csv", ".ods", ".xls", ".xlsb", ".xlsm", ".xlsx"],
3895
+ presentation: [".odp", ".pot", ".potx", ".pps", ".ppsx", ".ppt", ".pptx"],
3896
+ document: [
3897
+ ".pdf",
3898
+ ".doc",
3899
+ ".docm",
3900
+ ".docx",
3901
+ ".dot",
3902
+ ".dotx",
3903
+ ".odt",
3904
+ ".rtf",
3905
+ ".csv",
3906
+ ".xls",
3907
+ ".xlsb",
3908
+ ".xlsx",
3909
+ ".xlsm",
3910
+ ".ods",
3911
+ ".pot",
3912
+ ".potx",
3913
+ ".pps",
3914
+ ".ppsx",
3915
+ ".ppt",
3916
+ ".pptx",
3917
+ ".odp"
3918
+ ],
3919
+ text: [".log", ".md", ".rtf", ".text", ".txt"],
3920
+ csv: [".csv"],
3921
+ json: [".json"],
3922
+ xml: [".xml"],
3923
+ code: [
3924
+ ".c",
3925
+ ".cpp",
3926
+ ".cs",
3927
+ ".css",
3928
+ ".go",
3929
+ ".html",
3930
+ ".java",
3931
+ ".js",
3932
+ ".jsx",
3933
+ ".php",
3934
+ ".py",
3935
+ ".rb",
3936
+ ".rs",
3937
+ ".scss",
3938
+ ".sh",
3939
+ ".sql",
3940
+ ".swift",
3941
+ ".ts",
3942
+ ".tsx",
3943
+ ".vue",
3944
+ ".yml",
3945
+ ".yaml"
3946
+ ],
3947
+ archive: [".7z", ".bz2", ".gz", ".rar", ".tar", ".tgz", ".xz", ".zip"],
3948
+ audio: [
3949
+ "audio/*",
3950
+ ".aac",
3951
+ ".aiff",
3952
+ ".flac",
3953
+ ".m4a",
3954
+ ".mp3",
3955
+ ".ogg",
3956
+ ".opus",
3957
+ ".wav",
3958
+ ".wma"
3959
+ ],
3960
+ video: [
3961
+ "video/*",
3962
+ ".avi",
3963
+ ".mkv",
3964
+ ".mov",
3965
+ ".mp4",
3966
+ ".mpeg",
3967
+ ".mpg",
3968
+ ".webm",
3969
+ ".wmv"
3970
+ ],
3971
+ font: [".ttf", ".otf", ".woff", ".woff2"],
3972
+ email: [".eml", ".msg"]
3973
+ };
3974
+ function fileSignature(file) {
3975
+ return `${file.name}-${file.size}-${file.lastModified}-${file.type}`;
3976
+ }
3977
+ function normalizeAccept(accept) {
3978
+ if (!accept) return [];
3979
+ const groups = typeof accept === "string" ? [accept] : accept;
3980
+ return [...new Set(groups.flatMap((group) => FILE_UPLOAD_ACCEPTS[group]))];
3981
+ }
3982
+ function isAcceptedFile(file, accept) {
3983
+ if (!accept.length) return true;
3984
+ const type = file.type.toLowerCase();
3985
+ const name = file.name.toLowerCase();
3986
+ return accept.some((entry) => {
3987
+ if (entry.startsWith(".")) return name.endsWith(entry);
3988
+ if (entry.endsWith("/*")) return type.startsWith(entry.slice(0, -1));
3989
+ return type === entry;
3990
+ });
3991
+ }
3992
+ function formatFileSize(bytes) {
3993
+ if (!Number.isFinite(bytes) || bytes < 1024) return `${bytes || 0} B`;
3994
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
3995
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
3996
+ }
3997
+ function FileVisual({ file }) {
3998
+ const [previewUrl, setPreviewUrl] = (0, import_react29.useState)();
3999
+ const isImage = file.type.startsWith("image/");
4000
+ (0, import_react29.useEffect)(() => {
4001
+ if (!isImage || typeof URL.createObjectURL !== "function") return;
4002
+ const objectUrl = URL.createObjectURL(file);
4003
+ setPreviewUrl(objectUrl);
4004
+ return () => URL.revokeObjectURL(objectUrl);
4005
+ }, [file, isImage]);
4006
+ if (previewUrl) {
4007
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("img", { className: "fe-file-upload__thumbnail", src: previewUrl, alt: "" });
4008
+ }
4009
+ const extension = file.name.includes(".") ? file.name.slice(
4010
+ file.name.lastIndexOf(".") + 1,
4011
+ file.name.lastIndexOf(".") + 5
4012
+ ) : "file";
4013
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "fe-file-upload__file-type", "aria-hidden": "true", children: extension });
4014
+ }
4015
+ var FileUpload = (0, import_react29.forwardRef)(
4016
+ function FileUpload2({
4017
+ value,
4018
+ defaultValue = [],
4019
+ onChange,
4020
+ onAccept,
4021
+ onReject,
4022
+ onRemove,
4023
+ accept,
4024
+ maxSize = Infinity,
4025
+ maxFiles = Infinity,
4026
+ multiple = true,
4027
+ disabled = false,
4028
+ preventDuplicate = true,
4029
+ label = "Upload files",
4030
+ description,
4031
+ dropLabel = "Drop files here",
4032
+ browseLabel = "Browse files",
4033
+ removeLabel = (file) => `Remove ${file.name}`,
4034
+ showFileList = true,
4035
+ inputProps,
4036
+ className,
4037
+ "aria-label": ariaLabel,
4038
+ ...props
4039
+ }, forwardedRef) {
4040
+ const generatedId = (0, import_react29.useId)();
4041
+ const inputId = `${generatedId}-input`;
4042
+ const descriptionId = `${generatedId}-description`;
4043
+ const inputRef = (0, import_react29.useRef)(null);
4044
+ const dragDepthRef = (0, import_react29.useRef)(0);
4045
+ const [uncontrolledFiles, setUncontrolledFiles] = (0, import_react29.useState)(() => [
4046
+ ...defaultValue
4047
+ ]);
4048
+ const [isDragging, setIsDragging] = (0, import_react29.useState)(false);
4049
+ const [rejections, setRejections] = (0, import_react29.useState)([]);
4050
+ const files = value === void 0 ? uncontrolledFiles : [...value];
4051
+ const acceptList = (0, import_react29.useMemo)(() => normalizeAccept(accept), [accept]);
4052
+ const nativeAccept = acceptList.join(",") || void 0;
4053
+ const allowedFileCount = multiple ? maxFiles : 1;
4054
+ const safeMaxFiles = Number.isFinite(allowedFileCount) ? Math.max(0, Math.floor(allowedFileCount)) : Infinity;
4055
+ const helperText = description ?? [
4056
+ acceptList.length ? `Accepted: ${acceptList.join(", ")}` : void 0,
4057
+ Number.isFinite(maxSize) ? `Up to ${formatFileSize(maxSize)} per file` : void 0
4058
+ ].filter(Boolean).join(" \u2022 ");
4059
+ const assignInputRef = (node) => {
4060
+ inputRef.current = node;
4061
+ if (typeof forwardedRef === "function") forwardedRef(node);
4062
+ else if (forwardedRef) {
4063
+ forwardedRef.current = node;
4064
+ }
4065
+ };
4066
+ const commitFiles = (nextFiles) => {
4067
+ if (value === void 0) setUncontrolledFiles(nextFiles);
4068
+ onChange?.(nextFiles);
4069
+ };
4070
+ const addFiles = (fileList) => {
4071
+ if (disabled) return;
4072
+ const candidates = Array.from(fileList ?? []);
4073
+ const nextRejections = [];
4074
+ const accepted = [];
4075
+ const knownFiles = new Set(files.map(fileSignature));
4076
+ for (const file of candidates) {
4077
+ const signature = fileSignature(file);
4078
+ if (!isAcceptedFile(file, acceptList)) {
4079
+ nextRejections.push({
4080
+ file,
4081
+ code: "accept",
4082
+ message: `${file.name} is not an accepted file type.`
4083
+ });
4084
+ } else if (file.size > maxSize) {
4085
+ nextRejections.push({
4086
+ file,
4087
+ code: "max-size",
4088
+ message: `${file.name} exceeds ${formatFileSize(maxSize)}.`
4089
+ });
4090
+ } else if (preventDuplicate && knownFiles.has(signature)) {
4091
+ nextRejections.push({
4092
+ file,
4093
+ code: "duplicate",
4094
+ message: `${file.name} is already in the list.`
4095
+ });
4096
+ } else if (files.length + accepted.length >= safeMaxFiles) {
4097
+ nextRejections.push({
4098
+ file,
4099
+ code: "max-files",
4100
+ message: `Only ${safeMaxFiles} file${safeMaxFiles === 1 ? "" : "s"} can be selected.`
4101
+ });
4102
+ } else {
4103
+ knownFiles.add(signature);
4104
+ accepted.push(file);
4105
+ }
4106
+ }
4107
+ setRejections(nextRejections);
4108
+ if (nextRejections.length) onReject?.(nextRejections);
4109
+ if (!accepted.length) return;
4110
+ commitFiles([...files, ...accepted]);
4111
+ onAccept?.(accepted);
4112
+ };
4113
+ const openFileDialog = () => {
4114
+ if (!disabled) inputRef.current?.click();
4115
+ };
4116
+ const removeFile = (file, index) => {
4117
+ if (disabled) return;
4118
+ onRemove?.(file, index);
4119
+ commitFiles(files.filter((_, fileIndex) => fileIndex !== index));
4120
+ };
4121
+ const handleDragEnter = (event) => {
4122
+ event.preventDefault();
4123
+ if (disabled) return;
4124
+ dragDepthRef.current += 1;
4125
+ setIsDragging(true);
4126
+ };
4127
+ const handleDragLeave = (event) => {
4128
+ event.preventDefault();
4129
+ dragDepthRef.current -= 1;
4130
+ if (dragDepthRef.current <= 0) {
4131
+ dragDepthRef.current = 0;
4132
+ setIsDragging(false);
4133
+ }
4134
+ };
4135
+ const handleDrop = (event) => {
4136
+ event.preventDefault();
4137
+ dragDepthRef.current = 0;
4138
+ setIsDragging(false);
4139
+ addFiles(event.dataTransfer.files);
4140
+ };
4141
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
4142
+ "div",
4143
+ {
4144
+ ...props,
4145
+ className: ["fe-file-upload", className].filter(Boolean).join(" "),
4146
+ children: [
4147
+ label && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("label", { className: "fe-file-upload__label", htmlFor: inputId, children: label }),
4148
+ helperText && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { id: descriptionId, className: "fe-file-upload__description", children: helperText }),
4149
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
4150
+ "input",
4151
+ {
4152
+ ...inputProps,
4153
+ ref: assignInputRef,
4154
+ id: inputId,
4155
+ type: "file",
4156
+ className: "fe-file-upload__input",
4157
+ accept: nativeAccept,
4158
+ multiple,
4159
+ disabled,
4160
+ "aria-label": ariaLabel,
4161
+ "aria-describedby": helperText ? descriptionId : void 0,
4162
+ onChange: (event) => {
4163
+ addFiles(event.target.files);
4164
+ event.target.value = "";
4165
+ }
4166
+ }
4167
+ ),
4168
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
4169
+ "div",
4170
+ {
4171
+ className: [
4172
+ "fe-file-upload__dropzone",
4173
+ isDragging && "fe-file-upload__dropzone--dragging",
4174
+ disabled && "fe-file-upload__dropzone--disabled"
4175
+ ].filter(Boolean).join(" "),
4176
+ onDragEnter: handleDragEnter,
4177
+ onDragOver: (event) => event.preventDefault(),
4178
+ onDragLeave: handleDragLeave,
4179
+ onDrop: handleDrop,
4180
+ children: [
4181
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "fe-file-upload__drop-icon", "aria-hidden": "true", children: "\u2191" }),
4182
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "fe-file-upload__drop-label", children: dropLabel }),
4183
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "fe-file-upload__drop-hint", children: "or choose from your device" }),
4184
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
4185
+ Button,
4186
+ {
4187
+ hierarchy: "secondary-gray",
4188
+ disabled,
4189
+ onClick: openFileDialog,
4190
+ children: browseLabel
4191
+ }
4192
+ )
4193
+ ]
4194
+ }
4195
+ ),
4196
+ rejections.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "fe-file-upload__errors", role: "alert", children: rejections.map((rejection) => /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("p", { children: rejection.message }, `${fileSignature(rejection.file)}-${rejection.code}`)) }),
4197
+ showFileList && files.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("ul", { className: "fe-file-upload__list", "aria-label": "Selected files", children: files.map((file, index) => /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
4198
+ "li",
4199
+ {
4200
+ className: "fe-file-upload__item",
4201
+ children: [
4202
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "fe-file-upload__visual", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(FileVisual, { file }) }),
4203
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { className: "fe-file-upload__file-details", children: [
4204
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "fe-file-upload__file-name", title: file.name, children: file.name }),
4205
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { className: "fe-file-upload__file-size", children: formatFileSize(file.size) })
4206
+ ] }),
4207
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
4208
+ Button,
4209
+ {
4210
+ hierarchy: "tertiary-color",
4211
+ color: "error",
4212
+ destructive: true,
4213
+ size: "24",
4214
+ iconOnly: true,
4215
+ icon: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(CloseIcon, { size: 14 }),
4216
+ "aria-label": removeLabel(file),
4217
+ disabled,
4218
+ onClick: () => removeFile(file, index)
4219
+ }
4220
+ )
4221
+ ]
4222
+ },
4223
+ `${fileSignature(file)}-${index}`
4224
+ )) })
4225
+ ]
4226
+ }
4227
+ );
4228
+ }
4229
+ );
4230
+ FileUpload.displayName = "FileUpload";
4231
+
4232
+ // packages/file-preview/src/index.tsx
4233
+ var import_react30 = require("react");
4234
+ var import_react_dom4 = require("react-dom");
4235
+ var import_jsx_runtime36 = require("react/jsx-runtime");
4236
+ function clampIndex(index, length) {
4237
+ if (!length) return 0;
4238
+ return Math.min(Math.max(Math.floor(index), 0), length - 1);
4239
+ }
4240
+ function hasExtension(file, extensions) {
4241
+ const name = file.name.toLowerCase();
4242
+ return extensions.some((extension) => name.endsWith(extension));
4243
+ }
4244
+ function getFilePreviewKind(file) {
4245
+ const type = file.type.toLowerCase();
4246
+ if (type.startsWith("image/") || hasExtension(file, [".svg"])) return "image";
4247
+ if (type.startsWith("video/")) return "video";
4248
+ if (type.startsWith("audio/")) return "audio";
4249
+ if (type === "application/pdf" || hasExtension(file, [".pdf"])) return "pdf";
4250
+ return "unsupported";
4251
+ }
4252
+ function formatFileSize2(bytes) {
4253
+ if (bytes < 1024) return `${bytes} B`;
4254
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
4255
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
4256
+ }
4257
+ function getFileExtension(file) {
4258
+ const dotIndex = file.name.lastIndexOf(".");
4259
+ return dotIndex >= 0 ? file.name.slice(dotIndex + 1).toUpperCase() : "FILE";
4260
+ }
4261
+ function useFileObjectUrl(file) {
4262
+ const [preview, setPreview] = (0, import_react30.useState)();
4263
+ (0, import_react30.useEffect)(() => {
4264
+ if (!file || typeof URL.createObjectURL !== "function") {
4265
+ setPreview(void 0);
4266
+ return;
4267
+ }
4268
+ const url = URL.createObjectURL(file);
4269
+ setPreview({ file, url });
4270
+ return () => URL.revokeObjectURL(url);
4271
+ }, [file]);
4272
+ if (!preview || preview.file !== file) return void 0;
4273
+ return preview.url;
4274
+ }
4275
+ function startLocalDownload(file) {
4276
+ if (typeof document === "undefined" || typeof URL.createObjectURL !== "function") {
4277
+ return;
4278
+ }
4279
+ const url = URL.createObjectURL(file);
4280
+ const anchor = document.createElement("a");
4281
+ anchor.href = url;
4282
+ anchor.download = file.name;
4283
+ anchor.hidden = true;
4284
+ document.body.append(anchor);
4285
+ anchor.click();
4286
+ anchor.remove();
4287
+ window.setTimeout(() => URL.revokeObjectURL(url), 0);
4288
+ }
4289
+ function PreviewContent({ file }) {
4290
+ const kind = getFilePreviewKind(file);
4291
+ const url = useFileObjectUrl(file);
4292
+ if (url && kind === "image") {
4293
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("img", { className: "fe-file-preview__image", src: url, alt: file.name });
4294
+ }
4295
+ if (url && kind === "video") {
4296
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("video", { className: "fe-file-preview__video", controls: true, src: url, children: "Your browser cannot play this video." });
4297
+ }
4298
+ if (url && kind === "audio") {
4299
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("audio", { className: "fe-file-preview__audio", controls: true, src: url });
4300
+ }
4301
+ if (url && kind === "pdf") {
4302
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
4303
+ "iframe",
4304
+ {
4305
+ className: "fe-file-preview__pdf",
4306
+ title: `Preview ${file.name}`,
4307
+ src: `${url}#view=FitH`
4308
+ }
4309
+ );
4310
+ }
4311
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "fe-file-preview__unsupported", children: [
4312
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "fe-file-preview__file-type", "aria-hidden": "true", children: getFileExtension(file) }),
4313
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { children: "Preview is not available for this file type." }),
4314
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { children: file.name })
4315
+ ] });
4316
+ }
4317
+ function FilePreview({
4318
+ open,
4319
+ files,
4320
+ activeIndex,
4321
+ defaultActiveIndex = 0,
4322
+ onActiveIndexChange,
4323
+ onClose,
4324
+ onEscape,
4325
+ onDelete,
4326
+ onDownload,
4327
+ closeOnBackdropClick = true,
4328
+ closeOnEscape = true,
4329
+ closeLabel = "Close file preview",
4330
+ downloadLabel = "Download",
4331
+ deleteLabel = "Delete",
4332
+ hideDownload = false,
4333
+ className,
4334
+ "aria-label": ariaLabel,
4335
+ ...props
4336
+ }) {
4337
+ const titleId = (0, import_react30.useId)();
4338
+ const panelRef = (0, import_react30.useRef)(null);
4339
+ const [uncontrolledIndex, setUncontrolledIndex] = (0, import_react30.useState)(defaultActiveIndex);
4340
+ const resolvedIndex = clampIndex(
4341
+ activeIndex ?? uncontrolledIndex,
4342
+ files.length
4343
+ );
4344
+ const activeFile = files[resolvedIndex];
4345
+ const hasPrevious = resolvedIndex > 0;
4346
+ const hasNext = resolvedIndex < files.length - 1;
4347
+ const requestClose = (reason) => {
4348
+ if (reason === "escape") onEscape?.();
4349
+ onClose(reason);
4350
+ };
4351
+ useModalOverlay({
4352
+ open,
4353
+ onClose: () => requestClose("escape"),
4354
+ panelRef,
4355
+ priority: 1200,
4356
+ closeOnEscape
4357
+ });
4358
+ (0, import_react30.useEffect)(() => {
4359
+ if (activeIndex === void 0) {
4360
+ setUncontrolledIndex((index) => clampIndex(index, files.length));
4361
+ }
4362
+ }, [activeIndex, files.length]);
4363
+ const changeActiveIndex = (nextIndex) => {
4364
+ const next = clampIndex(nextIndex, files.length);
4365
+ const nextFile = files[next];
4366
+ if (!nextFile || next === resolvedIndex) return;
4367
+ if (activeIndex === void 0) setUncontrolledIndex(next);
4368
+ onActiveIndexChange?.(next, nextFile);
4369
+ };
4370
+ const handleKeyDown = (event) => {
4371
+ if (event.key === "ArrowLeft" && hasPrevious) {
4372
+ event.preventDefault();
4373
+ changeActiveIndex(resolvedIndex - 1);
4374
+ }
4375
+ if (event.key === "ArrowRight" && hasNext) {
4376
+ event.preventDefault();
4377
+ changeActiveIndex(resolvedIndex + 1);
4378
+ }
4379
+ };
4380
+ if (!open || typeof document === "undefined") return null;
4381
+ return (0, import_react_dom4.createPortal)(
4382
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
4383
+ "div",
4384
+ {
4385
+ className: "fe-file-preview-backdrop",
4386
+ role: "presentation",
4387
+ onMouseDown: (event) => {
4388
+ if (event.target === event.currentTarget && closeOnBackdropClick) {
4389
+ requestClose("backdrop");
4390
+ }
4391
+ },
4392
+ children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
4393
+ "div",
4394
+ {
4395
+ ...props,
4396
+ ref: panelRef,
4397
+ className: ["fe-file-preview", className].filter(Boolean).join(" "),
4398
+ role: "dialog",
4399
+ "aria-modal": "true",
4400
+ "aria-labelledby": activeFile ? titleId : void 0,
4401
+ "aria-label": ariaLabel ?? (activeFile ? void 0 : "File preview"),
4402
+ tabIndex: -1,
4403
+ onKeyDown: handleKeyDown,
4404
+ children: [
4405
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("header", { className: "fe-file-preview__header", children: [
4406
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "fe-file-preview__heading", children: [
4407
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("h2", { id: titleId, children: activeFile?.name ?? "File preview" }),
4408
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { "aria-label": `${resolvedIndex + 1} of ${files.length} files`, children: files.length ? `${resolvedIndex + 1} / ${files.length}` : "0 / 0" })
4409
+ ] }),
4410
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
4411
+ Button,
4412
+ {
4413
+ hierarchy: "tertiary-gray",
4414
+ size: "32",
4415
+ iconOnly: true,
4416
+ icon: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(CloseIcon, {}),
4417
+ "aria-label": closeLabel,
4418
+ onClick: () => requestClose("close")
4419
+ }
4420
+ )
4421
+ ] }),
4422
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "fe-file-preview__body", children: [
4423
+ activeFile ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PreviewContent, { file: activeFile }) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("p", { className: "fe-file-preview__empty", children: "No files to preview." }),
4424
+ activeFile && files.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
4425
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
4426
+ Button,
4427
+ {
4428
+ className: "fe-file-preview__navigation fe-file-preview__navigation--previous",
4429
+ hierarchy: "secondary-gray",
4430
+ size: "40",
4431
+ iconOnly: true,
4432
+ icon: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ChevronDownIcon, {}),
4433
+ "aria-label": "Previous file",
4434
+ disabled: !hasPrevious,
4435
+ onClick: () => changeActiveIndex(resolvedIndex - 1)
4436
+ }
4437
+ ),
4438
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
4439
+ Button,
4440
+ {
4441
+ className: "fe-file-preview__navigation fe-file-preview__navigation--next",
4442
+ hierarchy: "secondary-gray",
4443
+ size: "40",
4444
+ iconOnly: true,
4445
+ icon: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ChevronDownIcon, {}),
4446
+ "aria-label": "Next file",
4447
+ disabled: !hasNext,
4448
+ onClick: () => changeActiveIndex(resolvedIndex + 1)
4449
+ }
4450
+ )
4451
+ ] })
4452
+ ] }),
4453
+ activeFile && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("footer", { className: "fe-file-preview__footer", children: [
4454
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "fe-file-preview__metadata", children: [
4455
+ getFilePreviewKind(activeFile),
4456
+ " \xB7",
4457
+ " ",
4458
+ formatFileSize2(activeFile.size)
4459
+ ] }),
4460
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "fe-file-preview__actions", children: [
4461
+ !hideDownload && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
4462
+ Button,
4463
+ {
4464
+ hierarchy: "secondary-gray",
4465
+ onClick: () => {
4466
+ onDownload?.(activeFile, resolvedIndex);
4467
+ startLocalDownload(activeFile);
4468
+ },
4469
+ children: downloadLabel
4470
+ }
4471
+ ),
4472
+ onDelete && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
4473
+ Button,
4474
+ {
4475
+ hierarchy: "secondary-color",
4476
+ color: "error",
4477
+ destructive: true,
4478
+ onClick: () => onDelete(activeFile, resolvedIndex),
4479
+ children: deleteLabel
4480
+ }
4481
+ )
4482
+ ] })
4483
+ ] })
4484
+ ]
4485
+ }
4486
+ )
4487
+ }
4488
+ ),
4489
+ document.body
4490
+ );
4491
+ }
3044
4492
  // Annotate the CommonJS export names for ESM import in node:
3045
4493
  0 && (module.exports = {
3046
4494
  Avatar,
@@ -3055,14 +4503,25 @@ function AvatarGroup({
3055
4503
  CurrencyInput,
3056
4504
  DateTimePicker,
3057
4505
  Drawer,
4506
+ DrawerWidths,
4507
+ EmailInput,
3058
4508
  ExpandableSection,
4509
+ EyeIcon,
4510
+ EyeOffIcon,
4511
+ FILE_UPLOAD_ACCEPTS,
4512
+ FilePreview,
4513
+ FileUpload,
3059
4514
  Loading,
4515
+ MailboxIcon,
3060
4516
  Message,
3061
4517
  Modal,
3062
4518
  MoreHorizontalIcon,
3063
4519
  MoreVerticalIcon,
3064
4520
  NumberInput,
3065
4521
  Pagination,
4522
+ PasswordInput,
4523
+ PhoneIcon,
4524
+ PhoneNumberInput,
3066
4525
  PlusIcon,
3067
4526
  ProgressBar,
3068
4527
  RadioButton,
@@ -3082,6 +4541,7 @@ function AvatarGroup({
3082
4541
  TableHead,
3083
4542
  TableHeader,
3084
4543
  TableRow,
4544
+ Tabs,
3085
4545
  TextArea,
3086
4546
  TextInput,
3087
4547
  Toggle,
@@ -3093,7 +4553,9 @@ function AvatarGroup({
3093
4553
  chevron_right,
3094
4554
  chevron_up,
3095
4555
  copy,
4556
+ formatFileSize,
3096
4557
  formatNumber,
4558
+ getFilePreviewKind,
3097
4559
  getIconSize,
3098
4560
  key,
3099
4561
  lock,
@@ -3101,9 +4563,13 @@ function AvatarGroup({
3101
4563
  log_out,
3102
4564
  message,
3103
4565
  minus_square,
4566
+ normalizePhoneNumber,
3104
4567
  plus,
3105
4568
  plus_square,
3106
4569
  search,
3107
4570
  trash,
4571
+ validateEmail,
4572
+ validatePassword,
4573
+ validatePhoneNumber,
3108
4574
  x_close
3109
4575
  });