@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/README.md +41 -5
- package/dist/chunk-NDMLXSI5.mjs +182 -0
- package/dist/icons.d.mts +33 -0
- package/dist/icons.d.ts +33 -0
- package/dist/icons.js +229 -0
- package/dist/icons.mjs +48 -0
- package/dist/index.d.mts +178 -50
- package/dist/index.d.ts +178 -50
- package/dist/index.js +1683 -400
- package/dist/index.mjs +1567 -423
- package/dist/styles.css +632 -104
- package/package.json +8 -3
- package/dist/styles.d.mts +0 -2
- package/dist/styles.d.ts +0 -2
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
|
|
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__ */
|
|
151
|
-
/* @__PURE__ */
|
|
152
|
-
items.map((item, index) => item === "start-ellipsis" || item === "end-ellipsis" ? /* @__PURE__ */
|
|
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__ */
|
|
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
|
|
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__ */
|
|
272
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
275
|
-
/* @__PURE__ */
|
|
276
|
-
/* @__PURE__ */
|
|
277
|
-
/* @__PURE__ */
|
|
278
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
321
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
323
|
+
return /* @__PURE__ */ jsx3("thead", { ...props });
|
|
325
324
|
}
|
|
326
325
|
function TableBody(props) {
|
|
327
|
-
return /* @__PURE__ */
|
|
326
|
+
return /* @__PURE__ */ jsx3("tbody", { ...props });
|
|
328
327
|
}
|
|
329
328
|
function TableRow({ children, ...props }) {
|
|
330
329
|
const { striped } = useContext(TableContext);
|
|
331
|
-
return /* @__PURE__ */
|
|
330
|
+
return /* @__PURE__ */ jsx3("tr", { "data-striped": striped || void 0, ...props, children });
|
|
332
331
|
}
|
|
333
332
|
function TableCell({ children, ...props }) {
|
|
334
|
-
return /* @__PURE__ */
|
|
333
|
+
return /* @__PURE__ */ jsx3("td", { ...props, children });
|
|
335
334
|
}
|
|
336
335
|
function TableHeader({ children, ...props }) {
|
|
337
|
-
return /* @__PURE__ */
|
|
336
|
+
return /* @__PURE__ */ jsx3("th", { scope: "col", ...props, children });
|
|
338
337
|
}
|
|
339
338
|
function TableCaption(props) {
|
|
340
|
-
return /* @__PURE__ */
|
|
339
|
+
return /* @__PURE__ */ jsx3("caption", { ...props });
|
|
341
340
|
}
|
|
342
341
|
|
|
343
342
|
// packages/toggle/src/index.tsx
|
|
344
|
-
import {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
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__ */
|
|
353
|
-
/* @__PURE__ */
|
|
354
|
-
/* @__PURE__ */
|
|
355
|
-
|
|
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
|
|
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__ */
|
|
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__ */
|
|
378
|
-
/* @__PURE__ */
|
|
379
|
-
title && /* @__PURE__ */
|
|
380
|
-
/* @__PURE__ */
|
|
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__ */
|
|
383
|
-
footer && /* @__PURE__ */
|
|
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/
|
|
388
|
-
import {
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
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
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
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
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
const
|
|
486
|
-
|
|
487
|
-
|
|
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
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
if (
|
|
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
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
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
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
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
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
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(/[
|
|
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(
|
|
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)
|
|
604
|
-
|
|
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)
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
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
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
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
|
-
|
|
647
|
-
|
|
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
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
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 {
|
|
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] =
|
|
682
|
-
|
|
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] =
|
|
686
|
-
const [month, setMonth] =
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
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(
|
|
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([
|
|
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 ? [
|
|
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(
|
|
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)
|
|
1594
|
+
if (isRange)
|
|
1595
|
+
setRange(editingEnd ? [rangeValue[0], next] : [next, rangeValue[1]]);
|
|
729
1596
|
else setSingle(next);
|
|
730
1597
|
};
|
|
731
|
-
return /* @__PURE__ */
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
/* @__PURE__ */
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
/* @__PURE__ */
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
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/
|
|
763
|
-
import {
|
|
764
|
-
import { jsx as
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
},
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
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
|
|
789
|
-
import { jsx as
|
|
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] =
|
|
1914
|
+
const [internalExpanded, setInternalExpanded] = useState10(defaultExpanded);
|
|
792
1915
|
const isExpanded = expanded ?? internalExpanded;
|
|
793
|
-
const id =
|
|
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__ */
|
|
801
|
-
/* @__PURE__ */
|
|
802
|
-
/* @__PURE__ */
|
|
803
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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
|
|
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__ */
|
|
824
|
-
/* @__PURE__ */
|
|
825
|
-
label && /* @__PURE__ */
|
|
826
|
-
!label && /* @__PURE__ */
|
|
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
|
|
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__ */
|
|
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__ */
|
|
1977
|
+
return /* @__PURE__ */ jsx19(SkeletonBase, { variant: "circle", width: size, height: size, ...props });
|
|
855
1978
|
}
|
|
856
1979
|
function SkeletonSquare({ size = 80, ...props }) {
|
|
857
|
-
return /* @__PURE__ */
|
|
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__ */
|
|
1983
|
+
return /* @__PURE__ */ jsx19(SkeletonBase, { variant: "box", width, height, ...props });
|
|
861
1984
|
}
|
|
862
1985
|
function SkeletonLine({ width = "100%", height = 12, ...props }) {
|
|
863
|
-
return /* @__PURE__ */
|
|
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
|
|
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
|
|
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 =
|
|
892
|
-
const panelRef =
|
|
893
|
-
|
|
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__ */
|
|
2028
|
+
/* @__PURE__ */ jsx20("div", { className: "fe-modal-backdrop", role: "presentation", onMouseDown: (event) => {
|
|
906
2029
|
if (event.target === event.currentTarget && closeOnBackdropClick) onClose();
|
|
907
|
-
}, children: /* @__PURE__ */
|
|
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__ */
|
|
920
|
-
/* @__PURE__ */
|
|
921
|
-
title && /* @__PURE__ */
|
|
922
|
-
description && /* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
927
|
-
hasFooter && /* @__PURE__ */
|
|
928
|
-
footer && /* @__PURE__ */
|
|
929
|
-
actions.length > 0 && /* @__PURE__ */
|
|
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
|
|
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__ */
|
|
950
|
-
(label || !indeterminate && showValue) && /* @__PURE__ */
|
|
951
|
-
label && /* @__PURE__ */
|
|
952
|
-
!indeterminate && showValue && /* @__PURE__ */
|
|
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__ */
|
|
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
|
|
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__ */
|
|
969
|
-
dot && /* @__PURE__ */
|
|
970
|
-
/* @__PURE__ */
|
|
971
|
-
onRemove && /* @__PURE__ */
|
|
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
|
|
977
|
-
import { jsx as
|
|
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] =
|
|
1011
|
-
|
|
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__ */
|
|
1019
|
-
/* @__PURE__ */
|
|
1020
|
-
/* @__PURE__ */
|
|
1021
|
-
entry.title && /* @__PURE__ */
|
|
1022
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1025
|
-
/* @__PURE__ */
|
|
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
|
|
1040
|
-
import { jsx as
|
|
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
|
-
|
|
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
|
-
|
|
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__ */
|
|
1069
|
-
/* @__PURE__ */
|
|
1070
|
-
action && /* @__PURE__ */
|
|
1071
|
-
onClose && /* @__PURE__ */
|
|
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
|
-
|
|
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
|
};
|