@houssemdi2000/design-system 1.4.0 → 1.4.1

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.
@@ -2,10 +2,10 @@ import React from "react";
2
2
  import "./SmartTable.css";
3
3
  export interface TableColumn<T> {
4
4
  key: keyof T;
5
- label: string;
5
+ label: React.ReactNode;
6
6
  width?: string;
7
7
  align?: "left" | "center" | "right";
8
- render?: (value: T[keyof T], row: T) => React.ReactNode;
8
+ render?: (value: T[keyof T], row: T, index: number) => React.ReactNode;
9
9
  sortable?: boolean;
10
10
  }
11
11
  export interface SmartTableProps<T> {
@@ -17,7 +17,14 @@ export interface SmartTableProps<T> {
17
17
  striped?: boolean;
18
18
  bordered?: boolean;
19
19
  emptyText?: string;
20
+ selectedRowColor?: string;
20
21
  isDarkMode?: boolean;
21
22
  enableSorting?: boolean;
23
+ withCheckBox?: boolean;
24
+ checkBoxColor?: string;
25
+ withActions?: boolean;
26
+ actions?: React.ReactNode | ((row: T) => React.ReactNode);
27
+ /** clé unique par ligne (fortement recommandé) */
28
+ rowKey?: (row: T) => string | number;
22
29
  }
23
- export declare function SmartTable<T>({ data, columns, loading, clickable, onRowClick, striped, bordered, emptyText, isDarkMode, enableSorting, }: SmartTableProps<T>): import("react/jsx-runtime").JSX.Element;
30
+ export declare function SmartTable<T>({ data, columns, loading, clickable, onRowClick, striped, bordered, emptyText, isDarkMode, enableSorting, withCheckBox, checkBoxColor, withActions, actions, rowKey, selectedRowColor, }: SmartTableProps<T>): import("react/jsx-runtime").JSX.Element;
@@ -8,3 +8,4 @@ export declare const FullTable: () => import("react/jsx-runtime").JSX.Element;
8
8
  export declare const WithFilterBar: () => import("react/jsx-runtime").JSX.Element;
9
9
  export declare const WithPagination: () => import("react/jsx-runtime").JSX.Element;
10
10
  export declare const WithSorting: () => import("react/jsx-runtime").JSX.Element;
11
+ export declare const Custom: () => import("react/jsx-runtime").JSX.Element;
@@ -36,7 +36,6 @@ export interface TableFilterBarProps {
36
36
  onReset?: () => void;
37
37
  isDarkMode?: boolean;
38
38
  gap?: number;
39
- collapsible?: boolean;
40
39
  resetButton?: React.ReactNode;
41
40
  }
42
41
  export declare const TableFilterBar: React.FC<TableFilterBarProps>;
@@ -5,3 +5,4 @@ declare const _default: {
5
5
  };
6
6
  export default _default;
7
7
  export declare const Default: () => import("react/jsx-runtime").JSX.Element;
8
+ export declare const NoBg: () => import("react/jsx-runtime").JSX.Element;
package/dist/index.esm.js CHANGED
@@ -420,10 +420,11 @@ const ThemeProvider = ({ children, }) => {
420
420
  }, children: children }) }));
421
421
  };
422
422
 
