ng-hub-ui-spreadsheet 22.5.0 → 22.7.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
@@ -179,6 +179,14 @@ A column says what it is called and how to get a cell out of a row:
179
179
 
180
180
  **Why two names.** Make the visible name the key and renaming a column means rewriting every reference to it — the mistake Excel made, and the reason a renamed column there breaks formulas across the workbook. Keep them apart and a rename is a rename.
181
181
 
182
+ A column can also **hint at an empty cell**: `placeholder` is shown while the pointer rests on a cell that holds nothing, never in place of a value. A **cell can carry one of its own**, for the row where the column's hint would not tell the truth:
183
+
184
+ ```typescript
185
+ cell: (row) => ({ value: row.due, editable: true, placeholder: row.id === 'c' ? 'after the cabling' : null });
186
+ ```
187
+
188
+ Left out or `null`, the column's placeholder is used.
189
+
182
190
  Read the sheet back as plain data keyed by alias:
183
191
 
184
192
  ```typescript
@@ -217,10 +225,8 @@ open — a product whose folded row opens its variants while its own row is only
217
225
  let-open="open"
218
226
  >
219
227
  @if (opensItsVariants(row)) {
220
- <a (click)="open()">{{ row.name }}</a>
221
- } @else {
222
- {{ row.name }}
223
- }
228
+ <a (click)="open()">{{ row.name }}</a>
229
+ } @else { {{ row.name }} }
224
230
  </ng-template>
225
231
  ```
226
232
 
@@ -248,23 +254,23 @@ For a cell that opens the row's own detail, put the detail in an `expansion` tem
248
254
 
249
255
  ## ⌨️ Keyboard
250
256
 
251
- | Key | What it does |
252
- | ----------------------------- | ---------------------------------------------------- |
253
- | Arrows | Move one cell |
254
- | Shift + arrows | Extend the selection |
255
- | `Tab` / `Shift+Tab` | Move sideways, falling onto the next row at the edge |
256
- | `Home` / `End` | First and last cell of the row |
257
- | `Ctrl+Home` / `Ctrl+End` | First and last cell of the sheet |
258
- | `Page Up` / `Page Down` | Move by `pageSize` rows |
259
- | Any printable character | Replace the cell and start editing |
260
- | `F2`, `Enter` | Edit, keeping the value |
261
- | `Alt` + `Down` | Open a cell that holds a list or a date |
262
- | `Enter` / `Tab` while editing | Commit and move down / right |
263
- | `Escape` | Revert the edit, then clear the selection |
264
- | `Delete` / `Backspace` | Empty every editable cell of the selection |
265
- | `Ctrl+C` / `X` / `V` | Copy, cut, paste |
266
- | `Ctrl+A` | Select the sheet |
267
- | `Ctrl+Space` / `Shift+Space` | Select the column / the row |
257
+ | Key | What it does |
258
+ | ----------------------------- | --------------------------------------------------------------------- |
259
+ | Arrows | Move one cell |
260
+ | Shift + arrows | Extend the selection |
261
+ | `Tab` / `Shift+Tab` | Move sideways, falling onto the next row at the edge |
262
+ | `Home` / `End` | First and last cell of the row |
263
+ | `Ctrl+Home` / `Ctrl+End` | First and last cell of the sheet |
264
+ | `Page Up` / `Page Down` | Move by `pageSize` rows |
265
+ | Any printable character | Replace the cell and start editing |
266
+ | `F2`, `Enter` | Edit, keeping the value |
267
+ | `Alt` + `Down` | Open a cell that holds a list or a date |
268
+ | `Enter` / `Tab` while editing | Commit and move down / right |
269
+ | `Escape` | Revert the edit, then clear the selection |
270
+ | `Delete` / `Backspace` | Empty one cell into its editor, or every editable cell of a selection |
271
+ | `Ctrl+C` / `X` / `V` | Copy, cut, paste |
272
+ | `Ctrl+A` | Select the sheet |
273
+ | `Ctrl+Space` / `Shift+Space` | Select the column / the row |
268
274
 
