@ixfx/components 0.9.7 → 0.10.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 (155) hide show
  1. package/bundle/index.d.ts +839 -68
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +16398 -13118
  4. package/bundle/index.js.map +1 -1
  5. package/bundle/style.css +2 -2
  6. package/dist/ac-text.d.ts +1 -1
  7. package/dist/ac-text.js +2 -2
  8. package/dist/{ac-token-TCLAZeVg.d.ts → ac-token--_vCHXWw.d.ts} +2 -2
  9. package/dist/{ac-token-TCLAZeVg.d.ts.map → ac-token--_vCHXWw.d.ts.map} +1 -1
  10. package/dist/ac-token.d.ts +1 -1
  11. package/dist/ac-token.js +2 -2
  12. package/dist/button.d.ts +1 -1
  13. package/dist/button.d.ts.map +1 -1
  14. package/dist/checkbox.js +1 -1
  15. package/dist/{colour-picker-CSxwUmtE.js → colour-picker-R73i0QTP.js} +2 -2
  16. package/dist/{colour-picker-CSxwUmtE.js.map → colour-picker-R73i0QTP.js.map} +1 -1
  17. package/dist/colour-picker.d.ts +1 -1
  18. package/dist/colour-picker.js +1 -1
  19. package/dist/crumbs.d.ts +2 -2
  20. package/dist/crumbs.js +2 -2
  21. package/dist/data-display.js +1 -1
  22. package/dist/{data-grid-8N0Kd5-6.d.ts → data-grid-C5hk_pzK.d.ts} +34 -4
  23. package/dist/data-grid-C5hk_pzK.d.ts.map +1 -0
  24. package/dist/data-grid.d.ts +2 -2
  25. package/dist/data-grid.js +126 -18
  26. package/dist/data-grid.js.map +1 -1
  27. package/dist/{detail-list-CQguZg9h.d.ts → detail-list-CxPpv89T.d.ts} +6 -5
  28. package/dist/detail-list-CxPpv89T.d.ts.map +1 -0
  29. package/dist/detail-list.d.ts +3 -3
  30. package/dist/detail-list.js +5 -3
  31. package/dist/detail-list.js.map +1 -1
  32. package/dist/editable-label.js +1 -1
  33. package/dist/{fallbacks-BcKGq-2F.js → fallbacks-DQ_5OsmR.js} +2 -2
  34. package/dist/{fallbacks-BcKGq-2F.js.map → fallbacks-DQ_5OsmR.js.map} +1 -1
  35. package/dist/{grid-list-CSw1VMXT.d.ts → grid-list-BGvoWbZz.d.ts} +30 -69
  36. package/dist/grid-list-BGvoWbZz.d.ts.map +1 -0
  37. package/dist/{grid-list-mL0GJTQR.js → grid-list-DSnYOGh7.js} +64 -233
  38. package/dist/grid-list-DSnYOGh7.js.map +1 -0
  39. package/dist/grid-list.d.ts +2 -2
  40. package/dist/grid-list.js +1 -1
  41. package/dist/{grouped-item-lister-CEZ72VOs.d.ts → grouped-item-lister-fdZHVxFM.d.ts} +2 -2
  42. package/dist/{grouped-item-lister-CEZ72VOs.d.ts.map → grouped-item-lister-fdZHVxFM.d.ts.map} +1 -1
  43. package/dist/grouped-item-lister.d.ts +1 -1
  44. package/dist/{icon-Dy33gu4Z.js → icon-BCJJYEpm.js} +2 -2
  45. package/dist/{icon-Dy33gu4Z.js.map → icon-BCJJYEpm.js.map} +1 -1
  46. package/dist/{icon-DR_3rSyZ.d.ts → icon-CDGprSdE.d.ts} +2 -2
  47. package/dist/icon-CDGprSdE.d.ts.map +1 -0
  48. package/dist/icons.d.ts +2 -2
  49. package/dist/icons.js +1 -1
  50. package/dist/incr-search.d.ts +1 -1
  51. package/dist/{index--qnhBWZJ.d.ts → index--5BSdbnL.d.ts} +2 -2
  52. package/dist/{index--qnhBWZJ.d.ts.map → index--5BSdbnL.d.ts.map} +1 -1
  53. package/dist/{index-C59-JEPl.d.ts → index-9AhaHIT2.d.ts} +3 -3
  54. package/dist/{index-C59-JEPl.d.ts.map → index-9AhaHIT2.d.ts.map} +1 -1
  55. package/dist/{index-DsjpDksO.d.ts → index-CS9yM8L-.d.ts} +2 -2
  56. package/dist/{index-DsjpDksO.d.ts.map → index-CS9yM8L-.d.ts.map} +1 -1
  57. package/dist/{index-BUB5SICW.d.ts → index-CoqtMSd9.d.ts} +2 -2
  58. package/dist/{index-BUB5SICW.d.ts.map → index-CoqtMSd9.d.ts.map} +1 -1
  59. package/dist/{index-CJ5fshD3.d.ts → index-UvnoZUAo.d.ts} +2 -2
  60. package/dist/{index-CJ5fshD3.d.ts.map → index-UvnoZUAo.d.ts.map} +1 -1
  61. package/dist/{index-BOUaDIW-.d.ts → index-tq6f8007.d.ts} +2 -2
  62. package/dist/{index-BOUaDIW-.d.ts.map → index-tq6f8007.d.ts.map} +1 -1
  63. package/dist/index.d.ts +648 -22
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +4815 -2323
  66. package/dist/index.js.map +1 -1
  67. package/dist/{labelled-input-base-Dp_9KP0G.d.ts → labelled-input-base-DiTme1JO.d.ts} +2 -2
  68. package/dist/{labelled-input-base-Dp_9KP0G.d.ts.map → labelled-input-base-DiTme1JO.d.ts.map} +1 -1
  69. package/dist/labelled-radial-input.d.ts +2 -2
  70. package/dist/labelled-radial-input.d.ts.map +1 -1
  71. package/dist/labelled-radial-input.js +2 -2
  72. package/dist/labelled-range-input.d.ts +1 -1
  73. package/dist/{labelled-slider-input-aEYDvW2S.js → labelled-slider-input-CF2RtzgG.js} +3 -3
  74. package/dist/{labelled-slider-input-aEYDvW2S.js.map → labelled-slider-input-CF2RtzgG.js.map} +1 -1
  75. package/dist/labelled-slider-input.d.ts +1 -1
  76. package/dist/labelled-slider-input.js +1 -1
  77. package/dist/{list-native-drag-controller-B0hWdbtM.js → list-native-drag-controller-D97TYjn1.js} +36 -5
  78. package/dist/list-native-drag-controller-D97TYjn1.js.map +1 -0
  79. package/dist/{list-native-drag-controller-Cmpx7jnx.d.ts → list-native-drag-controller-DWiXQZou.d.ts} +3 -2
  80. package/dist/list-native-drag-controller-DWiXQZou.d.ts.map +1 -0
  81. package/dist/{menu-CMXhIaNZ.js → menu-C8a-84S5.js} +4 -4
  82. package/dist/{menu-CMXhIaNZ.js.map → menu-C8a-84S5.js.map} +1 -1
  83. package/dist/{menu-item-ZmkXNjek.d.ts → menu-item-CZi9vy5O.d.ts} +2 -2
  84. package/dist/{menu-item-ZmkXNjek.d.ts.map → menu-item-CZi9vy5O.d.ts.map} +1 -1
  85. package/dist/{menu-item-BYGQzyCe.js → menu-item-DzizkMH-.js} +3 -3
  86. package/dist/{menu-item-BYGQzyCe.js.map → menu-item-DzizkMH-.js.map} +1 -1
  87. package/dist/menu.d.ts +2 -2
  88. package/dist/menu.js +2 -2
  89. package/dist/miller.d.ts +2 -2
  90. package/dist/miller.js +1 -1
  91. package/dist/narrowed-text.js +1 -1
  92. package/dist/notifier.js +1 -1
  93. package/dist/pan-text-CoYmt2qd.d.ts +67 -0
  94. package/dist/pan-text-CoYmt2qd.d.ts.map +1 -0
  95. package/dist/pan-text-CqtvjPyK.js +235 -0
  96. package/dist/pan-text-CqtvjPyK.js.map +1 -0
  97. package/dist/panel.d.ts +1 -1
  98. package/dist/panel.js +1 -1
  99. package/dist/polar-pad.js +1 -1
  100. package/dist/{radial-input-DyxfbNzD.js → radial-input-KMVltQfe.js} +2 -2
  101. package/dist/{radial-input-DyxfbNzD.js.map → radial-input-KMVltQfe.js.map} +1 -1
  102. package/dist/radial-input.js +1 -1
  103. package/dist/range-input.js +1 -1
  104. package/dist/range.js +1 -1
  105. package/dist/select-horiz.js +1 -1
  106. package/dist/{slider-input-Cb5uSV42.js → slider-input-ByHdotzp.js} +2 -2
  107. package/dist/{slider-input-Cb5uSV42.js.map → slider-input-ByHdotzp.js.map} +1 -1
  108. package/dist/slider-input.js +1 -1
  109. package/dist/snackbar.js +1 -1
  110. package/dist/{split-layout-Bx0g8k8-.js → split-layout-3yBOEVZW.js} +2 -2
  111. package/dist/{split-layout-Bx0g8k8-.js.map → split-layout-3yBOEVZW.js.map} +1 -1
  112. package/dist/{split-layout-C5SYbDrq.d.ts → split-layout-JK3xWVX2.d.ts} +2 -2
  113. package/dist/{split-layout-C5SYbDrq.d.ts.map → split-layout-JK3xWVX2.d.ts.map} +1 -1
  114. package/dist/split-layout.d.ts +1 -1
  115. package/dist/split-layout.js +1 -1
  116. package/dist/style.css +2 -2
  117. package/dist/swipe.js +1 -1
  118. package/dist/{tab-list-DbMIL520.d.ts → tab-list-CGyPt07Z.d.ts} +2 -2
  119. package/dist/{tab-list-DbMIL520.d.ts.map → tab-list-CGyPt07Z.d.ts.map} +1 -1
  120. package/dist/tabs.d.ts +1 -1
  121. package/dist/tabs.js +1 -1
  122. package/dist/{timeline-THyvH8xy.js → timeline-CFlBFFGZ.js} +2 -2
  123. package/dist/{timeline-THyvH8xy.js.map → timeline-CFlBFFGZ.js.map} +1 -1
  124. package/dist/timeline.js +1 -1
  125. package/dist/{titlebar-B5zSTZnF.d.ts → titlebar-Tqu-VvMU.d.ts} +2 -2
  126. package/dist/{titlebar-B5zSTZnF.d.ts.map → titlebar-Tqu-VvMU.d.ts.map} +1 -1
  127. package/dist/titlebar.d.ts +1 -1
  128. package/dist/titlebar.js +2 -2
  129. package/dist/{tree-DAFBO_MF.js → tree-C25xYUa6.js} +5 -3
  130. package/dist/tree-C25xYUa6.js.map +1 -0
  131. package/dist/{tree-component-BW2iCFq9.d.ts → tree-component-mw8x-n2Y.d.ts} +4 -2
  132. package/dist/tree-component-mw8x-n2Y.d.ts.map +1 -0
  133. package/dist/tree.d.ts +4 -3
  134. package/dist/tree.d.ts.map +1 -1
  135. package/dist/tree.js +1 -1
  136. package/dist/{vertical-list-CHrXmmQ3.d.ts → vertical-list--tFanQwM.d.ts} +92 -4
  137. package/dist/vertical-list--tFanQwM.d.ts.map +1 -0
  138. package/dist/vertical-list.d.ts +2 -2
  139. package/dist/vertical-list.js +618 -29
  140. package/dist/vertical-list.js.map +1 -1
  141. package/dist/xy-pad.js +1 -1
  142. package/docs-user/data-grid.md +59 -0
  143. package/docs-user/grid-list.md +14 -0
  144. package/docs-user/index.json +2 -2
  145. package/package.json +1 -1
  146. package/dist/data-grid-8N0Kd5-6.d.ts.map +0 -1
  147. package/dist/detail-list-CQguZg9h.d.ts.map +0 -1
  148. package/dist/grid-list-CSw1VMXT.d.ts.map +0 -1
  149. package/dist/grid-list-mL0GJTQR.js.map +0 -1
  150. package/dist/icon-DR_3rSyZ.d.ts.map +0 -1
  151. package/dist/list-native-drag-controller-B0hWdbtM.js.map +0 -1
  152. package/dist/list-native-drag-controller-Cmpx7jnx.d.ts.map +0 -1
  153. package/dist/tree-DAFBO_MF.js.map +0 -1
  154. package/dist/tree-component-BW2iCFq9.d.ts.map +0 -1
  155. package/dist/vertical-list-CHrXmmQ3.d.ts.map +0 -1
