material 3.3.2 → 3.3.3

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 (149) hide show
  1. package/README.md +2 -2
  2. package/dist/components/slider/config.js +0 -46
  3. package/dist/components/slider/features/controller.js +805 -171
  4. package/dist/components/slider/features/dom.js +29 -62
  5. package/dist/components/slider/features/index.js +1 -3
  6. package/dist/components/slider/features/states.js +2 -30
  7. package/dist/components/slider/slider.js +3 -6
  8. package/dist/components/slider/types.d.ts +0 -26
  9. package/dist/core/canvas/resize.d.ts +1 -1
  10. package/dist/core/canvas/resize.js +24 -11
  11. package/dist/core/dom/classes.js +17 -118
  12. package/dist/core/dom/create.d.ts +0 -2
  13. package/dist/core/dom/create.js +0 -72
  14. package/dist/core/utils/mobile.js +9 -29
  15. package/dist/elements/preupgrade/badge.css +1 -1
  16. package/dist/elements/preupgrade/bottom-app-bar.css +1 -1
  17. package/dist/elements/preupgrade/bottom-sheet.css +1 -1
  18. package/dist/elements/preupgrade/button-group.css +1 -1
  19. package/dist/elements/preupgrade/button.css +1 -1
  20. package/dist/elements/preupgrade/card.css +1 -1
  21. package/dist/elements/preupgrade/carousel.css +1 -1
  22. package/dist/elements/preupgrade/checkbox.css +1 -1
  23. package/dist/elements/preupgrade/chips.css +1 -1
  24. package/dist/elements/preupgrade/datepicker.css +1 -1
  25. package/dist/elements/preupgrade/dialog.css +1 -1
  26. package/dist/elements/preupgrade/divider.css +1 -1
  27. package/dist/elements/preupgrade/drawer.css +1 -1
  28. package/dist/elements/preupgrade/extended-fab.css +1 -1
  29. package/dist/elements/preupgrade/fab-menu.css +1 -1
  30. package/dist/elements/preupgrade/fab.css +1 -1
  31. package/dist/elements/preupgrade/icon-button.css +1 -1
  32. package/dist/elements/preupgrade/list.css +1 -1
  33. package/dist/elements/preupgrade/loading-indicator.css +1 -1
  34. package/dist/elements/preupgrade/menu.css +1 -1
  35. package/dist/elements/preupgrade/navigation-bar.css +1 -1
  36. package/dist/elements/preupgrade/navigation-rail.css +1 -1
  37. package/dist/elements/preupgrade/progress.css +1 -1
  38. package/dist/elements/preupgrade/radios.css +1 -1
  39. package/dist/elements/preupgrade/search.css +1 -1
  40. package/dist/elements/preupgrade/select.css +1 -1
  41. package/dist/elements/preupgrade/side-sheet.css +1 -1
  42. package/dist/elements/preupgrade/slider.css +1 -1
  43. package/dist/elements/preupgrade/snackbar.css +1 -1
  44. package/dist/elements/preupgrade/split-button.css +1 -1
  45. package/dist/elements/preupgrade/switch.css +1 -1
  46. package/dist/elements/preupgrade/tabs.css +1 -1
  47. package/dist/elements/preupgrade/text-field.css +1 -1
  48. package/dist/elements/preupgrade/timepicker.css +1 -1
  49. package/dist/elements/preupgrade/toolbar.css +1 -1
  50. package/dist/elements/preupgrade/tooltip.css +1 -1
  51. package/dist/elements/preupgrade/top-app-bar.css +1 -1
  52. package/dist/elements/preupgrade.css +1 -1
  53. package/dist/package.json +1 -1
  54. package/dist/styles/badge.css +1 -1
  55. package/dist/styles/base.css +1 -1
  56. package/dist/styles/bottom-app-bar.css +1 -1
  57. package/dist/styles/bottom-sheet.css +1 -1
  58. package/dist/styles/button-group.css +1 -1
  59. package/dist/styles/button.css +1 -1
  60. package/dist/styles/card.css +1 -1
  61. package/dist/styles/carousel.css +1 -1
  62. package/dist/styles/checkbox.css +1 -1
  63. package/dist/styles/chips.css +1 -1
  64. package/dist/styles/contrast.css +1 -1
  65. package/dist/styles/datepicker.css +1 -1
  66. package/dist/styles/dialog.css +1 -1
  67. package/dist/styles/divider.css +1 -1
  68. package/dist/styles/drawer.css +1 -1
  69. package/dist/styles/extended-fab.css +1 -1
  70. package/dist/styles/fab-menu.css +1 -1
  71. package/dist/styles/fab.css +1 -1
  72. package/dist/styles/icon-button.css +1 -1
  73. package/dist/styles/list.css +1 -1
  74. package/dist/styles/loading-indicator.css +1 -1
  75. package/dist/styles/menu.css +1 -1
  76. package/dist/styles/navigation-bar.css +1 -1
  77. package/dist/styles/navigation-rail.css +1 -1
  78. package/dist/styles/progress.css +1 -1
  79. package/dist/styles/radios.css +1 -1
  80. package/dist/styles/search.css +1 -1
  81. package/dist/styles/select.css +1 -1
  82. package/dist/styles/side-sheet.css +1 -1
  83. package/dist/styles/slider.css +1 -1
  84. package/dist/styles/snackbar.css +1 -1
  85. package/dist/styles/split-button.css +1 -1
  86. package/dist/styles/switch.css +1 -1
  87. package/dist/styles/tabs.css +1 -1
  88. package/dist/styles/text-field.css +1 -1
  89. package/dist/styles/timepicker.css +1 -1
  90. package/dist/styles/toolbar.css +1 -1
  91. package/dist/styles/tooltip.css +1 -1
  92. package/dist/styles/top-app-bar.css +1 -1
  93. package/dist/styles/typography.css +1 -1
  94. package/dist/styles/utilities.css +1 -1
  95. package/dist/styles.css +1 -1
  96. package/dist/themes/autumn-contrast.css +1 -1
  97. package/dist/themes/autumn.css +1 -1
  98. package/dist/themes/baseline-contrast.css +1 -1
  99. package/dist/themes/baseline.css +1 -1
  100. package/dist/themes/brownbeige-contrast.css +1 -1
  101. package/dist/themes/brownbeige.css +1 -1
  102. package/dist/themes/content-contrast.css +1 -1
  103. package/dist/themes/content.css +1 -1
  104. package/dist/themes/desert-contrast.css +1 -1
  105. package/dist/themes/desert.css +1 -1
  106. package/dist/themes/expressive-contrast.css +1 -1
  107. package/dist/themes/expressive.css +1 -1
  108. package/dist/themes/fidelity-contrast.css +1 -1
  109. package/dist/themes/fidelity.css +1 -1
  110. package/dist/themes/forest-contrast.css +1 -1
  111. package/dist/themes/forest.css +1 -1
  112. package/dist/themes/fruit-salad-contrast.css +1 -1
  113. package/dist/themes/fruit-salad.css +1 -1
  114. package/dist/themes/highcontrast-contrast.css +1 -1
  115. package/dist/themes/highcontrast.css +1 -1
  116. package/dist/themes/monochrome-contrast.css +1 -1
  117. package/dist/themes/monochrome.css +1 -1
  118. package/dist/themes/neutral-contrast.css +1 -1
  119. package/dist/themes/neutral.css +1 -1
  120. package/dist/themes/ocean-contrast.css +1 -1
  121. package/dist/themes/ocean.css +1 -1
  122. package/dist/themes/rainbow-contrast.css +1 -1
  123. package/dist/themes/rainbow.css +1 -1
  124. package/dist/themes/sageivory-contrast.css +1 -1
  125. package/dist/themes/sageivory.css +1 -1
  126. package/dist/themes/spring-contrast.css +1 -1
  127. package/dist/themes/spring.css +1 -1
  128. package/dist/themes/summer-contrast.css +1 -1
  129. package/dist/themes/summer.css +1 -1
  130. package/dist/themes/sunset-contrast.css +1 -1
  131. package/dist/themes/sunset.css +1 -1
  132. package/dist/themes/tealcaramel-contrast.css +1 -1
  133. package/dist/themes/tealcaramel.css +1 -1
  134. package/dist/themes/vibrant-contrast.css +1 -1
  135. package/dist/themes/vibrant.css +1 -1
  136. package/package.json +1 -1
  137. package/dist/components/card/features.js +0 -217
  138. package/dist/components/chips/chip/constants.js +0 -18
  139. package/dist/components/chips/chip/index.js +0 -1
  140. package/dist/components/chips/schema.js +0 -46
  141. package/dist/components/progress/features/index.js +0 -4
  142. package/dist/components/progress/features/resize-observer.js +0 -40
  143. package/dist/components/slider/api.js +0 -108
  144. package/dist/components/slider/features/handlers.js +0 -379
  145. package/dist/components/slider/features/range.js +0 -70
  146. package/dist/components/slider/features/tracks.js +0 -287
  147. package/dist/components/tabs/scroll-indicators.js +0 -78
  148. package/dist/components/tabs/state.js +0 -44
  149. package/dist/core/utils/validate.js +0 -114