269
275
  ## 📋 The Clipboard
270
276
 
@@ -336,58 +342,58 @@ danglingColumnKeys(Object.keys(this.savedState), this.columns); // ['discount']
336
342
 
337
343
  ### Inputs
338
344
 
339
- | Input | Type | Default | Description |
340
- | -------------------- | ----------------------------------------- | ---------------- | --------------------------------------------------------------------------------- |
341
- | `rows` | `readonly TRow[]` | — | **Required.** The rows. Never written to. |
342
- | `columns` | `readonly HubSpreadsheetColumn<TRow>[]` | — | **Required.** What each column shows and allows. |
343
- | `rowKey` | `(row: TRow) => string` | — | **Required.** A stable name per row. |
344
- | `states` | `Record<string, HubSpreadsheetCellState>` | `{}` | Save state per cell, keyed `` `${rowKey}\t${columnKey}` ``. |
345
- | `errors` | `Record<string, string>` | `{}` | A validation message per cell, keyed the same way. Marks the cell, not the sheet. |
346
- | `decimalMark` | `',' \| '.'` | `','` | How this reader types decimals. |
347
- | `emptyText` | `string` | `''` | What an empty sheet says. |
348
- | `pageSize` | `number` | `10` | Rows travelled by `Page Up` and `Page Down`. |
349
- | `readonly` | `boolean` | `false` | Turns off every editor, whatever the cells say. |
350
- | `formulas` | `boolean` | `false` | Reads a cell that starts with `=` as a formula. See below. |
351
- | `editOn` | `'click' \| 'double-click'` | `'double-click'` | What opens the editor with the pointer. Typing opens it either way. |
352
- | `expansion` | `TemplateRef<HubSpreadsheetExpansionContext<TRow>> \| null` | `null` | A template drawn under a row that is open. See below. |
353
- | `expandedRow` | `string \| null` | `null` | Two-way. Which row is open, by its key. |
354
- | `direction` | `'auto' \| 'ltr' \| 'rtl'` | `'auto'` | Which way the sheet runs. `auto` follows the page; the other two force it. |
355
- | `frozenColumns` | `number` | `0` | How many columns stay pinned to the leading edge. |
356
- | `frozenRows` | `number` | `0` | How many rows stay pinned below the header. |
357
- | `virtual` | `boolean` | `false` | Draws only the rows in view. Gives the sheet a height; see below. |
358
- | `rowHeight` | `number` | `0` | How tall a row is while virtualising. Nought measures the first one drawn. |
359
- | `spans` | `readonly HubGridSpan[]` | `[]` | Merged blocks, declared by their anchor. |
360
- | `structure` | `HubSpreadsheetStructureOptions<TRow>` | `{}` | Which structural changes are offered. Everything refused by default. |
361
- | `retiredColumnKeys` | `readonly string[]` | `[]` | Aliases of deleted columns, so a new one never reuses them. |
362
- | `contextMenu` | `boolean` | `false` | Offers the structural changes on right-click. |
363
- | `mergeable` | `boolean` | `false` | Offers putting cells together, and taking them apart, in that menu. |
364
- | `disjointSelection` | `boolean` | `true` | Whether `Ctrl`-clicking adds a second block instead of starting a new selection. |
365
- | `fillHandle` | `boolean` | `false` | Draws the grip at the corner of the selection. |
366
- | `canUndo` | `boolean` | `false` | Whether `Ctrl+Z` has anything to ask for. The history belongs to the host. |
367
- | `canRedo` | `boolean` | `false` | The same for `Ctrl+Shift+Z` and `Ctrl+Y`. |
368
- | `resizableColumns` | `boolean` | `false` | Lets the reader drag a header's trailing edge. |
369
- | `reorderableColumns` | `boolean` | `false` | Lets the reader drag a header to move its column. |
370
- | `columnWidths` | `Record<string, number>` | `{}` | Two-way. Widths keyed by alias, so one survives its column being moved. |
371
- | `minColumnWidth` | `number` | `48` | The floor a drag cannot go below, in pixels. |
345
+ | Input | Type | Default | Description |
346
+ | -------------------- | ----------------------------------------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------- |
347
+ | `rows` | `readonly TRow[]` | — | **Required.** The rows. Never written to. |
348
+ | `columns` | `readonly HubSpreadsheetColumn<TRow>[]` | — | **Required.** What each column shows and allows. |
349
+ | `rowKey` | `(row: TRow) => string` | — | **Required.** A stable name per row. |
350
+ | `states` | `Record<string, HubSpreadsheetCellState>` | `{}` | Save state per cell, keyed `` `${rowKey}\t${columnKey}` ``. |
351
+ | `errors` | `Record<string, string>` | `{}` | A validation message per cell, keyed the same way. Rings the cell and opens in a tooltip on hover or focus. |
352
+ | `decimalMark` | `',' \| '.'` | `','` | How this reader types decimals. |
353
+ | `emptyText` | `string` | `''` | What an empty sheet says. |
354
+ | `pageSize` | `number` | `10` | Rows travelled by `Page Up` and `Page Down`. |
355
+ | `readonly` | `boolean` | `false` | Turns off every editor, whatever the cells say. |
356
+ | `formulas` | `boolean` | `false` | Reads a cell that starts with `=` as a formula. See below. |
357
+ | `editOn` | `'click' \| 'double-click'` | `'double-click'` | What opens the editor with the pointer. Typing opens it either way. |
358
+ | `expansion` | `TemplateRef<HubSpreadsheetExpansionContext<TRow>> \| null` | `null` | A template drawn under a row that is open. See below. |
359
+ | `expandedRow` | `string \| null` | `null` | Two-way. Which row is open, by its key. |
360
+ | `direction` | `'auto' \| 'ltr' \| 'rtl'` | `'auto'` | Which way the sheet runs. `auto` follows the page; the other two force it. |
361
+ | `frozenColumns` | `number` | `0` | How many columns stay pinned to the leading edge. |
362
+ | `frozenRows` | `number` | `0` | How many rows stay pinned below the header. |
363
+ | `virtual` | `boolean` | `false` | Draws only the rows in view. Gives the sheet a height; see below. |
364
+ | `rowHeight` | `number` | `0` | How tall a row is while virtualising. Nought measures the first one drawn. |
365
+ | `spans` | `readonly HubGridSpan[]` | `[]` | Merged blocks, declared by their anchor. |
366
+ | `structure` | `HubSpreadsheetStructureOptions<TRow>` | `{}` | Which structural changes are offered. Everything refused by default. |
367
+ | `retiredColumnKeys` | `readonly string[]` | `[]` | Aliases of deleted columns, so a new one never reuses them. |
368
+ | `contextMenu` | `boolean` | `false` | Offers the structural changes on right-click. |
369
+ | `mergeable` | `boolean` | `false` | Offers putting cells together, and taking them apart, in that menu. |
370
+ | `disjointSelection` | `boolean` | `true` | Whether `Ctrl`-clicking adds a second block instead of starting a new selection. |
371
+ | `fillHandle` | `boolean` | `false` | Draws the grip at the corner of the selection. |
372
+ | `canUndo` | `boolean` | `false` | Whether `Ctrl+Z` has anything to ask for. The history belongs to the host. |
373
+ | `canRedo` | `boolean` | `false` | The same for `Ctrl+Shift+Z` and `Ctrl+Y`. |
374
+ | `resizableColumns` | `boolean` | `false` | Lets the reader drag a header's trailing edge. |
375
+ | `reorderableColumns` | `boolean` | `false` | Lets the reader drag a header to move its column. |
376
+ | `columnWidths` | `Record<string, number>` | `{}` | Two-way. Widths keyed by alias, so one survives its column being moved. |
377
+ | `minColumnWidth` | `number` | `48` | The floor a drag cannot go below, in pixels. |
372
378
 
