@ixfx/components 0.6.2 → 0.7.1

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 (181) hide show
  1. package/bundle/index.d.ts +1918 -835
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +22137 -16840
  4. package/bundle/index.js.map +1 -1
  5. package/bundle/style.css +1 -1
  6. package/dist/ac-text.d.ts +1 -1
  7. package/dist/ac-text.js +3 -2
  8. package/dist/ac-text.js.map +1 -1
  9. package/dist/{ac-token-BAa6ke09.d.ts → ac-token--_vCHXWw.d.ts} +2 -2
  10. package/dist/{ac-token-BAa6ke09.d.ts.map → ac-token--_vCHXWw.d.ts.map} +1 -1
  11. package/dist/ac-token.d.ts +1 -1
  12. package/dist/ac-token.js +3 -2
  13. package/dist/ac-token.js.map +1 -1
  14. package/dist/{button-Bn0BuLpO.js → button-DsFbV4XD.js} +5 -4
  15. package/dist/button-DsFbV4XD.js.map +1 -0
  16. package/dist/button.d.ts.map +1 -1
  17. package/dist/button.js +1 -1
  18. package/dist/checkbox.js +1 -1
  19. package/dist/{colour-picker-0stHB90J.js → colour-picker-Ddsk-7E_.js} +4 -3
  20. package/dist/{colour-picker-0stHB90J.js.map → colour-picker-Ddsk-7E_.js.map} +1 -1
  21. package/dist/colour-picker.js +1 -1
  22. package/dist/crumbs.d.ts +1 -1
  23. package/dist/crumbs.js +4 -2
  24. package/dist/crumbs.js.map +1 -1
  25. package/dist/data-display.js +1 -1
  26. package/dist/{data-grid-C8qIo1-u.d.ts → data-grid-Bh4YrQGK.d.ts} +2 -2
  27. package/dist/{data-grid-C8qIo1-u.d.ts.map → data-grid-Bh4YrQGK.d.ts.map} +1 -1
  28. package/dist/data-grid.d.ts +1 -1
  29. package/dist/data-grid.js +4 -2
  30. package/dist/data-grid.js.map +1 -1
  31. package/dist/{defaults-BCiDhZbF.js → defaults-BJwDsMH4.js} +27 -20
  32. package/dist/defaults-BJwDsMH4.js.map +1 -0
  33. package/dist/editable-label-rzXkjf1H.d.ts +75 -0
  34. package/dist/editable-label-rzXkjf1H.d.ts.map +1 -0
  35. package/dist/editable-label.d.ts +2 -75
  36. package/dist/editable-label.js +2 -1
  37. package/dist/editable-label.js.map +1 -1
  38. package/dist/{fallbacks-DEE1nCTt.js → fallbacks-DNI9xt0F.js} +2 -2
  39. package/dist/{fallbacks-DEE1nCTt.js.map → fallbacks-DNI9xt0F.js.map} +1 -1
  40. package/dist/{grouped-item-lister-_pMDwIo1.d.ts → grouped-item-lister-DnWB-eFT.d.ts} +2 -2
  41. package/dist/{grouped-item-lister-_pMDwIo1.d.ts.map → grouped-item-lister-DnWB-eFT.d.ts.map} +1 -1
  42. package/dist/grouped-item-lister.d.ts +1 -1
  43. package/dist/{hex-editor-Bk6rxhfg.js → hex-editor-BiRfwTz1.js} +2 -2
  44. package/dist/{hex-editor-Bk6rxhfg.js.map → hex-editor-BiRfwTz1.js.map} +1 -1
  45. package/dist/hex.js +1 -1
  46. package/dist/{icon-DpA9x2Ve.d.ts → icon-CDGprSdE.d.ts} +1 -12
  47. package/dist/icon-CDGprSdE.d.ts.map +1 -0
  48. package/dist/{icons-Bm2ByQ3s.js → icon-DcEEGQa_.js} +38 -12
  49. package/dist/icon-DcEEGQa_.js.map +1 -0
  50. package/dist/icons.d.ts +3 -3
  51. package/dist/icons.js +9 -3
  52. package/dist/icons.js.map +1 -0
  53. package/dist/{index-CKtLhgYj.d.ts → index-9AhaHIT2.d.ts} +3 -3
  54. package/dist/{index-CKtLhgYj.d.ts.map → index-9AhaHIT2.d.ts.map} +1 -1
  55. package/dist/index-CG2vIgPv.d.ts +101 -0
  56. package/dist/index-CG2vIgPv.d.ts.map +1 -0
  57. package/dist/{index-BtGFYfaK.d.ts → index-CS9yM8L-.d.ts} +14 -4
  58. package/dist/index-CS9yM8L-.d.ts.map +1 -0
  59. package/dist/index.d.ts +861 -71
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +4257 -931
  62. package/dist/index.js.map +1 -1
  63. package/dist/interaction-D5XdKzbR.js +2 -0
  64. package/dist/labelled-radial-input.js +2 -1
  65. package/dist/labelled-radial-input.js.map +1 -1
  66. package/dist/labelled-slider-input-DzigjMwP.js +808 -0
  67. package/dist/labelled-slider-input-DzigjMwP.js.map +1 -0
  68. package/dist/labelled-slider-input.d.ts +2 -0
  69. package/dist/labelled-slider-input.js +2 -0
  70. package/dist/{types-DlVNJez_.d.ts → list-selection-types-DSuRNWpx.d.ts} +10 -2
  71. package/dist/list-selection-types-DSuRNWpx.d.ts.map +1 -0
  72. package/dist/menu-CXDFJxNm.js +825 -0
  73. package/dist/menu-CXDFJxNm.js.map +1 -0
  74. package/dist/{menu-item-Bs2MYyHq.d.ts → menu-item-CZi9vy5O.d.ts} +4 -2
  75. package/dist/menu-item-CZi9vy5O.d.ts.map +1 -0
  76. package/dist/menu-item-D2S4i8u1.js +809 -0
  77. package/dist/menu-item-D2S4i8u1.js.map +1 -0
  78. package/dist/menu.d.ts +2 -2
  79. package/dist/menu.js +2 -1
  80. package/dist/miller.d.ts +1 -1
  81. package/dist/miller.js +3 -2
  82. package/dist/miller.js.map +1 -1
  83. package/dist/narrowed-text.js +4 -2
  84. package/dist/narrowed-text.js.map +1 -1
  85. package/dist/notification-pill-DyZydXoZ.d.ts.map +1 -1
  86. package/dist/notifier.js +4 -3
  87. package/dist/notifier.js.map +1 -1
  88. package/dist/panel.d.ts +13 -13
  89. package/dist/panel.d.ts.map +1 -1
  90. package/dist/panel.js +37 -253
  91. package/dist/panel.js.map +1 -1
  92. package/dist/plots.js +1 -1
  93. package/dist/polar-pad.js +1 -1
  94. package/dist/{radial-input-Dk8Wydp5.js → radial-input-Dp5qz0ly.js} +2 -2
  95. package/dist/{radial-input-Dk8Wydp5.js.map → radial-input-Dp5qz0ly.js.map} +1 -1
  96. package/dist/radial-input.js +1 -1
  97. package/dist/range-input.js +1 -1
  98. package/dist/range.js +1 -1
  99. package/dist/registry-BEtb8_wB.js +46 -0
  100. package/dist/registry-BEtb8_wB.js.map +1 -0
  101. package/dist/select-horiz.js +3 -2
  102. package/dist/select-horiz.js.map +1 -1
  103. package/dist/{slider-input-XppH3vcy.d.ts → slider-input-BfRUW2ZB.d.ts} +16 -3
  104. package/dist/slider-input-BfRUW2ZB.d.ts.map +1 -0
  105. package/dist/{slider-input-CT4gcF-o.js → slider-input-De4eoT11.js} +382 -67
  106. package/dist/slider-input-De4eoT11.js.map +1 -0
  107. package/dist/slider-input.d.ts +1 -1
  108. package/dist/slider-input.js +1 -1
  109. package/dist/snackbar.js +1 -1
  110. package/dist/split-layout-BFSbUZQv.js +969 -0
  111. package/dist/split-layout-BFSbUZQv.js.map +1 -0
  112. package/dist/split-layout-JK3xWVX2.d.ts +179 -0
  113. package/dist/split-layout-JK3xWVX2.d.ts.map +1 -0
  114. package/dist/split-layout.d.ts +2 -60
  115. package/dist/split-layout.js +1 -617
  116. package/dist/style.css +1 -1
  117. package/dist/swipe.js +1 -1
  118. package/dist/{tab-list-D_1cYhB_.d.ts → tab-list-CGyPt07Z.d.ts} +10 -2
  119. package/dist/tab-list-CGyPt07Z.d.ts.map +1 -0
  120. package/dist/tabs.d.ts +1 -1
  121. package/dist/tabs.js +128 -27
  122. package/dist/tabs.js.map +1 -1
  123. package/dist/{tickled-controller-BtevrRLV.d.ts → tickled-controller-CRzdIEjJ.d.ts} +7 -1
  124. package/dist/tickled-controller-CRzdIEjJ.d.ts.map +1 -0
  125. package/dist/{tickled-controller-DkAU-0qL.js → tickled-controller-h9GmJ_bU.js} +8 -2
  126. package/dist/tickled-controller-h9GmJ_bU.js.map +1 -0
  127. package/dist/titlebar-Bj5pfdw_.d.ts +50 -0
  128. package/dist/titlebar-Bj5pfdw_.d.ts.map +1 -0
  129. package/dist/titlebar.d.ts +2 -0
  130. package/dist/titlebar.js +324 -0
  131. package/dist/titlebar.js.map +1 -0
  132. package/dist/tooltip-BlvBUQxx.d.ts.map +1 -1
  133. package/dist/{tree-BO6BXI2b.js → tree-Ch4W8qXQ.js} +4 -3
  134. package/dist/{tree-BO6BXI2b.js.map → tree-Ch4W8qXQ.js.map} +1 -1
  135. package/dist/tree.d.ts +1 -1
  136. package/dist/tree.js +1 -1
  137. package/dist/vertical-list-ClnqTkF3.js +814 -0
  138. package/dist/vertical-list-ClnqTkF3.js.map +1 -0
  139. package/dist/vertical-list.d.ts +8 -9
  140. package/dist/vertical-list.d.ts.map +1 -1
  141. package/dist/vertical-list.js +1 -736
  142. package/dist/{xy-axis-B6yMjckW.js → xy-axis-DWizs0bt.js} +109 -3
  143. package/dist/xy-axis-DWizs0bt.js.map +1 -0
  144. package/dist/xy-pad.js +1 -1
  145. package/docs-user/README.md +5 -0
  146. package/docs-user/detail-list.md +398 -0
  147. package/docs-user/dock.md +461 -0
  148. package/docs-user/icons.md +4 -0
  149. package/docs-user/index.json +28 -3
  150. package/docs-user/labelled-slider-input.md +198 -0
  151. package/docs-user/llms.txt +6 -1
  152. package/docs-user/panel.md +20 -1
  153. package/docs-user/slider-input.md +55 -15
  154. package/docs-user/split-layout.md +136 -170
  155. package/docs-user/tabs.md +54 -0
  156. package/docs-user/titlebar.md +102 -0
  157. package/docs-user/toolbar.md +95 -22
  158. package/docs-user/twosplit-layout.md +254 -0
  159. package/docs-user/user-catalog.md +8 -1
  160. package/docs-user/user-theming.md +109 -0
  161. package/llms.txt +6 -1
  162. package/package.json +1 -2
  163. package/dist/button-Bn0BuLpO.js.map +0 -1
  164. package/dist/defaults-BCiDhZbF.js.map +0 -1
  165. package/dist/editable-label.d.ts.map +0 -1
  166. package/dist/icon-DpA9x2Ve.d.ts.map +0 -1
  167. package/dist/icons-Bm2ByQ3s.js.map +0 -1
  168. package/dist/index-BtGFYfaK.d.ts.map +0 -1
  169. package/dist/menu-DIfU70AA.js +0 -1609
  170. package/dist/menu-DIfU70AA.js.map +0 -1
  171. package/dist/menu-item-Bs2MYyHq.d.ts.map +0 -1
  172. package/dist/slider-input-CT4gcF-o.js.map +0 -1
  173. package/dist/slider-input-XppH3vcy.d.ts.map +0 -1
  174. package/dist/split-layout.d.ts.map +0 -1
  175. package/dist/split-layout.js.map +0 -1
  176. package/dist/tab-list-D_1cYhB_.d.ts.map +0 -1
  177. package/dist/tickled-controller-BtevrRLV.d.ts.map +0 -1
  178. package/dist/tickled-controller-DkAU-0qL.js.map +0 -1
  179. package/dist/types-DlVNJez_.d.ts.map +0 -1
  180. package/dist/vertical-list.js.map +0 -1
  181. package/dist/xy-axis-B6yMjckW.js.map +0 -1
