mtrl 0.8.0-next.36 → 0.8.0-next.37

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 (68) hide show
  1. package/README.md +11 -0
  2. package/dist/README.md +11 -0
  3. package/dist/components/slider/features/controller.js +10 -49
  4. package/dist/components/slider/features/index.d.ts +1 -1
  5. package/dist/components/slider/features/index.js +1 -1
  6. package/dist/components/slider/features/states.js +19 -19
  7. package/dist/components/slider/features/tracks.d.ts +13 -0
  8. package/dist/components/slider/features/tracks.js +174 -0
  9. package/dist/components/slider/slider.d.ts +1 -1
  10. package/dist/components/slider/slider.js +2 -2
  11. package/dist/index.cjs +12 -12
  12. package/dist/package.json +1 -1
  13. package/dist/styles/badge.css +1 -1
  14. package/dist/styles/base.css +1 -1
  15. package/dist/styles/bottom-app-bar.css +1 -1
  16. package/dist/styles/bottom-sheet.css +1 -1
  17. package/dist/styles/button-group.css +1 -1
  18. package/dist/styles/button.css +1 -1
  19. package/dist/styles/card.css +1 -1
  20. package/dist/styles/carousel.css +1 -1
  21. package/dist/styles/checkbox.css +1 -1
  22. package/dist/styles/chips.css +1 -1
  23. package/dist/styles/dialog.css +1 -1
  24. package/dist/styles/divider.css +1 -1
  25. package/dist/styles/drawer.css +1 -1
  26. package/dist/styles/extended-fab.css +1 -1
  27. package/dist/styles/fab.css +1 -1
  28. package/dist/styles/icon-button.css +1 -1
  29. package/dist/styles/list.css +1 -1
  30. package/dist/styles/loading-indicator.css +1 -1
  31. package/dist/styles/menu.css +1 -1
  32. package/dist/styles/navigation.css +1 -1
  33. package/dist/styles/progress.css +1 -1
  34. package/dist/styles/radios.css +1 -1
  35. package/dist/styles/search.css +1 -1
  36. package/dist/styles/segmented-button.css +1 -1
  37. package/dist/styles/select.css +1 -1
  38. package/dist/styles/side-sheet.css +1 -1
  39. package/dist/styles/slider.css +2 -2
  40. package/dist/styles/snackbar.css +1 -1
  41. package/dist/styles/split-button.css +1 -1
  42. package/dist/styles/switch.css +1 -1
  43. package/dist/styles/tabs.css +1 -1
  44. package/dist/styles/textfield.css +1 -1
  45. package/dist/styles/timepicker.css +1 -1
  46. package/dist/styles/top-app-bar.css +1 -1
  47. package/dist/styles/utilities.css +1 -1
  48. package/dist/styles.css +2 -2
  49. package/dist/themes/autumn.css +1 -1
  50. package/dist/themes/baseline.css +1 -1
  51. package/dist/themes/brownbeige.css +1 -1
  52. package/dist/themes/browngreen.css +1 -1
  53. package/dist/themes/desert.css +1 -1
  54. package/dist/themes/forest.css +1 -1
  55. package/dist/themes/highcontrast.css +1 -1
  56. package/dist/themes/legacy.css +1 -1
  57. package/dist/themes/material.css +1 -1
  58. package/dist/themes/ocean.css +1 -1
  59. package/dist/themes/sageivory.css +1 -1
  60. package/dist/themes/spring.css +1 -1
  61. package/dist/themes/summer.css +1 -1
  62. package/dist/themes/sunset.css +1 -1
  63. package/dist/themes/tealcaramel.css +1 -1
  64. package/dist/themes/winter.css +1 -1
  65. package/package.json +2 -1
  66. package/src/styles/components/_slider.scss +39 -10
  67. package/dist/components/slider/features/canvas.d.ts +0 -47
  68. package/dist/components/slider/features/canvas.js +0 -570