@@ -0,0 +1,235 @@
1
+ import { t as themeFallbacks } from "./fallbacks-DQ_5OsmR.js";
2
+ import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
3
+ import { LitElement, css, html } from "lit";
4
+ import { property, query, state } from "lit/decorators.js";
5
+ import { classMap } from "lit/directives/class-map.js";
6
+ //#region src/pan-text/pan-text.ts
7
+ const SPEED = 45;
8
+ const END_PADDING = 4;
9
+ const START_DELAY = 300;
10
+ const END_DWELL = 2e3;
11
+ const RESET_DURATION = 400;
12
+ const PAN_EASING = `cubic-bezier(0.25, 0.46, 0.45, 0.94)`;
13
+ let PanTextElement = class PanTextElement extends LitElement {
14
+ constructor(..._args) {
15
+ super(..._args);
16
+ this.direction = `end`;
17
+ this.disabled = false;
18
+ this.mode = `hover`;
19
+ this._isOverflowing = false;
20
+ this._isHovering = false;
21
+ this._loopActive = false;
22
+ this._loopAtEnd = false;
23
+ this._overflow = 0;
24
+ this._resizeObserver = null;
25
+ this._loopTimer = 0;
26
+ this._onMouseEnter = () => {
27
+ this._isHovering = true;
28
+ };
29
+ this._onMouseLeave = () => {
30
+ this._isHovering = false;
31
+ };
32
+ this._measure = () => {
33
+ if (this._isHovering || this._loopAtEnd) return;
34
+ const el = this._textEl;
35
+ if (!el) return;
36
+ this._overflow = Math.max(0, el.scrollWidth - el.clientWidth);
37
+ const overflowing = this._overflow > 0;
38
+ this.classList.toggle(`is-overflowing`, overflowing);
39
+ if (overflowing !== this._isOverflowing) this._isOverflowing = overflowing;
40
+ if (this._loopActive && this.mode === `loop` && !this.disabled && overflowing && this._loopTimer === 0) this._scheduleLoopPan(START_DELAY);
41
+ if (!overflowing && this._loopAtEnd) {
42
+ this._loopAtEnd = false;
43
+ this.requestUpdate();
44
+ }
45
+ };
46
+ }
47
+ connectedCallback() {
48
+ super.connectedCallback();
49
+ this._resizeObserver = new ResizeObserver(() => this._measure());
50
+ this.addEventListener(`mouseenter`, this._onMouseEnter);
51
+ this.addEventListener(`mouseleave`, this._onMouseLeave);
52
+ }
53
+ disconnectedCallback() {
54
+ super.disconnectedCallback();
55
+ this._clearLoopTimer();
56
+ this._loopActive = false;
57
+ this._loopAtEnd = false;
58
+ this._resizeObserver?.disconnect();
59
+ this._resizeObserver = null;
60
+ this.removeEventListener(`mouseenter`, this._onMouseEnter);
61
+ this.removeEventListener(`mouseleave`, this._onMouseLeave);
62
+ }
63
+ firstUpdated() {
64
+ this._measure();
65
+ this._resizeObserver?.observe(this);
66
+ document.fonts?.ready.then(() => this._measure());
67
+ if (this.mode === `loop`) this.startLoop();
68
+ }
69
+ updated(changed) {
70
+ if (changed.has(`mode`)) {
71
+ if (this.mode === `loop`) this.startLoop();
72
+ else this.stopLoop();
73
+ }
74
+ if (changed.has(`disabled`) && this.disabled) this.stopLoop();
75
+ this._measure();
76
+ }
77
+ /**
78
+ * Whether a loop pan is currently active (between `startLoop()` and `stopLoop()`).
79
+ */
80
+ get looping() {
81
+ return this._loopActive;
82
+ }
83
+ /**
84
+ * Begin looping: pan to the end, dwell there for 2 seconds, reset to the
85
+ * start and pan again, repeating until `stopLoop()` is called. A no-op when
86
+ * `disabled`, when there is nothing to reveal, or under reduced-motion.
87
+ */
88
+ startLoop() {
89
+ if (this.disabled || this._prefersReducedMotion()) return;
90
+ this._loopActive = true;
91
+ this._loopAtEnd = false;
92
+ this.requestUpdate();
93
+ if (this._isOverflowing && this._loopTimer === 0) this._scheduleLoopPan(START_DELAY);
94
+ }
95
+ /**
96
+ * Stop a loop started with `startLoop()` and snap back to the rest position.
97
+ */
98
+ stopLoop() {
99
+ if (!this._loopActive && !this._loopAtEnd && this._loopTimer === 0) return;
100
+ this._clearLoopTimer();
101
+ this._loopActive = false;
102
+ this._loopAtEnd = false;
103
+ this.requestUpdate();
104
+ }
105
+ _prefersReducedMotion() {
106
+ return globalThis.matchMedia?.(`(prefers-reduced-motion: reduce)`).matches ?? false;
107
+ }
108
+ _panDuration() {
109
+ return Math.max(1.5, (this._overflow + END_PADDING) / SPEED);
110
+ }
111
+ _clearLoopTimer() {
112
+ if (this._loopTimer !== 0) {
113
+ clearTimeout(this._loopTimer);
114
+ this._loopTimer = 0;
115
+ }
116
+ }
117
+ _scheduleLoopPan(delay) {
118
+ this._clearLoopTimer();
119
+ this._loopTimer = window.setTimeout(() => {
120
+ this._loopTimer = 0;
121
+ if (!this._loopActive || this.disabled || !this._isOverflowing) return;
122
+ this._loopAtEnd = true;
123
+ this.requestUpdate();
124
+ const dwell = this._panDuration() * 1e3 + END_DWELL;
125
+ this._loopTimer = window.setTimeout(() => {
126
+ this._loopTimer = 0;
127
+ if (!this._loopActive) return;
128
+ this._loopAtEnd = false;
129
+ this.requestUpdate();
130
+ this._scheduleLoopPan(700);
131
+ }, dwell);
132
+ }, delay);
133
+ }
134
+ _textStyle() {
135
+ if (!this._isOverflowing) return ``;
136
+ const distance = this._overflow + END_PADDING;
137
+ const duration = Math.max(1.5, distance / SPEED);
138
+ const revealEnd = this.direction === `end`;
139
+ const restX = revealEnd ? 0 : -distance;
140
+ const hoverX = revealEnd ? -distance : 0;
141
+ if (this._loopActive && this.mode === `loop`) {
142
+ if (this._loopAtEnd) return [
143
+ `transform: translateX(${hoverX}px)`,
144
+ `transition: transform ${duration}s ${PAN_EASING}`,
145
+ `overflow: visible`,
146
+ `text-overflow: clip`
147
+ ].join(`; `);
148
+ return [
149
+ `transform: translateX(${restX}px)`,
150
+ `transition: transform ${RESET_DURATION}ms ${PAN_EASING}`,
151
+ revealEnd ? `` : `overflow: visible; text-overflow: clip`
152
+ ].filter(Boolean).join(`; `);
153
+ }
154
+ if (this._isHovering) return [
155
+ `transform: translateX(${hoverX}px)`,
156
+ `transition: transform ${duration}s ${PAN_EASING} ${START_DELAY}ms`,
157
+ `overflow: visible`,
158
+ `text-overflow: clip`
159
+ ].join(`; `);
160
+ return [
161
+ `transform: translateX(${restX}px)`,
162
+ `transition: transform 400ms ${PAN_EASING}`,
163
+ revealEnd ? `` : `overflow: visible; text-overflow: clip`
164
+ ].filter(Boolean).join(`; `);
165
+ }
166
+ render() {
167
+ const textClasses = {
168
+ "is-overflowing": this._isOverflowing,
169
+ "is-hovering": this._isHovering
170
+ };
171
+ return html`
172
+ <span class="text ${classMap(textClasses)}" part="text" style=${this._textStyle()}>
173
+ <slot @slotchange=${this._measure}></slot>
174
+ </span>
175
+ `;
176
+ }
177
+ static {
178
+ this.styles = [themeFallbacks, css`
179
+ /* Renders like plain inline text: no colours, border, padding or margin
180
+ of its own — it only adds the clipping needed to pan on hover. */
181
+ :host {
182
+ display: inline-block;
183
+ overflow: hidden;
184
+ white-space: nowrap;
185
+ max-width: 100%;
186
+ box-sizing: border-box;
187
+ font: inherit;
188
+ color: inherit;
189
+ }
190
+
191
+ :host([disabled]) {
192
+ opacity: var(--disabled-opacity, 0.5);
193
+ pointer-events: none;
194
+ }
195
+
196
+ .text {
197
+ display: block;
198
+ overflow: hidden;
199
+ text-overflow: ellipsis;
200
+ white-space: nowrap;
201
+ will-change: transform;
202
+ }
203
+
204
+ @media (prefers-reduced-motion: reduce) {
205
+ .text {
206
+ transition: none !important;
207
+ transform: none !important;
208
+ }
209
+ }
210
+ `];
211
+ }
212
+ };
213
+ __decorate([property({
214
+ type: String,
215
+ attribute: `direction`
216
+ })], PanTextElement.prototype, "direction", void 0);
217
+ __decorate([property({
218
+ type: Boolean,
219
+ attribute: `disabled`
220
+ })], PanTextElement.prototype, "disabled", void 0);
221
+ __decorate([property({
222
+ type: String,
223
+ attribute: `mode`,
224
+ reflect: true
225
+ })], PanTextElement.prototype, "mode", void 0);
226
+ __decorate([state()], PanTextElement.prototype, "_isOverflowing", void 0);
227
+ __decorate([state()], PanTextElement.prototype, "_isHovering", void 0);
228
+ __decorate([state()], PanTextElement.prototype, "_loopActive", void 0);
229
+ __decorate([state()], PanTextElement.prototype, "_loopAtEnd", void 0);
230
+ __decorate([query(`.text`)], PanTextElement.prototype, "_textEl", void 0);
231
+ PanTextElement = __decorate([safeCustomElement(`ixfx-pan-text`)], PanTextElement);
232
+ //#endregion
233
+ export { PanTextElement as t };
234
+
235
+ //# sourceMappingURL=pan-text-CqtvjPyK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pan-text-CqtvjPyK.js","names":["customElement"],"sources":["../src/pan-text/pan-text.ts"],"sourcesContent":["import type { PropertyValues } from 'lit';\nimport { css, html, LitElement } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\n\nconst SPEED = 45; // px per second\nconst END_PADDING = 4;\nconst START_DELAY = 300; // ms to wait on hover before panning begins\nconst END_DWELL = 2000; // ms to dwell at the end of the text in loop mode\nconst RESET_DURATION = 400; // ms to snap back to the start in loop mode\n// Decelerating curve: moves off fast then eases into the reveal (~easeOutQuad).\nconst PAN_EASING = `cubic-bezier(0.25, 0.46, 0.45, 0.94)`;\n\nexport type PanTextMode = `hover` | `loop`;\n\n@customElement(`ixfx-pan-text`)\nexport class PanTextElement extends LitElement {\n @property({ type: String, attribute: `direction` }) direction: `start` | `end` = `end`;\n @property({ type: Boolean, attribute: `disabled` }) disabled = false;\n /**\n * Interaction mode.\n * - `hover` (default): pans once while hovered.\n * - `loop`: pans repeatedly — dwell 2s at the end, reset to the start,\n * and pan again — until `stopLoop()` is called. Auto-starts when set.\n */\n @property({ type: String, attribute: `mode`, reflect: true }) mode: PanTextMode = `hover`;\n\n @state() private _isOverflowing = false;\n @state() private _isHovering = false;\n @state() private _loopActive = false;\n @state() private _loopAtEnd = false;\n\n @query(`.text`) private _textEl!: HTMLElement | null;\n\n private _overflow = 0;\n private _resizeObserver: ResizeObserver | null = null;\n private _loopTimer = 0;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this._resizeObserver = new ResizeObserver(() => this._measure());\n this.addEventListener(`mouseenter`, this._onMouseEnter);\n this.addEventListener(`mouseleave`, this._onMouseLeave);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._clearLoopTimer();\n // Reset without requesting an update — the element is leaving the DOM.\n this._loopActive = false;\n this._loopAtEnd = false;\n this._resizeObserver?.disconnect();\n this._resizeObserver = null;\n this.removeEventListener(`mouseenter`, this._onMouseEnter);\n this.removeEventListener(`mouseleave`, this._onMouseLeave);\n }\n\n override firstUpdated(): void {\n this._measure();\n this._resizeObserver?.observe(this);\n // Text metrics change once web fonts load; re-check when they settle.\n document.fonts?.ready.then(() => this._measure());\n if (this.mode === `loop`)\n this.startLoop();\n }\n\n protected override updated(changed: PropertyValues<this>): void {\n if (changed.has(`mode`)) {\n if (this.mode === `loop`)\n this.startLoop();\n else\n this.stopLoop();\n }\n if (changed.has(`disabled`) && this.disabled)\n this.stopLoop();\n this._measure();\n }\n\n /**\n * Whether a loop pan is currently active (between `startLoop()` and `stopLoop()`).\n */\n get looping(): boolean {\n return this._loopActive;\n }\n\n /**\n * Begin looping: pan to the end, dwell there for 2 seconds, reset to the\n * start and pan again, repeating until `stopLoop()` is called. A no-op when\n * `disabled`, when there is nothing to reveal, or under reduced-motion.\n */\n startLoop(): void {\n if (this.disabled || this._prefersReducedMotion())\n return;\n this._loopActive = true;\n this._loopAtEnd = false;\n this.requestUpdate();\n if (this._isOverflowing && this._loopTimer === 0)\n this._scheduleLoopPan(START_DELAY);\n // Otherwise `_measure()` picks it up once overflow is known.\n }\n\n /**\n * Stop a loop started with `startLoop()` and snap back to the rest position.\n */\n stopLoop(): void {\n if (!this._loopActive && !this._loopAtEnd && this._loopTimer === 0)\n return;\n this._clearLoopTimer();\n this._loopActive = false;\n this._loopAtEnd = false;\n this.requestUpdate();\n }\n\n private _prefersReducedMotion(): boolean {\n return globalThis.matchMedia?.(`(prefers-reduced-motion: reduce)`).matches ?? false;\n }\n\n private _panDuration(): number {\n return Math.max(1.5, (this._overflow + END_PADDING) / SPEED);\n }\n\n private _clearLoopTimer(): void {\n if (this._loopTimer !== 0) {\n clearTimeout(this._loopTimer);\n this._loopTimer = 0;\n }\n }\n\n private _scheduleLoopPan(delay: number): void {\n this._clearLoopTimer();\n this._loopTimer = window.setTimeout(() => {\n this._loopTimer = 0;\n if (!this._loopActive || this.disabled || !this._isOverflowing)\n return;\n this._loopAtEnd = true;\n this.requestUpdate();\n const dwell = this._panDuration() * 1000 + END_DWELL;\n this._loopTimer = window.setTimeout(() => {\n this._loopTimer = 0;\n if (!this._loopActive)\n return;\n this._loopAtEnd = false;\n this.requestUpdate();\n this._scheduleLoopPan(RESET_DURATION + START_DELAY);\n }, dwell);\n }, delay);\n }\n\n private _onMouseEnter = (): void => {\n this._isHovering = true;\n };\n\n private _onMouseLeave = (): void => {\n this._isHovering = false;\n };\n\n /**\n * Measures how far the slotted text overflows its container. The measurement\n * is taken on the inner `.text` span (which clips with an ellipsis), not on\n * the host — the host never overflows, so measuring it always yielded zero\n * and the hover interaction never activated.\n *\n * Skipped while hovering, because the hover styles switch `.text` to\n * `overflow: visible` and the measurement would collapse to zero mid-pan.\n */\n private _measure = (): void => {\n if (this._isHovering || this._loopAtEnd)\n return;\n const el = this._textEl;\n if (!el)\n return;\n\n this._overflow = Math.max(0, el.scrollWidth - el.clientWidth);\n const overflowing = this._overflow > 0;\n\n this.classList.toggle(`is-overflowing`, overflowing);\n if (overflowing !== this._isOverflowing) {\n this._isOverflowing = overflowing;\n }\n // A loop requested before overflow was known (fonts, resize, late slot)\n // starts here once there is something to reveal.\n if (this._loopActive && this.mode === `loop` && !this.disabled && overflowing && this._loopTimer === 0)\n this._scheduleLoopPan(START_DELAY);\n if (!overflowing && this._loopAtEnd) {\n this._loopAtEnd = false;\n this.requestUpdate();\n }\n };\n\n private _textStyle(): string {\n if (!this._isOverflowing)\n return ``;\n\n const distance = this._overflow + END_PADDING;\n const duration = Math.max(1.5, distance / SPEED);\n const revealEnd = this.direction === `end`;\n\n // \"end\": rest shows the start of the text, hover pans left to the end.\n // \"start\": rest shows the end of the text, hover pans right to the start.\n const restX = revealEnd ? 0 : -distance;\n const hoverX = revealEnd ? -distance : 0;\n\n // Loop mode drives the same transform off a timer instead of hover. The\n // dwell/reset delays live in the timeout chain, so the transition itself\n // carries no extra delay.\n if (this._loopActive && this.mode === `loop`) {\n if (this._loopAtEnd) {\n return [\n `transform: translateX(${hoverX}px)`,\n `transition: transform ${duration}s ${PAN_EASING}`,\n `overflow: visible`,\n `text-overflow: clip`,\n ].join(`; `);\n }\n return [\n `transform: translateX(${restX}px)`,\n `transition: transform ${RESET_DURATION}ms ${PAN_EASING}`,\n revealEnd ? `` : `overflow: visible; text-overflow: clip`,\n ].filter(Boolean).join(`; `);\n }\n\n if (this._isHovering) {\n return [\n `transform: translateX(${hoverX}px)`,\n `transition: transform ${duration}s ${PAN_EASING} ${START_DELAY}ms`,\n `overflow: visible`,\n `text-overflow: clip`,\n ].join(`; `);\n }\n\n return [\n `transform: translateX(${restX}px)`,\n `transition: transform 400ms ${PAN_EASING}`,\n // \"start\" mode keeps the tail visible at rest, so it can't clip/ellipsis.\n revealEnd ? `` : `overflow: visible; text-overflow: clip`,\n ].filter(Boolean).join(`; `);\n }\n\n protected override render() {\n const textClasses = {\n 'is-overflowing': this._isOverflowing,\n 'is-hovering': this._isHovering,\n };\n\n return html`\n <span class=\"text ${classMap(textClasses)}\" part=\"text\" style=${this._textStyle()}>\n <slot @slotchange=${this._measure}></slot>\n </span>\n `;\n }\n\n static override styles = [themeFallbacks, css`\n /* Renders like plain inline text: no colours, border, padding or margin\n of its own — it only adds the clipping needed to pan on hover. */\n :host {\n display: inline-block;\n overflow: hidden;\n white-space: nowrap;\n max-width: 100%;\n box-sizing: border-box;\n font: inherit;\n color: inherit;\n }\n\n :host([disabled]) {\n opacity: var(--disabled-opacity, 0.5);\n pointer-events: none;\n }\n\n .text {\n display: block;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n will-change: transform;\n }\n\n @media (prefers-reduced-motion: reduce) {\n .text {\n transition: none !important;\n transform: none !important;\n }\n }\n `];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-pan-text': PanTextElement;\n }\n}\n"],"mappings":"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"}
package/dist/panel.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as TitlebarToggleDetail, c as TitlebarVariant, i as TitlebarOrientation, o as TitlebarToggleEvent, s as TitlebarToggleInteraction, t as TitlebarCloseEvent } from "./titlebar-B5zSTZnF.js";
1
+ import { a as TitlebarToggleDetail, c as TitlebarVariant, i as TitlebarOrientation, o as TitlebarToggleEvent, s as TitlebarToggleInteraction, t as TitlebarCloseEvent } from "./titlebar-Tqu-VvMU.js";
2
2
  import { LitElement } from "lit";
