@dragunio/fe-libs 0.1.8 → 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,
@@ -71,7 +82,9 @@ __export(index_exports, {
71
82
  chevron_right: () => chevron_right,
72
83
  chevron_up: () => chevron_up,
73
84
  copy: () => copy,
85
+ formatFileSize: () => formatFileSize,
74
86
  formatNumber: () => formatNumber,
87
+ getFilePreviewKind: () => getFilePreviewKind,
75
88
  getIconSize: () => getIconSize,
76
89
  key: () => key,
77
90
  lock: () => lock,
@@ -79,10 +92,14 @@ __export(index_exports, {
79
92
  log_out: () => log_out,
80
93
  message: () => message,
81
94
  minus_square: () => minus_square,
95
+ normalizePhoneNumber: () => normalizePhoneNumber,
82
96
  plus: () => plus,
83
97
  plus_square: () => plus_square,
84
98
  search: () => search,
85
99
  trash: () => trash,
100
+ validateEmail: () => validateEmail,
101
+ validatePassword: () => validatePassword,
102
+ validatePhoneNumber: () => validatePhoneNumber,
86
103
  x_close: () => x_close
87
104
  });
88
105
  module.exports = __toCommonJS(index_exports);
@@ -327,6 +344,82 @@ function SearchIcon(props) {
327
344
  )
328
345
  ] });
329
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
+ }
330
423
 
331
424
  // packages/button-bar/src/index.tsx
332
425
  var import_jsx_runtime6 = require("react/jsx-runtime");
@@ -926,42 +1019,262 @@ var Toggle = (0, import_react7.forwardRef)(function Toggle2({
926
1019
  Toggle.displayName = "Toggle";
927
1020
 
928
1021
  // packages/drawer/src/index.tsx
929
- var import_react8 = require("react");
1022
+ var import_react9 = require("react");
930
1023
  var import_react_dom = require("react-dom");
931
- var import_jsx_runtime11 = require("react/jsx-runtime");
932
- function Drawer({ open, onClose, title, footer, side = "right", width = 400, fullScreen = false, children, closeOnBackdropClick = true, className, style, ...props }) {
933
- (0, import_react8.useEffect)(() => {
934
- 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
+ });
935
1119
  const onKeyDown = (event) => {
936
- 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
+ }
937
1147
  };
938
1148
  document.addEventListener("keydown", onKeyDown);
939
- return () => document.removeEventListener("keydown", onKeyDown);
940
- }, [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
+ });
941
1208
  if (!open || typeof document === "undefined") return null;
942
1209
  const panelStyle = !fullScreen && (side === "left" || side === "right") ? { ...style, width: typeof width === "number" ? `${width}px` : width } : style;
943
- return (0, import_react_dom.createPortal)(/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "fe-drawer-backdrop", role: "presentation", onMouseDown: (event) => {
944
- if (event.target === event.currentTarget && closeOnBackdropClick) onClose();
945
- }, children: /* @__PURE__ */ (0, import_jsx_runtime11.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: [
946
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("header", { className: "fe-drawer__header", children: [
947
- title && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("h2", { children: title }),
948
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("button", { type: "button", "aria-label": "Close drawer", onClick: onClose, children: "\xD7" })
949
- ] }),
950
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "fe-drawer__body", children }),
951
- footer && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("footer", { className: "fe-drawer__footer", children: footer })
952
- ] }) }), 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
+ );
953
1266
  }
954
1267
 
955
1268
  // packages/form-controls/src/controls/TextInput/text-input.tsx
956
- var import_react10 = require("react");
1269
+ var import_react11 = require("react");
957
1270
 
958
1271
  // packages/tooltip/src/index.tsx
959
- var import_react9 = require("react");
1272
+ var import_react10 = require("react");
960
1273
  var import_jsx_runtime12 = require("react/jsx-runtime");
