@ixfx/components 0.2.6 → 0.3.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 (141) hide show
  1. package/bundle/index.d.ts +213 -117
  2. package/bundle/index.d.ts.map +1 -1
  3. package/bundle/index.js +1438 -686
  4. package/bundle/index.js.map +1 -1
  5. package/dist/ac-text.js +3 -3
  6. package/dist/ac-text.js.map +1 -1
  7. package/dist/{button-B9ztaKyl.js → button-DMt5XWUK.js} +4 -4
  8. package/dist/{button-B9ztaKyl.js.map → button-DMt5XWUK.js.map} +1 -1
  9. package/dist/button.js +1 -1
  10. package/dist/checkbox.d.ts +2 -3
  11. package/dist/checkbox.d.ts.map +1 -1
  12. package/dist/checkbox.js +1 -1
  13. package/dist/checkbox.js.map +1 -1
  14. package/dist/{colour-C3MQIjFJ-BJV-QC-3.js → colour-C3MQIjFJ-BLXg8W3U.js} +2 -2
  15. package/dist/{colour-C3MQIjFJ-BJV-QC-3.js.map → colour-C3MQIjFJ-BLXg8W3U.js.map} +1 -1
  16. package/dist/{colour-picker-BNqDz4wK.js → colour-picker-K6zu82lm.js} +5 -5
  17. package/dist/{colour-picker-BNqDz4wK.js.map → colour-picker-K6zu82lm.js.map} +1 -1
  18. package/dist/colour-picker.js +1 -1
  19. package/dist/crumbs.d.ts +2 -3
  20. package/dist/crumbs.d.ts.map +1 -1
  21. package/dist/crumbs.js +10 -10
  22. package/dist/crumbs.js.map +1 -1
  23. package/dist/data-display.js +3 -3
  24. package/dist/{decorate-O4m1U4l3.js → decorate-D7rC1gLP.js} +10 -8
  25. package/dist/decorate-D7rC1gLP.js.map +1 -0
  26. package/dist/{defaults-FEZaGiYZ.js → defaults-C7elhuyJ.js} +2 -2
  27. package/dist/{defaults-FEZaGiYZ.js.map → defaults-C7elhuyJ.js.map} +1 -1
  28. package/dist/{dist-By5URG0Y.js → dist-BX0OVIm7.js} +2 -2
  29. package/dist/{dist-By5URG0Y.js.map → dist-BX0OVIm7.js.map} +1 -1
  30. package/dist/{dist-D7kJgnSE.js → dist-TAGYwaju.js} +1 -1
  31. package/dist/{dist-D7kJgnSE.js.map → dist-TAGYwaju.js.map} +1 -1
  32. package/dist/editable-label.d.ts +6 -1
  33. package/dist/editable-label.d.ts.map +1 -1
  34. package/dist/editable-label.js +49 -2
  35. package/dist/editable-label.js.map +1 -1
  36. package/dist/{hex-editor-gH3mteMr.js → hex-editor-CsN_ySkH.js} +85 -85
  37. package/dist/hex-editor-CsN_ySkH.js.map +1 -0
  38. package/dist/{hex-editor-2_s0Ua5t.d.ts → hex-editor-DlfoA65y.d.ts} +5 -5
  39. package/dist/{hex-editor-2_s0Ua5t.d.ts.map → hex-editor-DlfoA65y.d.ts.map} +1 -1
  40. package/dist/hex.d.ts +1 -1
  41. package/dist/hex.js +1 -1
  42. package/dist/{highlight-CAjwQ4GE.js → highlight-TPbSHruI.js} +3 -3
  43. package/dist/highlight-TPbSHruI.js.map +1 -0
  44. package/dist/{icon-CYACf6o8.js → icon-9NWTXtE1.js} +4 -5
  45. package/dist/icon-9NWTXtE1.js.map +1 -0
  46. package/dist/icon-CeTDJhC7.d.ts.map +1 -1
  47. package/dist/icons.js +3 -3
  48. package/dist/{incr-search-BZawvrfl.js → incr-search-DSKKsk6w.js} +12 -10
  49. package/dist/incr-search-DSKKsk6w.js.map +1 -0
  50. package/dist/incr-search.d.ts +1 -1
  51. package/dist/incr-search.js +2 -2
  52. package/dist/{index-CwGkb9s1.d.ts → index--hrxPBkQ.d.ts} +69 -69
  53. package/dist/index--hrxPBkQ.d.ts.map +1 -0
  54. package/dist/{index-kY5gxbkI.d.ts → index-DSlPeWLK.d.ts} +15 -15
  55. package/dist/{index-kY5gxbkI.d.ts.map → index-DSlPeWLK.d.ts.map} +1 -1
  56. package/dist/{index-V2cJorlA.d.ts → index-hXFn14tM.d.ts} +4 -4
  57. package/dist/index-hXFn14tM.d.ts.map +1 -0
  58. package/dist/index.d.ts +109 -13
  59. package/dist/index.d.ts.map +1 -1
  60. package/dist/index.js +748 -52
  61. package/dist/index.js.map +1 -1
  62. package/dist/keyboard-De_vOHLg.js.map +1 -1
  63. package/dist/{labelled-input-base-BvgH7ldm.js → labelled-input-base-CqPL5rKm.js} +2 -2
  64. package/dist/labelled-input-base-CqPL5rKm.js.map +1 -0
  65. package/dist/labelled-radial-input.js +3 -3
  66. package/dist/labelled-radial-input.js.map +1 -1
  67. package/dist/labelled-range-input.js +2 -2
  68. package/dist/led.js +1 -1
  69. package/dist/{menu-C3eANB5M.js → menu-DJJuCm-5.js} +48 -48
  70. package/dist/menu-DJJuCm-5.js.map +1 -0
  71. package/dist/{menu-item-6IU5weHi.js → menu-item-CKRfP0pN.js} +10 -10
  72. package/dist/menu-item-CKRfP0pN.js.map +1 -0
  73. package/dist/menu.d.ts +1 -1
  74. package/dist/menu.js +2 -2
  75. package/dist/miller.d.ts +5 -7
  76. package/dist/miller.d.ts.map +1 -1
  77. package/dist/miller.js +14 -14
  78. package/dist/miller.js.map +1 -1
  79. package/dist/narrowed-text.d.ts.map +1 -1
  80. package/dist/narrowed-text.js +4 -4
  81. package/dist/narrowed-text.js.map +1 -1
  82. package/dist/panel.js +2 -2
  83. package/dist/panel.js.map +1 -1
  84. package/dist/plots.js +1 -1
  85. package/dist/polar-pad.d.ts.map +1 -1
  86. package/dist/polar-pad.js +1 -1
  87. package/dist/polar-pad.js.map +1 -1
  88. package/dist/{popup-Ddx9LCzY.js → popup-ImtS9KnS.js} +1 -1
  89. package/dist/{popup-Ddx9LCzY.js.map → popup-ImtS9KnS.js.map} +1 -1
  90. package/dist/{prominence-CreDBdCs.js → prominence--ic9uWBl.js} +1 -1
  91. package/dist/{prominence-CreDBdCs.js.map → prominence--ic9uWBl.js.map} +1 -1
  92. package/dist/{radial-input-Dbc6fgCK.js → radial-input-DZA6WaFu.js} +14 -14
  93. package/dist/radial-input-DZA6WaFu.js.map +1 -0
  94. package/dist/radial-input.js +1 -1
  95. package/dist/range-input.js +1 -1
  96. package/dist/range.js +2 -2
  97. package/dist/{registry-CZEB1YI9.js → registry-Q2gYQCHM.js} +1 -1
  98. package/dist/{registry-CZEB1YI9.js.map → registry-Q2gYQCHM.js.map} +1 -1
  99. package/dist/selecthorizontal.js +1 -1
  100. package/dist/snap-container.js +1 -1
  101. package/dist/split-layout.js +4 -4
  102. package/dist/split-layout.js.map +1 -1
  103. package/dist/swipe.d.ts +1 -2
  104. package/dist/swipe.d.ts.map +1 -1
  105. package/dist/swipe.js +2 -2
  106. package/dist/swipe.js.map +1 -1
  107. package/dist/tab-list-BnqISNvO.d.ts.map +1 -1
  108. package/dist/tabs.js +2 -2
  109. package/dist/tabs.js.map +1 -1
  110. package/dist/{timeline-B62Sz6J_.js → timeline-Cv75Th2U.js} +120 -116
  111. package/dist/timeline-Cv75Th2U.js.map +1 -0
  112. package/dist/timeline.d.ts +1 -1
  113. package/dist/timeline.js +1 -1
  114. package/dist/tooltip-CwGfb4lp.d.ts.map +1 -1
  115. package/dist/tree-CvvKbO-f.js +1330 -0
  116. package/dist/tree-CvvKbO-f.js.map +1 -0
  117. package/dist/{tree-component-CQpoPo4s.d.ts → tree-component-D8Bg48tt.d.ts} +12 -12
  118. package/dist/{tree-component-CQpoPo4s.d.ts.map → tree-component-D8Bg48tt.d.ts.map} +1 -1
  119. package/dist/tree.d.ts +1 -1
  120. package/dist/tree.js +1 -1143
  121. package/dist/xy-axis-D9uwpGTT.d.ts.map +1 -1
  122. package/dist/{xy-axis-C7fNxDwY.js → xy-axis-DL0tfJDr.js} +10 -10
  123. package/dist/{xy-axis-C7fNxDwY.js.map → xy-axis-DL0tfJDr.js.map} +1 -1
  124. package/dist/xy-pad.js +2 -2
  125. package/package.json +3 -3
  126. package/dist/decorate-O4m1U4l3.js.map +0 -1
  127. package/dist/hex-editor-gH3mteMr.js.map +0 -1
  128. package/dist/highlight-CAjwQ4GE.js.map +0 -1
  129. package/dist/icon-CYACf6o8.js.map +0 -1
  130. package/dist/incr-search-BZawvrfl.js.map +0 -1
  131. package/dist/index-CwGkb9s1.d.ts.map +0 -1
  132. package/dist/index-V2cJorlA.d.ts.map +0 -1
  133. package/dist/labelled-input-base-BvgH7ldm.js.map +0 -1
  134. package/dist/menu-C3eANB5M.js.map +0 -1
  135. package/dist/menu-item-6IU5weHi.js.map +0 -1
  136. package/dist/radial-input-Dbc6fgCK.js.map +0 -1
  137. package/dist/timeline-B62Sz6J_.js.map +0 -1
  138. package/dist/tree-data-model-DGvRVOFY.js +0 -190
  139. package/dist/tree-data-model-DGvRVOFY.js.map +0 -1
  140. package/dist/tree.js.map +0 -1
  141. /package/dist/{interaction-CQDQJf2Q.js → interaction-DG7X1rhI.js} +0 -0