3
3
  //#region src/panel/panel.d.ts
4
4
  /** Backwards-compatible aliases: canonical types now live in `../titlebar/titlebar.js`. */
package/dist/panel.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as themeFallbacks } from "./fallbacks-BcKGq-2F.js";
1
+ import { t as themeFallbacks } from "./fallbacks-DQ_5OsmR.js";
2
2
  import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
3
3
  import "./titlebar.js";
4
4
  import { LitElement, css, html, nothing } from "lit";
package/dist/polar-pad.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as themeFallbacks } from "./fallbacks-BcKGq-2F.js";
1
+ import { t as themeFallbacks } from "./fallbacks-DQ_5OsmR.js";
2
2
  import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
3
3
  import { t as prominenceStyles } from "./prominence-DlFShic3.js";
4
4
  import { t as resolveAxisStep } from "./keyboard-B5xD7Fz-.js";
@@ -1,4 +1,4 @@
1
- import { t as themeFallbacks } from "./fallbacks-BcKGq-2F.js";
1
+ import { t as themeFallbacks } from "./fallbacks-DQ_5OsmR.js";
2
2
  import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
3
3
  import { t as prominenceStyles } from "./prominence-DlFShic3.js";
4
4
  import { t as resolveAxisStep } from "./keyboard-B5xD7Fz-.js";
