react-gridix 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.html +1742 -0
- package/README.md +1042 -2
- package/dist/index.d.ts +305 -0
- package/dist/react-gridix.cjs +1 -0
- package/dist/react-gridix.js +668 -0
- package/dist/style.css +1 -0
- package/package.json +39 -4
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import { ComponentType } from 'react';
|
|
2
|
+
import { CSSProperties } from 'react';
|
|
3
|
+
import { JSX as JSX_2 } from 'react';
|
|
4
|
+
import { ReactNode } from 'react';
|
|
5
|
+
|
|
6
|
+
declare type AnyRow = Record<string, any>;
|
|
7
|
+
|
|
8
|
+
export declare interface CellEditableParams<T = Record<string, any>> {
|
|
9
|
+
/** The raw value stored in the row (read from nested objects for `"a.b"` fields). */
|
|
10
|
+
value: unknown;
|
|
11
|
+
/** The value as text, after `valueFormatter`. */
|
|
12
|
+
formattedValue: string;
|
|
13
|
+
row: T;
|
|
14
|
+
rowIndex: number;
|
|
15
|
+
field: string;
|
|
16
|
+
column: ColumnDef<T>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export declare interface CellEditEvent<T> {
|
|
20
|
+
rowId: string | number;
|
|
21
|
+
rowIndex: number;
|
|
22
|
+
/** The column's field, for example `"contact.phone"`. */
|
|
23
|
+
field: string;
|
|
24
|
+
oldValue: unknown;
|
|
25
|
+
newValue: unknown;
|
|
26
|
+
/** The updated row. */
|
|
27
|
+
row: T;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Props received by a column's `cellEditor` component. */
|
|
31
|
+
export declare interface CellEditorProps<T = Record<string, any>> {
|
|
32
|
+
/** The current draft value (starts as the cell's raw value). */
|
|
33
|
+
value: unknown;
|
|
34
|
+
row: T;
|
|
35
|
+
rowIndex: number;
|
|
36
|
+
field: string;
|
|
37
|
+
column: ColumnDef<T>;
|
|
38
|
+
/** Update the draft value without saving it. */
|
|
39
|
+
onChange: (value: unknown) => void;
|
|
40
|
+
/**
|
|
41
|
+
* Save and close the editor. Pass the value to save, or call with no value to save the
|
|
42
|
+
* current draft. `move` also starts editing the neighbouring cell ("down" and so on).
|
|
43
|
+
*/
|
|
44
|
+
onCommit: (value?: unknown, move?: MoveDirection) => void;
|
|
45
|
+
/** Close the editor without saving. */
|
|
46
|
+
onCancel: () => void;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export declare interface CellParams<T = Record<string, any>> extends CellEditableParams<T> {
|
|
50
|
+
/** Whether this cell may be changed (the column's `editable` setting, or the grid's). */
|
|
51
|
+
editable: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Saves a new value for this cell straight away, without opening the editor. It runs `validate`
|
|
54
|
+
* and fires `onCellEdit` / `onRowsChange` like any edit. Returns false if the value was rejected
|
|
55
|
+
* or the cell is not editable.
|
|
56
|
+
*/
|
|
57
|
+
updateValue: (value: unknown) => boolean;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export declare function Checkbox({ checked, onChange, indeterminate, variant, disabled, label, "aria-label": ariaLabel, id, name, indicator, className, style, classNames, styles, }: CheckboxProps): JSX_2.Element;
|
|
61
|
+
|
|
62
|
+
export declare interface CheckboxProps {
|
|
63
|
+
checked: boolean;
|
|
64
|
+
/** Called once per click (or Space key press) with the new value. */
|
|
65
|
+
onChange: (checked: boolean) => void;
|
|
66
|
+
/**
|
|
67
|
+
* Shows the mixed ("some are selected") state, with a dash instead of a tick. Use it together
|
|
68
|
+
* with `checked={false}`. Clicking a mixed checkbox calls `onChange(true)`.
|
|
69
|
+
*/
|
|
70
|
+
indeterminate?: boolean;
|
|
71
|
+
/** Default `"native"`. */
|
|
72
|
+
variant?: CheckboxVariant;
|
|
73
|
+
disabled?: boolean;
|
|
74
|
+
/** Text next to the box. Clicking it toggles the checkbox. */
|
|
75
|
+
label?: ReactNode;
|
|
76
|
+
/** Accessible name when there is no visible `label`. */
|
|
77
|
+
"aria-label"?: string;
|
|
78
|
+
id?: string;
|
|
79
|
+
/** Only used by the `"native"` variant. */
|
|
80
|
+
name?: string;
|
|
81
|
+
/** Replaces what is drawn inside the `"button"` and `"tick"` variants (for example `"★"` or your own icon). */
|
|
82
|
+
indicator?: ReactNode;
|
|
83
|
+
/** Classes for the root element (same as `classNames.root`). */
|
|
84
|
+
className?: string;
|
|
85
|
+
/** Inline styles for the root element (same as `styles.root`). */
|
|
86
|
+
style?: CSSProperties;
|
|
87
|
+
/** Classes per part. */
|
|
88
|
+
classNames?: Partial<Record<CheckboxSlot, string>>;
|
|
89
|
+
/** Inline styles per part. */
|
|
90
|
+
styles?: Partial<Record<CheckboxSlot, CSSProperties>>;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export declare type CheckboxSlot = "root" | "control" | "indicator" | "label";
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* - `"button"`: a `<button>` box with a `<span>` inside that is shown when checked.
|
|
97
|
+
* - `"tick"`: a `<button>` box that fills in and shows a tick when checked.
|
|
98
|
+
* - `"native"`: the browser's own `<input type="checkbox">`.
|
|
99
|
+
*/
|
|
100
|
+
export declare type CheckboxVariant = "button" | "tick" | "native";
|
|
101
|
+
|
|
102
|
+
/** Options for the checkbox drawn in a `type: "boolean"` column. */
|
|
103
|
+
export declare interface ColumnCheckboxOptions {
|
|
104
|
+
/** Overrides the grid's `checkboxVariant` for this column. */
|
|
105
|
+
variant?: CheckboxVariant;
|
|
106
|
+
/** A custom character (or any node) drawn inside the box when checked, for example `"✕"` or `"★"`. */
|
|
107
|
+
indicator?: ReactNode;
|
|
108
|
+
className?: string;
|
|
109
|
+
style?: CSSProperties;
|
|
110
|
+
classNames?: Partial<Record<CheckboxSlot, string>>;
|
|
111
|
+
styles?: Partial<Record<CheckboxSlot, CSSProperties>>;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export declare interface ColumnDef<T = Record<string, any>> {
|
|
115
|
+
/**
|
|
116
|
+
* Key of the row object this column reads and writes. Use dot notation for nested objects:
|
|
117
|
+
* `"contact.phone"`. Edits to a nested field copy the objects on the way and never change your data in place.
|
|
118
|
+
*/
|
|
119
|
+
field: FieldPath<T> & string;
|
|
120
|
+
/**
|
|
121
|
+
* Text shown in the header. Defaults to the field name, except for `type: "boolean"` columns,
|
|
122
|
+
* which default to an empty string.
|
|
123
|
+
*/
|
|
124
|
+
headerName?: string;
|
|
125
|
+
/**
|
|
126
|
+
* "number" columns sort numerically and parse edits as numbers.
|
|
127
|
+
* "boolean" columns show a checkbox that toggles with one click (see `checkbox`).
|
|
128
|
+
*/
|
|
129
|
+
type?: "text" | "number" | "boolean";
|
|
130
|
+
width?: number | string;
|
|
131
|
+
minWidth?: number | string;
|
|
132
|
+
align?: "left" | "center" | "right";
|
|
133
|
+
/** Overrides the grid-level `sortable`. */
|
|
134
|
+
sortable?: boolean;
|
|
135
|
+
/** Show a filter indicator in this column's header. Default false. Clicking it opens the filter popup. */
|
|
136
|
+
filterable?: boolean;
|
|
137
|
+
/** Placeholder of the default filter text box. */
|
|
138
|
+
filterPlaceholder?: string;
|
|
139
|
+
/** A React component drawn instead of the default dot. Receives `{ column, active, open }`. */
|
|
140
|
+
filterIndicator?: ComponentType<FilterIndicatorProps<T>>;
|
|
141
|
+
/** Classes for this column's filter indicator button (Tailwind works). */
|
|
142
|
+
filterIndicatorClassName?: string;
|
|
143
|
+
/** Inline styles for this column's filter indicator button. */
|
|
144
|
+
filterIndicatorStyle?: CSSProperties;
|
|
145
|
+
/** Classes for this column's filter popup. */
|
|
146
|
+
filterPopupClassName?: string;
|
|
147
|
+
/** Inline styles for this column's filter popup. */
|
|
148
|
+
filterPopupStyle?: CSSProperties;
|
|
149
|
+
/** A React component that replaces the filter text box inside the popup. */
|
|
150
|
+
filterRenderer?: ComponentType<FilterRendererProps<T>>;
|
|
151
|
+
/**
|
|
152
|
+
* `true` / `false`, or a function that decides per cell. Overrides the grid-level `editable`.
|
|
153
|
+
* Example: `editable: ({ row }) => row.status !== "locked"`.
|
|
154
|
+
*/
|
|
155
|
+
editable?: boolean | ((params: CellEditableParams<T>) => boolean);
|
|
156
|
+
/** Text used for display, global search and filtering. */
|
|
157
|
+
valueFormatter?: (value: any, row: T) => string;
|
|
158
|
+
/** Turns the typed text into the stored value. */
|
|
159
|
+
valueParser?: (text: string, row: T) => unknown;
|
|
160
|
+
/** Return false to reject an edit. The editor stays open and is marked invalid. */
|
|
161
|
+
validate?: (value: unknown, row: T) => boolean;
|
|
162
|
+
/** Custom sort. Return a negative, zero or positive number. */
|
|
163
|
+
comparator?: (a: any, b: any, rowA: T, rowB: T) => number;
|
|
164
|
+
/** A React component that renders the cell content. Define it outside render so it keeps its identity. */
|
|
165
|
+
cellRenderer?: ComponentType<CellParams<T>>;
|
|
166
|
+
/** A React component used instead of the text box when editing this column. */
|
|
167
|
+
cellEditor?: ComponentType<CellEditorProps<T>>;
|
|
168
|
+
/** A React component that renders the header label (the filter indicator and sort arrow are still added). */
|
|
169
|
+
headerRenderer?: ComponentType<HeaderRendererProps<T>>;
|
|
170
|
+
/** Classes for the whole column: its header cell and every body cell. Tailwind works. */
|
|
171
|
+
className?: string;
|
|
172
|
+
/** Inline styles for the whole column: its header cell and every body cell. */
|
|
173
|
+
style?: CSSProperties;
|
|
174
|
+
headerClassName?: string;
|
|
175
|
+
headerStyle?: CSSProperties;
|
|
176
|
+
cellClassName?: string | ((params: CellParams<T>) => string);
|
|
177
|
+
cellStyle?: CSSProperties | ((params: CellParams<T>) => CSSProperties);
|
|
178
|
+
/** Look of the checkbox in a `type: "boolean"` column. */
|
|
179
|
+
checkbox?: ColumnCheckboxOptions;
|
|
180
|
+
/**
|
|
181
|
+
* For `type: "boolean"` columns: draws a checkbox in the header, with the header name as its
|
|
182
|
+
* label (no label when the name is empty). Clicking it checks every row that matches the current
|
|
183
|
+
* search and filters (all pages), or unchecks them all when they are already checked. It shows a
|
|
184
|
+
* mixed state when only some are checked. Ignored when the column has a `headerRenderer`.
|
|
185
|
+
*/
|
|
186
|
+
headerCheckbox?: boolean;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export declare function DataGrid<T extends AnyRow = AnyRow>({ columns, rows, getRowId, editable, enterMovesDown, onCellEdit, onRowsChange, sortable, defaultSort, onSortChange, searchable, searchPlaceholder, pagination, paginationPosition, pageSize: initialPageSize, pageSizeOptions, onRowClick, toolbar, emptyMessage, striped, stripeColors, checkboxVariant, animateRows, theme, maxHeight, className, style, classNames, styles, rowClassName, rowStyle, }: DataGridProps<T>): JSX_2.Element;
|
|
190
|
+
|
|
191
|
+
export declare interface DataGridProps<T = Record<string, any>> {
|
|
192
|
+
columns: ColumnDef<T>[];
|
|
193
|
+
rows: T[];
|
|
194
|
+
/** Stable id for each row. Defaults to the row's index in `rows`. */
|
|
195
|
+
getRowId?: (row: T, index: number) => string | number;
|
|
196
|
+
/** Allow editing cells (double-click, Enter/F2, or just start typing). Default false. */
|
|
197
|
+
editable?: boolean;
|
|
198
|
+
/**
|
|
199
|
+
* After Enter saves a cell, start editing the cell below (Shift+Enter: the cell above).
|
|
200
|
+
* Tab and Shift+Tab move across the row. Default true.
|
|
201
|
+
*/
|
|
202
|
+
enterMovesDown?: boolean;
|
|
203
|
+
/** Fires after a cell edit is committed. */
|
|
204
|
+
onCellEdit?: (event: CellEditEvent<T>) => void;
|
|
205
|
+
/** Fires with the full updated array after a cell edit. Handy for `setRows`. */
|
|
206
|
+
onRowsChange?: (rows: T[]) => void;
|
|
207
|
+
/** Header click sorting. Default true. */
|
|
208
|
+
sortable?: boolean;
|
|
209
|
+
/** Uncontrolled initial sort. */
|
|
210
|
+
defaultSort?: SortModel | null;
|
|
211
|
+
onSortChange?: (sort: SortModel | null) => void;
|
|
212
|
+
/** Global search box above the grid. Default true. */
|
|
213
|
+
searchable?: boolean;
|
|
214
|
+
searchPlaceholder?: string;
|
|
215
|
+
/** Default true. */
|
|
216
|
+
pagination?: boolean;
|
|
217
|
+
/** Where the row count and page controls go: "bottom" (default), "top" or "both". */
|
|
218
|
+
paginationPosition?: PaginationPosition;
|
|
219
|
+
pageSize?: number;
|
|
220
|
+
pageSizeOptions?: number[];
|
|
221
|
+
onRowClick?: (row: T, rowIndex: number) => void;
|
|
222
|
+
/** Extra content on the right side of the toolbar. */
|
|
223
|
+
toolbar?: ReactNode;
|
|
224
|
+
emptyMessage?: ReactNode;
|
|
225
|
+
/** Alternate row shading. Default false. */
|
|
226
|
+
striped?: boolean;
|
|
227
|
+
/** Two colours for the alternating rows, for example `["#ffffff", "#f1f5f9"]`. Implies `striped`. */
|
|
228
|
+
stripeColors?: [string, string];
|
|
229
|
+
/** Checkbox style for `type: "boolean"` columns: "button", "tick" or "native" (default). */
|
|
230
|
+
checkboxVariant?: CheckboxVariant;
|
|
231
|
+
/** Rows slide in smoothly when they render (new page, sort, search). Default true. Respects "reduce motion". */
|
|
232
|
+
animateRows?: boolean;
|
|
233
|
+
/**
|
|
234
|
+
* Name of a theme. Nothing changes unless you pass one: "ocean", "midnight", "sunset" or "forest",
|
|
235
|
+
* or the name of your own `[data-rk-theme="..."]` CSS.
|
|
236
|
+
*/
|
|
237
|
+
theme?: GridTheme | (string & {});
|
|
238
|
+
/** Makes the body scroll with a sticky header, e.g. 400 or "60vh". */
|
|
239
|
+
maxHeight?: number | string;
|
|
240
|
+
/** Tailwind or any CSS classes for the root element. */
|
|
241
|
+
className?: string;
|
|
242
|
+
/** Inline styles for the root element. */
|
|
243
|
+
style?: CSSProperties;
|
|
244
|
+
/** Classes per part of the grid. */
|
|
245
|
+
classNames?: Partial<Record<GridSlot, string>>;
|
|
246
|
+
/** Inline styles per part of the grid. */
|
|
247
|
+
styles?: Partial<Record<GridSlot, CSSProperties>>;
|
|
248
|
+
rowClassName?: string | ((row: T, rowIndex: number) => string);
|
|
249
|
+
rowStyle?: CSSProperties | ((row: T, rowIndex: number) => CSSProperties);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Every field a column can point at: top-level keys, plus dot paths into nested objects
|
|
254
|
+
* (`"contact.phone"`). Goes up to 5 levels deep. Arrays are treated as plain values.
|
|
255
|
+
*/
|
|
256
|
+
export declare type FieldPath<T, D extends number = 5> = [D] extends [never] ? never : T extends Primitive | readonly unknown[] ? never : {
|
|
257
|
+
[K in keyof T & string]: NonNullable<T[K]> extends Primitive | readonly unknown[] ? K : K | `${K}.${FieldPath<NonNullable<T[K]>, Prev[D]>}`;
|
|
258
|
+
}[keyof T & string];
|
|
259
|
+
|
|
260
|
+
/** Props received by a column's `filterIndicator` component. */
|
|
261
|
+
export declare interface FilterIndicatorProps<T = Record<string, any>> {
|
|
262
|
+
column: ColumnDef<T>;
|
|
263
|
+
/** True while a filter text is set for this column. */
|
|
264
|
+
active: boolean;
|
|
265
|
+
/** True while the filter popup is open. */
|
|
266
|
+
open: boolean;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/** Props received by a column's `filterRenderer` component (it is shown inside the filter popup). */
|
|
270
|
+
export declare interface FilterRendererProps<T = Record<string, any>> {
|
|
271
|
+
column: ColumnDef<T>;
|
|
272
|
+
value: string;
|
|
273
|
+
onChange: (value: string) => void;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export declare type GridSlot = "root" | "toolbar" | "search" | "scroll" | "table" | "thead" | "headerRow" | "headerCell" | "filterIndicator" | "filterPopup" | "filterInput" | "tbody" | "row" | "cell" | "editor" | "empty" | "footer" | "rowCount" | "pageInfo" | "pageSize" | "pagination" | "pageButton" | "checkbox" | "checkboxControl" | "checkboxIndicator";
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Built-in themes. A theme only applies when you pass its name to `<DataGrid theme="..." />`.
|
|
280
|
+
* Any other string works too if you define `[data-rk-theme="name"]` CSS variables yourself.
|
|
281
|
+
*/
|
|
282
|
+
export declare type GridTheme = "ocean" | "midnight" | "sunset" | "forest";
|
|
283
|
+
|
|
284
|
+
/** Props received by a column's `headerRenderer` component. */
|
|
285
|
+
export declare interface HeaderRendererProps<T = Record<string, any>> {
|
|
286
|
+
column: ColumnDef<T>;
|
|
287
|
+
sortDirection: SortDirection | null;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export declare type MoveDirection = "down" | "up" | "left" | "right" | "none";
|
|
291
|
+
|
|
292
|
+
export declare type PaginationPosition = "bottom" | "top" | "both";
|
|
293
|
+
|
|
294
|
+
declare type Prev = [never, 0, 1, 2, 3, 4, 5];
|
|
295
|
+
|
|
296
|
+
declare type Primitive = string | number | boolean | bigint | symbol | null | undefined | Date | ((...args: any[]) => any);
|
|
297
|
+
|
|
298
|
+
export declare type SortDirection = "asc" | "desc";
|
|
299
|
+
|
|
300
|
+
export declare interface SortModel {
|
|
301
|
+
field: string;
|
|
302
|
+
direction: SortDirection;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
export { }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("react/jsx-runtime"),f=require("react"),ct=require("react-dom"),oe=(...o)=>o.filter(Boolean).join(" ");function ut(){return l.jsx("svg",{viewBox:"0 0 16 16",width:"100%",height:"100%","aria-hidden":"true",focusable:"false",children:l.jsx("path",{d:"M3.5 8.5l3 3 6-7",fill:"none",stroke:"currentColor",strokeWidth:"2.2",strokeLinecap:"round",strokeLinejoin:"round"})})}function ft(){return l.jsx("svg",{viewBox:"0 0 16 16",width:"100%",height:"100%","aria-hidden":"true",focusable:"false",children:l.jsx("path",{d:"M4 8h8",fill:"none",stroke:"currentColor",strokeWidth:"2.2",strokeLinecap:"round"})})}function je({checked:o,onChange:d,indeterminate:c=!1,variant:g="native",disabled:P=!1,label:x,"aria-label":m,id:A,name:U,indicator:T,className:W,style:w,classNames:k={},styles:E={}}){const B=c?"indeterminate":o?"checked":"unchecked";return l.jsxs("label",{className:oe("rk-checkbox",`rk-checkbox--${g}`,B==="checked"&&"rk-checkbox--checked",c&&"rk-checkbox--indeterminate",P&&"rk-checkbox--disabled",k.root,W),style:{...E.root,...w},"data-state":B,children:[g==="native"?l.jsx("input",{type:"checkbox",id:A,name:U,ref:y=>{y&&(y.indeterminate=c)},className:oe("rk-checkbox__control",k.control),style:E.control,checked:o,disabled:P,"aria-label":m,"data-state":B,onChange:y=>d(y.target.checked)}):l.jsx("button",{type:"button",role:"checkbox",id:A,className:oe("rk-checkbox__control",k.control),style:E.control,"aria-checked":c?"mixed":o,"aria-label":m,disabled:P,"data-state":B,onClick:()=>d(!o),children:l.jsx("span",{className:oe("rk-checkbox__indicator",T!==void 0&&!c&&"rk-checkbox__indicator--custom",k.indicator),style:E.indicator,"data-state":B,"aria-hidden":"true",children:c?g==="tick"?l.jsx(ft,{}):null:T!==void 0?T:g==="tick"?l.jsx(ut,{}):null})}),x!=null&&x!==!1&&x!==""&&l.jsx("span",{className:oe("rk-checkbox__label",k.label),style:E.label,children:x})]})}const ve=(...o)=>o.filter(Boolean).join(" "),ht=typeof window<"u"?f.useLayoutEffect:f.useEffect;function pt({column:o,label:d,value:c,onChange:g,theme:P,indicatorClassName:x,indicatorStyle:m,popupClassName:A,popupStyle:U,inputClassName:T,inputStyle:W}){const[w,k]=f.useState(!1),[E,B]=f.useState({top:0,left:0}),y=f.useRef(null),z=f.useRef(null),O=c.trim()!=="",$=f.useCallback(()=>{var R;const b=y.current;if(!b)return;const F=b.getBoundingClientRect(),K=((R=z.current)==null?void 0:R.offsetWidth)??260,L=Math.max(8,Math.min(F.left,window.innerWidth-K-8));B({top:F.bottom+6,left:L})},[]);ht(()=>{w&&$()},[w,$]),f.useEffect(()=>{if(!w)return;const b=K=>{var R,ie;const L=K.target;(R=z.current)!=null&&R.contains(L)||(ie=y.current)!=null&&ie.contains(L)||k(!1)},F=K=>{var L;K.key==="Escape"&&(k(!1),(L=y.current)==null||L.focus())};return document.addEventListener("mousedown",b),document.addEventListener("keydown",F),window.addEventListener("resize",$),window.addEventListener("scroll",$,!0),()=>{document.removeEventListener("mousedown",b),document.removeEventListener("keydown",F),window.removeEventListener("resize",$),window.removeEventListener("scroll",$,!0)}},[w,$]);const pe=()=>{var b;k(!1),(b=y.current)==null||b.focus()};return l.jsxs(l.Fragment,{children:[l.jsx("button",{ref:y,type:"button",className:ve("rk-grid__filter-btn",O&&"rk-grid__filter-btn--active",w&&"rk-grid__filter-btn--open",x),style:m,"aria-label":`Filter ${d}`,"aria-haspopup":"dialog","aria-expanded":w,"data-active":O||void 0,onClick:b=>{b.stopPropagation(),w||$(),k(F=>!F)},children:o.filterIndicator?f.createElement(o.filterIndicator,{column:o,active:O,open:w}):l.jsx("span",{className:"rk-grid__filter-dot","aria-hidden":"true"})}),w&&typeof document<"u"&&ct.createPortal(l.jsxs("div",{ref:z,role:"dialog","aria-label":`Filter ${d}`,"data-rk-theme":P||void 0,className:ve("rk-grid-popup",A),style:{position:"fixed",top:E.top,left:E.left,...U},children:[o.filterRenderer?f.createElement(o.filterRenderer,{column:o,value:c,onChange:g}):l.jsx("input",{autoFocus:!0,type:"text",className:ve("rk-grid__filter-input",T),style:W,value:c,placeholder:o.filterPlaceholder??`Filter ${d}…`,"aria-label":`Filter text for ${d}`,onChange:b=>g(b.target.value),onKeyDown:b=>{b.key==="Enter"&&pe()}}),O&&l.jsx("button",{type:"button",className:"rk-grid__filter-clear",onClick:()=>g(""),children:"Clear"})]}),document.body)]})}const we=new Set(["__proto__","prototype","constructor"]),We=(o,d)=>Object.prototype.hasOwnProperty.call(o,d);function V(o,d){if(o===null||typeof o!="object")return;if(We(o,d))return o[d];let c=o;for(const g of d.split(".")){if(c==null||typeof c!="object"||we.has(g))return;c=c[g]}return c}function ze(o,d,c){if(Array.isArray(o)){const g=[...o];return g[d]=c,g}return{...o,[d]:c}}function Ee(o,d,c){const g=o??{};if(We(g,d)||!d.includes("."))return we.has(d)?o:ze(g,d,c);const[P,...x]=d.split(".");if(we.has(P))return o;const m=g[P];return ze(g,P,Ee(m!==null&&typeof m=="object"?m:{},x.join("."),c))}const D=(...o)=>o.filter(Boolean).join(" "),Oe=(o,d)=>`${typeof o}:${o}\0${d}`,Se=o=>o.headerName??(o.type==="boolean"?"":o.field),he=o=>Se(o)||o.field;function ye(o,d){const c=V(d,o.field);return o.valueFormatter?o.valueFormatter(c,d):o.type==="boolean"&&typeof c=="boolean"?c?"Yes":"No":c==null?"":c instanceof Date?c.toLocaleDateString():String(c)}function gt(o,d){return typeof o=="number"&&typeof d=="number"?o-d:o instanceof Date&&d instanceof Date?o.getTime()-d.getTime():typeof o=="boolean"&&typeof d=="boolean"?Number(o)-Number(d):String(o).localeCompare(String(d),void 0,{numeric:!0,sensitivity:"base"})}function bt({columns:o,rows:d,getRowId:c,editable:g=!1,enterMovesDown:P=!0,onCellEdit:x,onRowsChange:m,sortable:A=!0,defaultSort:U=null,onSortChange:T,searchable:W=!0,searchPlaceholder:w="Search…",pagination:k=!0,paginationPosition:E="bottom",pageSize:B=10,pageSizeOptions:y=[5,10,25,50],onRowClick:z,toolbar:O,emptyMessage:$="No rows to show",striped:pe=!1,stripeColors:b,checkboxVariant:F="native",animateRows:K=!0,theme:L,maxHeight:R,className:ie,style:qe,classNames:S={},styles:j={},rowClassName:ge,rowStyle:be}){const _=(e,t)=>({className:D(t,S[e]),style:j[e]}),[Ne,Ce]=f.useState(d),Y=f.useRef(d);f.useEffect(()=>{Y.current=d,Ce(d)},[d]);const De=e=>{Y.current=e,Ce(e)},[H,Ge]=f.useState(""),[Q,Je]=f.useState({}),[v,Ue]=f.useState(U),[Ye,X]=f.useState(0),[I,He]=f.useState(B),[Z,ee]=f.useState(null),q=f.useRef(0),le=f.useRef(null),ke=f.useRef(new Map),Pe=f.useMemo(()=>Ne.map((e,t)=>({row:e,index:t,id:c?c(e,t):t})),[Ne,c]),te=f.useMemo(()=>{const e=H.trim().toLowerCase(),t=Object.entries(Q).filter(([n,i])=>i.trim()!==""&&o.some(s=>s.field===n&&s.filterable));let r=Pe.filter(({row:n})=>e&&!o.some(s=>ye(s,n).toLowerCase().includes(e))?!1:t.every(([i,s])=>{const h=o.find(a=>a.field===i);return h?ye(h,n).toLowerCase().includes(s.trim().toLowerCase()):!0}));if(v){const n=o.find(i=>i.field===v.field);if(n){const i=v.direction==="asc"?1:-1;r=[...r].sort((s,h)=>{const a=V(s.row,n.field),u=V(h.row,n.field),p=a==null||a==="",N=u==null||u==="";return p||N?p===N?0:p?1:-1:(n.comparator?n.comparator(a,u,s.row,h.row):gt(a,u))*i})}}return r},[Pe,o,H,Q,v]);f.useEffect(()=>X(0),[H,Q,v,I]);const Ie=f.useRef(null),G=te.length,re=k?Math.max(1,Math.ceil(G/I)):1,C=Math.min(Ye,re-1),M=k?te.slice(C*I,C*I+I):te,Qe=G===0?0:k?C*I+1:1,Xe=k?Math.min(G,(C+1)*I):G,$e=e=>e.sortable??A,Le=`${C}|${I}|${v?`${v.field}:${v.direction}`:""}|${H}|${JSON.stringify(Q)}`,Te=f.useRef(!0);f.useEffect(()=>{if(Te.current){Te.current=!1;return}const e=Ie.current;e&&typeof e.scrollTo=="function"&&e.scrollTop>0&&e.scrollTo({top:0,behavior:"smooth"})},[Le]);const se=(e,t,r)=>({value:V(t,e.field),formattedValue:ye(e,t),row:t,rowIndex:r,field:e.field,column:e}),xe=(e,t)=>{const r=e.editable??g;return typeof r=="function"?r(t):!!r},ae=(e,t)=>xe(e,t)&&!(e.type==="boolean"&&!e.cellEditor),Ze=(e,t)=>{const r=se(e,t.row,t.index),n=xe(e,r);return{...r,editable:n,updateValue:i=>n&&Fe(t,e,{value:i})}},Be=e=>{if(!$e(e))return;let t;!v||v.field!==e.field?t={field:e.field,direction:"asc"}:v.direction==="asc"?t={field:e.field,direction:"desc"}:t=null,Ue(t),T==null||T(t)},de=(e,t)=>{var r;return(r=ke.current.get(Oe(e,t)))==null?void 0:r.focus()},J=()=>{q.current+=1,ee(null)},ce=(e,t,r={})=>{if(!ae(t,se(t,e.row,e.index)))return!1;const n=V(e.row,t.field),i=t.cellEditor?n:r.text??(n==null?"":String(n));return le.current=i,q.current+=1,ee({id:e.id,field:t.field,draft:i,session:q.current,select:r.select??"end",invalid:!1}),!0},Fe=(e,t,r)=>{const n=Y.current[e.index]??e.row,i=V(n,t.field);let s;if("value"in r)s=r.value;else if(t.valueParser)s=t.valueParser(r.text,n);else if(t.type==="number")if(r.text.trim()==="")s=null;else{const u=Number(r.text);if(!Number.isFinite(u))return!1;s=u}else s=r.text;if(Object.is(s,i))return!0;if(t.validate&&!t.validate(s,n))return!1;const h=Ee(n,t.field,s),a=Y.current.map((u,p)=>p===e.index?h:u);return De(a),x==null||x({rowId:e.id,rowIndex:e.index,field:t.field,oldValue:i,newValue:s,row:h}),m==null||m(a),!0},Me=(e,t,r)=>{const n=M.findIndex(p=>p.id===e.id),i=o.findIndex(p=>p.field===t);if(n<0||i<0)return null;const s=(p,N)=>ae(N,se(N,p.row,p.index));if(r==="down"||r==="up"){const p=r==="down"?1:-1;for(let N=n+p;N>=0&&N<M.length;N+=p)if(s(M[N],o[i]))return{entry:M[N],col:o[i]};return null}const h=r==="right"?1:-1;let a=n,u=i+h;for(;a>=0&&a<M.length;){for(;u>=0&&u<o.length;){if(s(M[a],o[u]))return{entry:M[a],col:o[u]};u+=h}a+=h,u=h>0?0:o.length-1}return null},ne=(e,t,r,n={})=>{const{move:i="none",focus:s=!0}=n;if(!Fe(e,t,r))return ee(a=>a&&{...a,invalid:!0}),!1;const h=i==="none"?null:Me(e,t.field,i);return h?ce(h.entry,h.col,{select:"all"}):(J(),s&&de(e.id,t.field)),!0},et=(e,t,r)=>{if(e.nativeEvent.isComposing)return;const n=e.currentTarget.value;if(e.key==="Enter"){e.preventDefault();const i=P?e.shiftKey?"up":"down":"none";ne(t,r,{text:n},{move:i})}else if(e.key==="Escape")e.preventDefault(),J(),de(t.id,r.field);else if(e.key==="Tab"){const i=e.shiftKey?"left":"right";Me(t,r.field,i)&&(e.preventDefault(),ne(t,r,{text:n},{move:i}))}},tt=(e,t,r,n)=>{e.target!==e.currentTarget||!ae(r,n)||(e.key==="Enter"||e.key==="F2"?(e.preventDefault(),ce(t,r)):!r.cellEditor&&e.key.length===1&&!e.ctrlKey&&!e.metaKey&&!e.altKey&&(e.preventDefault(),ce(t,r,{text:e.key})))},rt=(e,t,r)=>t.cellEditor?l.jsx("div",{className:"rk-grid__custom-editor",onBlur:n=>{n.currentTarget.contains(n.relatedTarget)||r.session===q.current&&(ne(e,t,{value:le.current},{focus:!1})||J())},onKeyDown:n=>{n.key==="Escape"&&(n.preventDefault(),n.stopPropagation(),J(),de(e.id,t.field))},children:f.createElement(t.cellEditor,{value:r.draft,row:e.row,rowIndex:e.index,field:t.field,column:t,onChange:n=>{le.current=n,ee(i=>i&&i.session===r.session?{...i,draft:n,invalid:!1}:i)},onCommit:(n,i="none")=>{r.session===q.current&&ne(e,t,{value:n===void 0?le.current:n},{move:i})},onCancel:()=>{J(),de(e.id,t.field)}})}):l.jsx("input",{autoFocus:!0,className:D("rk-grid__editor",r.invalid&&"rk-grid__editor--invalid",S.editor),style:{textAlign:t.align,...j.editor},value:r.draft===null||r.draft===void 0?"":String(r.draft),inputMode:t.type==="number"?"decimal":void 0,"aria-label":`Edit ${he(t)}`,"aria-invalid":r.invalid||void 0,onChange:n=>{const i=n.target.value;ee(s=>s&&{...s,draft:i,invalid:!1})},onFocus:n=>{const i=n.currentTarget;r.select==="all"?i.select():i.setSelectionRange(i.value.length,i.value.length)},onBlur:n=>{r.session===q.current&&(ne(e,t,{text:n.currentTarget.value},{focus:!1})||J())},onKeyDown:n=>et(n,e,t)}),Ke=e=>{var r,n,i,s,h,a,u,p;const t=e.checkbox??{};return{variant:t.variant??F,indicator:t.indicator,className:t.className,style:t.style,classNames:{root:D(S.checkbox,(r=t.classNames)==null?void 0:r.root),control:D(S.checkboxControl,(n=t.classNames)==null?void 0:n.control),indicator:D(S.checkboxIndicator,(i=t.classNames)==null?void 0:i.indicator),label:(s=t.classNames)==null?void 0:s.label},styles:{root:{...j.checkbox,...(h=t.styles)==null?void 0:h.root},control:{...j.checkboxControl,...(a=t.styles)==null?void 0:a.control},indicator:{...j.checkboxIndicator,...(u=t.styles)==null?void 0:u.indicator},label:(p=t.styles)==null?void 0:p.label}}},ue=e=>e.stopPropagation(),nt=(e,t)=>l.jsx("span",{className:"rk-grid__checkbox-cell",onClick:ue,onDoubleClick:ue,children:l.jsx(je,{...Ke(e),checked:!!t.value,disabled:!t.editable,"aria-label":`Toggle ${he(e)}`,onChange:r=>t.updateValue(r)})}),Re=e=>te.filter(t=>xe(e,se(e,t.row,t.index))),ot=(e,t)=>{const r=new Map(Re(e).map(s=>[s.index,s])),n=[],i=Y.current.map((s,h)=>{const a=r.get(h);if(!a)return s;const u=V(s,e.field);if(!!u===t||e.validate&&!e.validate(t,s))return s;const p=Ee(s,e.field,t);return n.push({rowId:a.id,rowIndex:h,field:e.field,oldValue:u,newValue:t,row:p}),p});n.length!==0&&(De(i),n.forEach(s=>x==null?void 0:x(s)),m==null||m(i))},it=e=>{const t=Re(e),r=t.length>0?t:te,n=r.filter(s=>!!V(s.row,e.field)).length,i=r.length>0&&n===r.length;return l.jsx("span",{className:"rk-grid__header-checkbox",onClick:ue,onDoubleClick:ue,children:l.jsx(je,{...Ke(e),checked:i,indeterminate:n>0&&!i,disabled:t.length===0,label:Se(e)||void 0,"aria-label":`Select all ${he(e)}`,onChange:s=>ot(e,s)})})},lt=pe||!!b,st=b?{"--rk-stripe-a":b[0],"--rk-stripe-b":b[1]}:void 0,at=k&&(E==="top"||E==="both"),dt=!k||E==="bottom"||E==="both",Ve=e=>l.jsxs("div",{className:D("rk-grid__footer",e==="top"&&"rk-grid__footer--top",S.footer),style:j.footer,"data-position":e,children:[l.jsx("span",{..._("rowCount","rk-grid__count"),children:G===0?"0 rows":`${Qe}–${Xe} of ${G}`}),k&&l.jsxs("div",{..._("pagination","rk-grid__pagination"),children:[l.jsxs("label",{className:"rk-grid__page-size-label",children:["Rows per page",l.jsx("select",{value:I,onChange:t=>He(Number(t.target.value)),..._("pageSize","rk-grid__page-size"),children:(y.includes(I)?y:[...y,I].sort((t,r)=>t-r)).map(t=>l.jsx("option",{value:t,children:t},t))})]}),l.jsx("button",{type:"button","aria-label":"First page",disabled:C===0,onClick:()=>X(0),..._("pageButton","rk-grid__page-btn"),children:"«"}),l.jsx("button",{type:"button","aria-label":"Previous page",disabled:C===0,onClick:()=>X(C-1),..._("pageButton","rk-grid__page-btn"),children:"‹"}),l.jsxs("span",{..._("pageInfo","rk-grid__page-info"),children:["Page ",C+1," of ",re]}),l.jsx("button",{type:"button","aria-label":"Next page",disabled:C>=re-1,onClick:()=>X(C+1),..._("pageButton","rk-grid__page-btn"),children:"›"}),l.jsx("button",{type:"button","aria-label":"Last page",disabled:C>=re-1,onClick:()=>X(re-1),..._("pageButton","rk-grid__page-btn"),children:"»"})]})]});return l.jsxs("div",{className:D("rk-grid",S.root,ie),style:{...st,...j.root,...qe},"data-rk-theme":L||void 0,children:[(W||O)&&l.jsxs("div",{..._("toolbar","rk-grid__toolbar"),children:[W?l.jsx("input",{type:"search",value:H,onChange:e=>Ge(e.target.value),placeholder:w,"aria-label":"Search all columns",..._("search","rk-grid__search")}):l.jsx("span",{}),O]}),at&&Ve("top"),l.jsx("div",{ref:Ie,..._("scroll","rk-grid__scroll"),style:{...j.scroll,...R!==void 0?{maxHeight:R}:null},children:l.jsxs("table",{..._("table","rk-grid__table"),role:"grid",children:[l.jsx("thead",{..._("thead","rk-grid__thead"),children:l.jsx("tr",{..._("headerRow","rk-grid__tr"),children:o.map(e=>{const t=(v==null?void 0:v.field)===e.field?v.direction:null,r=$e(e);return l.jsx("th",{scope:"col","aria-sort":t?t==="asc"?"ascending":"descending":r?"none":void 0,tabIndex:r?0:void 0,onClick:()=>Be(e),onKeyDown:n=>{r&&n.target===n.currentTarget&&(n.key==="Enter"||n.key===" ")&&(n.preventDefault(),Be(e))},className:D("rk-grid__th",r&&"rk-grid__th--sortable",S.headerCell,e.className,e.headerClassName),style:{width:e.width,minWidth:e.minWidth,textAlign:e.align,...j.headerCell,...e.style,...e.headerStyle},children:l.jsxs("span",{className:"rk-grid__th-content",children:[e.headerRenderer?f.createElement(e.headerRenderer,{column:e,sortDirection:t}):e.headerCheckbox&&e.type==="boolean"?it(e):Se(e),e.filterable&&l.jsx(pt,{column:e,label:he(e),value:Q[e.field]??"",onChange:n=>Je(i=>({...i,[e.field]:n})),theme:L,indicatorClassName:D(S.filterIndicator,e.filterIndicatorClassName),indicatorStyle:{...j.filterIndicator,...e.filterIndicatorStyle},popupClassName:D(S.filterPopup,e.filterPopupClassName),popupStyle:{...j.filterPopup,...e.filterPopupStyle},inputClassName:S.filterInput,inputStyle:j.filterInput}),r&&l.jsx("span",{className:"rk-grid__sort","aria-hidden":"true",children:t==="asc"?"▲":t==="desc"?"▼":"↕"})]})},e.field)})})}),l.jsx("tbody",{..._("tbody","rk-grid__tbody"),children:M.length===0?l.jsx("tr",{children:l.jsx("td",{colSpan:o.length,..._("empty","rk-grid__empty"),children:$})}):M.map((e,t)=>{const{row:r,id:n,index:i}=e,s=typeof ge=="function"?ge(r,i):ge,h=typeof be=="function"?be(r,i):be;return l.jsx("tr",{onClick:z?()=>z(r,i):void 0,className:D("rk-grid__tr","rk-grid__row",lt&&(t%2===0?"rk-grid__row--stripe-a":"rk-grid__row--stripe-b"),K&&"rk-grid__row--enter",z&&"rk-grid__row--clickable",S.row,s),style:{...K?{"--rk-i":Math.min(t,24)}:null,...j.row,...h},children:o.map(a=>{const u=Ze(a,e),p=typeof a.cellClassName=="function"?a.cellClassName(u):a.cellClassName,N=typeof a.cellStyle=="function"?a.cellStyle(u):a.cellStyle,_e=Z!==null&&Z.id===n&&Z.field===a.field,me=ae(a,u);return l.jsx("td",{ref:fe=>{const Ae=Oe(n,a.field);fe?ke.current.set(Ae,fe):ke.current.delete(Ae)},tabIndex:me?0:void 0,onDoubleClick:me?()=>ce(e,a):void 0,onKeyDown:fe=>tt(fe,e,a,u),className:D("rk-grid__td",me&&"rk-grid__td--editable",_e&&"rk-grid__td--editing",S.cell,a.className,p),style:{textAlign:a.align,...j.cell,...a.style,...N},children:_e&&Z?rt(e,a,Z):a.cellRenderer?f.createElement(a.cellRenderer,u):a.type==="boolean"&&!a.cellEditor?nt(a,u):u.formattedValue},a.field)})},n)})},Le)]})}),dt&&Ve("bottom")]})}exports.Checkbox=je;exports.DataGrid=bt;
|