mtrl 0.2.6 → 0.2.8

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/demo/build.ts +349 -0
  2. package/demo/index.html +110 -0
  3. package/demo/main.js +448 -0
  4. package/demo/styles.css +239 -0
  5. package/index.ts +18 -0
  6. package/package.json +14 -3
  7. package/server.ts +86 -0
  8. package/src/components/badge/api.ts +70 -63
  9. package/src/components/badge/badge.ts +16 -2
  10. package/src/components/badge/config.ts +66 -13
  11. package/src/components/badge/features.ts +51 -42
  12. package/src/components/badge/index.ts +27 -2
  13. package/src/components/badge/types.ts +62 -30
  14. package/src/components/bottom-app-bar/bottom-app-bar.ts +154 -0
  15. package/src/components/bottom-app-bar/config.ts +29 -0
  16. package/src/components/bottom-app-bar/index.ts +17 -0
  17. package/src/components/bottom-app-bar/types.ts +114 -0
  18. package/src/components/button/api.ts +5 -0
  19. package/src/components/button/button.ts +0 -1
  20. package/src/components/button/config.ts +6 -2
  21. package/src/components/button/index.ts +10 -2
  22. package/src/components/button/types.ts +20 -2
  23. package/src/components/card/card.ts +13 -25
  24. package/src/components/card/config.ts +83 -30
  25. package/src/components/card/content.ts +8 -10
  26. package/src/components/card/features.ts +4 -3
  27. package/src/components/card/index.ts +29 -2
  28. package/src/components/card/types.ts +33 -22
  29. package/src/components/checkbox/config.ts +3 -4
  30. package/src/components/checkbox/index.ts +1 -2
  31. package/src/components/checkbox/types.ts +12 -3
  32. package/src/components/chip/api.ts +170 -221
  33. package/src/components/chip/chip.ts +34 -302
  34. package/src/components/chip/config.ts +1 -2
  35. package/src/components/chip/index.ts +10 -2
  36. package/src/components/chip/types.ts +224 -35
  37. package/src/components/datepicker/api.ts +265 -0
  38. package/src/components/datepicker/config.ts +141 -0
  39. package/src/components/datepicker/datepicker.ts +341 -0
  40. package/src/components/datepicker/index.ts +12 -0
  41. package/src/components/datepicker/render.ts +450 -0
  42. package/src/components/datepicker/types.ts +397 -0
  43. package/src/components/datepicker/utils.ts +289 -0
  44. package/src/components/dialog/api.ts +55 -21
  45. package/src/components/dialog/config.ts +12 -9
  46. package/src/components/dialog/dialog.ts +6 -3
  47. package/src/components/dialog/features.ts +345 -151
  48. package/src/components/dialog/index.ts +38 -8
  49. package/src/components/dialog/types.ts +40 -14
  50. package/src/components/divider/config.ts +81 -0
  51. package/src/components/divider/divider.ts +37 -0
  52. package/src/components/divider/features.ts +207 -0
  53. package/src/components/divider/index.ts +9 -0
  54. package/src/components/divider/types.ts +55 -0
  55. package/src/components/extended-fab/api.ts +141 -0
  56. package/src/components/extended-fab/config.ts +112 -0
  57. package/src/components/extended-fab/extended-fab.ts +125 -0
  58. package/src/components/extended-fab/index.ts +9 -0
  59. package/src/components/extended-fab/types.ts +304 -0
  60. package/src/components/fab/api.ts +97 -0
  61. package/src/components/fab/config.ts +93 -0
  62. package/src/components/fab/fab.ts +67 -0
  63. package/src/components/fab/index.ts +9 -0
  64. package/src/components/fab/types.ts +251 -0
  65. package/src/components/list/config.ts +4 -5
  66. package/src/components/list/features.ts +6 -7
  67. package/src/components/list/index.ts +7 -9
  68. package/src/components/list/list-item.ts +12 -13
  69. package/src/components/list/types.ts +50 -5
  70. package/src/components/list/utils.ts +30 -3
  71. package/src/components/menu/features/items-manager.ts +9 -9
  72. package/src/components/menu/features/positioning.ts +7 -7
  73. package/src/components/menu/features/visibility.ts +7 -7
  74. package/src/components/menu/index.ts +7 -9
  75. package/src/components/menu/menu-item.ts +6 -6
  76. package/src/components/menu/menu.ts +22 -0
  77. package/src/components/menu/types.ts +29 -10
  78. package/src/components/menu/utils.ts +67 -0
  79. package/src/components/navigation/api.ts +78 -50
  80. package/src/components/navigation/config.ts +22 -10
  81. package/src/components/navigation/features/items.ts +284 -0
  82. package/src/components/navigation/index.ts +0 -6
  83. package/src/components/navigation/nav-item.ts +70 -33
  84. package/src/components/navigation/navigation.ts +53 -3
  85. package/src/components/navigation/types.ts +117 -70
  86. package/src/components/progress/api.ts +2 -3
  87. package/src/components/progress/config.ts +2 -3
  88. package/src/components/progress/index.ts +0 -1
  89. package/src/components/progress/progress.ts +1 -2
  90. package/src/components/progress/types.ts +186 -33
  91. package/src/components/radios/config.ts +1 -1
  92. package/src/components/radios/index.ts +0 -1
  93. package/src/components/radios/types.ts +0 -7
  94. package/src/components/search/api.ts +203 -0
  95. package/src/components/search/config.ts +86 -0
  96. package/src/components/search/features/index.ts +4 -0
  97. package/src/components/search/features/search.ts +717 -0
  98. package/src/components/search/features/states.ts +169 -0
  99. package/src/components/search/features/structure.ts +197 -0
  100. package/src/components/search/index.ts +7 -0
  101. package/src/components/search/search.ts +52 -0
  102. package/src/components/search/types.ts +175 -0
  103. package/src/components/segmented-button/config.ts +80 -0
  104. package/src/components/segmented-button/index.ts +4 -0
  105. package/src/components/segmented-button/segment.ts +154 -0
  106. package/src/components/segmented-button/segmented-button.ts +249 -0
  107. package/src/components/segmented-button/types.ts +254 -0
  108. package/src/components/slider/accessibility.md +5 -5
  109. package/src/components/slider/api.ts +41 -120
  110. package/src/components/slider/config.ts +51 -47
  111. package/src/components/slider/features/handlers.ts +495 -0
  112. package/src/components/slider/features/index.ts +1 -2
  113. package/src/components/slider/features/slider.ts +66 -84
  114. package/src/components/slider/features/states.ts +195 -0
  115. package/src/components/slider/features/structure.ts +136 -206
  116. package/src/components/slider/features/ui.ts +145 -206
  117. package/src/components/slider/index.ts +2 -11
  118. package/src/components/slider/slider.ts +9 -12
  119. package/src/components/slider/types.ts +67 -26
  120. package/src/components/snackbar/config.ts +2 -3
  121. package/src/components/snackbar/constants.ts +0 -32
  122. package/src/components/snackbar/index.ts +0 -1
  123. package/src/components/snackbar/position.ts +9 -1
  124. package/src/components/snackbar/types.ts +122 -46
  125. package/src/components/switch/config.ts +2 -3
  126. package/src/components/switch/index.ts +0 -1
  127. package/src/components/switch/types.ts +3 -2
  128. package/src/components/tabs/config.ts +3 -4
  129. package/src/components/tabs/features.ts +4 -2
  130. package/src/components/tabs/index.ts +0 -15
  131. package/src/components/tabs/indicator.ts +73 -13
  132. package/src/components/tabs/tab-api.ts +12 -4
  133. package/src/components/tabs/tab.ts +18 -6
  134. package/src/components/tabs/types.ts +23 -5
  135. package/src/components/textfield/config.ts +2 -3
  136. package/src/components/textfield/index.ts +0 -1
  137. package/src/components/textfield/types.ts +17 -3
  138. package/src/components/timepicker/README.md +277 -0
  139. package/src/components/timepicker/api.ts +632 -0
  140. package/src/components/timepicker/clockdial.ts +482 -0
  141. package/src/components/timepicker/config.ts +228 -0
  142. package/src/components/timepicker/index.ts +3 -0
  143. package/src/components/timepicker/render.ts +613 -0
  144. package/src/components/timepicker/timepicker.ts +117 -0
  145. package/src/components/timepicker/types.ts +336 -0
  146. package/src/components/timepicker/utils.ts +241 -0
  147. package/src/components/tooltip/api.ts +1 -1
  148. package/src/components/tooltip/config.ts +27 -6
  149. package/src/components/tooltip/index.ts +0 -1
  150. package/src/components/tooltip/types.ts +13 -3
  151. package/src/components/top-app-bar/config.ts +83 -0
  152. package/src/components/top-app-bar/index.ts +11 -0
  153. package/src/components/top-app-bar/top-app-bar.ts +316 -0
  154. package/src/components/top-app-bar/types.ts +140 -0
  155. package/src/core/build/_ripple.scss +6 -6
  156. package/src/core/build/ripple.ts +72 -95
  157. package/src/core/compose/features/icon.ts +3 -1
  158. package/src/core/compose/features/ripple.ts +4 -1
  159. package/src/core/compose/features/textlabel.ts +23 -2
  160. package/src/core/dom/create.ts +5 -0
  161. package/src/index.ts +9 -0
  162. package/src/styles/abstract/_theme.scss +9 -1
  163. package/src/styles/components/_badge.scss +182 -0
  164. package/src/styles/components/_bottom-app-bar.scss +103 -0
  165. package/src/{components/button/_styles.scss → styles/components/_button.scss} +0 -10
  166. package/src/{components/checkbox/_styles.scss → styles/components/_checkbox.scss} +0 -2
  167. package/src/styles/components/_datepicker.scss +358 -0
  168. package/src/styles/components/_dialog.scss +259 -0
  169. package/src/styles/components/_divider.scss +57 -0
  170. package/src/styles/components/_extended-fab.scss +267 -0
  171. package/src/styles/components/_fab.scss +225 -0
  172. package/src/{components/navigation/_styles.scss → styles/components/_navigation.scss} +1 -0
  173. package/src/styles/components/_search.scss +306 -0
  174. package/src/styles/components/_segmented-button.scss +117 -0
  175. package/src/{components/slider/_styles.scss → styles/components/_slider.scss} +83 -24
  176. package/src/{components/switch/_styles.scss → styles/components/_switch.scss} +0 -2
  177. package/src/{components/tabs/_styles.scss → styles/components/_tabs.scss} +95 -33
  178. package/src/{components/textfield/_styles.scss → styles/components/_textfield.scss} +70 -67
  179. package/src/styles/components/_timepicker.scss +451 -0
  180. package/src/styles/components/_top-app-bar.scss +225 -0
  181. package/src/styles/main.scss +98 -49
  182. package/src/styles/themes/_autumn.scss +21 -0
  183. package/src/styles/themes/_base-theme.scss +61 -0
  184. package/src/styles/themes/_baseline.scss +58 -0
  185. package/src/styles/themes/_bluekhaki.scss +125 -0
  186. package/src/styles/themes/_brownbeige.scss +125 -0
  187. package/src/styles/themes/_browngreen.scss +125 -0
  188. package/src/styles/themes/_forest.scss +6 -0
  189. package/src/styles/themes/_greenbeige.scss +125 -0
  190. package/src/styles/themes/_material.scss +125 -0
  191. package/src/styles/themes/_ocean.scss +6 -0
  192. package/src/styles/themes/_sageivory.scss +125 -0
  193. package/src/styles/themes/_spring.scss +6 -0
  194. package/src/styles/themes/_summer.scss +5 -0
  195. package/src/styles/themes/_sunset.scss +5 -0
  196. package/src/styles/themes/_tealcaramel.scss +125 -0
  197. package/src/styles/themes/_winter.scss +6 -0
  198. package/src/components/badge/_styles.scss +0 -174
  199. package/src/components/badge/constants.ts +0 -30
  200. package/src/components/button/constants.ts +0 -11
  201. package/src/components/card/constants.ts +0 -84
  202. package/src/components/dialog/_styles.scss +0 -213
  203. package/src/components/dialog/constants.ts +0 -32
  204. package/src/components/menu/constants.ts +0 -154
  205. package/src/components/navigation/constants.ts +0 -200
  206. package/src/components/navigation/features/items.js +0 -192
  207. package/src/components/progress/constants.ts +0 -29
  208. package/src/components/slider/features/appearance.ts +0 -94
  209. package/src/components/slider/features/disabled.ts +0 -68
  210. package/src/components/slider/features/events.ts +0 -164
  211. package/src/components/slider/features/interactions.ts +0 -396
  212. package/src/components/slider/features/keyboard.ts +0 -233
  213. package/src/components/switch/constants.ts +0 -80
  214. package/src/components/tabs/constants.ts +0 -89
  215. package/src/core/collection/adapters/mongodb.js +0 -232
  216. /package/src/{components/card/_styles.scss → styles/components/_card.scss} +0 -0
  217. /package/src/{components/carousel/_styles.scss → styles/components/_carousel.scss} +0 -0
  218. /package/src/{components/chip/_styles.scss → styles/components/_chip.scss} +0 -0
  219. /package/src/{components/list/_styles.scss → styles/components/_list.scss} +0 -0
  220. /package/src/{components/menu/_styles.scss → styles/components/_menu.scss} +0 -0
  221. /package/src/{components/progress/_styles.scss → styles/components/_progress.scss} +0 -0
  222. /package/src/{components/radios/_styles.scss → styles/components/_radios.scss} +0 -0
  223. /package/src/{components/sheet/_styles.scss → styles/components/_sheet.scss} +0 -0
  224. /package/src/{components/snackbar/_styles.scss → styles/components/_snackbar.scss} +0 -0
  225. /package/src/{components/tooltip/_styles.scss → styles/components/_tooltip.scss} +0 -0
  226. /package/src/styles/utilities/{_color.scss → _colors.scss} +0 -0
