@classytic/fluid 0.3.6 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/core.d.mts +14 -18
- package/dist/client/core.mjs +105 -279
- package/dist/client/spreadsheet.d.mts +207 -0
- package/dist/client/spreadsheet.mjs +611 -0
- package/dist/client/table.d.mts +41 -5
- package/dist/client/table.mjs +54 -7
- package/dist/dropdown-wrapper-B86u9Fri.mjs +357 -0
- package/dist/forms.mjs +4 -4
- package/package.json +32 -15
- package/dist/api-pagination-DBTE0yk4.mjs +0 -190
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
2
|
+
import * as react from "react";
|
|
3
|
+
import { ComponentType, ReactNode } from "react";
|
|
4
|
+
|
|
5
|
+
//#region src/components/spreadsheet/types.d.ts
|
|
6
|
+
interface SpreadsheetColumn<TData = unknown> {
|
|
7
|
+
/** Unique column identifier — also used as the field key unless `field` is set */
|
|
8
|
+
id: string;
|
|
9
|
+
/** Optional field key on the data object (defaults to `id`) */
|
|
10
|
+
field?: string;
|
|
11
|
+
/** Column header label */
|
|
12
|
+
header: string | ReactNode;
|
|
13
|
+
/** CSS width: '20%', '120px', 'minmax(100px, 1fr)', etc. */
|
|
14
|
+
width: string;
|
|
15
|
+
/** Text alignment */
|
|
16
|
+
align?: "left" | "right" | "center";
|
|
17
|
+
/** Component that renders the cell content */
|
|
18
|
+
cell: ComponentType<CellRenderProps<TData>>;
|
|
19
|
+
/** Label shown above the field in mobile card layout */
|
|
20
|
+
mobileLabel?: string;
|
|
21
|
+
/** grid-cols-12 span for mobile card layout (default 12 = full width) */
|
|
22
|
+
mobileSpan?: number;
|
|
23
|
+
/** Hide column conditionally (e.g., hide actions when read-only) */
|
|
24
|
+
hiddenWhen?: (ctx: {
|
|
25
|
+
isReadOnly: boolean;
|
|
26
|
+
}) => boolean;
|
|
27
|
+
/** Data type hint for clipboard paste coercion. "number" coerces pasted strings to numbers. */
|
|
28
|
+
dataType?: "string" | "number";
|
|
29
|
+
}
|
|
30
|
+
interface CellRenderProps<TData = unknown> {
|
|
31
|
+
/** Current field value */
|
|
32
|
+
value: unknown;
|
|
33
|
+
/** Full row data object */
|
|
34
|
+
row: TData;
|
|
35
|
+
/** Stable row ID (UUID) */
|
|
36
|
+
rowId: string;
|
|
37
|
+
/** Visual row index (0-based, accounts for filtering) */
|
|
38
|
+
rowIndex: number;
|
|
39
|
+
/** Column definition */
|
|
40
|
+
column: SpreadsheetColumn<TData>;
|
|
41
|
+
/**
|
|
42
|
+
* Commit a value change.
|
|
43
|
+
* - Single field: `onChange("debit", 100)`
|
|
44
|
+
* - Multi-field batch: `onChange({ debit: 100, credit: 0 })`
|
|
45
|
+
*/
|
|
46
|
+
onChange: (fieldOrPatch: string | Record<string, unknown>, value?: unknown) => void;
|
|
47
|
+
/** Whether the spreadsheet is in read-only mode */
|
|
48
|
+
isReadOnly: boolean;
|
|
49
|
+
/** Data attributes for keyboard navigation */
|
|
50
|
+
cellRef?: string;
|
|
51
|
+
}
|
|
52
|
+
interface SpreadsheetTableProps<TData = unknown> {
|
|
53
|
+
/** Column definitions */
|
|
54
|
+
columns: SpreadsheetColumn<TData>[];
|
|
55
|
+
/** Items state from useSpreadsheetStore */
|
|
56
|
+
items: Map<string, TData>;
|
|
57
|
+
/** Ordered row IDs (can be pre-filtered for search) */
|
|
58
|
+
orderedIds: string[];
|
|
59
|
+
/** Dispatch function from useSpreadsheetStore */
|
|
60
|
+
dispatch: (action: SpreadsheetAction<TData>) => void;
|
|
61
|
+
/** Read-only mode (e.g., posted journal entries) */
|
|
62
|
+
isReadOnly?: boolean;
|
|
63
|
+
/** Enable row virtualization (recommended when > 30 rows) */
|
|
64
|
+
virtualize?: boolean;
|
|
65
|
+
/** Estimated row height for virtualization (default: 48) */
|
|
66
|
+
estimateRowHeight?: number;
|
|
67
|
+
/** Render a footer row (e.g., totals) — used inside <tfoot> on desktop */
|
|
68
|
+
footer?: ReactNode;
|
|
69
|
+
/** Separate footer for mobile card layout (avoids <tr> inside <div>) */
|
|
70
|
+
mobileFooter?: ReactNode;
|
|
71
|
+
/** Render row action buttons (add/remove) */
|
|
72
|
+
rowActions?: (props: {
|
|
73
|
+
rowId: string;
|
|
74
|
+
rowIndex: number;
|
|
75
|
+
isReadOnly: boolean;
|
|
76
|
+
}) => ReactNode;
|
|
77
|
+
/** CSS class for the table container */
|
|
78
|
+
className?: string;
|
|
79
|
+
/** Accessible label for the table */
|
|
80
|
+
ariaLabel?: string;
|
|
81
|
+
/** Called when a row is added (receives the ID of the row to insert after) */
|
|
82
|
+
onAddRow?: (afterRowId: string) => void;
|
|
83
|
+
/** Called when a row is removed */
|
|
84
|
+
onRemoveRow?: (rowId: string) => void;
|
|
85
|
+
}
|
|
86
|
+
interface SpreadsheetState<TData> {
|
|
87
|
+
items: Map<string, TData>;
|
|
88
|
+
orderedIds: string[];
|
|
89
|
+
}
|
|
90
|
+
type SpreadsheetAction<TData = unknown> = {
|
|
91
|
+
type: "SET_ALL";
|
|
92
|
+
items: TData[];
|
|
93
|
+
getId?: (item: TData) => string;
|
|
94
|
+
} | {
|
|
95
|
+
type: "UPDATE_CELL";
|
|
96
|
+
rowId: string;
|
|
97
|
+
field: string;
|
|
98
|
+
value: unknown;
|
|
99
|
+
} | {
|
|
100
|
+
type: "UPDATE_ROW";
|
|
101
|
+
rowId: string;
|
|
102
|
+
patch: Partial<TData>;
|
|
103
|
+
} | {
|
|
104
|
+
type: "ADD_ROW";
|
|
105
|
+
afterRowId: string;
|
|
106
|
+
item: TData;
|
|
107
|
+
newId?: string;
|
|
108
|
+
} | {
|
|
109
|
+
type: "REMOVE_ROW";
|
|
110
|
+
rowId: string;
|
|
111
|
+
} | {
|
|
112
|
+
type: "BATCH";
|
|
113
|
+
actions: SpreadsheetAction<TData>[];
|
|
114
|
+
};
|
|
115
|
+
//#endregion
|
|
116
|
+
//#region src/components/spreadsheet/spreadsheet-table.d.ts
|
|
117
|
+
declare function SpreadsheetTable<TData = unknown>({
|
|
118
|
+
columns,
|
|
119
|
+
items,
|
|
120
|
+
orderedIds,
|
|
121
|
+
dispatch,
|
|
122
|
+
isReadOnly,
|
|
123
|
+
footer,
|
|
124
|
+
mobileFooter,
|
|
125
|
+
rowActions,
|
|
126
|
+
className,
|
|
127
|
+
ariaLabel,
|
|
128
|
+
onAddRow,
|
|
129
|
+
virtualize,
|
|
130
|
+
estimateRowHeight
|
|
131
|
+
}: SpreadsheetTableProps<TData>): react_jsx_runtime0.JSX.Element;
|
|
132
|
+
//#endregion
|
|
133
|
+
//#region src/components/spreadsheet/spreadsheet-row.d.ts
|
|
134
|
+
interface SpreadsheetRowProps<TData = unknown> {
|
|
135
|
+
rowId: string;
|
|
136
|
+
rowIndex: number;
|
|
137
|
+
item: TData;
|
|
138
|
+
visibleColumns: SpreadsheetColumn<TData>[];
|
|
139
|
+
dispatch: (action: SpreadsheetAction<TData>) => void;
|
|
140
|
+
isReadOnly: boolean;
|
|
141
|
+
rowActions?: (props: {
|
|
142
|
+
rowId: string;
|
|
143
|
+
rowIndex: number;
|
|
144
|
+
isReadOnly: boolean;
|
|
145
|
+
}) => ReactNode;
|
|
146
|
+
onCellKeyDown?: (e: React.KeyboardEvent, rowId: string, colId: string) => void;
|
|
147
|
+
cellAttr?: string;
|
|
148
|
+
isMobile?: boolean;
|
|
149
|
+
style?: React.CSSProperties;
|
|
150
|
+
/** Ref callback from virtualizer for dynamic row measurement */
|
|
151
|
+
measureRef?: (node: HTMLElement | null) => void;
|
|
152
|
+
}
|
|
153
|
+
declare function SpreadsheetRowInner<TData>({
|
|
154
|
+
rowId,
|
|
155
|
+
rowIndex,
|
|
156
|
+
item,
|
|
157
|
+
visibleColumns,
|
|
158
|
+
dispatch,
|
|
159
|
+
isReadOnly,
|
|
160
|
+
rowActions,
|
|
161
|
+
onCellKeyDown,
|
|
162
|
+
cellAttr,
|
|
163
|
+
isMobile,
|
|
164
|
+
style,
|
|
165
|
+
measureRef
|
|
166
|
+
}: SpreadsheetRowProps<TData>): react_jsx_runtime0.JSX.Element;
|
|
167
|
+
declare const SpreadsheetRow: typeof SpreadsheetRowInner;
|
|
168
|
+
//#endregion
|
|
169
|
+
//#region src/components/spreadsheet/use-spreadsheet-store.d.ts
|
|
170
|
+
declare function useSpreadsheetStore<TData>(initialItems?: TData[], getId?: (item: TData) => string): {
|
|
171
|
+
items: Map<string, TData>;
|
|
172
|
+
orderedIds: string[];
|
|
173
|
+
dispatch: react.ActionDispatch<[action: SpreadsheetAction<TData>]>;
|
|
174
|
+
getOrderedItems: () => TData[];
|
|
175
|
+
rowCount: number;
|
|
176
|
+
};
|
|
177
|
+
type SpreadsheetStore<TData> = ReturnType<typeof useSpreadsheetStore<TData>>;
|
|
178
|
+
//#endregion
|
|
179
|
+
//#region src/components/spreadsheet/use-spreadsheet-keyboard.d.ts
|
|
180
|
+
interface UseSpreadsheetKeyboardOptions {
|
|
181
|
+
/** Ordered row IDs (visible/filtered) */
|
|
182
|
+
orderedIds: string[];
|
|
183
|
+
/** Column IDs in display order */
|
|
184
|
+
columnIds: string[];
|
|
185
|
+
/** Ref to the table container element */
|
|
186
|
+
containerRef: React.RefObject<HTMLElement | null>;
|
|
187
|
+
/** Add a row when navigating past the end */
|
|
188
|
+
onAddRow?: (afterRowId: string) => void;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Keyboard navigation for spreadsheet cells.
|
|
192
|
+
*
|
|
193
|
+
* Tab → next cell → wrap to next row
|
|
194
|
+
* Shift+Tab → previous cell → wrap to previous row
|
|
195
|
+
* Enter → commit + move down (same column, next row)
|
|
196
|
+
*/
|
|
197
|
+
declare function useSpreadsheetKeyboard({
|
|
198
|
+
orderedIds,
|
|
199
|
+
columnIds,
|
|
200
|
+
containerRef,
|
|
201
|
+
onAddRow
|
|
202
|
+
}: UseSpreadsheetKeyboardOptions): {
|
|
203
|
+
handleCellKeyDown: (e: React.KeyboardEvent, rowId: string, colId: string) => void;
|
|
204
|
+
CELL_ATTR: string;
|
|
205
|
+
};
|
|
206
|
+
//#endregion
|
|
207
|
+
export { type CellRenderProps, type SpreadsheetAction, type SpreadsheetColumn, SpreadsheetRow, type SpreadsheetState, type SpreadsheetStore, SpreadsheetTable, type SpreadsheetTableProps, useSpreadsheetKeyboard, useSpreadsheetStore };
|