@@ -1,7 +1,71 @@
1
- import { n as safeCustomElement, t as __decorate } from "./decorate-O4m1U4l3.js";
1
+ import { n as safeCustomElement, t as __decorate } from "./decorate-D7rC1gLP.js";
2
2
  import { LitElement, css, html, nothing } from "lit";
3
3
  import { property, state } from "lit/decorators.js";
4
4
  import "@clinth/vcanvas";
5
+ //#region src/timeline/timeline-controller.ts
6
+ /**
7
+ * External adapter class that can configure a timeline element
8
+ * with musical time, custom label formatting, etc.
9
+ *
10
+ * The controller has no import of any timeline element type.
11
+ * Users create a controller, pass it the component instance,
12
+ * and the controller calls the component's public API.
13
+ */
14
+ var TimelineController = class {
15
+ #host;
16
+ #config;
17
+ #bpm = 120;
18
+ #timeSignatureNumerator = 4;
19
+ #timeSignatureDenominator = 4;
20
+ constructor(timeline, config) {
21
+ this.#host = timeline;
22
+ this.#config = config;
23
+ timeline.min = config.logicalMin;
24
+ timeline.max = config.logicalMax;
25
+ if (config.labelFormatter) timeline.formatLabel = config.labelFormatter;
26
+ timeline.addEventListener(`track-select`, this.#onTrackSelect);
27
+ }
28
+ /** Update the tempo (BPM) for musical time calculations. */
29
+ setTempo(bpm) {
30
+ this.#bpm = bpm;
31
+ this.#updateFormatLabel();
32
+ }
33
+ /** Update the time signature for musical time calculations. */
34
+ setTimeSignature(numerator, denominator) {
35
+ this.#timeSignatureNumerator = numerator;
36
+ this.#timeSignatureDenominator = denominator;
37
+ this.#updateFormatLabel();
38
+ }
39
+ /** Set the visible view range on the timeline. */
40
+ setViewRange(range) {
41
+ this.#host.setViewRange(range);
42
+ }
43
+ /** Clean up any resources held by the controller. */
44
+ dispose() {
45
+ this.#host.removeEventListener(`track-select`, this.#onTrackSelect);
46
+ }
47
+ #onTrackSelect = (e) => {
48
+ const detail = e.detail;
49
+ const trackEventIds = this.#host.getTrackEvents(detail.trackKey).map((e) => e.id);
50
+ if (detail.shiftKey) {
51
+ const current = new Set(this.#host.selectedIds);
52
+ for (const id of trackEventIds) if (current.has(id)) current.delete(id);
53
+ else current.add(id);
54
+ this.#host.selectedIds = [...current];
55
+ } else this.#host.selectedIds = trackEventIds;
56
+ };
57
+ #updateFormatLabel() {
58
+ if (this.#config.labelFormatter) return;
59
+ this.#bpm;
60
+ const num = this.#timeSignatureNumerator;
61
+ this.#host.formatLabel = (v) => {
62
+ const beatsPerBar = num;
63
+ const totalBeats = v;
64
+ return `${Math.floor(totalBeats / beatsPerBar) + 1}.${Math.floor(totalBeats % beatsPerBar) + 1}`;
65
+ };
66
+ }
67
+ };
68
+ //#endregion
5
69
  //#region src/timeline/timeline-draw.ts
