@zeyos/zx 2.3.0 → 3.0.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/CHANGELOG.md +87 -0
- package/DESIGN-SYSTEM.md +136 -0
- package/MIGRATION.md +155 -4
- package/README.md +24 -13
- package/dist/types/compat/map/data.d.ts +3 -2
- package/dist/types/components/account-menu/account-menu.d.ts +144 -0
- package/dist/types/components/app-rail/app-rail.d.ts +250 -0
- package/dist/types/components/app-sidebar/app-sidebar.d.ts +169 -0
- package/dist/types/components/avatar/avatar.d.ts +100 -0
- package/dist/types/components/chart/chart.d.ts +321 -0
- package/dist/types/components/date-picker/month-picker.d.ts +6 -0
- package/dist/types/components/dialog/dialog.d.ts +9 -0
- package/dist/types/components/dock/dock.d.ts +495 -0
- package/dist/types/components/dropdown/dropdown.d.ts +2 -2
- package/dist/types/components/field/field.d.ts +14 -0
- package/dist/types/components/field-upload/field-upload.d.ts +37 -4
- package/dist/types/components/form/form.d.ts +25 -3
- package/dist/types/components/grid/grid.d.ts +172 -0
- package/dist/types/components/launcher/launcher.d.ts +300 -0
- package/dist/types/components/layout/layout.d.ts +4 -4
- package/dist/types/components/menu-button/menu-button.d.ts +10 -2
- package/dist/types/components/modal/modal.d.ts +25 -0
- package/dist/types/components/multi-value-editor/multi-value-editor.d.ts +7 -1
- package/dist/types/components/questionnaire/items.d.ts +327 -0
- package/dist/types/components/questionnaire/questionnaire.d.ts +449 -0
- package/dist/types/components/sheet/sheet-stack.d.ts +167 -0
- package/dist/types/components/sheet/sheet.d.ts +294 -0
- package/dist/types/components/split-view/split-view.d.ts +2 -21
- package/dist/types/components/table/table.d.ts +219 -12
- package/dist/types/components/tooltip/tooltip.d.ts +2 -2
- package/dist/types/components/value-list/value-list.d.ts +24 -3
- package/dist/types/core/dom.d.ts +114 -0
- package/dist/types/core/drag-axis.d.ts +111 -0
- package/dist/types/core/position.d.ts +4 -2
- package/dist/types/index.d.ts +12 -2
- package/dist/zx-compat.esm.js +641 -277
- package/dist/zx-compat.esm.min.js +1 -1
- package/dist/zx-compat.global.js +7609 -2236
- package/dist/zx-compat.global.min.js +3 -3
- package/dist/zx-zeyos.esm.js +546 -87
- package/dist/zx-zeyos.esm.min.js +1 -1
- package/dist/zx.css +1452 -101
- package/dist/zx.esm.js +7952 -2592
- package/dist/zx.esm.min.js +3 -3
- package/dist/zx.global.js +7952 -2592
- package/dist/zx.global.min.js +3 -3
- package/dist/zx.min.css +1 -1
- package/docs/api.json +2276 -337
- package/docs/llms.md +426 -30
- package/docs/llms.txt +21 -9
- package/package.json +4 -2
- package/src/compat/globals.js +3 -1
- package/src/compat/map/data.js +31 -9
- package/src/components/account-menu/account-menu.css +70 -0
- package/src/components/account-menu/account-menu.js +208 -0
- package/src/components/app-rail/app-rail.css +107 -0
- package/src/components/app-rail/app-rail.js +668 -0
- package/src/components/app-sidebar/app-sidebar.css +68 -0
- package/src/components/app-sidebar/app-sidebar.js +388 -0
- package/src/components/avatar/avatar.css +61 -0
- package/src/components/avatar/avatar.js +222 -0
- package/src/components/button/button.css +0 -1
- package/src/components/chart/chart.css +61 -0
- package/src/components/chart/chart.js +518 -0
- package/src/components/date-picker/month-picker.js +9 -0
- package/src/components/dialog/dialog.js +11 -4
- package/src/components/dock/dock.css +228 -0
- package/src/components/dock/dock.js +977 -0
- package/src/components/dropdown/dropdown.js +1 -1
- package/src/components/field/field.js +2 -0
- package/src/components/field-upload/field-upload.js +9 -4
- package/src/components/form/form.js +6 -3
- package/src/components/grid/grid.css +6 -0
- package/src/components/grid/grid.js +213 -0
- package/src/components/launcher/launcher.css +100 -0
- package/src/components/launcher/launcher.js +557 -0
- package/src/components/layout/layout.js +2 -2
- package/src/components/menu-button/menu-button.js +27 -2
- package/src/components/modal/modal.css +5 -1
- package/src/components/modal/modal.js +37 -2
- package/src/components/multi-value-editor/multi-value-editor.js +2 -1
- package/src/components/questionnaire/items.js +370 -0
- package/src/components/questionnaire/questionnaire.css +387 -0
- package/src/components/questionnaire/questionnaire.js +1033 -0
- package/src/components/select/select.css +0 -1
- package/src/components/sheet/sheet-stack.js +304 -0
- package/src/components/sheet/sheet.css +351 -0
- package/src/components/sheet/sheet.js +551 -0
- package/src/components/split-view/split-view.js +76 -161
- package/src/components/table/table.css +43 -0
- package/src/components/table/table.js +523 -45
- package/src/components/tooltip/tooltip.js +5 -2
- package/src/components/value-list/value-list.js +6 -3
- package/src/core/dom.js +302 -0
- package/src/core/drag-axis.js +203 -0
- package/src/core/position.js +68 -22
- package/src/index.js +19 -2
- package/styles/tokens/dark.css +2 -3
- package/styles/tokens/global.css +5 -5
- package/styles/tokens/semantic.css +5 -3
- package/styles/tokens/themes.css +1 -1
- package/styles/zx.css +10 -1
- package/dist/types/components/permission/permission.d.ts +0 -96
- package/src/components/permission/permission.css +0 -47
- package/src/components/permission/permission.js +0 -201
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { Component } from '../../core/component.js';
|
|
2
|
+
export { resolveSize } from '../../core/drag-axis.js';
|
|
3
|
+
import { STEP, STEP_LARGE, dragAxis, resolveSize } from '../../core/drag-axis.js';
|
|
2
4
|
import { h, restoreTarget, snapshotTarget } from '../../core/dom.js';
|
|
3
5
|
import { storage } from '../../core/storage.js';
|
|
4
6
|
import { uid } from '../../core/util.js';
|
|
5
7
|
|
|
6
|
-
/** Pixels an arrow key moves the divider. */
|
|
7
|
-
const STEP = 16;
|
|
8
|
-
/** Pixels a shifted arrow key moves the divider. */
|
|
9
|
-
const STEP_LARGE = 64;
|
|
10
8
|
/** Storage namespace shared by every split view that opted into persistence. */
|
|
11
9
|
const STORAGE_NAMESPACE = 'split-view';
|
|
12
10
|
|
|
@@ -79,6 +77,8 @@ export class SplitView extends Component {
|
|
|
79
77
|
#observer = null;
|
|
80
78
|
/** @type {ReturnType<typeof storage>|null} */
|
|
81
79
|
#store = null;
|
|
80
|
+
/** @type {ReturnType<typeof dragAxis>|null} */
|
|
81
|
+
#drag = null;
|
|
82
82
|
|
|
83
83
|
/**
|
|
84
84
|
* Creates a split view, or turns an existing element into one.
|
|
@@ -102,11 +102,33 @@ export class SplitView extends Component {
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
const divider = this.refs.divider;
|
|
105
|
-
this
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
105
|
+
this.#drag = dragAxis(divider, {
|
|
106
|
+
orientation: this._orientation,
|
|
107
|
+
disabled: () => this._disabled,
|
|
108
|
+
onStart: () => {
|
|
109
|
+
this._startSize = this.getSize();
|
|
110
|
+
/** @type {HTMLElement} */ (this.el).dataset.dragging = 'true';
|
|
111
|
+
},
|
|
112
|
+
onMove: (delta) => this.#trackDelta(delta, false),
|
|
113
|
+
onEnd: (delta, moved) => {
|
|
114
|
+
// A drag that ends back where it started still has a final position to restore.
|
|
115
|
+
if (moved) this.#trackDelta(delta, true);
|
|
116
|
+
delete /** @type {HTMLElement} */ (this.el).dataset.dragging;
|
|
117
|
+
if (!moved) return;
|
|
118
|
+
this.#persist();
|
|
119
|
+
this.#emitResizeEnd();
|
|
120
|
+
},
|
|
121
|
+
onStep: (direction, large) => this.#stepBy(direction * (large ? STEP_LARGE : STEP)),
|
|
122
|
+
onJump: (edge) => this.#jumpTo(edge),
|
|
123
|
+
onActivate: () => {
|
|
124
|
+
if (!this.options.collapsible) return;
|
|
125
|
+
if (this._collapsed === null) {
|
|
126
|
+
this.collapse(/** @type {'start'|'end'} */ (this.options.collapsible));
|
|
127
|
+
} else {
|
|
128
|
+
this.expand();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
});
|
|
110
132
|
this.listen(divider, 'dblclick', () => this.#onDoubleClick());
|
|
111
133
|
|
|
112
134
|
if (typeof ResizeObserver === 'function') {
|
|
@@ -133,16 +155,8 @@ export class SplitView extends Component {
|
|
|
133
155
|
this._collapsed = null;
|
|
134
156
|
this._disabled = Boolean(options.disabled);
|
|
135
157
|
this._destroyed = false;
|
|
136
|
-
|
|
137
|
-
/** Handle of the frame a pending drag update is scheduled in; `0` if none. */
|
|
138
|
-
this._frame = 0;
|
|
139
|
-
/** @type {number|null} */
|
|
140
|
-
this._pointerId = null;
|
|
141
|
-
this._startClient = 0;
|
|
158
|
+
/** Start-pane size when the current drag began, in pixels. */
|
|
142
159
|
this._startSize = 0;
|
|
143
|
-
this._pointerClient = 0;
|
|
144
|
-
/** Whether the pointer left its starting position, which separates a drag from a click. */
|
|
145
|
-
this._moved = false;
|
|
146
160
|
/** Container size of the last observer pass; `-1` forces the next one to run. */
|
|
147
161
|
this._lastTotal = -1;
|
|
148
162
|
|
|
@@ -307,7 +321,8 @@ export class SplitView extends Component {
|
|
|
307
321
|
*/
|
|
308
322
|
disable() {
|
|
309
323
|
this._disabled = true;
|
|
310
|
-
this.#
|
|
324
|
+
this.#drag?.cancel();
|
|
325
|
+
delete /** @type {HTMLElement} */ (this.el).dataset.dragging;
|
|
311
326
|
this.refs.divider.setAttribute('aria-disabled', 'true');
|
|
312
327
|
this.refs.divider.setAttribute('tabindex', '-1');
|
|
313
328
|
return this;
|
|
@@ -328,11 +343,8 @@ export class SplitView extends Component {
|
|
|
328
343
|
destroy() {
|
|
329
344
|
if (this._destroyed) return;
|
|
330
345
|
this._destroyed = true;
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
this._frame = 0;
|
|
334
|
-
}
|
|
335
|
-
this.#releasePointer();
|
|
346
|
+
this.#drag?.destroy();
|
|
347
|
+
this.#drag = null;
|
|
336
348
|
this.#observer?.disconnect();
|
|
337
349
|
this.#observer = null;
|
|
338
350
|
super.destroy();
|
|
@@ -390,55 +402,20 @@ export class SplitView extends Component {
|
|
|
390
402
|
return this;
|
|
391
403
|
}
|
|
392
404
|
|
|
393
|
-
/** @param {PointerEvent} event @returns {void} */
|
|
394
|
-
#onPointerDown(event) {
|
|
395
|
-
if (this._disabled || this._dragging || event.button !== 0) return;
|
|
396
|
-
// No preventDefault(): cancelling pointerdown suppresses the compatibility mouse events the
|
|
397
|
-
// double-click reset is built on. `user-select: none` on the divider stops the text selection
|
|
398
|
-
// this would otherwise be guarding against.
|
|
399
|
-
this._dragging = true;
|
|
400
|
-
this._pointerId = event.pointerId;
|
|
401
|
-
this._startClient = axisClient(event, this._orientation);
|
|
402
|
-
this._pointerClient = this._startClient;
|
|
403
|
-
this._startSize = this.getSize();
|
|
404
|
-
this._moved = false;
|
|
405
|
-
/** @type {HTMLElement} */ (this.el).dataset.dragging = 'true';
|
|
406
|
-
try {
|
|
407
|
-
this.refs.divider.setPointerCapture(event.pointerId);
|
|
408
|
-
} catch {
|
|
409
|
-
// A pointer that ended between the event and this call cannot be captured; the drag simply
|
|
410
|
-
// finishes on the next pointerup.
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
/** @param {PointerEvent} event @returns {void} */
|
|
415
|
-
#onPointerMove(event) {
|
|
416
|
-
if (!this._dragging || event.pointerId !== this._pointerId) return;
|
|
417
|
-
this._pointerClient = axisClient(event, this._orientation);
|
|
418
|
-
if (this._pointerClient !== this._startClient) this._moved = true;
|
|
419
|
-
if (this._frame !== 0) return;
|
|
420
|
-
// One write and at most one `resize` per frame, however fast the pointer reports.
|
|
421
|
-
this._frame = requestAnimationFrame(() => {
|
|
422
|
-
this._frame = 0;
|
|
423
|
-
this.#trackPointer(false);
|
|
424
|
-
});
|
|
425
|
-
}
|
|
426
|
-
|
|
427
405
|
/**
|
|
428
|
-
*
|
|
406
|
+
* Applies a pointer delta as a new start-pane size.
|
|
407
|
+
* @param {number} delta Pixels travelled along the axis since the drag began.
|
|
429
408
|
* @param {boolean} settle Whether to apply the snap radius, which only makes sense at drag end.
|
|
430
409
|
* @returns {void}
|
|
431
410
|
*/
|
|
432
|
-
#
|
|
433
|
-
if (
|
|
411
|
+
#trackDelta(delta, settle) {
|
|
412
|
+
if (this._destroyed) return;
|
|
434
413
|
const { total, divider, min, max } = this.#metrics();
|
|
435
414
|
if (total <= 0) return;
|
|
436
415
|
// Dragging a folded pane brings it back rather than doing nothing; a plain click does not,
|
|
437
416
|
// because this runs only once the pointer has actually moved.
|
|
438
417
|
if (this._collapsed !== null) this.expand();
|
|
439
|
-
let next = clampSize({
|
|
440
|
-
size: this._startSize + (this._pointerClient - this._startClient), min, max, total, divider
|
|
441
|
-
});
|
|
418
|
+
let next = clampSize({ size: this._startSize + delta, min, max, total, divider });
|
|
442
419
|
if (settle) {
|
|
443
420
|
next = clampSize({
|
|
444
421
|
size: snapSize(next, this.#snapTargets(total, divider), Number(this.options.snap)),
|
|
@@ -451,91 +428,36 @@ export class SplitView extends Component {
|
|
|
451
428
|
}
|
|
452
429
|
|
|
453
430
|
/**
|
|
454
|
-
*
|
|
455
|
-
* @param {number}
|
|
456
|
-
* @returns {
|
|
431
|
+
* Moves the divider by a keyboard step and reports it as a completed resize.
|
|
432
|
+
* @param {number} amount Signed pixels.
|
|
433
|
+
* @returns {void}
|
|
457
434
|
*/
|
|
458
|
-
#
|
|
459
|
-
const { min, max } = this.#metrics();
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
if (Number.isFinite(initial)) targets.unshift(initial);
|
|
464
|
-
return targets;
|
|
435
|
+
#stepBy(amount) {
|
|
436
|
+
const { total, divider, min, max } = this.#metrics();
|
|
437
|
+
if (total <= 0) return;
|
|
438
|
+
if (this._collapsed !== null) this.expand();
|
|
439
|
+
this.#commit(clampSize({ size: this.getSize() + amount, min, max, total, divider }), total);
|
|
465
440
|
}
|
|
466
441
|
|
|
467
442
|
/**
|
|
468
|
-
*
|
|
469
|
-
*
|
|
470
|
-
* @param {PointerEvent|null} event Ending pointer event, or null when ending programmatically.
|
|
443
|
+
* Sends the divider to one end of its travel.
|
|
444
|
+
* @param {'min'|'max'} edge Bound to jump to.
|
|
471
445
|
* @returns {void}
|
|
472
|
-
* @fires SplitView#resizeend
|
|
473
446
|
*/
|
|
474
|
-
#
|
|
475
|
-
if (!this._dragging) return;
|
|
476
|
-
if (event && event.pointerId !== this._pointerId) return;
|
|
477
|
-
if (this._frame !== 0) {
|
|
478
|
-
cancelAnimationFrame(this._frame);
|
|
479
|
-
this._frame = 0;
|
|
480
|
-
}
|
|
481
|
-
if (event) this._pointerClient = axisClient(event, this._orientation);
|
|
482
|
-
const moved = this._moved;
|
|
483
|
-
// A drag that ends back where it started still has a final position to restore and report.
|
|
484
|
-
if (moved) this.#trackPointer(true);
|
|
485
|
-
this._dragging = false;
|
|
486
|
-
this._moved = false;
|
|
487
|
-
this.#releasePointer();
|
|
488
|
-
delete /** @type {HTMLElement} */ (this.el).dataset.dragging;
|
|
489
|
-
if (!moved) return;
|
|
490
|
-
this.#persist();
|
|
491
|
-
this.#emitResizeEnd();
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
/** @returns {void} */
|
|
495
|
-
#releasePointer() {
|
|
496
|
-
const pointerId = this._pointerId;
|
|
497
|
-
this._pointerId = null;
|
|
498
|
-
if (pointerId === null) return;
|
|
499
|
-
try {
|
|
500
|
-
this.refs.divider.releasePointerCapture(pointerId);
|
|
501
|
-
} catch {
|
|
502
|
-
// The capture is already gone once the pointer was cancelled or the node was detached.
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
/** @param {KeyboardEvent} event @returns {void} */
|
|
507
|
-
#onKeyDown(event) {
|
|
508
|
-
if (this._disabled) return;
|
|
509
|
-
const key = event.key;
|
|
510
|
-
|
|
511
|
-
if (key === 'Enter' || key === ' ') {
|
|
512
|
-
if (!this.options.collapsible) return;
|
|
513
|
-
event.preventDefault();
|
|
514
|
-
if (this._collapsed === null) {
|
|
515
|
-
this.collapse(/** @type {'start'|'end'} */ (this.options.collapsible));
|
|
516
|
-
} else {
|
|
517
|
-
this.expand();
|
|
518
|
-
}
|
|
519
|
-
return;
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
const horizontal = this._orientation === 'horizontal';
|
|
523
|
-
const shrink = horizontal ? 'ArrowLeft' : 'ArrowUp';
|
|
524
|
-
const grow = horizontal ? 'ArrowRight' : 'ArrowDown';
|
|
525
|
-
if (key !== shrink && key !== grow && key !== 'Home' && key !== 'End') return;
|
|
526
|
-
event.preventDefault();
|
|
527
|
-
// A key that moves the divider implies the pane should be visible again.
|
|
528
|
-
if (this._collapsed !== null) this.expand();
|
|
529
|
-
|
|
447
|
+
#jumpTo(edge) {
|
|
530
448
|
const { total, divider, min, max } = this.#metrics();
|
|
531
449
|
if (total <= 0) return;
|
|
450
|
+
if (this._collapsed !== null) this.expand();
|
|
532
451
|
const bounds = sizeBounds({ min, max, total, divider });
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
if (key === 'End') next = bounds.max;
|
|
536
|
-
else if (key !== 'Home') next = this.getSize() + (key === grow ? step : -step);
|
|
452
|
+
this.#commit(clampSize({ size: bounds[edge], min, max, total, divider }), total);
|
|
453
|
+
}
|
|
537
454
|
|
|
538
|
-
|
|
455
|
+
/**
|
|
456
|
+
* @param {number} size
|
|
457
|
+
* @param {number} total
|
|
458
|
+
* @returns {void}
|
|
459
|
+
*/
|
|
460
|
+
#commit(size, total) {
|
|
539
461
|
if (size === this._size) return;
|
|
540
462
|
this.#applySize(size);
|
|
541
463
|
this.emit('resize', { size, ratio: size / total });
|
|
@@ -543,6 +465,20 @@ export class SplitView extends Component {
|
|
|
543
465
|
this.#emitResizeEnd();
|
|
544
466
|
}
|
|
545
467
|
|
|
468
|
+
/**
|
|
469
|
+
* @param {number} total
|
|
470
|
+
* @param {number} divider
|
|
471
|
+
* @returns {number[]}
|
|
472
|
+
*/
|
|
473
|
+
#snapTargets(total, divider) {
|
|
474
|
+
const { min, max } = this.#metrics();
|
|
475
|
+
const bounds = sizeBounds({ min, max, total, divider });
|
|
476
|
+
const targets = [bounds.min, bounds.max];
|
|
477
|
+
const initial = resolveSize(this.options.size, total);
|
|
478
|
+
if (Number.isFinite(initial)) targets.unshift(initial);
|
|
479
|
+
return targets;
|
|
480
|
+
}
|
|
481
|
+
|
|
546
482
|
/**
|
|
547
483
|
* Resets the divider to the initial `size`. A percentage goes back to being a percentage rather
|
|
548
484
|
* than to the pixel value it happens to work out at, so the pane keeps tracking the container.
|
|
@@ -583,7 +519,7 @@ export class SplitView extends Component {
|
|
|
583
519
|
* @returns {void}
|
|
584
520
|
*/
|
|
585
521
|
#onContainerResize() {
|
|
586
|
-
if (this._destroyed || this
|
|
522
|
+
if (this._destroyed || this.#drag?.isDragging()) return;
|
|
587
523
|
const { total, divider, min, max } = this.#metrics();
|
|
588
524
|
if (total <= 0 || total === this._lastTotal) return;
|
|
589
525
|
this._lastTotal = total;
|
|
@@ -688,27 +624,6 @@ export function clampSize({ size, min = 0, max = null, total = 0, divider = 0 })
|
|
|
688
624
|
return Math.min(bounds.max, Math.max(bounds.min, requested));
|
|
689
625
|
}
|
|
690
626
|
|
|
691
|
-
/**
|
|
692
|
-
* Resolves a size option to pixels without touching the DOM.
|
|
693
|
-
*
|
|
694
|
-
* Numbers, bare numeric strings, and `px` lengths are pixels; a percentage resolves against
|
|
695
|
-
* `total`. Every other CSS length — `rem`, `vh`, `calc()` — needs the browser, so it returns `NaN`
|
|
696
|
-
* and the caller hands the value to CSS instead of guessing at it.
|
|
697
|
-
* @param {number|string} value Size option.
|
|
698
|
-
* @param {number} total Container size along the split axis, in pixels.
|
|
699
|
-
* @returns {number} Pixels, or `NaN` when only the browser can resolve the value.
|
|
700
|
-
*/
|
|
701
|
-
export function resolveSize(value, total) {
|
|
702
|
-
if (typeof value === 'number') return Number.isFinite(value) ? value : Number.NaN;
|
|
703
|
-
if (typeof value !== 'string') return Number.NaN;
|
|
704
|
-
const match = /^([+-]?(?:\d+\.?\d*|\.\d+))(px|%)?$/i.exec(value.trim());
|
|
705
|
-
if (!match) return Number.NaN;
|
|
706
|
-
const amount = Number(match[1]);
|
|
707
|
-
if (!Number.isFinite(amount)) return Number.NaN;
|
|
708
|
-
if ((match[2] ?? '').toLowerCase() !== '%') return amount;
|
|
709
|
-
const span = Number(total);
|
|
710
|
-
return Number.isFinite(span) ? (amount / 100) * span : Number.NaN;
|
|
711
|
-
}
|
|
712
627
|
|
|
713
628
|
/**
|
|
714
629
|
* Pulls a size onto the nearest target within a radius, leaving it alone when nothing is close.
|
|
@@ -177,6 +177,49 @@
|
|
|
177
177
|
text-align: center;
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
+
/* --- Hierarchical line items --------------------------------------------------------------- */
|
|
181
|
+
|
|
182
|
+
.zx-table__tree-cell {
|
|
183
|
+
display: flex;
|
|
184
|
+
min-inline-size: 0;
|
|
185
|
+
align-items: center;
|
|
186
|
+
gap: var(--zx-space-1);
|
|
187
|
+
padding-inline-start: calc(var(--zx-table-depth, 0) * var(--zx-space-4));
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.zx-table__tree-toggle,
|
|
191
|
+
.zx-table__tree-spacer {
|
|
192
|
+
inline-size: 24px;
|
|
193
|
+
block-size: 24px;
|
|
194
|
+
flex: 0 0 24px;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.zx-table__tree-toggle {
|
|
198
|
+
display: inline-grid;
|
|
199
|
+
min-block-size: 0;
|
|
200
|
+
place-items: center;
|
|
201
|
+
padding: 0;
|
|
202
|
+
border: 0;
|
|
203
|
+
border-radius: var(--zx-radius-sm);
|
|
204
|
+
background: transparent;
|
|
205
|
+
color: var(--zx-color-text-muted);
|
|
206
|
+
cursor: pointer;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.zx-table__tree-toggle:hover {
|
|
210
|
+
background: var(--zx-color-bg-hover);
|
|
211
|
+
color: var(--zx-color-text);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.zx-table__tree-toggle:focus-visible {
|
|
215
|
+
outline: 0;
|
|
216
|
+
box-shadow: var(--zx-focus-ring);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.zx-table__cell-content {
|
|
220
|
+
min-inline-size: 0;
|
|
221
|
+
}
|
|
222
|
+
|
|
180
223
|
/* --- Inline editing (Table editMode) -------------------------------------------------------- */
|
|
181
224
|
|
|
182
225
|
/* Reserve a control-sized content box in every body cell as soon as the table is editable, so
|