@rovula/ui 0.1.28 → 0.1.29
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/cjs/bundle.css +501 -67
- package/dist/cjs/bundle.js +589 -589
- package/dist/cjs/bundle.js.map +1 -1
- package/dist/cjs/types/components/DataTable/DataTable.d.ts +195 -4
- package/dist/cjs/types/components/DataTable/DataTable.editing.d.ts +20 -0
- package/dist/cjs/types/components/DataTable/DataTable.editing.types.d.ts +145 -0
- package/dist/cjs/types/components/DataTable/DataTable.stories.d.ts +268 -6
- package/dist/cjs/types/components/Dropdown/Dropdown.d.ts +22 -0
- package/dist/cjs/types/components/Dropdown/Dropdown.stories.d.ts +4 -0
- package/dist/cjs/types/components/ScrollArea/ScrollArea.d.ts +3 -3
- package/dist/cjs/types/components/ScrollArea/ScrollArea.stories.d.ts +4 -0
- package/dist/cjs/types/components/Table/Table.d.ts +33 -3
- package/dist/cjs/types/components/Table/Table.stories.d.ts +86 -4
- package/dist/cjs/types/components/TextInput/TextInput.stories.d.ts +8 -0
- package/dist/cjs/types/components/TextInput/TextInput.styles.d.ts +1 -0
- package/dist/components/DataTable/DataTable.editing.js +385 -0
- package/dist/components/DataTable/DataTable.editing.types.js +1 -0
- package/dist/components/DataTable/DataTable.js +983 -50
- package/dist/components/DataTable/DataTable.stories.js +1077 -25
- package/dist/components/Dropdown/Dropdown.js +8 -6
- package/dist/components/ScrollArea/ScrollArea.js +2 -2
- package/dist/components/ScrollArea/ScrollArea.stories.js +68 -2
- package/dist/components/Table/Table.js +103 -13
- package/dist/components/Table/Table.stories.js +226 -9
- package/dist/components/TextInput/TextInput.js +6 -4
- package/dist/components/TextInput/TextInput.stories.js +8 -0
- package/dist/components/TextInput/TextInput.styles.js +7 -1
- package/dist/esm/bundle.css +501 -67
- package/dist/esm/bundle.js +1545 -1545
- package/dist/esm/bundle.js.map +1 -1
- package/dist/esm/types/components/DataTable/DataTable.d.ts +195 -4
- package/dist/esm/types/components/DataTable/DataTable.editing.d.ts +20 -0
- package/dist/esm/types/components/DataTable/DataTable.editing.types.d.ts +145 -0
- package/dist/esm/types/components/DataTable/DataTable.stories.d.ts +268 -6
- package/dist/esm/types/components/Dropdown/Dropdown.d.ts +22 -0
- package/dist/esm/types/components/Dropdown/Dropdown.stories.d.ts +4 -0
- package/dist/esm/types/components/ScrollArea/ScrollArea.d.ts +3 -3
- package/dist/esm/types/components/ScrollArea/ScrollArea.stories.d.ts +4 -0
- package/dist/esm/types/components/Table/Table.d.ts +33 -3
- package/dist/esm/types/components/Table/Table.stories.d.ts +86 -4
- package/dist/esm/types/components/TextInput/TextInput.stories.d.ts +8 -0
- package/dist/esm/types/components/TextInput/TextInput.styles.d.ts +1 -0
- package/dist/index.d.ts +493 -122
- package/dist/src/theme/global.css +747 -96
- package/package.json +14 -2
- package/src/components/DataTable/DataTable.editing.tsx +861 -0
- package/src/components/DataTable/DataTable.editing.types.ts +192 -0
- package/src/components/DataTable/DataTable.stories.tsx +2169 -31
- package/src/components/DataTable/DataTable.test.tsx +696 -0
- package/src/components/DataTable/DataTable.tsx +2260 -94
- package/src/components/Dropdown/Dropdown.tsx +22 -6
- package/src/components/ScrollArea/ScrollArea.stories.tsx +146 -3
- package/src/components/ScrollArea/ScrollArea.tsx +6 -6
- package/src/components/Table/Table.stories.tsx +789 -44
- package/src/components/Table/Table.tsx +294 -28
- package/src/components/TextInput/TextInput.stories.tsx +80 -0
- package/src/components/TextInput/TextInput.styles.ts +7 -1
- package/src/components/TextInput/TextInput.tsx +21 -14
- package/src/test/setup.ts +50 -0
- package/src/theme/global.css +81 -42
- package/src/theme/presets/colors.js +12 -0
- package/src/theme/themes/variable.css +27 -28
- package/src/theme/tokens/baseline.css +2 -1
- package/src/theme/tokens/components/scrollbar.css +9 -4
- package/src/theme/tokens/components/table.css +63 -0
|
@@ -41,6 +41,17 @@ export type DropdownProps = {
|
|
|
41
41
|
selectedOption: Options | null | undefined;
|
|
42
42
|
onClick: (option: Options) => void;
|
|
43
43
|
}) => ReactNode;
|
|
44
|
+
/**
|
|
45
|
+
* When `true`, keep focus on the input after selecting an option so the
|
|
46
|
+
* menu stays open (useful for inline row-editing where the user may Tab
|
|
47
|
+
* to the next field instead of closing the dropdown).
|
|
48
|
+
*/
|
|
49
|
+
keepOpenAfterSelect?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Render the options list via a React portal so it escapes containers
|
|
52
|
+
* with `overflow: hidden/auto` (e.g. DataTable scroll wrappers).
|
|
53
|
+
*/
|
|
54
|
+
portal?: boolean;
|
|
44
55
|
} & Omit<InputProps, "value" | "onSelect">;
|
|
45
56
|
declare const Dropdown: React.ForwardRefExoticComponent<{
|
|
46
57
|
id?: string;
|
|
@@ -71,5 +82,16 @@ declare const Dropdown: React.ForwardRefExoticComponent<{
|
|
|
71
82
|
selectedOption: Options | null | undefined;
|
|
72
83
|
onClick: (option: Options) => void;
|
|
73
84
|
}) => ReactNode;
|
|
85
|
+
/**
|
|
86
|
+
* When `true`, keep focus on the input after selecting an option so the
|
|
87
|
+
* menu stays open (useful for inline row-editing where the user may Tab
|
|
88
|
+
* to the next field instead of closing the dropdown).
|
|
89
|
+
*/
|
|
90
|
+
keepOpenAfterSelect?: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Render the options list via a React portal so it escapes containers
|
|
93
|
+
* with `overflow: hidden/auto` (e.g. DataTable scroll wrappers).
|
|
94
|
+
*/
|
|
95
|
+
portal?: boolean;
|
|
74
96
|
} & Omit<InputProps, "onSelect" | "value"> & React.RefAttributes<HTMLInputElement>>;
|
|
75
97
|
export default Dropdown;
|
|
@@ -31,6 +31,8 @@ declare const meta: {
|
|
|
31
31
|
selectedOption: Options | null | undefined;
|
|
32
32
|
onClick: (option: Options) => void;
|
|
33
33
|
}) => React.ReactNode;
|
|
34
|
+
keepOpenAfterSelect?: boolean;
|
|
35
|
+
portal?: boolean;
|
|
34
36
|
} & Omit<import("../..").InputProps, "onSelect" | "value"> & React.RefAttributes<HTMLInputElement>>;
|
|
35
37
|
tags: string[];
|
|
36
38
|
parameters: {
|
|
@@ -64,6 +66,8 @@ declare const meta: {
|
|
|
64
66
|
selectedOption: Options | null | undefined;
|
|
65
67
|
onClick: (option: Options) => void;
|
|
66
68
|
}) => React.ReactNode) | undefined;
|
|
69
|
+
keepOpenAfterSelect?: boolean | undefined;
|
|
70
|
+
portal?: boolean | undefined;
|
|
67
71
|
suppressHydrationWarning?: boolean | undefined | undefined;
|
|
68
72
|
color?: string | undefined | undefined;
|
|
69
73
|
height?: number | string | undefined | undefined;
|
|
@@ -3,9 +3,9 @@ export type ScrollbarSize = "m" | "s" | "xs";
|
|
|
3
3
|
export interface ScrollAreaProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
4
4
|
/**
|
|
5
5
|
* Scrollbar thickness.
|
|
6
|
-
* - `m` — 12 px (shows track border)
|
|
7
|
-
* - `s` — 6 px (
|
|
8
|
-
* - `xs` — 2 px (
|
|
6
|
+
* - `m` — 12 px (default, shows track border + 2px thumb inset)
|
|
7
|
+
* - `s` — 6 px (shows track border + 2px thumb inset)
|
|
8
|
+
* - `xs` — 2 px (no track border, no thumb inset)
|
|
9
9
|
*/
|
|
10
10
|
scrollbarSize?: ScrollbarSize;
|
|
11
11
|
/**
|
|
@@ -2,12 +2,42 @@ import * as React from "react";
|
|
|
2
2
|
declare const Table: React.ForwardRefExoticComponent<{
|
|
3
3
|
rootClassName?: string;
|
|
4
4
|
rootRef?: React.LegacyRef<HTMLDivElement>;
|
|
5
|
+
/**
|
|
6
|
+
* Wraps the table in a rounded frame (`rounded-md` + `border-table-c-border`).
|
|
7
|
+
* Uses an outer `overflow-hidden` shell and an inner scroll area so corners clip
|
|
8
|
+
* cleanly (same pattern as scrollable bordered tables elsewhere in the system).
|
|
9
|
+
* For pagination in the same frame, wrap `Table` + `TablePagination` in your own
|
|
10
|
+
* bordered div instead of relying on this prop alone.
|
|
11
|
+
*/
|
|
12
|
+
bordered?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* When false, render only `<table>` (no inner `overflow-auto` wrapper).
|
|
15
|
+
* Use when a parent already provides the scrollport — e.g. `DataTable` — so
|
|
16
|
+
* `sticky` header rows stick to the correct ancestor.
|
|
17
|
+
* Ignored when `bordered` is true (bordered tables always use the inner scroll shell).
|
|
18
|
+
*/
|
|
19
|
+
scrollableWrapper?: boolean;
|
|
5
20
|
} & React.HTMLAttributes<HTMLTableElement> & React.RefAttributes<HTMLTableElement>>;
|
|
6
21
|
declare const TableHeader: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & React.RefAttributes<HTMLTableSectionElement>>;
|
|
7
|
-
declare const TableBody: React.ForwardRefExoticComponent<
|
|
22
|
+
declare const TableBody: React.ForwardRefExoticComponent<{
|
|
23
|
+
striped?: boolean;
|
|
24
|
+
} & React.HTMLAttributes<HTMLTableSectionElement> & React.RefAttributes<HTMLTableSectionElement>>;
|
|
8
25
|
declare const TableFooter: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableSectionElement> & React.RefAttributes<HTMLTableSectionElement>>;
|
|
9
|
-
declare const TableRow: React.ForwardRefExoticComponent<
|
|
26
|
+
declare const TableRow: React.ForwardRefExoticComponent<{
|
|
27
|
+
divided?: boolean;
|
|
28
|
+
colDivided?: boolean;
|
|
29
|
+
} & React.HTMLAttributes<HTMLTableRowElement> & React.RefAttributes<HTMLTableRowElement>>;
|
|
10
30
|
declare const TableHead: React.ForwardRefExoticComponent<React.ThHTMLAttributes<HTMLTableCellElement> & React.RefAttributes<HTMLTableCellElement>>;
|
|
11
31
|
declare const TableCell: React.ForwardRefExoticComponent<React.TdHTMLAttributes<HTMLTableCellElement> & React.RefAttributes<HTMLTableCellElement>>;
|
|
12
32
|
declare const TableCaption: React.ForwardRefExoticComponent<React.HTMLAttributes<HTMLTableCaptionElement> & React.RefAttributes<HTMLTableCaptionElement>>;
|
|
13
|
-
export
|
|
33
|
+
export interface TablePaginationProps {
|
|
34
|
+
pageIndex: number;
|
|
35
|
+
pageSize: number;
|
|
36
|
+
totalCount: number;
|
|
37
|
+
pageSizeOptions?: number[];
|
|
38
|
+
onPageChange: (pageIndex: number) => void;
|
|
39
|
+
onPageSizeChange: (pageSize: number) => void;
|
|
40
|
+
className?: string;
|
|
41
|
+
}
|
|
42
|
+
declare const TablePagination: React.ForwardRefExoticComponent<TablePaginationProps & React.RefAttributes<HTMLDivElement>>;
|
|
43
|
+
export { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption, TablePagination, };
|
|
@@ -1,17 +1,28 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import type { StoryObj } from "@storybook/react";
|
|
2
3
|
declare const meta: {
|
|
3
4
|
title: string;
|
|
4
5
|
component: React.ForwardRefExoticComponent<{
|
|
5
6
|
rootClassName?: string;
|
|
6
7
|
rootRef?: React.LegacyRef<HTMLDivElement>;
|
|
8
|
+
bordered?: boolean;
|
|
9
|
+
scrollableWrapper?: boolean;
|
|
7
10
|
} & React.HTMLAttributes<HTMLTableElement> & React.RefAttributes<HTMLTableElement>>;
|
|
8
11
|
tags: string[];
|
|
9
12
|
parameters: {
|
|
10
13
|
layout: string;
|
|
11
14
|
};
|
|
15
|
+
argTypes: {
|
|
16
|
+
bordered: {
|
|
17
|
+
control: "boolean";
|
|
18
|
+
description: string;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
12
21
|
decorators: ((Story: import("@storybook/csf").PartialStoryFn<import("@storybook/react").ReactRenderer, {
|
|
13
22
|
rootClassName?: string | undefined;
|
|
14
23
|
rootRef?: React.LegacyRef<HTMLDivElement> | undefined;
|
|
24
|
+
bordered?: boolean | undefined;
|
|
25
|
+
scrollableWrapper?: boolean | undefined;
|
|
15
26
|
defaultChecked?: boolean | undefined | undefined;
|
|
16
27
|
defaultValue?: string | number | readonly string[] | undefined;
|
|
17
28
|
suppressContentEditableWarning?: boolean | undefined | undefined;
|
|
@@ -283,7 +294,78 @@ declare const meta: {
|
|
|
283
294
|
}>) => import("react/jsx-runtime").JSX.Element)[];
|
|
284
295
|
};
|
|
285
296
|
export default meta;
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
297
|
+
/** NON-STRIPED — horizontal row strokes, no column dividers */
|
|
298
|
+
export declare const Default: StoryObj;
|
|
299
|
+
/** NON-STRIPED + COL DIVIDED — horizontal row strokes + vertical column dividers */
|
|
300
|
+
export declare const NonStripedDivided: StoryObj;
|
|
301
|
+
/** STRIPED — alternating bg-a / bg-b, NO row strokes, NO column dividers */
|
|
302
|
+
export declare const Striped: StoryObj;
|
|
303
|
+
/**
|
|
304
|
+
* STRIPED + COL DIVIDED — alternating bg, NO row strokes, WITH column dividers.
|
|
305
|
+
* Primary Xspector table style.
|
|
306
|
+
*/
|
|
307
|
+
export declare const StripedAndDivided: StoryObj;
|
|
308
|
+
/** SELECTED ROW — data-[state=selected] applies transparent-primary-12. Row 1 pre-selected. */
|
|
309
|
+
export declare const WithSelectedRow: StoryObj;
|
|
310
|
+
/**
|
|
311
|
+
* WITH FOOTER — tfoot summary row with bg-table-bg-main + top border.
|
|
312
|
+
* TableFooter is inside Table so bordered works naturally.
|
|
313
|
+
*/
|
|
314
|
+
export declare const WithFooter: StoryObj;
|
|
315
|
+
/**
|
|
316
|
+
* WITH PAGINATION — TablePagination is a sibling of Table so needs an explicit
|
|
317
|
+
* outer wrapper (not covered by Table's bordered prop).
|
|
318
|
+
*/
|
|
319
|
+
export declare const WithPagination: StoryObj;
|
|
320
|
+
/** EMPTY STATE — single full-width row with centered message */
|
|
321
|
+
export declare const Empty: StoryObj;
|
|
322
|
+
/** ALL STATES SIDE-BY-SIDE — reference sheet for design review */
|
|
323
|
+
export declare const AllStates: StoryObj;
|
|
324
|
+
/**
|
|
325
|
+
* WITH SCROLL (Figma 9637-10817)
|
|
326
|
+
*
|
|
327
|
+
* Demonstrates both axes of overflow:
|
|
328
|
+
* - Vertical: fixed-height container → body rows overflow and scroll vertically
|
|
329
|
+
* - Horizontal: 10 columns wider than the viewport → native h-scroll bar appears
|
|
330
|
+
*
|
|
331
|
+
* Implementation notes:
|
|
332
|
+
* - Outer div sets the fixed height and owns the rounded border
|
|
333
|
+
* (TablePagination must sit outside the scrollable Table)
|
|
334
|
+
* - Table gets rootClassName="flex-1 min-h-0" so it grows to fill flex space
|
|
335
|
+
* and allows overflow-auto to kick in
|
|
336
|
+
* - TableHeader gets className="sticky top-0 z-10" for a frozen header row
|
|
337
|
+
*/
|
|
338
|
+
export declare const WithScroll: StoryObj;
|
|
339
|
+
/**
|
|
340
|
+
* SCROLLBAR SIZES — per-axis demo
|
|
341
|
+
*
|
|
342
|
+
* Combine ui-scrollbar-x-{size} + ui-scrollbar-y-{size} independently.
|
|
343
|
+
* CSS: height → horizontal bar thickness | width → vertical bar thickness
|
|
344
|
+
*/
|
|
345
|
+
export declare const ScrollbarSizes: StoryObj;
|
|
346
|
+
/** PANEL DEFAULT — transparent rows + panel-sub-line row dividers */
|
|
347
|
+
export declare const PanelDefault: StoryObj;
|
|
348
|
+
/** PANEL NON-STRIPED DIVIDED — row dividers + vertical column dividers */
|
|
349
|
+
export declare const PanelNonStripedDivided: StoryObj;
|
|
350
|
+
/** PANEL STRIPED — alternating rows (both transparent in panel mode), no row strokes */
|
|
351
|
+
export declare const PanelStriped: StoryObj;
|
|
352
|
+
/** PANEL STRIPED + COL DIVIDED */
|
|
353
|
+
export declare const PanelStripedAndDivided: StoryObj;
|
|
354
|
+
/** PANEL SELECTED ROW — table-panel-selected (yellow/olive) */
|
|
355
|
+
export declare const PanelWithSelectedRow: StoryObj;
|
|
356
|
+
/** PANEL WITH FOOTER */
|
|
357
|
+
export declare const PanelWithFooter: StoryObj;
|
|
358
|
+
/**
|
|
359
|
+
* PANEL WITH PAGINATION
|
|
360
|
+
* TablePagination sits inside the same data-surface="panel" scope so it
|
|
361
|
+
* automatically picks up the panel tokens — no variant prop needed.
|
|
362
|
+
*/
|
|
363
|
+
export declare const PanelWithPagination: StoryObj;
|
|
364
|
+
/** PANEL EMPTY STATE */
|
|
365
|
+
export declare const PanelEmpty: StoryObj;
|
|
366
|
+
/**
|
|
367
|
+
* PANEL WITH SCROLL — sticky header + both scroll axes inside a fixed-height panel.
|
|
368
|
+
*/
|
|
369
|
+
export declare const PanelWithScroll: StoryObj;
|
|
370
|
+
/** PANEL ALL STATES — all variants side-by-side for design review */
|
|
371
|
+
export declare const PanelAllStates: StoryObj;
|
|
@@ -390,6 +390,14 @@ export declare const Default: {
|
|
|
390
390
|
};
|
|
391
391
|
render: (args: {}) => import("react/jsx-runtime").JSX.Element;
|
|
392
392
|
};
|
|
393
|
+
/**
|
|
394
|
+
* `isFloatingLabel={false}` — visible **`placeholder`**, no floating animation,
|
|
395
|
+
* and no inner `<label>` when `label` is empty (e.g. table cells, compact filters).
|
|
396
|
+
* Pair with `required={false}` + `hasClearIcon={false}` when mimicking inline fields.
|
|
397
|
+
*/
|
|
398
|
+
export declare const NonFloatingLabel: {
|
|
399
|
+
render: () => import("react/jsx-runtime").JSX.Element;
|
|
400
|
+
};
|
|
393
401
|
export declare const CustomLabel: {
|
|
394
402
|
args: {
|
|
395
403
|
label: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare const inputVariant: (props?: ({
|
|
2
|
+
floatingLabelPlaceholder?: boolean | null | undefined;
|
|
2
3
|
size?: "sm" | "md" | "lg" | null | undefined;
|
|
3
4
|
rounded?: "none" | "normal" | "full" | null | undefined;
|
|
4
5
|
variant?: "outline" | "flat" | "underline" | null | undefined;
|
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
|
3
|
+
import TextInput from "@/components/TextInput/TextInput";
|
|
4
|
+
import NumberInput from "@/components/NumberInput";
|
|
5
|
+
import { Checkbox } from "@/components/Checkbox/Checkbox";
|
|
6
|
+
import Dropdown from "@/components/Dropdown/Dropdown";
|
|
7
|
+
import { customInputVariant } from "@/components/Dropdown/Dropdown.styles";
|
|
8
|
+
import { cn } from "@/utils/cn";
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// EditContext — shared between engine and DataTable render layer
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
export const EditContext = React.createContext(null);
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// useDataTableEditing — manages edit state (row / cell)
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
export function useDataTableEditing(opts) {
|
|
17
|
+
const { enabled, editDisplayMode, editTrigger, editableColumnIds } = opts;
|
|
18
|
+
const [editingRowId, setEditingRowId] = useState(null);
|
|
19
|
+
const [editingCell, setEditingCell] = useState(null);
|
|
20
|
+
const tabMovingRef = React.useRef(false);
|
|
21
|
+
const requestRowEdit = useCallback((rowId) => {
|
|
22
|
+
setEditingRowId(rowId);
|
|
23
|
+
setEditingCell(null);
|
|
24
|
+
}, []);
|
|
25
|
+
const requestCellEdit = useCallback((rowId, columnId) => {
|
|
26
|
+
setEditingCell({ rowId, columnId });
|
|
27
|
+
setEditingRowId(null);
|
|
28
|
+
}, []);
|
|
29
|
+
const clearEdit = useCallback(() => {
|
|
30
|
+
setEditingRowId(null);
|
|
31
|
+
setEditingCell(null);
|
|
32
|
+
}, []);
|
|
33
|
+
const onFieldBlur = useCallback((_rowId, _columnId) => {
|
|
34
|
+
if (tabMovingRef.current)
|
|
35
|
+
return;
|
|
36
|
+
if (editDisplayMode === "cell") {
|
|
37
|
+
setEditingCell(null);
|
|
38
|
+
}
|
|
39
|
+
}, [editDisplayMode]);
|
|
40
|
+
const moveCellEdit = useCallback((rowId, fromColumnId, delta) => {
|
|
41
|
+
const idx = editableColumnIds.indexOf(fromColumnId);
|
|
42
|
+
if (idx < 0) {
|
|
43
|
+
setEditingCell(null);
|
|
44
|
+
return "exited";
|
|
45
|
+
}
|
|
46
|
+
const next = idx + delta;
|
|
47
|
+
if (next < 0 || next >= editableColumnIds.length) {
|
|
48
|
+
setEditingCell(null);
|
|
49
|
+
return "exited";
|
|
50
|
+
}
|
|
51
|
+
tabMovingRef.current = true;
|
|
52
|
+
setEditingCell({ rowId, columnId: editableColumnIds[next] });
|
|
53
|
+
requestAnimationFrame(() => {
|
|
54
|
+
tabMovingRef.current = false;
|
|
55
|
+
});
|
|
56
|
+
return "moved";
|
|
57
|
+
}, [editableColumnIds]);
|
|
58
|
+
// Esc exits row edit
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
if (!enabled || editDisplayMode !== "row" || !editingRowId)
|
|
61
|
+
return;
|
|
62
|
+
const onKey = (e) => {
|
|
63
|
+
if (e.key === "Escape")
|
|
64
|
+
setEditingRowId(null);
|
|
65
|
+
};
|
|
66
|
+
document.addEventListener("keydown", onKey);
|
|
67
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
68
|
+
}, [enabled, editDisplayMode, editingRowId]);
|
|
69
|
+
return useMemo(() => ({
|
|
70
|
+
editingRowId,
|
|
71
|
+
editingCell,
|
|
72
|
+
editDisplayMode,
|
|
73
|
+
editTrigger,
|
|
74
|
+
requestRowEdit,
|
|
75
|
+
requestCellEdit,
|
|
76
|
+
clearEdit,
|
|
77
|
+
onFieldBlur,
|
|
78
|
+
moveCellEdit,
|
|
79
|
+
}), [
|
|
80
|
+
editingRowId,
|
|
81
|
+
editingCell,
|
|
82
|
+
editDisplayMode,
|
|
83
|
+
editTrigger,
|
|
84
|
+
requestRowEdit,
|
|
85
|
+
requestCellEdit,
|
|
86
|
+
clearEdit,
|
|
87
|
+
onFieldBlur,
|
|
88
|
+
moveCellEdit,
|
|
89
|
+
]);
|
|
90
|
+
}
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
// resolveEditableColumns — wraps EditableColumnDef[] → ColumnDef[]
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
94
|
+
const EDIT_SELECT_PH_PREFIX = "__edit_ph__";
|
|
95
|
+
function editPlaceholderOption(label) {
|
|
96
|
+
return { value: `${EDIT_SELECT_PH_PREFIX}:${label}`, label };
|
|
97
|
+
}
|
|
98
|
+
function isPlaceholderOption(opt) {
|
|
99
|
+
var _a;
|
|
100
|
+
return (_a = opt === null || opt === void 0 ? void 0 : opt.value.startsWith(`${EDIT_SELECT_PH_PREFIX}:`)) !== null && _a !== void 0 ? _a : false;
|
|
101
|
+
}
|
|
102
|
+
function isEditingCell(editing, row, columnId) {
|
|
103
|
+
var _a;
|
|
104
|
+
const rowId = typeof row.original.id === "string"
|
|
105
|
+
? row.original.id
|
|
106
|
+
: row.id;
|
|
107
|
+
if (editing.editDisplayMode === "row")
|
|
108
|
+
return editing.editingRowId === rowId;
|
|
109
|
+
return (((_a = editing.editingCell) === null || _a === void 0 ? void 0 : _a.rowId) === rowId &&
|
|
110
|
+
editing.editingCell.columnId === columnId);
|
|
111
|
+
}
|
|
112
|
+
function getRowId(row) {
|
|
113
|
+
const orig = row.original;
|
|
114
|
+
return typeof orig.id === "string" ? orig.id : row.id;
|
|
115
|
+
}
|
|
116
|
+
function coerceValue(variant, rawValue) {
|
|
117
|
+
if (variant === "number") {
|
|
118
|
+
const n = Number(rawValue);
|
|
119
|
+
return Number.isNaN(n) ? 0 : n;
|
|
120
|
+
}
|
|
121
|
+
if (variant === "checkbox") {
|
|
122
|
+
return rawValue === "true";
|
|
123
|
+
}
|
|
124
|
+
return rawValue;
|
|
125
|
+
}
|
|
126
|
+
function buildPatch(col, row, rawValue, columnId) {
|
|
127
|
+
if (col.onCommit) {
|
|
128
|
+
return col.onCommit(row, rawValue);
|
|
129
|
+
}
|
|
130
|
+
return { [columnId]: coerceValue(col.editVariant, rawValue) };
|
|
131
|
+
}
|
|
132
|
+
export function resolveEditableColumns(columns, opts) {
|
|
133
|
+
const { editing, onCellCommit, alwaysEditing, enableCellTabTraversal, editableColumnIds, } = opts;
|
|
134
|
+
return columns.map((col) => {
|
|
135
|
+
var _a, _b;
|
|
136
|
+
const colEditing = col.enableEditing;
|
|
137
|
+
if (colEditing == null && col.editVariant == null) {
|
|
138
|
+
return col;
|
|
139
|
+
}
|
|
140
|
+
const columnId = (_b = (_a = col.accessorKey) !== null && _a !== void 0 ? _a : col.id) !== null && _b !== void 0 ? _b : "";
|
|
141
|
+
const originalCell = col.cell;
|
|
142
|
+
const wrappedCol = Object.assign(Object.assign({}, col), { cell: (cellProps) => {
|
|
143
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
144
|
+
const { row } = cellProps;
|
|
145
|
+
const rowId = getRowId(row);
|
|
146
|
+
const canEdit = typeof colEditing === "function"
|
|
147
|
+
? colEditing(row)
|
|
148
|
+
: colEditing !== false;
|
|
149
|
+
if (!canEdit) {
|
|
150
|
+
const always = (_a = alwaysEditing === null || alwaysEditing === void 0 ? void 0 : alwaysEditing(row)) !== null && _a !== void 0 ? _a : false;
|
|
151
|
+
const isRowActive = always ||
|
|
152
|
+
editing.editingRowId === rowId ||
|
|
153
|
+
((_b = editing.editingCell) === null || _b === void 0 ? void 0 : _b.rowId) === rowId;
|
|
154
|
+
const showDisabledField = always || (col.editShowDisabledField && isRowActive);
|
|
155
|
+
if (showDisabledField && (col.editVariant || colEditing != null)) {
|
|
156
|
+
return _jsx(DisabledEditCell, { row: row, col: col, columnId: columnId });
|
|
157
|
+
}
|
|
158
|
+
if (col.displayCell) {
|
|
159
|
+
return col.displayCell(row);
|
|
160
|
+
}
|
|
161
|
+
if (originalCell) {
|
|
162
|
+
return typeof originalCell === "function"
|
|
163
|
+
? originalCell(cellProps)
|
|
164
|
+
: originalCell;
|
|
165
|
+
}
|
|
166
|
+
const value = row.original[columnId];
|
|
167
|
+
return _jsx(_Fragment, { children: String(value !== null && value !== void 0 ? value : "") });
|
|
168
|
+
}
|
|
169
|
+
const always = (_c = alwaysEditing === null || alwaysEditing === void 0 ? void 0 : alwaysEditing(row)) !== null && _c !== void 0 ? _c : false;
|
|
170
|
+
const active = always || isEditingCell(editing, row, columnId);
|
|
171
|
+
if (!active) {
|
|
172
|
+
const previewContent = col.displayCell
|
|
173
|
+
? col.displayCell(row)
|
|
174
|
+
: String((_d = row.original[columnId]) !== null && _d !== void 0 ? _d : "");
|
|
175
|
+
const activate = () => {
|
|
176
|
+
if (editing.editDisplayMode === "row")
|
|
177
|
+
editing.requestRowEdit(rowId);
|
|
178
|
+
else
|
|
179
|
+
editing.requestCellEdit(rowId, columnId);
|
|
180
|
+
};
|
|
181
|
+
const handler = editing.editTrigger === "click"
|
|
182
|
+
? { onClick: activate }
|
|
183
|
+
: { onDoubleClick: activate };
|
|
184
|
+
return (_jsx("div", Object.assign({ className: cn("-mx-1 flex min-h-[32px] w-full min-w-0 cursor-pointer items-center rounded-sm px-1", "hover:bg-table-c-hover/35") }, handler, { children: previewContent })));
|
|
185
|
+
}
|
|
186
|
+
// ── Edit mode ──
|
|
187
|
+
const variant = (_e = col.editVariant) !== null && _e !== void 0 ? _e : "text";
|
|
188
|
+
const autoFocus = !always && editing.editDisplayMode === "cell";
|
|
189
|
+
const errorMsg = (_f = col.editError) === null || _f === void 0 ? void 0 : _f.call(col, row);
|
|
190
|
+
const commitAndBlur = (value) => {
|
|
191
|
+
const patch = buildPatch(col, row, value, columnId);
|
|
192
|
+
onCellCommit === null || onCellCommit === void 0 ? void 0 : onCellCommit(rowId, columnId, patch);
|
|
193
|
+
if (!always)
|
|
194
|
+
editing.onFieldBlur(rowId, columnId);
|
|
195
|
+
};
|
|
196
|
+
const handleTab = enableCellTabTraversal
|
|
197
|
+
? (e, commitFn) => {
|
|
198
|
+
if (e.key !== "Tab")
|
|
199
|
+
return;
|
|
200
|
+
if (editing.editDisplayMode === "row") {
|
|
201
|
+
const idx = editableColumnIds.indexOf(columnId);
|
|
202
|
+
if (idx < 0)
|
|
203
|
+
return;
|
|
204
|
+
const nextIdx = idx + (e.shiftKey ? -1 : 1);
|
|
205
|
+
if (nextIdx < 0 || nextIdx >= editableColumnIds.length)
|
|
206
|
+
return;
|
|
207
|
+
const nextColId = editableColumnIds[nextIdx];
|
|
208
|
+
commitFn();
|
|
209
|
+
e.preventDefault();
|
|
210
|
+
requestAnimationFrame(() => {
|
|
211
|
+
const el = document.querySelector(`[data-edit-cell="${rowId}:${nextColId}"] input, [data-edit-cell="${rowId}:${nextColId}"] button`);
|
|
212
|
+
el === null || el === void 0 ? void 0 : el.focus();
|
|
213
|
+
});
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
commitFn();
|
|
217
|
+
if (editing.moveCellEdit(rowId, columnId, e.shiftKey ? -1 : 1) ===
|
|
218
|
+
"moved") {
|
|
219
|
+
e.preventDefault();
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
: undefined;
|
|
223
|
+
if (variant === "select") {
|
|
224
|
+
return (_jsx("div", { "data-edit-cell": `${rowId}:${columnId}`, children: _jsx(EditCellSelect, { row: row, columnId: columnId, col: col, autoFocus: autoFocus, keepOpenAfterSelect: editing.editDisplayMode === "row" || always, onCommit: (label) => {
|
|
225
|
+
var _a;
|
|
226
|
+
const currentValue = String((_a = row.original[columnId]) !== null && _a !== void 0 ? _a : "");
|
|
227
|
+
if (label.trim() === currentValue.trim())
|
|
228
|
+
return;
|
|
229
|
+
const patch = buildPatch(col, row, label, columnId);
|
|
230
|
+
onCellCommit === null || onCellCommit === void 0 ? void 0 : onCellCommit(rowId, columnId, patch);
|
|
231
|
+
}, onBlurField: editing.editDisplayMode === "row"
|
|
232
|
+
? undefined
|
|
233
|
+
: () => {
|
|
234
|
+
if (!always)
|
|
235
|
+
editing.onFieldBlur(rowId, columnId);
|
|
236
|
+
}, onKeyDown: handleTab
|
|
237
|
+
? (e) => handleTab(e, () => { })
|
|
238
|
+
: undefined, errorMessage: errorMsg }) }));
|
|
239
|
+
}
|
|
240
|
+
if (variant === "number") {
|
|
241
|
+
return (_jsx("div", { "data-edit-cell": `${rowId}:${columnId}`, children: _jsx(EditCellNumber, { columnId: columnId, row: row, col: col, autoFocus: autoFocus, errorMessage: errorMsg, onBlur: (val) => commitAndBlur(val), onKeyDown: handleTab
|
|
242
|
+
? (e) => handleTab(e, () => {
|
|
243
|
+
const v = e.target.value.trim();
|
|
244
|
+
const patch = buildPatch(col, row, v, columnId);
|
|
245
|
+
onCellCommit === null || onCellCommit === void 0 ? void 0 : onCellCommit(rowId, columnId, patch);
|
|
246
|
+
})
|
|
247
|
+
: undefined }) }));
|
|
248
|
+
}
|
|
249
|
+
if (variant === "checkbox") {
|
|
250
|
+
return (_jsx("div", { "data-edit-cell": `${rowId}:${columnId}`, children: _jsx(EditCellCheckbox, { columnId: columnId, row: row, col: col, errorMessage: errorMsg, onCommit: (checked) => {
|
|
251
|
+
const patch = buildPatch(col, row, String(checked), columnId);
|
|
252
|
+
onCellCommit === null || onCellCommit === void 0 ? void 0 : onCellCommit(rowId, columnId, patch);
|
|
253
|
+
}, onKeyDown: handleTab
|
|
254
|
+
? (e) => handleTab(e, () => { })
|
|
255
|
+
: undefined }) }));
|
|
256
|
+
}
|
|
257
|
+
if (variant === "custom" && col.editCustomCell) {
|
|
258
|
+
const blur = () => {
|
|
259
|
+
if (!always)
|
|
260
|
+
editing.onFieldBlur(rowId, columnId);
|
|
261
|
+
};
|
|
262
|
+
return (_jsx("div", { "data-edit-cell": `${rowId}:${columnId}`, children: col.editCustomCell(row, {
|
|
263
|
+
commit: (rawValue) => {
|
|
264
|
+
const patch = buildPatch(col, row, rawValue, columnId);
|
|
265
|
+
onCellCommit === null || onCellCommit === void 0 ? void 0 : onCellCommit(rowId, columnId, patch);
|
|
266
|
+
},
|
|
267
|
+
blur,
|
|
268
|
+
columnId,
|
|
269
|
+
autoFocus,
|
|
270
|
+
errorMessage: errorMsg,
|
|
271
|
+
onKeyDown: handleTab
|
|
272
|
+
? (e) => handleTab(e, () => { })
|
|
273
|
+
: undefined,
|
|
274
|
+
}) }));
|
|
275
|
+
}
|
|
276
|
+
// variant === "text"
|
|
277
|
+
return (_jsx("div", { "data-edit-cell": `${rowId}:${columnId}`, children: _jsx(EditCellText, { columnId: columnId, row: row, placeholder: (_h = (_g = col.editTextProps) === null || _g === void 0 ? void 0 : _g.placeholder) !== null && _h !== void 0 ? _h : "", autoFocus: autoFocus, errorMessage: errorMsg, onBlur: (e) => commitAndBlur(e.currentTarget.value.trim()), onKeyDown: handleTab
|
|
278
|
+
? (e) => handleTab(e, () => {
|
|
279
|
+
const v = e.target.value.trim();
|
|
280
|
+
const patch = buildPatch(col, row, v, columnId);
|
|
281
|
+
onCellCommit === null || onCellCommit === void 0 ? void 0 : onCellCommit(rowId, columnId, patch);
|
|
282
|
+
})
|
|
283
|
+
: undefined }) }));
|
|
284
|
+
} });
|
|
285
|
+
return wrappedCol;
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
// ---------------------------------------------------------------------------
|
|
289
|
+
// Built-in cell editors
|
|
290
|
+
// ---------------------------------------------------------------------------
|
|
291
|
+
function EditCellText({ columnId, row, placeholder, autoFocus, errorMessage, onBlur, onKeyDown, }) {
|
|
292
|
+
var _a;
|
|
293
|
+
const value = String((_a = row.original[columnId]) !== null && _a !== void 0 ? _a : "");
|
|
294
|
+
return (_jsx(TextInput, { size: "sm", variant: "outline", rounded: "normal", fullwidth: true, isFloatingLabel: false, label: "", required: false, hasClearIcon: false, keepFooterSpace: false, defaultValue: value, placeholder: placeholder, "aria-label": placeholder || columnId, autoFocus: autoFocus, error: !!errorMessage, errorMessage: errorMessage, onBlur: onBlur, onKeyDown: onKeyDown, className: "rounded-md px-2 py-2 typography-small2" }));
|
|
295
|
+
}
|
|
296
|
+
function EditCellSelect({ row, columnId, col, autoFocus, onCommit, onBlurField, onKeyDown, keepOpenAfterSelect, errorMessage, }) {
|
|
297
|
+
var _a, _b, _c, _d, _e;
|
|
298
|
+
const displayValue = String((_a = row.original[columnId]) !== null && _a !== void 0 ? _a : "");
|
|
299
|
+
const rawOptions = typeof ((_b = col.editSelectProps) === null || _b === void 0 ? void 0 : _b.options) === "function"
|
|
300
|
+
? col.editSelectProps.options(row)
|
|
301
|
+
: (_d = (_c = col.editSelectProps) === null || _c === void 0 ? void 0 : _c.options) !== null && _d !== void 0 ? _d : [];
|
|
302
|
+
const options = useMemo(() => {
|
|
303
|
+
var _a, _b;
|
|
304
|
+
const ph = (_b = (_a = col.editSelectProps) === null || _a === void 0 ? void 0 : _a.placeholder) !== null && _b !== void 0 ? _b : columnId;
|
|
305
|
+
return [editPlaceholderOption(ph), ...rawOptions];
|
|
306
|
+
}, [rawOptions, (_e = col.editSelectProps) === null || _e === void 0 ? void 0 : _e.placeholder, columnId]);
|
|
307
|
+
const selected = useMemo(() => {
|
|
308
|
+
var _a;
|
|
309
|
+
const cur = displayValue.trim();
|
|
310
|
+
if (!cur)
|
|
311
|
+
return options[0];
|
|
312
|
+
return (_a = options.find((o) => o.label === cur)) !== null && _a !== void 0 ? _a : options[0];
|
|
313
|
+
}, [displayValue, options]);
|
|
314
|
+
return (_jsx("div", { children: _jsx(Dropdown, { id: `edit-dd-${columnId}-${row.id}`, options: options, value: selected, onSelect: (opt) => {
|
|
315
|
+
if (isPlaceholderOption(opt))
|
|
316
|
+
return;
|
|
317
|
+
onCommit(opt.label);
|
|
318
|
+
}, size: "sm", variant: "outline", rounded: "normal", fullwidth: true, required: false, isFloatingLabel: false, label: "", keepFooterSpace: false, segmentedInput: true, autoFocus: autoFocus, onBlur: onBlurField, onKeyDown: onKeyDown, keepOpenAfterSelect: keepOpenAfterSelect, portal: true, error: !!errorMessage, errorMessage: errorMessage, className: cn("rounded-md", customInputVariant({ size: "sm" }), displayValue.trim().length > 0 && "font-medium") }) }));
|
|
319
|
+
}
|
|
320
|
+
// ---------------------------------------------------------------------------
|
|
321
|
+
// EditCellNumber — inline number editor
|
|
322
|
+
// ---------------------------------------------------------------------------
|
|
323
|
+
function EditCellNumber({ columnId, row, col, autoFocus, errorMessage, onBlur, onKeyDown, }) {
|
|
324
|
+
var _a;
|
|
325
|
+
const rawValue = row.original[columnId];
|
|
326
|
+
const numericValue = rawValue === "" || rawValue == null ? undefined : Number(rawValue);
|
|
327
|
+
const np = col.editNumberProps;
|
|
328
|
+
return (_jsx(NumberInput, { size: "sm", variant: "outline", rounded: "normal", fullwidth: true, isFloatingLabel: false, label: "", required: false, hasClearIcon: false, keepFooterSpace: false, defaultValue: numericValue, placeholder: (_a = np === null || np === void 0 ? void 0 : np.placeholder) !== null && _a !== void 0 ? _a : columnId, "aria-label": (np === null || np === void 0 ? void 0 : np.placeholder) || columnId, autoFocus: autoFocus, min: np === null || np === void 0 ? void 0 : np.min, max: np === null || np === void 0 ? void 0 : np.max, step: np === null || np === void 0 ? void 0 : np.step, precision: np === null || np === void 0 ? void 0 : np.precision, allowDecimal: np === null || np === void 0 ? void 0 : np.allowDecimal, allowNegative: np === null || np === void 0 ? void 0 : np.allowNegative, hideControls: true, error: !!errorMessage, errorMessage: errorMessage, onBlur: (e) => onBlur(e.currentTarget.value.trim()), onKeyDown: onKeyDown, className: "rounded-md px-2 py-2 typography-small2" }));
|
|
329
|
+
}
|
|
330
|
+
// ---------------------------------------------------------------------------
|
|
331
|
+
// EditCellCheckbox — inline checkbox editor
|
|
332
|
+
// ---------------------------------------------------------------------------
|
|
333
|
+
function EditCellCheckbox({ columnId, row, col, errorMessage, onCommit, onKeyDown, }) {
|
|
334
|
+
var _a;
|
|
335
|
+
const rawValue = row.original[columnId];
|
|
336
|
+
const checked = rawValue === true || rawValue === "true";
|
|
337
|
+
const label = (_a = col.editCheckboxProps) === null || _a === void 0 ? void 0 : _a.label;
|
|
338
|
+
return (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsxs("div", { className: "flex items-center gap-2 min-h-[32px]", children: [_jsx(Checkbox, { checked: checked, onCheckedChange: (val) => {
|
|
339
|
+
onCommit(val === true);
|
|
340
|
+
}, onKeyDown: onKeyDown
|
|
341
|
+
? (e) => onKeyDown(e)
|
|
342
|
+
: undefined, "aria-label": label || columnId }), label && (_jsx("span", { className: "typography-small2 text-text-contrast-high select-none", children: label }))] }), errorMessage && (_jsx("span", { className: "typography-small3 text-error-500", children: errorMessage }))] }));
|
|
343
|
+
}
|
|
344
|
+
// ---------------------------------------------------------------------------
|
|
345
|
+
// Disabled cell editor — shown in alwaysEditing rows when canEdit is false
|
|
346
|
+
// ---------------------------------------------------------------------------
|
|
347
|
+
function DisabledEditCell({ row, col, columnId, }) {
|
|
348
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
349
|
+
const variant = (_a = col.editVariant) !== null && _a !== void 0 ? _a : "text";
|
|
350
|
+
if (variant === "select") {
|
|
351
|
+
const rawOptions = typeof ((_b = col.editSelectProps) === null || _b === void 0 ? void 0 : _b.options) === "function"
|
|
352
|
+
? col.editSelectProps.options(row)
|
|
353
|
+
: (_d = (_c = col.editSelectProps) === null || _c === void 0 ? void 0 : _c.options) !== null && _d !== void 0 ? _d : [];
|
|
354
|
+
const ph = (_f = (_e = col.editSelectProps) === null || _e === void 0 ? void 0 : _e.placeholder) !== null && _f !== void 0 ? _f : columnId;
|
|
355
|
+
const options = [editPlaceholderOption(ph), ...rawOptions];
|
|
356
|
+
const displayValue = String((_g = row.original[columnId]) !== null && _g !== void 0 ? _g : "");
|
|
357
|
+
const selected = (_h = options.find((o) => o.label === displayValue.trim())) !== null && _h !== void 0 ? _h : options[0];
|
|
358
|
+
return (_jsx(Dropdown, { id: `edit-dd-disabled-${columnId}-${row.id}`, options: options, value: selected, onSelect: () => { }, size: "sm", variant: "outline", rounded: "normal", fullwidth: true, required: false, isFloatingLabel: false, label: "", keepFooterSpace: false, segmentedInput: true, disabled: true, className: cn("rounded-md", customInputVariant({ size: "sm" })) }));
|
|
359
|
+
}
|
|
360
|
+
if (variant === "number") {
|
|
361
|
+
const rawValue = row.original[columnId];
|
|
362
|
+
const numericValue = rawValue === "" || rawValue == null ? undefined : Number(rawValue);
|
|
363
|
+
return (_jsx(NumberInput, { size: "sm", variant: "outline", rounded: "normal", fullwidth: true, isFloatingLabel: false, label: "", required: false, hasClearIcon: false, keepFooterSpace: false, defaultValue: numericValue, disabled: true, hideControls: true, className: "rounded-md px-2 py-2 typography-small2" }));
|
|
364
|
+
}
|
|
365
|
+
if (variant === "checkbox") {
|
|
366
|
+
const rawValue = row.original[columnId];
|
|
367
|
+
const checked = rawValue === true || rawValue === "true";
|
|
368
|
+
return (_jsxs("div", { className: "flex items-center gap-2 min-h-[32px]", children: [_jsx(Checkbox, { checked: checked, disabled: true }), ((_j = col.editCheckboxProps) === null || _j === void 0 ? void 0 : _j.label) && (_jsx("span", { className: "typography-small2 text-text-g-contrast-medium select-none", children: col.editCheckboxProps.label }))] }));
|
|
369
|
+
}
|
|
370
|
+
const value = String((_k = row.original[columnId]) !== null && _k !== void 0 ? _k : "");
|
|
371
|
+
const placeholder = (_m = (_l = col.editTextProps) === null || _l === void 0 ? void 0 : _l.placeholder) !== null && _m !== void 0 ? _m : "";
|
|
372
|
+
return (_jsx(TextInput, { size: "sm", variant: "outline", rounded: "normal", fullwidth: true, isFloatingLabel: false, label: "", required: false, hasClearIcon: false, keepFooterSpace: false, defaultValue: value, placeholder: placeholder, "aria-label": placeholder || columnId, disabled: true, className: "rounded-md px-2 py-2 typography-small2" }));
|
|
373
|
+
}
|
|
374
|
+
// ---------------------------------------------------------------------------
|
|
375
|
+
// Utility: detect editable column ids from column defs
|
|
376
|
+
// ---------------------------------------------------------------------------
|
|
377
|
+
export function detectEditableColumnIds(columns) {
|
|
378
|
+
return columns
|
|
379
|
+
.filter((col) => col.enableEditing != null || col.editVariant != null)
|
|
380
|
+
.map((col) => {
|
|
381
|
+
var _a, _b;
|
|
382
|
+
return (_b = (_a = col.accessorKey) !== null && _a !== void 0 ? _a : col.id) !== null && _b !== void 0 ? _b : "";
|
|
383
|
+
})
|
|
384
|
+
.filter(Boolean);
|
|
385
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|