package/README.md CHANGED
@@ -137,6 +137,17 @@ Button progress and card action buttons retain their dynamic imports in ESM.
137
137
  Enable code splitting in your application build to load those features on demand.
138
138
  The CommonJS compatibility bundle includes them eagerly.
139
139
 
140
+ Slider decoration uses DOM tracks and CSS backgrounds for ticks; it no longer
141
+ creates a canvas or subscribes to theme changes. Its public slider API and
142
+ accessible handles remain. Themes and per-slider colour overrides apply through
143
+ CSS. Custom styling that targets the former `.mtrl-slider-canvas` element must be
144
+ updated. Run `bun run slider:check` after building for slider geometry, keyboard,
145
+ pointer, resize, and lifecycle checks. For comparison with a previous canvas
146
+ build, pass `--reference=/path/to/reference` to `scripts/check-slider.ts`; that
147
+ directory must contain an ESM `slider.js` exporting `createSlider` and its full
148
+ `styles.css`. Comparison screenshots and measurements go to `analysis/slider-dom`.
149
+ CSS rounded corners differ slightly from the previous canvas curves.
150
+
140
151
  ### Checking distribution size
141
152
 
142
153
  ```bash
package/dist/README.md CHANGED
@@ -137,6 +137,17 @@ Button progress and card action buttons retain their dynamic imports in ESM.
137
137
  Enable code splitting in your application build to load those features on demand.
138
138
  The CommonJS compatibility bundle includes them eagerly.
139
139
 
140
+ Slider decoration uses DOM tracks and CSS backgrounds for ticks; it no longer
141
+ creates a canvas or subscribes to theme changes. Its public slider API and
142
+ accessible handles remain. Themes and per-slider colour overrides apply through
143
+ CSS. Custom styling that targets the former `.mtrl-slider-canvas` element must be
144
+ updated. Run `bun run slider:check` after building for slider geometry, keyboard,
145
+ pointer, resize, and lifecycle checks. For comparison with a previous canvas
146
+ build, pass `--reference=/path/to/reference` to `scripts/check-slider.ts`; that
147
+ directory must contain an ESM `slider.js` exporting `createSlider` and its full
148
+ `styles.css`. Comparison screenshots and measurements go to `analysis/slider-dom`.
149
+ CSS rounded corners differ slightly from the previous canvas curves.
150
+
140
151
  ### Checking distribution size
141
152
 
142
153
  ```bash
@@ -54,41 +54,9 @@ export const withController = (config) => (component) => {
54
54
  const range = state.max - state.min;
55
55
  return range === 0 ? 0 : ((value - state.min) / range) * 100;
56
56
  };