373
379
  ### Outputs
374
380
 
375
- | Output | Payload | Fires when |
376
- | ----------------------- | ------------------------------- | ---------------------------------------------------------------------------------------- |
377
- | `commit` | `HubSpreadsheetCommit<TRow>` | A cell took a new value, and it differs from the old one. |
378
- | `pasted` | `HubSpreadsheetPaste<TRow>` | A block was pasted. |
379
- | `filled` | `HubSpreadsheetPaste<TRow>` | The fill handle was dragged and released. |
380
- | `cleared` | `HubSpreadsheetCellRef<TRow>[]` | `Delete` was pressed over a selection. |
381
+ | Output | Payload | Fires when |
382
+ | ----------------------- | ------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
383
+ | `commit` | `HubSpreadsheetCommit<TRow>` | A cell took a new value, and it differs from the old one. |
384
+ | `pasted` | `HubSpreadsheetPaste<TRow>` | A block was pasted. |
385
+ | `filled` | `HubSpreadsheetPaste<TRow>` | The fill handle was dragged and released. |
386
+ | `cleared` | `HubSpreadsheetCellRef<TRow>[]` | `Delete` or `Backspace` was pressed over several cells. One cell opens its editor instead. |
381
387
  | `opened` | `HubSpreadsheetCellRef<TRow>` | A cell's template said the reader asked to open it — with the pointer, or with `Enter` where there is no field to edit. |