423
- var css_248z$e = ".st-wrapper{font-family:sans-serif;margin-top:8px;overflow-x:auto;width:100%}.st-wrapper.bordered{border:1px solid var(--color-border,#ddd);border-radius:6px}.st-table{border-collapse:collapse;font-size:14px;width:100%}.st-table th{background:var(--color-table-header,#f4f4f4);border-bottom:2px solid var(--color-border,#ddd);color:var(--color-table-header-text,#333);font-weight:600;padding:10px 8px;text-align:left}.st-sortable{cursor:pointer;user-select:none}.st-th-content{align-items:center;display:flex;gap:6px}.st-sort-icons{display:flex;flex-direction:column;font-size:10px;line-height:10px;opacity:.4}.st-sort-icons span.active{font-weight:700;opacity:1}.st-table td{border-bottom:1px solid var(--color-border,#eee);padding:10px 8px}.st-table tr.even{background:var(--color-row-even,#fff);color:var(--color-row-even-text,#333)}.st-table tr.odd{background:var(--color-row-odd,#f9f9f9);color:var(--color-row-odd-text,#333)}.st-table tr.clickable{cursor:pointer;transition:background .2s ease}.st-table tr.clickable:hover{background:var(--color-row-hover,#eaf3ff)}.st-empty,.st-loading{color:var(--color-text-light,#777);font-style:italic;padding:20px;text-align:center!important}@media (max-width:600px){.st-table td,.st-table th{padding:8px 6px}}";
423
+ var css_248z$e = ".st-wrapper{font-family:sans-serif;margin-top:8px;overflow-x:auto;width:100%}.st-wrapper.bordered{border:1px solid var(--color-border,#ddd);border-radius:6px}.st-table{border-collapse:collapse;font-size:14px;width:100%}.st-table th{background:var(--color-table-header,#f4f4f4);border-bottom:2px solid var(--color-border,#ddd);color:var(--color-table-header-text,#333);font-weight:600;padding:10px 8px;text-align:left}.st-sortable{cursor:pointer;user-select:none}.st-th-content{align-items:center;display:flex;gap:6px}.st-sort-icons{display:flex;flex-direction:column;font-size:10px;line-height:10px;opacity:.4}.st-sort-icons span.active{font-weight:700;opacity:1}.st-table td{border-bottom:1px solid var(--color-border,#eee);padding:10px 8px}.st-table tr.even{background:var(--color-row-even,#fff);color:var(--color-row-even-text,#333)}.st-table tr.odd{background:var(--color-row-odd,#f9f9f9);color:var(--color-row-odd-text,#333)}.st-table tr.clickable,.st-table tr.clickable.dark{cursor:pointer;transition:background .2s ease}.st-table tr.clickable:hover{background:var(--color-row-hover,#eaf3ff);color:var(--color-row-hover-text,#333)}.st-empty,.st-loading{color:var(--color-text-light,#777);font-style:italic;padding:20px;text-align:center!important}@media (max-width:600px){.st-table td,.st-table th{padding:8px 6px}}";
424
424
  styleInject(css_248z$e);
425
425
 
