mtrl 0.10.3 → 0.10.5

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 (226) hide show
  1. package/README.md +15 -5
  2. package/dist/README.md +15 -5
  3. package/dist/components/bottom-app-bar/bottom-app-bar.js +2 -1
  4. package/dist/components/bottom-app-bar/index.d.ts +3 -1
  5. package/dist/components/button/api.js +3 -0
  6. package/dist/components/button/constants.d.ts +2 -0
  7. package/dist/components/button/index.d.ts +1 -0
  8. package/dist/components/button/types.d.ts +7 -1
  9. package/dist/components/button-group/button-group.js +3 -0
  10. package/dist/components/button-group/config.js +2 -2
  11. package/dist/components/button-group/constants.d.ts +8 -2
  12. package/dist/components/button-group/index.d.ts +1 -0
  13. package/dist/components/button-group/types.d.ts +2 -0
  14. package/dist/components/card/index.d.ts +21 -3
  15. package/dist/components/card/index.js +1 -1
  16. package/dist/components/card/types.d.ts +19 -3
  17. package/dist/components/carousel/api.d.ts +1 -0
  18. package/dist/components/carousel/api.js +4 -0
  19. package/dist/components/carousel/features/scroll.d.ts +1 -0
  20. package/dist/components/carousel/features/scroll.js +117 -2
  21. package/dist/components/carousel/types.d.ts +10 -0
  22. package/dist/components/checkbox/api.js +3 -0
  23. package/dist/components/checkbox/config.js +1 -0
  24. package/dist/components/checkbox/types.d.ts +8 -2
  25. package/dist/components/chips/types.d.ts +5 -1
  26. package/dist/components/datepicker/index.d.ts +3 -1
  27. package/dist/components/datepicker/index.js +1 -1
  28. package/dist/components/datepicker/render.js +3 -3
  29. package/dist/components/extended-fab/api.d.ts +2 -0
  30. package/dist/components/extended-fab/api.js +3 -0
  31. package/dist/components/extended-fab/config.d.ts +1 -0
  32. package/dist/components/extended-fab/config.js +1 -0
  33. package/dist/components/extended-fab/types.d.ts +2 -0
  34. package/dist/components/fab/api.d.ts +2 -0
  35. package/dist/components/fab/api.js +3 -0
  36. package/dist/components/fab/config.d.ts +1 -0
  37. package/dist/components/fab/config.js +1 -0
  38. package/dist/components/fab/constants.d.ts +2 -1
  39. package/dist/components/fab/types.d.ts +2 -0
  40. package/dist/components/fab-menu/fab-menu.js +2 -1
  41. package/dist/components/icon-button/api.js +3 -0
  42. package/dist/components/icon-button/constants.d.ts +2 -0
  43. package/dist/components/icon-button/types.d.ts +2 -0
  44. package/dist/components/index.d.ts +18 -5
  45. package/dist/components/index.js +2 -1
  46. package/dist/components/list/types.d.ts +5 -3
  47. package/dist/components/menu/features/keyboard.js +8 -5
  48. package/dist/components/menu/features/opener.js +1 -1
  49. package/dist/components/menu/index.d.ts +1 -0
  50. package/dist/components/progress/features/canvas.js +1 -1
  51. package/dist/components/progress/features/colors.d.ts +2 -1
  52. package/dist/components/progress/features/colors.js +20 -10
  53. package/dist/components/radios/api.d.ts +1 -0
  54. package/dist/components/radios/api.js +3 -0
  55. package/dist/components/radios/constants.d.ts +6 -6
  56. package/dist/components/radios/radio.d.ts +1 -0
  57. package/dist/components/radios/radio.js +1 -0
  58. package/dist/components/radios/types.d.ts +2 -0
  59. package/dist/components/search/features/states.d.ts +2 -0
  60. package/dist/components/search/features/states.js +12 -1
  61. package/dist/components/search/features/structure.js +2 -0
  62. package/dist/components/segmented-button/config.js +2 -2
  63. package/dist/components/select/api.js +3 -0
  64. package/dist/components/select/constants.d.ts +1 -1
  65. package/dist/components/select/features.js +2 -0
  66. package/dist/components/select/index.d.ts +1 -0
  67. package/dist/components/select/types.d.ts +4 -0
  68. package/dist/components/switch/api.js +3 -0
  69. package/dist/components/switch/config.js +1 -0
  70. package/dist/components/switch/index.d.ts +6 -2
  71. package/dist/components/switch/index.js +1 -1
  72. package/dist/components/switch/types.d.ts +6 -2
  73. package/dist/components/tabs/config.js +2 -2
  74. package/dist/components/tabs/index.d.ts +36 -3
  75. package/dist/components/tabs/index.js +2 -1
  76. package/dist/components/tabs/tab.js +8 -1
  77. package/dist/components/tabs/types.d.ts +2 -0
  78. package/dist/components/tabs/utils.js +2 -1
  79. package/dist/components/textfield/api.d.ts +5 -0
  80. package/dist/components/textfield/api.js +209 -188
  81. package/dist/components/textfield/config.js +4 -3
  82. package/dist/components/textfield/constants.d.ts +24 -7
  83. package/dist/components/textfield/constants.js +9 -7
  84. package/dist/components/textfield/features/index.d.ts +3 -1
  85. package/dist/components/textfield/features/index.js +1 -0
  86. package/dist/components/textfield/features/leading-icon.js +1 -0
  87. package/dist/components/textfield/features/placement.js +15 -2
  88. package/dist/components/textfield/features/required.d.ts +33 -0
  89. package/dist/components/textfield/features/required.js +50 -0
  90. package/dist/components/textfield/features/supporting-text.js +43 -21
  91. package/dist/components/textfield/features/trailing-icon.d.ts +23 -1
  92. package/dist/components/textfield/features/trailing-icon.js +39 -5
  93. package/dist/components/textfield/index.d.ts +16 -1
  94. package/dist/components/textfield/index.js +1 -0
  95. package/dist/components/textfield/textfield.js +2 -2
  96. package/dist/components/textfield/types.d.ts +33 -3
  97. package/dist/components/toolbar/toolbar.js +2 -1
  98. package/dist/components/tooltip/constants.d.ts +4 -1
  99. package/dist/components/top-app-bar/index.d.ts +3 -1
  100. package/dist/components/top-app-bar/top-app-bar.d.ts +2 -57
  101. package/dist/components/top-app-bar/top-app-bar.js +2 -1
  102. package/dist/core/utils/theme.d.ts +6 -2
  103. package/dist/core/utils/theme.js +12 -19
  104. package/dist/elements/carousel.d.ts +5 -0
  105. package/dist/elements/carousel.js +1 -0
  106. package/dist/elements/css/datepicker.js +1 -1
  107. package/dist/elements/css/textfield.js +1 -1
  108. package/dist/elements/dialog.js +1 -1
  109. package/dist/elements/index.d.ts +15 -4
  110. package/dist/elements/index.js +2 -1
  111. package/dist/elements/preupgrade.css +1 -1
  112. package/dist/elements/textfield.d.ts +1 -1
  113. package/dist/elements/textfield.js +1 -1
  114. package/dist/index.cjs +0 -0
  115. package/dist/index.d.ts +293 -3
  116. package/dist/index.js +7 -3
  117. package/dist/package.json +16 -13
  118. package/dist/react/dialog.d.ts +3 -0
  119. package/dist/react/dialog.js +3 -0
  120. package/dist/react/index.d.ts +4 -1
  121. package/dist/react/index.js +2 -1
  122. package/dist/solid/dialog.d.ts +3 -0
  123. package/dist/solid/dialog.js +3 -0
  124. package/dist/solid/index.d.ts +4 -1
  125. package/dist/solid/index.js +2 -1
  126. package/dist/styles/badge.css +1 -1
  127. package/dist/styles/base.css +2 -2
  128. package/dist/styles/bottom-app-bar.css +1 -1
  129. package/dist/styles/bottom-sheet.css +1 -1
  130. package/dist/styles/button-group.css +1 -1
  131. package/dist/styles/button.css +1 -1
  132. package/dist/styles/card.css +1 -1
  133. package/dist/styles/carousel.css +1 -1
  134. package/dist/styles/checkbox.css +1 -1
  135. package/dist/styles/chips.css +1 -1
  136. package/dist/styles/datepicker.css +2 -2
  137. package/dist/styles/dialog.css +1 -1
  138. package/dist/styles/divider.css +1 -1
  139. package/dist/styles/drawer.css +1 -1
  140. package/dist/styles/extended-fab.css +1 -1
  141. package/dist/styles/fab-menu.css +1 -1
  142. package/dist/styles/fab.css +1 -1
  143. package/dist/styles/icon-button.css +1 -1
  144. package/dist/styles/list.css +1 -1
  145. package/dist/styles/loading-indicator.css +1 -1
  146. package/dist/styles/menu.css +1 -1
  147. package/dist/styles/navigation-rail.css +1 -1
  148. package/dist/styles/progress.css +1 -1
  149. package/dist/styles/radios.css +1 -1
  150. package/dist/styles/search.css +1 -1
  151. package/dist/styles/segmented-button.css +1 -1
  152. package/dist/styles/select.css +1 -1
  153. package/dist/styles/side-sheet.css +1 -1
  154. package/dist/styles/slider.css +1 -1
  155. package/dist/styles/snackbar.css +1 -1
  156. package/dist/styles/split-button.css +1 -1
  157. package/dist/styles/switch.css +1 -1
  158. package/dist/styles/tabs.css +1 -1
  159. package/dist/styles/textfield.css +2 -2
  160. package/dist/styles/timepicker.css +1 -1
  161. package/dist/styles/toolbar.css +1 -1
  162. package/dist/styles/tooltip.css +1 -1
  163. package/dist/styles/top-app-bar.css +1 -1
  164. package/dist/styles/utilities.css +1 -1
  165. package/dist/styles.css +2 -2
  166. package/dist/svelte/Dialog.svelte +3 -0
  167. package/dist/svelte/index.d.ts +5 -1
  168. package/dist/svelte/index.js +5 -1
  169. package/dist/themes/autumn.css +2 -2
  170. package/dist/themes/baseline.css +2 -2
  171. package/dist/themes/brownbeige.css +2 -2
  172. package/dist/themes/browngreen.css +2 -2
  173. package/dist/themes/content.css +2 -2
  174. package/dist/themes/desert.css +2 -2
  175. package/dist/themes/expressive.css +2 -2
  176. package/dist/themes/fidelity.css +2 -2
  177. package/dist/themes/forest.css +2 -2
  178. package/dist/themes/fruit-salad.css +2 -2
  179. package/dist/themes/highcontrast.css +2 -2
  180. package/dist/themes/legacy.css +2 -2
  181. package/dist/themes/material.css +2 -2
  182. package/dist/themes/monochrome.css +2 -2
  183. package/dist/themes/neutral.css +2 -2
  184. package/dist/themes/ocean.css +2 -2
  185. package/dist/themes/rainbow.css +2 -2
  186. package/dist/themes/sageivory.css +2 -2
  187. package/dist/themes/spring.css +2 -2
  188. package/dist/themes/summer.css +2 -2
  189. package/dist/themes/sunset.css +2 -2
  190. package/dist/themes/tealcaramel.css +2 -2
  191. package/dist/themes/vibrant.css +2 -2
  192. package/dist/themes/winter.css +2 -2
  193. package/dist/vue/dialog.d.ts +3 -0
  194. package/dist/vue/dialog.js +3 -0
  195. package/dist/vue/index.d.ts +4 -1
  196. package/dist/vue/index.js +2 -1
  197. package/package.json +16 -13
  198. package/src/styles/abstract/_theme.scss +6 -6
  199. package/src/styles/abstract/_variables.scss +14 -4
  200. package/src/styles/components/_datepicker.scss +15 -2
  201. package/src/styles/components/_textfield.scss +61 -8
  202. package/src/styles/themes/_autumn.scss +173 -0
  203. package/src/styles/themes/_base-theme.scss +100 -12
  204. package/src/styles/themes/_baseline.scss +172 -0
  205. package/src/styles/themes/_brownbeige.scss +150 -0
  206. package/src/styles/themes/_browngreen.scss +183 -0
  207. package/src/styles/themes/_content.scss +148 -0
  208. package/src/styles/themes/_desert.scss +150 -0
  209. package/src/styles/themes/_expressive.scss +150 -0
  210. package/src/styles/themes/_fidelity.scss +148 -0
  211. package/src/styles/themes/_forest.scss +175 -0
  212. package/src/styles/themes/_fruit-salad.scss +150 -0
  213. package/src/styles/themes/_highcontrast.scss +74 -0
  214. package/src/styles/themes/_legacy.scss +181 -0
  215. package/src/styles/themes/_material.scss +181 -0
  216. package/src/styles/themes/_monochrome.scss +134 -0
  217. package/src/styles/themes/_neutral.scss +150 -0
  218. package/src/styles/themes/_ocean.scss +175 -0
  219. package/src/styles/themes/_rainbow.scss +150 -0
  220. package/src/styles/themes/_sageivory.scss +150 -0
  221. package/src/styles/themes/_spring.scss +171 -0
  222. package/src/styles/themes/_summer.scss +150 -0
  223. package/src/styles/themes/_sunset.scss +175 -0
  224. package/src/styles/themes/_tealcaramel.scss +150 -0
  225. package/src/styles/themes/_vibrant.scss +150 -0
  226. package/src/styles/themes/_winter.scss +181 -0
