@juv/codego-react-ui 3.0.8 → 3.1.0

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/index.cjs CHANGED
@@ -2127,6 +2127,7 @@ function MetricRow({ items, divided = true, className }) {
2127
2127
 
2128
2128
  // src/components/ui/data-grid.tsx
2129
2129
  var React24 = __toESM(require("react"), 1);
2130
+ var import_react_dom = require("react-dom");
2130
2131
  var import_axios = __toESM(require("axios"), 1);
2131
2132
  var import_lucide_react15 = require("lucide-react");
2132
2133
 
@@ -4860,10 +4861,12 @@ function useServerDataGrid({ url, params }) {
4860
4861
  setData(res.data);
4861
4862
  const rawTotal = res.total;
4862
4863
  const rawPerPage = res.per_page;
4863
- const lastPage = Math.ceil(rawTotal / rawPerPage);
4864
+ const rawLastPage = res.last_page;
4865
+ const lastPage = rawLastPage ?? Math.ceil(rawTotal / rawPerPage);
4864
4866
  const pg = res.pagination ?? {
4865
4867
  first_page_url: res.first_page_url ?? `${url}?page=1`,
4866
4868
  last_page_url: res.last_page_url ?? `${url}?page=${lastPage}`,
4869
+ last_page: lastPage,
4867
4870
  next_page_url: res.next_page_url !== void 0 ? res.next_page_url : currentPage < lastPage ? `${url}?page=${currentPage + 1}` : null,
4868
4871
  prev_page_url: res.prev_page_url !== void 0 ? res.prev_page_url : currentPage > 1 ? `${url}?page=${currentPage - 1}` : null,
4869
4872
  per_page: rawPerPage,
@@ -4902,23 +4905,26 @@ function useServerDataGrid({ url, params }) {
4902
4905
  };
4903
4906
  }
4904
4907
  function DGModalShell({ title, onClose, children, footer }) {
4905
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4906
- "div",
4907
- {
4908
- className: "fixed inset-0 z-50 flex items-center justify-center p-4",
4909
- style: { background: "rgba(0,0,0,0.5)" },
4910
- onMouseDown: (e) => {
4911
- if (e.target === e.currentTarget) onClose();
4912
- },
4913
- children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "relative w-full max-w-lg rounded-2xl border border-border bg-card shadow-2xl flex flex-col max-h-[90vh]", children: [
4914
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border shrink-0", children: [
4915
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("h2", { className: "text-base font-semibold", children: title }),
4916
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { onClick: onClose, className: "text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react15.X, { className: "h-4 w-4" }) })
4917
- ] }),
4918
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "overflow-y-auto px-6 py-4 flex-1", children }),
4919
- footer && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "px-6 py-4 border-t border-border shrink-0 flex justify-end gap-2", children: footer })
4920
- ] })
4921
- }
4908
+ return (0, import_react_dom.createPortal)(
4909
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4910
+ "div",
4911
+ {
4912
+ className: "fixed inset-0 z-50 flex items-center justify-center p-4",
4913
+ style: { background: "rgba(0,0,0,0.5)" },
4914
+ onMouseDown: (e) => {
4915
+ if (e.target === e.currentTarget) onClose();
4916
+ },
4917
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "relative w-full max-w-lg rounded-2xl border border-border bg-card shadow-2xl flex flex-col max-h-[90vh]", children: [
4918
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border shrink-0", children: [
4919
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("h2", { className: "text-base font-semibold", children: title }),
4920
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { onClick: onClose, className: "text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_lucide_react15.X, { className: "h-4 w-4" }) })
4921
+ ] }),
4922
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "overflow-y-auto px-6 py-4 flex-1", children }),
4923
+ footer && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "px-6 py-4 border-t border-border shrink-0 flex justify-end gap-2", children: footer })
4924
+ ] })
4925
+ }
4926
+ ),
4927
+ document.body
4922
4928
  );
4923
4929
  }
4924
4930
  function DGFieldRenderer({ field, value, onChange }) {
@@ -5232,7 +5238,10 @@ function DataGrid({
5232
5238
  )
5233
5239
  ] })
5234
5240
  } : null;