426
- function SmartTable({ data, columns, loading = false, clickable = false, onRowClick, striped = true, bordered = false, emptyText = "No data available", isDarkMode = false, enableSorting = false, }) {
426
+ function SmartTable({ data, columns, loading = false, clickable = false, onRowClick, striped = true, bordered = false, emptyText = "No data available", isDarkMode = false, enableSorting = false, withCheckBox = false, checkBoxColor, withActions = false, actions, rowKey, selectedRowColor = isDarkMode ? tco.background : tco.backgroundDark, }) {
427
+ /* ---------------- sorting ---------------- */
427
428
  const [sortKey, setSortKey] = useState(null);
428
429
  const [sortDirection, setSortDirection] = useState(null);
429
430
  const handleSort = (key) => {
@@ -432,16 +433,14 @@ function SmartTable({ data, columns, loading = false, clickable = false, onRowCl
432
433
  setSortDirection("asc");
433
434
  return;
434
435
  }
435
- if (sortDirection === "asc") {
436
+ if (sortDirection === "asc")
436
437
  setSortDirection("desc");
437
- }
438
438
  else if (sortDirection === "desc") {
439
439
  setSortKey(null);
440
440
  setSortDirection(null);
441
441
  }
442
- else {
442
+ else
443
443
  setSortDirection("asc");
444
- }
445
444
  };
446
445
  const sortedData = useMemo(() => {
447
446
  if (!enableSorting || !sortKey || !sortDirection)
@@ -461,28 +460,87 @@ function SmartTable({ data, columns, loading = false, clickable = false, onRowCl
461
460
  : String(bVal).localeCompare(String(aVal));
462
461
  });
463
462
  }, [data, enableSorting, sortKey, sortDirection]);
464
- return (jsx("div", { className: `st-wrapper ${bordered ? "bordered" : ""}`, children: jsxs("table", { className: "st-table", children: [jsx("thead", { children: jsx("tr", { children: columns.map((col) => {
465
- var _a;
466
- return (jsx("th", { className: enableSorting && col.sortable ? "st-sortable" : "", onClick: () => enableSorting && col.sortable && handleSort(col.key), style: {
467
- width: col.width,
468
- textAlign: (_a = col.align) !== null && _a !== void 0 ? _a : "left",
469
- ["--color-table-header"]: isDarkMode
470
- ? tco.backgroundDark3
471
- : "",
472
- ["--color-table-header-text"]: isDarkMode
473
- ? tco.textDark
474
- : "",
475
- }, children: jsxs("div", { className: "st-th-content", children: [jsx("span", { children: col.label }), (enableSorting && col.sortable && col.sortable === true) ? (jsxs("span", { className: "st-sort-icons", children: [jsx("span", { className: sortKey === col.key && sortDirection === "asc"
476
- ? "active"
477
- : "", children: "\u25B2" }), jsx("span", { className: sortKey === col.key && sortDirection === "desc"
478
- ? "active"
479
- : "", children: "\u25BC" })] })) : null] }) }, String(col.key)));
480
- }) }) }), jsx("tbody", { children: loading ? (jsx("tr", { children: jsx("td", { colSpan: columns.length, className: "st-loading", children: "Loading..." }) })) : sortedData.length === 0 ? (jsx("tr", { children: jsx("td", { colSpan: columns.length, className: "st-empty", children: emptyText }) })) : (sortedData.map((row, index) => (jsx("tr", { style: {
463
+ /* ---------------- checkbox logic ---------------- */
464
+ const [selectedRows, setSelectedRows] = useState(new Set());
465
+ const getRowKey = (row, index) => (rowKey ? rowKey(row) : index);
466
+ const isSelected = (key) => selectedRows.has(key);
467
+ const toggleRow = (key) => {
468
+ setSelectedRows((prev) => {
469
+ const next = new Set(prev);
470
+ next.has(key) ? next.delete(key) : next.add(key);
471
+ return next;
472
+ });
473
+ };
474
+ const toggleAll = () => {
475
+ if (selectedRows.size === sortedData.length) {
476
+ setSelectedRows(new Set());
477
+ }
478
+ else {
479
+ setSelectedRows(new Set(sortedData.map((row, i) => getRowKey(row, i))));
480
+ }
481
+ };
482
+ /* ---------------- computed columns ---------------- */
483
+ const computedColumns = useMemo(() => {
484
+ let cols = columns;
485
+ /* checkbox column */
486
+ if (withCheckBox) {
487
+ cols = [
488
+ {
489
+ key: "__checkbox__",
490
+ label: (jsx("input", { type: "checkbox", checked: sortedData.length > 0 && selectedRows.size === sortedData.length, style: { accentColor: checkBoxColor }, onChange: toggleAll })),
491
+ width: "40px",
492
+ align: "center",
493
+ sortable: false,
494
+ render: (_, row, index) => {
495
+ const key = getRowKey(row, index);
496
+ return (jsx("input", { type: "checkbox", checked: isSelected(key), onClick: (e) => e.stopPropagation(), onChange: () => toggleRow(key), style: { accentColor: checkBoxColor, borderRadius: "100%" } }));
497
+ },
498
+ },
499
+ ...cols,
500
+ ];
501
+ }
502
+ /* actions column */
503
+ if (withActions) {
504
+ cols = [
505
+ ...cols,
506
+ {
507
+ key: "__actions__",
508
+ label: "Actions",
509
+ align: "center",
510
+ sortable: false,
511
+ render: (_, row) => (jsx("div", { className: "st-actions", onClick: (e) => e.stopPropagation(), children: typeof actions === "function" ? actions(row) : actions })),
512
+ },
513
+ ];
514
+ }
515
+ return cols;
516
+ }, [withCheckBox, withActions, columns, selectedRows, sortedData, actions]);
517
+ /* ---------------- row click ---------------- */
518
+ const handleRowClick = (row, index) => {
519
+ if (withCheckBox) {
520
+ toggleRow(getRowKey(row, index));
521
+ }
522
+ onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(row);
523
+ };
524
+ /* ---------------- render ---------------- */
525
+ return (jsx("div", { className: `st-wrapper ${bordered ? "bordered" : ""}`, children: jsxs("table", { className: "st-table", children: [jsx("thead", { children: jsx("tr", { children: computedColumns.map((col) => (jsx("th", { className: enableSorting && col.sortable ? "st-sortable" : "", onClick: () => enableSorting && col.sortable && handleSort(col.key), style: {
526
+ width: col.width,
527
+ textAlign: "left",
528
+ ["--color-table-header"]: isDarkMode
529
+ ? tco.backgroundDark3
530
+ : "",
531
+ ["--color-table-header-text"]: isDarkMode
532
+ ? tco.textDark
533
+ : "",
534
+ }, children: jsxs("div", { className: "st-th-content", children: [col.label, enableSorting && col.sortable && (jsxs("span", { className: "st-sort-icons", children: [jsx("span", { className: sortKey === col.key && sortDirection === "asc"
535
+ ? "active"
536
+ : "", children: "\u25B2" }), jsx("span", { className: sortKey === col.key && sortDirection === "desc"
537
+ ? "active"
538
+ : "", children: "\u25BC" })] }))] }) }, String(col.key)))) }) }), jsx("tbody", { children: loading ? (jsx("tr", { children: jsx("td", { colSpan: computedColumns.length, className: "st-loading", children: "Loading..." }) })) : sortedData.length === 0 ? (jsx("tr", { children: jsx("td", { colSpan: computedColumns.length, className: "st-empty", children: emptyText }) })) : (sortedData.map((row, index) => (jsx("tr", { style: {
481
539
  ["--color-row-even"]: isDarkMode
482
540
  ? tco.backgroundDark
483
541
  : "",
484
542
  ["--color-row-odd"]: isDarkMode
485
- ? tco.backgroundDark2
543
+ ? tco.backgroundDark
486
544
  : "",
487
545
  ["--color-row-even-text"]: isDarkMode
488
546
  ? tco.textDark
@@ -490,14 +548,16 @@ function SmartTable({ data, columns, loading = false, clickable = false, onRowCl
490
548
  ["--color-row-odd-text"]: isDarkMode
491
549
  ? tco.textDark
492
550
  : "",
493
- }, className: `${striped ? (index % 2 === 0 ? "even" : "odd") : ""} ${clickable ? "clickable" : ""}`, onClick: () => clickable && (onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(row)), children: columns.map((col) => {
494
- var _a;
551
+ ["--color-row-hover"]: isDarkMode
552
+ ? selectedRowColor
553
+ : selectedRowColor,
554
+ ["--color-row-hover-text"]: !isDarkMode && tco.background,
555
+ }, className: `${striped ? (index % 2 === 0 ? "even" : "odd") : ""} ${clickable ? (isDarkMode ? "clickable dark" : "clickable") : ""}`, onClick: () => clickable && handleRowClick(row, index), children: computedColumns.map((col) => {
495
556
  const value = row[col.key];
496
- const renderValue = col.render
497
- ? col.render(value, row)
498
- : value;
499
- return (jsx("td", { style: { textAlign: (_a = col.align) !== null && _a !== void 0 ? _a : "left" }, children: renderValue }, String(col.key)));
500
- }) }, index)))) })] }) }));
557
+ return (jsx("td", { children: col.render
558
+ ? col.render(value, row, index)
559
+ : value }, String(col.key)));
560
+ }) }, getRowKey(row, index))))) })] }) }));
501
561
  }
502
562
 
503
563
  var css_248z$d = ".pagination{align-items:center;display:flex;gap:6px;margin-top:16px}.pagination button{background:var(--pg-bg);border:1px solid var(--pg-border);border-radius:6px;color:var(--pg-text);cursor:pointer;font-size:14px;height:32px;min-width:32px;transition:all .2s ease}.pagination button:hover:not(:disabled){background:rgba(0,123,255,.1)}.pagination button.active{background:var(--pg-active);border-color:var(--pg-active);color:#fff}.pagination button:disabled{cursor:not-allowed;opacity:.5}";
@@ -524,38 +584,37 @@ const Pagination = ({ page, pageSize, total, onPageChange, isDarkMode = false, c
524
584
  }), jsx("button", { disabled: page === totalPages, onClick: () => goToPage(page + 1), children: "\u203A" })] }));
