@dragunio/fe-libs 0.1.4 → 0.1.6

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
@@ -1,3 +1,28 @@
1
+ import {
2
+ ChevronDownIcon,
3
+ ChevronUpIcon,
4
+ CloseIcon,
5
+ PlusIcon,
6
+ SearchIcon,
7
+ arrow_left,
8
+ check_square_fill,
9
+ chevron_down,
10
+ chevron_left,
11
+ chevron_right,
12
+ chevron_up,
13
+ copy,
14
+ key,
15
+ lock,
16
+ lock_unlocked,
17
+ log_out,
18
+ minus_square,
19
+ plus,
20
+ plus_square,
21
+ search,
22
+ trash,
23
+ x_close
24
+ } from "./chunk-NDMLXSI5.mjs";
25
+
1
26
  // packages/button/src/index.tsx
2
27
  import { forwardRef } from "react";
3
28
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -64,32 +89,6 @@ var Button = forwardRef(
64
89
  );
65
90
  Button.displayName = "Button";
66
91
 
67
- // packages/icons/src/index.tsx
68
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
69
- var iconProps = ({ size, ...props }) => ({
70
- width: size ?? 20,
71
- height: size ?? 20,
72
- fill: "none",
73
- viewBox: "0 0 24 24",
74
- "aria-hidden": true,
75
- ...props
76
- });
77
- function PlusIcon(props) {
78
- return /* @__PURE__ */ jsx2("svg", { ...iconProps(props), children: /* @__PURE__ */ jsx2("path", { d: "M12 5v14M5 12h14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) });
79
- }
80
- function ChevronDownIcon(props) {
81
- return /* @__PURE__ */ jsx2("svg", { ...iconProps(props), children: /* @__PURE__ */ jsx2("path", { d: "m6 9 6 6 6-6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) });
82
- }
83
- function CloseIcon(props) {
84
- return /* @__PURE__ */ jsx2("svg", { ...iconProps(props), children: /* @__PURE__ */ jsx2("path", { d: "m6 6 12 12M18 6 6 18", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) });
85
- }
86
- function SearchIcon(props) {
87
- return /* @__PURE__ */ jsxs2("svg", { ...iconProps(props), children: [
88
- /* @__PURE__ */ jsx2("circle", { cx: "11", cy: "11", r: "6.5", stroke: "currentColor", strokeWidth: "2" }),
89
- /* @__PURE__ */ jsx2("path", { d: "m16 16 4 4", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
90
- ] });
91
- }
92
-
93
92
  // packages/table/src/index.tsx
94
93
  import {
95
94
  createContext,
@@ -104,7 +103,7 @@ import {
104
103
 
105
104
  // packages/pagination/src/index.tsx
106
105
  import { useMemo, useState } from "react";
107
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
106
+ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
108
107
  var clamp = (value, min, max) => Math.min(Math.max(value, min), max);
109
108
  var range = (start, end) => Array.from({ length: Math.max(0, end - start + 1) }, (_, index) => start + index);
110
109
  function getItems(totalPages, page, siblingCount, boundaryCount) {
@@ -147,9 +146,9 @@ function Pagination({
147
146
  if (page === void 0) setUncontrolledPage(resolvedPage);
148
147
  if (resolvedPage !== currentPage) onPageChange?.(resolvedPage);
149
148
  };
150
- return /* @__PURE__ */ jsxs3("nav", { className: ["fe-pagination", className].filter(Boolean).join(" "), "aria-label": "Pagination", ...props, children: [
151
- /* @__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) }),
152
- 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(
149
+ return /* @__PURE__ */ jsxs2("nav", { className: ["fe-pagination", className].filter(Boolean).join(" "), "aria-label": "Pagination", ...props, children: [
150
+ /* @__PURE__ */ jsx2(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) }),
151
+ items.map((item, index) => item === "start-ellipsis" || item === "end-ellipsis" ? /* @__PURE__ */ jsx2("span", { className: "fe-pagination__ellipsis", "aria-hidden": "true", children: "\u2026" }, `${item}-${index}`) : /* @__PURE__ */ jsx2(
153
152
  Button,
154
153
  {
155
154
  className: "fe-pagination__button",
@@ -163,12 +162,12 @@ function Pagination({
163
162
  },
164
163
  item
165
164
  )),
166
- /* @__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) })
165
+ /* @__PURE__ */ jsx2(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) })
167
166
  ] });
168
167
  }
169
168
 
170
169
  // packages/table/src/index.tsx
171
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
170
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
172
171
  var TableContext = createContext({ striped: false });
173
172
  var MIN_COLUMN_WIDTH = 96;
174
173
  var MAX_COLUMN_WIDTH = 1200;
@@ -268,14 +267,14 @@ function DataTable({
268
267
  if (nextPage !== currentPage) onPageChange?.(nextPage);
269
268
  };
270
269
  const resolvedPaginationPosition = paginationPosition === "middle-bottom" ? "bottom-center" : paginationPosition;
271
- 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;
272
- return /* @__PURE__ */ jsxs4("div", { className: "fe-table", "data-resizing": isResizing || void 0, children: [
270
+ const paginationControl = shouldPaginate && totalPages > 1 ? /* @__PURE__ */ jsx3("div", { className: `fe-table__pagination fe-table__pagination--${resolvedPaginationPosition}`, children: /* @__PURE__ */ jsx3(Pagination, { page: currentPage, totalPages, onPageChange: changePage }) }) : null;
271
+ return /* @__PURE__ */ jsxs3("div", { className: "fe-table", "data-resizing": isResizing || void 0, children: [
273
272
  resolvedPaginationPosition === "top-right" && paginationControl,
274
- /* @__PURE__ */ jsxs4("table", { className: ["fe-table__table", className].filter(Boolean).join(" "), "data-fe-table": true, "data-striped": striped || void 0, ...props, children: [
275
- /* @__PURE__ */ jsx4("colgroup", { children: sizes2.map((size, index) => /* @__PURE__ */ jsx4("col", { style: { width: `${size}px` } }, index)) }),
276
- /* @__PURE__ */ jsx4("thead", { children: /* @__PURE__ */ jsx4("tr", { children: Array.from({ length: columnCount }, (_, columnIndex) => /* @__PURE__ */ jsxs4("th", { scope: "col", children: [
277
- /* @__PURE__ */ jsx4("span", { className: "fe-table__header-content", children: headers[columnIndex] ?? `Column ${columnIndex + 1}` }),
278
- /* @__PURE__ */ jsx4(
273
+ /* @__PURE__ */ jsxs3("table", { className: ["fe-table__table", className].filter(Boolean).join(" "), "data-fe-table": true, "data-striped": striped || void 0, ...props, children: [
274
+ /* @__PURE__ */ jsx3("colgroup", { children: sizes2.map((size, index) => /* @__PURE__ */ jsx3("col", { style: { width: `${size}px` } }, index)) }),
275
+ /* @__PURE__ */ jsx3("thead", { children: /* @__PURE__ */ jsx3("tr", { children: Array.from({ length: columnCount }, (_, columnIndex) => /* @__PURE__ */ jsxs3("th", { scope: "col", children: [
276
+ /* @__PURE__ */ jsx3("span", { className: "fe-table__header-content", children: headers[columnIndex] ?? `Column ${columnIndex + 1}` }),
277
+ /* @__PURE__ */ jsx3(
279
278
  "span",
280
279
  {
281
280
  className: "fe-table__resize-handle",
@@ -299,7 +298,7 @@ function DataTable({
299
298
  }
300
299
  )
301
300
  ] }, columnIndex)) }) }),
302
- /* @__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)) })
301
+ /* @__PURE__ */ jsx3("tbody", { children: pagedData.map((row, rowIndex) => /* @__PURE__ */ jsx3("tr", { children: Array.from({ length: columnCount }, (_, columnIndex) => /* @__PURE__ */ jsx3("td", { children: row[columnIndex] }, columnIndex)) }, shouldPaginate ? (currentPage - 1) * safePageSize + rowIndex : rowIndex)) })
303
302
  ] }),
304
303
  resolvedPaginationPosition !== "top-right" && paginationControl
305
304
  ] });
@@ -317,42 +316,63 @@ function Table({
317
316
  paginationPosition,
318
317
  ...props
319
318
  }) {
320
- if (headers || data) return /* @__PURE__ */ jsx4(DataTable, { headers: headers ?? [], data: data ?? [], striped: striped ?? true, pagination, pageSize, page, defaultPage, onPageChange, paginationPosition, ...props });
321
- return /* @__PURE__ */ jsx4(TableContext.Provider, { value: { striped: striped ?? false }, children: /* @__PURE__ */ jsx4("table", { "data-fe-table": true, "data-striped": striped || void 0, ...props, children }) });
319
+ if (headers || data) return /* @__PURE__ */ jsx3(DataTable, { headers: headers ?? [], data: data ?? [], striped: striped ?? true, pagination, pageSize, page, defaultPage, onPageChange, paginationPosition, ...props });
320
+ return /* @__PURE__ */ jsx3(TableContext.Provider, { value: { striped: striped ?? false }, children: /* @__PURE__ */ jsx3("table", { "data-fe-table": true, "data-striped": striped || void 0, ...props, children }) });
322
321
  }
323
322
  function TableHead(props) {
324
- return /* @__PURE__ */ jsx4("thead", { ...props });
323
+ return /* @__PURE__ */ jsx3("thead", { ...props });
325
324
  }
326
325
  function TableBody(props) {
327
- return /* @__PURE__ */ jsx4("tbody", { ...props });
326
+ return /* @__PURE__ */ jsx3("tbody", { ...props });
328
327
  }
329
328
  function TableRow({ children, ...props }) {
330
329
  const { striped } = useContext(TableContext);
331
- return /* @__PURE__ */ jsx4("tr", { "data-striped": striped || void 0, ...props, children });
330
+ return /* @__PURE__ */ jsx3("tr", { "data-striped": striped || void 0, ...props, children });
332
331
  }
333
332
  function TableCell({ children, ...props }) {
334
- return /* @__PURE__ */ jsx4("td", { ...props, children });
333
+ return /* @__PURE__ */ jsx3("td", { ...props, children });
335
334
  }
336
335
  function TableHeader({ children, ...props }) {
337
- return /* @__PURE__ */ jsx4("th", { scope: "col", ...props, children });
336
+ return /* @__PURE__ */ jsx3("th", { scope: "col", ...props, children });
338
337
  }
339
338
  function TableCaption(props) {
340
- return /* @__PURE__ */ jsx4("caption", { ...props });
339
+ return /* @__PURE__ */ jsx3("caption", { ...props });
341
340
  }
342
341
 
343
342
  // packages/toggle/src/index.tsx
344
- import { forwardRef as forwardRef2 } from "react";
345
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
346
- var Toggle = forwardRef2(function Toggle2({ color = "#16a34a", label, className, style, id, ...props }, ref) {
347
- const classes = ["fe-toggle", className].filter(Boolean).join(" ");
343
+ import {
344
+ forwardRef as forwardRef2
345
+ } from "react";
346
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
347
+ var Toggle = forwardRef2(function Toggle2({
348
+ color = "#16a34a",
349
+ label,
350
+ labelPosition = "right",
351
+ className,
352
+ style,
353
+ id,
354
+ ...props
355
+ }, ref) {
356
+ const classes = ["fe-toggle", `fe-toggle--label-${labelPosition}`, className].filter(Boolean).join(" ");
348
357
  const toggleStyle = {
349
358
  "--fe-toggle-color": color,
350
359
  ...style
351
360
  };
352
- return /* @__PURE__ */ jsxs5("label", { className: classes, style: toggleStyle, children: [
353
- /* @__PURE__ */ jsx5("input", { ref, id, className: "fe-toggle__input", type: "checkbox", role: "switch", ...props }),
354
- /* @__PURE__ */ jsx5("span", { className: "fe-toggle__control", "aria-hidden": "true" }),
355
- label && /* @__PURE__ */ jsx5("span", { className: "fe-toggle__label", children: label })
361
+ return /* @__PURE__ */ jsxs4("label", { className: classes, style: toggleStyle, children: [
362
+ label && labelPosition === "top" && /* @__PURE__ */ jsx4("span", { className: "fe-toggle__label", children: label }),
363
+ /* @__PURE__ */ jsx4(
364
+ "input",
365
+ {
366
+ ref,
367
+ id,
368
+ className: "fe-toggle__input",
369
+ type: "checkbox",
370
+ role: "switch",
371
+ ...props
372
+ }
373
+ ),
374
+ /* @__PURE__ */ jsx4("span", { className: "fe-toggle__control", "aria-hidden": "true" }),
375
+ label && labelPosition === "right" && /* @__PURE__ */ jsx4("span", { className: "fe-toggle__label", children: label })
356
376
  ] });
357
377
  });
358
378
  Toggle.displayName = "Toggle";
@@ -360,7 +380,7 @@ Toggle.displayName = "Toggle";
360
380
  // packages/drawer/src/index.tsx
361
381
  import { useEffect as useEffect2 } from "react";
362
382
  import { createPortal } from "react-dom";
363
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
383
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
364
384
  function Drawer({ open, onClose, title, footer, side = "right", width = 400, fullScreen = false, children, closeOnBackdropClick = true, className, style, ...props }) {
365
385
  useEffect2(() => {
366
386
  if (!open) return;
@@ -372,28 +392,47 @@ function Drawer({ open, onClose, title, footer, side = "right", width = 400, ful
372
392
  }, [onClose, open]);
373
393
  if (!open || typeof document === "undefined") return null;
374
394
  const panelStyle = !fullScreen && (side === "left" || side === "right") ? { ...style, width: typeof width === "number" ? `${width}px` : width } : style;
375
- return createPortal(/* @__PURE__ */ jsx6("div", { className: "fe-drawer-backdrop", role: "presentation", onMouseDown: (event) => {
395
+ return createPortal(/* @__PURE__ */ jsx5("div", { className: "fe-drawer-backdrop", role: "presentation", onMouseDown: (event) => {
376
396
  if (event.target === event.currentTarget && closeOnBackdropClick) onClose();
377
- }, 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: [
378
- /* @__PURE__ */ jsxs6("header", { className: "fe-drawer__header", children: [
379
- title && /* @__PURE__ */ jsx6("h2", { children: title }),
380
- /* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Close drawer", onClick: onClose, children: "\xD7" })
397
+ }, children: /* @__PURE__ */ jsxs5("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: [
398
+ /* @__PURE__ */ jsxs5("header", { className: "fe-drawer__header", children: [
399
+ title && /* @__PURE__ */ jsx5("h2", { children: title }),
400
+ /* @__PURE__ */ jsx5("button", { type: "button", "aria-label": "Close drawer", onClick: onClose, children: "\xD7" })
381
401
  ] }),
382
- /* @__PURE__ */ jsx6("div", { className: "fe-drawer__body", children }),
383
- footer && /* @__PURE__ */ jsx6("footer", { className: "fe-drawer__footer", children: footer })
402
+ /* @__PURE__ */ jsx5("div", { className: "fe-drawer__body", children }),
403
+ footer && /* @__PURE__ */ jsx5("footer", { className: "fe-drawer__footer", children: footer })
384
404
  ] }) }), document.body);
385
405
  }
386
406
 
387
- // packages/form-controls/src/index.tsx
388
- import {
389
- forwardRef as forwardRef3,
390
- useEffect as useEffect3,
391
- useId,
392
- useLayoutEffect,
393
- useRef as useRef2,
394
- useState as useState3
395
- } from "react";
396
- import { createPortal as createPortal2 } from "react-dom";
407
+ // packages/form-controls/src/controls/TextInput/text-input.tsx
408
+ import { forwardRef as forwardRef3, useId as useId2, useState as useState4 } from "react";
409
+
410
+ // packages/tooltip/src/index.tsx
411
+ import { cloneElement, useId, useState as useState3 } from "react";
412
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
413
+ function Tooltip({ content, children, placement = "top", disabled, className, ...props }) {
414
+ const [visible, setVisible] = useState3(false);
415
+ const id = useId();
416
+ const trigger = cloneElement(children, { "aria-describedby": visible ? id : void 0, onMouseEnter: (event) => {
417
+ children.props.onMouseEnter?.(event);
418
+ setVisible(true);
419
+ }, onMouseLeave: (event) => {
420
+ children.props.onMouseLeave?.(event);
421
+ setVisible(false);
422
+ }, onFocus: (event) => {
423
+ children.props.onFocus?.(event);
424
+ setVisible(true);
425
+ }, onBlur: (event) => {
426
+ children.props.onBlur?.(event);
427
+ setVisible(false);
428
+ } });
429
+ return /* @__PURE__ */ jsxs6("span", { className: ["fe-tooltip", `fe-tooltip--${placement}`, className].filter(Boolean).join(" "), ...props, children: [
430
+ trigger,
431
+ visible && !disabled && /* @__PURE__ */ jsx6("span", { id, role: "tooltip", className: "fe-tooltip__content", children: content })
432
+ ] });
433
+ }
434
+
435
+ // packages/form-controls/src/controls/Field/field.tsx
397
436
  import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
398
437
  function getFieldError(error, errorMessage) {
399
438
  if (errorMessage !== void 0 && errorMessage !== null) return errorMessage;
@@ -403,178 +442,682 @@ function getFieldError(error, errorMessage) {
403
442
  function getDescribedBy(existing, messageId2) {
404
443
  return [existing, messageId2].filter(Boolean).join(" ") || void 0;
405
444
  }
406
- var TextInput = forwardRef3(function TextInput2({ value, defaultValue = "", onChange, onValueChange, label, helperText, error, errorMessage, clearable = false, onClear, clearLabel = "Clear input", className, disabled, readOnly, id, "aria-describedby": ariaDescribedBy, "aria-labelledby": ariaLabelledBy, ...props }, ref) {
407
- const generatedId = useId();
408
- const inputId = id ?? `${generatedId}-input`;
409
- const labelId = `${generatedId}-label`;
410
- const messageId2 = `${generatedId}-message`;
411
- const controlled = value !== void 0;
412
- const [internalValue, setInternalValue] = useState3(defaultValue);
413
- const currentValue = controlled ? value : internalValue;
414
- const fieldError = getFieldError(error, errorMessage);
415
- const hasError = fieldError !== void 0 && fieldError !== false && fieldError !== null;
416
- const displayedMessage = hasError ? fieldError : helperText;
417
- const describedBy = getDescribedBy(ariaDescribedBy, displayedMessage ? messageId2 : void 0);
418
- const clear = () => {
419
- if (!controlled) setInternalValue("");
420
- onValueChange?.("");
421
- onClear?.();
422
- };
423
- const labelledBy = getDescribedBy(ariaLabelledBy, label ? labelId : void 0);
424
- return /* @__PURE__ */ jsxs7("label", { className: ["fe-text-input", hasError && "fe-text-input--error", className].filter(Boolean).join(" "), children: [
425
- label && /* @__PURE__ */ jsx7("span", { id: labelId, className: "fe-text-input__label", children: label }),
426
- /* @__PURE__ */ jsxs7("span", { className: "fe-text-input__control", children: [
427
- /* @__PURE__ */ jsx7("input", { ref, id: inputId, value: currentValue, disabled, readOnly, "aria-invalid": hasError || void 0, "aria-labelledby": labelledBy, "aria-describedby": describedBy, onChange: (event) => {
428
- if (!controlled) setInternalValue(event.target.value);
429
- onValueChange?.(event.target.value);
430
- onChange?.(event);
431
- }, ...props }),
432
- clearable && currentValue && !disabled && !readOnly && /* @__PURE__ */ jsx7(Button, { hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: /* @__PURE__ */ jsx7(CloseIcon, { size: 14 }), "aria-label": clearLabel, onClick: clear, className: "fe-text-input__clear" })
433
- ] }),
434
- displayedMessage && /* @__PURE__ */ jsx7("span", { id: messageId2, className: hasError ? "fe-text-input__error" : "fe-text-input__helper", children: displayedMessage })
445
+ function FieldLabel({
446
+ id,
447
+ label,
448
+ description,
449
+ descriptionDisplay,
450
+ isRequired = false
451
+ }) {
452
+ if (!label) return null;
453
+ return /* @__PURE__ */ jsxs7("span", { className: "fe-field__label", children: [
454
+ /* @__PURE__ */ jsx7("span", { id, children: label }),
455
+ isRequired && /* @__PURE__ */ jsx7("span", { className: "fe-field__required", "aria-hidden": "true", children: "*" }),
456
+ description && descriptionDisplay === "tooltip" && /* @__PURE__ */ jsx7(Tooltip, { content: description, children: /* @__PURE__ */ jsx7(
457
+ "span",
458
+ {
459
+ className: "fe-field__info",
460
+ tabIndex: 0,
461
+ role: "img",
462
+ "aria-label": "More information",
463
+ children: "i"
464
+ }
465
+ ) })
435
466
  ] });
436
- });
467
+ }
468
+ function FieldMessage({
469
+ id,
470
+ error,
471
+ description,
472
+ descriptionDisplay
473
+ }) {
474
+ if (error !== void 0 && error !== false && error !== null)
475
+ return /* @__PURE__ */ jsx7(
476
+ "span",
477
+ {
478
+ id,
479
+ className: "fe-field__message fe-field__message--error",
480
+ role: "alert",
481
+ children: error
482
+ }
483
+ );
484
+ if (description && descriptionDisplay === "inline")
485
+ return /* @__PURE__ */ jsx7("span", { id, className: "fe-field__message", children: description });
486
+ return null;
487
+ }
488
+
489
+ // packages/form-controls/src/controls/TextInput/text-input.tsx
490
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
491
+ var TextInput = forwardRef3(
492
+ function TextInput2({
493
+ value,
494
+ defaultValue = "",
495
+ onChange,
496
+ onValueChange,
497
+ label,
498
+ description,
499
+ descriptionDisplay = "inline",
500
+ helperText,
501
+ error,
502
+ errorMessage,
503
+ clearable = false,
504
+ onClear,
505
+ clearLabel = "Clear input",
506
+ className,
507
+ disabled,
508
+ readOnly,
509
+ id,
510
+ prefix,
511
+ suffix,
512
+ Prefix,
513
+ Suffix,
514
+ isRequired = false,
515
+ placeholder,
516
+ required,
517
+ "aria-describedby": ariaDescribedBy,
518
+ "aria-labelledby": ariaLabelledBy,
519
+ ...props
520
+ }, ref) {
521
+ const generatedId = useId2();
522
+ const inputId = id ?? generatedId + "-input";
523
+ const labelId = generatedId + "-label";
524
+ const messageId2 = generatedId + "-message";
525
+ const controlled = value !== void 0;
526
+ const [internalValue, setInternalValue] = useState4(defaultValue);
527
+ const currentValue = controlled ? value : internalValue;
528
+ const fieldError = getFieldError(error, errorMessage);
529
+ const hasError = fieldError !== void 0 && fieldError !== false && fieldError !== null;
530
+ const resolvedDescription = description ?? helperText;
531
+ const hasMessage = hasError || resolvedDescription && descriptionDisplay === "inline";
532
+ const describedBy = getDescribedBy(
533
+ ariaDescribedBy,
534
+ hasMessage ? messageId2 : void 0
535
+ );
536
+ const resolvedPrefix = prefix ?? Prefix;
537
+ const resolvedSuffix = suffix ?? Suffix;
538
+ const labelledBy = getDescribedBy(
539
+ ariaLabelledBy,
540
+ label ? labelId : void 0
541
+ );
542
+ const clear = () => {
543
+ if (!controlled) setInternalValue("");
544
+ onValueChange?.("");
545
+ onClear?.();
546
+ };
547
+ return /* @__PURE__ */ jsxs8(
548
+ "div",
549
+ {
550
+ className: [
551
+ "fe-text-input",
552
+ hasError && "fe-text-input--error",
553
+ className
554
+ ].filter(Boolean).join(" "),
555
+ children: [
556
+ /* @__PURE__ */ jsx8(
557
+ FieldLabel,
558
+ {
559
+ id: labelId,
560
+ label,
561
+ description: resolvedDescription,
562
+ descriptionDisplay,
563
+ isRequired
564
+ }
565
+ ),
566
+ /* @__PURE__ */ jsxs8("span", { className: "fe-text-input__control", children: [
567
+ resolvedPrefix && /* @__PURE__ */ jsx8("span", { className: "fe-text-input__prefix", children: resolvedPrefix }),
568
+ /* @__PURE__ */ jsxs8("span", { className: "fe-text-input__input-wrap", children: [
569
+ /* @__PURE__ */ jsx8(
570
+ "input",
571
+ {
572
+ ref,
573
+ id: inputId,
574
+ value: currentValue,
575
+ placeholder,
576
+ required: isRequired || required,
577
+ disabled,
578
+ readOnly,
579
+ "aria-invalid": hasError || void 0,
580
+ "aria-required": isRequired || void 0,
581
+ "aria-labelledby": labelledBy,
582
+ "aria-describedby": describedBy,
583
+ onChange: (event) => {
584
+ if (!controlled) setInternalValue(event.target.value);
585
+ onValueChange?.(event.target.value);
586
+ onChange?.(event);
587
+ },
588
+ ...props
589
+ }
590
+ ),
591
+ isRequired && placeholder && !currentValue && /* @__PURE__ */ jsxs8("span", { className: "fe-text-input__placeholder", "aria-hidden": "true", children: [
592
+ /* @__PURE__ */ jsx8("span", { children: placeholder }),
593
+ /* @__PURE__ */ jsx8("span", { className: "fe-field__required", children: "*" })
594
+ ] })
595
+ ] }),
596
+ resolvedSuffix && /* @__PURE__ */ jsx8("span", { className: "fe-text-input__suffix", children: resolvedSuffix }),
597
+ clearable && currentValue && !disabled && !readOnly && /* @__PURE__ */ jsx8(
598
+ Button,
599
+ {
600
+ hierarchy: "tertiary-gray",
601
+ size: "24",
602
+ iconOnly: true,
603
+ icon: /* @__PURE__ */ jsx8(CloseIcon, { size: 14 }),
604
+ "aria-label": clearLabel,
605
+ onClick: clear,
606
+ className: "fe-text-input__clear"
607
+ }
608
+ )
609
+ ] }),
610
+ /* @__PURE__ */ jsx8(
611
+ FieldMessage,
612
+ {
613
+ id: messageId2,
614
+ error: fieldError,
615
+ description: resolvedDescription,
616
+ descriptionDisplay
617
+ }
618
+ )
619
+ ]
620
+ }
621
+ );
622
+ }
623
+ );
437
624
  TextInput.displayName = "TextInput";
438
- var TextArea = forwardRef3(function TextArea2({ value, defaultValue = "", onChange, onValueChange, label, helperText, error, errorMessage, clearable = false, onClear, clearLabel = "Clear text area", className, disabled, readOnly, id, "aria-describedby": ariaDescribedBy, "aria-labelledby": ariaLabelledBy, ...props }, ref) {
439
- const generatedId = useId();
440
- const inputId = id ?? `${generatedId}-input`;
441
- const labelId = `${generatedId}-label`;
442
- const messageId2 = `${generatedId}-message`;
443
- const controlled = value !== void 0;
444
- const [internalValue, setInternalValue] = useState3(defaultValue);
445
- const currentValue = controlled ? value : internalValue;
446
- const fieldError = getFieldError(error, errorMessage);
447
- const hasError = fieldError !== void 0 && fieldError !== false && fieldError !== null;
448
- const displayedMessage = hasError ? fieldError : helperText;
449
- const describedBy = getDescribedBy(ariaDescribedBy, displayedMessage ? messageId2 : void 0);
450
- const clear = () => {
451
- if (!controlled) setInternalValue("");
452
- onValueChange?.("");
453
- onClear?.();
454
- };
455
- const labelledBy = getDescribedBy(ariaLabelledBy, label ? labelId : void 0);
456
- return /* @__PURE__ */ jsxs7("label", { className: ["fe-text-area", hasError && "fe-text-area--error", className].filter(Boolean).join(" "), children: [
457
- label && /* @__PURE__ */ jsx7("span", { id: labelId, className: "fe-text-area__label", children: label }),
458
- /* @__PURE__ */ jsxs7("span", { className: "fe-text-area__control", children: [
459
- /* @__PURE__ */ jsx7("textarea", { ref, id: inputId, value: currentValue, disabled, readOnly, "aria-invalid": hasError || void 0, "aria-labelledby": labelledBy, "aria-describedby": describedBy, onChange: (event) => {
460
- if (!controlled) setInternalValue(event.target.value);
461
- onValueChange?.(event.target.value);
462
- onChange?.(event);
463
- }, ...props }),
464
- clearable && currentValue && !disabled && !readOnly && /* @__PURE__ */ jsx7(Button, { hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: /* @__PURE__ */ jsx7(CloseIcon, { size: 14 }), "aria-label": clearLabel, onClick: clear, className: "fe-text-area__clear" })
465
- ] }),
466
- displayedMessage && /* @__PURE__ */ jsx7("span", { id: messageId2, className: hasError ? "fe-text-area__error" : "fe-text-area__helper", children: displayedMessage })
467
- ] });
468
- });
469
- TextArea.displayName = "TextArea";
470
- var Selection = forwardRef3(function Selection2({ className, label, helperText, error, options, placeholder = "Select an option", size = "medium", id, value, defaultValue, onChange, multiple = false, searchable = false, tag = false, clearable = false, disabled = false, name, onKeyDown, ...props }, ref) {
471
- const generatedId = useId();
472
- const listboxId = id ?? generatedId;
473
- const isControlled = value !== void 0;
474
- const [internalValue, setInternalValue] = useState3(defaultValue ?? (multiple ? [] : ""));
475
- const selectedValue = isControlled ? value : internalValue;
476
- const selectedValues = Array.isArray(selectedValue) ? selectedValue : selectedValue === "" || selectedValue === null || selectedValue === void 0 ? [] : [selectedValue];
477
- const selectedOptions = options.filter((option) => selectedValues.some((item) => String(item) === String(option.value)));
478
- const [open, setOpen] = useState3(false);
479
- const [query, setQuery] = useState3("");
480
- const [activeIndex, setActiveIndex] = useState3(0);
481
- const rootRef = useRef2(null);
482
- const menuRef = useRef2(null);
483
- const [menuPosition, setMenuPosition] = useState3(null);
484
- useEffect3(() => {
485
- const close = (event) => {
486
- const target = event.target;
487
- if (!rootRef.current?.contains(target) && !menuRef.current?.contains(target)) setOpen(false);
625
+
626
+ // packages/form-controls/src/controls/TextArea/text-area.tsx
627
+ import {
628
+ forwardRef as forwardRef4,
629
+ useId as useId3,
630
+ useImperativeHandle,
631
+ useLayoutEffect,
632
+ useRef as useRef2,
633
+ useState as useState5
634
+ } from "react";
635
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
636
+ var TextArea = forwardRef4(
637
+ function TextArea2({
638
+ value,
639
+ defaultValue = "",
640
+ onChange,
641
+ onValueChange,
642
+ label,
643
+ description,
644
+ descriptionDisplay = "inline",
645
+ helperText,
646
+ error,
647
+ errorMessage,
648
+ autosize = false,
649
+ clearable = false,
650
+ onClear,
651
+ clearLabel = "Clear text area",
652
+ className,
653
+ disabled,
654
+ readOnly,
655
+ id,
656
+ isRequired = false,
657
+ placeholder,
658
+ required,
659
+ "aria-describedby": ariaDescribedBy,
660
+ "aria-labelledby": ariaLabelledBy,
661
+ ...props
662
+ }, ref) {
663
+ const generatedId = useId3();
664
+ const inputId = id ?? generatedId + "-input";
665
+ const labelId = generatedId + "-label";
666
+ const messageId2 = generatedId + "-message";
667
+ const controlled = value !== void 0;
668
+ const [internalValue, setInternalValue] = useState5(defaultValue);
669
+ const textareaRef = useRef2(null);
670
+ const currentValue = controlled ? value : internalValue;
671
+ const fieldError = getFieldError(error, errorMessage);
672
+ const hasError = fieldError !== void 0 && fieldError !== false && fieldError !== null;
673
+ const resolvedDescription = description ?? helperText;
674
+ const hasMessage = hasError || resolvedDescription && descriptionDisplay === "inline";
675
+ const describedBy = getDescribedBy(
676
+ ariaDescribedBy,
677
+ hasMessage ? messageId2 : void 0
678
+ );
679
+ const labelledBy = getDescribedBy(
680
+ ariaLabelledBy,
681
+ label ? labelId : void 0
682
+ );
683
+ const resizeToContent = (textarea) => {
684
+ textarea.style.height = "auto";
685
+ textarea.style.height = `${textarea.scrollHeight}px`;
488
686
  };
489
- document.addEventListener("mousedown", close);
490
- return () => document.removeEventListener("mousedown", close);
491
- }, []);
492
- useLayoutEffect(() => {
493
- if (!open) return;
494
- const updateMenuPosition = () => {
495
- const rect = rootRef.current?.getBoundingClientRect();
496
- if (rect) setMenuPosition({ top: rect.bottom + 7, left: rect.left, width: rect.width });
687
+ useImperativeHandle(ref, () => textareaRef.current, []);
688
+ useLayoutEffect(() => {
689
+ if (autosize && textareaRef.current) {
690
+ resizeToContent(textareaRef.current);
691
+ }
692
+ }, [autosize, currentValue]);
693
+ const clear = () => {
694
+ if (!controlled) setInternalValue("");
695
+ onValueChange?.("");
696
+ onClear?.();
497
697
  };
498
- updateMenuPosition();
499
- window.addEventListener("resize", updateMenuPosition);
500
- document.addEventListener("scroll", updateMenuPosition, true);
501
- return () => {
502
- window.removeEventListener("resize", updateMenuPosition);
503
- document.removeEventListener("scroll", updateMenuPosition, true);
698
+ return /* @__PURE__ */ jsxs9(
699
+ "div",
700
+ {
701
+ className: [
702
+ "fe-text-area",
703
+ hasError && "fe-text-area--error",
704
+ autosize && "fe-text-area--autosize",
705
+ className
706
+ ].filter(Boolean).join(" "),
707
+ children: [
708
+ /* @__PURE__ */ jsx9(
709
+ FieldLabel,
710
+ {
711
+ id: labelId,
712
+ label,
713
+ description: resolvedDescription,
714
+ descriptionDisplay,
715
+ isRequired
716
+ }
717
+ ),
718
+ /* @__PURE__ */ jsxs9("span", { className: "fe-text-area__control", children: [
719
+ /* @__PURE__ */ jsx9(
720
+ "textarea",
721
+ {
722
+ ref: textareaRef,
723
+ id: inputId,
724
+ value: currentValue,
725
+ placeholder,
726
+ required: isRequired || required,
727
+ disabled,
728
+ readOnly,
729
+ "aria-invalid": hasError || void 0,
730
+ "aria-required": isRequired || void 0,
731
+ "aria-labelledby": labelledBy,
732
+ "aria-describedby": describedBy,
733
+ onChange: (event) => {
734
+ if (!controlled) setInternalValue(event.target.value);
735
+ if (autosize) resizeToContent(event.currentTarget);
736
+ onValueChange?.(event.target.value);
737
+ onChange?.(event);
738
+ },
739
+ ...props
740
+ }
741
+ ),
742
+ isRequired && placeholder && !currentValue && /* @__PURE__ */ jsxs9("span", { className: "fe-text-area__placeholder", "aria-hidden": "true", children: [
743
+ /* @__PURE__ */ jsx9("span", { children: placeholder }),
744
+ /* @__PURE__ */ jsx9("span", { className: "fe-field__required", children: "*" })
745
+ ] }),
746
+ clearable && currentValue && !disabled && !readOnly && /* @__PURE__ */ jsx9(
747
+ Button,
748
+ {
749
+ hierarchy: "tertiary-gray",
750
+ size: "24",
751
+ iconOnly: true,
752
+ icon: /* @__PURE__ */ jsx9(CloseIcon, { size: 14 }),
753
+ "aria-label": clearLabel,
754
+ onClick: clear,
755
+ className: "fe-text-area__clear"
756
+ }
757
+ )
758
+ ] }),
759
+ /* @__PURE__ */ jsx9(
760
+ FieldMessage,
761
+ {
762
+ id: messageId2,
763
+ error: fieldError,
764
+ description: resolvedDescription,
765
+ descriptionDisplay
766
+ }
767
+ )
768
+ ]
769
+ }
770
+ );
771
+ }
772
+ );
773
+ TextArea.displayName = "TextArea";
774
+
775
+ // packages/form-controls/src/controls/Selection/selection.tsx
776
+ import {
777
+ forwardRef as forwardRef5,
778
+ useEffect as useEffect3,
779
+ useId as useId4,
780
+ useLayoutEffect as useLayoutEffect2,
781
+ useRef as useRef3,
782
+ useState as useState6
783
+ } from "react";
784
+ import { createPortal as createPortal2 } from "react-dom";
785
+ import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
786
+ var Selection = forwardRef5(
787
+ function Selection2({
788
+ className,
789
+ label,
790
+ isRequired = false,
791
+ description,
792
+ descriptionDisplay = "inline",
793
+ helperText,
794
+ error,
795
+ errorMessage,
796
+ options,
797
+ placeholder = "Select an option",
798
+ size = "medium",
799
+ id,
800
+ value,
801
+ defaultValue,
802
+ onChange,
803
+ multiple = false,
804
+ searchable = false,
805
+ tag = false,
806
+ clearable = false,
807
+ disabled = false,
808
+ name,
809
+ onKeyDown,
810
+ "aria-label": ariaLabel,
811
+ "aria-describedby": ariaDescribedBy,
812
+ "aria-labelledby": ariaLabelledBy,
813
+ ...props
814
+ }, ref) {
815
+ const generatedId = useId4();
816
+ const triggerId = id ?? generatedId + "-trigger";
817
+ const listboxId = triggerId + "-listbox";
818
+ const labelId = generatedId + "-label";
819
+ const messageId2 = generatedId + "-message";
820
+ const fieldError = getFieldError(error, errorMessage);
821
+ const hasError = fieldError !== void 0 && fieldError !== false && fieldError !== null;
822
+ const resolvedDescription = description ?? helperText;
823
+ const hasMessage = hasError || resolvedDescription && descriptionDisplay === "inline";
824
+ const describedBy = getDescribedBy(
825
+ ariaDescribedBy,
826
+ hasMessage ? messageId2 : void 0
827
+ );
828
+ const labelledBy = getDescribedBy(
829
+ ariaLabelledBy,
830
+ label ? labelId : void 0
831
+ );
832
+ const isControlled = value !== void 0;
833
+ const [internalValue, setInternalValue] = useState6(
834
+ defaultValue ?? (multiple ? [] : "")
835
+ );
836
+ const selectedValue = isControlled ? value : internalValue;
837
+ const selectedValues = Array.isArray(selectedValue) ? selectedValue : selectedValue === "" || selectedValue === null || selectedValue === void 0 ? [] : [selectedValue];
838
+ const selectedOptions = options.filter(
839
+ (option) => selectedValues.some((item) => String(item) === String(option.value))
840
+ );
841
+ const [open, setOpen] = useState6(false);
842
+ const [query, setQuery] = useState6("");
843
+ const [activeIndex, setActiveIndex] = useState6(0);
844
+ const rootRef = useRef3(null);
845
+ const menuRef = useRef3(null);
846
+ const [menuPosition, setMenuPosition] = useState6(null);
847
+ useEffect3(() => {
848
+ const close = (event) => {
849
+ const target = event.target;
850
+ if (!rootRef.current?.contains(target) && !menuRef.current?.contains(target))
851
+ setOpen(false);
852
+ };
853
+ document.addEventListener("mousedown", close);
854
+ return () => document.removeEventListener("mousedown", close);
855
+ }, []);
856
+ useLayoutEffect2(() => {
857
+ if (!open) return;
858
+ const updateMenuPosition = () => {
859
+ const rect = rootRef.current?.getBoundingClientRect();
860
+ if (rect)
861
+ setMenuPosition({
862
+ top: rect.bottom + 7,
863
+ left: rect.left,
864
+ width: rect.width
865
+ });
866
+ };
867
+ updateMenuPosition();
868
+ window.addEventListener("resize", updateMenuPosition);
869
+ document.addEventListener("scroll", updateMenuPosition, true);
870
+ return () => {
871
+ window.removeEventListener("resize", updateMenuPosition);
872
+ document.removeEventListener("scroll", updateMenuPosition, true);
873
+ };
874
+ }, [open]);
875
+ const filteredOptions = options.filter(
876
+ (option) => !query || (option.searchText ?? (typeof option.label === "string" ? option.label : String(option.value))).toLowerCase().includes(query.toLowerCase())
877
+ );
878
+ const commit = (next) => {
879
+ if (!isControlled) setInternalValue(next);
880
+ const selected = options.filter(
881
+ (option) => (Array.isArray(next) ? next : [next]).some(
882
+ (item) => String(item) === String(option.value)
883
+ )
884
+ );
885
+ onChange?.(next, multiple ? selected : selected[0]);
504
886
  };
505
- }, [open]);
506
- const filteredOptions = options.filter((option) => !query || (option.searchText ?? (typeof option.label === "string" ? option.label : String(option.value))).toLowerCase().includes(query.toLowerCase()));
507
- const commit = (next) => {
508
- if (!isControlled) setInternalValue(next);
509
- const selected = options.filter((option) => (Array.isArray(next) ? next : [next]).some((item) => String(item) === String(option.value)));
510
- onChange?.(next, multiple ? selected : selected[0]);
511
- };
512
- const choose = (option) => {
513
- if (option.disabled) return;
514
- const isSelected = selectedValues.some((item) => String(item) === String(option.value));
515
- if (multiple) commit(isSelected ? selectedValues.filter((item) => String(item) !== String(option.value)) : [...selectedValues, option.value]);
516
- else {
517
- commit(option.value);
518
- setOpen(false);
887
+ const choose = (option) => {
888
+ if (option.disabled) return;
889
+ const isSelected = selectedValues.some(
890
+ (item) => String(item) === String(option.value)
891
+ );
892
+ if (multiple)
893
+ commit(
894
+ isSelected ? selectedValues.filter(
895
+ (item) => String(item) !== String(option.value)
896
+ ) : [...selectedValues, option.value]
897
+ );
898
+ else {
899
+ commit(option.value);
900
+ setOpen(false);
901
+ setQuery("");
902
+ }
903
+ };
904
+ const clear = () => {
905
+ commit(multiple ? [] : "");
519
906
  setQuery("");
520
- }
521
- };
522
- const clear = () => {
523
- commit(multiple ? [] : "");
524
- setQuery("");
525
- };
526
- const displayLabel = selectedOptions.length ? selectedOptions.map((option) => option.label) : null;
527
- const onTriggerKeyDown = (event) => {
528
- onKeyDown?.(event);
529
- if (disabled) return;
530
- if (event.key === "ArrowDown" || event.key === "ArrowUp") {
531
- event.preventDefault();
532
- setOpen(true);
533
- setActiveIndex((current) => Math.max(0, Math.min(filteredOptions.length - 1, current + (event.key === "ArrowDown" ? 1 : -1))));
534
- }
535
- if (event.key === "Enter" || event.key === " ") {
536
- event.preventDefault();
537
- if (!open) setOpen(true);
538
- else if (filteredOptions[activeIndex]) choose(filteredOptions[activeIndex]);
539
- }
540
- if (event.key === "Escape") setOpen(false);
541
- };
542
- return /* @__PURE__ */ jsxs7("div", { ref, className: ["fe-selection", `fe-selection--${size}`, open && "fe-selection--open", clearable && selectedOptions.length > 0 && "fe-selection--clearable", error && "fe-selection--error", disabled && "fe-selection--disabled", className].filter(Boolean).join(" "), ...props, children: [
543
- label && /* @__PURE__ */ jsx7("span", { className: "fe-selection__label", children: label }),
544
- /* @__PURE__ */ jsxs7("div", { ref: rootRef, className: "fe-selection__control", children: [
545
- name && selectedValues.map((item) => /* @__PURE__ */ jsx7("input", { type: "hidden", name: multiple ? `${name}[]` : name, value: item }, String(item))),
546
- /* @__PURE__ */ jsxs7("button", { type: "button", className: "fe-selection__trigger", disabled, "aria-invalid": error || void 0, "aria-haspopup": "listbox", "aria-expanded": open, "aria-controls": listboxId, onClick: () => setOpen((current) => !current), onKeyDown: onTriggerKeyDown, children: [
547
- /* @__PURE__ */ jsx7("span", { className: ["fe-selection__value", !selectedOptions.length && "is-placeholder", tag && selectedOptions.length > 1 && "is-tags"].filter(Boolean).join(" "), children: displayLabel ? tag && multiple ? selectedOptions.map((option) => /* @__PURE__ */ jsxs7("span", { className: "fe-selection__tag", children: [
548
- option.label,
549
- /* @__PURE__ */ jsx7("span", { "aria-hidden": "true", children: "\xD7" })
550
- ] }, String(option.value))) : displayLabel.map((item, index) => /* @__PURE__ */ jsxs7("span", { children: [
551
- item,
552
- index < displayLabel.length - 1 ? ", " : ""
553
- ] }, index)) : placeholder }),
554
- /* @__PURE__ */ jsx7("span", { className: "fe-selection__actions", children: /* @__PURE__ */ jsx7("span", { className: "fe-selection__chevron", "aria-hidden": "true" }) })
555
- ] }),
556
- clearable && selectedOptions.length > 0 && /* @__PURE__ */ jsx7("button", { type: "button", className: "fe-selection__clear", "aria-label": "Clear selection", onClick: clear }),
557
- open && menuPosition && createPortal2(/* @__PURE__ */ jsxs7("div", { ref: menuRef, id: listboxId, className: "fe-selection__menu", style: { position: "fixed", top: menuPosition.top, left: menuPosition.left, width: menuPosition.width }, role: "listbox", "aria-multiselectable": multiple || void 0, children: [
558
- searchable && /* @__PURE__ */ jsxs7("div", { className: "fe-selection__search", children: [
559
- /* @__PURE__ */ jsx7("span", { "aria-hidden": "true", children: "\u2315" }),
560
- /* @__PURE__ */ jsx7("input", { autoFocus: true, value: query, onChange: (event) => {
561
- setQuery(event.target.value);
562
- setActiveIndex(0);
563
- }, placeholder: "Search\u2026", "aria-label": "Search options" })
564
- ] }),
565
- /* @__PURE__ */ jsx7("div", { className: "fe-selection__options", children: filteredOptions.length ? filteredOptions.map((option, index) => {
566
- const isSelected = selectedValues.some((item) => String(item) === String(option.value));
567
- return /* @__PURE__ */ jsxs7("button", { type: "button", className: [isSelected && "is-selected", index === activeIndex && "is-active"].filter(Boolean).join(" "), role: "option", "aria-selected": isSelected, disabled: option.disabled, onMouseMove: () => setActiveIndex(index), onClick: () => choose(option), children: [
568
- /* @__PURE__ */ jsx7("span", { children: option.label }),
569
- isSelected && /* @__PURE__ */ jsx7("span", { className: "fe-selection__check", "aria-hidden": "true", children: "\u2713" })
570
- ] }, String(option.value));
571
- }) : /* @__PURE__ */ jsx7("p", { className: "fe-selection__empty", children: "No matching options" }) })
572
- ] }), document.body)
573
- ] }),
574
- helperText && /* @__PURE__ */ jsx7("span", { className: "fe-selection__helper", children: helperText })
575
- ] });
576
- });
907
+ };
908
+ const displayLabel = selectedOptions.length ? selectedOptions.map((option) => option.label) : null;
909
+ const onTriggerKeyDown = (event) => {
910
+ onKeyDown?.(event);
911
+ if (disabled) return;
912
+ if (event.key === "ArrowDown" || event.key === "ArrowUp") {
913
+ event.preventDefault();
914
+ setOpen(true);
915
+ setActiveIndex(
916
+ (current) => Math.max(
917
+ 0,
918
+ Math.min(
919
+ filteredOptions.length - 1,
920
+ current + (event.key === "ArrowDown" ? 1 : -1)
921
+ )
922
+ )
923
+ );
924
+ }
925
+ if (event.key === "Enter" || event.key === " ") {
926
+ event.preventDefault();
927
+ if (!open) setOpen(true);
928
+ else if (filteredOptions[activeIndex])
929
+ choose(filteredOptions[activeIndex]);
930
+ }
931
+ if (event.key === "Escape") setOpen(false);
932
+ };
933
+ return /* @__PURE__ */ jsxs10(
934
+ "div",
935
+ {
936
+ ref,
937
+ className: [
938
+ "fe-selection",
939
+ "fe-selection--" + size,
940
+ open && "fe-selection--open",
941
+ clearable && selectedOptions.length > 0 && "fe-selection--clearable",
942
+ hasError && "fe-selection--error",
943
+ disabled && "fe-selection--disabled",
944
+ className
945
+ ].filter(Boolean).join(" "),
946
+ ...props,
947
+ children: [
948
+ /* @__PURE__ */ jsx10(
949
+ FieldLabel,
950
+ {
951
+ id: labelId,
952
+ label,
953
+ description: resolvedDescription,
954
+ descriptionDisplay,
955
+ isRequired
956
+ }
957
+ ),
958
+ /* @__PURE__ */ jsxs10("div", { ref: rootRef, className: "fe-selection__control", children: [
959
+ name && selectedValues.map((item) => /* @__PURE__ */ jsx10(
960
+ "input",
961
+ {
962
+ type: "hidden",
963
+ name: multiple ? name + "[]" : name,
964
+ value: item
965
+ },
966
+ String(item)
967
+ )),
968
+ /* @__PURE__ */ jsxs10(
969
+ "button",
970
+ {
971
+ id: triggerId,
972
+ type: "button",
973
+ className: "fe-selection__trigger",
974
+ disabled,
975
+ "aria-label": ariaLabel,
976
+ "aria-invalid": hasError || void 0,
977
+ "aria-required": isRequired || void 0,
978
+ "aria-labelledby": labelledBy,
979
+ "aria-describedby": describedBy,
980
+ "aria-haspopup": "listbox",
981
+ "aria-expanded": open,
982
+ "aria-controls": listboxId,
983
+ onClick: () => setOpen((current) => !current),
984
+ onKeyDown: onTriggerKeyDown,
985
+ children: [
986
+ /* @__PURE__ */ jsx10(
987
+ "span",
988
+ {
989
+ className: [
990
+ "fe-selection__value",
991
+ !selectedOptions.length && "is-placeholder",
992
+ tag && selectedOptions.length > 1 && "is-tags"
993
+ ].filter(Boolean).join(" "),
994
+ children: displayLabel ? tag && multiple ? selectedOptions.map((option) => /* @__PURE__ */ jsxs10(
995
+ "span",
996
+ {
997
+ className: "fe-selection__tag",
998
+ children: [
999
+ option.label,
1000
+ /* @__PURE__ */ jsx10("span", { "aria-hidden": "true", children: "\xD7" })
1001
+ ]
1002
+ },
1003
+ String(option.value)
1004
+ )) : displayLabel.map((item, index) => /* @__PURE__ */ jsxs10("span", { children: [
1005
+ item,
1006
+ index < displayLabel.length - 1 ? ", " : ""
1007
+ ] }, index)) : /* @__PURE__ */ jsxs10(Fragment2, { children: [
1008
+ /* @__PURE__ */ jsx10("span", { children: placeholder }),
1009
+ isRequired && /* @__PURE__ */ jsx10("span", { className: "fe-field__required", "aria-hidden": "true", children: "*" })
1010
+ ] })
1011
+ }
1012
+ ),
1013
+ /* @__PURE__ */ jsx10("span", { className: "fe-selection__actions", children: /* @__PURE__ */ jsx10("span", { className: "fe-selection__chevron", "aria-hidden": "true" }) })
1014
+ ]
1015
+ }
1016
+ ),
1017
+ clearable && selectedOptions.length > 0 && !disabled && /* @__PURE__ */ jsx10(
1018
+ "button",
1019
+ {
1020
+ type: "button",
1021
+ className: "fe-selection__clear",
1022
+ "aria-label": "Clear selection",
1023
+ onClick: clear
1024
+ }
1025
+ ),
1026
+ open && menuPosition && createPortal2(
1027
+ /* @__PURE__ */ jsxs10(
1028
+ "div",
1029
+ {
1030
+ ref: menuRef,
1031
+ id: listboxId,
1032
+ className: "fe-selection__menu",
1033
+ style: {
1034
+ position: "fixed",
1035
+ top: menuPosition.top,
1036
+ left: menuPosition.left,
1037
+ width: menuPosition.width
1038
+ },
1039
+ role: "listbox",
1040
+ "aria-multiselectable": multiple || void 0,
1041
+ children: [
1042
+ searchable && /* @__PURE__ */ jsxs10("div", { className: "fe-selection__search", children: [
1043
+ /* @__PURE__ */ jsx10("span", { "aria-hidden": "true", children: "\u2315" }),
1044
+ /* @__PURE__ */ jsx10(
1045
+ "input",
1046
+ {
1047
+ autoFocus: true,
1048
+ value: query,
1049
+ onChange: (event) => {
1050
+ setQuery(event.target.value);
1051
+ setActiveIndex(0);
1052
+ },
1053
+ placeholder: "Search\u2026",
1054
+ "aria-label": "Search options"
1055
+ }
1056
+ )
1057
+ ] }),
1058
+ /* @__PURE__ */ jsx10("div", { className: "fe-selection__options", children: filteredOptions.length ? filteredOptions.map((option, index) => {
1059
+ const isSelected = selectedValues.some(
1060
+ (item) => String(item) === String(option.value)
1061
+ );
1062
+ return /* @__PURE__ */ jsxs10(
1063
+ "button",
1064
+ {
1065
+ type: "button",
1066
+ className: [
1067
+ isSelected && "is-selected",
1068
+ index === activeIndex && "is-active"
1069
+ ].filter(Boolean).join(" "),
1070
+ role: "option",
1071
+ "aria-selected": isSelected,
1072
+ disabled: option.disabled,
1073
+ onMouseMove: () => setActiveIndex(index),
1074
+ onClick: () => choose(option),
1075
+ children: [
1076
+ /* @__PURE__ */ jsx10("span", { children: option.label }),
1077
+ isSelected && /* @__PURE__ */ jsx10(
1078
+ "span",
1079
+ {
1080
+ className: "fe-selection__check",
1081
+ "aria-hidden": "true",
1082
+ children: "\u2713"
1083
+ }
1084
+ )
1085
+ ]
1086
+ },
1087
+ String(option.value)
1088
+ );
1089
+ }) : /* @__PURE__ */ jsx10("p", { className: "fe-selection__empty", children: "No matching options" }) })
1090
+ ]
1091
+ }
1092
+ ),
1093
+ document.body
1094
+ )
1095
+ ] }),
1096
+ /* @__PURE__ */ jsx10(
1097
+ FieldMessage,
1098
+ {
1099
+ id: messageId2,
1100
+ error: fieldError,
1101
+ description: resolvedDescription,
1102
+ descriptionDisplay
1103
+ }
1104
+ )
1105
+ ]
1106
+ }
1107
+ );
1108
+ }
1109
+ );
577
1110
  Selection.displayName = "Selection";
1111
+
1112
+ // packages/form-controls/src/controls/NumberInput/number-input.tsx
1113
+ import {
1114
+ forwardRef as forwardRef6,
1115
+ useEffect as useEffect4,
1116
+ useId as useId5,
1117
+ useRef as useRef4,
1118
+ useState as useState7
1119
+ } from "react";
1120
+ import { jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
578
1121
  function formatNumber(value, decimals = 2, thousandSeparator = ",", decimalSeparator = ".") {
579
1122
  return new Intl.NumberFormat("en-US", {
580
1123
  minimumFractionDigits: 0,
@@ -583,16 +1126,24 @@ function formatNumber(value, decimals = 2, thousandSeparator = ",", decimalSepar
583
1126
  }).format(value).replace(/,/g, thousandSeparator).replace(/\./g, decimalSeparator);
584
1127
  }
585
1128
  function escapeRegExp(value) {
586
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1129
+ return value.replace(/[.*+?^$\x7B\x7D()|[\]\\]/g, "\\$&");
587
1130
  }
588
1131
  function groupInteger(value, separator) {
589
1132
  return value.replace(/\B(?=(\d{3})+(?!\d))/g, separator);
590
1133
  }
1134
+ function roundToDecimals(value, decimals) {
1135
+ const precision = Math.min(Math.max(0, decimals), 15);
1136
+ const multiplier = 10 ** precision;
1137
+ return Math.round((value + Number.EPSILON) * multiplier) / multiplier;
1138
+ }
591
1139
  function normalizeNumberInput(raw, options) {
592
1140
  const { allowDecimal, decimalSeparator, thousandSeparator, min, max } = options;
593
1141
  const decimals = Math.max(0, options.decimals);
594
1142
  const negative = raw.trimStart().startsWith("-") && (min === void 0 || min < 0);
595
- const decimalExpression = new RegExp(`[^0-9${allowDecimal ? escapeRegExp(decimalSeparator) : ""}]`, "g");
1143
+ const decimalExpression = new RegExp(
1144
+ "[^0-9" + (allowDecimal ? escapeRegExp(decimalSeparator) : "") + "]",
1145
+ "g"
1146
+ );
596
1147
  const cleaned = raw.replace(decimalExpression, "");
597
1148
  const decimalIndex = allowDecimal ? cleaned.indexOf(decimalSeparator) : -1;
598
1149
  const hasDecimal = decimalIndex >= 0;
@@ -600,64 +1151,320 @@ function normalizeNumberInput(raw, options) {
600
1151
  const rawFraction = hasDecimal ? cleaned.slice(decimalIndex + decimalSeparator.length).replace(new RegExp(escapeRegExp(decimalSeparator), "g"), "") : "";
601
1152
  const integer = rawInteger.replace(/^0+(?=\d)/, "") || (rawInteger ? "0" : "");
602
1153
  const fraction = rawFraction.slice(0, decimals);
603
- if (!integer && !fraction) return { display: negative ? "-" : "", value: null };
604
- const numericValue = Number(`${negative ? "-" : ""}${integer || "0"}${hasDecimal ? `.${fraction || "0"}` : ""}`);
1154
+ if (!integer && !fraction)
1155
+ return { display: negative ? "-" : "", value: null };
1156
+ const numericValue = Number(
1157
+ (negative ? "-" : "") + (integer || "0") + (hasDecimal ? "." + (fraction || "0") : "")
1158
+ );
605
1159
  if (!Number.isFinite(numericValue)) return { display: "", value: null };
606
1160
  const lowerBound = min === void 0 ? numericValue : Math.max(numericValue, min);
607
1161
  const value = max === void 0 ? lowerBound : Math.min(lowerBound, max);
608
- if (value !== numericValue) return { display: formatNumber(value, decimals, thousandSeparator, decimalSeparator), value };
609
- return { display: `${negative ? "-" : ""}${groupInteger(integer || "0", thousandSeparator)}${hasDecimal ? `${decimalSeparator}${fraction}` : ""}`, value };
610
- }
611
- var NumberInput = forwardRef3(function NumberInput2({ value, defaultValue = null, onValueChange, allowDecimal = true, decimals = 2, min, max, decimalSeparator = ".", thousandSeparator = ",", label, helperText, error, errorMessage, className, onBlur, onFocus, "aria-describedby": ariaDescribedBy, ...props }, ref) {
612
- const generatedId = useId();
613
- const messageId2 = `${generatedId}-message`;
614
- const isControlled = value !== void 0;
615
- const [internalValue, setInternalValue] = useState3(defaultValue);
616
- const [focused, setFocused] = useState3(false);
617
- const actualValue = isControlled ? value ?? null : internalValue;
618
- const [text, setText] = useState3(actualValue === null ? "" : formatNumber(actualValue, decimals, thousandSeparator, decimalSeparator));
619
- const fieldError = getFieldError(error, errorMessage);
620
- const hasError = fieldError !== void 0 && fieldError !== false && fieldError !== null;
621
- const displayedMessage = hasError ? fieldError : helperText;
622
- const describedBy = getDescribedBy(ariaDescribedBy, displayedMessage ? messageId2 : void 0);
623
- useEffect3(() => {
624
- if (!focused) setText(actualValue === null ? "" : formatNumber(actualValue, decimals, thousandSeparator, decimalSeparator));
625
- }, [actualValue, decimalSeparator, decimals, focused, thousandSeparator]);
626
- const updateValue = (nextText) => {
627
- const next = normalizeNumberInput(nextText, { allowDecimal, decimals, decimalSeparator, thousandSeparator, min, max });
628
- setText(next.display);
629
- const nextValue = next.value;
630
- if (!isControlled) setInternalValue(nextValue);
631
- onValueChange?.(nextValue);
1162
+ if (value !== numericValue)
1163
+ return {
1164
+ display: formatNumber(
1165
+ value,
1166
+ decimals,
1167
+ thousandSeparator,
1168
+ decimalSeparator
1169
+ ),
1170
+ value
1171
+ };
1172
+ return {
1173
+ display: (negative ? "-" : "") + groupInteger(integer || "0", thousandSeparator) + (hasDecimal ? decimalSeparator + fraction : ""),
1174
+ value
632
1175
  };
633
- return /* @__PURE__ */ jsxs7("label", { className: ["fe-number-input", hasError && "fe-number-input--error", className].filter(Boolean).join(" "), children: [
634
- label && /* @__PURE__ */ jsx7("span", { className: "fe-number-input__label", children: label }),
635
- /* @__PURE__ */ jsx7("input", { ref, inputMode: allowDecimal ? "decimal" : "numeric", value: text, onFocus: (event) => {
636
- setFocused(true);
637
- onFocus?.(event);
638
- }, onChange: (event) => updateValue(event.target.value), onBlur: (event) => {
639
- setFocused(false);
640
- onBlur?.(event);
641
- }, ...props, "aria-invalid": hasError || void 0, "aria-describedby": describedBy }),
642
- displayedMessage && /* @__PURE__ */ jsx7("span", { id: messageId2, className: hasError ? "fe-number-input__error" : "fe-number-input__helper", children: displayedMessage })
643
- ] });
644
- });
1176
+ }
1177
+ var NumberInput = forwardRef6(
1178
+ function NumberInput2({
1179
+ value,
1180
+ defaultValue = null,
1181
+ onValueChange,
1182
+ allowDecimal = true,
1183
+ decimals = 2,
1184
+ min,
1185
+ max,
1186
+ decimalSeparator = ".",
1187
+ thousandSeparator = ",",
1188
+ label,
1189
+ description,
1190
+ descriptionDisplay = "inline",
1191
+ helperText,
1192
+ error,
1193
+ errorMessage,
1194
+ isRequired = false,
1195
+ className,
1196
+ onBlur,
1197
+ onFocus,
1198
+ placeholder,
1199
+ required,
1200
+ endAdornment,
1201
+ prefix,
1202
+ suffix,
1203
+ Prefix,
1204
+ Suffix,
1205
+ step = 1,
1206
+ showStepper = true,
1207
+ incrementLabel = "Increase value",
1208
+ decrementLabel = "Decrease value",
1209
+ "aria-describedby": ariaDescribedBy,
1210
+ "aria-labelledby": ariaLabelledBy,
1211
+ onKeyDown,
1212
+ ...props
1213
+ }, ref) {
1214
+ const inputRef = useRef4(null);
1215
+ const generatedId = useId5();
1216
+ const messageId2 = generatedId + "-message";
1217
+ const isControlled = value !== void 0;
1218
+ const [internalValue, setInternalValue] = useState7(defaultValue);
1219
+ const [focused, setFocused] = useState7(false);
1220
+ const actualValue = isControlled ? value ?? null : internalValue;
1221
+ const [text, setText] = useState7(
1222
+ actualValue === null ? "" : formatNumber(
1223
+ actualValue,
1224
+ decimals,
1225
+ thousandSeparator,
1226
+ decimalSeparator
1227
+ )
1228
+ );
1229
+ const fieldError = getFieldError(error, errorMessage);
1230
+ const hasError = fieldError !== void 0 && fieldError !== false && fieldError !== null;
1231
+ const labelId = generatedId + "-label";
1232
+ const resolvedDescription = description ?? helperText;
1233
+ const hasMessage = hasError || resolvedDescription && descriptionDisplay === "inline";
1234
+ const describedBy = getDescribedBy(
1235
+ ariaDescribedBy,
1236
+ hasMessage ? messageId2 : void 0
1237
+ );
1238
+ const labelledBy = getDescribedBy(
1239
+ ariaLabelledBy,
1240
+ label ? labelId : void 0
1241
+ );
1242
+ const resolvedPrefix = prefix ?? Prefix;
1243
+ const resolvedSuffix = suffix ?? Suffix;
1244
+ useEffect4(() => {
1245
+ if (!focused)
1246
+ setText(
1247
+ actualValue === null ? "" : formatNumber(
1248
+ actualValue,
1249
+ decimals,
1250
+ thousandSeparator,
1251
+ decimalSeparator
1252
+ )
1253
+ );
1254
+ }, [actualValue, decimalSeparator, decimals, focused, thousandSeparator]);
1255
+ const updateValue = (nextText) => {
1256
+ const next = normalizeNumberInput(nextText, {
1257
+ allowDecimal,
1258
+ decimals,
1259
+ decimalSeparator,
1260
+ thousandSeparator,
1261
+ min,
1262
+ max
1263
+ });
1264
+ setText(next.display);
1265
+ if (!isControlled) setInternalValue(next.value);
1266
+ onValueChange?.(next.value);
1267
+ };
1268
+ const setValue = (nextValue) => {
1269
+ const clamped = Math.min(
1270
+ max ?? Number.POSITIVE_INFINITY,
1271
+ Math.max(min ?? Number.NEGATIVE_INFINITY, nextValue)
1272
+ );
1273
+ const normalized = roundToDecimals(
1274
+ clamped,
1275
+ allowDecimal ? decimals : 0
1276
+ );
1277
+ setText(
1278
+ formatNumber(
1279
+ normalized,
1280
+ decimals,
1281
+ thousandSeparator,
1282
+ decimalSeparator
1283
+ )
1284
+ );
1285
+ if (!isControlled) setInternalValue(normalized);
1286
+ onValueChange?.(normalized);
1287
+ };
1288
+ const adjustValue = (direction) => {
1289
+ if (props.disabled || props.readOnly || !Number.isFinite(step) || step <= 0)
1290
+ return;
1291
+ const baseValue = actualValue ?? min ?? 0;
1292
+ setValue(baseValue + direction * step);
1293
+ inputRef.current?.focus();
1294
+ };
1295
+ const stepIsUsable = Number.isFinite(step) && step > 0;
1296
+ const disableIncrement = Boolean(props.disabled || props.readOnly) || !stepIsUsable || max !== void 0 && actualValue !== null && actualValue >= max;
1297
+ const disableDecrement = Boolean(props.disabled || props.readOnly) || !stepIsUsable || min !== void 0 && actualValue !== null && actualValue <= min;
1298
+ return /* @__PURE__ */ jsxs11(
1299
+ "div",
1300
+ {
1301
+ className: [
1302
+ "fe-number-input",
1303
+ hasError && "fe-number-input--error",
1304
+ className
1305
+ ].filter(Boolean).join(" "),
1306
+ children: [
1307
+ /* @__PURE__ */ jsx11(
1308
+ FieldLabel,
1309
+ {
1310
+ id: labelId,
1311
+ label,
1312
+ description: resolvedDescription,
1313
+ descriptionDisplay,
1314
+ isRequired
1315
+ }
1316
+ ),
1317
+ /* @__PURE__ */ jsxs11("span", { className: "fe-number-input__control", children: [
1318
+ resolvedPrefix && /* @__PURE__ */ jsx11("span", { className: "fe-number-input__prefix", children: resolvedPrefix }),
1319
+ /* @__PURE__ */ jsxs11("span", { className: "fe-number-input__input-wrap", children: [
1320
+ /* @__PURE__ */ jsx11(
1321
+ "input",
1322
+ {
1323
+ ref: (node) => {
1324
+ inputRef.current = node;
1325
+ if (typeof ref === "function") ref(node);
1326
+ else if (ref) ref.current = node;
1327
+ },
1328
+ inputMode: allowDecimal ? "decimal" : "numeric",
1329
+ value: text,
1330
+ placeholder,
1331
+ required: isRequired || required,
1332
+ onFocus: (event) => {
1333
+ setFocused(true);
1334
+ onFocus?.(event);
1335
+ },
1336
+ onChange: (event) => updateValue(event.target.value),
1337
+ onBlur: (event) => {
1338
+ setFocused(false);
1339
+ onBlur?.(event);
1340
+ },
1341
+ onKeyDown: (event) => {
1342
+ onKeyDown?.(event);
1343
+ if (event.defaultPrevented) return;
1344
+ if (event.key === "ArrowUp" || event.key === "ArrowDown") {
1345
+ event.preventDefault();
1346
+ adjustValue(event.key === "ArrowUp" ? 1 : -1);
1347
+ }
1348
+ },
1349
+ ...props,
1350
+ "aria-invalid": hasError || void 0,
1351
+ "aria-required": isRequired || void 0,
1352
+ "aria-labelledby": labelledBy,
1353
+ "aria-describedby": describedBy
1354
+ }
1355
+ ),
1356
+ isRequired && placeholder && !text && /* @__PURE__ */ jsxs11(
1357
+ "span",
1358
+ {
1359
+ className: "fe-number-input__placeholder",
1360
+ "aria-hidden": "true",
1361
+ children: [
1362
+ /* @__PURE__ */ jsx11("span", { children: placeholder }),
1363
+ /* @__PURE__ */ jsx11("span", { className: "fe-field__required", children: "*" })
1364
+ ]
1365
+ }
1366
+ )
1367
+ ] }),
1368
+ resolvedSuffix && /* @__PURE__ */ jsx11("span", { className: "fe-number-input__suffix", children: resolvedSuffix }),
1369
+ endAdornment,
1370
+ showStepper && /* @__PURE__ */ jsxs11("span", { className: "fe-number-input__stepper", children: [
1371
+ /* @__PURE__ */ jsx11(
1372
+ Button,
1373
+ {
1374
+ hierarchy: "tertiary-gray",
1375
+ size: "24",
1376
+ iconOnly: true,
1377
+ icon: /* @__PURE__ */ jsx11(ChevronUpIcon, { size: 12 }),
1378
+ "aria-label": incrementLabel,
1379
+ disabled: disableIncrement,
1380
+ onMouseDown: (event) => event.preventDefault(),
1381
+ onClick: () => adjustValue(1)
1382
+ }
1383
+ ),
1384
+ /* @__PURE__ */ jsx11(
1385
+ Button,
1386
+ {
1387
+ hierarchy: "tertiary-gray",
1388
+ size: "24",
1389
+ iconOnly: true,
1390
+ icon: /* @__PURE__ */ jsx11(ChevronDownIcon, { size: 12 }),
1391
+ "aria-label": decrementLabel,
1392
+ disabled: disableDecrement,
1393
+ onMouseDown: (event) => event.preventDefault(),
1394
+ onClick: () => adjustValue(-1)
1395
+ }
1396
+ )
1397
+ ] })
1398
+ ] }),
1399
+ /* @__PURE__ */ jsx11(
1400
+ FieldMessage,
1401
+ {
1402
+ id: messageId2,
1403
+ error: fieldError,
1404
+ description: resolvedDescription,
1405
+ descriptionDisplay
1406
+ }
1407
+ )
1408
+ ]
1409
+ }
1410
+ );
1411
+ }
1412
+ );
645
1413
  NumberInput.displayName = "NumberInput";
646
- function CurrencyInput({ suffix = "VND", currencies, currency, defaultCurrency, onCurrencyChange, className, ...props }) {
647
- const [internalCurrency, setInternalCurrency] = useState3(defaultCurrency ?? currencies?.[0]?.code ?? "");
1414
+
1415
+ // packages/form-controls/src/controls/CurrencyInput/currency-input.tsx
1416
+ import { useState as useState8 } from "react";
1417
+ import { jsx as jsx12 } from "react/jsx-runtime";
1418
+ function CurrencyInput({
1419
+ suffix = "VND",
1420
+ currencies,
1421
+ currency,
1422
+ defaultCurrency,
1423
+ onCurrencyChange,
1424
+ className,
1425
+ disabled,
1426
+ ...props
1427
+ }) {
1428
+ const [internalCurrency, setInternalCurrency] = useState8(
1429
+ defaultCurrency ?? currencies?.[0]?.code ?? ""
1430
+ );
648
1431
  const selectedCurrency = currency ?? internalCurrency;
649
1432
  const current = currencies?.find((item) => item.code === selectedCurrency);
650
1433
  const currencySuffix = current?.suffix ?? current?.code ?? suffix;
651
- return /* @__PURE__ */ jsxs7("div", { className: ["fe-currency-input", className].filter(Boolean).join(" "), children: [
652
- /* @__PURE__ */ jsx7(NumberInput, { ...props, className: "fe-currency-input__number" }),
653
- currencies?.length ? /* @__PURE__ */ jsx7("select", { className: "fe-currency-input__currency", "aria-label": "Currency", value: selectedCurrency, onChange: (event) => {
654
- const next = currencies.find((item) => item.code === event.target.value);
655
- if (!next) return;
656
- if (currency === void 0) setInternalCurrency(next.code);
657
- onCurrencyChange?.(next);
658
- }, children: currencies.map((item) => /* @__PURE__ */ jsx7("option", { value: item.code, children: item.label ?? item.code }, item.code)) }) : /* @__PURE__ */ jsx7("span", { className: "fe-currency-input__suffix", children: currencySuffix })
659
- ] });
1434
+ const endAdornment = currencies?.length ? /* @__PURE__ */ jsx12(
1435
+ Selection,
1436
+ {
1437
+ className: "fe-currency-input__currency",
1438
+ "aria-label": "Currency",
1439
+ options: currencies.map((item) => ({
1440
+ label: item.label ?? item.code,
1441
+ value: item.code
1442
+ })),
1443
+ disabled,
1444
+ value: selectedCurrency,
1445
+ size: "small",
1446
+ onChange: (value) => {
1447
+ const next = currencies.find((item) => item.code === String(value));
1448
+ if (!next) return;
1449
+ if (currency === void 0) setInternalCurrency(next.code);
1450
+ onCurrencyChange?.(next);
1451
+ }
1452
+ }
1453
+ ) : /* @__PURE__ */ jsx12("span", { className: "fe-currency-input__suffix", children: currencySuffix });
1454
+ return /* @__PURE__ */ jsx12(
1455
+ NumberInput,
1456
+ {
1457
+ ...props,
1458
+ disabled,
1459
+ className: ["fe-currency-input", className].filter(Boolean).join(" "),
1460
+ endAdornment
1461
+ }
1462
+ );
660
1463
  }
1464
+
1465
+ // packages/form-controls/src/controls/DateTimePicker/date-time-picker.tsx
1466
+ import { useEffect as useEffect5, useId as useId6, useRef as useRef5, useState as useState9 } from "react";
1467
+ import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
661
1468
  var pad = (value) => String(value).padStart(2, "0");
662
1469
  function formatDate(date, format) {
663
1470
  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()));
@@ -675,24 +1482,66 @@ function mergeDateTime(day, time) {
675
1482
  return next;
676
1483
  }
677
1484
  function DateTimePicker(props) {
678
- const { label, format = "dd/MM/yyyy HH:mm", disabled, placeholder, locale = "en-US", className, mode = "single" } = props;
1485
+ const {
1486
+ label,
1487
+ description,
1488
+ descriptionDisplay = "inline",
1489
+ helperText,
1490
+ error,
1491
+ errorMessage,
1492
+ isRequired = false,
1493
+ format = "dd/MM/yyyy HH:mm",
1494
+ disabled,
1495
+ placeholder,
1496
+ locale = "en-US",
1497
+ className,
1498
+ mode = "single",
1499
+ id,
1500
+ "aria-describedby": ariaDescribedBy,
1501
+ "aria-labelledby": ariaLabelledBy
1502
+ } = props;
1503
+ const generatedId = useId6();
1504
+ const triggerId = id ?? generatedId + "-trigger";
1505
+ const labelId = generatedId + "-label";
1506
+ const messageId2 = generatedId + "-message";
1507
+ const fieldError = getFieldError(error, errorMessage);
1508
+ const hasError = fieldError !== void 0 && fieldError !== false && fieldError !== null;
1509
+ const resolvedDescription = description ?? helperText;
1510
+ const hasMessage = hasError || resolvedDescription && descriptionDisplay === "inline";
1511
+ const describedBy = getDescribedBy(
1512
+ ariaDescribedBy,
1513
+ hasMessage ? messageId2 : void 0
1514
+ );
1515
+ const labelledBy = getDescribedBy(
1516
+ ariaLabelledBy,
1517
+ label ? labelId : void 0
1518
+ );
679
1519
  const isRange = mode === "range";
680
1520
  const controlled = props.value !== void 0;
681
- const [singleInternal, setSingleInternal] = useState3((!isRange ? props.defaultValue : null) ?? null);
682
- const [rangeInternal, setRangeInternal] = useState3((isRange ? props.defaultValue : void 0) ?? [null, null]);
1521
+ const [singleInternal, setSingleInternal] = useState9(
1522
+ (!isRange ? props.defaultValue : null) ?? null
1523
+ );
1524
+ const [rangeInternal, setRangeInternal] = useState9(
1525
+ (isRange ? props.defaultValue : void 0) ?? [null, null]
1526
+ );
683
1527
  const singleValue = !isRange ? props.value ?? singleInternal : null;
684
1528
  const rangeValue = isRange ? props.value ?? rangeInternal : [null, null];
685
- const [open, setOpen] = useState3(false);
686
- const [month, setMonth] = useState3(() => new Date((isRange ? rangeValue[0] : singleValue) ?? /* @__PURE__ */ new Date()));
687
- const [editingEnd, setEditingEnd] = useState3(false);
688
- const rootRef = useRef2(null);
689
- useEffect3(() => {
1529
+ const [open, setOpen] = useState9(false);
1530
+ const [month, setMonth] = useState9(
1531
+ () => new Date((isRange ? rangeValue[0] : singleValue) ?? /* @__PURE__ */ new Date())
1532
+ );
1533
+ const [editingEnd, setEditingEnd] = useState9(false);
1534
+ const rootRef = useRef5(null);
1535
+ useEffect5(() => {
690
1536
  const onPointerDown = (event) => {
691
1537
  if (!rootRef.current?.contains(event.target)) setOpen(false);
692
1538
  };
693
1539
  document.addEventListener("mousedown", onPointerDown);
694
1540
  return () => document.removeEventListener("mousedown", onPointerDown);
695
1541
  }, []);
1542
+ useEffect5(() => {
1543
+ if (disabled) setOpen(false);
1544
+ }, [disabled]);
696
1545
  const setSingle = (next) => {
697
1546
  if (!controlled) setSingleInternal(next);
698
1547
  props.onChange?.(next);
@@ -703,13 +1552,24 @@ function DateTimePicker(props) {
703
1552
  };
704
1553
  const selectDay = (day) => {
705
1554
  if (!isRange) {
706
- setSingle(mergeDateTime(day, singleValue ? `${pad(singleValue.getHours())}:${pad(singleValue.getMinutes())}` : "00:00"));
1555
+ setSingle(
1556
+ mergeDateTime(
1557
+ day,
1558
+ singleValue ? pad(singleValue.getHours()) + ":" + pad(singleValue.getMinutes()) : "00:00"
1559
+ )
1560
+ );
707
1561
  setOpen(false);
708
1562
  return;
709
1563
  }
710
1564
  const [start, end] = rangeValue;
711
1565
  if (!start || end || editingEnd) {
712
- setRange([mergeDateTime(day, start ? `${pad(start.getHours())}:${pad(start.getMinutes())}` : "00:00"), null]);
1566
+ setRange([
1567
+ mergeDateTime(
1568
+ day,
1569
+ start ? pad(start.getHours()) + ":" + pad(start.getMinutes()) : "00:00"
1570
+ ),
1571
+ null
1572
+ ]);
713
1573
  setEditingEnd(false);
714
1574
  return;
715
1575
  }
@@ -717,97 +1577,360 @@ function DateTimePicker(props) {
717
1577
  setRange(nextEnd < start ? [nextEnd, start] : [start, nextEnd]);
718
1578
  setEditingEnd(false);
719
1579
  };
720
- const shownValue = isRange ? [rangeValue[0] && formatDate(rangeValue[0], format), rangeValue[1] && formatDate(rangeValue[1], format)].filter(Boolean).join(" \u2014 ") : singleValue && formatDate(singleValue, format);
1580
+ const shownValue = isRange ? [
1581
+ rangeValue[0] && formatDate(rangeValue[0], format),
1582
+ rangeValue[1] && formatDate(rangeValue[1], format)
1583
+ ].filter(Boolean).join(" \u2014 ") : singleValue && formatDate(singleValue, format);
721
1584
  const firstDay = new Date(month.getFullYear(), month.getMonth(), 1);
722
1585
  const offset = (firstDay.getDay() + 6) % 7;
723
- const days = Array.from({ length: 42 }, (_, index) => new Date(month.getFullYear(), month.getMonth(), index - offset + 1));
1586
+ const days = Array.from(
1587
+ { length: 42 },
1588
+ (_, index) => new Date(month.getFullYear(), month.getMonth(), index - offset + 1)
1589
+ );
724
1590
  const selectedForTime = isRange ? editingEnd ? rangeValue[1] : rangeValue[0] : singleValue;
725
1591
  const setTime = (time) => {
726
1592
  if (!selectedForTime) return;
727
1593
  const next = mergeDateTime(selectedForTime, time);
728
- if (isRange) setRange(editingEnd ? [rangeValue[0], next] : [next, rangeValue[1]]);
1594
+ if (isRange)
1595
+ setRange(editingEnd ? [rangeValue[0], next] : [next, rangeValue[1]]);
729
1596
  else setSingle(next);
730
1597
  };
731
- return /* @__PURE__ */ jsxs7("div", { ref: rootRef, className: ["fe-datetime-picker", className].filter(Boolean).join(" "), children: [
732
- label && /* @__PURE__ */ jsx7("span", { className: "fe-datetime-picker__label", children: label }),
733
- /* @__PURE__ */ jsxs7("button", { type: "button", className: "fe-datetime-picker__trigger", disabled, "aria-expanded": open, onClick: () => setOpen((current) => !current), children: [
734
- /* @__PURE__ */ jsx7("span", { "aria-hidden": "true", children: "\u25F7" }),
735
- /* @__PURE__ */ jsx7("span", { children: shownValue || placeholder || (isRange ? "Select date range" : "Select date and time") })
736
- ] }),
737
- open && /* @__PURE__ */ jsxs7("div", { className: "fe-datetime-picker__popper", role: "dialog", "aria-label": "Date and time picker", children: [
738
- /* @__PURE__ */ jsxs7("div", { className: "fe-datetime-picker__month", children: [
739
- /* @__PURE__ */ jsx7("button", { type: "button", "aria-label": "Previous month", onClick: () => setMonth((current) => new Date(current.getFullYear(), current.getMonth() - 1, 1)), children: "\u2039" }),
740
- /* @__PURE__ */ jsx7("strong", { children: month.toLocaleDateString(locale, { month: "long", year: "numeric" }) }),
741
- /* @__PURE__ */ jsx7("button", { type: "button", "aria-label": "Next month", onClick: () => setMonth((current) => new Date(current.getFullYear(), current.getMonth() + 1, 1)), children: "\u203A" })
742
- ] }),
743
- /* @__PURE__ */ jsx7("div", { className: "fe-datetime-picker__weekdays", children: ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"].map((day) => /* @__PURE__ */ jsx7("span", { children: day }, day)) }),
744
- /* @__PURE__ */ jsx7("div", { className: "fe-datetime-picker__days", children: days.map((day) => {
745
- const inMonth = day.getMonth() === month.getMonth();
746
- const selected = isRange ? sameDay(day, rangeValue[0]) || sameDay(day, rangeValue[1]) : sameDay(day, singleValue);
747
- const inRange = isRange && rangeValue[0] && rangeValue[1] && day > startOfDay(rangeValue[0]) && day < startOfDay(rangeValue[1]);
748
- return /* @__PURE__ */ jsx7("button", { type: "button", className: [!inMonth && "is-other-month", selected && "is-selected", inRange && "is-in-range"].filter(Boolean).join(" "), onClick: () => selectDay(day), children: day.getDate() }, day.toISOString());
749
- }) }),
750
- isRange && /* @__PURE__ */ jsxs7("div", { className: "fe-datetime-picker__range-tabs", children: [
751
- /* @__PURE__ */ jsx7("button", { type: "button", className: !editingEnd ? "is-active" : "", onClick: () => setEditingEnd(false), children: "Start" }),
752
- /* @__PURE__ */ jsx7("button", { type: "button", className: editingEnd ? "is-active" : "", onClick: () => setEditingEnd(true), children: "End" })
753
- ] }),
754
- /* @__PURE__ */ jsxs7("label", { className: "fe-datetime-picker__time", children: [
755
- "Time",
756
- /* @__PURE__ */ jsx7("input", { type: "time", value: selectedForTime ? `${pad(selectedForTime.getHours())}:${pad(selectedForTime.getMinutes())}` : "00:00", onChange: (event) => setTime(event.target.value), disabled: !selectedForTime })
757
- ] })
758
- ] })
759
- ] });
1598
+ return /* @__PURE__ */ jsxs12(
1599
+ "div",
1600
+ {
1601
+ ref: rootRef,
1602
+ className: [
1603
+ "fe-datetime-picker",
1604
+ hasError && "fe-datetime-picker--error",
1605
+ className
1606
+ ].filter(Boolean).join(" "),
1607
+ children: [
1608
+ /* @__PURE__ */ jsx13(
1609
+ FieldLabel,
1610
+ {
1611
+ id: labelId,
1612
+ label,
1613
+ description: resolvedDescription,
1614
+ descriptionDisplay,
1615
+ isRequired
1616
+ }
1617
+ ),
1618
+ /* @__PURE__ */ jsxs12(
1619
+ "button",
1620
+ {
1621
+ id: triggerId,
1622
+ type: "button",
1623
+ className: "fe-datetime-picker__trigger",
1624
+ disabled,
1625
+ "aria-invalid": hasError || void 0,
1626
+ "aria-required": isRequired || void 0,
1627
+ "aria-labelledby": labelledBy,
1628
+ "aria-describedby": describedBy,
1629
+ "aria-expanded": open,
1630
+ onClick: () => setOpen((current) => !current),
1631
+ children: [
1632
+ /* @__PURE__ */ jsx13("span", { "aria-hidden": "true", children: "\u25F7" }),
1633
+ /* @__PURE__ */ jsxs12(
1634
+ "span",
1635
+ {
1636
+ className: !shownValue && placeholder ? "fe-datetime-picker__value is-placeholder" : "fe-datetime-picker__value",
1637
+ children: [
1638
+ shownValue || placeholder || (isRange ? "Select date range" : "Select date and time"),
1639
+ isRequired && placeholder && !shownValue && /* @__PURE__ */ jsx13("span", { className: "fe-field__required", "aria-hidden": "true", children: "*" })
1640
+ ]
1641
+ }
1642
+ )
1643
+ ]
1644
+ }
1645
+ ),
1646
+ open && /* @__PURE__ */ jsxs12(
1647
+ "div",
1648
+ {
1649
+ className: "fe-datetime-picker__popper",
1650
+ role: "dialog",
1651
+ "aria-label": "Date and time picker",
1652
+ children: [
1653
+ /* @__PURE__ */ jsxs12("div", { className: "fe-datetime-picker__month", children: [
1654
+ /* @__PURE__ */ jsx13(
1655
+ "button",
1656
+ {
1657
+ type: "button",
1658
+ "aria-label": "Previous month",
1659
+ onClick: () => setMonth(
1660
+ (current) => new Date(current.getFullYear(), current.getMonth() - 1, 1)
1661
+ ),
1662
+ children: "\u2039"
1663
+ }
1664
+ ),
1665
+ /* @__PURE__ */ jsx13("strong", { children: month.toLocaleDateString(locale, {
1666
+ month: "long",
1667
+ year: "numeric"
1668
+ }) }),
1669
+ /* @__PURE__ */ jsx13(
1670
+ "button",
1671
+ {
1672
+ type: "button",
1673
+ "aria-label": "Next month",
1674
+ onClick: () => setMonth(
1675
+ (current) => new Date(current.getFullYear(), current.getMonth() + 1, 1)
1676
+ ),
1677
+ children: "\u203A"
1678
+ }
1679
+ )
1680
+ ] }),
1681
+ /* @__PURE__ */ jsx13("div", { className: "fe-datetime-picker__weekdays", children: ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"].map((day) => /* @__PURE__ */ jsx13("span", { children: day }, day)) }),
1682
+ /* @__PURE__ */ jsx13("div", { className: "fe-datetime-picker__days", children: days.map((day) => {
1683
+ const inMonth = day.getMonth() === month.getMonth();
1684
+ const selected = isRange ? sameDay(day, rangeValue[0]) || sameDay(day, rangeValue[1]) : sameDay(day, singleValue);
1685
+ const inRange = isRange && rangeValue[0] && rangeValue[1] && day > startOfDay(rangeValue[0]) && day < startOfDay(rangeValue[1]);
1686
+ return /* @__PURE__ */ jsx13(
1687
+ "button",
1688
+ {
1689
+ type: "button",
1690
+ className: [
1691
+ !inMonth && "is-other-month",
1692
+ selected && "is-selected",
1693
+ inRange && "is-in-range"
1694
+ ].filter(Boolean).join(" "),
1695
+ onClick: () => selectDay(day),
1696
+ children: day.getDate()
1697
+ },
1698
+ day.toISOString()
1699
+ );
1700
+ }) }),
1701
+ isRange && /* @__PURE__ */ jsxs12("div", { className: "fe-datetime-picker__range-tabs", children: [
1702
+ /* @__PURE__ */ jsx13(
1703
+ "button",
1704
+ {
1705
+ type: "button",
1706
+ className: !editingEnd ? "is-active" : "",
1707
+ onClick: () => setEditingEnd(false),
1708
+ children: "Start"
1709
+ }
1710
+ ),
1711
+ /* @__PURE__ */ jsx13(
1712
+ "button",
1713
+ {
1714
+ type: "button",
1715
+ className: editingEnd ? "is-active" : "",
1716
+ onClick: () => setEditingEnd(true),
1717
+ children: "End"
1718
+ }
1719
+ )
1720
+ ] }),
1721
+ /* @__PURE__ */ jsxs12("label", { className: "fe-datetime-picker__time", children: [
1722
+ "Time",
1723
+ /* @__PURE__ */ jsx13(
1724
+ "input",
1725
+ {
1726
+ type: "time",
1727
+ value: selectedForTime ? pad(selectedForTime.getHours()) + ":" + pad(selectedForTime.getMinutes()) : "00:00",
1728
+ onChange: (event) => setTime(event.target.value),
1729
+ disabled: !selectedForTime
1730
+ }
1731
+ )
1732
+ ] })
1733
+ ]
1734
+ }
1735
+ ),
1736
+ /* @__PURE__ */ jsx13(
1737
+ FieldMessage,
1738
+ {
1739
+ id: messageId2,
1740
+ error: fieldError,
1741
+ description: resolvedDescription,
1742
+ descriptionDisplay
1743
+ }
1744
+ )
1745
+ ]
1746
+ }
1747
+ );
760
1748
  }
761
1749
 
762
- // packages/tooltip/src/index.tsx
763
- import { cloneElement, useId as useId2, useState as useState4 } from "react";
764
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
765
- function Tooltip({ content, children, placement = "top", disabled, className, ...props }) {
766
- const [visible, setVisible] = useState4(false);
767
- const id = useId2();
768
- const trigger = cloneElement(children, { "aria-describedby": visible ? id : void 0, onMouseEnter: (event) => {
769
- children.props.onMouseEnter?.(event);
770
- setVisible(true);
771
- }, onMouseLeave: (event) => {
772
- children.props.onMouseLeave?.(event);
773
- setVisible(false);
774
- }, onFocus: (event) => {
775
- children.props.onFocus?.(event);
776
- setVisible(true);
777
- }, onBlur: (event) => {
778
- children.props.onBlur?.(event);
779
- setVisible(false);
780
- } });
781
- return /* @__PURE__ */ jsxs8("span", { className: ["fe-tooltip", `fe-tooltip--${placement}`, className].filter(Boolean).join(" "), ...props, children: [
782
- trigger,
783
- visible && !disabled && /* @__PURE__ */ jsx8("span", { id, role: "tooltip", className: "fe-tooltip__content", children: content })
784
- ] });
785
- }
1750
+ // packages/form-controls/src/controls/Checkbox/checkbox.tsx
1751
+ import { forwardRef as forwardRef7 } from "react";
1752
+ import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
1753
+ var Checkbox = forwardRef7(
1754
+ function Checkbox2({
1755
+ label,
1756
+ labelPosition = "right",
1757
+ className,
1758
+ style,
1759
+ id,
1760
+ disabled,
1761
+ ...props
1762
+ }, ref) {
1763
+ const classes = [
1764
+ "fe-checkbox",
1765
+ `fe-checkbox--label-${labelPosition}`,
1766
+ disabled && "fe-checkbox--disabled",
1767
+ className
1768
+ ].filter(Boolean).join(" ");
1769
+ return /* @__PURE__ */ jsxs13("label", { className: classes, style, children: [
1770
+ label && labelPosition === "top" && /* @__PURE__ */ jsx14("span", { className: "fe-checkbox__label", children: label }),
1771
+ /* @__PURE__ */ jsxs13("span", { className: "fe-checkbox__content", children: [
1772
+ /* @__PURE__ */ jsx14(
1773
+ "input",
1774
+ {
1775
+ ref,
1776
+ id,
1777
+ className: "fe-checkbox__input",
1778
+ type: "checkbox",
1779
+ disabled,
1780
+ ...props
1781
+ }
1782
+ ),
1783
+ /* @__PURE__ */ jsx14("span", { className: "fe-checkbox__control", "aria-hidden": "true" }),
1784
+ label && labelPosition === "right" && /* @__PURE__ */ jsx14("span", { className: "fe-checkbox__label", children: label })
1785
+ ] })
1786
+ ] });
1787
+ }
1788
+ );
1789
+ Checkbox.displayName = "Checkbox";
1790
+
1791
+ // packages/form-controls/src/controls/RadioButton/radio-button.tsx
1792
+ import { forwardRef as forwardRef8 } from "react";
1793
+ import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
1794
+ var RadioButton = forwardRef8(
1795
+ function RadioButton2({
1796
+ label,
1797
+ labelPosition = "right",
1798
+ className,
1799
+ style,
1800
+ id,
1801
+ disabled,
1802
+ ...props
1803
+ }, ref) {
1804
+ const classes = [
1805
+ "fe-radio-button",
1806
+ `fe-radio-button--label-${labelPosition}`,
1807
+ disabled && "fe-radio-button--disabled",
1808
+ className
1809
+ ].filter(Boolean).join(" ");
1810
+ return /* @__PURE__ */ jsxs14("label", { className: classes, style, children: [
1811
+ label && labelPosition === "top" && /* @__PURE__ */ jsx15("span", { className: "fe-radio-button__label", children: label }),
1812
+ /* @__PURE__ */ jsxs14("span", { className: "fe-radio-button__content", children: [
1813
+ /* @__PURE__ */ jsx15(
1814
+ "input",
1815
+ {
1816
+ ref,
1817
+ id,
1818
+ className: "fe-radio-button__input",
1819
+ type: "radio",
1820
+ disabled,
1821
+ ...props
1822
+ }
1823
+ ),
1824
+ /* @__PURE__ */ jsx15("span", { className: "fe-radio-button__control", "aria-hidden": "true" }),
1825
+ label && labelPosition === "right" && /* @__PURE__ */ jsx15("span", { className: "fe-radio-button__label", children: label })
1826
+ ] })
1827
+ ] });
1828
+ }
1829
+ );
1830
+ RadioButton.displayName = "RadioButton";
1831
+
1832
+ // packages/form-controls/src/controls/RadioGroup/radio-group.tsx
1833
+ import { forwardRef as forwardRef9, useId as useId7 } from "react";
1834
+ import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
1835
+ var RadioGroup = forwardRef9(
1836
+ function RadioGroup2({
1837
+ label,
1838
+ labelPosition = "top",
1839
+ options,
1840
+ name,
1841
+ value,
1842
+ defaultValue,
1843
+ onChange,
1844
+ disabled = false,
1845
+ direction = "vertical",
1846
+ isRequired = false,
1847
+ className,
1848
+ id,
1849
+ "aria-label": ariaLabel,
1850
+ "aria-labelledby": ariaLabelledBy,
1851
+ ...props
1852
+ }, ref) {
1853
+ const generatedId = useId7();
1854
+ const groupName = name ?? `fe-radio-group-${generatedId}`;
1855
+ const labelId = `${id ?? generatedId}-label`;
1856
+ const isControlled = value !== void 0;
1857
+ const classes = [
1858
+ "fe-radio-group",
1859
+ `fe-radio-group--label-${labelPosition}`,
1860
+ `fe-radio-group--${direction}`,
1861
+ disabled && "fe-radio-group--disabled",
1862
+ className
1863
+ ].filter(Boolean).join(" ");
1864
+ const handleChange = (option, event) => {
1865
+ if (event.target.checked) onChange?.(option.value, option, event);
1866
+ };
1867
+ return /* @__PURE__ */ jsxs15("div", { ref, className: classes, ...props, children: [
1868
+ label && labelPosition === "top" && /* @__PURE__ */ jsxs15("span", { id: labelId, className: "fe-radio-group__label", children: [
1869
+ label,
1870
+ isRequired && /* @__PURE__ */ jsx16("span", { className: "fe-radio-group__required", "aria-hidden": "true", children: "*" })
1871
+ ] }),
1872
+ /* @__PURE__ */ jsx16(
1873
+ "div",
1874
+ {
1875
+ id,
1876
+ className: "fe-radio-group__options",
1877
+ role: "radiogroup",
1878
+ "aria-label": label ? void 0 : ariaLabel,
1879
+ "aria-labelledby": label ? labelId : ariaLabelledBy,
1880
+ "aria-required": isRequired || void 0,
1881
+ children: options.map((option) => {
1882
+ const optionDisabled = disabled || option.disabled;
1883
+ const optionValue = String(option.value);
1884
+ return /* @__PURE__ */ jsx16(
1885
+ RadioButton,
1886
+ {
1887
+ name: groupName,
1888
+ value: optionValue,
1889
+ label: option.label,
1890
+ disabled: optionDisabled,
1891
+ required: isRequired,
1892
+ checked: isControlled ? option.value === value : void 0,
1893
+ defaultChecked: !isControlled ? option.value === defaultValue : void 0,
1894
+ onChange: (event) => handleChange(option, event)
1895
+ },
1896
+ optionValue
1897
+ );
1898
+ })
1899
+ }
1900
+ ),
1901
+ label && labelPosition === "right" && /* @__PURE__ */ jsxs15("span", { id: labelId, className: "fe-radio-group__label", children: [
1902
+ label,
1903
+ isRequired && /* @__PURE__ */ jsx16("span", { className: "fe-radio-group__required", "aria-hidden": "true", children: "*" })
1904
+ ] })
1905
+ ] });
1906
+ }
1907
+ );
1908
+ RadioGroup.displayName = "RadioGroup";
786
1909
 
787
1910
  // packages/expandable-section/src/index.tsx
788
- import { useId as useId3, useState as useState5 } from "react";
789
- import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
1911
+ import { useId as useId8, useState as useState10 } from "react";
1912
+ import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
790
1913
  function ExpandableSection({ title, children, expanded, defaultExpanded = false, onExpandedChange, disabled, className, ...props }) {
791
- const [internalExpanded, setInternalExpanded] = useState5(defaultExpanded);
1914
+ const [internalExpanded, setInternalExpanded] = useState10(defaultExpanded);
792
1915
  const isExpanded = expanded ?? internalExpanded;
793
- const id = useId3();
1916
+ const id = useId8();
794
1917
  const toggle = () => {
795
1918
  if (disabled) return;
796
1919
  const next = !isExpanded;
797
1920
  if (expanded === void 0) setInternalExpanded(next);
798
1921
  onExpandedChange?.(next);
799
1922
  };
800
- return /* @__PURE__ */ jsxs9("section", { className: ["fe-expandable-section", isExpanded && "fe-expandable-section--expanded", disabled && "fe-expandable-section--disabled", className].filter(Boolean).join(" "), ...props, children: [
801
- /* @__PURE__ */ jsxs9("button", { className: "fe-expandable-section__trigger", type: "button", "aria-expanded": isExpanded, "aria-controls": id, disabled, onClick: toggle, children: [
802
- /* @__PURE__ */ jsx9("span", { children: title }),
803
- /* @__PURE__ */ jsx9("span", { className: "fe-expandable-section__chevron", "aria-hidden": "true" })
1923
+ return /* @__PURE__ */ jsxs16("section", { className: ["fe-expandable-section", isExpanded && "fe-expandable-section--expanded", disabled && "fe-expandable-section--disabled", className].filter(Boolean).join(" "), ...props, children: [
1924
+ /* @__PURE__ */ jsxs16("button", { className: "fe-expandable-section__trigger", type: "button", "aria-expanded": isExpanded, "aria-controls": id, disabled, onClick: toggle, children: [
1925
+ /* @__PURE__ */ jsx17("span", { children: title }),
1926
+ /* @__PURE__ */ jsx17("span", { className: "fe-expandable-section__chevron", "aria-hidden": "true" })
804
1927
  ] }),
805
- /* @__PURE__ */ jsx9("div", { id, className: "fe-expandable-section__content", "aria-hidden": !isExpanded, children: /* @__PURE__ */ jsx9("div", { className: "fe-expandable-section__content-inner", children }) })
1928
+ /* @__PURE__ */ jsx17("div", { id, className: "fe-expandable-section__content", "aria-hidden": !isExpanded, children: /* @__PURE__ */ jsx17("div", { className: "fe-expandable-section__content-inner", children }) })
806
1929
  ] });
807
1930
  }
808
1931
 
809
1932
  // packages/loading/src/index.tsx
810
- import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
1933
+ import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
811
1934
  var sizes = {
812
1935
  small: "16px",
813
1936
  medium: "24px",
@@ -820,15 +1943,15 @@ function Loading({ size = "medium", color = "#2878f0", label, className, style,
820
1943
  "--fe-loading-color": color,
821
1944
  ...style
822
1945
  };
823
- return /* @__PURE__ */ jsxs10("span", { className: ["fe-loading", className].filter(Boolean).join(" "), style: loadingStyle, role: "status", ...props, children: [
824
- /* @__PURE__ */ jsx10("span", { className: "fe-loading__spinner", "aria-hidden": "true" }),
825
- label && /* @__PURE__ */ jsx10("span", { className: "fe-loading__label", children: label }),
826
- !label && /* @__PURE__ */ jsx10("span", { className: "fe-loading__sr-only", children: "Loading" })
1946
+ return /* @__PURE__ */ jsxs17("span", { className: ["fe-loading", className].filter(Boolean).join(" "), style: loadingStyle, role: "status", ...props, children: [
1947
+ /* @__PURE__ */ jsx18("span", { className: "fe-loading__spinner", "aria-hidden": "true" }),
1948
+ label && /* @__PURE__ */ jsx18("span", { className: "fe-loading__label", children: label }),
1949
+ !label && /* @__PURE__ */ jsx18("span", { className: "fe-loading__sr-only", children: "Loading" })
827
1950
  ] });
828
1951
  }
829
1952
 
830
1953
  // packages/skeleton/src/index.tsx
831
- import { Fragment as Fragment2, jsx as jsx11 } from "react/jsx-runtime";
1954
+ import { Fragment as Fragment3, jsx as jsx19 } from "react/jsx-runtime";
832
1955
  var pixels = (value) => typeof value === "number" ? `${value}px` : value;
833
1956
  function SkeletonBase({ variant = "box", shape, width, height, count = 1, animated = true, className, style, ...props }) {
834
1957
  const resolvedVariant = shape ?? variant;
@@ -839,7 +1962,7 @@ function SkeletonBase({ variant = "box", shape, width, height, count = 1, animat
839
1962
  "--fe-skeleton-height": resolvedHeight,
840
1963
  ...style
841
1964
  };
842
- return /* @__PURE__ */ jsx11(Fragment2, { children: Array.from({ length: Math.max(1, count) }, (_, index) => /* @__PURE__ */ jsx11(
1965
+ return /* @__PURE__ */ jsx19(Fragment3, { children: Array.from({ length: Math.max(1, count) }, (_, index) => /* @__PURE__ */ jsx19(
843
1966
  "div",
844
1967
  {
845
1968
  className: ["fe-skeleton", `fe-skeleton--${resolvedVariant}`, animated && "fe-skeleton--animated", className].filter(Boolean).join(" "),
@@ -851,16 +1974,16 @@ function SkeletonBase({ variant = "box", shape, width, height, count = 1, animat
851
1974
  )) });
852
1975
  }
853
1976
  function SkeletonCircle({ size = 40, ...props }) {
854
- return /* @__PURE__ */ jsx11(SkeletonBase, { variant: "circle", width: size, height: size, ...props });
1977
+ return /* @__PURE__ */ jsx19(SkeletonBase, { variant: "circle", width: size, height: size, ...props });
855
1978
  }
856
1979
  function SkeletonSquare({ size = 80, ...props }) {
857
- return /* @__PURE__ */ jsx11(SkeletonBase, { variant: "box", width: size, height: size, ...props });
1980
+ return /* @__PURE__ */ jsx19(SkeletonBase, { variant: "box", width: size, height: size, ...props });
858
1981
  }
859
1982
  function SkeletonBox({ width = "100%", height = 80, ...props }) {
860
- return /* @__PURE__ */ jsx11(SkeletonBase, { variant: "box", width, height, ...props });
1983
+ return /* @__PURE__ */ jsx19(SkeletonBase, { variant: "box", width, height, ...props });
861
1984
  }
862
1985
  function SkeletonLine({ width = "100%", height = 12, ...props }) {
863
- return /* @__PURE__ */ jsx11(SkeletonBase, { variant: "line", width, height, ...props });
1986
+ return /* @__PURE__ */ jsx19(SkeletonBase, { variant: "line", width, height, ...props });
864
1987
  }
865
1988
  var Skeleton = Object.assign(SkeletonBase, {
866
1989
  Circle: SkeletonCircle,
@@ -870,9 +1993,9 @@ var Skeleton = Object.assign(SkeletonBase, {
870
1993
  });
871
1994
 
872
1995
  // packages/modal/src/index.tsx
873
- import { useEffect as useEffect4, useId as useId4, useRef as useRef3 } from "react";
1996
+ import { useEffect as useEffect6, useId as useId9, useRef as useRef6 } from "react";
874
1997
  import { createPortal as createPortal3 } from "react-dom";
875
- import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
1998
+ import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
876
1999
  function Modal({
877
2000
  open,
878
2001
  onClose,
@@ -888,9 +2011,9 @@ function Modal({
888
2011
  className,
889
2012
  ...props
890
2013
  }) {
891
- const titleId = useId4();
892
- const panelRef = useRef3(null);
893
- useEffect4(() => {
2014
+ const titleId = useId9();
2015
+ const panelRef = useRef6(null);
2016
+ useEffect6(() => {
894
2017
  if (!open) return;
895
2018
  const onKeyDown = (event) => {
896
2019
  if (event.key === "Escape") onClose();
@@ -902,9 +2025,9 @@ function Modal({
902
2025
  if (!open || typeof document === "undefined") return null;
903
2026
  const hasFooter = footer || actions.length > 0;
904
2027
  return createPortal3(
905
- /* @__PURE__ */ jsx12("div", { className: "fe-modal-backdrop", role: "presentation", onMouseDown: (event) => {
2028
+ /* @__PURE__ */ jsx20("div", { className: "fe-modal-backdrop", role: "presentation", onMouseDown: (event) => {
906
2029
  if (event.target === event.currentTarget && closeOnBackdropClick) onClose();
907
- }, children: /* @__PURE__ */ jsxs11(
2030
+ }, children: /* @__PURE__ */ jsxs18(
908
2031
  "div",
909
2032
  {
910
2033
  ref: panelRef,
@@ -916,17 +2039,17 @@ function Modal({
916
2039
  tabIndex: -1,
917
2040
  ...props,
918
2041
  children: [
919
- (title || description || closeButton) && /* @__PURE__ */ jsxs11("header", { className: "fe-modal__header", children: [
920
- /* @__PURE__ */ jsxs11("div", { className: "fe-modal__heading", children: [
921
- title && /* @__PURE__ */ jsx12("h2", { id: titleId, children: title }),
922
- description && /* @__PURE__ */ jsx12("p", { children: description })
2042
+ (title || description || closeButton) && /* @__PURE__ */ jsxs18("header", { className: "fe-modal__header", children: [
2043
+ /* @__PURE__ */ jsxs18("div", { className: "fe-modal__heading", children: [
2044
+ title && /* @__PURE__ */ jsx20("h2", { id: titleId, children: title }),
2045
+ description && /* @__PURE__ */ jsx20("p", { children: description })
923
2046
  ] }),
924
- closeButton && /* @__PURE__ */ jsx12(Button, { hierarchy: "tertiary-gray", size: "32", iconOnly: true, icon: /* @__PURE__ */ jsx12(CloseIcon, {}), "aria-label": closeLabel, onClick: onClose })
2047
+ closeButton && /* @__PURE__ */ jsx20(Button, { hierarchy: "tertiary-gray", size: "32", iconOnly: true, icon: /* @__PURE__ */ jsx20(CloseIcon, {}), "aria-label": closeLabel, onClick: onClose })
925
2048
  ] }),
926
- /* @__PURE__ */ jsx12("div", { className: "fe-modal__body", children }),
927
- hasFooter && /* @__PURE__ */ jsxs11("footer", { className: "fe-modal__footer", children: [
928
- footer && /* @__PURE__ */ jsx12("div", { className: "fe-modal__footer-content", children: footer }),
929
- actions.length > 0 && /* @__PURE__ */ jsx12("div", { className: "fe-modal__actions", children: actions.map(({ label, ...action }, index) => /* @__PURE__ */ jsx12(Button, { ...action, children: label }, index)) })
2049
+ /* @__PURE__ */ jsx20("div", { className: "fe-modal__body", children }),
2050
+ hasFooter && /* @__PURE__ */ jsxs18("footer", { className: "fe-modal__footer", children: [
2051
+ footer && /* @__PURE__ */ jsx20("div", { className: "fe-modal__footer-content", children: footer }),
2052
+ actions.length > 0 && /* @__PURE__ */ jsx20("div", { className: "fe-modal__actions", children: actions.map(({ label, ...action }, index) => /* @__PURE__ */ jsx20(Button, { ...action, children: label }, index)) })
930
2053
  ] })
931
2054
  ]
932
2055
  }
@@ -936,7 +2059,7 @@ function Modal({
936
2059
  }
937
2060
 
938
2061
  // packages/progress/src/index.tsx
939
- import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
2062
+ import { jsx as jsx21, jsxs as jsxs19 } from "react/jsx-runtime";
940
2063
  function ProgressBar({ value, max = 100, label, showValue = true, size = "medium", color = "#2878f0", className, style, "aria-label": ariaLabel, ...props }) {
941
2064
  const indeterminate = value === null || value === void 0;
942
2065
  const percentage = indeterminate ? 0 : Math.min(100, Math.max(0, Number(value) / Math.max(1, max) * 100));
@@ -946,17 +2069,17 @@ function ProgressBar({ value, max = 100, label, showValue = true, size = "medium
946
2069
  ...style
947
2070
  };
948
2071
  const visibleValue = `${Math.round(percentage)}%`;
949
- return /* @__PURE__ */ jsxs12("div", { className: ["fe-progress", `fe-progress--${size}`, indeterminate && "fe-progress--indeterminate", className].filter(Boolean).join(" "), style: progressStyle, ...props, children: [
950
- (label || !indeterminate && showValue) && /* @__PURE__ */ jsxs12("div", { className: "fe-progress__meta", children: [
951
- label && /* @__PURE__ */ jsx13("span", { className: "fe-progress__label", children: label }),
952
- !indeterminate && showValue && /* @__PURE__ */ jsx13("output", { className: "fe-progress__value", children: visibleValue })
2072
+ return /* @__PURE__ */ jsxs19("div", { className: ["fe-progress", `fe-progress--${size}`, indeterminate && "fe-progress--indeterminate", className].filter(Boolean).join(" "), style: progressStyle, ...props, children: [
2073
+ (label || !indeterminate && showValue) && /* @__PURE__ */ jsxs19("div", { className: "fe-progress__meta", children: [
2074
+ label && /* @__PURE__ */ jsx21("span", { className: "fe-progress__label", children: label }),
2075
+ !indeterminate && showValue && /* @__PURE__ */ jsx21("output", { className: "fe-progress__value", children: visibleValue })
953
2076
  ] }),
954
- /* @__PURE__ */ jsx13("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__ */ jsx13("span", { className: "fe-progress__indicator" }) })
2077
+ /* @__PURE__ */ jsx21("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__ */ jsx21("span", { className: "fe-progress__indicator" }) })
955
2078
  ] });
956
2079
  }
957
2080
 
958
2081
  // packages/chip/src/index.tsx
959
- import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
2082
+ import { jsx as jsx22, jsxs as jsxs20 } from "react/jsx-runtime";
960
2083
  var statuses = ["default", "info", "success", "warning", "error", "neutral", "pending", "processing"];
961
2084
  function Chip({ children, status = "default", color, variant = "subtle", dot = false, onRemove, removeLabel = "Remove", className, style, ...props }) {
962
2085
  const usesCustomColor = Boolean(color);
@@ -965,16 +2088,16 @@ function Chip({ children, status = "default", color, variant = "subtle", dot = f
965
2088
  ...style
966
2089
  };
967
2090
  const resolvedStatus = statuses.includes(status) ? status : "default";
968
- return /* @__PURE__ */ jsxs13("span", { className: ["fe-chip", `fe-chip--${variant}`, `fe-chip--${usesCustomColor ? "custom" : resolvedStatus}`, className].filter(Boolean).join(" "), style: chipStyle, ...props, children: [
969
- dot && /* @__PURE__ */ jsx14("span", { className: "fe-chip__dot", "aria-hidden": "true" }),
970
- /* @__PURE__ */ jsx14("span", { className: "fe-chip__content", children }),
971
- onRemove && /* @__PURE__ */ jsx14(Button, { hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: /* @__PURE__ */ jsx14(CloseIcon, { size: 14 }), "aria-label": removeLabel, onClick: onRemove, className: "fe-chip__remove" })
2091
+ return /* @__PURE__ */ jsxs20("span", { className: ["fe-chip", `fe-chip--${variant}`, `fe-chip--${usesCustomColor ? "custom" : resolvedStatus}`, className].filter(Boolean).join(" "), style: chipStyle, ...props, children: [
2092
+ dot && /* @__PURE__ */ jsx22("span", { className: "fe-chip__dot", "aria-hidden": "true" }),
2093
+ /* @__PURE__ */ jsx22("span", { className: "fe-chip__content", children }),
2094
+ onRemove && /* @__PURE__ */ jsx22(Button, { hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: /* @__PURE__ */ jsx22(CloseIcon, { size: 14 }), "aria-label": removeLabel, onClick: onRemove, className: "fe-chip__remove" })
972
2095
  ] });
973
2096
  }
974
2097
 
975
2098
  // packages/message/src/index.tsx
976
- import { useEffect as useEffect5, useState as useState6 } from "react";
977
- import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
2099
+ import { useEffect as useEffect7, useState as useState11 } from "react";
2100
+ import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
978
2101
  var messageId = 0;
979
2102
  var entries = [];
980
2103
  var listeners = /* @__PURE__ */ new Set();
@@ -1007,22 +2130,22 @@ var message = {
1007
2130
  };
1008
2131
  var icons = { success: "\u2713", info: "i", warning: "!", error: "\xD7" };
1009
2132
  function Message({ maxCount = 4, closeLabel = "Close notification", className, ...props }) {
1010
- const [visibleEntries, setVisibleEntries] = useState6(entries);
1011
- useEffect5(() => {
2133
+ const [visibleEntries, setVisibleEntries] = useState11(entries);
2134
+ useEffect7(() => {
1012
2135
  const listener = (nextEntries) => setVisibleEntries(nextEntries);
1013
2136
  listeners.add(listener);
1014
2137
  return () => {
1015
2138
  listeners.delete(listener);
1016
2139
  };
1017
2140
  }, []);
1018
- return /* @__PURE__ */ jsx15("div", { className: ["fe-message-viewport", className].filter(Boolean).join(" "), "aria-live": "polite", ...props, children: visibleEntries.slice(-Math.max(1, maxCount)).map((entry) => /* @__PURE__ */ jsxs14("div", { className: `fe-message fe-message--${entry.severity ?? "info"}`, role: entry.severity === "error" ? "alert" : "status", children: [
1019
- /* @__PURE__ */ jsx15("span", { className: "fe-message__icon", "aria-hidden": "true", children: icons[entry.severity ?? "info"] }),
1020
- /* @__PURE__ */ jsxs14("div", { className: "fe-message__body", children: [
1021
- entry.title && /* @__PURE__ */ jsx15("strong", { className: "fe-message__title", children: entry.title }),
1022
- /* @__PURE__ */ jsx15("div", { className: "fe-message__content", children: entry.content })
2141
+ return /* @__PURE__ */ jsx23("div", { className: ["fe-message-viewport", className].filter(Boolean).join(" "), "aria-live": "polite", ...props, children: visibleEntries.slice(-Math.max(1, maxCount)).map((entry) => /* @__PURE__ */ jsxs21("div", { className: `fe-message fe-message--${entry.severity ?? "info"}`, role: entry.severity === "error" ? "alert" : "status", children: [
2142
+ /* @__PURE__ */ jsx23("span", { className: "fe-message__icon", "aria-hidden": "true", children: icons[entry.severity ?? "info"] }),
2143
+ /* @__PURE__ */ jsxs21("div", { className: "fe-message__body", children: [
2144
+ entry.title && /* @__PURE__ */ jsx23("strong", { className: "fe-message__title", children: entry.title }),
2145
+ /* @__PURE__ */ jsx23("div", { className: "fe-message__content", children: entry.content })
1023
2146
  ] }),
1024
- entry.action && /* @__PURE__ */ jsx15("span", { className: "fe-message__action", children: entry.action }),
1025
- /* @__PURE__ */ jsx15(Button, { className: "fe-message__close", hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: "\xD7", "aria-label": closeLabel, onClick: () => dismiss(entry.id) })
2147
+ entry.action && /* @__PURE__ */ jsx23("span", { className: "fe-message__action", children: entry.action }),
2148
+ /* @__PURE__ */ jsx23(Button, { className: "fe-message__close", hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: "\xD7", "aria-label": closeLabel, onClick: () => dismiss(entry.id) })
1026
2149
  ] }, entry.id)) });
1027
2150
  }
1028
2151
  ((Message2) => {
@@ -1036,8 +2159,8 @@ function Message({ maxCount = 4, closeLabel = "Close notification", className, .
1036
2159
  })(Message || (Message = {}));
1037
2160
 
1038
2161
  // packages/snackbar/src/index.tsx
1039
- import { useEffect as useEffect6 } from "react";
1040
- import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
2162
+ import { useEffect as useEffect8 } from "react";
2163
+ import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
1041
2164
  function Snackbar({
1042
2165
  open,
1043
2166
  message: message2,
@@ -1051,12 +2174,12 @@ function Snackbar({
1051
2174
  }) {
1052
2175
  const vertical = anchorOrigin.vertical ?? "bottom";
1053
2176
  const horizontal = anchorOrigin.horizontal ?? "center";
1054
- useEffect6(() => {
2177
+ useEffect8(() => {
1055
2178
  if (!open || autoHideDuration === null) return void 0;
1056
2179
  const timer = window.setTimeout(() => onClose?.("timeout"), autoHideDuration);
1057
2180
  return () => window.clearTimeout(timer);
1058
2181
  }, [open, autoHideDuration, onClose]);
1059
- useEffect6(() => {
2182
+ useEffect8(() => {
1060
2183
  if (!open) return void 0;
1061
2184
  const onKeyDown = (event) => {
1062
2185
  if (event.key === "Escape") onClose?.("escapeKeyDown");
@@ -1065,15 +2188,17 @@ function Snackbar({
1065
2188
  return () => window.removeEventListener("keydown", onKeyDown);
1066
2189
  }, [open, onClose]);
1067
2190
  if (!open) return null;
1068
- return /* @__PURE__ */ jsx16("div", { className: ["fe-snackbar", `fe-snackbar--${vertical}`, `fe-snackbar--${horizontal}`, className].filter(Boolean).join(" "), ...props, children: /* @__PURE__ */ jsxs15("div", { className: "fe-snackbar__content", role: "status", "aria-live": "polite", children: [
1069
- /* @__PURE__ */ jsx16("span", { className: "fe-snackbar__message", children: message2 }),
1070
- action && /* @__PURE__ */ jsx16("span", { className: "fe-snackbar__action", children: action }),
1071
- onClose && /* @__PURE__ */ jsx16(Button, { className: "fe-snackbar__close", hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: "\xD7", "aria-label": closeLabel, onClick: () => onClose("closeButton") })
2191
+ return /* @__PURE__ */ jsx24("div", { className: ["fe-snackbar", `fe-snackbar--${vertical}`, `fe-snackbar--${horizontal}`, className].filter(Boolean).join(" "), ...props, children: /* @__PURE__ */ jsxs22("div", { className: "fe-snackbar__content", role: "status", "aria-live": "polite", children: [
2192
+ /* @__PURE__ */ jsx24("span", { className: "fe-snackbar__message", children: message2 }),
2193
+ action && /* @__PURE__ */ jsx24("span", { className: "fe-snackbar__action", children: action }),
2194
+ onClose && /* @__PURE__ */ jsx24(Button, { className: "fe-snackbar__close", hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: "\xD7", "aria-label": closeLabel, onClick: () => onClose("closeButton") })
1072
2195
  ] }) });
1073
2196
  }
1074
2197
  export {
1075
2198
  Button,
2199
+ Checkbox,
1076
2200
  ChevronDownIcon,
2201
+ ChevronUpIcon,
1077
2202
  Chip,
1078
2203
  CloseIcon,
1079
2204
  CurrencyInput,
@@ -1087,6 +2212,8 @@ export {
1087
2212
  Pagination,
1088
2213
  PlusIcon,
1089
2214
  ProgressBar,
2215
+ RadioButton,
2216
+ RadioGroup,
1090
2217
  SearchIcon,
1091
2218
  Selection,
1092
2219
  Skeleton,
@@ -1106,7 +2233,24 @@ export {
1106
2233
  TextInput,
1107
2234
  Toggle,
1108
2235
  Tooltip,
2236
+ arrow_left,
2237
+ check_square_fill,
2238
+ chevron_down,
2239
+ chevron_left,
2240
+ chevron_right,
2241
+ chevron_up,
2242
+ copy,
1109
2243
  formatNumber,
1110
2244
  getIconSize,
1111
- message
2245
+ key,
2246
+ lock,
2247
+ lock_unlocked,
2248
+ log_out,
2249
+ message,
2250
+ minus_square,
2251
+ plus,
2252
+ plus_square,
2253
+ search,
2254
+ trash,
2255
+ x_close
1112
2256
  };