5235
- const visibleCols = [
5241
+ const visibleCols = defaultActions?.position === "first" ? [
5242
+ ...actionsCol ? [actionsCol] : [],
5243
+ ...columns.filter((c) => !hiddenCols.includes(String(c.key)))
5244
+ ] : [
5236
5245
  ...columns.filter((c) => !hiddenCols.includes(String(c.key))),
5237
5246
  ...actionsCol ? [actionsCol] : []
5238
5247
  ];
@@ -5372,7 +5381,7 @@ function DataGrid({
5372
5381
  ),
5373
5382
  serverPagination && (() => {
5374
5383
  const { pagination, currentPage: cp, goToPage } = serverPagination;
5375
- const totalServerPages = Math.ceil(pagination.total / pagination.per_page);
5384
+ const totalServerPages = pagination.last_page ?? Math.ceil(pagination.total / pagination.per_page);
5376
5385
  const pageLinks = Array.from({ length: totalServerPages }, (_, i) => i + 1);
5377
5386
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
5378
5387
  /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
@@ -9483,6 +9492,7 @@ function Stepper({
9483
9492
 
9484
9493
  // src/components/ui/table.tsx
9485
9494
  var React44 = __toESM(require("react"), 1);
9495
+ var import_react_dom2 = require("react-dom");
9486
9496
  var import_axios2 = __toESM(require("axios"), 1);
9487
9497
  var import_lucide_react28 = require("lucide-react");
9488
9498
  var import_jsx_runtime55 = require("react/jsx-runtime");
@@ -9505,10 +9515,12 @@ function useServerTable({ url, params }) {
9505
9515
  setData(res.data);
9506
9516
  const rawTotal = res.total;
9507
9517
  const rawPerPage = res.per_page;
9508
- const lastPage = Math.ceil(rawTotal / rawPerPage);
9518
+ const rawLastPage = res.last_page;
9519
+ const lastPage = rawLastPage ?? Math.ceil(rawTotal / rawPerPage);
9509
9520
  const pg = res.pagination ?? {
9510
9521
  first_page_url: res.first_page_url ?? `${url}?page=1`,
9511
9522
  last_page_url: res.last_page_url ?? `${url}?page=${lastPage}`,
9523
+ last_page: lastPage,
9512
9524
  next_page_url: res.next_page_url !== void 0 ? res.next_page_url : currentPage < lastPage ? `${url}?page=${currentPage + 1}` : null,
9513
9525
  prev_page_url: res.prev_page_url !== void 0 ? res.prev_page_url : currentPage > 1 ? `${url}?page=${currentPage - 1}` : null,
9514
9526
  per_page: rawPerPage,
@@ -9547,23 +9559,26 @@ function useServerTable({ url, params }) {
9547
9559
  };
9548
9560
  }
9549
9561
  function ModalShell({ title, onClose, children, footer }) {
9550
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
9551
- "div",
9552
- {
9553
- className: "fixed inset-0 z-50 flex items-center justify-center p-4",
9554
- style: { background: "rgba(0,0,0,0.5)" },
9555
- onMouseDown: (e) => {
9556
- if (e.target === e.currentTarget) onClose();
9557
- },
9558
- children: /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "relative w-full max-w-lg rounded-2xl border border-border bg-card shadow-2xl flex flex-col max-h-[90vh]", children: [
9559
- /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border shrink-0", children: [
9560
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("h2", { className: "text-base font-semibold", children: title }),
9561
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("button", { onClick: onClose, className: "text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_lucide_react28.X, { className: "h-4 w-4" }) })
9562
- ] }),
9563
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "overflow-y-auto px-6 py-4 flex-1", children }),
9564
- footer && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "px-6 py-4 border-t border-border shrink-0 flex justify-end gap-2", children: footer })
9565
- ] })
9566
- }
9562
+ return (0, import_react_dom2.createPortal)(
9563
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
9564
+ "div",
9565
+ {
9566
+ className: "fixed inset-0 z-50 flex items-center justify-center p-4",
9567
+ style: { background: "rgba(0,0,0,0.5)" },
9568
+ onMouseDown: (e) => {
9569
+ if (e.target === e.currentTarget) onClose();
9570
+ },
9571
+ children: /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "relative w-full max-w-lg rounded-2xl border border-border bg-card shadow-2xl flex flex-col max-h-[90vh]", children: [
9572
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border shrink-0", children: [
9573
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("h2", { className: "text-base font-semibold", children: title }),
9574
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("button", { onClick: onClose, className: "text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_lucide_react28.X, { className: "h-4 w-4" }) })
9575
+ ] }),
9576
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "overflow-y-auto px-6 py-4 flex-1", children }),
9577
+ footer && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "px-6 py-4 border-t border-border shrink-0 flex justify-end gap-2", children: footer })
9578
+ ] })
9579
+ }
9580
+ ),
9581
+ document.body
9567
9582
  );
9568
9583
  }
9569
9584
  function FieldRenderer({ field, value, onChange }) {
@@ -9906,7 +9921,7 @@ function Table({
9906
9921
  )
9907
9922
  ] })
9908
9923
  };
