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.
- package/demo/build.ts +349 -0
- package/demo/index.html +110 -0
- package/demo/main.js +448 -0
- package/demo/styles.css +239 -0
- package/index.ts +18 -0
- package/package.json +14 -3
- package/server.ts +86 -0
- package/src/components/badge/api.ts +70 -63
- package/src/components/badge/badge.ts +16 -2
- package/src/components/badge/config.ts +66 -13
- package/src/components/badge/features.ts +51 -42
- package/src/components/badge/index.ts +27 -2
- package/src/components/badge/types.ts +62 -30
- package/src/components/bottom-app-bar/bottom-app-bar.ts +154 -0
- package/src/components/bottom-app-bar/config.ts +29 -0
- package/src/components/bottom-app-bar/index.ts +17 -0
- package/src/components/bottom-app-bar/types.ts +114 -0
- package/src/components/button/api.ts +5 -0
- package/src/components/button/button.ts +0 -1
- package/src/components/button/config.ts +6 -2
- package/src/components/button/index.ts +10 -2
- package/src/components/button/types.ts +20 -2
- package/src/components/card/card.ts +13 -25
- package/src/components/card/config.ts +83 -30
- package/src/components/card/content.ts +8 -10
- package/src/components/card/features.ts +4 -3
- package/src/components/card/index.ts +29 -2
- package/src/components/card/types.ts +33 -22
- package/src/components/checkbox/config.ts +3 -4
- package/src/components/checkbox/index.ts +1 -2
- package/src/components/checkbox/types.ts +12 -3
- package/src/components/chip/api.ts +170 -221
- package/src/components/chip/chip.ts +34 -302
- package/src/components/chip/config.ts +1 -2
- package/src/components/chip/index.ts +10 -2
- package/src/components/chip/types.ts +224 -35
- package/src/components/datepicker/api.ts +265 -0
- package/src/components/datepicker/config.ts +141 -0
- package/src/components/datepicker/datepicker.ts +341 -0
- package/src/components/datepicker/index.ts +12 -0
- package/src/components/datepicker/render.ts +450 -0
- package/src/components/datepicker/types.ts +397 -0
- package/src/components/datepicker/utils.ts +289 -0
- package/src/components/dialog/api.ts +55 -21
- package/src/components/dialog/config.ts +12 -9
- package/src/components/dialog/dialog.ts +6 -3
- package/src/components/dialog/features.ts +345 -151
- package/src/components/dialog/index.ts +38 -8
- package/src/components/dialog/types.ts +40 -14
- package/src/components/divider/config.ts +81 -0
- package/src/components/divider/divider.ts +37 -0
- package/src/components/divider/features.ts +207 -0
- package/src/components/divider/index.ts +9 -0
- package/src/components/divider/types.ts +55 -0
- package/src/components/extended-fab/api.ts +141 -0
- package/src/components/extended-fab/config.ts +112 -0
- package/src/components/extended-fab/extended-fab.ts +125 -0
- package/src/components/extended-fab/index.ts +9 -0
- package/src/components/extended-fab/types.ts +304 -0
- package/src/components/fab/api.ts +97 -0
- package/src/components/fab/config.ts +93 -0
- package/src/components/fab/fab.ts +67 -0
- package/src/components/fab/index.ts +9 -0
- package/src/components/fab/types.ts +251 -0
- package/src/components/list/config.ts +4 -5
- package/src/components/list/features.ts +6 -7
- package/src/components/list/index.ts +7 -9
- package/src/components/list/list-item.ts +12 -13
- package/src/components/list/types.ts +50 -5
- package/src/components/list/utils.ts +30 -3
- package/src/components/menu/features/items-manager.ts +9 -9
- package/src/components/menu/features/positioning.ts +7 -7
- package/src/components/menu/features/visibility.ts +7 -7
- package/src/components/menu/index.ts +7 -9
- package/src/components/menu/menu-item.ts +6 -6
- package/src/components/menu/menu.ts +22 -0
- package/src/components/menu/types.ts +29 -10
- package/src/components/menu/utils.ts +67 -0
- package/src/components/navigation/api.ts +78 -50
- package/src/components/navigation/config.ts +22 -10
- package/src/components/navigation/features/items.ts +284 -0
- package/src/components/navigation/index.ts +0 -6
- package/src/components/navigation/nav-item.ts +70 -33
- package/src/components/navigation/navigation.ts +53 -3
- package/src/components/navigation/types.ts +117 -70
- package/src/components/progress/api.ts +2 -3
- package/src/components/progress/config.ts +2 -3
- package/src/components/progress/index.ts +0 -1
- package/src/components/progress/progress.ts +1 -2
- package/src/components/progress/types.ts +186 -33
- package/src/components/radios/config.ts +1 -1
- package/src/components/radios/index.ts +0 -1
- package/src/components/radios/types.ts +0 -7
- package/src/components/search/api.ts +203 -0
- package/src/components/search/config.ts +86 -0
- package/src/components/search/features/index.ts +4 -0
- package/src/components/search/features/search.ts +717 -0
- package/src/components/search/features/states.ts +169 -0
- package/src/components/search/features/structure.ts +197 -0
- package/src/components/search/index.ts +7 -0
- package/src/components/search/search.ts +52 -0
- package/src/components/search/types.ts +175 -0
- package/src/components/segmented-button/config.ts +80 -0
- package/src/components/segmented-button/index.ts +4 -0
- package/src/components/segmented-button/segment.ts +154 -0
- package/src/components/segmented-button/segmented-button.ts +249 -0
- package/src/components/segmented-button/types.ts +254 -0
- package/src/components/slider/accessibility.md +5 -5
- package/src/components/slider/api.ts +41 -120
- package/src/components/slider/config.ts +51 -47
- package/src/components/slider/features/handlers.ts +495 -0
- package/src/components/slider/features/index.ts +1 -2
- package/src/components/slider/features/slider.ts +66 -84
- package/src/components/slider/features/states.ts +195 -0
- package/src/components/slider/features/structure.ts +136 -206
- package/src/components/slider/features/ui.ts +145 -206
- package/src/components/slider/index.ts +2 -11
- package/src/components/slider/slider.ts +9 -12
- package/src/components/slider/types.ts +67 -26
- package/src/components/snackbar/config.ts +2 -3
- package/src/components/snackbar/constants.ts +0 -32
- package/src/components/snackbar/index.ts +0 -1
- package/src/components/snackbar/position.ts +9 -1
- package/src/components/snackbar/types.ts +122 -46
- package/src/components/switch/config.ts +2 -3
- package/src/components/switch/index.ts +0 -1
- package/src/components/switch/types.ts +3 -2
- package/src/components/tabs/config.ts +3 -4
- package/src/components/tabs/features.ts +4 -2
- package/src/components/tabs/index.ts +0 -15
- package/src/components/tabs/indicator.ts +73 -13
- package/src/components/tabs/tab-api.ts +12 -4
- package/src/components/tabs/tab.ts +18 -6
- package/src/components/tabs/types.ts +23 -5
- package/src/components/textfield/config.ts +2 -3
- package/src/components/textfield/index.ts +0 -1
- package/src/components/textfield/types.ts +17 -3
- package/src/components/timepicker/README.md +277 -0
- package/src/components/timepicker/api.ts +632 -0
- package/src/components/timepicker/clockdial.ts +482 -0
- package/src/components/timepicker/config.ts +228 -0
- package/src/components/timepicker/index.ts +3 -0
- package/src/components/timepicker/render.ts +613 -0
- package/src/components/timepicker/timepicker.ts +117 -0
- package/src/components/timepicker/types.ts +336 -0
- package/src/components/timepicker/utils.ts +241 -0
- package/src/components/tooltip/api.ts +1 -1
- package/src/components/tooltip/config.ts +27 -6
- package/src/components/tooltip/index.ts +0 -1
- package/src/components/tooltip/types.ts +13 -3
- package/src/components/top-app-bar/config.ts +83 -0
- package/src/components/top-app-bar/index.ts +11 -0
- package/src/components/top-app-bar/top-app-bar.ts +316 -0
- package/src/components/top-app-bar/types.ts +140 -0
- package/src/core/build/_ripple.scss +6 -6
- package/src/core/build/ripple.ts +72 -95
- package/src/core/compose/features/icon.ts +3 -1
- package/src/core/compose/features/ripple.ts +4 -1
- package/src/core/compose/features/textlabel.ts +23 -2
- package/src/core/dom/create.ts +5 -0
- package/src/index.ts +9 -0
- package/src/styles/abstract/_theme.scss +9 -1
- package/src/styles/components/_badge.scss +182 -0
- package/src/styles/components/_bottom-app-bar.scss +103 -0
- package/src/{components/button/_styles.scss → styles/components/_button.scss} +0 -10
- package/src/{components/checkbox/_styles.scss → styles/components/_checkbox.scss} +0 -2
- package/src/styles/components/_datepicker.scss +358 -0
- package/src/styles/components/_dialog.scss +259 -0
- package/src/styles/components/_divider.scss +57 -0
- package/src/styles/components/_extended-fab.scss +267 -0
- package/src/styles/components/_fab.scss +225 -0
- package/src/{components/navigation/_styles.scss → styles/components/_navigation.scss} +1 -0
- package/src/styles/components/_search.scss +306 -0
- package/src/styles/components/_segmented-button.scss +117 -0
- package/src/{components/slider/_styles.scss → styles/components/_slider.scss} +83 -24
- package/src/{components/switch/_styles.scss → styles/components/_switch.scss} +0 -2
- package/src/{components/tabs/_styles.scss → styles/components/_tabs.scss} +95 -33
- package/src/{components/textfield/_styles.scss → styles/components/_textfield.scss} +70 -67
- package/src/styles/components/_timepicker.scss +451 -0
- package/src/styles/components/_top-app-bar.scss +225 -0
- package/src/styles/main.scss +98 -49
- package/src/styles/themes/_autumn.scss +21 -0
- package/src/styles/themes/_base-theme.scss +61 -0
- package/src/styles/themes/_baseline.scss +58 -0
- package/src/styles/themes/_bluekhaki.scss +125 -0
- package/src/styles/themes/_brownbeige.scss +125 -0
- package/src/styles/themes/_browngreen.scss +125 -0
- package/src/styles/themes/_forest.scss +6 -0
- package/src/styles/themes/_greenbeige.scss +125 -0
- package/src/styles/themes/_material.scss +125 -0
- package/src/styles/themes/_ocean.scss +6 -0
- package/src/styles/themes/_sageivory.scss +125 -0
- package/src/styles/themes/_spring.scss +6 -0
- package/src/styles/themes/_summer.scss +5 -0
- package/src/styles/themes/_sunset.scss +5 -0
- package/src/styles/themes/_tealcaramel.scss +125 -0
- package/src/styles/themes/_winter.scss +6 -0
- package/src/components/badge/_styles.scss +0 -174
- package/src/components/badge/constants.ts +0 -30
- package/src/components/button/constants.ts +0 -11
- package/src/components/card/constants.ts +0 -84
- package/src/components/dialog/_styles.scss +0 -213
- package/src/components/dialog/constants.ts +0 -32
- package/src/components/menu/constants.ts +0 -154
- package/src/components/navigation/constants.ts +0 -200
- package/src/components/navigation/features/items.js +0 -192
- package/src/components/progress/constants.ts +0 -29
- package/src/components/slider/features/appearance.ts +0 -94
- package/src/components/slider/features/disabled.ts +0 -68
- package/src/components/slider/features/events.ts +0 -164
- package/src/components/slider/features/interactions.ts +0 -396
- package/src/components/slider/features/keyboard.ts +0 -233
- package/src/components/switch/constants.ts +0 -80
- package/src/components/tabs/constants.ts +0 -89
- package/src/core/collection/adapters/mongodb.js +0 -232
- /package/src/{components/card/_styles.scss → styles/components/_card.scss} +0 -0
- /package/src/{components/carousel/_styles.scss → styles/components/_carousel.scss} +0 -0
- /package/src/{components/chip/_styles.scss → styles/components/_chip.scss} +0 -0
- /package/src/{components/list/_styles.scss → styles/components/_list.scss} +0 -0
- /package/src/{components/menu/_styles.scss → styles/components/_menu.scss} +0 -0
- /package/src/{components/progress/_styles.scss → styles/components/_progress.scss} +0 -0
- /package/src/{components/radios/_styles.scss → styles/components/_radios.scss} +0 -0
- /package/src/{components/sheet/_styles.scss → styles/components/_sheet.scss} +0 -0
- /package/src/{components/snackbar/_styles.scss → styles/components/_snackbar.scss} +0 -0
- /package/src/{components/tooltip/_styles.scss → styles/components/_tooltip.scss} +0 -0
- /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
|
-
|
|
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
|
-
|
|
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?:
|
|
47
|
+
size?: DialogSize | string;
|
|
25
48
|
|
|
26
49
|
/** Dialog animation variant */
|
|
27
|
-
animation?:
|
|
50
|
+
animation?: DialogAnimation | string;
|
|
28
51
|
|
|
29
52
|
/** Footer buttons alignment */
|
|
30
|
-
footerAlignment?:
|
|
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
|
-
|
|
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
|
|
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:
|
|
190
|
+
setFooterAlignment: (alignment: DialogFooterAlignment | string) => DialogComponent;
|
|
171
191
|
|
|
172
192
|
/** Sets dialog size */
|
|
173
|
-
setSize: (size:
|
|
193
|
+
setSize: (size: DialogSize | string) => DialogComponent;
|
|
174
194
|
|
|
175
195
|
/** Adds event listener */
|
|
176
|
-
on: (event:
|
|
196
|
+
on: (event: DialogEventType | string, handler: (event: DialogEvent) => void) => DialogComponent;
|
|
177
197
|
|
|
178
198
|
/** Removes event listener */
|
|
179
|
-
off: (event:
|
|
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?:
|
|
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
|
+
});
|