@@ -0,0 +1,112 @@
1
+ // src/components/extended-fab/config.ts
2
+ import {
3
+ createComponentConfig,
4
+ createElementConfig,
5
+ BaseComponentConfig
6
+ } from '../../core/config/component-config';
7
+ import { ExtendedFabConfig } from './types';
8
+
9
+ /**
10
+ * Default configuration for the Extended FAB component
11
+ */
12
+ export const defaultConfig: ExtendedFabConfig = {
13
+ variant: 'primary',
14
+ type: 'button',
15
+ ripple: true,
16
+ iconPosition: 'start',
17
+ width: 'fixed'
18
+ };
19
+
20
+ /**
21
+ * Creates the base configuration for Extended FAB component
22
+ * @param {ExtendedFabConfig} config - User provided configuration
23
+ * @returns {ExtendedFabConfig} Complete configuration with defaults applied
24
+ */
25
+ export const createBaseConfig = (config: ExtendedFabConfig = {}): ExtendedFabConfig =>
26
+ createComponentConfig(defaultConfig, config, 'extended-fab') as ExtendedFabConfig;
27
+
28
+ /**
29
+ * Generates element configuration for the Extended FAB component
30
+ * @param {ExtendedFabConfig} config - Extended FAB configuration
31
+ * @returns {Object} Element configuration object for withElement
32
+ */
33
+ export const getElementConfig = (config: ExtendedFabConfig) => {
34
+ // Create the attributes object
35
+ const attrs: Record<string, any> = {
36
+ type: config.type || 'button',
37
+ 'aria-label': config.ariaLabel || config.text || (config.icon ? 'action' : undefined)
38
+ };
39
+
40
+ // Build class list
41
+ let classNames = [`${config.prefix}-extended-fab`];
42
+
43
+ // Add variant class
44
+ if (config.variant) {
45
+ classNames.push(`${config.prefix}-extended-fab--${config.variant}`);
46
+ }
47
+
48
+ // Add width class
49
+ if (config.width) {
50
+ classNames.push(`${config.prefix}-extended-fab--${config.width}`);
51
+ }
52
+
53
+ // Add animation class if specified
54
+ if (config.animate) {
55
+ classNames.push(`${config.prefix}-extended-fab--animate-enter`);
56
+ }
57
+
58
+ // Add position class if specified
59
+ if (config.position) {
60
+ classNames.push(`${config.prefix}-extended-fab--${config.position}`);
61
+ }
62
+
63
+ // Add collapse-on-scroll class if specified
64
+ if (config.collapseOnScroll) {
65
+ classNames.push(`${config.prefix}-extended-fab--collapsible`);
66
+ }
67
+
68
+ // Add user classes
69
+ if (config.class) {
70
+ classNames.push(config.class);
71
+ }
72
+
73
+ // Only add disabled attribute if it's explicitly true
74
+ if (config.disabled === true) {
75
+ attrs.disabled = true;
76
+ classNames.push(`${config.prefix}-extended-fab--disabled`);
77
+ }
78
+
79
+ return createElementConfig(config, {
80
+ tag: 'button',
81
+ attrs,
82
+ className: classNames,
83
+ forwardEvents: {
84
+ click: (component) => !component.element.disabled,
85
+ focus: true,
86
+ blur: true
87
+ },
88
+ interactive: true
89
+ });
90
+ };
91
+
92
+ /**
93
+ * Creates API configuration for the Extended FAB component
94
+ * @param {Object} comp - Component with disabled and lifecycle features
95
+ * @returns {Object} API configuration object
96
+ */
97
+ export const getApiConfig = (comp: any) => ({
98
+ disabled: {
99
+ enable: () => comp.disabled.enable(),
100
+ disable: () => comp.disabled.disable()
101
+ },
102
+ lifecycle: {
103
+ destroy: () => comp.lifecycle.destroy()
104
+ },
105
+ className: comp.getClass('extended-fab'),
106
+ text: {
107
+ setText: (text: string) => comp.text.setText(text),
108
+ getText: () => comp.text.getText()
109
+ }
110
+ });
111
+
112
+ export default defaultConfig;
@@ -0,0 +1,125 @@
1
+ // src/components/extended-fab/extended-fab.ts
2
+ import { pipe } from '../../core/compose';
3
+ import { createBase, withElement } from '../../core/compose/component';
4
+ import {
5
+ withEvents,
6
+ withIcon,
7
+ withVariant,
8
+ withRipple,
9
+ withDisabled,
10
+ withLifecycle,
11
+ withText
12
+ } from '../../core/compose/features';
13
+ import { withAPI } from './api';
14
+ import { ExtendedFabConfig, ExtendedFabComponent } from './types';
15
+ import { createBaseConfig, getElementConfig, getApiConfig } from './config';
16
+
17
+ /**
18
+ * Creates a new Extended Floating Action Button (Extended FAB) component
19
+ *
20
+ * @param {ExtendedFabConfig} config - Extended FAB configuration object
21
+ * @returns {ExtendedFabComponent} Extended FAB component instance
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * // Create a basic Extended FAB with icon and text
26
+ * const extendedFab = createExtendedFab({
27
+ * icon: '<svg>...</svg>',
28
+ * text: 'Create',
29
+ * ariaLabel: 'Create new item'
30
+ * });
31
+ *
32
+ * // Create a tertiary Extended FAB with a custom position
33
+ * const customExtendedFab = createExtendedFab({
34
+ * text: 'Add to cart',
35
+ * icon: '<svg>...</svg>',
36
+ * variant: 'tertiary',
37
+ * position: 'bottom-right',
38
+ * collapseOnScroll: true
39
+ * });
40
+ *
41
+ * // Add click handler
42
+ * extendedFab.on('click', () => {
43
+ * console.log('Extended FAB clicked');
44
+ * });
45
+ * ```
46
+ */
47
+ const createExtendedFab = (config: ExtendedFabConfig = {}): ExtendedFabComponent => {
48
+ const fabConfig = createBaseConfig(config);
49
+
50
+ // Set up scroll collapse handler if needed
51
+ const setupScrollCollapse = (component: ExtendedFabComponent): void => {
52
+ if (fabConfig.collapseOnScroll) {
53
+ let lastScrollY = window.scrollY;
54
+ let ticking = false;
55
+ const scrollThreshold = 10; // Minimum scroll amount to trigger collapse/expand
56
+
57
+ const handleScroll = () => {
58
+ if (!ticking) {
59
+ window.requestAnimationFrame(() => {
60
+ const currentScrollY = window.scrollY;
61
+ const scrollDelta = currentScrollY - lastScrollY;
62
+
63
+ // If scrolling down beyond threshold, collapse
64
+ if (scrollDelta > scrollThreshold) {
65
+ component.collapse();
66
+ }
67
+ // If scrolling up beyond threshold, expand
68
+ else if (scrollDelta < -scrollThreshold) {
69
+ component.expand();
70
+ }
71
+ // If at the top of the page, ensure expanded
72
+ if (currentScrollY <= 0) {
73
+ component.expand();
74
+ }
75
+
76
+ lastScrollY = currentScrollY;
77
+ ticking = false;
78
+ });
79
+
80
+ ticking = true;
81
+ }
82
+ };
83
+
84
+ // Add scroll listener
85
+ window.addEventListener('scroll', handleScroll, { passive: true });
86
+
87
+ // Ensure it's expanded by default
88
+ requestAnimationFrame(() => {
89
+ component.expand();
90
+ });
91
+
92
+ // Clean up on destroy
93
+ const originalDestroy = component.destroy;
94
+ component.destroy = () => {
95
+ window.removeEventListener('scroll', handleScroll);
96
+ originalDestroy.call(component);
97
+ };
98
+ }
99
+ };
100
+
101
+ try {
102
+ const extendedFab = pipe(
103
+ createBase,
104
+ withEvents(),
105
+ withElement(getElementConfig(fabConfig)),
106
+ withVariant(fabConfig),
107
+ withIcon(fabConfig),
108
+ withText(fabConfig),
109
+ withDisabled(fabConfig),
110
+ withRipple(fabConfig),
111
+ withLifecycle(),
112
+ comp => withAPI(getApiConfig(comp))(comp)
113
+ )(fabConfig);
114
+
115
+ // Set up scroll collapse after component is created
116
+ setupScrollCollapse(extendedFab);
117
+
118
+ return extendedFab;
119
+ } catch (error) {
120
+ console.error('Extended FAB creation error:', error);
121
+ throw new Error(`Failed to create Extended FAB: ${(error as Error).message}`);
122
+ }
123
+ };
124
+
125
+ export default createExtendedFab;
@@ -0,0 +1,9 @@
1
+ // src/components/extended-fab/index.ts
2
+ export { default, default as createExtendedFab } from './extended-fab';
3
+ export {
4
+ ExtendedFabConfig,
5
+ ExtendedFabComponent,
6
+ ExtendedFabVariant,
7
+ ExtendedFabWidth,
8
+ ExtendedFabPosition
9
+ } from './types';
@@ -0,0 +1,304 @@
1
+ // src/components/extended-fab/types.ts
2
+
3
+ /**
4
+ * Extended FAB variants
5
+ * @category Components
6
+ */
7
+ export type ExtendedFabVariant = 'primary' | 'secondary' | 'tertiary' | 'surface';
8
+
9
+ /**
10
+ * Extended FAB width behavior
11
+ * @category Components
12
+ */
13
+ export type ExtendedFabWidth = 'fixed' | 'fluid';
14
+
15
+ /**
16
+ * Extended FAB position
17
+ * @category Components
18
+ */
19
+ export type ExtendedFabPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
20
+
21
+ /**
22
+ * Configuration interface for the Extended FAB component
23
+ * @category Components
24
+ */
25
+ export interface ExtendedFabConfig {
26
+ /**
27
+ * Extended FAB variant that determines visual styling
28
+ * @default 'primary'
29
+ */
30
+ variant?: ExtendedFabVariant | string;
31
+
32
+ /**
33
+ * Whether the Extended FAB is initially disabled
34
+ * @default false
35
+ */
36
+ disabled?: boolean;
37
+
38
+ /**
39
+ * Extended FAB icon HTML content
40
+ * @example '<svg>...</svg>'
41
+ */
42
+ icon?: string;
43
+
44
+ /**
45
+ * Icon size in pixels or other CSS units
46
+ * @example '24px'
47
+ */
48
+ iconSize?: string;
49
+
50
+ /**
51
+ * Position of the icon relative to the text
52
+ * @default 'start'
53
+ */
54
+ iconPosition?: 'start' | 'end';
55
+
56
+ /**
57
+ * Text label for the Extended FAB
58
+ * @example 'Create'
59
+ */
60
+ text?: string;
61
+
62
+ /**
63
+ * Additional CSS classes to add to the Extended FAB
64
+ * @example 'home-fab bottom-right'
65
+ */
66
+ class?: string;
67
+
68
+ /**
69
+ * Button value attribute
70
+ */
71
+ value?: string;
72
+
73
+ /**
74
+ * Position of the Extended FAB on the screen
75
+ * @example 'bottom-right'
76
+ */
77
+ position?: ExtendedFabPosition | string;
78
+
79
+ /**
80
+ * Button type attribute
81
+ * @default 'button'
82
+ */
83
+ type?: 'button' | 'submit' | 'reset';
84
+
85
+ /**
86
+ * Accessible label for screen readers
87
+ */
88
+ ariaLabel?: string;
89
+
90
+ /**
91
+ * Whether to enable ripple effect
92
+ * @default true
93
+ */
94
+ ripple?: boolean;
95
+
96
+ /**
97
+ * Component prefix for class names
98
+ * @default 'mtrl'
99
+ */
100
+ prefix?: string;
101
+
102
+ /**
103
+ * Component name used in class generation
104
+ */
105
+ componentName?: string;
106
+
107
+ /**
108
+ * Ripple effect configuration
109
+ */
110
+ rippleConfig?: {
111
+ /** Duration of the ripple animation in milliseconds */
112
+ duration?: number;
113
+ /** Timing function for the ripple animation */
114
+ timing?: string;
115
+ /** Opacity values for ripple start and end [start, end] */
116
+ opacity?: [string, string];
117
+ };
118
+
119
+ /**
120
+ * Whether to show the Extended FAB with an entrance animation
121
+ * @default false
122
+ */
123
+ animate?: boolean;
124
+
125
+ /**
126
+ * Width behavior of the Extended FAB
127
+ * @default 'fixed'
128
+ */
129
+ width?: ExtendedFabWidth | string;
130
+
131
+ /**
132
+ * Whether the Extended FAB should collapse to a standard FAB on scroll
133
+ * @default false
134
+ */
135
+ collapseOnScroll?: boolean;
136
+ }
137
+
138
+ /**
139
+ * Extended FAB component interface
140
+ * @category Components
141
+ */
142
+ export interface ExtendedFabComponent {
143
+ /** The Extended FAB's DOM element */
144
+ element: HTMLButtonElement;
145
+
146
+ /** API for managing Extended FAB icons */
147
+ icon: {
148
+ /** Sets the icon HTML content */
149
+ setIcon: (html: string) => any;
150
+ /** Gets the current icon HTML content */
151
+ getIcon: () => string;
152
+ /** Gets the icon DOM element */
153
+ getElement: () => HTMLElement | null;
154
+ };
155
+
156
+ /** API for managing text content */
157
+ text: {
158
+ /** Sets the text content */
159
+ setText: (text: string) => any;
160
+ /** Gets the current text content */
161
+ getText: () => string;
162
+ /** Gets the text DOM element */
163
+ getElement: () => HTMLElement | null;
164
+ };
165
+
166
+ /** API for managing disabled state */
167
+ disabled: {
168
+ /** Enables the Extended FAB */
169
+ enable: () => void;
170
+ /** Disables the Extended FAB */
171
+ disable: () => void;
172
+ /** Checks if the Extended FAB is disabled */
173
+ isDisabled: () => boolean;
174
+ };
175
+
176
+ /** API for managing component lifecycle */
177
+ lifecycle: {
178
+ /** Destroys the component and cleans up resources */
179
+ destroy: () => void;
180
+ };
181
+
182
+ /**
183
+ * Gets a class name with the component's prefix
184
+ * @param name - Base class name
185
+ * @returns Prefixed class name
186
+ */
187
+ getClass: (name: string) => string;
188
+
189
+ /**
190
+ * Gets the Extended FAB's value attribute
191
+ * @returns Extended FAB value
192
+ */
193
+ getValue: () => string;
194
+
195
+ /**
196
+ * Sets the Extended FAB's value attribute
197
+ * @param value - New value
198
+ * @returns The Extended FAB component for chaining
199
+ */
200
+ setValue: (value: string) => ExtendedFabComponent;
201
+
202
+ /**
203
+ * Enables the Extended FAB (removes disabled attribute)
204
+ * @returns The Extended FAB component for chaining
205
+ */
206
+ enable: () => ExtendedFabComponent;
207
+
208
+ /**
209
+ * Disables the Extended FAB (adds disabled attribute)
210
+ * @returns The Extended FAB component for chaining
211
+ */
212
+ disable: () => ExtendedFabComponent;
213
+
214
+ /**
215
+ * Sets the Extended FAB's icon
216
+ * @param icon - Icon HTML content
217
+ * @returns The Extended FAB component for chaining
218
+ */
219
+ setIcon: (icon: string) => ExtendedFabComponent;
220
+
221
+ /**
222
+ * Gets the Extended FAB's icon HTML content
223
+ * @returns Icon HTML
224
+ */
225
+ getIcon: () => string;
226
+
227
+ /**
228
+ * Sets the Extended FAB's text content
229
+ * @param text - Text content
230
+ * @returns The Extended FAB component for chaining
231
+ */
232
+ setText: (text: string) => ExtendedFabComponent;
233
+
234
+ /**
235
+ * Gets the Extended FAB's text content
236
+ * @returns Text content
237
+ */
238
+ getText: () => string;
239
+
240
+ /**
241
+ * Sets the Extended FAB's position
242
+ * @param position - Position value ('top-right', 'bottom-left', etc.)
243
+ * @returns The Extended FAB component for chaining
244
+ */
245
+ setPosition: (position: string) => ExtendedFabComponent;
246
+
247
+ /**
248
+ * Gets the current position of the Extended FAB
249
+ * @returns Current position
250
+ */
251
+ getPosition: () => string | null;
252
+
253
+ /**
254
+ * Lowers the Extended FAB (useful for pressed state)
255
+ * @returns The Extended FAB component for chaining
256
+ */
257
+ lower: () => ExtendedFabComponent;
258
+
259
+ /**
260
+ * Raises the Extended FAB back to its default elevation
261
+ * @returns The Extended FAB component for chaining
262
+ */
263
+ raise: () => ExtendedFabComponent;
264
+
265
+ /**
266
+ * Collapses the Extended FAB into a standard FAB
267
+ * @returns The Extended FAB component for chaining
268
+ */
269
+ collapse: () => ExtendedFabComponent;
270
+
271
+ /**
272
+ * Expands a collapsed Extended FAB back to its full size
273
+ * @returns The Extended FAB component for chaining
274
+ */
275
+ expand: () => ExtendedFabComponent;
276
+
277
+ /**
278
+ * Destroys the Extended FAB component and cleans up resources
279
+ */
280
+ destroy: () => void;
281
+
282
+ /**
283
+ * Adds an event listener to the Extended FAB
284
+ * @param event - Event name ('click', 'focus', etc.)
285
+ * @param handler - Event handler function
286
+ * @returns The Extended FAB component for chaining
287
+ */
288
+ on: (event: string, handler: Function) => ExtendedFabComponent;
289
+
290
+ /**
291
+ * Removes an event listener from the Extended FAB
292
+ * @param event - Event name
293
+ * @param handler - Event handler function
294
+ * @returns The Extended FAB component for chaining
295
+ */
296
+ off: (event: string, handler: Function) => ExtendedFabComponent;
297
+
298
+ /**
299
+ * Adds CSS classes to the Extended FAB element
300
+ * @param classes - One or more class names to add
301
+ * @returns The Extended FAB component for chaining
302
+ */
303
+ addClass: (...classes: string[]) => ExtendedFabComponent;
304
+ }
@@ -0,0 +1,97 @@
1
+ // src/components/fab/api.ts
2
+ import { FabComponent } from './types';
3
+
4
+ interface ApiOptions {
5
+ disabled: {
6
+ enable: () => void;
7
+ disable: () => void;
8
+ };
9
+ lifecycle: {
10
+ destroy: () => void;
11
+ };
12
+ className: string;
13
+ }
14
+
15
+ interface ComponentWithElements {
16
+ element: HTMLElement;
17
+ icon: {
18
+ setIcon: (html: string) => any;
19
+ getIcon: () => string;
20
+ getElement: () => HTMLElement | null;
21
+ };
22
+ getClass: (name: string) => string;
23
+ }
24
+
25
+ /**
26
+ * Enhances a FAB component with API methods
27
+ * @param {ApiOptions} options - API configuration options
28
+ * @returns {Function} Higher-order function that adds API methods to component
29
+ * @internal This is an internal utility for the FAB component
30
+ */
31
+ export const withAPI = ({ disabled, lifecycle, className }: ApiOptions) =>
32
+ (component: ComponentWithElements): FabComponent => ({
33
+ ...component as any,
34
+ element: component.element as HTMLButtonElement,
35
+
36
+ getValue: () => component.element.value,
37
+
38
+ setValue(value: string) {
39
+ component.element.value = value;
40
+ return this;
41
+ },
42
+
43
+ enable() {
44
+ disabled.enable();
45
+ return this;
46
+ },
47
+
48
+ disable() {
49
+ disabled.disable();
50
+ return this;
51
+ },
52
+
53
+ setIcon(icon: string) {
54
+ component.icon.setIcon(icon);
55
+ return this;
56
+ },
57
+
58
+ getIcon() {
59
+ return component.icon.getIcon();
60
+ },
61
+
62
+ setPosition(position: string) {
63
+ // First remove any existing position classes
64
+ const positions = ['top-right', 'top-left', 'bottom-right', 'bottom-left'];
65
+ positions.forEach(pos => {
66
+ component.element.classList.remove(`${className}--${pos}`);
67
+ });
68
+
69
+ // Add new position class
70
+ component.element.classList.add(`${className}--${position}`);
71
+ return this;
72
+ },
73
+
74
+ getPosition() {
75
+ const positions = ['top-right', 'top-left', 'bottom-right', 'bottom-left'];
76
+ for (const pos of positions) {
77
+ if (component.element.classList.contains(`${className}--${pos}`)) {
78
+ return pos;
79
+ }
80
+ }
81
+ return null;
82
+ },
83
+
84
+ lower() {
85
+ component.element.classList.add(`${className}--lowered`);
86
+ return this;
87
+ },
88
+
89
+ raise() {
90
+ component.element.classList.remove(`${className}--lowered`);
91
+ return this;
92
+ },
93
+
94
+ destroy() {
95
+ lifecycle.destroy();
96
+ }
97
+ });