9909
- return [...columns, actionsCol];
9924
+ return defaultActions.position === "first" ? [actionsCol, ...columns] : [...columns, actionsCol];
9910
9925
  }, [columns, defaultActions]);
9911
9926
  const handleSort = (key) => {
9912
9927
  if (sortKey !== key) {
@@ -10002,9 +10017,9 @@ function Table({
10002
10017
  }
10003
10018
  ),
10004
10019
  /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
10005
- filteredData.length,
10020
+ serverPagination ? serverPagination.pagination.total : filteredData.length,
10006
10021
  " ",
10007
- filteredData.length === 1 ? "row" : "rows",
10022
+ (serverPagination ? serverPagination.pagination.total : filteredData.length) === 1 ? "row" : "rows",
10008
10023
  search && ` \xB7 filtered from ${tableData.length}`
10009
10024
  ] })
10010
10025
  ] })
@@ -10178,7 +10193,7 @@ function Table({
10178
10193
  ] }),
10179
10194
  serverPagination && (() => {
10180
10195
  const { pagination: pagination2, currentPage: cp, goToPage } = serverPagination;
10181
- const totalServerPages = Math.ceil(pagination2.total / pagination2.per_page);
10196
+ const totalServerPages = pagination2.last_page ?? Math.ceil(pagination2.total / pagination2.per_page);
10182
10197
  const pageLinks = Array.from({ length: totalServerPages }, (_, i) => i + 1);
10183
10198
  return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
10184
10199
  /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
package/dist/index.d.cts CHANGED
@@ -344,6 +344,7 @@ interface ServerPaginationLink {
344
344
  interface ServerPagination {
345
345
  first_page_url: string;
346
346
  last_page_url: string;
347
+ last_page: number;
347
348
  next_page_url: string | null;
348
349
  prev_page_url: string | null;
349
350
  per_page: number;
@@ -412,6 +413,8 @@ interface DefaultActionsConfig<T> {
412
413
  baseUrl: string;
413
414
  /** Row key used as the URL id segment. Defaults to "id". */
414
415
  idKey?: keyof T;
416
+ /** Position of the Actions column. Default "last". */
417
+ position?: "first" | "last";
415
418
  /** Fields rendered in the Edit modal form. Auto-derived from row keys when omitted. */
416
419
  editForm?: ActionField[];
417
420
  /** Fields rendered in the View modal. Auto-derived from row keys when omitted. */
package/dist/index.d.ts CHANGED
@@ -344,6 +344,7 @@ interface ServerPaginationLink {
344
344
  interface ServerPagination {
345
345
  first_page_url: string;
346
346
  last_page_url: string;
347
+ last_page: number;
347
348
  next_page_url: string | null;
348
349
  prev_page_url: string | null;
349
350
  per_page: number;
@@ -412,6 +413,8 @@ interface DefaultActionsConfig<T> {
412
413
  baseUrl: string;
413
414
  /** Row key used as the URL id segment. Defaults to "id". */
414
415
  idKey?: keyof T;
416
+ /** Position of the Actions column. Default "last". */
417
+ position?: "first" | "last";
415
418
  /** Fields rendered in the Edit modal form. Auto-derived from row keys when omitted. */
416
419
  editForm?: ActionField[];
417
420
  /** Fields rendered in the View modal. Auto-derived from row keys when omitted. */
@@ -53077,6 +53077,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
53077
53077
 
53078
53078
  // src/components/ui/data-grid.tsx
53079
53079
  var React24 = __toESM(require_react(), 1);
53080
+ var import_react_dom = __toESM(require_react_dom(), 1);
53080
53081
 
53081
53082
  // node_modules/axios/lib/helpers/bind.js
53082
53083
  function bind(fn, thisArg) {
@@ -61435,10 +61436,12 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
61435
61436
  setData(res.data);
61436
61437
  const rawTotal = res.total;
61437
61438
  const rawPerPage = res.per_page;
61438
- const lastPage = Math.ceil(rawTotal / rawPerPage);
61439
+ const rawLastPage = res.last_page;
61440
+ const lastPage = rawLastPage ?? Math.ceil(rawTotal / rawPerPage);
61439
61441
  const pg = res.pagination ?? {
61440
61442
  first_page_url: res.first_page_url ?? `${url2}?page=1`,
61441
61443
  last_page_url: res.last_page_url ?? `${url2}?page=${lastPage}`,
61444
+ last_page: lastPage,
61442
61445
  next_page_url: res.next_page_url !== void 0 ? res.next_page_url : currentPage < lastPage ? `${url2}?page=${currentPage + 1}` : null,
61443
61446
  prev_page_url: res.prev_page_url !== void 0 ? res.prev_page_url : currentPage > 1 ? `${url2}?page=${currentPage - 1}` : null,
61444
61447
  per_page: rawPerPage,
@@ -61477,23 +61480,26 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
61477
61480
  };
61478
61481
  }
61479
61482
  function DGModalShell({ title, onClose, children, footer }) {
61480
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
61481
- "div",
61482
- {
61483
- className: "fixed inset-0 z-50 flex items-center justify-center p-4",
61484
- style: { background: "rgba(0,0,0,0.5)" },
61485
- onMouseDown: (e) => {
61486
- if (e.target === e.currentTarget) onClose();
61487
- },
61488
- children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "relative w-full max-w-lg rounded-2xl border border-border bg-card shadow-2xl flex flex-col max-h-[90vh]", children: [
61489
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border shrink-0", children: [
61490
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("h2", { className: "text-base font-semibold", children: title }),
61491
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { onClick: onClose, className: "text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(X, { className: "h-4 w-4" }) })
61492
- ] }),
61493
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "overflow-y-auto px-6 py-4 flex-1", children }),
61494
- footer && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "px-6 py-4 border-t border-border shrink-0 flex justify-end gap-2", children: footer })
61495
- ] })
61496
- }
61483
+ return (0, import_react_dom.createPortal)(
61484
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
61485
+ "div",
61486
+ {
61487
+ className: "fixed inset-0 z-50 flex items-center justify-center p-4",
61488
+ style: { background: "rgba(0,0,0,0.5)" },
61489
+ onMouseDown: (e) => {
61490
+ if (e.target === e.currentTarget) onClose();
61491
+ },
61492
+ children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "relative w-full max-w-lg rounded-2xl border border-border bg-card shadow-2xl flex flex-col max-h-[90vh]", children: [
61493
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border shrink-0", children: [
61494
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("h2", { className: "text-base font-semibold", children: title }),
61495
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("button", { onClick: onClose, className: "text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(X, { className: "h-4 w-4" }) })
61496
+ ] }),
61497
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "overflow-y-auto px-6 py-4 flex-1", children }),
61498
+ footer && /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "px-6 py-4 border-t border-border shrink-0 flex justify-end gap-2", children: footer })
61499
+ ] })
61500
+ }
61501
+ ),
61502
+ document.body
61497
61503
  );
