@dragunio/fe-libs 0.1.7 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -2,8 +2,12 @@ import {
2
2
  ChevronDownIcon,
3
3
  ChevronUpIcon,
4
4
  CloseIcon,
5
+ EyeIcon,
6
+ EyeOffIcon,
7
+ MailboxIcon,
5
8
  MoreHorizontalIcon,
6
9
  MoreVerticalIcon,
10
+ PhoneIcon,
7
11
  PlusIcon,
8
12
  SearchIcon,
9
13
  arrow_left,
@@ -23,7 +27,7 @@ import {
23
27
  search,
24
28
  trash,
25
29
  x_close
26
- } from "./chunk-GT4546FD.mjs";
30
+ } from "./chunk-BAZJ5UJ5.mjs";
27
31
 
28
32
  // packages/button/src/index.tsx
29
33
  import { forwardRef } from "react";
@@ -107,9 +111,23 @@ function ButtonBar({
107
111
  const rootRef = useRef(null);
108
112
  const moreMenuId = useId();
109
113
  const visibleCount = Math.max(0, Math.floor(maxVisible));
110
- const visibleActions = actions.slice(0, visibleCount);
111
- const overflowActions = actions.slice(visibleCount);
112
- const hasOverflow = overflowActions.length > 0;
114
+ const actionCount = actions.filter(
115
+ (item) => item !== "|"
116
+ ).length;
117
+ const hasOverflow = actionCount > visibleCount;
118
+ let visibleActionEndIndex = actions.length;
119
+ if (hasOverflow) {
120
+ visibleActionEndIndex = 0;
121
+ let renderedActionCount = 0;
122
+ while (visibleActionEndIndex < actions.length && renderedActionCount < visibleCount) {
123
+ if (actions[visibleActionEndIndex] !== "|") renderedActionCount += 1;
124
+ visibleActionEndIndex += 1;
125
+ }
126
+ }
127
+ const visibleActions = actions.slice(0, visibleActionEndIndex).filter((item) => item !== "|");
128
+ const overflowItems = actions.slice(visibleActionEndIndex).filter(
129
+ (item, index, items) => item !== "|" || items.slice(0, index).some((candidate) => candidate !== "|") && items.slice(index + 1).some((candidate) => candidate !== "|") && items[index - 1] !== "|"
130
+ );
113
131
  const {
114
132
  onClick: onMoreClick,
115
133
  disabled: moreDisabled,
@@ -133,18 +151,20 @@ function ButtonBar({
133
151
  document.removeEventListener("keydown", onKeyDown);
134
152
  };
135
153
  }, [isMoreOpen]);
136
- const renderAction = (action, shouldCloseMore = false) => {
137
- const { id, onClick, disabled, ...buttonProps } = action;
154
+ const renderAction = (action, isOverflowAction = false) => {
155
+ const { id, className: className2, onClick, disabled, prefix, ...buttonProps } = action;
138
156
  return /* @__PURE__ */ createElement(
139
157
  Button,
140
158
  {
141
159
  ...buttonProps,
160
+ className: [className2, isOverflowAction && "fe-button-bar__menu-action"].filter(Boolean).join(" ") || void 0,
142
161
  disabled,
143
162
  key: id,
144
163
  onClick: (event) => {
145
164
  onClick?.(event);
146
- if (shouldCloseMore && !disabled) setIsMoreOpen(false);
147
- }
165
+ if (isOverflowAction && !disabled) setIsMoreOpen(false);
166
+ },
167
+ prefix: isOverflowAction ? /* @__PURE__ */ jsx2("span", { className: "fe-button-bar__menu-icon", children: prefix }) : prefix
148
168
  }
149
169
  );
150
170
  };
@@ -182,7 +202,17 @@ function ButtonBar({
182
202
  className: "fe-button-bar__menu",
183
203
  id: moreMenuId,
184
204
  role: "group",
185
- children: overflowActions.map((action) => renderAction(action, true))
205
+ children: overflowItems.map(
206
+ (item, index) => item === "|" ? /* @__PURE__ */ jsx2(
207
+ "div",
208
+ {
209
+ "aria-orientation": "horizontal",
210
+ className: "fe-button-bar__menu-divider",
211
+ role: "separator"
212
+ },
213
+ `divider-${index}`
214
+ ) : renderAction(item, true)
215
+ )
186
216
  }
187
217
  )
188
218
  ] })
@@ -191,21 +221,223 @@ function ButtonBar({
191
221
  );
192
222
  }
193
223
 
224
+ // packages/tabs/src/index.tsx
225
+ import {
226
+ forwardRef as forwardRef2,
227
+ useCallback,
228
+ useEffect as useEffect2,
229
+ useId as useId2,
230
+ useRef as useRef2,
231
+ useState as useState2
232
+ } from "react";
233
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
234
+ var hasPanel = (item) => Object.prototype.hasOwnProperty.call(item, "content");
235
+ function findSelectableTab(items, value) {
236
+ return items.find((item) => item.id === value && !item.disabled) ?? items.find((item) => !item.disabled);
237
+ }
238
+ function scrollBehavior() {
239
+ return typeof window !== "undefined" && window.matchMedia?.("(prefers-reduced-motion: reduce)").matches ? "auto" : "smooth";
240
+ }
241
+ var Tabs = forwardRef2(function Tabs2({
242
+ items,
243
+ value,
244
+ defaultValue,
245
+ onChange,
246
+ variant = "tab",
247
+ scrollButtons = "auto",
248
+ previousScrollLabel = "Scroll tabs backward",
249
+ nextScrollLabel = "Scroll tabs forward",
250
+ className,
251
+ "aria-label": ariaLabel = "Tabs",
252
+ "aria-labelledby": ariaLabelledBy,
253
+ ...props
254
+ }, ref) {
255
+ const generatedId = useId2();
256
+ const listRef = useRef2(null);
257
+ const tabRefs = useRef2(/* @__PURE__ */ new Map());
258
+ const [uncontrolledValue, setUncontrolledValue] = useState2(
259
+ () => findSelectableTab(items, defaultValue)?.id
260
+ );
261
+ const [scrollState, setScrollState] = useState2({
262
+ hasOverflow: false,
263
+ canScrollBackward: false,
264
+ canScrollForward: false
265
+ });
266
+ const activeTab = findSelectableTab(items, value ?? uncontrolledValue);
267
+ const activeIndex = activeTab ? items.findIndex((item) => item.id === activeTab.id) : -1;
268
+ useEffect2(() => {
269
+ if (value === void 0 && activeTab?.id !== uncontrolledValue) {
270
+ setUncontrolledValue(activeTab?.id);
271
+ }
272
+ }, [activeTab?.id, uncontrolledValue, value]);
273
+ const updateScrollState = useCallback(() => {
274
+ const list = listRef.current;
275
+ if (!list) return;
276
+ const maxScroll = Math.max(0, list.scrollWidth - list.clientWidth);
277
+ setScrollState({
278
+ hasOverflow: maxScroll > 1,
279
+ canScrollBackward: list.scrollLeft > 1,
280
+ canScrollForward: list.scrollLeft < maxScroll - 1
281
+ });
282
+ }, []);
283
+ useEffect2(() => {
284
+ const list = listRef.current;
285
+ if (!list) return;
286
+ updateScrollState();
287
+ list.addEventListener("scroll", updateScrollState, { passive: true });
288
+ const observer = typeof ResizeObserver === "undefined" ? void 0 : new ResizeObserver(updateScrollState);
289
+ observer?.observe(list);
290
+ window.addEventListener("resize", updateScrollState);
291
+ return () => {
292
+ list.removeEventListener("scroll", updateScrollState);
293
+ observer?.disconnect();
294
+ window.removeEventListener("resize", updateScrollState);
295
+ };
296
+ }, [items, updateScrollState]);
297
+ useEffect2(() => {
298
+ const tab = activeTab ? tabRefs.current.get(activeTab.id) : void 0;
299
+ tab?.scrollIntoView?.({
300
+ behavior: scrollBehavior(),
301
+ block: "nearest",
302
+ inline: "nearest"
303
+ });
304
+ }, [activeTab?.id]);
305
+ const selectTab = (item, event) => {
306
+ if (item.disabled || item.id === activeTab?.id) return;
307
+ if (value === void 0) setUncontrolledValue(item.id);
308
+ onChange?.(item.id, item, event);
309
+ };
310
+ const selectFromKeyboard = (item, event) => {
311
+ const enabledItems = items.filter((candidate) => !candidate.disabled);
312
+ const currentIndex = enabledItems.findIndex(
313
+ (candidate) => candidate.id === item.id
314
+ );
315
+ if (currentIndex === -1) return;
316
+ let nextIndex;
317
+ if (event.key === "ArrowRight" || event.key === "ArrowDown") {
318
+ nextIndex = (currentIndex + 1) % enabledItems.length;
319
+ } else if (event.key === "ArrowLeft" || event.key === "ArrowUp") {
320
+ nextIndex = (currentIndex - 1 + enabledItems.length) % enabledItems.length;
321
+ } else if (event.key === "Home") {
322
+ nextIndex = 0;
323
+ } else if (event.key === "End") {
324
+ nextIndex = enabledItems.length - 1;
325
+ }
326
+ if (nextIndex === void 0) return;
327
+ event.preventDefault();
328
+ const nextItem = enabledItems[nextIndex];
329
+ if (!nextItem) return;
330
+ tabRefs.current.get(nextItem.id)?.focus();
331
+ selectTab(nextItem, event);
332
+ };
333
+ const scrollTabs = (direction) => {
334
+ const list = listRef.current;
335
+ if (!list) return;
336
+ list.scrollBy({
337
+ left: direction * Math.max(160, Math.round(list.clientWidth * 0.75)),
338
+ behavior: scrollBehavior()
339
+ });
340
+ };
341
+ const showScrollButtons = scrollButtons === "always" || scrollButtons === "auto" && scrollState.hasOverflow;
342
+ const classes = ["fe-tabs", `fe-tabs--${variant}`, className].filter(Boolean).join(" ");
343
+ return /* @__PURE__ */ jsxs3("div", { ...props, className: classes, ref, children: [
344
+ /* @__PURE__ */ jsxs3("div", { className: "fe-tabs__navigation", children: [
345
+ showScrollButtons && /* @__PURE__ */ jsx3(
346
+ Button,
347
+ {
348
+ "aria-label": previousScrollLabel,
349
+ className: "fe-tabs__scroll-button",
350
+ disabled: !scrollState.canScrollBackward,
351
+ hierarchy: "tertiary-gray",
352
+ icon: /* @__PURE__ */ jsx3(chevron_left, { size: 18 }),
353
+ iconOnly: true,
354
+ onClick: () => scrollTabs(-1),
355
+ size: "32"
356
+ }
357
+ ),
358
+ /* @__PURE__ */ jsx3("div", { className: "fe-tabs__scroller", ref: listRef, children: /* @__PURE__ */ jsx3(
359
+ "div",
360
+ {
361
+ "aria-label": ariaLabelledBy ? void 0 : ariaLabel,
362
+ "aria-labelledby": ariaLabelledBy,
363
+ "aria-orientation": "horizontal",
364
+ className: "fe-tabs__list",
365
+ role: "tablist",
366
+ children: items.map((item, index) => {
367
+ const selected = item.id === activeTab?.id;
368
+ const panelId = `${generatedId}-panel-${index}`;
369
+ return /* @__PURE__ */ jsx3(
370
+ "button",
371
+ {
372
+ "aria-controls": hasPanel(item) ? panelId : void 0,
373
+ "aria-selected": selected,
374
+ className: "fe-tabs__tab",
375
+ disabled: item.disabled,
376
+ id: `${generatedId}-tab-${index}`,
377
+ onClick: (event) => selectTab(item, event),
378
+ onKeyDown: (event) => selectFromKeyboard(item, event),
379
+ ref: (node) => {
380
+ if (node) tabRefs.current.set(item.id, node);
381
+ else tabRefs.current.delete(item.id);
382
+ },
383
+ role: "tab",
384
+ tabIndex: selected ? 0 : -1,
385
+ type: "button",
386
+ children: item.label
387
+ },
388
+ item.id
389
+ );
390
+ })
391
+ }
392
+ ) }),
393
+ showScrollButtons && /* @__PURE__ */ jsx3(
394
+ Button,
395
+ {
396
+ "aria-label": nextScrollLabel,
397
+ className: "fe-tabs__scroll-button",
398
+ disabled: !scrollState.canScrollForward,
399
+ hierarchy: "tertiary-gray",
400
+ icon: /* @__PURE__ */ jsx3(chevron_right, { size: 18 }),
401
+ iconOnly: true,
402
+ onClick: () => scrollTabs(1),
403
+ size: "32"
404
+ }
405
+ )
406
+ ] }),
407
+ items.map(
408
+ (item, index) => hasPanel(item) ? /* @__PURE__ */ jsx3(
409
+ "div",
410
+ {
411
+ "aria-labelledby": `${generatedId}-tab-${index}`,
412
+ className: "fe-tabs__panel",
413
+ hidden: item.id !== activeTab?.id,
414
+ id: `${generatedId}-panel-${index}`,
415
+ role: "tabpanel",
416
+ tabIndex: 0,
417
+ children: item.content
418
+ },
419
+ item.id
420
+ ) : null
421
+ )
422
+ ] });
423
+ });
424
+ Tabs.displayName = "Tabs";
425
+
194
426
  // packages/table/src/index.tsx
195
427
  import {
196
428
  createContext,
197
429
  isValidElement,
198
- useCallback,
430
+ useCallback as useCallback2,
199
431
  useContext,
200
- useEffect as useEffect2,
432
+ useEffect as useEffect3,
201
433
  useMemo as useMemo2,
202
- useRef as useRef2,
203
- useState as useState3
434
+ useRef as useRef3,
435
+ useState as useState4
204
436
  } from "react";
205
437
 
206
438
  // packages/pagination/src/index.tsx
207
- import { useMemo, useState as useState2 } from "react";
208
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
439
+ import { useMemo, useState as useState3 } from "react";
440
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
209
441
  var clamp = (value, min, max) => Math.min(Math.max(value, min), max);
210
442
  var range = (start, end) => Array.from({ length: Math.max(0, end - start + 1) }, (_, index) => start + index);