@@ -8,6 +8,7 @@
8
8
  * @category Components
9
9
  */
10
10
  export { default } from "./select.js";
11
+ export type { SelectEvents } from "./types.js";
11
12
  export type { SelectConfig, SelectComponent, SelectOption, SelectEvent, SelectChangeEvent } from "./types.js";
12
13
  /**
13
14
  * Constants for select configuration
@@ -160,6 +160,8 @@ export interface SelectComponent {
160
160
  element: HTMLElement;
161
161
  /**
162
162
  * The textfield component
163
+ * @deprecated Renamed `textField` in 1.0 (FLO-383); `textfield` remains as an alias through
164
+ * 1.x.
163
165
  */
164
166
  textfield: TextfieldComponent;
165
167
  /**
@@ -249,6 +251,8 @@ export interface SelectComponent {
249
251
  * @returns Select component for chaining
250
252
  */
251
253
  disable: () => SelectComponent;
254
+ /** Whether the select is disabled (FLO-384) */
255
+ isDisabled: () => boolean;
252
256
  /**
253
257
  * Sets the error state on the select
254
258
  * @param error - Whether to show error state
@@ -90,6 +90,9 @@ export const withAPI = ({ disabled, lifecycle, checkable }) => (component) => ({
90
90
  disabled.enable();
91
91
  return this;
92
92
  },
93
+ isDisabled() {
94
+ return disabled.isDisabled();
95
+ },
93
96
  disable() {
94
97
  disabled.disable();
95
98
  return this;
@@ -15,6 +15,7 @@ export const getApiConfig = (comp) => ({
15
15
  disabled: {
16
16
  enable: comp.disabled.enable,
17
17
  disable: comp.disabled.disable,
18
+ isDisabled: comp.disabled.isDisabled,
18
19
  },
19
20
  lifecycle: {
20
21
  destroy: comp.lifecycle.destroy,
@@ -1,5 +1,9 @@
1
1
  export { default } from "./switch.js";
2
2
  export { SWITCH_LABEL_POSITIONS, SWITCH_STATES, SWITCH_EVENTS, SWITCH_DEFAULTS, SWITCH_CLASSES } from "./constants.js";
3
3
  export type { SwitchConfig, SwitchComponent, SwitchEvents, SwitchChangePayload } from "./types.js";
4
- export { withSupportingText } from "./features.js";
5
- export type { SupportingTextComponent } from "./features.js";
4
+ export {
5
+ /** @deprecated Internal, no replacement: removed from mtrl/components/switch in 1.0.0 (FLO-381). */
6
+ withSupportingText, } from "./features.js";
7
+ export type {
8
+ /** @deprecated Internal, no replacement: removed from mtrl/components/switch in 1.0.0 (FLO-381). */
9
+ SupportingTextComponent, } from "./features.js";
@@ -1,3 +1,3 @@
1
1
  export { default } from "./switch.js";