61498
61504
  }
61499
61505
  function DGFieldRenderer({ field, value, onChange }) {
@@ -61807,7 +61813,10 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
61807
61813
  )
61808
61814
  ] })
61809
61815
  } : null;
61810
- const visibleCols = [
61816
+ const visibleCols = defaultActions?.position === "first" ? [
61817
+ ...actionsCol ? [actionsCol] : [],
61818
+ ...columns.filter((c) => !hiddenCols.includes(String(c.key)))
61819
+ ] : [
61811
61820
  ...columns.filter((c) => !hiddenCols.includes(String(c.key))),
61812
61821
  ...actionsCol ? [actionsCol] : []
61813
61822
  ];
@@ -61947,7 +61956,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
61947
61956
  ),
61948
61957
  serverPagination && (() => {
61949
61958
  const { pagination, currentPage: cp, goToPage } = serverPagination;
61950
- const totalServerPages = Math.ceil(pagination.total / pagination.per_page);
61959
+ const totalServerPages = pagination.last_page ?? Math.ceil(pagination.total / pagination.per_page);
61951
61960
  const pageLinks = Array.from({ length: totalServerPages }, (_, i) => i + 1);
61952
61961
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
61953
61962
  /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
@@ -62598,7 +62607,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
62598
62607
 
62599
62608
  // node_modules/@react-leaflet/core/lib/component.js
62600
62609
  var import_react5 = __toESM(require_react(), 1);
62601
- var import_react_dom = __toESM(require_react_dom(), 1);
62610
+ var import_react_dom2 = __toESM(require_react_dom(), 1);
62602
62611
 
62603
62612
  // node_modules/@react-leaflet/core/lib/context.js
62604
62613
  var import_react4 = __toESM(require_react(), 1);
@@ -62651,7 +62660,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
62651
62660
  props.children
62652
62661
  ]);
62653
62662
  const contentNode = instance._contentNode;
62654
- return contentNode ? /* @__PURE__ */ (0, import_react_dom.createPortal)(props.children, contentNode) : null;
62663
+ return contentNode ? /* @__PURE__ */ (0, import_react_dom2.createPortal)(props.children, contentNode) : null;
62655
62664
  }
62656
62665
  return /* @__PURE__ */ (0, import_react5.forwardRef)(OverlayComponent);
62657
62666
  }