525
585
  };
526
586
 
527
- var css_248z$c = ".tfb-container{align-items:\"flex-start\";background:var(--tf-bg);border:1px solid var(--tf-border);border-radius:8px;display:flex;font-family:sans-serif;justify-content:space-between;margin-bottom:12px;padding:12px}.tfb-wrapper{display:flex;flex-wrap:wrap;width:70%}.tfb-item{color:var(--tf-text);display:flex;flex-direction:column;font-size:13px;gap:4px}.tfb-item input,.tfb-item select{border:1px solid var(--tf-border);border-radius:6px;font-size:13px;padding:6px 8px}.tfb-radio-group{display:flex;gap:8px}.tfb-reset{align-self:flex-end;background:#e63946;border:none;border-radius:6px;color:#fff;cursor:pointer;padding:6px 12px}.tfp-wrapper-toggle{align-items:flex-end;display:flex;justify-content:flex-end;width:30%}.tfp-wrapper-toggle button{background:transparent;border:1px solid var(--tf-border);border-radius:6px;cursor:pointer;font-size:14px;padding:4px 8px}.tfp-wrapper-toggle button:hover{opacity:.8}.tfp-wrapper-toggle-open{display:flex;justify-content:flex-end;margin-bottom:10;width:100%}.tfp-wrapper-toggle-open button{background:transparent;border:1px solid var(--tf-border);border-radius:6px;cursor:pointer;font-size:14px;padding:4px 8px}";
587
+ var css_248z$c = "*{box-sizing:border-box}.tfb-container{align-items:flex-start;background:var(--tf-bg);border-radius:8px;display:flex;font-family:sans-serif;justify-content:space-between;margin-bottom:12px;padding:12px;position:relative}.tfb-wrapper{display:flex;flex-wrap:wrap;gap:16px;padding-right:80px;width:70%}.tfb-item{color:var(--tf-text);display:flex;flex-direction:column;font-size:13px;gap:4px}.tfb-item input,.tfb-item select{background:transparent;border:1px solid var(--tf-border);border-radius:6px;color:var(--tf-text);font-size:13px;padding:6px 8px}.tfb-item input:focus,.tfb-item select:focus{border-color:#4f46e5;outline:none}.tfb-item input[type=checkbox]{appearance:none;-webkit-appearance:none;border:2px solid var(--tf-border);border-radius:50%;cursor:pointer;height:16px;position:relative;width:16px}.tfb-item input[type=checkbox]:checked{background-color:#4f46e5;border-color:#4f46e5}.tfb-item input[type=checkbox]:checked:after{background:#fff;border-radius:50%;content:\"\";height:6px;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:6px}.tfb-radio-group{display:flex;gap:8px}.tfb-radio-group label{align-items:center;cursor:pointer;display:flex;font-size:13px;gap:4px}.tfb-reset{background:#e63946;border:none;border-radius:6px;color:#fff;cursor:pointer;font-size:13px;padding:6px 12px;position:absolute;right:12px;top:12px}.tfb-reset:hover{opacity:.9}.tfp-wrapper-toggle{align-items:flex-end;display:flex;justify-content:flex-end;width:30%}.tfp-wrapper-toggle button{background:transparent;border:1px solid var(--tf-border);border-radius:6px;color:var(--tf-text);cursor:pointer;font-size:14px;padding:4px 8px}.tfp-wrapper-toggle button:hover{opacity:.8}.tfp-wrapper-toggle-open{display:flex;justify-content:flex-end;margin-bottom:10px;width:100%}.tfp-wrapper-toggle-open button{background:transparent;border:1px solid var(--tf-border);border-radius:6px;color:var(--tf-text);cursor:pointer;font-size:14px;padding:4px 8px}";
528
588
  styleInject(css_248z$c);