@@ -8,7 +8,6 @@ export const withDom = (config) => (component) => {
8
8
  const value = config.value !== undefined ? config.value : min;
9
9
  const isDisabled = config.disabled === true;
10
10
  const formatter = config.valueFormatter || ((val) => val.toString());
11
- const valuePercent = ((value - min) / (max - min)) * 100;
12
11
  const container = createElement({
13
12
  tag: "div",
14
13
  className: getClass("slider__container"),
@@ -20,83 +19,56 @@ export const withDom = (config) => (component) => {
20
19
  const label = config.label || "";
21
20
  const handleLabel = config.range && label ? `${label} minimum` : label;
22
21
  const secondHandleLabel = label ? `${label} maximum` : "";
23
- const handleAttributes = {
24
- role: "slider",
25
- "aria-valuemin": String(min),
26
- "aria-valuemax": String(max),
27
- "aria-valuenow": String(value),
28
- "aria-orientation": config.orientation === "vertical" ? "vertical" : "horizontal",
29
- tabindex: isDisabled ? "-1" : "0",
30
- "aria-disabled": isDisabled ? "true" : "false",
31
- "data-value": String(value),
32
- "data-handle-index": "0",
33
- };
34
- if (handleLabel) {
35
- handleAttributes["aria-label"] = handleLabel;
36
- }
37
- const handle = createElement({
38
- tag: "div",
39
- className: getClass("slider__handle"),
40
- attributes: handleAttributes,
41
- container: container,
42
- });
43
- setStyles(handle, {
44
- left: `${valuePercent}%`,
45
- });
46
- const valueBubble = createElement({
47
- tag: "div",
48
- className: getClass("slider__value"),
49
- attributes: {
50
- "aria-hidden": "true",
51
- "data-handle-index": "0",
52
- },
53
- text: formatter(value),
54
- container: container,
55
- });
56
- setStyles(valueBubble, {
57
- left: `${valuePercent}%`,
58
- });
59
- let secondHandle;
60
- let secondValueBubble;
61
- if (config.range) {
62
- const secondValue = config.secondValue !== undefined ? config.secondValue : max;
63
- const secondValuePercent = ((secondValue - min) / (max - min)) * 100;
64
- const secondHandleAttributes = {
22
+ const handleElement = (index, handleValue, name) => {
23
+ const attributes = {
65
24
  role: "slider",
66
25
  "aria-valuemin": String(min),
67
26
  "aria-valuemax": String(max),
68
- "aria-valuenow": String(secondValue),
27
+ "aria-valuenow": String(handleValue),
69
28
  "aria-orientation": config.orientation === "vertical" ? "vertical" : "horizontal",
70
29
  tabindex: isDisabled ? "-1" : "0",
71
30
  "aria-disabled": isDisabled ? "true" : "false",
72
- "data-value": String(secondValue),
73
- "data-handle-index": "1",
31
+ "data-value": String(handleValue),
32
+ "data-handle-index": String(index),
74
33
  };
75
- if (secondHandleLabel) {
76
- secondHandleAttributes["aria-label"] = secondHandleLabel;
34
+ if (name) {
35
+ attributes["aria-label"] = name;
77
36
  }
78
- secondHandle = createElement({
37
+ const element = createElement({
79
38
  tag: "div",
80
39
  className: getClass("slider__handle"),
81
- attributes: secondHandleAttributes,
40
+ attributes,
82
41
  container: container,
83
42
  });
84
- setStyles(secondHandle, {
85
- left: `${secondValuePercent}%`,
43
+ setStyles(element, {
44
+ left: `${((handleValue - min) / (max - min)) * 100}%`,
86
45
  });
87
- secondValueBubble = createElement({
46
+ return element;
47
+ };
48
+ const bubbleElement = (index, bubbleValue) => {
49
+ const element = createElement({
88
50
  tag: "div",
89
51
  className: getClass("slider__value"),
90
52
  attributes: {
91
53
  "aria-hidden": "true",
92
- "data-handle-index": "1",
54
+ "data-handle-index": String(index),
93
55
  },
94
- text: formatter(secondValue),
56
+ text: formatter(bubbleValue),
95
57
  container: container,
96
58
  });
97
- setStyles(secondValueBubble, {
98
- left: `${secondValuePercent}%`,
59
+ setStyles(element, {
60
+ left: `${((bubbleValue - min) / (max - min)) * 100}%`,
99
61
  });
62
+ return element;
63
+ };
64
+ const handle = handleElement(0, value, handleLabel);
65
+ const valueBubble = bubbleElement(0, value);
66
+ let secondHandle;
67
+ let secondValueBubble;
68
+ if (config.range) {
69
+ const secondValue = config.secondValue !== undefined ? config.secondValue : max;
70
+ secondHandle = handleElement(1, secondValue, secondHandleLabel);
71
+ secondValueBubble = bubbleElement(1, secondValue);
100
72
  }
101
73
  const name = config.name;
102
74
  const formFields = name
@@ -115,10 +87,5 @@ export const withDom = (config) => (component) => {
115
87
  secondHandle,
116
88
  secondValueBubble,
117
89
  formFields,
118
- getContainer: () => container,
119
- getHandle: () => handle,
120
- getValueBubble: () => valueBubble,
121
- getSecondHandle: () => secondHandle || null,
122
- getSecondValueBubble: () => secondValueBubble || null,
123
90
  };
124
91
  };
@@ -1,5 +1,3 @@
1
- export { withRange } from "./range.js";
2
1
  export { withStates } from "./states.js";
3
- export { withController } from "./controller.js";
4
- export { withTracks } from "./tracks.js";
2
+ export { withController, withTracks } from "./controller.js";
5
3
  export { withDom } from "./dom.js";
@@ -1,8 +1,7 @@
1
1
  import { SLIDER_COLORS } from "../types.js";
2
- import { SLIDER_SIZES } from "../constants.js";
3
2
  export const withStates = (config) => (component) => {
4
- const handle = component.handle ?? component.structure?.handle;
5
- const secondHandle = component.secondHandle ?? component.structure?.secondHandle;
3
+ const handle = component.handle;
4
+ const secondHandle = component.secondHandle;
6
5
  const setFieldsDisabled = (disabled) => {
7
6
  for (const field of component.formFields ?? []) {
8
7
  if (field)
@@ -44,11 +43,6 @@ export const withStates = (config) => (component) => {
44
43
  function getActiveColor() {
45
44
  return (Object.values(SLIDER_COLORS).find((colorName) => component.element.classList.contains(`${component.getClass("slider")}--${colorName}`)) || SLIDER_COLORS.PRIMARY);
46
45
  }
47
- function getActiveSize() {
48
- const sizeKeys = Object.keys(SLIDER_SIZES);
49
- const foundKey = sizeKeys.find((sizeKey) => component.element.classList.contains(`${component.getClass("slider")}--${sizeKey.toLowerCase()}`));
50
- return foundKey || "XS";
51
- }
52
46
  if (config.disabled === true)
53
47
  disableComponent();
54
48
  return Object.assign(component, {
@@ -78,28 +72,6 @@ export const withStates = (config) => (component) => {
78
72
  getColor() {
79
73
  return getActiveColor();
80
74
  },
81
- setSize(size) {
82
- const sizeKeys = Object.keys(SLIDER_SIZES);
83
- sizeKeys.forEach((sizeKey) => {
84
- component.element.classList.remove(`${component.getClass("slider")}--${sizeKey.toLowerCase()}`);
85
- });
86
- let sizeKey;
87
- if (typeof size === "string" && size in SLIDER_SIZES) {
88
- sizeKey = size;
89
- }
90
- else if (typeof size === "number") {
91
- const entry = Object.entries(SLIDER_SIZES).find(([, value]) => value === size);
92
- sizeKey = entry ? entry[0] : "XS";
93
- }
94
- else {
95
- sizeKey = "XS";
96
- }
97
- component.element.classList.add(`${component.getClass("slider")}--${sizeKey.toLowerCase()}`);
98
- return this;
99
- },
100
- getSize() {
101
- return getActiveSize();
102
- },
103
75
  showTicks(show) {
104
76
  config.ticks = show;
105
77
  component.renderTracks?.();
@@ -1,15 +1,12 @@
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, withTracks, withDom, } from "./features/index.js";
5
- import { withAPI } from "./api.js";
6
- import { createBaseConfig, getElementConfig, getApiConfig } from "./config.js";
4
+ import { withStates, withController, withTracks, withDom, } from "./features/index.js";
5
+ import { createBaseConfig, getElementConfig } from "./config.js";
7
6
  const createSlider = (config = {}) => {
8
7
  const baseConfig = createBaseConfig(config);
9
8
  try {
10
- const component = pipe(createBase, withEvents(), withElement(getElementConfig(baseConfig)), withRange(baseConfig), withDom(baseConfig), withTextLabel(baseConfig), withIcon(baseConfig), withLifecycle(), withStates(baseConfig), withTracks(baseConfig), withController(baseConfig, () => slider))(baseConfig);
11
- const apiOptions = getApiConfig(component);
12
- const slider = withAPI(apiOptions)(component);
9
+ const slider = pipe(createBase, withEvents(), withElement(getElementConfig(baseConfig)), withDom(baseConfig), withTextLabel(baseConfig), withIcon(baseConfig), withLifecycle(), withStates(baseConfig), withTracks(baseConfig), withController(baseConfig, () => slider))(baseConfig);
13
10
  if (baseConfig.on && typeof slider.on === "function") {
14
11
  Object.entries(baseConfig.on).forEach(([event, handler]) => {
15
12
  if (typeof handler === "function") {
@@ -47,10 +47,8 @@ export interface SliderEvent {
47
47
  }
48
48
  export type SliderActiveHandle = "first" | "second" | null;
49
49
  export interface SliderState {
50
- component: SliderStateComponent;
51
50
  value: number;
52
51
  secondValue: number | null;
53
- previousValue?: number;
54
52
  min: number;
55
53
  max: number;
56
54
  step: number;
@@ -67,7 +65,6 @@ export interface SliderStateComponent {
67
65
  valueBubble?: HTMLElement | null;
68
66
  secondHandle?: HTMLElement | null;
69
67
  secondValueBubble?: HTMLElement | null;
70
- components?: Record<string, HTMLElement | null | undefined>;
71
68
  getClass: (name: string) => string;
72
69
  emit: (event: string, data: unknown) => unknown;
73
70
  disabled?: {
@@ -80,31 +77,8 @@ export interface SliderStateComponent {
80
77
  destroy?: () => void;
81
78
  mount?: () => void;
82
79
  };
83
- slider?: {
84
- setValue?: (value: number, triggerEvent?: boolean) => unknown;
85
- };
86
80
  }
87
81
  export type SliderPointerEvent = MouseEvent | TouchEvent;
88
- export interface SliderElements {
89
- container?: HTMLElement | null;
90
- handle?: HTMLElement | null;
91
- valueBubble?: HTMLElement | null;
92
- secondHandle?: HTMLElement | null;
93
- secondValueBubble?: HTMLElement | null;
94
- [key: string]: HTMLElement | null | undefined;
95
- }
96
- export interface SliderUiRenderer {
97
- getPercentage: (value: number) => number;
98
- getValueFromPosition: (position: number) => number;
99
- roundToStep: (value: number) => number;
100
- clamp: (value: number, min?: number, max?: number) => number;
101
- showValueBubble: (bubbleElement: HTMLElement | null, show: boolean) => void;
102
- updateUi: () => void;
103
- render: () => void;
104
- }
105
- export interface SliderEventHelpers {
106
- triggerEvent: (eventName: string, originalEvent?: Event | null) => void;
107
- }
108
82
  export interface SliderEvents extends TouchEvents {
109
83
  change: (payload: SliderEvent) => void;
110
84
  input: (payload: SliderEvent) => void;
@@ -1 +1 @@
1
- export declare const observeCanvasResize: (element: HTMLElement, _canvas: HTMLCanvasElement, onResize: () => void) => (() => void);
1
+ export declare const observeCanvasResize: (element: HTMLElement, canvas: HTMLCanvasElement | null | undefined, onResize: () => void) => (() => void);
@@ -1,4 +1,4 @@
1
- export const observeCanvasResize = (element, _canvas, onResize) => {
1
+ export const observeCanvasResize = (element, canvas, onResize) => {
2
2
  let timeoutId = null;
3
3
  const debouncedResize = () => {
4
4
  if (timeoutId)
@@ -7,6 +7,21 @@ export const observeCanvasResize = (element, _canvas, onResize) => {
7
7
  onResize();
8
8
  }, 100);
9
9
  };
10
+ const view = canvas ? element.ownerDocument?.defaultView ?? null : null;
11
+ let resolution = null;
12
+ function onResolutionChange() {
13
+ resolution?.removeEventListener("change", onResolutionChange);
14
+ armResolution();
15
+ debouncedResize();
16
+ }
17
+ function armResolution() {
18
+ if (!view?.matchMedia)
19
+ return;
20
+ resolution = view.matchMedia(`(resolution: ${view.devicePixelRatio || 1}dppx)`);
21
+ resolution.addEventListener("change", onResolutionChange);
22
+ }
23
+ armResolution();
24
+ let stopWidth;
10
25
  if (typeof ResizeObserver !== 'undefined') {
11
26
  let seen = -1;
12
27
  const observer = new ResizeObserver((entries) => {
@@ -19,18 +34,16 @@ export const observeCanvasResize = (element, _canvas, onResize) => {
19
34
  }
20
35
  });
21
36
  observer.observe(element);
22
- return () => {
23
- if (timeoutId)
24
- clearTimeout(timeoutId);
25
- observer.disconnect();
26
- };
37
+ stopWidth = () => observer.disconnect();
27
38
  }
28
39
  else {
29
40
  window.addEventListener('resize', debouncedResize);
30
- return () => {
31
- if (timeoutId)
32
- clearTimeout(timeoutId);
33
- window.removeEventListener('resize', debouncedResize);
34
- };
41
+ stopWidth = () => window.removeEventListener('resize', debouncedResize);
35
42
  }
43
+ return () => {
44
+ if (timeoutId)
45
+ clearTimeout(timeoutId);
46
+ resolution?.removeEventListener("change", onResolutionChange);
47
+ stopWidth();
48
+ };
36
49
  };
@@ -56,134 +56,33 @@ export const normalizeClasses = (...classes) => {
56
56
  }
57
57
  return result;
58
58
  };
59
- export const addClass = (element, ...classes) => {
60
- if (classes.length === 0)
61
- return element;
62
- if (classes.length === 1 && Array.isArray(classes[0])) {
63
- return addClass(element, ...classes[0]);
64
- }
65
- if (classes.length === 1 && typeof classes[0] === "string") {
66
- const cls = classes[0];
67
- if (cls && !cls.includes(" ")) {
68
- const prefixed = cls;
69
- if (!prefixed.includes(" ")) {
70
- element.classList.add(prefixed);
71
- return element;
72
- }
73
- }
74
- }
75
- const normalized = normalizeClasses(...classes);
76
- for (const cls of normalized) {
77
- const prefixed = cls;
78
- if (prefixed.includes(" ")) {
79
- prefixed.split(" ").forEach((c) => {
80
- const trimmed = c.trim();
81
- if (trimmed)
82
- element.classList.add(trimmed);
83
- });
84
- }
85
- else {
86
- element.classList.add(prefixed);
87
- }
59
+ const forEachClass = (classes, apply) => {
60
+ if (classes.length === 1 &&
61
+ typeof classes[0] === "string" &&
62
+ classes[0] &&
63
+ !classes[0].includes(" ")) {
64
+ apply(classes[0]);
65
+ return;
88
66
  }
67
+ for (const name of normalizeClasses(...classes))
68
+ apply(name);
69
+ };
70
+ export const addClass = (element, ...classes) => {
71
+ forEachClass(classes, (name) => element.classList.add(name));
89
72
  return element;
90
73
  };
91
74
  export const removeClass = (element, ...classes) => {
92
- if (classes.length === 0)
93
- return element;
94
- if (classes.length === 1 && Array.isArray(classes[0])) {
95
- return removeClass(element, ...classes[0]);
96
- }
97
- if (classes.length === 1 && typeof classes[0] === "string") {
98
- const cls = classes[0];
99
- if (cls && !cls.includes(" ")) {
100
- const prefixed = cls;
101
- if (!prefixed.includes(" ")) {
102
- element.classList.remove(prefixed);
103
- return element;
104
- }
105
- }
106
- }
107
- const normalized = normalizeClasses(...classes);
108
- for (const cls of normalized) {
109
- const prefixed = cls;
110
- if (prefixed.includes(" ")) {
111
- prefixed.split(" ").forEach((c) => {
112
- const trimmed = c.trim();
113
- if (trimmed)
114
- element.classList.remove(trimmed);
115
- });
116
- }
117
- else {
118
- element.classList.remove(prefixed);
119
- }
120
- }
75
+ forEachClass(classes, (name) => element.classList.remove(name));
121
76
  return element;
122
77
  };
123
78
  export const toggleClass = (element, ...classes) => {
124
- if (classes.length === 1 && Array.isArray(classes[0])) {
125
- return toggleClass(element, ...classes[0]);
126
- }
127
- if (classes.length === 1 && typeof classes[0] === "string") {
128
- const cls = classes[0];
129
- if (cls && !cls.includes(" ")) {
130
- const prefixed = cls;
131
- if (!prefixed.includes(" ")) {
132
- element.classList.toggle(prefixed);
133
- return element;
134
- }
135
- }
136
- }
137
- const normalized = normalizeClasses(...classes);
138
- for (const cls of normalized) {
139
- const prefixed = cls;
140
- if (prefixed.includes(" ")) {
141
- prefixed.split(" ").forEach((c) => {
142
- const trimmed = c.trim();
143
- if (trimmed)
144
- element.classList.toggle(trimmed);
145
- });
146
- }
147
- else {
148
- element.classList.toggle(prefixed);
149
- }
150
- }
79
+ forEachClass(classes, (name) => element.classList.toggle(name));
151
80
  return element;
152
81
  };
153
82
  export const hasClass = (element, ...classes) => {
154
- if (classes.length === 0)
155
- return true;
156
- if (classes.length === 1 && Array.isArray(classes[0])) {
157
- return hasClass(element, ...classes[0]);
158
- }
159
- if (classes.length === 1 && typeof classes[0] === "string") {
160
- const cls = classes[0];
161
- if (cls && !cls.includes(" ")) {
162
- const prefixed = cls;
163
- if (!prefixed.includes(" ")) {
164
- return element.classList.contains(prefixed);
165
- }
166
- }
167
- }
168
- const normalized = normalizeClasses(...classes);
169
- for (const cls of normalized) {
170
- const prefixed = cls;
171
- if (prefixed.includes(" ")) {
172
- const tokens = prefixed
173
- .split(" ")
174
- .map((c) => c.trim())
175
- .filter(Boolean);
176
- for (const token of tokens) {
177
- if (!element.classList.contains(token)) {
178
- return false;
179
- }
180
- }
181
- }
182
- else {
183
- if (!element.classList.contains(prefixed)) {
184
- return false;
185
- }
186
- }
83
+ for (const name of normalizeClasses(...classes)) {
84
+ if (!element.classList.contains(name))
85
+ return false;
187
86
  }
188
87
  return true;
189
88
  };
@@ -45,8 +45,6 @@ export interface ForwardedEventPayload<E extends Event = Event, TElement extends
45
45
  originalEvent: E;
46
46
  }
47
47
  export declare const createElement: (options?: CreateElementOptions) => HTMLElement;
48
- export declare const createElementPooled: (options?: CreateElementOptions) => HTMLElement;
49
- export declare const releaseElement: (element: HTMLElement) => void;
50
48
  export declare const createSVGElement: (options?: CreateSVGElementOptions) => SVGElement;
51
49
  export declare const removeEventHandlers: (element: HTMLElement | SVGElement) => void;
52
50
  declare global {
@@ -64,52 +64,6 @@ const setupEventForwarding = (element, forwardEvents, context) => {
64
64
  element.addEventListener(nativeEvent, handler, options);
65
65
  }
66
66
  };
67
- class ElementPool {
68
- constructor() {
69
- this.pools = new Map();
70
- this.maxSize = 20;
71
- }
72
- acquire(tag = "div") {
73
- const pool = this.pools.get(tag);
74
- if (pool?.length) {
75
- const element = pool.pop();
76
- element.className = "";
77
- element.replaceChildren();
78
- element.removeAttribute("id");
79
- Object.keys(element.dataset).forEach((key) => delete element.dataset[key]);
80
- return element;
81
- }
82
- return document.createElement(tag);
83
- }
84
- release(element) {
85
- const tag = element.tagName.toLowerCase();
86
- let pool = this.pools.get(tag);
87
- if (!pool) {
88
- pool = [];
89
- this.pools.set(tag, pool);
90
- }
91
- if (pool.length < this.maxSize) {
92
- this.cleanElement(element);
93
- pool.push(element);
94
- }
95
- }
96
- cleanElement(element) {
97
- const handlers = element.__eventHandlers;
98
- if (handlers) {
99
- for (const event in handlers) {
100
- element.removeEventListener(event, handlers[event]);
101
- }
102
- delete element.__eventHandlers;
103
- }
104
- element.className = "";
105
- element.replaceChildren();
106
- element.removeAttribute("id");
107
- Object.keys(element.dataset).forEach((key) => delete element.dataset[key]);
108
- element.parentNode?.removeChild(element);
109
- }
110
- }
111
- let elementPool;
112
- const getElementPool = () => elementPool ?? (elementPool = new ElementPool());
113
67
  export const createElement = (options = {}) => {
114
68
  if (!options || Object.keys(options).length === 0) {
115
69
  return document.createElement("div");
@@ -171,32 +125,6 @@ export const createElement = (options = {}) => {
171
125
  options.onCreate(element, options.context);
172
126
  return element;
173
127
  };
174
- export const createElementPooled = (options = {}) => {
175
- const element = getElementPool().acquire(options.tag || "div");
176
- if (options.html)
177
- setHTML(element, options.html);
178
- else if (options.text)
179
- element.textContent = options.text;
180
- if (options.id)
181
- element.id = options.id;
182
- const classSource = options.className || options.class;
183
- if (classSource)
184
- addClass(element, classSource);
185
- if (options.data)
186
- Object.assign(element.dataset, options.data);
187
- if (options.attributes)
188
- setAttributes(element, options.attributes);
189
- if (options.forwardEvents)
190
- setupEventForwarding(element, options.forwardEvents, options.context);
191
- if (options.container)
192
- options.container.appendChild(element);
193
- if (options.onCreate)
194
- options.onCreate(element, options.context);
195
- return element;
196
- };
197
- export const releaseElement = (element) => {
198
- getElementPool().release(element);
199
- };
200
128
  export const createSVGElement = (options = {}) => {
201
129
  const element = document.createElementNS("http://www.w3.org/2000/svg", options.tag || "svg");
202
130
  if (options.text)
@@ -25,36 +25,16 @@ function isMouseEvent(event) {
25
25
  return 'clientX' in event && 'clientY' in event;
26
26
  }
27
27
  export const normalizeEvent = (event) => {
28
- if (isTouchEvent(event) && event.touches.length > 0) {
29
- const touch = event.touches[0];
30
- return {
31
- clientX: touch.clientX,
32
- clientY: touch.clientY,
33
- pageX: touch.pageX,
34
- pageY: touch.pageY,
35
- target: event.target,
36
- preventDefault: () => event.preventDefault(),
37
- stopPropagation: () => event.stopPropagation(),
38
- type: event.type
39
- };
40
- }
41
- if (isMouseEvent(event)) {
42
- return {
43
- clientX: event.clientX,
44
- clientY: event.clientY,
45
- pageX: event.pageX,
46
- pageY: event.pageY,
47
- target: event.target,
48
- preventDefault: () => event.preventDefault(),
49
- stopPropagation: () => event.stopPropagation(),
50
- type: event.type
51
- };
52
- }
28
+ const point = isTouchEvent(event) && event.touches.length > 0
29
+ ? event.touches[0]
30
+ : isMouseEvent(event)
31
+ ? event
32
+ : undefined;
53
33
  return {
54
- clientX: 0,
55
- clientY: 0,
56
- pageX: 0,
57
- pageY: 0,
34
+ clientX: point ? point.clientX : 0,
35
+ clientY: point ? point.clientY : 0,
36
+ pageX: point ? point.pageX : 0,
37
+ pageY: point ? point.pageY : 0,
58
38
  target: event.target,
59
39
  preventDefault: () => event.preventDefault(),
60
40
  stopPropagation: () => event.stopPropagation(),
@@ -1,2 +1,2 @@
1
- /*! material v3.3.2 | MIT */
1
+ /*! material v3.3.3 | MIT */
2
2
  @layer mtrl.preupgrade{m-badge:not(:defined){display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;vertical-align:middle;overflow:hidden;height:16px;min-width:16px;max-width:34px;padding:0 4px;border-radius:var(--mtrl-sys-shape-corner-full, 9999px);font-weight:500;font-size:11px;line-height:16px;background-color:var(--mtrl-sys-color-error);color:var(--mtrl-sys-color-on-error)}m-badge:not(:defined)[color=primary]{background-color:var(--mtrl-sys-color-primary);color:var(--mtrl-sys-color-on-primary)}m-badge:not(:defined)[color=secondary]{background-color:var(--mtrl-sys-color-secondary);color:var(--mtrl-sys-color-on-secondary)}m-badge:not(:defined)[color=tertiary]{background-color:var(--mtrl-sys-color-tertiary);color:var(--mtrl-sys-color-on-tertiary)}m-badge:not(:defined)[color=success]{background-color:var(--mtrl-sys-color-success);color:var(--mtrl-sys-color-on-success)}m-badge:not(:defined)[color=warning]{background-color:var(--mtrl-sys-color-warning);color:var(--mtrl-sys-color-on-warning)}m-badge:not(:defined)[color=info]{background-color:var(--mtrl-sys-color-info);color:var(--mtrl-sys-color-on-info)}m-badge:not(:defined):empty[label]:not([label=""])::before{content:attr(label)}m-badge:not(:defined):not([variant=small]):is(:empty:not([label]),[label=""],[label="0"]){width:0;height:0;min-width:0;max-width:none;padding:0;font-size:0;background-color:rgba(0,0,0,0)}m-badge:not(:defined)[variant=small]{width:6px;height:6px;min-width:6px;max-width:none;padding:0;font-size:0}[data-mtrl-ssr]:not(:defined):not(#\0),[data-mtrl-ssr]:not(:defined):not(#\0)::before,[data-mtrl-ssr]:not(:defined):not(#\0)::after,[data-mtrl-ssr]:not(:defined):not(#\0) > :defined{all:revert-layer}}
@@ -1,2 +1,2 @@
1
- /*! material v3.3.2 | MIT */
1
+ /*! material v3.3.3 | MIT */
2
2
  @layer mtrl.preupgrade{m-bottom-app-bar:not(:defined){position:absolute;bottom:0;left:0;right:0;display:flex;align-items:center;gap:4px;box-sizing:border-box;height:80px;padding:12px 16px 12px 4px;background-color:var(--mtrl-sys-color-surface-container)}m-bottom-app-bar:not(:defined)>[slot=fab]{margin-left:auto}[data-mtrl-ssr]:not(:defined):not(#\0),[data-mtrl-ssr]:not(:defined):not(#\0)::before,[data-mtrl-ssr]:not(:defined):not(#\0)::after,[data-mtrl-ssr]:not(:defined):not(#\0) > :defined{all:revert-layer}}
@@ -1,2 +1,2 @@
1
- /*! material v3.3.2 | MIT */
1
+ /*! material v3.3.3 | MIT */
2
2
  @layer mtrl.preupgrade{m-bottom-sheet:not(:defined){display:none}[data-mtrl-ssr]:not(:defined):not(#\0),[data-mtrl-ssr]:not(:defined):not(#\0)::before,[data-mtrl-ssr]:not(:defined):not(#\0)::after,[data-mtrl-ssr]:not(:defined):not(#\0) > :defined{all:revert-layer}}
@@ -1,2 +1,2 @@
1
- /*! material v3.3.2 | MIT */
1
+ /*! material v3.3.3 | MIT */
2
2
  @layer mtrl.preupgrade{m-button-group:not(:defined){display:inline-flex;vertical-align:baseline;gap:12px;white-space:nowrap}m-button-group:not(:defined)::before{width:0;height:32px;margin-inline-end:-12px;align-self:flex-start}m-button-group:not(:defined):has(>[icon]:empty:first-child){align-items:center}m-button-group:not(:defined):has(>[icon]:empty:first-child)::before{content:""}m-button-group:not(:defined)[size=xs]{gap:18px}m-button-group:not(:defined):is([size=m],[size=l],[size=xl]){gap:8px}m-button-group:not(:defined)[density=comfortable]>*{height:36px}m-button-group:not(:defined)[density=compact]>*{height:32px}m-button-group:not(:defined)[size=xs]>*{height:32px;padding:0 13px}m-button-group:not(:defined)[size=xs][density=comfortable]>*{height:28px}m-button-group:not(:defined)[size=xs][density=compact]>*{height:24px}m-button-group:not(:defined)[size=xs]::before{height:26px;margin-inline-end:-18px}m-button-group:not(:defined)[size=m]>*{height:56px;padding:0 25px;font-size:16px;line-height:24px;letter-spacing:.15px}m-button-group:not(:defined)[size=m][density=comfortable]>*{height:52px}m-button-group:not(:defined)[size=m][density=compact]>*{height:48px}m-button-group:not(:defined)[size=m]::before{height:40px}m-button-group:not(:defined)[size=l]>*{height:96px;padding:0 50px;font-size:24px;line-height:32px}m-button-group:not(:defined)[size=l][density=comfortable]>*{height:92px}m-button-group:not(:defined)[size=l][density=compact]>*{height:88px}m-button-group:not(:defined)[size=l]::before{height:64px}m-button-group:not(:defined)[size=xl]>*{height:136px;padding:0 67px;font-size:32px;line-height:40px}m-button-group:not(:defined)[size=xl][density=comfortable]>*{height:132px}m-button-group:not(:defined)[size=xl][density=compact]>*{height:128px}m-button-group:not(:defined)[size=xl]::before{height:88px}m-button-group:not(:defined):is([size=m],[size=l],[size=xl])::before{margin-inline-end:-8px}m-button-group:not(:defined):is([size=l],[size=xl])>*{letter-spacing:0;font-weight:400}m-button-group:not(:defined)[density=comfortable]::before{margin-block-start:-2px}m-button-group:not(:defined)[density=compact]::before{margin-block-start:-4px}m-button-group:not(:defined)>*{visibility:hidden;display:inline-flex;align-items:center;flex:none;min-width:58px;font-family:var(--mtrl-ref-typeface-plain, Roboto, sans-serif);height:40px;padding:0 17px;font-size:14px;line-height:20px;letter-spacing:.1px;font-weight:500}m-button-group:not(:defined)>*[icon]:empty{min-width:0;padding:0;aspect-ratio:1}m-button-group:not(:defined)[kind=connected]{gap:2px}m-button-group:not(:defined)[kind=connected]::before{margin-inline-end:-2px}m-button-group:not(:defined):is(:not([size]),[size=xs],[size=s])[kind=connected]>*{min-width:48px}[data-mtrl-ssr]:not(:defined):not(#\0),[data-mtrl-ssr]:not(:defined):not(#\0)::before,[data-mtrl-ssr]:not(:defined):not(#\0)::after,[data-mtrl-ssr]:not(:defined):not(#\0) > :defined{all:revert-layer}}
@@ -1,2 +1,2 @@
1
- /*! material v3.3.2 | MIT */
1
+ /*! material v3.3.3 | MIT */
2
2
  @layer mtrl.preupgrade{m-button:not(:defined){display:inline-flex;vertical-align:middle;align-items:center;justify-content:center;box-sizing:border-box;min-width:58px;white-space:nowrap;background-color:var(--mtrl-sys-color-primary);color:var(--mtrl-sys-color-on-primary);height:40px;padding:0 16px;gap:8px;border-radius:20px;font-family:var(--mtrl-ref-typeface-plain, Roboto, sans-serif);font-size:14px;line-height:20px;letter-spacing:.1px;font-weight:500}m-button:not(:defined)[icon]::before,m-button:not(:defined)[icon][icon-position=end]::after{width:20px;height:20px}m-button:not(:defined)[size=xs]{height:32px;padding:0 12px;gap:4px;border-radius:16px;font-family:var(--mtrl-ref-typeface-plain, Roboto, sans-serif);font-size:14px;line-height:20px;letter-spacing:.1px;font-weight:500}m-button:not(:defined)[size=xs][icon]::before,m-button:not(:defined)[size=xs][icon][icon-position=end]::after{width:20px;height:20px}m-button:not(:defined)[size=s]{height:40px;padding:0 16px;gap:8px;border-radius:20px;font-family:var(--mtrl-ref-typeface-plain, Roboto, sans-serif);font-size:14px;line-height:20px;letter-spacing:.1px;font-weight:500}m-button:not(:defined)[size=s][icon]::before,m-button:not(:defined)[size=s][icon][icon-position=end]::after{width:20px;height:20px}m-button:not(:defined)[size=m]{height:56px;padding:0 24px;gap:8px;border-radius:28px;font-family:var(--mtrl-ref-typeface-brand, Roboto, sans-serif);font-size:16px;line-height:24px;letter-spacing:.15px;font-weight:500}m-button:not(:defined)[size=m][icon]::before,m-button:not(:defined)[size=m][icon][icon-position=end]::after{width:24px;height:24px}m-button:not(:defined)[size=l]{height:96px;padding:0 48px;gap:12px;border-radius:48px;font-family:var(--mtrl-ref-typeface-brand, Roboto, sans-serif);font-size:24px;line-height:32px;letter-spacing:0;font-weight:400}m-button:not(:defined)[size=l][icon]::before,m-button:not(:defined)[size=l][icon][icon-position=end]::after{width:32px;height:32px}m-button:not(:defined)[size=xl]{height:136px;padding:0 64px;gap:16px;border-radius:68px;font-family:var(--mtrl-ref-typeface-brand, Roboto, sans-serif);font-size:32px;line-height:40px;letter-spacing:0;font-weight:400}m-button:not(:defined)[size=xl][icon]::before,m-button:not(:defined)[size=xl][icon][icon-position=end]::after{width:40px;height:40px}m-button:not(:defined)[variant=filled]{background-color:var(--mtrl-sys-color-primary);color:var(--mtrl-sys-color-on-primary)}m-button:not(:defined)[variant=elevated]{background-color:var(--mtrl-sys-color-surface-container-low);color:var(--mtrl-sys-color-primary)}m-button:not(:defined)[variant=tonal]{background-color:var(--mtrl-sys-color-secondary-container);color:var(--mtrl-sys-color-on-secondary-container)}m-button:not(:defined)[variant=outlined]{background-color:rgba(0,0,0,0);color:var(--mtrl-sys-color-on-surface-variant)}m-button:not(:defined)[variant=text]{background-color:rgba(0,0,0,0);color:var(--mtrl-sys-color-primary)}m-button:not(:defined)[variant=outlined]{border:1px solid var(--mtrl-sys-color-outline-variant)}m-button:not(:defined)[variant=text]{padding:0 12px}m-button:not(:defined)[icon]::before,m-button:not(:defined)[icon][icon-position=end]::after{content:"";flex:none}m-button:not(:defined)[icon][icon-position=end]::before{content:none}m-button:not(:defined)[icon]:not([size]),m-button:not(:defined)[icon][size=s]{padding-inline-start:12px}m-button:not(:defined)[icon]:not([size])[icon-position=end],m-button:not(:defined)[icon][size=s][icon-position=end]{padding-inline-start:16px;padding-inline-end:12px}m-button:not(:defined)[variant=text][icon]:not([size]),m-button:not(:defined)[variant=text][icon][size=xs],m-button:not(:defined)[variant=text][icon][size=s]{padding-inline:12px 16px}m-button:not(:defined)[variant=text][icon]:not([size])[icon-position=end],m-button:not(:defined)[variant=text][icon][size=xs][icon-position=end],m-button:not(:defined)[variant=text][icon][size=s][icon-position=end]{padding-inline:16px 12px}m-button:not(:defined)[variant=text][icon][size=m]{padding:0 24px}m-button:not(:defined)[variant=text][icon][size=l]{padding:0 48px}m-button:not(:defined)[variant=text][icon][size=xl]{padding:0 64px}[data-mtrl-ssr]:not(:defined):not(#\0),[data-mtrl-ssr]:not(:defined):not(#\0)::before,[data-mtrl-ssr]:not(:defined):not(#\0)::after,[data-mtrl-ssr]:not(:defined):not(#\0) > :defined{all:revert-layer}}