@@ -0,0 +1,808 @@
1
+ import { t as themeFallbacks } from "./fallbacks-DNI9xt0F.js";
2
+ import { n as safeCustomElement, t as __decorate } from "./decorate-VRK8rslU.js";
3
+ import { t as prominenceStyles } from "./prominence-DlFShic3.js";
4
+ import { t as LabelledInputBase } from "./labelled-input-base-hoKGwyKT.js";
5
+ import { EditableLabel } from "./editable-label.js";
6
+ import { t as resolveAxisStep } from "./keyboard-B5xD7Fz-.js";
7
+ import { t as WheelNudgeMixin } from "./wheel-nudge-BlSCe_hD.js";
8
+ import "./slider-input-De4eoT11.js";
9
+ import { css, html } from "lit";
10
+ import { property } from "lit/decorators.js";
11
+ //#region src/editable-label/editable-number.ts
12
+ const DRAG_THRESHOLD_PX = 3;
13
+ let EditableNumber = class EditableNumber extends WheelNudgeMixin(EditableLabel) {
14
+ #dragStartY;
15
+ #dragStartValue;
16
+ #dragging;
17
+ #hasDragged;
18
+ #dragCurrentValue;
19
+ #lastInputValue;
20
+ #firstUpdateComplete;
21
+ constructor() {
22
+ super();
23
+ this.dragSensitivity = 1;
24
+ this.noDrag = false;
25
+ this.precision = 0;
26
+ this.#dragStartY = 0;
27
+ this.#dragStartValue = 0;
28
+ this.#dragging = false;
29
+ this.#hasDragged = false;
30
+ this.#dragCurrentValue = 0;
31
+ this.#lastInputValue = ``;
32
+ this.#firstUpdateComplete = false;
33
+ this._stopNativeInput = (e) => {
34
+ e.stopPropagation();
35
+ };
36
+ this._handleMouseEnter = () => {
37
+ if (this.displayTextLogic !== `transient` || this._editing) return;
38
+ this._hovering = true;
39
+ this._clearTransientTimer();
40
+ this._transientTimer = window.setTimeout(() => {
41
+ this._transientShowingValue = true;
42
+ this._requestDisplayUpdate();
43
+ }, this.appearDelay);
44
+ };
45
+ this._handleMouseLeave = () => {
46
+ if (this.displayTextLogic !== `transient` || this._editing) return;
47
+ this._hovering = false;
48
+ this._clearTransientTimer();
49
+ if (this._transientShowingValue) this._transientTimer = window.setTimeout(() => {
50
+ if (!this._hovering) {
51
+ this._transientShowingValue = false;
52
+ this._requestDisplayUpdate();
53
+ }
54
+ }, this.disappearDelay);
55
+ };
56
+ this._handleClick = () => {
57
+ if (this.disabled) return;
58
+ this.renderRoot?.querySelector(`.number`)?.focus();
59
+ };
60
+ this._handleFocus = () => {};
61
+ this._handleBeforeInput = (e) => {
62
+ if (e.inputType !== `insertText` || !e.data) return;
63
+ if (!this._isAllowedInput(e.data)) {
64
+ e.preventDefault();
65
+ return;
66
+ }
67
+ const contentEl = this._contentEl;
68
+ if (!contentEl) return;
69
+ const currentContent = contentEl.textContent ?? ``;
70
+ const insertPosition = contentEl.selectionStart ?? currentContent.length;
71
+ const newValue = currentContent.slice(0, insertPosition) + e.data + currentContent.slice(insertPosition);
72
+ if (newValue !== this.#lastInputValue) {
73
+ this.#lastInputValue = newValue;
74
+ this.dispatchEvent(new CustomEvent(`input`, {
75
+ detail: { value: newValue },
76
+ bubbles: true,
77
+ composed: true
78
+ }));
79
+ }
80
+ };
81
+ this._handleKeydown = (e) => {
82
+ if (!this._editing) return;
83
+ if (e.key === `Enter`) {
84
+ e.preventDefault();
85
+ this._tryCommit();
86
+ if (this.mode === `editor`) this._contentEl?.blur();
87
+ } else if (e.key === `Escape`) {
88
+ e.preventDefault();
89
+ this.dispatchEvent(new CustomEvent(`cancelled`, {
90
+ detail: { value: this._prevValue },
91
+ bubbles: true,
92
+ composed: true
93
+ }));
94
+ this._cancelEdit();
95
+ this.dispatchEvent(new CustomEvent(`change`, {
96
+ detail: { value: this._prevValue },
97
+ bubbles: true,
98
+ composed: true
99
+ }));
100
+ if (this.mode === `editor`) this._contentEl?.blur();
101
+ }
102
+ };
103
+ this._onKeyDown = (e) => {
104
+ if (this._editing || this.disabled) return;
105
+ if (this._handleArrowKey(e)) return;
106
+ if (e.key.length === 1) {
107
+ this._onUserInteraction();
108
+ this._beginEdit();
109
+ }
110
+ };
111
+ this._onPointerDown = (e) => {
112
+ if (e.button !== 0) return;
113
+ if (this._editing) return;
114
+ if (this.disabled || this.noDrag) return;
115
+ e.preventDefault();
116
+ this.renderRoot?.querySelector(`.number`)?.focus();
117
+ this.#dragStartY = e.clientY;
118
+ this.#dragStartValue = this._parseValue();
119
+ this.#dragCurrentValue = this.#dragStartValue;
120
+ this.#dragging = false;
121
+ this.#hasDragged = false;
122
+ this.setPointerCapture(e.pointerId);
123
+ };
124
+ this._onPointerMove = (e) => {
125
+ if (!(e.buttons & 1)) return;
126
+ if (this._editing) return;
127
+ if (this.disabled || this.noDrag) return;
128
+ const deltaY = this.#dragStartY - e.clientY;
129
+ if (!this.#dragging && Math.abs(deltaY) < DRAG_THRESHOLD_PX) return;
130
+ this.#dragging = true;
131
+ this.#hasDragged = true;
132
+ this.toggleAttribute(`dragging`, true);
133
+ this._onUserInteraction();
134
+ const raw = this.#dragStartValue + deltaY * this.dragSensitivity * (this.step || 1);
135
+ const snapped = this._clamp(this._snap(raw));
136
+ this.#dragCurrentValue = this.step !== void 0 ? snapped : Number.parseFloat(snapped.toFixed(this.precision));
137
+ const dragValueStr = this.step !== void 0 ? this._formatNumber(this.#dragCurrentValue) : this.#dragCurrentValue.toFixed(this.precision);
138
+ if (dragValueStr !== this.#lastInputValue) {
139
+ this.#lastInputValue = dragValueStr;
140
+ this.dispatchEvent(new CustomEvent(`input`, {
141
+ detail: { value: dragValueStr },
142
+ bubbles: true,
143
+ composed: true
144
+ }));
145
+ }
146
+ this._requestDisplayUpdate();
147
+ this._updateValueCss(this._normalizedValue(this.#dragCurrentValue));
148
+ };
149
+ this._onPointerUp = (e) => {
150
+ if (this.hasPointerCapture(e.pointerId)) this.releasePointerCapture(e.pointerId);
151
+ if (!this.#dragging) return;
152
+ if (this.disabled || this.noDrag) return;
153
+ this.#dragging = false;
154
+ this.toggleAttribute(`dragging`, false);
155
+ const finalStr = this.step !== void 0 ? this._formatNumber(this.#dragCurrentValue) : this.#dragCurrentValue.toFixed(this.precision);
156
+ const prev = this.value;
157
+ this.value = finalStr;
158
+ if (finalStr !== prev) this.dispatchEvent(new CustomEvent(`change`, {
159
+ detail: { value: finalStr },
160
+ bubbles: true,
161
+ composed: true
162
+ }));
163
+ };
164
+ this._interceptClick = (e) => {
165
+ if (this.#hasDragged) {
166
+ e.stopImmediatePropagation();
167
+ this.#hasDragged = false;
168
+ }
169
+ };
170
+ this.mode = `editor`;
171
+ this.entryMode = `number`;
172
+ this.value = `0`;
173
+ }
174
+ render() {
175
+ return html`
176
+ ${this.fillStyle ? html`<div class="track"></div>` : ``}
177
+ ${this.fillStyle ? html`<div class="value"><div class="bar"></div></div>` : ``}
178
+ <div
179
+ class="number"
180
+ part="content"
181
+ tabindex="${this.disabled ? -1 : 0}"
182
+ contenteditable="${this._editing ? `plaintext-only` : `false`}"
183
+ data-placeholder="${this.placeholder}"
184
+ @click=${this._handleClick}
185
+ @focus=${this._handleFocus}
186
+ @blur=${this._handleBlur}
187
+ @keydown=${this._handleKeydown}
188
+ @beforeinput=${this._handleBeforeInput}
189
+ @input=${this._stopNativeInput}
190
+ ></div>
191
+ `;
192
+ }
193
+ connectedCallback() {
194
+ super.connectedCallback();
195
+ this.addEventListener(`pointerdown`, this._onPointerDown);
196
+ this.addEventListener(`pointermove`, this._onPointerMove);
197
+ this.addEventListener(`pointerup`, this._onPointerUp);
198
+ this.addEventListener(`keydown`, this._onKeyDown);
199
+ this.addEventListener(`click`, this._interceptClick, { capture: true });
200
+ this.addEventListener(`mouseenter`, this._handleMouseEnter);
201
+ this.addEventListener(`mouseleave`, this._handleMouseLeave);
202
+ }
203
+ disconnectedCallback() {
204
+ super.disconnectedCallback();
205
+ this.removeEventListener(`pointerdown`, this._onPointerDown);
206
+ this.removeEventListener(`pointermove`, this._onPointerMove);
207
+ this.removeEventListener(`pointerup`, this._onPointerUp);
208
+ this.removeEventListener(`keydown`, this._onKeyDown);
209
+ this.removeEventListener(`click`, this._interceptClick);
210
+ this.removeEventListener(`mouseenter`, this._handleMouseEnter);
211
+ this.removeEventListener(`mouseleave`, this._handleMouseLeave);
212
+ }
213
+ /** Override to use .number instead of .content for text display */
214
+ get _contentEl() {
215
+ return this.renderRoot?.querySelector(`.number`) ?? void 0;
216
+ }
217
+ firstUpdated(changedProperties) {
218
+ super.firstUpdated(changedProperties);
219
+ if (this.displayTextLogic === `show`) this._showModeWaitingToHide = true;
220
+ this._updateValueCss(this._normalizedValue());
221
+ this._requestDisplayUpdate();
222
+ }
223
+ _onUserInteraction() {
224
+ if (this.displayTextLogic === `show` && !this._editing) {
225
+ this._clearTransientTimer();
226
+ this._showModeWaitingToHide = false;
227
+ this._requestDisplayUpdate();
228
+ this._transientTimer = window.setTimeout(() => {
229
+ this._showModeWaitingToHide = true;
230
+ this._requestDisplayUpdate();
231
+ }, this.disappearDelay);
232
+ return;
233
+ }
234
+ if (this.displayTextLogic === `transient` && !this._editing) {
235
+ this._clearTransientTimer();
236
+ this._transientShowingValue = true;
237
+ this._requestDisplayUpdate();
238
+ this._transientTimer = window.setTimeout(() => {
239
+ if (!this._hovering) {
240
+ this._transientShowingValue = false;
241
+ this._requestDisplayUpdate();
242
+ }
243
+ }, this.disappearDelay);
244
+ return;
245
+ }
246
+ super._onUserInteraction();
247
+ }
248
+ _onValueChange() {
249
+ if (this.displayTextLogic !== `show` || this._editing) return;
250
+ this._clearTransientTimer();
251
+ this._showModeWaitingToHide = false;
252
+ this._requestDisplayUpdate();
253
+ this._transientTimer = window.setTimeout(() => {
254
+ this._showModeWaitingToHide = true;
255
+ this._requestDisplayUpdate();
256
+ }, this.disappearDelay);
257
+ }
258
+ updated(changedProperties) {
259
+ super.updated(changedProperties);
260
+ if (!this._editing) this._updateValueCss(this._normalizedValue());
261
+ }
262
+ _updateValueCss(normalized) {
263
+ this.style.setProperty(`--value`, String(normalized));
264
+ let valueStart = 0;
265
+ let valueEnd = normalized;
266
+ if (this.linearStyle === `bipolar`) {
267
+ if (normalized <= .5) {
268
+ valueStart = normalized;
269
+ valueEnd = .5;
270
+ } else {
271
+ valueStart = .5;
272
+ valueEnd = normalized;
273
+ }
274
+ } else if (this.linearStyle === `unipolar`) {
275
+ valueStart = .5 - normalized * .5;
276
+ valueEnd = .5 + normalized * .5;
277
+ }
278
+ this.style.setProperty(`--value-start`, String(valueStart));
279
+ this.style.setProperty(`--value-end`, String(valueEnd));
280
+ if (this.fillStyle === `circular` && this.circularStyle === `offset`) {
281
+ const h = this.offsetHeight;
282
+ const w = this.offsetWidth;
283
+ const r = h / 2 - 2;
284
+ const leftEdge = 2;
285
+ const rightEdge = w - 2;
286
+ const valueCenterPx = leftEdge + r + normalized * (rightEdge - leftEdge - 2 * r);
287
+ this.style.setProperty(`--radius`, `${r}px`);
288
+ this.style.setProperty(`--value-center-px`, `${valueCenterPx}px`);
289
+ this.style.setProperty(`--component-width-px`, `${w}px`);
290
+ this.style.setProperty(`--component-height-px`, `${h}px`);
291
+ }
292
+ }
293
+ _getDisplayText() {
294
+ if (this._shouldUseDisplayText()) return this.displayText ?? ``;
295
+ if (this.#dragging) {
296
+ const formatted = this.step !== void 0 ? this._formatNumber(this.#dragCurrentValue) : this.#dragCurrentValue.toFixed(this.precision);
297
+ return this.formatter ? this.formatter(formatted) : formatted;
298
+ }
299
+ if (this.formatter) {
300
+ const raw = Number.parseFloat(this.value);
301
+ return this.formatter(Number.isNaN(raw) ? this.value : String(raw));
302
+ }
303
+ return this._formatDisplay();
304
+ }
305
+ _tryCommit() {
306
+ const el = this.renderRoot?.querySelector(`.number`);
307
+ if (el) {
308
+ const n = Number.parseFloat(el.textContent?.trim() ?? ``);
309
+ if (!Number.isNaN(n)) el.textContent = this._formatNumber(this._clamp(this._snap(n)));
310
+ }
311
+ super._tryCommit();
312
+ }
313
+ _handleArrowKey(e) {
314
+ const range = (this.max ?? 100) - (this.min ?? 0);
315
+ if (range === 0) return false;
316
+ const effectiveStep = resolveAxisStep(range, this.stops, this.step, e.shiftKey);
317
+ let delta = 0;
318
+ let handled = false;
319
+ switch (e.key) {
320
+ case `ArrowUp`:
321
+ case `ArrowRight`:
322
+ delta = effectiveStep;
323
+ handled = true;
324
+ break;
325
+ case `ArrowDown`:
326
+ case `ArrowLeft`:
327
+ delta = -effectiveStep;
328
+ handled = true;
329
+ break;
330
+ case `Home`:
331
+ delta = -(this._parseValue() - (this.min ?? 0));
332
+ handled = true;
333
+ break;
334
+ case `End`:
335
+ delta = (this.max ?? 0) - this._parseValue();
336
+ handled = true;
337
+ }
338
+ if (handled) {
339
+ e.preventDefault();
340
+ this._applyDelta(delta);
341
+ return true;
342
+ }
343
+ return false;
344
+ }
345
+ /**
346
+ * Apply a signed delta to the current value, clamp/snap/format, and fire
347
+ * `input`/`change`. Shared between arrow-key handler and the wheel handler.
348
+ */
349
+ _applyDelta(delta) {
350
+ const prev = this.value;
351
+ const current = this._parseValue();
352
+ const newValue = this._clamp(this._snap(current + delta));
353
+ const newValueStr = this.step !== void 0 ? this._formatNumber(newValue) : newValue.toFixed(this.precision);
354
+ this.value = newValueStr;
355
+ this._requestDisplayUpdate();
356
+ this._updateValueCss(this._normalizedValue(newValue));
357
+ if (newValueStr !== prev) this.dispatchEvent(new CustomEvent(`input`, {
358
+ detail: { value: newValueStr },
359
+ bubbles: true,
360
+ composed: true
361
+ }));
362
+ requestAnimationFrame(() => {
363
+ if (this.value !== prev) this.dispatchEvent(new CustomEvent(`change`, {
364
+ detail: { value: this.value },
365
+ bubbles: true,
366
+ composed: true
367
+ }));
368
+ });
369
+ }
370
+ _shouldHandleWheel() {
371
+ if (this._editing) return false;
372
+ return super._shouldHandleWheel();
373
+ }
374
+ _applyWheelDelta(direction, event) {
375
+ const range = (this.max ?? 100) - (this.min ?? 0);
376
+ if (range === 0) return;
377
+ const effectiveStep = resolveAxisStep(range, this.stops, this.step, event.shiftKey);
378
+ this._applyDelta(direction * effectiveStep);
379
+ }
380
+ _parseValue() {
381
+ return Number.parseFloat(this.value) || 0;
382
+ }
383
+ /**
384
+ * Formats the stored value for display, inferring decimal places from the value
385
+ * string itself. This preserves typed precision (e.g. "0.1234" stays "0.1234")
386
+ * and also respects trailing zeros written by drag storage (e.g. "5.0" stays "5.0").
387
+ */
388
+ _formatDisplay() {
389
+ const n = Number.parseFloat(this.value);
390
+ if (Number.isNaN(n)) return this.value;
391
+ if (this.precision !== void 0) return n.toFixed(this.precision);
392
+ const dot = this.value.indexOf(`.`);
393
+ const dp = dot >= 0 ? this.value.length - dot - 1 : 0;
394
+ return n.toFixed(dp);
395
+ }
396
+ _clamp(n) {
397
+ if (this.min !== void 0) n = Math.max(this.min, n);
398
+ if (this.max !== void 0) n = Math.min(this.max, n);
399
+ return n;
400
+ }
401
+ _snap(n) {
402
+ if (this.stops && this.stops > 1) {
403
+ const min = this.min ?? 0;
404
+ const stopStep = ((this.max ?? 100) - min) / this.stops;
405
+ return Math.round((n - min) / stopStep) * stopStep + min;
406
+ }
407
+ if (!this.step) return n;
408
+ return Math.round(n / this.step) * this.step;
409
+ }
410
+ _inferDecimals(n) {
411
+ if (this.step !== void 0) {
412
+ const s = String(this.step);
413
+ const dot = s.indexOf(`.`);
414
+ return dot >= 0 ? s.length - dot - 1 : 0;
415
+ }
416
+ const s = String(n ?? this._parseValue());
417
+ const dot = s.indexOf(`.`);
418
+ return dot >= 0 ? s.length - dot - 1 : 0;
419
+ }
420
+ _formatNumber(n) {
421
+ return n.toFixed(this._inferDecimals(n));
422
+ }
423
+ /** Returns a 0..1 fraction for the given value within [min, max]. */
424
+ _normalizedValue(n = this._parseValue()) {
425
+ if (this.min === void 0 || this.max === void 0) return 0;
426
+ if (this.max === this.min) return 0;
427
+ return Math.max(0, Math.min(1, (n - this.min) / (this.max - this.min)));
428
+ }
429
+ static {
430
+ this.styles = [
431
+ themeFallbacks,
432
+ prominenceStyles,
433
+ ...EditableLabel.styles,
434
+ css`
435
+ :host {
436
+ font-size: var(--text-s,11px);
437
+ --value: 0;
438
+ --value-start: 0;
439
+ --value-end: 0;
440
+ --_fill-color-alpha: color-mix(
441
+ in oklch,
442
+ var(--fill-color, var(--accent, oklch(60% 0.15 140))) calc(var(--fill-opacity, 0.25) * 100%),
443
+ transparent
444
+ );
445
+ }
446
+
447
+ /* ── Layout (when fill-style is enabled) ── */
448
+ :host([fill-style]) {
449
+ display: grid;
450
+ position: relative;
451
+ grid-template-columns: 1fr;
452
+ grid-template-rows: 1fr;
453
+ min-height: 1.5em;
454
+ min-width: 5em;
455
+ }
456
+
457
+ :host([fill-style]) .track,
458
+ :host([fill-style]) .value {
459
+ grid-area: 1 / 1;
460
+ position: absolute;
461
+ inset: 0;
462
+ }
463
+
464
+ /* Track background styling */
465
+ :host([fill-style]) .track {
466
+ z-index: 0;
467
+ background: var(--surface-4, oklch(22% 0.02 240));
468
+ border: var(--border, 1px solid oklch(25% 0.02 240));
469
+ }
470
+
471
+ :host([fill-style]) .value {
472
+ z-index: 1;
473
+ }
474
+
475
+ :host([fill-style="linear"]) .track {
476
+ border-radius: var(--radius-s, 3px);
477
+ }
478
+
479
+ :host([fill-style="circular"]) .track {
480
+ border-radius: 50%;
481
+ overflow: hidden;
482
+ }
483
+
484
+ /* Linear: all linear-styles use .bar positioned via --value-start and --value-end */
485
+ :host([fill-style="linear"]) .value {
486
+ overflow: hidden;
487
+ }
488
+
489
+ :host([fill-style="linear"]) .bar {
490
+ position: absolute;
491
+ top: 0;
492
+ bottom: 0;
493
+ left: calc(var(--value-start, 0) * 100%);
494
+ width: calc((var(--value-end, 0) - var(--value-start, 0)) * 100%);
495
+ background: var(--fill-image, var(--_fill-color-alpha));
496
+ }
497
+
498
+ /* Circular grow: filled circle growing from center */
499
+ :host([fill-style="circular"][circular-style="grow"]) .value,
500
+ :host([fill-style="circular"]:not([circular-style])) .value {
501
+ background: var(--fill-image, var(--_fill-color-alpha));
502
+ clip-path: circle(calc(var(--value) * 50%) at 50% 50%);
503
+ }
504
+
505
+ /* Circular offset: value circle slides left/right from center.
506
+ Track circle is centered, filling the height.
507
+ Value circle is same size, offset by --value-offset-px.
508
+ At value=0.5: value circle centered on track (invisible when overlaid)
509
+ At value=0: value circle at far left
510
+ At value=1: value circle at far right
511
+ */
512
+ :host([fill-style="circular"][circular-style="offset"]) {
513
+ min-width: 80px;
514
+ min-height: 26px;
515
+ overflow: hidden;
516
+ }
517
+
518
+ :host([fill-style="circular"][circular-style="offset"]) .track {
519
+ position: absolute;
520
+ top: 50%;
521
+ border-radius: 50%;
522
+ background: var(--surface-4, oklch(22% 0.02 240));
523
+ border: var(--border, 1px solid oklch(25% 0.02 240));
524
+ width: calc(var(--radius, 11px) * 2);
525
+ height: calc(var(--radius, 11px) * 2);
526
+ left: 50%;
527
+ transform: translate(-50%, -50%);
528
+ }
529
+
530
+ :host([fill-style="circular"][circular-style="offset"]) .value {
531
+ position: absolute;
532
+ top: 50%;
533
+ background: var(--fill-image, var(--_fill-color-alpha));
534
+ border-radius: 50%;
535
+ width: calc(var(--radius, 11px) * 2);
536
+ height: calc(var(--radius, 11px) * 2);
537
+ transform: translate(calc(var(--value-center-px, 13px) - var(--radius, 11px)), -50%);
538
+ }
539
+
540
+ :host([fill-style="circular"][circular-style="offset"]) .number {
541
+ border-radius: 0;
542
+ }
543
+
544
+ /* Circular dot: full circle */
545
+ :host([fill-style="circular"][circular-style="dot"]) .value {
546
+ background: var(--fill-image, var(--_fill-color-alpha));
547
+ }
548
+
549
+ /* ── Number (top layer - text display) ── */
550
+ :host([fill-style]) .number {
551
+ position: absolute;
552
+ inset: 0;
553
+ z-index: 2;
554
+ display: flex;
555
+ align-items: center;
556
+ justify-content: center;
557
+ font-family: inherit;
558
+ font-size: inherit;
559
+ color: inherit;
560
+ padding: var(--space-xs, 3px) var(--space-s, 4px);
561
+ }
562
+
563
+ :host([fill-style="circular"]) .number {
564
+ border-radius: 50%;
565
+ }
566
+
567
+ /* Drag cursor + no text selection while not in text-edit mode */
568
+ :host(:not([disabled]):not([no-drag])) .number:not([contenteditable="plaintext-only"]) {
569
+ cursor: ns-resize;
570
+ user-select: none;
571
+ -webkit-user-select: none;
572
+ touch-action: none;
573
+ }
574
+
575
+ /* Focus outline */
576
+ :host .number {
577
+ outline: none;
578
+ }
579
+
580
+ :host .number:focus-visible {
581
+ outline: 2px solid var(--accent);
582
+ outline-offset: 2px;
583
+ }
584
+
585
+ /* ── Circular host sizing ── */
586
+ :host([fill-style="circular"][circular-style="grow"]),
587
+ :host([fill-style="circular"]:not([circular-style])) {
588
+ aspect-ratio: 1;
589
+ }
590
+ `
591
+ ];
592
+ }
593
+ };
594
+ __decorate([property({ type: Number })], EditableNumber.prototype, "min", void 0);
595
+ __decorate([property({ type: Number })], EditableNumber.prototype, "max", void 0);
596
+ __decorate([property({ type: Number })], EditableNumber.prototype, "step", void 0);
597
+ __decorate([property({ type: Number })], EditableNumber.prototype, "stops", void 0);
598
+ __decorate([property({
599
+ type: Number,
600
+ attribute: `drag-sensitivity`
601
+ })], EditableNumber.prototype, "dragSensitivity", void 0);
602
+ __decorate([property({ attribute: `fill-style` })], EditableNumber.prototype, "fillStyle", void 0);
603
+ __decorate([property({ attribute: `linear-style` })], EditableNumber.prototype, "linearStyle", void 0);
604
+ __decorate([property({ attribute: `circular-style` })], EditableNumber.prototype, "circularStyle", void 0);
605
+ __decorate([property({
606
+ type: Boolean,
607
+ attribute: `no-drag`
608
+ })], EditableNumber.prototype, "noDrag", void 0);
609
+ __decorate([property({ type: Number })], EditableNumber.prototype, "precision", void 0);
610
+ EditableNumber = __decorate([safeCustomElement(`ixfx-editable-number`)], EditableNumber);
611
+ //#endregion
612
+ //#region src/labelled-slider-input/labelled-slider-input.ts
613
+ let LabelledSliderInput = class LabelledSliderInput extends LabelledInputBase {
614
+ constructor(..._args) {
615
+ super(..._args);
616
+ this.inputSelector = `ixfx-slider-input`;
617
+ this.orientation = `horizontal`;
618
+ this.singleStyle = `range`;
619
+ this.markerStyle = `needle`;
620
+ this.stops = void 0;
621
+ this.disabled = false;
622
+ this.swipeable = false;
623
+ this.lighttouch = false;
624
+ this.switchHeight = 80;
625
+ }
626
+ _renderEditableNumber() {
627
+ if (this._isMini) return html``;
628
+ return html`
629
+ <ixfx-editable-number
630
+ class="number"
631
+ mode="label"
632
+ no-drag
633
+ ?lighttouch=${this.lighttouch}
634
+ .value=${String(this.value)}
635
+ .min=${this.min}
636
+ .max=${this.max}
637
+ .step=${this.step}
638
+ .dragSensitivity=${this.dragSensitivity}
639
+ .precision=${this.precision}
640
+ .displayText=${this.label}
641
+ .displayTextLogic=${this._isDragging ? `hidden` : this.displayTextLogic}
642
+ .formatter=${this._formatter}
643
+ @change=${this._handleNumberChange}
644
+ ></ixfx-editable-number>
645
+ `;
646
+ }
647
+ _syncValue(v) {
648
+ super._syncValue(v);
649
+ const input = this.renderRoot?.querySelector(this.inputSelector);
650
+ if (input && typeof input.valueA === `number` && input.valueA !== v) input.valueA = v;
651
+ }
652
+ render() {
653
+ return html`
654
+ <div class="wrap ${this._isMini ? `mini` : ``}">
655
+ ${this._renderEditableNumber()}
656
+ <ixfx-slider-input
657
+ class="slider"
658
+ ?lighttouch=${this.lighttouch}
659
+ ?disabled=${this.disabled}
660
+ ?swipeable=${this.swipeable}
661
+ .valueA=${this.value}
662
+ .min=${this.min}
663
+ .max=${this.max}
664
+ .step=${this.step}
665
+ .stops=${this.stops}
666
+ .orientation=${this.orientation}
667
+ .singleStyle=${this.singleStyle}
668
+ .markerStyle=${this.markerStyle}
669
+ @input=${this._handleSliderInput}
670
+ @change=${this._handleInputChange}
671
+ ></ixfx-slider-input>
672
+ </div>
673
+ `;
674
+ }
675
+ static {
676
+ this.styles = css`
677
+ :host {
678
+ display: block;
679
+ container-type: size;
680
+ min-height: var(--min-height, 20px);
681
+ min-width: var(--min-width, 50px);
682
+ width: var(--width, auto);
683
+ height: var(--height, 100px);
684
+ }
685
+
686
+ /* One focus ring for the whole control: the inner slider's own ring is
687
+ suppressed (see ixfx-slider-input below) and re-drawn here so it wraps
688
+ the label + slider group instead of just the track. */
689
+ :host(:focus-within) {
690
+ outline: 2px solid var(--accent);
691
+ outline-offset: 2px;
692
+ }
693
+
694
+ .wrap {
695
+ display: flex;
696
+ width: 100%;
697
+ height: 100%;
698
+ align-items: center;
699
+ }
700
+
701
+ ixfx-editable-number {
702
+ flex-shrink: 0;
703
+ }
704
+
705
+ ixfx-slider-input {
706
+ flex: 1;
707
+ min-width: 0;
708
+ /* Suppress the slider's own focus ring; the wrapper draws one around
709
+ the whole control via :host(:focus-within) above. */
710
+ --slider-input-svg-focus-outline: none;
711
+ --slider-input-svg-focus-outline-offset: 0;
712
+ }
713
+
714
+ /* Default (compact): horizontal — label beside slider */
715
+ .wrap {
716
+ flex-direction: var(--flow, row);
717
+ justify-content: flex-start;
718
+ align-items: center;
719
+ }
720
+
721
+ ixfx-editable-number {
722
+ --label-align: left;
723
+ width: var(--label-width, 5ch);
724
+ --label-min-width: var(--label-width, 5ch);
725
+ /* Block fill/background variables from reaching editable-number */
726
+ --fill-color: initial;
727
+ --fill-opacity: initial;
728
+ --fill-image: initial;
729
+ }
730
+
731
+ /* Vertically-stacked layout: applied when the container is tall enough
732
+ to fit label + slider, OR when the author forces it with --flow:
733
+ column (a style query, so an explicit --flow: column brings the
734
+ label/slider companion rules too — not just the flex direction — and
735
+ therefore works at any --height, not only >= 80px). */
736
+ @container (height >= 80px) or style(--flow: column) {
737
+ .wrap {
738
+ flex-direction: var(--flow, column);
739
+ /* Centre the label+slider group so any height the component is
740
+ given beyond what the two need is split evenly above and below,
741
+ rather than dumped into a stretched slider. */
742
+ justify-content: center;
743
+ align-items: center;
744
+ }
745
+
746
+ ixfx-editable-number {
747
+ --label-align: center;
748
+ /* Stretch (not width: 100%): in the normal stacked column this is
749
+ visually identical (full-width centered label), but a hardcoded
750
+ 100% width would also apply when --flow forces a row at this
751
+ height — eating the whole row and squeezing the slider to zero. */
752
+ align-self: stretch;
753
+ width: auto;
754
+ }
755
+
756
+ ixfx-slider-input {
757
+ width: 100%;
758
+ /* Don't stretch to fill the column. The slider paints its bar
759
+ thickness as a fraction of the height it's handed, so a fat
760
+ lane-track-width in a tall slot leaves most of that slot as
761
+ dead space. Cap it to a sensible band (override with
762
+ --slider-thickness) and let the centred group absorb the rest. */
763
+ flex: 0 1 auto;
764
+ height: var(--slider-thickness, 2.5em);
765
+ max-height: 100%;
766
+ }
767
+ }
768
+
769
+ /* Mini mode: slider fills the full component */
770
+ .wrap.mini {
771
+ gap: 0;
772
+ }
773
+
774
+ .wrap.mini ixfx-slider-input {
775
+ width: 100%;
776
+ height: 100%;
777
+ }
778
+ `;
779
+ }
780
+ };
781
+ __decorate([property({ type: String })], LabelledSliderInput.prototype, "orientation", void 0);
782
+ __decorate([property({
783
+ type: String,
784
+ attribute: `single-style`
785
+ })], LabelledSliderInput.prototype, "singleStyle", void 0);
786
+ __decorate([property({
787
+ type: String,
788
+ attribute: `marker-style`
789
+ })], LabelledSliderInput.prototype, "markerStyle", void 0);
790
+ __decorate([property({ type: Number })], LabelledSliderInput.prototype, "stops", void 0);
791
+ __decorate([property({
792
+ type: Boolean,
793
+ reflect: true
794
+ })], LabelledSliderInput.prototype, "disabled", void 0);
795
+ __decorate([property({
796
+ type: Boolean,
797
+ reflect: true
798
+ })], LabelledSliderInput.prototype, "swipeable", void 0);
799
+ __decorate([property({ type: Boolean })], LabelledSliderInput.prototype, "lighttouch", void 0);
800
+ __decorate([property({
801
+ type: Number,
802
+ attribute: `switch-height`
803
+ })], LabelledSliderInput.prototype, "switchHeight", void 0);
804
+ LabelledSliderInput = __decorate([safeCustomElement(`ixfx-labelled-slider-input`)], LabelledSliderInput);
805
+ //#endregion
806
+ export { EditableNumber as n, LabelledSliderInput as t };
807
+
808
+ //# sourceMappingURL=labelled-slider-input-DzigjMwP.js.map