@@ -873,4 +873,4 @@ RadialInputElement = __decorate([safeCustomElement(`ixfx-radial-input`)], Radial
873
873
  //#endregion
874
874
  export { RadialInputElement as t };
875
875
 
876
- //# sourceMappingURL=radial-input-DyxfbNzD.js.map
876
+ //# sourceMappingURL=radial-input-KMVltQfe.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"radial-input-DyxfbNzD.js","names":["#_radius","#dragging","#dragStartY","#valueAtDragStart","#onPointerMove","#onPointerUp","#setValueFromRelative","#stepByRelativeDelta","#lanes","#getRelativeValue","#quantise","#isUserInteraction","#scheduleChangeEvent","#fireChangeEvent","#changeDebounceTimer","#getCssVar","#getEffectiveMarkerStyle","#getNeedlePath","#onPointerDown","#onKeyDown","#renderCircleFill","#renderWedge","#renderCircleBorder","#renderLane","#renderMidpointMarker","#renderValueMarker","customElement"],"sources":["../src/radial-input/svg-utils.ts","../src/radial-input/radial-input.ts"],"sourcesContent":["/**\n * SVG utilities for radial input component\n * Handles geometry calculations for flattened circle arcs\n */\n\nimport type { ValueMode } from './types.js';\n\nexport interface Point {\n x: number;\n y: number;\n}\n\nexport interface ArcParameters {\n startAngle: number; // radians\n endAngle: number; // radians\n radius: number;\n center: Point;\n}\n\nconst PI2 = Math.PI * 2;\nconst MIDPOINT_ANGLE = -Math.PI / 2; // Top-center of circle\n\n/**\n * Convert polar coordinates (angle in radians, radius) to SVG Cartesian coordinates\n * @param angle - Angle in radians (0 = right/east, increases clockwise in SVG)\n * @param radius - Distance from center\n * @param center - Center point (default: {x: 50, y: 50})\n * @returns Point in SVG coordinates\n */\nexport function polarToCartesian(\n angle: number,\n radius: number,\n center: Point = { x: 50, y: 50 },\n): Point {\n return {\n x: center.x + Math.cos(angle) * radius,\n y: center.y + Math.sin(angle) * radius,\n };\n}\n\n/**\n * Convert SVG Cartesian coordinates to polar (angle in radians, radius)\n * @param x - X coordinate\n * @param y - Y coordinate\n * @param center - Center point (default: {x: 50, y: 50})\n * @returns Angle in radians (0..2π) and radius\n */\nexport function cartesianToPolar(\n x: number,\n y: number,\n center: Point = { x: 50, y: 50 },\n): { angle: number; radius: number } {\n const dx = x - center.x;\n const dy = y - center.y;\n const radius = Math.sqrt(dx * dx + dy * dy);\n const raw = Math.atan2(dy, dx);\n const angle = ((raw % PI2) + PI2) % PI2; // Normalize to 0..2π\n return { angle, radius };\n}\n\n/**\n * Calculate start and end angles for a flattened circle\n * @param flatten - How much of the circle to hide (0..1): 0 = full circle, 0.5 = half circle, 1 = no arc\n * @returns Start and end angles in radians\n */\nexport function getFlattenedCircleAngles(flatten: number): {\n startAngle: number;\n endAngle: number;\n totalArc: number;\n} {\n // flatten represents the percentage of circle hidden\n // 0 = full circle (360°), 0.5 = half circle (180°), 1 = no arc (0°)\n const visibleArc = PI2 * (1 - flatten); // Total visible arc in radians\n\n // Center the visible arc at the top (angle = -π/2)\n // Start and end angles are symmetric around top-center\n const halfArc = visibleArc / 2;\n const topAngle = -Math.PI / 2; // Top center (270° in standard coords, but -90° from east)\n\n const startAngle = topAngle - halfArc;\n const endAngle = topAngle + halfArc;\n const totalArc = endAngle - startAngle;\n\n return { startAngle, endAngle, totalArc };\n}\n\n/**\n * Map a value (0..1) to an angle based on value mode\n * @param relativeValue - Value in 0..1 range\n * @param valueMode - How to interpret the value\n * @param flatten - Circle flattening amount (0..1)\n * @returns Angle in radians\n */\nexport function valueToAngle(\n relativeValue: number,\n valueMode: ValueMode,\n flatten: number,\n): number {\n const { startAngle, endAngle, totalArc } = getFlattenedCircleAngles(flatten);\n\n switch (valueMode) {\n case `range`:\n // Linear mapping from start to end\n return startAngle + relativeValue * totalArc;\n\n case `bipolar`: {\n // Midpoint is at top (MIDPOINT_ANGLE = -π/2)\n if (relativeValue <= 0.5) {\n // Map 0..0.5 to startAngle..MIDPOINT_ANGLE (going counterclockwise to top)\n const t = relativeValue / 0.5;\n return startAngle + t * (MIDPOINT_ANGLE - startAngle);\n } else {\n // Map 0.5..1 to MIDPOINT_ANGLE..endAngle (going clockwise from top)\n const t = (relativeValue - 0.5) / 0.5;\n return MIDPOINT_ANGLE + t * (endAngle - MIDPOINT_ANGLE);\n }\n }\n\n case `unipolar`: {\n // Marker stays at top for unipolar mode\n return MIDPOINT_ANGLE;\n }\n\n default:\n return startAngle;\n }\n}\n\n/**\n * Get start and end angles for a value arc\n * @param relativeValue - Value in 0..1 range\n * @param valueMode - How to interpret the value\n * @param flatten - Circle flattening amount (0..1)\n * @returns Start and end angles for the arc\n */\nexport function getValueArcAngles(\n relativeValue: number,\n valueMode: ValueMode,\n flatten: number,\n): { startAngle: number; endAngle: number } {\n const { startAngle, endAngle, totalArc } = getFlattenedCircleAngles(flatten);\n\n switch (valueMode) {\n case `range`:\n // Arc from start to value position\n return {\n startAngle,\n endAngle: startAngle + relativeValue * totalArc,\n };\n\n case `bipolar`: {\n // Midpoint is at top (MIDPOINT_ANGLE = -π/2)\n if (relativeValue < 0.5) {\n // Arc from some point toward top (going counterclockwise)\n const t = relativeValue / 0.5;\n const valueAngle = startAngle + t * (MIDPOINT_ANGLE - startAngle);\n return {\n startAngle: valueAngle,\n endAngle: MIDPOINT_ANGLE,\n };\n } else if (relativeValue > 0.5) {\n // Arc from top going clockwise\n const t = (relativeValue - 0.5) / 0.5;\n const valueAngle = MIDPOINT_ANGLE + t * (endAngle - MIDPOINT_ANGLE);\n return {\n startAngle: MIDPOINT_ANGLE,\n endAngle: valueAngle,\n };\n } else {\n // Exactly at midpoint, no arc\n return { startAngle: MIDPOINT_ANGLE, endAngle: MIDPOINT_ANGLE };\n }\n }\n\n case `unipolar`: {\n // Spread symmetrically from top (MIDPOINT_ANGLE = -π/2)\n const spreadAmount = relativeValue * totalArc / 2;\n return {\n startAngle: MIDPOINT_ANGLE - spreadAmount,\n endAngle: MIDPOINT_ANGLE + spreadAmount,\n };\n }\n\n default:\n return { startAngle, endAngle: startAngle };\n }\n}\n\n/**\n * Get start and end angles for an anchored arc\n * Centered on current value position, extends equally in both directions\n * @param relativeValue - Current value position (0..1)\n * @param laneValue - Width of the arc (0..1, where 1 = full range)\n * @param valueMode - How to interpret the value\n * @param flatten - Circle flattening amount (0..1)\n * @returns Start and end angles for the arc\n */\nexport function getAnchoredArcAngles(\n relativeValue: number,\n laneValue: number,\n valueMode: ValueMode,\n flatten: number,\n): { startAngle: number; endAngle: number } {\n const { startAngle, endAngle, totalArc } = getFlattenedCircleAngles(flatten);\n\n // Get the angle for the current value (this is the center of the arc)\n const centerAngle = valueToAngle(relativeValue, valueMode, flatten);\n\n // Calculate half-width of the arc\n // laneValue is 0..1, where 1 = full range\n const halfWidth = (laneValue * totalArc) / 2;\n\n let arcStart = centerAngle - halfWidth;\n let arcEnd = centerAngle + halfWidth;\n\n // Clamp to valid bounds (prevent wrapping)\n // The valid range is [startAngle, endAngle]\n if (arcStart < startAngle)\n arcStart = startAngle;\n if (arcEnd > endAngle)\n arcEnd = endAngle;\n\n // If the arc would be degenerate after clamping, return a single point\n if (arcStart >= arcEnd) {\n return { startAngle: centerAngle, endAngle: centerAngle };\n }\n\n return { startAngle: arcStart, endAngle: arcEnd };\n}\n\n/**\n * Generate SVG path for an arc\n * @param startAngle - Start angle in radians\n * @param endAngle - End angle in radians\n * @param radius - Arc radius\n * @param center - Center point\n * @returns SVG path data string\n */\nexport function generateArcPath(\n startAngle: number,\n endAngle: number,\n radius: number,\n center: Point = { x: 50, y: 50 },\n): string {\n if (startAngle === endAngle) {\n return ``; // No arc to draw\n }\n\n // Calculate arc length to determine large-arc-flag\n let arcLength = endAngle - startAngle;\n\n // Handle wrap-around case (e.g., from 5.5 to 0.5 radians)\n if (arcLength < 0) {\n arcLength += PI2;\n }\n\n // Handle full or near-full circle case\n // When arcLength is nearly 2π, start and end points are essentially the same\n // and drawing a full circle needs special handling\n if (arcLength >= PI2 - 0.001) {\n // Draw a full circle by going almost all the way around\n const adjustedEnd = startAngle + PI2 - 0.001;\n const start = polarToCartesian(startAngle, radius, center);\n const end = polarToCartesian(adjustedEnd, radius, center);\n return `M ${start.x},${start.y} A ${radius},${radius} 0 1 1 ${end.x},${end.y}`;\n }\n\n const start = polarToCartesian(startAngle, radius, center);\n const end = polarToCartesian(endAngle, radius, center);\n\n const largeArcFlag = arcLength > Math.PI ? 1 : 0;\n\n return `M ${start.x},${start.y} A ${radius},${radius} 0 ${largeArcFlag} 1 ${end.x},${end.y}`;\n}\n\n/**\n * Generate SVG path for a full flattened circle border\n * @param radius - Circle radius\n * @param flatten - Flattening amount (0..1)\n * @param center - Center point\n * @returns SVG path data string\n */\nexport function generateCircleBorderPath(\n radius: number,\n flatten: number,\n center: Point = { x: 50, y: 50 },\n): string {\n const { startAngle, endAngle } = getFlattenedCircleAngles(flatten);\n return generateArcPath(startAngle, endAngle, radius, center);\n}\n\n/**\n * Generate SVG path data for a filled wedge (pie-slice) sector\n * @param startAngle - Start angle in radians\n * @param endAngle - End angle in radians\n * @param radius - Wedge radius (same as dial radius)\n * @param center - Center point\n * @param clockwise - Whether to draw arc clockwise (true) or counterclockwise (false)\n * @returns SVG path data string for filled wedge\n */\nexport function generateWedgePath(\n startAngle: number,\n endAngle: number,\n radius: number,\n center: Point = { x: 50, y: 50 },\n clockwise: boolean = true,\n): string {\n if (startAngle === endAngle) {\n return ``; // No wedge to draw\n }\n\n // Calculate arc length (always positive, representing shortest path)\n let arcLength = endAngle - startAngle;\n if (arcLength < 0) {\n arcLength += PI2;\n }\n\n // Handle full or near-full circle case\n if (arcLength >= PI2 - 0.001) {\n // Draw a near-full circle wedge\n const start = polarToCartesian(startAngle, radius, center);\n const adjustedEnd = startAngle + PI2 - 0.001;\n const adjEnd = polarToCartesian(adjustedEnd, radius, center);\n const largeArcFlag = 1;\n const sweepFlag = clockwise ? 1 : 0;\n return `M ${center.x},${center.y} L ${start.x},${start.y} A ${radius},${radius} 0 ${largeArcFlag} ${sweepFlag} ${adjEnd.x},${adjEnd.y} Z`;\n }\n\n let actualStartAngle = startAngle;\n let actualEndAngle = endAngle;\n let actualClockwise = clockwise;\n\n // When going counterclockwise and arcLength > π, we want the short clockwise path instead\n // by swapping start and end\n if (!clockwise && arcLength > Math.PI) {\n actualStartAngle = endAngle;\n actualEndAngle = startAngle;\n actualClockwise = true;\n arcLength = PI2 - arcLength;\n }\n\n const start = polarToCartesian(actualStartAngle, radius, center);\n const end = polarToCartesian(actualEndAngle, radius, center);\n\n const largeArcFlag = arcLength > Math.PI ? 1 : 0;\n const sweepFlag = actualClockwise ? 1 : 0;\n\n // M center L start A radius radius 0 large sweep end Z\n return `M ${center.x},${center.y} L ${start.x},${start.y} A ${radius},${radius} 0 ${largeArcFlag} ${sweepFlag} ${end.x},${end.y} Z`;\n}\n\n/**\n * Get wedge angles based on value mode\n * @param relativeValue - Value in 0..1 range\n * @param valueMode - How to interpret the value\n * @param flatten - Circle flattening amount (0..1)\n * @returns Object with startAngle, endAngle, and clockwise flag\n */\nexport function getWedgeAngles(\n relativeValue: number,\n valueMode: ValueMode,\n flatten: number,\n): { startAngle: number; endAngle: number; clockwise: boolean } {\n const { startAngle, totalArc } = getFlattenedCircleAngles(flatten);\n const valueAngle = valueToAngle(relativeValue, valueMode, flatten);\n\n switch (valueMode) {\n case `range`:\n // Wedge from startAngle to valueAngle (always clockwise)\n return {\n startAngle,\n endAngle: valueAngle,\n clockwise: true,\n };\n\n case `bipolar`: {\n // When value < 0.5, go counterclockwise from midpoint to value\n // When value >= 0.5, go clockwise from midpoint to value\n if (relativeValue < 0.5) {\n return {\n startAngle: MIDPOINT_ANGLE,\n endAngle: valueAngle,\n clockwise: false,\n };\n } else {\n return {\n startAngle: MIDPOINT_ANGLE,\n endAngle: valueAngle,\n clockwise: true,\n };\n }\n }\n\n case `unipolar`: {\n // Wedge centered at MIDPOINT, spreading value * totalArc/2 in each direction\n const halfSpread = relativeValue * totalArc / 2;\n return {\n startAngle: MIDPOINT_ANGLE - halfSpread,\n endAngle: MIDPOINT_ANGLE + halfSpread,\n clockwise: true,\n };\n }\n\n default:\n return { startAngle, endAngle: startAngle, clockwise: true };\n }\n}\n\n/**\n * Get position for a marker (needle or dot) at a given value\n * @param relativeValue - Value in 0..1 range\n * @param valueMode - How to interpret the value\n * @param flatten - Circle flattening amount (0..1)\n * @param radius - Circle radius\n * @param center - Center point\n * @returns Angle in radians and position point\n */\nexport function getMarkerPosition(\n relativeValue: number,\n valueMode: ValueMode,\n flatten: number,\n radius: number,\n center: Point = { x: 50, y: 50 },\n): { angle: number; position: Point } {\n const angle = valueToAngle(relativeValue, valueMode, flatten);\n const position = polarToCartesian(angle, radius, center);\n return { angle, position };\n}\n\n/**\n * Get position for midpoint marker (used in bipolar/unipolar modes)\n * @param radius - Circle radius\n * @param center - Center point\n * @returns Position at top-center of circle\n */\nexport function getMidpointPosition(\n radius: number,\n center: Point = { x: 50, y: 50 },\n): { angle: number; position: Point } {\n const position = polarToCartesian(MIDPOINT_ANGLE, radius, center);\n return { angle: MIDPOINT_ANGLE, position };\n}\n\n/**\n * Clamp a value between min and max\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Scale a value from one range to another\n */\nexport function scale(\n value: number,\n fromMin: number,\n fromMax: number,\n toMin: number,\n toMax: number,\n): number {\n const normalized = (value - fromMin) / (fromMax - fromMin);\n return toMin + normalized * (toMax - toMin);\n}\n","/**\n * Radial input component\n * A rotary dial input inspired by Ableton Live and music production software.\n *\n * Mouse wheel: up = increase, down = decrease, with the same step resolution as\n * arrow keys (Shift halves the step). The dial must have focus by default, or\n * set the `lighttouch` boolean attribute to react on hover instead. See\n * `docs/infra-mousewheel.md`.\n */\n\nimport type { PropertyValues } from 'lit';\nimport type { WheelDirection } from '../mixins/wheel-nudge.js';\nimport type {\n LaneData,\n LaneType,\n MarkerStyle,\n RadialInputChangeDetail,\n RadialInputInputDetail,\n ValueMode,\n} from './types.js';\nimport { css, html, LitElement, svg } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { KEY_STEP_DIVISOR, resolveAxisStep } from '../keyboard.js';\nimport { WheelNudgeMixin } from '../mixins/wheel-nudge.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { prominenceStyles } from '../styles/prominence.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport {\n clamp,\n generateArcPath,\n generateCircleBorderPath,\n generateWedgePath,\n getAnchoredArcAngles,\n getMarkerPosition,\n getMidpointPosition,\n getValueArcAngles,\n getWedgeAngles,\n scale,\n} from './svg-utils.js';\n\nconst CENTER = { x: 50, y: 50 }; // Center point in viewBox\n\n@customElement(`ixfx-radial-input`)\nexport class RadialInputElement extends WheelNudgeMixin(LitElement) {\n // Internal backing field for radius (used with custom setter for clamping)\n #_radius = 45;\n\n // Radius property (controls dial size, 10-50 range to prevent clipping)\n @property({ type: Number })\n get radius(): number {\n return this.#_radius;\n }\n\n set radius(v: number) {\n this.#_radius = clamp(v, 10, 50);\n }\n\n // Value properties (matches ixfx-range API)\n @property({ type: Number })\n value = 0;\n\n @property({ type: Number })\n min = 0;\n\n @property({ type: Number })\n max = 100;\n\n @property({ type: Number })\n step: number | undefined = undefined;\n\n @property({ type: Number })\n stops?: number;\n\n // Value mode\n @property({ type: String, attribute: `value-mode` })\n valueMode: ValueMode = `range`;\n\n // Appearance\n @property({ type: Number })\n flatten = 0.3;\n\n @property({ type: String, attribute: `marker-style` })\n markerStyle: MarkerStyle = `needle`;\n\n @property({ type: Boolean })\n wedge = false;\n\n // Interaction\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n // Internal state\n #lanes: Map<string, LaneData> = new Map();\n #dragging = false;\n #dragStartY = 0;\n #valueAtDragStart = 0;\n #changeDebounceTimer: number | undefined;\n #isUserInteraction = false;\n\n constructor() {\n super();\n // Initialize default lanes\n // Note: value lane will be updated in willUpdate() to reflect initial value\n this.#lanes.set(`track`, {\n key: `track`,\n value: 1, // Full range\n type: `fixed`,\n offset: 0,\n width: 0.16,\n });\n this.#lanes.set(`value`, {\n key: `value`,\n value: 0, // Will be updated in willUpdate()\n type: `value`,\n offset: 0,\n width: 0.24,\n });\n }\n\n // Lane management API\n addLane(\n key: string,\n options?: {\n value?: number;\n type?: LaneType;\n offset?: number;\n width?: number;\n },\n ): void {\n const relativeValue = this.#getRelativeValue();\n this.#lanes.set(key, {\n key,\n value: options?.value ?? relativeValue,\n type: options?.type ?? `value`,\n offset: options?.offset ?? 0,\n width: options?.width ?? 0.1,\n });\n this.requestUpdate();\n }\n\n setLaneValue(key: string, value: number): void {\n const lane = this.#lanes.get(key);\n if (lane) {\n lane.value = clamp(value, 0, 1);\n this.requestUpdate();\n }\n }\n\n removeLane(key: string): void {\n this.#lanes.delete(key);\n this.requestUpdate();\n }\n\n getLanes(): ReadonlyMap<string, LaneData> {\n return new Map(this.#lanes);\n }\n\n getLane(key: string): LaneData | undefined {\n return this.#lanes.get(key);\n }\n\n // Internal helpers\n #getRelativeValue(): number {\n return scale(this.value, this.min, this.max, 0, 1);\n }\n\n #getEffectiveMarkerStyle(): MarkerStyle {\n if (this.valueMode === `unipolar` && this.markerStyle === `needle`) {\n return `none`;\n }\n return this.markerStyle;\n }\n\n #quantise(value: number): number {\n if (this.stops && this.stops > 1) {\n const range = this.max - this.min;\n const step = range / this.stops;\n return Math.round((value - this.min) / step) * step + this.min;\n }\n return value;\n }\n\n #setValueFromRelative(relativeValue: number, isUserInteraction = false): void {\n const newValue = scale(relativeValue, 0, 1, this.min, this.max);\n const clampedValue = this.#quantise(clamp(newValue, this.min, this.max));\n\n if (clampedValue === this.value)\n return;\n\n const previousValue = this.value;\n this.value = clampedValue;\n this.#isUserInteraction = isUserInteraction;\n\n // Update 'value' lane if it exists\n const valueLane = this.#lanes.get(`value`);\n if (valueLane && valueLane.type === `value`) {\n valueLane.value = this.#getRelativeValue();\n }\n\n // Update data-tooltip for live tooltips\n if (this.hasAttribute(`data-tooltip-live`)) {\n const percentage = Math.round(this.#getRelativeValue() * 100);\n this.setAttribute(`data-tooltip`, `${percentage}%`);\n }\n\n // Fire input event only for user interactions\n if (isUserInteraction) {\n this.dispatchEvent(\n new CustomEvent<RadialInputInputDetail>(`input`, {\n detail: {\n value: this.value,\n valueRelative: this.#getRelativeValue(),\n },\n bubbles: true,\n composed: true,\n }),\n );\n\n // Debounce change event\n this.#scheduleChangeEvent(previousValue);\n } else {\n // Immediate change event for programmatic changes\n this.#fireChangeEvent(previousValue);\n }\n }\n\n #scheduleChangeEvent(previousValue: number): void {\n if (this.#changeDebounceTimer !== undefined) {\n clearTimeout(this.#changeDebounceTimer);\n }\n\n this.#changeDebounceTimer = window.setTimeout(() => {\n this.#fireChangeEvent(previousValue);\n this.#changeDebounceTimer = undefined;\n }, 150);\n }\n\n #fireChangeEvent(previousValue: number): void {\n this.dispatchEvent(\n new CustomEvent<RadialInputChangeDetail>(`change`, {\n detail: {\n value: this.value,\n valueRelative: this.#getRelativeValue(),\n previousValue,\n },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n // Pointer interaction handlers\n #onPointerDown = (event: PointerEvent): void => {\n if (this.disabled)\n return;\n\n event.preventDefault();\n const svg = this.renderRoot.querySelector(`svg`);\n svg?.focus();\n this.#dragging = true;\n this.#dragStartY = event.clientY;\n this.#valueAtDragStart = this.value;\n this.toggleAttribute(`dragging`, true);\n\n if (svg) {\n svg.setPointerCapture(event.pointerId);\n }\n\n window.addEventListener(`pointermove`, this.#onPointerMove);\n window.addEventListener(`pointerup`, this.#onPointerUp);\n window.addEventListener(`pointercancel`, this.#onPointerUp);\n };\n\n #onPointerMove = (event: PointerEvent): void => {\n if (!this.#dragging)\n return;\n\n event.preventDefault();\n\n // Calculate sensitivity: full range = 2× component height\n const sensitivity = this.clientHeight * 2;\n const shiftDivisor = event.shiftKey ? KEY_STEP_DIVISOR : 1;\n const effectiveSensitivity = sensitivity * shiftDivisor;\n\n // Calculate delta (negative because up = increase)\n const deltaY = this.#dragStartY - event.clientY;\n const deltaValue = (deltaY / effectiveSensitivity) * (this.max - this.min);\n const newValue = this.#valueAtDragStart + deltaValue;\n\n const relativeValue = scale(newValue, this.min, this.max, 0, 1);\n this.#setValueFromRelative(clamp(relativeValue, 0, 1), true);\n };\n\n #onPointerUp = (): void => {\n this.#dragging = false;\n this.toggleAttribute(`dragging`, false);\n\n const svg = this.renderRoot.querySelector(`svg`);\n if (svg && `hasPointerCapture` in svg && typeof svg.hasPointerCapture === `function`) {\n if (svg.hasPointerCapture(1)) {\n svg.releasePointerCapture(1);\n }\n }\n\n window.removeEventListener(`pointermove`, this.#onPointerMove);\n window.removeEventListener(`pointerup`, this.#onPointerUp);\n window.removeEventListener(`pointercancel`, this.#onPointerUp);\n };\n\n // Keyboard interaction handler\n #onKeyDown = (event: KeyboardEvent): void => {\n if (this.disabled)\n return;\n\n const range = this.max - this.min;\n const effectiveStep = resolveAxisStep(range, this.stops, this.step, event.shiftKey);\n\n let handled = false;\n\n switch (event.key) {\n case `ArrowUp`:\n case `ArrowRight`:\n this.#stepByRelativeDelta(effectiveStep / range, true);\n handled = true;\n break;\n\n case `ArrowDown`:\n case `ArrowLeft`:\n this.#stepByRelativeDelta(-effectiveStep / range, true);\n handled = true;\n break;\n\n case `Home`:\n this.#setValueFromRelative(0, true);\n handled = true;\n break;\n\n case `End`:\n this.#setValueFromRelative(1, true);\n handled = true;\n break;\n }\n\n if (handled) {\n event.preventDefault();\n }\n };\n\n /**\n * Apply a relative-delta nudge to the current value, clamped to [min, max] and\n * quantised. Shared between keyboard arrow keys and the wheel handler.\n */\n #stepByRelativeDelta(relativeDelta: number, isUserInteraction: boolean): void {\n this.#setValueFromRelative(\n clamp(this.#getRelativeValue() + relativeDelta, 0, 1),\n isUserInteraction,\n );\n }\n\n // Wheel handler — installed by WheelNudgeMixin on the host. Inverted from the\n // shared convention (`docs/infra-mousewheel.md`): wheel forward/up decreases\n // the value, wheel backward/down increases it. Matches the perceived\n // rotation of a physical rotary dial — turning the dial clockwise is the\n // most natural \"forward\" gesture and should reduce the value.\n override _applyWheelDelta(direction: WheelDirection, event: WheelEvent): void {\n const range = this.max - this.min;\n const effectiveStep = resolveAxisStep(range, this.stops, this.step, event.shiftKey);\n this.#stepByRelativeDelta(-direction * effectiveStep / range, true);\n }\n\n // Rendering helpers\n #renderCircleBorder() {\n const path = generateCircleBorderPath(this.radius, this.flatten, CENTER);\n const borderWidth = this.#getCssVar(`--dial-border-width`, 2);\n const borderColor = getComputedStyle(this).getPropertyValue(`--dial-border-color`).trim() || `var(--surface-4)`;\n return svg`<path class=\"dial-border\" d=\"${path}\" fill=\"none\" stroke=\"${borderColor}\" stroke-width=\"${borderWidth}\" stroke-linecap=\"round\" vector-effect=\"non-scaling-stroke\" />`;\n }\n\n #renderCircleFill() {\n const path = generateCircleBorderPath(this.radius, this.flatten, CENTER);\n const fill = getComputedStyle(this).getPropertyValue(`--dial-fill`).trim() || `transparent`;\n return svg`<path class=\"dial-fill\" d=\"${path}\" fill=\"${fill}\" />`;\n }\n\n #renderWedge() {\n const relativeValue = this.#getRelativeValue();\n const { startAngle, endAngle, clockwise } = getWedgeAngles(\n relativeValue,\n this.valueMode,\n this.flatten,\n );\n\n const path = generateWedgePath(startAngle, endAngle, this.radius, CENTER, clockwise);\n if (!path)\n return svg``;\n\n return svg`<path class=\"wedge\" d=\"${path}\" />`;\n }\n\n #renderLane(lane: LaneData) {\n let arcPath = ``;\n\n if (lane.type === `fixed`) {\n // Fixed lanes always show full range\n arcPath = generateCircleBorderPath(\n this.radius - lane.offset * this.radius,\n this.flatten,\n CENTER,\n );\n } else if (lane.type === `anchored`) {\n // Anchored lanes: centered on current value, arc width based on lane.value\n const { startAngle, endAngle } = getAnchoredArcAngles(\n this.#getRelativeValue(),\n lane.value,\n this.valueMode,\n this.flatten,\n );\n arcPath = generateArcPath(\n startAngle,\n endAngle,\n this.radius - lane.offset * this.radius,\n CENTER,\n );\n } else {\n // Value lanes follow the value mode\n const { startAngle, endAngle } = getValueArcAngles(\n lane.value,\n this.valueMode,\n this.flatten,\n );\n arcPath = generateArcPath(\n startAngle,\n endAngle,\n this.radius - lane.offset * this.radius,\n CENTER,\n );\n }\n\n if (!arcPath)\n return svg``;\n\n return svg`\n <path \n class=\"lane\" \n data-lane-key=\"${lane.key}\" \n part=\"lane lane-${lane.key}\"\n d=\"${arcPath}\"\n style=\"\n stroke-width: calc(var(--lane-${lane.key}-width, var(--lane-width)) * ${this.radius}%);\n stroke-linecap: round;\n \"\n />\n `;\n }\n\n #getNeedlePath(angle: number, length: number, offset: number): string {\n const startRadius = offset * this.radius;\n const endRadius = length * this.radius;\n\n const start = {\n x: CENTER.x + Math.cos(angle) * startRadius,\n y: CENTER.y + Math.sin(angle) * startRadius,\n };\n const end = {\n x: CENTER.x + Math.cos(angle) * endRadius,\n y: CENTER.y + Math.sin(angle) * endRadius,\n };\n\n return `M ${start.x} ${start.y} L ${end.x} ${end.y}`;\n }\n\n #renderValueMarker(needlePath?: string) {\n const relativeValue = this.#getRelativeValue();\n const { angle, position } = getMarkerPosition(\n relativeValue,\n this.valueMode,\n this.flatten,\n this.radius,\n CENTER,\n );\n\n const markerOffset = this.#getCssVar(`--marker-offset`, 1);\n const markerBorderWidth = this.#getCssVar(`--marker-border-width`, 0);\n const effectiveStyle = this.#getEffectiveMarkerStyle();\n\n if (effectiveStyle === `dot`) {\n const size = this.#getCssVar(`--marker-thickness`, 0.15);\n const r = size * this.radius;\n const dotX = CENTER.x + (position.x - CENTER.x) * markerOffset;\n const dotY = CENTER.y + (position.y - CENTER.y) * markerOffset;\n\n if (markerBorderWidth > 0) {\n return svg`\n <g class=\"value-marker\" part=\"value-marker\">\n <use href=\"#dot-path\" class=\"marker-border\" />\n <use href=\"#dot-path\" class=\"marker-fill\" />\n </g>\n `;\n }\n\n return svg`\n <g class=\"value-marker\" part=\"value-marker\">\n <circle cx=\"${dotX}\" cy=\"${dotY}\" r=\"${r}\" />\n </g>\n `;\n } else if (effectiveStyle === `needle`) {\n if (markerBorderWidth > 0 && needlePath) {\n return svg`\n <g class=\"value-marker\" part=\"value-marker\">\n <use href=\"#needle-path\" class=\"marker-border\" />\n <use href=\"#needle-path\" class=\"marker-fill\" />\n </g>\n `;\n }\n\n const length = this.#getCssVar(`--marker-length`, 0.8);\n const offset = this.#getCssVar(`--marker-offset`, 0.2);\n const path = this.#getNeedlePath(angle, length, offset);\n\n return svg`\n <g class=\"value-marker\" part=\"value-marker\">\n <path d=\"${path}\" />\n </g>\n `;\n }\n }\n\n #renderMidpointMarker() {\n // Only show in bipolar/unipolar modes\n if (this.valueMode !== `bipolar` && this.valueMode !== `unipolar`) {\n return svg``;\n }\n\n const { position } = getMidpointPosition(this.radius, CENTER);\n\n if (this.markerStyle === `dot`) {\n const size = this.#getCssVar(`--midpoint-thickness`, 0.08);\n return svg`\n <g class=\"midpoint-marker\" part=\"midpoint-marker\">\n <circle \n cx=\"${position.x}\" \n cy=\"${position.y}\" \n r=\"${size * this.radius}\" \n />\n </g>\n `;\n } else {\n // Needle style\n const length = this.#getCssVar(`--midpoint-length`, 0.15);\n const offset = this.#getCssVar(`--midpoint-offset`, 0.85);\n\n const angle = -Math.PI / 2; // Top of circle\n const startRadius = offset * this.radius;\n const endRadius = (offset + length) * this.radius;\n\n const start = {\n x: CENTER.x + Math.cos(angle) * startRadius,\n y: CENTER.y + Math.sin(angle) * startRadius,\n };\n const end = {\n x: CENTER.x + Math.cos(angle) * endRadius,\n y: CENTER.y + Math.sin(angle) * endRadius,\n };\n\n return svg`\n <g class=\"midpoint-marker\" part=\"midpoint-marker\">\n <line \n x1=\"${start.x}\" \n y1=\"${start.y}\" \n x2=\"${end.x}\" \n y2=\"${end.y}\" \n />\n </g>\n `;\n }\n }\n\n #getCssVar(name: string, defaultValue: number): number {\n const style = getComputedStyle(this);\n const val = style.getPropertyValue(name).trim();\n if (!val)\n return defaultValue;\n\n // Handle CSS calc() expressions with var(--value-relative)\n if (val.includes(`calc(`)) {\n // Get the current --value-relative value\n const valueRelative = style.getPropertyValue(`--value-relative`).trim();\n if (!valueRelative) {\n // Fallback to default if --value-relative not set\n const parsed = Number.parseFloat(val.replace(/[^0-9.-]/g, ``));\n return Number.isNaN(parsed) ? defaultValue : parsed;\n }\n\n // Replace var(--value-relative) with the actual value\n const evalStr = val.replace(/var\\(--value-relative\\)/g, valueRelative);\n\n // Use Function constructor for safe evaluation (no eval)\n try {\n // Create a function that evaluates math expressions\n // eslint-disable-next-line no-new-func\n const fn = new Function(`return ${evalStr.replace(/calc\\s*\\(([^)]+)\\)/g, `$1`)}`);\n const result = fn();\n return typeof result === `number` && !Number.isNaN(result) ? result : defaultValue;\n } catch {\n // Fallback: try to parse just numbers\n const parsed = Number.parseFloat(val.replace(/[^0-9.-]/g, ``));\n return Number.isNaN(parsed) ? defaultValue : parsed;\n }\n }\n\n const parsed = Number.parseFloat(val);\n return Number.isNaN(parsed) ? defaultValue : parsed;\n }\n\n // Lifecycle methods\n\n protected override willUpdate(changed: PropertyValues): void {\n super.willUpdate(changed);\n\n // Ensure value lane reflects current value before first render\n // This handles declaratively set initial values\n if (changed.has(`value`) || !this.hasUpdated) {\n const valueLane = this.#lanes.get(`value`);\n if (valueLane && valueLane.type === `value`) {\n valueLane.value = this.#getRelativeValue();\n }\n }\n }\n\n override render(): unknown {\n const lanes = Array.from(this.#lanes.values());\n\n const relativeValue = this.#getRelativeValue();\n const { angle, position } = getMarkerPosition(\n relativeValue,\n this.valueMode,\n this.flatten,\n this.radius,\n CENTER,\n );\n\n const needleLength = this.#getCssVar(`--marker-length`, 0.8);\n const needleOffset = this.#getCssVar(`--marker-offset`, 0.2);\n const markerBorderWidth = this.#getCssVar(`--marker-border-width`, 0);\n const needlePath = markerBorderWidth > 0 ? this.#getNeedlePath(angle, needleLength, needleOffset) : undefined;\n\n const dotSize = this.#getCssVar(`--marker-thickness`, 0.15);\n const dotR = dotSize * this.radius;\n\n const defs = [];\n if (needlePath) {\n defs.push(svg`<path id=\"needle-path\" d=\"${needlePath}\" />`);\n }\n if (markerBorderWidth > 0) {\n defs.push(svg`<circle id=\"dot-path\" cx=\"${position.x}\" cy=\"${position.y}\" r=\"${dotR}\" />`);\n }\n\n return html`\n <svg\n viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"xMidYMid meet\"\n tabindex=\"${this.disabled ? -1 : 0}\"\n @pointerdown=\"${this.#onPointerDown}\"\n @keydown=\"${this.#onKeyDown}\"\n style=\"cursor: ${this.#dragging ? `ns-resize` : `grab`}\"\n >\n ${defs.length > 0 ? svg`<defs>${defs}</defs>` : ``}\n ${this.#renderCircleFill()}\n ${this.wedge ? this.#renderWedge() : ``}\n ${this.#renderCircleBorder()}\n ${lanes.map(lane => this.#renderLane(lane))}\n ${this.#renderMidpointMarker()}\n ${this.#renderValueMarker(needlePath)}\n </svg>\n `;\n }\n\n protected override updated(changed: PropertyValues): void {\n super.updated(changed);\n\n // Update --radius CSS variable when property changes\n if (changed.has(`radius`)) {\n this.style.setProperty(`--radius`, `${this.radius}%`);\n }\n\n // Update --value-relative CSS variable\n this.style.setProperty(`--value-relative`, this.#getRelativeValue().toString());\n\n // Adjust component height based on flatten to reduce wasted vertical space.\n // The dial is flattened at the top, so we don't need full height.\n if (changed.has(`flatten`)) {\n const markerThickness = this.#getCssVar(`--marker-thickness`, 0.15);\n const radius = this.#getCssVar(`--radius`, 45);\n const markerPadding = Math.round(markerThickness * radius) + 5;\n const viewBoxHeight = Math.round(100 * (1 - this.flatten)) + markerPadding;\n // Set CSS variable to control host height\n this.style.setProperty(`--dial-height`, `${viewBoxHeight}px`);\n // Also update SVG viewBox to match\n const svg = this.renderRoot.querySelector(`svg`);\n if (svg) {\n svg.setAttribute(`viewBox`, `0 0 100 ${viewBoxHeight}`);\n }\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n if (this.#changeDebounceTimer !== undefined) {\n clearTimeout(this.#changeDebounceTimer);\n }\n this.#onPointerUp();\n }\n\n override firstUpdated(): void {\n const markerThickness = this.#getCssVar(`--marker-thickness`, 0.15);\n const radius = this.#getCssVar(`--radius`, 45);\n const markerPadding = Math.round(markerThickness * radius);\n const viewBoxHeight = Math.round(100 * (1 - this.flatten)) + markerPadding;\n this.style.setProperty(`--dial-height`, `${viewBoxHeight}px`);\n const svg = this.renderRoot.querySelector(`svg`);\n if (svg) {\n svg.setAttribute(`viewBox`, `0 0 100 ${viewBoxHeight}`);\n }\n }\n\n static override styles = [themeFallbacks, prominenceStyles, css`\n :host {\n display: inline-block;\n width: 100px;\n height: var(--dial-height, 100px);\n touch-action: none;\n user-select: none;\n tabindex: 0;\n\n /* Dynamic value - set by JS */\n --value-relative: 0;\n\n /* Lane widths (used in stroke-width calculations) */\n --lane-width: 0.16;\n --lane-track-width: 0.08;\n --lane-value-width: 0.12;\n }\n\n :host([disabled]) {\n cursor: not-allowed;\n }\n\n svg {\n width: 100%;\n height: 100%;\n outline: none;\n }\n\n svg:active {\n cursor: grabbing;\n }\n\n svg:focus-visible {\n outline: var(--radial-input-svg-focus-outline, 2px solid var(--accent));\n outline-offset: var(--radial-input-svg-focus-outline-offset, 2px);\n }\n\n .dial-border {\n fill: none;\n stroke: var(--dial-border-color, var(--surface-4));\n stroke-width: var(--dial-border-width, 2px);\n stroke-linecap: round;\n vector-effect: non-scaling-stroke;\n }\n\n .dial-fill {\n fill: var(--dial-fill, transparent);\n }\n\n .wedge {\n fill: var(--wedge-fill, var(--accent));\n fill-opacity: var(--wedge-fill-opacity, 0.25);\n stroke: var(--wedge-border-color, var(--accent));\n stroke-width: var(--wedge-border-width, 0);\n stroke-opacity: var(--wedge-border-opacity, 1);\n vector-effect: non-scaling-stroke;\n }\n\n .lane {\n fill: none;\n stroke-linecap: round;\n stroke-dasharray: var(--lane-dasharray, none);\n stroke-dashoffset: var(--lane-dashoffset, 0);\n vector-effect: non-scaling-stroke;\n }\n\n .lane[data-lane-key='track'] {\n stroke: var(--lane-track-color, var(--surface-4));\n }\n\n .lane[data-lane-key='value'] {\n stroke: var(--lane-value-color, var(--accent));\n }\n\n .lane:not([data-lane-key='track']):not([data-lane-key='value']) {\n stroke: var(--lane-color, var(--accent));\n }\n\n .value-marker path,\n .value-marker .marker-fill {\n stroke: var(--marker-color, var(--accent));\n stroke-width: calc(var(--marker-thickness, 0.15) * var(--radius, 45%));\n stroke-linecap: round;\n stroke-dasharray: var(--marker-dasharray, none);\n stroke-dashoffset: var(--marker-dashoffset, 0);\n vector-effect: non-scaling-stroke;\n }\n\n .value-marker .marker-border {\n stroke: var(--marker-border-color, transparent);\n stroke-width: calc((var(--marker-thickness, 0.15) + var(--marker-border-width, 0) * 2) * var(--radius, 45%));\n stroke-linecap: round;\n vector-effect: non-scaling-stroke;\n }\n\n .value-marker .marker-border {\n fill: none;\n }\n\n .value-marker .marker-fill,\n .value-marker circle {\n fill: var(--marker-color, var(--accent));\n }\n\n .midpoint-marker line {\n stroke: var(--midpoint-color, var(--surface-muted-text));\n stroke-width: var(--midpoint-thickness, 1px);\n stroke-linecap: round;\n vector-effect: non-scaling-stroke;\n }\n\n .midpoint-marker circle {\n fill: var(--midpoint-color, var(--surface-muted-text));\n stroke: var(--midpoint-border-color, transparent);\n stroke-width: var(--midpoint-border-width, 0);\n vector-effect: non-scaling-stroke;\n }\n `];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-radial-input': RadialInputElement;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"radial-input-KMVltQfe.js","names":["#_radius","#dragging","#dragStartY","#valueAtDragStart","#onPointerMove","#onPointerUp","#setValueFromRelative","#stepByRelativeDelta","#lanes","#getRelativeValue","#quantise","#isUserInteraction","#scheduleChangeEvent","#fireChangeEvent","#changeDebounceTimer","#getCssVar","#getEffectiveMarkerStyle","#getNeedlePath","#onPointerDown","#onKeyDown","#renderCircleFill","#renderWedge","#renderCircleBorder","#renderLane","#renderMidpointMarker","#renderValueMarker","customElement"],"sources":["../src/radial-input/svg-utils.ts","../src/radial-input/radial-input.ts"],"sourcesContent":["/**\n * SVG utilities for radial input component\n * Handles geometry calculations for flattened circle arcs\n */\n\nimport type { ValueMode } from './types.js';\n\nexport interface Point {\n x: number;\n y: number;\n}\n\nexport interface ArcParameters {\n startAngle: number; // radians\n endAngle: number; // radians\n radius: number;\n center: Point;\n}\n\nconst PI2 = Math.PI * 2;\nconst MIDPOINT_ANGLE = -Math.PI / 2; // Top-center of circle\n\n/**\n * Convert polar coordinates (angle in radians, radius) to SVG Cartesian coordinates\n * @param angle - Angle in radians (0 = right/east, increases clockwise in SVG)\n * @param radius - Distance from center\n * @param center - Center point (default: {x: 50, y: 50})\n * @returns Point in SVG coordinates\n */\nexport function polarToCartesian(\n angle: number,\n radius: number,\n center: Point = { x: 50, y: 50 },\n): Point {\n return {\n x: center.x + Math.cos(angle) * radius,\n y: center.y + Math.sin(angle) * radius,\n };\n}\n\n/**\n * Convert SVG Cartesian coordinates to polar (angle in radians, radius)\n * @param x - X coordinate\n * @param y - Y coordinate\n * @param center - Center point (default: {x: 50, y: 50})\n * @returns Angle in radians (0..2π) and radius\n */\nexport function cartesianToPolar(\n x: number,\n y: number,\n center: Point = { x: 50, y: 50 },\n): { angle: number; radius: number } {\n const dx = x - center.x;\n const dy = y - center.y;\n const radius = Math.sqrt(dx * dx + dy * dy);\n const raw = Math.atan2(dy, dx);\n const angle = ((raw % PI2) + PI2) % PI2; // Normalize to 0..2π\n return { angle, radius };\n}\n\n/**\n * Calculate start and end angles for a flattened circle\n * @param flatten - How much of the circle to hide (0..1): 0 = full circle, 0.5 = half circle, 1 = no arc\n * @returns Start and end angles in radians\n */\nexport function getFlattenedCircleAngles(flatten: number): {\n startAngle: number;\n endAngle: number;\n totalArc: number;\n} {\n // flatten represents the percentage of circle hidden\n // 0 = full circle (360°), 0.5 = half circle (180°), 1 = no arc (0°)\n const visibleArc = PI2 * (1 - flatten); // Total visible arc in radians\n\n // Center the visible arc at the top (angle = -π/2)\n // Start and end angles are symmetric around top-center\n const halfArc = visibleArc / 2;\n const topAngle = -Math.PI / 2; // Top center (270° in standard coords, but -90° from east)\n\n const startAngle = topAngle - halfArc;\n const endAngle = topAngle + halfArc;\n const totalArc = endAngle - startAngle;\n\n return { startAngle, endAngle, totalArc };\n}\n\n/**\n * Map a value (0..1) to an angle based on value mode\n * @param relativeValue - Value in 0..1 range\n * @param valueMode - How to interpret the value\n * @param flatten - Circle flattening amount (0..1)\n * @returns Angle in radians\n */\nexport function valueToAngle(\n relativeValue: number,\n valueMode: ValueMode,\n flatten: number,\n): number {\n const { startAngle, endAngle, totalArc } = getFlattenedCircleAngles(flatten);\n\n switch (valueMode) {\n case `range`:\n // Linear mapping from start to end\n return startAngle + relativeValue * totalArc;\n\n case `bipolar`: {\n // Midpoint is at top (MIDPOINT_ANGLE = -π/2)\n if (relativeValue <= 0.5) {\n // Map 0..0.5 to startAngle..MIDPOINT_ANGLE (going counterclockwise to top)\n const t = relativeValue / 0.5;\n return startAngle + t * (MIDPOINT_ANGLE - startAngle);\n } else {\n // Map 0.5..1 to MIDPOINT_ANGLE..endAngle (going clockwise from top)\n const t = (relativeValue - 0.5) / 0.5;\n return MIDPOINT_ANGLE + t * (endAngle - MIDPOINT_ANGLE);\n }\n }\n\n case `unipolar`: {\n // Marker stays at top for unipolar mode\n return MIDPOINT_ANGLE;\n }\n\n default:\n return startAngle;\n }\n}\n\n/**\n * Get start and end angles for a value arc\n * @param relativeValue - Value in 0..1 range\n * @param valueMode - How to interpret the value\n * @param flatten - Circle flattening amount (0..1)\n * @returns Start and end angles for the arc\n */\nexport function getValueArcAngles(\n relativeValue: number,\n valueMode: ValueMode,\n flatten: number,\n): { startAngle: number; endAngle: number } {\n const { startAngle, endAngle, totalArc } = getFlattenedCircleAngles(flatten);\n\n switch (valueMode) {\n case `range`:\n // Arc from start to value position\n return {\n startAngle,\n endAngle: startAngle + relativeValue * totalArc,\n };\n\n case `bipolar`: {\n // Midpoint is at top (MIDPOINT_ANGLE = -π/2)\n if (relativeValue < 0.5) {\n // Arc from some point toward top (going counterclockwise)\n const t = relativeValue / 0.5;\n const valueAngle = startAngle + t * (MIDPOINT_ANGLE - startAngle);\n return {\n startAngle: valueAngle,\n endAngle: MIDPOINT_ANGLE,\n };\n } else if (relativeValue > 0.5) {\n // Arc from top going clockwise\n const t = (relativeValue - 0.5) / 0.5;\n const valueAngle = MIDPOINT_ANGLE + t * (endAngle - MIDPOINT_ANGLE);\n return {\n startAngle: MIDPOINT_ANGLE,\n endAngle: valueAngle,\n };\n } else {\n // Exactly at midpoint, no arc\n return { startAngle: MIDPOINT_ANGLE, endAngle: MIDPOINT_ANGLE };\n }\n }\n\n case `unipolar`: {\n // Spread symmetrically from top (MIDPOINT_ANGLE = -π/2)\n const spreadAmount = relativeValue * totalArc / 2;\n return {\n startAngle: MIDPOINT_ANGLE - spreadAmount,\n endAngle: MIDPOINT_ANGLE + spreadAmount,\n };\n }\n\n default:\n return { startAngle, endAngle: startAngle };\n }\n}\n\n/**\n * Get start and end angles for an anchored arc\n * Centered on current value position, extends equally in both directions\n * @param relativeValue - Current value position (0..1)\n * @param laneValue - Width of the arc (0..1, where 1 = full range)\n * @param valueMode - How to interpret the value\n * @param flatten - Circle flattening amount (0..1)\n * @returns Start and end angles for the arc\n */\nexport function getAnchoredArcAngles(\n relativeValue: number,\n laneValue: number,\n valueMode: ValueMode,\n flatten: number,\n): { startAngle: number; endAngle: number } {\n const { startAngle, endAngle, totalArc } = getFlattenedCircleAngles(flatten);\n\n // Get the angle for the current value (this is the center of the arc)\n const centerAngle = valueToAngle(relativeValue, valueMode, flatten);\n\n // Calculate half-width of the arc\n // laneValue is 0..1, where 1 = full range\n const halfWidth = (laneValue * totalArc) / 2;\n\n let arcStart = centerAngle - halfWidth;\n let arcEnd = centerAngle + halfWidth;\n\n // Clamp to valid bounds (prevent wrapping)\n // The valid range is [startAngle, endAngle]\n if (arcStart < startAngle)\n arcStart = startAngle;\n if (arcEnd > endAngle)\n arcEnd = endAngle;\n\n // If the arc would be degenerate after clamping, return a single point\n if (arcStart >= arcEnd) {\n return { startAngle: centerAngle, endAngle: centerAngle };\n }\n\n return { startAngle: arcStart, endAngle: arcEnd };\n}\n\n/**\n * Generate SVG path for an arc\n * @param startAngle - Start angle in radians\n * @param endAngle - End angle in radians\n * @param radius - Arc radius\n * @param center - Center point\n * @returns SVG path data string\n */\nexport function generateArcPath(\n startAngle: number,\n endAngle: number,\n radius: number,\n center: Point = { x: 50, y: 50 },\n): string {\n if (startAngle === endAngle) {\n return ``; // No arc to draw\n }\n\n // Calculate arc length to determine large-arc-flag\n let arcLength = endAngle - startAngle;\n\n // Handle wrap-around case (e.g., from 5.5 to 0.5 radians)\n if (arcLength < 0) {\n arcLength += PI2;\n }\n\n // Handle full or near-full circle case\n // When arcLength is nearly 2π, start and end points are essentially the same\n // and drawing a full circle needs special handling\n if (arcLength >= PI2 - 0.001) {\n // Draw a full circle by going almost all the way around\n const adjustedEnd = startAngle + PI2 - 0.001;\n const start = polarToCartesian(startAngle, radius, center);\n const end = polarToCartesian(adjustedEnd, radius, center);\n return `M ${start.x},${start.y} A ${radius},${radius} 0 1 1 ${end.x},${end.y}`;\n }\n\n const start = polarToCartesian(startAngle, radius, center);\n const end = polarToCartesian(endAngle, radius, center);\n\n const largeArcFlag = arcLength > Math.PI ? 1 : 0;\n\n return `M ${start.x},${start.y} A ${radius},${radius} 0 ${largeArcFlag} 1 ${end.x},${end.y}`;\n}\n\n/**\n * Generate SVG path for a full flattened circle border\n * @param radius - Circle radius\n * @param flatten - Flattening amount (0..1)\n * @param center - Center point\n * @returns SVG path data string\n */\nexport function generateCircleBorderPath(\n radius: number,\n flatten: number,\n center: Point = { x: 50, y: 50 },\n): string {\n const { startAngle, endAngle } = getFlattenedCircleAngles(flatten);\n return generateArcPath(startAngle, endAngle, radius, center);\n}\n\n/**\n * Generate SVG path data for a filled wedge (pie-slice) sector\n * @param startAngle - Start angle in radians\n * @param endAngle - End angle in radians\n * @param radius - Wedge radius (same as dial radius)\n * @param center - Center point\n * @param clockwise - Whether to draw arc clockwise (true) or counterclockwise (false)\n * @returns SVG path data string for filled wedge\n */\nexport function generateWedgePath(\n startAngle: number,\n endAngle: number,\n radius: number,\n center: Point = { x: 50, y: 50 },\n clockwise: boolean = true,\n): string {\n if (startAngle === endAngle) {\n return ``; // No wedge to draw\n }\n\n // Calculate arc length (always positive, representing shortest path)\n let arcLength = endAngle - startAngle;\n if (arcLength < 0) {\n arcLength += PI2;\n }\n\n // Handle full or near-full circle case\n if (arcLength >= PI2 - 0.001) {\n // Draw a near-full circle wedge\n const start = polarToCartesian(startAngle, radius, center);\n const adjustedEnd = startAngle + PI2 - 0.001;\n const adjEnd = polarToCartesian(adjustedEnd, radius, center);\n const largeArcFlag = 1;\n const sweepFlag = clockwise ? 1 : 0;\n return `M ${center.x},${center.y} L ${start.x},${start.y} A ${radius},${radius} 0 ${largeArcFlag} ${sweepFlag} ${adjEnd.x},${adjEnd.y} Z`;\n }\n\n let actualStartAngle = startAngle;\n let actualEndAngle = endAngle;\n let actualClockwise = clockwise;\n\n // When going counterclockwise and arcLength > π, we want the short clockwise path instead\n // by swapping start and end\n if (!clockwise && arcLength > Math.PI) {\n actualStartAngle = endAngle;\n actualEndAngle = startAngle;\n actualClockwise = true;\n arcLength = PI2 - arcLength;\n }\n\n const start = polarToCartesian(actualStartAngle, radius, center);\n const end = polarToCartesian(actualEndAngle, radius, center);\n\n const largeArcFlag = arcLength > Math.PI ? 1 : 0;\n const sweepFlag = actualClockwise ? 1 : 0;\n\n // M center L start A radius radius 0 large sweep end Z\n return `M ${center.x},${center.y} L ${start.x},${start.y} A ${radius},${radius} 0 ${largeArcFlag} ${sweepFlag} ${end.x},${end.y} Z`;\n}\n\n/**\n * Get wedge angles based on value mode\n * @param relativeValue - Value in 0..1 range\n * @param valueMode - How to interpret the value\n * @param flatten - Circle flattening amount (0..1)\n * @returns Object with startAngle, endAngle, and clockwise flag\n */\nexport function getWedgeAngles(\n relativeValue: number,\n valueMode: ValueMode,\n flatten: number,\n): { startAngle: number; endAngle: number; clockwise: boolean } {\n const { startAngle, totalArc } = getFlattenedCircleAngles(flatten);\n const valueAngle = valueToAngle(relativeValue, valueMode, flatten);\n\n switch (valueMode) {\n case `range`:\n // Wedge from startAngle to valueAngle (always clockwise)\n return {\n startAngle,\n endAngle: valueAngle,\n clockwise: true,\n };\n\n case `bipolar`: {\n // When value < 0.5, go counterclockwise from midpoint to value\n // When value >= 0.5, go clockwise from midpoint to value\n if (relativeValue < 0.5) {\n return {\n startAngle: MIDPOINT_ANGLE,\n endAngle: valueAngle,\n clockwise: false,\n };\n } else {\n return {\n startAngle: MIDPOINT_ANGLE,\n endAngle: valueAngle,\n clockwise: true,\n };\n }\n }\n\n case `unipolar`: {\n // Wedge centered at MIDPOINT, spreading value * totalArc/2 in each direction\n const halfSpread = relativeValue * totalArc / 2;\n return {\n startAngle: MIDPOINT_ANGLE - halfSpread,\n endAngle: MIDPOINT_ANGLE + halfSpread,\n clockwise: true,\n };\n }\n\n default:\n return { startAngle, endAngle: startAngle, clockwise: true };\n }\n}\n\n/**\n * Get position for a marker (needle or dot) at a given value\n * @param relativeValue - Value in 0..1 range\n * @param valueMode - How to interpret the value\n * @param flatten - Circle flattening amount (0..1)\n * @param radius - Circle radius\n * @param center - Center point\n * @returns Angle in radians and position point\n */\nexport function getMarkerPosition(\n relativeValue: number,\n valueMode: ValueMode,\n flatten: number,\n radius: number,\n center: Point = { x: 50, y: 50 },\n): { angle: number; position: Point } {\n const angle = valueToAngle(relativeValue, valueMode, flatten);\n const position = polarToCartesian(angle, radius, center);\n return { angle, position };\n}\n\n/**\n * Get position for midpoint marker (used in bipolar/unipolar modes)\n * @param radius - Circle radius\n * @param center - Center point\n * @returns Position at top-center of circle\n */\nexport function getMidpointPosition(\n radius: number,\n center: Point = { x: 50, y: 50 },\n): { angle: number; position: Point } {\n const position = polarToCartesian(MIDPOINT_ANGLE, radius, center);\n return { angle: MIDPOINT_ANGLE, position };\n}\n\n/**\n * Clamp a value between min and max\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\n/**\n * Scale a value from one range to another\n */\nexport function scale(\n value: number,\n fromMin: number,\n fromMax: number,\n toMin: number,\n toMax: number,\n): number {\n const normalized = (value - fromMin) / (fromMax - fromMin);\n return toMin + normalized * (toMax - toMin);\n}\n","/**\n * Radial input component\n * A rotary dial input inspired by Ableton Live and music production software.\n *\n * Mouse wheel: up = increase, down = decrease, with the same step resolution as\n * arrow keys (Shift halves the step). The dial must have focus by default, or\n * set the `lighttouch` boolean attribute to react on hover instead. See\n * `docs/infra-mousewheel.md`.\n */\n\nimport type { PropertyValues } from 'lit';\nimport type { WheelDirection } from '../mixins/wheel-nudge.js';\nimport type {\n LaneData,\n LaneType,\n MarkerStyle,\n RadialInputChangeDetail,\n RadialInputInputDetail,\n ValueMode,\n} from './types.js';\nimport { css, html, LitElement, svg } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport { KEY_STEP_DIVISOR, resolveAxisStep } from '../keyboard.js';\nimport { WheelNudgeMixin } from '../mixins/wheel-nudge.js';\nimport { themeFallbacks } from '../styles/fallbacks.js';\nimport { prominenceStyles } from '../styles/prominence.js';\nimport { safeCustomElement as customElement } from '../util/custom-elements.js';\nimport {\n clamp,\n generateArcPath,\n generateCircleBorderPath,\n generateWedgePath,\n getAnchoredArcAngles,\n getMarkerPosition,\n getMidpointPosition,\n getValueArcAngles,\n getWedgeAngles,\n scale,\n} from './svg-utils.js';\n\nconst CENTER = { x: 50, y: 50 }; // Center point in viewBox\n\n@customElement(`ixfx-radial-input`)\nexport class RadialInputElement extends WheelNudgeMixin(LitElement) {\n // Internal backing field for radius (used with custom setter for clamping)\n #_radius = 45;\n\n // Radius property (controls dial size, 10-50 range to prevent clipping)\n @property({ type: Number })\n get radius(): number {\n return this.#_radius;\n }\n\n set radius(v: number) {\n this.#_radius = clamp(v, 10, 50);\n }\n\n // Value properties (matches ixfx-range API)\n @property({ type: Number })\n value = 0;\n\n @property({ type: Number })\n min = 0;\n\n @property({ type: Number })\n max = 100;\n\n @property({ type: Number })\n step: number | undefined = undefined;\n\n @property({ type: Number })\n stops?: number;\n\n // Value mode\n @property({ type: String, attribute: `value-mode` })\n valueMode: ValueMode = `range`;\n\n // Appearance\n @property({ type: Number })\n flatten = 0.3;\n\n @property({ type: String, attribute: `marker-style` })\n markerStyle: MarkerStyle = `needle`;\n\n @property({ type: Boolean })\n wedge = false;\n\n // Interaction\n @property({ type: Boolean, reflect: true })\n disabled = false;\n\n // Internal state\n #lanes: Map<string, LaneData> = new Map();\n #dragging = false;\n #dragStartY = 0;\n #valueAtDragStart = 0;\n #changeDebounceTimer: number | undefined;\n #isUserInteraction = false;\n\n constructor() {\n super();\n // Initialize default lanes\n // Note: value lane will be updated in willUpdate() to reflect initial value\n this.#lanes.set(`track`, {\n key: `track`,\n value: 1, // Full range\n type: `fixed`,\n offset: 0,\n width: 0.16,\n });\n this.#lanes.set(`value`, {\n key: `value`,\n value: 0, // Will be updated in willUpdate()\n type: `value`,\n offset: 0,\n width: 0.24,\n });\n }\n\n // Lane management API\n addLane(\n key: string,\n options?: {\n value?: number;\n type?: LaneType;\n offset?: number;\n width?: number;\n },\n ): void {\n const relativeValue = this.#getRelativeValue();\n this.#lanes.set(key, {\n key,\n value: options?.value ?? relativeValue,\n type: options?.type ?? `value`,\n offset: options?.offset ?? 0,\n width: options?.width ?? 0.1,\n });\n this.requestUpdate();\n }\n\n setLaneValue(key: string, value: number): void {\n const lane = this.#lanes.get(key);\n if (lane) {\n lane.value = clamp(value, 0, 1);\n this.requestUpdate();\n }\n }\n\n removeLane(key: string): void {\n this.#lanes.delete(key);\n this.requestUpdate();\n }\n\n getLanes(): ReadonlyMap<string, LaneData> {\n return new Map(this.#lanes);\n }\n\n getLane(key: string): LaneData | undefined {\n return this.#lanes.get(key);\n }\n\n // Internal helpers\n #getRelativeValue(): number {\n return scale(this.value, this.min, this.max, 0, 1);\n }\n\n #getEffectiveMarkerStyle(): MarkerStyle {\n if (this.valueMode === `unipolar` && this.markerStyle === `needle`) {\n return `none`;\n }\n return this.markerStyle;\n }\n\n #quantise(value: number): number {\n if (this.stops && this.stops > 1) {\n const range = this.max - this.min;\n const step = range / this.stops;\n return Math.round((value - this.min) / step) * step + this.min;\n }\n return value;\n }\n\n #setValueFromRelative(relativeValue: number, isUserInteraction = false): void {\n const newValue = scale(relativeValue, 0, 1, this.min, this.max);\n const clampedValue = this.#quantise(clamp(newValue, this.min, this.max));\n\n if (clampedValue === this.value)\n return;\n\n const previousValue = this.value;\n this.value = clampedValue;\n this.#isUserInteraction = isUserInteraction;\n\n // Update 'value' lane if it exists\n const valueLane = this.#lanes.get(`value`);\n if (valueLane && valueLane.type === `value`) {\n valueLane.value = this.#getRelativeValue();\n }\n\n // Update data-tooltip for live tooltips\n if (this.hasAttribute(`data-tooltip-live`)) {\n const percentage = Math.round(this.#getRelativeValue() * 100);\n this.setAttribute(`data-tooltip`, `${percentage}%`);\n }\n\n // Fire input event only for user interactions\n if (isUserInteraction) {\n this.dispatchEvent(\n new CustomEvent<RadialInputInputDetail>(`input`, {\n detail: {\n value: this.value,\n valueRelative: this.#getRelativeValue(),\n },\n bubbles: true,\n composed: true,\n }),\n );\n\n // Debounce change event\n this.#scheduleChangeEvent(previousValue);\n } else {\n // Immediate change event for programmatic changes\n this.#fireChangeEvent(previousValue);\n }\n }\n\n #scheduleChangeEvent(previousValue: number): void {\n if (this.#changeDebounceTimer !== undefined) {\n clearTimeout(this.#changeDebounceTimer);\n }\n\n this.#changeDebounceTimer = window.setTimeout(() => {\n this.#fireChangeEvent(previousValue);\n this.#changeDebounceTimer = undefined;\n }, 150);\n }\n\n #fireChangeEvent(previousValue: number): void {\n this.dispatchEvent(\n new CustomEvent<RadialInputChangeDetail>(`change`, {\n detail: {\n value: this.value,\n valueRelative: this.#getRelativeValue(),\n previousValue,\n },\n bubbles: true,\n composed: true,\n }),\n );\n }\n\n // Pointer interaction handlers\n #onPointerDown = (event: PointerEvent): void => {\n if (this.disabled)\n return;\n\n event.preventDefault();\n const svg = this.renderRoot.querySelector(`svg`);\n svg?.focus();\n this.#dragging = true;\n this.#dragStartY = event.clientY;\n this.#valueAtDragStart = this.value;\n this.toggleAttribute(`dragging`, true);\n\n if (svg) {\n svg.setPointerCapture(event.pointerId);\n }\n\n window.addEventListener(`pointermove`, this.#onPointerMove);\n window.addEventListener(`pointerup`, this.#onPointerUp);\n window.addEventListener(`pointercancel`, this.#onPointerUp);\n };\n\n #onPointerMove = (event: PointerEvent): void => {\n if (!this.#dragging)\n return;\n\n event.preventDefault();\n\n // Calculate sensitivity: full range = 2× component height\n const sensitivity = this.clientHeight * 2;\n const shiftDivisor = event.shiftKey ? KEY_STEP_DIVISOR : 1;\n const effectiveSensitivity = sensitivity * shiftDivisor;\n\n // Calculate delta (negative because up = increase)\n const deltaY = this.#dragStartY - event.clientY;\n const deltaValue = (deltaY / effectiveSensitivity) * (this.max - this.min);\n const newValue = this.#valueAtDragStart + deltaValue;\n\n const relativeValue = scale(newValue, this.min, this.max, 0, 1);\n this.#setValueFromRelative(clamp(relativeValue, 0, 1), true);\n };\n\n #onPointerUp = (): void => {\n this.#dragging = false;\n this.toggleAttribute(`dragging`, false);\n\n const svg = this.renderRoot.querySelector(`svg`);\n if (svg && `hasPointerCapture` in svg && typeof svg.hasPointerCapture === `function`) {\n if (svg.hasPointerCapture(1)) {\n svg.releasePointerCapture(1);\n }\n }\n\n window.removeEventListener(`pointermove`, this.#onPointerMove);\n window.removeEventListener(`pointerup`, this.#onPointerUp);\n window.removeEventListener(`pointercancel`, this.#onPointerUp);\n };\n\n // Keyboard interaction handler\n #onKeyDown = (event: KeyboardEvent): void => {\n if (this.disabled)\n return;\n\n const range = this.max - this.min;\n const effectiveStep = resolveAxisStep(range, this.stops, this.step, event.shiftKey);\n\n let handled = false;\n\n switch (event.key) {\n case `ArrowUp`:\n case `ArrowRight`:\n this.#stepByRelativeDelta(effectiveStep / range, true);\n handled = true;\n break;\n\n case `ArrowDown`:\n case `ArrowLeft`:\n this.#stepByRelativeDelta(-effectiveStep / range, true);\n handled = true;\n break;\n\n case `Home`:\n this.#setValueFromRelative(0, true);\n handled = true;\n break;\n\n case `End`:\n this.#setValueFromRelative(1, true);\n handled = true;\n break;\n }\n\n if (handled) {\n event.preventDefault();\n }\n };\n\n /**\n * Apply a relative-delta nudge to the current value, clamped to [min, max] and\n * quantised. Shared between keyboard arrow keys and the wheel handler.\n */\n #stepByRelativeDelta(relativeDelta: number, isUserInteraction: boolean): void {\n this.#setValueFromRelative(\n clamp(this.#getRelativeValue() + relativeDelta, 0, 1),\n isUserInteraction,\n );\n }\n\n // Wheel handler — installed by WheelNudgeMixin on the host. Inverted from the\n // shared convention (`docs/infra-mousewheel.md`): wheel forward/up decreases\n // the value, wheel backward/down increases it. Matches the perceived\n // rotation of a physical rotary dial — turning the dial clockwise is the\n // most natural \"forward\" gesture and should reduce the value.\n override _applyWheelDelta(direction: WheelDirection, event: WheelEvent): void {\n const range = this.max - this.min;\n const effectiveStep = resolveAxisStep(range, this.stops, this.step, event.shiftKey);\n this.#stepByRelativeDelta(-direction * effectiveStep / range, true);\n }\n\n // Rendering helpers\n #renderCircleBorder() {\n const path = generateCircleBorderPath(this.radius, this.flatten, CENTER);\n const borderWidth = this.#getCssVar(`--dial-border-width`, 2);\n const borderColor = getComputedStyle(this).getPropertyValue(`--dial-border-color`).trim() || `var(--surface-4)`;\n return svg`<path class=\"dial-border\" d=\"${path}\" fill=\"none\" stroke=\"${borderColor}\" stroke-width=\"${borderWidth}\" stroke-linecap=\"round\" vector-effect=\"non-scaling-stroke\" />`;\n }\n\n #renderCircleFill() {\n const path = generateCircleBorderPath(this.radius, this.flatten, CENTER);\n const fill = getComputedStyle(this).getPropertyValue(`--dial-fill`).trim() || `transparent`;\n return svg`<path class=\"dial-fill\" d=\"${path}\" fill=\"${fill}\" />`;\n }\n\n #renderWedge() {\n const relativeValue = this.#getRelativeValue();\n const { startAngle, endAngle, clockwise } = getWedgeAngles(\n relativeValue,\n this.valueMode,\n this.flatten,\n );\n\n const path = generateWedgePath(startAngle, endAngle, this.radius, CENTER, clockwise);\n if (!path)\n return svg``;\n\n return svg`<path class=\"wedge\" d=\"${path}\" />`;\n }\n\n #renderLane(lane: LaneData) {\n let arcPath = ``;\n\n if (lane.type === `fixed`) {\n // Fixed lanes always show full range\n arcPath = generateCircleBorderPath(\n this.radius - lane.offset * this.radius,\n this.flatten,\n CENTER,\n );\n } else if (lane.type === `anchored`) {\n // Anchored lanes: centered on current value, arc width based on lane.value\n const { startAngle, endAngle } = getAnchoredArcAngles(\n this.#getRelativeValue(),\n lane.value,\n this.valueMode,\n this.flatten,\n );\n arcPath = generateArcPath(\n startAngle,\n endAngle,\n this.radius - lane.offset * this.radius,\n CENTER,\n );\n } else {\n // Value lanes follow the value mode\n const { startAngle, endAngle } = getValueArcAngles(\n lane.value,\n this.valueMode,\n this.flatten,\n );\n arcPath = generateArcPath(\n startAngle,\n endAngle,\n this.radius - lane.offset * this.radius,\n CENTER,\n );\n }\n\n if (!arcPath)\n return svg``;\n\n return svg`\n <path \n class=\"lane\" \n data-lane-key=\"${lane.key}\" \n part=\"lane lane-${lane.key}\"\n d=\"${arcPath}\"\n style=\"\n stroke-width: calc(var(--lane-${lane.key}-width, var(--lane-width)) * ${this.radius}%);\n stroke-linecap: round;\n \"\n />\n `;\n }\n\n #getNeedlePath(angle: number, length: number, offset: number): string {\n const startRadius = offset * this.radius;\n const endRadius = length * this.radius;\n\n const start = {\n x: CENTER.x + Math.cos(angle) * startRadius,\n y: CENTER.y + Math.sin(angle) * startRadius,\n };\n const end = {\n x: CENTER.x + Math.cos(angle) * endRadius,\n y: CENTER.y + Math.sin(angle) * endRadius,\n };\n\n return `M ${start.x} ${start.y} L ${end.x} ${end.y}`;\n }\n\n #renderValueMarker(needlePath?: string) {\n const relativeValue = this.#getRelativeValue();\n const { angle, position } = getMarkerPosition(\n relativeValue,\n this.valueMode,\n this.flatten,\n this.radius,\n CENTER,\n );\n\n const markerOffset = this.#getCssVar(`--marker-offset`, 1);\n const markerBorderWidth = this.#getCssVar(`--marker-border-width`, 0);\n const effectiveStyle = this.#getEffectiveMarkerStyle();\n\n if (effectiveStyle === `dot`) {\n const size = this.#getCssVar(`--marker-thickness`, 0.15);\n const r = size * this.radius;\n const dotX = CENTER.x + (position.x - CENTER.x) * markerOffset;\n const dotY = CENTER.y + (position.y - CENTER.y) * markerOffset;\n\n if (markerBorderWidth > 0) {\n return svg`\n <g class=\"value-marker\" part=\"value-marker\">\n <use href=\"#dot-path\" class=\"marker-border\" />\n <use href=\"#dot-path\" class=\"marker-fill\" />\n </g>\n `;\n }\n\n return svg`\n <g class=\"value-marker\" part=\"value-marker\">\n <circle cx=\"${dotX}\" cy=\"${dotY}\" r=\"${r}\" />\n </g>\n `;\n } else if (effectiveStyle === `needle`) {\n if (markerBorderWidth > 0 && needlePath) {\n return svg`\n <g class=\"value-marker\" part=\"value-marker\">\n <use href=\"#needle-path\" class=\"marker-border\" />\n <use href=\"#needle-path\" class=\"marker-fill\" />\n </g>\n `;\n }\n\n const length = this.#getCssVar(`--marker-length`, 0.8);\n const offset = this.#getCssVar(`--marker-offset`, 0.2);\n const path = this.#getNeedlePath(angle, length, offset);\n\n return svg`\n <g class=\"value-marker\" part=\"value-marker\">\n <path d=\"${path}\" />\n </g>\n `;\n }\n }\n\n #renderMidpointMarker() {\n // Only show in bipolar/unipolar modes\n if (this.valueMode !== `bipolar` && this.valueMode !== `unipolar`) {\n return svg``;\n }\n\n const { position } = getMidpointPosition(this.radius, CENTER);\n\n if (this.markerStyle === `dot`) {\n const size = this.#getCssVar(`--midpoint-thickness`, 0.08);\n return svg`\n <g class=\"midpoint-marker\" part=\"midpoint-marker\">\n <circle \n cx=\"${position.x}\" \n cy=\"${position.y}\" \n r=\"${size * this.radius}\" \n />\n </g>\n `;\n } else {\n // Needle style\n const length = this.#getCssVar(`--midpoint-length`, 0.15);\n const offset = this.#getCssVar(`--midpoint-offset`, 0.85);\n\n const angle = -Math.PI / 2; // Top of circle\n const startRadius = offset * this.radius;\n const endRadius = (offset + length) * this.radius;\n\n const start = {\n x: CENTER.x + Math.cos(angle) * startRadius,\n y: CENTER.y + Math.sin(angle) * startRadius,\n };\n const end = {\n x: CENTER.x + Math.cos(angle) * endRadius,\n y: CENTER.y + Math.sin(angle) * endRadius,\n };\n\n return svg`\n <g class=\"midpoint-marker\" part=\"midpoint-marker\">\n <line \n x1=\"${start.x}\" \n y1=\"${start.y}\" \n x2=\"${end.x}\" \n y2=\"${end.y}\" \n />\n </g>\n `;\n }\n }\n\n #getCssVar(name: string, defaultValue: number): number {\n const style = getComputedStyle(this);\n const val = style.getPropertyValue(name).trim();\n if (!val)\n return defaultValue;\n\n // Handle CSS calc() expressions with var(--value-relative)\n if (val.includes(`calc(`)) {\n // Get the current --value-relative value\n const valueRelative = style.getPropertyValue(`--value-relative`).trim();\n if (!valueRelative) {\n // Fallback to default if --value-relative not set\n const parsed = Number.parseFloat(val.replace(/[^0-9.-]/g, ``));\n return Number.isNaN(parsed) ? defaultValue : parsed;\n }\n\n // Replace var(--value-relative) with the actual value\n const evalStr = val.replace(/var\\(--value-relative\\)/g, valueRelative);\n\n // Use Function constructor for safe evaluation (no eval)\n try {\n // Create a function that evaluates math expressions\n // eslint-disable-next-line no-new-func\n const fn = new Function(`return ${evalStr.replace(/calc\\s*\\(([^)]+)\\)/g, `$1`)}`);\n const result = fn();\n return typeof result === `number` && !Number.isNaN(result) ? result : defaultValue;\n } catch {\n // Fallback: try to parse just numbers\n const parsed = Number.parseFloat(val.replace(/[^0-9.-]/g, ``));\n return Number.isNaN(parsed) ? defaultValue : parsed;\n }\n }\n\n const parsed = Number.parseFloat(val);\n return Number.isNaN(parsed) ? defaultValue : parsed;\n }\n\n // Lifecycle methods\n\n protected override willUpdate(changed: PropertyValues): void {\n super.willUpdate(changed);\n\n // Ensure value lane reflects current value before first render\n // This handles declaratively set initial values\n if (changed.has(`value`) || !this.hasUpdated) {\n const valueLane = this.#lanes.get(`value`);\n if (valueLane && valueLane.type === `value`) {\n valueLane.value = this.#getRelativeValue();\n }\n }\n }\n\n override render(): unknown {\n const lanes = Array.from(this.#lanes.values());\n\n const relativeValue = this.#getRelativeValue();\n const { angle, position } = getMarkerPosition(\n relativeValue,\n this.valueMode,\n this.flatten,\n this.radius,\n CENTER,\n );\n\n const needleLength = this.#getCssVar(`--marker-length`, 0.8);\n const needleOffset = this.#getCssVar(`--marker-offset`, 0.2);\n const markerBorderWidth = this.#getCssVar(`--marker-border-width`, 0);\n const needlePath = markerBorderWidth > 0 ? this.#getNeedlePath(angle, needleLength, needleOffset) : undefined;\n\n const dotSize = this.#getCssVar(`--marker-thickness`, 0.15);\n const dotR = dotSize * this.radius;\n\n const defs = [];\n if (needlePath) {\n defs.push(svg`<path id=\"needle-path\" d=\"${needlePath}\" />`);\n }\n if (markerBorderWidth > 0) {\n defs.push(svg`<circle id=\"dot-path\" cx=\"${position.x}\" cy=\"${position.y}\" r=\"${dotR}\" />`);\n }\n\n return html`\n <svg\n viewBox=\"0 0 100 100\"\n preserveAspectRatio=\"xMidYMid meet\"\n tabindex=\"${this.disabled ? -1 : 0}\"\n @pointerdown=\"${this.#onPointerDown}\"\n @keydown=\"${this.#onKeyDown}\"\n style=\"cursor: ${this.#dragging ? `ns-resize` : `grab`}\"\n >\n ${defs.length > 0 ? svg`<defs>${defs}</defs>` : ``}\n ${this.#renderCircleFill()}\n ${this.wedge ? this.#renderWedge() : ``}\n ${this.#renderCircleBorder()}\n ${lanes.map(lane => this.#renderLane(lane))}\n ${this.#renderMidpointMarker()}\n ${this.#renderValueMarker(needlePath)}\n </svg>\n `;\n }\n\n protected override updated(changed: PropertyValues): void {\n super.updated(changed);\n\n // Update --radius CSS variable when property changes\n if (changed.has(`radius`)) {\n this.style.setProperty(`--radius`, `${this.radius}%`);\n }\n\n // Update --value-relative CSS variable\n this.style.setProperty(`--value-relative`, this.#getRelativeValue().toString());\n\n // Adjust component height based on flatten to reduce wasted vertical space.\n // The dial is flattened at the top, so we don't need full height.\n if (changed.has(`flatten`)) {\n const markerThickness = this.#getCssVar(`--marker-thickness`, 0.15);\n const radius = this.#getCssVar(`--radius`, 45);\n const markerPadding = Math.round(markerThickness * radius) + 5;\n const viewBoxHeight = Math.round(100 * (1 - this.flatten)) + markerPadding;\n // Set CSS variable to control host height\n this.style.setProperty(`--dial-height`, `${viewBoxHeight}px`);\n // Also update SVG viewBox to match\n const svg = this.renderRoot.querySelector(`svg`);\n if (svg) {\n svg.setAttribute(`viewBox`, `0 0 100 ${viewBoxHeight}`);\n }\n }\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n if (this.#changeDebounceTimer !== undefined) {\n clearTimeout(this.#changeDebounceTimer);\n }\n this.#onPointerUp();\n }\n\n override firstUpdated(): void {\n const markerThickness = this.#getCssVar(`--marker-thickness`, 0.15);\n const radius = this.#getCssVar(`--radius`, 45);\n const markerPadding = Math.round(markerThickness * radius);\n const viewBoxHeight = Math.round(100 * (1 - this.flatten)) + markerPadding;\n this.style.setProperty(`--dial-height`, `${viewBoxHeight}px`);\n const svg = this.renderRoot.querySelector(`svg`);\n if (svg) {\n svg.setAttribute(`viewBox`, `0 0 100 ${viewBoxHeight}`);\n }\n }\n\n static override styles = [themeFallbacks, prominenceStyles, css`\n :host {\n display: inline-block;\n width: 100px;\n height: var(--dial-height, 100px);\n touch-action: none;\n user-select: none;\n tabindex: 0;\n\n /* Dynamic value - set by JS */\n --value-relative: 0;\n\n /* Lane widths (used in stroke-width calculations) */\n --lane-width: 0.16;\n --lane-track-width: 0.08;\n --lane-value-width: 0.12;\n }\n\n :host([disabled]) {\n cursor: not-allowed;\n }\n\n svg {\n width: 100%;\n height: 100%;\n outline: none;\n }\n\n svg:active {\n cursor: grabbing;\n }\n\n svg:focus-visible {\n outline: var(--radial-input-svg-focus-outline, 2px solid var(--accent));\n outline-offset: var(--radial-input-svg-focus-outline-offset, 2px);\n }\n\n .dial-border {\n fill: none;\n stroke: var(--dial-border-color, var(--surface-4));\n stroke-width: var(--dial-border-width, 2px);\n stroke-linecap: round;\n vector-effect: non-scaling-stroke;\n }\n\n .dial-fill {\n fill: var(--dial-fill, transparent);\n }\n\n .wedge {\n fill: var(--wedge-fill, var(--accent));\n fill-opacity: var(--wedge-fill-opacity, 0.25);\n stroke: var(--wedge-border-color, var(--accent));\n stroke-width: var(--wedge-border-width, 0);\n stroke-opacity: var(--wedge-border-opacity, 1);\n vector-effect: non-scaling-stroke;\n }\n\n .lane {\n fill: none;\n stroke-linecap: round;\n stroke-dasharray: var(--lane-dasharray, none);\n stroke-dashoffset: var(--lane-dashoffset, 0);\n vector-effect: non-scaling-stroke;\n }\n\n .lane[data-lane-key='track'] {\n stroke: var(--lane-track-color, var(--surface-4));\n }\n\n .lane[data-lane-key='value'] {\n stroke: var(--lane-value-color, var(--accent));\n }\n\n .lane:not([data-lane-key='track']):not([data-lane-key='value']) {\n stroke: var(--lane-color, var(--accent));\n }\n\n .value-marker path,\n .value-marker .marker-fill {\n stroke: var(--marker-color, var(--accent));\n stroke-width: calc(var(--marker-thickness, 0.15) * var(--radius, 45%));\n stroke-linecap: round;\n stroke-dasharray: var(--marker-dasharray, none);\n stroke-dashoffset: var(--marker-dashoffset, 0);\n vector-effect: non-scaling-stroke;\n }\n\n .value-marker .marker-border {\n stroke: var(--marker-border-color, transparent);\n stroke-width: calc((var(--marker-thickness, 0.15) + var(--marker-border-width, 0) * 2) * var(--radius, 45%));\n stroke-linecap: round;\n vector-effect: non-scaling-stroke;\n }\n\n .value-marker .marker-border {\n fill: none;\n }\n\n .value-marker .marker-fill,\n .value-marker circle {\n fill: var(--marker-color, var(--accent));\n }\n\n .midpoint-marker line {\n stroke: var(--midpoint-color, var(--surface-muted-text));\n stroke-width: var(--midpoint-thickness, 1px);\n stroke-linecap: round;\n vector-effect: non-scaling-stroke;\n }\n\n .midpoint-marker circle {\n fill: var(--midpoint-color, var(--surface-muted-text));\n stroke: var(--midpoint-border-color, transparent);\n stroke-width: var(--midpoint-border-width, 0);\n vector-effect: non-scaling-stroke;\n }\n `];\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'ixfx-radial-input': RadialInputElement;\n }\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { t as RadialInputElement } from "./radial-input-DyxfbNzD.js";
1
+ import { t as RadialInputElement } from "./radial-input-KMVltQfe.js";
2
2
  export { RadialInputElement };
@@ -1,4 +1,4 @@
1
- import { t as themeFallbacks } from "./fallbacks-BcKGq-2F.js";
1
+ import { t as themeFallbacks } from "./fallbacks-DQ_5OsmR.js";
2
2
  import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
3
3
  import { t as WheelNudgeMixin } from "./wheel-nudge-D5rmht3v.js";
4
4
  import { t as tooltipValueStyles } from "./tooltip-CJt3WLmN.js";
package/dist/range.js CHANGED
@@ -1,4 +1,4 @@
1
- import { t as themeFallbacks } from "./fallbacks-BcKGq-2F.js";
1
+ import { t as themeFallbacks } from "./fallbacks-DQ_5OsmR.js";
2
2
  import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
3
3
  import { t as prominenceStyles } from "./prominence-DlFShic3.js";
4
4
  import { t as WheelNudgeMixin } from "./wheel-nudge-D5rmht3v.js";
@@ -1,6 +1,6 @@
1
1
  import { t as TickledController } from "./tickled-controller-Dh1Uh_vG.js";
2
2
  import { n as tickledStyles, t as tickledItemStyles } from "./tickled-styles-BrAHEj1q.js";
3
- import { t as themeFallbacks } from "./fallbacks-BcKGq-2F.js";
3
+ import { t as themeFallbacks } from "./fallbacks-DQ_5OsmR.js";
4
4
  import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
5
5
  import "./interaction-BskmlA9t.js";
6
6
  import { t as scrollFadeStyles } from "./scroll-fade-CAs1EabA.js";
@@ -1,4 +1,4 @@
1
- import { t as themeFallbacks } from "./fallbacks-BcKGq-2F.js";
1
+ import { t as themeFallbacks } from "./fallbacks-DQ_5OsmR.js";
2
2
  import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
3
3
  import { t as prominenceStyles } from "./prominence-DlFShic3.js";
4
4
  import { t as resolveAxisStep } from "./keyboard-B5xD7Fz-.js";
@@ -1971,4 +1971,4 @@ SliderInputElement = __decorate([safeCustomElement(`ixfx-slider-input`)], Slider
1971
1971
  //#endregion
1972
1972
  export { SliderInputElement as t };
1973
1973
 
1974
- //# sourceMappingURL=slider-input-Cb5uSV42.js.map
1974
+ //# sourceMappingURL=slider-input-ByHdotzp.js.map