529
589
 
530
- const TableFilterBar = ({ filters, values, onChange, onReset, resetButton, isDarkMode = false, position = "left", gap = 16, collapsible = true, }) => {
531
- const [isOpen, setIsOpen] = useState(true);
532
- return (jsxs(Fragment, { children: [isOpen && (jsxs("div", { className: "tfb-container", style: {
533
- ["--tf-bg"]: isDarkMode ? tco.backgroundDark2 : "#fff",
534
- ["--tf-border"]: isDarkMode ? tco.borderDark : "#ddd",
535
- ["--tf-text"]: isDarkMode ? tco.textDark : "#333",
536
- justifyContent: position === "left"
537
- ? "flex-start"
538
- : position === "center"
539
- ? "center"
540
- : "flex-end",
541
- gap: gap,
542
- }, children: [jsxs("div", { className: "tfb-wrapper", style: {
543
- justifyContent: position === "left"
544
- ? "flex-start"
545
- : position === "center"
546
- ? "center"
547
- : "flex-end",
548
- gap: gap,
549
- }, children: [filters.map((filter) => {
550
- var _a, _b;
551
- return (jsxs("div", { style: {
552
- width: filter.width === "large"
553
- ? "50%"
554
- : filter.width === "medium"
555
- ? "30%"
556
- : "",
557
- }, className: "tfb-item", children: [jsx("label", { children: filter.label }), filter.type === "text" && (jsx("input", { type: "text", placeholder: filter.placeholder, value: (_a = values[filter.key]) !== null && _a !== void 0 ? _a : "", onChange: (e) => onChange(filter.key, e.target.value) })), filter.type === "select" && (jsxs("select", { value: (_b = values[filter.key]) !== null && _b !== void 0 ? _b : "", onChange: (e) => onChange(filter.key, e.target.value), children: [jsx("option", { value: "", children: "All" }), filter.options.map((opt) => (jsx("option", { value: opt.value, children: opt.label }, opt.value)))] })), filter.type === "checkbox" && (jsx("input", { type: "checkbox", checked: !!values[filter.key], onChange: (e) => onChange(filter.key, e.target.checked) })), filter.type === "radio" && (jsx("div", { className: "tfb-radio-group", children: filter.options.map((opt) => (jsxs("label", { children: [jsx("input", { type: "radio", name: filter.key, value: opt.value, checked: values[filter.key] === opt.value, onChange: () => onChange(filter.key, opt.value) }), opt.label] }, opt.value))) }))] }, filter.key));
558
- }), resetButton ? resetButton : (jsx("button", { className: "tfb-reset", onClick: onReset, children: "Reset" }))] }), jsx("div", { className: "tfp-wrapper-toggle", children: collapsible && (jsx("button", { onClick: () => setIsOpen(false), title: "Hide filters", children: "✕" })) })] })), collapsible && !isOpen && (jsx("div", { className: "tfp-wrapper-toggle-open", children: jsx("button", { onClick: () => setIsOpen(true), title: "Show filters", children: "🔍" }) }))] }));
590
+ const TableFilterBar = ({ filters, values, onChange, onReset, resetButton, isDarkMode = false, position = "left", gap = 16, }) => {
591
+ return (jsx(Fragment, { children: jsxs("div", { className: "tfb-container", style: {
592
+ ["--tf-bg"]: isDarkMode ? tco.backgroundDark : "#fff",
593
+ ["--tf-border"]: isDarkMode ? tco.borderDark : "#ddd",
594
+ ["--tf-text"]: isDarkMode ? tco.textDark : "#333",
595
+ justifyContent: position === "left"
596
+ ? "flex-start"
597
+ : position === "center"
598
+ ? "center"
599
+ : "flex-end",
600
+ gap: gap,
601
+ }, children: [jsx("div", { className: "tfb-wrapper", style: {
602
+ justifyContent: position === "left"
603
+ ? "flex-start"
604
+ : position === "center"
605
+ ? "center"
606
+ : "flex-end",
607
+ gap: gap,
608
+ }, children: filters.map((filter) => {
609
+ var _a, _b;
610
+ return (jsxs("div", { style: {
611
+ width: filter.width === "large"
612
+ ? "50%"
613
+ : filter.width === "medium"
614
+ ? "30%"
615
+ : "",
616
+ }, className: "tfb-item", children: [jsx("label", { children: filter.label }), filter.type === "text" && (jsx("input", { type: "text", placeholder: filter.placeholder, value: (_a = values[filter.key]) !== null && _a !== void 0 ? _a : "", onChange: (e) => onChange(filter.key, e.target.value) })), filter.type === "select" && (jsxs("select", { value: (_b = values[filter.key]) !== null && _b !== void 0 ? _b : "", onChange: (e) => onChange(filter.key, e.target.value), children: [jsx("option", { value: "", children: "All" }), filter.options.map((opt) => (jsx("option", { value: opt.value, children: opt.label }, opt.value)))] })), filter.type === "checkbox" && (jsx("input", { type: "checkbox", checked: !!values[filter.key], onChange: (e) => onChange(filter.key, e.target.checked) })), filter.type === "radio" && (jsx("div", { className: "tfb-radio-group", children: filter.options.map((opt) => (jsxs("label", { children: [jsx("input", { type: "radio", name: filter.key, value: opt.value, checked: values[filter.key] === opt.value, onChange: () => onChange(filter.key, opt.value) }), opt.label] }, opt.value))) }))] }, filter.key));
617
+ }) }), resetButton ? (resetButton) : (jsx("button", { className: "tfb-reset", onClick: onReset, children: "Reset" }))] }) }));
559
618
  };
560
619
 
561
620
  var css_248z$b = ".txt{font-family:system-ui,-apple-system,sans-serif;margin:0}.txt-title{font-size:28px;line-height:1.2}.txt-subtitle{font-size:20px;opacity:.9}.txt-body{font-size:14px}.txt-caption{font-size:12px;opacity:.7}.txt-overline{font-size:11px;letter-spacing:.08em;text-transform:uppercase}.txt-muted{opacity:.6}.txt-error{color:#e53935}.txt-success{color:#2e7d32}.txt-regular{font-weight:400}.txt-medium{font-weight:500}.txt-bold{font-weight:700}.txt-left{text-align:left}.txt-center{text-align:center}.txt-right{text-align:right}";
@@ -650,11 +709,11 @@ const Footer = ({ left, center, right, sections = [], isDarkMode = false, height
650
709
  }) }))] }));