211
443
  function getItems(totalPages, page, siblingCount, boundaryCount) {
@@ -237,7 +469,7 @@ function Pagination({
237
469
  ...props
238
470
  }) {
239
471
  const safeTotalPages = Math.max(1, Math.floor(totalPages));
240
- const [uncontrolledPage, setUncontrolledPage] = useState2(() => clamp(defaultPage, 1, safeTotalPages));
472
+ const [uncontrolledPage, setUncontrolledPage] = useState3(() => clamp(defaultPage, 1, safeTotalPages));
241
473
  const currentPage = clamp(page ?? uncontrolledPage, 1, safeTotalPages);
242
474
  const items = useMemo(
243
475
  () => getItems(safeTotalPages, currentPage, Math.max(0, siblingCount), Math.max(0, boundaryCount)),
@@ -248,9 +480,9 @@ function Pagination({
248
480
  if (page === void 0) setUncontrolledPage(resolvedPage);
249
481
  if (resolvedPage !== currentPage) onPageChange?.(resolvedPage);
250
482
  };
251
- return /* @__PURE__ */ jsxs3("nav", { className: ["fe-pagination", className].filter(Boolean).join(" "), "aria-label": "Pagination", ...props, children: [
252
- /* @__PURE__ */ jsx3(Button, { className: "fe-pagination__button fe-pagination__button--control", hierarchy: "secondary-gray", size: "40", iconOnly: true, icon: "\u2039", "aria-label": previousLabel, disabled: disabled || currentPage === 1, onClick: () => selectPage(currentPage - 1) }),
253
- items.map((item, index) => item === "start-ellipsis" || item === "end-ellipsis" ? /* @__PURE__ */ jsx3("span", { className: "fe-pagination__ellipsis", "aria-hidden": "true", children: "\u2026" }, `${item}-${index}`) : /* @__PURE__ */ jsx3(
483
+ return /* @__PURE__ */ jsxs4("nav", { className: ["fe-pagination", className].filter(Boolean).join(" "), "aria-label": "Pagination", ...props, children: [
484
+ /* @__PURE__ */ jsx4(Button, { className: "fe-pagination__button fe-pagination__button--control", hierarchy: "secondary-gray", size: "40", iconOnly: true, icon: "\u2039", "aria-label": previousLabel, disabled: disabled || currentPage === 1, onClick: () => selectPage(currentPage - 1) }),
485
+ items.map((item, index) => item === "start-ellipsis" || item === "end-ellipsis" ? /* @__PURE__ */ jsx4("span", { className: "fe-pagination__ellipsis", "aria-hidden": "true", children: "\u2026" }, `${item}-${index}`) : /* @__PURE__ */ jsx4(
254
486
  Button,
255
487
  {
256
488
  className: "fe-pagination__button",
@@ -264,12 +496,12 @@ function Pagination({
264
496
  },
265
497
  item
266
498
  )),
267
- /* @__PURE__ */ jsx3(Button, { className: "fe-pagination__button fe-pagination__button--control", hierarchy: "secondary-gray", size: "40", iconOnly: true, icon: "\u203A", "aria-label": nextLabel, disabled: disabled || currentPage === safeTotalPages, onClick: () => selectPage(currentPage + 1) })
499
+ /* @__PURE__ */ jsx4(Button, { className: "fe-pagination__button fe-pagination__button--control", hierarchy: "secondary-gray", size: "40", iconOnly: true, icon: "\u203A", "aria-label": nextLabel, disabled: disabled || currentPage === safeTotalPages, onClick: () => selectPage(currentPage + 1) })
268
500
  ] });
269
501
  }
270
502
 
271
503
  // packages/table/src/index.tsx
272
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
504
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
273
505
  var TableContext = createContext({ striped: false });
274
506
  var MIN_COLUMN_WIDTH = 96;
275
507
  var MAX_COLUMN_WIDTH = 1200;
@@ -319,33 +551,33 @@ function DataTable({
319
551
  () => getInitialColumnSizes(headers, data, defaultColumnSizes, safeMinWidth),
320
552
  [headers, data, defaultColumnSizes, safeMinWidth]
321
553
  );
322
- const [uncontrolledSizes, setUncontrolledSizes] = useState3(generatedSizes);
554
+ const [uncontrolledSizes, setUncontrolledSizes] = useState4(generatedSizes);
323
555
  const shouldPaginate = pagination ?? pageSize !== void 0;
324
556
  const safePageSize = Math.max(1, Math.floor(pageSize ?? 10));
325
557
  const totalPages = Math.max(1, Math.ceil(data.length / safePageSize));
326
- const [uncontrolledPage, setUncontrolledPage] = useState3(() => Math.min(Math.max(1, defaultPage), totalPages));
558
+ const [uncontrolledPage, setUncontrolledPage] = useState4(() => Math.min(Math.max(1, defaultPage), totalPages));
327
559
  const currentPage = Math.min(Math.max(1, page ?? uncontrolledPage), totalPages);
328
560
  const pagedData = shouldPaginate ? data.slice((currentPage - 1) * safePageSize, currentPage * safePageSize) : data;
329
- const resizeState = useRef2();
330
- const [isResizing, setIsResizing] = useState3(false);
561
+ const resizeState = useRef3();
562
+ const [isResizing, setIsResizing] = useState4(false);
331
563
  const sizes2 = columnSizes ? getInitialColumnSizes(headers, data, columnSizes, safeMinWidth).map((size) => Math.max(safeMinWidth, size)) : uncontrolledSizes.map((size) => Math.max(safeMinWidth, size));
332
- useEffect2(() => {
564
+ useEffect3(() => {
333
565
  if (columnSizes) return;
334
566
  setUncontrolledSizes((currentSizes) => {
335
567
  const nextSizes = generatedSizes.map((generatedSize, index) => currentSizes[index] ?? generatedSize);
336
568
  return sameSizes(currentSizes, nextSizes) ? currentSizes : nextSizes;
337
569
  });
338
570
  }, [columnSizes, generatedSizes]);
339
- useEffect2(() => {
571
+ useEffect3(() => {
340
572
  if (page === void 0 && uncontrolledPage > totalPages) setUncontrolledPage(totalPages);
341
573
  }, [page, totalPages, uncontrolledPage]);
342
- const updateColumnSize = useCallback((columnIndex, nextSize) => {
574
+ const updateColumnSize = useCallback2((columnIndex, nextSize) => {
343
575
  const clampedSize = Math.min(MAX_COLUMN_WIDTH, Math.max(safeMinWidth, Math.round(nextSize)));
344
576
  const nextSizes = sizes2.map((size, index) => index === columnIndex ? clampedSize : size);
345
577
  if (!columnSizes) setUncontrolledSizes(nextSizes);
346
578
  onColumnResize?.(nextSizes, columnIndex);
347
579
  }, [columnSizes, onColumnResize, safeMinWidth, sizes2]);
348
- useEffect2(() => {
580
+ useEffect3(() => {
349
581
  const onPointerMove = (event) => {
350
582
  const activeResize = resizeState.current;
351
583
  if (!activeResize) return;
@@ -369,14 +601,14 @@ function DataTable({
369
601
  if (nextPage !== currentPage) onPageChange?.(nextPage);
370
602
  };
371
603
  const resolvedPaginationPosition = paginationPosition === "middle-bottom" ? "bottom-center" : paginationPosition;
372
- const paginationControl = shouldPaginate && totalPages > 1 ? /* @__PURE__ */ jsx4("div", { className: `fe-table__pagination fe-table__pagination--${resolvedPaginationPosition}`, children: /* @__PURE__ */ jsx4(Pagination, { page: currentPage, totalPages, onPageChange: changePage }) }) : null;
373
- return /* @__PURE__ */ jsxs4("div", { className: "fe-table", "data-resizing": isResizing || void 0, children: [
604
+ const paginationControl = shouldPaginate && totalPages > 1 ? /* @__PURE__ */ jsx5("div", { className: `fe-table__pagination fe-table__pagination--${resolvedPaginationPosition}`, children: /* @__PURE__ */ jsx5(Pagination, { page: currentPage, totalPages, onPageChange: changePage }) }) : null;
605
+ return /* @__PURE__ */ jsxs5("div", { className: "fe-table", "data-resizing": isResizing || void 0, children: [
374
606
  resolvedPaginationPosition === "top-right" && paginationControl,
375
- /* @__PURE__ */ jsxs4("table", { className: ["fe-table__table", className].filter(Boolean).join(" "), "data-fe-table": true, "data-striped": striped || void 0, ...props, children: [
376
- /* @__PURE__ */ jsx4("colgroup", { children: sizes2.map((size, index) => /* @__PURE__ */ jsx4("col", { style: { width: `${size}px` } }, index)) }),
377
- /* @__PURE__ */ jsx4("thead", { children: /* @__PURE__ */ jsx4("tr", { children: Array.from({ length: columnCount }, (_, columnIndex) => /* @__PURE__ */ jsxs4("th", { scope: "col", children: [
378
- /* @__PURE__ */ jsx4("span", { className: "fe-table__header-content", children: headers[columnIndex] ?? `Column ${columnIndex + 1}` }),
379
- /* @__PURE__ */ jsx4(
607
+ /* @__PURE__ */ jsxs5("table", { className: ["fe-table__table", className].filter(Boolean).join(" "), "data-fe-table": true, "data-striped": striped || void 0, ...props, children: [
608
+ /* @__PURE__ */ jsx5("colgroup", { children: sizes2.map((size, index) => /* @__PURE__ */ jsx5("col", { style: { width: `${size}px` } }, index)) }),
609
+ /* @__PURE__ */ jsx5("thead", { children: /* @__PURE__ */ jsx5("tr", { children: Array.from({ length: columnCount }, (_, columnIndex) => /* @__PURE__ */ jsxs5("th", { scope: "col", children: [
610
+ /* @__PURE__ */ jsx5("span", { className: "fe-table__header-content", children: headers[columnIndex] ?? `Column ${columnIndex + 1}` }),
611
+ /* @__PURE__ */ jsx5(
380
612
  "span",
381
613
  {
382
614
  className: "fe-table__resize-handle",
@@ -400,7 +632,7 @@ function DataTable({
400
632
  }
401
633
  )
402
634
  ] }, columnIndex)) }) }),
403
- /* @__PURE__ */ jsx4("tbody", { children: pagedData.map((row, rowIndex) => /* @__PURE__ */ jsx4("tr", { children: Array.from({ length: columnCount }, (_, columnIndex) => /* @__PURE__ */ jsx4("td", { children: row[columnIndex] }, columnIndex)) }, shouldPaginate ? (currentPage - 1) * safePageSize + rowIndex : rowIndex)) })
635
+ /* @__PURE__ */ jsx5("tbody", { children: pagedData.map((row, rowIndex) => /* @__PURE__ */ jsx5("tr", { children: Array.from({ length: columnCount }, (_, columnIndex) => /* @__PURE__ */ jsx5("td", { children: row[columnIndex] }, columnIndex)) }, shouldPaginate ? (currentPage - 1) * safePageSize + rowIndex : rowIndex)) })
404
636
  ] }),
405
637
  resolvedPaginationPosition !== "top-right" && paginationControl
406
638
  ] });
@@ -418,35 +650,35 @@ function Table({
418
650
  paginationPosition,
419
651
  ...props
420
652
  }) {
421
- if (headers || data) return /* @__PURE__ */ jsx4(DataTable, { headers: headers ?? [], data: data ?? [], striped: striped ?? true, pagination, pageSize, page, defaultPage, onPageChange, paginationPosition, ...props });
422
- return /* @__PURE__ */ jsx4(TableContext.Provider, { value: { striped: striped ?? false }, children: /* @__PURE__ */ jsx4("table", { "data-fe-table": true, "data-striped": striped || void 0, ...props, children }) });
653
+ if (headers || data) return /* @__PURE__ */ jsx5(DataTable, { headers: headers ?? [], data: data ?? [], striped: striped ?? true, pagination, pageSize, page, defaultPage, onPageChange, paginationPosition, ...props });
654
+ return /* @__PURE__ */ jsx5(TableContext.Provider, { value: { striped: striped ?? false }, children: /* @__PURE__ */ jsx5("table", { "data-fe-table": true, "data-striped": striped || void 0, ...props, children }) });
423
655
  }
424
656
  function TableHead(props) {
425
- return /* @__PURE__ */ jsx4("thead", { ...props });
657
+ return /* @__PURE__ */ jsx5("thead", { ...props });
426
658
  }
427
659
  function TableBody(props) {
428
- return /* @__PURE__ */ jsx4("tbody", { ...props });
660
+ return /* @__PURE__ */ jsx5("tbody", { ...props });
429
661
  }
430
662
  function TableRow({ children, ...props }) {
431
663
  const { striped } = useContext(TableContext);
432
- return /* @__PURE__ */ jsx4("tr", { "data-striped": striped || void 0, ...props, children });
664
+ return /* @__PURE__ */ jsx5("tr", { "data-striped": striped || void 0, ...props, children });
433
665
  }
434
666
  function TableCell({ children, ...props }) {
435
- return /* @__PURE__ */ jsx4("td", { ...props, children });
667
+ return /* @__PURE__ */ jsx5("td", { ...props, children });
436
668
  }
437
669
  function TableHeader({ children, ...props }) {
438
- return /* @__PURE__ */ jsx4("th", { scope: "col", ...props, children });
670
+ return /* @__PURE__ */ jsx5("th", { scope: "col", ...props, children });
439
671
  }
440
672
  function TableCaption(props) {
441
- return /* @__PURE__ */ jsx4("caption", { ...props });
673
+ return /* @__PURE__ */ jsx5("caption", { ...props });
442
674
  }
443
675
 
444
676
  // packages/toggle/src/index.tsx
445
677
  import {
446
- forwardRef as forwardRef2
678
+ forwardRef as forwardRef3
447
679
  } from "react";
448
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
449
- var Toggle = forwardRef2(function Toggle2({
680
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
681
+ var Toggle = forwardRef3(function Toggle2({
450
682
  color = "#16a34a",
451
683
  label,
452
684
  labelPosition = "right",
@@ -460,9 +692,9 @@ var Toggle = forwardRef2(function Toggle2({
460
692
  "--fe-toggle-color": color,
461
693
  ...style
462
694
  };
463
- return /* @__PURE__ */ jsxs5("label", { className: classes, style: toggleStyle, children: [
464
- label && labelPosition === "top" && /* @__PURE__ */ jsx5("span", { className: "fe-toggle__label", children: label }),
465
- /* @__PURE__ */ jsx5(
695
+ return /* @__PURE__ */ jsxs6("label", { className: classes, style: toggleStyle, children: [
696
+ label && labelPosition === "top" && /* @__PURE__ */ jsx6("span", { className: "fe-toggle__label", children: label }),
697
+ /* @__PURE__ */ jsx6(
466
698
  "input",
467
699
  {
468
700
  ref,
@@ -473,48 +705,271 @@ var Toggle = forwardRef2(function Toggle2({
473
705
  ...props
474
706
  }
475
707
  ),
476
- /* @__PURE__ */ jsx5("span", { className: "fe-toggle__control", "aria-hidden": "true" }),
477
- label && labelPosition === "right" && /* @__PURE__ */ jsx5("span", { className: "fe-toggle__label", children: label })
708
+ /* @__PURE__ */ jsx6("span", { className: "fe-toggle__control", "aria-hidden": "true" }),
709
+ label && labelPosition === "right" && /* @__PURE__ */ jsx6("span", { className: "fe-toggle__label", children: label })
478
710
  ] });
479
711
  });
480
712
  Toggle.displayName = "Toggle";
481
713
 
482
714
  // packages/drawer/src/index.tsx
483
- import { useEffect as useEffect3 } from "react";
715
+ import {
716
+ useId as useId3,
717
+ useRef as useRef5
718
+ } from "react";
484
719
  import { createPortal } from "react-dom";
485
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
486
- function Drawer({ open, onClose, title, footer, side = "right", width = 400, fullScreen = false, children, closeOnBackdropClick = true, className, style, ...props }) {
487
- useEffect3(() => {
488
- if (!open) return;
720
+
721
+ // packages/overlay/src/useModalOverlay.ts
722
+ import { useEffect as useEffect4, useLayoutEffect, useRef as useRef4 } from "react";
723
+ var FOCUSABLE_SELECTOR = [
724
+ "a[href]",
725
+ "area[href]",
726
+ "input:not([disabled])",
727
+ "select:not([disabled])",
728
+ "textarea:not([disabled])",
729
+ "button:not([disabled])",
730
+ "iframe",
731
+ "object",
732
+ "embed",
733
+ '[contenteditable="true"]',
734
+ '[tabindex]:not([tabindex="-1"])'
735
+ ].join(",");
736
+ var overlayStack = [];
737
+ var scrollLockCount = 0;
738
+ var savedBodyStyles = null;
739
+ var useIsomorphicLayoutEffect = typeof window === "undefined" ? useEffect4 : useLayoutEffect;
740
+ function lockBodyScroll() {
741
+ if (typeof document === "undefined" || scrollLockCount++ > 0) return;
742
+ const { body, documentElement } = document;
743
+ savedBodyStyles = {
744
+ overflow: body.style.overflow,
745
+ overscrollBehavior: body.style.overscrollBehavior,
746
+ paddingRight: body.style.paddingRight
747
+ };
748
+ const scrollbarWidth = Math.max(
749
+ 0,
750
+ window.innerWidth - documentElement.clientWidth
751
+ );
752
+ const currentPadding = Number.parseFloat(window.getComputedStyle(body).paddingRight) || 0;
753
+ body.style.overflow = "hidden";
754
+ body.style.overscrollBehavior = "none";
755
+ if (scrollbarWidth > 0)
756
+ body.style.paddingRight = `${currentPadding + scrollbarWidth}px`;
757
+ }
758
+ function unlockBodyScroll() {
759
+ if (typeof document === "undefined" || scrollLockCount === 0) return;
760
+ scrollLockCount -= 1;
761
+ if (scrollLockCount > 0 || !savedBodyStyles) return;
762
+ const { body } = document;
763
+ body.style.overflow = savedBodyStyles.overflow;
764
+ body.style.overscrollBehavior = savedBodyStyles.overscrollBehavior;
765
+ body.style.paddingRight = savedBodyStyles.paddingRight;
766
+ savedBodyStyles = null;
767
+ }
768
+ function getFocusableElements(panel) {
769
+ return Array.from(
770
+ panel.querySelectorAll(FOCUSABLE_SELECTOR)
771
+ ).filter(
772
+ (element) => element.tabIndex >= 0 && !element.hasAttribute("disabled") && element.getAttribute("aria-hidden") !== "true"
773
+ );
774
+ }
775
+ function getTopOverlay() {
776
+ return overlayStack.reduce((top, candidate) => {
777
+ if (!top || candidate.priority > top.priority) return candidate;
778
+ if (candidate.priority < top.priority) return top;
779
+ const topNode = top.panelRef.current?.parentElement;
780
+ const candidateNode = candidate.panelRef.current?.parentElement;
781
+ if (topNode && candidateNode) {
782
+ const position = topNode.compareDocumentPosition(candidateNode);
783
+ if (position & Node.DOCUMENT_POSITION_FOLLOWING) return candidate;
784
+ if (position & Node.DOCUMENT_POSITION_PRECEDING) return top;
785
+ }
786
+ return candidate;
787
+ }, void 0);
788
+ }
789
+ function useModalOverlay(options) {
790
+ const overlayIdRef = useRef4();
791
+ const previouslyFocusedRef = useRef4(null);
792
+ const optionsRef = useRef4(options);
793
+ optionsRef.current = options;
794
+ if (!overlayIdRef.current) overlayIdRef.current = /* @__PURE__ */ Symbol("fe-overlay");
795
+ useIsomorphicLayoutEffect(() => {
796
+ if (!options.open || typeof document === "undefined") return;
797
+ const overlayId = overlayIdRef.current;
798
+ previouslyFocusedRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
799
+ overlayStack.push({
800
+ id: overlayId,
801
+ panelRef: options.panelRef,
802
+ priority: options.priority ?? 0
803
+ });
804
+ lockBodyScroll();
805
+ const focusInitialElement = () => {
806
+ const { initialFocusRef, panelRef } = optionsRef.current;
807
+ const focusTarget = initialFocusRef?.current ?? panelRef.current;
808
+ focusTarget?.focus();
809
+ };
810
+ let cancelled = false;
811
+ queueMicrotask(() => {
812
+ if (!cancelled && getTopOverlay()?.id === overlayId)
813
+ focusInitialElement();
814
+ });
489
815
  const onKeyDown = (event) => {
490
- if (event.key === "Escape") onClose();
816
+ if (getTopOverlay()?.id !== overlayId) return;
817
+ if (event.key === "Escape") {
818
+ if (optionsRef.current.closeOnEscape !== false) {
819
+ event.preventDefault();
820
+ optionsRef.current.onClose();
821
+ }
822
+ return;
823
+ }
824
+ if (event.key !== "Tab") return;
825
+ const panel = optionsRef.current.panelRef.current;
826
+ if (!panel) return;
827
+ const focusable = getFocusableElements(panel);
828
+ if (!focusable.length) {
829
+ event.preventDefault();
830
+ panel.focus();
831
+ return;
832
+ }
833
+ const first = focusable[0];
834
+ const last = focusable[focusable.length - 1];
835
+ const activeElement = document.activeElement;
836
+ if (event.shiftKey && (activeElement === first || !panel.contains(activeElement))) {
837
+ event.preventDefault();
838
+ last.focus();
839
+ } else if (!event.shiftKey && (activeElement === last || !panel.contains(activeElement))) {
840
+ event.preventDefault();
841
+ first.focus();
842
+ }
491
843
  };
492
844
  document.addEventListener("keydown", onKeyDown);
493
- return () => document.removeEventListener("keydown", onKeyDown);
494
- }, [onClose, open]);
845
+ return () => {
846
+ document.removeEventListener("keydown", onKeyDown);
847
+ cancelled = true;
848
+ const stackIndex = overlayStack.findIndex(
849
+ (entry) => entry.id === overlayId
850
+ );
851
+ if (stackIndex !== -1) overlayStack.splice(stackIndex, 1);
852
+ unlockBodyScroll();
853
+ if (optionsRef.current.restoreFocus !== false) {
854
+ const nextOverlay = getTopOverlay()?.panelRef.current;
855
+ if (nextOverlay) nextOverlay.focus();
856
+ else if (previouslyFocusedRef.current?.isConnected) {
857
+ previouslyFocusedRef.current.focus();
858
+ }
859
+ }
860
+ };
861
+ }, [options.open, options.panelRef]);
862
+ }
863
+
864
+ // packages/drawer/src/index.tsx
865
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
866
+ var DrawerWidths = {
867
+ small: 360,
868
+ medium: 400,
869
+ large: 480
870
+ };
871
+ function Drawer({
872
+ open,
873
+ onClose,
874
+ title,
875
+ description,
876
+ footer,
877
+ side = "right",
878
+ width = DrawerWidths.medium,
879
+ fullScreen = false,
880
+ children,
881
+ closeOnBackdropClick = true,
882
+ closeOnEscape = true,
883
+ closeLabel = "Close drawer",
884
+ initialFocusRef,
885
+ restoreFocus = true,
886
+ className,
887
+ style,
888
+ "aria-label": ariaLabel,
889
+ "aria-describedby": ariaDescribedBy,
890
+ ...props
891
+ }) {
892
+ const titleId = useId3();
893
+ const descriptionId = useId3();
894
+ const panelRef = useRef5(null);
895
+ useModalOverlay({
896
+ open,
897
+ onClose,
898
+ panelRef,
899
+ priority: 1e3,
900
+ closeOnEscape,
901
+ initialFocusRef,
902
+ restoreFocus
903
+ });
495
904
  if (!open || typeof document === "undefined") return null;
496
905
  const panelStyle = !fullScreen && (side === "left" || side === "right") ? { ...style, width: typeof width === "number" ? `${width}px` : width } : style;
497
- return createPortal(/* @__PURE__ */ jsx6("div", { className: "fe-drawer-backdrop", role: "presentation", onMouseDown: (event) => {
498
- if (event.target === event.currentTarget && closeOnBackdropClick) onClose();
499
- }, children: /* @__PURE__ */ jsxs6("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: [
500
- /* @__PURE__ */ jsxs6("header", { className: "fe-drawer__header", children: [
501
- title && /* @__PURE__ */ jsx6("h2", { children: title }),
502
- /* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Close drawer", onClick: onClose, children: "\xD7" })
503
- ] }),
504
- /* @__PURE__ */ jsx6("div", { className: "fe-drawer__body", children }),
505
- footer && /* @__PURE__ */ jsx6("footer", { className: "fe-drawer__footer", children: footer })
506
- ] }) }), document.body);
906
+ const describedBy = [description ? descriptionId : void 0, ariaDescribedBy].filter(Boolean).join(" ") || void 0;
907
+ return createPortal(
908
+ /* @__PURE__ */ jsx7(
909
+ "div",
910
+ {
911
+ className: "fe-drawer-backdrop",
912
+ role: "presentation",
913
+ onMouseDown: (event) => {
914
+ if (event.target === event.currentTarget && closeOnBackdropClick)
915
+ onClose();
916
+ },
917
+ children: /* @__PURE__ */ jsxs7(
918
+ "aside",
919
+ {
920
+ ref: panelRef,
921
+ className: [
922
+ "fe-drawer",
923
+ `fe-drawer--${side}`,
924
+ fullScreen && "fe-drawer--full-screen",
925
+ className
926
+ ].filter(Boolean).join(" "),
927
+ style: panelStyle,
928
+ role: "dialog",
929
+ "aria-modal": "true",
930
+ "aria-labelledby": title ? titleId : void 0,
931
+ "aria-describedby": describedBy,
932
+ "aria-label": ariaLabel ?? (title ? void 0 : "Drawer"),
933
+ tabIndex: -1,
934
+ ...props,
935
+ children: [
936
+ /* @__PURE__ */ jsxs7("header", { className: "fe-drawer__header", children: [
937
+ (title || description) && /* @__PURE__ */ jsxs7("div", { className: "fe-drawer__heading", children: [
938
+ title && /* @__PURE__ */ jsx7("h2", { id: titleId, children: title }),
939
+ description && /* @__PURE__ */ jsx7("p", { id: descriptionId, children: description })
940
+ ] }),
941
+ /* @__PURE__ */ jsx7(
942
+ Button,
943
+ {
944
+ hierarchy: "tertiary-gray",
945
+ size: "32",
946
+ iconOnly: true,
947
+ icon: /* @__PURE__ */ jsx7(CloseIcon, {}),
948
+ "aria-label": closeLabel,
949
+ onClick: onClose
950
+ }
951
+ )
952
+ ] }),
953
+ /* @__PURE__ */ jsx7("div", { className: "fe-drawer__body", children }),
954
+ footer && /* @__PURE__ */ jsx7("footer", { className: "fe-drawer__footer", children: footer })
955
+ ]
956
+ }
957
+ )
958
+ }
959
+ ),
960
+ document.body
961
+ );
507
962
  }
508
963
 
509
964
  // packages/form-controls/src/controls/TextInput/text-input.tsx
510
- import { forwardRef as forwardRef3, useId as useId3, useState as useState5 } from "react";
965
+ import { forwardRef as forwardRef4, useId as useId5, useState as useState6 } from "react";
511
966
 
512
967
  // packages/tooltip/src/index.tsx
513
- import { cloneElement, useId as useId2, useState as useState4 } from "react";
514
- import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
968
+ import { cloneElement, useId as useId4, useState as useState5 } from "react";
969
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
515
970
  function Tooltip({ content, children, placement = "top", disabled, className, ...props }) {
516
- const [visible, setVisible] = useState4(false);
517
- const id = useId2();
971
+ const [visible, setVisible] = useState5(false);
972
+ const id = useId4();
518
973
  const trigger = cloneElement(children, { "aria-describedby": visible ? id : void 0, onMouseEnter: (event) => {
519
974
  children.props.onMouseEnter?.(event);
520
975
  setVisible(true);
@@ -528,14 +983,14 @@ function Tooltip({ content, children, placement = "top", disabled, className, ..
528
983
  children.props.onBlur?.(event);
529
984
  setVisible(false);
530
985
  } });
531
- return /* @__PURE__ */ jsxs7("span", { className: ["fe-tooltip", `fe-tooltip--${placement}`, className].filter(Boolean).join(" "), ...props, children: [
986
+ return /* @__PURE__ */ jsxs8("span", { className: ["fe-tooltip", `fe-tooltip--${placement}`, className].filter(Boolean).join(" "), ...props, children: [
532
987
  trigger,
533
- visible && !disabled && /* @__PURE__ */ jsx7("span", { id, role: "tooltip", className: "fe-tooltip__content", children: content })
988
+ visible && !disabled && /* @__PURE__ */ jsx8("span", { id, role: "tooltip", className: "fe-tooltip__content", children: content })
534
989
  ] });
535
990
  }
536
991
 
537
992
  // packages/form-controls/src/controls/Field/field.tsx
538
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
993
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
539
994
  function getFieldError(error, errorMessage) {
540
995
  if (errorMessage !== void 0 && errorMessage !== null) return errorMessage;
541
996
  if (typeof error !== "boolean") return error;
@@ -552,10 +1007,10 @@ function FieldLabel({
552
1007
  isRequired = false
553
1008
  }) {
554
1009
  if (!label) return null;
555
- return /* @__PURE__ */ jsxs8("span", { className: "fe-field__label", children: [
556
- /* @__PURE__ */ jsx8("span", { id, children: label }),
557
- isRequired && /* @__PURE__ */ jsx8("span", { className: "fe-field__required", "aria-hidden": "true", children: "*" }),
558
- description && descriptionDisplay === "tooltip" && /* @__PURE__ */ jsx8(Tooltip, { content: description, children: /* @__PURE__ */ jsx8(
1010
+ return /* @__PURE__ */ jsxs9("span", { className: "fe-field__label", children: [
1011
+ /* @__PURE__ */ jsx9("span", { id, children: label }),
1012
+ isRequired && /* @__PURE__ */ jsx9("span", { className: "fe-field__required", "aria-hidden": "true", children: "*" }),
1013
+ description && descriptionDisplay === "tooltip" && /* @__PURE__ */ jsx9(Tooltip, { content: description, children: /* @__PURE__ */ jsx9(
559
1014
  "span",
560
1015
  {
561
1016
  className: "fe-field__info",
@@ -574,7 +1029,7 @@ function FieldMessage({
574
1029
  descriptionDisplay
575
1030
  }) {
576
1031
  if (error !== void 0 && error !== false && error !== null)
577
- return /* @__PURE__ */ jsx8(
1032
+ return /* @__PURE__ */ jsx9(
578
1033
  "span",
579
1034
  {
580
1035
  id,
@@ -584,13 +1039,13 @@ function FieldMessage({
584
1039
  }
585
1040
  );
586
1041
  if (description && descriptionDisplay === "inline")
587
- return /* @__PURE__ */ jsx8("span", { id, className: "fe-field__message", children: description });
1042
+ return /* @__PURE__ */ jsx9("span", { id, className: "fe-field__message", children: description });
588
1043
  return null;
589
1044
  }
590
1045
 
591
1046
  // packages/form-controls/src/controls/TextInput/text-input.tsx
592
- import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
593
- var TextInput = forwardRef3(
1047
+ import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1048
+ var TextInput = forwardRef4(
594
1049
  function TextInput2({
595
1050
  value,
596
1051
  defaultValue = "",
@@ -620,12 +1075,12 @@ var TextInput = forwardRef3(
620
1075
  "aria-labelledby": ariaLabelledBy,
621
1076
  ...props
622
1077
  }, ref) {
623
- const generatedId = useId3();
1078
+ const generatedId = useId5();
624
1079
  const inputId = id ?? generatedId + "-input";
625
1080
  const labelId = generatedId + "-label";
626
1081
  const messageId2 = generatedId + "-message";
627
1082
  const controlled = value !== void 0;
628
- const [internalValue, setInternalValue] = useState5(defaultValue);
1083
+ const [internalValue, setInternalValue] = useState6(defaultValue);
629
1084
  const currentValue = controlled ? value : internalValue;
630
1085
  const fieldError = getFieldError(error, errorMessage);
631
1086
  const hasError = fieldError !== void 0 && fieldError !== false && fieldError !== null;
@@ -646,7 +1101,7 @@ var TextInput = forwardRef3(
646
1101
  onValueChange?.("");
647
1102
  onClear?.();
648
1103
  };
649
- return /* @__PURE__ */ jsxs9(
1104
+ return /* @__PURE__ */ jsxs10(
650
1105
  "div",
651
1106
  {
652
1107
  className: [
@@ -655,7 +1110,7 @@ var TextInput = forwardRef3(
655
1110
  className
656
1111
  ].filter(Boolean).join(" "),
657
1112
  children: [
658
- /* @__PURE__ */ jsx9(
1113
+ /* @__PURE__ */ jsx10(
659
1114
  FieldLabel,
660
1115
  {
661
1116
  id: labelId,
@@ -665,10 +1120,10 @@ var TextInput = forwardRef3(
665
1120
  isRequired
666
1121
  }
667
1122
  ),
668
- /* @__PURE__ */ jsxs9("span", { className: "fe-text-input__control", children: [
669
- resolvedPrefix && /* @__PURE__ */ jsx9("span", { className: "fe-text-input__prefix", children: resolvedPrefix }),
670
- /* @__PURE__ */ jsxs9("span", { className: "fe-text-input__input-wrap", children: [
671
- /* @__PURE__ */ jsx9(
1123
+ /* @__PURE__ */ jsxs10("span", { className: "fe-text-input__control", children: [
1124
+ resolvedPrefix && /* @__PURE__ */ jsx10("span", { className: "fe-text-input__prefix", children: resolvedPrefix }),
1125
+ /* @__PURE__ */ jsxs10("span", { className: "fe-text-input__input-wrap", children: [
1126
+ /* @__PURE__ */ jsx10(
672
1127
  "input",
673
1128
  {
674
1129
  ref,
@@ -690,26 +1145,26 @@ var TextInput = forwardRef3(
690
1145
  ...props
691
1146
  }
692
1147
  ),
693
- isRequired && placeholder && !currentValue && /* @__PURE__ */ jsxs9("span", { className: "fe-text-input__placeholder", "aria-hidden": "true", children: [
694
- /* @__PURE__ */ jsx9("span", { children: placeholder }),
695
- /* @__PURE__ */ jsx9("span", { className: "fe-field__required", children: "*" })
1148
+ isRequired && placeholder && !currentValue && /* @__PURE__ */ jsxs10("span", { className: "fe-text-input__placeholder", "aria-hidden": "true", children: [
1149
+ /* @__PURE__ */ jsx10("span", { children: placeholder }),
1150
+ /* @__PURE__ */ jsx10("span", { className: "fe-field__required", children: "*" })
696
1151
  ] })
697
1152
  ] }),
698
- resolvedSuffix && /* @__PURE__ */ jsx9("span", { className: "fe-text-input__suffix", children: resolvedSuffix }),
699
- clearable && currentValue && !disabled && !readOnly && /* @__PURE__ */ jsx9(
1153
+ resolvedSuffix && /* @__PURE__ */ jsx10("span", { className: "fe-text-input__suffix", children: resolvedSuffix }),
1154
+ clearable && currentValue && !disabled && !readOnly && /* @__PURE__ */ jsx10(
700
1155
  Button,
701
1156
  {
702
1157
  hierarchy: "tertiary-gray",
703
1158
  size: "24",
704
1159
  iconOnly: true,
705
- icon: /* @__PURE__ */ jsx9(CloseIcon, { size: 14 }),
1160
+ icon: /* @__PURE__ */ jsx10(CloseIcon, { size: 14 }),
706
1161
  "aria-label": clearLabel,
707
1162
  onClick: clear,
708
1163
  className: "fe-text-input__clear"
709
1164
  }
710
1165
  )
711
1166
  ] }),
712
- /* @__PURE__ */ jsx9(
1167
+ /* @__PURE__ */ jsx10(
713
1168
  FieldMessage,
714
1169
  {
715
1170
  id: messageId2,
@@ -725,17 +1180,264 @@ var TextInput = forwardRef3(
725
1180
  );
726
1181
  TextInput.displayName = "TextInput";
727
1182
 
1183
+ // packages/form-controls/src/controls/EmailInput/email-input.tsx
1184
+ import { forwardRef as forwardRef5 } from "react";
1185
+
1186
+ // packages/form-controls/src/controls/ValidatedInput/validation.ts
1187
+ import { useState as useState7 } from "react";
1188
+ var invalidValueMessage = "Invalid value.";
1189
+ function toValidationError(result) {
1190
+ if (typeof result === "string") return result || void 0;
1191
+ return result === false ? invalidValueMessage : void 0;
1192
+ }
1193
+ function validateEmail(value, required = false) {
1194
+ const email = value.trim();
1195
+ if (!email) return required ? "Email is required." : void 0;
1196
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email) ? void 0 : "Enter a valid email address.";
1197
+ }
1198
+ function validatePassword(value, required = false) {
1199
+ if (!value) return required ? "Password is required." : void 0;
1200
+ if (value.length < 8) return "Use at least 8 characters.";
1201
+ if (!/[a-z]/.test(value) || !/[A-Z]/.test(value) || !/\d/.test(value))
1202
+ return "Include uppercase, lowercase, and a number.";
1203
+ return void 0;
1204
+ }
1205
+ function validatePhoneNumber(value, required = false) {
1206
+ const phoneNumber = value.trim();
1207
+ if (!phoneNumber) return required ? "Phone number is required." : void 0;
1208
+ if (!/^\+?[\d() ]+$/.test(phoneNumber))
1209
+ return "Use only numbers, spaces, parentheses, and an optional leading +.";
1210
+ const digitCount = phoneNumber.replace(/\D/g, "").length;
1211
+ return digitCount >= 7 && digitCount <= 15 ? void 0 : "Enter a phone number with 7 to 15 digits.";
1212
+ }
1213
+ function normalizePhoneNumber(value) {
1214
+ return value.replace(/[^\d+() ]/g, "");
1215
+ }
1216
+ function useInputValidation({
1217
+ error,
1218
+ errorMessage,
1219
+ isRequired = false,
1220
+ required = false,
1221
+ validate,
1222
+ validateOn = "blur",
1223
+ builtInValidator
1224
+ }) {
1225
+ const [validationError, setValidationError] = useState7();
1226
+ const [hasValidated, setHasValidated] = useState7(false);
1227
+ const hasExternalError = error !== void 0 || errorMessage !== void 0;
1228
+ const validateValue = (value) => {
1229
+ const builtInError = builtInValidator(value, isRequired || required);
1230
+ const customError = builtInError ? void 0 : toValidationError(validate?.(value));
1231
+ const nextError = builtInError ?? customError;
1232
+ setHasValidated(true);
1233
+ setValidationError(nextError);
1234
+ return nextError;
1235
+ };
1236
+ return {
1237
+ error: hasExternalError ? getFieldError(error, errorMessage) : validationError,
1238
+ onValueChange(value) {
1239
+ if (validateOn === "change" || hasValidated) validateValue(value);
1240
+ },
1241
+ onBlur(value) {
1242
+ if (validateOn === "blur") validateValue(value);
1243
+ }
1244
+ };
1245
+ }
1246
+
1247
+ // packages/form-controls/src/controls/EmailInput/email-input.tsx
1248
+ import { jsx as jsx11 } from "react/jsx-runtime";
1249
+ var EmailInput = forwardRef5(
1250
+ function EmailInput2({
1251
+ error,
1252
+ errorMessage,
1253
+ isRequired,
1254
+ required,
1255
+ validate,
1256
+ validateOn,
1257
+ onBlur,
1258
+ onValueChange,
1259
+ autoComplete,
1260
+ className,
1261
+ ...props
1262
+ }, ref) {
1263
+ const validation = useInputValidation({
1264
+ error,
1265
+ errorMessage,
1266
+ isRequired,
1267
+ required,
1268
+ validate,
1269
+ validateOn,
1270
+ builtInValidator: validateEmail
1271
+ });
1272
+ return /* @__PURE__ */ jsx11(
1273
+ TextInput,
1274
+ {
1275
+ ...props,
1276
+ ref,
1277
+ className: ["fe-email-input", className].filter(Boolean).join(" "),
1278
+ type: "email",
1279
+ inputMode: "email",
1280
+ autoComplete: autoComplete ?? "email",
1281
+ isRequired,
1282
+ required,
1283
+ prefix: /* @__PURE__ */ jsx11(MailboxIcon, { size: 18 }),
1284
+ error: validation.error,
1285
+ onValueChange: (value) => {
1286
+ validation.onValueChange(value);
1287
+ onValueChange?.(value);
1288
+ },
1289
+ onBlur: (event) => {
1290
+ validation.onBlur(event.currentTarget.value);
1291
+ onBlur?.(event);
1292
+ }
1293
+ }
1294
+ );
1295
+ }
1296
+ );
1297
+ EmailInput.displayName = "EmailInput";
1298
+
1299
+ // packages/form-controls/src/controls/PasswordInput/password-input.tsx
1300
+ import { forwardRef as forwardRef6, useState as useState8 } from "react";
1301
+ import { jsx as jsx12 } from "react/jsx-runtime";
1302
+ var PasswordInput = forwardRef6(
1303
+ function PasswordInput2({
1304
+ error,
1305
+ errorMessage,
1306
+ isRequired,
1307
+ required,
1308
+ validate,
1309
+ validateOn,
1310
+ onBlur,
1311
+ onValueChange,
1312
+ autoComplete,
1313
+ className,
1314
+ showPasswordLabel = "Show password",
1315
+ hidePasswordLabel = "Hide password",
1316
+ ...props
1317
+ }, ref) {
1318
+ const [visible, setVisible] = useState8(false);
1319
+ const validation = useInputValidation({
1320
+ error,
1321
+ errorMessage,
1322
+ isRequired,
1323
+ required,
1324
+ validate,
1325
+ validateOn,
1326
+ builtInValidator: validatePassword
1327
+ });
1328
+ const toggleLabel = visible ? hidePasswordLabel : showPasswordLabel;
1329
+ return /* @__PURE__ */ jsx12(
1330
+ TextInput,
1331
+ {
1332
+ ...props,
1333
+ ref,
1334
+ className: ["fe-password-input", className].filter(Boolean).join(" "),
1335
+ type: visible ? "text" : "password",
1336
+ autoComplete: autoComplete ?? "current-password",
1337
+ isRequired,
1338
+ required,
1339
+ suffix: /* @__PURE__ */ jsx12(
1340
+ Button,
1341
+ {
1342
+ hierarchy: "tertiary-gray",
1343
+ size: "24",
1344
+ iconOnly: true,
1345
+ icon: visible ? /* @__PURE__ */ jsx12(EyeOffIcon, { size: 16 }) : /* @__PURE__ */ jsx12(EyeIcon, { size: 16 }),
1346
+ "aria-label": toggleLabel,
1347
+ "aria-pressed": visible,
1348
+ className: "fe-password-input__toggle",
1349
+ onMouseDown: (event) => event.preventDefault(),
1350
+ onClick: () => setVisible((previous) => !previous)
1351
+ }
1352
+ ),
1353
+ error: validation.error,
1354
+ onValueChange: (value) => {
1355
+ validation.onValueChange(value);
1356
+ onValueChange?.(value);
1357
+ },
1358
+ onBlur: (event) => {
1359
+ validation.onBlur(event.currentTarget.value);
1360
+ onBlur?.(event);
1361
+ }
1362
+ }
1363
+ );
1364
+ }
1365
+ );
1366
+ PasswordInput.displayName = "PasswordInput";
1367
+
1368
+ // packages/form-controls/src/controls/PhoneNumberInput/phone-number-input.tsx
1369
+ import { forwardRef as forwardRef7, useState as useState9 } from "react";
1370
+ import { jsx as jsx13 } from "react/jsx-runtime";
1371
+ var PhoneNumberInput = forwardRef7(function PhoneNumberInput2({
1372
+ value,
1373
+ defaultValue = "",
1374
+ error,
1375
+ errorMessage,
1376
+ isRequired,
1377
+ required,
1378
+ validate,
1379
+ validateOn,
1380
+ onBlur,
1381
+ onValueChange,
1382
+ autoComplete,
1383
+ className,
1384
+ ...props
1385
+ }, ref) {
1386
+ const controlled = value !== void 0;
1387
+ const [uncontrolledValue, setUncontrolledValue] = useState9(
1388
+ () => normalizePhoneNumber(defaultValue)
1389
+ );
1390
+ const currentValue = controlled ? value : uncontrolledValue;
1391
+ const validation = useInputValidation({
1392
+ error,
1393
+ errorMessage,
1394
+ isRequired,
1395
+ required,
1396
+ validate,
1397
+ validateOn,
1398
+ builtInValidator: validatePhoneNumber
1399
+ });
1400
+ return /* @__PURE__ */ jsx13(
1401
+ TextInput,
1402
+ {
1403
+ ...props,
1404
+ ref,
1405
+ className: ["fe-phone-number-input", className].filter(Boolean).join(" "),
1406
+ type: "tel",
1407
+ inputMode: "tel",
1408
+ autoComplete: autoComplete ?? "tel",
1409
+ value: currentValue,
1410
+ isRequired,
1411
+ required,
1412
+ prefix: /* @__PURE__ */ jsx13(PhoneIcon, { size: 18 }),
1413
+ error: validation.error,
1414
+ onValueChange: (nextValue) => {
1415
+ const normalizedValue = normalizePhoneNumber(nextValue);
1416
+ if (!controlled) setUncontrolledValue(normalizedValue);
1417
+ validation.onValueChange(normalizedValue);
1418
+ onValueChange?.(normalizedValue);
1419
+ },
1420
+ onBlur: (event) => {
1421
+ const normalizedValue = normalizePhoneNumber(event.currentTarget.value);
1422
+ validation.onBlur(normalizedValue);
1423
+ onBlur?.(event);
1424
+ }
1425
+ }
1426
+ );
1427
+ });
1428
+ PhoneNumberInput.displayName = "PhoneNumberInput";
1429
+
728
1430
  // packages/form-controls/src/controls/TextArea/text-area.tsx
729
1431
  import {
730
- forwardRef as forwardRef4,
731
- useId as useId4,
1432
+ forwardRef as forwardRef8,
1433
+ useId as useId6,
732
1434
  useImperativeHandle,
733
- useLayoutEffect,
734
- useRef as useRef3,
735
- useState as useState6
1435
+ useLayoutEffect as useLayoutEffect2,
1436
+ useRef as useRef6,
1437
+ useState as useState10
736
1438
  } from "react";
737
- import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
738
- var TextArea = forwardRef4(
1439
+ import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
1440
+ var TextArea = forwardRef8(
739
1441
  function TextArea2({
740
1442
  value,
741
1443
  defaultValue = "",
@@ -762,13 +1464,13 @@ var TextArea = forwardRef4(
762
1464
  "aria-labelledby": ariaLabelledBy,
763
1465
  ...props
764
1466
  }, ref) {
765
- const generatedId = useId4();
1467
+ const generatedId = useId6();
766
1468
  const inputId = id ?? generatedId + "-input";
767
1469
  const labelId = generatedId + "-label";
768
1470
  const messageId2 = generatedId + "-message";
769
1471
  const controlled = value !== void 0;
770
- const [internalValue, setInternalValue] = useState6(defaultValue);
771
- const textareaRef = useRef3(null);
1472
+ const [internalValue, setInternalValue] = useState10(defaultValue);
1473
+ const textareaRef = useRef6(null);
772
1474
  const currentValue = controlled ? value : internalValue;
773
1475
  const fieldError = getFieldError(error, errorMessage);
774
1476
  const hasError = fieldError !== void 0 && fieldError !== false && fieldError !== null;
@@ -787,7 +1489,7 @@ var TextArea = forwardRef4(
787
1489
  textarea.style.height = `${textarea.scrollHeight}px`;
788
1490
  };
789
1491
  useImperativeHandle(ref, () => textareaRef.current, []);
790
- useLayoutEffect(() => {
1492
+ useLayoutEffect2(() => {
791
1493
  if (autosize && textareaRef.current) {
792
1494
  resizeToContent(textareaRef.current);
793
1495
  }
@@ -797,7 +1499,7 @@ var TextArea = forwardRef4(
797
1499
  onValueChange?.("");
798
1500
  onClear?.();
799
1501
  };
800
- return /* @__PURE__ */ jsxs10(
1502
+ return /* @__PURE__ */ jsxs11(
801
1503
  "div",
802
1504
  {
803
1505
  className: [
@@ -807,7 +1509,7 @@ var TextArea = forwardRef4(
807
1509
  className
808
1510
  ].filter(Boolean).join(" "),
809
1511
  children: [
810
- /* @__PURE__ */ jsx10(
1512
+ /* @__PURE__ */ jsx14(
811
1513
  FieldLabel,
812
1514
  {
813
1515
  id: labelId,
@@ -817,8 +1519,8 @@ var TextArea = forwardRef4(
817
1519
  isRequired
818
1520
  }
819
1521
  ),
820
- /* @__PURE__ */ jsxs10("span", { className: "fe-text-area__control", children: [
821
- /* @__PURE__ */ jsx10(
1522
+ /* @__PURE__ */ jsxs11("span", { className: "fe-text-area__control", children: [
1523
+ /* @__PURE__ */ jsx14(
822
1524
  "textarea",
823
1525
  {
824
1526
  ref: textareaRef,
@@ -841,24 +1543,24 @@ var TextArea = forwardRef4(
841
1543
  ...props
842
1544
  }
843
1545
  ),
844
- isRequired && placeholder && !currentValue && /* @__PURE__ */ jsxs10("span", { className: "fe-text-area__placeholder", "aria-hidden": "true", children: [
845
- /* @__PURE__ */ jsx10("span", { children: placeholder }),
846
- /* @__PURE__ */ jsx10("span", { className: "fe-field__required", children: "*" })
1546
+ isRequired && placeholder && !currentValue && /* @__PURE__ */ jsxs11("span", { className: "fe-text-area__placeholder", "aria-hidden": "true", children: [
1547
+ /* @__PURE__ */ jsx14("span", { children: placeholder }),
1548
+ /* @__PURE__ */ jsx14("span", { className: "fe-field__required", children: "*" })
847
1549
  ] }),
848
- clearable && currentValue && !disabled && !readOnly && /* @__PURE__ */ jsx10(
1550
+ clearable && currentValue && !disabled && !readOnly && /* @__PURE__ */ jsx14(
849
1551
  Button,
850
1552
  {
851
1553
  hierarchy: "tertiary-gray",
852
1554
  size: "24",
853
1555
  iconOnly: true,
854
- icon: /* @__PURE__ */ jsx10(CloseIcon, { size: 14 }),
1556
+ icon: /* @__PURE__ */ jsx14(CloseIcon, { size: 14 }),
855
1557
  "aria-label": clearLabel,
856
1558
  onClick: clear,
857
1559
  className: "fe-text-area__clear"
858
1560
  }
859
1561
  )
860
1562
  ] }),
861
- /* @__PURE__ */ jsx10(
1563
+ /* @__PURE__ */ jsx14(
862
1564
  FieldMessage,
863
1565
  {
864
1566
  id: messageId2,
@@ -876,16 +1578,31 @@ TextArea.displayName = "TextArea";
876
1578
 
877
1579
  // packages/form-controls/src/controls/Selection/selection.tsx
878
1580
  import {
879
- forwardRef as forwardRef5,
880
- useEffect as useEffect4,
881
- useId as useId5,
882
- useLayoutEffect as useLayoutEffect2,
883
- useRef as useRef4,
884
- useState as useState7
1581
+ forwardRef as forwardRef9,
1582
+ useEffect as useEffect5,
1583
+ useId as useId7,
1584
+ useLayoutEffect as useLayoutEffect3,
1585
+ useRef as useRef7,
1586
+ useState as useState11
885
1587
  } from "react";
886
1588
  import { createPortal as createPortal2 } from "react-dom";
887
- import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
888
- var Selection = forwardRef5(
1589
+
1590
+ // packages/overlay/src/getPortalZIndex.ts
1591
+ var DEFAULT_PORTAL_Z_INDEX = 1e3;
1592
+ function getPortalZIndex(anchor) {
1593
+ if (!anchor || typeof window === "undefined") return DEFAULT_PORTAL_Z_INDEX;
1594
+ let highestAncestorZIndex = DEFAULT_PORTAL_Z_INDEX - 1;
1595
+ for (let element = anchor; element; element = element.parentElement) {
1596
+ const zIndex = Number.parseInt(window.getComputedStyle(element).zIndex, 10);
1597
+ if (Number.isFinite(zIndex))
1598
+ highestAncestorZIndex = Math.max(highestAncestorZIndex, zIndex);
1599
+ }
1600
+ return Math.max(DEFAULT_PORTAL_Z_INDEX, highestAncestorZIndex + 1);
1601
+ }
1602
+
1603
+ // packages/form-controls/src/controls/Selection/selection.tsx
1604
+ import { Fragment as Fragment2, jsx as jsx15, jsxs as jsxs12 } from "react/jsx-runtime";
1605
+ var Selection = forwardRef9(
889
1606
  function Selection2({
890
1607
  className,
891
1608
  label,
@@ -914,7 +1631,7 @@ var Selection = forwardRef5(
914
1631
  "aria-labelledby": ariaLabelledBy,
915
1632
  ...props
916
1633
  }, ref) {
917
- const generatedId = useId5();
1634
+ const generatedId = useId7();
918
1635
  const triggerId = id ?? generatedId + "-trigger";
919
1636
  const listboxId = triggerId + "-listbox";
920
1637
  const labelId = generatedId + "-label";
@@ -932,7 +1649,7 @@ var Selection = forwardRef5(
932
1649
  label ? labelId : void 0
933
1650
  );
934
1651
  const isControlled = value !== void 0;
935
- const [internalValue, setInternalValue] = useState7(
1652
+ const [internalValue, setInternalValue] = useState11(
936
1653
  defaultValue ?? (multiple ? [] : "")
937
1654
  );
938
1655
  const selectedValue = isControlled ? value : internalValue;
@@ -940,13 +1657,13 @@ var Selection = forwardRef5(
940
1657
  const selectedOptions = options.filter(
941
1658
  (option) => selectedValues.some((item) => String(item) === String(option.value))
942
1659
  );
943
- const [open, setOpen] = useState7(false);
944
- const [query, setQuery] = useState7("");
945
- const [activeIndex, setActiveIndex] = useState7(0);
946
- const rootRef = useRef4(null);
947
- const menuRef = useRef4(null);
948
- const [menuPosition, setMenuPosition] = useState7(null);
949
- useEffect4(() => {
1660
+ const [open, setOpen] = useState11(false);
1661
+ const [query, setQuery] = useState11("");
1662
+ const [activeIndex, setActiveIndex] = useState11(0);
1663
+ const rootRef = useRef7(null);
1664
+ const menuRef = useRef7(null);
1665
+ const [menuPosition, setMenuPosition] = useState11(null);
1666
+ useEffect5(() => {
950
1667
  const close = (event) => {
951
1668
  const target = event.target;
952
1669
  if (!rootRef.current?.contains(target) && !menuRef.current?.contains(target))
@@ -955,7 +1672,7 @@ var Selection = forwardRef5(
955
1672
  document.addEventListener("mousedown", close);
956
1673
  return () => document.removeEventListener("mousedown", close);
957
1674
  }, []);
958
- useLayoutEffect2(() => {
1675
+ useLayoutEffect3(() => {
959
1676
  if (!open) return;
960
1677
  const updateMenuPosition = () => {
961
1678
  const rect = rootRef.current?.getBoundingClientRect();
@@ -963,7 +1680,8 @@ var Selection = forwardRef5(
963
1680
  setMenuPosition({
964
1681
  top: rect.bottom + 7,
965
1682
  left: rect.left,
966
- width: rect.width
1683
+ width: rect.width,
1684
+ zIndex: getPortalZIndex(rootRef.current)
967
1685
  });
968
1686
  };
969
1687
  updateMenuPosition();
@@ -1032,7 +1750,7 @@ var Selection = forwardRef5(
1032
1750
  }
1033
1751
  if (event.key === "Escape") setOpen(false);
1034
1752
  };
1035
- return /* @__PURE__ */ jsxs11(
1753
+ return /* @__PURE__ */ jsxs12(
1036
1754
  "div",
1037
1755
  {
1038
1756
  ref,
@@ -1047,7 +1765,7 @@ var Selection = forwardRef5(
1047
1765
  ].filter(Boolean).join(" "),
1048
1766
  ...props,
1049
1767
  children: [
1050
- /* @__PURE__ */ jsx11(
1768
+ /* @__PURE__ */ jsx15(
1051
1769
  FieldLabel,
1052
1770
  {
1053
1771
  id: labelId,
@@ -1057,8 +1775,8 @@ var Selection = forwardRef5(
1057
1775
  isRequired
1058
1776
  }
1059
1777
  ),
1060
- /* @__PURE__ */ jsxs11("div", { ref: rootRef, className: "fe-selection__control", children: [
1061
- name && selectedValues.map((item) => /* @__PURE__ */ jsx11(
1778
+ /* @__PURE__ */ jsxs12("div", { ref: rootRef, className: "fe-selection__control", children: [
1779
+ name && selectedValues.map((item) => /* @__PURE__ */ jsx15(
1062
1780
  "input",
1063
1781
  {
1064
1782
  type: "hidden",
@@ -1067,7 +1785,7 @@ var Selection = forwardRef5(
1067
1785
  },
1068
1786
  String(item)
1069
1787
  )),
1070
- /* @__PURE__ */ jsxs11(
1788
+ /* @__PURE__ */ jsxs12(
1071
1789
  "button",
1072
1790
  {
1073
1791
  id: triggerId,
@@ -1085,7 +1803,7 @@ var Selection = forwardRef5(
1085
1803
  onClick: () => setOpen((current) => !current),
1086
1804
  onKeyDown: onTriggerKeyDown,
1087
1805
  children: [
1088
- /* @__PURE__ */ jsx11(
1806
+ /* @__PURE__ */ jsx15(
1089
1807
  "span",
1090
1808
  {
1091
1809
  className: [
@@ -1093,30 +1811,30 @@ var Selection = forwardRef5(
1093
1811
  !selectedOptions.length && "is-placeholder",
1094
1812
  tag && selectedOptions.length > 1 && "is-tags"
1095
1813
  ].filter(Boolean).join(" "),
1096
- children: displayLabel ? tag && multiple ? selectedOptions.map((option) => /* @__PURE__ */ jsxs11(
1814
+ children: displayLabel ? tag && multiple ? selectedOptions.map((option) => /* @__PURE__ */ jsxs12(
1097
1815
  "span",
1098
1816
  {
1099
1817
  className: "fe-selection__tag",
1100
1818
  children: [
1101
1819
  option.label,
1102
- /* @__PURE__ */ jsx11("span", { "aria-hidden": "true", children: "\xD7" })
1820
+ /* @__PURE__ */ jsx15("span", { "aria-hidden": "true", children: "\xD7" })
1103
1821
  ]
1104
1822
  },
1105
1823
  String(option.value)
1106
- )) : displayLabel.map((item, index) => /* @__PURE__ */ jsxs11("span", { children: [
1824
+ )) : displayLabel.map((item, index) => /* @__PURE__ */ jsxs12("span", { children: [
1107
1825
  item,
1108
1826
  index < displayLabel.length - 1 ? ", " : ""
1109
- ] }, index)) : /* @__PURE__ */ jsxs11(Fragment2, { children: [
1110
- /* @__PURE__ */ jsx11("span", { children: placeholder }),
1111
- isRequired && /* @__PURE__ */ jsx11("span", { className: "fe-field__required", "aria-hidden": "true", children: "*" })
1827
+ ] }, index)) : /* @__PURE__ */ jsxs12(Fragment2, { children: [
1828
+ /* @__PURE__ */ jsx15("span", { children: placeholder }),
1829
+ isRequired && /* @__PURE__ */ jsx15("span", { className: "fe-field__required", "aria-hidden": "true", children: "*" })
1112
1830
  ] })
1113
1831
  }
1114
1832
  ),
1115
- /* @__PURE__ */ jsx11("span", { className: "fe-selection__actions", children: /* @__PURE__ */ jsx11("span", { className: "fe-selection__chevron", "aria-hidden": "true" }) })
1833
+ /* @__PURE__ */ jsx15("span", { className: "fe-selection__actions", children: /* @__PURE__ */ jsx15("span", { className: "fe-selection__chevron", "aria-hidden": "true" }) })
1116
1834
  ]
1117
1835
  }
1118
1836
  ),
1119
- clearable && selectedOptions.length > 0 && !disabled && /* @__PURE__ */ jsx11(
1837
+ clearable && selectedOptions.length > 0 && !disabled && /* @__PURE__ */ jsx15(
1120
1838
  "button",
1121
1839
  {
1122
1840
  type: "button",
@@ -1126,7 +1844,7 @@ var Selection = forwardRef5(
1126
1844
  }
1127
1845
  ),
1128
1846
  open && menuPosition && createPortal2(
1129
- /* @__PURE__ */ jsxs11(
1847
+ /* @__PURE__ */ jsxs12(
1130
1848
  "div",
1131
1849
  {
1132
1850
  ref: menuRef,
@@ -1136,14 +1854,15 @@ var Selection = forwardRef5(
1136
1854
  position: "fixed",
1137
1855
  top: menuPosition.top,
1138
1856
  left: menuPosition.left,
1139
- width: menuPosition.width
1857
+ width: menuPosition.width,
1858
+ zIndex: menuPosition.zIndex
1140
1859
  },
1141
1860
  role: "listbox",
1142
1861
  "aria-multiselectable": multiple || void 0,
1143
1862
  children: [
1144
- searchable && /* @__PURE__ */ jsxs11("div", { className: "fe-selection__search", children: [
1145
- /* @__PURE__ */ jsx11("span", { "aria-hidden": "true", children: "\u2315" }),
1146
- /* @__PURE__ */ jsx11(
1863
+ searchable && /* @__PURE__ */ jsxs12("div", { className: "fe-selection__search", children: [
1864
+ /* @__PURE__ */ jsx15("span", { "aria-hidden": "true", children: "\u2315" }),
1865
+ /* @__PURE__ */ jsx15(
1147
1866
  "input",
1148
1867
  {
1149
1868
  autoFocus: true,
@@ -1157,11 +1876,11 @@ var Selection = forwardRef5(
1157
1876
  }
1158
1877
  )
1159
1878
  ] }),
1160
- /* @__PURE__ */ jsx11("div", { className: "fe-selection__options", children: filteredOptions.length ? filteredOptions.map((option, index) => {
1879
+ /* @__PURE__ */ jsx15("div", { className: "fe-selection__options", children: filteredOptions.length ? filteredOptions.map((option, index) => {
1161
1880
  const isSelected = selectedValues.some(
1162
1881
  (item) => String(item) === String(option.value)
1163
1882
  );
1164
- return /* @__PURE__ */ jsxs11(
1883
+ return /* @__PURE__ */ jsxs12(
1165
1884
  "button",
1166
1885
  {
1167
1886
  type: "button",
@@ -1175,8 +1894,8 @@ var Selection = forwardRef5(
1175
1894
  onMouseMove: () => setActiveIndex(index),
1176
1895
  onClick: () => choose(option),
1177
1896
  children: [
1178
- /* @__PURE__ */ jsx11("span", { children: option.label }),
1179
- isSelected && /* @__PURE__ */ jsx11(
1897
+ /* @__PURE__ */ jsx15("span", { children: option.label }),
1898
+ isSelected && /* @__PURE__ */ jsx15(
1180
1899
  "span",
1181
1900
  {
1182
1901
  className: "fe-selection__check",
@@ -1188,14 +1907,14 @@ var Selection = forwardRef5(
1188
1907
  },
1189
1908
  String(option.value)
1190
1909
  );
1191
- }) : /* @__PURE__ */ jsx11("p", { className: "fe-selection__empty", children: "No matching options" }) })
1910
+ }) : /* @__PURE__ */ jsx15("p", { className: "fe-selection__empty", children: "No matching options" }) })
1192
1911
  ]
1193
1912
  }
1194
1913
  ),
1195
1914
  document.body
1196
1915
  )
1197
1916
  ] }),
1198
- /* @__PURE__ */ jsx11(
1917
+ /* @__PURE__ */ jsx15(
1199
1918
  FieldMessage,
1200
1919
  {
1201
1920
  id: messageId2,
@@ -1213,13 +1932,13 @@ Selection.displayName = "Selection";
1213
1932
 
1214
1933
  // packages/form-controls/src/controls/NumberInput/number-input.tsx
1215
1934
  import {
1216
- forwardRef as forwardRef6,
1217
- useEffect as useEffect5,
1218
- useId as useId6,
1219
- useRef as useRef5,
1220
- useState as useState8
1935
+ forwardRef as forwardRef10,
1936
+ useEffect as useEffect6,
1937
+ useId as useId8,
1938
+ useRef as useRef8,
1939
+ useState as useState12
1221
1940
  } from "react";
1222
- import { jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
1941
+ import { jsx as jsx16, jsxs as jsxs13 } from "react/jsx-runtime";
1223
1942
  function formatNumber(value, decimals = 2, thousandSeparator = ",", decimalSeparator = ".") {
1224
1943
  return new Intl.NumberFormat("en-US", {
1225
1944
  minimumFractionDigits: 0,
@@ -1276,7 +1995,7 @@ function normalizeNumberInput(raw, options) {
1276
1995
  value
1277
1996
  };
1278
1997
  }
1279
- var NumberInput = forwardRef6(
1998
+ var NumberInput = forwardRef10(
1280
1999
  function NumberInput2({
1281
2000
  value,
1282
2001
  defaultValue = null,
@@ -1313,14 +2032,14 @@ var NumberInput = forwardRef6(
1313
2032
  onKeyDown,
1314
2033
  ...props
1315
2034
  }, ref) {
1316
- const inputRef = useRef5(null);
1317
- const generatedId = useId6();
2035
+ const inputRef = useRef8(null);
2036
+ const generatedId = useId8();
1318
2037
  const messageId2 = generatedId + "-message";
1319
2038
  const isControlled = value !== void 0;
1320
- const [internalValue, setInternalValue] = useState8(defaultValue);
1321
- const [focused, setFocused] = useState8(false);
2039
+ const [internalValue, setInternalValue] = useState12(defaultValue);
2040
+ const [focused, setFocused] = useState12(false);
1322
2041
  const actualValue = isControlled ? value ?? null : internalValue;
1323
- const [text, setText] = useState8(
2042
+ const [text, setText] = useState12(
1324
2043
  actualValue === null ? "" : formatNumber(
1325
2044
  actualValue,
1326
2045
  decimals,
@@ -1343,7 +2062,7 @@ var NumberInput = forwardRef6(
1343
2062
  );
1344
2063
  const resolvedPrefix = prefix ?? Prefix;
1345
2064
  const resolvedSuffix = suffix ?? Suffix;
1346
- useEffect5(() => {
2065
+ useEffect6(() => {
1347
2066
  if (!focused)
1348
2067
  setText(
1349
2068
  actualValue === null ? "" : formatNumber(
@@ -1397,7 +2116,7 @@ var NumberInput = forwardRef6(
1397
2116
  const stepIsUsable = Number.isFinite(step) && step > 0;
1398
2117
  const disableIncrement = Boolean(props.disabled || props.readOnly) || !stepIsUsable || max !== void 0 && actualValue !== null && actualValue >= max;
1399
2118
  const disableDecrement = Boolean(props.disabled || props.readOnly) || !stepIsUsable || min !== void 0 && actualValue !== null && actualValue <= min;
1400
- return /* @__PURE__ */ jsxs12(
2119
+ return /* @__PURE__ */ jsxs13(
1401
2120
  "div",
1402
2121
  {
1403
2122
  className: [
@@ -1406,7 +2125,7 @@ var NumberInput = forwardRef6(
1406
2125
  className
1407
2126
  ].filter(Boolean).join(" "),
1408
2127
  children: [
1409
- /* @__PURE__ */ jsx12(
2128
+ /* @__PURE__ */ jsx16(
1410
2129
  FieldLabel,
1411
2130
  {
1412
2131
  id: labelId,
@@ -1416,10 +2135,10 @@ var NumberInput = forwardRef6(
1416
2135
  isRequired
1417
2136
  }
1418
2137
  ),
1419
- /* @__PURE__ */ jsxs12("span", { className: "fe-number-input__control", children: [
1420
- resolvedPrefix && /* @__PURE__ */ jsx12("span", { className: "fe-number-input__prefix", children: resolvedPrefix }),
1421
- /* @__PURE__ */ jsxs12("span", { className: "fe-number-input__input-wrap", children: [
1422
- /* @__PURE__ */ jsx12(
2138
+ /* @__PURE__ */ jsxs13("span", { className: "fe-number-input__control", children: [
2139
+ resolvedPrefix && /* @__PURE__ */ jsx16("span", { className: "fe-number-input__prefix", children: resolvedPrefix }),
2140
+ /* @__PURE__ */ jsxs13("span", { className: "fe-number-input__input-wrap", children: [
2141
+ /* @__PURE__ */ jsx16(
1423
2142
  "input",
1424
2143
  {
1425
2144
  ref: (node) => {
@@ -1455,41 +2174,41 @@ var NumberInput = forwardRef6(
1455
2174
  "aria-describedby": describedBy
1456
2175
  }
1457
2176
  ),
1458
- isRequired && placeholder && !text && /* @__PURE__ */ jsxs12(
2177
+ isRequired && placeholder && !text && /* @__PURE__ */ jsxs13(
1459
2178
  "span",
1460
2179
  {
1461
2180
  className: "fe-number-input__placeholder",
1462
2181
  "aria-hidden": "true",
1463
2182
  children: [
1464
- /* @__PURE__ */ jsx12("span", { children: placeholder }),
1465
- /* @__PURE__ */ jsx12("span", { className: "fe-field__required", children: "*" })
2183
+ /* @__PURE__ */ jsx16("span", { children: placeholder }),
2184
+ /* @__PURE__ */ jsx16("span", { className: "fe-field__required", children: "*" })
1466
2185
  ]
1467
2186
  }
1468
2187
  )
1469
2188
  ] }),
1470
- resolvedSuffix && /* @__PURE__ */ jsx12("span", { className: "fe-number-input__suffix", children: resolvedSuffix }),
2189
+ resolvedSuffix && /* @__PURE__ */ jsx16("span", { className: "fe-number-input__suffix", children: resolvedSuffix }),
1471
2190
  endAdornment,
1472
- showStepper && /* @__PURE__ */ jsxs12("span", { className: "fe-number-input__stepper", children: [
1473
- /* @__PURE__ */ jsx12(
2191
+ showStepper && /* @__PURE__ */ jsxs13("span", { className: "fe-number-input__stepper", children: [
2192
+ /* @__PURE__ */ jsx16(
1474
2193
  Button,
1475
2194
  {
1476
2195
  hierarchy: "tertiary-gray",
1477
2196
  size: "24",
1478
2197
  iconOnly: true,
1479
- icon: /* @__PURE__ */ jsx12(ChevronUpIcon, { size: 12 }),
2198
+ icon: /* @__PURE__ */ jsx16(ChevronUpIcon, { size: 12 }),
1480
2199
  "aria-label": incrementLabel,
1481
2200
  disabled: disableIncrement,
1482
2201
  onMouseDown: (event) => event.preventDefault(),
1483
2202
  onClick: () => adjustValue(1)
1484
2203
  }
1485
2204
  ),
1486
- /* @__PURE__ */ jsx12(
2205
+ /* @__PURE__ */ jsx16(
1487
2206
  Button,
1488
2207
  {
1489
2208
  hierarchy: "tertiary-gray",
1490
2209
  size: "24",
1491
2210
  iconOnly: true,
1492
- icon: /* @__PURE__ */ jsx12(ChevronDownIcon, { size: 12 }),
2211
+ icon: /* @__PURE__ */ jsx16(ChevronDownIcon, { size: 12 }),
1493
2212
  "aria-label": decrementLabel,
1494
2213
  disabled: disableDecrement,
1495
2214
  onMouseDown: (event) => event.preventDefault(),
@@ -1498,7 +2217,7 @@ var NumberInput = forwardRef6(
1498
2217
  )
1499
2218
  ] })
1500
2219
  ] }),
1501
- /* @__PURE__ */ jsx12(
2220
+ /* @__PURE__ */ jsx16(
1502
2221
  FieldMessage,
1503
2222
  {
1504
2223
  id: messageId2,
@@ -1515,8 +2234,8 @@ var NumberInput = forwardRef6(
1515
2234
  NumberInput.displayName = "NumberInput";
1516
2235
 
1517
2236
  // packages/form-controls/src/controls/CurrencyInput/currency-input.tsx
1518
- import { useState as useState9 } from "react";
1519
- import { jsx as jsx13 } from "react/jsx-runtime";
2237
+ import { useState as useState13 } from "react";
2238
+ import { jsx as jsx17 } from "react/jsx-runtime";
1520
2239
  function CurrencyInput({
1521
2240
  suffix = "VND",
1522
2241
  currencies,
@@ -1527,13 +2246,13 @@ function CurrencyInput({
1527
2246
  disabled,
1528
2247
  ...props
1529
2248
  }) {
1530
- const [internalCurrency, setInternalCurrency] = useState9(
2249
+ const [internalCurrency, setInternalCurrency] = useState13(
1531
2250
  defaultCurrency ?? currencies?.[0]?.code ?? ""
1532
2251
  );
1533
2252
  const selectedCurrency = currency ?? internalCurrency;
1534
2253
  const current = currencies?.find((item) => item.code === selectedCurrency);
1535
2254
  const currencySuffix = current?.suffix ?? current?.code ?? suffix;
1536
- const endAdornment = currencies?.length ? /* @__PURE__ */ jsx13(
2255
+ const endAdornment = currencies?.length ? /* @__PURE__ */ jsx17(
1537
2256
  Selection,
1538
2257
  {
1539
2258
  className: "fe-currency-input__currency",
@@ -1552,8 +2271,8 @@ function CurrencyInput({
1552
2271
  onCurrencyChange?.(next);
1553
2272
  }
1554
2273
  }
1555
- ) : /* @__PURE__ */ jsx13("span", { className: "fe-currency-input__suffix", children: currencySuffix });
1556
- return /* @__PURE__ */ jsx13(
2274
+ ) : /* @__PURE__ */ jsx17("span", { className: "fe-currency-input__suffix", children: currencySuffix });
2275
+ return /* @__PURE__ */ jsx17(
1557
2276
  NumberInput,
1558
2277
  {
1559
2278
  ...props,
@@ -1565,8 +2284,8 @@ function CurrencyInput({
1565
2284
  }
1566
2285
 
1567
2286
  // packages/form-controls/src/controls/DateTimePicker/date-time-picker.tsx
1568
- import { useEffect as useEffect6, useId as useId7, useRef as useRef6, useState as useState10 } from "react";
1569
- import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
2287
+ import { useEffect as useEffect7, useId as useId9, useRef as useRef9, useState as useState14 } from "react";
2288
+ import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
1570
2289
  var pad = (value) => String(value).padStart(2, "0");
1571
2290
  function formatDate(date, format) {
1572
2291
  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()));
@@ -1602,7 +2321,7 @@ function DateTimePicker(props) {
1602
2321
  "aria-describedby": ariaDescribedBy,
1603
2322
  "aria-labelledby": ariaLabelledBy
1604
2323
  } = props;
1605
- const generatedId = useId7();
2324
+ const generatedId = useId9();
1606
2325
  const triggerId = id ?? generatedId + "-trigger";
1607
2326
  const labelId = generatedId + "-label";
1608
2327
  const messageId2 = generatedId + "-message";
@@ -1620,28 +2339,28 @@ function DateTimePicker(props) {
1620
2339
  );
1621
2340
  const isRange = mode === "range";
1622
2341
  const controlled = props.value !== void 0;
1623
- const [singleInternal, setSingleInternal] = useState10(
2342
+ const [singleInternal, setSingleInternal] = useState14(
1624
2343
  (!isRange ? props.defaultValue : null) ?? null
1625
2344
  );
1626
- const [rangeInternal, setRangeInternal] = useState10(
2345
+ const [rangeInternal, setRangeInternal] = useState14(
1627
2346
  (isRange ? props.defaultValue : void 0) ?? [null, null]
1628
2347
  );
1629
2348
  const singleValue = !isRange ? props.value ?? singleInternal : null;
1630
2349
  const rangeValue = isRange ? props.value ?? rangeInternal : [null, null];
1631
- const [open, setOpen] = useState10(false);
1632
- const [month, setMonth] = useState10(
2350
+ const [open, setOpen] = useState14(false);
2351
+ const [month, setMonth] = useState14(
1633
2352
  () => new Date((isRange ? rangeValue[0] : singleValue) ?? /* @__PURE__ */ new Date())
1634
2353
  );
1635
- const [editingEnd, setEditingEnd] = useState10(false);
1636
- const rootRef = useRef6(null);
1637
- useEffect6(() => {
2354
+ const [editingEnd, setEditingEnd] = useState14(false);
2355
+ const rootRef = useRef9(null);
2356
+ useEffect7(() => {
1638
2357
  const onPointerDown = (event) => {
1639
2358
  if (!rootRef.current?.contains(event.target)) setOpen(false);
1640
2359
  };
1641
2360
  document.addEventListener("mousedown", onPointerDown);
1642
2361
  return () => document.removeEventListener("mousedown", onPointerDown);
1643
2362
  }, []);
1644
- useEffect6(() => {
2363
+ useEffect7(() => {
1645
2364
  if (disabled) setOpen(false);
1646
2365
  }, [disabled]);
1647
2366
  const setSingle = (next) => {
@@ -1697,7 +2416,7 @@ function DateTimePicker(props) {
1697
2416
  setRange(editingEnd ? [rangeValue[0], next] : [next, rangeValue[1]]);
1698
2417
  else setSingle(next);
1699
2418
  };
1700
- return /* @__PURE__ */ jsxs13(
2419
+ return /* @__PURE__ */ jsxs14(
1701
2420
  "div",
1702
2421
  {
1703
2422
  ref: rootRef,
@@ -1707,7 +2426,7 @@ function DateTimePicker(props) {
1707
2426
  className
1708
2427
  ].filter(Boolean).join(" "),
1709
2428
  children: [
1710
- /* @__PURE__ */ jsx14(
2429
+ /* @__PURE__ */ jsx18(
1711
2430
  FieldLabel,
1712
2431
  {
1713
2432
  id: labelId,
@@ -1717,7 +2436,7 @@ function DateTimePicker(props) {
1717
2436
  isRequired
1718
2437
  }
1719
2438
  ),
1720
- /* @__PURE__ */ jsxs13(
2439
+ /* @__PURE__ */ jsxs14(
1721
2440
  "button",
1722
2441
  {
1723
2442
  id: triggerId,
@@ -1731,29 +2450,29 @@ function DateTimePicker(props) {
1731
2450
  "aria-expanded": open,
1732
2451
  onClick: () => setOpen((current) => !current),
1733
2452
  children: [
1734
- /* @__PURE__ */ jsx14("span", { "aria-hidden": "true", children: "\u25F7" }),
1735
- /* @__PURE__ */ jsxs13(
2453
+ /* @__PURE__ */ jsx18("span", { "aria-hidden": "true", children: "\u25F7" }),
2454
+ /* @__PURE__ */ jsxs14(
1736
2455
  "span",
1737
2456
  {
1738
2457
  className: !shownValue && placeholder ? "fe-datetime-picker__value is-placeholder" : "fe-datetime-picker__value",
1739
2458
  children: [
1740
2459
  shownValue || placeholder || (isRange ? "Select date range" : "Select date and time"),
1741
- isRequired && placeholder && !shownValue && /* @__PURE__ */ jsx14("span", { className: "fe-field__required", "aria-hidden": "true", children: "*" })
2460
+ isRequired && placeholder && !shownValue && /* @__PURE__ */ jsx18("span", { className: "fe-field__required", "aria-hidden": "true", children: "*" })
1742
2461
  ]
1743
2462
  }
1744
2463
  )
1745
2464
  ]
1746
2465
  }
1747
2466
  ),
1748
- open && /* @__PURE__ */ jsxs13(
2467
+ open && /* @__PURE__ */ jsxs14(
1749
2468
  "div",
1750
2469
  {
1751
2470
  className: "fe-datetime-picker__popper",
1752
2471
  role: "dialog",
1753
2472
  "aria-label": "Date and time picker",
1754
2473
  children: [
1755
- /* @__PURE__ */ jsxs13("div", { className: "fe-datetime-picker__month", children: [
1756
- /* @__PURE__ */ jsx14(
2474
+ /* @__PURE__ */ jsxs14("div", { className: "fe-datetime-picker__month", children: [
2475
+ /* @__PURE__ */ jsx18(
1757
2476
  "button",
1758
2477
  {
1759
2478
  type: "button",
@@ -1764,11 +2483,11 @@ function DateTimePicker(props) {
1764
2483
  children: "\u2039"
1765
2484
  }
1766
2485
  ),
1767
- /* @__PURE__ */ jsx14("strong", { children: month.toLocaleDateString(locale, {
2486
+ /* @__PURE__ */ jsx18("strong", { children: month.toLocaleDateString(locale, {
1768
2487
  month: "long",
1769
2488
  year: "numeric"
1770
2489
  }) }),
1771
- /* @__PURE__ */ jsx14(
2490
+ /* @__PURE__ */ jsx18(
1772
2491
  "button",
1773
2492
  {
1774
2493
  type: "button",
@@ -1780,12 +2499,12 @@ function DateTimePicker(props) {
1780
2499
  }
1781
2500
  )
1782
2501
  ] }),
1783
- /* @__PURE__ */ jsx14("div", { className: "fe-datetime-picker__weekdays", children: ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"].map((day) => /* @__PURE__ */ jsx14("span", { children: day }, day)) }),
1784
- /* @__PURE__ */ jsx14("div", { className: "fe-datetime-picker__days", children: days.map((day) => {
2502
+ /* @__PURE__ */ jsx18("div", { className: "fe-datetime-picker__weekdays", children: ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"].map((day) => /* @__PURE__ */ jsx18("span", { children: day }, day)) }),
2503
+ /* @__PURE__ */ jsx18("div", { className: "fe-datetime-picker__days", children: days.map((day) => {
1785
2504
  const inMonth = day.getMonth() === month.getMonth();
1786
2505
  const selected = isRange ? sameDay(day, rangeValue[0]) || sameDay(day, rangeValue[1]) : sameDay(day, singleValue);
1787
2506
  const inRange = isRange && rangeValue[0] && rangeValue[1] && day > startOfDay(rangeValue[0]) && day < startOfDay(rangeValue[1]);
1788
- return /* @__PURE__ */ jsx14(
2507
+ return /* @__PURE__ */ jsx18(
1789
2508
  "button",
1790
2509
  {
1791
2510
  type: "button",
@@ -1800,8 +2519,8 @@ function DateTimePicker(props) {
1800
2519
  day.toISOString()
1801
2520
  );
1802
2521
  }) }),
1803
- isRange && /* @__PURE__ */ jsxs13("div", { className: "fe-datetime-picker__range-tabs", children: [
1804
- /* @__PURE__ */ jsx14(
2522
+ isRange && /* @__PURE__ */ jsxs14("div", { className: "fe-datetime-picker__range-tabs", children: [
2523
+ /* @__PURE__ */ jsx18(
1805
2524
  "button",
1806
2525
  {
1807
2526
  type: "button",
@@ -1810,7 +2529,7 @@ function DateTimePicker(props) {
1810
2529
  children: "Start"
1811
2530
  }
1812
2531
  ),
1813
- /* @__PURE__ */ jsx14(
2532
+ /* @__PURE__ */ jsx18(
1814
2533
  "button",
1815
2534
  {
1816
2535
  type: "button",
@@ -1820,9 +2539,9 @@ function DateTimePicker(props) {
1820
2539
  }
1821
2540
  )
1822
2541
  ] }),
1823
- /* @__PURE__ */ jsxs13("label", { className: "fe-datetime-picker__time", children: [
2542
+ /* @__PURE__ */ jsxs14("label", { className: "fe-datetime-picker__time", children: [
1824
2543
  "Time",
1825
- /* @__PURE__ */ jsx14(
2544
+ /* @__PURE__ */ jsx18(
1826
2545
  "input",
1827
2546
  {
1828
2547
  type: "time",
@@ -1835,7 +2554,7 @@ function DateTimePicker(props) {
1835
2554
  ]
1836
2555
  }
1837
2556
  ),
1838
- /* @__PURE__ */ jsx14(
2557
+ /* @__PURE__ */ jsx18(
1839
2558
  FieldMessage,
1840
2559
  {
1841
2560
  id: messageId2,
@@ -1850,9 +2569,9 @@ function DateTimePicker(props) {
1850
2569
  }
1851
2570
 
1852
2571
  // packages/form-controls/src/controls/Checkbox/checkbox.tsx
1853
- import { forwardRef as forwardRef7 } from "react";
1854
- import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
1855
- var Checkbox = forwardRef7(
2572
+ import { forwardRef as forwardRef11 } from "react";
2573
+ import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
2574
+ var Checkbox = forwardRef11(
1856
2575
  function Checkbox2({
1857
2576
  label,
1858
2577
  labelPosition = "right",
@@ -1868,10 +2587,10 @@ var Checkbox = forwardRef7(
1868
2587
  disabled && "fe-checkbox--disabled",
1869
2588
  className
1870
2589
  ].filter(Boolean).join(" ");
1871
- return /* @__PURE__ */ jsxs14("label", { className: classes, style, children: [
1872
- label && labelPosition === "top" && /* @__PURE__ */ jsx15("span", { className: "fe-checkbox__label", children: label }),
1873
- /* @__PURE__ */ jsxs14("span", { className: "fe-checkbox__content", children: [
1874
- /* @__PURE__ */ jsx15(
2590
+ return /* @__PURE__ */ jsxs15("label", { className: classes, style, children: [
2591
+ label && labelPosition === "top" && /* @__PURE__ */ jsx19("span", { className: "fe-checkbox__label", children: label }),
2592
+ /* @__PURE__ */ jsxs15("span", { className: "fe-checkbox__content", children: [
2593
+ /* @__PURE__ */ jsx19(
1875
2594
  "input",
1876
2595
  {
1877
2596
  ref,
@@ -1882,8 +2601,8 @@ var Checkbox = forwardRef7(
1882
2601
  ...props
1883
2602
  }
1884
2603
  ),
1885
- /* @__PURE__ */ jsx15("span", { className: "fe-checkbox__control", "aria-hidden": "true" }),
1886
- label && labelPosition === "right" && /* @__PURE__ */ jsx15("span", { className: "fe-checkbox__label", children: label })
2604
+ /* @__PURE__ */ jsx19("span", { className: "fe-checkbox__control", "aria-hidden": "true" }),
2605
+ label && labelPosition === "right" && /* @__PURE__ */ jsx19("span", { className: "fe-checkbox__label", children: label })
1887
2606
  ] })
1888
2607
  ] });
1889
2608
  }
@@ -1891,9 +2610,9 @@ var Checkbox = forwardRef7(
1891
2610
  Checkbox.displayName = "Checkbox";
1892
2611
 
1893
2612
  // packages/form-controls/src/controls/RadioButton/radio-button.tsx
1894
- import { forwardRef as forwardRef8 } from "react";
1895
- import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
1896
- var RadioButton = forwardRef8(
2613
+ import { forwardRef as forwardRef12 } from "react";
2614
+ import { jsx as jsx20, jsxs as jsxs16 } from "react/jsx-runtime";
2615
+ var RadioButton = forwardRef12(
1897
2616
  function RadioButton2({
1898
2617
  label,
1899
2618
  labelPosition = "right",
@@ -1909,10 +2628,10 @@ var RadioButton = forwardRef8(
1909
2628
  disabled && "fe-radio-button--disabled",
1910
2629
  className
1911
2630
  ].filter(Boolean).join(" ");
1912
- return /* @__PURE__ */ jsxs15("label", { className: classes, style, children: [
1913
- label && labelPosition === "top" && /* @__PURE__ */ jsx16("span", { className: "fe-radio-button__label", children: label }),
1914
- /* @__PURE__ */ jsxs15("span", { className: "fe-radio-button__content", children: [
1915
- /* @__PURE__ */ jsx16(
2631
+ return /* @__PURE__ */ jsxs16("label", { className: classes, style, children: [
2632
+ label && labelPosition === "top" && /* @__PURE__ */ jsx20("span", { className: "fe-radio-button__label", children: label }),
2633
+ /* @__PURE__ */ jsxs16("span", { className: "fe-radio-button__content", children: [
2634
+ /* @__PURE__ */ jsx20(
1916
2635
  "input",
1917
2636
  {
1918
2637
  ref,
@@ -1923,8 +2642,8 @@ var RadioButton = forwardRef8(
1923
2642
  ...props
1924
2643
  }
1925
2644
  ),
1926
- /* @__PURE__ */ jsx16("span", { className: "fe-radio-button__control", "aria-hidden": "true" }),
1927
- label && labelPosition === "right" && /* @__PURE__ */ jsx16("span", { className: "fe-radio-button__label", children: label })
2645
+ /* @__PURE__ */ jsx20("span", { className: "fe-radio-button__control", "aria-hidden": "true" }),
2646
+ label && labelPosition === "right" && /* @__PURE__ */ jsx20("span", { className: "fe-radio-button__label", children: label })
1928
2647
  ] })
1929
2648
  ] });
1930
2649
  }
@@ -1932,9 +2651,9 @@ var RadioButton = forwardRef8(
1932
2651
  RadioButton.displayName = "RadioButton";
1933
2652
 
1934
2653
  // packages/form-controls/src/controls/RadioGroup/radio-group.tsx
1935
- import { forwardRef as forwardRef9, useId as useId8 } from "react";
1936
- import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
1937
- var RadioGroup = forwardRef9(
2654
+ import { forwardRef as forwardRef13, useId as useId10 } from "react";
2655
+ import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
2656
+ var RadioGroup = forwardRef13(
1938
2657
  function RadioGroup2({
1939
2658
  label,
1940
2659
  labelPosition = "top",
@@ -1952,7 +2671,7 @@ var RadioGroup = forwardRef9(
1952
2671
  "aria-labelledby": ariaLabelledBy,
1953
2672
  ...props
1954
2673
  }, ref) {
1955
- const generatedId = useId8();
2674
+ const generatedId = useId10();
1956
2675
  const groupName = name ?? `fe-radio-group-${generatedId}`;
1957
2676
  const labelId = `${id ?? generatedId}-label`;
1958
2677
  const isControlled = value !== void 0;
@@ -1966,12 +2685,12 @@ var RadioGroup = forwardRef9(
1966
2685
  const handleChange = (option, event) => {
1967
2686
  if (event.target.checked) onChange?.(option.value, option, event);
1968
2687
  };
1969
- return /* @__PURE__ */ jsxs16("div", { ref, className: classes, ...props, children: [
1970
- label && labelPosition === "top" && /* @__PURE__ */ jsxs16("span", { id: labelId, className: "fe-radio-group__label", children: [
2688
+ return /* @__PURE__ */ jsxs17("div", { ref, className: classes, ...props, children: [
2689
+ label && labelPosition === "top" && /* @__PURE__ */ jsxs17("span", { id: labelId, className: "fe-radio-group__label", children: [
1971
2690
  label,
1972
- isRequired && /* @__PURE__ */ jsx17("span", { className: "fe-radio-group__required", "aria-hidden": "true", children: "*" })
2691
+ isRequired && /* @__PURE__ */ jsx21("span", { className: "fe-radio-group__required", "aria-hidden": "true", children: "*" })
1973
2692
  ] }),
1974
- /* @__PURE__ */ jsx17(
2693
+ /* @__PURE__ */ jsx21(
1975
2694
  "div",
1976
2695
  {
1977
2696
  id,
@@ -1983,7 +2702,7 @@ var RadioGroup = forwardRef9(
1983
2702
  children: options.map((option) => {
1984
2703
  const optionDisabled = disabled || option.disabled;
1985
2704
  const optionValue = String(option.value);
1986
- return /* @__PURE__ */ jsx17(
2705
+ return /* @__PURE__ */ jsx21(
1987
2706
  RadioButton,
1988
2707
  {
1989
2708
  name: groupName,
@@ -2000,9 +2719,9 @@ var RadioGroup = forwardRef9(
2000
2719
  })
2001
2720
  }
2002
2721
  ),
2003
- label && labelPosition === "right" && /* @__PURE__ */ jsxs16("span", { id: labelId, className: "fe-radio-group__label", children: [
2722
+ label && labelPosition === "right" && /* @__PURE__ */ jsxs17("span", { id: labelId, className: "fe-radio-group__label", children: [
2004
2723
  label,
2005
- isRequired && /* @__PURE__ */ jsx17("span", { className: "fe-radio-group__required", "aria-hidden": "true", children: "*" })
2724
+ isRequired && /* @__PURE__ */ jsx21("span", { className: "fe-radio-group__required", "aria-hidden": "true", children: "*" })
2006
2725
  ] })
2007
2726
  ] });
2008
2727
  }
@@ -2010,29 +2729,29 @@ var RadioGroup = forwardRef9(
2010
2729
  RadioGroup.displayName = "RadioGroup";
2011
2730
 
2012
2731
  // packages/expandable-section/src/index.tsx
2013
- import { useId as useId9, useState as useState11 } from "react";
2014
- import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
2732
+ import { useId as useId11, useState as useState15 } from "react";
2733
+ import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
2015
2734
  function ExpandableSection({ title, children, expanded, defaultExpanded = false, onExpandedChange, disabled, className, ...props }) {
2016
- const [internalExpanded, setInternalExpanded] = useState11(defaultExpanded);
2735
+ const [internalExpanded, setInternalExpanded] = useState15(defaultExpanded);
2017
2736
  const isExpanded = expanded ?? internalExpanded;
2018
- const id = useId9();
2737
+ const id = useId11();
2019
2738
  const toggle = () => {
2020
2739
  if (disabled) return;
2021
2740
  const next = !isExpanded;
2022
2741
  if (expanded === void 0) setInternalExpanded(next);
2023
2742
  onExpandedChange?.(next);
2024
2743
  };
2025
- return /* @__PURE__ */ jsxs17("section", { className: ["fe-expandable-section", isExpanded && "fe-expandable-section--expanded", disabled && "fe-expandable-section--disabled", className].filter(Boolean).join(" "), ...props, children: [
2026
- /* @__PURE__ */ jsxs17("button", { className: "fe-expandable-section__trigger", type: "button", "aria-expanded": isExpanded, "aria-controls": id, disabled, onClick: toggle, children: [
2027
- /* @__PURE__ */ jsx18("span", { children: title }),
2028
- /* @__PURE__ */ jsx18("span", { className: "fe-expandable-section__chevron", "aria-hidden": "true" })
2744
+ return /* @__PURE__ */ jsxs18("section", { className: ["fe-expandable-section", isExpanded && "fe-expandable-section--expanded", disabled && "fe-expandable-section--disabled", className].filter(Boolean).join(" "), ...props, children: [
2745
+ /* @__PURE__ */ jsxs18("button", { className: "fe-expandable-section__trigger", type: "button", "aria-expanded": isExpanded, "aria-controls": id, disabled, onClick: toggle, children: [
2746
+ /* @__PURE__ */ jsx22("span", { children: title }),
2747
+ /* @__PURE__ */ jsx22("span", { className: "fe-expandable-section__chevron", "aria-hidden": "true" })
2029
2748
  ] }),
2030
- /* @__PURE__ */ jsx18("div", { id, className: "fe-expandable-section__content", "aria-hidden": !isExpanded, children: /* @__PURE__ */ jsx18("div", { className: "fe-expandable-section__content-inner", children }) })
2749
+ /* @__PURE__ */ jsx22("div", { id, className: "fe-expandable-section__content", "aria-hidden": !isExpanded, children: /* @__PURE__ */ jsx22("div", { className: "fe-expandable-section__content-inner", children }) })
2031
2750
  ] });
2032
2751
  }
2033
2752
 
2034
2753
  // packages/loading/src/index.tsx
2035
- import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
2754
+ import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
2036
2755
  var sizes = {
2037
2756
  small: "16px",
2038
2757
  medium: "24px",
@@ -2045,15 +2764,15 @@ function Loading({ size = "medium", color = "#2878f0", label, className, style,
2045
2764
  "--fe-loading-color": color,
2046
2765
  ...style
2047
2766
  };
2048
- return /* @__PURE__ */ jsxs18("span", { className: ["fe-loading", className].filter(Boolean).join(" "), style: loadingStyle, role: "status", ...props, children: [
2049
- /* @__PURE__ */ jsx19("span", { className: "fe-loading__spinner", "aria-hidden": "true" }),
2050
- label && /* @__PURE__ */ jsx19("span", { className: "fe-loading__label", children: label }),
2051
- !label && /* @__PURE__ */ jsx19("span", { className: "fe-loading__sr-only", children: "Loading" })
2767
+ return /* @__PURE__ */ jsxs19("span", { className: ["fe-loading", className].filter(Boolean).join(" "), style: loadingStyle, role: "status", ...props, children: [
2768
+ /* @__PURE__ */ jsx23("span", { className: "fe-loading__spinner", "aria-hidden": "true" }),
2769
+ label && /* @__PURE__ */ jsx23("span", { className: "fe-loading__label", children: label }),
2770
+ !label && /* @__PURE__ */ jsx23("span", { className: "fe-loading__sr-only", children: "Loading" })
2052
2771
  ] });
2053
2772
  }
2054
2773
 
2055
2774
  // packages/skeleton/src/index.tsx
2056
- import { Fragment as Fragment3, jsx as jsx20 } from "react/jsx-runtime";
2775
+ import { Fragment as Fragment3, jsx as jsx24 } from "react/jsx-runtime";
2057
2776
  var pixels = (value) => typeof value === "number" ? `${value}px` : value;
2058
2777
  function SkeletonBase({ variant = "box", shape, width, height, count = 1, animated = true, className, style, ...props }) {
2059
2778
  const resolvedVariant = shape ?? variant;
@@ -2064,7 +2783,7 @@ function SkeletonBase({ variant = "box", shape, width, height, count = 1, animat
2064
2783
  "--fe-skeleton-height": resolvedHeight,
2065
2784
  ...style
2066
2785
  };
2067
- return /* @__PURE__ */ jsx20(Fragment3, { children: Array.from({ length: Math.max(1, count) }, (_, index) => /* @__PURE__ */ jsx20(
2786
+ return /* @__PURE__ */ jsx24(Fragment3, { children: Array.from({ length: Math.max(1, count) }, (_, index) => /* @__PURE__ */ jsx24(
2068
2787
  "div",
2069
2788
  {
2070
2789
  className: ["fe-skeleton", `fe-skeleton--${resolvedVariant}`, animated && "fe-skeleton--animated", className].filter(Boolean).join(" "),
@@ -2076,16 +2795,16 @@ function SkeletonBase({ variant = "box", shape, width, height, count = 1, animat
2076
2795
  )) });
2077
2796
  }
2078
2797
  function SkeletonCircle({ size = 40, ...props }) {
2079
- return /* @__PURE__ */ jsx20(SkeletonBase, { variant: "circle", width: size, height: size, ...props });
2798
+ return /* @__PURE__ */ jsx24(SkeletonBase, { variant: "circle", width: size, height: size, ...props });
2080
2799
  }
2081
2800
  function SkeletonSquare({ size = 80, ...props }) {
2082
- return /* @__PURE__ */ jsx20(SkeletonBase, { variant: "box", width: size, height: size, ...props });
2801
+ return /* @__PURE__ */ jsx24(SkeletonBase, { variant: "box", width: size, height: size, ...props });
2083
2802
  }
2084
2803
  function SkeletonBox({ width = "100%", height = 80, ...props }) {
2085
- return /* @__PURE__ */ jsx20(SkeletonBase, { variant: "box", width, height, ...props });
2804
+ return /* @__PURE__ */ jsx24(SkeletonBase, { variant: "box", width, height, ...props });
2086
2805
  }
2087
2806
  function SkeletonLine({ width = "100%", height = 12, ...props }) {
2088
- return /* @__PURE__ */ jsx20(SkeletonBase, { variant: "line", width, height, ...props });
2807
+ return /* @__PURE__ */ jsx24(SkeletonBase, { variant: "line", width, height, ...props });
2089
2808
  }
2090
2809
  var Skeleton = Object.assign(SkeletonBase, {
2091
2810
  Circle: SkeletonCircle,
@@ -2095,9 +2814,12 @@ var Skeleton = Object.assign(SkeletonBase, {
2095
2814
  });
2096
2815
 
2097
2816
  // packages/modal/src/index.tsx
2098
- import { useEffect as useEffect7, useId as useId10, useRef as useRef7 } from "react";
2817
+ import {
2818
+ useId as useId12,
2819
+ useRef as useRef10
2820
+ } from "react";
2099
2821
  import { createPortal as createPortal3 } from "react-dom";
2100
- import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
2822
+ import { jsx as jsx25, jsxs as jsxs20 } from "react/jsx-runtime";
2101
2823
  function Modal({
2102
2824
  open,
2103
2825
  onClose,
@@ -2108,60 +2830,87 @@ function Modal({
2108
2830
  actions = [],
2109
2831
  size = "medium",
2110
2832
  closeOnBackdropClick = true,
2833
+ closeOnEscape = true,
2111
2834
  closeButton = true,
2112
2835
  closeLabel = "Close modal",
2836
+ initialFocusRef,
2837
+ restoreFocus = true,
2113
2838
  className,
2839
+ "aria-label": ariaLabel,
2840
+ "aria-describedby": ariaDescribedBy,
2114
2841
  ...props
2115
2842
  }) {
2116
- const titleId = useId10();
2117
- const panelRef = useRef7(null);
2118
- useEffect7(() => {
2119
- if (!open) return;
2120
- const onKeyDown = (event) => {
2121
- if (event.key === "Escape") onClose();
2122
- };
2123
- document.addEventListener("keydown", onKeyDown);
2124
- panelRef.current?.focus();
2125
- return () => document.removeEventListener("keydown", onKeyDown);
2126
- }, [onClose, open]);
2843
+ const titleId = useId12();
2844
+ const descriptionId = useId12();
2845
+ const panelRef = useRef10(null);
2846
+ useModalOverlay({
2847
+ open,
2848
+ onClose,
2849
+ panelRef,
2850
+ priority: 1100,
2851
+ closeOnEscape,
2852
+ initialFocusRef,
2853
+ restoreFocus
2854
+ });
2127
2855
  if (!open || typeof document === "undefined") return null;
2128
2856
  const hasFooter = footer || actions.length > 0;
2857
+ const describedBy = [description ? descriptionId : void 0, ariaDescribedBy].filter(Boolean).join(" ") || void 0;
2129
2858
  return createPortal3(
2130
- /* @__PURE__ */ jsx21("div", { className: "fe-modal-backdrop", role: "presentation", onMouseDown: (event) => {
2131
- if (event.target === event.currentTarget && closeOnBackdropClick) onClose();
2132
- }, children: /* @__PURE__ */ jsxs19(
2859
+ /* @__PURE__ */ jsx25(
2133
2860
  "div",
2134
2861
  {
2135
- ref: panelRef,
2136
- className: ["fe-modal", `fe-modal--${size}`, className].filter(Boolean).join(" "),
2137
- role: "dialog",
2138
- "aria-modal": "true",
2139
- "aria-labelledby": title ? titleId : void 0,
2140
- "aria-label": title ? void 0 : "Modal",
2141
- tabIndex: -1,
2142
- ...props,
2143
- children: [
2144
- (title || description || closeButton) && /* @__PURE__ */ jsxs19("header", { className: "fe-modal__header", children: [
2145
- /* @__PURE__ */ jsxs19("div", { className: "fe-modal__heading", children: [
2146
- title && /* @__PURE__ */ jsx21("h2", { id: titleId, children: title }),
2147
- description && /* @__PURE__ */ jsx21("p", { children: description })
2148
- ] }),
2149
- closeButton && /* @__PURE__ */ jsx21(Button, { hierarchy: "tertiary-gray", size: "32", iconOnly: true, icon: /* @__PURE__ */ jsx21(CloseIcon, {}), "aria-label": closeLabel, onClick: onClose })
2150
- ] }),
2151
- /* @__PURE__ */ jsx21("div", { className: "fe-modal__body", children }),
2152
- hasFooter && /* @__PURE__ */ jsxs19("footer", { className: "fe-modal__footer", children: [
2153
- footer && /* @__PURE__ */ jsx21("div", { className: "fe-modal__footer-content", children: footer }),
2154
- actions.length > 0 && /* @__PURE__ */ jsx21("div", { className: "fe-modal__actions", children: actions.map(({ label, ...action }, index) => /* @__PURE__ */ jsx21(Button, { ...action, children: label }, index)) })
2155
- ] })
2156
- ]
2862
+ className: "fe-modal-backdrop",
2863
+ role: "presentation",
2864
+ onMouseDown: (event) => {
2865
+ if (event.target === event.currentTarget && closeOnBackdropClick)
2866
+ onClose();
2867
+ },
2868
+ children: /* @__PURE__ */ jsxs20(
2869
+ "div",
2870
+ {
2871
+ ref: panelRef,
2872
+ className: ["fe-modal", `fe-modal--${size}`, className].filter(Boolean).join(" "),
2873
+ role: "dialog",
2874
+ "aria-modal": "true",
2875
+ "aria-labelledby": title ? titleId : void 0,
2876
+ "aria-describedby": describedBy,
2877
+ "aria-label": ariaLabel ?? (title ? void 0 : "Modal"),
2878
+ tabIndex: -1,
2879
+ ...props,
2880
+ children: [
2881
+ (title || description || closeButton) && /* @__PURE__ */ jsxs20("header", { className: "fe-modal__header", children: [
2882
+ /* @__PURE__ */ jsxs20("div", { className: "fe-modal__heading", children: [
2883
+ title && /* @__PURE__ */ jsx25("h2", { id: titleId, children: title }),
2884
+ description && /* @__PURE__ */ jsx25("p", { id: descriptionId, children: description })
2885
+ ] }),
2886
+ closeButton && /* @__PURE__ */ jsx25(
2887
+ Button,
2888
+ {
2889
+ hierarchy: "tertiary-gray",
2890
+ size: "32",
2891
+ iconOnly: true,
2892
+ icon: /* @__PURE__ */ jsx25(CloseIcon, {}),
2893
+ "aria-label": closeLabel,
2894
+ onClick: onClose
2895
+ }
2896
+ )
2897
+ ] }),
2898
+ /* @__PURE__ */ jsx25("div", { className: "fe-modal__body", children }),
2899
+ hasFooter && /* @__PURE__ */ jsxs20("footer", { className: "fe-modal__footer", children: [
2900
+ footer && /* @__PURE__ */ jsx25("div", { className: "fe-modal__footer-content", children: footer }),
2901
+ actions.length > 0 && /* @__PURE__ */ jsx25("div", { className: "fe-modal__actions", children: actions.map(({ label, ...action }, index) => /* @__PURE__ */ jsx25(Button, { ...action, children: label }, index)) })
2902
+ ] })
2903
+ ]
2904
+ }
2905
+ )
2157
2906
  }
2158
- ) }),
2907
+ ),
2159
2908
  document.body
2160
2909
  );
2161
2910
  }
2162
2911
 
2163
2912
  // packages/progress/src/index.tsx
2164
- import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
2913
+ import { jsx as jsx26, jsxs as jsxs21 } from "react/jsx-runtime";
2165
2914
  function ProgressBar({ value, max = 100, label, showValue = true, size = "medium", color = "#2878f0", className, style, "aria-label": ariaLabel, ...props }) {
2166
2915
  const indeterminate = value === null || value === void 0;
2167
2916
  const percentage = indeterminate ? 0 : Math.min(100, Math.max(0, Number(value) / Math.max(1, max) * 100));
@@ -2171,17 +2920,17 @@ function ProgressBar({ value, max = 100, label, showValue = true, size = "medium
2171
2920
  ...style
2172
2921
  };
2173
2922
  const visibleValue = `${Math.round(percentage)}%`;
2174
- return /* @__PURE__ */ jsxs20("div", { className: ["fe-progress", `fe-progress--${size}`, indeterminate && "fe-progress--indeterminate", className].filter(Boolean).join(" "), style: progressStyle, ...props, children: [
2175
- (label || !indeterminate && showValue) && /* @__PURE__ */ jsxs20("div", { className: "fe-progress__meta", children: [
2176
- label && /* @__PURE__ */ jsx22("span", { className: "fe-progress__label", children: label }),
2177
- !indeterminate && showValue && /* @__PURE__ */ jsx22("output", { className: "fe-progress__value", children: visibleValue })
2923
+ return /* @__PURE__ */ jsxs21("div", { className: ["fe-progress", `fe-progress--${size}`, indeterminate && "fe-progress--indeterminate", className].filter(Boolean).join(" "), style: progressStyle, ...props, children: [
2924
+ (label || !indeterminate && showValue) && /* @__PURE__ */ jsxs21("div", { className: "fe-progress__meta", children: [
2925
+ label && /* @__PURE__ */ jsx26("span", { className: "fe-progress__label", children: label }),
2926
+ !indeterminate && showValue && /* @__PURE__ */ jsx26("output", { className: "fe-progress__value", children: visibleValue })
2178
2927
  ] }),
2179
- /* @__PURE__ */ jsx22("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__ */ jsx22("span", { className: "fe-progress__indicator" }) })
2928
+ /* @__PURE__ */ jsx26("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__ */ jsx26("span", { className: "fe-progress__indicator" }) })
2180
2929
  ] });
2181
2930
  }
2182
2931
 
2183
2932
  // packages/chip/src/index.tsx
2184
- import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
2933
+ import { jsx as jsx27, jsxs as jsxs22 } from "react/jsx-runtime";
2185
2934
  var statuses = ["default", "info", "success", "warning", "error", "neutral", "pending", "processing"];
2186
2935
  function Chip({ children, status = "default", color, variant = "subtle", dot = false, onRemove, removeLabel = "Remove", className, style, ...props }) {
2187
2936
  const usesCustomColor = Boolean(color);
@@ -2190,16 +2939,16 @@ function Chip({ children, status = "default", color, variant = "subtle", dot = f
2190
2939
  ...style
2191
2940
  };
2192
2941
  const resolvedStatus = statuses.includes(status) ? status : "default";
2193
- return /* @__PURE__ */ jsxs21("span", { className: ["fe-chip", `fe-chip--${variant}`, `fe-chip--${usesCustomColor ? "custom" : resolvedStatus}`, className].filter(Boolean).join(" "), style: chipStyle, ...props, children: [
2194
- dot && /* @__PURE__ */ jsx23("span", { className: "fe-chip__dot", "aria-hidden": "true" }),
2195
- /* @__PURE__ */ jsx23("span", { className: "fe-chip__content", children }),
2196
- onRemove && /* @__PURE__ */ jsx23(Button, { hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: /* @__PURE__ */ jsx23(CloseIcon, { size: 14 }), "aria-label": removeLabel, onClick: onRemove, className: "fe-chip__remove" })
2942
+ return /* @__PURE__ */ jsxs22("span", { className: ["fe-chip", `fe-chip--${variant}`, `fe-chip--${usesCustomColor ? "custom" : resolvedStatus}`, className].filter(Boolean).join(" "), style: chipStyle, ...props, children: [
2943
+ dot && /* @__PURE__ */ jsx27("span", { className: "fe-chip__dot", "aria-hidden": "true" }),
2944
+ /* @__PURE__ */ jsx27("span", { className: "fe-chip__content", children }),
2945
+ onRemove && /* @__PURE__ */ jsx27(Button, { hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: /* @__PURE__ */ jsx27(CloseIcon, { size: 14 }), "aria-label": removeLabel, onClick: onRemove, className: "fe-chip__remove" })
2197
2946
  ] });
2198
2947
  }
2199
2948
 
2200
2949
  // packages/message/src/index.tsx
2201
- import { useEffect as useEffect8, useState as useState12 } from "react";
2202
- import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
2950
+ import { useEffect as useEffect8, useState as useState16 } from "react";
2951
+ import { jsx as jsx28, jsxs as jsxs23 } from "react/jsx-runtime";
2203
2952
  var messageId = 0;
2204
2953
  var entries = [];
2205
2954
  var listeners = /* @__PURE__ */ new Set();
@@ -2232,7 +2981,7 @@ var message = {
2232
2981
  };
2233
2982
  var icons = { success: "\u2713", info: "i", warning: "!", error: "\xD7" };
2234
2983
  function Message({ maxCount = 4, closeLabel = "Close notification", className, ...props }) {
2235
- const [visibleEntries, setVisibleEntries] = useState12(entries);
2984
+ const [visibleEntries, setVisibleEntries] = useState16(entries);
2236
2985
  useEffect8(() => {
2237
2986
  const listener = (nextEntries) => setVisibleEntries(nextEntries);
2238
2987
  listeners.add(listener);
@@ -2240,14 +2989,14 @@ function Message({ maxCount = 4, closeLabel = "Close notification", className, .
2240
2989
  listeners.delete(listener);
2241
2990
  };
2242
2991
  }, []);
2243
- return /* @__PURE__ */ jsx24("div", { className: ["fe-message-viewport", className].filter(Boolean).join(" "), "aria-live": "polite", ...props, children: visibleEntries.slice(-Math.max(1, maxCount)).map((entry) => /* @__PURE__ */ jsxs22("div", { className: `fe-message fe-message--${entry.severity ?? "info"}`, role: entry.severity === "error" ? "alert" : "status", children: [
2244
- /* @__PURE__ */ jsx24("span", { className: "fe-message__icon", "aria-hidden": "true", children: icons[entry.severity ?? "info"] }),
2245
- /* @__PURE__ */ jsxs22("div", { className: "fe-message__body", children: [
2246
- entry.title && /* @__PURE__ */ jsx24("strong", { className: "fe-message__title", children: entry.title }),
2247
- /* @__PURE__ */ jsx24("div", { className: "fe-message__content", children: entry.content })
2992
+ return /* @__PURE__ */ jsx28("div", { className: ["fe-message-viewport", className].filter(Boolean).join(" "), "aria-live": "polite", ...props, children: visibleEntries.slice(-Math.max(1, maxCount)).map((entry) => /* @__PURE__ */ jsxs23("div", { className: `fe-message fe-message--${entry.severity ?? "info"}`, role: entry.severity === "error" ? "alert" : "status", children: [
2993
+ /* @__PURE__ */ jsx28("span", { className: "fe-message__icon", "aria-hidden": "true", children: icons[entry.severity ?? "info"] }),
2994
+ /* @__PURE__ */ jsxs23("div", { className: "fe-message__body", children: [
2995
+ entry.title && /* @__PURE__ */ jsx28("strong", { className: "fe-message__title", children: entry.title }),
2996
+ /* @__PURE__ */ jsx28("div", { className: "fe-message__content", children: entry.content })
2248
2997
  ] }),
2249
- entry.action && /* @__PURE__ */ jsx24("span", { className: "fe-message__action", children: entry.action }),
2250
- /* @__PURE__ */ jsx24(Button, { className: "fe-message__close", hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: "\xD7", "aria-label": closeLabel, onClick: () => dismiss(entry.id) })
2998
+ entry.action && /* @__PURE__ */ jsx28("span", { className: "fe-message__action", children: entry.action }),
2999
+ /* @__PURE__ */ jsx28(Button, { className: "fe-message__close", hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: "\xD7", "aria-label": closeLabel, onClick: () => dismiss(entry.id) })
2251
3000
  ] }, entry.id)) });
2252
3001
  }
2253
3002
  ((Message2) => {
@@ -2262,7 +3011,7 @@ function Message({ maxCount = 4, closeLabel = "Close notification", className, .
2262
3011
 
2263
3012
  // packages/snackbar/src/index.tsx
2264
3013
  import { useEffect as useEffect9 } from "react";
2265
- import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
3014
+ import { jsx as jsx29, jsxs as jsxs24 } from "react/jsx-runtime";
2266
3015
  function Snackbar({
2267
3016
  open,
2268
3017
  message: message2,
@@ -2290,16 +3039,16 @@ function Snackbar({
2290
3039
  return () => window.removeEventListener("keydown", onKeyDown);
2291
3040
  }, [open, onClose]);
2292
3041
  if (!open) return null;
2293
- return /* @__PURE__ */ jsx25("div", { className: ["fe-snackbar", `fe-snackbar--${vertical}`, `fe-snackbar--${horizontal}`, className].filter(Boolean).join(" "), ...props, children: /* @__PURE__ */ jsxs23("div", { className: "fe-snackbar__content", role: "status", "aria-live": "polite", children: [
2294
- /* @__PURE__ */ jsx25("span", { className: "fe-snackbar__message", children: message2 }),
2295
- action && /* @__PURE__ */ jsx25("span", { className: "fe-snackbar__action", children: action }),
2296
- onClose && /* @__PURE__ */ jsx25(Button, { className: "fe-snackbar__close", hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: "\xD7", "aria-label": closeLabel, onClick: () => onClose("closeButton") })
3042
+ return /* @__PURE__ */ jsx29("div", { className: ["fe-snackbar", `fe-snackbar--${vertical}`, `fe-snackbar--${horizontal}`, className].filter(Boolean).join(" "), ...props, children: /* @__PURE__ */ jsxs24("div", { className: "fe-snackbar__content", role: "status", "aria-live": "polite", children: [
3043
+ /* @__PURE__ */ jsx29("span", { className: "fe-snackbar__message", children: message2 }),
3044
+ action && /* @__PURE__ */ jsx29("span", { className: "fe-snackbar__action", children: action }),
3045
+ onClose && /* @__PURE__ */ jsx29(Button, { className: "fe-snackbar__close", hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: "\xD7", "aria-label": closeLabel, onClick: () => onClose("closeButton") })
2297
3046
  ] }) });
2298
3047
  }
2299
3048
 
2300
3049
  // packages/avatar/src/index.tsx
2301
- import { Children, isValidElement as isValidElement2, useState as useState13 } from "react";
2302
- import { jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
3050
+ import { Children, isValidElement as isValidElement2, useState as useState17 } from "react";
3051
+ import { jsx as jsx30, jsxs as jsxs25 } from "react/jsx-runtime";
2303
3052
  var FALLBACK_AVATARS = [
2304
3053
  {
2305
3054
  background: "#E0E7FF",
@@ -2632,7 +3381,7 @@ function AvatarFallbackIcon({ avatar }) {
2632
3381
  shirt,
2633
3382
  skin
2634
3383
  } = avatar;
2635
- return /* @__PURE__ */ jsxs24(
3384
+ return /* @__PURE__ */ jsxs25(
2636
3385
  "svg",
2637
3386
  {
2638
3387
  className: "fe-avatar__fallback-icon",
@@ -2640,15 +3389,15 @@ function AvatarFallbackIcon({ avatar }) {
2640
3389
  focusable: "false",
2641
3390
  "aria-hidden": "true",
2642
3391
  children: [
2643
- /* @__PURE__ */ jsx26("rect", { width: "24", height: "24", fill: background }),
2644
- /* @__PURE__ */ jsx26(
3392
+ /* @__PURE__ */ jsx30("rect", { width: "24", height: "24", fill: background }),
3393
+ /* @__PURE__ */ jsx30(
2645
3394
  "path",
2646
3395
  {
2647
3396
  d: "M3 24c.52-3.79 3.58-6.25 9-6.25S20.48 20.21 21 24",
2648
3397
  fill: shirt
2649
3398
  }
2650
3399
  ),
2651
- /* @__PURE__ */ jsx26(
3400
+ /* @__PURE__ */ jsx30(
2652
3401
  "path",
2653
3402
  {
2654
3403
  d: "M8.1 17.65h7.8l1.05 2.05H7.05l1.05-2.05Z",
@@ -2656,38 +3405,38 @@ function AvatarFallbackIcon({ avatar }) {
2656
3405
  opacity: ".72"
2657
3406
  }
2658
3407
  ),
2659
- /* @__PURE__ */ jsx26("circle", { cx: "12", cy: "10.25", r: "5.25", fill: skin }),
2660
- hairStyle === 0 && /* @__PURE__ */ jsx26(
3408
+ /* @__PURE__ */ jsx30("circle", { cx: "12", cy: "10.25", r: "5.25", fill: skin }),
3409
+ hairStyle === 0 && /* @__PURE__ */ jsx30(
2661
3410
  "path",
2662
3411
  {
2663
3412
  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",
2664
3413
  fill: hair
2665
3414
  }
2666
3415
  ),
2667
- hairStyle === 1 && /* @__PURE__ */ jsx26(
3416
+ hairStyle === 1 && /* @__PURE__ */ jsx30(
2668
3417
  "path",
2669
3418
  {
2670
3419
  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",
2671
3420
  fill: hair
2672
3421
  }
2673
3422
  ),
2674
- hairStyle === 2 && /* @__PURE__ */ jsx26(
3423
+ hairStyle === 2 && /* @__PURE__ */ jsx30(
2675
3424
  "path",
2676
3425
  {
2677
3426
  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",
2678
3427
  fill: hair
2679
3428
  }
2680
3429
  ),
2681
- hairStyle === 3 && /* @__PURE__ */ jsx26(
3430
+ hairStyle === 3 && /* @__PURE__ */ jsx30(
2682
3431
  "path",
2683
3432
  {
2684
3433
  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",
2685
3434
  fill: hair
2686
3435
  }
2687
3436
  ),
2688
- /* @__PURE__ */ jsx26("circle", { cx: "10.05", cy: "10.65", r: ".48", fill: "#3B2924" }),
2689
- /* @__PURE__ */ jsx26("circle", { cx: "13.95", cy: "10.65", r: ".48", fill: "#3B2924" }),
2690
- expression === 0 && /* @__PURE__ */ jsx26(
3437
+ /* @__PURE__ */ jsx30("circle", { cx: "10.05", cy: "10.65", r: ".48", fill: "#3B2924" }),
3438
+ /* @__PURE__ */ jsx30("circle", { cx: "13.95", cy: "10.65", r: ".48", fill: "#3B2924" }),
3439
+ expression === 0 && /* @__PURE__ */ jsx30(
2691
3440
  "path",
2692
3441
  {
2693
3442
  d: "M10.25 13.2c1.08.66 2.42.66 3.5 0",
@@ -2697,7 +3446,7 @@ function AvatarFallbackIcon({ avatar }) {
2697
3446
  strokeLinecap: "round"
2698
3447
  }
2699
3448
  ),
2700
- expression === 1 && /* @__PURE__ */ jsx26(
3449
+ expression === 1 && /* @__PURE__ */ jsx30(
2701
3450
  "path",
2702
3451
  {
2703
3452
  d: "M10.5 13.2h3",
@@ -2707,7 +3456,7 @@ function AvatarFallbackIcon({ avatar }) {
2707
3456
  strokeLinecap: "round"
2708
3457
  }
2709
3458
  ),
2710
- expression === 2 && /* @__PURE__ */ jsx26(
3459
+ expression === 2 && /* @__PURE__ */ jsx30(
2711
3460
  "path",
2712
3461
  {
2713
3462
  d: "M10.6 13.38c.84-.44 1.96-.44 2.8 0",
@@ -2717,11 +3466,11 @@ function AvatarFallbackIcon({ avatar }) {
2717
3466
  strokeLinecap: "round"
2718
3467
  }
2719
3468
  ),
2720
- expression === 3 && /* @__PURE__ */ jsx26("circle", { cx: "12", cy: "13.2", r: ".82", fill: "#B95A5A" }),
2721
- glasses && /* @__PURE__ */ jsxs24("g", { fill: "none", stroke: "#3C4355", strokeWidth: ".65", children: [
2722
- /* @__PURE__ */ jsx26("circle", { cx: "10", cy: "10.55", r: "1.45" }),
2723
- /* @__PURE__ */ jsx26("circle", { cx: "14", cy: "10.55", r: "1.45" }),
2724
- /* @__PURE__ */ jsx26("path", { d: "M11.45 10.55h1.1M8.55 10.55H7.5m9 0h-1.05" })
3469
+ expression === 3 && /* @__PURE__ */ jsx30("circle", { cx: "12", cy: "13.2", r: ".82", fill: "#B95A5A" }),
3470
+ glasses && /* @__PURE__ */ jsxs25("g", { fill: "none", stroke: "#3C4355", strokeWidth: ".65", children: [
3471
+ /* @__PURE__ */ jsx30("circle", { cx: "10", cy: "10.55", r: "1.45" }),
3472
+ /* @__PURE__ */ jsx30("circle", { cx: "14", cy: "10.55", r: "1.45" }),
3473
+ /* @__PURE__ */ jsx30("path", { d: "M11.45 10.55h1.1M8.55 10.55H7.5m9 0h-1.05" })
2725
3474
  ] })
2726
3475
  ]
2727
3476
  }
@@ -2740,10 +3489,10 @@ function Avatar({
2740
3489
  "aria-label": ariaLabel,
2741
3490
  ...props
2742
3491
  }) {
2743
- const [generatedFallbackIndex] = useState13(
3492
+ const [generatedFallbackIndex] = useState17(
2744
3493
  () => Math.floor(Math.random() * FALLBACK_AVATARS.length)
2745
3494
  );
2746
- const [failedImageSrc, setFailedImageSrc] = useState13();
3495
+ const [failedImageSrc, setFailedImageSrc] = useState17();
2747
3496
  const imageSrc = src?.trim();
2748
3497
  const trimmedContent = content?.trim() ?? "";
2749
3498
  const showImage = Boolean(imageSrc && failedImageSrc !== imageSrc);
@@ -2755,7 +3504,7 @@ function Avatar({
2755
3504
  ...style
2756
3505
  };
2757
3506
  const fallbackLabel = (alt ?? trimmedContent) || "Avatar";
2758
- return /* @__PURE__ */ jsxs24(
3507
+ return /* @__PURE__ */ jsxs25(
2759
3508
  "span",
2760
3509
  {
2761
3510
  className: ["fe-avatar", `fe-avatar--${shape}`, className].filter(Boolean).join(" "),
@@ -2764,7 +3513,7 @@ function Avatar({
2764
3513
  "aria-label": showImage ? ariaLabel : ariaLabel ?? fallbackLabel,
2765
3514
  ...props,
2766
3515
  children: [
2767
- showImage && /* @__PURE__ */ jsx26(
3516
+ showImage && /* @__PURE__ */ jsx30(
2768
3517
  "img",
2769
3518
  {
2770
3519
  className: "fe-avatar__image",
@@ -2773,8 +3522,8 @@ function Avatar({
2773
3522
  onError: () => setFailedImageSrc(imageSrc)
2774
3523
  }
2775
3524
  ),
2776
- !showImage && initials && /* @__PURE__ */ jsx26("span", { className: "fe-avatar__initials", "aria-hidden": "true", children: initials }),
2777
- !showImage && !initials && /* @__PURE__ */ jsx26(AvatarFallbackIcon, { avatar: selectedFallback })
3525
+ !showImage && initials && /* @__PURE__ */ jsx30("span", { className: "fe-avatar__initials", "aria-hidden": "true", children: initials }),
3526
+ !showImage && !initials && /* @__PURE__ */ jsx30(AvatarFallbackIcon, { avatar: selectedFallback })
2778
3527
  ]
2779
3528
  }
2780
3529
  );
@@ -2800,7 +3549,7 @@ function AvatarGroup({
2800
3549
  "--fe-avatar-font-size": resolveFontSize(firstAvatarSize)
2801
3550
  };
2802
3551
  const singleContent = avatars.length === 1 ? avatars[0]?.props.content?.trim() ?? "" : "";
2803
- return /* @__PURE__ */ jsxs24(
3552
+ return /* @__PURE__ */ jsxs25(
2804
3553
  "div",
2805
3554
  {
2806
3555
  className: ["fe-avatar-group", className].filter(Boolean).join(" "),
@@ -2808,8 +3557,8 @@ function AvatarGroup({
2808
3557
  role: role ?? "group",
2809
3558
  ...props,
2810
3559
  children: [
2811
- /* @__PURE__ */ jsxs24("div", { className: "fe-avatar-group__items", children: [
2812
- visibleAvatars.map((avatar, index) => /* @__PURE__ */ jsx26(
3560
+ /* @__PURE__ */ jsxs25("div", { className: "fe-avatar-group__items", children: [
3561
+ visibleAvatars.map((avatar, index) => /* @__PURE__ */ jsx30(
2813
3562
  "span",
2814
3563
  {
2815
3564
  className: "fe-avatar-group__item",
@@ -2818,7 +3567,7 @@ function AvatarGroup({
2818
3567
  },
2819
3568
  avatar.key ?? index
2820
3569
  )),
2821
- hasOverflow && /* @__PURE__ */ jsxs24(
3570
+ hasOverflow && /* @__PURE__ */ jsxs25(
2822
3571
  "span",
2823
3572
  {
2824
3573
  className: "fe-avatar-group__more",
@@ -2832,11 +3581,645 @@ function AvatarGroup({
2832
3581
  }
2833
3582
  )
2834
3583
  ] }),
2835
- singleContent && /* @__PURE__ */ jsx26("span", { className: "fe-avatar-group__content", children: singleContent })
3584
+ singleContent && /* @__PURE__ */ jsx30("span", { className: "fe-avatar-group__content", children: singleContent })
2836
3585
  ]
2837
3586
  }
2838
3587
  );
2839
3588
  }
3589
+
3590
+ // packages/file-upload/src/index.tsx
3591
+ import {
3592
+ forwardRef as forwardRef14,
3593
+ useId as useId13,
3594
+ useMemo as useMemo3,
3595
+ useRef as useRef11,
3596
+ useState as useState18,
3597
+ useEffect as useEffect10
3598
+ } from "react";
3599
+ import { jsx as jsx31, jsxs as jsxs26 } from "react/jsx-runtime";
3600
+ var FILE_UPLOAD_ACCEPTS = {
3601
+ all: [],
3602
+ image: [
3603
+ "image/*",
3604
+ ".avif",
3605
+ ".bmp",
3606
+ ".gif",
3607
+ ".heic",
3608
+ ".heif",
3609
+ ".ico",
3610
+ ".jpeg",
3611
+ ".jpg",
3612
+ ".png",
3613
+ ".svg",
3614
+ ".tif",
3615
+ ".tiff",
3616
+ ".webp"
3617
+ ],
3618
+ pdf: [".pdf"],
3619
+ word: [".doc", ".docm", ".docx", ".dot", ".dotx", ".odt", ".rtf"],
3620
+ spreadsheet: [".csv", ".ods", ".xls", ".xlsb", ".xlsm", ".xlsx"],
3621
+ presentation: [".odp", ".pot", ".potx", ".pps", ".ppsx", ".ppt", ".pptx"],
3622
+ document: [
3623
+ ".pdf",
3624
+ ".doc",
3625
+ ".docm",
3626
+ ".docx",
3627
+ ".dot",
3628
+ ".dotx",
3629
+ ".odt",
3630
+ ".rtf",
3631
+ ".csv",
3632
+ ".xls",
3633
+ ".xlsb",
3634
+ ".xlsx",
3635
+ ".xlsm",
3636
+ ".ods",
3637
+ ".pot",
3638
+ ".potx",
3639
+ ".pps",
3640
+ ".ppsx",
3641
+ ".ppt",
3642
+ ".pptx",
3643
+ ".odp"
3644
+ ],
3645
+ text: [".log", ".md", ".rtf", ".text", ".txt"],
3646
+ csv: [".csv"],
3647
+ json: [".json"],
3648
+ xml: [".xml"],
3649
+ code: [
3650
+ ".c",
3651
+ ".cpp",
3652
+ ".cs",
3653
+ ".css",
3654
+ ".go",
3655
+ ".html",
3656
+ ".java",
3657
+ ".js",
3658
+ ".jsx",
3659
+ ".php",
3660
+ ".py",
3661
+ ".rb",
3662
+ ".rs",
3663
+ ".scss",
3664
+ ".sh",
3665
+ ".sql",
3666
+ ".swift",
3667
+ ".ts",
3668
+ ".tsx",
3669
+ ".vue",
3670
+ ".yml",
3671
+ ".yaml"
3672
+ ],
3673
+ archive: [".7z", ".bz2", ".gz", ".rar", ".tar", ".tgz", ".xz", ".zip"],
3674
+ audio: [
3675
+ "audio/*",
3676
+ ".aac",
3677
+ ".aiff",
3678
+ ".flac",
3679
+ ".m4a",
3680
+ ".mp3",
3681
+ ".ogg",
3682
+ ".opus",
3683
+ ".wav",
3684
+ ".wma"
3685
+ ],
3686
+ video: [
3687
+ "video/*",
3688
+ ".avi",
3689
+ ".mkv",
3690
+ ".mov",
3691
+ ".mp4",
3692
+ ".mpeg",
3693
+ ".mpg",
3694
+ ".webm",
3695
+ ".wmv"
3696
+ ],
3697
+ font: [".ttf", ".otf", ".woff", ".woff2"],
3698
+ email: [".eml", ".msg"]
3699
+ };
3700
+ function fileSignature(file) {
3701
+ return `${file.name}-${file.size}-${file.lastModified}-${file.type}`;
3702
+ }
3703
+ function normalizeAccept(accept) {
3704
+ if (!accept) return [];
3705
+ const groups = typeof accept === "string" ? [accept] : accept;
3706
+ return [...new Set(groups.flatMap((group) => FILE_UPLOAD_ACCEPTS[group]))];
3707
+ }
3708
+ function isAcceptedFile(file, accept) {
3709
+ if (!accept.length) return true;
3710
+ const type = file.type.toLowerCase();
3711
+ const name = file.name.toLowerCase();
3712
+ return accept.some((entry) => {
3713
+ if (entry.startsWith(".")) return name.endsWith(entry);
3714
+ if (entry.endsWith("/*")) return type.startsWith(entry.slice(0, -1));
3715
+ return type === entry;
3716
+ });
3717
+ }
3718
+ function formatFileSize(bytes) {
3719
+ if (!Number.isFinite(bytes) || bytes < 1024) return `${bytes || 0} B`;
3720
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
3721
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
3722
+ }
3723
+ function FileVisual({ file }) {
3724
+ const [previewUrl, setPreviewUrl] = useState18();
3725
+ const isImage = file.type.startsWith("image/");
3726
+ useEffect10(() => {
3727
+ if (!isImage || typeof URL.createObjectURL !== "function") return;
3728
+ const objectUrl = URL.createObjectURL(file);
3729
+ setPreviewUrl(objectUrl);
3730
+ return () => URL.revokeObjectURL(objectUrl);
3731
+ }, [file, isImage]);
3732
+ if (previewUrl) {
3733
+ return /* @__PURE__ */ jsx31("img", { className: "fe-file-upload__thumbnail", src: previewUrl, alt: "" });
3734
+ }
3735
+ const extension = file.name.includes(".") ? file.name.slice(
3736
+ file.name.lastIndexOf(".") + 1,
3737
+ file.name.lastIndexOf(".") + 5
3738
+ ) : "file";
3739
+ return /* @__PURE__ */ jsx31("span", { className: "fe-file-upload__file-type", "aria-hidden": "true", children: extension });
3740
+ }
3741
+ var FileUpload = forwardRef14(
3742
+ function FileUpload2({
3743
+ value,
3744
+ defaultValue = [],
3745
+ onChange,
3746
+ onAccept,
3747
+ onReject,
3748
+ onRemove,
3749
+ accept,
3750
+ maxSize = Infinity,
3751
+ maxFiles = Infinity,
3752
+ multiple = true,
3753
+ disabled = false,
3754
+ preventDuplicate = true,
3755
+ label = "Upload files",
3756
+ description,
3757
+ dropLabel = "Drop files here",
3758
+ browseLabel = "Browse files",
3759
+ removeLabel = (file) => `Remove ${file.name}`,
3760
+ showFileList = true,
3761
+ inputProps,
3762
+ className,
3763
+ "aria-label": ariaLabel,
3764
+ ...props
3765
+ }, forwardedRef) {
3766
+ const generatedId = useId13();
3767
+ const inputId = `${generatedId}-input`;
3768
+ const descriptionId = `${generatedId}-description`;
3769
+ const inputRef = useRef11(null);
3770
+ const dragDepthRef = useRef11(0);
3771
+ const [uncontrolledFiles, setUncontrolledFiles] = useState18(() => [
3772
+ ...defaultValue
3773
+ ]);
3774
+ const [isDragging, setIsDragging] = useState18(false);
3775
+ const [rejections, setRejections] = useState18([]);
3776
+ const files = value === void 0 ? uncontrolledFiles : [...value];
3777
+ const acceptList = useMemo3(() => normalizeAccept(accept), [accept]);
3778
+ const nativeAccept = acceptList.join(",") || void 0;
3779
+ const allowedFileCount = multiple ? maxFiles : 1;
3780
+ const safeMaxFiles = Number.isFinite(allowedFileCount) ? Math.max(0, Math.floor(allowedFileCount)) : Infinity;
3781
+ const helperText = description ?? [
3782
+ acceptList.length ? `Accepted: ${acceptList.join(", ")}` : void 0,
3783
+ Number.isFinite(maxSize) ? `Up to ${formatFileSize(maxSize)} per file` : void 0
3784
+ ].filter(Boolean).join(" \u2022 ");
3785
+ const assignInputRef = (node) => {
3786
+ inputRef.current = node;
3787
+ if (typeof forwardedRef === "function") forwardedRef(node);
3788
+ else if (forwardedRef) {
3789
+ forwardedRef.current = node;
3790
+ }
3791
+ };
3792
+ const commitFiles = (nextFiles) => {
3793
+ if (value === void 0) setUncontrolledFiles(nextFiles);
3794
+ onChange?.(nextFiles);
3795
+ };
3796
+ const addFiles = (fileList) => {
3797
+ if (disabled) return;
3798
+ const candidates = Array.from(fileList ?? []);
3799
+ const nextRejections = [];
3800
+ const accepted = [];
3801
+ const knownFiles = new Set(files.map(fileSignature));
3802
+ for (const file of candidates) {
3803
+ const signature = fileSignature(file);
3804
+ if (!isAcceptedFile(file, acceptList)) {
3805
+ nextRejections.push({
3806
+ file,
3807
+ code: "accept",
3808
+ message: `${file.name} is not an accepted file type.`
3809
+ });
3810
+ } else if (file.size > maxSize) {
3811
+ nextRejections.push({
3812
+ file,
3813
+ code: "max-size",
3814
+ message: `${file.name} exceeds ${formatFileSize(maxSize)}.`
3815
+ });
3816
+ } else if (preventDuplicate && knownFiles.has(signature)) {
3817
+ nextRejections.push({
3818
+ file,
3819
+ code: "duplicate",
3820
+ message: `${file.name} is already in the list.`
3821
+ });
3822
+ } else if (files.length + accepted.length >= safeMaxFiles) {
3823
+ nextRejections.push({
3824
+ file,
3825
+ code: "max-files",
3826
+ message: `Only ${safeMaxFiles} file${safeMaxFiles === 1 ? "" : "s"} can be selected.`
3827
+ });
3828
+ } else {
3829
+ knownFiles.add(signature);
3830
+ accepted.push(file);
3831
+ }
3832
+ }
3833
+ setRejections(nextRejections);
3834
+ if (nextRejections.length) onReject?.(nextRejections);
3835
+ if (!accepted.length) return;
3836
+ commitFiles([...files, ...accepted]);
3837
+ onAccept?.(accepted);
3838
+ };
3839
+ const openFileDialog = () => {
3840
+ if (!disabled) inputRef.current?.click();
3841
+ };
3842
+ const removeFile = (file, index) => {
3843
+ if (disabled) return;
3844
+ onRemove?.(file, index);
3845
+ commitFiles(files.filter((_, fileIndex) => fileIndex !== index));
3846
+ };
3847
+ const handleDragEnter = (event) => {
3848
+ event.preventDefault();
3849
+ if (disabled) return;
3850
+ dragDepthRef.current += 1;
3851
+ setIsDragging(true);
3852
+ };
3853
+ const handleDragLeave = (event) => {
3854
+ event.preventDefault();
3855
+ dragDepthRef.current -= 1;
3856
+ if (dragDepthRef.current <= 0) {
3857
+ dragDepthRef.current = 0;
3858
+ setIsDragging(false);
3859
+ }
3860
+ };
3861
+ const handleDrop = (event) => {
3862
+ event.preventDefault();
3863
+ dragDepthRef.current = 0;
3864
+ setIsDragging(false);
3865
+ addFiles(event.dataTransfer.files);
3866
+ };
3867
+ return /* @__PURE__ */ jsxs26(
3868
+ "div",
3869
+ {
3870
+ ...props,
3871
+ className: ["fe-file-upload", className].filter(Boolean).join(" "),
3872
+ children: [
3873
+ label && /* @__PURE__ */ jsx31("label", { className: "fe-file-upload__label", htmlFor: inputId, children: label }),
3874
+ helperText && /* @__PURE__ */ jsx31("span", { id: descriptionId, className: "fe-file-upload__description", children: helperText }),
3875
+ /* @__PURE__ */ jsx31(
3876
+ "input",
3877
+ {
3878
+ ...inputProps,
3879
+ ref: assignInputRef,
3880
+ id: inputId,
3881
+ type: "file",
3882
+ className: "fe-file-upload__input",
3883
+ accept: nativeAccept,
3884
+ multiple,
3885
+ disabled,
3886
+ "aria-label": ariaLabel,
3887
+ "aria-describedby": helperText ? descriptionId : void 0,
3888
+ onChange: (event) => {
3889
+ addFiles(event.target.files);
3890
+ event.target.value = "";
3891
+ }
3892
+ }
3893
+ ),
3894
+ /* @__PURE__ */ jsxs26(
3895
+ "div",
3896
+ {
3897
+ className: [
3898
+ "fe-file-upload__dropzone",
3899
+ isDragging && "fe-file-upload__dropzone--dragging",
3900
+ disabled && "fe-file-upload__dropzone--disabled"
3901
+ ].filter(Boolean).join(" "),
3902
+ onDragEnter: handleDragEnter,
3903
+ onDragOver: (event) => event.preventDefault(),
3904
+ onDragLeave: handleDragLeave,
3905
+ onDrop: handleDrop,
3906
+ children: [
3907
+ /* @__PURE__ */ jsx31("span", { className: "fe-file-upload__drop-icon", "aria-hidden": "true", children: "\u2191" }),
3908
+ /* @__PURE__ */ jsx31("span", { className: "fe-file-upload__drop-label", children: dropLabel }),
3909
+ /* @__PURE__ */ jsx31("span", { className: "fe-file-upload__drop-hint", children: "or choose from your device" }),
3910
+ /* @__PURE__ */ jsx31(
3911
+ Button,
3912
+ {
3913
+ hierarchy: "secondary-gray",
3914
+ disabled,
3915
+ onClick: openFileDialog,
3916
+ children: browseLabel
3917
+ }
3918
+ )
3919
+ ]
3920
+ }
3921
+ ),
3922
+ rejections.length > 0 && /* @__PURE__ */ jsx31("div", { className: "fe-file-upload__errors", role: "alert", children: rejections.map((rejection) => /* @__PURE__ */ jsx31("p", { children: rejection.message }, `${fileSignature(rejection.file)}-${rejection.code}`)) }),
3923
+ showFileList && files.length > 0 && /* @__PURE__ */ jsx31("ul", { className: "fe-file-upload__list", "aria-label": "Selected files", children: files.map((file, index) => /* @__PURE__ */ jsxs26(
3924
+ "li",
3925
+ {
3926
+ className: "fe-file-upload__item",
3927
+ children: [
3928
+ /* @__PURE__ */ jsx31("span", { className: "fe-file-upload__visual", children: /* @__PURE__ */ jsx31(FileVisual, { file }) }),
3929
+ /* @__PURE__ */ jsxs26("span", { className: "fe-file-upload__file-details", children: [
3930
+ /* @__PURE__ */ jsx31("span", { className: "fe-file-upload__file-name", title: file.name, children: file.name }),
3931
+ /* @__PURE__ */ jsx31("span", { className: "fe-file-upload__file-size", children: formatFileSize(file.size) })
3932
+ ] }),
3933
+ /* @__PURE__ */ jsx31(
3934
+ Button,
3935
+ {
3936
+ hierarchy: "tertiary-color",
3937
+ color: "error",
3938
+ destructive: true,
3939
+ size: "24",
3940
+ iconOnly: true,
3941
+ icon: /* @__PURE__ */ jsx31(CloseIcon, { size: 14 }),
3942
+ "aria-label": removeLabel(file),
3943
+ disabled,
3944
+ onClick: () => removeFile(file, index)
3945
+ }
3946
+ )
3947
+ ]
3948
+ },
3949
+ `${fileSignature(file)}-${index}`
3950
+ )) })
3951
+ ]
3952
+ }
3953
+ );
3954
+ }
3955
+ );
3956
+ FileUpload.displayName = "FileUpload";
3957
+
3958
+ // packages/file-preview/src/index.tsx
3959
+ import {
3960
+ useEffect as useEffect11,
3961
+ useId as useId14,
3962
+ useRef as useRef12,
3963
+ useState as useState19
3964
+ } from "react";
3965
+ import { createPortal as createPortal4 } from "react-dom";
3966
+ import { Fragment as Fragment4, jsx as jsx32, jsxs as jsxs27 } from "react/jsx-runtime";
3967
+ function clampIndex(index, length) {
3968
+ if (!length) return 0;
3969
+ return Math.min(Math.max(Math.floor(index), 0), length - 1);
3970
+ }
3971
+ function hasExtension(file, extensions) {
3972
+ const name = file.name.toLowerCase();
3973
+ return extensions.some((extension) => name.endsWith(extension));
3974
+ }
3975
+ function getFilePreviewKind(file) {
3976
+ const type = file.type.toLowerCase();
3977
+ if (type.startsWith("image/") || hasExtension(file, [".svg"])) return "image";
3978
+ if (type.startsWith("video/")) return "video";
3979
+ if (type.startsWith("audio/")) return "audio";
3980
+ if (type === "application/pdf" || hasExtension(file, [".pdf"])) return "pdf";
3981
+ return "unsupported";
3982
+ }
3983
+ function formatFileSize2(bytes) {
3984
+ if (bytes < 1024) return `${bytes} B`;
3985
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
3986
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
3987
+ }
3988
+ function getFileExtension(file) {
3989
+ const dotIndex = file.name.lastIndexOf(".");
3990
+ return dotIndex >= 0 ? file.name.slice(dotIndex + 1).toUpperCase() : "FILE";
3991
+ }
3992
+ function useFileObjectUrl(file) {
3993
+ const [preview, setPreview] = useState19();
3994
+ useEffect11(() => {
3995
+ if (!file || typeof URL.createObjectURL !== "function") {
3996
+ setPreview(void 0);
3997
+ return;
3998
+ }
3999
+ const url = URL.createObjectURL(file);
4000
+ setPreview({ file, url });
4001
+ return () => URL.revokeObjectURL(url);
4002
+ }, [file]);
4003
+ if (!preview || preview.file !== file) return void 0;
4004
+ return preview.url;
4005
+ }
4006
+ function startLocalDownload(file) {
4007
+ if (typeof document === "undefined" || typeof URL.createObjectURL !== "function") {
4008
+ return;
4009
+ }
4010
+ const url = URL.createObjectURL(file);
4011
+ const anchor = document.createElement("a");
4012
+ anchor.href = url;
4013
+ anchor.download = file.name;
4014
+ anchor.hidden = true;
4015
+ document.body.append(anchor);
4016
+ anchor.click();
4017
+ anchor.remove();
4018
+ window.setTimeout(() => URL.revokeObjectURL(url), 0);
4019
+ }
4020
+ function PreviewContent({ file }) {
4021
+ const kind = getFilePreviewKind(file);
4022
+ const url = useFileObjectUrl(file);
4023
+ if (url && kind === "image") {
4024
+ return /* @__PURE__ */ jsx32("img", { className: "fe-file-preview__image", src: url, alt: file.name });
4025
+ }
4026
+ if (url && kind === "video") {
4027
+ return /* @__PURE__ */ jsx32("video", { className: "fe-file-preview__video", controls: true, src: url, children: "Your browser cannot play this video." });
4028
+ }
4029
+ if (url && kind === "audio") {
4030
+ return /* @__PURE__ */ jsx32("audio", { className: "fe-file-preview__audio", controls: true, src: url });
4031
+ }
4032
+ if (url && kind === "pdf") {
4033
+ return /* @__PURE__ */ jsx32(
4034
+ "iframe",
4035
+ {
4036
+ className: "fe-file-preview__pdf",
4037
+ title: `Preview ${file.name}`,
4038
+ src: `${url}#view=FitH`
4039
+ }
4040
+ );
4041
+ }
4042
+ return /* @__PURE__ */ jsxs27("div", { className: "fe-file-preview__unsupported", children: [
4043
+ /* @__PURE__ */ jsx32("span", { className: "fe-file-preview__file-type", "aria-hidden": "true", children: getFileExtension(file) }),
4044
+ /* @__PURE__ */ jsx32("p", { children: "Preview is not available for this file type." }),
4045
+ /* @__PURE__ */ jsx32("span", { children: file.name })
4046
+ ] });
4047
+ }
4048
+ function FilePreview({
4049
+ open,
4050
+ files,
4051
+ activeIndex,
4052
+ defaultActiveIndex = 0,
4053
+ onActiveIndexChange,
4054
+ onClose,
4055
+ onEscape,
4056
+ onDelete,
4057
+ onDownload,
4058
+ closeOnBackdropClick = true,
4059
+ closeOnEscape = true,
4060
+ closeLabel = "Close file preview",
4061
+ downloadLabel = "Download",
4062
+ deleteLabel = "Delete",
4063
+ hideDownload = false,
4064
+ className,
4065
+ "aria-label": ariaLabel,
4066
+ ...props
4067
+ }) {
4068
+ const titleId = useId14();
4069
+ const panelRef = useRef12(null);
4070
+ const [uncontrolledIndex, setUncontrolledIndex] = useState19(defaultActiveIndex);
4071
+ const resolvedIndex = clampIndex(
4072
+ activeIndex ?? uncontrolledIndex,
4073
+ files.length
4074
+ );
4075
+ const activeFile = files[resolvedIndex];
4076
+ const hasPrevious = resolvedIndex > 0;
4077
+ const hasNext = resolvedIndex < files.length - 1;
4078
+ const requestClose = (reason) => {
4079
+ if (reason === "escape") onEscape?.();
4080
+ onClose(reason);
4081
+ };
4082
+ useModalOverlay({
4083
+ open,
4084
+ onClose: () => requestClose("escape"),
4085
+ panelRef,
4086
+ priority: 1200,
4087
+ closeOnEscape
4088
+ });
4089
+ useEffect11(() => {
4090
+ if (activeIndex === void 0) {
4091
+ setUncontrolledIndex((index) => clampIndex(index, files.length));
4092
+ }
4093
+ }, [activeIndex, files.length]);
4094
+ const changeActiveIndex = (nextIndex) => {
4095
+ const next = clampIndex(nextIndex, files.length);
4096
+ const nextFile = files[next];
4097
+ if (!nextFile || next === resolvedIndex) return;
4098
+ if (activeIndex === void 0) setUncontrolledIndex(next);
4099
+ onActiveIndexChange?.(next, nextFile);
4100
+ };
4101
+ const handleKeyDown = (event) => {
4102
+ if (event.key === "ArrowLeft" && hasPrevious) {
4103
+ event.preventDefault();
4104
+ changeActiveIndex(resolvedIndex - 1);
4105
+ }
4106
+ if (event.key === "ArrowRight" && hasNext) {
4107
+ event.preventDefault();
4108
+ changeActiveIndex(resolvedIndex + 1);
4109
+ }
4110
+ };
4111
+ if (!open || typeof document === "undefined") return null;
4112
+ return createPortal4(
4113
+ /* @__PURE__ */ jsx32(
4114
+ "div",
4115
+ {
4116
+ className: "fe-file-preview-backdrop",
4117
+ role: "presentation",
4118
+ onMouseDown: (event) => {
4119
+ if (event.target === event.currentTarget && closeOnBackdropClick) {
4120
+ requestClose("backdrop");
4121
+ }
4122
+ },
4123
+ children: /* @__PURE__ */ jsxs27(
4124
+ "div",
4125
+ {
4126
+ ...props,
4127
+ ref: panelRef,
4128
+ className: ["fe-file-preview", className].filter(Boolean).join(" "),
4129
+ role: "dialog",
4130
+ "aria-modal": "true",
4131
+ "aria-labelledby": activeFile ? titleId : void 0,
4132
+ "aria-label": ariaLabel ?? (activeFile ? void 0 : "File preview"),
4133
+ tabIndex: -1,
4134
+ onKeyDown: handleKeyDown,
4135
+ children: [
4136
+ /* @__PURE__ */ jsxs27("header", { className: "fe-file-preview__header", children: [
4137
+ /* @__PURE__ */ jsxs27("div", { className: "fe-file-preview__heading", children: [
4138
+ /* @__PURE__ */ jsx32("h2", { id: titleId, children: activeFile?.name ?? "File preview" }),
4139
+ /* @__PURE__ */ jsx32("span", { "aria-label": `${resolvedIndex + 1} of ${files.length} files`, children: files.length ? `${resolvedIndex + 1} / ${files.length}` : "0 / 0" })
4140
+ ] }),
4141
+ /* @__PURE__ */ jsx32(
4142
+ Button,
4143
+ {
4144
+ hierarchy: "tertiary-gray",
4145
+ size: "32",
4146
+ iconOnly: true,
4147
+ icon: /* @__PURE__ */ jsx32(CloseIcon, {}),
4148
+ "aria-label": closeLabel,
4149
+ onClick: () => requestClose("close")
4150
+ }
4151
+ )
4152
+ ] }),
4153
+ /* @__PURE__ */ jsxs27("div", { className: "fe-file-preview__body", children: [
4154
+ activeFile ? /* @__PURE__ */ jsx32(PreviewContent, { file: activeFile }) : /* @__PURE__ */ jsx32("p", { className: "fe-file-preview__empty", children: "No files to preview." }),
4155
+ activeFile && files.length > 1 && /* @__PURE__ */ jsxs27(Fragment4, { children: [
4156
+ /* @__PURE__ */ jsx32(
4157
+ Button,
4158
+ {
4159
+ className: "fe-file-preview__navigation fe-file-preview__navigation--previous",
4160
+ hierarchy: "secondary-gray",
4161
+ size: "40",
4162
+ iconOnly: true,
4163
+ icon: /* @__PURE__ */ jsx32(ChevronDownIcon, {}),
4164
+ "aria-label": "Previous file",
4165
+ disabled: !hasPrevious,
4166
+ onClick: () => changeActiveIndex(resolvedIndex - 1)
4167
+ }
4168
+ ),
4169
+ /* @__PURE__ */ jsx32(
4170
+ Button,
4171
+ {
4172
+ className: "fe-file-preview__navigation fe-file-preview__navigation--next",
4173
+ hierarchy: "secondary-gray",
4174
+ size: "40",
4175
+ iconOnly: true,
4176
+ icon: /* @__PURE__ */ jsx32(ChevronDownIcon, {}),
4177
+ "aria-label": "Next file",
4178
+ disabled: !hasNext,
4179
+ onClick: () => changeActiveIndex(resolvedIndex + 1)
4180
+ }
4181
+ )
4182
+ ] })
4183
+ ] }),
4184
+ activeFile && /* @__PURE__ */ jsxs27("footer", { className: "fe-file-preview__footer", children: [
4185
+ /* @__PURE__ */ jsxs27("span", { className: "fe-file-preview__metadata", children: [
4186
+ getFilePreviewKind(activeFile),
4187
+ " \xB7",
4188
+ " ",
4189
+ formatFileSize2(activeFile.size)
4190
+ ] }),
4191
+ /* @__PURE__ */ jsxs27("div", { className: "fe-file-preview__actions", children: [
4192
+ !hideDownload && /* @__PURE__ */ jsx32(
4193
+ Button,
4194
+ {
4195
+ hierarchy: "secondary-gray",
4196
+ onClick: () => {
4197
+ onDownload?.(activeFile, resolvedIndex);
4198
+ startLocalDownload(activeFile);
4199
+ },
4200
+ children: downloadLabel
4201
+ }
4202
+ ),
4203
+ onDelete && /* @__PURE__ */ jsx32(
4204
+ Button,
4205
+ {
4206
+ hierarchy: "secondary-color",
4207
+ color: "error",
4208
+ destructive: true,
4209
+ onClick: () => onDelete(activeFile, resolvedIndex),
4210
+ children: deleteLabel
4211
+ }
4212
+ )
4213
+ ] })
4214
+ ] })
4215
+ ]
4216
+ }
4217
+ )
4218
+ }
4219
+ ),
4220
+ document.body
4221
+ );
4222
+ }
2840
4223
  export {
2841
4224
  Avatar,
2842
4225
  AvatarGroup,
@@ -2850,14 +4233,25 @@ export {
2850
4233
  CurrencyInput,
2851
4234
  DateTimePicker,
2852
4235
  Drawer,
4236
+ DrawerWidths,
4237
+ EmailInput,
2853
4238
  ExpandableSection,
4239
+ EyeIcon,
4240
+ EyeOffIcon,
4241
+ FILE_UPLOAD_ACCEPTS,
4242
+ FilePreview,
4243
+ FileUpload,
2854
4244
  Loading,
4245
+ MailboxIcon,
2855
4246
  Message,
2856
4247
  Modal,
2857
4248
  MoreHorizontalIcon,
2858
4249
  MoreVerticalIcon,
2859
4250
  NumberInput,
2860
4251
  Pagination,
4252
+ PasswordInput,
4253
+ PhoneIcon,
4254
+ PhoneNumberInput,
2861
4255
  PlusIcon,
2862
4256
  ProgressBar,
2863
4257
  RadioButton,
@@ -2877,6 +4271,7 @@ export {
2877
4271
  TableHead,
2878
4272
  TableHeader,
2879
4273
  TableRow,
4274
+ Tabs,
2880
4275
  TextArea,
2881
4276
  TextInput,
2882
4277
  Toggle,
@@ -2888,7 +4283,9 @@ export {
2888
4283
  chevron_right,
2889
4284
  chevron_up,
2890
4285
  copy,
4286
+ formatFileSize,
2891
4287
  formatNumber,
4288
+ getFilePreviewKind,
2892
4289
  getIconSize,
2893
4290
  key,
2894
4291
  lock,
@@ -2896,9 +4293,13 @@ export {
2896
4293
  log_out,
2897
4294
  message,
2898
4295
  minus_square,
4296
+ normalizePhoneNumber,
2899
4297
  plus,
2900
4298
  plus_square,
2901
4299
  search,
2902
4300
  trash,
4301
+ validateEmail,
4302
+ validatePassword,
4303
+ validatePhoneNumber,
2903
4304
  x_close
2904
4305
  };