flexdesk 0.17.15 → 0.17.17
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 +42 -0
- package/css/base.css +236 -5
- package/css/flexdesk.css +326 -13
- package/css/tokens.css +3 -0
- 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 +326 -13
- package/dist/flow.js +3 -3
- package/dist/tiles.js +84 -9
- package/dist/tiles.js.map +2 -2
- package/dist/tokens.css +3 -0
- package/dist/widgets.js +4559 -4091
- package/dist/widgets.js.map +4 -4
- package/dist/wm.js +212 -40
- 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/notifications.md +23 -1
- package/docs/components/panels-and-desktops.md +22 -0
- package/docs/components/shell.md +91 -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 +66 -13
- package/src/tiling/shell.js +4 -1
- package/src/tiling/wm.js +205 -35
- 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/notification_history.js +11 -1
- package/src/ui/components/wizard.js +4 -1
- package/src/ui/notification_center.js +47 -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/dist/flexdesk.css
CHANGED
|
@@ -551,6 +551,17 @@
|
|
|
551
551
|
color: #bcbcbc;
|
|
552
552
|
line-height: 1.4;
|
|
553
553
|
}
|
|
554
|
+
/* The text of a toast and of a history entry can be selected and copied (STORY-0131);
|
|
555
|
+
* the body's `user-select: none` (reset.css) would otherwise hold it. */
|
|
556
|
+
.twm-notification__title,
|
|
557
|
+
.twm-notification__body,
|
|
558
|
+
.twm-notification__description,
|
|
559
|
+
.twm-notification__status,
|
|
560
|
+
.twm-notification-history__item-title,
|
|
561
|
+
.twm-notification-history__item-body {
|
|
562
|
+
user-select: text;
|
|
563
|
+
cursor: text;
|
|
564
|
+
}
|
|
554
565
|
.twm-notification-history__empty {
|
|
555
566
|
text-align: center;
|
|
556
567
|
color: #6c6c6c;
|
|
@@ -2314,7 +2325,7 @@ body.twm-dt-col-resizing {
|
|
|
2314
2325
|
border: 1px solid var(--surface-3);
|
|
2315
2326
|
border-radius: var(--radius-md);
|
|
2316
2327
|
box-shadow: 0 6px 24px rgba(0,0,0,0.45);
|
|
2317
|
-
z-index:
|
|
2328
|
+
z-index: var(--z-context-menu);
|
|
2318
2329
|
display: none;
|
|
2319
2330
|
pointer-events: auto;
|
|
2320
2331
|
min-width: 180px;
|
|
@@ -3869,20 +3880,25 @@ body.twm-window-maximized .twm-resize-handle {
|
|
|
3869
3880
|
}
|
|
3870
3881
|
|
|
3871
3882
|
/* Selected — set by `_onConfigClick()` while the config dialog is open, and
|
|
3872
|
-
cleared from every sibling by the same handler.
|
|
3883
|
+
cleared from every sibling by the same handler. `--configuring` is the same
|
|
3884
|
+
look set by the embedder through `setConfiguring()` (0.17.16), one per open
|
|
3885
|
+
config window, and no handler clears it. It reads `--accent-lighter`
|
|
3873
3886
|
(BUG-0045): `--accent-bright` is a border colour on this background and not
|
|
3874
3887
|
a text one. It was #78b9ff, which no mix of `--accent-bright` with white
|
|
3875
3888
|
gives exactly; `--accent-lighter` (about #73b6e3) is the nearest. */
|
|
3876
|
-
.tile.tile--selected
|
|
3889
|
+
.tile.tile--selected,
|
|
3890
|
+
.tile.tile--configuring {
|
|
3877
3891
|
border-color: var(--accent-lighter);
|
|
3878
3892
|
box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-lighter) 30%, transparent), var(--shadow-md);
|
|
3879
3893
|
}
|
|
3880
3894
|
|
|
3881
|
-
.tile.tile--selected .tile-header
|
|
3895
|
+
.tile.tile--selected .tile-header,
|
|
3896
|
+
.tile.tile--configuring .tile-header {
|
|
3882
3897
|
background: color-mix(in srgb, var(--accent-lighter) 10%, transparent);
|
|
3883
3898
|
}
|
|
3884
3899
|
|
|
3885
|
-
.tile.tile--selected .tile-title
|
|
3900
|
+
.tile.tile--selected .tile-title,
|
|
3901
|
+
.tile.tile--configuring .tile-title {
|
|
3886
3902
|
color: var(--accent-lighter);
|
|
3887
3903
|
}
|
|
3888
3904
|
|
|
@@ -4609,6 +4625,215 @@ body.twm-window-maximized .twm-resize-handle {
|
|
|
4609
4625
|
text-overflow: ellipsis;
|
|
4610
4626
|
}
|
|
4611
4627
|
|
|
4628
|
+
/* ══ CATEGORY PICKER (STORY-0126) ══════════════════════════════════════
|
|
4629
|
+
`CategoryPicker` (category_picker.js): a search field over three columns —
|
|
4630
|
+
categories, the active category's items, the highlighted item's detail.
|
|
4631
|
+
Placed by `ActionDropdown.position` (inline top/left/max-height), so it is
|
|
4632
|
+
`position: fixed` on --z-over-windows: over the managed window it opened
|
|
4633
|
+
from. It shrinks to the inline max-height and its columns scroll inside.
|
|
4634
|
+
A category's colour arrives as `--twm-category-picker-color` on its rows. */
|
|
4635
|
+
.twm-category-picker {
|
|
4636
|
+
position: fixed;
|
|
4637
|
+
z-index: var(--z-over-windows);
|
|
4638
|
+
display: flex;
|
|
4639
|
+
flex-direction: column;
|
|
4640
|
+
box-sizing: border-box;
|
|
4641
|
+
width: 640px;
|
|
4642
|
+
max-width: calc(100vw - 2 * var(--space-md));
|
|
4643
|
+
height: 440px;
|
|
4644
|
+
background: var(--surface-1);
|
|
4645
|
+
border: 1px solid var(--border-strong);
|
|
4646
|
+
border-radius: var(--radius-lg);
|
|
4647
|
+
box-shadow: var(--shadow-lg);
|
|
4648
|
+
color: var(--text-primary);
|
|
4649
|
+
font-family: inherit;
|
|
4650
|
+
font-size: var(--font-size-md);
|
|
4651
|
+
overflow: hidden;
|
|
4652
|
+
}
|
|
4653
|
+
.twm-category-picker[hidden] {
|
|
4654
|
+
display: none;
|
|
4655
|
+
}
|
|
4656
|
+
.twm-category-picker__search {
|
|
4657
|
+
flex: none;
|
|
4658
|
+
padding: var(--space-md);
|
|
4659
|
+
border-bottom: 1px solid var(--border-default);
|
|
4660
|
+
}
|
|
4661
|
+
.twm-category-picker__input {
|
|
4662
|
+
width: 100%;
|
|
4663
|
+
box-sizing: border-box;
|
|
4664
|
+
padding: var(--space-sm) var(--space-md);
|
|
4665
|
+
background: var(--surface-0);
|
|
4666
|
+
border: 1px solid var(--border-strong);
|
|
4667
|
+
border-radius: var(--radius-sm);
|
|
4668
|
+
color: var(--text-primary);
|
|
4669
|
+
font-family: inherit;
|
|
4670
|
+
font-size: var(--font-size-md);
|
|
4671
|
+
}
|
|
4672
|
+
.twm-category-picker__input:focus {
|
|
4673
|
+
outline: none;
|
|
4674
|
+
border-color: var(--accent-bright);
|
|
4675
|
+
}
|
|
4676
|
+
.twm-category-picker__body {
|
|
4677
|
+
flex: 1 1 auto;
|
|
4678
|
+
min-height: 0;
|
|
4679
|
+
display: flex;
|
|
4680
|
+
}
|
|
4681
|
+
.twm-category-picker__column {
|
|
4682
|
+
flex: none;
|
|
4683
|
+
box-sizing: border-box;
|
|
4684
|
+
padding: var(--space-sm) 0;
|
|
4685
|
+
border-right: 1px solid var(--border-default);
|
|
4686
|
+
overflow-y: auto;
|
|
4687
|
+
}
|
|
4688
|
+
.twm-category-picker__categories {
|
|
4689
|
+
width: 170px;
|
|
4690
|
+
}
|
|
4691
|
+
.twm-category-picker__items {
|
|
4692
|
+
width: 220px;
|
|
4693
|
+
}
|
|
4694
|
+
.twm-category-picker__category,
|
|
4695
|
+
.twm-category-picker__item {
|
|
4696
|
+
display: flex;
|
|
4697
|
+
align-items: center;
|
|
4698
|
+
gap: var(--space-md);
|
|
4699
|
+
width: 100%;
|
|
4700
|
+
box-sizing: border-box;
|
|
4701
|
+
padding: var(--space-sm) var(--space-lg);
|
|
4702
|
+
background: transparent;
|
|
4703
|
+
border: none;
|
|
4704
|
+
color: var(--text-primary);
|
|
4705
|
+
font-family: inherit;
|
|
4706
|
+
font-size: var(--font-size-md);
|
|
4707
|
+
text-align: left;
|
|
4708
|
+
cursor: pointer;
|
|
4709
|
+
}
|
|
4710
|
+
.twm-category-picker__category:hover,
|
|
4711
|
+
.twm-category-picker__item:hover {
|
|
4712
|
+
background: var(--state-hover);
|
|
4713
|
+
}
|
|
4714
|
+
.twm-category-picker__category--active,
|
|
4715
|
+
.twm-category-picker__item--highlighted,
|
|
4716
|
+
.twm-category-picker__category--active:hover,
|
|
4717
|
+
.twm-category-picker__item--highlighted:hover {
|
|
4718
|
+
background: var(--state-selected);
|
|
4719
|
+
}
|
|
4720
|
+
/* The column the arrow keys move in marks its row with an accent edge. */
|
|
4721
|
+
.twm-category-picker__column--current .twm-category-picker__category--active,
|
|
4722
|
+
.twm-category-picker__column--current .twm-category-picker__item--highlighted {
|
|
4723
|
+
box-shadow: inset 2px 0 0 var(--accent-bright);
|
|
4724
|
+
}
|
|
4725
|
+
.twm-category-picker__category--empty {
|
|
4726
|
+
color: var(--text-dim);
|
|
4727
|
+
}
|
|
4728
|
+
.twm-category-picker__dot {
|
|
4729
|
+
flex: none;
|
|
4730
|
+
width: 8px;
|
|
4731
|
+
height: 8px;
|
|
4732
|
+
border-radius: var(--radius-circle);
|
|
4733
|
+
/* background-color, not the shorthand: the colour is the caller's, and a
|
|
4734
|
+
url() in the shorthand would be fetched */
|
|
4735
|
+
background-color: var(--twm-category-picker-color, var(--text-muted));
|
|
4736
|
+
}
|
|
4737
|
+
.twm-category-picker__category-label,
|
|
4738
|
+
.twm-category-picker__item-label {
|
|
4739
|
+
flex: 1 1 auto;
|
|
4740
|
+
min-width: 0;
|
|
4741
|
+
overflow: hidden;
|
|
4742
|
+
white-space: nowrap;
|
|
4743
|
+
text-overflow: ellipsis;
|
|
4744
|
+
}
|
|
4745
|
+
.twm-category-picker__count {
|
|
4746
|
+
flex: none;
|
|
4747
|
+
color: var(--text-muted);
|
|
4748
|
+
font-size: var(--font-size-xs);
|
|
4749
|
+
font-variant-numeric: tabular-nums;
|
|
4750
|
+
}
|
|
4751
|
+
.twm-category-picker__badge,
|
|
4752
|
+
.twm-category-picker__item .twm-category-picker__icon {
|
|
4753
|
+
flex: none;
|
|
4754
|
+
display: flex;
|
|
4755
|
+
align-items: center;
|
|
4756
|
+
justify-content: center;
|
|
4757
|
+
width: 22px;
|
|
4758
|
+
height: 22px;
|
|
4759
|
+
box-sizing: border-box;
|
|
4760
|
+
color: var(--twm-category-picker-color, var(--text-muted));
|
|
4761
|
+
}
|
|
4762
|
+
.twm-category-picker__badge {
|
|
4763
|
+
border: 1px solid var(--twm-category-picker-color, var(--text-muted));
|
|
4764
|
+
border-radius: var(--radius-sm);
|
|
4765
|
+
font-family: var(--font-family-mono);
|
|
4766
|
+
font-size: var(--font-size-xs);
|
|
4767
|
+
font-weight: var(--font-weight-semibold);
|
|
4768
|
+
overflow: hidden;
|
|
4769
|
+
white-space: nowrap;
|
|
4770
|
+
}
|
|
4771
|
+
.twm-category-picker__item .twm-category-picker__icon {
|
|
4772
|
+
font-size: 18px;
|
|
4773
|
+
}
|
|
4774
|
+
/* One category's hits while a query is set: role="group", named by its header. */
|
|
4775
|
+
.twm-category-picker__hits {
|
|
4776
|
+
display: flex;
|
|
4777
|
+
flex-direction: column;
|
|
4778
|
+
}
|
|
4779
|
+
.twm-category-picker__group {
|
|
4780
|
+
display: flex;
|
|
4781
|
+
align-items: center;
|
|
4782
|
+
gap: var(--space-sm);
|
|
4783
|
+
padding: var(--space-md) var(--space-lg) var(--space-xs);
|
|
4784
|
+
color: var(--text-muted);
|
|
4785
|
+
font-size: var(--font-size-xs);
|
|
4786
|
+
text-transform: uppercase;
|
|
4787
|
+
letter-spacing: 0.06em;
|
|
4788
|
+
}
|
|
4789
|
+
.twm-category-picker__empty,
|
|
4790
|
+
.twm-category-picker__detail-empty {
|
|
4791
|
+
padding: var(--space-md) var(--space-lg);
|
|
4792
|
+
color: var(--text-muted);
|
|
4793
|
+
}
|
|
4794
|
+
.twm-category-picker__detail {
|
|
4795
|
+
flex: 1 1 auto;
|
|
4796
|
+
min-width: 0;
|
|
4797
|
+
display: flex;
|
|
4798
|
+
flex-direction: column;
|
|
4799
|
+
gap: var(--space-md);
|
|
4800
|
+
padding: var(--space-xl);
|
|
4801
|
+
overflow-y: auto;
|
|
4802
|
+
}
|
|
4803
|
+
.twm-category-picker__title {
|
|
4804
|
+
color: var(--text-bright);
|
|
4805
|
+
font-size: var(--font-size-xl);
|
|
4806
|
+
font-weight: var(--font-weight-semibold);
|
|
4807
|
+
}
|
|
4808
|
+
.twm-category-picker__description {
|
|
4809
|
+
color: var(--text-secondary);
|
|
4810
|
+
line-height: var(--line-height-normal);
|
|
4811
|
+
}
|
|
4812
|
+
.twm-category-picker__preview-label {
|
|
4813
|
+
margin-top: var(--space-sm);
|
|
4814
|
+
color: var(--text-muted);
|
|
4815
|
+
font-size: var(--font-size-xs);
|
|
4816
|
+
text-transform: uppercase;
|
|
4817
|
+
letter-spacing: 0.06em;
|
|
4818
|
+
}
|
|
4819
|
+
.twm-category-picker__preview {
|
|
4820
|
+
margin: 0;
|
|
4821
|
+
padding: var(--space-md);
|
|
4822
|
+
background: var(--surface-0);
|
|
4823
|
+
border: 1px solid var(--border-default);
|
|
4824
|
+
border-radius: var(--radius-sm);
|
|
4825
|
+
color: var(--text-body);
|
|
4826
|
+
font-family: var(--font-family-mono);
|
|
4827
|
+
font-size: var(--font-size-sm);
|
|
4828
|
+
white-space: pre-wrap;
|
|
4829
|
+
overflow-wrap: anywhere;
|
|
4830
|
+
}
|
|
4831
|
+
.twm-category-picker__add {
|
|
4832
|
+
margin-top: auto;
|
|
4833
|
+
align-self: flex-end;
|
|
4834
|
+
}
|
|
4835
|
+
/* ══ end CATEGORY PICKER ══ */
|
|
4836
|
+
|
|
4612
4837
|
/* ── from code.css ───────────────────────── */
|
|
4613
4838
|
/* Code language tabs */
|
|
4614
4839
|
.twm-code-tabs-header {
|
|
@@ -4825,6 +5050,12 @@ body.twm-window-maximized .twm-resize-handle {
|
|
|
4825
5050
|
.twm-managed-window:focus-within {
|
|
4826
5051
|
border-color: #505050;
|
|
4827
5052
|
}
|
|
5053
|
+
/* BUG-0053. The frame is focusable (tabindex -1) so a press on it keeps focus
|
|
5054
|
+
in the window; the focus-within border above already shows that, so the
|
|
5055
|
+
frame draws no outline of its own. */
|
|
5056
|
+
.twm-managed-window:focus {
|
|
5057
|
+
outline: none;
|
|
5058
|
+
}
|
|
4828
5059
|
/* Minimize animation class — targets taskbar item via CSS custom properties */
|
|
4829
5060
|
.twm-managed-window--minimizing {
|
|
4830
5061
|
transform: translate(var(--mw-target-x, 0px), var(--mw-target-y, 100vh)) scale(var(--mw-target-scale, 0.1));
|
|
@@ -11084,6 +11315,11 @@ button.twm-alerts__ref:hover { text-decoration: underline; }
|
|
|
11084
11315
|
flex: 1 1 140px;
|
|
11085
11316
|
min-width: 0;
|
|
11086
11317
|
}
|
|
11318
|
+
/* A picker has no helper text: its empty helper takes no room (it held a
|
|
11319
|
+
* 28px gap under every picker, and the series header line off its centre). */
|
|
11320
|
+
.twm-plot-config__picker > .twm-autocomplete-field__helper:empty {
|
|
11321
|
+
display: none;
|
|
11322
|
+
}
|
|
11087
11323
|
.twm-plot-config__axes,
|
|
11088
11324
|
.twm-plot-config__list,
|
|
11089
11325
|
.twm-plot-config__series-list {
|
|
@@ -11117,37 +11353,114 @@ button.twm-alerts__ref:hover { text-decoration: underline; }
|
|
|
11117
11353
|
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
|
11118
11354
|
gap: var(--space-xs) var(--space-md);
|
|
11119
11355
|
}
|
|
11356
|
+
/* A series is one block (BUG-0052): a header line (picker, legend label,
|
|
11357
|
+
* remove) over its fields, one per line on the editor's 96px label column —
|
|
11358
|
+
* colour, width, dash, stack group, the embedder's `extraSeriesFields` (their
|
|
11359
|
+
* box is `display: contents`, so its rows are rows of the column) and the
|
|
11360
|
+
* overlay. Until 0.17.15 all of it was one wrapped line. */
|
|
11120
11361
|
.twm-plot-config__series {
|
|
11121
11362
|
display: flex;
|
|
11122
11363
|
flex-direction: column;
|
|
11123
|
-
gap: var(--space-
|
|
11124
|
-
padding: var(--space-
|
|
11364
|
+
gap: var(--space-xs);
|
|
11365
|
+
padding: var(--space-sm) 0;
|
|
11125
11366
|
border-top: 1px solid var(--border-subtle);
|
|
11367
|
+
min-width: 0;
|
|
11368
|
+
}
|
|
11369
|
+
.twm-plot-config__series-head {
|
|
11370
|
+
display: flex;
|
|
11371
|
+
flex-wrap: wrap;
|
|
11372
|
+
align-items: center;
|
|
11373
|
+
gap: var(--space-xs);
|
|
11374
|
+
min-width: 0;
|
|
11375
|
+
}
|
|
11376
|
+
.twm-plot-config__series-head > .twm-plot-config__picker {
|
|
11377
|
+
flex: 2 1 140px;
|
|
11378
|
+
}
|
|
11379
|
+
.twm-plot-config__series-head > .twm-plot-config__input {
|
|
11380
|
+
flex: 1 1 100px;
|
|
11381
|
+
}
|
|
11382
|
+
.twm-plot-config__series-fields {
|
|
11383
|
+
display: flex;
|
|
11384
|
+
flex-direction: column;
|
|
11385
|
+
gap: var(--space-xxs);
|
|
11386
|
+
min-width: 0;
|
|
11387
|
+
}
|
|
11388
|
+
.twm-plot-config__series-extra {
|
|
11389
|
+
display: contents;
|
|
11126
11390
|
}
|
|
11127
|
-
.twm-plot-config__series-main,
|
|
11128
11391
|
.twm-plot-config__row {
|
|
11129
11392
|
display: flex;
|
|
11130
11393
|
flex-wrap: wrap;
|
|
11131
11394
|
align-items: center;
|
|
11132
11395
|
gap: var(--space-xs);
|
|
11133
11396
|
}
|
|
11134
|
-
.twm-plot-config__series-main > .twm-plot-config__input:not(.twm-plot-config__input--number):not(.twm-plot-config__input--select),
|
|
11135
11397
|
.twm-plot-config__row > .twm-plot-config__input:not(.twm-plot-config__input--number):not(.twm-plot-config__input--select) {
|
|
11136
11398
|
flex: 1 1 100px;
|
|
11137
11399
|
}
|
|
11138
|
-
.twm-plot-config__series-main > .twm-plot-config__input--select,
|
|
11139
11400
|
.twm-plot-config__row > .twm-plot-config__input--select {
|
|
11140
11401
|
flex: 0 1 auto;
|
|
11141
11402
|
}
|
|
11142
|
-
|
|
11143
|
-
|
|
11403
|
+
/* On a field line a colour is the swatch and a hex box sized to `#rrggbb`. */
|
|
11404
|
+
.twm-plot-config__field > .twm-color-field {
|
|
11405
|
+
flex: 0 1 auto;
|
|
11406
|
+
flex-wrap: nowrap;
|
|
11407
|
+
}
|
|
11408
|
+
.twm-plot-config__field > .twm-color-field > .twm-color-field__hex {
|
|
11409
|
+
flex: 0 1 auto;
|
|
11410
|
+
width: 10ch;
|
|
11411
|
+
}
|
|
11412
|
+
/* A colour's hex box is a well like the editor's other inputs. */
|
|
11413
|
+
.twm-plot-config .twm-color-field__hex {
|
|
11414
|
+
box-sizing: border-box;
|
|
11415
|
+
padding: var(--space-xxs) var(--space-xs);
|
|
11416
|
+
background: var(--surface-3);
|
|
11417
|
+
color: var(--text-primary);
|
|
11418
|
+
border: 1px solid var(--border-strong);
|
|
11419
|
+
border-radius: var(--radius-sm);
|
|
11420
|
+
}
|
|
11421
|
+
/* ... and still shows a hex that is not a colour (the well's border above
|
|
11422
|
+
* would otherwise hide ColorField's invalid border). */
|
|
11423
|
+
.twm-plot-config .twm-color-field--invalid .twm-color-field__hex {
|
|
11424
|
+
border-color: var(--color-danger);
|
|
11425
|
+
}
|
|
11426
|
+
/* A field line's select keeps to its options, as the number boxes do. */
|
|
11427
|
+
.twm-plot-config__series-fields .twm-plot-config__field > .twm-plot-config__input--select {
|
|
11428
|
+
flex: 0 1 auto;
|
|
11429
|
+
max-width: 100%;
|
|
11430
|
+
}
|
|
11431
|
+
/* An embedder's control drawn by a field spec's `render(slot)`. */
|
|
11432
|
+
.twm-plot-config__slot {
|
|
11433
|
+
flex: 1 1 auto;
|
|
11434
|
+
min-width: 0;
|
|
11144
11435
|
}
|
|
11436
|
+
/* A field's hint, under its control: past the label column. Only a field
|
|
11437
|
+
* with a hint wraps, so a number box never drops under its label. */
|
|
11438
|
+
.twm-plot-config__field--hinted {
|
|
11439
|
+
flex-wrap: wrap;
|
|
11440
|
+
}
|
|
11441
|
+
.twm-plot-config__hint {
|
|
11442
|
+
box-sizing: border-box;
|
|
11443
|
+
flex: 1 0 100%;
|
|
11444
|
+
padding-left: calc(96px + var(--space-sm));
|
|
11445
|
+
font-size: var(--font-size-xs);
|
|
11446
|
+
color: var(--text-muted);
|
|
11447
|
+
}
|
|
11448
|
+
/* The overlay's own fields, under its source: set in by a rule, their label
|
|
11449
|
+
* column shortened by as much, so their controls stay on the series' column. */
|
|
11145
11450
|
.twm-plot-config__overlay,
|
|
11146
11451
|
.twm-plot-config__overlay-fields {
|
|
11147
11452
|
display: flex;
|
|
11148
11453
|
flex-direction: column;
|
|
11149
11454
|
gap: var(--space-xxs);
|
|
11150
|
-
|
|
11455
|
+
min-width: 0;
|
|
11456
|
+
}
|
|
11457
|
+
.twm-plot-config__overlay-fields:not(:empty) {
|
|
11458
|
+
margin-left: var(--space-sm);
|
|
11459
|
+
padding-left: calc(var(--space-sm) - 1px);
|
|
11460
|
+
border-left: 1px solid var(--border-subtle);
|
|
11461
|
+
}
|
|
11462
|
+
.twm-plot-config__overlay-fields > .twm-plot-config__field > .twm-plot-config__label {
|
|
11463
|
+
flex-basis: calc(96px - 2 * var(--space-sm));
|
|
11151
11464
|
}
|
|
11152
11465
|
.twm-plot-config__overlay-source {
|
|
11153
11466
|
color: var(--text-muted);
|
package/dist/flow.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
modalHost
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-XJNADRGR.js";
|
|
4
4
|
import {
|
|
5
5
|
DataTable
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-2Z2ENHR3.js";
|
|
7
7
|
import {
|
|
8
8
|
choiceList,
|
|
9
9
|
selectBox,
|
|
10
10
|
shownValue,
|
|
11
11
|
toggleChips
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-PGZ4EHSE.js";
|
|
13
13
|
import "./chunk-HNU6MM2B.js";
|
|
14
14
|
import "./chunk-WUFLGETN.js";
|
|
15
15
|
import {
|
package/dist/tiles.js
CHANGED
|
@@ -17,11 +17,11 @@ import {
|
|
|
17
17
|
} from "./chunk-MIW7D6WC.js";
|
|
18
18
|
import {
|
|
19
19
|
showContextMenu
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-7JI7HHSY.js";
|
|
21
21
|
import {
|
|
22
22
|
modalHost,
|
|
23
23
|
openModal
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-XJNADRGR.js";
|
|
25
25
|
import {
|
|
26
26
|
buildHistogramTrace,
|
|
27
27
|
buildLegendLayout,
|
|
@@ -36,11 +36,11 @@ import {
|
|
|
36
36
|
purge,
|
|
37
37
|
resize,
|
|
38
38
|
strideDownsampleShared
|
|
39
|
-
} from "./chunk-
|
|
40
|
-
import "./chunk-
|
|
39
|
+
} from "./chunk-7OL6F2AM.js";
|
|
40
|
+
import "./chunk-2Z2ENHR3.js";
|
|
41
41
|
import {
|
|
42
42
|
isHexColor
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-PGZ4EHSE.js";
|
|
44
44
|
import "./chunk-HNU6MM2B.js";
|
|
45
45
|
import "./chunk-WUFLGETN.js";
|
|
46
46
|
import {
|
|
@@ -220,6 +220,9 @@ var TileBase = class {
|
|
|
220
220
|
* @param {{resolve: Function}} [options.dataSource] - Where this tile asks for its
|
|
221
221
|
* own rows. Handed down by `TileGrid`; absent for a grid whose data is
|
|
222
222
|
* broadcast with `setData()`, and then nothing ever calls `loadData()`.
|
|
223
|
+
* @param {boolean} [options.configOnDoubleClick=true] - A double-click on the
|
|
224
|
+
* title strip (not on its buttons or an editable field in it) does what
|
|
225
|
+
* the cogwheel does. False leaves the cogwheel as the only way in.
|
|
223
226
|
*/
|
|
224
227
|
constructor({
|
|
225
228
|
id,
|
|
@@ -230,7 +233,8 @@ var TileBase = class {
|
|
|
230
233
|
headless = false,
|
|
231
234
|
host = null,
|
|
232
235
|
stateGuard = null,
|
|
233
|
-
dataSource = null
|
|
236
|
+
dataSource = null,
|
|
237
|
+
configOnDoubleClick = true
|
|
234
238
|
}) {
|
|
235
239
|
this.host = host;
|
|
236
240
|
this.dataSource = dataSource;
|
|
@@ -241,6 +245,8 @@ var TileBase = class {
|
|
|
241
245
|
this.config = { ...this.getDefaultConfig(), ...config };
|
|
242
246
|
this.readonly = readonly;
|
|
243
247
|
this.headless = headless;
|
|
248
|
+
this.configOnDoubleClick = configOnDoubleClick;
|
|
249
|
+
this._configuring = false;
|
|
244
250
|
this.element = null;
|
|
245
251
|
this.contentElement = null;
|
|
246
252
|
this.chartInstance = null;
|
|
@@ -413,7 +419,7 @@ var TileBase = class {
|
|
|
413
419
|
mount(container) {
|
|
414
420
|
if (this._disposed) return;
|
|
415
421
|
this.element = document.createElement("div");
|
|
416
|
-
this.element.className = `tile${this.readonly ? " tile--readonly" : ""}`;
|
|
422
|
+
this.element.className = `tile${this.readonly ? " tile--readonly" : ""}${this._configuring ? " tile--configuring" : ""}`;
|
|
417
423
|
const stateGuard = this.stateGuard;
|
|
418
424
|
const setDataset = () => {
|
|
419
425
|
this.element.dataset.tileId = this.id;
|
|
@@ -669,6 +675,12 @@ var TileBase = class {
|
|
|
669
675
|
e.stopPropagation();
|
|
670
676
|
this._onConfigClick();
|
|
671
677
|
});
|
|
678
|
+
header.addEventListener("dblclick", (e) => {
|
|
679
|
+
if (!this.configOnDoubleClick || !configBtn) return;
|
|
680
|
+
if (e.target.closest?.('button, input, textarea, select, [contenteditable=""], [contenteditable="true"], .tile-menu-dropdown')) return;
|
|
681
|
+
e.stopPropagation();
|
|
682
|
+
this._onConfigClick();
|
|
683
|
+
});
|
|
672
684
|
const menuBtn = header.querySelector(".tile-menu-btn");
|
|
673
685
|
const menuDropdown = header.querySelector(".tile-menu-dropdown");
|
|
674
686
|
if (menuBtn && menuDropdown) {
|
|
@@ -759,6 +771,33 @@ var TileBase = class {
|
|
|
759
771
|
}
|
|
760
772
|
if (this._menuHome && menu.parentNode !== this._menuHome) this._menuHome.appendChild(menu);
|
|
761
773
|
}
|
|
774
|
+
/**
|
|
775
|
+
* Mark this tile as being configured, or clear the mark (STORY-0128).
|
|
776
|
+
* A convenience for `grid.setConfiguring(tile.id, on)`, which is the API:
|
|
777
|
+
* the grid holds the mark by tile id, so it outlives this tile instance
|
|
778
|
+
* (`setLayout` disposes and rebuilds every tile). A tile with no grid
|
|
779
|
+
* holds the mark itself.
|
|
780
|
+
*
|
|
781
|
+
* @param {boolean} [on=true]
|
|
782
|
+
*/
|
|
783
|
+
setConfiguring(on = true) {
|
|
784
|
+
if (typeof this.grid?.setConfiguring === "function") {
|
|
785
|
+
this.grid.setConfiguring(this.id, on);
|
|
786
|
+
return;
|
|
787
|
+
}
|
|
788
|
+
this._applyConfiguring(on);
|
|
789
|
+
}
|
|
790
|
+
/** Draw (or clear) the configuring mark. Called by the grid.
|
|
791
|
+
* @param {boolean} on
|
|
792
|
+
* @private */
|
|
793
|
+
_applyConfiguring(on) {
|
|
794
|
+
this._configuring = !!on;
|
|
795
|
+
this.element?.classList.toggle("tile--configuring", this._configuring);
|
|
796
|
+
}
|
|
797
|
+
/** True while this tile is marked as being configured. */
|
|
798
|
+
get isConfiguring() {
|
|
799
|
+
return this._configuring;
|
|
800
|
+
}
|
|
762
801
|
/**
|
|
763
802
|
* Handle config button click — highlight tile and emit config request.
|
|
764
803
|
* @private
|
|
@@ -3028,6 +3067,8 @@ var TileGrid = class {
|
|
|
3028
3067
|
* @param {*} [options.scope=null] - The board's scope, a filter every tile
|
|
3029
3068
|
* follows (0.16.1); see `setScope`.
|
|
3030
3069
|
* @param {Function} [options.onScopeChange] - `(scope)` after `setScope` changed it.
|
|
3070
|
+
* @param {boolean} [options.configOnDoubleClick=true] - Whether a double-click
|
|
3071
|
+
* on a tile's title strip opens its config, as its cogwheel does (0.17.16).
|
|
3031
3072
|
*/
|
|
3032
3073
|
constructor({
|
|
3033
3074
|
container,
|
|
@@ -3052,13 +3093,18 @@ var TileGrid = class {
|
|
|
3052
3093
|
// a binding is, only that a tile may have somewhere to ask.
|
|
3053
3094
|
dataSource = null,
|
|
3054
3095
|
scope = null,
|
|
3055
|
-
onScopeChange = null
|
|
3096
|
+
onScopeChange = null,
|
|
3097
|
+
// STORY-0128. Handed to every tile: false turns off the
|
|
3098
|
+
// title strip's double-click to configure.
|
|
3099
|
+
configOnDoubleClick = true
|
|
3056
3100
|
}) {
|
|
3057
3101
|
this.host = host;
|
|
3058
3102
|
this.scope = scope;
|
|
3059
3103
|
this._onScopeChangeCallback = onScopeChange;
|
|
3060
3104
|
this.stateGuard = stateGuard;
|
|
3061
3105
|
this.dataSource = dataSource;
|
|
3106
|
+
this.configOnDoubleClick = configOnDoubleClick;
|
|
3107
|
+
this._configuringIds = /* @__PURE__ */ new Set();
|
|
3062
3108
|
this.container = container;
|
|
3063
3109
|
this.columns = columns;
|
|
3064
3110
|
this.rowHeight = rowHeight;
|
|
@@ -3176,10 +3222,12 @@ var TileGrid = class {
|
|
|
3176
3222
|
readonly: this.readonly,
|
|
3177
3223
|
host: this.host,
|
|
3178
3224
|
stateGuard: this.stateGuard,
|
|
3179
|
-
dataSource: this.dataSource
|
|
3225
|
+
dataSource: this.dataSource,
|
|
3226
|
+
configOnDoubleClick: this.configOnDoubleClick
|
|
3180
3227
|
});
|
|
3181
3228
|
if (!tile) return null;
|
|
3182
3229
|
tile.scope = this.scope;
|
|
3230
|
+
if (this._configuringIds.has(tileId)) tile._applyConfiguring(true);
|
|
3183
3231
|
const layoutEntry = {
|
|
3184
3232
|
id: tileId,
|
|
3185
3233
|
type,
|
|
@@ -3298,6 +3346,33 @@ var TileGrid = class {
|
|
|
3298
3346
|
config: this.tiles.get(l.id)?.config || l.config
|
|
3299
3347
|
}));
|
|
3300
3348
|
}
|
|
3349
|
+
/**
|
|
3350
|
+
* Mark a tile as being configured, or clear the mark (STORY-0128).
|
|
3351
|
+
*
|
|
3352
|
+
* A config request (cogwheel or title double-click) highlights the
|
|
3353
|
+
* requesting tile with `tile--selected` and takes that highlight off every
|
|
3354
|
+
* other tile: one selection per grid. An embedder that keeps a config
|
|
3355
|
+
* window open per tile marks each such tile here instead. The mark
|
|
3356
|
+
* (`tile--configuring`, drawn like the selection) is the embedder's alone:
|
|
3357
|
+
* no config request clears it, and it is held by id, so a tile that
|
|
3358
|
+
* `setLayout` rebuilds (or an id added later) is marked again. Clear it
|
|
3359
|
+
* when that tile's config window closes.
|
|
3360
|
+
*
|
|
3361
|
+
* @param {string} tileId
|
|
3362
|
+
* @param {boolean} [on=true]
|
|
3363
|
+
*/
|
|
3364
|
+
setConfiguring(tileId, on = true) {
|
|
3365
|
+
if (on) this._configuringIds.add(tileId);
|
|
3366
|
+
else this._configuringIds.delete(tileId);
|
|
3367
|
+
this.tiles.get(tileId)?._applyConfiguring(!!on);
|
|
3368
|
+
}
|
|
3369
|
+
/**
|
|
3370
|
+
* @param {string} tileId
|
|
3371
|
+
* @returns {boolean} Whether the tile is marked as being configured.
|
|
3372
|
+
*/
|
|
3373
|
+
isConfiguring(tileId) {
|
|
3374
|
+
return this._configuringIds.has(tileId);
|
|
3375
|
+
}
|
|
3301
3376
|
/**
|
|
3302
3377
|
* Set layout and rebuild tiles.
|
|
3303
3378
|
* @param {Array|Object} layout - Layout array or object with tiles property
|