mtrl 0.2.7 → 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/package.json +14 -3
- package/server.ts +86 -0
- package/src/components/badge/api.ts +23 -14
- package/src/components/badge/badge.ts +2 -2
- package/src/components/badge/config.ts +10 -11
- package/src/components/badge/features.ts +15 -10
- package/src/components/badge/index.ts +27 -2
- package/src/components/badge/types.ts +28 -8
- package/src/components/bottom-app-bar/bottom-app-bar.ts +2 -44
- package/src/components/bottom-app-bar/config.ts +1 -45
- package/src/components/bottom-app-bar/index.ts +7 -1
- package/src/components/bottom-app-bar/types.ts +7 -1
- package/src/components/button/button.ts +0 -1
- package/src/components/button/config.ts +1 -2
- package/src/components/button/index.ts +10 -2
- package/src/components/button/types.ts +14 -2
- package/src/components/card/config.ts +17 -9
- package/src/components/card/content.ts +8 -10
- package/src/components/card/features.ts +4 -6
- package/src/components/card/index.ts +29 -2
- package/src/components/card/types.ts +6 -23
- 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 +18 -25
- package/src/components/datepicker/config.ts +9 -12
- package/src/components/datepicker/datepicker.ts +7 -12
- package/src/components/datepicker/index.ts +10 -7
- package/src/components/datepicker/render.ts +16 -18
- package/src/components/datepicker/types.ts +164 -35
- package/src/components/datepicker/utils.ts +1 -2
- package/src/components/dialog/api.ts +7 -8
- package/src/components/dialog/config.ts +3 -4
- package/src/components/dialog/features.ts +56 -22
- package/src/components/dialog/index.ts +38 -8
- package/src/components/dialog/types.ts +33 -10
- package/src/components/divider/index.ts +5 -1
- package/src/components/extended-fab/config.ts +6 -2
- package/src/components/extended-fab/index.ts +7 -2
- package/src/components/extended-fab/types.ts +21 -4
- package/src/components/fab/config.ts +3 -4
- package/src/components/fab/fab.ts +1 -1
- package/src/components/fab/index.ts +7 -2
- package/src/components/fab/types.ts +21 -4
- 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/config.ts +22 -10
- package/src/components/navigation/features/items.ts +31 -27
- package/src/components/navigation/index.ts +0 -6
- package/src/components/navigation/nav-item.ts +12 -24
- package/src/components/navigation/navigation.ts +4 -6
- package/src/components/navigation/types.ts +228 -203
- 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/config.ts +1 -2
- package/src/components/search/features/search.ts +14 -15
- package/src/components/search/features/states.ts +5 -1
- package/src/components/search/features/structure.ts +3 -4
- package/src/components/search/index.ts +0 -3
- package/src/components/search/types.ts +18 -6
- package/src/components/segmented-button/config.ts +20 -7
- package/src/components/segmented-button/segment.ts +6 -7
- package/src/components/segmented-button/segmented-button.ts +4 -5
- package/src/components/segmented-button/types.ts +37 -2
- package/src/components/slider/types.ts +34 -8
- 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/index.ts +0 -15
- package/src/components/tabs/tab-api.ts +12 -4
- package/src/components/tabs/tab.ts +18 -6
- package/src/components/tabs/types.ts +13 -3
- 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/api.ts +1 -1
- package/src/components/timepicker/clockdial.ts +1 -1
- package/src/components/timepicker/config.ts +102 -4
- package/src/components/timepicker/index.ts +1 -6
- package/src/components/timepicker/render.ts +1 -1
- package/src/components/timepicker/timepicker.ts +1 -1
- 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/core/compose/features/textlabel.ts +0 -3
- package/src/{components/tabs/_styles.scss → styles/components/_tabs.scss} +1 -1
- package/src/{components/textfield/_styles.scss → styles/components/_textfield.scss} +70 -67
- package/src/styles/main.scss +98 -49
- package/src/components/badge/constants.ts +0 -40
- package/src/components/button/constants.ts +0 -11
- package/src/components/card/constants.ts +0 -84
- package/src/components/datepicker/constants.ts +0 -98
- package/src/components/dialog/constants.ts +0 -32
- package/src/components/extended-fab/constants.ts +0 -36
- package/src/components/fab/constants.ts +0 -41
- package/src/components/menu/constants.ts +0 -154
- package/src/components/navigation/constants.ts +0 -200
- package/src/components/progress/constants.ts +0 -29
- package/src/components/search/constants.ts +0 -21
- package/src/components/segmented-button/constants.ts +0 -42
- package/src/components/switch/constants.ts +0 -80
- package/src/components/tabs/constants.ts +0 -89
- package/src/components/timepicker/constants.ts +0 -138
- /package/src/{components/badge/_styles.scss → styles/components/_badge.scss} +0 -0
- /package/src/{components/bottom-app-bar/_styles.scss → styles/components/_bottom-app-bar.scss} +0 -0
- /package/src/{components/button/_styles.scss → styles/components/_button.scss} +0 -0
- /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/checkbox/_styles.scss → styles/components/_checkbox.scss} +0 -0
- /package/src/{components/chip/_styles.scss → styles/components/_chip.scss} +0 -0
- /package/src/{components/datepicker/_styles.scss → styles/components/_datepicker.scss} +0 -0
- /package/src/{components/dialog/_styles.scss → styles/components/_dialog.scss} +0 -0
- /package/src/{components/divider/_styles.scss → styles/components/_divider.scss} +0 -0
- /package/src/{components/extended-fab/_styles.scss → styles/components/_extended-fab.scss} +0 -0
- /package/src/{components/fab/_styles.scss → styles/components/_fab.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/navigation/_styles.scss → styles/components/_navigation.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/search/_styles.scss → styles/components/_search.scss} +0 -0
- /package/src/{components/segmented-button/_styles.scss → styles/components/_segmented-button.scss} +0 -0
- /package/src/{components/sheet/_styles.scss → styles/components/_sheet.scss} +0 -0
- /package/src/{components/slider/_styles.scss → styles/components/_slider.scss} +0 -0
- /package/src/{components/snackbar/_styles.scss → styles/components/_snackbar.scss} +0 -0
- /package/src/{components/switch/_styles.scss → styles/components/_switch.scss} +0 -0
- /package/src/{components/timepicker/_styles.scss → styles/components/_timepicker.scss} +0 -0
- /package/src/{components/tooltip/_styles.scss → styles/components/_tooltip.scss} +0 -0
- /package/src/{components/top-app-bar/_styles.scss → styles/components/_top-app-bar.scss} +0 -0
- /package/src/styles/utilities/{_color.scss → _colors.scss} +0 -0
|
@@ -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;
|
|
@@ -64,7 +87,7 @@ export interface DialogConfig {
|
|
|
64
87
|
|
|
65
88
|
/** Event handlers for dialog events */
|
|
66
89
|
on?: {
|
|
67
|
-
[key in
|
|
90
|
+
[key in DialogEventType]?: (event: DialogEvent) => void;
|
|
68
91
|
};
|
|
69
92
|
}
|
|
70
93
|
|
|
@@ -164,16 +187,16 @@ export interface DialogComponent {
|
|
|
164
187
|
getButtons: () => DialogButton[];
|
|
165
188
|
|
|
166
189
|
/** Sets footer alignment */
|
|
167
|
-
setFooterAlignment: (alignment:
|
|
190
|
+
setFooterAlignment: (alignment: DialogFooterAlignment | string) => DialogComponent;
|
|
168
191
|
|
|
169
192
|
/** Sets dialog size */
|
|
170
|
-
setSize: (size:
|
|
193
|
+
setSize: (size: DialogSize | string) => DialogComponent;
|
|
171
194
|
|
|
172
195
|
/** Adds event listener */
|
|
173
|
-
on: (event:
|
|
196
|
+
on: (event: DialogEventType | string, handler: (event: DialogEvent) => void) => DialogComponent;
|
|
174
197
|
|
|
175
198
|
/** Removes event listener */
|
|
176
|
-
off: (event:
|
|
199
|
+
off: (event: DialogEventType | string, handler: (event: DialogEvent) => void) => DialogComponent;
|
|
177
200
|
|
|
178
201
|
/** Gets dialog header element */
|
|
179
202
|
getHeaderElement: () => HTMLElement | null;
|
|
@@ -220,5 +243,5 @@ export interface DialogConfirmOptions {
|
|
|
220
243
|
cancelVariant?: string;
|
|
221
244
|
|
|
222
245
|
/** Dialog size */
|
|
223
|
-
size?:
|
|
246
|
+
size?: DialogSize | string;
|
|
224
247
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
// src/components/divider/index.ts
|
|
2
2
|
|
|
3
|
-
export
|
|
3
|
+
// Use a more explicit export to avoid bundler confusion
|
|
4
|
+
import { createDivider } from './divider';
|
|
5
|
+
export { createDivider };
|
|
6
|
+
|
|
7
|
+
// Export types
|
|
4
8
|
export type { DividerConfig } from './config';
|
|
5
9
|
export type { DividerComponent } from './types';
|
|
@@ -5,13 +5,12 @@ import {
|
|
|
5
5
|
BaseComponentConfig
|
|
6
6
|
} from '../../core/config/component-config';
|
|
7
7
|
import { ExtendedFabConfig } from './types';
|
|
8
|
-
import { FAB_VARIANTS, EXTENDED_FAB_WIDTH } from './constants';
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
10
|
* Default configuration for the Extended FAB component
|
|
12
11
|
*/
|
|
13
12
|
export const defaultConfig: ExtendedFabConfig = {
|
|
14
|
-
variant:
|
|
13
|
+
variant: 'primary',
|
|
15
14
|
type: 'button',
|
|
16
15
|
ripple: true,
|
|
17
16
|
iconPosition: 'start',
|
|
@@ -41,6 +40,11 @@ export const getElementConfig = (config: ExtendedFabConfig) => {
|
|
|
41
40
|
// Build class list
|
|
42
41
|
let classNames = [`${config.prefix}-extended-fab`];
|
|
43
42
|
|
|
43
|
+
// Add variant class
|
|
44
|
+
if (config.variant) {
|
|
45
|
+
classNames.push(`${config.prefix}-extended-fab--${config.variant}`);
|
|
46
|
+
}
|
|
47
|
+
|
|
44
48
|
// Add width class
|
|
45
49
|
if (config.width) {
|
|
46
50
|
classNames.push(`${config.prefix}-extended-fab--${config.width}`);
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
// src/components/extended-fab/index.ts
|
|
2
2
|
export { default, default as createExtendedFab } from './extended-fab';
|
|
3
|
-
export {
|
|
4
|
-
|
|
3
|
+
export {
|
|
4
|
+
ExtendedFabConfig,
|
|
5
|
+
ExtendedFabComponent,
|
|
6
|
+
ExtendedFabVariant,
|
|
7
|
+
ExtendedFabWidth,
|
|
8
|
+
ExtendedFabPosition
|
|
9
|
+
} from './types';
|
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
// src/components/extended-fab/types.ts
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Extended FAB variants
|
|
5
|
+
* @category Components
|
|
6
|
+
*/
|
|
7
|
+
export type ExtendedFabVariant = 'primary' | 'secondary' | 'tertiary' | 'surface';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Extended FAB width behavior
|
|
11
|
+
* @category Components
|
|
12
|
+
*/
|
|
13
|
+
export type ExtendedFabWidth = 'fixed' | 'fluid';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Extended FAB position
|
|
17
|
+
* @category Components
|
|
18
|
+
*/
|
|
19
|
+
export type ExtendedFabPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
|
|
3
20
|
|
|
4
21
|
/**
|
|
5
22
|
* Configuration interface for the Extended FAB component
|
|
@@ -10,7 +27,7 @@ export interface ExtendedFabConfig {
|
|
|
10
27
|
* Extended FAB variant that determines visual styling
|
|
11
28
|
* @default 'primary'
|
|
12
29
|
*/
|
|
13
|
-
variant?:
|
|
30
|
+
variant?: ExtendedFabVariant | string;
|
|
14
31
|
|
|
15
32
|
/**
|
|
16
33
|
* Whether the Extended FAB is initially disabled
|
|
@@ -57,7 +74,7 @@ export interface ExtendedFabConfig {
|
|
|
57
74
|
* Position of the Extended FAB on the screen
|
|
58
75
|
* @example 'bottom-right'
|
|
59
76
|
*/
|
|
60
|
-
position?:
|
|
77
|
+
position?: ExtendedFabPosition | string;
|
|
61
78
|
|
|
62
79
|
/**
|
|
63
80
|
* Button type attribute
|
|
@@ -109,7 +126,7 @@ export interface ExtendedFabConfig {
|
|
|
109
126
|
* Width behavior of the Extended FAB
|
|
110
127
|
* @default 'fixed'
|
|
111
128
|
*/
|
|
112
|
-
width?:
|
|
129
|
+
width?: ExtendedFabWidth | string;
|
|
113
130
|
|
|
114
131
|
/**
|
|
115
132
|
* Whether the Extended FAB should collapse to a standard FAB on scroll
|
|
@@ -5,14 +5,13 @@ import {
|
|
|
5
5
|
BaseComponentConfig
|
|
6
6
|
} from '../../core/config/component-config';
|
|
7
7
|
import { FabConfig } from './types';
|
|
8
|
-
import { FAB_VARIANTS, FAB_SIZES } from './constants';
|
|
9
8
|
|
|
10
9
|
/**
|
|
11
10
|
* Default configuration for the FAB component
|
|
12
11
|
*/
|
|
13
12
|
export const defaultConfig: FabConfig = {
|
|
14
|
-
variant:
|
|
15
|
-
size:
|
|
13
|
+
variant: 'primary',
|
|
14
|
+
size: 'default',
|
|
16
15
|
type: 'button',
|
|
17
16
|
ripple: true
|
|
18
17
|
};
|
|
@@ -38,7 +37,7 @@ export const getElementConfig = (config: FabConfig) => {
|
|
|
38
37
|
};
|
|
39
38
|
|
|
40
39
|
// Add size class
|
|
41
|
-
const fabSizeClass = `${config.prefix}-fab--${config.size ||
|
|
40
|
+
const fabSizeClass = `${config.prefix}-fab--${config.size || 'default'}`;
|
|
42
41
|
let classNames = [fabSizeClass];
|
|
43
42
|
|
|
44
43
|
// Add animation class if specified
|
|
@@ -29,7 +29,7 @@ import { createBaseConfig, getElementConfig, getApiConfig } from './config';
|
|
|
29
29
|
*
|
|
30
30
|
* // Create a small FAB with a custom position
|
|
31
31
|
* const smallFab = createFab({
|
|
32
|
-
* size:
|
|
32
|
+
* size: 'small',
|
|
33
33
|
* icon: '<svg>...</svg>',
|
|
34
34
|
* variant: 'secondary',
|
|
35
35
|
* position: 'bottom-right'
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
// src/components/fab/index.ts
|
|
2
2
|
export { default, default as createFab } from './fab';
|
|
3
|
-
export {
|
|
4
|
-
|
|
3
|
+
export {
|
|
4
|
+
FabConfig,
|
|
5
|
+
FabComponent,
|
|
6
|
+
FabVariant,
|
|
7
|
+
FabSize,
|
|
8
|
+
FabPosition
|
|
9
|
+
} from './types';
|
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
// src/components/fab/types.ts
|
|
2
|
-
|
|
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';
|
|
3
20
|
|
|
4
21
|
/**
|
|
5
22
|
* Configuration interface for the FAB component
|
|
@@ -10,13 +27,13 @@ export interface FabConfig {
|
|
|
10
27
|
* FAB variant that determines visual styling
|
|
11
28
|
* @default 'primary'
|
|
12
29
|
*/
|
|
13
|
-
variant?:
|
|
30
|
+
variant?: FabVariant | string;
|
|
14
31
|
|
|
15
32
|
/**
|
|
16
33
|
* FAB size variant
|
|
17
34
|
* @default 'default'
|
|
18
35
|
*/
|
|
19
|
-
size?:
|
|
36
|
+
size?: FabSize | string;
|
|
20
37
|
|
|
21
38
|
/**
|
|
22
39
|
* Whether the FAB is initially disabled
|
|
@@ -51,7 +68,7 @@ export interface FabConfig {
|
|
|
51
68
|
* Position of the FAB on the screen
|
|
52
69
|
* @example 'bottom-right'
|
|
53
70
|
*/
|
|
54
|
-
position?:
|
|
71
|
+
position?: FabPosition | string;
|
|
55
72
|
|
|
56
73
|
/**
|
|
57
74
|
* Button type attribute
|
|
@@ -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[];
|
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
// src/components/list/utils.ts
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
// List element class names as strings for internal use
|
|
4
|
+
const LIST_CLASS_NAMES = {
|
|
5
|
+
ROOT: 'list',
|
|
6
|
+
GROUP: 'list-group',
|
|
7
|
+
GROUP_TITLE: 'list-group-title',
|
|
8
|
+
DIVIDER: 'list-divider',
|
|
9
|
+
SECTION: 'list-section',
|
|
10
|
+
SECTION_TITLE: 'list-section-title',
|
|
11
|
+
ITEM: 'list-item',
|
|
12
|
+
ITEM_CONTENT: 'list-item-content',
|
|
13
|
+
ITEM_LEADING: 'list-item-leading',
|
|
14
|
+
ITEM_TEXT: 'list-item-text',
|
|
15
|
+
ITEM_OVERLINE: 'list-item-overline',
|
|
16
|
+
ITEM_HEADLINE: 'list-item-headline',
|
|
17
|
+
ITEM_SUPPORTING: 'list-item-supporting',
|
|
18
|
+
ITEM_META: 'list-item-meta',
|
|
19
|
+
ITEM_TRAILING: 'list-item-trailing'
|
|
20
|
+
};
|
|
3
21
|
|
|
4
22
|
/**
|
|
5
23
|
* Creates a divider element
|
|
@@ -8,7 +26,7 @@ import { LIST_CLASSES } from './constants';
|
|
|
8
26
|
*/
|
|
9
27
|
export const createDivider = (prefix: string): HTMLElement => {
|
|
10
28
|
const divider = document.createElement('div');
|
|
11
|
-
divider.className = `${prefix}-${
|
|
29
|
+
divider.className = `${prefix}-${LIST_CLASS_NAMES.DIVIDER}`;
|
|
12
30
|
divider.setAttribute('role', 'separator');
|
|
13
31
|
return divider;
|
|
14
32
|
};
|
|
@@ -21,7 +39,7 @@ export const createDivider = (prefix: string): HTMLElement => {
|
|
|
21
39
|
*/
|
|
22
40
|
export const createSectionTitle = (title: string, prefix: string): HTMLElement => {
|
|
23
41
|
const titleEl = document.createElement('div');
|
|
24
|
-
titleEl.className = `${prefix}-${
|
|
42
|
+
titleEl.className = `${prefix}-${LIST_CLASS_NAMES.SECTION_TITLE}`;
|
|
25
43
|
titleEl.textContent = title;
|
|
26
44
|
return titleEl;
|
|
27
45
|
};
|
|
@@ -44,4 +62,13 @@ export const createElement = (tag: string, className: string, content?: string |
|
|
|
44
62
|
}
|
|
45
63
|
}
|
|
46
64
|
return element;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Gets the class name for a list element
|
|
69
|
+
* @param {string} element - Element name
|
|
70
|
+
* @returns {string} The class name string
|
|
71
|
+
*/
|
|
72
|
+
export const getListClass = (element: keyof typeof LIST_CLASS_NAMES): string => {
|
|
73
|
+
return LIST_CLASS_NAMES[element];
|
|
47
74
|
};
|