651
710
  };
652
711
 
653
- var css_248z$5 = ".layout{display:flex;flex-direction:column;font-family:sans-serif;min-height:100vh}.layout.dark{background:#0f172a;color:#fff}.layout-main{display:flex;flex:1;overflow:hidden}.layout-content{flex:1;overflow-y:auto;padding:16px}";
712
+ var css_248z$5 = ".layout{display:flex;flex-direction:column;font-family:sans-serif;min-height:100vh}.layout.dark{background:#0f172a;color:#fff}.layout-main{display:flex;flex:1;overflow:hidden}.layout-sidebar{display:flex;flex-shrink:0}.layout-content{flex:1;margin-left:50px;overflow-y:auto;padding:16px}";
654
713
  styleInject(css_248z$5);
655
714
 
656
- const Layout = ({ header, sidebar, footer, children, withSidebar = true, withHeader = true, withFooter = true, sidebarWidth = 260, isDarkMode = false }) => {
657
- return (jsxs("div", { className: `layout ${isDarkMode ? "dark" : ""}`, children: [withHeader && header, jsxs("div", { className: "layout-main", children: [withSidebar && sidebar && (jsx("aside", { className: "layout-sidebar", style: { width: sidebarWidth }, children: sidebar })), jsx("main", { className: "layout-content", children: children })] }), withFooter && footer] }));
715
+ const Layout = ({ header, sidebar, footer, children, withSidebar = true, withHeader = true, withFooter = true, sidebarWidth = 260, isDarkMode = false, }) => {
716
+ return (jsxs("div", { className: `layout ${isDarkMode ? "dark" : ""}`, children: [withHeader && header, jsxs("div", { className: "layout-main", children: [withSidebar && sidebar && (jsx("aside", { className: "layout-sidebar", children: sidebar })), jsx("main", { className: "layout-content", children: children })] }), withFooter && footer] }));
658
717
  };
659
718
 
660
719
  var css_248z$4 = ".dd-wrapper{display:flex;font-family:sans-serif}.dd-wrapper.vertical{flex-direction:column}.dd-wrapper.horizontal{flex-direction:row;overflow-x:auto}.dd-item{cursor:grab;transition:transform .2s ease,opacity .2s ease;user-select:none}.dd-item.dragging{opacity:.5;transform:scale(.98)}.dd-wrapper.dark .dd-item{background:#0f172a;color:#fff}";