@dragunio/fe-libs 0.1.2 → 0.1.3
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 +51 -14
- package/dist/index.d.mts +234 -5
- package/dist/index.d.ts +234 -5
- package/dist/index.js +636 -158
- package/dist/index.mjs +601 -138
- package/dist/styles.css +669 -10
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -97,11 +97,78 @@ import {
|
|
|
97
97
|
useCallback,
|
|
98
98
|
useContext,
|
|
99
99
|
useEffect,
|
|
100
|
-
useMemo,
|
|
100
|
+
useMemo as useMemo2,
|
|
101
101
|
useRef,
|
|
102
|
-
useState
|
|
102
|
+
useState as useState2
|
|
103
103
|
} from "react";
|
|
104
|
+
|
|
105
|
+
// packages/pagination/src/index.tsx
|
|
106
|
+
import { useMemo, useState } from "react";
|
|
104
107
|
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
108
|
+
var clamp = (value, min, max) => Math.min(Math.max(value, min), max);
|
|
109
|
+
var range = (start, end) => Array.from({ length: Math.max(0, end - start + 1) }, (_, index) => start + index);
|
|
110
|
+
function getItems(totalPages, page, siblingCount, boundaryCount) {
|
|
111
|
+
const visibleCount = boundaryCount * 2 + siblingCount * 2 + 3;
|
|
112
|
+
if (totalPages <= visibleCount) return range(1, totalPages);
|
|
113
|
+
const startPages = range(1, boundaryCount);
|
|
114
|
+
const endPages = range(totalPages - boundaryCount + 1, totalPages);
|
|
115
|
+
const siblingsStart = Math.max(Math.min(page - siblingCount, totalPages - boundaryCount - siblingCount * 2 - 1), boundaryCount + 2);
|
|
116
|
+
const siblingsEnd = Math.min(Math.max(page + siblingCount, boundaryCount + siblingCount * 2 + 2), totalPages - boundaryCount - 1);
|
|
117
|
+
return [
|
|
118
|
+
...startPages,
|
|
119
|
+
...siblingsStart > boundaryCount + 2 ? ["start-ellipsis"] : siblingsStart === boundaryCount + 2 ? [boundaryCount + 1] : [],
|
|
120
|
+
...range(siblingsStart, siblingsEnd),
|
|
121
|
+
...siblingsEnd < totalPages - boundaryCount - 1 ? ["end-ellipsis"] : siblingsEnd === totalPages - boundaryCount - 1 ? [totalPages - boundaryCount] : [],
|
|
122
|
+
...endPages
|
|
123
|
+
];
|
|
124
|
+
}
|
|
125
|
+
function Pagination({
|
|
126
|
+
page,
|
|
127
|
+
defaultPage = 1,
|
|
128
|
+
totalPages,
|
|
129
|
+
onPageChange,
|
|
130
|
+
siblingCount = 1,
|
|
131
|
+
boundaryCount = 1,
|
|
132
|
+
disabled = false,
|
|
133
|
+
previousLabel = "Previous page",
|
|
134
|
+
nextLabel = "Next page",
|
|
135
|
+
className,
|
|
136
|
+
...props
|
|
137
|
+
}) {
|
|
138
|
+
const safeTotalPages = Math.max(1, Math.floor(totalPages));
|
|
139
|
+
const [uncontrolledPage, setUncontrolledPage] = useState(() => clamp(defaultPage, 1, safeTotalPages));
|
|
140
|
+
const currentPage = clamp(page ?? uncontrolledPage, 1, safeTotalPages);
|
|
141
|
+
const items = useMemo(
|
|
142
|
+
() => getItems(safeTotalPages, currentPage, Math.max(0, siblingCount), Math.max(0, boundaryCount)),
|
|
143
|
+
[safeTotalPages, currentPage, siblingCount, boundaryCount]
|
|
144
|
+
);
|
|
145
|
+
const selectPage = (nextPage) => {
|
|
146
|
+
const resolvedPage = clamp(nextPage, 1, safeTotalPages);
|
|
147
|
+
if (page === void 0) setUncontrolledPage(resolvedPage);
|
|
148
|
+
if (resolvedPage !== currentPage) onPageChange?.(resolvedPage);
|
|
149
|
+
};
|
|
150
|
+
return /* @__PURE__ */ jsxs3("nav", { className: ["fe-pagination", className].filter(Boolean).join(" "), "aria-label": "Pagination", ...props, children: [
|
|
151
|
+
/* @__PURE__ */ jsx3(Button, { className: "fe-pagination__button fe-pagination__button--control", hierarchy: "secondary-gray", size: "40", iconOnly: true, icon: "\u2039", "aria-label": previousLabel, disabled: disabled || currentPage === 1, onClick: () => selectPage(currentPage - 1) }),
|
|
152
|
+
items.map((item, index) => item === "start-ellipsis" || item === "end-ellipsis" ? /* @__PURE__ */ jsx3("span", { className: "fe-pagination__ellipsis", "aria-hidden": "true", children: "\u2026" }, `${item}-${index}`) : /* @__PURE__ */ jsx3(
|
|
153
|
+
Button,
|
|
154
|
+
{
|
|
155
|
+
className: "fe-pagination__button",
|
|
156
|
+
hierarchy: item === currentPage ? "primary" : "secondary-gray",
|
|
157
|
+
size: "40",
|
|
158
|
+
"aria-label": `Page ${item}`,
|
|
159
|
+
"aria-current": item === currentPage ? "page" : void 0,
|
|
160
|
+
disabled,
|
|
161
|
+
onClick: () => selectPage(item),
|
|
162
|
+
children: item
|
|
163
|
+
},
|
|
164
|
+
item
|
|
165
|
+
)),
|
|
166
|
+
/* @__PURE__ */ jsx3(Button, { className: "fe-pagination__button fe-pagination__button--control", hierarchy: "secondary-gray", size: "40", iconOnly: true, icon: "\u203A", "aria-label": nextLabel, disabled: disabled || currentPage === safeTotalPages, onClick: () => selectPage(currentPage + 1) })
|
|
167
|
+
] });
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// packages/table/src/index.tsx
|
|
171
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
105
172
|
var TableContext = createContext({ striped: false });
|
|
106
173
|
var MIN_COLUMN_WIDTH = 96;
|
|
107
174
|
var MAX_COLUMN_WIDTH = 1200;
|
|
@@ -119,9 +186,9 @@ function autoColumnSize(columnIndex, headers, data) {
|
|
|
119
186
|
const longestText = values.reduce((longest, value) => Math.max(longest, getText(value).length), 0);
|
|
120
187
|
return Math.min(MAX_COLUMN_WIDTH, Math.max(MIN_COLUMN_WIDTH, longestText * 8 + 40));
|
|
121
188
|
}
|
|
122
|
-
function getInitialColumnSizes(headers, data,
|
|
189
|
+
function getInitialColumnSizes(headers, data, sizes2, minColumnWidth = MIN_COLUMN_WIDTH) {
|
|
123
190
|
return Array.from({ length: getColumnCount(headers, data) }, (_, columnIndex) => {
|
|
124
|
-
const suppliedSize =
|
|
191
|
+
const suppliedSize = sizes2?.[columnIndex];
|
|
125
192
|
return typeof suppliedSize === "number" && Number.isFinite(suppliedSize) ? Math.min(MAX_COLUMN_WIDTH, Math.max(minColumnWidth, suppliedSize)) : autoColumnSize(columnIndex, headers, data);
|
|
126
193
|
});
|
|
127
194
|
}
|
|
@@ -136,19 +203,31 @@ function DataTable({
|
|
|
136
203
|
columnSizes,
|
|
137
204
|
onColumnResize,
|
|
138
205
|
minColumnWidth = MIN_COLUMN_WIDTH,
|
|
206
|
+
pagination,
|
|
207
|
+
pageSize,
|
|
208
|
+
page,
|
|
209
|
+
defaultPage = 1,
|
|
210
|
+
onPageChange,
|
|
211
|
+
paginationPosition = "bottom-right",
|
|
139
212
|
className,
|
|
140
213
|
...props
|
|
141
214
|
}) {
|
|
142
215
|
const columnCount = getColumnCount(headers, data);
|
|
143
216
|
const safeMinWidth = Math.max(1, minColumnWidth);
|
|
144
|
-
const generatedSizes =
|
|
217
|
+
const generatedSizes = useMemo2(
|
|
145
218
|
() => getInitialColumnSizes(headers, data, defaultColumnSizes, safeMinWidth),
|
|
146
219
|
[headers, data, defaultColumnSizes, safeMinWidth]
|
|
147
220
|
);
|
|
148
|
-
const [uncontrolledSizes, setUncontrolledSizes] =
|
|
221
|
+
const [uncontrolledSizes, setUncontrolledSizes] = useState2(generatedSizes);
|
|
222
|
+
const shouldPaginate = pagination ?? pageSize !== void 0;
|
|
223
|
+
const safePageSize = Math.max(1, Math.floor(pageSize ?? 10));
|
|
224
|
+
const totalPages = Math.max(1, Math.ceil(data.length / safePageSize));
|
|
225
|
+
const [uncontrolledPage, setUncontrolledPage] = useState2(() => Math.min(Math.max(1, defaultPage), totalPages));
|
|
226
|
+
const currentPage = Math.min(Math.max(1, page ?? uncontrolledPage), totalPages);
|
|
227
|
+
const pagedData = shouldPaginate ? data.slice((currentPage - 1) * safePageSize, currentPage * safePageSize) : data;
|
|
149
228
|
const resizeState = useRef();
|
|
150
|
-
const [isResizing, setIsResizing] =
|
|
151
|
-
const
|
|
229
|
+
const [isResizing, setIsResizing] = useState2(false);
|
|
230
|
+
const sizes2 = columnSizes ? getInitialColumnSizes(headers, data, columnSizes, safeMinWidth).map((size) => Math.max(safeMinWidth, size)) : uncontrolledSizes.map((size) => Math.max(safeMinWidth, size));
|
|
152
231
|
useEffect(() => {
|
|
153
232
|
if (columnSizes) return;
|
|
154
233
|
setUncontrolledSizes((currentSizes) => {
|
|
@@ -156,12 +235,15 @@ function DataTable({
|
|
|
156
235
|
return sameSizes(currentSizes, nextSizes) ? currentSizes : nextSizes;
|
|
157
236
|
});
|
|
158
237
|
}, [columnSizes, generatedSizes]);
|
|
238
|
+
useEffect(() => {
|
|
239
|
+
if (page === void 0 && uncontrolledPage > totalPages) setUncontrolledPage(totalPages);
|
|
240
|
+
}, [page, totalPages, uncontrolledPage]);
|
|
159
241
|
const updateColumnSize = useCallback((columnIndex, nextSize) => {
|
|
160
242
|
const clampedSize = Math.min(MAX_COLUMN_WIDTH, Math.max(safeMinWidth, Math.round(nextSize)));
|
|
161
|
-
const nextSizes =
|
|
243
|
+
const nextSizes = sizes2.map((size, index) => index === columnIndex ? clampedSize : size);
|
|
162
244
|
if (!columnSizes) setUncontrolledSizes(nextSizes);
|
|
163
245
|
onColumnResize?.(nextSizes, columnIndex);
|
|
164
|
-
}, [columnSizes, onColumnResize, safeMinWidth,
|
|
246
|
+
}, [columnSizes, onColumnResize, safeMinWidth, sizes2]);
|
|
165
247
|
useEffect(() => {
|
|
166
248
|
const onPointerMove = (event) => {
|
|
167
249
|
const activeResize = resizeState.current;
|
|
@@ -181,74 +263,96 @@ function DataTable({
|
|
|
181
263
|
window.removeEventListener("pointercancel", stopResizing);
|
|
182
264
|
};
|
|
183
265
|
}, [updateColumnSize]);
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
"
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
266
|
+
const changePage = (nextPage) => {
|
|
267
|
+
if (page === void 0) setUncontrolledPage(nextPage);
|
|
268
|
+
if (nextPage !== currentPage) onPageChange?.(nextPage);
|
|
269
|
+
};
|
|
270
|
+
const resolvedPaginationPosition = paginationPosition === "middle-bottom" ? "bottom-center" : paginationPosition;
|
|
271
|
+
const paginationControl = shouldPaginate && totalPages > 1 ? /* @__PURE__ */ jsx4("div", { className: `fe-table__pagination fe-table__pagination--${resolvedPaginationPosition}`, children: /* @__PURE__ */ jsx4(Pagination, { page: currentPage, totalPages, onPageChange: changePage }) }) : null;
|
|
272
|
+
return /* @__PURE__ */ jsxs4("div", { className: "fe-table", "data-resizing": isResizing || void 0, children: [
|
|
273
|
+
resolvedPaginationPosition === "top-right" && paginationControl,
|
|
274
|
+
/* @__PURE__ */ jsxs4("table", { className: ["fe-table__table", className].filter(Boolean).join(" "), "data-fe-table": true, "data-striped": striped || void 0, ...props, children: [
|
|
275
|
+
/* @__PURE__ */ jsx4("colgroup", { children: sizes2.map((size, index) => /* @__PURE__ */ jsx4("col", { style: { width: `${size}px` } }, index)) }),
|
|
276
|
+
/* @__PURE__ */ jsx4("thead", { children: /* @__PURE__ */ jsx4("tr", { children: Array.from({ length: columnCount }, (_, columnIndex) => /* @__PURE__ */ jsxs4("th", { scope: "col", children: [
|
|
277
|
+
/* @__PURE__ */ jsx4("span", { className: "fe-table__header-content", children: headers[columnIndex] ?? `Column ${columnIndex + 1}` }),
|
|
278
|
+
/* @__PURE__ */ jsx4(
|
|
279
|
+
"span",
|
|
280
|
+
{
|
|
281
|
+
className: "fe-table__resize-handle",
|
|
282
|
+
role: "separator",
|
|
283
|
+
"aria-label": `Resize ${getText(headers[columnIndex]) || `column ${columnIndex + 1}`}`,
|
|
284
|
+
"aria-orientation": "vertical",
|
|
285
|
+
"aria-valuemin": safeMinWidth,
|
|
286
|
+
"aria-valuemax": MAX_COLUMN_WIDTH,
|
|
287
|
+
"aria-valuenow": sizes2[columnIndex] ?? safeMinWidth,
|
|
288
|
+
tabIndex: 0,
|
|
289
|
+
onPointerDown: (event) => {
|
|
290
|
+
event.preventDefault();
|
|
291
|
+
resizeState.current = { columnIndex, startX: event.clientX, startWidth: sizes2[columnIndex] ?? safeMinWidth };
|
|
292
|
+
setIsResizing(true);
|
|
293
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
294
|
+
},
|
|
295
|
+
onKeyDown: (event) => {
|
|
296
|
+
if (event.key === "ArrowLeft") updateColumnSize(columnIndex, (sizes2[columnIndex] ?? safeMinWidth) - 16);
|
|
297
|
+
if (event.key === "ArrowRight") updateColumnSize(columnIndex, (sizes2[columnIndex] ?? safeMinWidth) + 16);
|
|
298
|
+
}
|
|
208
299
|
}
|
|
209
|
-
|
|
210
|
-
)
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
300
|
+
)
|
|
301
|
+
] }, columnIndex)) }) }),
|
|
302
|
+
/* @__PURE__ */ jsx4("tbody", { children: pagedData.map((row, rowIndex) => /* @__PURE__ */ jsx4("tr", { children: Array.from({ length: columnCount }, (_, columnIndex) => /* @__PURE__ */ jsx4("td", { children: row[columnIndex] }, columnIndex)) }, shouldPaginate ? (currentPage - 1) * safePageSize + rowIndex : rowIndex)) })
|
|
303
|
+
] }),
|
|
304
|
+
resolvedPaginationPosition !== "top-right" && paginationControl
|
|
305
|
+
] });
|
|
214
306
|
}
|
|
215
|
-
function Table({
|
|
216
|
-
|
|
217
|
-
|
|
307
|
+
function Table({
|
|
308
|
+
headers,
|
|
309
|
+
data,
|
|
310
|
+
striped,
|
|
311
|
+
children,
|
|
312
|
+
pagination,
|
|
313
|
+
pageSize,
|
|
314
|
+
page,
|
|
315
|
+
defaultPage,
|
|
316
|
+
onPageChange,
|
|
317
|
+
paginationPosition,
|
|
318
|
+
...props
|
|
319
|
+
}) {
|
|
320
|
+
if (headers || data) return /* @__PURE__ */ jsx4(DataTable, { headers: headers ?? [], data: data ?? [], striped: striped ?? true, pagination, pageSize, page, defaultPage, onPageChange, paginationPosition, ...props });
|
|
321
|
+
return /* @__PURE__ */ jsx4(TableContext.Provider, { value: { striped: striped ?? false }, children: /* @__PURE__ */ jsx4("table", { "data-fe-table": true, "data-striped": striped || void 0, ...props, children }) });
|
|
218
322
|
}
|
|
219
323
|
function TableHead(props) {
|
|
220
|
-
return /* @__PURE__ */
|
|
324
|
+
return /* @__PURE__ */ jsx4("thead", { ...props });
|
|
221
325
|
}
|
|
222
326
|
function TableBody(props) {
|
|
223
|
-
return /* @__PURE__ */
|
|
327
|
+
return /* @__PURE__ */ jsx4("tbody", { ...props });
|
|
224
328
|
}
|
|
225
329
|
function TableRow({ children, ...props }) {
|
|
226
330
|
const { striped } = useContext(TableContext);
|
|
227
|
-
return /* @__PURE__ */
|
|
331
|
+
return /* @__PURE__ */ jsx4("tr", { "data-striped": striped || void 0, ...props, children });
|
|
228
332
|
}
|
|
229
333
|
function TableCell({ children, ...props }) {
|
|
230
|
-
return /* @__PURE__ */
|
|
334
|
+
return /* @__PURE__ */ jsx4("td", { ...props, children });
|
|
231
335
|
}
|
|
232
336
|
function TableHeader({ children, ...props }) {
|
|
233
|
-
return /* @__PURE__ */
|
|
337
|
+
return /* @__PURE__ */ jsx4("th", { scope: "col", ...props, children });
|
|
234
338
|
}
|
|
235
339
|
function TableCaption(props) {
|
|
236
|
-
return /* @__PURE__ */
|
|
340
|
+
return /* @__PURE__ */ jsx4("caption", { ...props });
|
|
237
341
|
}
|
|
238
342
|
|
|
239
343
|
// packages/toggle/src/index.tsx
|
|
240
344
|
import { forwardRef as forwardRef2 } from "react";
|
|
241
|
-
import { jsx as
|
|
345
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
242
346
|
var Toggle = forwardRef2(function Toggle2({ color = "#16a34a", label, className, style, id, ...props }, ref) {
|
|
243
347
|
const classes = ["fe-toggle", className].filter(Boolean).join(" ");
|
|
244
348
|
const toggleStyle = {
|
|
245
349
|
"--fe-toggle-color": color,
|
|
246
350
|
...style
|
|
247
351
|
};
|
|
248
|
-
return /* @__PURE__ */
|
|
249
|
-
/* @__PURE__ */
|
|
250
|
-
/* @__PURE__ */
|
|
251
|
-
label && /* @__PURE__ */
|
|
352
|
+
return /* @__PURE__ */ jsxs5("label", { className: classes, style: toggleStyle, children: [
|
|
353
|
+
/* @__PURE__ */ jsx5("input", { ref, id, className: "fe-toggle__input", type: "checkbox", role: "switch", ...props }),
|
|
354
|
+
/* @__PURE__ */ jsx5("span", { className: "fe-toggle__control", "aria-hidden": "true" }),
|
|
355
|
+
label && /* @__PURE__ */ jsx5("span", { className: "fe-toggle__label", children: label })
|
|
252
356
|
] });
|
|
253
357
|
});
|
|
254
358
|
Toggle.displayName = "Toggle";
|
|
@@ -256,7 +360,7 @@ Toggle.displayName = "Toggle";
|
|
|
256
360
|
// packages/drawer/src/index.tsx
|
|
257
361
|
import { useEffect as useEffect2 } from "react";
|
|
258
362
|
import { createPortal } from "react-dom";
|
|
259
|
-
import { jsx as
|
|
363
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
260
364
|
function Drawer({ open, onClose, title, footer, side = "right", width = 400, fullScreen = false, children, closeOnBackdropClick = true, className, style, ...props }) {
|
|
261
365
|
useEffect2(() => {
|
|
262
366
|
if (!open) return;
|
|
@@ -268,15 +372,15 @@ function Drawer({ open, onClose, title, footer, side = "right", width = 400, ful
|
|
|
268
372
|
}, [onClose, open]);
|
|
269
373
|
if (!open || typeof document === "undefined") return null;
|
|
270
374
|
const panelStyle = !fullScreen && (side === "left" || side === "right") ? { ...style, width: typeof width === "number" ? `${width}px` : width } : style;
|
|
271
|
-
return createPortal(/* @__PURE__ */
|
|
375
|
+
return createPortal(/* @__PURE__ */ jsx6("div", { className: "fe-drawer-backdrop", role: "presentation", onMouseDown: (event) => {
|
|
272
376
|
if (event.target === event.currentTarget && closeOnBackdropClick) onClose();
|
|
273
|
-
}, children: /* @__PURE__ */
|
|
274
|
-
/* @__PURE__ */
|
|
275
|
-
title && /* @__PURE__ */
|
|
276
|
-
/* @__PURE__ */
|
|
377
|
+
}, children: /* @__PURE__ */ jsxs6("aside", { className: ["fe-drawer", `fe-drawer--${side}`, fullScreen && "fe-drawer--full-screen", className].filter(Boolean).join(" "), style: panelStyle, role: "dialog", "aria-modal": "true", "aria-label": typeof title === "string" ? title : "Drawer", ...props, children: [
|
|
378
|
+
/* @__PURE__ */ jsxs6("header", { className: "fe-drawer__header", children: [
|
|
379
|
+
title && /* @__PURE__ */ jsx6("h2", { children: title }),
|
|
380
|
+
/* @__PURE__ */ jsx6("button", { type: "button", "aria-label": "Close drawer", onClick: onClose, children: "\xD7" })
|
|
277
381
|
] }),
|
|
278
|
-
/* @__PURE__ */
|
|
279
|
-
footer && /* @__PURE__ */
|
|
382
|
+
/* @__PURE__ */ jsx6("div", { className: "fe-drawer__body", children }),
|
|
383
|
+
footer && /* @__PURE__ */ jsx6("footer", { className: "fe-drawer__footer", children: footer })
|
|
280
384
|
] }) }), document.body);
|
|
281
385
|
}
|
|
282
386
|
|
|
@@ -286,20 +390,92 @@ import {
|
|
|
286
390
|
useEffect as useEffect3,
|
|
287
391
|
useId,
|
|
288
392
|
useRef as useRef2,
|
|
289
|
-
useState as
|
|
393
|
+
useState as useState3
|
|
290
394
|
} from "react";
|
|
291
|
-
import { jsx as
|
|
395
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
396
|
+
function getFieldError(error, errorMessage) {
|
|
397
|
+
if (errorMessage !== void 0 && errorMessage !== null) return errorMessage;
|
|
398
|
+
if (typeof error !== "boolean") return error;
|
|
399
|
+
return error ? "Invalid value" : void 0;
|
|
400
|
+
}
|
|
401
|
+
function getDescribedBy(existing, messageId2) {
|
|
402
|
+
return [existing, messageId2].filter(Boolean).join(" ") || void 0;
|
|
403
|
+
}
|
|
404
|
+
var TextInput = forwardRef3(function TextInput2({ value, defaultValue = "", onChange, onValueChange, label, helperText, error, errorMessage, clearable = false, onClear, clearLabel = "Clear input", className, disabled, readOnly, id, "aria-describedby": ariaDescribedBy, "aria-labelledby": ariaLabelledBy, ...props }, ref) {
|
|
405
|
+
const generatedId = useId();
|
|
406
|
+
const inputId = id ?? `${generatedId}-input`;
|
|
407
|
+
const labelId = `${generatedId}-label`;
|
|
408
|
+
const messageId2 = `${generatedId}-message`;
|
|
409
|
+
const controlled = value !== void 0;
|
|
410
|
+
const [internalValue, setInternalValue] = useState3(defaultValue);
|
|
411
|
+
const currentValue = controlled ? value : internalValue;
|
|
412
|
+
const fieldError = getFieldError(error, errorMessage);
|
|
413
|
+
const hasError = fieldError !== void 0 && fieldError !== false && fieldError !== null;
|
|
414
|
+
const displayedMessage = hasError ? fieldError : helperText;
|
|
415
|
+
const describedBy = getDescribedBy(ariaDescribedBy, displayedMessage ? messageId2 : void 0);
|
|
416
|
+
const clear = () => {
|
|
417
|
+
if (!controlled) setInternalValue("");
|
|
418
|
+
onValueChange?.("");
|
|
419
|
+
onClear?.();
|
|
420
|
+
};
|
|
421
|
+
const labelledBy = getDescribedBy(ariaLabelledBy, label ? labelId : void 0);
|
|
422
|
+
return /* @__PURE__ */ jsxs7("label", { className: ["fe-text-input", hasError && "fe-text-input--error", className].filter(Boolean).join(" "), children: [
|
|
423
|
+
label && /* @__PURE__ */ jsx7("span", { id: labelId, className: "fe-text-input__label", children: label }),
|
|
424
|
+
/* @__PURE__ */ jsxs7("span", { className: "fe-text-input__control", children: [
|
|
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 })
|
|
433
|
+
] });
|
|
434
|
+
});
|
|
435
|
+
TextInput.displayName = "TextInput";
|
|
436
|
+
var TextArea = forwardRef3(function TextArea2({ value, defaultValue = "", onChange, onValueChange, label, helperText, error, errorMessage, clearable = false, onClear, clearLabel = "Clear text area", className, disabled, readOnly, id, "aria-describedby": ariaDescribedBy, "aria-labelledby": ariaLabelledBy, ...props }, ref) {
|
|
437
|
+
const generatedId = useId();
|
|
438
|
+
const inputId = id ?? `${generatedId}-input`;
|
|
439
|
+
const labelId = `${generatedId}-label`;
|
|
440
|
+
const messageId2 = `${generatedId}-message`;
|
|
441
|
+
const controlled = value !== void 0;
|
|
442
|
+
const [internalValue, setInternalValue] = useState3(defaultValue);
|
|
443
|
+
const currentValue = controlled ? value : internalValue;
|
|
444
|
+
const fieldError = getFieldError(error, errorMessage);
|
|
445
|
+
const hasError = fieldError !== void 0 && fieldError !== false && fieldError !== null;
|
|
446
|
+
const displayedMessage = hasError ? fieldError : helperText;
|
|
447
|
+
const describedBy = getDescribedBy(ariaDescribedBy, displayedMessage ? messageId2 : void 0);
|
|
448
|
+
const clear = () => {
|
|
449
|
+
if (!controlled) setInternalValue("");
|
|
450
|
+
onValueChange?.("");
|
|
451
|
+
onClear?.();
|
|
452
|
+
};
|
|
453
|
+
const labelledBy = getDescribedBy(ariaLabelledBy, label ? labelId : void 0);
|
|
454
|
+
return /* @__PURE__ */ jsxs7("label", { className: ["fe-text-area", hasError && "fe-text-area--error", className].filter(Boolean).join(" "), children: [
|
|
455
|
+
label && /* @__PURE__ */ jsx7("span", { id: labelId, className: "fe-text-area__label", children: label }),
|
|
456
|
+
/* @__PURE__ */ jsxs7("span", { className: "fe-text-area__control", children: [
|
|
457
|
+
/* @__PURE__ */ jsx7("textarea", { ref, id: inputId, value: currentValue, disabled, readOnly, "aria-invalid": hasError || void 0, "aria-labelledby": labelledBy, "aria-describedby": describedBy, onChange: (event) => {
|
|
458
|
+
if (!controlled) setInternalValue(event.target.value);
|
|
459
|
+
onValueChange?.(event.target.value);
|
|
460
|
+
onChange?.(event);
|
|
461
|
+
}, ...props }),
|
|
462
|
+
clearable && currentValue && !disabled && !readOnly && /* @__PURE__ */ jsx7(Button, { hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: /* @__PURE__ */ jsx7(CloseIcon, { size: 14 }), "aria-label": clearLabel, onClick: clear, className: "fe-text-area__clear" })
|
|
463
|
+
] }),
|
|
464
|
+
displayedMessage && /* @__PURE__ */ jsx7("span", { id: messageId2, className: hasError ? "fe-text-area__error" : "fe-text-area__helper", children: displayedMessage })
|
|
465
|
+
] });
|
|
466
|
+
});
|
|
467
|
+
TextArea.displayName = "TextArea";
|
|
292
468
|
var Selection = forwardRef3(function Selection2({ className, label, helperText, error, options, placeholder = "Select an option", size = "medium", id, value, defaultValue, onChange, multiple = false, searchable = false, tag = false, clearable = false, disabled = false, name, onKeyDown, ...props }, ref) {
|
|
293
469
|
const generatedId = useId();
|
|
294
470
|
const listboxId = id ?? generatedId;
|
|
295
471
|
const isControlled = value !== void 0;
|
|
296
|
-
const [internalValue, setInternalValue] =
|
|
472
|
+
const [internalValue, setInternalValue] = useState3(defaultValue ?? (multiple ? [] : ""));
|
|
297
473
|
const selectedValue = isControlled ? value : internalValue;
|
|
298
474
|
const selectedValues = Array.isArray(selectedValue) ? selectedValue : selectedValue === "" || selectedValue === null || selectedValue === void 0 ? [] : [selectedValue];
|
|
299
475
|
const selectedOptions = options.filter((option) => selectedValues.some((item) => String(item) === String(option.value)));
|
|
300
|
-
const [open, setOpen] =
|
|
301
|
-
const [query, setQuery] =
|
|
302
|
-
const [activeIndex, setActiveIndex] =
|
|
476
|
+
const [open, setOpen] = useState3(false);
|
|
477
|
+
const [query, setQuery] = useState3("");
|
|
478
|
+
const [activeIndex, setActiveIndex] = useState3(0);
|
|
303
479
|
const rootRef = useRef2(null);
|
|
304
480
|
useEffect3(() => {
|
|
305
481
|
const close = (event) => {
|
|
@@ -344,39 +520,39 @@ var Selection = forwardRef3(function Selection2({ className, label, helperText,
|
|
|
344
520
|
}
|
|
345
521
|
if (event.key === "Escape") setOpen(false);
|
|
346
522
|
};
|
|
347
|
-
return /* @__PURE__ */
|
|
348
|
-
label && /* @__PURE__ */
|
|
349
|
-
/* @__PURE__ */
|
|
350
|
-
name && selectedValues.map((item) => /* @__PURE__ */
|
|
351
|
-
/* @__PURE__ */
|
|
352
|
-
/* @__PURE__ */
|
|
523
|
+
return /* @__PURE__ */ jsxs7("div", { ref, className: ["fe-selection", `fe-selection--${size}`, open && "fe-selection--open", clearable && selectedOptions.length > 0 && "fe-selection--clearable", error && "fe-selection--error", disabled && "fe-selection--disabled", className].filter(Boolean).join(" "), ...props, children: [
|
|
524
|
+
label && /* @__PURE__ */ jsx7("span", { className: "fe-selection__label", children: label }),
|
|
525
|
+
/* @__PURE__ */ jsxs7("div", { ref: rootRef, className: "fe-selection__control", children: [
|
|
526
|
+
name && selectedValues.map((item) => /* @__PURE__ */ jsx7("input", { type: "hidden", name: multiple ? `${name}[]` : name, value: item }, String(item))),
|
|
527
|
+
/* @__PURE__ */ jsxs7("button", { type: "button", className: "fe-selection__trigger", disabled, "aria-invalid": error || void 0, "aria-haspopup": "listbox", "aria-expanded": open, "aria-controls": listboxId, onClick: () => setOpen((current) => !current), onKeyDown: onTriggerKeyDown, children: [
|
|
528
|
+
/* @__PURE__ */ jsx7("span", { className: ["fe-selection__value", !selectedOptions.length && "is-placeholder", tag && selectedOptions.length > 1 && "is-tags"].filter(Boolean).join(" "), children: displayLabel ? tag && multiple ? selectedOptions.map((option) => /* @__PURE__ */ jsxs7("span", { className: "fe-selection__tag", children: [
|
|
353
529
|
option.label,
|
|
354
|
-
/* @__PURE__ */
|
|
355
|
-
] }, String(option.value))) : displayLabel.map((item, index) => /* @__PURE__ */
|
|
530
|
+
/* @__PURE__ */ jsx7("span", { "aria-hidden": "true", children: "\xD7" })
|
|
531
|
+
] }, String(option.value))) : displayLabel.map((item, index) => /* @__PURE__ */ jsxs7("span", { children: [
|
|
356
532
|
item,
|
|
357
533
|
index < displayLabel.length - 1 ? ", " : ""
|
|
358
534
|
] }, index)) : placeholder }),
|
|
359
|
-
/* @__PURE__ */
|
|
535
|
+
/* @__PURE__ */ jsx7("span", { className: "fe-selection__actions", children: /* @__PURE__ */ jsx7("span", { className: "fe-selection__chevron", "aria-hidden": "true" }) })
|
|
360
536
|
] }),
|
|
361
|
-
clearable && selectedOptions.length > 0 && /* @__PURE__ */
|
|
362
|
-
open && /* @__PURE__ */
|
|
363
|
-
searchable && /* @__PURE__ */
|
|
364
|
-
/* @__PURE__ */
|
|
365
|
-
/* @__PURE__ */
|
|
537
|
+
clearable && selectedOptions.length > 0 && /* @__PURE__ */ jsx7("button", { type: "button", className: "fe-selection__clear", "aria-label": "Clear selection", onClick: clear }),
|
|
538
|
+
open && /* @__PURE__ */ jsxs7("div", { id: listboxId, className: "fe-selection__menu", role: "listbox", "aria-multiselectable": multiple || void 0, children: [
|
|
539
|
+
searchable && /* @__PURE__ */ jsxs7("div", { className: "fe-selection__search", children: [
|
|
540
|
+
/* @__PURE__ */ jsx7("span", { "aria-hidden": "true", children: "\u2315" }),
|
|
541
|
+
/* @__PURE__ */ jsx7("input", { autoFocus: true, value: query, onChange: (event) => {
|
|
366
542
|
setQuery(event.target.value);
|
|
367
543
|
setActiveIndex(0);
|
|
368
544
|
}, placeholder: "Search\u2026", "aria-label": "Search options" })
|
|
369
545
|
] }),
|
|
370
|
-
/* @__PURE__ */
|
|
546
|
+
/* @__PURE__ */ jsx7("div", { className: "fe-selection__options", children: filteredOptions.length ? filteredOptions.map((option, index) => {
|
|
371
547
|
const isSelected = selectedValues.some((item) => String(item) === String(option.value));
|
|
372
|
-
return /* @__PURE__ */
|
|
373
|
-
/* @__PURE__ */
|
|
374
|
-
isSelected && /* @__PURE__ */
|
|
548
|
+
return /* @__PURE__ */ jsxs7("button", { type: "button", className: [isSelected && "is-selected", index === activeIndex && "is-active"].filter(Boolean).join(" "), role: "option", "aria-selected": isSelected, disabled: option.disabled, onMouseMove: () => setActiveIndex(index), onClick: () => choose(option), children: [
|
|
549
|
+
/* @__PURE__ */ jsx7("span", { children: option.label }),
|
|
550
|
+
isSelected && /* @__PURE__ */ jsx7("span", { className: "fe-selection__check", "aria-hidden": "true", children: "\u2713" })
|
|
375
551
|
] }, String(option.value));
|
|
376
|
-
}) : /* @__PURE__ */
|
|
552
|
+
}) : /* @__PURE__ */ jsx7("p", { className: "fe-selection__empty", children: "No matching options" }) })
|
|
377
553
|
] })
|
|
378
554
|
] }),
|
|
379
|
-
helperText && /* @__PURE__ */
|
|
555
|
+
helperText && /* @__PURE__ */ jsx7("span", { className: "fe-selection__helper", children: helperText })
|
|
380
556
|
] });
|
|
381
557
|
});
|
|
382
558
|
Selection.displayName = "Selection";
|
|
@@ -413,12 +589,18 @@ function normalizeNumberInput(raw, options) {
|
|
|
413
589
|
if (value !== numericValue) return { display: formatNumber(value, decimals, thousandSeparator, decimalSeparator), value };
|
|
414
590
|
return { display: `${negative ? "-" : ""}${groupInteger(integer || "0", thousandSeparator)}${hasDecimal ? `${decimalSeparator}${fraction}` : ""}`, value };
|
|
415
591
|
}
|
|
416
|
-
var NumberInput = forwardRef3(function NumberInput2({ value, defaultValue = null, onValueChange, allowDecimal = true, decimals = 2, min, max, decimalSeparator = ".", thousandSeparator = ",", label, helperText, error, className, onBlur, onFocus, ...props }, ref) {
|
|
592
|
+
var NumberInput = forwardRef3(function NumberInput2({ value, defaultValue = null, onValueChange, allowDecimal = true, decimals = 2, min, max, decimalSeparator = ".", thousandSeparator = ",", label, helperText, error, errorMessage, className, onBlur, onFocus, "aria-describedby": ariaDescribedBy, ...props }, ref) {
|
|
593
|
+
const generatedId = useId();
|
|
594
|
+
const messageId2 = `${generatedId}-message`;
|
|
417
595
|
const isControlled = value !== void 0;
|
|
418
|
-
const [internalValue, setInternalValue] =
|
|
419
|
-
const [focused, setFocused] =
|
|
596
|
+
const [internalValue, setInternalValue] = useState3(defaultValue);
|
|
597
|
+
const [focused, setFocused] = useState3(false);
|
|
420
598
|
const actualValue = isControlled ? value ?? null : internalValue;
|
|
421
|
-
const [text, setText] =
|
|
599
|
+
const [text, setText] = useState3(actualValue === null ? "" : formatNumber(actualValue, decimals, thousandSeparator, decimalSeparator));
|
|
600
|
+
const fieldError = getFieldError(error, errorMessage);
|
|
601
|
+
const hasError = fieldError !== void 0 && fieldError !== false && fieldError !== null;
|
|
602
|
+
const displayedMessage = hasError ? fieldError : helperText;
|
|
603
|
+
const describedBy = getDescribedBy(ariaDescribedBy, displayedMessage ? messageId2 : void 0);
|
|
422
604
|
useEffect3(() => {
|
|
423
605
|
if (!focused) setText(actualValue === null ? "" : formatNumber(actualValue, decimals, thousandSeparator, decimalSeparator));
|
|
424
606
|
}, [actualValue, decimalSeparator, decimals, focused, thousandSeparator]);
|
|
@@ -429,32 +611,32 @@ var NumberInput = forwardRef3(function NumberInput2({ value, defaultValue = null
|
|
|
429
611
|
if (!isControlled) setInternalValue(nextValue);
|
|
430
612
|
onValueChange?.(nextValue);
|
|
431
613
|
};
|
|
432
|
-
return /* @__PURE__ */
|
|
433
|
-
label && /* @__PURE__ */
|
|
434
|
-
/* @__PURE__ */
|
|
614
|
+
return /* @__PURE__ */ jsxs7("label", { className: ["fe-number-input", hasError && "fe-number-input--error", className].filter(Boolean).join(" "), children: [
|
|
615
|
+
label && /* @__PURE__ */ jsx7("span", { className: "fe-number-input__label", children: label }),
|
|
616
|
+
/* @__PURE__ */ jsx7("input", { ref, inputMode: allowDecimal ? "decimal" : "numeric", value: text, onFocus: (event) => {
|
|
435
617
|
setFocused(true);
|
|
436
618
|
onFocus?.(event);
|
|
437
619
|
}, onChange: (event) => updateValue(event.target.value), onBlur: (event) => {
|
|
438
620
|
setFocused(false);
|
|
439
621
|
onBlur?.(event);
|
|
440
|
-
}, ...props }),
|
|
441
|
-
|
|
622
|
+
}, ...props, "aria-invalid": hasError || void 0, "aria-describedby": describedBy }),
|
|
623
|
+
displayedMessage && /* @__PURE__ */ jsx7("span", { id: messageId2, className: hasError ? "fe-number-input__error" : "fe-number-input__helper", children: displayedMessage })
|
|
442
624
|
] });
|
|
443
625
|
});
|
|
444
626
|
NumberInput.displayName = "NumberInput";
|
|
445
627
|
function CurrencyInput({ suffix = "VND", currencies, currency, defaultCurrency, onCurrencyChange, className, ...props }) {
|
|
446
|
-
const [internalCurrency, setInternalCurrency] =
|
|
628
|
+
const [internalCurrency, setInternalCurrency] = useState3(defaultCurrency ?? currencies?.[0]?.code ?? "");
|
|
447
629
|
const selectedCurrency = currency ?? internalCurrency;
|
|
448
630
|
const current = currencies?.find((item) => item.code === selectedCurrency);
|
|
449
631
|
const currencySuffix = current?.suffix ?? current?.code ?? suffix;
|
|
450
|
-
return /* @__PURE__ */
|
|
451
|
-
/* @__PURE__ */
|
|
452
|
-
currencies?.length ? /* @__PURE__ */
|
|
632
|
+
return /* @__PURE__ */ jsxs7("div", { className: ["fe-currency-input", className].filter(Boolean).join(" "), children: [
|
|
633
|
+
/* @__PURE__ */ jsx7(NumberInput, { ...props, className: "fe-currency-input__number" }),
|
|
634
|
+
currencies?.length ? /* @__PURE__ */ jsx7("select", { className: "fe-currency-input__currency", "aria-label": "Currency", value: selectedCurrency, onChange: (event) => {
|
|
453
635
|
const next = currencies.find((item) => item.code === event.target.value);
|
|
454
636
|
if (!next) return;
|
|
455
637
|
if (currency === void 0) setInternalCurrency(next.code);
|
|
456
638
|
onCurrencyChange?.(next);
|
|
457
|
-
}, children: currencies.map((item) => /* @__PURE__ */
|
|
639
|
+
}, children: currencies.map((item) => /* @__PURE__ */ jsx7("option", { value: item.code, children: item.label ?? item.code }, item.code)) }) : /* @__PURE__ */ jsx7("span", { className: "fe-currency-input__suffix", children: currencySuffix })
|
|
458
640
|
] });
|
|
459
641
|
}
|
|
460
642
|
var pad = (value) => String(value).padStart(2, "0");
|
|
@@ -477,13 +659,13 @@ function DateTimePicker(props) {
|
|
|
477
659
|
const { label, format = "dd/MM/yyyy HH:mm", disabled, placeholder, locale = "en-US", className, mode = "single" } = props;
|
|
478
660
|
const isRange = mode === "range";
|
|
479
661
|
const controlled = props.value !== void 0;
|
|
480
|
-
const [singleInternal, setSingleInternal] =
|
|
481
|
-
const [rangeInternal, setRangeInternal] =
|
|
662
|
+
const [singleInternal, setSingleInternal] = useState3((!isRange ? props.defaultValue : null) ?? null);
|
|
663
|
+
const [rangeInternal, setRangeInternal] = useState3((isRange ? props.defaultValue : void 0) ?? [null, null]);
|
|
482
664
|
const singleValue = !isRange ? props.value ?? singleInternal : null;
|
|
483
665
|
const rangeValue = isRange ? props.value ?? rangeInternal : [null, null];
|
|
484
|
-
const [open, setOpen] =
|
|
485
|
-
const [month, setMonth] =
|
|
486
|
-
const [editingEnd, setEditingEnd] =
|
|
666
|
+
const [open, setOpen] = useState3(false);
|
|
667
|
+
const [month, setMonth] = useState3(() => new Date((isRange ? rangeValue[0] : singleValue) ?? /* @__PURE__ */ new Date()));
|
|
668
|
+
const [editingEnd, setEditingEnd] = useState3(false);
|
|
487
669
|
const rootRef = useRef2(null);
|
|
488
670
|
useEffect3(() => {
|
|
489
671
|
const onPointerDown = (event) => {
|
|
@@ -527,42 +709,42 @@ function DateTimePicker(props) {
|
|
|
527
709
|
if (isRange) setRange(editingEnd ? [rangeValue[0], next] : [next, rangeValue[1]]);
|
|
528
710
|
else setSingle(next);
|
|
529
711
|
};
|
|
530
|
-
return /* @__PURE__ */
|
|
531
|
-
label && /* @__PURE__ */
|
|
532
|
-
/* @__PURE__ */
|
|
533
|
-
/* @__PURE__ */
|
|
534
|
-
/* @__PURE__ */
|
|
712
|
+
return /* @__PURE__ */ jsxs7("div", { ref: rootRef, className: ["fe-datetime-picker", className].filter(Boolean).join(" "), children: [
|
|
713
|
+
label && /* @__PURE__ */ jsx7("span", { className: "fe-datetime-picker__label", children: label }),
|
|
714
|
+
/* @__PURE__ */ jsxs7("button", { type: "button", className: "fe-datetime-picker__trigger", disabled, "aria-expanded": open, onClick: () => setOpen((current) => !current), children: [
|
|
715
|
+
/* @__PURE__ */ jsx7("span", { "aria-hidden": "true", children: "\u25F7" }),
|
|
716
|
+
/* @__PURE__ */ jsx7("span", { children: shownValue || placeholder || (isRange ? "Select date range" : "Select date and time") })
|
|
535
717
|
] }),
|
|
536
|
-
open && /* @__PURE__ */
|
|
537
|
-
/* @__PURE__ */
|
|
538
|
-
/* @__PURE__ */
|
|
539
|
-
/* @__PURE__ */
|
|
540
|
-
/* @__PURE__ */
|
|
718
|
+
open && /* @__PURE__ */ jsxs7("div", { className: "fe-datetime-picker__popper", role: "dialog", "aria-label": "Date and time picker", children: [
|
|
719
|
+
/* @__PURE__ */ jsxs7("div", { className: "fe-datetime-picker__month", children: [
|
|
720
|
+
/* @__PURE__ */ jsx7("button", { type: "button", "aria-label": "Previous month", onClick: () => setMonth((current) => new Date(current.getFullYear(), current.getMonth() - 1, 1)), children: "\u2039" }),
|
|
721
|
+
/* @__PURE__ */ jsx7("strong", { children: month.toLocaleDateString(locale, { month: "long", year: "numeric" }) }),
|
|
722
|
+
/* @__PURE__ */ jsx7("button", { type: "button", "aria-label": "Next month", onClick: () => setMonth((current) => new Date(current.getFullYear(), current.getMonth() + 1, 1)), children: "\u203A" })
|
|
541
723
|
] }),
|
|
542
|
-
/* @__PURE__ */
|
|
543
|
-
/* @__PURE__ */
|
|
724
|
+
/* @__PURE__ */ jsx7("div", { className: "fe-datetime-picker__weekdays", children: ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"].map((day) => /* @__PURE__ */ jsx7("span", { children: day }, day)) }),
|
|
725
|
+
/* @__PURE__ */ jsx7("div", { className: "fe-datetime-picker__days", children: days.map((day) => {
|
|
544
726
|
const inMonth = day.getMonth() === month.getMonth();
|
|
545
727
|
const selected = isRange ? sameDay(day, rangeValue[0]) || sameDay(day, rangeValue[1]) : sameDay(day, singleValue);
|
|
546
728
|
const inRange = isRange && rangeValue[0] && rangeValue[1] && day > startOfDay(rangeValue[0]) && day < startOfDay(rangeValue[1]);
|
|
547
|
-
return /* @__PURE__ */
|
|
729
|
+
return /* @__PURE__ */ jsx7("button", { type: "button", className: [!inMonth && "is-other-month", selected && "is-selected", inRange && "is-in-range"].filter(Boolean).join(" "), onClick: () => selectDay(day), children: day.getDate() }, day.toISOString());
|
|
548
730
|
}) }),
|
|
549
|
-
isRange && /* @__PURE__ */
|
|
550
|
-
/* @__PURE__ */
|
|
551
|
-
/* @__PURE__ */
|
|
731
|
+
isRange && /* @__PURE__ */ jsxs7("div", { className: "fe-datetime-picker__range-tabs", children: [
|
|
732
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: !editingEnd ? "is-active" : "", onClick: () => setEditingEnd(false), children: "Start" }),
|
|
733
|
+
/* @__PURE__ */ jsx7("button", { type: "button", className: editingEnd ? "is-active" : "", onClick: () => setEditingEnd(true), children: "End" })
|
|
552
734
|
] }),
|
|
553
|
-
/* @__PURE__ */
|
|
735
|
+
/* @__PURE__ */ jsxs7("label", { className: "fe-datetime-picker__time", children: [
|
|
554
736
|
"Time",
|
|
555
|
-
/* @__PURE__ */
|
|
737
|
+
/* @__PURE__ */ jsx7("input", { type: "time", value: selectedForTime ? `${pad(selectedForTime.getHours())}:${pad(selectedForTime.getMinutes())}` : "00:00", onChange: (event) => setTime(event.target.value), disabled: !selectedForTime })
|
|
556
738
|
] })
|
|
557
739
|
] })
|
|
558
740
|
] });
|
|
559
741
|
}
|
|
560
742
|
|
|
561
743
|
// packages/tooltip/src/index.tsx
|
|
562
|
-
import { cloneElement, useId as useId2, useState as
|
|
563
|
-
import { jsx as
|
|
744
|
+
import { cloneElement, useId as useId2, useState as useState4 } from "react";
|
|
745
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
564
746
|
function Tooltip({ content, children, placement = "top", disabled, className, ...props }) {
|
|
565
|
-
const [visible, setVisible] =
|
|
747
|
+
const [visible, setVisible] = useState4(false);
|
|
566
748
|
const id = useId2();
|
|
567
749
|
const trigger = cloneElement(children, { "aria-describedby": visible ? id : void 0, onMouseEnter: (event) => {
|
|
568
750
|
children.props.onMouseEnter?.(event);
|
|
@@ -577,17 +759,17 @@ function Tooltip({ content, children, placement = "top", disabled, className, ..
|
|
|
577
759
|
children.props.onBlur?.(event);
|
|
578
760
|
setVisible(false);
|
|
579
761
|
} });
|
|
580
|
-
return /* @__PURE__ */
|
|
762
|
+
return /* @__PURE__ */ jsxs8("span", { className: ["fe-tooltip", `fe-tooltip--${placement}`, className].filter(Boolean).join(" "), ...props, children: [
|
|
581
763
|
trigger,
|
|
582
|
-
visible && !disabled && /* @__PURE__ */
|
|
764
|
+
visible && !disabled && /* @__PURE__ */ jsx8("span", { id, role: "tooltip", className: "fe-tooltip__content", children: content })
|
|
583
765
|
] });
|
|
584
766
|
}
|
|
585
767
|
|
|
586
768
|
// packages/expandable-section/src/index.tsx
|
|
587
|
-
import { useId as useId3, useState as
|
|
588
|
-
import { jsx as
|
|
769
|
+
import { useId as useId3, useState as useState5 } from "react";
|
|
770
|
+
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
589
771
|
function ExpandableSection({ title, children, expanded, defaultExpanded = false, onExpandedChange, disabled, className, ...props }) {
|
|
590
|
-
const [internalExpanded, setInternalExpanded] =
|
|
772
|
+
const [internalExpanded, setInternalExpanded] = useState5(defaultExpanded);
|
|
591
773
|
const isExpanded = expanded ?? internalExpanded;
|
|
592
774
|
const id = useId3();
|
|
593
775
|
const toggle = () => {
|
|
@@ -596,26 +778,304 @@ function ExpandableSection({ title, children, expanded, defaultExpanded = false,
|
|
|
596
778
|
if (expanded === void 0) setInternalExpanded(next);
|
|
597
779
|
onExpandedChange?.(next);
|
|
598
780
|
};
|
|
599
|
-
return /* @__PURE__ */
|
|
600
|
-
/* @__PURE__ */
|
|
601
|
-
/* @__PURE__ */
|
|
602
|
-
/* @__PURE__ */
|
|
781
|
+
return /* @__PURE__ */ jsxs9("section", { className: ["fe-expandable-section", isExpanded && "fe-expandable-section--expanded", disabled && "fe-expandable-section--disabled", className].filter(Boolean).join(" "), ...props, children: [
|
|
782
|
+
/* @__PURE__ */ jsxs9("button", { className: "fe-expandable-section__trigger", type: "button", "aria-expanded": isExpanded, "aria-controls": id, disabled, onClick: toggle, children: [
|
|
783
|
+
/* @__PURE__ */ jsx9("span", { children: title }),
|
|
784
|
+
/* @__PURE__ */ jsx9("span", { className: "fe-expandable-section__chevron", "aria-hidden": "true" })
|
|
785
|
+
] }),
|
|
786
|
+
/* @__PURE__ */ jsx9("div", { id, className: "fe-expandable-section__content", "aria-hidden": !isExpanded, children: /* @__PURE__ */ jsx9("div", { className: "fe-expandable-section__content-inner", children }) })
|
|
787
|
+
] });
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
// packages/loading/src/index.tsx
|
|
791
|
+
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
792
|
+
var sizes = {
|
|
793
|
+
small: "16px",
|
|
794
|
+
medium: "24px",
|
|
795
|
+
large: "40px"
|
|
796
|
+
};
|
|
797
|
+
function Loading({ size = "medium", color = "#2878f0", label, className, style, ...props }) {
|
|
798
|
+
const diameter = typeof size === "number" ? `${size}px` : sizes[size];
|
|
799
|
+
const loadingStyle = {
|
|
800
|
+
"--fe-loading-size": diameter,
|
|
801
|
+
"--fe-loading-color": color,
|
|
802
|
+
...style
|
|
803
|
+
};
|
|
804
|
+
return /* @__PURE__ */ jsxs10("span", { className: ["fe-loading", className].filter(Boolean).join(" "), style: loadingStyle, role: "status", ...props, children: [
|
|
805
|
+
/* @__PURE__ */ jsx10("span", { className: "fe-loading__spinner", "aria-hidden": "true" }),
|
|
806
|
+
label && /* @__PURE__ */ jsx10("span", { className: "fe-loading__label", children: label }),
|
|
807
|
+
!label && /* @__PURE__ */ jsx10("span", { className: "fe-loading__sr-only", children: "Loading" })
|
|
808
|
+
] });
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
// packages/skeleton/src/index.tsx
|
|
812
|
+
import { Fragment as Fragment2, jsx as jsx11 } from "react/jsx-runtime";
|
|
813
|
+
var pixels = (value) => typeof value === "number" ? `${value}px` : value;
|
|
814
|
+
function SkeletonBase({ variant = "box", shape, width, height, count = 1, animated = true, className, style, ...props }) {
|
|
815
|
+
const resolvedVariant = shape ?? variant;
|
|
816
|
+
const resolvedWidth = pixels(width) ?? (resolvedVariant === "circle" ? "40px" : "100%");
|
|
817
|
+
const resolvedHeight = pixels(height) ?? (resolvedVariant === "circle" ? resolvedWidth : resolvedVariant === "line" ? "12px" : "80px");
|
|
818
|
+
const skeletonStyle = {
|
|
819
|
+
"--fe-skeleton-width": resolvedWidth,
|
|
820
|
+
"--fe-skeleton-height": resolvedHeight,
|
|
821
|
+
...style
|
|
822
|
+
};
|
|
823
|
+
return /* @__PURE__ */ jsx11(Fragment2, { children: Array.from({ length: Math.max(1, count) }, (_, index) => /* @__PURE__ */ jsx11(
|
|
824
|
+
"div",
|
|
825
|
+
{
|
|
826
|
+
className: ["fe-skeleton", `fe-skeleton--${resolvedVariant}`, animated && "fe-skeleton--animated", className].filter(Boolean).join(" "),
|
|
827
|
+
style: skeletonStyle,
|
|
828
|
+
"aria-hidden": "true",
|
|
829
|
+
...props
|
|
830
|
+
},
|
|
831
|
+
index
|
|
832
|
+
)) });
|
|
833
|
+
}
|
|
834
|
+
function SkeletonCircle({ size = 40, ...props }) {
|
|
835
|
+
return /* @__PURE__ */ jsx11(SkeletonBase, { variant: "circle", width: size, height: size, ...props });
|
|
836
|
+
}
|
|
837
|
+
function SkeletonSquare({ size = 80, ...props }) {
|
|
838
|
+
return /* @__PURE__ */ jsx11(SkeletonBase, { variant: "box", width: size, height: size, ...props });
|
|
839
|
+
}
|
|
840
|
+
function SkeletonBox({ width = "100%", height = 80, ...props }) {
|
|
841
|
+
return /* @__PURE__ */ jsx11(SkeletonBase, { variant: "box", width, height, ...props });
|
|
842
|
+
}
|
|
843
|
+
function SkeletonLine({ width = "100%", height = 12, ...props }) {
|
|
844
|
+
return /* @__PURE__ */ jsx11(SkeletonBase, { variant: "line", width, height, ...props });
|
|
845
|
+
}
|
|
846
|
+
var Skeleton = Object.assign(SkeletonBase, {
|
|
847
|
+
Circle: SkeletonCircle,
|
|
848
|
+
Square: SkeletonSquare,
|
|
849
|
+
Box: SkeletonBox,
|
|
850
|
+
Line: SkeletonLine
|
|
851
|
+
});
|
|
852
|
+
|
|
853
|
+
// packages/modal/src/index.tsx
|
|
854
|
+
import { useEffect as useEffect4, useId as useId4, useRef as useRef3 } from "react";
|
|
855
|
+
import { createPortal as createPortal2 } from "react-dom";
|
|
856
|
+
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
857
|
+
function Modal({
|
|
858
|
+
open,
|
|
859
|
+
onClose,
|
|
860
|
+
title,
|
|
861
|
+
description,
|
|
862
|
+
children,
|
|
863
|
+
footer,
|
|
864
|
+
actions = [],
|
|
865
|
+
size = "medium",
|
|
866
|
+
closeOnBackdropClick = true,
|
|
867
|
+
closeButton = true,
|
|
868
|
+
closeLabel = "Close modal",
|
|
869
|
+
className,
|
|
870
|
+
...props
|
|
871
|
+
}) {
|
|
872
|
+
const titleId = useId4();
|
|
873
|
+
const panelRef = useRef3(null);
|
|
874
|
+
useEffect4(() => {
|
|
875
|
+
if (!open) return;
|
|
876
|
+
const onKeyDown = (event) => {
|
|
877
|
+
if (event.key === "Escape") onClose();
|
|
878
|
+
};
|
|
879
|
+
document.addEventListener("keydown", onKeyDown);
|
|
880
|
+
panelRef.current?.focus();
|
|
881
|
+
return () => document.removeEventListener("keydown", onKeyDown);
|
|
882
|
+
}, [onClose, open]);
|
|
883
|
+
if (!open || typeof document === "undefined") return null;
|
|
884
|
+
const hasFooter = footer || actions.length > 0;
|
|
885
|
+
return createPortal2(
|
|
886
|
+
/* @__PURE__ */ jsx12("div", { className: "fe-modal-backdrop", role: "presentation", onMouseDown: (event) => {
|
|
887
|
+
if (event.target === event.currentTarget && closeOnBackdropClick) onClose();
|
|
888
|
+
}, children: /* @__PURE__ */ jsxs11(
|
|
889
|
+
"div",
|
|
890
|
+
{
|
|
891
|
+
ref: panelRef,
|
|
892
|
+
className: ["fe-modal", `fe-modal--${size}`, className].filter(Boolean).join(" "),
|
|
893
|
+
role: "dialog",
|
|
894
|
+
"aria-modal": "true",
|
|
895
|
+
"aria-labelledby": title ? titleId : void 0,
|
|
896
|
+
"aria-label": title ? void 0 : "Modal",
|
|
897
|
+
tabIndex: -1,
|
|
898
|
+
...props,
|
|
899
|
+
children: [
|
|
900
|
+
(title || description || closeButton) && /* @__PURE__ */ jsxs11("header", { className: "fe-modal__header", children: [
|
|
901
|
+
/* @__PURE__ */ jsxs11("div", { className: "fe-modal__heading", children: [
|
|
902
|
+
title && /* @__PURE__ */ jsx12("h2", { id: titleId, children: title }),
|
|
903
|
+
description && /* @__PURE__ */ jsx12("p", { children: description })
|
|
904
|
+
] }),
|
|
905
|
+
closeButton && /* @__PURE__ */ jsx12(Button, { hierarchy: "tertiary-gray", size: "32", iconOnly: true, icon: /* @__PURE__ */ jsx12(CloseIcon, {}), "aria-label": closeLabel, onClick: onClose })
|
|
906
|
+
] }),
|
|
907
|
+
/* @__PURE__ */ jsx12("div", { className: "fe-modal__body", children }),
|
|
908
|
+
hasFooter && /* @__PURE__ */ jsxs11("footer", { className: "fe-modal__footer", children: [
|
|
909
|
+
footer && /* @__PURE__ */ jsx12("div", { className: "fe-modal__footer-content", children: footer }),
|
|
910
|
+
actions.length > 0 && /* @__PURE__ */ jsx12("div", { className: "fe-modal__actions", children: actions.map(({ label, ...action }, index) => /* @__PURE__ */ jsx12(Button, { ...action, children: label }, index)) })
|
|
911
|
+
] })
|
|
912
|
+
]
|
|
913
|
+
}
|
|
914
|
+
) }),
|
|
915
|
+
document.body
|
|
916
|
+
);
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
// packages/progress/src/index.tsx
|
|
920
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
921
|
+
function ProgressBar({ value, max = 100, label, showValue = true, size = "medium", color = "#2878f0", className, style, "aria-label": ariaLabel, ...props }) {
|
|
922
|
+
const indeterminate = value === null || value === void 0;
|
|
923
|
+
const percentage = indeterminate ? 0 : Math.min(100, Math.max(0, Number(value) / Math.max(1, max) * 100));
|
|
924
|
+
const progressStyle = {
|
|
925
|
+
"--fe-progress-value": `${percentage}%`,
|
|
926
|
+
"--fe-progress-color": color,
|
|
927
|
+
...style
|
|
928
|
+
};
|
|
929
|
+
const visibleValue = `${Math.round(percentage)}%`;
|
|
930
|
+
return /* @__PURE__ */ jsxs12("div", { className: ["fe-progress", `fe-progress--${size}`, indeterminate && "fe-progress--indeterminate", className].filter(Boolean).join(" "), style: progressStyle, ...props, children: [
|
|
931
|
+
(label || !indeterminate && showValue) && /* @__PURE__ */ jsxs12("div", { className: "fe-progress__meta", children: [
|
|
932
|
+
label && /* @__PURE__ */ jsx13("span", { className: "fe-progress__label", children: label }),
|
|
933
|
+
!indeterminate && showValue && /* @__PURE__ */ jsx13("output", { className: "fe-progress__value", children: visibleValue })
|
|
603
934
|
] }),
|
|
604
|
-
/* @__PURE__ */
|
|
935
|
+
/* @__PURE__ */ jsx13("div", { className: "fe-progress__track", role: "progressbar", "aria-label": ariaLabel ?? (typeof label === "string" ? label : "Progress"), "aria-valuemin": indeterminate ? void 0 : 0, "aria-valuemax": indeterminate ? void 0 : max, "aria-valuenow": indeterminate ? void 0 : Number(value), "aria-valuetext": indeterminate ? "Loading" : visibleValue, children: /* @__PURE__ */ jsx13("span", { className: "fe-progress__indicator" }) })
|
|
936
|
+
] });
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
// packages/chip/src/index.tsx
|
|
940
|
+
import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
941
|
+
var statuses = ["default", "info", "success", "warning", "error", "neutral", "pending", "processing"];
|
|
942
|
+
function Chip({ children, status = "default", color, variant = "subtle", dot = false, onRemove, removeLabel = "Remove", className, style, ...props }) {
|
|
943
|
+
const usesCustomColor = Boolean(color);
|
|
944
|
+
const chipStyle = {
|
|
945
|
+
...usesCustomColor ? { "--fe-chip-custom-color": color } : {},
|
|
946
|
+
...style
|
|
947
|
+
};
|
|
948
|
+
const resolvedStatus = statuses.includes(status) ? status : "default";
|
|
949
|
+
return /* @__PURE__ */ jsxs13("span", { className: ["fe-chip", `fe-chip--${variant}`, `fe-chip--${usesCustomColor ? "custom" : resolvedStatus}`, className].filter(Boolean).join(" "), style: chipStyle, ...props, children: [
|
|
950
|
+
dot && /* @__PURE__ */ jsx14("span", { className: "fe-chip__dot", "aria-hidden": "true" }),
|
|
951
|
+
/* @__PURE__ */ jsx14("span", { className: "fe-chip__content", children }),
|
|
952
|
+
onRemove && /* @__PURE__ */ jsx14(Button, { hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: /* @__PURE__ */ jsx14(CloseIcon, { size: 14 }), "aria-label": removeLabel, onClick: onRemove, className: "fe-chip__remove" })
|
|
605
953
|
] });
|
|
606
954
|
}
|
|
955
|
+
|
|
956
|
+
// packages/message/src/index.tsx
|
|
957
|
+
import { useEffect as useEffect5, useState as useState6 } from "react";
|
|
958
|
+
import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
959
|
+
var messageId = 0;
|
|
960
|
+
var entries = [];
|
|
961
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
962
|
+
var timers = /* @__PURE__ */ new Map();
|
|
963
|
+
var publish = () => listeners.forEach((listener) => listener(entries));
|
|
964
|
+
function dismiss(id) {
|
|
965
|
+
const timer = timers.get(id);
|
|
966
|
+
if (timer) window.clearTimeout(timer);
|
|
967
|
+
timers.delete(id);
|
|
968
|
+
const entry = entries.find((item) => item.id === id);
|
|
969
|
+
entries = entries.filter((item) => item.id !== id);
|
|
970
|
+
entry?.onClose?.();
|
|
971
|
+
publish();
|
|
972
|
+
}
|
|
973
|
+
function show({ duration = 4500, severity = "info", ...options }) {
|
|
974
|
+
const id = ++messageId;
|
|
975
|
+
entries = [...entries, { id, duration, severity, ...options }];
|
|
976
|
+
publish();
|
|
977
|
+
if (duration !== null) timers.set(id, window.setTimeout(() => dismiss(id), duration));
|
|
978
|
+
return id;
|
|
979
|
+
}
|
|
980
|
+
var message = {
|
|
981
|
+
show,
|
|
982
|
+
success: (content, options = {}) => show({ content, severity: "success", ...options }),
|
|
983
|
+
info: (content, options = {}) => show({ content, severity: "info", ...options }),
|
|
984
|
+
warning: (content, options = {}) => show({ content, severity: "warning", ...options }),
|
|
985
|
+
error: (content, options = {}) => show({ content, severity: "error", ...options }),
|
|
986
|
+
dismiss,
|
|
987
|
+
clear: () => [...entries].forEach((entry) => dismiss(entry.id))
|
|
988
|
+
};
|
|
989
|
+
var icons = { success: "\u2713", info: "i", warning: "!", error: "\xD7" };
|
|
990
|
+
function Message({ maxCount = 4, closeLabel = "Close notification", className, ...props }) {
|
|
991
|
+
const [visibleEntries, setVisibleEntries] = useState6(entries);
|
|
992
|
+
useEffect5(() => {
|
|
993
|
+
const listener = (nextEntries) => setVisibleEntries(nextEntries);
|
|
994
|
+
listeners.add(listener);
|
|
995
|
+
return () => {
|
|
996
|
+
listeners.delete(listener);
|
|
997
|
+
};
|
|
998
|
+
}, []);
|
|
999
|
+
return /* @__PURE__ */ jsx15("div", { className: ["fe-message-viewport", className].filter(Boolean).join(" "), "aria-live": "polite", ...props, children: visibleEntries.slice(-Math.max(1, maxCount)).map((entry) => /* @__PURE__ */ jsxs14("div", { className: `fe-message fe-message--${entry.severity ?? "info"}`, role: entry.severity === "error" ? "alert" : "status", children: [
|
|
1000
|
+
/* @__PURE__ */ jsx15("span", { className: "fe-message__icon", "aria-hidden": "true", children: icons[entry.severity ?? "info"] }),
|
|
1001
|
+
/* @__PURE__ */ jsxs14("div", { className: "fe-message__body", children: [
|
|
1002
|
+
entry.title && /* @__PURE__ */ jsx15("strong", { className: "fe-message__title", children: entry.title }),
|
|
1003
|
+
/* @__PURE__ */ jsx15("div", { className: "fe-message__content", children: entry.content })
|
|
1004
|
+
] }),
|
|
1005
|
+
entry.action && /* @__PURE__ */ jsx15("span", { className: "fe-message__action", children: entry.action }),
|
|
1006
|
+
/* @__PURE__ */ jsx15(Button, { className: "fe-message__close", hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: "\xD7", "aria-label": closeLabel, onClick: () => dismiss(entry.id) })
|
|
1007
|
+
] }, entry.id)) });
|
|
1008
|
+
}
|
|
1009
|
+
((Message2) => {
|
|
1010
|
+
Message2.show = message.show;
|
|
1011
|
+
Message2.success = message.success;
|
|
1012
|
+
Message2.info = message.info;
|
|
1013
|
+
Message2.warning = message.warning;
|
|
1014
|
+
Message2.error = message.error;
|
|
1015
|
+
Message2.dismiss = message.dismiss;
|
|
1016
|
+
Message2.clear = message.clear;
|
|
1017
|
+
})(Message || (Message = {}));
|
|
1018
|
+
|
|
1019
|
+
// packages/snackbar/src/index.tsx
|
|
1020
|
+
import { useEffect as useEffect6 } from "react";
|
|
1021
|
+
import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1022
|
+
function Snackbar({
|
|
1023
|
+
open,
|
|
1024
|
+
message: message2,
|
|
1025
|
+
autoHideDuration = 5e3,
|
|
1026
|
+
onClose,
|
|
1027
|
+
action,
|
|
1028
|
+
anchorOrigin = {},
|
|
1029
|
+
closeLabel = "Close notification",
|
|
1030
|
+
className,
|
|
1031
|
+
...props
|
|
1032
|
+
}) {
|
|
1033
|
+
const vertical = anchorOrigin.vertical ?? "bottom";
|
|
1034
|
+
const horizontal = anchorOrigin.horizontal ?? "center";
|
|
1035
|
+
useEffect6(() => {
|
|
1036
|
+
if (!open || autoHideDuration === null) return void 0;
|
|
1037
|
+
const timer = window.setTimeout(() => onClose?.("timeout"), autoHideDuration);
|
|
1038
|
+
return () => window.clearTimeout(timer);
|
|
1039
|
+
}, [open, autoHideDuration, onClose]);
|
|
1040
|
+
useEffect6(() => {
|
|
1041
|
+
if (!open) return void 0;
|
|
1042
|
+
const onKeyDown = (event) => {
|
|
1043
|
+
if (event.key === "Escape") onClose?.("escapeKeyDown");
|
|
1044
|
+
};
|
|
1045
|
+
window.addEventListener("keydown", onKeyDown);
|
|
1046
|
+
return () => window.removeEventListener("keydown", onKeyDown);
|
|
1047
|
+
}, [open, onClose]);
|
|
1048
|
+
if (!open) return null;
|
|
1049
|
+
return /* @__PURE__ */ jsx16("div", { className: ["fe-snackbar", `fe-snackbar--${vertical}`, `fe-snackbar--${horizontal}`, className].filter(Boolean).join(" "), ...props, children: /* @__PURE__ */ jsxs15("div", { className: "fe-snackbar__content", role: "status", "aria-live": "polite", children: [
|
|
1050
|
+
/* @__PURE__ */ jsx16("span", { className: "fe-snackbar__message", children: message2 }),
|
|
1051
|
+
action && /* @__PURE__ */ jsx16("span", { className: "fe-snackbar__action", children: action }),
|
|
1052
|
+
onClose && /* @__PURE__ */ jsx16(Button, { className: "fe-snackbar__close", hierarchy: "tertiary-gray", size: "24", iconOnly: true, icon: "\xD7", "aria-label": closeLabel, onClick: () => onClose("closeButton") })
|
|
1053
|
+
] }) });
|
|
1054
|
+
}
|
|
607
1055
|
export {
|
|
608
1056
|
Button,
|
|
609
1057
|
ChevronDownIcon,
|
|
1058
|
+
Chip,
|
|
610
1059
|
CloseIcon,
|
|
611
1060
|
CurrencyInput,
|
|
612
1061
|
DateTimePicker,
|
|
613
1062
|
Drawer,
|
|
614
1063
|
ExpandableSection,
|
|
1064
|
+
Loading,
|
|
1065
|
+
Message,
|
|
1066
|
+
Modal,
|
|
615
1067
|
NumberInput,
|
|
1068
|
+
Pagination,
|
|
616
1069
|
PlusIcon,
|
|
1070
|
+
ProgressBar,
|
|
617
1071
|
SearchIcon,
|
|
618
1072
|
Selection,
|
|
1073
|
+
Skeleton,
|
|
1074
|
+
SkeletonBox,
|
|
1075
|
+
SkeletonCircle,
|
|
1076
|
+
SkeletonLine,
|
|
1077
|
+
SkeletonSquare,
|
|
1078
|
+
Snackbar,
|
|
619
1079
|
Table,
|
|
620
1080
|
TableBody,
|
|
621
1081
|
TableCaption,
|
|
@@ -623,8 +1083,11 @@ export {
|
|
|
623
1083
|
TableHead,
|
|
624
1084
|
TableHeader,
|
|
625
1085
|
TableRow,
|
|
1086
|
+
TextArea,
|
|
1087
|
+
TextInput,
|
|
626
1088
|
Toggle,
|
|
627
1089
|
Tooltip,
|
|
628
1090
|
formatNumber,
|
|
629
|
-
getIconSize
|
|
1091
|
+
getIconSize,
|
|
1092
|
+
message
|
|
630
1093
|
};
|