entangle-ui 0.11.0 → 0.12.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.
Files changed (44) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/dist/esm/assets/src/components/controls/Slider/{Slider.css.ts.vanilla-Cqm3fQ0S.css → Slider.css.ts.vanilla-CLf_RC0A.css} +50 -47
  3. package/dist/esm/assets/src/components/navigation/Menu/{Menu.css.ts.vanilla-B5iVe5S2.css → Menu.css.ts.vanilla-Bhh1L5yl.css} +14 -11
  4. package/dist/esm/assets/src/components/primitives/Tooltip/{Tooltip.css.ts.vanilla-CrEFoLBX.css → Tooltip.css.ts.vanilla-BqaiGrFQ.css} +12 -9
  5. package/dist/esm/assets/src/components/shell/AppShell/{AppShell.css.ts.vanilla-BYmtU0O_.css → AppShell.css.ts.vanilla-BLK2-DRL.css} +1 -0
  6. package/dist/esm/assets/src/components/shell/MenuBar/{MenuBar.css.ts.vanilla-TgPcl4yA.css → MenuBar.css.ts.vanilla-Dt3w4f-q.css} +18 -6
  7. package/dist/esm/components/controls/Slider/Slider.css.js +10 -11
  8. package/dist/esm/components/controls/Slider/Slider.css.js.map +1 -1
  9. package/dist/esm/components/controls/Slider/Slider.js +40 -7
  10. package/dist/esm/components/controls/Slider/Slider.js.map +1 -1
  11. package/dist/esm/components/feedback/Spinner/Spinner.js +12 -3
  12. package/dist/esm/components/feedback/Spinner/Spinner.js.map +1 -1
  13. package/dist/esm/components/navigation/ContextMenu/ContextMenu.js +2 -2
  14. package/dist/esm/components/navigation/ContextMenu/ContextMenu.js.map +1 -1
  15. package/dist/esm/components/navigation/Menu/Menu.css.js +11 -10
  16. package/dist/esm/components/navigation/Menu/Menu.css.js.map +1 -1
  17. package/dist/esm/components/navigation/Menu/Menu.js +2 -2
  18. package/dist/esm/components/navigation/Menu/Menu.js.map +1 -1
  19. package/dist/esm/components/primitives/IconButton/IconButton.js +4 -2
  20. package/dist/esm/components/primitives/IconButton/IconButton.js.map +1 -1
  21. package/dist/esm/components/primitives/Tooltip/Tooltip.css.js +6 -5
  22. package/dist/esm/components/primitives/Tooltip/Tooltip.css.js.map +1 -1
  23. package/dist/esm/components/primitives/Tooltip/Tooltip.js +12 -2
  24. package/dist/esm/components/primitives/Tooltip/Tooltip.js.map +1 -1
  25. package/dist/esm/components/primitives/viewport/Viewport.js +5 -2
  26. package/dist/esm/components/primitives/viewport/Viewport.js.map +1 -1
  27. package/dist/esm/components/shell/AppShell/AppShell.css.js +1 -1
  28. package/dist/esm/components/shell/MenuBar/MenuBar.css.js +7 -6
  29. package/dist/esm/components/shell/MenuBar/MenuBar.css.js.map +1 -1
  30. package/dist/esm/components/shell/MenuBar/MenuBar.js +52 -3
  31. package/dist/esm/components/shell/MenuBar/MenuBar.js.map +1 -1
  32. package/dist/esm/{styles.js → styles.css.js} +1 -1
  33. package/dist/esm/styles.css.js.map +1 -0
  34. package/dist/tokens/tokens.dark.css +1 -1
  35. package/dist/tokens/tokens.json +1 -1
  36. package/dist/tokens/tokens.light.css +1 -1
  37. package/dist/types/components/controls/Slider/Slider.d.ts +7 -0
  38. package/dist/types/components/feedback/Spinner/Spinner.d.ts +6 -1
  39. package/dist/types/components/feedback/Spinner/Spinner.types.d.ts +8 -0
  40. package/dist/types/components/primitives/IconButton/IconButton.d.ts +2 -1
  41. package/dist/types/components/primitives/viewport/Viewport.d.ts +5 -2
  42. package/dist/types/components/shell/MenuBar/MenuBar.d.ts +862 -0
  43. package/package.json +2 -2
  44. package/dist/esm/styles.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,78 @@
1
1
  # entangle-ui
2
2
 