@@ -66471,6 +66480,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
66471
66480
 
66472
66481
  // src/components/ui/table.tsx
66473
66482
  var React46 = __toESM(require_react(), 1);
66483
+ var import_react_dom3 = __toESM(require_react_dom(), 1);
66474
66484
  var import_jsx_runtime55 = __toESM(require_jsx_runtime(), 1);
66475
66485
  function useServerTable({ url: url2, params }) {
66476
66486
  const [data, setData] = React46.useState([]);
@@ -66491,10 +66501,12 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
66491
66501
  setData(res.data);
66492
66502
  const rawTotal = res.total;
66493
66503
  const rawPerPage = res.per_page;
66494
- const lastPage = Math.ceil(rawTotal / rawPerPage);
66504
+ const rawLastPage = res.last_page;
66505
+ const lastPage = rawLastPage ?? Math.ceil(rawTotal / rawPerPage);
66495
66506
  const pg = res.pagination ?? {
66496
66507
  first_page_url: res.first_page_url ?? `${url2}?page=1`,
66497
66508
  last_page_url: res.last_page_url ?? `${url2}?page=${lastPage}`,
66509
+ last_page: lastPage,
66498
66510
  next_page_url: res.next_page_url !== void 0 ? res.next_page_url : currentPage < lastPage ? `${url2}?page=${currentPage + 1}` : null,
66499
66511
  prev_page_url: res.prev_page_url !== void 0 ? res.prev_page_url : currentPage > 1 ? `${url2}?page=${currentPage - 1}` : null,
66500
66512
  per_page: rawPerPage,
@@ -66533,23 +66545,26 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
66533
66545
  };
66534
66546
  }
66535
66547
  function ModalShell({ title, onClose, children, footer }) {
66536
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
66537
- "div",
66538
- {
66539
- className: "fixed inset-0 z-50 flex items-center justify-center p-4",
66540
- style: { background: "rgba(0,0,0,0.5)" },
66541
- onMouseDown: (e) => {
66542
- if (e.target === e.currentTarget) onClose();
66543
- },
66544
- children: /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "relative w-full max-w-lg rounded-2xl border border-border bg-card shadow-2xl flex flex-col max-h-[90vh]", children: [
66545
- /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border shrink-0", children: [
66546
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("h2", { className: "text-base font-semibold", children: title }),
66547
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("button", { onClick: onClose, className: "text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(X, { className: "h-4 w-4" }) })
66548
- ] }),
66549
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "overflow-y-auto px-6 py-4 flex-1", children }),
66550
- footer && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "px-6 py-4 border-t border-border shrink-0 flex justify-end gap-2", children: footer })
66551
- ] })
66552
- }
66548
+ return (0, import_react_dom3.createPortal)(
66549
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
66550
+ "div",
66551
+ {
66552
+ className: "fixed inset-0 z-50 flex items-center justify-center p-4",
66553
+ style: { background: "rgba(0,0,0,0.5)" },
66554
+ onMouseDown: (e) => {
66555
+ if (e.target === e.currentTarget) onClose();
66556
+ },
66557
+ children: /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "relative w-full max-w-lg rounded-2xl border border-border bg-card shadow-2xl flex flex-col max-h-[90vh]", children: [
66558
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border shrink-0", children: [
66559
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("h2", { className: "text-base font-semibold", children: title }),
66560
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("button", { onClick: onClose, className: "text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(X, { className: "h-4 w-4" }) })
66561
+ ] }),
66562
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "overflow-y-auto px-6 py-4 flex-1", children }),
66563
+ footer && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "px-6 py-4 border-t border-border shrink-0 flex justify-end gap-2", children: footer })
66564
+ ] })
66565
+ }
66566
+ ),
66567
+ document.body
66553
66568
  );
66554
66569
  }
66555
66570
  function FieldRenderer({ field, value, onChange }) {
@@ -66892,7 +66907,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
66892
66907
  )
66893
66908
  ] })
66894
66909
  };
66895
- return [...columns, actionsCol];
66910
+ return defaultActions.position === "first" ? [actionsCol, ...columns] : [...columns, actionsCol];
66896
66911
  }, [columns, defaultActions]);
66897
66912
  const handleSort = (key) => {
66898
66913
  if (sortKey !== key) {
@@ -66988,9 +67003,9 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
66988
67003
  }
66989
67004
  ),
66990
67005
  /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
66991
- filteredData.length,
67006
+ serverPagination ? serverPagination.pagination.total : filteredData.length,
66992
67007
  " ",
66993
- filteredData.length === 1 ? "row" : "rows",
67008
+ (serverPagination ? serverPagination.pagination.total : filteredData.length) === 1 ? "row" : "rows",
66994
67009
  search && ` \xB7 filtered from ${tableData.length}`
