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
@@ -1,15 +1,45 @@
1
1
  // src/components/dialog/index.ts
2
2
  export { default } from './dialog';
3
- export {
4
- DIALOG_SIZES,
5
- DIALOG_ANIMATIONS,
6
- DIALOG_FOOTER_ALIGNMENTS,
7
- DIALOG_EVENTS
8
- } from './constants';
9
3
  export {
10
4
  DialogConfig,
11
5
  DialogComponent,
12
6
  DialogButton,
13
7
  DialogEvent,
14
- DialogConfirmOptions
15
- } from './types';
8
+ DialogConfirmOptions,
9
+ DialogSize,
10
+ DialogAnimation,
11
+ DialogFooterAlignment,
12
+ DialogEventType
13
+ } from './types';
14
+
15
+ // Export common dialog constants for convenience and backward compatibility
16
+ export const DIALOG_SIZES = {
17
+ SMALL: 'small',
18
+ MEDIUM: 'medium',
19
+ LARGE: 'large',
20
+ FULLWIDTH: 'fullwidth',
21
+ FULLSCREEN: 'fullscreen'
22
+ } as const;
23
+
24
+ export const DIALOG_ANIMATIONS = {
25
+ SCALE: 'scale',
26
+ SLIDE_UP: 'slide-up',
27
+ SLIDE_DOWN: 'slide-down',
28
+ FADE: 'fade'
29
+ } as const;
30
+
31
+ export const DIALOG_FOOTER_ALIGNMENTS = {
32
+ RIGHT: 'right',
33
+ LEFT: 'left',
34
+ CENTER: 'center',
35
+ SPACE_BETWEEN: 'space-between'
36
+ } as const;
37
+
38
+ export const DIALOG_EVENTS = {
39
+ OPEN: 'open',
40
+ CLOSE: 'close',
41
+ BEFORE_OPEN: 'beforeopen',
42
+ BEFORE_CLOSE: 'beforeclose',
43
+ AFTER_OPEN: 'afteropen',
44
+ AFTER_CLOSE: 'afterclose'
45
+ } as const;
@@ -1,5 +1,28 @@
1
1
  // src/components/dialog/types.ts
2
- import { DIALOG_SIZES, DIALOG_ANIMATIONS, DIALOG_FOOTER_ALIGNMENTS, DIALOG_EVENTS } from './constants';
2
+
3
+ /**
4
+ * Dialog size types
5
+ * @category Components
6
+ */
7
+ export type DialogSize = 'small' | 'medium' | 'large' | 'fullwidth' | 'fullscreen';
8
+
9
+ /**
10
+ * Dialog animation types
11
+ * @category Components
12
+ */
13
+ export type DialogAnimation = 'scale' | 'slide-up' | 'slide-down' | 'fade';
14
+
15
+ /**
16
+ * Dialog footer alignment types
17
+ * @category Components
18
+ */
19
+ export type DialogFooterAlignment = 'right' | 'left' | 'center' | 'space-between';
20
+
21
+ /**
22
+ * Dialog event types
23
+ * @category Components
24
+ */
25
+ export type DialogEventType = 'open' | 'close' | 'beforeopen' | 'beforeclose' | 'afteropen' | 'afterclose';
3
26
 
4
27
  /**
5
28
  * Configuration interface for the Dialog component
@@ -21,13 +44,13 @@ export interface DialogConfig {
21
44
  class?: string;
22
45
 
23
46
  /** Dialog size variant */
24
- size?: keyof typeof DIALOG_SIZES | DIALOG_SIZES;
47
+ size?: DialogSize | string;
25
48
 
26
49
  /** Dialog animation variant */
27
- animation?: keyof typeof DIALOG_ANIMATIONS | DIALOG_ANIMATIONS;
50
+ animation?: DialogAnimation | string;
28
51
 
29
52
  /** Footer buttons alignment */
30
- footerAlignment?: keyof typeof DIALOG_FOOTER_ALIGNMENTS | DIALOG_FOOTER_ALIGNMENTS;
53
+ footerAlignment?: DialogFooterAlignment | string;
31
54
 
32
55
  /** Whether dialog is initially open */
33
56
  open?: boolean;
