@juv/codego-react-ui 3.0.7 → 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
 
@@ -4858,7 +4859,21 @@ function useServerDataGrid({ url, params }) {
4858
4859
  import_axios.default.get(url, { params: { ...params, page: currentPage } }).then(({ data: res }) => {
4859
4860
  if (cancelled) return;
4860
4861
  setData(res.data);
4861
- setPagination(res.pagination);
4862
+ const rawTotal = res.total;
4863
+ const rawPerPage = res.per_page;
4864
+ const rawLastPage = res.last_page;
4865
+ const lastPage = rawLastPage ?? Math.ceil(rawTotal / rawPerPage);
4866
+ const pg = res.pagination ?? {
4867
+ first_page_url: res.first_page_url ?? `${url}?page=1`,
4868
+ last_page_url: res.last_page_url ?? `${url}?page=${lastPage}`,
4869
+ last_page: lastPage,
4870
+ next_page_url: res.next_page_url !== void 0 ? res.next_page_url : currentPage < lastPage ? `${url}?page=${currentPage + 1}` : null,
4871
+ prev_page_url: res.prev_page_url !== void 0 ? res.prev_page_url : currentPage > 1 ? `${url}?page=${currentPage - 1}` : null,
4872
+ per_page: rawPerPage,
4873
+ total: rawTotal,
4874
+ links: res.links ?? []
4875
+ };
4876
+ setPagination(pg);
4862
4877
  if (res.data.length > 0) {
4863
4878
  setColumns(
4864
4879
  Object.keys(res.data[0]).map((key) => ({
@@ -4890,23 +4905,26 @@ function useServerDataGrid({ url, params }) {
4890
4905
  };
4891
4906
  }
4892
4907
  function DGModalShell({ title, onClose, children, footer }) {
4893
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4894
- "div",
4895
- {
4896
- className: "fixed inset-0 z-50 flex items-center justify-center p-4",
4897
- style: { background: "rgba(0,0,0,0.5)" },
4898
- onMouseDown: (e) => {
4899
- if (e.target === e.currentTarget) onClose();
4900
- },
4901
- 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: [
4902
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border shrink-0", children: [
4903
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("h2", { className: "text-base font-semibold", children: title }),
4904
- /* @__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" }) })
4905
- ] }),
4906
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "overflow-y-auto px-6 py-4 flex-1", children }),
4907
- 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 })
4908
- ] })
4909
- }
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
4910
4928
  );
4911
4929
  }
4912
4930
  function DGFieldRenderer({ field, value, onChange }) {
@@ -5220,7 +5238,10 @@ function DataGrid({
5220
5238
  )
5221
5239
  ] })
5222
5240
  } : null;
5223
- const visibleCols = [
5241
+ const visibleCols = defaultActions?.position === "first" ? [
5242
+ ...actionsCol ? [actionsCol] : [],
5243
+ ...columns.filter((c) => !hiddenCols.includes(String(c.key)))
5244
+ ] : [
5224
5245
  ...columns.filter((c) => !hiddenCols.includes(String(c.key))),
5225
5246
  ...actionsCol ? [actionsCol] : []
5226
5247
  ];
@@ -5360,7 +5381,7 @@ function DataGrid({
5360
5381
  ),
5361
5382
  serverPagination && (() => {
5362
5383
  const { pagination, currentPage: cp, goToPage } = serverPagination;
5363
- const totalServerPages = Math.ceil(pagination.total / pagination.per_page);
5384
+ const totalServerPages = pagination.last_page ?? Math.ceil(pagination.total / pagination.per_page);
5364
5385
  const pageLinks = Array.from({ length: totalServerPages }, (_, i) => i + 1);
5365
5386
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
5366
5387
  /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
@@ -9471,6 +9492,7 @@ function Stepper({
9471
9492
 
9472
9493
  // src/components/ui/table.tsx
9473
9494
  var React44 = __toESM(require("react"), 1);
9495
+ var import_react_dom2 = require("react-dom");
9474
9496
  var import_axios2 = __toESM(require("axios"), 1);
9475
9497
  var import_lucide_react28 = require("lucide-react");
9476
9498
  var import_jsx_runtime55 = require("react/jsx-runtime");
@@ -9491,7 +9513,21 @@ function useServerTable({ url, params }) {
9491
9513
  }).then(({ data: res }) => {
9492
9514
  if (cancelled) return;
9493
9515
  setData(res.data);
9494
- setPagination(res.pagination);
9516
+ const rawTotal = res.total;
9517
+ const rawPerPage = res.per_page;
9518
+ const rawLastPage = res.last_page;
9519
+ const lastPage = rawLastPage ?? Math.ceil(rawTotal / rawPerPage);
9520
+ const pg = res.pagination ?? {
9521
+ first_page_url: res.first_page_url ?? `${url}?page=1`,
9522
+ last_page_url: res.last_page_url ?? `${url}?page=${lastPage}`,
9523
+ last_page: lastPage,
9524
+ next_page_url: res.next_page_url !== void 0 ? res.next_page_url : currentPage < lastPage ? `${url}?page=${currentPage + 1}` : null,
9525
+ prev_page_url: res.prev_page_url !== void 0 ? res.prev_page_url : currentPage > 1 ? `${url}?page=${currentPage - 1}` : null,
9526
+ per_page: rawPerPage,
9527
+ total: rawTotal,
9528
+ links: res.links ?? []
9529
+ };
9530
+ setPagination(pg);
9495
9531
  if (res.data.length > 0) {
9496
9532
  setColumns(
9497
9533
  Object.keys(res.data[0]).map((key) => ({
@@ -9523,23 +9559,26 @@ function useServerTable({ url, params }) {
9523
9559
  };
9524
9560
  }
9525
9561
  function ModalShell({ title, onClose, children, footer }) {
9526
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
9527
- "div",
9528
- {
9529
- className: "fixed inset-0 z-50 flex items-center justify-center p-4",
9530
- style: { background: "rgba(0,0,0,0.5)" },
9531
- onMouseDown: (e) => {
9532
- if (e.target === e.currentTarget) onClose();
9533
- },
9534
- 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: [
9535
- /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border shrink-0", children: [
9536
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("h2", { className: "text-base font-semibold", children: title }),
9537
- /* @__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" }) })
9538
- ] }),
9539
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "overflow-y-auto px-6 py-4 flex-1", children }),
9540
- 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 })
9541
- ] })
9542
- }
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
9543
9582
  );
9544
9583
  }
9545
9584
  function FieldRenderer({ field, value, onChange }) {
@@ -9882,7 +9921,7 @@ function Table({
9882
9921
  )
9883
9922
  ] })
9884
9923
  };
9885
- return [...columns, actionsCol];
9924
+ return defaultActions.position === "first" ? [actionsCol, ...columns] : [...columns, actionsCol];
9886
9925
  }, [columns, defaultActions]);
9887
9926
  const handleSort = (key) => {
9888
9927
  if (sortKey !== key) {
@@ -9978,9 +10017,9 @@ function Table({
9978
10017
  }
9979
10018
  ),
9980
10019
  /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
9981
- filteredData.length,
10020
+ serverPagination ? serverPagination.pagination.total : filteredData.length,
9982
10021
  " ",
9983
- filteredData.length === 1 ? "row" : "rows",
10022
+ (serverPagination ? serverPagination.pagination.total : filteredData.length) === 1 ? "row" : "rows",
9984
10023
  search && ` \xB7 filtered from ${tableData.length}`
9985
10024
  ] })
9986
10025
  ] })
@@ -10154,7 +10193,7 @@ function Table({
10154
10193
  ] }),
10155
10194
  serverPagination && (() => {
10156
10195
  const { pagination: pagination2, currentPage: cp, goToPage } = serverPagination;
10157
- const totalServerPages = Math.ceil(pagination2.total / pagination2.per_page);
10196
+ const totalServerPages = pagination2.last_page ?? Math.ceil(pagination2.total / pagination2.per_page);
10158
10197
  const pageLinks = Array.from({ length: totalServerPages }, (_, i) => i + 1);
10159
10198
  return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
10160
10199
  /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
package/dist/index.d.cts CHANGED
@@ -344,16 +344,17 @@ 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;
350
351
  total: number;
351
352
  links: ServerPaginationLink[];
352
353
  }
353
- interface ServerTableResponse<T> {
354
+ interface ServerTableResponse<T> extends ServerPagination {
354
355
  current_page: number;
355
356
  data: T[];
356
- pagination: ServerPagination;
357
+ pagination?: ServerPagination;
357
358
  }
358
359
  interface UseServerTableOptions {
359
360
  /** Base URL — page param appended automatically: `url?page=N` */
@@ -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,16 +344,17 @@ 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;
350
351
  total: number;
351
352
  links: ServerPaginationLink[];
352
353
  }
353
- interface ServerTableResponse<T> {
354
+ interface ServerTableResponse<T> extends ServerPagination {
354
355
  current_page: number;
355
356
  data: T[];
356
- pagination: ServerPagination;
357
+ pagination?: ServerPagination;
357
358
  }
358
359
  interface UseServerTableOptions {
359
360
  /** Base URL — page param appended automatically: `url?page=N` */
@@ -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) {
@@ -61433,7 +61434,21 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
61433
61434
  axios_default.get(url2, { params: { ...params, page: currentPage } }).then(({ data: res }) => {
61434
61435
  if (cancelled) return;
61435
61436
  setData(res.data);
61436
- setPagination(res.pagination);
61437
+ const rawTotal = res.total;
61438
+ const rawPerPage = res.per_page;
61439
+ const rawLastPage = res.last_page;
61440
+ const lastPage = rawLastPage ?? Math.ceil(rawTotal / rawPerPage);
61441
+ const pg = res.pagination ?? {
61442
+ first_page_url: res.first_page_url ?? `${url2}?page=1`,
61443
+ last_page_url: res.last_page_url ?? `${url2}?page=${lastPage}`,
61444
+ last_page: lastPage,
61445
+ next_page_url: res.next_page_url !== void 0 ? res.next_page_url : currentPage < lastPage ? `${url2}?page=${currentPage + 1}` : null,
61446
+ prev_page_url: res.prev_page_url !== void 0 ? res.prev_page_url : currentPage > 1 ? `${url2}?page=${currentPage - 1}` : null,
61447
+ per_page: rawPerPage,
61448
+ total: rawTotal,
61449
+ links: res.links ?? []
61450
+ };
61451
+ setPagination(pg);
61437
61452
  if (res.data.length > 0) {
61438
61453
  setColumns(
61439
61454
  Object.keys(res.data[0]).map((key) => ({
@@ -61465,23 +61480,26 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
61465
61480
  };
61466
61481
  }
61467
61482
  function DGModalShell({ title, onClose, children, footer }) {
61468
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
61469
- "div",
61470
- {
61471
- className: "fixed inset-0 z-50 flex items-center justify-center p-4",
61472
- style: { background: "rgba(0,0,0,0.5)" },
61473
- onMouseDown: (e) => {
61474
- if (e.target === e.currentTarget) onClose();
61475
- },
61476
- 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: [
61477
- /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border shrink-0", children: [
61478
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("h2", { className: "text-base font-semibold", children: title }),
61479
- /* @__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" }) })
61480
- ] }),
61481
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("div", { className: "overflow-y-auto px-6 py-4 flex-1", children }),
61482
- 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 })
61483
- ] })
61484
- }
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
61485
61503
  );
61486
61504
  }
61487
61505
  function DGFieldRenderer({ field, value, onChange }) {
@@ -61795,7 +61813,10 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
61795
61813
  )
61796
61814
  ] })
61797
61815
  } : null;
61798
- const visibleCols = [
61816
+ const visibleCols = defaultActions?.position === "first" ? [
61817
+ ...actionsCol ? [actionsCol] : [],
61818
+ ...columns.filter((c) => !hiddenCols.includes(String(c.key)))
61819
+ ] : [
61799
61820
  ...columns.filter((c) => !hiddenCols.includes(String(c.key))),
61800
61821
  ...actionsCol ? [actionsCol] : []
61801
61822
  ];
@@ -61935,7 +61956,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
61935
61956
  ),
61936
61957
  serverPagination && (() => {
61937
61958
  const { pagination, currentPage: cp, goToPage } = serverPagination;
61938
- const totalServerPages = Math.ceil(pagination.total / pagination.per_page);
61959
+ const totalServerPages = pagination.last_page ?? Math.ceil(pagination.total / pagination.per_page);
61939
61960
  const pageLinks = Array.from({ length: totalServerPages }, (_, i) => i + 1);
61940
61961
  return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
61941
61962
  /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
@@ -62586,7 +62607,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
62586
62607
 
62587
62608
  // node_modules/@react-leaflet/core/lib/component.js
62588
62609
  var import_react5 = __toESM(require_react(), 1);
62589
- var import_react_dom = __toESM(require_react_dom(), 1);
62610
+ var import_react_dom2 = __toESM(require_react_dom(), 1);
62590
62611
 
62591
62612
  // node_modules/@react-leaflet/core/lib/context.js
62592
62613
  var import_react4 = __toESM(require_react(), 1);
@@ -62639,7 +62660,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
62639
62660
  props.children
62640
62661
  ]);
62641
62662
  const contentNode = instance._contentNode;
62642
- 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;
62643
62664
  }
62644
62665
  return /* @__PURE__ */ (0, import_react5.forwardRef)(OverlayComponent);
62645
62666
  }
@@ -66459,6 +66480,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
66459
66480
 
66460
66481
  // src/components/ui/table.tsx
66461
66482
  var React46 = __toESM(require_react(), 1);
66483
+ var import_react_dom3 = __toESM(require_react_dom(), 1);
66462
66484
  var import_jsx_runtime55 = __toESM(require_jsx_runtime(), 1);
66463
66485
  function useServerTable({ url: url2, params }) {
66464
66486
  const [data, setData] = React46.useState([]);
@@ -66477,7 +66499,21 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
66477
66499
  }).then(({ data: res }) => {
66478
66500
  if (cancelled) return;
66479
66501
  setData(res.data);
66480
- setPagination(res.pagination);
66502
+ const rawTotal = res.total;
66503
+ const rawPerPage = res.per_page;
66504
+ const rawLastPage = res.last_page;
66505
+ const lastPage = rawLastPage ?? Math.ceil(rawTotal / rawPerPage);
66506
+ const pg = res.pagination ?? {
66507
+ first_page_url: res.first_page_url ?? `${url2}?page=1`,
66508
+ last_page_url: res.last_page_url ?? `${url2}?page=${lastPage}`,
66509
+ last_page: lastPage,
66510
+ next_page_url: res.next_page_url !== void 0 ? res.next_page_url : currentPage < lastPage ? `${url2}?page=${currentPage + 1}` : null,
66511
+ prev_page_url: res.prev_page_url !== void 0 ? res.prev_page_url : currentPage > 1 ? `${url2}?page=${currentPage - 1}` : null,
66512
+ per_page: rawPerPage,
66513
+ total: rawTotal,
66514
+ links: res.links ?? []
66515
+ };
66516
+ setPagination(pg);
66481
66517
  if (res.data.length > 0) {
66482
66518
  setColumns(
66483
66519
  Object.keys(res.data[0]).map((key) => ({
@@ -66509,23 +66545,26 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
66509
66545
  };
66510
66546
  }
66511
66547
  function ModalShell({ title, onClose, children, footer }) {
66512
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
66513
- "div",
66514
- {
66515
- className: "fixed inset-0 z-50 flex items-center justify-center p-4",
66516
- style: { background: "rgba(0,0,0,0.5)" },
66517
- onMouseDown: (e) => {
66518
- if (e.target === e.currentTarget) onClose();
66519
- },
66520
- 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: [
66521
- /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border shrink-0", children: [
66522
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("h2", { className: "text-base font-semibold", children: title }),
66523
- /* @__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" }) })
66524
- ] }),
66525
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "overflow-y-auto px-6 py-4 flex-1", children }),
66526
- 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 })
66527
- ] })
66528
- }
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
66529
66568
  );
66530
66569
  }
66531
66570
  function FieldRenderer({ field, value, onChange }) {
@@ -66868,7 +66907,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
66868
66907
  )
66869
66908
  ] })
66870
66909
  };
66871
- return [...columns, actionsCol];
66910
+ return defaultActions.position === "first" ? [actionsCol, ...columns] : [...columns, actionsCol];
66872
66911
  }, [columns, defaultActions]);
66873
66912
  const handleSort = (key) => {
66874
66913
  if (sortKey !== key) {
@@ -66964,9 +67003,9 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
66964
67003
  }
66965
67004
  ),
66966
67005
  /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("span", { className: "text-xs text-muted-foreground", children: [
66967
- filteredData.length,
67006
+ serverPagination ? serverPagination.pagination.total : filteredData.length,
66968
67007
  " ",
66969
- filteredData.length === 1 ? "row" : "rows",
67008
+ (serverPagination ? serverPagination.pagination.total : filteredData.length) === 1 ? "row" : "rows",
66970
67009
  search && ` \xB7 filtered from ${tableData.length}`
66971
67010
  ] })
66972
67011
  ] })
@@ -67140,7 +67179,7 @@ ${n2.shaderPreludeCode.vertexSource}`, define: n2.shaderDefine }, defaultProject
67140
67179
  ] }),
67141
67180
  serverPagination && (() => {
67142
67181
  const { pagination: pagination2, currentPage: cp, goToPage } = serverPagination;
67143
- const totalServerPages = Math.ceil(pagination2.total / pagination2.per_page);
67182
+ const totalServerPages = pagination2.last_page ?? Math.ceil(pagination2.total / pagination2.per_page);
67144
67183
  const pageLinks = Array.from({ length: totalServerPages }, (_, i) => i + 1);
67145
67184
  return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
67146
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
 
@@ -4744,7 +4745,21 @@ function useServerDataGrid({ url, params }) {
4744
4745
  axios.get(url, { params: { ...params, page: currentPage } }).then(({ data: res }) => {
4745
4746
  if (cancelled) return;
4746
4747
  setData(res.data);
4747
- setPagination(res.pagination);
4748
+ const rawTotal = res.total;
4749
+ const rawPerPage = res.per_page;
4750
+ const rawLastPage = res.last_page;
4751
+ const lastPage = rawLastPage ?? Math.ceil(rawTotal / rawPerPage);
4752
+ const pg = res.pagination ?? {
4753
+ first_page_url: res.first_page_url ?? `${url}?page=1`,
4754
+ last_page_url: res.last_page_url ?? `${url}?page=${lastPage}`,
4755
+ last_page: lastPage,
4756
+ next_page_url: res.next_page_url !== void 0 ? res.next_page_url : currentPage < lastPage ? `${url}?page=${currentPage + 1}` : null,
4757
+ prev_page_url: res.prev_page_url !== void 0 ? res.prev_page_url : currentPage > 1 ? `${url}?page=${currentPage - 1}` : null,
4758
+ per_page: rawPerPage,
4759
+ total: rawTotal,
4760
+ links: res.links ?? []
4761
+ };
4762
+ setPagination(pg);
4748
4763
  if (res.data.length > 0) {
4749
4764
  setColumns(
4750
4765
  Object.keys(res.data[0]).map((key) => ({
@@ -4776,23 +4791,26 @@ function useServerDataGrid({ url, params }) {
4776
4791
  };
4777
4792
  }
4778
4793
  function DGModalShell({ title, onClose, children, footer }) {
4779
- return /* @__PURE__ */ jsx28(
4780
- "div",
4781
- {
4782
- className: "fixed inset-0 z-50 flex items-center justify-center p-4",
4783
- style: { background: "rgba(0,0,0,0.5)" },
4784
- onMouseDown: (e) => {
4785
- if (e.target === e.currentTarget) onClose();
4786
- },
4787
- 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: [
4788
- /* @__PURE__ */ jsxs27("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border shrink-0", children: [
4789
- /* @__PURE__ */ jsx28("h2", { className: "text-base font-semibold", children: title }),
4790
- /* @__PURE__ */ jsx28("button", { onClick: onClose, className: "text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ jsx28(X7, { className: "h-4 w-4" }) })
4791
- ] }),
4792
- /* @__PURE__ */ jsx28("div", { className: "overflow-y-auto px-6 py-4 flex-1", children }),
4793
- footer && /* @__PURE__ */ jsx28("div", { className: "px-6 py-4 border-t border-border shrink-0 flex justify-end gap-2", children: footer })
4794
- ] })
4795
- }
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
4796
4814
  );
4797
4815
  }
4798
4816
  function DGFieldRenderer({ field, value, onChange }) {
@@ -5106,7 +5124,10 @@ function DataGrid({
5106
5124
  )
5107
5125
  ] })
5108
5126
  } : null;
5109
- const visibleCols = [
5127
+ const visibleCols = defaultActions?.position === "first" ? [
5128
+ ...actionsCol ? [actionsCol] : [],
5129
+ ...columns.filter((c) => !hiddenCols.includes(String(c.key)))
5130
+ ] : [
5110
5131
  ...columns.filter((c) => !hiddenCols.includes(String(c.key))),
5111
5132
  ...actionsCol ? [actionsCol] : []
5112
5133
  ];
@@ -5246,7 +5267,7 @@ function DataGrid({
5246
5267
  ),
5247
5268
  serverPagination && (() => {
5248
5269
  const { pagination, currentPage: cp, goToPage } = serverPagination;
5249
- const totalServerPages = Math.ceil(pagination.total / pagination.per_page);
5270
+ const totalServerPages = pagination.last_page ?? Math.ceil(pagination.total / pagination.per_page);
5250
5271
  const pageLinks = Array.from({ length: totalServerPages }, (_, i) => i + 1);
5251
5272
  return /* @__PURE__ */ jsxs27("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
5252
5273
  /* @__PURE__ */ jsxs27("span", { className: "text-xs text-muted-foreground", children: [
@@ -9357,6 +9378,7 @@ function Stepper({
9357
9378
 
9358
9379
  // src/components/ui/table.tsx
9359
9380
  import * as React44 from "react";
9381
+ import { createPortal as createPortal4 } from "react-dom";
9360
9382
  import axios2 from "axios";
9361
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";
9362
9384
  import { Fragment as Fragment15, jsx as jsx55, jsxs as jsxs48 } from "react/jsx-runtime";
@@ -9377,7 +9399,21 @@ function useServerTable({ url, params }) {
9377
9399
  }).then(({ data: res }) => {
9378
9400
  if (cancelled) return;
9379
9401
  setData(res.data);
9380
- setPagination(res.pagination);
9402
+ const rawTotal = res.total;
9403
+ const rawPerPage = res.per_page;
9404
+ const rawLastPage = res.last_page;
9405
+ const lastPage = rawLastPage ?? Math.ceil(rawTotal / rawPerPage);
9406
+ const pg = res.pagination ?? {
9407
+ first_page_url: res.first_page_url ?? `${url}?page=1`,
9408
+ last_page_url: res.last_page_url ?? `${url}?page=${lastPage}`,
9409
+ last_page: lastPage,
9410
+ next_page_url: res.next_page_url !== void 0 ? res.next_page_url : currentPage < lastPage ? `${url}?page=${currentPage + 1}` : null,
9411
+ prev_page_url: res.prev_page_url !== void 0 ? res.prev_page_url : currentPage > 1 ? `${url}?page=${currentPage - 1}` : null,
9412
+ per_page: rawPerPage,
9413
+ total: rawTotal,
9414
+ links: res.links ?? []
9415
+ };
9416
+ setPagination(pg);
9381
9417
  if (res.data.length > 0) {
9382
9418
  setColumns(
9383
9419
  Object.keys(res.data[0]).map((key) => ({
@@ -9409,23 +9445,26 @@ function useServerTable({ url, params }) {
9409
9445
  };
9410
9446
  }
9411
9447
  function ModalShell({ title, onClose, children, footer }) {
9412
- return /* @__PURE__ */ jsx55(
9413
- "div",
9414
- {
9415
- className: "fixed inset-0 z-50 flex items-center justify-center p-4",
9416
- style: { background: "rgba(0,0,0,0.5)" },
9417
- onMouseDown: (e) => {
9418
- if (e.target === e.currentTarget) onClose();
9419
- },
9420
- 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: [
9421
- /* @__PURE__ */ jsxs48("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border shrink-0", children: [
9422
- /* @__PURE__ */ jsx55("h2", { className: "text-base font-semibold", children: title }),
9423
- /* @__PURE__ */ jsx55("button", { onClick: onClose, className: "text-muted-foreground hover:text-foreground transition-colors", children: /* @__PURE__ */ jsx55(X13, { className: "h-4 w-4" }) })
9424
- ] }),
9425
- /* @__PURE__ */ jsx55("div", { className: "overflow-y-auto px-6 py-4 flex-1", children }),
9426
- footer && /* @__PURE__ */ jsx55("div", { className: "px-6 py-4 border-t border-border shrink-0 flex justify-end gap-2", children: footer })
9427
- ] })
9428
- }
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
9429
9468
  );
9430
9469
  }
9431
9470
  function FieldRenderer({ field, value, onChange }) {
@@ -9768,7 +9807,7 @@ function Table({
9768
9807
  )
9769
9808
  ] })
9770
9809
  };
9771
- return [...columns, actionsCol];
9810
+ return defaultActions.position === "first" ? [actionsCol, ...columns] : [...columns, actionsCol];
9772
9811
  }, [columns, defaultActions]);
9773
9812
  const handleSort = (key) => {
9774
9813
  if (sortKey !== key) {
@@ -9864,9 +9903,9 @@ function Table({
9864
9903
  }
9865
9904
  ),
9866
9905
  /* @__PURE__ */ jsxs48("span", { className: "text-xs text-muted-foreground", children: [
9867
- filteredData.length,
9906
+ serverPagination ? serverPagination.pagination.total : filteredData.length,
9868
9907
  " ",
9869
- filteredData.length === 1 ? "row" : "rows",
9908
+ (serverPagination ? serverPagination.pagination.total : filteredData.length) === 1 ? "row" : "rows",
9870
9909
  search && ` \xB7 filtered from ${tableData.length}`
9871
9910
  ] })
9872
9911
  ] })
@@ -10040,7 +10079,7 @@ function Table({
10040
10079
  ] }),
10041
10080
  serverPagination && (() => {
10042
10081
  const { pagination: pagination2, currentPage: cp, goToPage } = serverPagination;
10043
- const totalServerPages = Math.ceil(pagination2.total / pagination2.per_page);
10082
+ const totalServerPages = pagination2.last_page ?? Math.ceil(pagination2.total / pagination2.per_page);
10044
10083
  const pageLinks = Array.from({ length: totalServerPages }, (_, i) => i + 1);
10045
10084
  return /* @__PURE__ */ jsxs48("div", { className: "flex items-center justify-between gap-2 flex-wrap", children: [
10046
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.7",
7
+ "version": "3.1.0",
8
8
  "description": "Reusable React UI components",
9
9
  "license": "MIT",
10
10
  "main": "dist/index.js",