3
+ ## 0.12.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#109](https://github.com/SebastianWebdev/entangle-ui/pull/109) [`b61bfbd`](https://github.com/SebastianWebdev/entangle-ui/commit/b61bfbda7608652cdbcc68c7235980c6a113a9b4) Thanks [@SebastianWebdev](https://github.com/SebastianWebdev)! - **E1 — AppShell top-chrome + MenuBar fill/inset.** `AppShell.MenuBar` now paints
8
+ the menu-bar chrome background (`--etui-shell-menubar-bg`) on the slot, and
9
+ `MenuBar` stretches to fill its host slot so the top chrome reads as one
10
+ continuous strip instead of a lighter content-width block. MenuBar triggers now
11
+ inset their hover/active fill (rounded, vertically centered) from the chrome
12
+ edges. Docs clarify that side toolbar slots (`AppShell.Toolbar position="left|right"`)
13
+ are the intended home for docked panels. Visual default change — no API change.
14
+
15
+ - [#109](https://github.com/SebastianWebdev/entangle-ui/pull/109) [`b61bfbd`](https://github.com/SebastianWebdev/entangle-ui/commit/b61bfbda7608652cdbcc68c7235980c6a113a9b4) Thanks [@SebastianWebdev](https://github.com/SebastianWebdev)! - **G1 — Align `Button` / `IconButton` icon API.** `IconButton` now accepts an
16
+ optional `icon` prop mirroring `Button`'s `icon`, so `<IconButton icon={…} />`
17
+ type-checks and the two components share one API. `children` still works for
18
+ back-compat (now optional); when both are set, `icon` wins. Additive.
19
+
20
+ - [#109](https://github.com/SebastianWebdev/entangle-ui/pull/109) [`b61bfbd`](https://github.com/SebastianWebdev/entangle-ui/commit/b61bfbda7608652cdbcc68c7235980c6a113a9b4) Thanks [@SebastianWebdev](https://github.com/SebastianWebdev)! - **E2 — MenuBar checkable / radio items.** Add `MenuBar.CheckboxItem`
21
+ (`checked` / `defaultChecked` / `onCheckedChange`) and `MenuBar.RadioGroup` +
22
+ `MenuBar.RadioItem` (`value` / `defaultValue` / `onValueChange`), mirroring the
23
+ navigation `Menu` API. Items reserve a leading check-mark gutter so checked and
24
+ unchecked rows align, use `role="menuitemcheckbox"` / `role="menuitemradio"` with
25
+ `aria-checked`, participate in arrow-key navigation, and keep the menu open on
26
+ activation by default (`closeOnClick={false}`). Additive.
27
+
28
+ - [#109](https://github.com/SebastianWebdev/entangle-ui/pull/109) [`b61bfbd`](https://github.com/SebastianWebdev/entangle-ui/commit/b61bfbda7608652cdbcc68c7235980c6a113a9b4) Thanks [@SebastianWebdev](https://github.com/SebastianWebdev)! - **F1 — Slider value tooltip → portal.** The drag value tooltip was an
29
+ absolutely-positioned child of the slider wrapper, so any ancestor `overflow`
30
+ (e.g. a `PropertySection` header) clipped it. It now renders in a portal to
31
+ `document.body` with fixed viewport coordinates anchored to the thumb, so it can
32
+ never be clipped. Added `tooltipPlacement?: 'top' | 'bottom'` (default `'top'`).
33
+ The portal is only mounted while dragging, so the idle/drag hot path is
34
+ unchanged. Default visual placement (above the thumb) is unchanged.
35
+
36
+ - [#109](https://github.com/SebastianWebdev/entangle-ui/pull/109) [`b61bfbd`](https://github.com/SebastianWebdev/entangle-ui/commit/b61bfbda7608652cdbcc68c7235980c6a113a9b4) Thanks [@SebastianWebdev](https://github.com/SebastianWebdev)! - **G2 — `Spinner` `decorative` (live-region opt-out).** Add `decorative?: boolean`
37
+ to `Spinner`. When set, the spinner renders `role="presentation"` + `aria-hidden`
38
+ with no `aria-live`, for use inside an existing live region (e.g. `StatusBar`,
39
+ which is itself `role="status"`) so activity isn't announced twice. Default
40
+ behavior (`role="status"` + `aria-live="polite"`) is unchanged. Additive.
41
+
42
+ ### Patch Changes
43
+
44
+ - [#109](https://github.com/SebastianWebdev/entangle-ui/pull/109) [`b61bfbd`](https://github.com/SebastianWebdev/entangle-ui/commit/b61bfbda7608652cdbcc68c7235980c6a113a9b4) Thanks [@SebastianWebdev](https://github.com/SebastianWebdev)! - **F2 — Tooltip z-index on the Positioner (renders under panels).** The tooltip
45
+ z-index (`--etui-z-tooltip`) was set on the inner `Popup`, trapped inside the
46
+ portaled `Positioner`'s own `position: fixed` stacking context, so a positioned
47
+ sibling at a lower z-index (e.g. an `AppShell` slot at `--etui-z-base`) painted
48
+ over the tooltip. The token now lives on the `Positioner`. Audited the other Base
49
+ UI `Positioner`/`Popup` pairs and applied the same fix to the navigation `Menu`
50
+ and `ContextMenu` (dropdown z-index now on their positioners). `HoverCard`,
51
+ `Select` and `Popover` were already correct (z-index on the positioned element).
52
+
53
+ - [#109](https://github.com/SebastianWebdev/entangle-ui/pull/109) [`b61bfbd`](https://github.com/SebastianWebdev/entangle-ui/commit/b61bfbda7608652cdbcc68c7235980c6a113a9b4) Thanks [@SebastianWebdev](https://github.com/SebastianWebdev)! - **G3 — `Viewport` docs lead with "2D only".** The `Viewport` JSDoc, docs page,
54
+ and skill reference now lead with the 2D-only boundary (it owns a 2D pan/zoom
55
+ transform, not a 3D camera) and point to hosting your own WebGL/WebGPU canvas
56
+ for 3D. Docs-only; no API change.
57
+
58
+ - [#111](https://github.com/SebastianWebdev/entangle-ui/pull/111) [`f933917`](https://github.com/SebastianWebdev/entangle-ui/commit/f933917f99da18ce70ed08bbfb103d03250346c2) Thanks [@SebastianWebdev](https://github.com/SebastianWebdev)! - Fix `entangle-ui/styles.css` being tree-shaken out of production builds.
59
+
60
+ The `./styles.css` export resolved to `dist/esm/styles.js` — a JS shim whose
61
+ only job is to `import` the dark-theme tokens + global-scrollbar stylesheets for
62
+ their side effects. But the package's `sideEffects` allowlist only matches
63
+ `*.css`, `*.css.ts`, and `*.css.js`, so a plain `styles.js` (which exports
64
+ nothing) was flagged side-effect-free and dropped by production bundlers. The
65
+ canonical `import 'entangle-ui/styles.css'` setup then shipped **zero** `--etui-*`
66
+ token definitions: no colours, no fonts, and menu/tooltip popups with no
67
+ background or stacking. Dev was unaffected because dev servers don't tree-shake,
68
+ so the failure only surfaced in `build`/`preview`.
69
+
70
+ The stylesheet entry is now emitted as `dist/esm/styles.css.js`, which matches
71
+ the existing `*.css.js` side-effect glob (the same bucket as every component's
72
+ compiled style module), so the import survives production tree-shaking and the
73
+ dark theme lands on `:root` in dev and prod alike. No source or API change is
74
+ required in consumer apps.
75
+
3
76
  ## 0.11.0
4
77
 
5
78
  ### Minor Changes
@@ -1,15 +1,15 @@
1
- .Slider_sliderContainerRecipe__t8kxxs3 {
1
+ .Slider_sliderContainerRecipe__t8kxxs2 {
2
2
  display: flex;
3
3
  flex-direction: column;
4
4
  gap: var(--etui-spacing-xs);
5
5
  width: 100%;
6
6
  min-width: 0;
7
7
  }
8
- .Slider_sliderContainerRecipe_disabled_true__t8kxxs4 {
8
+ .Slider_sliderContainerRecipe_disabled_true__t8kxxs3 {
9
9
  opacity: 0.5;
10
10
  pointer-events: none;
11
11
  }
12
- .Slider_sliderWrapperStyle__t8kxxs6 {
12
+ .Slider_sliderWrapperStyle__t8kxxs5 {
13
13
  position: relative;
14
14
  display: flex;
15
15
  align-items: center;
@@ -18,56 +18,56 @@
18
18
  padding: 0px 0;
19
19
  width: 100%;
20
20
  }
21
- .Slider_trackRecipe__t8kxxs7 {
21
+ .Slider_trackRecipe__t8kxxs6 {
22
22
  position: relative;
23
23
  flex: 1;
24
24
  border-radius: var(--etui-radius-sm);
25
25
  overflow: hidden;
26
26
  border: 1px solid;
27
27
  }
28
- .Slider_trackRecipe_size_sm__t8kxxs8 {
28
+ .Slider_trackRecipe_size_sm__t8kxxs7 {
29
29
  height: 4px;
30
30
  }
31
- .Slider_trackRecipe_size_md__t8kxxs9 {
31
+ .Slider_trackRecipe_size_md__t8kxxs8 {
32
32
  height: 6px;
33
33
  }
34
- .Slider_trackRecipe_size_lg__t8kxxsa {
34
+ .Slider_trackRecipe_size_lg__t8kxxs9 {
35
35
  height: 8px;
36
36
  }
37
- .Slider_trackRecipe_error_true__t8kxxsb {
37
+ .Slider_trackRecipe_error_true__t8kxxsa {
38
38
  background: var(--etui-color-accent-error);
39
39
  border-color: var(--etui-color-border-error);
40
40
  }
41
- .Slider_trackRecipe_error_true__t8kxxsb:hover {
41
+ .Slider_trackRecipe_error_true__t8kxxsa:hover {
42
42
  border-color: var(--etui-color-border-error);
43
43
  }
44
- .Slider_trackRecipe_error_false__t8kxxsc {
44
+ .Slider_trackRecipe_error_false__t8kxxsb {
45
45
  background: var(--etui-color-surface-default);
46
46
  border-color: var(--etui-color-border-default);
47
47
  }
48
- .Slider_trackRecipe_error_false__t8kxxsc:hover {
48
+ .Slider_trackRecipe_error_false__t8kxxsb:hover {
49
49
  border-color: var(--etui-color-border-focus);
50
50
  }
51
- .Slider_fillRecipe__t8kxxsd {
51
+ .Slider_fillRecipe__t8kxxsc {
52
52
  position: absolute;
53
53
  left: 0;
54
54
  top: 0;
55
55
  bottom: 0;
56
56
  width: var(--fillPercentageVar__t8kxxs0);
57
57
  }
58
- .Slider_fillRecipe_error_true__t8kxxse {
58
+ .Slider_fillRecipe_error_true__t8kxxsd {
59
59
  background: var(--etui-color-accent-error);
60
60
  }
61
- .Slider_fillRecipe_error_false__t8kxxsf {
61
+ .Slider_fillRecipe_error_false__t8kxxse {
62
62
  background: var(--etui-color-accent-primary);
63
63
  }
64
- .Slider_fillRecipe_isDragging_true__t8kxxsg {
64
+ .Slider_fillRecipe_isDragging_true__t8kxxsf {
65
65
  transition: none;
66
66
  }
67
- .Slider_fillRecipe_isDragging_false__t8kxxsh {
67
+ .Slider_fillRecipe_isDragging_false__t8kxxsg {
68
68
  transition: width 0.1s ease-out;
69
69
  }
70
- .Slider_thumbRecipe__t8kxxsi {
70
+ .Slider_thumbRecipe__t8kxxsh {
71
71
  position: absolute;
72
72
  top: 50%;
73
73
  left: var(--thumbPercentageVar__t8kxxs1);
@@ -77,38 +77,38 @@
77
77
  cursor: grab;
78
78
  box-shadow: var(--etui-shadow-sm);
79
79
  }
80
- .Slider_thumbRecipe__t8kxxsi:hover {
80
+ .Slider_thumbRecipe__t8kxxsh:hover {
81
81
  transform: translate(-50%, -50%) scale(1.1);
82
82
  box-shadow: var(--etui-shadow-md);
83
83
  }
84
- .Slider_thumbRecipe_size_sm__t8kxxsj {
84
+ .Slider_thumbRecipe_size_sm__t8kxxsi {
85
85
  width: 12px;
86
86
  height: 12px;
87
87
  }
88
- .Slider_thumbRecipe_size_md__t8kxxsk {
88
+ .Slider_thumbRecipe_size_md__t8kxxsj {
89
89
  width: 16px;
90
90
  height: 16px;
91
91
  }
92
- .Slider_thumbRecipe_size_lg__t8kxxsl {
92
+ .Slider_thumbRecipe_size_lg__t8kxxsk {
93
93
  width: 20px;
94
94
  height: 20px;
95
95
  }
96
- .Slider_thumbRecipe_error_true__t8kxxsm {
96
+ .Slider_thumbRecipe_error_true__t8kxxsl {
97
97
  background: var(--etui-color-accent-error);
98
98
  }
99
- .Slider_thumbRecipe_error_false__t8kxxsn {
99
+ .Slider_thumbRecipe_error_false__t8kxxsm {
100
100
  background: var(--etui-color-accent-primary);
101
101
  }
102
- .Slider_thumbRecipe_isDragging_true__t8kxxso {
102
+ .Slider_thumbRecipe_isDragging_true__t8kxxsn {
103
103
  cursor: grabbing;
104
104
  transform: translate(-50%, -50%) scale(1.15);
105
105
  box-shadow: var(--etui-shadow-lg);
106
106
  transition: none;
107
107
  }
108
- .Slider_thumbRecipe_isDragging_false__t8kxxsp {
108
+ .Slider_thumbRecipe_isDragging_false__t8kxxso {
109
109
  transition: all var(--etui-transition-fast);
110
110
  }
111
- .Slider_ticksStyle__t8kxxsq {
111
+ .Slider_ticksStyle__t8kxxsp {
112
112
  position: absolute;
113
113
  top: 100%;
114
114
  left: 0;
@@ -119,7 +119,7 @@
119
119
  align-items: flex-start;
120
120
  pointer-events: none;
121
121
  }
122
- .Slider_ticksStyle__t8kxxsq::before {
122
+ .Slider_ticksStyle__t8kxxsp::before {
123
123
  content: "";
124
124
  position: absolute;
125
125
  top: 2px;
@@ -128,17 +128,14 @@
128
128
  height: 1px;
129
129
  background: var(--etui-color-border-default);
130
130
  }
131
- .Slider_tickStyle__t8kxxsr {
131
+ .Slider_tickStyle__t8kxxsq {
132
132
  width: 1px;
133
133
  height: 4px;
134
134
  background: var(--etui-color-text-muted);
135
135
  margin-top: 2px;
136
136
  }
137
- .Slider_tooltipRecipe__t8kxxss {
138
- position: absolute;
139
- bottom: calc(100% + 8px);
140
- left: var(--tooltipPercentageVar__t8kxxs2);
141
- transform: translateX(-50%);
137
+ .Slider_sliderTooltipRecipe__t8kxxsr {
138
+ position: fixed;
142
139
  background: var(--etui-color-bg-elevated);
143
140
  color: var(--etui-color-text-primary);
144
141
  border: 1px solid var(--etui-color-border-default);
@@ -149,9 +146,11 @@
149
146
  white-space: nowrap;
150
147
  pointer-events: none;
151
148
  z-index: var(--etui-z-tooltip);
152
- transition: all var(--etui-transition-fast);
153
149
  }
154
- .Slider_tooltipRecipe__t8kxxss::after {
150
+ .Slider_sliderTooltipRecipe_placement_top__t8kxxss {
151
+ transform: translate(-50%, calc(-100% - 8px));
152
+ }
153
+ .Slider_sliderTooltipRecipe_placement_top__t8kxxss::after {
155
154
  content: "";
156
155
  position: absolute;
157
156
  top: 100%;
@@ -163,25 +162,29 @@
163
162
  border-right: 4px solid transparent;
164
163
  border-top: 4px solid var(--etui-color-border-default);
165
164
  }
166
- .Slider_tooltipRecipe_visible_true__t8kxxst {
167
- opacity: 1;
168
- transform: translateX(-50%) translateY(0);
165
+ .Slider_sliderTooltipRecipe_placement_bottom__t8kxxst {
166
+ transform: translate(-50%, 8px);
169
167
  }
170
- .Slider_tooltipRecipe_visible_false__t8kxxsu {
171
- opacity: 0;
172
- transform: translateX(-50%) translateY(4px);
168
+ .Slider_sliderTooltipRecipe_placement_bottom__t8kxxst::after {
169
+ content: "";
170
+ position: absolute;
171
+ bottom: 100%;
172
+ left: 50%;
173
+ transform: translateX(-50%);
174
+ width: 0;
175
+ height: 0;
176
+ border-left: 4px solid transparent;
177
+ border-right: 4px solid transparent;
178
+ border-bottom: 4px solid var(--etui-color-border-default);
173
179
  }
174
180
  @media (prefers-reduced-motion: reduce) {
175
- .Slider_thumbRecipe__t8kxxsi {
181
+ .Slider_thumbRecipe__t8kxxsh {
176
182
  transition: none;
177
183
  }
178
- .Slider_thumbRecipe__t8kxxsi:hover {
184
+ .Slider_thumbRecipe__t8kxxsh:hover {
179
185
  transform: translate(-50%, -50%);
180
186
  }
181
- .Slider_thumbRecipe_isDragging_false__t8kxxsp {
182
- transition: none;
183
- }
184
- .Slider_tooltipRecipe__t8kxxss {
187
+ .Slider_thumbRecipe_isDragging_false__t8kxxso {
185
188
  transition: none;
186
189
  }
187
190
  }
@@ -1,4 +1,7 @@
1
- .Menu_menuContentStyle__1pkkb710 {
1
+ .Menu_menuPositionerStyle__1pkkb710 {
2
+ z-index: var(--etui-z-dropdown);
3
+ }
4
+ .Menu_menuContentStyle__1pkkb711 {
2
5
  min-width: 200px;
3
6
  max-width: 360px;
4
7
  background: var(--etui-color-bg-elevated);
@@ -13,11 +16,11 @@
13
16
  transform-origin: var(--transform-origin);
14
17
  transition: opacity var(--etui-transition-fast), transform var(--etui-transition-fast);
15
18
  }
16
- .Menu_menuContentStyle__1pkkb710[data-starting-style], .Menu_menuContentStyle__1pkkb710[data-ending-style] {
19
+ .Menu_menuContentStyle__1pkkb711[data-starting-style], .Menu_menuContentStyle__1pkkb711[data-ending-style] {
17
20
  opacity: 0;
18
21
  transform: scale(0.96);
19
22
  }
20
- .Menu_menuItemStyle__1pkkb711 {
23
+ .Menu_menuItemStyle__1pkkb712 {
21
24
  display: flex;
22
25
  align-items: center;
23
26
  gap: var(--etui-spacing-sm);
@@ -33,15 +36,15 @@
33
36
  font-size: var(--etui-font-size-md);
34
37
  font-family: var(--etui-font-family-sans);
35
38
  }
36
- .Menu_menuItemStyle__1pkkb711[data-highlighted] {
39
+ .Menu_menuItemStyle__1pkkb712[data-highlighted] {
37
40
  background: var(--etui-color-surface-hover);
38
41
  }
39
- .Menu_menuItemStyle__1pkkb711[data-disabled] {
42
+ .Menu_menuItemStyle__1pkkb712[data-disabled] {
40
43
  color: var(--etui-color-text-disabled);
41
44
  cursor: not-allowed;
42
45
  pointer-events: none;
43
46
  }
44
- .Menu_itemStartSlotStyle__1pkkb712 {
47
+ .Menu_itemStartSlotStyle__1pkkb713 {
45
48
  display: inline-flex;
46
49
  align-items: center;
47
50
  justify-content: center;
@@ -50,14 +53,14 @@
50
53
  flex-shrink: 0;
51
54
  color: var(--etui-color-text-secondary);
52
55
  }
53
- .Menu_itemLabelStyle__1pkkb713 {
56
+ .Menu_itemLabelStyle__1pkkb714 {
54
57
  flex: 1;
55
58
  min-width: 0;
56
59
  overflow: hidden;
57
60
  text-overflow: ellipsis;
58
61
  white-space: nowrap;
59
62
  }
60
- .Menu_itemEndSlotStyle__1pkkb714 {
63
+ .Menu_itemEndSlotStyle__1pkkb715 {
61
64
  display: inline-flex;
62
65
  align-items: center;
63
66
  gap: var(--etui-spacing-xs);
@@ -66,13 +69,13 @@
66
69
  flex-shrink: 0;
67
70
  color: var(--etui-color-text-muted);
68
71
  }
69
- .Menu_shortcutStyle__1pkkb715 {
72
+ .Menu_shortcutStyle__1pkkb716 {
70
73
  font-size: var(--etui-font-size-xs);
71
74
  color: var(--etui-color-text-muted);
72
75
  letter-spacing: 0.03em;
73
76
  white-space: nowrap;
74
77
  }
75
- .Menu_groupLabelStyle__1pkkb716 {
78
+ .Menu_groupLabelStyle__1pkkb717 {
76
79
  display: block;
77
80
  padding: var(--etui-spacing-xs) var(--etui-spacing-sm);
78
81
  font-size: var(--etui-font-size-xs);
@@ -81,7 +84,7 @@
81
84
  font-family: var(--etui-font-family-sans);
82
85
  color: var(--etui-color-text-muted);
83
86
  }
84
- .Menu_separatorStyle__1pkkb717 {
87
+ .Menu_separatorStyle__1pkkb718 {
85
88
  margin: var(--etui-spacing-xs) 0;
86
89
  border-top: 1px solid var(--etui-color-border-default);
87
90
  height: 0;
@@ -24,7 +24,10 @@
24
24
  opacity: 0;
25
25
  transform: scale(0.96);
26
26
  }
27
- .Tooltip_tooltipTriggerStyle__u81kis1 {
27
+ .Tooltip_tooltipPositionerStyle__u81kis1 {
28
+ z-index: var(--etui-z-tooltip);
29
+ }
30
+ .Tooltip_tooltipTriggerStyle__u81kis2 {
28
31
  display: inline-block;
29
32
  cursor: pointer;
30
33
  width: fit-content;
@@ -33,17 +36,17 @@
33
36
  z-index: 1;
34
37
  pointer-events: none;
35
38
  }
36
- .Tooltip_tooltipTriggerStyle__u81kis1:focus {
39
+ .Tooltip_tooltipTriggerStyle__u81kis2:focus {
37
40
  outline: none;
38
41
  box-shadow: var(--etui-shadow-focus);
39
42
  }
40
- .Tooltip_tooltipTriggerStyle__u81kis1 > * {
43
+ .Tooltip_tooltipTriggerStyle__u81kis2 > * {
41
44
  pointer-events: auto;
42
45
  }
43
- .Tooltip_arrowFillStyle__u81kis2 {
46
+ .Tooltip_arrowFillStyle__u81kis3 {
44
47
  fill: var(--etui-color-bg-elevated);
45
48
  }
46
- .Tooltip_tooltipArrowStyle__u81kis3 {
49
+ .Tooltip_tooltipArrowStyle__u81kis4 {
47
50
  display: flex;
48
51
  transform-style: preserve-3d;
49
52
  backface-visibility: hidden;
@@ -53,19 +56,19 @@
53
56
  -moz-osx-font-smoothing: grayscale;
54
57
  will-change: transform;
55
58
  }
56
- .Tooltip_tooltipArrowStyle__u81kis3[data-side="top"] {
59
+ .Tooltip_tooltipArrowStyle__u81kis4[data-side="top"] {
57
60
  bottom: -8px;
58
61
  rotate: 180deg;
59
62
  }
60
- .Tooltip_tooltipArrowStyle__u81kis3[data-side="bottom"] {
63
+ .Tooltip_tooltipArrowStyle__u81kis4[data-side="bottom"] {
61
64
  top: -8px;
62
65
  rotate: 0deg;
63
66
  }
64
- .Tooltip_tooltipArrowStyle__u81kis3[data-side="left"] {
67
+ .Tooltip_tooltipArrowStyle__u81kis4[data-side="left"] {
65
68
  right: -13px;
66
69
  rotate: 90deg;
67
70
  }
68
- .Tooltip_tooltipArrowStyle__u81kis3[data-side="right"] {
71
+ .Tooltip_tooltipArrowStyle__u81kis4[data-side="right"] {
69
72
  left: -13px;
70
73
  rotate: -90deg;
71
74
  }
@@ -32,6 +32,7 @@ html:has(.AppShell_viewportLockClass__1m62ws20) body {
32
32
  }
33
33
  .AppShell_menuBarSlot__1m62ws22 {
34
34
  grid-area: menubar;
35
+ background: var(--etui-shell-menubar-bg);
35
36
  }
36
37
  .AppShell_toolbarTopSlot__1m62ws23 {
37
38
  grid-area: toolbar-top;
@@ -8,6 +8,7 @@
8
8
  padding: 0 var(--etui-spacing-sm);
9
9
  user-select: none;
10
10
  flex-shrink: 0;
11
+ width: 100%;
11
12
  }
12
13
  .MenuBar_menuBarRoot_size_sm__1h81mxv1 {
13
14
  height: 24px;
@@ -17,13 +18,15 @@
17
18
  }
18
19
  .MenuBar_menuContainer__1h81mxv3 {
19
20
  position: relative;
21
+ display: flex;
22
+ align-items: center;
20
23
  height: 100%;
21
24
  }
22
25
  .MenuBar_trigger__1h81mxv4 {
23
26
  display: inline-flex;
24
27
  align-items: center;
25
- height: 100%;
26
- padding: 0 var(--etui-spacing-md);
28
+ padding: var(--etui-spacing-xs) var(--etui-spacing-md);
29
+ border-radius: var(--etui-radius-sm);
27
30
  border: none;
28
31
  color: inherit;
29
32
  font: inherit;
@@ -95,15 +98,24 @@
95
98
  color: var(--etui-shell-menubar-shortcut-text);
96
99
  font-size: var(--etui-font-size-xs);
97
100
  }
98
- .MenuBar_separator__1h81mxva {
101
+ .MenuBar_indicatorSlot__1h81mxva {
102
+ display: inline-flex;
103
+ align-items: center;
104
+ justify-content: center;
105
+ width: 16px;
106
+ height: 16px;
107
+ flex-shrink: 0;
108
+ color: var(--etui-color-text-secondary);
109
+ }
110
+ .MenuBar_separator__1h81mxvb {
99
111
  height: 1px;
100
112
  margin: var(--etui-spacing-xs) 0;
101
113
  background: var(--etui-color-border-default);
102
114
  }
103
- .MenuBar_subTrigger__1h81mxvb {
115
+ .MenuBar_subTrigger__1h81mxvc {
104
116
  justify-content: space-between;
105
117
  }
106
- .MenuBar_subDropdown__1h81mxvc {
118
+ .MenuBar_subDropdown__1h81mxvd {
107
119
  position: absolute;
108
120
  top: calc(-1 * var(--etui-spacing-xs));
109
121
  left: 100%;
@@ -115,6 +127,6 @@
115
127
  padding: var(--etui-spacing-xs) 0;
116
128
  z-index: calc(var(--etui-z-dropdown) + 1);
117
129
  }
118
- .MenuBar_subContainer__1h81mxvd {
130
+ .MenuBar_subContainer__1h81mxve {
119
131
  position: relative;
120
132
  }
@@ -1,17 +1,16 @@
1
- import './../../../assets/src/components/controls/Slider/Slider.css.ts.vanilla-Cqm3fQ0S.css';
1
+ import './../../../assets/src/components/controls/Slider/Slider.css.ts.vanilla-CLf_RC0A.css';
2
2
  import { createRuntimeFn } from '@vanilla-extract/recipes/createRuntimeFn';
3
3
 
4
4
  var fillPercentageVar = 'var(--fillPercentageVar__t8kxxs0)';
5
- var fillRecipe = createRuntimeFn({defaultClassName:'Slider_fillRecipe__t8kxxsd',variantClassNames:{error:{true:'Slider_fillRecipe_error_true__t8kxxse',false:'Slider_fillRecipe_error_false__t8kxxsf'},isDragging:{true:'Slider_fillRecipe_isDragging_true__t8kxxsg',false:'Slider_fillRecipe_isDragging_false__t8kxxsh'}},defaultVariants:{error:false,isDragging:false},compoundVariants:[]});
6
- var sliderContainerRecipe = createRuntimeFn({defaultClassName:'Slider_sliderContainerRecipe__t8kxxs3',variantClassNames:{disabled:{true:'Slider_sliderContainerRecipe_disabled_true__t8kxxs4',false:'Slider_sliderContainerRecipe_disabled_false__t8kxxs5'}},defaultVariants:{disabled:false},compoundVariants:[]});
7
- var sliderWrapperStyle = 'Slider_sliderWrapperStyle__t8kxxs6';
5
+ var fillRecipe = createRuntimeFn({defaultClassName:'Slider_fillRecipe__t8kxxsc',variantClassNames:{error:{true:'Slider_fillRecipe_error_true__t8kxxsd',false:'Slider_fillRecipe_error_false__t8kxxse'},isDragging:{true:'Slider_fillRecipe_isDragging_true__t8kxxsf',false:'Slider_fillRecipe_isDragging_false__t8kxxsg'}},defaultVariants:{error:false,isDragging:false},compoundVariants:[]});
6
+ var sliderContainerRecipe = createRuntimeFn({defaultClassName:'Slider_sliderContainerRecipe__t8kxxs2',variantClassNames:{disabled:{true:'Slider_sliderContainerRecipe_disabled_true__t8kxxs3',false:'Slider_sliderContainerRecipe_disabled_false__t8kxxs4'}},defaultVariants:{disabled:false},compoundVariants:[]});
7
+ var sliderTooltipRecipe = createRuntimeFn({defaultClassName:'Slider_sliderTooltipRecipe__t8kxxsr',variantClassNames:{placement:{top:'Slider_sliderTooltipRecipe_placement_top__t8kxxss',bottom:'Slider_sliderTooltipRecipe_placement_bottom__t8kxxst'}},defaultVariants:{placement:'top'},compoundVariants:[]});
8
+ var sliderWrapperStyle = 'Slider_sliderWrapperStyle__t8kxxs5';
8
9
  var thumbPercentageVar = 'var(--thumbPercentageVar__t8kxxs1)';
9
- var thumbRecipe = createRuntimeFn({defaultClassName:'Slider_thumbRecipe__t8kxxsi',variantClassNames:{size:{sm:'Slider_thumbRecipe_size_sm__t8kxxsj',md:'Slider_thumbRecipe_size_md__t8kxxsk',lg:'Slider_thumbRecipe_size_lg__t8kxxsl'},error:{true:'Slider_thumbRecipe_error_true__t8kxxsm',false:'Slider_thumbRecipe_error_false__t8kxxsn'},isDragging:{true:'Slider_thumbRecipe_isDragging_true__t8kxxso',false:'Slider_thumbRecipe_isDragging_false__t8kxxsp'}},defaultVariants:{size:'md',error:false,isDragging:false},compoundVariants:[]});
10
- var tickStyle = 'Slider_tickStyle__t8kxxsr';
11
- var ticksStyle = 'Slider_ticksStyle__t8kxxsq';
12
- var tooltipPercentageVar = 'var(--tooltipPercentageVar__t8kxxs2)';
13
- var tooltipRecipe = createRuntimeFn({defaultClassName:'Slider_tooltipRecipe__t8kxxss',variantClassNames:{visible:{true:'Slider_tooltipRecipe_visible_true__t8kxxst',false:'Slider_tooltipRecipe_visible_false__t8kxxsu'}},defaultVariants:{visible:false},compoundVariants:[]});
14
- var trackRecipe = createRuntimeFn({defaultClassName:'Slider_trackRecipe__t8kxxs7',variantClassNames:{size:{sm:'Slider_trackRecipe_size_sm__t8kxxs8',md:'Slider_trackRecipe_size_md__t8kxxs9',lg:'Slider_trackRecipe_size_lg__t8kxxsa'},error:{true:'Slider_trackRecipe_error_true__t8kxxsb',false:'Slider_trackRecipe_error_false__t8kxxsc'}},defaultVariants:{size:'md',error:false},compoundVariants:[]});
10
+ var thumbRecipe = createRuntimeFn({defaultClassName:'Slider_thumbRecipe__t8kxxsh',variantClassNames:{size:{sm:'Slider_thumbRecipe_size_sm__t8kxxsi',md:'Slider_thumbRecipe_size_md__t8kxxsj',lg:'Slider_thumbRecipe_size_lg__t8kxxsk'},error:{true:'Slider_thumbRecipe_error_true__t8kxxsl',false:'Slider_thumbRecipe_error_false__t8kxxsm'},isDragging:{true:'Slider_thumbRecipe_isDragging_true__t8kxxsn',false:'Slider_thumbRecipe_isDragging_false__t8kxxso'}},defaultVariants:{size:'md',error:false,isDragging:false},compoundVariants:[]});
11
+ var tickStyle = 'Slider_tickStyle__t8kxxsq';
12
+ var ticksStyle = 'Slider_ticksStyle__t8kxxsp';
13
+ var trackRecipe = createRuntimeFn({defaultClassName:'Slider_trackRecipe__t8kxxs6',variantClassNames:{size:{sm:'Slider_trackRecipe_size_sm__t8kxxs7',md:'Slider_trackRecipe_size_md__t8kxxs8',lg:'Slider_trackRecipe_size_lg__t8kxxs9'},error:{true:'Slider_trackRecipe_error_true__t8kxxsa',false:'Slider_trackRecipe_error_false__t8kxxsb'}},defaultVariants:{size:'md',error:false},compoundVariants:[]});
15
14
 
16
- export { fillPercentageVar, fillRecipe, sliderContainerRecipe, sliderWrapperStyle, thumbPercentageVar, thumbRecipe, tickStyle, ticksStyle, tooltipPercentageVar, tooltipRecipe, trackRecipe };
15
+ export { fillPercentageVar, fillRecipe, sliderContainerRecipe, sliderTooltipRecipe, sliderWrapperStyle, thumbPercentageVar, thumbRecipe, tickStyle, ticksStyle, trackRecipe };
17
16
  //# sourceMappingURL=Slider.css.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Slider.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"Slider.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;"}
@@ -2,12 +2,13 @@
2
2
  import { jsxs, jsx } from 'react/jsx-runtime';
3
3
  import { assignInlineVars } from '@vanilla-extract/dynamic';
4
4
  import React, { useState, useRef, useCallback, useEffect } from 'react';
5
+ import { createPortal } from 'react-dom';
5
6
  import { FormHelperText } from '../../form/FormHelperText.js';
6
7
  import { FormLabel } from '../../form/FormLabel.js';
7
8
  import { InputWrapper } from '../../form/InputWrapper.js';
8
9
  import { useKeyboardContext } from '../../../context/KeyboardContext.js';
9
10
  import { cx } from '../../../utils/cx.js';
10
- import { sliderWrapperStyle, fillPercentageVar, fillRecipe, trackRecipe, thumbPercentageVar, thumbRecipe, ticksStyle, tickStyle, tooltipPercentageVar, tooltipRecipe, sliderContainerRecipe } from './Slider.css.js';
11
+ import { sliderWrapperStyle, fillPercentageVar, fillRecipe, trackRecipe, thumbPercentageVar, thumbRecipe, ticksStyle, tickStyle, sliderTooltipRecipe, sliderContainerRecipe } from './Slider.css.js';
11
12
 
12
13
  /**
13
14
  * Clamps a value between min and max bounds
@@ -73,10 +74,13 @@ function roundToPrecision(value, precision) {
73
74
  * />
74
75
  * ```
75
76
  */
76
- const Slider = ({ value, onChange, min = 0, max = 100, step = 1, precisionStep, largeStep, precision = 2, size = 'md', disabled = false, readOnly = false, label, helperText, errorMessage, error = false, required = false, unit, formatValue, showTooltip = true, showTicks = false, tickCount = 5, className, testId, onFocus, onBlur, onKeyDown, ref, ...props }) => {
77
+ const Slider = ({ value, onChange, min = 0, max = 100, step = 1, precisionStep, largeStep, precision = 2, size = 'md', disabled = false, readOnly = false, label, helperText, errorMessage, error = false, required = false, unit, formatValue, showTooltip = true, tooltipPlacement = 'top', showTicks = false, tickCount = 5, className, testId, onFocus, onBlur, onKeyDown, ref, ...props }) => {
77
78
  const [isDragging, setIsDragging] = useState(false);
78
79
  const [isFocused, setIsFocused] = useState(false);
79
80
  const [showTooltipState, setShowTooltipState] = useState(false);
81
+ // Viewport coordinates of the portaled value tooltip (null until a drag
82
+ // starts). Updated only while dragging so the portal stays off the idle path.
83
+ const [tooltipPos, setTooltipPos] = useState(null);
80
84
  const sliderRef = useRef(null);
81
85
  const trackRef = useRef(null);
82
86
  const dragStartRef = useRef(null);
@@ -135,6 +139,22 @@ const Slider = ({ value, onChange, min = 0, max = 100, step = 1, precisionStep,
135
139
  const steps = Math.round((newValue - min) / currentStep);
136
140
  return min + steps * currentStep;
137
141
  }, [min, max, value, getStepSize]);
142
+ /**
143
+ * Computes the portaled tooltip's viewport position for a (snapped) value,
144
+ * anchored to the thumb. Reads the same track rect the drag math already
145
+ * reads, so it adds no extra layout pass per frame.
146
+ */
147
+ const updateTooltipPos = useCallback((v) => {
148
+ const track = trackRef.current;
149
+ if (!track)
150
+ return;
151
+ const rect = track.getBoundingClientRect();
152
+ const pct = clamp((v - min) / (max - min), 0, 1);
153
+ setTooltipPos({
154
+ left: rect.left + pct * rect.width,
155
+ top: tooltipPlacement === 'bottom' ? rect.bottom : rect.top,
156
+ });
157
+ }, [min, max, tooltipPlacement]);
138
158
  /**
139
159
  * Handle mouse down on track or thumb
140
160
  */
@@ -147,11 +167,20 @@ const Slider = ({ value, onChange, min = 0, max = 100, step = 1, precisionStep,
147
167
  // Use the current step size (depends on keyboard modifiers)
148
168
  const newValue = positionToValue(event.clientX);
149
169
  applyValue(newValue);
170
+ if (showTooltip)
171
+ updateTooltipPos(newValue);
150
172
  dragStartRef.current = {
151
173
  startX: event.clientX,
152
174
  startValue: newValue,
153
175
  };
154
- }, [disabled, readOnly, positionToValue, applyValue, showTooltip]);
176
+ }, [
177
+ disabled,
178
+ readOnly,
179
+ positionToValue,
180
+ applyValue,
181
+ showTooltip,
182
+ updateTooltipPos,
183
+ ]);
155
184
  /**
156
185
  * Handle global mouse move during drag
157
186
  */
@@ -163,8 +192,10 @@ const Slider = ({ value, onChange, min = 0, max = 100, step = 1, precisionStep,
163
192
  // Use the current step size (depends on keyboard modifiers)
164
193
  const newValue = positionToValue(event.clientX);
165
194
  applyValue(newValue);
195
+ if (showTooltip)
196
+ updateTooltipPos(newValue);
166
197
  });
167
- }, [isDragging, positionToValue, applyValue]);
198
+ }, [isDragging, positionToValue, applyValue, showTooltip, updateTooltipPos]);
168
199
  /**
169
200
  * Handle global mouse up to end drag
170
201
  */
@@ -254,9 +285,11 @@ const Slider = ({ value, onChange, min = 0, max = 100, step = 1, precisionStep,
254
285
  [fillPercentageVar]: `${percentage}%`,
255
286
  }) }) }), jsx("div", { className: thumbRecipe({ size, error, isDragging }), style: assignInlineVars({
256
287
  [thumbPercentageVar]: `${percentage}%`,
257
- }) }), showTicks && (jsx("div", { className: ticksStyle, children: ticks.map(i => (jsx("div", { className: tickStyle }, i))) })), showTooltip && (jsx("div", { className: tooltipRecipe({ visible: showTooltipState }), style: assignInlineVars({
258
- [tooltipPercentageVar]: `${percentage}%`,
259
- }), children: displayValue }))] }) }), (helperText ?? (error && errorMessage)) && (jsx(FormHelperText, { error: error, children: error && errorMessage ? errorMessage : helperText }))] }));
288
+ }) }), showTicks && (jsx("div", { className: ticksStyle, children: ticks.map(i => (jsx("div", { className: tickStyle }, i))) })), showTooltip &&
289
+ showTooltipState &&
290
+ tooltipPos &&
291
+ typeof document !== 'undefined' &&
292
+ createPortal(jsx("div", { className: sliderTooltipRecipe({ placement: tooltipPlacement }), style: { left: tooltipPos.left, top: tooltipPos.top }, role: "presentation", "data-testid": testId ? `${testId}-tooltip` : undefined, children: displayValue }), document.body)] }) }), (helperText ?? (error && errorMessage)) && (jsx(FormHelperText, { error: error, children: error && errorMessage ? errorMessage : helperText }))] }));
260
293
  };
261
294
  Slider.displayName = 'Slider';
262
295