2
2
  export { SWITCH_LABEL_POSITIONS, SWITCH_STATES, SWITCH_EVENTS, SWITCH_DEFAULTS, SWITCH_CLASSES } from "./constants.js";
3
- export { withSupportingText } from "./features.js";
3
+ export { withSupportingText, } from "./features.js";
@@ -47,13 +47,13 @@ export interface SwitchConfig {
47
47
  /** Index signature for additional properties */
48
48
  [key: string]: unknown;
49
49
  }
50
- /** A checked-state change from the native input or a programmatic setter. */
50
+ /** A checked-state change from native input activation. Public setters are silent. */
51
51
  export interface SwitchChangePayload {
52
52
  /** The new checked state. */
53
53
  checked: boolean;
54
54
  /** The input's HTML value attribute, not the boolean checked state. */
55
55
  value: string;
56
- /** Present for input-driven changes; absent for check/uncheck/toggle/setValue. */
56
+ /** The original native change event, when supplied by the emitter. */
57
57
  nativeEvent?: Event;
58
58
  }
59
59
  /** Emitter events: change, and the input's focus and blur (FLO-267). */
@@ -108,6 +108,8 @@ export interface SwitchComponent {
108
108
  enable: () => SwitchComponent;
109
109
  /** Disables the switch */
110
110
  disable: () => SwitchComponent;
111
+ /** Whether the switch is disabled (FLO-384) */
112
+ isDisabled: () => boolean;
111
113
  /** Destroys the switch component and cleans up resources */
112
114
  destroy: () => void;
113
115
  }
