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
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// src/components/fab/config.ts
|
|
2
|
+
import {
|
|
3
|
+
createComponentConfig,
|
|
4
|
+
createElementConfig,
|
|
5
|
+
BaseComponentConfig
|
|
6
|
+
} from '../../core/config/component-config';
|
|
7
|
+
import { FabConfig } from './types';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Default configuration for the FAB component
|
|
11
|
+
*/
|
|
12
|
+
export const defaultConfig: FabConfig = {
|
|
13
|
+
variant: 'primary',
|
|
14
|
+
size: 'default',
|
|
15
|
+
type: 'button',
|
|
16
|
+
ripple: true
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Creates the base configuration for FAB component
|
|
21
|
+
* @param {FabConfig} config - User provided configuration
|
|
22
|
+
* @returns {FabConfig} Complete configuration with defaults applied
|
|
23
|
+
*/
|
|
24
|
+
export const createBaseConfig = (config: FabConfig = {}): FabConfig =>
|
|
25
|
+
createComponentConfig(defaultConfig, config, 'fab') as FabConfig;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Generates element configuration for the FAB component
|
|
29
|
+
* @param {FabConfig} config - FAB configuration
|
|
30
|
+
* @returns {Object} Element configuration object for withElement
|
|
31
|
+
*/
|
|
32
|
+
export const getElementConfig = (config: FabConfig) => {
|
|
33
|
+
// Create the attributes object
|
|
34
|
+
const attrs: Record<string, any> = {
|
|
35
|
+
type: config.type || 'button',
|
|
36
|
+
'aria-label': config.ariaLabel || (config.icon ? 'action' : undefined)
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// Add size class
|
|
40
|
+
const fabSizeClass = `${config.prefix}-fab--${config.size || 'default'}`;
|
|
41
|
+
let classNames = [fabSizeClass];
|
|
42
|
+
|
|
43
|
+
// Add animation class if specified
|
|
44
|
+
if (config.animate) {
|
|
45
|
+
classNames.push(`${config.prefix}-fab--animate-enter`);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Add position class if specified
|
|
49
|
+
if (config.position) {
|
|
50
|
+
classNames.push(`${config.prefix}-fab--${config.position}`);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Add user classes
|
|
54
|
+
if (config.class) {
|
|
55
|
+
classNames.push(config.class);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Only add disabled attribute if it's explicitly true
|
|
59
|
+
if (config.disabled === true) {
|
|
60
|
+
attrs.disabled = true;
|
|
61
|
+
classNames.push(`${config.prefix}-fab--disabled`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return createElementConfig(config, {
|
|
65
|
+
tag: 'button',
|
|
66
|
+
attrs,
|
|
67
|
+
className: classNames,
|
|
68
|
+
forwardEvents: {
|
|
69
|
+
click: (component) => !component.element.disabled,
|
|
70
|
+
focus: true,
|
|
71
|
+
blur: true
|
|
72
|
+
},
|
|
73
|
+
interactive: true
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Creates API configuration for the FAB component
|
|
79
|
+
* @param {Object} comp - Component with disabled and lifecycle features
|
|
80
|
+
* @returns {Object} API configuration object
|
|
81
|
+
*/
|
|
82
|
+
export const getApiConfig = (comp: any) => ({
|
|
83
|
+
disabled: {
|
|
84
|
+
enable: () => comp.disabled.enable(),
|
|
85
|
+
disable: () => comp.disabled.disable()
|
|
86
|
+
},
|
|
87
|
+
lifecycle: {
|
|
88
|
+
destroy: () => comp.lifecycle.destroy()
|
|
89
|
+
},
|
|
90
|
+
className: comp.getClass('fab')
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
export default defaultConfig;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// src/components/fab/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
|
+
} from '../../core/compose/features';
|
|
12
|
+
import { withAPI } from './api';
|
|
13
|
+
import { FabConfig, FabComponent } from './types';
|
|
14
|
+
import { createBaseConfig, getElementConfig, getApiConfig } from './config';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Creates a new Floating Action Button (FAB) component
|
|
18
|
+
*
|
|
19
|
+
* @param {FabConfig} config - FAB configuration object
|
|
20
|
+
* @returns {FabComponent} FAB component instance
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* // Create a default FAB with a plus icon
|
|
25
|
+
* const fab = createFab({
|
|
26
|
+
* icon: '<svg>...</svg>',
|
|
27
|
+
* ariaLabel: 'Add new item'
|
|
28
|
+
* });
|
|
29
|
+
*
|
|
30
|
+
* // Create a small FAB with a custom position
|
|
31
|
+
* const smallFab = createFab({
|
|
32
|
+
* size: 'small',
|
|
33
|
+
* icon: '<svg>...</svg>',
|
|
34
|
+
* variant: 'secondary',
|
|
35
|
+
* position: 'bottom-right'
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* // Add click handler
|
|
39
|
+
* fab.on('click', () => {
|
|
40
|
+
* console.log('FAB clicked');
|
|
41
|
+
* });
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
const createFab = (config: FabConfig = {}): FabComponent => {
|
|
45
|
+
const fabConfig = createBaseConfig(config);
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
const fab = pipe(
|
|
49
|
+
createBase,
|
|
50
|
+
withEvents(),
|
|
51
|
+
withElement(getElementConfig(fabConfig)),
|
|
52
|
+
withVariant(fabConfig),
|
|
53
|
+
withIcon(fabConfig),
|
|
54
|
+
withDisabled(fabConfig),
|
|
55
|
+
withRipple(fabConfig),
|
|
56
|
+
withLifecycle(),
|
|
57
|
+
comp => withAPI(getApiConfig(comp))(comp)
|
|
58
|
+
)(fabConfig);
|
|
59
|
+
|
|
60
|
+
return fab;
|
|
61
|
+
} catch (error) {
|
|
62
|
+
console.error('FAB creation error:', error);
|
|
63
|
+
throw new Error(`Failed to create FAB: ${(error as Error).message}`);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
export default createFab;
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
// src/components/fab/types.ts
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* FAB variants for styling
|
|
5
|
+
* @category Components
|
|
6
|
+
*/
|
|
7
|
+
export type FabVariant = 'primary' | 'secondary' | 'tertiary' | 'surface';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* FAB size variants
|
|
11
|
+
* @category Components
|
|
12
|
+
*/
|
|
13
|
+
export type FabSize = 'small' | 'default' | 'large';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* FAB position options
|
|
17
|
+
* @category Components
|
|
18
|
+
*/
|
|
19
|
+
export type FabPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Configuration interface for the FAB component
|
|
23
|
+
* @category Components
|
|
24
|
+
*/
|
|
25
|
+
export interface FabConfig {
|
|
26
|
+
/**
|
|
27
|
+
* FAB variant that determines visual styling
|
|
28
|
+
* @default 'primary'
|
|
29
|
+
*/
|
|
30
|
+
variant?: FabVariant | string;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* FAB size variant
|
|
34
|
+
* @default 'default'
|
|
35
|
+
*/
|
|
36
|
+
size?: FabSize | string;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Whether the FAB is initially disabled
|
|
40
|
+
* @default false
|
|
41
|
+
*/
|
|
42
|
+
disabled?: boolean;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* FAB icon HTML content
|
|
46
|
+
* @example '<svg>...</svg>'
|
|
47
|
+
*/
|
|
48
|
+
icon?: string;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Icon size in pixels or other CSS units
|
|
52
|
+
* @example '24px'
|
|
53
|
+
*/
|
|
54
|
+
iconSize?: string;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Additional CSS classes to add to the FAB
|
|
58
|
+
* @example 'home-fab bottom-right'
|
|
59
|
+
*/
|
|
60
|
+
class?: string;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Button value attribute
|
|
64
|
+
*/
|
|
65
|
+
value?: string;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Position of the FAB on the screen
|
|
69
|
+
* @example 'bottom-right'
|
|
70
|
+
*/
|
|
71
|
+
position?: FabPosition | string;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Button type attribute
|
|
75
|
+
* @default 'button'
|
|
76
|
+
*/
|
|
77
|
+
type?: 'button' | 'submit' | 'reset';
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Accessible label for screen readers
|
|
81
|
+
*/
|
|
82
|
+
ariaLabel?: string;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Whether to enable ripple effect
|
|
86
|
+
* @default true
|
|
87
|
+
*/
|
|
88
|
+
ripple?: boolean;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Component prefix for class names
|
|
92
|
+
* @default 'mtrl'
|
|
93
|
+
*/
|
|
94
|
+
prefix?: string;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Component name used in class generation
|
|
98
|
+
*/
|
|
99
|
+
componentName?: string;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Ripple effect configuration
|
|
103
|
+
*/
|
|
104
|
+
rippleConfig?: {
|
|
105
|
+
/** Duration of the ripple animation in milliseconds */
|
|
106
|
+
duration?: number;
|
|
107
|
+
/** Timing function for the ripple animation */
|
|
108
|
+
timing?: string;
|
|
109
|
+
/** Opacity values for ripple start and end [start, end] */
|
|
110
|
+
opacity?: [string, string];
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Whether to show the FAB with an entrance animation
|
|
115
|
+
* @default false
|
|
116
|
+
*/
|
|
117
|
+
animate?: boolean;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* FAB component interface
|
|
122
|
+
* @category Components
|
|
123
|
+
*/
|
|
124
|
+
export interface FabComponent {
|
|
125
|
+
/** The FAB's DOM element */
|
|
126
|
+
element: HTMLButtonElement;
|
|
127
|
+
|
|
128
|
+
/** API for managing FAB icons */
|
|
129
|
+
icon: {
|
|
130
|
+
/** Sets the icon HTML content */
|
|
131
|
+
setIcon: (html: string) => any;
|
|
132
|
+
/** Gets the current icon HTML content */
|
|
133
|
+
getIcon: () => string;
|
|
134
|
+
/** Gets the icon DOM element */
|
|
135
|
+
getElement: () => HTMLElement | null;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
/** API for managing disabled state */
|
|
139
|
+
disabled: {
|
|
140
|
+
/** Enables the FAB */
|
|
141
|
+
enable: () => void;
|
|
142
|
+
/** Disables the FAB */
|
|
143
|
+
disable: () => void;
|
|
144
|
+
/** Checks if the FAB is disabled */
|
|
145
|
+
isDisabled: () => boolean;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
/** API for managing component lifecycle */
|
|
149
|
+
lifecycle: {
|
|
150
|
+
/** Destroys the component and cleans up resources */
|
|
151
|
+
destroy: () => void;
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Gets a class name with the component's prefix
|
|
156
|
+
* @param name - Base class name
|
|
157
|
+
* @returns Prefixed class name
|
|
158
|
+
*/
|
|
159
|
+
getClass: (name: string) => string;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Gets the FAB's value attribute
|
|
163
|
+
* @returns FAB value
|
|
164
|
+
*/
|
|
165
|
+
getValue: () => string;
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Sets the FAB's value attribute
|
|
169
|
+
* @param value - New value
|
|
170
|
+
* @returns The FAB component for chaining
|
|
171
|
+
*/
|
|
172
|
+
setValue: (value: string) => FabComponent;
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Enables the FAB (removes disabled attribute)
|
|
176
|
+
* @returns The FAB component for chaining
|
|
177
|
+
*/
|
|
178
|
+
enable: () => FabComponent;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Disables the FAB (adds disabled attribute)
|
|
182
|
+
* @returns The FAB component for chaining
|
|
183
|
+
*/
|
|
184
|
+
disable: () => FabComponent;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Sets the FAB's icon
|
|
188
|
+
* @param icon - Icon HTML content
|
|
189
|
+
* @returns The FAB component for chaining
|
|
190
|
+
*/
|
|
191
|
+
setIcon: (icon: string) => FabComponent;
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Gets the FAB's icon HTML content
|
|
195
|
+
* @returns Icon HTML
|
|
196
|
+
*/
|
|
197
|
+
getIcon: () => string;
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Sets the FAB's position
|
|
201
|
+
* @param position - Position value ('top-right', 'bottom-left', etc.)
|
|
202
|
+
* @returns The FAB component for chaining
|
|
203
|
+
*/
|
|
204
|
+
setPosition: (position: string) => FabComponent;
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Gets the current position of the FAB
|
|
208
|
+
* @returns Current position
|
|
209
|
+
*/
|
|
210
|
+
getPosition: () => string | null;
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Lowers the FAB (useful for pressed state)
|
|
214
|
+
* @returns The FAB component for chaining
|
|
215
|
+
*/
|
|
216
|
+
lower: () => FabComponent;
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Raises the FAB back to its default elevation
|
|
220
|
+
* @returns The FAB component for chaining
|
|
221
|
+
*/
|
|
222
|
+
raise: () => FabComponent;
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Destroys the FAB component and cleans up resources
|
|
226
|
+
*/
|
|
227
|
+
destroy: () => void;
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Adds an event listener to the FAB
|
|
231
|
+
* @param event - Event name ('click', 'focus', etc.)
|
|
232
|
+
* @param handler - Event handler function
|
|
233
|
+
* @returns The FAB component for chaining
|
|
234
|
+
*/
|
|
235
|
+
on: (event: string, handler: Function) => FabComponent;
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Removes an event listener from the FAB
|
|
239
|
+
* @param event - Event name
|
|
240
|
+
* @param handler - Event handler function
|
|
241
|
+
* @returns The FAB component for chaining
|
|
242
|
+
*/
|
|
243
|
+
off: (event: string, handler: Function) => FabComponent;
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Adds CSS classes to the FAB element
|
|
247
|
+
* @param classes - One or more class names to add
|
|
248
|
+
* @returns The FAB component for chaining
|
|
249
|
+
*/
|
|
250
|
+
addClass: (...classes: string[]) => FabComponent;
|
|
251
|
+
}
|
|
@@ -5,14 +5,13 @@ import {
|
|
|
5
5
|
BaseComponentConfig
|
|
6
6
|
} from '../../core/config/component-config';
|
|
7
7
|
import { ListConfig, BaseComponent } from './types';
|
|
8
|
-
import { LIST_TYPES, LIST_LAYOUTS } from './constants';
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
10
|
* Default configuration for the List component
|
|
12
11
|
*/
|
|
13
12
|
export const defaultConfig: ListConfig = {
|
|
14
|
-
type:
|
|
15
|
-
layout:
|
|
13
|
+
type: 'default',
|
|
14
|
+
layout: 'horizontal',
|
|
16
15
|
items: []
|
|
17
16
|
};
|
|
18
17
|
|
|
@@ -32,9 +31,9 @@ export const createBaseConfig = (config: ListConfig = {}): ListConfig =>
|
|
|
32
31
|
export const getElementConfig = (config: ListConfig) =>
|
|
33
32
|
createElementConfig(config, {
|
|
34
33
|
tag: 'div',
|
|
35
|
-
role: config.type ===
|
|
34
|
+
role: config.type === 'default' ? 'list' : 'listbox',
|
|
36
35
|
attrs: {
|
|
37
|
-
'aria-multiselectable': config.type ===
|
|
36
|
+
'aria-multiselectable': config.type === 'multi' ? 'true' : undefined
|
|
38
37
|
},
|
|
39
38
|
componentName: 'list',
|
|
40
39
|
className: config.class
|
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
BaseComponent,
|
|
7
7
|
SelectionChangeEvent
|
|
8
8
|
} from './types';
|
|
9
|
-
import { LIST_TYPES, LIST_LAYOUTS } from './constants';
|
|
10
9
|
import { createDivider, createSectionTitle } from './utils';
|
|
11
10
|
import createListItem from './list-item';
|
|
12
11
|
|
|
@@ -23,7 +22,7 @@ export const withListContent = (config: ListConfig) =>
|
|
|
23
22
|
const selectedItems = new Set<string>();
|
|
24
23
|
|
|
25
24
|
// Set list type
|
|
26
|
-
element.setAttribute('data-type', config.type ||
|
|
25
|
+
element.setAttribute('data-type', config.type || 'default');
|
|
27
26
|
|
|
28
27
|
// Handle keyboard navigation
|
|
29
28
|
const handleKeyDown = (event: KeyboardEvent): void => {
|
|
@@ -71,7 +70,7 @@ export const withListContent = (config: ListConfig) =>
|
|
|
71
70
|
if (!itemData || itemData.disabled) return;
|
|
72
71
|
|
|
73
72
|
switch (config.type) {
|
|
74
|
-
case
|
|
73
|
+
case 'single':
|
|
75
74
|
// Deselect previously selected item
|
|
76
75
|
selectedItems.forEach(selectedId => {
|
|
77
76
|
const selected = items.get(selectedId);
|
|
@@ -88,7 +87,7 @@ export const withListContent = (config: ListConfig) =>
|
|
|
88
87
|
selectedItems.add(id);
|
|
89
88
|
break;
|
|
90
89
|
|
|
91
|
-
case
|
|
90
|
+
case 'multi':
|
|
92
91
|
const isSelected = selectedItems.has(id);
|
|
93
92
|
if (isSelected) {
|
|
94
93
|
itemElement.classList.remove(`${prefix}-list-item--selected`);
|
|
@@ -119,8 +118,8 @@ export const withListContent = (config: ListConfig) =>
|
|
|
119
118
|
|
|
120
119
|
const item = createListItem({
|
|
121
120
|
...itemConfig,
|
|
122
|
-
layout: config.layout ||
|
|
123
|
-
role: config.type ===
|
|
121
|
+
layout: config.layout || 'horizontal',
|
|
122
|
+
role: config.type === 'radio' ? 'radio' : 'option'
|
|
124
123
|
});
|
|
125
124
|
|
|
126
125
|
item.element.dataset.id = itemConfig.id;
|
|
@@ -200,7 +199,7 @@ export const withListContent = (config: ListConfig) =>
|
|
|
200
199
|
|
|
201
200
|
const item = createListItem({
|
|
202
201
|
...itemConfig,
|
|
203
|
-
layout: config.layout ||
|
|
202
|
+
layout: config.layout || 'horizontal'
|
|
204
203
|
});
|
|
205
204
|
|
|
206
205
|
item.element.dataset.id = itemConfig.id;
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
// src/components/list/index.ts
|
|
2
|
-
export { default } from './list'
|
|
3
|
-
export { default as createListItem } from './list-item'
|
|
4
|
-
export {
|
|
5
|
-
LIST_TYPES,
|
|
6
|
-
LIST_LAYOUTS,
|
|
7
|
-
LIST_ITEM_LAYOUTS
|
|
8
|
-
} from './constants'
|
|
2
|
+
export { default } from './list';
|
|
3
|
+
export { default as createListItem } from './list-item';
|
|
9
4
|
export {
|
|
10
5
|
ListConfig,
|
|
11
6
|
ListComponent,
|
|
12
7
|
ListItemConfig,
|
|
13
|
-
ListSectionConfig
|
|
14
|
-
|
|
8
|
+
ListSectionConfig,
|
|
9
|
+
ListType,
|
|
10
|
+
ListLayout,
|
|
11
|
+
ListItemLayout
|
|
12
|
+
} from './types';
|
|
@@ -4,8 +4,7 @@ import { pipe } from '../../core/compose';
|
|
|
4
4
|
import { createBase, withElement } from '../../core/compose/component';
|
|
5
5
|
import { withEvents, withDisabled } from '../../core/compose/features';
|
|
6
6
|
import { ListItemConfig } from './types';
|
|
7
|
-
import {
|
|
8
|
-
import { createElement } from './utils';
|
|
7
|
+
import { createElement, getListClass } from './utils';
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
10
|
* Creates list item content based on configuration
|
|
@@ -16,14 +15,14 @@ import { createElement } from './utils';
|
|
|
16
15
|
const withItemContent = (config: ListItemConfig) => (component: any): any => {
|
|
17
16
|
const { element } = component;
|
|
18
17
|
const prefix = config.prefix || PREFIX;
|
|
19
|
-
const isVertical = config.layout ===
|
|
18
|
+
const isVertical = config.layout === 'vertical';
|
|
20
19
|
|
|
21
20
|
// Create content container
|
|
22
|
-
const content = createElement('div', `${prefix}-${
|
|
21
|
+
const content = createElement('div', `${prefix}-${getListClass('ITEM_CONTENT')}`);
|
|
23
22
|
|
|
24
23
|
// Add leading content (icon/avatar)
|
|
25
24
|
if (config.leading) {
|
|
26
|
-
const leading = createElement('div', `${prefix}-${
|
|
25
|
+
const leading = createElement('div', `${prefix}-${getListClass('ITEM_LEADING')}`);
|
|
27
26
|
if (typeof config.leading === 'string') {
|
|
28
27
|
leading.innerHTML = config.leading;
|
|
29
28
|
} else {
|
|
@@ -33,23 +32,23 @@ const withItemContent = (config: ListItemConfig) => (component: any): any => {
|
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
// Text wrapper for proper alignment
|
|
36
|
-
const textWrapper = createElement('div', `${prefix}-${
|
|
35
|
+
const textWrapper = createElement('div', `${prefix}-${getListClass('ITEM_TEXT')}`);
|
|
37
36
|
|
|
38
37
|
// Add overline text (vertical only)
|
|
39
38
|
if (isVertical && config.overline) {
|
|
40
|
-
const overline = createElement('div', `${prefix}-${
|
|
39
|
+
const overline = createElement('div', `${prefix}-${getListClass('ITEM_OVERLINE')}`, config.overline);
|
|
41
40
|
textWrapper.appendChild(overline);
|
|
42
41
|
}
|
|
43
42
|
|
|
44
43
|
// Add headline (primary text)
|
|
45
44
|
if (config.headline) {
|
|
46
|
-
const headline = createElement('div', `${prefix}-${
|
|
45
|
+
const headline = createElement('div', `${prefix}-${getListClass('ITEM_HEADLINE')}`, config.headline);
|
|
47
46
|
textWrapper.appendChild(headline);
|
|
48
47
|
}
|
|
49
48
|
|
|
50
49
|
// Add supporting text (secondary text)
|
|
51
50
|
if (config.supportingText) {
|
|
52
|
-
const supporting = createElement('div', `${prefix}-${
|
|
51
|
+
const supporting = createElement('div', `${prefix}-${getListClass('ITEM_SUPPORTING')}`, config.supportingText);
|
|
53
52
|
textWrapper.appendChild(supporting);
|
|
54
53
|
}
|
|
55
54
|
|
|
@@ -57,7 +56,7 @@ const withItemContent = (config: ListItemConfig) => (component: any): any => {
|
|
|
57
56
|
|
|
58
57
|
// Add meta information (vertical only)
|
|
59
58
|
if (isVertical && config.meta) {
|
|
60
|
-
const meta = createElement('div', `${prefix}-${
|
|
59
|
+
const meta = createElement('div', `${prefix}-${getListClass('ITEM_META')}`);
|
|
61
60
|
if (typeof config.meta === 'string') {
|
|
62
61
|
meta.textContent = config.meta;
|
|
63
62
|
} else {
|
|
@@ -70,7 +69,7 @@ const withItemContent = (config: ListItemConfig) => (component: any): any => {
|
|
|
70
69
|
|
|
71
70
|
// Add trailing content (icon/meta)
|
|
72
71
|
if (config.trailing) {
|
|
73
|
-
const trailing = createElement('div', `${prefix}-${
|
|
72
|
+
const trailing = createElement('div', `${prefix}-${getListClass('ITEM_TRAILING')}`);
|
|
74
73
|
if (typeof config.trailing === 'string') {
|
|
75
74
|
trailing.innerHTML = config.trailing;
|
|
76
75
|
} else {
|
|
@@ -82,7 +81,7 @@ const withItemContent = (config: ListItemConfig) => (component: any): any => {
|
|
|
82
81
|
// Handle selected state
|
|
83
82
|
if (config.selected) {
|
|
84
83
|
element.setAttribute('aria-selected', 'true');
|
|
85
|
-
element.classList.add(`${prefix}-${
|
|
84
|
+
element.classList.add(`${prefix}-${getListClass('ITEM')}--selected`);
|
|
86
85
|
}
|
|
87
86
|
|
|
88
87
|
return component;
|
|
@@ -100,7 +99,7 @@ const createListItem = (config: ListItemConfig): any => {
|
|
|
100
99
|
prefix: PREFIX
|
|
101
100
|
};
|
|
102
101
|
|
|
103
|
-
const layoutClass = config.layout ===
|
|
102
|
+
const layoutClass = config.layout === 'vertical' ? 'vertical' : '';
|
|
104
103
|
const combinedClass = `${layoutClass} ${config.class || ''}`.trim();
|
|
105
104
|
|
|
106
105
|
return pipe(
|
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
// src/components/list/types.ts
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* List type variants
|
|
5
|
+
* @category Components
|
|
6
|
+
*/
|
|
7
|
+
export type ListType = 'default' | 'single' | 'multi' | 'radio';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* List layout variants
|
|
11
|
+
* @category Components
|
|
12
|
+
*/
|
|
13
|
+
export type ListLayout = 'horizontal' | 'vertical';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* List item layout variants
|
|
17
|
+
* @category Components
|
|
18
|
+
*/
|
|
19
|
+
export type ListItemLayout = 'horizontal' | 'vertical';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* List element class names
|
|
23
|
+
* @internal
|
|
24
|
+
*/
|
|
25
|
+
export interface ListClasses {
|
|
26
|
+
ROOT: string;
|
|
27
|
+
GROUP: string;
|
|
28
|
+
GROUP_TITLE: string;
|
|
29
|
+
DIVIDER: string;
|
|
30
|
+
SECTION: string;
|
|
31
|
+
SECTION_TITLE: string;
|
|
32
|
+
ITEM: string;
|
|
33
|
+
ITEM_CONTENT: string;
|
|
34
|
+
ITEM_LEADING: string;
|
|
35
|
+
ITEM_TEXT: string;
|
|
36
|
+
ITEM_OVERLINE: string;
|
|
37
|
+
ITEM_HEADLINE: string;
|
|
38
|
+
ITEM_SUPPORTING: string;
|
|
39
|
+
ITEM_META: string;
|
|
40
|
+
ITEM_TRAILING: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* List item states
|
|
45
|
+
* @internal
|
|
46
|
+
*/
|
|
47
|
+
export type ListItemState = 'selected' | 'disabled' | 'focused' | 'hovered';
|
|
3
48
|
|
|
4
49
|
/**
|
|
5
50
|
* List item configuration
|
|
@@ -9,7 +54,7 @@ export interface ListItemConfig {
|
|
|
9
54
|
id: string;
|
|
10
55
|
|
|
11
56
|
/** Item layout (horizontal/vertical) */
|
|
12
|
-
layout?:
|
|
57
|
+
layout?: ListLayout | string;
|
|
13
58
|
|
|
14
59
|
/** Leading content (icon/avatar) */
|
|
15
60
|
leading?: string | HTMLElement;
|
|
@@ -70,7 +115,7 @@ export interface SelectionChangeEvent {
|
|
|
70
115
|
item?: ListItemData;
|
|
71
116
|
|
|
72
117
|
/** List selection type */
|
|
73
|
-
type:
|
|
118
|
+
type: ListType | string;
|
|
74
119
|
}
|
|
75
120
|
|
|
76
121
|
/**
|
|
@@ -92,10 +137,10 @@ export interface ListItemData {
|
|
|
92
137
|
*/
|
|
93
138
|
export interface ListConfig {
|
|
94
139
|
/** List selection type */
|
|
95
|
-
type?:
|
|
140
|
+
type?: ListType | string;
|
|
96
141
|
|
|
97
142
|
/** List layout */
|
|
98
|
-
layout?:
|
|
143
|
+
layout?: ListLayout | string;
|
|
99
144
|
|
|
100
145
|
/** List items */
|
|
101
146
|
items?: ListItemConfig[];
|