@fluixi-ui/bulk-editor 0.2.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.
@@ -0,0 +1,16 @@
1
+ import { type FormulaFn } from '@fluixi-ui/formula';
2
+ import type { CellEvaluator } from './types.js';
3
+ export interface FormulaEvaluatorOptions {
4
+ /** Extra functions merged over (and overriding) the built-ins, matched case-insensitively. */
5
+ functions?: Record<string, FormulaFn>;
6
+ }
7
+ /**
8
+ * A drop-in `evaluate` hook that turns `=`-prefixed cell values into spreadsheet
9
+ * formulas (arithmetic, A1 refs, ranges, SUM/IF/…). Non-formula values pass
10
+ * through unchanged. Wire it up with `<BulkEditor evaluate={formulaEvaluator()} />`.
11
+ *
12
+ * The editor's `get` already resolves A1 addresses against the original row
13
+ * order with a cycle guard, so cross-cell references and ranges work as-is.
14
+ */
15
+ export declare function formulaEvaluator(options?: FormulaEvaluatorOptions): CellEvaluator;
16
+ //# sourceMappingURL=formula.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formula.d.ts","sourceRoot":"","sources":["../src/formula.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,uBAAuB;IACtC,8FAA8F;IAC9F,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACvC;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE,uBAAuB,GAAG,aAAa,CAEjF"}
@@ -0,0 +1,13 @@
1
+ import { evaluateFormula } from "@fluixi-ui/formula";
2
+ function formulaEvaluator(options) {
3
+ return ({
4
+ raw,
5
+ get
6
+ }) => evaluateFormula(raw, {
7
+ resolve: get,
8
+ functions: options?.functions
9
+ });
10
+ }
11
+ export {
12
+ formulaEvaluator
13
+ };
@@ -0,0 +1,9 @@
1
+ import '@fluixi-ui/tokens/css/base.css';
2
+ import '@fluixi-ui/tokens/css/parts/motion.css';
3
+ import '@fluixi-ui/tokens/css/bulk-editor.css';
4
+ import '@fluixi-ui/tokens/css/parts/menu.css';
5
+ export * from './types.js';
6
+ export { BulkEditor } from './bulk-editor.js';
7
+ export { formulaEvaluator, type FormulaEvaluatorOptions } from './formula.js';
8
+ export { createBulkEditorState, colToLabel, labelToCol, parseAddress, matchesFilter, type BulkEditorState, } from './state.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,gCAAgC,CAAC;AACxC,OAAO,wCAAwC,CAAC;AAChD,OAAO,uCAAuC,CAAC;AAC/C,OAAO,sCAAsC,CAAC;AAE9C,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EACL,qBAAqB,EACrB,UAAU,EACV,UAAU,EACV,YAAY,EACZ,aAAa,EACb,KAAK,eAAe,GACrB,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,16 @@
1
+ import "@fluixi-ui/tokens/css/base.css";
2
+ import "@fluixi-ui/tokens/css/parts/motion.css";
3
+ import "@fluixi-ui/tokens/css/bulk-editor.css";
4
+ import "@fluixi-ui/tokens/css/parts/menu.css";
5
+ import { BulkEditor } from "./bulk-editor.js";
6
+ import { formulaEvaluator } from "./formula.js";
7
+ import { colToLabel, createBulkEditorState, labelToCol, matchesFilter, parseAddress } from "./state.js";
8
+ export {
9
+ BulkEditor,
10
+ colToLabel,
11
+ createBulkEditorState,
12
+ formulaEvaluator,
13
+ labelToCol,
14
+ matchesFilter,
15
+ parseAddress
16
+ };
@@ -0,0 +1,105 @@
1
+ import { type Accessor } from '@fluixi/reactive/signal';
2
+ import type { BulkEditorColumn, BulkEditorRow, BulkEditorStateOptions, CellPosition, CellRange, Selection } from './types.js';
3
+ /**
4
+ * Match a cell value against a filter term. Numeric terms may use comparison
5
+ * operators (`>20`, `<=5`, `!=0`) or modulo (`%3`, `%3=1`); anything else is a
6
+ * case-insensitive substring match.
7
+ */
8
+ export declare function matchesFilter(value: string, filter: string): boolean;
9
+ export declare function colToLabel(col: number): string;
10
+ export declare function labelToCol(label: string): number;
11
+ /** `"B3"` → `{ row: 2, col: 1 }`, or `null` if not a valid A1 address. */
12
+ export declare function parseAddress(address: string): CellPosition | null;
13
+ export interface BulkEditorState {
14
+ readonly columns: Accessor<BulkEditorColumn[]>;
15
+ readonly dataRows: Accessor<BulkEditorRow[]>;
16
+ /** Rows to render — original (groups included) or the flat sorted/filtered view. */
17
+ readonly viewRows: Accessor<BulkEditorRow[]>;
18
+ readonly rowCount: Accessor<number>;
19
+ readonly colCount: Accessor<number>;
20
+ sort: Accessor<{
21
+ colKey: string;
22
+ dir: 'asc' | 'desc';
23
+ } | null>;
24
+ sortBy: (colKey: string) => void;
25
+ setSort: (next: {
26
+ colKey: string;
27
+ dir: 'asc' | 'desc';
28
+ } | null) => void;
29
+ columnWidths: Accessor<Map<string, number>>;
30
+ setColumnWidth: (colKey: string, width: number) => void;
31
+ resetColumnWidth: (colKey: string) => void;
32
+ columnOrder: Accessor<string[] | null>;
33
+ setColumnOrder: (keys: string[] | null) => void;
34
+ /** Move `fromKey` so it lands at `toKey`'s position. */
35
+ moveColumn: (fromKey: string, toKey: string) => void;
36
+ /** The footer value for a column (built-in or custom `aggregate`), or `''`. */
37
+ getColumnAggregate: (colKey: string) => string;
38
+ columnFilters: Accessor<Map<string, string>>;
39
+ getColumnFilter: (colKey: string) => string;
40
+ setColumnFilter: (colKey: string, text: string) => void;
41
+ clearFilters: () => void;
42
+ rowAt: (r: number) => BulkEditorRow | undefined;
43
+ colAt: (c: number) => BulkEditorColumn | undefined;
44
+ cellAddress: (r: number, c: number) => string;
45
+ getRaw: (rowId: string, colKey: string) => string;
46
+ getComputed: (rowId: string, colKey: string) => string;
47
+ getDisplay: (rowId: string, colKey: string) => string;
48
+ getRawAt: (r: number, c: number) => string;
49
+ getComputedAt: (r: number, c: number) => string;
50
+ getDisplayAt: (r: number, c: number) => string;
51
+ setCellAt: (r: number, c: number, value: string) => void;
52
+ isColumnReadOnly: (col: BulkEditorColumn) => boolean;
53
+ lockedCells: Accessor<Set<string>>;
54
+ isCellLocked: (rowId: string, colKey: string) => boolean;
55
+ isCellLockedAt: (r: number, c: number) => boolean;
56
+ setCellLocked: (rowId: string, colKey: string, locked: boolean) => void;
57
+ toggleCellLock: (rowId: string, colKey: string) => void;
58
+ /** A row's lock state derived from its editable cells. */
59
+ getRowLockState: (rowId: string) => 'all' | 'some' | 'none';
60
+ toggleRowLock: (rowId: string) => void;
61
+ getColumnLockState: (colKey: string) => 'all' | 'some' | 'none';
62
+ toggleColumnLock: (colKey: string) => void;
63
+ lockSelection: (locked: boolean) => void;
64
+ errors: Accessor<Map<string, string>>;
65
+ getError: (rowId: string, colKey: string) => string | undefined;
66
+ getErrorAt: (r: number, c: number) => string | undefined;
67
+ hasErrors: Accessor<boolean>;
68
+ selection: Accessor<Selection | null>;
69
+ selectionRange: Accessor<CellRange | null>;
70
+ hasSelection: Accessor<boolean>;
71
+ isSelected: (r: number, c: number) => boolean;
72
+ isAnchor: (r: number, c: number) => boolean;
73
+ selectCell: (r: number, c: number, extend?: boolean) => void;
74
+ move: (dr: number, dc: number, extend?: boolean) => void;
75
+ selectRow: (r: number) => void;
76
+ selectColumn: (c: number) => void;
77
+ selectAll: () => void;
78
+ clearSelection: () => void;
79
+ editing: Accessor<CellPosition | null>;
80
+ editBuffer: Accessor<string>;
81
+ setEditBuffer: (value: string) => void;
82
+ isEditing: (r: number, c: number) => boolean;
83
+ startEdit: (r: number, c: number, initChar?: string) => boolean;
84
+ commitEdit: () => void;
85
+ cancelEdit: () => void;
86
+ clearRange: () => void;
87
+ fillDown: () => void;
88
+ toggleCheckbox: (r: number, c: number) => void;
89
+ getColumnCheckedState: (colKey: string) => 'all' | 'some' | 'none';
90
+ toggleColumnChecked: (colKey: string) => void;
91
+ getSelectionTSV: () => string;
92
+ pasteTSV: (text: string) => void;
93
+ undo: () => void;
94
+ redo: () => void;
95
+ canUndo: Accessor<boolean>;
96
+ canRedo: Accessor<boolean>;
97
+ }
98
+ /**
99
+ * The headless spreadsheet engine: dimensions, a per-cell raw-value store synced
100
+ * from `rows().data`, a 2D range-selection model, an edit buffer, and the bulk
101
+ * operations (fill, clear, TSV copy/paste). No DOM, no JSX — the component wires
102
+ * events to these actions and reads the accessors to render.
103
+ */
104
+ export declare function createBulkEditorState(options: BulkEditorStateOptions): BulkEditorState;
105
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"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"}