tosijs-ui 1.16.10 → 1.16.12

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/CHANGELOG.md CHANGED
@@ -1,5 +1,74 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.16.12
4
+
5
+ Two additions for task-focused screens: a table row can open to show a detail element, and a
6
+ schema form can show a hand-picked set of fields. Both are off until you ask for them.
7
+
8
+ - **`<tosi-table>` rows can expand to a detail element** (#220). Set
9
+ `rowDetail = (row) => element` and each row can open to show that element underneath it,
10
+ across the full width of the table. A column with `expander: true` renders the toggle;
11
+ `toggleRowDetail(row, open?)` does it from code, and `rowexpand` / `rowcollapse` report it.
12
+ The detail stays in view while the columns scroll sideways, is built once per expansion and
13
+ kept while the row is scrolled out of view, and the toggled row keeps its place on screen.
14
+ Expansion follows the row through sorting and filtering; with `rowId` it also survives a
15
+ reload of the data, and `expandedRowIds` can be read and set. `rowHasDetail` hides the
16
+ toggle on rows with nothing to show. Pinned rows are not expandable. A table placed in a
17
+ detail keeps its own selection, editing and column resizing.
18
+ - **The scrollbar of a table with `rowDetail` is approximate.** Rows are no longer all one
19
+ height, so the table places them by interpolation (tosijs's variable-height list). A table
20
+ that does not set `rowDetail` is unchanged.
21
+ - **`<tosi-schema-form>` takes a `fields` map for curated forms** (#221). It maps paths into
22
+ the schema to `{ caption, help, readOnly, editor }`, in display order, and the form shows
23
+ only those. Controls, choices, `required` and constraints still come from the schema.
24
+ `editor` is any function returning an element with a `value` and a `change` event, such as
25
+ an element creator from this library, or a field plugin object. The editor's `value` must be
26
+ of the schema's type, so a native `<input>` suits string properties only.
27
+ - **A curated form still owns the whole value.** Properties that are not shown keep their
28
+ values, the whole value is validated, and an error in a property that is not shown is
29
+ listed above the fields. A path the schema does not describe renders as a placeholder that
30
+ says so.
31
+ - **Fixed: an error on a plugin-rendered field was never shown** under that field. The form
32
+ now shows it there, a missing required value included, as it does for built-in controls.
33
+ - **Fixed: `readOnly` on a schema form did not reach a plugin control that is a custom
34
+ element, or a `<textarea>`.** Both are now locked with the rest of the form, through
35
+ `disabled` or, for a component that has only that, `readOnly`. Of these, the form
36
+ releases only what it locked: one a plugin disabled itself stays disabled.
37
+
38
+ `dist/iife.js` grows by about 2.5 kB gzip.
39
+
40
+ ## 1.16.11
41
+
42
+ In-page links work, teaching examples show their test result, and "Download ePub" stops
43
+ offering a book that was never built. `dist/iife.js` grows by 1.2 kB gzip.
44
+
45
+ - **Headings have ids.** Every heading rendered from markdown now carries an `id`, so
46
+ `[text](#that-heading)` and `/page/#that-heading` go somewhere. Before this they were
47
+ links that did nothing, with no error anywhere. The id is the GitHub slug of the heading
48
+ text, with `-1`, `-2` for a repeat on the same page. Arriving at a heading scrolls it to
49
+ the top of the page.
50
+ - **The build warns about an in-page link that matches nothing** on its page, naming the
51
+ page and the anchor. Under `strict: true` it fails the build.
52
+ - **An inset's `#anchor` is matched as the heading's id**, the one the page carries:
53
+ `install.md#whats-new` now matches "What's new", and `#usage-1` names the second "Usage".
54
+ The 1.16.9 spelling still matches (`#what-s-new`).
55
+ - **Inline views show the test result** (#219). An example opened with `{"view": "code"}` or
56
+ `{"view": "console"}` has one line under its preview: the count when its tests pass, the
57
+ first failure in red when they do not. It covers the `test` block and a `tjs` example's
58
+ inline tests, and clicking it opens the tab with the detail.
59
+ - **An example in an inline view always runs its tests**, whatever the page's tests switch says (it is off
60
+ by default away from localhost). A `tjs` example with inline tests therefore transpiles in
61
+ the page when it is in an inline view on a deployed site, where it used to run from the
62
+ copy the build transpiled. Examples without a `view` option are unchanged.
63
+ - **Inline views hide empty tabs.** `html`, `css` and `DOM tests` appear only when the
64
+ example has that block. The full-screen code view still shows them all.
65
+ - **A long section title keeps its arrow.** In the sidebar, a section title that wraps no
66
+ longer leaves the disclosure triangle alone on a line above it.
67
+ - **"Download ePub" follows the build** (#218). The settings menu links to the ePub at the
68
+ URL the build wrote, shows a submenu for a site with several volumes, and has no entry on
69
+ a site that builds none. It used to appear on every site and 404 on those. A hand-written
70
+ `<tosi-doc-system config>` without the new `ebooks` key keeps the old derived link.
71
+
3
72
  ## 1.16.10
4
73
 
5
74
  Print now opens with the book cover.
@@ -38,9 +38,17 @@ export interface ColumnOptions {
38
38
  * table has no business reaching into it.
39
39
  */
40
40
  editable?: boolean;
41
+ /**
42
+ * Render this column as the row's disclosure toggle for `rowDetail`. The cell holds one
43
+ * button; `prop` is unused (give it any unique string) and the header is left blank
44
+ * unless you set `name`.
45
+ */
46
+ expander?: boolean;
41
47
  headerCell?: (options: ColumnOptions) => HTMLElement;
42
48
  dataCell?: (options: ColumnOptions) => HTMLElement;
43
49
  }
50
+ /** Builds the element shown under an expanded row. `null` means the row has no detail. */
51
+ export type RowDetailFn = (row: any) => HTMLElement | null;
44
52
  export interface TableData {
45
53
  columns?: ColumnOptions[] | null;
46
54
  array: any[];
@@ -164,6 +172,46 @@ export declare class TosiTable extends TosiTable_base {
164
172
  ':host .row-edge-top': {
165
173
  boxShadow: string;
166
174
  };
175
+ ':host .scroll-area.has-row-detail': {
176
+ containerType: string;
177
+ };
178
+ ':host .tr.row-expanded': {
179
+ height: string;
180
+ };
181
+ ':host .tr-detail': {
182
+ gridColumn: string;
183
+ position: string;
184
+ left: string;
185
+ width: string;
186
+ boxSizing: string;
187
+ padding: string;
188
+ background: string;
189
+ boxShadow: string;
190
+ };
191
+ ':host .td.expander-cell': {
192
+ justifyContent: string;
193
+ padding: number;
194
+ };
195
+ ':host .row-expander': {
196
+ color: string;
197
+ background: string;
198
+ boxShadow: string;
199
+ padding: number;
200
+ display: string;
201
+ alignItems: string;
202
+ justifyContent: string;
203
+ width: string;
204
+ height: string;
205
+ };
206
+ ':host .row-expander[hidden]': {
207
+ display: string;
208
+ };
209
+ ':host .row-expander > *': {
210
+ transition: string;
211
+ };
212
+ ':host .row-expander[aria-expanded="true"] > *': {
213
+ transform: string;
214
+ };
167
215
  ':host .th .menu-trigger': {
168
216
  color: string;
169
217
  background: string;
@@ -195,6 +243,63 @@ export declare class TosiTable extends TosiTable_base {
195
243
  get schema(): JSONSchema | null;
196
244
  set schema(schema: JSONSchema | null);
197
245
  selectionChanged: SelectCallback;
246
+ private _rowDetail;
247
+ private _rowId;
248
+ /** Keys of the expanded rows: `rowId(row)` when there is a `rowId`, else the row itself. */
249
+ private _expanded;
250
+ /** One detail container per expanded row, kept so its state survives scrolling. */
251
+ private _detailEls;
252
+ /** The row each detail was built from: a detail is only as current as its row. */
253
+ private _detailRows;
254
+ private _detailCount;
255
+ /**
256
+ * Builds the element shown under an expanded row, from that row's data. Return `null`
257
+ * for a row with no detail. Called once per expansion: the element is kept while the row
258
+ * stays expanded (scrolling it out of view and back does not rebuild it) and dropped when
259
+ * the row collapses or the table's `array` is replaced.
260
+ */
261
+ get rowDetail(): RowDetailFn | null;
262
+ set rowDetail(fn: RowDetailFn | null);
263
+ /**
264
+ * Which rows have a detail, for the `expander` column: a row this returns `false` for
265
+ * gets no toggle. Unset, every row gets one.
266
+ */
267
+ rowHasDetail: ((row: any) => boolean) | null;
268
+ /**
269
+ * A stable id for a row. Without it expansion follows the row OBJECT, which is enough
270
+ * for sorting and filtering; with it expansion also survives replacing `array` with new
271
+ * objects, and `expandedRowIds` can be read and set.
272
+ */
273
+ get rowId(): ((row: any) => string) | null;
274
+ set rowId(fn: ((row: any) => string) | null);
275
+ private _pendingExpandedIds;
276
+ private _warnedPendingIds;
277
+ /**
278
+ * Ids of the expanded rows. Needs `rowId`; without one this reads empty. Assigning it
279
+ * fires no `rowexpand` / `rowcollapse`: those report a toggle, not a restore.
280
+ */
281
+ get expandedRowIds(): string[];
282
+ set expandedRowIds(ids: string[] | null);
283
+ private forgetDetails;
284
+ private detailKey;
285
+ isRowExpanded(row: any): boolean;
286
+ /**
287
+ * Expand or collapse a row's detail (`open` omitted toggles). Fires `rowexpand` or
288
+ * `rowcollapse` with `detail: { row, element }`. The toggled row keeps its place on
289
+ * screen.
290
+ */
291
+ toggleRowDetail(row: any, open?: boolean): void;
292
+ /** The detail container for a row, built on first use. `null` when the row has none. */
293
+ private detailFor;
294
+ private stampedRow;
295
+ /** A row's cells: its children, less the detail that an expanded row also holds. */
296
+ private rowCells;
297
+ private syncDetail;
298
+ private syncStampedDetails;
299
+ /** Have the virtual list re-measure its rows after one changed height. */
300
+ private remeasureRows;
301
+ /** Is this event target inside one of THIS table's row details? */
302
+ private inDetail;
198
303
  rowRendered: ((item: any, cells: HTMLElement[]) => void) | null;
199
304
  private selectedKey;
200
305
  private selectBinding;