y11n-spreadsheet 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,10 +4,13 @@ An accessible spreadsheet web component built with [Lit 3.0](https://lit.dev). I
4
4
 
5
5
  ## Features
6
6
 
7
- - Full keyboard navigation (arrows, Tab, Enter, Escape, Ctrl+A)
7
+ - Full keyboard navigation (arrows, Ctrl+Arrow data-edge jumps, Tab, Enter, Escape, Ctrl+A)
8
+ - Row/column selection via headers (click, Shift+click, drag) or Ctrl+Space / Shift+Space
9
+ - Fill down/right (Ctrl+D / Ctrl+R) and multi-cell entry (Ctrl+Enter)
10
+ - CSV/TSV import and export
8
11
  - Copy/cut/paste with TSV clipboard format
9
12
  - Undo/redo with Ctrl+Z / Ctrl+Shift+Z (or Ctrl+Y)
10
- - Formula engine with 20+ built-in functions and custom function support
13
+ - Formula engine with 50+ built-in functions and custom function support
11
14
  - Arrow key cell reference insertion during formula editing
12
15
  - Virtual rendering for large datasets (1000+ rows)
13
16
  - Dual-mode formula bar (raw / formatted)
@@ -74,8 +77,36 @@ sheet.setData(data);
74
77
  sheet.getData() // Returns a copy of the grid data
75
78
  sheet.setData(data) // Replaces grid data (clears undo/redo)
76
79
  sheet.registerFunction('DOUBLE', (ctx, val) => Number(val) * 2)
80
+
81
+ // Formatting
82
+ sheet.setCellFormat('0:0', { bold: true, verticalAlign: 'top', wrap: true })
83
+ sheet.setRangeFormat({ start: { row: 1, col: 1 }, end: { row: 9, col: 1 } },
84
+ { numberFormat: { type: 'date', datePattern: 'DD/MM/YYYY' } })
85
+
86
+ // CSV / TSV
87
+ sheet.toCSV() // display values, A1 → last used cell
88
+ sheet.toCSV({ values: 'raw', delimiter: '\t' }) // formulas, as TSV
89
+ sheet.toCSV({ range: { start: { row: 0, col: 0 }, end: { row: 9, col: 3 } } })
90
+ sheet.fromCSV(text) // write at A1 (undoable)
91
+ sheet.fromCSV(text, { start: { row: 5, col: 0 }, delimiter: ';' })
77
92
  ```
78
93
 
94
+ `fromCSV` drops values outside `rows` × `cols` (and throws a `RangeError` for a negative or non-integer `start`); use the exported `parseDelimited(text)` to size the grid first if needed.
95
+
96
+ ### Cell formats
97
+
98
+ | Property | Type | Description |
99
+ |----------|------|-------------|
100
+ | `bold`, `italic`, `underline`, `strikethrough` | `boolean` | Text styling |
101
+ | `textColor`, `backgroundColor` | `string` | CSS colors |
102
+ | `textAlign` | `'left' \| 'center' \| 'right'` | Horizontal alignment |
103
+ | `verticalAlign` | `'top' \| 'middle' \| 'bottom'` | Vertical alignment (default middle) |
104
+ | `wrap` | `boolean` | Wrap text instead of truncating. Rows keep their fixed height, so only the lines that fit are shown |
105
+ | `fontSize` | `number` | Font size in px |
106
+ | `numberFormat` | `NumberFormatOptions` | `{ type: 'number' \| 'currency' \| 'percent' \| 'scientific' \| 'date', decimals?, currencySymbol?, thousandsSep?, datePattern? }` |
107
+
108
+ The `date` type renders date serial numbers (as returned by `DATE`, `TODAY`, `NOW`) using `datePattern` (default `YYYY-MM-DD`; tokens `YYYY YY MM M DD D HH H mm ss`).
109
+
79
110
  ### Events
80
111
 
81
112
  ```js
@@ -89,7 +120,7 @@ sheet.addEventListener('selection-change', (e) => {
89
120
  console.log(e.detail.range); // { start: { row, col }, end: { row, col } }
90
121
  });
91
122
 
92
- // Bulk operation (paste, cut, clear, undo, redo)
123
+ // Bulk operation (paste, cut, clear, fill, import, undo, redo)
93
124
  sheet.addEventListener('data-change', (e) => {
94
125
  console.log(e.detail.updates, e.detail.source, e.detail.operation);
95
126
  });
@@ -107,10 +138,15 @@ Formulas start with `=`. Supported syntax:
107
138
 
108
139
  | Category | Functions |
109
140
  |----------|-----------|
110
- | Aggregates | `SUM`, `AVERAGE`, `MIN`, `MAX`, `COUNT`, `COUNTA` |
111
- | Conditional | `IF(condition, trueVal, falseVal)` |
112
- | Math | `ABS`, `ROUND` |
113
- | String | `CONCAT`, `UPPER`, `LOWER`, `LEN`, `TRIM` |
141
+ | Aggregates | `SUM`, `AVERAGE`, `MIN`, `MAX`, `COUNT`, `COUNTA`, `PRODUCT`, `MEDIAN` |
142
+ | Conditional aggregates | `SUMIF`, `COUNTIF`, `AVERAGEIF`, `SUMIFS`, `COUNTIFS`, `AVERAGEIFS` |
143
+ | Logic | `IF`, `IFS`, `IFERROR`, `AND`, `OR`, `NOT` |
144
+ | Lookup | `VLOOKUP`, `HLOOKUP`, `XLOOKUP`, `INDEX`, `MATCH` |
145
+ | Math | `ABS`, `ROUND`, `ROUNDUP`, `ROUNDDOWN`, `INT`, `MOD`, `POWER`, `SQRT`, `CEILING`, `FLOOR` |
146
+ | Text | `CONCAT`, `TEXTJOIN`, `UPPER`, `LOWER`, `LEN`, `TRIM`, `LEFT`, `RIGHT`, `MID`, `SUBSTITUTE`, `FIND`, `TEXT`, `VALUE` |
147
+ | Date | `DATE`, `TODAY`, `NOW`, `YEAR`, `MONTH`, `DAY`, `WEEKDAY` |
148
+
149
+ Omitted arguments use their defaults, e.g. `=XLOOKUP(75, A1:A9, B1:B9, , -1)`. Criteria in `SUMIF`/`COUNTIF`/`AVERAGEIF` and the `*IFS` functions accept operators (`">5"`, `"<>x"`) and wildcards (`*`, `?`, `~` to escape). `XLOOKUP` supports match modes `0`, `-1`, `1` (not wildcard mode `2`) and search modes `1`/`-1`; it returns a single value (no spilling).
114
150
 
115
151
  **Custom functions**:
116
152
 
@@ -163,6 +199,7 @@ y11n-spreadsheet {
163
199
  | `--ls-formula-mode-active-bg` | `#dbeafe` | Active mode toggle background |
164
200
  | `--ls-ref-highlight-border` | `#1a73e8` | Reference highlight border |
165
201
  | `--ls-ref-highlight-bg` | `rgba(26, 115, 232, 0.15)` | Reference highlight fill |
202
+ | `--ls-header-selected-bg` | `#dbe7fb` | Row/column header background for selected rows/columns |
166
203
 
167
204
  </details>
168
205
 
@@ -180,11 +217,19 @@ y11n-spreadsheet::part(editor) {
180
217
  |-----|--------|
181
218
  | Arrow keys | Move active cell |
182
219
  | Shift + Arrow | Extend selection |
220
+ | Ctrl/Cmd + Arrow | Jump to the edge of the data region |
221
+ | Ctrl/Cmd + Shift + Arrow | Extend selection to the edge of the data region |
222
+ | Ctrl + Space | Select entire column(s) |
223
+ | Shift + Space | Select entire row(s) |
224
+ | Ctrl + Shift + Space, Ctrl+A | Select all |
183
225
  | Tab / Shift+Tab | Move right / left |
184
- | Enter | Start editing / commit edit |
226
+ | Enter / Shift+Enter (editing) | Commit edit and move down / up |
227
+ | Ctrl/Cmd + Enter (editing) | Commit the value into every selected cell |
228
+ | Enter, F2 | Start editing |
185
229
  | Escape | Cancel edit / clear selection |
186
230
  | Delete, Backspace | Clear selected cells |
187
- | Ctrl+A | Select all |
231
+ | Ctrl/Cmd + D | Fill down (copy the top row of the selection into the rest) |
232
+ | Ctrl/Cmd + R | Fill right (copy the left column of the selection into the rest) |
188
233
  | Ctrl+C / X / V | Copy / Cut / Paste |
189
234
  | Ctrl+Z | Undo |
190
235
  | Ctrl+Shift+Z / Ctrl+Y | Redo |
@@ -210,7 +255,7 @@ import type {
210
255
  } from 'y11n-spreadsheet';
211
256
  ```
212
257
 
213
- Utility functions for coordinate conversion:
258
+ Utility functions for coordinate conversion, dates, and delimited text:
214
259
 
215
260
  ```ts
216
261
  import { cellKey, parseKey, colToLetter, letterToCol, refToCoord, coordToRef } from 'y11n-spreadsheet';
@@ -221,6 +266,12 @@ colToLetter(0) // "A"
221
266
  letterToCol("AA") // 26
222
267
  refToCoord("B3") // { row: 2, col: 1 }
223
268
  coordToRef({row:0, col:0}) // "A1"
269
+
270
+ import { dateToSerial, dateSerialToDate, parseDelimited, serializeDelimited } from 'y11n-spreadsheet';
271
+
272
+ dateToSerial(2024, 0, 1) // 45292 (month is 0-indexed)
273
+ parseDelimited('a,"b,c"\n1,2') // [['a', 'b,c'], ['1', '2']]
274
+ serializeDelimited([['a', 'b,c']]) // 'a,"b,c"'
224
275
  ```
225
276
 
226
277
  ## Exports
@@ -282,9 +333,11 @@ src/
282
333
  components/y11n-formula-bar.ts # Formula bar sub-component
283
334
  controllers/
284
335
  selection-manager.ts # Selection state (Lit ReactiveController)
285
- clipboard-manager.ts # Clipboard operations (TSV format)
336
+ clipboard-manager.ts # Clipboard operations (TSV + HTML formats)
286
337
  engine/
287
338
  formula-engine.ts # Recursive descent formula parser
339
+ utils/
340
+ delimited.ts # CSV/TSV parsing and serialization
288
341
  __tests__/ # Unit tests colocated with source
289
342
  e2e/ # Playwright E2E tests
290
343
  stories/ # Storybook stories
@@ -81,11 +81,6 @@ export declare class ClipboardManager {
81
81
  id: string;
82
82
  value: string;
83
83
  }>;
84
- /**
85
- * Parse TSV text into a 2D array of strings, respecting quoted fields.
86
- * Quoted fields may contain tabs, newlines, and escaped quotes ("").
87
- */
88
- private _parseTSVRows;
89
84
  /**
90
85
  * Adjust cell references in a formula by the given row/col offset.
91
86
  * Absolute references (`$A$1`) are not adjusted.
@@ -99,8 +94,6 @@ export declare class ClipboardManager {
99
94
  */
100
95
  adjustFormulaReferences(formula: string, rowOffset: number, colOffset: number): string;
101
96
  private serializeRange;
102
- /** Quote a TSV field if it contains tabs, newlines, or double-quotes */
103
- private _quoteTSVField;
104
97
  /**
105
98
  * Convert a selection range to an HTML table string.
106
99
  * Includes inline styles for visual formatting and data-format for lossless round-trip.
@@ -1 +1 @@
1
- {"version":3,"file":"clipboard-manager.d.ts","sourceRoot":"","sources":["../../src/controllers/clipboard-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,UAAU,EACf,KAAK,QAAQ,EAEb,KAAK,cAAc,EAIpB,MAAM,aAAa,CAAC;AAErB,0DAA0D;AAC1D,MAAM,WAAW,WAAW;IAC1B,qCAAqC;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,oGAAoG;IACpG,OAAO,CAAC,gBAAgB,CAA+B;IACvD,OAAO,CAAC,eAAe,CAAyB;IAChD,sFAAsF;IACtF,OAAO,CAAC,gBAAgB,CAAuB;IAE/C;;;;;;;OAOG;IACG,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAmC/D;IAED;;;;;;OAMG;IACG,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CASlE;IAED;;;;;;;;;;OAUG;IACG,KAAK,CACT,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,CA+C/B;IAED;;;OAGG;IACH,OAAO,CAAC,cAAc;IAuCtB;;;OAGG;IACH,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC,GAAG,IAAI,CA0ClG;IAED;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAuBlC;;;;;;;;;;;;OAYG;IACH,QAAQ,CACN,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAgBtC;IAED;;;OAGG;IACH,OAAO,CAAC,aAAa;IAuErB;;;;;;;;;;OAUG;IACH,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CA+DrF;IAID,OAAO,CAAC,cAAc;IAgBtB,wEAAwE;IACxE,OAAO,CAAC,cAAc;IAOtB;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAgC7B,sDAAsD;IACtD,OAAO,CAAC,oBAAoB;IAe5B,2FAA2F;IAC3F,OAAO,CAAC,mBAAmB;IAsC3B,wEAAwE;IACxE,OAAO,CAAC,eAAe;IA+BvB,OAAO,CAAC,qBAAqB;IAkB7B,OAAO,CAAC,iBAAiB;IAQzB,qCAAqC;IACrC,OAAO,CAAC,WAAW;IAUnB,wIAAwI;IACxI,OAAO,CAAC,YAAY;CAerB"}
1
+ {"version":3,"file":"clipboard-manager.d.ts","sourceRoot":"","sources":["../../src/controllers/clipboard-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,UAAU,EACf,KAAK,QAAQ,EAEb,KAAK,cAAc,EAIpB,MAAM,aAAa,CAAC;AAGrB,0DAA0D;AAC1D,MAAM,WAAW,WAAW;IAC1B,qCAAqC;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,oGAAoG;IACpG,OAAO,CAAC,gBAAgB,CAA+B;IACvD,OAAO,CAAC,eAAe,CAAyB;IAChD,sFAAsF;IACtF,OAAO,CAAC,gBAAgB,CAAuB;IAE/C;;;;;;;OAOG;IACG,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAmC/D;IAED;;;;;;OAMG;IACG,GAAG,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CASlE;IAED;;;;;;;;;;OAUG;IACG,KAAK,CACT,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,CA+C/B;IAED;;;OAGG;IACH,OAAO,CAAC,cAAc;IAuCtB;;;OAGG;IACH,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC,GAAG,IAAI,CA0ClG;IAED;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAuBlC;;;;;;;;;;;;OAYG;IACH,QAAQ,CACN,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAgBtC;IAID;;;;;;;;;;OAUG;IACH,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CA+DrF;IAID,OAAO,CAAC,cAAc;IAgBtB;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAgC7B,sDAAsD;IACtD,OAAO,CAAC,oBAAoB;IAiB5B,2FAA2F;IAC3F,OAAO,CAAC,mBAAmB;IA0C3B,wEAAwE;IACxE,OAAO,CAAC,eAAe;IAoCvB,OAAO,CAAC,qBAAqB;IAqB7B,OAAO,CAAC,iBAAiB;IAQzB,qCAAqC;IACrC,OAAO,CAAC,WAAW;IAUnB,wIAAwI;IACxI,OAAO,CAAC,YAAY;CAerB"}
@@ -14,6 +14,12 @@ export declare class SelectionManager implements ReactiveController {
14
14
  anchor: CellCoord;
15
15
  /** The current end of the selection */
16
16
  head: CellCoord;
17
+ /**
18
+ * Active cell when it differs from `head` (e.g. after selecting whole
19
+ * rows/columns, where the active cell stays put while the range spans the
20
+ * full grid). `null` means the active cell is `head`.
21
+ */
22
+ private _active;
17
23
  /** Whether a drag selection is in progress */
18
24
  private _isDragging;
19
25
  /** Grid bounds */
@@ -26,7 +32,9 @@ export declare class SelectionManager implements ReactiveController {
26
32
  setBounds(maxRows: number, maxCols: number): void;
27
33
  /** Get the normalized selection range (top-left to bottom-right) */
28
34
  get range(): SelectionRange;
29
- /** Get the currently active cell (head of selection) */
35
+ /** The active-cell override, or `null` when the active cell follows the head. */
36
+ get activeOverride(): CellCoord | null;
37
+ /** Get the currently active cell (the head, unless rows/columns were selected) */
30
38
  get activeCell(): CellCoord;
31
39
  /** Check if a cell is within the current selection */
32
40
  isCellSelected(row: number, col: number): boolean;
@@ -66,10 +74,41 @@ export declare class SelectionManager implements ReactiveController {
66
74
  * @param extend - If true, keeps the anchor and extends the selection
67
75
  */
68
76
  moveTo(row: number, col: number, extend?: boolean): void;
77
+ /**
78
+ * Restore a full selection state (e.g. from an undo snapshot).
79
+ *
80
+ * @param anchor - Selection anchor
81
+ * @param head - Selection head
82
+ * @param active - Active-cell override; omit or pass `null` for the head
83
+ */
84
+ setSelection(anchor: CellCoord, head: CellCoord, active?: CellCoord | null): void;
69
85
  /** Select all cells */
70
86
  selectAll(): void;
87
+ /**
88
+ * Select every row of the columns between `fromCol` and `toCol` (inclusive).
89
+ * The head sits on `toCol`, so Shift+Left/Right keeps growing whole columns.
90
+ *
91
+ * @param fromCol - Column the selection is anchored at
92
+ * @param toCol - Column the selection extends to
93
+ * @param active - Cell to keep active; defaults to the current active row in `toCol`
94
+ */
95
+ selectColumns(fromCol: number, toCol: number, active?: CellCoord): void;
96
+ /**
97
+ * Select every column of the rows between `fromRow` and `toRow` (inclusive).
98
+ * The head sits on `toRow`, so Shift+Up/Down keeps growing whole rows.
99
+ *
100
+ * @param fromRow - Row the selection is anchored at
101
+ * @param toRow - Row the selection extends to
102
+ * @param active - Cell to keep active; defaults to the current active column in `toRow`
103
+ */
104
+ selectRows(fromRow: number, toRow: number, active?: CellCoord): void;
71
105
  /** Clear selection (collapse to active cell) */
72
106
  clearSelection(): void;
107
+ /**
108
+ * Keep the active-cell override only while extending and only while it is
109
+ * still inside the range; otherwise the head is the active cell again.
110
+ */
111
+ private _syncActive;
73
112
  /**
74
113
  * Clamp a coordinate to the valid grid bounds.
75
114
  *
@@ -78,4 +117,21 @@ export declare class SelectionManager implements ReactiveController {
78
117
  */
79
118
  clamp(coord: CellCoord): CellCoord;
80
119
  }
120
+ /**
121
+ * Find the target of a Ctrl/Cmd+Arrow jump, following spreadsheet semantics:
122
+ *
123
+ * - From a filled cell whose neighbour is also filled: move to the last
124
+ * filled cell of that contiguous run.
125
+ * - Otherwise: move to the next filled cell in that direction, or to the
126
+ * grid edge if there is none.
127
+ *
128
+ * @param from - Starting cell
129
+ * @param dRow - Row direction (-1, 0, or 1)
130
+ * @param dCol - Column direction (-1, 0, or 1)
131
+ * @param rows - Grid row count
132
+ * @param cols - Grid column count
133
+ * @param isFilled - Whether the cell at (row, col) has content
134
+ * @returns The cell to jump to (equal to `from` when already at the edge)
135
+ */
136
+ export declare function findDataEdge(from: CellCoord, dRow: number, dCol: number, rows: number, cols: number, isFilled: (row: number, col: number) => boolean): CellCoord;
81
137
  //# sourceMappingURL=selection-manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"selection-manager.d.ts","sourceRoot":"","sources":["../../src/controllers/selection-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,sBAAsB,EAAE,MAAM,KAAK,CAAC;AAC3E,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAElE;;;;;;;GAOG;AACH,qBAAa,gBAAiB,YAAW,kBAAkB;IACzD,IAAI,EAAE,sBAAsB,CAAC;IAE7B,iDAAiD;IACjD,MAAM,EAAE,SAAS,CAAsB;IAEvC,uCAAuC;IACvC,IAAI,EAAE,SAAS,CAAsB;IAErC,8CAA8C;IAC9C,OAAO,CAAC,WAAW,CAAS;IAE5B,kBAAkB;IAClB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAS;IAEzB,YAAY,IAAI,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAKzE;IAED,aAAa,IAAI,IAAI,CAEpB;IAED,gBAAgB,IAAI,IAAI,CAEvB;IAED,kEAAkE;IAClE,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAKhD;IAED,oEAAoE;IACpE,IAAI,KAAK,IAAI,cAAc,CAW1B;IAED,wDAAwD;IACxD,IAAI,UAAU,IAAI,SAAS,CAE1B;IAED,sDAAsD;IACtD,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAGhD;IAED,gDAAgD;IAChD,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAE9C;IAID;;;;;;OAMG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,IAAI,CAW7D;IAED;;;;;OAKG;IACH,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAI9C;IAED,uEAAuE;IACvE,YAAY,IAAI,IAAI,CAEnB;IAED,IAAI,UAAU,IAAI,OAAO,CAExB;IAID;;;;;;OAMG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,IAAI,CAWrD;IAED;;;;;;OAMG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,IAAI,CAOrD;IAED,uBAAuB;IACvB,SAAS,IAAI,IAAI,CAIhB;IAED,gDAAgD;IAChD,cAAc,IAAI,IAAI,CAGrB;IAID;;;;;OAKG;IACH,KAAK,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CAKjC;CACF"}
1
+ {"version":3,"file":"selection-manager.d.ts","sourceRoot":"","sources":["../../src/controllers/selection-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,sBAAsB,EAAE,MAAM,KAAK,CAAC;AAC3E,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAElE;;;;;;;GAOG;AACH,qBAAa,gBAAiB,YAAW,kBAAkB;IACzD,IAAI,EAAE,sBAAsB,CAAC;IAE7B,iDAAiD;IACjD,MAAM,EAAE,SAAS,CAAsB;IAEvC,uCAAuC;IACvC,IAAI,EAAE,SAAS,CAAsB;IAErC;;;;OAIG;IACH,OAAO,CAAC,OAAO,CAA0B;IAEzC,8CAA8C;IAC9C,OAAO,CAAC,WAAW,CAAS;IAE5B,kBAAkB;IAClB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAS;IAEzB,YAAY,IAAI,EAAE,sBAAsB,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAKzE;IAED,aAAa,IAAI,IAAI,CAEpB;IAED,gBAAgB,IAAI,IAAI,CAEvB;IAED,kEAAkE;IAClE,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAMhD;IAED,oEAAoE;IACpE,IAAI,KAAK,IAAI,cAAc,CAW1B;IAED,iFAAiF;IACjF,IAAI,cAAc,IAAI,SAAS,GAAG,IAAI,CAErC;IAED,kFAAkF;IAClF,IAAI,UAAU,IAAI,SAAS,CAE1B;IAED,sDAAsD;IACtD,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAGhD;IAED,gDAAgD;IAChD,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAG9C;IAID;;;;;;OAMG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,IAAI,CAY7D;IAED;;;;;OAKG;IACH,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAI9C;IAED,uEAAuE;IACvE,YAAY,IAAI,IAAI,CAEnB;IAED,IAAI,UAAU,IAAI,OAAO,CAExB;IAID;;;;;;OAMG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,IAAI,CAerD;IAED;;;;;;OAMG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,IAAI,CAQrD;IAED;;;;;;OAMG;IACH,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI,GAAG,IAAI,CAMhF;IAED,uBAAuB;IACvB,SAAS,IAAI,IAAI,CAKhB;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI,CAOtE;IAED;;;;;;;OAOG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI,CAOnE;IAED,gDAAgD;IAChD,cAAc,IAAI,IAAI,CAMrB;IAID;;;OAGG;IACH,OAAO,CAAC,WAAW;IAOnB;;;;;OAKG;IACH,KAAK,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CAKjC;CACF;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,GAC9C,SAAS,CAoBX"}
@@ -120,6 +120,12 @@ export declare class FormulaEngine {
120
120
  * Called after LPAREN has already been consumed.
121
121
  */
122
122
  private _parseIF;
123
+ /**
124
+ * Parse IFS(cond1, value1, cond2, value2, ...). Conditions are evaluated in
125
+ * order until one is true; only that condition's value is evaluated.
126
+ * No true condition → #N/A. Called after LPAREN has already been consumed.
127
+ */
128
+ private _parseIFS;
123
129
  /** Advance past one function argument without evaluating it. */
124
130
  private _skipArgument;
125
131
  private _compareValues;
@@ -1 +1 @@
1
- {"version":3,"file":"formula-engine.d.ts","sourceRoot":"","sources":["../../src/engine/formula-engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"formula-engine.d.ts","sourceRoot":"","sources":["../../src/engine/formula-engine.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -7,5 +7,8 @@ export { SelectionManager } from './controllers/selection-manager.js';
7
7
  export { ClipboardManager } from './controllers/clipboard-manager.js';
8
8
  export type { PasteUpdate } from './controllers/clipboard-manager.js';
9
9
  export type { CellCoord, CellData, CellFormat, GridData, SelectionRange, FormulaContext, FormulaFunction, CellChangeDetail, SelectionChangeDetail, DataChangeDetail, FormatChangeDetail, NumberFormatType, NumberFormatOptions, } from './types.js';
10
- export { cellKey, parseKey, colToLetter, letterToCol, refToCoord, coordToRef, formatsEqual, formatNumber } from './types.js';
10
+ export { cellKey, parseKey, colToLetter, letterToCol, refToCoord, coordToRef, formatsEqual, formatNumber, dateToSerial, dateSerialToDate } from './types.js';
11
+ export { parseDelimited, serializeDelimited, quoteDelimitedField } from './utils/delimited.js';
12
+ export { findDataEdge } from './controllers/selection-manager.js';
13
+ export type { CSVExportOptions, CSVImportOptions } from './y11n-spreadsheet.js';
11
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAChG,YAAY,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,YAAY,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACtE,YAAY,EACV,SAAS,EACT,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,cAAc,EACd,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAChG,YAAY,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,YAAY,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACtE,YAAY,EACV,SAAS,EACT,QAAQ,EACR,UAAU,EACV,QAAQ,EACR,cAAc,EACd,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC7J,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC/F,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAClE,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}