@rufous/ui 0.2.106 → 0.3.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.
- package/dist/main.cjs +88 -43
- package/dist/main.css +44 -2
- package/dist/main.d.cts +40 -1
- package/dist/main.d.ts +40 -1
- package/dist/main.js +88 -43
- package/package.json +2 -2
package/dist/main.cjs
CHANGED
|
@@ -2252,10 +2252,12 @@ function AutocompleteInner(props, _ref) {
|
|
|
2252
2252
|
className = "",
|
|
2253
2253
|
style,
|
|
2254
2254
|
sx,
|
|
2255
|
+
open: openProp,
|
|
2255
2256
|
onOpen,
|
|
2256
2257
|
onClose
|
|
2257
2258
|
} = props;
|
|
2258
|
-
const [
|
|
2259
|
+
const [internalOpen, setInternalOpen] = (0, import_react19.useState)(false);
|
|
2260
|
+
const open = openProp !== void 0 ? openProp : internalOpen;
|
|
2259
2261
|
const [inputStr, setInputStr] = (0, import_react19.useState)("");
|
|
2260
2262
|
const [filterQuery, setFilterQuery] = (0, import_react19.useState)("");
|
|
2261
2263
|
const [focusedIdx, setFocusedIdx] = (0, import_react19.useState)(-1);
|
|
@@ -2341,20 +2343,20 @@ function AutocompleteInner(props, _ref) {
|
|
|
2341
2343
|
const openPopup = (0, import_react19.useCallback)(() => {
|
|
2342
2344
|
if (disabled) return;
|
|
2343
2345
|
calcPopupStyle();
|
|
2344
|
-
|
|
2346
|
+
if (openProp === void 0) setInternalOpen(true);
|
|
2345
2347
|
setFocusedIdx(-1);
|
|
2346
2348
|
setFilterQuery("");
|
|
2347
2349
|
onOpen?.();
|
|
2348
|
-
}, [disabled, calcPopupStyle, onOpen]);
|
|
2350
|
+
}, [disabled, calcPopupStyle, onOpen, openProp]);
|
|
2349
2351
|
const closePopup = (0, import_react19.useCallback)((justSelected = false) => {
|
|
2350
|
-
|
|
2352
|
+
if (openProp === void 0) setInternalOpen(false);
|
|
2351
2353
|
setFocusedIdx(-1);
|
|
2352
2354
|
onClose?.();
|
|
2353
2355
|
if (!justSelected && !freeSolo && !multiple && value == null) {
|
|
2354
2356
|
setInputStr("");
|
|
2355
2357
|
onInputChange?.(null, "");
|
|
2356
2358
|
}
|
|
2357
|
-
}, [freeSolo, multiple, value, onInputChange, onClose]);
|
|
2359
|
+
}, [openProp, freeSolo, multiple, value, onInputChange, onClose]);
|
|
2358
2360
|
(0, import_react19.useEffect)(() => {
|
|
2359
2361
|
if (!open) return;
|
|
2360
2362
|
const handleOutside = (e) => {
|
|
@@ -4439,6 +4441,12 @@ function DataGrid({
|
|
|
4439
4441
|
columns: initialColumnsProp,
|
|
4440
4442
|
data,
|
|
4441
4443
|
actions,
|
|
4444
|
+
loading = false,
|
|
4445
|
+
pagination = true,
|
|
4446
|
+
paginationMode = "client",
|
|
4447
|
+
rowCount,
|
|
4448
|
+
paginationModel,
|
|
4449
|
+
onPaginationModelChange,
|
|
4442
4450
|
pageSize: initialPageSize = 10,
|
|
4443
4451
|
pageSizeOptions = [5, 10, 25, 50],
|
|
4444
4452
|
title,
|
|
@@ -4479,6 +4487,23 @@ function DataGrid({
|
|
|
4479
4487
|
const [sortDirection, setSortDirection] = (0, import_react23.useState)(null);
|
|
4480
4488
|
const [filterText, setFilterText] = (0, import_react23.useState)("");
|
|
4481
4489
|
const [currentPage, setCurrentPage] = (0, import_react23.useState)(1);
|
|
4490
|
+
const activePage = paginationModel ? paginationModel.page + 1 : currentPage;
|
|
4491
|
+
const activePageSize = paginationModel ? paginationModel.pageSize : pageSize;
|
|
4492
|
+
const handlePageChange = (newPage) => {
|
|
4493
|
+
if (onPaginationModelChange) {
|
|
4494
|
+
onPaginationModelChange({ page: newPage - 1, pageSize: activePageSize });
|
|
4495
|
+
} else {
|
|
4496
|
+
setCurrentPage(newPage);
|
|
4497
|
+
}
|
|
4498
|
+
};
|
|
4499
|
+
const handlePageSizeChange = (newSize) => {
|
|
4500
|
+
if (onPaginationModelChange) {
|
|
4501
|
+
onPaginationModelChange({ page: 0, pageSize: newSize });
|
|
4502
|
+
} else {
|
|
4503
|
+
setPageSize(newSize);
|
|
4504
|
+
setCurrentPage(1);
|
|
4505
|
+
}
|
|
4506
|
+
};
|
|
4482
4507
|
const [resizingColumn, setResizingColumn] = (0, import_react23.useState)(null);
|
|
4483
4508
|
const [startX, setStartX] = (0, import_react23.useState)(0);
|
|
4484
4509
|
const [startWidth, setStartWidth] = (0, import_react23.useState)(0);
|
|
@@ -4711,11 +4736,14 @@ function DataGrid({
|
|
|
4711
4736
|
return 0;
|
|
4712
4737
|
});
|
|
4713
4738
|
}, [filteredData, sortField, sortDirection, resolvedColumns]);
|
|
4714
|
-
const
|
|
4739
|
+
const isServer = paginationMode === "server";
|
|
4740
|
+
const totalRows = isServer ? rowCount ?? data.length : filteredData.length;
|
|
4741
|
+
const totalPages = Math.max(1, Math.ceil(totalRows / activePageSize));
|
|
4715
4742
|
const paginatedData = (0, import_react23.useMemo)(() => {
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
4743
|
+
if (isServer) return data;
|
|
4744
|
+
const start = (activePage - 1) * activePageSize;
|
|
4745
|
+
return sortedData.slice(start, start + activePageSize);
|
|
4746
|
+
}, [isServer, data, sortedData, activePage, activePageSize]);
|
|
4719
4747
|
const handleExport = () => {
|
|
4720
4748
|
const exportableCols = resolvedColumns.filter((c) => !c.hidden && c.isExportable !== false);
|
|
4721
4749
|
const headers = exportableCols.map((c) => c.headerName).join(",");
|
|
@@ -4810,7 +4838,7 @@ function DataGrid({
|
|
|
4810
4838
|
onClick: () => setShowManageColumns(true)
|
|
4811
4839
|
},
|
|
4812
4840
|
/* @__PURE__ */ import_react23.default.createElement(import_lucide_react2.Columns, { size: 16 })
|
|
4813
|
-
)), /* @__PURE__ */ import_react23.default.createElement("button", { className: "dg-action-btn", onClick: handleExport }, /* @__PURE__ */ import_react23.default.createElement(import_lucide_react2.Download, { size: 14 }), " Export CSV"), headerActions && /* @__PURE__ */ import_react23.default.createElement("div", { className: `dg-header-slot ${alignClass(headerActions.align)}` }, headerActions.content))), /* @__PURE__ */ import_react23.default.createElement("div", { className: `dg-toolbar ${alignClass(toolbarContent?.align)}` }, toolbarContent?.content || ""), /* @__PURE__ */ import_react23.default.createElement("div", { className: `dg-table-wrap${paginatedData.length === 0 ? " dg-table-wrap--empty" : ""}` }, /* @__PURE__ */ import_react23.default.createElement("table", { className: "dg-table" }, /* @__PURE__ */ import_react23.default.createElement("thead", null, /* @__PURE__ */ import_react23.default.createElement("tr", null, visibleColumns.map((col, idx) => {
|
|
4841
|
+
)), /* @__PURE__ */ import_react23.default.createElement("button", { className: "dg-action-btn", onClick: handleExport }, /* @__PURE__ */ import_react23.default.createElement(import_lucide_react2.Download, { size: 14 }), " Export CSV"), headerActions && /* @__PURE__ */ import_react23.default.createElement("div", { className: `dg-header-slot ${alignClass(headerActions.align)}` }, headerActions.content))), /* @__PURE__ */ import_react23.default.createElement("div", { className: `dg-toolbar ${alignClass(toolbarContent?.align)}` }, toolbarContent?.content || ""), /* @__PURE__ */ import_react23.default.createElement("div", { className: `dg-table-wrap${paginatedData.length === 0 && !loading ? " dg-table-wrap--empty" : ""}` }, loading && /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-loading-overlay" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-loading-spinner" })), /* @__PURE__ */ import_react23.default.createElement("table", { className: "dg-table" }, /* @__PURE__ */ import_react23.default.createElement("thead", null, /* @__PURE__ */ import_react23.default.createElement("tr", null, visibleColumns.map((col, idx) => {
|
|
4814
4842
|
const colField = String(col.field);
|
|
4815
4843
|
const width = columnWidths[colField] || 200;
|
|
4816
4844
|
const leftOffset = getLeftOffset(col, idx);
|
|
@@ -4924,17 +4952,14 @@ function DataGrid({
|
|
|
4924
4952
|
},
|
|
4925
4953
|
action.icon
|
|
4926
4954
|
)))));
|
|
4927
|
-
})()))))), paginatedData.length === 0 && /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-empty-state" }, /* @__PURE__ */ import_react23.default.createElement("svg", { className: "dg-empty-icon", viewBox: "0 0 200 160", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ import_react23.default.createElement("rect", { x: "20", y: "30", width: "160", height: "100", rx: "8", fill: "var(--hover-color)", stroke: "var(--border-color)", strokeWidth: "1.5" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "20", y: "30", width: "160", height: "28", rx: "8", fill: "var(--border-color)", opacity: "0.5" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "20", y: "50", width: "160", height: "8", rx: "0", fill: "var(--border-color)", opacity: "0.5" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "72", y1: "30", x2: "72", y2: "130", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "128", y1: "30", x2: "128", y2: "130", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "20", y1: "78", x2: "180", y2: "78", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "20", y1: "104", x2: "180", y2: "104", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "32", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "84", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "140", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "32", y: "113", width: "20", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "84", y: "113", width: "32", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "140", y: "113", width: "20", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ import_react23.default.createElement("circle", { cx: "148", cy: "108", r: "26", fill: "var(--surface-color)", stroke: "var(--border-color)", strokeWidth: "1.5" }), /* @__PURE__ */ import_react23.default.createElement("circle", { cx: "145", cy: "105", r: "10", stroke: "var(--text-secondary)", strokeWidth: "2.5", opacity: "0.5" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "152", y1: "113", x2: "161", y2: "122", stroke: "var(--text-secondary)", strokeWidth: "2.5", strokeLinecap: "round", opacity: "0.5" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "141", y1: "101", x2: "149", y2: "109", stroke: "var(--text-secondary)", strokeWidth: "2", strokeLinecap: "round", opacity: "0.5" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "149", y1: "101", x2: "141", y2: "109", stroke: "var(--text-secondary)", strokeWidth: "2", strokeLinecap: "round", opacity: "0.5" })), /* @__PURE__ */ import_react23.default.createElement("p", { className: "dg-empty-title" }, "No data found"), /* @__PURE__ */ import_react23.default.createElement("p", { className: "dg-empty-subtitle" }, filterText || hasActiveFilters ? "Try adjusting your search or filters" : "No records to display"))), /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-pagination" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-page-info" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-per-page" }, /* @__PURE__ */ import_react23.default.createElement("span", null, "Rows per page:"), /* @__PURE__ */ import_react23.default.createElement(
|
|
4955
|
+
})()))))), paginatedData.length === 0 && /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-empty-state" }, /* @__PURE__ */ import_react23.default.createElement("svg", { className: "dg-empty-icon", viewBox: "0 0 200 160", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ import_react23.default.createElement("rect", { x: "20", y: "30", width: "160", height: "100", rx: "8", fill: "var(--hover-color)", stroke: "var(--border-color)", strokeWidth: "1.5" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "20", y: "30", width: "160", height: "28", rx: "8", fill: "var(--border-color)", opacity: "0.5" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "20", y: "50", width: "160", height: "8", rx: "0", fill: "var(--border-color)", opacity: "0.5" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "72", y1: "30", x2: "72", y2: "130", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "128", y1: "30", x2: "128", y2: "130", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "20", y1: "78", x2: "180", y2: "78", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "20", y1: "104", x2: "180", y2: "104", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "32", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "84", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "140", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "32", y: "113", width: "20", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "84", y: "113", width: "32", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ import_react23.default.createElement("rect", { x: "140", y: "113", width: "20", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ import_react23.default.createElement("circle", { cx: "148", cy: "108", r: "26", fill: "var(--surface-color)", stroke: "var(--border-color)", strokeWidth: "1.5" }), /* @__PURE__ */ import_react23.default.createElement("circle", { cx: "145", cy: "105", r: "10", stroke: "var(--text-secondary)", strokeWidth: "2.5", opacity: "0.5" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "152", y1: "113", x2: "161", y2: "122", stroke: "var(--text-secondary)", strokeWidth: "2.5", strokeLinecap: "round", opacity: "0.5" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "141", y1: "101", x2: "149", y2: "109", stroke: "var(--text-secondary)", strokeWidth: "2", strokeLinecap: "round", opacity: "0.5" }), /* @__PURE__ */ import_react23.default.createElement("line", { x1: "149", y1: "101", x2: "141", y2: "109", stroke: "var(--text-secondary)", strokeWidth: "2", strokeLinecap: "round", opacity: "0.5" })), /* @__PURE__ */ import_react23.default.createElement("p", { className: "dg-empty-title" }, "No data found"), /* @__PURE__ */ import_react23.default.createElement("p", { className: "dg-empty-subtitle" }, filterText || hasActiveFilters ? "Try adjusting your search or filters" : "No records to display"))), pagination && /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-pagination" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-page-info" }, /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-per-page" }, /* @__PURE__ */ import_react23.default.createElement("span", null, "Rows per page:"), /* @__PURE__ */ import_react23.default.createElement(
|
|
4928
4956
|
"select",
|
|
4929
4957
|
{
|
|
4930
|
-
value:
|
|
4931
|
-
onChange: (e) =>
|
|
4932
|
-
setPageSize(Number(e.target.value));
|
|
4933
|
-
setCurrentPage(1);
|
|
4934
|
-
}
|
|
4958
|
+
value: activePageSize,
|
|
4959
|
+
onChange: (e) => handlePageSizeChange(Number(e.target.value))
|
|
4935
4960
|
},
|
|
4936
4961
|
pageSizeOptions.map((o) => /* @__PURE__ */ import_react23.default.createElement("option", { key: o, value: o }, o))
|
|
4937
|
-
)), /* @__PURE__ */ import_react23.default.createElement("span", null, (
|
|
4962
|
+
)), /* @__PURE__ */ import_react23.default.createElement("span", null, (activePage - 1) * activePageSize + 1, "\u2013", Math.min(activePage * activePageSize, totalRows), " of ", totalRows)), /* @__PURE__ */ import_react23.default.createElement("div", { className: "dg-page-nav" }, /* @__PURE__ */ import_react23.default.createElement("button", { className: "dg-page-btn", disabled: activePage === 1, onClick: () => handlePageChange(activePage - 1) }, /* @__PURE__ */ import_react23.default.createElement(import_lucide_react2.ChevronLeft, { size: 15 })), /* @__PURE__ */ import_react23.default.createElement("span", { className: "dg-page-fraction" }, activePage, " / ", totalPages), /* @__PURE__ */ import_react23.default.createElement("button", { className: "dg-page-btn", disabled: activePage === totalPages, onClick: () => handlePageChange(activePage + 1) }, /* @__PURE__ */ import_react23.default.createElement(import_lucide_react2.ChevronRight, { size: 15 })))), activeMenu && /* @__PURE__ */ import_react23.default.createElement(
|
|
4938
4963
|
"div",
|
|
4939
4964
|
{
|
|
4940
4965
|
ref: menuRef,
|
|
@@ -5110,6 +5135,7 @@ var Select = import_react24.default.forwardRef(function Select2(props, ref) {
|
|
|
5110
5135
|
disabled = false,
|
|
5111
5136
|
required = false,
|
|
5112
5137
|
multiple = false,
|
|
5138
|
+
groupBy,
|
|
5113
5139
|
className = "",
|
|
5114
5140
|
style,
|
|
5115
5141
|
sx
|
|
@@ -5289,32 +5315,51 @@ var Select = import_react24.default.forwardRef(function Select2(props, ref) {
|
|
|
5289
5315
|
),
|
|
5290
5316
|
helperText && /* @__PURE__ */ import_react24.default.createElement("div", { className: `rf-text-field__helper-text${error ? " rf-text-field__helper-text--error" : ""}` }, helperText),
|
|
5291
5317
|
open && !disabled && import_react_dom5.default.createPortal(
|
|
5292
|
-
/* @__PURE__ */ import_react24.default.createElement("div", { ref: popupRef, className: "rf-select__popup", role: "presentation", style: popupStyle }, /* @__PURE__ */ import_react24.default.createElement("ul", { ref: listRef, className: "rf-select__listbox", role: "listbox", "aria-multiselectable": multiple },
|
|
5293
|
-
const
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5310
|
-
|
|
5311
|
-
|
|
5312
|
-
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
+
/* @__PURE__ */ import_react24.default.createElement("div", { ref: popupRef, className: "rf-select__popup", role: "presentation", style: popupStyle }, /* @__PURE__ */ import_react24.default.createElement("ul", { ref: listRef, className: "rf-select__listbox", role: "listbox", "aria-multiselectable": multiple }, (() => {
|
|
5319
|
+
const renderOpt = (opt, selectableIdx) => {
|
|
5320
|
+
const selected = isSelected(opt.value);
|
|
5321
|
+
const focused = focusedIdx === selectableIdx;
|
|
5322
|
+
return /* @__PURE__ */ import_react24.default.createElement(
|
|
5323
|
+
"li",
|
|
5324
|
+
{
|
|
5325
|
+
key: opt.value,
|
|
5326
|
+
"data-idx": selectableIdx,
|
|
5327
|
+
role: "option",
|
|
5328
|
+
"aria-selected": selected,
|
|
5329
|
+
"aria-disabled": opt.disabled,
|
|
5330
|
+
className: [
|
|
5331
|
+
"rf-select__option",
|
|
5332
|
+
selected ? "rf-select__option--selected" : "",
|
|
5333
|
+
focused ? "rf-select__option--focused" : "",
|
|
5334
|
+
opt.disabled ? "rf-select__option--disabled" : ""
|
|
5335
|
+
].filter(Boolean).join(" "),
|
|
5336
|
+
onMouseEnter: () => setFocusedIdx(selectableIdx),
|
|
5337
|
+
onMouseLeave: () => setFocusedIdx(-1),
|
|
5338
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
5339
|
+
onClick: (e) => selectOption(opt, e)
|
|
5340
|
+
},
|
|
5341
|
+
/* @__PURE__ */ import_react24.default.createElement("span", { className: "rf-select__option-label" }, opt.label),
|
|
5342
|
+
/* @__PURE__ */ import_react24.default.createElement("span", { className: "rf-select__option-check", "aria-hidden": "true" }, /* @__PURE__ */ import_react24.default.createElement(CheckIcon2, null))
|
|
5343
|
+
);
|
|
5344
|
+
};
|
|
5345
|
+
let sCounter = 0;
|
|
5346
|
+
const selectableIdxMap = /* @__PURE__ */ new Map();
|
|
5347
|
+
options.forEach((o) => {
|
|
5348
|
+
if (!o.disabled) selectableIdxMap.set(o, sCounter++);
|
|
5349
|
+
});
|
|
5350
|
+
const resolveGroup = groupBy ? groupBy : (o) => o.group ?? "";
|
|
5351
|
+
const hasGroups = groupBy != null || options.some((o) => o.group != null);
|
|
5352
|
+
if (!hasGroups) {
|
|
5353
|
+
return options.map((opt) => renderOpt(opt, selectableIdxMap.get(opt) ?? -1));
|
|
5354
|
+
}
|
|
5355
|
+
const groupMap = /* @__PURE__ */ new Map();
|
|
5356
|
+
options.forEach((opt) => {
|
|
5357
|
+
const g = resolveGroup(opt);
|
|
5358
|
+
if (!groupMap.has(g)) groupMap.set(g, []);
|
|
5359
|
+
groupMap.get(g).push(opt);
|
|
5360
|
+
});
|
|
5361
|
+
return Array.from(groupMap.entries()).map(([groupName, groupOpts]) => /* @__PURE__ */ import_react24.default.createElement("li", { key: groupName, role: "presentation" }, /* @__PURE__ */ import_react24.default.createElement("div", { className: "rf-select__group-header" }, groupName), /* @__PURE__ */ import_react24.default.createElement("ul", { className: "rf-select__group-items", role: "group" }, groupOpts.map((opt) => renderOpt(opt, selectableIdxMap.get(opt) ?? -1)))));
|
|
5362
|
+
})())),
|
|
5318
5363
|
document.body
|
|
5319
5364
|
)
|
|
5320
5365
|
);
|
package/dist/main.css
CHANGED
|
@@ -443,6 +443,7 @@
|
|
|
443
443
|
overflow-x: auto;
|
|
444
444
|
overflow-y: auto;
|
|
445
445
|
flex: 1;
|
|
446
|
+
position: relative;
|
|
446
447
|
}
|
|
447
448
|
.dg-table-wrap--empty {
|
|
448
449
|
display: flex;
|
|
@@ -936,6 +937,30 @@
|
|
|
936
937
|
--tf-hover-border-color: var(--text-secondary);
|
|
937
938
|
--tf-primary-color: var(--primary-color);
|
|
938
939
|
}
|
|
940
|
+
.dg-loading-overlay {
|
|
941
|
+
position: absolute;
|
|
942
|
+
inset: 0;
|
|
943
|
+
top: 41px;
|
|
944
|
+
background: rgba(255, 255, 255, 0.65);
|
|
945
|
+
display: flex;
|
|
946
|
+
align-items: center;
|
|
947
|
+
justify-content: center;
|
|
948
|
+
z-index: 20;
|
|
949
|
+
pointer-events: all;
|
|
950
|
+
}
|
|
951
|
+
.dg-loading-spinner {
|
|
952
|
+
width: 32px;
|
|
953
|
+
height: 32px;
|
|
954
|
+
border: 3px solid rgba(0, 0, 0, 0.1);
|
|
955
|
+
border-top-color: var(--primary-color, #f15b24);
|
|
956
|
+
border-radius: 50%;
|
|
957
|
+
animation: dg-spin 0.7s linear infinite;
|
|
958
|
+
}
|
|
959
|
+
@keyframes dg-spin {
|
|
960
|
+
to {
|
|
961
|
+
transform: rotate(360deg);
|
|
962
|
+
}
|
|
963
|
+
}
|
|
939
964
|
.dg-empty-state {
|
|
940
965
|
flex: 1;
|
|
941
966
|
display: flex;
|
|
@@ -2702,6 +2727,23 @@ pre {
|
|
|
2702
2727
|
.rf-select__option--selected .rf-select__option-check {
|
|
2703
2728
|
opacity: 1;
|
|
2704
2729
|
}
|
|
2730
|
+
.rf-select__group-header {
|
|
2731
|
+
padding: 6px 16px 4px;
|
|
2732
|
+
font-size: 0.7rem;
|
|
2733
|
+
font-weight: 700;
|
|
2734
|
+
letter-spacing: 0.07em;
|
|
2735
|
+
text-transform: uppercase;
|
|
2736
|
+
color: var(--primary-color, #a41b06);
|
|
2737
|
+
background: #fff5f5;
|
|
2738
|
+
position: sticky;
|
|
2739
|
+
top: 0;
|
|
2740
|
+
z-index: 1;
|
|
2741
|
+
}
|
|
2742
|
+
.rf-select__group-items {
|
|
2743
|
+
padding: 0;
|
|
2744
|
+
list-style: none;
|
|
2745
|
+
margin: 0;
|
|
2746
|
+
}
|
|
2705
2747
|
|
|
2706
2748
|
/* lib/styles/slider.css */
|
|
2707
2749
|
.rf-slider {
|
|
@@ -6321,11 +6363,11 @@ pre {
|
|
|
6321
6363
|
z-index: 2;
|
|
6322
6364
|
}
|
|
6323
6365
|
.rf-text-field__adornment--start {
|
|
6324
|
-
margin-left:
|
|
6366
|
+
margin-left: 0px;
|
|
6325
6367
|
margin-right: -6px;
|
|
6326
6368
|
}
|
|
6327
6369
|
.rf-text-field__adornment--end {
|
|
6328
|
-
margin-right:
|
|
6370
|
+
margin-right: 0px;
|
|
6329
6371
|
margin-left: -6px;
|
|
6330
6372
|
}
|
|
6331
6373
|
.rf-text-field--standard .rf-text-field__adornment--start {
|
package/dist/main.d.cts
CHANGED
|
@@ -762,6 +762,15 @@ interface AutocompleteProps<T = string> {
|
|
|
762
762
|
style?: CSSProperties;
|
|
763
763
|
/** Scoped style overrides. Supports nested CSS selectors with & */
|
|
764
764
|
sx?: SxProp;
|
|
765
|
+
/**
|
|
766
|
+
* Controlled open state. When provided the dropdown respects this value.
|
|
767
|
+
* Pair with `onOpen` and `onClose` to sync your own state:
|
|
768
|
+
* ```
|
|
769
|
+
* const [open, setOpen] = useState(false);
|
|
770
|
+
* <Autocomplete open={open} onOpen={() => setOpen(true)} onClose={() => setOpen(false)} />
|
|
771
|
+
* ```
|
|
772
|
+
*/
|
|
773
|
+
open?: boolean;
|
|
765
774
|
/** Called when the popup opens */
|
|
766
775
|
onOpen?: () => void;
|
|
767
776
|
/** Called when the popup closes */
|
|
@@ -863,10 +872,37 @@ interface DataGridToolbarSlot {
|
|
|
863
872
|
content: React__default.ReactNode;
|
|
864
873
|
align?: 'left' | 'center' | 'right';
|
|
865
874
|
}
|
|
875
|
+
interface PaginationModel {
|
|
876
|
+
/** 0-indexed current page */
|
|
877
|
+
page: number;
|
|
878
|
+
pageSize: number;
|
|
879
|
+
}
|
|
866
880
|
interface DataGridProps<T> {
|
|
867
881
|
columns: Column<T>[];
|
|
868
882
|
data: T[];
|
|
869
883
|
actions?: Action<T>[] | ((item: T) => Action<T>[]);
|
|
884
|
+
/** Show a loading overlay over the table body */
|
|
885
|
+
loading?: boolean;
|
|
886
|
+
/** Show the pagination bar. Defaults to true. */
|
|
887
|
+
pagination?: boolean;
|
|
888
|
+
/**
|
|
889
|
+
* 'client' (default) — DataGrid filters, sorts, and paginates data internally.
|
|
890
|
+
* 'server' — data is already the current page; DataGrid skips client-side
|
|
891
|
+
* filtering/sorting/slicing and delegates everything to the server.
|
|
892
|
+
*/
|
|
893
|
+
paginationMode?: 'client' | 'server';
|
|
894
|
+
/**
|
|
895
|
+
* Total number of rows across all pages (server mode).
|
|
896
|
+
* Used to compute total page count when paginationMode="server".
|
|
897
|
+
*/
|
|
898
|
+
rowCount?: number;
|
|
899
|
+
/**
|
|
900
|
+
* Controlled pagination state. page is 0-indexed.
|
|
901
|
+
* When provided, the DataGrid uses these values instead of internal state.
|
|
902
|
+
*/
|
|
903
|
+
paginationModel?: PaginationModel;
|
|
904
|
+
/** Called whenever the page or pageSize changes. page is 0-indexed. */
|
|
905
|
+
onPaginationModelChange?: (model: PaginationModel) => void;
|
|
870
906
|
pageSize?: number;
|
|
871
907
|
pageSizeOptions?: number[];
|
|
872
908
|
title?: string;
|
|
@@ -886,12 +922,13 @@ interface DataGridProps<T> {
|
|
|
886
922
|
|
|
887
923
|
declare function DataGrid<T extends {
|
|
888
924
|
id: string | number;
|
|
889
|
-
}>({ columns: initialColumnsProp, data, actions, pageSize: initialPageSize, pageSizeOptions, title, className, sx, onRowDoubleClick, onCellDoubleClick, headerActions, toolbarContent, }: DataGridProps<T>): React__default.JSX.Element;
|
|
925
|
+
}>({ columns: initialColumnsProp, data, actions, loading, pagination, paginationMode, rowCount, paginationModel, onPaginationModelChange, pageSize: initialPageSize, pageSizeOptions, title, className, sx, onRowDoubleClick, onCellDoubleClick, headerActions, toolbarContent, }: DataGridProps<T>): React__default.JSX.Element;
|
|
890
926
|
|
|
891
927
|
type SelectOption = {
|
|
892
928
|
value: string | number;
|
|
893
929
|
label: string;
|
|
894
930
|
disabled?: boolean;
|
|
931
|
+
group?: string;
|
|
895
932
|
};
|
|
896
933
|
interface SelectProps {
|
|
897
934
|
options: SelectOption[] | string[];
|
|
@@ -907,6 +944,8 @@ interface SelectProps {
|
|
|
907
944
|
disabled?: boolean;
|
|
908
945
|
required?: boolean;
|
|
909
946
|
multiple?: boolean;
|
|
947
|
+
/** Group options by returning a category string */
|
|
948
|
+
groupBy?: (option: SelectOption) => string;
|
|
910
949
|
className?: string;
|
|
911
950
|
style?: CSSProperties;
|
|
912
951
|
sx?: SxProp;
|
package/dist/main.d.ts
CHANGED
|
@@ -762,6 +762,15 @@ interface AutocompleteProps<T = string> {
|
|
|
762
762
|
style?: CSSProperties;
|
|
763
763
|
/** Scoped style overrides. Supports nested CSS selectors with & */
|
|
764
764
|
sx?: SxProp;
|
|
765
|
+
/**
|
|
766
|
+
* Controlled open state. When provided the dropdown respects this value.
|
|
767
|
+
* Pair with `onOpen` and `onClose` to sync your own state:
|
|
768
|
+
* ```
|
|
769
|
+
* const [open, setOpen] = useState(false);
|
|
770
|
+
* <Autocomplete open={open} onOpen={() => setOpen(true)} onClose={() => setOpen(false)} />
|
|
771
|
+
* ```
|
|
772
|
+
*/
|
|
773
|
+
open?: boolean;
|
|
765
774
|
/** Called when the popup opens */
|
|
766
775
|
onOpen?: () => void;
|
|
767
776
|
/** Called when the popup closes */
|
|
@@ -863,10 +872,37 @@ interface DataGridToolbarSlot {
|
|
|
863
872
|
content: React__default.ReactNode;
|
|
864
873
|
align?: 'left' | 'center' | 'right';
|
|
865
874
|
}
|
|
875
|
+
interface PaginationModel {
|
|
876
|
+
/** 0-indexed current page */
|
|
877
|
+
page: number;
|
|
878
|
+
pageSize: number;
|
|
879
|
+
}
|
|
866
880
|
interface DataGridProps<T> {
|
|
867
881
|
columns: Column<T>[];
|
|
868
882
|
data: T[];
|
|
869
883
|
actions?: Action<T>[] | ((item: T) => Action<T>[]);
|
|
884
|
+
/** Show a loading overlay over the table body */
|
|
885
|
+
loading?: boolean;
|
|
886
|
+
/** Show the pagination bar. Defaults to true. */
|
|
887
|
+
pagination?: boolean;
|
|
888
|
+
/**
|
|
889
|
+
* 'client' (default) — DataGrid filters, sorts, and paginates data internally.
|
|
890
|
+
* 'server' — data is already the current page; DataGrid skips client-side
|
|
891
|
+
* filtering/sorting/slicing and delegates everything to the server.
|
|
892
|
+
*/
|
|
893
|
+
paginationMode?: 'client' | 'server';
|
|
894
|
+
/**
|
|
895
|
+
* Total number of rows across all pages (server mode).
|
|
896
|
+
* Used to compute total page count when paginationMode="server".
|
|
897
|
+
*/
|
|
898
|
+
rowCount?: number;
|
|
899
|
+
/**
|
|
900
|
+
* Controlled pagination state. page is 0-indexed.
|
|
901
|
+
* When provided, the DataGrid uses these values instead of internal state.
|
|
902
|
+
*/
|
|
903
|
+
paginationModel?: PaginationModel;
|
|
904
|
+
/** Called whenever the page or pageSize changes. page is 0-indexed. */
|
|
905
|
+
onPaginationModelChange?: (model: PaginationModel) => void;
|
|
870
906
|
pageSize?: number;
|
|
871
907
|
pageSizeOptions?: number[];
|
|
872
908
|
title?: string;
|
|
@@ -886,12 +922,13 @@ interface DataGridProps<T> {
|
|
|
886
922
|
|
|
887
923
|
declare function DataGrid<T extends {
|
|
888
924
|
id: string | number;
|
|
889
|
-
}>({ columns: initialColumnsProp, data, actions, pageSize: initialPageSize, pageSizeOptions, title, className, sx, onRowDoubleClick, onCellDoubleClick, headerActions, toolbarContent, }: DataGridProps<T>): React__default.JSX.Element;
|
|
925
|
+
}>({ columns: initialColumnsProp, data, actions, loading, pagination, paginationMode, rowCount, paginationModel, onPaginationModelChange, pageSize: initialPageSize, pageSizeOptions, title, className, sx, onRowDoubleClick, onCellDoubleClick, headerActions, toolbarContent, }: DataGridProps<T>): React__default.JSX.Element;
|
|
890
926
|
|
|
891
927
|
type SelectOption = {
|
|
892
928
|
value: string | number;
|
|
893
929
|
label: string;
|
|
894
930
|
disabled?: boolean;
|
|
931
|
+
group?: string;
|
|
895
932
|
};
|
|
896
933
|
interface SelectProps {
|
|
897
934
|
options: SelectOption[] | string[];
|
|
@@ -907,6 +944,8 @@ interface SelectProps {
|
|
|
907
944
|
disabled?: boolean;
|
|
908
945
|
required?: boolean;
|
|
909
946
|
multiple?: boolean;
|
|
947
|
+
/** Group options by returning a category string */
|
|
948
|
+
groupBy?: (option: SelectOption) => string;
|
|
910
949
|
className?: string;
|
|
911
950
|
style?: CSSProperties;
|
|
912
951
|
sx?: SxProp;
|
package/dist/main.js
CHANGED
|
@@ -2098,10 +2098,12 @@ function AutocompleteInner(props, _ref) {
|
|
|
2098
2098
|
className = "",
|
|
2099
2099
|
style,
|
|
2100
2100
|
sx,
|
|
2101
|
+
open: openProp,
|
|
2101
2102
|
onOpen,
|
|
2102
2103
|
onClose
|
|
2103
2104
|
} = props;
|
|
2104
|
-
const [
|
|
2105
|
+
const [internalOpen, setInternalOpen] = useState5(false);
|
|
2106
|
+
const open = openProp !== void 0 ? openProp : internalOpen;
|
|
2105
2107
|
const [inputStr, setInputStr] = useState5("");
|
|
2106
2108
|
const [filterQuery, setFilterQuery] = useState5("");
|
|
2107
2109
|
const [focusedIdx, setFocusedIdx] = useState5(-1);
|
|
@@ -2187,20 +2189,20 @@ function AutocompleteInner(props, _ref) {
|
|
|
2187
2189
|
const openPopup = useCallback2(() => {
|
|
2188
2190
|
if (disabled) return;
|
|
2189
2191
|
calcPopupStyle();
|
|
2190
|
-
|
|
2192
|
+
if (openProp === void 0) setInternalOpen(true);
|
|
2191
2193
|
setFocusedIdx(-1);
|
|
2192
2194
|
setFilterQuery("");
|
|
2193
2195
|
onOpen?.();
|
|
2194
|
-
}, [disabled, calcPopupStyle, onOpen]);
|
|
2196
|
+
}, [disabled, calcPopupStyle, onOpen, openProp]);
|
|
2195
2197
|
const closePopup = useCallback2((justSelected = false) => {
|
|
2196
|
-
|
|
2198
|
+
if (openProp === void 0) setInternalOpen(false);
|
|
2197
2199
|
setFocusedIdx(-1);
|
|
2198
2200
|
onClose?.();
|
|
2199
2201
|
if (!justSelected && !freeSolo && !multiple && value == null) {
|
|
2200
2202
|
setInputStr("");
|
|
2201
2203
|
onInputChange?.(null, "");
|
|
2202
2204
|
}
|
|
2203
|
-
}, [freeSolo, multiple, value, onInputChange, onClose]);
|
|
2205
|
+
}, [openProp, freeSolo, multiple, value, onInputChange, onClose]);
|
|
2204
2206
|
useEffect5(() => {
|
|
2205
2207
|
if (!open) return;
|
|
2206
2208
|
const handleOutside = (e) => {
|
|
@@ -4311,6 +4313,12 @@ function DataGrid({
|
|
|
4311
4313
|
columns: initialColumnsProp,
|
|
4312
4314
|
data,
|
|
4313
4315
|
actions,
|
|
4316
|
+
loading = false,
|
|
4317
|
+
pagination = true,
|
|
4318
|
+
paginationMode = "client",
|
|
4319
|
+
rowCount,
|
|
4320
|
+
paginationModel,
|
|
4321
|
+
onPaginationModelChange,
|
|
4314
4322
|
pageSize: initialPageSize = 10,
|
|
4315
4323
|
pageSizeOptions = [5, 10, 25, 50],
|
|
4316
4324
|
title,
|
|
@@ -4351,6 +4359,23 @@ function DataGrid({
|
|
|
4351
4359
|
const [sortDirection, setSortDirection] = useState9(null);
|
|
4352
4360
|
const [filterText, setFilterText] = useState9("");
|
|
4353
4361
|
const [currentPage, setCurrentPage] = useState9(1);
|
|
4362
|
+
const activePage = paginationModel ? paginationModel.page + 1 : currentPage;
|
|
4363
|
+
const activePageSize = paginationModel ? paginationModel.pageSize : pageSize;
|
|
4364
|
+
const handlePageChange = (newPage) => {
|
|
4365
|
+
if (onPaginationModelChange) {
|
|
4366
|
+
onPaginationModelChange({ page: newPage - 1, pageSize: activePageSize });
|
|
4367
|
+
} else {
|
|
4368
|
+
setCurrentPage(newPage);
|
|
4369
|
+
}
|
|
4370
|
+
};
|
|
4371
|
+
const handlePageSizeChange = (newSize) => {
|
|
4372
|
+
if (onPaginationModelChange) {
|
|
4373
|
+
onPaginationModelChange({ page: 0, pageSize: newSize });
|
|
4374
|
+
} else {
|
|
4375
|
+
setPageSize(newSize);
|
|
4376
|
+
setCurrentPage(1);
|
|
4377
|
+
}
|
|
4378
|
+
};
|
|
4354
4379
|
const [resizingColumn, setResizingColumn] = useState9(null);
|
|
4355
4380
|
const [startX, setStartX] = useState9(0);
|
|
4356
4381
|
const [startWidth, setStartWidth] = useState9(0);
|
|
@@ -4583,11 +4608,14 @@ function DataGrid({
|
|
|
4583
4608
|
return 0;
|
|
4584
4609
|
});
|
|
4585
4610
|
}, [filteredData, sortField, sortDirection, resolvedColumns]);
|
|
4586
|
-
const
|
|
4611
|
+
const isServer = paginationMode === "server";
|
|
4612
|
+
const totalRows = isServer ? rowCount ?? data.length : filteredData.length;
|
|
4613
|
+
const totalPages = Math.max(1, Math.ceil(totalRows / activePageSize));
|
|
4587
4614
|
const paginatedData = useMemo2(() => {
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4615
|
+
if (isServer) return data;
|
|
4616
|
+
const start = (activePage - 1) * activePageSize;
|
|
4617
|
+
return sortedData.slice(start, start + activePageSize);
|
|
4618
|
+
}, [isServer, data, sortedData, activePage, activePageSize]);
|
|
4591
4619
|
const handleExport = () => {
|
|
4592
4620
|
const exportableCols = resolvedColumns.filter((c) => !c.hidden && c.isExportable !== false);
|
|
4593
4621
|
const headers = exportableCols.map((c) => c.headerName).join(",");
|
|
@@ -4682,7 +4710,7 @@ function DataGrid({
|
|
|
4682
4710
|
onClick: () => setShowManageColumns(true)
|
|
4683
4711
|
},
|
|
4684
4712
|
/* @__PURE__ */ React75.createElement(Columns, { size: 16 })
|
|
4685
|
-
)), /* @__PURE__ */ React75.createElement("button", { className: "dg-action-btn", onClick: handleExport }, /* @__PURE__ */ React75.createElement(Download, { size: 14 }), " Export CSV"), headerActions && /* @__PURE__ */ React75.createElement("div", { className: `dg-header-slot ${alignClass(headerActions.align)}` }, headerActions.content))), /* @__PURE__ */ React75.createElement("div", { className: `dg-toolbar ${alignClass(toolbarContent?.align)}` }, toolbarContent?.content || ""), /* @__PURE__ */ React75.createElement("div", { className: `dg-table-wrap${paginatedData.length === 0 ? " dg-table-wrap--empty" : ""}` }, /* @__PURE__ */ React75.createElement("table", { className: "dg-table" }, /* @__PURE__ */ React75.createElement("thead", null, /* @__PURE__ */ React75.createElement("tr", null, visibleColumns.map((col, idx) => {
|
|
4713
|
+
)), /* @__PURE__ */ React75.createElement("button", { className: "dg-action-btn", onClick: handleExport }, /* @__PURE__ */ React75.createElement(Download, { size: 14 }), " Export CSV"), headerActions && /* @__PURE__ */ React75.createElement("div", { className: `dg-header-slot ${alignClass(headerActions.align)}` }, headerActions.content))), /* @__PURE__ */ React75.createElement("div", { className: `dg-toolbar ${alignClass(toolbarContent?.align)}` }, toolbarContent?.content || ""), /* @__PURE__ */ React75.createElement("div", { className: `dg-table-wrap${paginatedData.length === 0 && !loading ? " dg-table-wrap--empty" : ""}` }, loading && /* @__PURE__ */ React75.createElement("div", { className: "dg-loading-overlay" }, /* @__PURE__ */ React75.createElement("div", { className: "dg-loading-spinner" })), /* @__PURE__ */ React75.createElement("table", { className: "dg-table" }, /* @__PURE__ */ React75.createElement("thead", null, /* @__PURE__ */ React75.createElement("tr", null, visibleColumns.map((col, idx) => {
|
|
4686
4714
|
const colField = String(col.field);
|
|
4687
4715
|
const width = columnWidths[colField] || 200;
|
|
4688
4716
|
const leftOffset = getLeftOffset(col, idx);
|
|
@@ -4796,17 +4824,14 @@ function DataGrid({
|
|
|
4796
4824
|
},
|
|
4797
4825
|
action.icon
|
|
4798
4826
|
)))));
|
|
4799
|
-
})()))))), paginatedData.length === 0 && /* @__PURE__ */ React75.createElement("div", { className: "dg-empty-state" }, /* @__PURE__ */ React75.createElement("svg", { className: "dg-empty-icon", viewBox: "0 0 200 160", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ React75.createElement("rect", { x: "20", y: "30", width: "160", height: "100", rx: "8", fill: "var(--hover-color)", stroke: "var(--border-color)", strokeWidth: "1.5" }), /* @__PURE__ */ React75.createElement("rect", { x: "20", y: "30", width: "160", height: "28", rx: "8", fill: "var(--border-color)", opacity: "0.5" }), /* @__PURE__ */ React75.createElement("rect", { x: "20", y: "50", width: "160", height: "8", rx: "0", fill: "var(--border-color)", opacity: "0.5" }), /* @__PURE__ */ React75.createElement("line", { x1: "72", y1: "30", x2: "72", y2: "130", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ React75.createElement("line", { x1: "128", y1: "30", x2: "128", y2: "130", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ React75.createElement("line", { x1: "20", y1: "78", x2: "180", y2: "78", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ React75.createElement("line", { x1: "20", y1: "104", x2: "180", y2: "104", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ React75.createElement("rect", { x: "32", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ React75.createElement("rect", { x: "84", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ React75.createElement("rect", { x: "140", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ React75.createElement("rect", { x: "32", y: "113", width: "20", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ React75.createElement("rect", { x: "84", y: "113", width: "32", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ React75.createElement("rect", { x: "140", y: "113", width: "20", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ React75.createElement("circle", { cx: "148", cy: "108", r: "26", fill: "var(--surface-color)", stroke: "var(--border-color)", strokeWidth: "1.5" }), /* @__PURE__ */ React75.createElement("circle", { cx: "145", cy: "105", r: "10", stroke: "var(--text-secondary)", strokeWidth: "2.5", opacity: "0.5" }), /* @__PURE__ */ React75.createElement("line", { x1: "152", y1: "113", x2: "161", y2: "122", stroke: "var(--text-secondary)", strokeWidth: "2.5", strokeLinecap: "round", opacity: "0.5" }), /* @__PURE__ */ React75.createElement("line", { x1: "141", y1: "101", x2: "149", y2: "109", stroke: "var(--text-secondary)", strokeWidth: "2", strokeLinecap: "round", opacity: "0.5" }), /* @__PURE__ */ React75.createElement("line", { x1: "149", y1: "101", x2: "141", y2: "109", stroke: "var(--text-secondary)", strokeWidth: "2", strokeLinecap: "round", opacity: "0.5" })), /* @__PURE__ */ React75.createElement("p", { className: "dg-empty-title" }, "No data found"), /* @__PURE__ */ React75.createElement("p", { className: "dg-empty-subtitle" }, filterText || hasActiveFilters ? "Try adjusting your search or filters" : "No records to display"))), /* @__PURE__ */ React75.createElement("div", { className: "dg-pagination" }, /* @__PURE__ */ React75.createElement("div", { className: "dg-page-info" }, /* @__PURE__ */ React75.createElement("div", { className: "dg-per-page" }, /* @__PURE__ */ React75.createElement("span", null, "Rows per page:"), /* @__PURE__ */ React75.createElement(
|
|
4827
|
+
})()))))), paginatedData.length === 0 && /* @__PURE__ */ React75.createElement("div", { className: "dg-empty-state" }, /* @__PURE__ */ React75.createElement("svg", { className: "dg-empty-icon", viewBox: "0 0 200 160", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ React75.createElement("rect", { x: "20", y: "30", width: "160", height: "100", rx: "8", fill: "var(--hover-color)", stroke: "var(--border-color)", strokeWidth: "1.5" }), /* @__PURE__ */ React75.createElement("rect", { x: "20", y: "30", width: "160", height: "28", rx: "8", fill: "var(--border-color)", opacity: "0.5" }), /* @__PURE__ */ React75.createElement("rect", { x: "20", y: "50", width: "160", height: "8", rx: "0", fill: "var(--border-color)", opacity: "0.5" }), /* @__PURE__ */ React75.createElement("line", { x1: "72", y1: "30", x2: "72", y2: "130", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ React75.createElement("line", { x1: "128", y1: "30", x2: "128", y2: "130", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ React75.createElement("line", { x1: "20", y1: "78", x2: "180", y2: "78", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ React75.createElement("line", { x1: "20", y1: "104", x2: "180", y2: "104", stroke: "var(--border-color)", strokeWidth: "1" }), /* @__PURE__ */ React75.createElement("rect", { x: "32", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ React75.createElement("rect", { x: "84", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ React75.createElement("rect", { x: "140", y: "87", width: "28", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.4" }), /* @__PURE__ */ React75.createElement("rect", { x: "32", y: "113", width: "20", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ React75.createElement("rect", { x: "84", y: "113", width: "32", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ React75.createElement("rect", { x: "140", y: "113", width: "20", height: "6", rx: "3", fill: "var(--border-color)", opacity: "0.3" }), /* @__PURE__ */ React75.createElement("circle", { cx: "148", cy: "108", r: "26", fill: "var(--surface-color)", stroke: "var(--border-color)", strokeWidth: "1.5" }), /* @__PURE__ */ React75.createElement("circle", { cx: "145", cy: "105", r: "10", stroke: "var(--text-secondary)", strokeWidth: "2.5", opacity: "0.5" }), /* @__PURE__ */ React75.createElement("line", { x1: "152", y1: "113", x2: "161", y2: "122", stroke: "var(--text-secondary)", strokeWidth: "2.5", strokeLinecap: "round", opacity: "0.5" }), /* @__PURE__ */ React75.createElement("line", { x1: "141", y1: "101", x2: "149", y2: "109", stroke: "var(--text-secondary)", strokeWidth: "2", strokeLinecap: "round", opacity: "0.5" }), /* @__PURE__ */ React75.createElement("line", { x1: "149", y1: "101", x2: "141", y2: "109", stroke: "var(--text-secondary)", strokeWidth: "2", strokeLinecap: "round", opacity: "0.5" })), /* @__PURE__ */ React75.createElement("p", { className: "dg-empty-title" }, "No data found"), /* @__PURE__ */ React75.createElement("p", { className: "dg-empty-subtitle" }, filterText || hasActiveFilters ? "Try adjusting your search or filters" : "No records to display"))), pagination && /* @__PURE__ */ React75.createElement("div", { className: "dg-pagination" }, /* @__PURE__ */ React75.createElement("div", { className: "dg-page-info" }, /* @__PURE__ */ React75.createElement("div", { className: "dg-per-page" }, /* @__PURE__ */ React75.createElement("span", null, "Rows per page:"), /* @__PURE__ */ React75.createElement(
|
|
4800
4828
|
"select",
|
|
4801
4829
|
{
|
|
4802
|
-
value:
|
|
4803
|
-
onChange: (e) =>
|
|
4804
|
-
setPageSize(Number(e.target.value));
|
|
4805
|
-
setCurrentPage(1);
|
|
4806
|
-
}
|
|
4830
|
+
value: activePageSize,
|
|
4831
|
+
onChange: (e) => handlePageSizeChange(Number(e.target.value))
|
|
4807
4832
|
},
|
|
4808
4833
|
pageSizeOptions.map((o) => /* @__PURE__ */ React75.createElement("option", { key: o, value: o }, o))
|
|
4809
|
-
)), /* @__PURE__ */ React75.createElement("span", null, (
|
|
4834
|
+
)), /* @__PURE__ */ React75.createElement("span", null, (activePage - 1) * activePageSize + 1, "\u2013", Math.min(activePage * activePageSize, totalRows), " of ", totalRows)), /* @__PURE__ */ React75.createElement("div", { className: "dg-page-nav" }, /* @__PURE__ */ React75.createElement("button", { className: "dg-page-btn", disabled: activePage === 1, onClick: () => handlePageChange(activePage - 1) }, /* @__PURE__ */ React75.createElement(ChevronLeft, { size: 15 })), /* @__PURE__ */ React75.createElement("span", { className: "dg-page-fraction" }, activePage, " / ", totalPages), /* @__PURE__ */ React75.createElement("button", { className: "dg-page-btn", disabled: activePage === totalPages, onClick: () => handlePageChange(activePage + 1) }, /* @__PURE__ */ React75.createElement(ChevronRight, { size: 15 })))), activeMenu && /* @__PURE__ */ React75.createElement(
|
|
4810
4835
|
"div",
|
|
4811
4836
|
{
|
|
4812
4837
|
ref: menuRef,
|
|
@@ -4987,6 +5012,7 @@ var Select = React76.forwardRef(function Select2(props, ref) {
|
|
|
4987
5012
|
disabled = false,
|
|
4988
5013
|
required = false,
|
|
4989
5014
|
multiple = false,
|
|
5015
|
+
groupBy,
|
|
4990
5016
|
className = "",
|
|
4991
5017
|
style,
|
|
4992
5018
|
sx
|
|
@@ -5166,32 +5192,51 @@ var Select = React76.forwardRef(function Select2(props, ref) {
|
|
|
5166
5192
|
),
|
|
5167
5193
|
helperText && /* @__PURE__ */ React76.createElement("div", { className: `rf-text-field__helper-text${error ? " rf-text-field__helper-text--error" : ""}` }, helperText),
|
|
5168
5194
|
open && !disabled && ReactDOM4.createPortal(
|
|
5169
|
-
/* @__PURE__ */ React76.createElement("div", { ref: popupRef, className: "rf-select__popup", role: "presentation", style: popupStyle }, /* @__PURE__ */ React76.createElement("ul", { ref: listRef, className: "rf-select__listbox", role: "listbox", "aria-multiselectable": multiple },
|
|
5170
|
-
const
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5178
|
-
|
|
5179
|
-
|
|
5180
|
-
|
|
5181
|
-
|
|
5182
|
-
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
+
/* @__PURE__ */ React76.createElement("div", { ref: popupRef, className: "rf-select__popup", role: "presentation", style: popupStyle }, /* @__PURE__ */ React76.createElement("ul", { ref: listRef, className: "rf-select__listbox", role: "listbox", "aria-multiselectable": multiple }, (() => {
|
|
5196
|
+
const renderOpt = (opt, selectableIdx) => {
|
|
5197
|
+
const selected = isSelected(opt.value);
|
|
5198
|
+
const focused = focusedIdx === selectableIdx;
|
|
5199
|
+
return /* @__PURE__ */ React76.createElement(
|
|
5200
|
+
"li",
|
|
5201
|
+
{
|
|
5202
|
+
key: opt.value,
|
|
5203
|
+
"data-idx": selectableIdx,
|
|
5204
|
+
role: "option",
|
|
5205
|
+
"aria-selected": selected,
|
|
5206
|
+
"aria-disabled": opt.disabled,
|
|
5207
|
+
className: [
|
|
5208
|
+
"rf-select__option",
|
|
5209
|
+
selected ? "rf-select__option--selected" : "",
|
|
5210
|
+
focused ? "rf-select__option--focused" : "",
|
|
5211
|
+
opt.disabled ? "rf-select__option--disabled" : ""
|
|
5212
|
+
].filter(Boolean).join(" "),
|
|
5213
|
+
onMouseEnter: () => setFocusedIdx(selectableIdx),
|
|
5214
|
+
onMouseLeave: () => setFocusedIdx(-1),
|
|
5215
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
5216
|
+
onClick: (e) => selectOption(opt, e)
|
|
5217
|
+
},
|
|
5218
|
+
/* @__PURE__ */ React76.createElement("span", { className: "rf-select__option-label" }, opt.label),
|
|
5219
|
+
/* @__PURE__ */ React76.createElement("span", { className: "rf-select__option-check", "aria-hidden": "true" }, /* @__PURE__ */ React76.createElement(CheckIcon2, null))
|
|
5220
|
+
);
|
|
5221
|
+
};
|
|
5222
|
+
let sCounter = 0;
|
|
5223
|
+
const selectableIdxMap = /* @__PURE__ */ new Map();
|
|
5224
|
+
options.forEach((o) => {
|
|
5225
|
+
if (!o.disabled) selectableIdxMap.set(o, sCounter++);
|
|
5226
|
+
});
|
|
5227
|
+
const resolveGroup = groupBy ? groupBy : (o) => o.group ?? "";
|
|
5228
|
+
const hasGroups = groupBy != null || options.some((o) => o.group != null);
|
|
5229
|
+
if (!hasGroups) {
|
|
5230
|
+
return options.map((opt) => renderOpt(opt, selectableIdxMap.get(opt) ?? -1));
|
|
5231
|
+
}
|
|
5232
|
+
const groupMap = /* @__PURE__ */ new Map();
|
|
5233
|
+
options.forEach((opt) => {
|
|
5234
|
+
const g = resolveGroup(opt);
|
|
5235
|
+
if (!groupMap.has(g)) groupMap.set(g, []);
|
|
5236
|
+
groupMap.get(g).push(opt);
|
|
5237
|
+
});
|
|
5238
|
+
return Array.from(groupMap.entries()).map(([groupName, groupOpts]) => /* @__PURE__ */ React76.createElement("li", { key: groupName, role: "presentation" }, /* @__PURE__ */ React76.createElement("div", { className: "rf-select__group-header" }, groupName), /* @__PURE__ */ React76.createElement("ul", { className: "rf-select__group-items", role: "group" }, groupOpts.map((opt) => renderOpt(opt, selectableIdxMap.get(opt) ?? -1)))));
|
|
5239
|
+
})())),
|
|
5195
5240
|
document.body
|
|
5196
5241
|
)
|
|
5197
5242
|
);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rufous/ui",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.01",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Experimental: A lightweight React UI component library (Beta)",
|
|
7
7
|
"style": "./dist/main.css",
|
|
@@ -93,4 +93,4 @@
|
|
|
93
93
|
"react": "^18.0.0 || ^19.0.0",
|
|
94
94
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
95
95
|
}
|
|
96
|
-
}
|
|
96
|
+
}
|