66995
67010
  ] })
66996
67011
  ] })
@@ -67164,7 +67179,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
67164
67179
  ] }),
67165
67180
  serverPagination && (() => {
67166
67181
  const { pagination: pagination2, currentPage: cp, goToPage } = serverPagination;
67167
- const totalServerPages = Math.ceil(pagination2.total / pagination2.per_page);
67182
+ const totalServerPages = pagination2.last_page ?? Math.ceil(pagination2.total / pagination2.per_page);
67168
67183
  const pageLinks = Array.from({ length: totalServerPages }, (_, i) => i + 1);
67169
67184
  return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
67170
67185
  /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
package/dist/index.js CHANGED
@@ -1996,6 +1996,7 @@ function MetricRow({ items, divided = true, className }) {
1996
1996
 
1997
1997
  // src/components/ui/data-grid.tsx
1998
1998
  import * as React24 from "react";
1999
+ import { createPortal as createPortal2 } from "react-dom";
1999
2000
  import axios from "axios";
2000
2001
  import { ChevronUp, ChevronDown as ChevronDown4, ChevronsUpDown, ChevronLeft as ChevronLeft5, ChevronRight as ChevronRight7, Search as Search4, Settings2, Check as Check5, Eye, Pencil, Trash, Loader2, X as X7 } from "lucide-react";
2001
2002
 
@@ -4746,10 +4747,12 @@ function useServerDataGrid({ url, params }) {
4746
4747
  setData(res.data);
4747
4748
  const rawTotal = res.total;
4748
4749
  const rawPerPage = res.per_page;
4749
- const lastPage = Math.ceil(rawTotal / rawPerPage);
4750
+ const rawLastPage = res.last_page;
4751
+ const lastPage = rawLastPage ?? Math.ceil(rawTotal / rawPerPage);
4750
4752
  const pg = res.pagination ?? {
4751
4753
  first_page_url: res.first_page_url ?? `${url}?page=1`,
4752
4754
  last_page_url: res.last_page_url ?? `${url}?page=${lastPage}`,
4755
+ last_page: lastPage,
4753
4756
  next_page_url: res.next_page_url !== void 0 ? res.next_page_url : currentPage < lastPage ? `${url}?page=${currentPage + 1}` : null,
4754
4757
  prev_page_url: res.prev_page_url !== void 0 ? res.prev_page_url : currentPage > 1 ? `${url}?page=${currentPage - 1}` : null,
4755
4758
  per_page: rawPerPage,
@@ -4788,23 +4791,26 @@ function useServerDataGrid({ url, params }) {
4788
4791
  };
4789
4792
  }
4790
4793
  function DGModalShell({ title, onClose, children, footer }) {
4791
- return /* @__PURE__ */ jsx28(
4792
- "div",
4793
- {
4794
- className: "fixed inset-0 z-50 flex items-center justify-center p-4",
4795
- style: { background: "rgba(0,0,0,0.5)" },
4796
- onMouseDown: (e) => {
4797
- if (e.target === e.currentTarget) onClose();
4798
- },
4799
- children: /* @__PURE__ */ jsxs27("div", { className: "relative w-full max-w-lg rounded-2xl border border-border bg-card shadow-2xl flex flex-col max-h-[90vh]", children: [
4800
- /* @__PURE__ */ jsxs27("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border shrink-0", children: [
4801
- /* @__PURE__ */ jsx28("h2", { className: "text-base font-semibold", children: title }),
4802
- /* @__PURE__ */ jsx28("button", { onClick: onClose, className: "text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ jsx28(X7, { className: "h-4 w-4" }) })
4803
- ] }),
4804
- /* @__PURE__ */ jsx28("div", { className: "overflow-y-auto px-6 py-4 flex-1", children }),
4805
- footer && /* @__PURE__ */ jsx28("div", { className: "px-6 py-4 border-t border-border shrink-0 flex justify-end gap-2", children: footer })
4806
- ] })
4807
- }
4794
+ return createPortal2(
4795
+ /* @__PURE__ */ jsx28(
4796
+ "div",
4797
+ {
4798
+ className: "fixed inset-0 z-50 flex items-center justify-center p-4",
4799
+ style: { background: "rgba(0,0,0,0.5)" },
4800
+ onMouseDown: (e) => {
4801
+ if (e.target === e.currentTarget) onClose();
4802
+ },
4803
+ children: /* @__PURE__ */ jsxs27("div", { className: "relative w-full max-w-lg rounded-2xl border border-border bg-card shadow-2xl flex flex-col max-h-[90vh]", children: [
4804
+ /* @__PURE__ */ jsxs27("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border shrink-0", children: [
4805
+ /* @__PURE__ */ jsx28("h2", { className: "text-base font-semibold", children: title }),
4806
+ /* @__PURE__ */ jsx28("button", { onClick: onClose, className: "text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ jsx28(X7, { className: "h-4 w-4" }) })
4807
+ ] }),
4808
+ /* @__PURE__ */ jsx28("div", { className: "overflow-y-auto px-6 py-4 flex-1", children }),
4809
+ footer && /* @__PURE__ */ jsx28("div", { className: "px-6 py-4 border-t border-border shrink-0 flex justify-end gap-2", children: footer })
4810
+ ] })
4811
+ }
4812
+ ),
4813
+ document.body
4808
4814
  );
4809
4815
  }
4810
4816
  function DGFieldRenderer({ field, value, onChange }) {
@@ -5118,7 +5124,10 @@ function DataGrid({
5118
5124
  )
5119
5125
  ] })
5120
5126
  } : null;
5121
- const visibleCols = [
5127
+ const visibleCols = defaultActions?.position === "first" ? [
5128
+ ...actionsCol ? [actionsCol] : [],
5129
+ ...columns.filter((c) => !hiddenCols.includes(String(c.key)))
5130
+ ] : [
5122
5131
  ...columns.filter((c) => !hiddenCols.includes(String(c.key))),
5123
5132
  ...actionsCol ? [actionsCol] : []
5124
5133
  ];
@@ -5258,7 +5267,7 @@ function DataGrid({
5258
5267
  ),
5259
5268
  serverPagination && (() => {
5260
5269
  const { pagination, currentPage: cp, goToPage } = serverPagination;
5261
- const totalServerPages = Math.ceil(pagination.total / pagination.per_page);
5270
+ const totalServerPages = pagination.last_page ?? Math.ceil(pagination.total / pagination.per_page);
5262
5271
  const pageLinks = Array.from({ length: totalServerPages }, (_, i) => i + 1);
5263
5272
  return /* @__PURE__ */ jsxs27("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
5264
5273
  /* @__PURE__ */ jsxs27("span", { className: "text-xs text-muted-foreground", children: [
@@ -9369,6 +9378,7 @@ function Stepper({
9369
9378
 
9370
9379
  // src/components/ui/table.tsx
9371
9380
  import * as React44 from "react";
9381
+ import { createPortal as createPortal4 } from "react-dom";
9372
9382
  import axios2 from "axios";
9373
9383
  import { ChevronLeft as ChevronLeft6, ChevronRight as ChevronRight9, Search as Search5, Trash2 as Trash23, ChevronsUpDown as ChevronsUpDown2, ChevronUp as ChevronUp2, ChevronDown as ChevronDown7, X as X13, Eye as Eye2, Pencil as Pencil2, Trash as Trash3, Loader2 as Loader22 } from "lucide-react";
9374
9384
  import { Fragment as Fragment15, jsx as jsx55, jsxs as jsxs48 } from "react/jsx-runtime";
@@ -9391,10 +9401,12 @@ function useServerTable({ url, params }) {
9391
9401
  setData(res.data);
9392
9402
  const rawTotal = res.total;
9393
9403
  const rawPerPage = res.per_page;
9394
- const lastPage = Math.ceil(rawTotal / rawPerPage);
9404
+ const rawLastPage = res.last_page;
9405
+ const lastPage = rawLastPage ?? Math.ceil(rawTotal / rawPerPage);
9395
9406
  const pg = res.pagination ?? {
9396
9407
  first_page_url: res.first_page_url ?? `${url}?page=1`,
9397
9408
  last_page_url: res.last_page_url ?? `${url}?page=${lastPage}`,
9409
+ last_page: lastPage,
9398
9410
  next_page_url: res.next_page_url !== void 0 ? res.next_page_url : currentPage < lastPage ? `${url}?page=${currentPage + 1}` : null,
9399
9411
  prev_page_url: res.prev_page_url !== void 0 ? res.prev_page_url : currentPage > 1 ? `${url}?page=${currentPage - 1}` : null,
9400
9412
  per_page: rawPerPage,
@@ -9433,23 +9445,26 @@ function useServerTable({ url, params }) {
9433
9445
  };
9434
9446
  }
9435
9447
  function ModalShell({ title, onClose, children, footer }) {
9436
- return /* @__PURE__ */ jsx55(
9437
- "div",
9438
- {
9439
- className: "fixed inset-0 z-50 flex items-center justify-center p-4",
9440
- style: { background: "rgba(0,0,0,0.5)" },
9441
- onMouseDown: (e) => {
9442
- if (e.target === e.currentTarget) onClose();
9443
- },
9444
- children: /* @__PURE__ */ jsxs48("div", { className: "relative w-full max-w-lg rounded-2xl border border-border bg-card shadow-2xl flex flex-col max-h-[90vh]", children: [
9445
- /* @__PURE__ */ jsxs48("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border shrink-0", children: [
9446
- /* @__PURE__ */ jsx55("h2", { className: "text-base font-semibold", children: title }),
9447
- /* @__PURE__ */ jsx55("button", { onClick: onClose, className: "text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ jsx55(X13, { className: "h-4 w-4" }) })
9448
- ] }),
9449
- /* @__PURE__ */ jsx55("div", { className: "overflow-y-auto px-6 py-4 flex-1", children }),
9450
- footer && /* @__PURE__ */ jsx55("div", { className: "px-6 py-4 border-t border-border shrink-0 flex justify-end gap-2", children: footer })
9451
- ] })
9452
- }
9448
+ return createPortal4(
9449
+ /* @__PURE__ */ jsx55(
9450
+ "div",
9451
+ {
9452
+ className: "fixed inset-0 z-50 flex items-center justify-center p-4",
9453
+ style: { background: "rgba(0,0,0,0.5)" },
9454
+ onMouseDown: (e) => {
9455
+ if (e.target === e.currentTarget) onClose();
9456
+ },
9457
+ children: /* @__PURE__ */ jsxs48("div", { className: "relative w-full max-w-lg rounded-2xl border border-border bg-card shadow-2xl flex flex-col max-h-[90vh]", children: [
9458
+ /* @__PURE__ */ jsxs48("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border shrink-0", children: [
9459
+ /* @__PURE__ */ jsx55("h2", { className: "text-base font-semibold", children: title }),
9460
+ /* @__PURE__ */ jsx55("button", { onClick: onClose, className: "text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ jsx55(X13, { className: "h-4 w-4" }) })
9461
+ ] }),
9462
+ /* @__PURE__ */ jsx55("div", { className: "overflow-y-auto px-6 py-4 flex-1", children }),
9463
+ footer && /* @__PURE__ */ jsx55("div", { className: "px-6 py-4 border-t border-border shrink-0 flex justify-end gap-2", children: footer })
9464
+ ] })
9465
+ }
9466
+ ),
9467
+ document.body
9453
9468
  );
9454
9469
  }
9455
9470
  function FieldRenderer({ field, value, onChange }) {
@@ -9792,7 +9807,7 @@ function Table({
9792
9807
  )
9793
9808
  ] })
9794
9809
  };
9795
- return [...columns, actionsCol];
9810
+ return defaultActions.position === "first" ? [actionsCol, ...columns] : [...columns, actionsCol];
9796
9811
  }, [columns, defaultActions]);
9797
9812
  const handleSort = (key) => {
9798
9813
  if (sortKey !== key) {
@@ -9888,9 +9903,9 @@ function Table({
9888
9903
  }
9889
9904
  ),
9890
9905
  /* @__PURE__ */ jsxs48("span", { className: "text-xs text-muted-foreground", children: [
9891
- filteredData.length,
9906
+ serverPagination ? serverPagination.pagination.total : filteredData.length,
9892
9907
  " ",
9893
- filteredData.length === 1 ? "row" : "rows",
9908
+ (serverPagination ? serverPagination.pagination.total : filteredData.length) === 1 ? "row" : "rows",
9894
9909
  search && ` \xB7 filtered from ${tableData.length}`
9895
9910
  ] })
9896
9911
  ] })
@@ -10064,7 +10079,7 @@ function Table({
10064
10079
  ] }),
10065
10080
  serverPagination && (() => {
10066
10081
  const { pagination: pagination2, currentPage: cp, goToPage } = serverPagination;
10067
- const totalServerPages = Math.ceil(pagination2.total / pagination2.per_page);
10082
+ const totalServerPages = pagination2.last_page ?? Math.ceil(pagination2.total / pagination2.per_page);
10068
10083
  const pageLinks = Array.from({ length: totalServerPages }, (_, i) => i + 1);
10069
10084
  return /* @__PURE__ */ jsxs48("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
10070
10085
  /* @__PURE__ */ jsxs48("span", { className: "text-xs text-muted-foreground", children: [
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "registry": "https://registry.npmjs.org/",
5
5
  "access": "public"
6
6
  },
7
- "version": "3.0.8",
7
+ "version": "3.1.0",
8
8
  "description": "Reusable React UI components",
9
9
  "license": "MIT",
10
10
  "main": "dist/index.js",