@@ -118,6 +120,7 @@ export interface ApiOptions {
118
120
  disabled: {
119
121
  enable: () => void;
120
122
  disable: () => void;
123
+ isDisabled: () => boolean;
121
124
  };
122
125
  lifecycle: {
123
126
  destroy: () => void;
@@ -146,6 +149,7 @@ export interface BaseComponent {
146
149
  disabled?: {
147
150
  enable: () => void;
148
151
  disable: () => void;
152
+ isDisabled: () => boolean;
149
153
  };
150
154
  lifecycle?: {
151
155
  destroy: () => void;
@@ -1,4 +1,4 @@
1
- import { createComponentConfig } from "../../core/config/component.js";
1
+ import { createComponentConfig, processClassNames } from "../../core/config/component.js";
2
2
  import { withElement } from "../../core/compose/component.js";
3
3
  import { TAB_STATES, TABS_DEFAULTS } from "./constants.js";
4
4
  export const defaultTabConfig = {
@@ -24,7 +24,7 @@ export const getTabsElementConfig = (config) => {
24
24
  className: [
25
25
  `${config.prefix}-tabs`,
26
26
  `${config.prefix}-tabs--${config.variant || "primary"}`,
27
- config.class,
27
+ processClassNames(config.className || ""),
28
28
  ].filter((name) => Boolean(name)),
29
29
  };
30
30
  return (component) => withElement(elementConfig)(component);
@@ -6,7 +6,40 @@ import { createTabIndicator } from "./indicator.js";
6
6
  import { updateTabPanels, setupKeyboardNavigation } from "./utils.js";
7
7
  export { TAB_VARIANTS, TAB_STATES, TAB_INDICATOR_WIDTH_STRATEGIES, TAB_EVENTS, TABS_EVENTS, TABS_DEFAULTS, TABS_CLASSES, TAB_CLASSES, } from "./constants.js";
8
8
  export type { TabsConfig, TabsComponent, TabComponent, TabConfig, TabChangeEventData, IndicatorConfig, } from "./types.js";
9
- export { addScrollIndicators, setupResponsiveBehavior, createTabsState, createTabIndicator, updateTabPanels, setupKeyboardNavigation, };
10
- export { withTabsManagement, withScrollable, withDivider, withIndicator } from "./features.js";
11
- export type { TabsManagementConfig, TabsManagementComponent, ScrollableConfig, ScrollableComponent, DividerConfig, IndicatorFeatureConfig, IndicatorComponent } from "./features.js";
9
+ export {
10
+ /** @deprecated Internal, no replacement: removed from mtrl/components/tabs in 1.0.0 (FLO-381). */
11
+ addScrollIndicators, setupResponsiveBehavior,
12
+ /** @deprecated Internal, no replacement: removed from mtrl/components/tabs in 1.0.0 (FLO-381). */
13
+ createTabsState,
14
+ /** @deprecated Internal, no replacement: removed from mtrl/components/tabs in 1.0.0 (FLO-381). */
15
+ createTabIndicator,
16
+ /** @deprecated Internal, no replacement: removed from mtrl/components/tabs in 1.0.0 (FLO-381). */
17
+ updateTabPanels,
18
+ /** @deprecated Internal, no replacement: removed from mtrl/components/tabs in 1.0.0 (FLO-381). */
19
+ setupKeyboardNavigation, };
20
+ export {
21
+ /** @deprecated Internal, no replacement: removed from mtrl/components/tabs in 1.0.0 (FLO-381). */
22
+ withTabsManagement,
23
+ /** @deprecated Internal, no replacement: removed from mtrl/components/tabs in 1.0.0 (FLO-381). */
24
+ withScrollable,
25
+ /** @deprecated Internal, no replacement: removed from mtrl/components/tabs in 1.0.0 (FLO-381). */
26
+ withDivider,
27
+ /** @deprecated Internal, no replacement: removed from mtrl/components/tabs in 1.0.0 (FLO-381). */
28
+ withIndicator, } from "./features.js";
29
+ export type {
30
+ /** @deprecated Internal, no replacement: removed from mtrl/components/tabs in 1.0.0 (FLO-381). */
31
+ TabsManagementConfig,
32
+ /** @deprecated Internal, no replacement: removed from mtrl/components/tabs in 1.0.0 (FLO-381). */
33
+ TabsManagementComponent,
34
+ /** @deprecated Internal, no replacement: removed from mtrl/components/tabs in 1.0.0 (FLO-381). */
35
+ ScrollableConfig,
36
+ /** @deprecated Internal, no replacement: removed from mtrl/components/tabs in 1.0.0 (FLO-381). */
37
+ ScrollableComponent,
38
+ /** @deprecated Internal, no replacement: removed from mtrl/components/tabs in 1.0.0 (FLO-381). */
39
+ DividerConfig,
40
+ /** @deprecated Internal, no replacement: removed from mtrl/components/tabs in 1.0.0 (FLO-381). */
41
+ IndicatorFeatureConfig,
42
+ /** @deprecated Internal, no replacement: removed from mtrl/components/tabs in 1.0.0 (FLO-381). */
43
+ IndicatorComponent, } from "./features.js";
12
44
  export default createTabs;
45
+ export { createTab } from "./tab.js";
@@ -6,5 +6,6 @@ import { createTabIndicator } from "./indicator.js";
6
6
  import { updateTabPanels, setupKeyboardNavigation } from "./utils.js";
7
7
  export { TAB_VARIANTS, TAB_STATES, TAB_INDICATOR_WIDTH_STRATEGIES, TAB_EVENTS, TABS_EVENTS, TABS_DEFAULTS, TABS_CLASSES, TAB_CLASSES, } from "./constants.js";
8
8
  export { addScrollIndicators, setupResponsiveBehavior, createTabsState, createTabIndicator, updateTabPanels, setupKeyboardNavigation, };
9
- export { withTabsManagement, withScrollable, withDivider, withIndicator } from "./features.js";
9
+ export { withTabsManagement, withScrollable, withDivider, withIndicator, } from "./features.js";
10
10
  export default createTabs;
11
+ export { createTab } from "./tab.js";
@@ -1,3 +1,4 @@
1
+ import { processClassNames } from "../../core/config/component.js";
1
2
  import { syncTabControls, tabIdFor } from "./utils.js";
2
3
  import { pipe } from "../../core/compose/index.js";
3
4
  import { createBase } from "../../core/compose/component.js";
@@ -24,7 +25,10 @@ export const createTab = (config = {}) => {
24
25
  value: baseConfig.value,
25
26
  prefix: baseConfig.prefix,
26
27
  variant: "text",
27
- class: `${baseConfig.prefix}-tab`,
28
+ class: [
29
+ `${baseConfig.prefix}-tab`,
30
+ processClassNames(baseConfig.className || ""),
31
+ ].filter(Boolean).join(" "),
28
32
  });
29
33
  baseComponent.element = button.element;
30
34
  baseComponent.element.setAttribute("role", "tab");
@@ -95,6 +99,9 @@ export const createTab = (config = {}) => {
95
99
  this.element.setAttribute("aria-disabled", "true");
96
100
  return this;
97
101
  },
102
+ isDisabled() {
103
+ return button.isDisabled();
104
+ },
98
105
  setText(content) {
99
106
  button.setText(content);
100
107
  this.updateLayoutStyle();
@@ -299,6 +299,8 @@ export interface TabComponent {
299
299
  enable: () => TabComponent;
300
300
  /** Disables the tab (adds disabled attribute) */
301
301
  disable: () => TabComponent;
302
+ /** Whether the tab is disabled (FLO-384) */
303
+ isDisabled: () => boolean;
302
304
  /** Sets the tab's text content */
303
305
  setText: (content: string) => TabComponent;
304
306
  /** Gets the tab's text content */
@@ -21,7 +21,8 @@ export function findRegisteredPanel(tab) {
21
21
  const tabId = tab.id;
22
22
  if (!tabId || typeof document === "undefined")
23
23
  return null;
24
- const labelled = document.querySelector(`[role="tabpanel"][aria-labelledby="${tabId}"]`);
24
+ const labelled = Array.from(document.querySelectorAll('[role="tabpanel"]'))
25
+ .find((panel) => panel.getAttribute("aria-labelledby") === tabId);
25
26
  if (labelled)
26
27
  return labelled;
27
28
  if (tabId.startsWith("tab-")) {
@@ -12,6 +12,11 @@ type ComponentWithDensity = BaseComponent & {
12
12
  setError?: (error: boolean, message?: string) => void;
13
13
  isError?: () => boolean;
14
14
  field?: HTMLElement;
15
+ input?: HTMLInputElement | HTMLTextAreaElement;
16
+ trailingIcon?: HTMLElement | null;
17
+ setTrailingIcon?: (html: string, label?: string) => void;
18
+ setRequired?: (required: boolean) => void;
19
+ isRequired?: () => boolean;
15
20
  };
16
21
  /**
17
22
  * Enhances textfield component with API methods
@@ -1,201 +1,222 @@
1
- export const withAPI = ({ disabled, lifecycle }) => (component) => ({
2
- element: component.element,
3
- field: component.field ?? component.element,
4
- input: component.input,
5
- getValue: component.getValue || (() => ""),
6
- setValue(value) {
7
- component.setValue?.(value);
8
- return this;
9
- },
10
- setAttribute(name, value) {
11
- component.setAttribute?.(name, value);
12
- return this;
13
- },
14
- getAttribute(name) {
15
- return component.getAttribute?.(name) || null;
16
- },
17
- removeAttribute(name) {
18
- component.removeAttribute?.(name);
19
- return this;
20
- },
21
- setVariant(variant) {
22
- const PREFIX = component.config?.prefix || "mtrl";
23
- const COMPONENT = component.config?.componentName || "textfield";
24
- component.element.classList.remove(`${PREFIX}-${COMPONENT}--filled`, `${PREFIX}-${COMPONENT}--outlined`);
25
- component.element.classList.add(`${PREFIX}-${COMPONENT}--${variant}`);
26
- if (component.updateElementPositions) {
27
- component.schedulePositionUpdate?.();
28
- }
29
- return this;
30
- },
31
- getVariant() {
32
- const PREFIX = component.config?.prefix || "mtrl";
33
- const COMPONENT = component.config?.componentName || "textfield";
34
- if (component.element.classList.contains(`${PREFIX}-${COMPONENT}--outlined`)) {
35
- return "outlined";
36
- }
37
- return "filled";
38
- },
39
- setLabel(text) {
40
- component.label?.setText(text);
41
- if (component.updateElementPositions) {
42
- component.schedulePositionUpdate?.();
43
- }
44
- return this;
45
- },
46
- getLabel() {
47
- return component.label?.getText() || "";
48
- },
49
- get leadingIcon() {
50
- return component.leadingIcon ?? null;
51
- },
52
- setLeadingIcon(html) {
53
- if (component.setLeadingIcon) {
54
- component.setLeadingIcon(html);
1
+ export const withAPI = ({ disabled, lifecycle }) => (component) => {
2
+ const setTrailingDisabled = (off) => {
3
+ const icon = component.trailingIcon;
4
+ if (icon?.tagName === "BUTTON")
5
+ icon.disabled = off;
6
+ };
7
+ return {
8
+ element: component.element,
9
+ field: component.field ?? component.element,
10
+ input: component.input,
11
+ getValue: component.getValue || (() => ""),
12
+ setValue(value) {
13
+ component.setValue?.(value);
14
+ return this;
15
+ },
16
+ setAttribute(name, value) {
17
+ component.setAttribute?.(name, value);
18
+ return this;
19
+ },
20
+ getAttribute(name) {
21
+ return component.getAttribute?.(name) || null;
22
+ },
23
+ removeAttribute(name) {
24
+ component.removeAttribute?.(name);
25
+ return this;
26
+ },
27
+ setVariant(variant) {
28
+ const PREFIX = component.config?.prefix || "mtrl";
29
+ const COMPONENT = component.config?.componentName || "textfield";
30
+ component.element.classList.remove(`${PREFIX}-${COMPONENT}--filled`, `${PREFIX}-${COMPONENT}--outlined`);
31
+ component.element.classList.add(`${PREFIX}-${COMPONENT}--${variant}`);
55
32
  if (component.updateElementPositions) {
56
33
  component.schedulePositionUpdate?.();
57
34
  }
58
- }
59
- return this;
60
- },
61
- removeLeadingIcon() {
62
- if (component.removeLeadingIcon) {
63
- component.removeLeadingIcon();
64
- if (component.updateElementPositions) {
65
- component.schedulePositionUpdate?.();
35
+ return this;
36
+ },
37
+ getVariant() {
38
+ const PREFIX = component.config?.prefix || "mtrl";
39
+ const COMPONENT = component.config?.componentName || "textfield";
40
+ if (component.element.classList.contains(`${PREFIX}-${COMPONENT}--outlined`)) {
41
+ return "outlined";
66
42
  }
67
- }
68
- return this;
69
- },
70
- get trailingIcon() {
71
- return component.trailingIcon ?? null;
72
- },
73
- setTrailingIcon(html) {
74
- if (component.setTrailingIcon) {
75
- component.setTrailingIcon(html);
43
+ return "filled";
44
+ },
45
+ setLabel(text) {
46
+ component.label?.setText(text);
76
47
  if (component.updateElementPositions) {
77
48
  component.schedulePositionUpdate?.();
78
49
  }
79
- }
80
- return this;
81
- },
82
- removeTrailingIcon() {
83
- if (component.removeTrailingIcon) {
84
- component.removeTrailingIcon();
85
- if (component.updateElementPositions) {
86
- component.schedulePositionUpdate?.();
50
+ return this;
51
+ },
52
+ getLabel() {
53
+ return component.label?.getText() || "";
54
+ },
55
+ get leadingIcon() {
56
+ return component.leadingIcon ?? null;
57
+ },
58
+ setLeadingIcon(html) {
59
+ if (component.setLeadingIcon) {
60
+ component.setLeadingIcon(html);
61
+ if (component.updateElementPositions) {
62
+ component.schedulePositionUpdate?.();
63
+ }
87
64
  }
88
- }
89
- return this;
90
- },
91
- get supportingTextElement() {
92
- return component.element.querySelector(`.${component.getClass("textfield__helper")}`);
93
- },
94
- setSupportingText(text, isError) {
95
- if (component.setSupportingText) {
96
- component.setSupportingText(text, isError);
97
- }
98
- return this;
99
- },
100
- removeSupportingText() {
101
- if (component.removeSupportingText) {
102
- component.removeSupportingText();
103
- }
104
- return this;
105
- },
106
- get prefixTextElement() {
107
- return component.prefixTextElement ?? null;
108
- },
109
- setPrefixText(text) {
110
- if (component.setPrefixText) {
111
- component.setPrefixText(text);
112
- if (component.updateElementPositions) {
113
- component.schedulePositionUpdate?.();
65
+ return this;
66
+ },
67
+ removeLeadingIcon() {
68
+ if (component.removeLeadingIcon) {
69
+ component.removeLeadingIcon();
70
+ if (component.updateElementPositions) {
71
+ component.schedulePositionUpdate?.();
72
+ }
114
73
  }
115
- }
116
- return this;
117
- },
118
- removePrefixText() {
119
- if (component.removePrefixText) {
120
- component.removePrefixText();
121
- if (component.updateElementPositions) {
122
- component.schedulePositionUpdate?.();
74
+ return this;
75
+ },
76
+ get trailingIcon() {
77
+ return component.trailingIcon ?? null;
78
+ },
79
+ setTrailingIcon(html, label) {
80
+ if (component.setTrailingIcon) {
81
+ component.setTrailingIcon(html, label);
82
+ if (component.updateElementPositions) {
83
+ component.schedulePositionUpdate?.();
84
+ }
123
85
  }
124
- }
125
- return this;
126
- },
127
- get suffixTextElement() {
128
- return component.suffixTextElement ?? null;
129
- },
130
- setSuffixText(text) {
131
- if (component.setSuffixText) {
132
- component.setSuffixText(text);
133
- if (component.updateElementPositions) {
134
- component.schedulePositionUpdate?.();
86
+ return this;
87
+ },
88
+ removeTrailingIcon() {
89
+ if (component.removeTrailingIcon) {
90
+ component.removeTrailingIcon();
91
+ if (component.updateElementPositions) {
92
+ component.schedulePositionUpdate?.();
93
+ }
94
+ }
95
+ return this;
96
+ },
97
+ get supportingTextElement() {
98
+ return component.element.querySelector(`.${component.getClass("textfield__helper")}`);
99
+ },
100
+ setSupportingText(text, isError) {
101
+ if (component.setSupportingText) {
102
+ component.setSupportingText(text, isError);
103
+ }
104
+ return this;
105
+ },
106
+ removeSupportingText() {
107
+ if (component.removeSupportingText) {
108
+ component.removeSupportingText();
109
+ }
110
+ return this;
111
+ },
112
+ get prefixTextElement() {
113
+ return component.prefixTextElement ?? null;
114
+ },
115
+ setPrefixText(text) {
116
+ if (component.setPrefixText) {
117
+ component.setPrefixText(text);
118
+ if (component.updateElementPositions) {
119
+ component.schedulePositionUpdate?.();
120
+ }
121
+ }
122
+ return this;
123
+ },
124
+ removePrefixText() {
125
+ if (component.removePrefixText) {
126
+ component.removePrefixText();
127
+ if (component.updateElementPositions) {
128
+ component.schedulePositionUpdate?.();
129
+ }
130
+ }
131
+ return this;
132
+ },
133
+ get suffixTextElement() {
134
+ return component.suffixTextElement ?? null;
135
+ },
136
+ setSuffixText(text) {
137
+ if (component.setSuffixText) {
138
+ component.setSuffixText(text);
139
+ if (component.updateElementPositions) {
140
+ component.schedulePositionUpdate?.();
141
+ }
142
+ }
143
+ return this;
144
+ },
145
+ removeSuffixText() {
146
+ if (component.removeSuffixText) {
147
+ component.removeSuffixText();
148
+ if (component.updateElementPositions) {
149
+ component.schedulePositionUpdate?.();
150
+ }
151
+ }
152
+ return this;
153
+ },
154
+ updatePositions() {
155
+ if (component.input && component.element) {
156
+ const hasValue = component.input.value && component.input.value.length > 0;
157
+ const isAutofilled = component.input.matches?.(":-webkit-autofill") || false;
158
+ if (hasValue || isAutofilled) {
159
+ component.element.classList.remove(`${component.config?.prefix || "mtrl"}-textfield--empty`);
160
+ }
161
+ else {
162
+ component.element.classList.add(`${component.config?.prefix || "mtrl"}-textfield--empty`);
163
+ }
135
164
  }
136
- }
137
- return this;
138
- },
139
- removeSuffixText() {
140
- if (component.removeSuffixText) {
141
- component.removeSuffixText();
142
165
  if (component.updateElementPositions) {
143
- component.schedulePositionUpdate?.();
166
+ component.updateElementPositions();
167
+ }
168
+ return this;
169
+ },
170
+ setError(error, message) {
171
+ if (component.setError) {
172
+ component.setError(error, message);
144
173
  }
145
- }
146
- return this;
147
- },
148
- updatePositions() {
149
- if (component.input && component.element) {
150
- const hasValue = component.input.value && component.input.value.length > 0;
151
- const isAutofilled = component.input.matches?.(":-webkit-autofill") || false;
152
- if (hasValue || isAutofilled) {
153
- component.element.classList.remove(`${component.config?.prefix || "mtrl"}-textfield--empty`);
154
- }
155
- else {
156
- component.element.classList.add(`${component.config?.prefix || "mtrl"}-textfield--empty`);
157
- }
158
- }
159
- if (component.updateElementPositions) {
160
- component.updateElementPositions();
161
- }
162
- return this;
163
- },
164
- setError(error, message) {
165
- if (component.setError) {
166
- component.setError(error, message);
167
- }
168
- return this;
169
- },
170
- isError() {
171
- return component.isError?.() || false;
172
- },
173
- setDensity(density) {
174
- if (component.density?.set) {
175
- component.density.set(density);
176
- }
177
- return this;
178
- },
179
- getDensity() {
180
- return component.density?.current || "default";
181
- },
182
- on(event, handler) {
183
- component.on?.(event, handler);
184
- return this;
185
- },
186
- off(event, handler) {
187
- component.off?.(event, handler);
188
- return this;
189
- },
190
- enable() {
191
- disabled.enable();
192
- return this;
193
- },
194
- disable() {
195
- disabled.disable();
196
- return this;
197
- },
198
- destroy() {
199
- lifecycle.destroy();
200
- },
201
- });
174
+ return this;
175
+ },
176
+ isError() {
177
+ return component.isError?.() || false;
178
+ },
179
+ setDensity(density) {
180
+ if (component.density?.set) {
181
+ component.density.set(density);
182
+ }
183
+ component.schedulePositionUpdate?.();
184
+ return this;
185
+ },
186
+ getDensity() {
187
+ return component.density?.current || "default";
188
+ },
189
+ on(event, handler) {
190
+ component.on?.(event, handler);
191
+ return this;
192
+ },
193
+ off(event, handler) {
194
+ component.off?.(event, handler);
195
+ return this;
196
+ },
197
+ enable() {
198
+ disabled.enable();
199
+ setTrailingDisabled(false);
200
+ return this;
201
+ },
202
+ isDisabled() {
203
+ return disabled.isDisabled();
204
+ },
205
+ disable() {
206
+ disabled.disable();
207
+ setTrailingDisabled(true);
208
+ return this;
209
+ },
210
+ setRequired(required) {
211
+ component.setRequired?.(required);
212
+ component.schedulePositionUpdate?.();
213
+ return this;
214
+ },
215
+ isRequired() {
216
+ return component.isRequired?.() ?? Boolean(component.input?.required);
217
+ },
218
+ destroy() {
219
+ lifecycle.destroy();
220
+ },
221
+ };
222
+ };