@@ -54,10 +77,7 @@ export interface DialogConfig {
54
77
  buttons?: DialogButton[];
55
78
 
56
79
  /** Whether to show a divider between header and content */
57
- headerDivider?: boolean;
58
-
59
- /** Whether to show a divider between content and footer */
60
- footerDivider?: boolean;
80
+ divider?: boolean;
61
81
 
62
82
  /** Dialog z-index (defaults to 1000) */
63
83
  zIndex?: number;
@@ -67,7 +87,7 @@ export interface DialogConfig {
67
87
 
68
88
  /** Event handlers for dialog events */
69
89
  on?: {
70
- [key in keyof typeof DIALOG_EVENTS]?: (event: DialogEvent) => void;
90
+ [key in DialogEventType]?: (event: DialogEvent) => void;
71
91
  };
72
92
  }
73
93
 
@@ -167,16 +187,16 @@ export interface DialogComponent {
167
187
  getButtons: () => DialogButton[];
168
188
 
169
189
  /** Sets footer alignment */
170
- setFooterAlignment: (alignment: keyof typeof DIALOG_FOOTER_ALIGNMENTS | DIALOG_FOOTER_ALIGNMENTS) => DialogComponent;
190
+ setFooterAlignment: (alignment: DialogFooterAlignment | string) => DialogComponent;
171
191
 
172
192
  /** Sets dialog size */
173
- setSize: (size: keyof typeof DIALOG_SIZES | DIALOG_SIZES) => DialogComponent;
193
+ setSize: (size: DialogSize | string) => DialogComponent;
174
194
 
175
195
  /** Adds event listener */
176
- on: (event: keyof typeof DIALOG_EVENTS | DIALOG_EVENTS, handler: (event: DialogEvent) => void) => DialogComponent;
196
+ on: (event: DialogEventType | string, handler: (event: DialogEvent) => void) => DialogComponent;
177
197
 
178
198
  /** Removes event listener */
179
- off: (event: keyof typeof DIALOG_EVENTS | DIALOG_EVENTS, handler: (event: DialogEvent) => void) => DialogComponent;
199
+ off: (event: DialogEventType | string, handler: (event: DialogEvent) => void) => DialogComponent;
180
200
 
181
201
  /** Gets dialog header element */
182
202
  getHeaderElement: () => HTMLElement | null;
@@ -187,6 +207,12 @@ export interface DialogComponent {
187
207
  /** Gets dialog footer element */
188
208
  getFooterElement: () => HTMLElement | null;
189
209
 
210
+ /** Shows or hides the divider */
211
+ toggleDivider: (show: boolean) => DialogComponent;
212
+
213
+ /** Checks if the dialog has a divider */
214
+ hasDivider: () => boolean;
215
+
190
216
  /** Creates a confirmation dialog with Yes/No buttons */
191
217
  confirm: (options?: DialogConfirmOptions) => Promise<boolean>;
192
218
 
@@ -217,5 +243,5 @@ export interface DialogConfirmOptions {
217
243
  cancelVariant?: string;
218
244
 
219
245
  /** Dialog size */
220
- size?: keyof typeof DIALOG_SIZES | DIALOG_SIZES;
246
+ size?: DialogSize | string;
221
247
  }
@@ -0,0 +1,81 @@
1
+ // src/components/divider/config.ts
2
+ import { createComponentConfig } from '../../core/config/component-config';
3
+
4
+ /**
5
+ * Configuration options for divider components
6
+ */
7
+ export interface DividerConfig {
8
+ /**
9
+ * CSS class prefix (defaults to 'mtrl')
10
+ */
11
+ prefix?: string;
12
+
13
+ /**
14
+ * CSS class to add to the divider
15
+ */
16
+ class?: string;
17
+
18
+ /**
19
+ * Orientation of the divider ('horizontal' or 'vertical')
20
+ * @default 'horizontal'
21
+ */
22
+ orientation?: 'horizontal' | 'vertical';
23
+
24
+ /**
25
+ * Variant of the divider ('full-width' or 'inset')
26
+ * @default 'full-width'
27
+ */
28
+ variant?: 'full-width' | 'inset' | 'middle-inset';
29
+
30
+ /**
31
+ * Custom inset value (left margin for horizontal, top margin for vertical)
32
+ * @default 16 for 'inset', undefined for 'full-width'
33
+ */
34
+ insetStart?: number;
35
+
36
+ /**
37
+ * Custom inset end value (right margin for horizontal, bottom margin for vertical)
38
+ * @default 0 for 'inset', undefined for 'full-width'
39
+ */
40
+ insetEnd?: number;
41
+
42
+ /**
43
+ * Color of the divider (uses 'outline-variant' from theme by default)
44
+ */
45
+ color?: string;
46
+
47
+ /**
48
+ * Thickness of the divider in pixels
49
+ * @default 1
50
+ */
51
+ thickness?: number;
52
+
53
+ /**
54
+ * Used internally for component composition
55
+ * @private
56
+ */
57
+ componentName?: string;
58
+ }
59
+
60
+ /**
61
+ * Default configuration for dividers
62
+ */
63
+ export const defaultConfig: Partial<DividerConfig> = {
64
+ orientation: 'horizontal',
65
+ variant: 'full-width',
66
+ thickness: 1
67
+ };
68
+
69
+ /**
70
+ * Creates a base configuration object for divider
71
+ *
72
+ * @param config - User provided configuration
73
+ * @returns Complete configuration with defaults applied
74
+ */
75
+ export const createBaseConfig = (config: DividerConfig = {}): DividerConfig => {
76
+ return createComponentConfig(
77
+ defaultConfig as DividerConfig,
78
+ config,
79
+ 'divider'
80
+ );
81
+ };
@@ -0,0 +1,37 @@
1
+ // src/components/divider/divider.ts
2
+ import {
3
+ createBase,
4
+ withElement,
5
+ pipe,
6
+ withVariant
7
+ } from '../../core/compose';
8
+ import { PREFIX } from '../../core/config';
9
+ import { DividerConfig, createBaseConfig } from './config';
10
+ import { withOrientation, withInset, withStyle } from './features';
11
+ import { DividerComponent } from './types';
12
+
13
+ /**
14
+ * Creates a divider component
15
+ *
16
+ * @param config - Divider configuration options
17
+ * @returns Divider component instance
18
+ */
19
+ export const createDivider = (config: DividerConfig = {}): DividerComponent => {
20
+ // Process configuration
21
+ const processedConfig = createBaseConfig(config);
22
+
23
+ // Create component through composition
24
+ return pipe(
25
+ createBase,
26
+ withElement({
27
+ tag: 'hr',
28
+ componentName: 'divider',
29
+ prefix: processedConfig.prefix || PREFIX,
30
+ className: config.class
31
+ }),
32
+ withOrientation(processedConfig),
33
+ withVariant(processedConfig),
34
+ withInset(processedConfig),
35
+ withStyle(processedConfig)
36
+ )(processedConfig) as DividerComponent;
37
+ };
@@ -0,0 +1,207 @@
1
+ // src/components/divider/features.ts
2
+ import { BaseComponent, ElementComponent } from '../../core/compose';
3
+ import { DividerConfig } from './config';
4
+ import { DividerComponent } from './types';
5
+
6
+ /**
7
+ * Adds orientation functionality to divider
8
+ *
9
+ * @param config - Divider configuration
10
+ * @returns Function that enhances a component with orientation capabilities
11
+ */
12
+ export const withOrientation = (config: DividerConfig) =>
13
+ <C extends ElementComponent & BaseComponent>(component: C): C & Partial<DividerComponent> => {
14
+ const orientation = config.orientation || 'horizontal';
15
+
16
+ // Apply the orientation class
17
+ component.element.classList.add(`${component.getClass('divider')}--${orientation}`);
18
+
19
+ // Set styles based on orientation and thickness
20
+ const thickness = config.thickness || 1;
21
+
22
+ if (orientation === 'horizontal') {
23
+ component.element.style.height = `${thickness}px`;
24
+ component.element.style.width = '100%';
25
+ } else {
26
+ component.element.style.width = `${thickness}px`;
27
+ component.element.style.height = '100%';
28
+ }
29
+
30
+ return {
31
+ ...component,
32
+
33
+ getOrientation() {
34
+ return orientation;
35
+ },
36
+
37
+ setOrientation(newOrientation: 'horizontal' | 'vertical') {
38
+ // Remove existing orientation class
39
+ component.element.classList.remove(`${component.getClass('divider')}--${orientation}`);
40
+
41
+ // Add new orientation class
42
+ component.element.classList.add(`${component.getClass('divider')}--${newOrientation}`);
43
+
44
+ // Update styles
45
+ if (newOrientation === 'horizontal') {
46
+ component.element.style.height = `${thickness}px`;
47
+ component.element.style.width = '100%';
48
+
49
+ // Reset vertical styles
50
+ component.element.style.marginTop = '';
51
+ component.element.style.marginBottom = '';
52
+ } else {
53
+ component.element.style.width = `${thickness}px`;
54
+ component.element.style.height = '100%';
55
+
56
+ // Reset horizontal styles
57
+ component.element.style.marginLeft = '';
58
+ component.element.style.marginRight = '';
59
+ }
60
+
61
+ return this as unknown as DividerComponent;
62
+ }
63
+ };
64
+ };
65
+
66
+ /**
67
+ * Adds inset functionality to divider
68
+ *
69
+ * @param config - Divider configuration
70
+ * @returns Function that enhances a component with inset capabilities
71
+ */
72
+ export const withInset = (config: DividerConfig) =>
73
+ <C extends ElementComponent & Partial<DividerComponent>>(component: C): C & Partial<DividerComponent> => {
74
+ const variant = config.variant || 'full-width';
75
+ const orientation = config.orientation || 'horizontal';
76
+
77
+ // Apply inset styles based on variant
78
+ if (variant === 'inset' || variant === 'middle-inset') {
79
+ if (orientation === 'horizontal') {
80
+ const insetStart = config.insetStart !== undefined ? config.insetStart : 16;
81
+ const insetEnd = config.insetEnd !== undefined ? config.insetEnd : (variant === 'middle-inset' ? 16 : 0);
82
+
83
+ component.element.style.marginLeft = `${insetStart}px`;
84
+ component.element.style.marginRight = `${insetEnd}px`;
85
+ } else {
86
+ const insetStart = config.insetStart !== undefined ? config.insetStart : 16;
87
+ const insetEnd = config.insetEnd !== undefined ? config.insetEnd : (variant === 'middle-inset' ? 16 : 0);
88
+
89
+ component.element.style.marginTop = `${insetStart}px`;
90
+ component.element.style.marginBottom = `${insetEnd}px`;
91
+ }
92
+ }
93
+
94
+ return {
95
+ ...component,
96
+
97
+ getVariant() {
98
+ return variant as 'full-width' | 'inset' | 'middle-inset';
99
+ },
100
+
101
+ setVariant(newVariant: 'full-width' | 'inset' | 'middle-inset') {
102
+ // Remove existing variant class
103
+ component.element.classList.remove(`${component.getClass('divider')}--${variant}`);
104
+
105
+ // Add new variant class
106
+ component.element.classList.add(`${component.getClass('divider')}--${newVariant}`);
107
+
108
+ // Update styles
109
+ const currentOrientation = component.getOrientation ? component.getOrientation() : orientation;
110
+
111
+ if (newVariant === 'full-width') {
112
+ if (currentOrientation === 'horizontal') {
113
+ component.element.style.marginLeft = '';
114
+ component.element.style.marginRight = '';
115
+ } else {
116
+ component.element.style.marginTop = '';
117
+ component.element.style.marginBottom = '';
118
+ }
119
+ } else {
120
+ const insetStart = config.insetStart !== undefined ? config.insetStart : 16;
121
+ const insetEnd = config.insetEnd !== undefined ? config.insetEnd : (newVariant === 'middle-inset' ? 16 : 0);
122
+
123
+ if (currentOrientation === 'horizontal') {
124
+ component.element.style.marginLeft = `${insetStart}px`;
125
+ component.element.style.marginRight = `${insetEnd}px`;
126
+ } else {
127
+ component.element.style.marginTop = `${insetStart}px`;
128
+ component.element.style.marginBottom = `${insetEnd}px`;
129
+ }
130
+ }
131
+
132
+ return this as unknown as DividerComponent;
133
+ },
134
+
135
+ setInset(insetStart?: number, insetEnd?: number) {
136
+ const currentOrientation = component.getOrientation ? component.getOrientation() : orientation;
137
+ const currentVariant = component.getVariant ? component.getVariant() : variant;
138
+
139
+ if (currentVariant !== 'full-width') {
140
+ if (currentOrientation === 'horizontal') {
141
+ if (insetStart !== undefined) {
142
+ component.element.style.marginLeft = `${insetStart}px`;
143
+ }
144
+
145
+ if (insetEnd !== undefined) {
146
+ component.element.style.marginRight = `${insetEnd}px`;
147
+ }
148
+ } else {
149
+ if (insetStart !== undefined) {
150
+ component.element.style.marginTop = `${insetStart}px`;
151
+ }
152
+
153
+ if (insetEnd !== undefined) {
154
+ component.element.style.marginBottom = `${insetEnd}px`;
155
+ }
156
+ }
157
+ }
158
+
159
+ return this as unknown as DividerComponent;
160
+ }
161
+ };
162
+ };
163
+
164
+ /**
165
+ * Adds style customization to divider
166
+ *
167
+ * @param config - Divider configuration
168
+ * @returns Function that enhances a component with style capabilities
169
+ */
170
+ export const withStyle = (config: DividerConfig) =>
171
+ <C extends ElementComponent & Partial<DividerComponent>>(component: C): C & Partial<DividerComponent> => {
172
+ // Apply custom color if provided
173
+ if (config.color) {
174
+ component.element.style.backgroundColor = config.color;
175
+ }
176
+
177
+ // Apply thickness
178
+ const thickness = config.thickness || 1;
179
+ const orientation = config.orientation || 'horizontal';
180
+
181
+ if (orientation === 'horizontal') {
182
+ component.element.style.height = `${thickness}px`;
183
+ } else {
184
+ component.element.style.width = `${thickness}px`;
185
+ }
186
+
187
+ return {
188
+ ...component,
189
+
190
+ setThickness(newThickness: number) {
191
+ const currentOrientation = component.getOrientation ? component.getOrientation() : orientation;
192
+
193
+ if (currentOrientation === 'horizontal') {
194
+ component.element.style.height = `${newThickness}px`;
195
+ } else {
196
+ component.element.style.width = `${newThickness}px`;
197
+ }
198
+
199
+ return this as unknown as DividerComponent;
200
+ },
201
+
202
+ setColor(color: string) {
203
+ component.element.style.backgroundColor = color;
204
+ return this as unknown as DividerComponent;
205
+ }
206
+ };
207
+ };
@@ -0,0 +1,9 @@
1
+ // src/components/divider/index.ts
2
+
3
+ // Use a more explicit export to avoid bundler confusion
4
+ import { createDivider } from './divider';
5
+ export { createDivider };
6
+
7
+ // Export types
8
+ export type { DividerConfig } from './config';
9
+ export type { DividerComponent } from './types';
@@ -0,0 +1,55 @@
1
+ // src/components/divider/types.ts
2
+ import { BaseComponent, ElementComponent } from '../../core/compose';
3
+
4
+ /**
5
+ * Divider component interface
6
+ */
7
+ export interface DividerComponent extends BaseComponent, ElementComponent {
8
+ /**
9
+ * Gets current orientation
10
+ * @returns Current orientation
11
+ */
12
+ getOrientation: () => 'horizontal' | 'vertical';
13
+
14
+ /**
15
+ * Sets orientation of the divider
16
+ * @param orientation - New orientation
17
+ * @returns DividerComponent instance for chaining
18
+ */
19
+ setOrientation: (orientation: 'horizontal' | 'vertical') => DividerComponent;
20
+
21
+ /**
22
+ * Gets current variant
23
+ * @returns Current variant
24
+ */
25
+ getVariant: () => 'full-width' | 'inset' | 'middle-inset';
26
+
27
+ /**
28
+ * Sets variant of the divider
29
+ * @param variant - New variant
30
+ * @returns DividerComponent instance for chaining
31
+ */
32
+ setVariant: (variant: 'full-width' | 'inset' | 'middle-inset') => DividerComponent;
33
+
34
+ /**
35
+ * Sets custom inset values
36
+ * @param insetStart - Start inset value
37
+ * @param insetEnd - End inset value
38
+ * @returns DividerComponent instance for chaining
39
+ */
40
+ setInset: (insetStart?: number, insetEnd?: number) => DividerComponent;
41
+
42
+ /**
43
+ * Sets thickness of the divider
44
+ * @param thickness - Thickness in pixels
45
+ * @returns DividerComponent instance for chaining
46
+ */
47
+ setThickness: (thickness: number) => DividerComponent;
48
+
49
+ /**
50
+ * Sets custom color for the divider
51
+ * @param color - CSS color value
52
+ * @returns DividerComponent instance for chaining
53
+ */
54
+ setColor: (color: string) => DividerComponent;
55
+ }
@@ -0,0 +1,141 @@
1
+ // src/components/extended-fab/api.ts
2
+ import { ExtendedFabComponent } from './types';
3
+
4
+ interface ApiOptions {
5
+ disabled: {
6
+ enable: () => void;
7
+ disable: () => void;
8
+ };
9
+ lifecycle: {
10
+ destroy: () => void;
11
+ };
12
+ text: {
13
+ setText: (text: string) => any;
14
+ getText: () => string;
15
+ };
16
+ className: string;
17
+ }
18
+
19
+ interface ComponentWithElements {
20
+ element: HTMLElement;
21
+ icon: {
22
+ setIcon: (html: string) => any;
23
+ getIcon: () => string;
24
+ getElement: () => HTMLElement | null;
25
+ };
26
+ text: {
27
+ setText: (text: string) => any;
28
+ getText: () => string;
29
+ getElement: () => HTMLElement | null;
30
+ };
31
+ getClass: (name: string) => string;
32
+ }
33
+
34
+ /**
35
+ * Enhances an Extended FAB component with API methods
36
+ * @param {ApiOptions} options - API configuration options
37
+ * @returns {Function} Higher-order function that adds API methods to component
38
+ * @internal This is an internal utility for the Extended FAB component
39
+ */
40
+ export const withAPI = ({ disabled, lifecycle, text, className }: ApiOptions) =>
41
+ (component: ComponentWithElements): ExtendedFabComponent => ({
42
+ ...component as any,
43
+ element: component.element as HTMLButtonElement,
44
+
45
+ getValue: () => component.element.value,
46
+
47
+ setValue(value: string) {
48
+ component.element.value = value;
49
+ return this;
50
+ },
51
+
52
+ enable() {
53
+ disabled.enable();
54
+ return this;
55
+ },
56
+
57
+ disable() {
58
+ disabled.disable();
59
+ return this;
60
+ },
61
+
62
+ setIcon(icon: string) {
63
+ component.icon.setIcon(icon);
64
+ return this;
65
+ },
66
+
67
+ getIcon() {
68
+ return component.icon.getIcon();
69
+ },
70
+
71
+ setText(newText: string) {
72
+ text.setText(newText);
73
+ return this;
74
+ },
75
+
76
+ getText() {
77
+ return text.getText();
78
+ },
79
+
80
+ setPosition(position: string) {
81
+ // First remove any existing position classes
82
+ const positions = ['top-right', 'top-left', 'bottom-right', 'bottom-left'];
83
+ positions.forEach(pos => {
84
+ component.element.classList.remove(`${className}--${pos}`);
85
+ });
86
+
87
+ // Add new position class
88
+ component.element.classList.add(`${className}--${position}`);
89
+ return this;
90
+ },
91
+
92
+ getPosition() {
93
+ const positions = ['top-right', 'top-left', 'bottom-right', 'bottom-left'];
94
+ for (const pos of positions) {
95
+ if (component.element.classList.contains(`${className}--${pos}`)) {
96
+ return pos;
97
+ }
98
+ }
99
+ return null;
100
+ },
101
+
102
+ lower() {
103
+ component.element.classList.add(`${className}--lowered`);
104
+ return this;
105
+ },
106
+
107
+ raise() {
108
+ component.element.classList.remove(`${className}--lowered`);
109
+ return this;
110
+ },
111
+
112
+ collapse() {
113
+ component.element.classList.add(`${className}--collapsed`);
114
+
115
+ // Emit a custom event that can be listened to
116
+ const event = new CustomEvent('collapse', {
117
+ bubbles: true,
118
+ cancelable: true
119
+ });
120
+ component.element.dispatchEvent(event);
121
+
122
+ return this;
123
+ },
124
+
125
+ expand() {
126
+ component.element.classList.remove(`${className}--collapsed`);
127
+
128
+ // Emit a custom event that can be listened to
129
+ const event = new CustomEvent('expand', {
130
+ bubbles: true,
131
+ cancelable: true
132
+ });
133
+ component.element.dispatchEvent(event);
134
+
135
+ return this;
136
+ },
137
+
138
+ destroy() {
139
+ lifecycle.destroy();
140
+ }
141
+ });