mtrl 0.1.3 → 0.2.0
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/README.md +70 -22
- package/index.ts +33 -0
- package/package.json +14 -5
- package/src/components/button/{styles.scss → _styles.scss} +2 -2
- package/src/components/button/api.ts +89 -0
- package/src/components/button/button.ts +50 -0
- package/src/components/button/config.ts +75 -0
- package/src/components/button/constants.ts +17 -0
- package/src/components/button/index.ts +4 -0
- package/src/components/button/types.ts +118 -0
- package/src/components/card/{styles.scss → _styles.scss} +79 -7
- package/src/components/card/{actions.js → actions.ts} +15 -18
- package/src/components/card/{api.js → api.ts} +33 -33
- package/src/components/card/card.ts +41 -0
- package/src/components/card/config.ts +99 -0
- package/src/components/card/{constants.js → constants.ts} +11 -10
- package/src/components/card/{content.js → content.ts} +15 -18
- package/src/components/card/{features.js → features.ts} +104 -94
- package/src/components/card/{header.js → header.ts} +21 -25
- package/src/components/card/index.ts +19 -0
- package/src/components/card/media.ts +52 -0
- package/src/components/card/types.ts +174 -0
- package/src/components/checkbox/api.ts +82 -0
- package/src/components/checkbox/checkbox.ts +75 -0
- package/src/components/checkbox/config.ts +90 -0
- package/src/components/checkbox/index.ts +4 -0
- package/src/components/checkbox/types.ts +146 -0
- package/src/components/chip/_styles.scss +372 -0
- package/src/components/chip/api.ts +115 -0
- package/src/components/chip/chip-set.ts +225 -0
- package/src/components/chip/chip.ts +82 -0
- package/src/components/chip/config.ts +92 -0
- package/src/components/chip/constants.ts +38 -0
- package/src/components/chip/index.ts +4 -0
- package/src/components/chip/types.ts +172 -0
- package/src/components/list/api.ts +72 -0
- package/src/components/list/config.ts +43 -0
- package/src/components/list/{constants.js → constants.ts} +34 -7
- package/src/components/list/features.ts +224 -0
- package/src/components/list/index.ts +14 -0
- package/src/components/list/list-item.ts +120 -0
- package/src/components/list/list.ts +37 -0
- package/src/components/list/types.ts +179 -0
- package/src/components/list/utils.ts +47 -0
- package/src/components/menu/api.ts +119 -0
- package/src/components/menu/config.ts +54 -0
- package/src/components/menu/constants.ts +154 -0
- package/src/components/menu/features/items-manager.ts +457 -0
- package/src/components/menu/features/keyboard-navigation.ts +133 -0
- package/src/components/menu/features/positioning.ts +127 -0
- package/src/components/menu/features/{visibility.js → visibility.ts} +66 -64
- package/src/components/menu/index.ts +14 -0
- package/src/components/menu/menu-item.ts +43 -0
- package/src/components/menu/menu.ts +53 -0
- package/src/components/menu/types.ts +178 -0
- package/src/components/navigation/api.ts +79 -0
- package/src/components/navigation/config.ts +61 -0
- package/src/components/navigation/{constants.js → constants.ts} +10 -10
- package/src/components/navigation/index.ts +14 -0
- package/src/components/navigation/nav-item.ts +148 -0
- package/src/components/navigation/navigation.ts +50 -0
- package/src/components/navigation/types.ts +212 -0
- package/src/components/progress/_styles.scss +204 -0
- package/src/components/progress/api.ts +179 -0
- package/src/components/progress/config.ts +124 -0
- package/src/components/progress/constants.ts +43 -0
- package/src/components/progress/index.ts +5 -0
- package/src/components/progress/progress.ts +163 -0
- package/src/components/progress/types.ts +102 -0
- package/src/components/snackbar/api.ts +162 -0
- package/src/components/snackbar/config.ts +62 -0
- package/src/components/snackbar/{constants.js → constants.ts} +21 -4
- package/src/components/snackbar/features.ts +76 -0
- package/src/components/snackbar/index.ts +4 -0
- package/src/components/snackbar/position.ts +71 -0
- package/src/components/snackbar/queue.ts +76 -0
- package/src/components/snackbar/snackbar.ts +60 -0
- package/src/components/snackbar/types.ts +58 -0
- package/src/components/switch/api.ts +77 -0
- package/src/components/switch/config.ts +74 -0
- package/src/components/switch/index.ts +4 -0
- package/src/components/switch/switch.ts +52 -0
- package/src/components/switch/types.ts +142 -0
- package/src/components/textfield/api.ts +72 -0
- package/src/components/textfield/config.ts +54 -0
- package/src/components/textfield/{constants.js → constants.ts} +38 -5
- package/src/components/textfield/index.ts +4 -0
- package/src/components/textfield/textfield.ts +50 -0
- package/src/components/textfield/types.ts +139 -0
- package/src/core/compose/base.ts +43 -0
- package/src/core/compose/component.ts +247 -0
- package/src/core/compose/features/checkable.ts +155 -0
- package/src/core/compose/features/disabled.ts +116 -0
- package/src/core/compose/features/events.ts +65 -0
- package/src/core/compose/features/icon.ts +67 -0
- package/src/core/compose/features/index.ts +35 -0
- package/src/core/compose/features/input.ts +174 -0
- package/src/core/compose/features/lifecycle.ts +139 -0
- package/src/core/compose/features/position.ts +94 -0
- package/src/core/compose/features/ripple.ts +55 -0
- package/src/core/compose/features/size.ts +29 -0
- package/src/core/compose/features/style.ts +31 -0
- package/src/core/compose/features/text.ts +44 -0
- package/src/core/compose/features/textinput.ts +225 -0
- package/src/core/compose/features/textlabel.ts +92 -0
- package/src/core/compose/features/track.ts +84 -0
- package/src/core/compose/features/variant.ts +29 -0
- package/src/core/compose/features/withEvents.ts +137 -0
- package/src/core/compose/index.ts +54 -0
- package/src/core/compose/{pipe.js → pipe.ts} +16 -11
- package/src/core/config/component-config.ts +136 -0
- package/src/core/config.ts +211 -0
- package/src/core/dom/{attributes.js → attributes.ts} +11 -11
- package/src/core/dom/classes.ts +60 -0
- package/src/core/dom/create.ts +188 -0
- package/src/core/dom/events.ts +209 -0
- package/src/core/dom/index.ts +10 -0
- package/src/core/dom/utils.ts +97 -0
- package/src/core/index.ts +111 -0
- package/src/core/state/disabled.ts +81 -0
- package/src/core/state/emitter.ts +94 -0
- package/src/core/state/events.ts +88 -0
- package/src/core/state/index.ts +16 -0
- package/src/core/state/lifecycle.ts +131 -0
- package/src/core/state/store.ts +197 -0
- package/src/core/utils/index.ts +45 -0
- package/src/core/utils/{mobile.js → mobile.ts} +48 -24
- package/src/core/utils/object.ts +41 -0
- package/src/core/utils/validate.ts +234 -0
- package/src/{index.js → index.ts} +3 -2
- package/index.js +0 -11
- package/src/components/button/api.js +0 -54
- package/src/components/button/button.js +0 -81
- package/src/components/button/config.js +0 -10
- package/src/components/button/constants.js +0 -63
- package/src/components/button/index.js +0 -2
- package/src/components/card/card.js +0 -102
- package/src/components/card/config.js +0 -16
- package/src/components/card/index.js +0 -7
- package/src/components/card/media.js +0 -56
- package/src/components/checkbox/api.js +0 -45
- package/src/components/checkbox/checkbox.js +0 -96
- package/src/components/checkbox/index.js +0 -2
- package/src/components/container/api.js +0 -42
- package/src/components/container/container.js +0 -45
- package/src/components/container/index.js +0 -2
- package/src/components/container/styles.scss +0 -66
- package/src/components/list/index.js +0 -2
- package/src/components/list/list-item.js +0 -147
- package/src/components/list/list.js +0 -267
- package/src/components/menu/api.js +0 -117
- package/src/components/menu/constants.js +0 -42
- package/src/components/menu/features/items-manager.js +0 -375
- package/src/components/menu/features/keyboard-navigation.js +0 -129
- package/src/components/menu/features/positioning.js +0 -125
- package/src/components/menu/index.js +0 -2
- package/src/components/menu/menu-item.js +0 -41
- package/src/components/menu/menu.js +0 -54
- package/src/components/navigation/api.js +0 -43
- package/src/components/navigation/index.js +0 -2
- package/src/components/navigation/nav-item.js +0 -137
- package/src/components/navigation/navigation.js +0 -55
- package/src/components/snackbar/api.js +0 -125
- package/src/components/snackbar/features.js +0 -69
- package/src/components/snackbar/index.js +0 -2
- package/src/components/snackbar/position.js +0 -63
- package/src/components/snackbar/queue.js +0 -74
- package/src/components/snackbar/snackbar.js +0 -70
- package/src/components/switch/api.js +0 -44
- package/src/components/switch/index.js +0 -2
- package/src/components/switch/switch.js +0 -71
- package/src/components/textfield/api.js +0 -49
- package/src/components/textfield/index.js +0 -2
- package/src/components/textfield/textfield.js +0 -68
- package/src/core/build/_ripple.scss +0 -79
- package/src/core/build/constants.js +0 -51
- package/src/core/build/icon.js +0 -78
- package/src/core/build/ripple.js +0 -159
- package/src/core/build/text.js +0 -54
- package/src/core/compose/base.js +0 -8
- package/src/core/compose/component.js +0 -225
- package/src/core/compose/features/checkable.js +0 -114
- package/src/core/compose/features/disabled.js +0 -64
- package/src/core/compose/features/events.js +0 -48
- package/src/core/compose/features/icon.js +0 -33
- package/src/core/compose/features/index.js +0 -20
- package/src/core/compose/features/input.js +0 -100
- package/src/core/compose/features/lifecycle.js +0 -69
- package/src/core/compose/features/position.js +0 -60
- package/src/core/compose/features/ripple.js +0 -32
- package/src/core/compose/features/size.js +0 -9
- package/src/core/compose/features/style.js +0 -12
- package/src/core/compose/features/text.js +0 -17
- package/src/core/compose/features/textinput.js +0 -114
- package/src/core/compose/features/textlabel.js +0 -28
- package/src/core/compose/features/track.js +0 -49
- package/src/core/compose/features/variant.js +0 -9
- package/src/core/compose/features/withEvents.js +0 -67
- package/src/core/compose/index.js +0 -16
- package/src/core/config.js +0 -140
- package/src/core/dom/classes.js +0 -70
- package/src/core/dom/create.js +0 -132
- package/src/core/dom/events.js +0 -175
- package/src/core/dom/index.js +0 -5
- package/src/core/dom/utils.js +0 -22
- package/src/core/index.js +0 -23
- package/src/core/state/disabled.js +0 -51
- package/src/core/state/emitter.js +0 -63
- package/src/core/state/events.js +0 -29
- package/src/core/state/index.js +0 -6
- package/src/core/state/lifecycle.js +0 -64
- package/src/core/state/store.js +0 -112
- package/src/core/utils/index.js +0 -39
- package/src/core/utils/object.js +0 -22
- package/src/core/utils/validate.js +0 -37
- /package/src/components/checkbox/{styles.scss → _styles.scss} +0 -0
- /package/src/components/checkbox/{constants.js → constants.ts} +0 -0
- /package/src/components/list/{styles.scss → _styles.scss} +0 -0
- /package/src/components/menu/{styles.scss → _styles.scss} +0 -0
- /package/src/components/navigation/{styles.scss → _styles.scss} +0 -0
- /package/src/components/snackbar/{styles.scss → _styles.scss} +0 -0
- /package/src/components/switch/{styles.scss → _styles.scss} +0 -0
- /package/src/components/switch/{constants.js → constants.ts} +0 -0
- /package/src/components/textfield/{styles.scss → _styles.scss} +0 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// src/components/chip/chip.ts
|
|
2
|
+
import { pipe } from '../../core/compose';
|
|
3
|
+
import { createBase, withElement } from '../../core/compose/component';
|
|
4
|
+
import {
|
|
5
|
+
withEvents,
|
|
6
|
+
withText,
|
|
7
|
+
withIcon,
|
|
8
|
+
withVariant,
|
|
9
|
+
withSize,
|
|
10
|
+
withRipple,
|
|
11
|
+
withDisabled,
|
|
12
|
+
withLifecycle
|
|
13
|
+
} from '../../core/compose/features';
|
|
14
|
+
import { withAPI } from './api';
|
|
15
|
+
import { ChipConfig, ChipComponent, BaseComponent } from './types';
|
|
16
|
+
import { createBaseConfig, getElementConfig, getApiConfig } from './config';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new Chip component
|
|
20
|
+
* @param {ChipConfig} config - Chip configuration object
|
|
21
|
+
* @returns {ChipComponent} Chip component instance
|
|
22
|
+
*/
|
|
23
|
+
const createChip = (config: ChipConfig = {}): ChipComponent => {
|
|
24
|
+
const baseConfig = createBaseConfig(config);
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
const chip = pipe(
|
|
28
|
+
createBase,
|
|
29
|
+
withEvents(),
|
|
30
|
+
withElement(getElementConfig(baseConfig)),
|
|
31
|
+
withVariant(baseConfig),
|
|
32
|
+
withSize(baseConfig),
|
|
33
|
+
withText(baseConfig),
|
|
34
|
+
withIcon({
|
|
35
|
+
...baseConfig,
|
|
36
|
+
position: 'start',
|
|
37
|
+
iconContent: config.leadingIcon || config.icon
|
|
38
|
+
}),
|
|
39
|
+
withDisabled(baseConfig),
|
|
40
|
+
withRipple(baseConfig),
|
|
41
|
+
withLifecycle(),
|
|
42
|
+
comp => withAPI(getApiConfig(comp))(comp)
|
|
43
|
+
)(baseConfig);
|
|
44
|
+
|
|
45
|
+
// Add trailing icon if provided
|
|
46
|
+
if (config.trailingIcon) {
|
|
47
|
+
const trailingIconElement = document.createElement('span');
|
|
48
|
+
trailingIconElement.className = `${baseConfig.prefix}-chip-trailing-icon`;
|
|
49
|
+
trailingIconElement.innerHTML = config.trailingIcon;
|
|
50
|
+
chip.element.appendChild(trailingIconElement);
|
|
51
|
+
|
|
52
|
+
// Add event listener for remove/close action if needed
|
|
53
|
+
if (config.onTrailingIconClick) {
|
|
54
|
+
trailingIconElement.addEventListener('click', (e) => {
|
|
55
|
+
e.stopPropagation();
|
|
56
|
+
config.onTrailingIconClick!(chip as ChipComponent);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Initialize selected state if needed
|
|
62
|
+
if (config.selected) {
|
|
63
|
+
(chip as ChipComponent).setSelected(true);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Handle selection callback
|
|
67
|
+
if (config.onSelect) {
|
|
68
|
+
chip.element.addEventListener('click', () => {
|
|
69
|
+
if (chip.element.getAttribute('aria-disabled') !== 'true') {
|
|
70
|
+
config.onSelect!(chip as ChipComponent);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return chip as ChipComponent;
|
|
76
|
+
} catch (error) {
|
|
77
|
+
console.error('Chip creation error:', error instanceof Error ? error.message : String(error));
|
|
78
|
+
throw new Error(`Failed to create chip: ${error instanceof Error ? error.message : String(error)}`);
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export default createChip;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// src/components/chip/config.ts
|
|
2
|
+
import {
|
|
3
|
+
createComponentConfig,
|
|
4
|
+
createElementConfig,
|
|
5
|
+
BaseComponentConfig
|
|
6
|
+
} from '../../core/config/component-config';
|
|
7
|
+
import { ChipConfig, BaseComponent } from './types';
|
|
8
|
+
import { CHIP_VARIANTS } from './constants';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Default configuration for the Chip component
|
|
12
|
+
*/
|
|
13
|
+
export const defaultConfig: ChipConfig = {
|
|
14
|
+
variant: CHIP_VARIANTS.FILLED,
|
|
15
|
+
ripple: true
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Creates the base configuration for Chip component
|
|
20
|
+
* @param {ChipConfig} config - User provided configuration
|
|
21
|
+
* @returns {ChipConfig} Complete configuration with defaults applied
|
|
22
|
+
*/
|
|
23
|
+
export const createBaseConfig = (config: ChipConfig = {}): ChipConfig =>
|
|
24
|
+
createComponentConfig(defaultConfig, config, 'chip') as ChipConfig;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Generates element configuration for the Chip component
|
|
28
|
+
* @param {ChipConfig} config - Chip configuration
|
|
29
|
+
* @returns {Object} Element configuration object for withElement
|
|
30
|
+
*/
|
|
31
|
+
export const getElementConfig = (config: ChipConfig) => {
|
|
32
|
+
// Create the attributes object
|
|
33
|
+
const attrs: Record<string, any> = {
|
|
34
|
+
role: 'button',
|
|
35
|
+
tabindex: '0'
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Only add aria-disabled attribute if needed
|
|
39
|
+
if (config.disabled === true) {
|
|
40
|
+
attrs['aria-disabled'] = 'true';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Add aria-selected if specified
|
|
44
|
+
if (config.selected === true) {
|
|
45
|
+
attrs['aria-selected'] = 'true';
|
|
46
|
+
} else if (config.selected === false) {
|
|
47
|
+
attrs['aria-selected'] = 'false';
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Define additional classes
|
|
51
|
+
const className = [
|
|
52
|
+
config.class,
|
|
53
|
+
config.selected ? `${config.prefix}-chip--selected` : null
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
return createElementConfig(config, {
|
|
57
|
+
tag: 'div',
|
|
58
|
+
attrs,
|
|
59
|
+
className,
|
|
60
|
+
forwardEvents: {
|
|
61
|
+
click: (component: BaseComponent) => component.element.getAttribute('aria-disabled') !== 'true',
|
|
62
|
+
keydown: (component: BaseComponent, event: KeyboardEvent) => {
|
|
63
|
+
// Handle space and enter key for accessibility
|
|
64
|
+
if (event.key === ' ' || event.key === 'Enter') {
|
|
65
|
+
event.preventDefault();
|
|
66
|
+
component.element.click();
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
return false;
|
|
70
|
+
},
|
|
71
|
+
focus: true,
|
|
72
|
+
blur: true
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Creates API configuration for the Chip component
|
|
79
|
+
* @param {BaseComponent} comp - Component with disabled and lifecycle features
|
|
80
|
+
* @returns {Object} API configuration object
|
|
81
|
+
*/
|
|
82
|
+
export const getApiConfig = (comp: BaseComponent) => ({
|
|
83
|
+
disabled: {
|
|
84
|
+
enable: () => comp.disabled?.enable(),
|
|
85
|
+
disable: () => comp.disabled?.disable()
|
|
86
|
+
},
|
|
87
|
+
lifecycle: {
|
|
88
|
+
destroy: () => comp.lifecycle?.destroy?.()
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
export default defaultConfig;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// src/components/chip/constants.ts
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Available variants for the Chip component
|
|
5
|
+
* @enum {string}
|
|
6
|
+
*/
|
|
7
|
+
export const CHIP_VARIANTS = {
|
|
8
|
+
/** Standard filled chip with solid background */
|
|
9
|
+
FILLED: 'filled',
|
|
10
|
+
|
|
11
|
+
/** Outlined chip with transparent background and border */
|
|
12
|
+
OUTLINED: 'outlined',
|
|
13
|
+
|
|
14
|
+
/** Elevated chip with shadow */
|
|
15
|
+
ELEVATED: 'elevated',
|
|
16
|
+
|
|
17
|
+
/** Assist chip for suggesting actions */
|
|
18
|
+
ASSIST: 'assist',
|
|
19
|
+
|
|
20
|
+
/** Filter chip for filtering content */
|
|
21
|
+
FILTER: 'filter',
|
|
22
|
+
|
|
23
|
+
/** Input chip for representing user input */
|
|
24
|
+
INPUT: 'input',
|
|
25
|
+
|
|
26
|
+
/** Suggestion chip for presenting options */
|
|
27
|
+
SUGGESTION: 'suggestion'
|
|
28
|
+
} as const;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Available sizes for the Chip component
|
|
32
|
+
* @enum {string}
|
|
33
|
+
*/
|
|
34
|
+
export const CHIP_SIZES = {
|
|
35
|
+
SMALL: 'small',
|
|
36
|
+
MEDIUM: 'medium',
|
|
37
|
+
LARGE: 'large'
|
|
38
|
+
} as const;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
// src/components/chip/types.ts
|
|
2
|
+
import { CHIP_VARIANTS, CHIP_SIZES } from './constants';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Configuration interface for the Chip component
|
|
6
|
+
*/
|
|
7
|
+
export interface ChipConfig {
|
|
8
|
+
/** Chip variant (filled, outlined, elevated, assist, filter, input, suggestion) */
|
|
9
|
+
variant?: keyof typeof CHIP_VARIANTS | string;
|
|
10
|
+
|
|
11
|
+
/** Chip size (small, medium, large) */
|
|
12
|
+
size?: keyof typeof CHIP_SIZES | string;
|
|
13
|
+
|
|
14
|
+
/** Whether the chip is initially disabled */
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
|
|
17
|
+
/** Whether the chip is initially selected */
|
|
18
|
+
selected?: boolean;
|
|
19
|
+
|
|
20
|
+
/** Initial chip text content */
|
|
21
|
+
text?: string;
|
|
22
|
+
|
|
23
|
+
/** Initial chip icon HTML content */
|
|
24
|
+
icon?: string;
|
|
25
|
+
|
|
26
|
+
/** Optional leading icon HTML content */
|
|
27
|
+
leadingIcon?: string;
|
|
28
|
+
|
|
29
|
+
/** Optional trailing icon HTML content */
|
|
30
|
+
trailingIcon?: string;
|
|
31
|
+
|
|
32
|
+
/** Additional CSS classes */
|
|
33
|
+
class?: string;
|
|
34
|
+
|
|
35
|
+
/** Chip value attribute */
|
|
36
|
+
value?: string;
|
|
37
|
+
|
|
38
|
+
/** Whether to enable ripple effect */
|
|
39
|
+
ripple?: boolean;
|
|
40
|
+
|
|
41
|
+
/** Ripple effect configuration */
|
|
42
|
+
rippleConfig?: {
|
|
43
|
+
duration?: number;
|
|
44
|
+
timing?: string;
|
|
45
|
+
opacity?: [string, string];
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/** Function called when the trailing icon is clicked */
|
|
49
|
+
onTrailingIconClick?: (chip: ChipComponent) => void;
|
|
50
|
+
|
|
51
|
+
/** Function called when the chip is selected */
|
|
52
|
+
onSelect?: (chip: ChipComponent) => void;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Icon API interface
|
|
57
|
+
*/
|
|
58
|
+
export interface IconAPI {
|
|
59
|
+
setIcon: (html: string) => IconAPI;
|
|
60
|
+
getIcon: () => string;
|
|
61
|
+
getElement: () => HTMLElement | null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Text API interface
|
|
66
|
+
*/
|
|
67
|
+
export interface TextAPI {
|
|
68
|
+
setText: (content: string) => TextAPI;
|
|
69
|
+
getText: () => string;
|
|
70
|
+
getElement: () => HTMLElement | null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Chip component interface
|
|
75
|
+
*/
|
|
76
|
+
export interface ChipComponent {
|
|
77
|
+
element: HTMLElement;
|
|
78
|
+
text: TextAPI;
|
|
79
|
+
icon: IconAPI;
|
|
80
|
+
disabled: {
|
|
81
|
+
enable: () => void;
|
|
82
|
+
disable: () => void;
|
|
83
|
+
isDisabled: () => boolean;
|
|
84
|
+
};
|
|
85
|
+
lifecycle: {
|
|
86
|
+
destroy: () => void;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
/** Gets the class with the specified name */
|
|
90
|
+
getClass: (name: string) => string;
|
|
91
|
+
|
|
92
|
+
/** Gets the chip's value */
|
|
93
|
+
getValue: () => string | null;
|
|
94
|
+
|
|
95
|
+
/** Sets the chip's value */
|
|
96
|
+
setValue: (value: string) => ChipComponent;
|
|
97
|
+
|
|
98
|
+
/** Enables the chip */
|
|
99
|
+
enable: () => ChipComponent;
|
|
100
|
+
|
|
101
|
+
/** Disables the chip */
|
|
102
|
+
disable: () => ChipComponent;
|
|
103
|
+
|
|
104
|
+
/** Sets the chip's text content */
|
|
105
|
+
setText: (content: string) => ChipComponent;
|
|
106
|
+
|
|
107
|
+
/** Gets the chip's text content */
|
|
108
|
+
getText: () => string;
|
|
109
|
+
|
|
110
|
+
/** Sets the chip's icon */
|
|
111
|
+
setIcon: (icon: string) => ChipComponent;
|
|
112
|
+
|
|
113
|
+
/** Gets the chip's icon */
|
|
114
|
+
getIcon: () => string;
|
|
115
|
+
|
|
116
|
+
/** Sets the chip's trailing icon */
|
|
117
|
+
setTrailingIcon: (icon: string) => ChipComponent;
|
|
118
|
+
|
|
119
|
+
/** Checks if the chip is selected */
|
|
120
|
+
isSelected: () => boolean;
|
|
121
|
+
|
|
122
|
+
/** Sets the chip's selected state */
|
|
123
|
+
setSelected: (selected: boolean) => ChipComponent;
|
|
124
|
+
|
|
125
|
+
/** Toggles the chip's selected state */
|
|
126
|
+
toggleSelected: () => ChipComponent;
|
|
127
|
+
|
|
128
|
+
/** Destroys the chip component and cleans up resources */
|
|
129
|
+
destroy: () => void;
|
|
130
|
+
|
|
131
|
+
/** Adds event listener */
|
|
132
|
+
on: (event: string, handler: Function) => ChipComponent;
|
|
133
|
+
|
|
134
|
+
/** Removes event listener */
|
|
135
|
+
off: (event: string, handler: Function) => ChipComponent;
|
|
136
|
+
|
|
137
|
+
/** Add CSS classes */
|
|
138
|
+
addClass: (...classes: string[]) => ChipComponent;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* API options interface
|
|
143
|
+
*/
|
|
144
|
+
export interface ApiOptions {
|
|
145
|
+
disabled: {
|
|
146
|
+
enable: () => void;
|
|
147
|
+
disable: () => void;
|
|
148
|
+
};
|
|
149
|
+
lifecycle: {
|
|
150
|
+
destroy: () => void;
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Base component interface
|
|
156
|
+
*/
|
|
157
|
+
export interface BaseComponent {
|
|
158
|
+
element: HTMLElement;
|
|
159
|
+
getClass: (name?: string) => string;
|
|
160
|
+
config: any;
|
|
161
|
+
text?: TextAPI;
|
|
162
|
+
icon?: IconAPI;
|
|
163
|
+
disabled?: {
|
|
164
|
+
enable: () => void;
|
|
165
|
+
disable: () => void;
|
|
166
|
+
isDisabled: () => boolean;
|
|
167
|
+
};
|
|
168
|
+
lifecycle?: {
|
|
169
|
+
destroy: () => void;
|
|
170
|
+
};
|
|
171
|
+
[key: string]: any;
|
|
172
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// src/components/list/api.ts
|
|
2
|
+
import { BaseComponent, ListComponent, ListItemConfig } from './types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* API options interface
|
|
6
|
+
*/
|
|
7
|
+
interface ApiOptions {
|
|
8
|
+
disabled: {
|
|
9
|
+
enable: () => any;
|
|
10
|
+
disable: () => any;
|
|
11
|
+
};
|
|
12
|
+
lifecycle: {
|
|
13
|
+
destroy: () => void;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Enhances list component with API methods
|
|
19
|
+
* @param {ApiOptions} options - API configuration
|
|
20
|
+
* @returns {Function} Higher-order function that adds API methods to component
|
|
21
|
+
*/
|
|
22
|
+
export const withAPI = ({ disabled, lifecycle }: ApiOptions) =>
|
|
23
|
+
(component: BaseComponent): ListComponent => ({
|
|
24
|
+
...component as any,
|
|
25
|
+
element: component.element,
|
|
26
|
+
items: component.items as Map<string, any>,
|
|
27
|
+
selectedItems: component.selectedItems as Set<string>,
|
|
28
|
+
|
|
29
|
+
// Selection management
|
|
30
|
+
getSelected(): string[] {
|
|
31
|
+
return component.getSelected?.() || [];
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
setSelected(ids: string[]): void {
|
|
35
|
+
component.setSelected?.(ids);
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
// Item management
|
|
39
|
+
addItem(itemConfig: ListItemConfig): void {
|
|
40
|
+
component.addItem?.(itemConfig);
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
removeItem(id: string): void {
|
|
44
|
+
component.removeItem?.(id);
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
// Event handling
|
|
48
|
+
on(event: string, handler: Function): ListComponent {
|
|
49
|
+
component.on?.(event, handler);
|
|
50
|
+
return this;
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
off(event: string, handler: Function): ListComponent {
|
|
54
|
+
component.off?.(event, handler);
|
|
55
|
+
return this;
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
// State management
|
|
59
|
+
enable(): ListComponent {
|
|
60
|
+
disabled.enable();
|
|
61
|
+
return this;
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
disable(): ListComponent {
|
|
65
|
+
disabled.disable();
|
|
66
|
+
return this;
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
destroy(): void {
|
|
70
|
+
lifecycle.destroy();
|
|
71
|
+
}
|
|
72
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// src/components/list/config.ts
|
|
2
|
+
import {
|
|
3
|
+
createComponentConfig,
|
|
4
|
+
createElementConfig,
|
|
5
|
+
BaseComponentConfig
|
|
6
|
+
} from '../../core/config/component-config';
|
|
7
|
+
import { ListConfig, BaseComponent } from './types';
|
|
8
|
+
import { LIST_TYPES, LIST_LAYOUTS } from './constants';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Default configuration for the List component
|
|
12
|
+
*/
|
|
13
|
+
export const defaultConfig: ListConfig = {
|
|
14
|
+
type: LIST_TYPES.DEFAULT,
|
|
15
|
+
layout: LIST_LAYOUTS.HORIZONTAL,
|
|
16
|
+
items: []
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Creates the base configuration for List component
|
|
21
|
+
* @param {ListConfig} config - User provided configuration
|
|
22
|
+
* @returns {ListConfig} Complete configuration with defaults applied
|
|
23
|
+
*/
|
|
24
|
+
export const createBaseConfig = (config: ListConfig = {}): ListConfig =>
|
|
25
|
+
createComponentConfig(defaultConfig, config, 'list') as ListConfig;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Generates element configuration for the List component
|
|
29
|
+
* @param {ListConfig} config - List configuration
|
|
30
|
+
* @returns {Object} Element configuration object for withElement
|
|
31
|
+
*/
|
|
32
|
+
export const getElementConfig = (config: ListConfig) =>
|
|
33
|
+
createElementConfig(config, {
|
|
34
|
+
tag: 'div',
|
|
35
|
+
role: config.type === LIST_TYPES.DEFAULT ? 'list' : 'listbox',
|
|
36
|
+
attrs: {
|
|
37
|
+
'aria-multiselectable': config.type === LIST_TYPES.MULTI_SELECT ? 'true' : undefined
|
|
38
|
+
},
|
|
39
|
+
componentName: 'list',
|
|
40
|
+
className: config.class
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export default defaultConfig;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// src/components/list/constants.
|
|
1
|
+
// src/components/list/constants.ts
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* List types/variants
|
|
@@ -8,7 +8,7 @@ export const LIST_TYPES = {
|
|
|
8
8
|
SINGLE_SELECT: 'single', // Single selection list
|
|
9
9
|
MULTI_SELECT: 'multi', // Multiple selection list
|
|
10
10
|
RADIO: 'radio' // Radio button list
|
|
11
|
-
}
|
|
11
|
+
} as const;
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* List layout variants
|
|
@@ -16,7 +16,15 @@ export const LIST_TYPES = {
|
|
|
16
16
|
export const LIST_LAYOUTS = {
|
|
17
17
|
HORIZONTAL: 'horizontal', // Default horizontal layout
|
|
18
18
|
VERTICAL: 'vertical' // Items with more content stacked vertically
|
|
19
|
-
}
|
|
19
|
+
} as const;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* List item layouts
|
|
23
|
+
*/
|
|
24
|
+
export const LIST_ITEM_LAYOUTS = {
|
|
25
|
+
HORIZONTAL: 'horizontal', // Default horizontal layout
|
|
26
|
+
VERTICAL: 'vertical' // Stacked layout with vertical alignment
|
|
27
|
+
} as const;
|
|
20
28
|
|
|
21
29
|
/**
|
|
22
30
|
* List element class names
|
|
@@ -27,11 +35,20 @@ export const LIST_CLASSES = {
|
|
|
27
35
|
GROUP_TITLE: 'list-group-title',
|
|
28
36
|
DIVIDER: 'list-divider',
|
|
29
37
|
SECTION: 'list-section',
|
|
30
|
-
SECTION_TITLE: 'list-section-title'
|
|
31
|
-
|
|
38
|
+
SECTION_TITLE: 'list-section-title',
|
|
39
|
+
ITEM: 'list-item',
|
|
40
|
+
ITEM_CONTENT: 'list-item-content',
|
|
41
|
+
ITEM_LEADING: 'list-item-leading',
|
|
42
|
+
ITEM_TEXT: 'list-item-text',
|
|
43
|
+
ITEM_OVERLINE: 'list-item-overline',
|
|
44
|
+
ITEM_HEADLINE: 'list-item-headline',
|
|
45
|
+
ITEM_SUPPORTING: 'list-item-supporting',
|
|
46
|
+
ITEM_META: 'list-item-meta',
|
|
47
|
+
ITEM_TRAILING: 'list-item-trailing'
|
|
48
|
+
} as const;
|
|
32
49
|
|
|
33
50
|
/**
|
|
34
|
-
* List
|
|
51
|
+
* List validation schema
|
|
35
52
|
*/
|
|
36
53
|
export const LIST_SCHEMA = {
|
|
37
54
|
type: 'object',
|
|
@@ -86,4 +103,14 @@ export const LIST_SCHEMA = {
|
|
|
86
103
|
optional: true
|
|
87
104
|
}
|
|
88
105
|
}
|
|
89
|
-
}
|
|
106
|
+
} as const;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* List item states
|
|
110
|
+
*/
|
|
111
|
+
export const LIST_ITEM_STATES = {
|
|
112
|
+
SELECTED: 'selected',
|
|
113
|
+
DISABLED: 'disabled',
|
|
114
|
+
FOCUSED: 'focused',
|
|
115
|
+
HOVERED: 'hovered'
|
|
116
|
+
} as const;
|