382
- | `selectionChange` | `HubGridRange \| null` | The selected rectangle changed. |
383
- | `selectionRangesChange` | `readonly HubGridRange[]` | Every rectangle of the selection, whenever it changes. One entry unless blocks were held with `Ctrl`. |
384
- | `insertRequested` | `HubSpreadsheetInsertRequest` | The reader asked to add rows or columns. |
385
- | `deleteRequested` | `HubSpreadsheetDeleteRequest` | The reader asked to remove rows or columns. |
386
- | `undoRequested` | `void` | `Ctrl+Z`. The sheet undoes nothing itself. |
387
- | `redoRequested` | `void` | `Ctrl+Shift+Z` or `Ctrl+Y`. |
388
- | `columnMoved` | `{ from, to, key, keys }` | A header was dropped. `keys` arrives already reordered. |
389
- | `mergeRequested` | `HubSpreadsheetMergeRequest` | The reader asked to put a selection together. Carries what it swallows. |
390
- | `unmergeRequested` | `readonly HubGridCoords[]` | The reader asked to take apart the blocks their selection touches. |
388
+ | `selectionChange` | `HubGridRange \| null` | The selected rectangle changed. |
389
+ | `selectionRangesChange` | `readonly HubGridRange[]` | Every rectangle of the selection, whenever it changes. One entry unless blocks were held with `Ctrl`. |
390
+ | `insertRequested` | `HubSpreadsheetInsertRequest` | The reader asked to add rows or columns. |
391
+ | `deleteRequested` | `HubSpreadsheetDeleteRequest` | The reader asked to remove rows or columns. |
392
+ | `undoRequested` | `void` | `Ctrl+Z`. The sheet undoes nothing itself. |
393
+ | `redoRequested` | `void` | `Ctrl+Shift+Z` or `Ctrl+Y`. |
394
+ | `columnMoved` | `{ from, to, key, keys }` | A header was dropped. `keys` arrives already reordered. |
395
+ | `mergeRequested` | `HubSpreadsheetMergeRequest` | The reader asked to put a selection together. Carries what it swallows. |
396
+ | `unmergeRequested` | `readonly HubGridCoords[]` | The reader asked to take apart the blocks their selection touches. |
391
397
 
392
398
  ### Helpers
393
399