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