6
70
  const NICE_STEPS = [
7
71
  1,
@@ -12,15 +76,15 @@ const NICE_STEPS = [
12
76
  /**
13
77
  * Dispatch to adaptive or fixed grid mode.
14
78
  */
15
- const resolveGrid = (viewRange, userScale, viewportWidth, mode = `adaptive`, fixedMinorStep, ppu) => {
79
+ function resolveGrid(viewRange, userScale, viewportWidth, mode = `adaptive`, fixedMinorStep, ppu) {
16
80
  if (mode === `fixed` && fixedMinorStep !== void 0 && ppu !== void 0) return resolveFixedGrid(fixedMinorStep, ppu);
17
81
  return resolveAdaptiveGrid(viewRange, userScale, viewportWidth);
18
- };
82
+ }
19
83
  /**
20
84
  * Compute a nice major/minor grid resolution for the current view.
21
85
  * Uses a 1-2-5-10 "nice number" algorithm.
22
86
  */
23
- const resolveAdaptiveGrid = (viewRange, userScale, viewportWidth) => {
87
+ function resolveAdaptiveGrid(viewRange, userScale, viewportWidth) {
24
88
  const span = viewRange.max - viewRange.min;
25
89
  if (span <= 0 || viewportWidth <= 0) return {
26
90
  majorStep: 100,
@@ -29,7 +93,7 @@ const resolveAdaptiveGrid = (viewRange, userScale, viewportWidth) => {
29
93
  };
30
94
  const targetPx = 80 * scaleMultiplier(userScale);
31
95
  const rawStep = span / Math.max(2, Math.floor(viewportWidth / targetPx));
32
- const magnitude = Math.pow(10, Math.floor(Math.log10(rawStep)));
96
+ const magnitude = 10 ** Math.floor(Math.log10(rawStep));
33
97
  let bestStep = magnitude;
34
98
  for (const n of NICE_STEPS) {
35
99
  const candidate = n * magnitude;
@@ -46,14 +110,14 @@ const resolveAdaptiveGrid = (viewRange, userScale, viewportWidth) => {
46
110
  minorDivisions,
47
111
  minorStep
48
112
  };
49
- };
113
+ }
50
114
  /**
51
115
  * Fixed grid: user specifies a base minor step in logical units.
52
116
  * If the minor step at current zoom would produce lines < 5px apart,
53
117
  * double the effective step until they're >= 5px.
54
118
  * Major = 4× effective minor.
55
119
  */
56
- const resolveFixedGrid = (baseMinorStep, ppu) => {
120
+ function resolveFixedGrid(baseMinorStep, ppu) {
57
121
  const MIN_PX_BETWEEN = 5;
58
122
  let effectiveMinor = baseMinorStep;
59
123
  while (effectiveMinor * ppu < MIN_PX_BETWEEN && effectiveMinor < 0xe8d4a51000) effectiveMinor *= 2;
@@ -63,8 +127,8 @@ const resolveFixedGrid = (baseMinorStep, ppu) => {
63
127
  minorDivisions,
64
128
  minorStep: effectiveMinor
65
129
  };
66
- };
67
- const scaleMultiplier = (scale) => {
130
+ }
131
+ function scaleMultiplier(scale) {
68
132
  switch (scale) {
69
133
  case `x-wide`: return 2;
70
134
  case `wide`: return 1.5;
@@ -73,8 +137,8 @@ const scaleMultiplier = (scale) => {
73
137
  case `x-slim`: return .5;
74
138
  default: return 1;
75
139
  }
76
- };
77
- const drawMajorMinorGrid = (ctx, region, resolution, altMajorBg, vars, ppu) => {
140
+ }
141
+ function drawMajorMinorGrid(ctx, region, resolution, altMajorBg, vars, ppu) {
78
142
  const { majorStep, minorStep } = resolution;
79
143
  if (majorStep <= 0) return;
80
144
  const regionEnd = region.x + region.width;
@@ -88,7 +152,7 @@ const drawMajorMinorGrid = (ctx, region, resolution, altMajorBg, vars, ppu) => {
88
152
  }
89
153
  if (minorStep > 0) {
90
154
  ctx.strokeStyle = vars[`--timeline-grid-minor-color`] ?? `rgba(255,255,255,0.05)`;
91
- ctx.lineWidth = parseFloat(vars[`--timeline-grid-minor-width`] ?? `0.5`);
155
+ ctx.lineWidth = Number.parseFloat(vars[`--timeline-grid-minor-width`] ?? `0.5`);
92
156
  ctx.beginPath();
93
157
  const firstMinor = Math.floor(region.x / minorStep) * minorStep;
94
158
  for (let val = firstMinor; val < regionEnd; val += minorStep) {
@@ -100,7 +164,7 @@ const drawMajorMinorGrid = (ctx, region, resolution, altMajorBg, vars, ppu) => {
100
164
  ctx.stroke();
101
165
  }
102
166
  ctx.strokeStyle = vars[`--timeline-grid-major-color`] ?? `rgba(255,255,255,0.12)`;
103
- ctx.lineWidth = parseFloat(vars[`--timeline-grid-major-width`] ?? `1`);
167
+ ctx.lineWidth = Number.parseFloat(vars[`--timeline-grid-major-width`] ?? `1`);
104
168
  ctx.beginPath();
105
169
  const firstMajor = Math.floor(region.x / majorStep) * majorStep;
106
170
  for (let val = firstMajor; val < regionEnd; val += majorStep) {
@@ -109,13 +173,13 @@ const drawMajorMinorGrid = (ctx, region, resolution, altMajorBg, vars, ppu) => {
109
173
  ctx.lineTo(px, region.y + region.height);
110
174
  }
111
175
  ctx.stroke();
112
- };
176
+ }
113
177
  /**
114
178
  * Draw the axis header band. With 2D virtualization the axis is "sticky" —
115
179
  * it is always drawn at the current vertical scroll position (`scrollTop`)
116
180
  * so it appears fixed at the viewport top.
117
181
  */
118
- const drawAxis = (ctx, region, resolution, axisHeight, formatLabel, vars, ppu, scrollTop = 0) => {
182
+ function drawAxis(ctx, region, resolution, axisHeight, formatLabel, vars, ppu, scrollTop = 0) {
119
183
  const { majorStep } = resolution;
120
184
  if (majorStep <= 0 || axisHeight <= 0) return;
121
185
  const axisTop = scrollTop;
@@ -127,7 +191,7 @@ const drawAxis = (ctx, region, resolution, axisHeight, formatLabel, vars, ppu, s
127
191
  const bgLeft = region.x * ppu;
128
192
  ctx.fillRect(bgLeft, axisTop, region.width * ppu, bgHeight);
129
193
  ctx.strokeStyle = vars[`--timeline-grid-major-color`] ?? `rgba(255,255,255,0.12)`;
130
- ctx.lineWidth = parseFloat(vars[`--timeline-grid-major-width`] ?? `1`);
194
+ ctx.lineWidth = Number.parseFloat(vars[`--timeline-grid-major-width`] ?? `1`);
131
195
  ctx.beginPath();
132
196
  const firstMajor = Math.ceil(region.x / majorStep) * majorStep;
133
197
  for (let val = firstMajor; val < regionEnd; val += majorStep) {
@@ -152,8 +216,8 @@ const drawAxis = (ctx, region, resolution, axisHeight, formatLabel, vars, ppu, s
152
216
  ctx.fillText(formatLabel(val), px + labelPadding, axisTop + bgHeight / 2);
153
217
  }
154
218
  ctx.textAlign = `start`;
155
- };
156
- const drawTrackBackgrounds = (ctx, region, trackLayout, tracks, vars, ppu) => {
219
+ }
220
+ function drawTrackBackgrounds(ctx, region, trackLayout, tracks, vars, ppu) {
157
221
  const bgDefault = vars[`--timeline-track-bg`] ?? `#1a1a1a`;
158
222
  const bgAlt = vars[`--timeline-track-bg-alt`] ?? `#1e1e1e`;
159
223
  for (let i = 0; i < trackLayout.length; i++) {
@@ -161,7 +225,7 @@ const drawTrackBackgrounds = (ctx, region, trackLayout, tracks, vars, ppu) => {
161
225
  if (layout.y + layout.height < region.y) continue;
162
226
  if (layout.y > region.y + region.height) break;
163
227
  const track = tracks.find((t) => t.key === layout.trackKey);
164
- ctx.fillStyle = track?.color ? track.color + `22` : i % 2 === 0 ? bgDefault : bgAlt;
228
+ ctx.fillStyle = track?.color ? `${track.color}22` : i % 2 === 0 ? bgDefault : bgAlt;
165
229
  ctx.fillRect(region.x * ppu, layout.y, region.width * ppu, layout.height);
166
230
  ctx.strokeStyle = vars[`--timeline-grid-major-color`] ?? `rgba(255,255,255,0.12)`;
167
231
  ctx.lineWidth = .5;
@@ -170,13 +234,13 @@ const drawTrackBackgrounds = (ctx, region, trackLayout, tracks, vars, ppu) => {
170
234
  ctx.lineTo((region.x + region.width) * ppu, layout.y + layout.height);
171
235
  ctx.stroke();
172
236
  }
173
- };
174
- const drawEventRects = (ctx, region, events, trackLayout, selectedIds, tickledId, drag, vars, ppu) => {
237
+ }
238
+ function drawEventRects(ctx, region, events, trackLayout, selectedIds, tickledId, drag, vars, ppu) {
175
239
  const eventBg = vars[`--timeline-event-bg`] ?? `#3498db`;
176
240
  const eventSelectedBg = vars[`--timeline-event-selected-bg`] ?? `#5dade2`;
177
241
  const eventTickledBg = vars[`--timeline-event-tickled-bg`] ?? `#444`;
178
242
  const eventLabelColor = vars[`--timeline-event-label-color`] ?? `#fff`;
179
- const radius = parseFloat(vars[`--timeline-event-radius`] ?? `4`);
243
+ const radius = Number.parseFloat(vars[`--timeline-event-radius`] ?? `4`);
180
244
  const regionEnd = region.x + region.width;
181
245
  const padding = 3;
182
246
  for (const evt of events) {
@@ -230,8 +294,8 @@ const drawEventRects = (ctx, region, events, trackLayout, selectedIds, tickledId
230
294
  ctx.restore();
231
295
  }
232
296
  }
233
- };
234
- const drawMarquee = (ctx, drag, ppu) => {
297
+ }
298
+ function drawMarquee(ctx, drag, ppu) {
235
299
  if (drag.kind !== `marquee`) return;
236
300
  const x1 = Math.min(drag.startLogicalX, drag.currentLogicalX) * ppu;
237
301
  const x2 = Math.max(drag.startLogicalX, drag.currentLogicalX) * ppu;
@@ -242,8 +306,8 @@ const drawMarquee = (ctx, drag, ppu) => {
242
306
  ctx.strokeStyle = `rgba(100, 150, 255, 0.6)`;
243
307
  ctx.lineWidth = 1;
244
308
  ctx.strokeRect(x1, y1, x2 - x1, y2 - y1);
245
- };
246
- const drawRoundRect = (ctx, x, y, w, h, r) => {
309
+ }
310
+ function drawRoundRect(ctx, x, y, w, h, r) {
247
311
  r = Math.max(0, r);
248
312
  ctx.moveTo(x + r, y);
249
313
  ctx.arcTo(x + w, y, x + w, y + h, r);
@@ -251,7 +315,7 @@ const drawRoundRect = (ctx, x, y, w, h, r) => {
251
315
  ctx.arcTo(x, y + h, x, y, r);
252
316
  ctx.arcTo(x, y, x + w, y, r);
253
317
  ctx.closePath();
254
- };
318
+ }
255
319
  const TIMELINE_CSS_VARS = [
256
320
  `--timeline-bg`,
257
321
  `--timeline-track-bg`,
@@ -268,12 +332,12 @@ const TIMELINE_CSS_VARS = [
268
332
  `--timeline-event-radius`,
269
333
  `--timeline-axis-label-color`
270
334
  ];
271
- const resolveCssVars = (host) => {
335
+ function resolveCssVars(host) {
272
336
  const computed = getComputedStyle(host);
273
337
  const vars = {};
274
338
  for (const v of TIMELINE_CSS_VARS) vars[v] = computed.getPropertyValue(v).trim();
275
339
  return vars;
276
- };
340
+ }
277
341
  //#endregion
278
342
  //#region src/timeline/timeline-interactions.ts
279
343
  /** Hit zone near the edge of an event (px in screen space) */
@@ -282,13 +346,17 @@ const EDGE_HIT_PX = 8;
282
346
  * Convert a vcanvas logical (pixel) coordinate to timeline logical units.
283
347
  * vcanvas pixel coordinates are in the 1:1 pixel space; divide by ppu then add min.
284
348
  */
285
- const canvasToTimeline = (canvasX, ppu, min) => canvasX / ppu + min;
349
+ function canvasToTimeline(canvasX, ppu, min) {
350
+ return canvasX / ppu + min;
351
+ }
286
352
  /**
287
353
  * Convert screen-space pixel distance to timeline logical units.
288
354
  * Used for edge hit threshold: how many logical units does EDGE_HIT_PX correspond to.
289
355
  */
290
- const pxToLogicalUnits = (ppu) => ppu > 0 ? 1 / ppu : 1;
291
- const hitTest = (logicalX, y, events, trackLayout, ppu) => {
356
+ function pxToLogicalUnits(ppu) {
357
+ return ppu > 0 ? 1 / ppu : 1;
358
+ }
359
+ function hitTest(logicalX, y, events, trackLayout, ppu) {
292
360
  const track = trackLayout.find((tl) => y >= tl.y && y < tl.y + tl.height);
293
361
  if (!track) return {
294
362
  kind: `empty`,
@@ -321,17 +389,19 @@ const hitTest = (logicalX, y, events, trackLayout, ppu) => {
321
389
  y,
322
390
  trackKey: track.trackKey
323
391
  };
324
- };
325
- const trackAtY = (y, trackLayout) => {
392
+ }
393
+ function trackAtY(y, trackLayout) {
326
394
  return trackLayout.find((tl) => y >= tl.y && y < tl.y + tl.height)?.trackKey;
327
- };
395
+ }
328
396
  /** Sensitivity: how many pixels of vertical drag = 1 e-fold of zoom */
329
397
  const ZOOM_SENSITIVITY_PX = 100;
330
398
  /**
331
399
  * Subtract a deadzone from a value.
332
400
  * Returns 0 if |value| <= deadzone, otherwise value shifted toward zero by deadzone.
333
401
  */
334
- const applyDeadzone = (value, deadzone) => Math.abs(value) > deadzone ? value - Math.sign(value) * deadzone : 0;
402
+ function applyDeadzone(value, deadzone) {
403
+ return Math.abs(value) > deadzone ? value - Math.sign(value) * deadzone : 0;
404
+ }
335
405
  /**
336
406
  * Compute new ppu + viewMin from an axis-zoom drag.
337
407
  * Vertical delta (dy) controls zoom (up = zoom in, down = zoom out), anchored at `anchorUnit`.
@@ -339,7 +409,7 @@ const applyDeadzone = (value, deadzone) => Math.abs(value) > deadzone ? value -
339
409
  *
340
410
  * Returns { ppu, viewMin } — the caller uses host.setZoomPan() to apply.
341
411
  */
342
- const computeAxisZoom = (startViewMin, startPpu, anchorUnit, dx, dy) => {
412
+ function computeAxisZoom(startViewMin, startPpu, anchorUnit, dx, dy) {
343
413
  const newPpu = startPpu * Math.exp(-dy / ZOOM_SENSITIVITY_PX);
344
414
  let newMin = anchorUnit - (anchorUnit - startViewMin) * startPpu / newPpu;
345
415
  if (newPpu > 0) newMin += -dx / newPpu;
@@ -347,7 +417,7 @@ const computeAxisZoom = (startViewMin, startPpu, anchorUnit, dx, dy) => {
347
417
  ppu: newPpu,
348
418
  viewMin: newMin
349
419
  };
350
- };
420
+ }
351
421
  /**
352
422
  * Compute new vertical view range from a v-axis-zoom drag.
353
423
  * Horizontal delta (dx) controls zoom (right = zoom in, left = zoom out),
@@ -356,7 +426,7 @@ const computeAxisZoom = (startViewMin, startPpu, anchorUnit, dx, dy) => {
356
426
  *
357
427
  * Returns { vMin, vMax } — the caller uses host.setVerticalZoomPan() to apply.
358
428
  */
359
- const computeVerticalAxisZoom = (startVMin, startVMax, startVScale, anchorBaseY, dx, dy) => {
429
+ function computeVerticalAxisZoom(startVMin, startVMax, startVScale, anchorBaseY, dx, dy) {
360
430
  const startSpan = startVMax - startVMin;
361
431
  const newSpan = startSpan * Math.exp(-dx / ZOOM_SENSITIVITY_PX);
362
432
  let newMin = anchorBaseY - (startSpan > 0 ? (anchorBaseY - startVMin) / startSpan : .5) * newSpan;
@@ -365,12 +435,12 @@ const computeVerticalAxisZoom = (startVMin, startVMax, startVScale, anchorBaseY,
365
435
  vMin: newMin,
366
436
  vMax: newMin + newSpan
367
437
  };
368
- };
438
+ }
369
439
  /**
370
440
  * Attaches pointer and keyboard interaction handlers to the timeline.
371
441
  * Returns a cleanup function.
372
442
  */
373
- const attachTimelineInteractions = (host, vcanvasEl) => {
443
+ function attachTimelineInteractions(host, vcanvasEl) {
374
444
  const ac = new AbortController();
375
445
  const signal = ac.signal;
376
446
  vcanvasEl.addEventListener(`pointerdown`, (e) => {
@@ -431,7 +501,6 @@ const attachTimelineInteractions = (host, vcanvasEl) => {
431
501
  currentLogicalX: lx,
432
502
  currentY: ly
433
503
  };
434
- return;
435
504
  }
436
505
  }, { signal });
437
506
  vcanvasEl.addEventListener(`pointermove`, (e) => {
@@ -504,7 +573,6 @@ const attachTimelineInteractions = (host, vcanvasEl) => {
504
573
  end: newEnd
505
574
  } : ev);
506
575
  vcanvasEl.invalidateAll();
507
- return;
508
576
  }
509
577
  }, { signal });
510
578
  vcanvasEl.addEventListener(`pointerup`, (e) => {
@@ -577,8 +645,8 @@ const attachTimelineInteractions = (host, vcanvasEl) => {
577
645
  }
578
646
  }, { signal });
579
647
  return () => ac.abort();
580
- };
581
- const handleHover = (host, vcanvasEl, e) => {
648
+ }
649
+ function handleHover(host, vcanvasEl, e) {
582
650
  const ppu = host.pxPerUnit;
583
651
  const canvasCoord = vcanvasEl.convertFromViewportToCanvas(e.offsetX, e.offsetY);
584
652
  const lx = canvasToTimeline(canvasCoord.x, ppu, host.min);
@@ -602,22 +670,22 @@ const handleHover = (host, vcanvasEl, e) => {
602
670
  host._tickledId = newTickledId;
603
671
  vcanvasEl.invalidateAll();
604
672
  }
605
- };
606
- const toggleSelection = (host, eventId) => {
673
+ }
674
+ function toggleSelection(host, eventId) {
607
675
  const next = new Set(host._selectedIds);
608
676
  if (next.has(eventId)) next.delete(eventId);
609
677
  else next.add(eventId);
610
678
  host._selectedIds = next;
611
679
  fireSelectionChange(host);
612
680
  host.getVCanvas()?.invalidateAll();
613
- };
614
- const fireSelectionChange = (host) => {
681
+ }
682
+ function fireSelectionChange(host) {
615
683
  host.dispatchEvent(new CustomEvent(`selection-change`, {
616
684
  detail: { selectedIds: [...host._selectedIds] },
617
685
  bubbles: true,
618
686
  composed: true
619
687
  }));
620
- };
688
+ }
621
689
  //#endregion
622
690
  //#region src/timeline/timeline-styles.ts
623
691
  const timelineStyles = css`
@@ -1679,70 +1747,6 @@ __decorate([state()], IxfxTimelineElement.prototype, "_internalEvents", void 0);
1679
1747
  __decorate([state()], IxfxTimelineElement.prototype, "_internalTracks", void 0);
1680
1748
  IxfxTimelineElement = __decorate([safeCustomElement(`ixfx-timeline`)], IxfxTimelineElement);
1681
1749
  //#endregion
1682
- //#region src/timeline/timeline-controller.ts
1683
- /**
1684
- * External adapter class that can configure a timeline element
1685
- * with musical time, custom label formatting, etc.
1686
- *
1687
- * The controller has no import of any timeline element type.
1688
- * Users create a controller, pass it the component instance,
1689
- * and the controller calls the component's public API.
1690
- */
1691
- var TimelineController = class {
1692
- #host;
1693
- #config;
1694
- #bpm = 120;
1695
- #timeSignatureNumerator = 4;
1696
- #timeSignatureDenominator = 4;
1697
- constructor(timeline, config) {
1698
- this.#host = timeline;
1699
- this.#config = config;
1700
- timeline.min = config.logicalMin;
1701
- timeline.max = config.logicalMax;
1702
- if (config.labelFormatter) timeline.formatLabel = config.labelFormatter;
1703
- timeline.addEventListener(`track-select`, this.#onTrackSelect);
1704
- }
1705
- /** Update the tempo (BPM) for musical time calculations. */
1706
- setTempo(bpm) {
1707
- this.#bpm = bpm;
1708
- this.#updateFormatLabel();
1709
- }
1710
- /** Update the time signature for musical time calculations. */
1711
- setTimeSignature(numerator, denominator) {
1712
- this.#timeSignatureNumerator = numerator;
1713
- this.#timeSignatureDenominator = denominator;
1714
- this.#updateFormatLabel();
1715
- }
1716
- /** Set the visible view range on the timeline. */
1717
- setViewRange(range) {
1718
- this.#host.setViewRange(range);
1719
- }
1720
- /** Clean up any resources held by the controller. */
1721
- dispose() {
1722
- this.#host.removeEventListener(`track-select`, this.#onTrackSelect);
1723
- }
1724
- #onTrackSelect = (e) => {
1725
- const detail = e.detail;
1726
- const trackEventIds = this.#host.getTrackEvents(detail.trackKey).map((e) => e.id);
1727
- if (detail.shiftKey) {
1728
- const current = new Set(this.#host.selectedIds);
1729
- for (const id of trackEventIds) if (current.has(id)) current.delete(id);
1730
- else current.add(id);
1731
- this.#host.selectedIds = [...current];
1732
- } else this.#host.selectedIds = trackEventIds;
1733
- };
1734
- #updateFormatLabel() {
1735
- if (this.#config.labelFormatter) return;
1736
- this.#bpm;
1737
- const num = this.#timeSignatureNumerator;
1738
- this.#host.formatLabel = (v) => {
1739
- const beatsPerBar = num;
1740
- const totalBeats = v;
1741
- return `${Math.floor(totalBeats / beatsPerBar) + 1}.${Math.floor(totalBeats % beatsPerBar) + 1}`;
1742
- };
1743
- }
1744
- };
1745
- //#endregion
1746
- export { attachTimelineInteractions as a, timelineStyles as i, IxfxTimelineElement as n, resolveCssVars as o, TimelineTrackTabElement as r, resolveGrid as s, TimelineController as t };
1750
+ export { resolveCssVars as a, attachTimelineInteractions as i, TimelineTrackTabElement as n, resolveGrid as o, timelineStyles as r, TimelineController as s, IxfxTimelineElement as t };
1747
1751
 
1748
- //# sourceMappingURL=timeline-B62Sz6J_.js.map
1752
+ //# sourceMappingURL=timeline-Cv75Th2U.js.map