flexdesk 0.17.15 → 0.17.16
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 +23 -0
- package/css/base.css +224 -4
- package/css/flexdesk.css +314 -12
- package/dist/charts.js +104 -34
- package/dist/charts.js.map +3 -3
- package/dist/{chunk-2PM6ZMNS.js → chunk-2Z2ENHR3.js} +2 -2
- package/dist/{chunk-AD7FIA3Z.js → chunk-7JI7HHSY.js} +2 -2
- package/dist/{chunk-TLIV6QSU.js → chunk-7OL6F2AM.js} +3 -3
- package/dist/{chunk-MADMGRX2.js → chunk-PGZ4EHSE.js} +156 -9
- package/dist/chunk-PGZ4EHSE.js.map +7 -0
- package/dist/{chunk-OEG6NPAN.js → chunk-XJNADRGR.js} +2 -2
- package/dist/flexdesk.css +314 -12
- package/dist/flow.js +3 -3
- package/dist/tiles.js +84 -9
- package/dist/tiles.js.map +2 -2
- package/dist/widgets.js +448 -5
- package/dist/widgets.js.map +4 -4
- package/dist/wm.js +102 -14
- package/dist/wm.js.map +2 -2
- package/docs/README.md +1 -1
- package/docs/components/charts.md +70 -3
- package/docs/components/forms-and-dialogs.md +61 -0
- package/docs/components/menus.md +85 -1
- package/docs/components/shell.md +37 -0
- package/docs/components/tiles.md +37 -0
- package/package.json +1 -1
- package/src/charts/plot_config_editor.js +125 -29
- package/src/tiles/tile_base.js +48 -2
- package/src/tiles/tile_grid.js +42 -1
- package/src/tiling/kind_taxonomy.js +45 -0
- package/src/tiling/wm.js +86 -11
- package/src/ui/components/category_picker.js +556 -0
- package/src/ui/components/computing_status_window.js +3 -0
- package/src/ui/components/confirm_dialog.js +3 -0
- package/src/ui/components/managed_window.js +204 -9
- package/src/ui/components/wizard.js +4 -1
- package/widgets.js +2 -1
- package/dist/chunk-MADMGRX2.js.map +0 -7
- /package/dist/{chunk-2PM6ZMNS.js.map → chunk-2Z2ENHR3.js.map} +0 -0
- /package/dist/{chunk-AD7FIA3Z.js.map → chunk-7JI7HHSY.js.map} +0 -0
- /package/dist/{chunk-TLIV6QSU.js.map → chunk-7OL6F2AM.js.map} +0 -0
- /package/dist/{chunk-OEG6NPAN.js.map → chunk-XJNADRGR.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.17.16 (2026-10-27)
|
|
4
|
+
|
|
5
|
+
A patch release. Two new widgets and options; the other entries change what
|
|
6
|
+
embedders see (listed under "Changed behaviour"). Each entry links to its
|
|
7
|
+
section of the docs.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- [A categorised picker: `CategoryPicker`](docs/components/menus.md#a-categorised-picker-categorypicker-01716): a popover anchored to a trigger, like ActionDropdown, with a search field over categories (colour dot, count), the active category's items (icon or short badge) and a detail pane (description, optional monospace preview, an Add button). Typing filters across categories; arrows, Enter, Tab (cycling field and Add), double-click and Esc work as documented; IME composition is respected; ARIA combobox/listbox with `aria-activedescendant`. Exported from `@flexdesk/widgets` (STORY-0126).
|
|
12
|
+
- [A kind that lives in a window: `windowOnly` and `window`](docs/components/shell.md#a-kind-that-lives-in-a-window-windowonly-and-window-01716): a taxonomy kind can declare `window: { width, height }` and `windowOnly: true`. A window-only kind opens in a managed window from every open path, its window never docks into a tile, and a restored layout drops its tile tabs with one warning; `taxonomy.isWindowOnly` and `windowSize` answer (STORY-0127).
|
|
13
|
+
- [Tile title double-click and configuring marks](docs/components/tiles.md#a-double-click-on-the-title-strip-configures-the-tile-01716): a double-click on a tile's title strip does what its cogwheel does (`configOnDoubleClick`, default on); `grid.setConfiguring(tileId, on)` / `grid.isConfiguring(tileId)` keep any number of tiles marked as being configured (`tile--configuring`), across `setLayout` (STORY-0128).
|
|
14
|
+
- `ManagedWindow` options `persistGeometry` (default true) and `focusOnOpen` (default true; `'window'` focuses the frame), `ManagedWindow.configure({ storageKey, maxSavedWindows })`, `DEFAULT_MAX_SAVED_WINDOWS` (50) and `win.isClosed` (BUG-0053).
|
|
15
|
+
- The plot config editor's `extraSeriesFields` may return an array of field specs `{ label, control | render, hint? }` that the editor lays out on its own label column, and receives `ctx.field(label, control, { hint })` (BUG-0052).
|
|
16
|
+
|
|
17
|
+
### Changed behaviour
|
|
18
|
+
|
|
19
|
+
- [Windows: closing, focus and Esc](docs/components/forms-and-dialogs.md#windows-closing-focus-and-esc-01716): a closed `ManagedWindow` leaves the registry and releases its content and callbacks (`get(id)` answers null; build a new window to reopen). Saved geometry keeps the 50 most recently used ids (window-manager-minted `twm-mw-*` entries are purged). A new window takes focus (its first field) and gives it back on close; the computing status window does not take focus, and the run-progress dialog focuses its frame, not Stop. Esc closes a modal on top wherever focus is, otherwise the window holding focus, otherwise the topmost modal, and never when the key was already handled (`defaultPrevented`) or composing (BUG-0053).
|
|
20
|
+
- [A plot config series is one block](docs/components/charts.md#a-plot-config-series-is-one-block-and-an-embedders-fields-share-it-01716): each series is a header line (variable, label, remove) and fields on the editor's label column (colour as ColorField, width, dash, stack group, extra fields, overlay). `.twm-plot-config__series-main` is gone; new classes `__series-head`, `__series-fields`, `__slot`, `__hint`, `__field--hinted`. The config objects read and written are unchanged (BUG-0052).
|
|
21
|
+
|
|
22
|
+
### Removed or renamed exports
|
|
23
|
+
|
|
24
|
+
None. New exports: `CategoryPicker`, `DEFAULT_MAX_SAVED_WINDOWS`. flexdesk.css gains the category picker's classes, `.tile--configuring` and the plot config classes above, and drops `.twm-plot-config__series-main`; it defines no new custom property besides the picker's `--twm-category-picker-color`.
|
|
25
|
+
|
|
3
26
|
## 0.17.15 (2026-10-26)
|
|
4
27
|
|
|
5
28
|
A patch release with no API change. Its entries change what embedders see: a top-level tile loses its one-segment breadcrumb strip, every `openForm` row lays its inputs out anew, and a slide-out panel no longer crosses what lies right of its host. Each entry links to its section of the docs.
|
package/css/base.css
CHANGED
|
@@ -3344,20 +3344,25 @@ body.twm-window-maximized .twm-resize-handle {
|
|
|
3344
3344
|
}
|
|
3345
3345
|
|
|
3346
3346
|
/* Selected — set by `_onConfigClick()` while the config dialog is open, and
|
|
3347
|
-
cleared from every sibling by the same handler.
|
|
3347
|
+
cleared from every sibling by the same handler. `--configuring` is the same
|
|
3348
|
+
look set by the embedder through `setConfiguring()` (0.17.16), one per open
|
|
3349
|
+
config window, and no handler clears it. It reads `--accent-lighter`
|
|
3348
3350
|
(BUG-0045): `--accent-bright` is a border colour on this background and not
|
|
3349
3351
|
a text one. It was #78b9ff, which no mix of `--accent-bright` with white
|
|
3350
3352
|
gives exactly; `--accent-lighter` (about #73b6e3) is the nearest. */
|
|
3351
|
-
.tile.tile--selected
|
|
3353
|
+
.tile.tile--selected,
|
|
3354
|
+
.tile.tile--configuring {
|
|
3352
3355
|
border-color: var(--accent-lighter);
|
|
3353
3356
|
box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-lighter) 30%, transparent), var(--shadow-md);
|
|
3354
3357
|
}
|
|
3355
3358
|
|
|
3356
|
-
.tile.tile--selected .tile-header
|
|
3359
|
+
.tile.tile--selected .tile-header,
|
|
3360
|
+
.tile.tile--configuring .tile-header {
|
|
3357
3361
|
background: color-mix(in srgb, var(--accent-lighter) 10%, transparent);
|
|
3358
3362
|
}
|
|
3359
3363
|
|
|
3360
|
-
.tile.tile--selected .tile-title
|
|
3364
|
+
.tile.tile--selected .tile-title,
|
|
3365
|
+
.tile.tile--configuring .tile-title {
|
|
3361
3366
|
color: var(--accent-lighter);
|
|
3362
3367
|
}
|
|
3363
3368
|
|
|
@@ -3775,6 +3780,215 @@ body.twm-window-maximized .twm-resize-handle {
|
|
|
3775
3780
|
text-overflow: ellipsis;
|
|
3776
3781
|
}
|
|
3777
3782
|
|
|
3783
|
+
/* ══ CATEGORY PICKER (STORY-0126) ══════════════════════════════════════
|
|
3784
|
+
`CategoryPicker` (category_picker.js): a search field over three columns —
|
|
3785
|
+
categories, the active category's items, the highlighted item's detail.
|
|
3786
|
+
Placed by `ActionDropdown.position` (inline top/left/max-height), so it is
|
|
3787
|
+
`position: fixed` on --z-over-windows: over the managed window it opened
|
|
3788
|
+
from. It shrinks to the inline max-height and its columns scroll inside.
|
|
3789
|
+
A category's colour arrives as `--twm-category-picker-color` on its rows. */
|
|
3790
|
+
.twm-category-picker {
|
|
3791
|
+
position: fixed;
|
|
3792
|
+
z-index: var(--z-over-windows);
|
|
3793
|
+
display: flex;
|
|
3794
|
+
flex-direction: column;
|
|
3795
|
+
box-sizing: border-box;
|
|
3796
|
+
width: 640px;
|
|
3797
|
+
max-width: calc(100vw - 2 * var(--space-md));
|
|
3798
|
+
height: 440px;
|
|
3799
|
+
background: var(--surface-1);
|
|
3800
|
+
border: 1px solid var(--border-strong);
|
|
3801
|
+
border-radius: var(--radius-lg);
|
|
3802
|
+
box-shadow: var(--shadow-lg);
|
|
3803
|
+
color: var(--text-primary);
|
|
3804
|
+
font-family: inherit;
|
|
3805
|
+
font-size: var(--font-size-md);
|
|
3806
|
+
overflow: hidden;
|
|
3807
|
+
}
|
|
3808
|
+
.twm-category-picker[hidden] {
|
|
3809
|
+
display: none;
|
|
3810
|
+
}
|
|
3811
|
+
.twm-category-picker__search {
|
|
3812
|
+
flex: none;
|
|
3813
|
+
padding: var(--space-md);
|
|
3814
|
+
border-bottom: 1px solid var(--border-default);
|
|
3815
|
+
}
|
|
3816
|
+
.twm-category-picker__input {
|
|
3817
|
+
width: 100%;
|
|
3818
|
+
box-sizing: border-box;
|
|
3819
|
+
padding: var(--space-sm) var(--space-md);
|
|
3820
|
+
background: var(--surface-0);
|
|
3821
|
+
border: 1px solid var(--border-strong);
|
|
3822
|
+
border-radius: var(--radius-sm);
|
|
3823
|
+
color: var(--text-primary);
|
|
3824
|
+
font-family: inherit;
|
|
3825
|
+
font-size: var(--font-size-md);
|
|
3826
|
+
}
|
|
3827
|
+
.twm-category-picker__input:focus {
|
|
3828
|
+
outline: none;
|
|
3829
|
+
border-color: var(--accent-bright);
|
|
3830
|
+
}
|
|
3831
|
+
.twm-category-picker__body {
|
|
3832
|
+
flex: 1 1 auto;
|
|
3833
|
+
min-height: 0;
|
|
3834
|
+
display: flex;
|
|
3835
|
+
}
|
|
3836
|
+
.twm-category-picker__column {
|
|
3837
|
+
flex: none;
|
|
3838
|
+
box-sizing: border-box;
|
|
3839
|
+
padding: var(--space-sm) 0;
|
|
3840
|
+
border-right: 1px solid var(--border-default);
|
|
3841
|
+
overflow-y: auto;
|
|
3842
|
+
}
|
|
3843
|
+
.twm-category-picker__categories {
|
|
3844
|
+
width: 170px;
|
|
3845
|
+
}
|
|
3846
|
+
.twm-category-picker__items {
|
|
3847
|
+
width: 220px;
|
|
3848
|
+
}
|
|
3849
|
+
.twm-category-picker__category,
|
|
3850
|
+
.twm-category-picker__item {
|
|
3851
|
+
display: flex;
|
|
3852
|
+
align-items: center;
|
|
3853
|
+
gap: var(--space-md);
|
|
3854
|
+
width: 100%;
|
|
3855
|
+
box-sizing: border-box;
|
|
3856
|
+
padding: var(--space-sm) var(--space-lg);
|
|
3857
|
+
background: transparent;
|
|
3858
|
+
border: none;
|
|
3859
|
+
color: var(--text-primary);
|
|
3860
|
+
font-family: inherit;
|
|
3861
|
+
font-size: var(--font-size-md);
|
|
3862
|
+
text-align: left;
|
|
3863
|
+
cursor: pointer;
|
|
3864
|
+
}
|
|
3865
|
+
.twm-category-picker__category:hover,
|
|
3866
|
+
.twm-category-picker__item:hover {
|
|
3867
|
+
background: var(--state-hover);
|
|
3868
|
+
}
|
|
3869
|
+
.twm-category-picker__category--active,
|
|
3870
|
+
.twm-category-picker__item--highlighted,
|
|
3871
|
+
.twm-category-picker__category--active:hover,
|
|
3872
|
+
.twm-category-picker__item--highlighted:hover {
|
|
3873
|
+
background: var(--state-selected);
|
|
3874
|
+
}
|
|
3875
|
+
/* The column the arrow keys move in marks its row with an accent edge. */
|
|
3876
|
+
.twm-category-picker__column--current .twm-category-picker__category--active,
|
|
3877
|
+
.twm-category-picker__column--current .twm-category-picker__item--highlighted {
|
|
3878
|
+
box-shadow: inset 2px 0 0 var(--accent-bright);
|
|
3879
|
+
}
|
|
3880
|
+
.twm-category-picker__category--empty {
|
|
3881
|
+
color: var(--text-dim);
|
|
3882
|
+
}
|
|
3883
|
+
.twm-category-picker__dot {
|
|
3884
|
+
flex: none;
|
|
3885
|
+
width: 8px;
|
|
3886
|
+
height: 8px;
|
|
3887
|
+
border-radius: var(--radius-circle);
|
|
3888
|
+
/* background-color, not the shorthand: the colour is the caller's, and a
|
|
3889
|
+
url() in the shorthand would be fetched */
|
|
3890
|
+
background-color: var(--twm-category-picker-color, var(--text-muted));
|
|
3891
|
+
}
|
|
3892
|
+
.twm-category-picker__category-label,
|
|
3893
|
+
.twm-category-picker__item-label {
|
|
3894
|
+
flex: 1 1 auto;
|
|
3895
|
+
min-width: 0;
|
|
3896
|
+
overflow: hidden;
|
|
3897
|
+
white-space: nowrap;
|
|
3898
|
+
text-overflow: ellipsis;
|
|
3899
|
+
}
|
|
3900
|
+
.twm-category-picker__count {
|
|
3901
|
+
flex: none;
|
|
3902
|
+
color: var(--text-muted);
|
|
3903
|
+
font-size: var(--font-size-xs);
|
|
3904
|
+
font-variant-numeric: tabular-nums;
|
|
3905
|
+
}
|
|
3906
|
+
.twm-category-picker__badge,
|
|
3907
|
+
.twm-category-picker__item .twm-category-picker__icon {
|
|
3908
|
+
flex: none;
|
|
3909
|
+
display: flex;
|
|
3910
|
+
align-items: center;
|
|
3911
|
+
justify-content: center;
|
|
3912
|
+
width: 22px;
|
|
3913
|
+
height: 22px;
|
|
3914
|
+
box-sizing: border-box;
|
|
3915
|
+
color: var(--twm-category-picker-color, var(--text-muted));
|
|
3916
|
+
}
|
|
3917
|
+
.twm-category-picker__badge {
|
|
3918
|
+
border: 1px solid var(--twm-category-picker-color, var(--text-muted));
|
|
3919
|
+
border-radius: var(--radius-sm);
|
|
3920
|
+
font-family: var(--font-family-mono);
|
|
3921
|
+
font-size: var(--font-size-xs);
|
|
3922
|
+
font-weight: var(--font-weight-semibold);
|
|
3923
|
+
overflow: hidden;
|
|
3924
|
+
white-space: nowrap;
|
|
3925
|
+
}
|
|
3926
|
+
.twm-category-picker__item .twm-category-picker__icon {
|
|
3927
|
+
font-size: 18px;
|
|
3928
|
+
}
|
|
3929
|
+
/* One category's hits while a query is set: role="group", named by its header. */
|
|
3930
|
+
.twm-category-picker__hits {
|
|
3931
|
+
display: flex;
|
|
3932
|
+
flex-direction: column;
|
|
3933
|
+
}
|
|
3934
|
+
.twm-category-picker__group {
|
|
3935
|
+
display: flex;
|
|
3936
|
+
align-items: center;
|
|
3937
|
+
gap: var(--space-sm);
|
|
3938
|
+
padding: var(--space-md) var(--space-lg) var(--space-xs);
|
|
3939
|
+
color: var(--text-muted);
|
|
3940
|
+
font-size: var(--font-size-xs);
|
|
3941
|
+
text-transform: uppercase;
|
|
3942
|
+
letter-spacing: 0.06em;
|
|
3943
|
+
}
|
|
3944
|
+
.twm-category-picker__empty,
|
|
3945
|
+
.twm-category-picker__detail-empty {
|
|
3946
|
+
padding: var(--space-md) var(--space-lg);
|
|
3947
|
+
color: var(--text-muted);
|
|
3948
|
+
}
|
|
3949
|
+
.twm-category-picker__detail {
|
|
3950
|
+
flex: 1 1 auto;
|
|
3951
|
+
min-width: 0;
|
|
3952
|
+
display: flex;
|
|
3953
|
+
flex-direction: column;
|
|
3954
|
+
gap: var(--space-md);
|
|
3955
|
+
padding: var(--space-xl);
|
|
3956
|
+
overflow-y: auto;
|
|
3957
|
+
}
|
|
3958
|
+
.twm-category-picker__title {
|
|
3959
|
+
color: var(--text-bright);
|
|
3960
|
+
font-size: var(--font-size-xl);
|
|
3961
|
+
font-weight: var(--font-weight-semibold);
|
|
3962
|
+
}
|
|
3963
|
+
.twm-category-picker__description {
|
|
3964
|
+
color: var(--text-secondary);
|
|
3965
|
+
line-height: var(--line-height-normal);
|
|
3966
|
+
}
|
|
3967
|
+
.twm-category-picker__preview-label {
|
|
3968
|
+
margin-top: var(--space-sm);
|
|
3969
|
+
color: var(--text-muted);
|
|
3970
|
+
font-size: var(--font-size-xs);
|
|
3971
|
+
text-transform: uppercase;
|
|
3972
|
+
letter-spacing: 0.06em;
|
|
3973
|
+
}
|
|
3974
|
+
.twm-category-picker__preview {
|
|
3975
|
+
margin: 0;
|
|
3976
|
+
padding: var(--space-md);
|
|
3977
|
+
background: var(--surface-0);
|
|
3978
|
+
border: 1px solid var(--border-default);
|
|
3979
|
+
border-radius: var(--radius-sm);
|
|
3980
|
+
color: var(--text-body);
|
|
3981
|
+
font-family: var(--font-family-mono);
|
|
3982
|
+
font-size: var(--font-size-sm);
|
|
3983
|
+
white-space: pre-wrap;
|
|
3984
|
+
overflow-wrap: anywhere;
|
|
3985
|
+
}
|
|
3986
|
+
.twm-category-picker__add {
|
|
3987
|
+
margin-top: auto;
|
|
3988
|
+
align-self: flex-end;
|
|
3989
|
+
}
|
|
3990
|
+
/* ══ end CATEGORY PICKER ══ */
|
|
3991
|
+
|
|
3778
3992
|
/* ── from code.css ───────────────────────── */
|
|
3779
3993
|
/* Code language tabs */
|
|
3780
3994
|
.twm-code-tabs-header {
|
|
@@ -3934,6 +4148,12 @@ body.twm-window-maximized .twm-resize-handle {
|
|
|
3934
4148
|
.twm-managed-window:focus-within {
|
|
3935
4149
|
border-color: #505050;
|
|
3936
4150
|
}
|
|
4151
|
+
/* BUG-0053. The frame is focusable (tabindex -1) so a press on it keeps focus
|
|
4152
|
+
in the window; the focus-within border above already shows that, so the
|
|
4153
|
+
frame draws no outline of its own. */
|
|
4154
|
+
.twm-managed-window:focus {
|
|
4155
|
+
outline: none;
|
|
4156
|
+
}
|
|
3937
4157
|
/* Minimize animation class — targets taskbar item via CSS custom properties */
|
|
3938
4158
|
.twm-managed-window--minimizing {
|
|
3939
4159
|
transform: translate(var(--mw-target-x, 0px), var(--mw-target-y, 100vh)) scale(var(--mw-target-scale, 0.1));
|
package/css/flexdesk.css
CHANGED
|
@@ -3869,20 +3869,25 @@ body.twm-window-maximized .twm-resize-handle {
|
|
|
3869
3869
|
}
|
|
3870
3870
|
|
|
3871
3871
|
/* Selected — set by `_onConfigClick()` while the config dialog is open, and
|
|
3872
|
-
cleared from every sibling by the same handler.
|
|
3872
|
+
cleared from every sibling by the same handler. `--configuring` is the same
|
|
3873
|
+
look set by the embedder through `setConfiguring()` (0.17.16), one per open
|
|
3874
|
+
config window, and no handler clears it. It reads `--accent-lighter`
|
|
3873
3875
|
(BUG-0045): `--accent-bright` is a border colour on this background and not
|
|
3874
3876
|
a text one. It was #78b9ff, which no mix of `--accent-bright` with white
|
|
3875
3877
|
gives exactly; `--accent-lighter` (about #73b6e3) is the nearest. */
|
|
3876
|
-
.tile.tile--selected
|
|
3878
|
+
.tile.tile--selected,
|
|
3879
|
+
.tile.tile--configuring {
|
|
3877
3880
|
border-color: var(--accent-lighter);
|
|
3878
3881
|
box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-lighter) 30%, transparent), var(--shadow-md);
|
|
3879
3882
|
}
|
|
3880
3883
|
|
|
3881
|
-
.tile.tile--selected .tile-header
|
|
3884
|
+
.tile.tile--selected .tile-header,
|
|
3885
|
+
.tile.tile--configuring .tile-header {
|
|
3882
3886
|
background: color-mix(in srgb, var(--accent-lighter) 10%, transparent);
|
|
3883
3887
|
}
|
|
3884
3888
|
|
|
3885
|
-
.tile.tile--selected .tile-title
|
|
3889
|
+
.tile.tile--selected .tile-title,
|
|
3890
|
+
.tile.tile--configuring .tile-title {
|
|
3886
3891
|
color: var(--accent-lighter);
|
|
3887
3892
|
}
|
|
3888
3893
|
|
|
@@ -4609,6 +4614,215 @@ body.twm-window-maximized .twm-resize-handle {
|
|
|
4609
4614
|
text-overflow: ellipsis;
|
|
4610
4615
|
}
|
|
4611
4616
|
|
|
4617
|
+
/* ══ CATEGORY PICKER (STORY-0126) ══════════════════════════════════════
|
|
4618
|
+
`CategoryPicker` (category_picker.js): a search field over three columns —
|
|
4619
|
+
categories, the active category's items, the highlighted item's detail.
|
|
4620
|
+
Placed by `ActionDropdown.position` (inline top/left/max-height), so it is
|
|
4621
|
+
`position: fixed` on --z-over-windows: over the managed window it opened
|
|
4622
|
+
from. It shrinks to the inline max-height and its columns scroll inside.
|
|
4623
|
+
A category's colour arrives as `--twm-category-picker-color` on its rows. */
|
|
4624
|
+
.twm-category-picker {
|
|
4625
|
+
position: fixed;
|
|
4626
|
+
z-index: var(--z-over-windows);
|
|
4627
|
+
display: flex;
|
|
4628
|
+
flex-direction: column;
|
|
4629
|
+
box-sizing: border-box;
|
|
4630
|
+
width: 640px;
|
|
4631
|
+
max-width: calc(100vw - 2 * var(--space-md));
|
|
4632
|
+
height: 440px;
|
|
4633
|
+
background: var(--surface-1);
|
|
4634
|
+
border: 1px solid var(--border-strong);
|
|
4635
|
+
border-radius: var(--radius-lg);
|
|
4636
|
+
box-shadow: var(--shadow-lg);
|
|
4637
|
+
color: var(--text-primary);
|
|
4638
|
+
font-family: inherit;
|
|
4639
|
+
font-size: var(--font-size-md);
|
|
4640
|
+
overflow: hidden;
|
|
4641
|
+
}
|
|
4642
|
+
.twm-category-picker[hidden] {
|
|
4643
|
+
display: none;
|
|
4644
|
+
}
|
|
4645
|
+
.twm-category-picker__search {
|
|
4646
|
+
flex: none;
|
|
4647
|
+
padding: var(--space-md);
|
|
4648
|
+
border-bottom: 1px solid var(--border-default);
|
|
4649
|
+
}
|
|
4650
|
+
.twm-category-picker__input {
|
|
4651
|
+
width: 100%;
|
|
4652
|
+
box-sizing: border-box;
|
|
4653
|
+
padding: var(--space-sm) var(--space-md);
|
|
4654
|
+
background: var(--surface-0);
|
|
4655
|
+
border: 1px solid var(--border-strong);
|
|
4656
|
+
border-radius: var(--radius-sm);
|
|
4657
|
+
color: var(--text-primary);
|
|
4658
|
+
font-family: inherit;
|
|
4659
|
+
font-size: var(--font-size-md);
|
|
4660
|
+
}
|
|
4661
|
+
.twm-category-picker__input:focus {
|
|
4662
|
+
outline: none;
|
|
4663
|
+
border-color: var(--accent-bright);
|
|
4664
|
+
}
|
|
4665
|
+
.twm-category-picker__body {
|
|
4666
|
+
flex: 1 1 auto;
|
|
4667
|
+
min-height: 0;
|
|
4668
|
+
display: flex;
|
|
4669
|
+
}
|
|
4670
|
+
.twm-category-picker__column {
|
|
4671
|
+
flex: none;
|
|
4672
|
+
box-sizing: border-box;
|
|
4673
|
+
padding: var(--space-sm) 0;
|
|
4674
|
+
border-right: 1px solid var(--border-default);
|
|
4675
|
+
overflow-y: auto;
|
|
4676
|
+
}
|
|
4677
|
+
.twm-category-picker__categories {
|
|
4678
|
+
width: 170px;
|
|
4679
|
+
}
|
|
4680
|
+
.twm-category-picker__items {
|
|
4681
|
+
width: 220px;
|
|
4682
|
+
}
|
|
4683
|
+
.twm-category-picker__category,
|
|
4684
|
+
.twm-category-picker__item {
|
|
4685
|
+
display: flex;
|
|
4686
|
+
align-items: center;
|
|
4687
|
+
gap: var(--space-md);
|
|
4688
|
+
width: 100%;
|
|
4689
|
+
box-sizing: border-box;
|
|
4690
|
+
padding: var(--space-sm) var(--space-lg);
|
|
4691
|
+
background: transparent;
|
|
4692
|
+
border: none;
|
|
4693
|
+
color: var(--text-primary);
|
|
4694
|
+
font-family: inherit;
|
|
4695
|
+
font-size: var(--font-size-md);
|
|
4696
|
+
text-align: left;
|
|
4697
|
+
cursor: pointer;
|
|
4698
|
+
}
|
|
4699
|
+
.twm-category-picker__category:hover,
|
|
4700
|
+
.twm-category-picker__item:hover {
|
|
4701
|
+
background: var(--state-hover);
|
|
4702
|
+
}
|
|
4703
|
+
.twm-category-picker__category--active,
|
|
4704
|
+
.twm-category-picker__item--highlighted,
|
|
4705
|
+
.twm-category-picker__category--active:hover,
|
|
4706
|
+
.twm-category-picker__item--highlighted:hover {
|
|
4707
|
+
background: var(--state-selected);
|
|
4708
|
+
}
|
|
4709
|
+
/* The column the arrow keys move in marks its row with an accent edge. */
|
|
4710
|
+
.twm-category-picker__column--current .twm-category-picker__category--active,
|
|
4711
|
+
.twm-category-picker__column--current .twm-category-picker__item--highlighted {
|
|
4712
|
+
box-shadow: inset 2px 0 0 var(--accent-bright);
|
|
4713
|
+
}
|
|
4714
|
+
.twm-category-picker__category--empty {
|
|
4715
|
+
color: var(--text-dim);
|
|
4716
|
+
}
|
|
4717
|
+
.twm-category-picker__dot {
|
|
4718
|
+
flex: none;
|
|
4719
|
+
width: 8px;
|
|
4720
|
+
height: 8px;
|
|
4721
|
+
border-radius: var(--radius-circle);
|
|
4722
|
+
/* background-color, not the shorthand: the colour is the caller's, and a
|
|
4723
|
+
url() in the shorthand would be fetched */
|
|
4724
|
+
background-color: var(--twm-category-picker-color, var(--text-muted));
|
|
4725
|
+
}
|
|
4726
|
+
.twm-category-picker__category-label,
|
|
4727
|
+
.twm-category-picker__item-label {
|
|
4728
|
+
flex: 1 1 auto;
|
|
4729
|
+
min-width: 0;
|
|
4730
|
+
overflow: hidden;
|
|
4731
|
+
white-space: nowrap;
|
|
4732
|
+
text-overflow: ellipsis;
|
|
4733
|
+
}
|
|
4734
|
+
.twm-category-picker__count {
|
|
4735
|
+
flex: none;
|
|
4736
|
+
color: var(--text-muted);
|
|
4737
|
+
font-size: var(--font-size-xs);
|
|
4738
|
+
font-variant-numeric: tabular-nums;
|
|
4739
|
+
}
|
|
4740
|
+
.twm-category-picker__badge,
|
|
4741
|
+
.twm-category-picker__item .twm-category-picker__icon {
|
|
4742
|
+
flex: none;
|
|
4743
|
+
display: flex;
|
|
4744
|
+
align-items: center;
|
|
4745
|
+
justify-content: center;
|
|
4746
|
+
width: 22px;
|
|
4747
|
+
height: 22px;
|
|
4748
|
+
box-sizing: border-box;
|
|
4749
|
+
color: var(--twm-category-picker-color, var(--text-muted));
|
|
4750
|
+
}
|
|
4751
|
+
.twm-category-picker__badge {
|
|
4752
|
+
border: 1px solid var(--twm-category-picker-color, var(--text-muted));
|
|
4753
|
+
border-radius: var(--radius-sm);
|
|
4754
|
+
font-family: var(--font-family-mono);
|
|
4755
|
+
font-size: var(--font-size-xs);
|
|
4756
|
+
font-weight: var(--font-weight-semibold);
|
|
4757
|
+
overflow: hidden;
|
|
4758
|
+
white-space: nowrap;
|
|
4759
|
+
}
|
|
4760
|
+
.twm-category-picker__item .twm-category-picker__icon {
|
|
4761
|
+
font-size: 18px;
|
|
4762
|
+
}
|
|
4763
|
+
/* One category's hits while a query is set: role="group", named by its header. */
|
|
4764
|
+
.twm-category-picker__hits {
|
|
4765
|
+
display: flex;
|
|
4766
|
+
flex-direction: column;
|
|
4767
|
+
}
|
|
4768
|
+
.twm-category-picker__group {
|
|
4769
|
+
display: flex;
|
|
4770
|
+
align-items: center;
|
|
4771
|
+
gap: var(--space-sm);
|
|
4772
|
+
padding: var(--space-md) var(--space-lg) var(--space-xs);
|
|
4773
|
+
color: var(--text-muted);
|
|
4774
|
+
font-size: var(--font-size-xs);
|
|
4775
|
+
text-transform: uppercase;
|
|
4776
|
+
letter-spacing: 0.06em;
|
|
4777
|
+
}
|
|
4778
|
+
.twm-category-picker__empty,
|
|
4779
|
+
.twm-category-picker__detail-empty {
|
|
4780
|
+
padding: var(--space-md) var(--space-lg);
|
|
4781
|
+
color: var(--text-muted);
|
|
4782
|
+
}
|
|
4783
|
+
.twm-category-picker__detail {
|
|
4784
|
+
flex: 1 1 auto;
|
|
4785
|
+
min-width: 0;
|
|
4786
|
+
display: flex;
|
|
4787
|
+
flex-direction: column;
|
|
4788
|
+
gap: var(--space-md);
|
|
4789
|
+
padding: var(--space-xl);
|
|
4790
|
+
overflow-y: auto;
|
|
4791
|
+
}
|
|
4792
|
+
.twm-category-picker__title {
|
|
4793
|
+
color: var(--text-bright);
|
|
4794
|
+
font-size: var(--font-size-xl);
|
|
4795
|
+
font-weight: var(--font-weight-semibold);
|
|
4796
|
+
}
|
|
4797
|
+
.twm-category-picker__description {
|
|
4798
|
+
color: var(--text-secondary);
|
|
4799
|
+
line-height: var(--line-height-normal);
|
|
4800
|
+
}
|
|
4801
|
+
.twm-category-picker__preview-label {
|
|
4802
|
+
margin-top: var(--space-sm);
|
|
4803
|
+
color: var(--text-muted);
|
|
4804
|
+
font-size: var(--font-size-xs);
|
|
4805
|
+
text-transform: uppercase;
|
|
4806
|
+
letter-spacing: 0.06em;
|
|
4807
|
+
}
|
|
4808
|
+
.twm-category-picker__preview {
|
|
4809
|
+
margin: 0;
|
|
4810
|
+
padding: var(--space-md);
|
|
4811
|
+
background: var(--surface-0);
|
|
4812
|
+
border: 1px solid var(--border-default);
|
|
4813
|
+
border-radius: var(--radius-sm);
|
|
4814
|
+
color: var(--text-body);
|
|
4815
|
+
font-family: var(--font-family-mono);
|
|
4816
|
+
font-size: var(--font-size-sm);
|
|
4817
|
+
white-space: pre-wrap;
|
|
4818
|
+
overflow-wrap: anywhere;
|
|
4819
|
+
}
|
|
4820
|
+
.twm-category-picker__add {
|
|
4821
|
+
margin-top: auto;
|
|
4822
|
+
align-self: flex-end;
|
|
4823
|
+
}
|
|
4824
|
+
/* ══ end CATEGORY PICKER ══ */
|
|
4825
|
+
|
|
4612
4826
|
/* ── from code.css ───────────────────────── */
|
|
4613
4827
|
/* Code language tabs */
|
|
4614
4828
|
.twm-code-tabs-header {
|
|
@@ -4825,6 +5039,12 @@ body.twm-window-maximized .twm-resize-handle {
|
|
|
4825
5039
|
.twm-managed-window:focus-within {
|
|
4826
5040
|
border-color: #505050;
|
|
4827
5041
|
}
|
|
5042
|
+
/* BUG-0053. The frame is focusable (tabindex -1) so a press on it keeps focus
|
|
5043
|
+
in the window; the focus-within border above already shows that, so the
|
|
5044
|
+
frame draws no outline of its own. */
|
|
5045
|
+
.twm-managed-window:focus {
|
|
5046
|
+
outline: none;
|
|
5047
|
+
}
|
|
4828
5048
|
/* Minimize animation class — targets taskbar item via CSS custom properties */
|
|
4829
5049
|
.twm-managed-window--minimizing {
|
|
4830
5050
|
transform: translate(var(--mw-target-x, 0px), var(--mw-target-y, 100vh)) scale(var(--mw-target-scale, 0.1));
|
|
@@ -11084,6 +11304,11 @@ button.twm-alerts__ref:hover { text-decoration: underline; }
|
|
|
11084
11304
|
flex: 1 1 140px;
|
|
11085
11305
|
min-width: 0;
|
|
11086
11306
|
}
|
|
11307
|
+
/* A picker has no helper text: its empty helper takes no room (it held a
|
|
11308
|
+
* 28px gap under every picker, and the series header line off its centre). */
|
|
11309
|
+
.twm-plot-config__picker > .twm-autocomplete-field__helper:empty {
|
|
11310
|
+
display: none;
|
|
11311
|
+
}
|
|
11087
11312
|
.twm-plot-config__axes,
|
|
11088
11313
|
.twm-plot-config__list,
|
|
11089
11314
|
.twm-plot-config__series-list {
|
|
@@ -11117,37 +11342,114 @@ button.twm-alerts__ref:hover { text-decoration: underline; }
|
|
|
11117
11342
|
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
|
11118
11343
|
gap: var(--space-xs) var(--space-md);
|
|
11119
11344
|
}
|
|
11345
|
+
/* A series is one block (BUG-0052): a header line (picker, legend label,
|
|
11346
|
+
* remove) over its fields, one per line on the editor's 96px label column —
|
|
11347
|
+
* colour, width, dash, stack group, the embedder's `extraSeriesFields` (their
|
|
11348
|
+
* box is `display: contents`, so its rows are rows of the column) and the
|
|
11349
|
+
* overlay. Until 0.17.15 all of it was one wrapped line. */
|
|
11120
11350
|
.twm-plot-config__series {
|
|
11121
11351
|
display: flex;
|
|
11122
11352
|
flex-direction: column;
|
|
11123
|
-
gap: var(--space-
|
|
11124
|
-
padding: var(--space-
|
|
11353
|
+
gap: var(--space-xs);
|
|
11354
|
+
padding: var(--space-sm) 0;
|
|
11125
11355
|
border-top: 1px solid var(--border-subtle);
|
|
11356
|
+
min-width: 0;
|
|
11357
|
+
}
|
|
11358
|
+
.twm-plot-config__series-head {
|
|
11359
|
+
display: flex;
|
|
11360
|
+
flex-wrap: wrap;
|
|
11361
|
+
align-items: center;
|
|
11362
|
+
gap: var(--space-xs);
|
|
11363
|
+
min-width: 0;
|
|
11364
|
+
}
|
|
11365
|
+
.twm-plot-config__series-head > .twm-plot-config__picker {
|
|
11366
|
+
flex: 2 1 140px;
|
|
11367
|
+
}
|
|
11368
|
+
.twm-plot-config__series-head > .twm-plot-config__input {
|
|
11369
|
+
flex: 1 1 100px;
|
|
11370
|
+
}
|
|
11371
|
+
.twm-plot-config__series-fields {
|
|
11372
|
+
display: flex;
|
|
11373
|
+
flex-direction: column;
|
|
11374
|
+
gap: var(--space-xxs);
|
|
11375
|
+
min-width: 0;
|
|
11376
|
+
}
|
|
11377
|
+
.twm-plot-config__series-extra {
|
|
11378
|
+
display: contents;
|
|
11126
11379
|
}
|
|
11127
|
-
.twm-plot-config__series-main,
|
|
11128
11380
|
.twm-plot-config__row {
|
|
11129
11381
|
display: flex;
|
|
11130
11382
|
flex-wrap: wrap;
|
|
11131
11383
|
align-items: center;
|
|
11132
11384
|
gap: var(--space-xs);
|
|
11133
11385
|
}
|
|
11134
|
-
.twm-plot-config__series-main > .twm-plot-config__input:not(.twm-plot-config__input--number):not(.twm-plot-config__input--select),
|
|
11135
11386
|
.twm-plot-config__row > .twm-plot-config__input:not(.twm-plot-config__input--number):not(.twm-plot-config__input--select) {
|
|
11136
11387
|
flex: 1 1 100px;
|
|
11137
11388
|
}
|
|
11138
|
-
.twm-plot-config__series-main > .twm-plot-config__input--select,
|
|
11139
11389
|
.twm-plot-config__row > .twm-plot-config__input--select {
|
|
11140
11390
|
flex: 0 1 auto;
|
|
11141
11391
|
}
|
|
11142
|
-
|
|
11143
|
-
|
|
11392
|
+
/* On a field line a colour is the swatch and a hex box sized to `#rrggbb`. */
|
|
11393
|
+
.twm-plot-config__field > .twm-color-field {
|
|
11394
|
+
flex: 0 1 auto;
|
|
11395
|
+
flex-wrap: nowrap;
|
|
11396
|
+
}
|
|
11397
|
+
.twm-plot-config__field > .twm-color-field > .twm-color-field__hex {
|
|
11398
|
+
flex: 0 1 auto;
|
|
11399
|
+
width: 10ch;
|
|
11144
11400
|
}
|
|
11401
|
+
/* A colour's hex box is a well like the editor's other inputs. */
|
|
11402
|
+
.twm-plot-config .twm-color-field__hex {
|
|
11403
|
+
box-sizing: border-box;
|
|
11404
|
+
padding: var(--space-xxs) var(--space-xs);
|
|
11405
|
+
background: var(--surface-3);
|
|
11406
|
+
color: var(--text-primary);
|
|
11407
|
+
border: 1px solid var(--border-strong);
|
|
11408
|
+
border-radius: var(--radius-sm);
|
|
11409
|
+
}
|
|
11410
|
+
/* ... and still shows a hex that is not a colour (the well's border above
|
|
11411
|
+
* would otherwise hide ColorField's invalid border). */
|
|
11412
|
+
.twm-plot-config .twm-color-field--invalid .twm-color-field__hex {
|
|
11413
|
+
border-color: var(--color-danger);
|
|
11414
|
+
}
|
|
11415
|
+
/* A field line's select keeps to its options, as the number boxes do. */
|
|
11416
|
+
.twm-plot-config__series-fields .twm-plot-config__field > .twm-plot-config__input--select {
|
|
11417
|
+
flex: 0 1 auto;
|
|
11418
|
+
max-width: 100%;
|
|
11419
|
+
}
|
|
11420
|
+
/* An embedder's control drawn by a field spec's `render(slot)`. */
|
|
11421
|
+
.twm-plot-config__slot {
|
|
11422
|
+
flex: 1 1 auto;
|
|
11423
|
+
min-width: 0;
|
|
11424
|
+
}
|
|
11425
|
+
/* A field's hint, under its control: past the label column. Only a field
|
|
11426
|
+
* with a hint wraps, so a number box never drops under its label. */
|
|
11427
|
+
.twm-plot-config__field--hinted {
|
|
11428
|
+
flex-wrap: wrap;
|
|
11429
|
+
}
|
|
11430
|
+
.twm-plot-config__hint {
|
|
11431
|
+
box-sizing: border-box;
|
|
11432
|
+
flex: 1 0 100%;
|
|
11433
|
+
padding-left: calc(96px + var(--space-sm));
|
|
11434
|
+
font-size: var(--font-size-xs);
|
|
11435
|
+
color: var(--text-muted);
|
|
11436
|
+
}
|
|
11437
|
+
/* The overlay's own fields, under its source: set in by a rule, their label
|
|
11438
|
+
* column shortened by as much, so their controls stay on the series' column. */
|
|
11145
11439
|
.twm-plot-config__overlay,
|
|
11146
11440
|
.twm-plot-config__overlay-fields {
|
|
11147
11441
|
display: flex;
|
|
11148
11442
|
flex-direction: column;
|
|
11149
11443
|
gap: var(--space-xxs);
|
|
11150
|
-
|
|
11444
|
+
min-width: 0;
|
|
11445
|
+
}
|
|
11446
|
+
.twm-plot-config__overlay-fields:not(:empty) {
|
|
11447
|
+
margin-left: var(--space-sm);
|
|
11448
|
+
padding-left: calc(var(--space-sm) - 1px);
|
|
11449
|
+
border-left: 1px solid var(--border-subtle);
|
|
11450
|
+
}
|
|
11451
|
+
.twm-plot-config__overlay-fields > .twm-plot-config__field > .twm-plot-config__label {
|
|
11452
|
+
flex-basis: calc(96px - 2 * var(--space-sm));
|
|
11151
11453
|
}
|
|
11152
11454
|
.twm-plot-config__overlay-source {
|
|
11153
11455
|
color: var(--text-muted);
|