57
- const getTrackDimensions = () => {
58
- const components = getComponents();
59
- const { handle, container } = components;
60
- if (!handle || !container)
61
- return null;
62
- try {
63
- const handleRect = handle.getBoundingClientRect();
64
- const containerRect = container.getBoundingClientRect();
65
- const handleSize = handleRect.width || SLIDER_MEASUREMENTS.HANDLE_SIZE;
66
- const trackSize = containerRect.width;
67
- const edgeConstraint = (SLIDER_MEASUREMENTS.EDGE_PADDING / trackSize) * 100;
68
- const paddingPixels = state.activeHandle ? 6 : 8;
69
- const paddingPercent = (paddingPixels / trackSize) * 100;
70
- return { handleSize, trackSize, edgeConstraint, paddingPercent };
71
- }
72
- catch (error) {
73
- console.warn("Error calculating track dimensions:", error);
74
- return {
75
- handleSize: SLIDER_MEASUREMENTS.HANDLE_SIZE,
76
- trackSize: 200,
77
- edgeConstraint: 3,
78
- paddingPercent: 4,
79
- };
80
- }
81
- };
82
- const mapValueToVisualPercent = (valuePercent, trackSize = 200) => {
83
- const edgeConstraint = (SLIDER_MEASUREMENTS.EDGE_PADDING / trackSize) * 100;
84
- const minEdge = edgeConstraint;
85
- const maxEdge = 100 - edgeConstraint;
86
- const visualRange = maxEdge - minEdge;
87
- if (valuePercent <= 0)
88
- return minEdge;
89
- if (valuePercent >= 100)
90
- return maxEdge;
91
- return minEdge + (valuePercent / 100) * visualRange;
57
+ const visualPosition = (percent) => {
58
+ const ratio = Math.min(1, Math.max(0, percent / 100));
59
+ return `calc(${ratio * 100}% + ${SLIDER_MEASUREMENTS.EDGE_PADDING * (1 - 2 * ratio)}px)`;
92
60
  };
93
61
  const getValueFromPosition = (position) => {
94
62
  const components = getComponents();
@@ -123,25 +91,17 @@ export const withController = (config) => (component) => {
123
91
  const { handle, container, valueBubble, secondHandle, secondValueBubble } = components;
124
92
  if (!handle || !container)
125
93
  return;
126
- const dims = getTrackDimensions();
127
- if (!dims)
128
- return;
129
- const { trackSize } = dims;
130
- const percent = getPercentage(state.value);
131
- const adjustedPercent = mapValueToVisualPercent(percent, trackSize);
132
- handle.style.left = `${adjustedPercent}%`;
94
+ handle.style.left = visualPosition(getPercentage(state.value));
133
95
  handle.style.transform = "translate(-50%, -50%)";
134
96
  if (valueBubble) {
135
- valueBubble.style.left = `${adjustedPercent}%`;
97
+ valueBubble.style.left = visualPosition(getPercentage(state.value));
136
98
  valueBubble.style.transform = "translateX(-50%)";
137
99
  }
138
100
  if (config.range && secondHandle && state.secondValue !== null) {
139
- const secondPercent = getPercentage(state.secondValue);
140
- const adjustedSecondPercent = mapValueToVisualPercent(secondPercent, trackSize);
141
- secondHandle.style.left = `${adjustedSecondPercent}%`;
101
+ secondHandle.style.left = visualPosition(getPercentage(state.secondValue));
142
102
  secondHandle.style.transform = "translate(-50%, -50%)";
143
103
  if (secondValueBubble) {
144
- secondValueBubble.style.left = `${adjustedSecondPercent}%`;
104
+ secondValueBubble.style.left = visualPosition(getPercentage(state.secondValue));
145
105
  secondValueBubble.style.transform = "translateX(-50%)";
146
106
  }
147
107
  }
@@ -174,8 +134,8 @@ export const withController = (config) => (component) => {
174
134
  try {
175
135
  updateHandlePositions();
176
136
  updateValueBubbles();
177
- if (component.drawCanvas) {
178
- component.drawCanvas(state);
137
+ if (component.renderTracks) {
138
+ component.renderTracks(state);
179
139
  }
180
140
  }
181
141
  catch (error) {
@@ -307,6 +267,7 @@ export const withController = (config) => (component) => {
307
267
  },
308
268
  setStep(step) {
309
269
  state.step = step;
270
+ render();
310
271
  component.element.classList[step > 0 ? "add" : "remove"](`${component.getClass("slider")}--discrete`);
311
272
  if (config.ticks || config.tickLabels) {
312
273
  generateTicks();
@@ -1,5 +1,5 @@
1
1
  export { withRange } from "./range.js";
2
2
  export { withStates } from "./states.js";
3
3
  export { withController } from "./controller.js";
4
- export { withCanvas } from "./canvas.js";
4
+ export { withTracks } from "./tracks.js";
5
5
  export { withDom } from "./dom.js";
@@ -1,5 +1,5 @@
1
1
  export { withRange } from "./range.js";
2
2
  export { withStates } from "./states.js";
3
3
  export { withController } from "./controller.js";
4
- export { withCanvas } from "./canvas.js";
4
+ export { withTracks } from "./tracks.js";
5
5
  export { withDom } from "./dom.js";
@@ -1,6 +1,8 @@
1
1
  import { SLIDER_COLORS } from "../types.js";
2
2
  import { SLIDER_SIZES } from "../constants.js";
3
3
  export const withStates = (config) => (component) => {
4
+ const handle = component.handle ?? component.structure?.handle;
5
+ const secondHandle = component.secondHandle ?? component.structure?.secondHandle;
4
6
  const isDisabled = config.disabled === true;
5
7
  let initialization = null;
6
8
  if (isDisabled) {
@@ -11,31 +13,31 @@ export const withStates = (config) => (component) => {
11
13
  function disableComponent() {
12
14
  component.element.classList.add(`${component.getClass("slider")}--disabled`);
13
15
  component.element.setAttribute("aria-disabled", "true");
14
- if (component.structure?.handle) {
15
- component.structure.handle.tabIndex = -1;
16
- component.structure.handle.setAttribute("aria-disabled", "true");
16
+ if (handle) {
17
+ handle.tabIndex = -1;
18
+ handle.setAttribute("aria-disabled", "true");
17
19
  }
18
- if (config.range && component.structure?.secondHandle) {
19
- component.structure.secondHandle.tabIndex = -1;
20
- component.structure.secondHandle.setAttribute("aria-disabled", "true");
20
+ if (config.range && secondHandle) {
21
+ secondHandle.tabIndex = -1;
22
+ secondHandle.setAttribute("aria-disabled", "true");
21
23
  }
22
- if (component.drawCanvas) {
23
- component.drawCanvas();
24
+ if (component.renderTracks) {
25
+ component.renderTracks();
24
26
  }
25
27
  }
26
28
  function enableComponent() {
27
29
  component.element.classList.remove(`${component.getClass("slider")}--disabled`);
28
30
  component.element.setAttribute("aria-disabled", "false");
29
- if (component.structure?.handle) {
30
- component.structure.handle.tabIndex = 0;
31
- component.structure.handle.setAttribute("aria-disabled", "false");
31
+ if (handle) {
32
+ handle.tabIndex = 0;
33
+ handle.setAttribute("aria-disabled", "false");
32
34
  }
33
- if (config.range && component.structure?.secondHandle) {
34
- component.structure.secondHandle.tabIndex = 0;
35
- component.structure.secondHandle.setAttribute("aria-disabled", "false");
35
+ if (config.range && secondHandle) {
36
+ secondHandle.tabIndex = 0;
37
+ secondHandle.setAttribute("aria-disabled", "false");
36
38
  }
37
- if (component.drawCanvas) {
38
- component.drawCanvas();
39
+ if (component.renderTracks) {
40
+ component.renderTracks();
39
41
  }
40
42
  }
41
43
  function getActiveColor() {
@@ -105,9 +107,7 @@ export const withStates = (config) => (component) => {
105
107
  },
106
108
  showTicks(show) {
107
109
  config.ticks = show;
108
- if (component.slider) {
109
- component.slider.regenerateTicks();
110
- }
110
+ component.renderTracks?.();
111
111
  return this;
112
112
  },
113
113
  showCurrentValue(show) {
@@ -0,0 +1,13 @@
1
+ import { SliderConfig } from "../types.js";
2
+ import { SliderSize } from "../constants.js";
3
+ export declare const getTrackHeight: (size?: SliderSize) => number;
4
+ /**
5
+ * Gets the handle height based on the slider size
6
+ */
7
+ export declare const getHandleHeight: (size?: SliderSize) => number;
8
+ /**
9
+ * Gets the external track radius based on the slider size
10
+ */
11
+ export declare const getExternalTrackRadius: (size?: SliderSize) => number;
12
+ /** Decorative tracks and ticks. Handles and controller retain interaction ownership. */
13
+ export declare const withTracks: (config: SliderConfig) => (component: any) => any;
@@ -0,0 +1,174 @@
1
+ import { SLIDER_SIZES, SLIDER_MEASUREMENTS } from "../constants.js";
2
+ export const getTrackHeight = (size) => {
3
+ if (typeof size === "number") {
4
+ return Math.max(size, SLIDER_SIZES.XS);
5
+ }
6
+ if (typeof size === "string" && size in SLIDER_SIZES) {
7
+ return SLIDER_SIZES[size];
8
+ }
9
+ return SLIDER_SIZES.XS;
10
+ };
11
+ export const getHandleHeight = (size) => {
12
+ const trackHeight = getTrackHeight(size);
13
+ if (trackHeight <= SLIDER_SIZES.S) {
14
+ return SLIDER_MEASUREMENTS.SMALL_HANDLE_HEIGHT;
15
+ }
16
+ return trackHeight + SLIDER_MEASUREMENTS.HANDLE_HEIGHT_OFFSET;
17
+ };
18
+ export const getExternalTrackRadius = (size) => {
19
+ const trackHeight = getTrackHeight(size);
20
+ if (trackHeight <= SLIDER_SIZES.S) {
21
+ return SLIDER_MEASUREMENTS.SMALL_TRACK_EXTERNAL_RADIUS;
22
+ }
23
+ return trackHeight * SLIDER_MEASUREMENTS.LARGE_TRACK_RADIUS_RATIO;
24
+ };
25
+ export const withTracks = (config) => (component) => {
26
+ const container = component.container;
27
+ const element = (name, parent) => {
28
+ const node = document.createElement("div");
29
+ node.className = component.getClass(`slider-${name}`);
30
+ parent.append(node);
31
+ return node;
32
+ };
33
+ const visual = element("visual", container);
34
+ visual.setAttribute("aria-hidden", "true");
35
+ const track = element("track", visual);
36
+ const segments = Array.from({ length: 3 }, () => element("segment", track));
37
+ const ticks = [element("ticks", visual), element("ticks", visual)];
38
+ ticks[1].classList.add(component.getClass("slider-ticks--active"));
39
+ const dot = element("dot", visual);
40
+ let destroyed = false;
41
+ let size = config.size ?? "XS";
42
+ let state = {
43
+ value: config.value ?? 0, secondValue: config.secondValue ?? null,
44
+ min: config.min ?? 0, max: config.max ?? 100, step: config.step ?? 1,
45
+ };
46
+ const render = (next) => {
47
+ if (destroyed)
48
+ return;
49
+ if (next)
50
+ state = { ...next };
51
+ const width = container.getBoundingClientRect().width || 200;
52
+ const height = getTrackHeight(size);
53
+ const edge = SLIDER_MEASUREMENTS.EDGE_PADDING;
54
+ const position = (value) => edge + Math.min(1, Math.max(0, state.max === state.min ? 0 : (value - state.min) / (state.max - state.min))) * Math.max(0, width - 2 * edge);
55
+ const first = position(state.value);
56
+ const second = position(state.secondValue ?? state.max);
57
+ const zero = position(0);
58
+ const gap = SLIDER_MEASUREMENTS.HANDLE_GAP;
59
+ const reduction = SLIDER_MEASUREMENTS.HANDLE_GAP_PRESSED_REDUCTION;
60
+ const firstGap = gap - (state.pressed && (!config.range || state.activeHandle === "first") ? reduction : 0);
61
+ const secondGap = gap - (state.pressed && state.activeHandle === "second" ? reduction : 0);
62
+ const parts = [];
63
+ let activeStart = 0, activeEnd = first;
64
+ if (config.centered) {
65
+ activeStart = Math.min(zero, first);
66
+ activeEnd = Math.max(zero, first);
67
+ const centerGap = SLIDER_MEASUREMENTS.CENTER_GAP / 2;
68
+ if (Math.abs(first - zero) < firstGap) {
69
+ parts.push([0, first - firstGap, false], [zero, zero, true], [first + firstGap, width, false]);
70
+ }
71
+ else if (state.value >= 0) {
72
+ parts.push([0, zero - centerGap, false], [zero + centerGap, first - firstGap, true], [first + firstGap, width, false]);
73
+ }
74
+ else {
75
+ parts.push([0, first - firstGap, false], [first + firstGap, zero - centerGap, true], [zero + centerGap, width, false]);
76
+ }
77
+ }
78
+ else if (config.range && state.secondValue !== null) {
79
+ activeStart = Math.min(first, second);
80
+ activeEnd = Math.max(first, second);
81
+ const lowGap = first <= second ? firstGap : secondGap;
82
+ const highGap = first <= second ? secondGap : firstGap;
83
+ const start = activeStart + lowGap, end = activeEnd - highGap;
84
+ parts.push([0, activeStart - lowGap, false], [start, end - start > height ? end : start, true], [activeEnd + highGap, width, false]);
85
+ }
86
+ else {
87
+ parts.push([0, 0, false], [0, first - firstGap, true], [first + firstGap, width, false]);
88
+ }
89
+ segments.forEach((segment, index) => {
90
+ const [start, end, active] = parts[index] ?? [0, 0, false];
91
+ segment.style.left = `${start}px`;
92
+ segment.style.width = `${Math.max(0, end - start)}px`;
93
+ segment.classList.toggle(component.getClass("slider-segment--active"), active);
94
+ });
95
+ const discrete = !!config.ticks && state.step > 0 && state.max > state.min;
96
+ ticks.forEach(tick => { tick.hidden = !discrete; });
97
+ dot.hidden = !!config.ticks;
98
+ if (discrete) {
99
+ const spacing = (width - 2 * edge) * state.step / (state.max - state.min);
100
+ const last = position(state.min + Math.floor((state.max - state.min) / state.step) * state.step);
101
+ const holes = [state.value, ...(config.range && state.secondValue !== null ? [state.secondValue] : [])]
102
+ .filter(value => Math.abs((value - state.min) / state.step - Math.round((value - state.min) / state.step)) < 0.1)
103
+ .map(value => position(state.min + Math.round((value - state.min) / state.step) * state.step))
104
+ .sort((a, b) => a - b);
105
+ const mask = (intervals) => {
106
+ const merged = [];
107
+ for (const [start, end] of intervals.sort((a, b) => a[0] - b[0])) {
108
+ const previous = merged[merged.length - 1];
109
+ if (previous && start <= previous[1])
110
+ previous[1] = Math.max(previous[1], end);
111
+ else
112
+ merged.push([start, end]);
113
+ }
114
+ const stops = merged.flatMap(([start, end]) => [`black ${start}px`, `transparent ${start}px`, `transparent ${end}px`, `black ${end}px`]);
115
+ return stops.length ? `linear-gradient(to right, black 0px, ${stops.join(",")}, black 100%)` : "none";
116
+ };
117
+ ticks.forEach((tick, index) => {
118
+ tick.style.backgroundSize = `${Math.max(spacing, 0.01)}px 100%`;
119
+ tick.style.backgroundPosition = `${edge - spacing / 2}px center`;
120
+ tick.style.maskImage = mask([
121
+ ...holes.map(x => [x - 2, x + 2]),
122
+ ...(index === 0 ? [[activeStart - 2, activeEnd + 2]] : []),
123
+ ]);
124
+ });
125
+ ticks[0].style.clipPath = `inset(0 ${Math.max(0, width - last - 2)}px 0 0)`;
126
+ ticks[1].style.clipPath = `inset(0 ${Math.max(0, width - Math.min(last + 2, activeEnd + 2))}px 0 ${Math.max(0, activeStart - 2)}px)`;
127
+ }
128
+ };
129
+ const setSize = (next) => {
130
+ if (destroyed)
131
+ return;
132
+ size = next;
133
+ const handleHeight = getHandleHeight(size);
134
+ container.style.height = `${Math.max(handleHeight, SLIDER_MEASUREMENTS.MIN_HEIGHT)}px`;
135
+ track.style.height = `${getTrackHeight(size)}px`;
136
+ track.style.borderRadius = `${getExternalTrackRadius(size)}px`;
137
+ for (const handle of [component.handle, component.secondHandle]) {
138
+ if (handle)
139
+ handle.style.height = `${handleHeight}px`;
140
+ }
141
+ render();
142
+ };
143
+ component.renderTracks = render;
144
+ component.setSize = setSize;
145
+ component.getSize = () => size;
146
+ const setColor = component.appearance.setColor;
147
+ component.appearance.setColor = (color) => {
148
+ if (destroyed)
149
+ return;
150
+ setColor.call(component.appearance, color);
151
+ config.color = color;
152
+ };
153
+ setSize(size);
154
+ const resize = () => {
155
+ if (!destroyed)
156
+ render();
157
+ };
158
+ const observer = typeof ResizeObserver !== "undefined" ? new ResizeObserver(resize) : null;
159
+ if (observer)
160
+ observer.observe(container);
161
+ else
162
+ window.addEventListener("resize", resize);
163
+ const destroy = component.lifecycle.destroy;
164
+ component.lifecycle.destroy = () => {
165
+ if (destroyed)
166
+ return;
167
+ destroyed = true;
168
+ observer?.disconnect();
169
+ if (!observer)
170
+ window.removeEventListener("resize", resize);
171
+ destroy.call(component.lifecycle);
172
+ };
173
+ return component;
174
+ };
@@ -6,7 +6,7 @@ import { SliderConfig, SliderComponent } from "./types.js";
6
6
  * 1. Base component - Creates the foundation with event system
7
7
  * 2. Feature enhancement - Adds specific capabilities (range, icons)
8
8
  * 3. DOM creation - Creates DOM elements directly using optimized createElement
9
- * 4. Canvas rendering - Uses canvas for visual elements, keeping handles as DOM
9
+ * 4. Track rendering - Uses decorative DOM and CSS alongside accessible handles
10
10
  * 5. State management - Handles visual states and appearance
11
11
  * 6. Controller - Manages behavior, events, and UI rendering
12
12
  * 7. Lifecycle - Handles component lifecycle events
@@ -1,13 +1,13 @@
1
1
  import { pipe } from "../../core/compose/pipe.js";
2
2
  import { createBase, withElement } from "../../core/compose/component.js";
3
3
  import { withEvents, withLifecycle, withIcon, withTextLabel, } from "../../core/compose/features/index.js";
4
- import { withRange, withStates, withController, withCanvas, withDom, } from "./features/index.js";
4
+ import { withRange, withStates, withController, withTracks, withDom, } from "./features/index.js";
5
5
  import { withAPI } from "./api.js";
6
6
  import { createBaseConfig, getElementConfig, getApiConfig } from "./config.js";
7
7
  const createSlider = (config = {}) => {
8
8
  const baseConfig = createBaseConfig(config);
9
9
  try {
10
- const component = pipe(createBase, withEvents(), withElement(getElementConfig(baseConfig)), withRange(baseConfig), withDom(baseConfig), withTextLabel(baseConfig), withIcon(baseConfig), withLifecycle(), withStates(baseConfig), withCanvas(baseConfig), withController(baseConfig))(baseConfig);
10
+ const component = pipe(createBase, withEvents(), withElement(getElementConfig(baseConfig)), withRange(baseConfig), withDom(baseConfig), withTextLabel(baseConfig), withIcon(baseConfig), withLifecycle(), withStates(baseConfig), withTracks(baseConfig), withController(baseConfig))(baseConfig);
11
11
  const apiOptions = getApiConfig(component);
12
12
  const slider = withAPI(apiOptions)(component);
13
13
  if (baseConfig.on && typeof slider.on === "function") {