961
1274
  function Tooltip({ content, children, placement = "top", disabled, className, ...props }) {
962
- const [visible, setVisible] = (0, import_react9.useState)(false);
963
- const id = (0, import_react9.useId)();
964
- const trigger = (0, import_react9.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) => {
965
1278
  children.props.onMouseEnter?.(event);
966
1279
  setVisible(true);
967
1280
  }, onMouseLeave: (event) => {
@@ -1036,7 +1349,7 @@ function FieldMessage({
1036
1349
 
1037
1350
  // packages/form-controls/src/controls/TextInput/text-input.tsx
1038
1351
  var import_jsx_runtime14 = require("react/jsx-runtime");
1039
- var TextInput = (0, import_react10.forwardRef)(
1352
+ var TextInput = (0, import_react11.forwardRef)(
1040
1353
  function TextInput2({
1041
1354
  value,
1042
1355
  defaultValue = "",
@@ -1066,12 +1379,12 @@ var TextInput = (0, import_react10.forwardRef)(
1066
1379
  "aria-labelledby": ariaLabelledBy,
1067
1380
  ...props
1068
1381
  }, ref) {
1069
- const generatedId = (0, import_react10.useId)();
1382
+ const generatedId = (0, import_react11.useId)();
1070
1383
  const inputId = id ?? generatedId + "-input";
1071
1384
  const labelId = generatedId + "-label";
1072
1385
  const messageId2 = generatedId + "-message";
1073
1386
  const controlled = value !== void 0;
1074
- const [internalValue, setInternalValue] = (0, import_react10.useState)(defaultValue);
1387
+ const [internalValue, setInternalValue] = (0, import_react11.useState)(defaultValue);
1075
1388
  const currentValue = controlled ? value : internalValue;
1076
1389
  const fieldError = getFieldError(error, errorMessage);
1077
1390
  const hasError = fieldError !== void 0 && fieldError !== false && fieldError !== null;
@@ -1171,10 +1484,257 @@ var TextInput = (0, import_react10.forwardRef)(
1171
1484
  );
1172
1485
  TextInput.displayName = "TextInput";
1173
1486
 
1174
- // packages/form-controls/src/controls/TextArea/text-area.tsx
1175
- var import_react11 = require("react");
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
1176
1552
  var import_jsx_runtime15 = require("react/jsx-runtime");
1177
- var TextArea = (0, import_react11.forwardRef)(
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
+
1734
+ // packages/form-controls/src/controls/TextArea/text-area.tsx
1735
+ var import_react16 = require("react");
1736
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1737
+ var TextArea = (0, import_react16.forwardRef)(
1178
1738
  function TextArea2({
1179
1739
  value,
1180
1740
  defaultValue = "",
@@ -1201,13 +1761,13 @@ var TextArea = (0, import_react11.forwardRef)(
1201
1761
  "aria-labelledby": ariaLabelledBy,
1202
1762
  ...props
1203
1763
  }, ref) {
1204
- const generatedId = (0, import_react11.useId)();
1764
+ const generatedId = (0, import_react16.useId)();
1205
1765
  const inputId = id ?? generatedId + "-input";
1206
1766
  const labelId = generatedId + "-label";
1207
1767
  const messageId2 = generatedId + "-message";
1208
1768
  const controlled = value !== void 0;
1209
- const [internalValue, setInternalValue] = (0, import_react11.useState)(defaultValue);
1210
- const textareaRef = (0, import_react11.useRef)(null);
1769
+ const [internalValue, setInternalValue] = (0, import_react16.useState)(defaultValue);
1770
+ const textareaRef = (0, import_react16.useRef)(null);
1211
1771
  const currentValue = controlled ? value : internalValue;
1212
1772
  const fieldError = getFieldError(error, errorMessage);
1213
1773
  const hasError = fieldError !== void 0 && fieldError !== false && fieldError !== null;
@@ -1225,8 +1785,8 @@ var TextArea = (0, import_react11.forwardRef)(
1225
1785
  textarea.style.height = "auto";
1226
1786
  textarea.style.height = `${textarea.scrollHeight}px`;
1227
1787
  };
1228
- (0, import_react11.useImperativeHandle)(ref, () => textareaRef.current, []);
1229
- (0, import_react11.useLayoutEffect)(() => {
1788
+ (0, import_react16.useImperativeHandle)(ref, () => textareaRef.current, []);
1789
+ (0, import_react16.useLayoutEffect)(() => {
1230
1790
  if (autosize && textareaRef.current) {
1231
1791
  resizeToContent(textareaRef.current);
1232
1792
  }
@@ -1236,7 +1796,7 @@ var TextArea = (0, import_react11.forwardRef)(
1236
1796
  onValueChange?.("");
1237
1797
  onClear?.();
1238
1798
  };
1239
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1799
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1240
1800
  "div",
1241
1801
  {
1242
1802
  className: [
@@ -1246,7 +1806,7 @@ var TextArea = (0, import_react11.forwardRef)(
1246
1806
  className
1247
1807
  ].filter(Boolean).join(" "),
1248
1808
  children: [
1249
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1809
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1250
1810
  FieldLabel,
1251
1811
  {
1252
1812
  id: labelId,
@@ -1256,8 +1816,8 @@ var TextArea = (0, import_react11.forwardRef)(
1256
1816
  isRequired
1257
1817
  }
1258
1818
  ),
1259
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "fe-text-area__control", children: [
1260
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1819
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "fe-text-area__control", children: [
1820
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1261
1821
  "textarea",
1262
1822
  {
1263
1823
  ref: textareaRef,
@@ -1280,24 +1840,24 @@ var TextArea = (0, import_react11.forwardRef)(
1280
1840
  ...props
1281
1841
  }
1282
1842
  ),
1283
- isRequired && placeholder && !currentValue && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "fe-text-area__placeholder", "aria-hidden": "true", children: [
1284
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: placeholder }),
1285
- /* @__PURE__ */ (0, import_jsx_runtime15.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: "*" })
1286
1846
  ] }),
1287
- clearable && currentValue && !disabled && !readOnly && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1847
+ clearable && currentValue && !disabled && !readOnly && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1288
1848
  Button,
1289
1849
  {
1290
1850
  hierarchy: "tertiary-gray",
1291
1851
  size: "24",
1292
1852
  iconOnly: true,
1293
- icon: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(CloseIcon, { size: 14 }),
1853
+ icon: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(CloseIcon, { size: 14 }),
1294
1854
  "aria-label": clearLabel,
1295
1855
  onClick: clear,
1296
1856
  className: "fe-text-area__clear"
1297
1857
  }
1298
1858
  )
1299
1859
  ] }),
1300
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1860
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1301
1861
  FieldMessage,
1302
1862
  {
1303
1863
  id: messageId2,
@@ -1314,10 +1874,25 @@ var TextArea = (0, import_react11.forwardRef)(
1314
1874
  TextArea.displayName = "TextArea";
1315
1875
 
1316
1876
  // packages/form-controls/src/controls/Selection/selection.tsx
1317
- var import_react12 = require("react");
1877
+ var import_react17 = require("react");
1318
1878
  var import_react_dom2 = require("react-dom");
1319
- var import_jsx_runtime16 = require("react/jsx-runtime");
1320
- var Selection = (0, import_react12.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)(
1321
1896
  function Selection2({
1322
1897
  className,
1323
1898
  label,
@@ -1346,7 +1921,7 @@ var Selection = (0, import_react12.forwardRef)(
1346
1921
  "aria-labelledby": ariaLabelledBy,
1347
1922
  ...props
1348
1923
  }, ref) {
1349
- const generatedId = (0, import_react12.useId)();
1924
+ const generatedId = (0, import_react17.useId)();
1350
1925
  const triggerId = id ?? generatedId + "-trigger";
1351
1926
  const listboxId = triggerId + "-listbox";
1352
1927
  const labelId = generatedId + "-label";
@@ -1364,7 +1939,7 @@ var Selection = (0, import_react12.forwardRef)(
1364
1939
  label ? labelId : void 0
1365
1940
  );
1366
1941
  const isControlled = value !== void 0;
1367
- const [internalValue, setInternalValue] = (0, import_react12.useState)(
1942
+ const [internalValue, setInternalValue] = (0, import_react17.useState)(
1368
1943
  defaultValue ?? (multiple ? [] : "")
1369
1944
  );
1370
1945
  const selectedValue = isControlled ? value : internalValue;
@@ -1372,13 +1947,13 @@ var Selection = (0, import_react12.forwardRef)(
1372
1947
  const selectedOptions = options.filter(
1373
1948
  (option) => selectedValues.some((item) => String(item) === String(option.value))
1374
1949
  );
1375
- const [open, setOpen] = (0, import_react12.useState)(false);
1376
- const [query, setQuery] = (0, import_react12.useState)("");
1377
- const [activeIndex, setActiveIndex] = (0, import_react12.useState)(0);
1378
- const rootRef = (0, import_react12.useRef)(null);
1379
- const menuRef = (0, import_react12.useRef)(null);
1380
- const [menuPosition, setMenuPosition] = (0, import_react12.useState)(null);
1381
- (0, import_react12.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)(() => {
1382
1957
  const close = (event) => {
1383
1958
  const target = event.target;
1384
1959
  if (!rootRef.current?.contains(target) && !menuRef.current?.contains(target))
@@ -1387,7 +1962,7 @@ var Selection = (0, import_react12.forwardRef)(
1387
1962
  document.addEventListener("mousedown", close);
1388
1963
  return () => document.removeEventListener("mousedown", close);
1389
1964
  }, []);
1390
- (0, import_react12.useLayoutEffect)(() => {
1965
+ (0, import_react17.useLayoutEffect)(() => {
1391
1966
  if (!open) return;
1392
1967
  const updateMenuPosition = () => {
1393
1968
  const rect = rootRef.current?.getBoundingClientRect();
@@ -1395,7 +1970,8 @@ var Selection = (0, import_react12.forwardRef)(
1395
1970
  setMenuPosition({
1396
1971
  top: rect.bottom + 7,
1397
1972
  left: rect.left,
1398
- width: rect.width
1973
+ width: rect.width,
1974
+ zIndex: getPortalZIndex(rootRef.current)
1399
1975
  });
1400
1976
  };
1401
1977
  updateMenuPosition();
@@ -1464,7 +2040,7 @@ var Selection = (0, import_react12.forwardRef)(
1464
2040
  }
1465
2041
  if (event.key === "Escape") setOpen(false);
1466
2042
  };
1467
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2043
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
1468
2044
  "div",
1469
2045
  {
1470
2046
  ref,
@@ -1479,7 +2055,7 @@ var Selection = (0, import_react12.forwardRef)(
1479
2055
  ].filter(Boolean).join(" "),
1480
2056
  ...props,
1481
2057
  children: [
1482
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2058
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1483
2059
  FieldLabel,
1484
2060
  {
1485
2061
  id: labelId,
@@ -1489,8 +2065,8 @@ var Selection = (0, import_react12.forwardRef)(
1489
2065
  isRequired
1490
2066
  }
1491
2067
  ),
1492
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { ref: rootRef, className: "fe-selection__control", children: [
1493
- name && selectedValues.map((item) => /* @__PURE__ */ (0, import_jsx_runtime16.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)(
1494
2070
  "input",
1495
2071
  {
1496
2072
  type: "hidden",
@@ -1499,7 +2075,7 @@ var Selection = (0, import_react12.forwardRef)(
1499
2075
  },
1500
2076
  String(item)
1501
2077
  )),
1502
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2078
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
1503
2079
  "button",
1504
2080
  {
1505
2081
  id: triggerId,
@@ -1517,7 +2093,7 @@ var Selection = (0, import_react12.forwardRef)(
1517
2093
  onClick: () => setOpen((current) => !current),
1518
2094
  onKeyDown: onTriggerKeyDown,
1519
2095
  children: [
1520
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2096
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1521
2097
  "span",
1522
2098
  {
1523
2099
  className: [
@@ -1525,30 +2101,30 @@ var Selection = (0, import_react12.forwardRef)(
1525
2101
  !selectedOptions.length && "is-placeholder",
1526
2102
  tag && selectedOptions.length > 1 && "is-tags"
1527
2103
  ].filter(Boolean).join(" "),
1528
- children: displayLabel ? tag && multiple ? selectedOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2104
+ children: displayLabel ? tag && multiple ? selectedOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
1529
2105
  "span",
1530
2106
  {
1531
2107
  className: "fe-selection__tag",
1532
2108
  children: [
1533
2109
  option.label,
1534
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { "aria-hidden": "true", children: "\xD7" })
2110
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { "aria-hidden": "true", children: "\xD7" })
1535
2111
  ]
1536
2112
  },
1537
2113
  String(option.value)
1538
- )) : displayLabel.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { children: [
2114
+ )) : displayLabel.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("span", { children: [
1539
2115
  item,
1540
2116
  index < displayLabel.length - 1 ? ", " : ""
1541
- ] }, index)) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
1542
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: placeholder }),
1543
- isRequired && /* @__PURE__ */ (0, import_jsx_runtime16.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: "*" })
1544
2120
  ] })
1545
2121
  }
1546
2122
  ),
1547
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "fe-selection__actions", children: /* @__PURE__ */ (0, import_jsx_runtime16.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" }) })
1548
2124
  ]
1549
2125
  }
1550
2126
  ),
1551
- clearable && selectedOptions.length > 0 && !disabled && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2127
+ clearable && selectedOptions.length > 0 && !disabled && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1552
2128
  "button",
1553
2129
  {
1554
2130
  type: "button",
@@ -1558,7 +2134,7 @@ var Selection = (0, import_react12.forwardRef)(
1558
2134
  }
1559
2135
  ),
1560
2136
  open && menuPosition && (0, import_react_dom2.createPortal)(
1561
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2137
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
1562
2138
  "div",
1563
2139
  {
1564
2140
  ref: menuRef,
@@ -1568,14 +2144,15 @@ var Selection = (0, import_react12.forwardRef)(
1568
2144
  position: "fixed",
1569
2145
  top: menuPosition.top,
1570
2146
  left: menuPosition.left,
1571
- width: menuPosition.width
2147
+ width: menuPosition.width,
2148
+ zIndex: menuPosition.zIndex
1572
2149
  },
1573
2150
  role: "listbox",
1574
2151
  "aria-multiselectable": multiple || void 0,
1575
2152
  children: [
1576
- searchable && /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "fe-selection__search", children: [
1577
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { "aria-hidden": "true", children: "\u2315" }),
1578
- /* @__PURE__ */ (0, import_jsx_runtime16.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)(
1579
2156
  "input",
1580
2157
  {
1581
2158
  autoFocus: true,
@@ -1589,11 +2166,11 @@ var Selection = (0, import_react12.forwardRef)(
1589
2166
  }
1590
2167
  )
1591
2168
  ] }),
1592
- /* @__PURE__ */ (0, import_jsx_runtime16.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) => {
1593
2170
  const isSelected = selectedValues.some(
1594
2171
  (item) => String(item) === String(option.value)
1595
2172
  );
1596
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
2173
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
1597
2174
  "button",
1598
2175
  {
1599
2176
  type: "button",
@@ -1607,8 +2184,8 @@ var Selection = (0, import_react12.forwardRef)(
1607
2184
  onMouseMove: () => setActiveIndex(index),
1608
2185
  onClick: () => choose(option),
1609
2186
  children: [
1610
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: option.label }),
1611
- isSelected && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2187
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { children: option.label }),
2188
+ isSelected && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1612
2189
  "span",
1613
2190
  {
1614
2191
  className: "fe-selection__check",
@@ -1620,14 +2197,14 @@ var Selection = (0, import_react12.forwardRef)(
1620
2197
  },
1621
2198
  String(option.value)
1622
2199
  );
1623
- }) : /* @__PURE__ */ (0, import_jsx_runtime16.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" }) })
1624
2201
  ]
1625
2202
  }
1626
2203
  ),
1627
2204
  document.body
1628
2205
  )
1629
2206
  ] }),
1630
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2207
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1631
2208
  FieldMessage,
1632
2209
  {
1633
2210
  id: messageId2,
@@ -1644,8 +2221,8 @@ var Selection = (0, import_react12.forwardRef)(
1644
2221
  Selection.displayName = "Selection";
1645
2222
 
1646
2223
  // packages/form-controls/src/controls/NumberInput/number-input.tsx
1647
- var import_react13 = require("react");
1648
- var import_jsx_runtime17 = require("react/jsx-runtime");
2224
+ var import_react18 = require("react");
2225
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1649
2226
  function formatNumber(value, decimals = 2, thousandSeparator = ",", decimalSeparator = ".") {
1650
2227
  return new Intl.NumberFormat("en-US", {
1651
2228
  minimumFractionDigits: 0,
@@ -1702,7 +2279,7 @@ function normalizeNumberInput(raw, options) {
1702
2279
  value
1703
2280
  };
1704
2281
  }
1705
- var NumberInput = (0, import_react13.forwardRef)(
2282
+ var NumberInput = (0, import_react18.forwardRef)(
1706
2283
  function NumberInput2({
1707
2284
  value,
1708
2285
  defaultValue = null,
@@ -1739,14 +2316,14 @@ var NumberInput = (0, import_react13.forwardRef)(
1739
2316
  onKeyDown,
1740
2317
  ...props
1741
2318
  }, ref) {
1742
- const inputRef = (0, import_react13.useRef)(null);
1743
- const generatedId = (0, import_react13.useId)();
2319
+ const inputRef = (0, import_react18.useRef)(null);
2320
+ const generatedId = (0, import_react18.useId)();
1744
2321
  const messageId2 = generatedId + "-message";
1745
2322
  const isControlled = value !== void 0;
1746
- const [internalValue, setInternalValue] = (0, import_react13.useState)(defaultValue);
1747
- const [focused, setFocused] = (0, import_react13.useState)(false);
2323
+ const [internalValue, setInternalValue] = (0, import_react18.useState)(defaultValue);
2324
+ const [focused, setFocused] = (0, import_react18.useState)(false);
1748
2325
  const actualValue = isControlled ? value ?? null : internalValue;
1749
- const [text, setText] = (0, import_react13.useState)(
2326
+ const [text, setText] = (0, import_react18.useState)(
1750
2327
  actualValue === null ? "" : formatNumber(
1751
2328
  actualValue,
1752
2329
  decimals,
@@ -1769,7 +2346,7 @@ var NumberInput = (0, import_react13.forwardRef)(
1769
2346
  );
1770
2347
  const resolvedPrefix = prefix ?? Prefix;
1771
2348
  const resolvedSuffix = suffix ?? Suffix;
1772
- (0, import_react13.useEffect)(() => {
2349
+ (0, import_react18.useEffect)(() => {
1773
2350
  if (!focused)
1774
2351
  setText(
1775
2352
  actualValue === null ? "" : formatNumber(
@@ -1823,7 +2400,7 @@ var NumberInput = (0, import_react13.forwardRef)(
1823
2400
  const stepIsUsable = Number.isFinite(step) && step > 0;
1824
2401
  const disableIncrement = Boolean(props.disabled || props.readOnly) || !stepIsUsable || max !== void 0 && actualValue !== null && actualValue >= max;
1825
2402
  const disableDecrement = Boolean(props.disabled || props.readOnly) || !stepIsUsable || min !== void 0 && actualValue !== null && actualValue <= min;
1826
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
2403
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
1827
2404
  "div",
1828
2405
  {
1829
2406
  className: [
@@ -1832,7 +2409,7 @@ var NumberInput = (0, import_react13.forwardRef)(
1832
2409
  className
1833
2410
  ].filter(Boolean).join(" "),
1834
2411
  children: [
1835
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2412
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1836
2413
  FieldLabel,
1837
2414
  {
1838
2415
  id: labelId,
@@ -1842,10 +2419,10 @@ var NumberInput = (0, import_react13.forwardRef)(
1842
2419
  isRequired
1843
2420
  }
1844
2421
  ),
1845
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "fe-number-input__control", children: [
1846
- resolvedPrefix && /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { className: "fe-number-input__prefix", children: resolvedPrefix }),
1847
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "fe-number-input__input-wrap", children: [
1848
- /* @__PURE__ */ (0, import_jsx_runtime17.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)(
1849
2426
  "input",
1850
2427
  {
1851
2428
  ref: (node) => {
@@ -1881,41 +2458,41 @@ var NumberInput = (0, import_react13.forwardRef)(
1881
2458
  "aria-describedby": describedBy
1882
2459
  }
1883
2460
  ),
1884
- isRequired && placeholder && !text && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
2461
+ isRequired && placeholder && !text && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
1885
2462
  "span",
1886
2463
  {
1887
2464
  className: "fe-number-input__placeholder",
1888
2465
  "aria-hidden": "true",
1889
2466
  children: [
1890
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { children: placeholder }),
1891
- /* @__PURE__ */ (0, import_jsx_runtime17.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: "*" })
1892
2469
  ]
1893
2470
  }
1894
2471
  )
1895
2472
  ] }),
1896
- resolvedSuffix && /* @__PURE__ */ (0, import_jsx_runtime17.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 }),
1897
2474
  endAdornment,
1898
- showStepper && /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("span", { className: "fe-number-input__stepper", children: [
1899
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2475
+ showStepper && /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "fe-number-input__stepper", children: [
2476
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1900
2477
  Button,
1901
2478
  {
1902
2479
  hierarchy: "tertiary-gray",
1903
2480
  size: "24",
1904
2481
  iconOnly: true,
1905
- icon: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronUpIcon, { size: 12 }),
2482
+ icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ChevronUpIcon, { size: 12 }),
1906
2483
  "aria-label": incrementLabel,
1907
2484
  disabled: disableIncrement,
1908
2485
  onMouseDown: (event) => event.preventDefault(),
1909
2486
  onClick: () => adjustValue(1)
1910
2487
  }
1911
2488
  ),
1912
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2489
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1913
2490
  Button,
1914
2491
  {
1915
2492
  hierarchy: "tertiary-gray",
1916
2493
  size: "24",
1917
2494
  iconOnly: true,
1918
- icon: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(ChevronDownIcon, { size: 12 }),
2495
+ icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(ChevronDownIcon, { size: 12 }),
1919
2496
  "aria-label": decrementLabel,
1920
2497
  disabled: disableDecrement,
1921
2498
  onMouseDown: (event) => event.preventDefault(),
@@ -1924,7 +2501,7 @@ var NumberInput = (0, import_react13.forwardRef)(
1924
2501
  )
1925
2502
  ] })
1926
2503
  ] }),
1927
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2504
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1928
2505
  FieldMessage,
1929
2506
  {
1930
2507
  id: messageId2,
@@ -1941,8 +2518,8 @@ var NumberInput = (0, import_react13.forwardRef)(
1941
2518
  NumberInput.displayName = "NumberInput";
1942
2519
 
1943
2520
  // packages/form-controls/src/controls/CurrencyInput/currency-input.tsx
1944
- var import_react14 = require("react");
1945
- var import_jsx_runtime18 = require("react/jsx-runtime");
2521
+ var import_react19 = require("react");
2522
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1946
2523
  function CurrencyInput({
1947
2524
  suffix = "VND",
1948
2525
  currencies,
@@ -1953,13 +2530,13 @@ function CurrencyInput({
1953
2530
  disabled,
1954
2531
  ...props
1955
2532
  }) {
1956
- const [internalCurrency, setInternalCurrency] = (0, import_react14.useState)(
2533
+ const [internalCurrency, setInternalCurrency] = (0, import_react19.useState)(
1957
2534
  defaultCurrency ?? currencies?.[0]?.code ?? ""
1958
2535
  );
1959
2536
  const selectedCurrency = currency ?? internalCurrency;
1960
2537
  const current = currencies?.find((item) => item.code === selectedCurrency);
1961
2538
  const currencySuffix = current?.suffix ?? current?.code ?? suffix;
1962
- const endAdornment = currencies?.length ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2539
+ const endAdornment = currencies?.length ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1963
2540
  Selection,
1964
2541
  {
1965
2542
  className: "fe-currency-input__currency",
@@ -1978,8 +2555,8 @@ function CurrencyInput({
1978
2555
  onCurrencyChange?.(next);
1979
2556
  }
1980
2557
  }
1981
- ) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "fe-currency-input__suffix", children: currencySuffix });
1982
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2558
+ ) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "fe-currency-input__suffix", children: currencySuffix });
2559
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1983
2560
  NumberInput,
1984
2561
  {
1985
2562
  ...props,
@@ -1991,8 +2568,8 @@ function CurrencyInput({
1991
2568
  }
1992
2569
 
1993
2570
  // packages/form-controls/src/controls/DateTimePicker/date-time-picker.tsx
1994
- var import_react15 = require("react");
1995
- var import_jsx_runtime19 = require("react/jsx-runtime");
2571
+ var import_react20 = require("react");
2572
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1996
2573
  var pad = (value) => String(value).padStart(2, "0");
1997
2574
  function formatDate(date, format) {
1998
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()));
@@ -2028,7 +2605,7 @@ function DateTimePicker(props) {
2028
2605
  "aria-describedby": ariaDescribedBy,
2029
2606
  "aria-labelledby": ariaLabelledBy
2030
2607
  } = props;
2031
- const generatedId = (0, import_react15.useId)();
2608
+ const generatedId = (0, import_react20.useId)();
2032
2609
  const triggerId = id ?? generatedId + "-trigger";
2033
2610
  const labelId = generatedId + "-label";
2034
2611
  const messageId2 = generatedId + "-message";
@@ -2046,28 +2623,28 @@ function DateTimePicker(props) {
2046
2623
  );
2047
2624
  const isRange = mode === "range";
2048
2625
  const controlled = props.value !== void 0;
2049
- const [singleInternal, setSingleInternal] = (0, import_react15.useState)(
2626
+ const [singleInternal, setSingleInternal] = (0, import_react20.useState)(
2050
2627
  (!isRange ? props.defaultValue : null) ?? null
2051
2628
  );
2052
- const [rangeInternal, setRangeInternal] = (0, import_react15.useState)(
2629
+ const [rangeInternal, setRangeInternal] = (0, import_react20.useState)(
2053
2630
  (isRange ? props.defaultValue : void 0) ?? [null, null]
2054
2631
  );
2055
2632
  const singleValue = !isRange ? props.value ?? singleInternal : null;
2056
2633
  const rangeValue = isRange ? props.value ?? rangeInternal : [null, null];
2057
- const [open, setOpen] = (0, import_react15.useState)(false);
2058
- const [month, setMonth] = (0, import_react15.useState)(
2634
+ const [open, setOpen] = (0, import_react20.useState)(false);
2635
+ const [month, setMonth] = (0, import_react20.useState)(
2059
2636
  () => new Date((isRange ? rangeValue[0] : singleValue) ?? /* @__PURE__ */ new Date())
2060
2637
  );
2061
- const [editingEnd, setEditingEnd] = (0, import_react15.useState)(false);
2062
- const rootRef = (0, import_react15.useRef)(null);
2063
- (0, import_react15.useEffect)(() => {
2638
+ const [editingEnd, setEditingEnd] = (0, import_react20.useState)(false);
2639
+ const rootRef = (0, import_react20.useRef)(null);
2640
+ (0, import_react20.useEffect)(() => {
2064
2641
  const onPointerDown = (event) => {
2065
2642
  if (!rootRef.current?.contains(event.target)) setOpen(false);
2066
2643
  };
2067
2644
  document.addEventListener("mousedown", onPointerDown);
2068
2645
  return () => document.removeEventListener("mousedown", onPointerDown);
2069
2646
  }, []);
2070
- (0, import_react15.useEffect)(() => {
2647
+ (0, import_react20.useEffect)(() => {
2071
2648
  if (disabled) setOpen(false);
2072
2649
  }, [disabled]);
2073
2650
  const setSingle = (next) => {
@@ -2123,7 +2700,7 @@ function DateTimePicker(props) {
2123
2700
  setRange(editingEnd ? [rangeValue[0], next] : [next, rangeValue[1]]);
2124
2701
  else setSingle(next);
2125
2702
  };
2126
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2703
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2127
2704
  "div",
2128
2705
  {
2129
2706
  ref: rootRef,
@@ -2133,7 +2710,7 @@ function DateTimePicker(props) {
2133
2710
  className
2134
2711
  ].filter(Boolean).join(" "),
2135
2712
  children: [
2136
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2713
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2137
2714
  FieldLabel,
2138
2715
  {
2139
2716
  id: labelId,
@@ -2143,7 +2720,7 @@ function DateTimePicker(props) {
2143
2720
  isRequired
2144
2721
  }
2145
2722
  ),
2146
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2723
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2147
2724
  "button",
2148
2725
  {
2149
2726
  id: triggerId,
@@ -2157,29 +2734,29 @@ function DateTimePicker(props) {
2157
2734
  "aria-expanded": open,
2158
2735
  onClick: () => setOpen((current) => !current),
2159
2736
  children: [
2160
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { "aria-hidden": "true", children: "\u25F7" }),
2161
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2737
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { "aria-hidden": "true", children: "\u25F7" }),
2738
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2162
2739
  "span",
2163
2740
  {
2164
2741
  className: !shownValue && placeholder ? "fe-datetime-picker__value is-placeholder" : "fe-datetime-picker__value",
2165
2742
  children: [
2166
2743
  shownValue || placeholder || (isRange ? "Select date range" : "Select date and time"),
2167
- isRequired && placeholder && !shownValue && /* @__PURE__ */ (0, import_jsx_runtime19.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: "*" })
2168
2745
  ]
2169
2746
  }
2170
2747
  )
2171
2748
  ]
2172
2749
  }
2173
2750
  ),
2174
- open && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
2751
+ open && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
2175
2752
  "div",
2176
2753
  {
2177
2754
  className: "fe-datetime-picker__popper",
2178
2755
  role: "dialog",
2179
2756
  "aria-label": "Date and time picker",
2180
2757
  children: [
2181
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "fe-datetime-picker__month", children: [
2182
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2758
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "fe-datetime-picker__month", children: [
2759
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2183
2760
  "button",
2184
2761
  {
2185
2762
  type: "button",
@@ -2190,11 +2767,11 @@ function DateTimePicker(props) {
2190
2767
  children: "\u2039"
2191
2768
  }
2192
2769
  ),
2193
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("strong", { children: month.toLocaleDateString(locale, {
2770
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("strong", { children: month.toLocaleDateString(locale, {
2194
2771
  month: "long",
2195
2772
  year: "numeric"
2196
2773
  }) }),
2197
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2774
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2198
2775
  "button",
2199
2776
  {
2200
2777
  type: "button",
@@ -2206,12 +2783,12 @@ function DateTimePicker(props) {
2206
2783
  }
2207
2784
  )
2208
2785
  ] }),
2209
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("div", { className: "fe-datetime-picker__weekdays", children: ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"].map((day) => /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { children: day }, day)) }),
2210
- /* @__PURE__ */ (0, import_jsx_runtime19.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) => {
2211
2788
  const inMonth = day.getMonth() === month.getMonth();
2212
2789
  const selected = isRange ? sameDay(day, rangeValue[0]) || sameDay(day, rangeValue[1]) : sameDay(day, singleValue);
2213
2790
  const inRange = isRange && rangeValue[0] && rangeValue[1] && day > startOfDay(rangeValue[0]) && day < startOfDay(rangeValue[1]);
2214
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2791
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2215
2792
  "button",
2216
2793
  {
2217
2794
  type: "button",
@@ -2226,8 +2803,8 @@ function DateTimePicker(props) {
2226
2803
  day.toISOString()
2227
2804
  );
2228
2805
  }) }),
2229
- isRange && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "fe-datetime-picker__range-tabs", children: [
2230
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2806
+ isRange && /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "fe-datetime-picker__range-tabs", children: [
2807
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2231
2808
  "button",
2232
2809
  {
2233
2810
  type: "button",
@@ -2236,7 +2813,7 @@ function DateTimePicker(props) {
2236
2813
  children: "Start"
2237
2814
  }
2238
2815
  ),
2239
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2816
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2240
2817
  "button",
2241
2818
  {
2242
2819
  type: "button",
@@ -2246,9 +2823,9 @@ function DateTimePicker(props) {
2246
2823
  }
2247
2824
  )
2248
2825
  ] }),
2249
- /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("label", { className: "fe-datetime-picker__time", children: [
2826
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("label", { className: "fe-datetime-picker__time", children: [
2250
2827
  "Time",
2251
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2828
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2252
2829
  "input",
2253
2830
  {
2254
2831
  type: "time",
@@ -2261,7 +2838,7 @@ function DateTimePicker(props) {
2261
2838
  ]
2262
2839
  }
2263
2840
  ),
2264
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2841
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2265
2842
  FieldMessage,
2266
2843
  {
2267
2844
  id: messageId2,
@@ -2276,9 +2853,9 @@ function DateTimePicker(props) {
2276
2853
  }
2277
2854
 
2278
2855
  // packages/form-controls/src/controls/Checkbox/checkbox.tsx
2279
- var import_react16 = require("react");
2280
- var import_jsx_runtime20 = require("react/jsx-runtime");
2281
- var Checkbox = (0, import_react16.forwardRef)(
2856
+ var import_react21 = require("react");
2857
+ var import_jsx_runtime23 = require("react/jsx-runtime");
2858
+ var Checkbox = (0, import_react21.forwardRef)(
2282
2859
  function Checkbox2({
2283
2860
  label,
2284
2861
  labelPosition = "right",
@@ -2294,10 +2871,10 @@ var Checkbox = (0, import_react16.forwardRef)(
2294
2871
  disabled && "fe-checkbox--disabled",
2295
2872
  className
2296
2873
  ].filter(Boolean).join(" ");
2297
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("label", { className: classes, style, children: [
2298
- label && labelPosition === "top" && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "fe-checkbox__label", children: label }),
2299
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "fe-checkbox__content", children: [
2300
- /* @__PURE__ */ (0, import_jsx_runtime20.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)(
2301
2878
  "input",
2302
2879
  {
2303
2880
  ref,
@@ -2308,8 +2885,8 @@ var Checkbox = (0, import_react16.forwardRef)(
2308
2885
  ...props
2309
2886
  }
2310
2887
  ),
2311
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "fe-checkbox__control", "aria-hidden": "true" }),
2312
- label && labelPosition === "right" && /* @__PURE__ */ (0, import_jsx_runtime20.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 })
2313
2890
  ] })
2314
2891
  ] });
2315
2892
  }
@@ -2317,9 +2894,9 @@ var Checkbox = (0, import_react16.forwardRef)(
2317
2894
  Checkbox.displayName = "Checkbox";
2318
2895
 
2319
2896
  // packages/form-controls/src/controls/RadioButton/radio-button.tsx
2320
- var import_react17 = require("react");
2321
- var import_jsx_runtime21 = require("react/jsx-runtime");
2322
- var RadioButton = (0, import_react17.forwardRef)(
2897
+ var import_react22 = require("react");
2898
+ var import_jsx_runtime24 = require("react/jsx-runtime");
2899
+ var RadioButton = (0, import_react22.forwardRef)(
2323
2900
  function RadioButton2({
2324
2901
  label,
2325
2902
  labelPosition = "right",
@@ -2335,10 +2912,10 @@ var RadioButton = (0, import_react17.forwardRef)(
2335
2912
  disabled && "fe-radio-button--disabled",
2336
2913
  className
2337
2914
  ].filter(Boolean).join(" ");
2338
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("label", { className: classes, style, children: [
2339
- label && labelPosition === "top" && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "fe-radio-button__label", children: label }),
2340
- /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("span", { className: "fe-radio-button__content", children: [
2341
- /* @__PURE__ */ (0, import_jsx_runtime21.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)(
2342
2919
  "input",
2343
2920
  {
2344
2921
  ref,
@@ -2349,8 +2926,8 @@ var RadioButton = (0, import_react17.forwardRef)(
2349
2926
  ...props
2350
2927
  }
2351
2928
  ),
2352
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "fe-radio-button__control", "aria-hidden": "true" }),
2353
- label && labelPosition === "right" && /* @__PURE__ */ (0, import_jsx_runtime21.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 })
2354
2931
  ] })
2355
2932
  ] });
2356
2933
  }
@@ -2358,9 +2935,9 @@ var RadioButton = (0, import_react17.forwardRef)(
2358
2935
  RadioButton.displayName = "RadioButton";
2359
2936
 
2360
2937
  // packages/form-controls/src/controls/RadioGroup/radio-group.tsx
2361
- var import_react18 = require("react");
2362
- var import_jsx_runtime22 = require("react/jsx-runtime");
2363
- var RadioGroup = (0, import_react18.forwardRef)(
2938
+ var import_react23 = require("react");
2939
+ var import_jsx_runtime25 = require("react/jsx-runtime");
2940
+ var RadioGroup = (0, import_react23.forwardRef)(
2364
2941
  function RadioGroup2({
2365
2942
  label,
2366
2943
  labelPosition = "top",
@@ -2378,7 +2955,7 @@ var RadioGroup = (0, import_react18.forwardRef)(
2378
2955
  "aria-labelledby": ariaLabelledBy,
2379
2956
  ...props
2380
2957
  }, ref) {
2381
- const generatedId = (0, import_react18.useId)();
2958
+ const generatedId = (0, import_react23.useId)();
2382
2959
  const groupName = name ?? `fe-radio-group-${generatedId}`;
2383
2960
  const labelId = `${id ?? generatedId}-label`;
2384
2961
  const isControlled = value !== void 0;
@@ -2392,12 +2969,12 @@ var RadioGroup = (0, import_react18.forwardRef)(
2392
2969
  const handleChange = (option, event) => {
2393
2970
  if (event.target.checked) onChange?.(option.value, option, event);
2394
2971
  };
2395
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { ref, className: classes, ...props, children: [
2396
- label && labelPosition === "top" && /* @__PURE__ */ (0, import_jsx_runtime22.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: [
2397
2974
  label,
2398
- isRequired && /* @__PURE__ */ (0, import_jsx_runtime22.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: "*" })
2399
2976
  ] }),
2400
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2977
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2401
2978
  "div",
2402
2979
  {
2403
2980
  id,
@@ -2409,7 +2986,7 @@ var RadioGroup = (0, import_react18.forwardRef)(
2409
2986
  children: options.map((option) => {
2410
2987
  const optionDisabled = disabled || option.disabled;
2411
2988
  const optionValue = String(option.value);
2412
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
2989
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
2413
2990
  RadioButton,
2414
2991
  {
2415
2992
  name: groupName,
@@ -2426,9 +3003,9 @@ var RadioGroup = (0, import_react18.forwardRef)(
2426
3003
  })
2427
3004
  }
2428
3005
  ),
2429
- label && labelPosition === "right" && /* @__PURE__ */ (0, import_jsx_runtime22.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: [
2430
3007
  label,
2431
- isRequired && /* @__PURE__ */ (0, import_jsx_runtime22.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: "*" })
2432
3009
  ] })
2433
3010
  ] });
2434
3011
  }
@@ -2436,29 +3013,29 @@ var RadioGroup = (0, import_react18.forwardRef)(
2436
3013
  RadioGroup.displayName = "RadioGroup";
2437
3014
 
2438
3015
  // packages/expandable-section/src/index.tsx
2439
- var import_react19 = require("react");
2440
- var import_jsx_runtime23 = require("react/jsx-runtime");
3016
+ var import_react24 = require("react");
3017
+ var import_jsx_runtime26 = require("react/jsx-runtime");
2441
3018
  function ExpandableSection({ title, children, expanded, defaultExpanded = false, onExpandedChange, disabled, className, ...props }) {
2442
- const [internalExpanded, setInternalExpanded] = (0, import_react19.useState)(defaultExpanded);
3019
+ const [internalExpanded, setInternalExpanded] = (0, import_react24.useState)(defaultExpanded);
2443
3020
  const isExpanded = expanded ?? internalExpanded;
2444
- const id = (0, import_react19.useId)();
3021
+ const id = (0, import_react24.useId)();
2445
3022
  const toggle = () => {
2446
3023
  if (disabled) return;
2447
3024
  const next = !isExpanded;
2448
3025
  if (expanded === void 0) setInternalExpanded(next);
2449
3026
  onExpandedChange?.(next);
2450
3027
  };
2451
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("section", { className: ["fe-expandable-section", isExpanded && "fe-expandable-section--expanded", disabled && "fe-expandable-section--disabled", className].filter(Boolean).join(" "), ...props, children: [
2452
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("button", { className: "fe-expandable-section__trigger", type: "button", "aria-expanded": isExpanded, "aria-controls": id, disabled, onClick: toggle, children: [
2453
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: title }),
2454
- /* @__PURE__ */ (0, import_jsx_runtime23.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" })
2455
3032
  ] }),
2456
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { id, className: "fe-expandable-section__content", "aria-hidden": !isExpanded, children: /* @__PURE__ */ (0, import_jsx_runtime23.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 }) })
2457
3034
  ] });
2458
3035
  }
2459
3036
 
2460
3037
  // packages/loading/src/index.tsx
2461
- var import_jsx_runtime24 = require("react/jsx-runtime");
3038
+ var import_jsx_runtime27 = require("react/jsx-runtime");
2462
3039
  var sizes = {
2463
3040
  small: "16px",
2464
3041
  medium: "24px",
@@ -2471,15 +3048,15 @@ function Loading({ size = "medium", color = "#2878f0", label, className, style,
2471
3048
  "--fe-loading-color": color,
2472
3049
  ...style
2473
3050
  };
2474
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("span", { className: ["fe-loading", className].filter(Boolean).join(" "), style: loadingStyle, role: "status", ...props, children: [
2475
- /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "fe-loading__spinner", "aria-hidden": "true" }),
2476
- label && /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { className: "fe-loading__label", children: label }),
2477
- !label && /* @__PURE__ */ (0, import_jsx_runtime24.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" })
2478
3055
  ] });
2479
3056
  }
2480
3057
 
2481
3058
  // packages/skeleton/src/index.tsx
2482
- var import_jsx_runtime25 = require("react/jsx-runtime");
3059
+ var import_jsx_runtime28 = require("react/jsx-runtime");
2483
3060
  var pixels = (value) => typeof value === "number" ? `${value}px` : value;
2484
3061
  function SkeletonBase({ variant = "box", shape, width, height, count = 1, animated = true, className, style, ...props }) {
2485
3062
  const resolvedVariant = shape ?? variant;
@@ -2490,7 +3067,7 @@ function SkeletonBase({ variant = "box", shape, width, height, count = 1, animat
2490
3067
  "--fe-skeleton-height": resolvedHeight,
2491
3068
  ...style
2492
3069
  };
2493
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_jsx_runtime25.Fragment, { children: Array.from({ length: Math.max(1, count) }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime25.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)(
2494
3071
  "div",
2495
3072
  {
2496
3073
  className: ["fe-skeleton", `fe-skeleton--${resolvedVariant}`, animated && "fe-skeleton--animated", className].filter(Boolean).join(" "),
@@ -2502,16 +3079,16 @@ function SkeletonBase({ variant = "box", shape, width, height, count = 1, animat
2502
3079
  )) });
2503
3080
  }
2504
3081
  function SkeletonCircle({ size = 40, ...props }) {
2505
- return /* @__PURE__ */ (0, import_jsx_runtime25.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 });
2506
3083
  }
2507
3084
  function SkeletonSquare({ size = 80, ...props }) {
2508
- return /* @__PURE__ */ (0, import_jsx_runtime25.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 });
2509
3086
  }
2510
3087
  function SkeletonBox({ width = "100%", height = 80, ...props }) {
2511
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SkeletonBase, { variant: "box", width, height, ...props });
3088
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SkeletonBase, { variant: "box", width, height, ...props });
2512
3089
  }
2513
3090
  function SkeletonLine({ width = "100%", height = 12, ...props }) {
2514
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(SkeletonBase, { variant: "line", width, height, ...props });
3091
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(SkeletonBase, { variant: "line", width, height, ...props });
2515
3092
  }
2516
3093
  var Skeleton = Object.assign(SkeletonBase, {
2517
3094
  Circle: SkeletonCircle,
@@ -2521,9 +3098,9 @@ var Skeleton = Object.assign(SkeletonBase, {
2521
3098
  });
2522
3099
 
2523
3100
  // packages/modal/src/index.tsx
2524
- var import_react20 = require("react");
3101
+ var import_react25 = require("react");
2525
3102
  var import_react_dom3 = require("react-dom");
2526
- var import_jsx_runtime26 = require("react/jsx-runtime");
3103
+ var import_jsx_runtime29 = require("react/jsx-runtime");
2527
3104
  function Modal({
2528
3105
  open,
2529
3106
  onClose,
@@ -2534,60 +3111,87 @@ function Modal({
2534
3111
  actions = [],
2535
3112
  size = "medium",
2536
3113
  closeOnBackdropClick = true,
3114
+ closeOnEscape = true,
2537
3115
  closeButton = true,
2538
3116
  closeLabel = "Close modal",
3117
+ initialFocusRef,
3118
+ restoreFocus = true,
2539
3119
  className,
3120
+ "aria-label": ariaLabel,
3121
+ "aria-describedby": ariaDescribedBy,
2540
3122
  ...props
2541
3123
  }) {
2542
- const titleId = (0, import_react20.useId)();
2543
- const panelRef = (0, import_react20.useRef)(null);
2544
- (0, import_react20.useEffect)(() => {
2545
- if (!open) return;
2546
- const onKeyDown = (event) => {
2547
- if (event.key === "Escape") onClose();
2548
- };
2549
- document.addEventListener("keydown", onKeyDown);
2550
- panelRef.current?.focus();
2551
- return () => document.removeEventListener("keydown", onKeyDown);
2552
- }, [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
+ });
2553
3136
  if (!open || typeof document === "undefined") return null;
2554
3137
  const hasFooter = footer || actions.length > 0;
3138
+ const describedBy = [description ? descriptionId : void 0, ariaDescribedBy].filter(Boolean).join(" ") || void 0;
2555
3139
  return (0, import_react_dom3.createPortal)(
2556
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "fe-modal-backdrop", role: "presentation", onMouseDown: (event) => {
2557
- if (event.target === event.currentTarget && closeOnBackdropClick) onClose();
2558
- }, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
3140
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
2559
3141
  "div",
2560
3142
  {
2561
- ref: panelRef,
2562
- className: ["fe-modal", `fe-modal--${size}`, className].filter(Boolean).join(" "),
2563
- role: "dialog",
2564
- "aria-modal": "true",
2565
- "aria-labelledby": title ? titleId : void 0,
2566
- "aria-label": title ? void 0 : "Modal",
2567
- tabIndex: -1,
2568
- ...props,
2569
- children: [
2570
- (title || description || closeButton) && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("header", { className: "fe-modal__header", children: [
2571
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "fe-modal__heading", children: [
2572
- title && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("h2", { id: titleId, children: title }),
2573
- description && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("p", { children: description })
2574
- ] }),
2575
- closeButton && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Button, { hierarchy: "tertiary-gray", size: "32", iconOnly: true, icon: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(CloseIcon, {}), "aria-label": closeLabel, onClick: onClose })
2576
- ] }),
2577
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "fe-modal__body", children }),
2578
- hasFooter && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("footer", { className: "fe-modal__footer", children: [
2579
- footer && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "fe-modal__footer-content", children: footer }),
2580
- actions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "fe-modal__actions", children: actions.map(({ label, ...action }, index) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Button, { ...action, children: label }, index)) })
2581
- ] })
2582
- ]
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
+ )
2583
3187
  }
2584
- ) }),
3188
+ ),
2585
3189
  document.body
2586
3190
  );
2587
3191
  }
2588
3192
 
2589
3193
  // packages/progress/src/index.tsx
2590
- var import_jsx_runtime27 = require("react/jsx-runtime");
3194
+ var import_jsx_runtime30 = require("react/jsx-runtime");
2591
3195
  function ProgressBar({ value, max = 100, label, showValue = true, size = "medium", color = "#2878f0", className, style, "aria-label": ariaLabel, ...props }) {
2592
3196
  const indeterminate = value === null || value === void 0;
2593
3197
  const percentage = indeterminate ? 0 : Math.min(100, Math.max(0, Number(value) / Math.max(1, max) * 100));
@@ -2597,17 +3201,17 @@ function ProgressBar({ value, max = 100, label, showValue = true, size = "medium
2597
3201
  ...style
2598
3202
  };
2599
3203
  const visibleValue = `${Math.round(percentage)}%`;
2600
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: ["fe-progress", `fe-progress--${size}`, indeterminate && "fe-progress--indeterminate", className].filter(Boolean).join(" "), style: progressStyle, ...props, children: [
2601
- (label || !indeterminate && showValue) && /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "fe-progress__meta", children: [
2602
- label && /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "fe-progress__label", children: label }),
2603
- !indeterminate && showValue && /* @__PURE__ */ (0, import_jsx_runtime27.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 })
2604
3208
  ] }),
2605
- /* @__PURE__ */ (0, import_jsx_runtime27.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_runtime27.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" }) })
2606
3210
  ] });
2607
3211
  }
2608
3212
 
2609
3213
  // packages/chip/src/index.tsx
2610
- var import_jsx_runtime28 = require("react/jsx-runtime");
3214
+ var import_jsx_runtime31 = require("react/jsx-runtime");
2611
3215
  var statuses = ["default", "info", "success", "warning", "error", "neutral", "pending", "processing"];
2612
3216
  function Chip({ children, status = "default", color, variant = "subtle", dot = false, onRemove, removeLabel = "Remove", className, style, ...props }) {
2613
3217
  const usesCustomColor = Boolean(color);
@@ -2616,16 +3220,16 @@ function Chip({ children, status = "default", color, variant = "subtle", dot = f
2616
3220
  ...style
2617
3221
  };
2618
3222
  const resolvedStatus = statuses.includes(status) ? status : "default";
2619
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: ["fe-chip", `fe-chip--${variant}`, `fe-chip--${usesCustomColor ? "custom" : resolvedStatus}`, className].filter(Boolean).join(" "), style: chipStyle, ...props, children: [
2620
- dot && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "fe-chip__dot", "aria-hidden": "true" }),
2621
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "fe-chip__content", children }),
2622
- onRemove && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Button, { hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: /* @__PURE__ */ (0, import_jsx_runtime28.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" })
2623
3227
  ] });
2624
3228
  }
2625
3229
 
2626
3230
  // packages/message/src/index.tsx
2627
- var import_react21 = require("react");
2628
- var import_jsx_runtime29 = require("react/jsx-runtime");
3231
+ var import_react26 = require("react");
3232
+ var import_jsx_runtime32 = require("react/jsx-runtime");
2629
3233
  var messageId = 0;
2630
3234
  var entries = [];
2631
3235
  var listeners = /* @__PURE__ */ new Set();
@@ -2658,22 +3262,22 @@ var message = {
2658
3262
  };
2659
3263
  var icons = { success: "\u2713", info: "i", warning: "!", error: "\xD7" };
2660
3264
  function Message({ maxCount = 4, closeLabel = "Close notification", className, ...props }) {
2661
- const [visibleEntries, setVisibleEntries] = (0, import_react21.useState)(entries);
2662
- (0, import_react21.useEffect)(() => {
3265
+ const [visibleEntries, setVisibleEntries] = (0, import_react26.useState)(entries);
3266
+ (0, import_react26.useEffect)(() => {
2663
3267
  const listener = (nextEntries) => setVisibleEntries(nextEntries);
2664
3268
  listeners.add(listener);
2665
3269
  return () => {
2666
3270
  listeners.delete(listener);
2667
3271
  };
2668
3272
  }, []);
2669
- return /* @__PURE__ */ (0, import_jsx_runtime29.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_runtime29.jsxs)("div", { className: `fe-message fe-message--${entry.severity ?? "info"}`, role: entry.severity === "error" ? "alert" : "status", children: [
2670
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "fe-message__icon", "aria-hidden": "true", children: icons[entry.severity ?? "info"] }),
2671
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "fe-message__body", children: [
2672
- entry.title && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("strong", { className: "fe-message__title", children: entry.title }),
2673
- /* @__PURE__ */ (0, import_jsx_runtime29.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 })
2674
3278
  ] }),
2675
- entry.action && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "fe-message__action", children: entry.action }),
2676
- /* @__PURE__ */ (0, import_jsx_runtime29.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) })
2677
3281
  ] }, entry.id)) });
2678
3282
  }
2679
3283
  ((Message2) => {
@@ -2687,8 +3291,8 @@ function Message({ maxCount = 4, closeLabel = "Close notification", className, .
2687
3291
  })(Message || (Message = {}));
2688
3292
 
2689
3293
  // packages/snackbar/src/index.tsx
2690
- var import_react22 = require("react");
2691
- var import_jsx_runtime30 = require("react/jsx-runtime");
3294
+ var import_react27 = require("react");
3295
+ var import_jsx_runtime33 = require("react/jsx-runtime");
2692
3296
  function Snackbar({
2693
3297
  open,
2694
3298
  message: message2,
@@ -2702,12 +3306,12 @@ function Snackbar({
2702
3306
  }) {
2703
3307
  const vertical = anchorOrigin.vertical ?? "bottom";
2704
3308
  const horizontal = anchorOrigin.horizontal ?? "center";
2705
- (0, import_react22.useEffect)(() => {
3309
+ (0, import_react27.useEffect)(() => {
2706
3310
  if (!open || autoHideDuration === null) return void 0;
2707
3311
  const timer = window.setTimeout(() => onClose?.("timeout"), autoHideDuration);
2708
3312
  return () => window.clearTimeout(timer);
2709
3313
  }, [open, autoHideDuration, onClose]);
2710
- (0, import_react22.useEffect)(() => {
3314
+ (0, import_react27.useEffect)(() => {
2711
3315
  if (!open) return void 0;
2712
3316
  const onKeyDown = (event) => {
2713
3317
  if (event.key === "Escape") onClose?.("escapeKeyDown");
@@ -2716,16 +3320,16 @@ function Snackbar({
2716
3320
  return () => window.removeEventListener("keydown", onKeyDown);
2717
3321
  }, [open, onClose]);
2718
3322
  if (!open) return null;
2719
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: ["fe-snackbar", `fe-snackbar--${vertical}`, `fe-snackbar--${horizontal}`, className].filter(Boolean).join(" "), ...props, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "fe-snackbar__content", role: "status", "aria-live": "polite", children: [
2720
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "fe-snackbar__message", children: message2 }),
2721
- action && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "fe-snackbar__action", children: action }),
2722
- onClose && /* @__PURE__ */ (0, import_jsx_runtime30.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") })
2723
3327
  ] }) });
2724
3328
  }
2725
3329
 
2726
3330
  // packages/avatar/src/index.tsx
2727
- var import_react23 = require("react");
2728
- var import_jsx_runtime31 = require("react/jsx-runtime");
3331
+ var import_react28 = require("react");
3332
+ var import_jsx_runtime34 = require("react/jsx-runtime");
2729
3333
  var FALLBACK_AVATARS = [
2730
3334
  {
2731
3335
  background: "#E0E7FF",
@@ -3058,7 +3662,7 @@ function AvatarFallbackIcon({ avatar }) {
3058
3662
  shirt,
3059
3663
  skin
3060
3664
  } = avatar;
3061
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
3665
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
3062
3666
  "svg",
3063
3667
  {
3064
3668
  className: "fe-avatar__fallback-icon",
@@ -3066,15 +3670,15 @@ function AvatarFallbackIcon({ avatar }) {
3066
3670
  focusable: "false",
3067
3671
  "aria-hidden": "true",
3068
3672
  children: [
3069
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("rect", { width: "24", height: "24", fill: background }),
3070
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
3673
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("rect", { width: "24", height: "24", fill: background }),
3674
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
3071
3675
  "path",
3072
3676
  {
3073
3677
  d: "M3 24c.52-3.79 3.58-6.25 9-6.25S20.48 20.21 21 24",
3074
3678
  fill: shirt
3075
3679
  }
3076
3680
  ),
3077
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
3681
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
3078
3682
  "path",
3079
3683
  {
3080
3684
  d: "M8.1 17.65h7.8l1.05 2.05H7.05l1.05-2.05Z",
@@ -3082,38 +3686,38 @@ function AvatarFallbackIcon({ avatar }) {
3082
3686
  opacity: ".72"
3083
3687
  }
3084
3688
  ),
3085
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("circle", { cx: "12", cy: "10.25", r: "5.25", fill: skin }),
3086
- hairStyle === 0 && /* @__PURE__ */ (0, import_jsx_runtime31.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)(
3087
3691
  "path",
3088
3692
  {
3089
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",
3090
3694
  fill: hair
3091
3695
  }
3092
3696
  ),
3093
- hairStyle === 1 && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
3697
+ hairStyle === 1 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
3094
3698
  "path",
3095
3699
  {
3096
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",
3097
3701
  fill: hair
3098
3702
  }
3099
3703
  ),
3100
- hairStyle === 2 && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
3704
+ hairStyle === 2 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
3101
3705
  "path",
3102
3706
  {
3103
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",
3104
3708
  fill: hair
3105
3709
  }
3106
3710
  ),
3107
- hairStyle === 3 && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
3711
+ hairStyle === 3 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
3108
3712
  "path",
3109
3713
  {
3110
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",
3111
3715
  fill: hair
3112
3716
  }
3113
3717
  ),
3114
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("circle", { cx: "10.05", cy: "10.65", r: ".48", fill: "#3B2924" }),
3115
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("circle", { cx: "13.95", cy: "10.65", r: ".48", fill: "#3B2924" }),
3116
- expression === 0 && /* @__PURE__ */ (0, import_jsx_runtime31.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)(
3117
3721
  "path",
3118
3722
  {
3119
3723
  d: "M10.25 13.2c1.08.66 2.42.66 3.5 0",
@@ -3123,7 +3727,7 @@ function AvatarFallbackIcon({ avatar }) {
3123
3727
  strokeLinecap: "round"
3124
3728
  }
3125
3729
  ),
3126
- expression === 1 && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
3730
+ expression === 1 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
3127
3731
  "path",
3128
3732
  {
3129
3733
  d: "M10.5 13.2h3",
@@ -3133,7 +3737,7 @@ function AvatarFallbackIcon({ avatar }) {
3133
3737
  strokeLinecap: "round"
3134
3738
  }
3135
3739
  ),
3136
- expression === 2 && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
3740
+ expression === 2 && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
3137
3741
  "path",
3138
3742
  {
3139
3743
  d: "M10.6 13.38c.84-.44 1.96-.44 2.8 0",
@@ -3143,11 +3747,11 @@ function AvatarFallbackIcon({ avatar }) {
3143
3747
  strokeLinecap: "round"
3144
3748
  }
3145
3749
  ),
3146
- expression === 3 && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("circle", { cx: "12", cy: "13.2", r: ".82", fill: "#B95A5A" }),
3147
- glasses && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("g", { fill: "none", stroke: "#3C4355", strokeWidth: ".65", children: [
3148
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("circle", { cx: "10", cy: "10.55", r: "1.45" }),
3149
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("circle", { cx: "14", cy: "10.55", r: "1.45" }),
3150
- /* @__PURE__ */ (0, import_jsx_runtime31.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" })
3151
3755
  ] })
3152
3756
  ]
3153
3757
  }
@@ -3166,10 +3770,10 @@ function Avatar({
3166
3770
  "aria-label": ariaLabel,
3167
3771
  ...props
3168
3772
  }) {
3169
- const [generatedFallbackIndex] = (0, import_react23.useState)(
3773
+ const [generatedFallbackIndex] = (0, import_react28.useState)(
3170
3774
  () => Math.floor(Math.random() * FALLBACK_AVATARS.length)
3171
3775
  );
3172
- const [failedImageSrc, setFailedImageSrc] = (0, import_react23.useState)();
3776
+ const [failedImageSrc, setFailedImageSrc] = (0, import_react28.useState)();
3173
3777
  const imageSrc = src?.trim();
3174
3778
  const trimmedContent = content?.trim() ?? "";
3175
3779
  const showImage = Boolean(imageSrc && failedImageSrc !== imageSrc);
@@ -3181,7 +3785,7 @@ function Avatar({
3181
3785
  ...style
3182
3786
  };
3183
3787
  const fallbackLabel = (alt ?? trimmedContent) || "Avatar";
3184
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
3788
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
3185
3789
  "span",
3186
3790
  {
3187
3791
  className: ["fe-avatar", `fe-avatar--${shape}`, className].filter(Boolean).join(" "),
@@ -3190,7 +3794,7 @@ function Avatar({
3190
3794
  "aria-label": showImage ? ariaLabel : ariaLabel ?? fallbackLabel,
3191
3795
  ...props,
3192
3796
  children: [
3193
- showImage && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
3797
+ showImage && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
3194
3798
  "img",
3195
3799
  {
3196
3800
  className: "fe-avatar__image",
@@ -3199,8 +3803,8 @@ function Avatar({
3199
3803
  onError: () => setFailedImageSrc(imageSrc)
3200
3804
  }
3201
3805
  ),
3202
- !showImage && initials && /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "fe-avatar__initials", "aria-hidden": "true", children: initials }),
3203
- !showImage && !initials && /* @__PURE__ */ (0, import_jsx_runtime31.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 })
3204
3808
  ]
3205
3809
  }
3206
3810
  );
@@ -3213,7 +3817,7 @@ function AvatarGroup({
3213
3817
  role,
3214
3818
  ...props
3215
3819
  }) {
3216
- const avatars = import_react23.Children.toArray(children).filter(import_react23.isValidElement);
3820
+ const avatars = import_react28.Children.toArray(children).filter(import_react28.isValidElement);
3217
3821
  const hasMaxCount = typeof maxCount === "number" && Number.isFinite(maxCount) && maxCount > 0;
3218
3822
  const itemLimit = hasMaxCount ? Math.floor(maxCount) : avatars.length;
3219
3823
  const hasOverflow = avatars.length > itemLimit;
@@ -3226,7 +3830,7 @@ function AvatarGroup({
3226
3830
  "--fe-avatar-font-size": resolveFontSize(firstAvatarSize)
3227
3831
  };
3228
3832
  const singleContent = avatars.length === 1 ? avatars[0]?.props.content?.trim() ?? "" : "";
3229
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
3833
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
3230
3834
  "div",
3231
3835
  {
3232
3836
  className: ["fe-avatar-group", className].filter(Boolean).join(" "),
@@ -3234,8 +3838,8 @@ function AvatarGroup({
3234
3838
  role: role ?? "group",
3235
3839
  ...props,
3236
3840
  children: [
3237
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { className: "fe-avatar-group__items", children: [
3238
- visibleAvatars.map((avatar, index) => /* @__PURE__ */ (0, import_jsx_runtime31.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)(
3239
3843
  "span",
3240
3844
  {
3241
3845
  className: "fe-avatar-group__item",
@@ -3244,7 +3848,7 @@ function AvatarGroup({
3244
3848
  },
3245
3849
  avatar.key ?? index
3246
3850
  )),
3247
- hasOverflow && /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(
3851
+ hasOverflow && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
3248
3852
  "span",
3249
3853
  {
3250
3854
  className: "fe-avatar-group__more",
@@ -3258,11 +3862,633 @@ function AvatarGroup({
3258
3862
  }
3259
3863
  )
3260
3864
  ] }),
3261
- singleContent && /* @__PURE__ */ (0, import_jsx_runtime31.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 })
3262
3866
  ]
3263
3867
  }
3264
3868
  );
3265
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
+ }
3266
4492
  // Annotate the CommonJS export names for ESM import in node:
3267
4493
  0 && (module.exports = {
3268
4494
  Avatar,
@@ -3277,14 +4503,25 @@ function AvatarGroup({
3277
4503
  CurrencyInput,
3278
4504
  DateTimePicker,
3279
4505
  Drawer,
4506
+ DrawerWidths,
4507
+ EmailInput,
3280
4508
  ExpandableSection,
4509
+ EyeIcon,
4510
+ EyeOffIcon,
4511
+ FILE_UPLOAD_ACCEPTS,
4512
+ FilePreview,
4513
+ FileUpload,
3281
4514
  Loading,
4515
+ MailboxIcon,
3282
4516
  Message,
3283
4517
  Modal,
3284
4518
  MoreHorizontalIcon,
3285
4519
  MoreVerticalIcon,
3286
4520
  NumberInput,
3287
4521
  Pagination,
4522
+ PasswordInput,
4523
+ PhoneIcon,
4524
+ PhoneNumberInput,
3288
4525
  PlusIcon,
3289
4526
  ProgressBar,
3290
4527
  RadioButton,
@@ -3316,7 +4553,9 @@ function AvatarGroup({
3316
4553
  chevron_right,
3317
4554
  chevron_up,
3318
4555
  copy,
4556
+ formatFileSize,
3319
4557
  formatNumber,
4558
+ getFilePreviewKind,
3320
4559
  getIconSize,
3321
4560
  key,
3322
4561
  lock,
@@ -3324,9 +4563,13 @@ function AvatarGroup({
3324
4563
  log_out,
3325
4564
  message,
3326
4565
  minus_square,
4566
+ normalizePhoneNumber,
3327
4567
  plus,
3328
4568
  plus_square,
3329
4569
  search,
3330
4570
  trash,
4571
+ validateEmail,
4572
+ validatePassword,
4573
+ validatePhoneNumber,
3331
4574
  x_close
3332
4575
  });