mtrl 0.3.0 → 0.3.2
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/.env +15 -0
- package/CONTRIBUTING.md +8 -8
- package/DOCS.md +3 -3
- package/README.md +43 -20
- package/TESTING.md +128 -18
- package/dist/index.js +14865 -0
- package/git-user-stats.js +545 -0
- package/index.ts +9 -69
- package/package.json +10 -3
- package/src/components/badge/api.ts +15 -1
- package/src/components/badge/badge.ts +43 -4
- package/src/components/badge/config.ts +40 -8
- package/src/components/badge/index.ts +64 -3
- package/src/components/badge/types.ts +175 -33
- package/src/components/button/api.ts +63 -1
- package/src/components/button/button.ts +39 -3
- package/src/components/button/config.ts +21 -4
- package/src/components/button/index.ts +26 -1
- package/src/components/button/types.ts +7 -1
- package/src/components/card/api.ts +78 -9
- package/src/components/card/card.ts +58 -3
- package/src/components/card/config.ts +41 -11
- package/src/components/card/features.ts +39 -12
- package/src/components/card/index.ts +84 -19
- package/src/components/card/types.ts +218 -29
- package/src/components/carousel/carousel.ts +92 -28
- package/src/components/carousel/constants.ts +107 -21
- package/src/components/carousel/index.ts +31 -13
- package/src/components/checkbox/checkbox.ts +83 -16
- package/src/components/checkbox/index.ts +43 -1
- package/src/components/checkbox/types.ts +219 -32
- package/src/components/chips/api.ts +194 -0
- package/src/components/{chip → chips/chip}/api.ts +42 -2
- package/src/components/chips/chip/chip.ts +131 -0
- package/src/components/{chip → chips/chip}/config.ts +3 -3
- package/src/components/chips/chip/index.ts +3 -0
- package/src/components/chips/chips.md +481 -0
- package/src/components/chips/chips.ts +75 -0
- package/src/components/chips/config.ts +109 -0
- package/src/components/chips/constants.ts +61 -0
- package/src/components/chips/features/chip-items.ts +33 -0
- package/src/components/chips/features/container.ts +77 -0
- package/src/components/chips/features/controller.ts +448 -0
- package/src/components/chips/features/index.ts +5 -0
- package/src/components/chips/features/label.ts +108 -0
- package/src/components/chips/index.ts +11 -0
- package/src/components/chips/schema.ts +61 -0
- package/src/components/{chip → chips}/types.ts +203 -92
- package/src/components/dialog/dialog.ts +99 -16
- package/src/components/dialog/index.ts +97 -1
- package/src/components/dialog/types.ts +375 -69
- package/src/components/divider/config.ts +90 -6
- package/src/components/divider/divider.ts +32 -2
- package/src/components/divider/features.ts +26 -0
- package/src/components/divider/index.ts +30 -0
- package/src/components/divider/types.ts +86 -9
- package/src/components/extended-fab/api.ts +53 -1
- package/src/components/extended-fab/config.ts +29 -1
- package/src/components/extended-fab/extended-fab.ts +28 -0
- package/src/components/extended-fab/index.ts +36 -0
- package/src/components/extended-fab/types.ts +458 -13
- package/src/components/fab/api.ts +42 -2
- package/src/components/fab/config.ts +29 -1
- package/src/components/fab/fab.ts +16 -2
- package/src/components/fab/index.ts +35 -0
- package/src/components/fab/types.ts +374 -10
- package/src/components/list/api.ts +12 -2
- package/src/components/list/config.ts +21 -0
- package/src/components/list/features.ts +6 -0
- package/src/components/list/index.ts +56 -1
- package/src/components/list/list-item.ts +46 -2
- package/src/components/list/list.ts +73 -2
- package/src/components/list/types.ts +172 -0
- package/src/components/list/utils.ts +26 -2
- package/src/components/menu/api.ts +217 -20
- package/src/components/menu/config.ts +27 -0
- package/src/components/menu/features/visibility.ts +55 -6
- package/src/components/menu/index.ts +64 -0
- package/src/components/menu/menu-item.ts +46 -3
- package/src/components/menu/menu.ts +77 -1
- package/src/components/menu/types.ts +404 -39
- package/src/components/navigation/index.ts +4 -1
- package/src/components/navigation/types.ts +33 -0
- package/src/components/sheet/config.ts +1 -2
- package/src/components/sheet/features/gestures.ts +1 -1
- package/src/components/sheet/features/position.ts +1 -2
- package/src/components/sheet/features/state.ts +1 -1
- package/src/components/sheet/index.ts +10 -2
- package/src/components/sheet/sheet.ts +1 -2
- package/src/components/sheet/types.ts +29 -1
- package/src/components/slider/api.ts +1 -1
- package/src/components/slider/config.ts +1 -1
- package/src/components/slider/features/controller.ts +1 -1
- package/src/components/slider/features/handlers.ts +1 -1
- package/src/components/slider/features/states.ts +1 -1
- package/src/components/slider/index.ts +12 -5
- package/src/components/slider/schema.ts +1 -1
- package/src/components/slider/types.ts +31 -0
- package/src/components/snackbar/index.ts +7 -1
- package/src/components/snackbar/types.ts +25 -0
- package/src/components/switch/index.ts +5 -1
- package/src/components/switch/types.ts +13 -0
- package/src/components/tabs/tab-api.ts +1 -1
- package/src/components/tabs/types.ts +1 -1
- package/src/components/textfield/index.ts +7 -1
- package/src/components/textfield/types.ts +36 -0
- package/src/components/tooltip/api.ts +6 -2
- package/src/components/tooltip/config.ts +9 -28
- package/src/components/tooltip/index.ts +10 -1
- package/src/components/tooltip/types.ts +38 -3
- package/src/index.ts +129 -31
- package/src/styles/abstract/_mixins.scss +23 -9
- package/src/styles/abstract/_variables.scss +14 -4
- package/src/styles/components/_card.scss +1 -1
- package/src/styles/components/_chip.scss +323 -113
- package/src/styles/components/_tabs.scss +1 -1
- package/src/components/checkbox/constants.ts +0 -37
- package/src/components/chip/chip-set.ts +0 -225
- package/src/components/chip/chip.ts +0 -118
- package/src/components/chip/constants.ts +0 -28
- package/src/components/chip/index.ts +0 -12
- package/src/components/list/constants.ts +0 -116
- package/src/components/sheet/constants.ts +0 -20
- package/src/components/slider/constants.ts +0 -32
- package/src/components/snackbar/constants.ts +0 -26
- package/src/components/tooltip/constants.ts +0 -27
- package/test/components/button.test.js +0 -170
- package/test/components/checkbox.test.js +0 -238
- package/test/components/list.test.js +0 -105
- package/test/components/menu.test.js +0 -385
- package/test/components/navigation.test.js +0 -227
- package/test/components/snackbar.test.js +0 -234
- package/test/components/switch.test.js +0 -186
- package/test/components/textfield.test.js +0 -314
- package/test/core/emitter.test.js +0 -141
- package/test/core/ripple.test.js +0 -66
- package/test/setup.js +0 -371
- package/tsconfig.json +0 -22
- package/typedoc.json +0 -28
- package/typedoc.simple.json +0 -14
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
// src/components/button/api.ts
|
|
2
2
|
import { ButtonComponent } from './types';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* API configuration options for button component
|
|
6
|
+
* @category Components
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
4
9
|
interface ApiOptions {
|
|
5
10
|
disabled: {
|
|
6
11
|
enable: () => void;
|
|
@@ -11,6 +16,11 @@ interface ApiOptions {
|
|
|
11
16
|
};
|
|
12
17
|
}
|
|
13
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Component with required elements and methods for API enhancement
|
|
21
|
+
* @category Components
|
|
22
|
+
* @internal
|
|
23
|
+
*/
|
|
14
24
|
interface ComponentWithElements {
|
|
15
25
|
element: HTMLElement;
|
|
16
26
|
text: {
|
|
@@ -27,9 +37,13 @@ interface ComponentWithElements {
|
|
|
27
37
|
}
|
|
28
38
|
|
|
29
39
|
/**
|
|
30
|
-
* Enhances a button component with API methods
|
|
40
|
+
* Enhances a button component with API methods.
|
|
41
|
+
* This follows the higher-order function pattern to add public API methods
|
|
42
|
+
* to the component, making them available to the end user.
|
|
43
|
+
*
|
|
31
44
|
* @param {ApiOptions} options - API configuration options
|
|
32
45
|
* @returns {Function} Higher-order function that adds API methods to component
|
|
46
|
+
* @category Components
|
|
33
47
|
* @internal This is an internal utility for the Button component
|
|
34
48
|
*/
|
|
35
49
|
export const withAPI = ({ disabled, lifecycle }: ApiOptions) =>
|
|
@@ -37,52 +51,100 @@ export const withAPI = ({ disabled, lifecycle }: ApiOptions) =>
|
|
|
37
51
|
...component as any,
|
|
38
52
|
element: component.element as HTMLButtonElement,
|
|
39
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Gets the button's value attribute
|
|
56
|
+
* @returns Current value of the button
|
|
57
|
+
*/
|
|
40
58
|
getValue: () => component.element.value,
|
|
41
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Sets the button's value attribute
|
|
62
|
+
* @param value - New value to set
|
|
63
|
+
* @returns Button component for method chaining
|
|
64
|
+
*/
|
|
42
65
|
setValue(value: string) {
|
|
43
66
|
component.element.value = value;
|
|
44
67
|
return this;
|
|
45
68
|
},
|
|
46
69
|
|
|
70
|
+
/**
|
|
71
|
+
* Enables the button, making it interactive
|
|
72
|
+
* @returns Button component for method chaining
|
|
73
|
+
*/
|
|
47
74
|
enable() {
|
|
48
75
|
disabled.enable();
|
|
49
76
|
return this;
|
|
50
77
|
},
|
|
51
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Disables the button, making it non-interactive
|
|
81
|
+
* @returns Button component for method chaining
|
|
82
|
+
*/
|
|
52
83
|
disable() {
|
|
53
84
|
disabled.disable();
|
|
54
85
|
return this;
|
|
55
86
|
},
|
|
56
87
|
|
|
88
|
+
/**
|
|
89
|
+
* Sets the button's text content
|
|
90
|
+
* @param content - Text content to display
|
|
91
|
+
* @returns Button component for method chaining
|
|
92
|
+
*/
|
|
57
93
|
setText(content: string) {
|
|
58
94
|
component.text.setText(content);
|
|
59
95
|
this.updateCircularStyle();
|
|
60
96
|
return this;
|
|
61
97
|
},
|
|
62
98
|
|
|
99
|
+
/**
|
|
100
|
+
* Gets the button's current text content
|
|
101
|
+
* @returns Current text content
|
|
102
|
+
*/
|
|
63
103
|
getText() {
|
|
64
104
|
return component.text.getText();
|
|
65
105
|
},
|
|
66
106
|
|
|
107
|
+
/**
|
|
108
|
+
* Sets the button's icon HTML content
|
|
109
|
+
* @param icon - HTML string for the icon
|
|
110
|
+
* @returns Button component for method chaining
|
|
111
|
+
*/
|
|
67
112
|
setIcon(icon: string) {
|
|
68
113
|
component.icon.setIcon(icon);
|
|
69
114
|
this.updateCircularStyle();
|
|
70
115
|
return this;
|
|
71
116
|
},
|
|
72
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Gets the button's current icon HTML content
|
|
120
|
+
* @returns Current icon HTML
|
|
121
|
+
*/
|
|
73
122
|
getIcon() {
|
|
74
123
|
return component.icon.getIcon();
|
|
75
124
|
},
|
|
76
125
|
|
|
126
|
+
/**
|
|
127
|
+
* Sets the button's aria-label attribute for accessibility
|
|
128
|
+
* @param label - Accessible label text
|
|
129
|
+
* @returns Button component for method chaining
|
|
130
|
+
*/
|
|
77
131
|
setAriaLabel(label: string) {
|
|
78
132
|
component.element.setAttribute('aria-label', label);
|
|
79
133
|
return this;
|
|
80
134
|
},
|
|
81
135
|
|
|
136
|
+
/**
|
|
137
|
+
* Destroys the button component and cleans up resources
|
|
138
|
+
*/
|
|
82
139
|
destroy() {
|
|
83
140
|
lifecycle.destroy();
|
|
84
141
|
},
|
|
85
142
|
|
|
143
|
+
/**
|
|
144
|
+
* Updates the button's circular style based on content.
|
|
145
|
+
* If the button has an icon but no text, it will be styled as circular.
|
|
146
|
+
* @internal
|
|
147
|
+
*/
|
|
86
148
|
updateCircularStyle() {
|
|
87
149
|
const hasText = component.text.getElement();
|
|
88
150
|
if (!hasText && component.icon.getElement()) {
|
|
@@ -18,6 +18,10 @@ import { createBaseConfig, getElementConfig, getApiConfig } from './config';
|
|
|
18
18
|
/**
|
|
19
19
|
* Creates a new Button component with the specified configuration.
|
|
20
20
|
*
|
|
21
|
+
* The Button component implements the Material Design 3 Button component guidelines
|
|
22
|
+
* with support for different variants, states, and features. It follows accessibility
|
|
23
|
+
* best practices and provides a rich API for state management.
|
|
24
|
+
*
|
|
21
25
|
* The Button component is created using a functional composition pattern,
|
|
22
26
|
* applying various features through the pipe function. This approach allows
|
|
23
27
|
* for flexible and modular component construction.
|
|
@@ -32,16 +36,45 @@ import { createBaseConfig, getElementConfig, getApiConfig } from './config';
|
|
|
32
36
|
*
|
|
33
37
|
* @throws {Error} Throws an error if button creation fails for any reason
|
|
34
38
|
*
|
|
39
|
+
* @category Components
|
|
40
|
+
*
|
|
35
41
|
* @example
|
|
36
42
|
* // Create a simple text button
|
|
37
43
|
* const textButton = createButton({ text: 'Click me' });
|
|
44
|
+
* document.body.appendChild(textButton.element);
|
|
38
45
|
*
|
|
39
46
|
* @example
|
|
40
|
-
* // Create a
|
|
47
|
+
* // Create a filled button with an icon
|
|
41
48
|
* const primaryButton = createButton({
|
|
42
49
|
* text: 'Submit',
|
|
43
|
-
* variant: '
|
|
44
|
-
* icon: '
|
|
50
|
+
* variant: 'filled',
|
|
51
|
+
* icon: '<svg>...</svg>'
|
|
52
|
+
* });
|
|
53
|
+
*
|
|
54
|
+
* // Add a click event handler
|
|
55
|
+
* primaryButton.on('click', () => {
|
|
56
|
+
* console.log('Button clicked');
|
|
57
|
+
* });
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* // Create an outlined button with event handling
|
|
61
|
+
* const submitButton = createButton({
|
|
62
|
+
* text: 'Save',
|
|
63
|
+
* variant: 'outlined'
|
|
64
|
+
* });
|
|
65
|
+
*
|
|
66
|
+
* submitButton.on('click', async () => {
|
|
67
|
+
* submitButton.disable(); // Disable during async operation
|
|
68
|
+
* await saveData();
|
|
69
|
+
* submitButton.enable(); // Re-enable when done
|
|
70
|
+
* });
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* // Create an icon-only button (circular)
|
|
74
|
+
* const iconButton = createButton({
|
|
75
|
+
* icon: '<svg>...</svg>',
|
|
76
|
+
* ariaLabel: 'Add to favorites', // Important for accessibility
|
|
77
|
+
* variant: 'filled'
|
|
45
78
|
* });
|
|
46
79
|
*
|
|
47
80
|
* @example
|
|
@@ -50,6 +83,9 @@ import { createBaseConfig, getElementConfig, getApiConfig } from './config';
|
|
|
50
83
|
* text: 'Not available',
|
|
51
84
|
* disabled: true
|
|
52
85
|
* });
|
|
86
|
+
*
|
|
87
|
+
* // Later, enable the button when available
|
|
88
|
+
* disabledButton.enable();
|
|
53
89
|
*/
|
|
54
90
|
const createButton = (config: ButtonConfig = {}) => {
|
|
55
91
|
const baseConfig = createBaseConfig(config);
|
|
@@ -7,7 +7,10 @@ import {
|
|
|
7
7
|
import { ButtonConfig } from './types';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* Default configuration for the Button component
|
|
10
|
+
* Default configuration for the Button component.
|
|
11
|
+
* These values will be used when not explicitly specified by the user.
|
|
12
|
+
*
|
|
13
|
+
* @category Components
|
|
11
14
|
*/
|
|
12
15
|
export const defaultConfig: ButtonConfig = {
|
|
13
16
|
variant: 'filled',
|
|
@@ -16,17 +19,26 @@ export const defaultConfig: ButtonConfig = {
|
|
|
16
19
|
};
|
|
17
20
|
|
|
18
21
|
/**
|
|
19
|
-
* Creates the base configuration for Button component
|
|
22
|
+
* Creates the base configuration for Button component by merging user-provided
|
|
23
|
+
* config with default values.
|
|
24
|
+
*
|
|
20
25
|
* @param {ButtonConfig} config - User provided configuration
|
|
21
26
|
* @returns {ButtonConfig} Complete configuration with defaults applied
|
|
27
|
+
* @category Components
|
|
28
|
+
* @internal
|
|
22
29
|
*/
|
|
23
30
|
export const createBaseConfig = (config: ButtonConfig = {}): ButtonConfig =>
|
|
24
31
|
createComponentConfig(defaultConfig, config, 'button') as ButtonConfig;
|
|
25
32
|
|
|
26
33
|
/**
|
|
27
|
-
* Generates element configuration for the Button component
|
|
34
|
+
* Generates element configuration for the Button component.
|
|
35
|
+
* This function creates the necessary attributes and configuration
|
|
36
|
+
* for the DOM element creation process.
|
|
37
|
+
*
|
|
28
38
|
* @param {ButtonConfig} config - Button configuration
|
|
29
39
|
* @returns {Object} Element configuration object for withElement
|
|
40
|
+
* @category Components
|
|
41
|
+
* @internal
|
|
30
42
|
*/
|
|
31
43
|
export const getElementConfig = (config: ButtonConfig) => {
|
|
32
44
|
// Create the attributes object
|
|
@@ -62,9 +74,14 @@ export const getElementConfig = (config: ButtonConfig) => {
|
|
|
62
74
|
};
|
|
63
75
|
|
|
64
76
|
/**
|
|
65
|
-
* Creates API configuration for the Button component
|
|
77
|
+
* Creates API configuration for the Button component.
|
|
78
|
+
* This connects the core component features (like disabled state)
|
|
79
|
+
* to the public API methods exposed to users.
|
|
80
|
+
*
|
|
66
81
|
* @param {Object} comp - Component with disabled and lifecycle features
|
|
67
82
|
* @returns {Object} API configuration object
|
|
83
|
+
* @category Components
|
|
84
|
+
* @internal
|
|
68
85
|
*/
|
|
69
86
|
export const getApiConfig = (comp) => ({
|
|
70
87
|
disabled: {
|
|
@@ -1,12 +1,37 @@
|
|
|
1
1
|
// src/components/button/index.ts
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Button component module
|
|
5
|
+
* @module components/button
|
|
6
|
+
*/
|
|
7
|
+
|
|
2
8
|
export { default } from './button'
|
|
3
9
|
export { ButtonConfig, ButtonComponent, ButtonVariant } from './types'
|
|
4
10
|
|
|
5
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Constants for button variants - use these instead of string literals
|
|
13
|
+
* for better code completion and type safety.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* import { createButton, BUTTON_VARIANTS } from 'mtrl';
|
|
17
|
+
*
|
|
18
|
+
* // Create a filled button
|
|
19
|
+
* const primaryButton = createButton({
|
|
20
|
+
* text: 'Submit',
|
|
21
|
+
* variant: BUTTON_VARIANTS.FILLED
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* @category Components
|
|
25
|
+
*/
|
|
6
26
|
export const BUTTON_VARIANTS = {
|
|
27
|
+
/** Primary action button with solid background (high emphasis) */
|
|
7
28
|
FILLED: 'filled',
|
|
29
|
+
/** Secondary action button with medium emphasis */
|
|
8
30
|
TONAL: 'tonal',
|
|
31
|
+
/** Button with outline border and transparent background */
|
|
9
32
|
OUTLINED: 'outlined',
|
|
33
|
+
/** Button with slight elevation/shadow */
|
|
10
34
|
ELEVATED: 'elevated',
|
|
35
|
+
/** Button that appears as text without background or border (low emphasis) */
|
|
11
36
|
TEXT: 'text'
|
|
12
37
|
} as const;
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
// src/components/button/types.ts
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Button variant types
|
|
4
|
+
* Button variant types - controls the visual style of the button
|
|
5
5
|
* @category Components
|
|
6
|
+
* @remarks
|
|
7
|
+
* - filled: Primary action button with solid background (high emphasis)
|
|
8
|
+
* - tonal: Secondary action button with medium emphasis
|
|
9
|
+
* - outlined: Button with outline border and transparent background
|
|
10
|
+
* - elevated: Button with slight elevation/shadow
|
|
11
|
+
* - text: Button that appears as text without background or border (low emphasis)
|
|
6
12
|
*/
|
|
7
13
|
export type ButtonVariant = 'filled' | 'tonal' | 'outlined' | 'elevated' | 'text';
|
|
8
14
|
|
|
@@ -2,21 +2,31 @@
|
|
|
2
2
|
import { BaseComponent, CardComponent, ApiOptions } from './types';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Enhances a card component with API methods
|
|
5
|
+
* Enhances a card component with API methods.
|
|
6
|
+
* This follows the higher-order function pattern to add public API methods
|
|
7
|
+
* to the component, making them available to the end user.
|
|
6
8
|
*
|
|
7
9
|
* @param {ApiOptions} options - API configuration options
|
|
8
10
|
* @returns {Function} Higher-order function that adds API methods to component
|
|
9
|
-
* @
|
|
11
|
+
* @category Components
|
|
10
12
|
*/
|
|
11
13
|
export const withAPI = ({ lifecycle }: ApiOptions) => (component: BaseComponent): CardComponent => ({
|
|
12
14
|
...component,
|
|
13
15
|
element: component.element,
|
|
14
16
|
|
|
15
17
|
/**
|
|
16
|
-
* Adds content to the card
|
|
18
|
+
* Adds content to the card.
|
|
19
|
+
* This method appends content to the card component.
|
|
17
20
|
*
|
|
18
21
|
* @param {HTMLElement} contentElement - The content element to add
|
|
19
22
|
* @returns {CardComponent} The card instance for chaining
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const content = document.createElement('div');
|
|
26
|
+
* content.className = 'mtrl-card-content';
|
|
27
|
+
* content.textContent = 'Card content goes here';
|
|
28
|
+
* card.addContent(content);
|
|
29
|
+
* ```
|
|
20
30
|
*/
|
|
21
31
|
addContent(contentElement: HTMLElement): CardComponent {
|
|
22
32
|
if (contentElement && contentElement.classList.contains(`${component.getClass('card')}-content`)) {
|
|
@@ -72,11 +82,24 @@ export const withAPI = ({ lifecycle }: ApiOptions) => (component: BaseComponent)
|
|
|
72
82
|
},
|
|
73
83
|
|
|
74
84
|
/**
|
|
75
|
-
* Adds media to the card
|
|
85
|
+
* Adds media to the card.
|
|
86
|
+
* Places media elements at the specified position in the card.
|
|
76
87
|
*
|
|
77
88
|
* @param {HTMLElement} mediaElement - The media element to add
|
|
78
89
|
* @param {string} [position='top'] - Position to place media ('top', 'bottom')
|
|
79
90
|
* @returns {CardComponent} The card instance for chaining
|
|
91
|
+
* @example
|
|
92
|
+
* ```typescript
|
|
93
|
+
* // Creating media element
|
|
94
|
+
* const media = document.createElement('div');
|
|
95
|
+
* media.className = 'mtrl-card-media';
|
|
96
|
+
*
|
|
97
|
+
* // Adding at the top (default)
|
|
98
|
+
* card.addMedia(media);
|
|
99
|
+
*
|
|
100
|
+
* // Or adding at the bottom
|
|
101
|
+
* card.addMedia(media, 'bottom');
|
|
102
|
+
* ```
|
|
80
103
|
*/
|
|
81
104
|
addMedia(mediaElement: HTMLElement, position: 'top' | 'bottom' = 'top'): CardComponent {
|
|
82
105
|
if (mediaElement && mediaElement.classList.contains(`${component.getClass('card')}-media`)) {
|
|
@@ -90,10 +113,27 @@ export const withAPI = ({ lifecycle }: ApiOptions) => (component: BaseComponent)
|
|
|
90
113
|
},
|
|
91
114
|
|
|
92
115
|
/**
|
|
93
|
-
* Sets the card actions section
|
|
116
|
+
* Sets the card actions section.
|
|
117
|
+
* Replaces any existing actions with the provided actions element.
|
|
118
|
+
* Actions typically contain buttons or other interactive controls,
|
|
119
|
+
* and are placed at the bottom of the card.
|
|
94
120
|
*
|
|
95
121
|
* @param {HTMLElement} actionsElement - The actions element to add
|
|
96
122
|
* @returns {CardComponent} The card instance for chaining
|
|
123
|
+
* @example
|
|
124
|
+
* ```typescript
|
|
125
|
+
* // Create actions container
|
|
126
|
+
* const actions = document.createElement('div');
|
|
127
|
+
* actions.className = 'mtrl-card-actions';
|
|
128
|
+
*
|
|
129
|
+
* // Add buttons to actions
|
|
130
|
+
* const button = document.createElement('button');
|
|
131
|
+
* button.textContent = 'Action';
|
|
132
|
+
* actions.appendChild(button);
|
|
133
|
+
*
|
|
134
|
+
* // Set actions on card
|
|
135
|
+
* card.setActions(actions);
|
|
136
|
+
* ```
|
|
97
137
|
*/
|
|
98
138
|
setActions(actionsElement: HTMLElement): CardComponent {
|
|
99
139
|
if (actionsElement && actionsElement.classList.contains(`${component.getClass('card')}-actions`)) {
|
|
@@ -110,10 +150,23 @@ export const withAPI = ({ lifecycle }: ApiOptions) => (component: BaseComponent)
|
|
|
110
150
|
},
|
|
111
151
|
|
|
112
152
|
/**
|
|
113
|
-
* Makes the card draggable
|
|
153
|
+
* Makes the card draggable.
|
|
154
|
+
* Sets up native HTML5 drag and drop functionality and adds appropriate
|
|
155
|
+
* accessibility attributes. Automatically updates ARIA attributes during drag.
|
|
114
156
|
*
|
|
115
157
|
* @param {Function} [dragStartCallback] - Callback for drag start event
|
|
116
158
|
* @returns {CardComponent} The card instance for chaining
|
|
159
|
+
* @example
|
|
160
|
+
* ```typescript
|
|
161
|
+
* // Basic draggable card
|
|
162
|
+
* card.makeDraggable();
|
|
163
|
+
*
|
|
164
|
+
* // With custom drag start handler
|
|
165
|
+
* card.makeDraggable((event) => {
|
|
166
|
+
* // Set custom data or perform other actions on drag start
|
|
167
|
+
* event.dataTransfer.setData('text/plain', 'Card data');
|
|
168
|
+
* });
|
|
169
|
+
* ```
|
|
117
170
|
*/
|
|
118
171
|
makeDraggable(dragStartCallback?: (event: DragEvent) => void): CardComponent {
|
|
119
172
|
component.element.setAttribute('draggable', 'true');
|
|
@@ -134,10 +187,19 @@ export const withAPI = ({ lifecycle }: ApiOptions) => (component: BaseComponent)
|
|
|
134
187
|
},
|
|
135
188
|
|
|
136
189
|
/**
|
|
137
|
-
* Sets focus to the card
|
|
138
|
-
* Useful for programmatic focus management
|
|
190
|
+
* Sets focus to the card.
|
|
191
|
+
* Useful for programmatic focus management, especially in keyboard navigation
|
|
192
|
+
* scenarios or after dynamic content changes.
|
|
139
193
|
*
|
|
140
194
|
* @returns {CardComponent} The card instance for chaining
|
|
195
|
+
* @example
|
|
196
|
+
* ```typescript
|
|
197
|
+
* // Focus the card
|
|
198
|
+
* card.focus();
|
|
199
|
+
*
|
|
200
|
+
* // Can be chained with other methods
|
|
201
|
+
* card.setHeader(headerElement).focus();
|
|
202
|
+
* ```
|
|
141
203
|
*/
|
|
142
204
|
focus(): CardComponent {
|
|
143
205
|
component.element.focus();
|
|
@@ -145,7 +207,14 @@ export const withAPI = ({ lifecycle }: ApiOptions) => (component: BaseComponent)
|
|
|
145
207
|
},
|
|
146
208
|
|
|
147
209
|
/**
|
|
148
|
-
* Destroys the card component and removes event listeners
|
|
210
|
+
* Destroys the card component and removes event listeners.
|
|
211
|
+
* Call this method when the card is no longer needed to prevent memory leaks.
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* ```typescript
|
|
215
|
+
* // Clean up resources when done with the card
|
|
216
|
+
* card.destroy();
|
|
217
|
+
* ```
|
|
149
218
|
*/
|
|
150
219
|
destroy(): void {
|
|
151
220
|
lifecycle.destroy();
|
|
@@ -20,13 +20,68 @@ import {
|
|
|
20
20
|
import { withElevation } from './features';
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
|
-
* Creates a new Card component following Material Design 3 principles
|
|
23
|
+
* Creates a new Card component following Material Design 3 principles.
|
|
24
24
|
*
|
|
25
25
|
* Material Design 3 Cards are surfaces that display content and actions about a single topic.
|
|
26
|
-
* Cards can contain text, media, and UI controls.
|
|
26
|
+
* Cards can contain text, media, and UI controls. They provide entry points to more
|
|
27
|
+
* detailed information and can include interactive elements.
|
|
27
28
|
*
|
|
28
29
|
* @param {CardSchema} config - Card configuration object
|
|
29
|
-
* @returns {CardComponent} Card component instance
|
|
30
|
+
* @returns {CardComponent} Card component instance with the following API methods:
|
|
31
|
+
* - `addContent(contentElement)`: Adds content to the card
|
|
32
|
+
* - `setHeader(headerElement)`: Sets the card header
|
|
33
|
+
* - `addMedia(mediaElement, position)`: Adds media to the card
|
|
34
|
+
* - `setActions(actionsElement)`: Sets the card actions section
|
|
35
|
+
* - `makeDraggable(dragStartCallback)`: Makes the card draggable
|
|
36
|
+
* - `focus()`: Sets focus to the card
|
|
37
|
+
* - `destroy()`: Destroys the card component and removes event listeners
|
|
38
|
+
*
|
|
39
|
+
* @throws {Error} Throws an error if card creation fails
|
|
40
|
+
* @category Components
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* // Create a basic card
|
|
44
|
+
* const card = createCard({
|
|
45
|
+
* variant: 'elevated',
|
|
46
|
+
* header: {
|
|
47
|
+
* title: 'Card Title',
|
|
48
|
+
* subtitle: 'Secondary text'
|
|
49
|
+
* },
|
|
50
|
+
* content: {
|
|
51
|
+
* text: 'Card content goes here.'
|
|
52
|
+
* }
|
|
53
|
+
* });
|
|
54
|
+
*
|
|
55
|
+
* // Create an interactive card with actions
|
|
56
|
+
* const cardWithActions = createCard({
|
|
57
|
+
* variant: 'filled',
|
|
58
|
+
* interactive: true,
|
|
59
|
+
* header: { title: 'Interactive Card' },
|
|
60
|
+
* content: { text: 'Click the buttons below.' },
|
|
61
|
+
* buttons: [
|
|
62
|
+
* { text: 'Action 1', variant: 'text' },
|
|
63
|
+
* { text: 'Action 2', variant: 'filled' }
|
|
64
|
+
* ]
|
|
65
|
+
* });
|
|
66
|
+
*
|
|
67
|
+
* // Card with media
|
|
68
|
+
* const mediaCard = createCard({
|
|
69
|
+
* media: {
|
|
70
|
+
* src: '/path/to/image.jpg',
|
|
71
|
+
* alt: 'Descriptive alt text',
|
|
72
|
+
* aspectRatio: '16:9'
|
|
73
|
+
* },
|
|
74
|
+
* header: { title: 'Media Card' }
|
|
75
|
+
* });
|
|
76
|
+
*
|
|
77
|
+
* // Using API methods
|
|
78
|
+
* const card = createCard();
|
|
79
|
+
* const content = document.createElement('div');
|
|
80
|
+
* content.className = 'mtrl-card-content';
|
|
81
|
+
* content.textContent = 'Added programmatically';
|
|
82
|
+
* card.addContent(content);
|
|
83
|
+
* card.makeDraggable();
|
|
84
|
+
* ```
|
|
30
85
|
*/
|
|
31
86
|
const createCard = (config: CardSchema = {}): CardComponent => {
|
|
32
87
|
// Process inline configuration (map shorthand properties)
|
|
@@ -12,8 +12,11 @@ import {
|
|
|
12
12
|
import { CardComponent, CardSchema, ButtonConfig, BaseComponent } from './types';
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* Default configuration for the Card component
|
|
15
|
+
* Default configuration for the Card component.
|
|
16
|
+
* These values are used when no configuration is provided.
|
|
17
|
+
*
|
|
16
18
|
* @const {CardSchema}
|
|
19
|
+
* @category Components
|
|
17
20
|
*/
|
|
18
21
|
export const defaultConfig: CardSchema = {
|
|
19
22
|
variant: 'elevated',
|
|
@@ -24,11 +27,18 @@ export const defaultConfig: CardSchema = {
|
|
|
24
27
|
};
|
|
25
28
|
|
|
26
29
|
/**
|
|
27
|
-
* Processes inline configuration options into standard config format
|
|
28
|
-
* Maps shorthand properties to their proper config counterparts
|
|
30
|
+
* Processes inline configuration options into standard config format.
|
|
31
|
+
* Maps shorthand properties to their proper config counterparts for ease of use.
|
|
29
32
|
*
|
|
30
33
|
* @param {CardSchema} config - Raw card configuration
|
|
31
34
|
* @returns {CardSchema} Processed configuration
|
|
35
|
+
* @category Components
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* // Before processing, these are equivalent:
|
|
39
|
+
* { header: { title: 'Example' } }
|
|
40
|
+
* { headerConfig: { title: 'Example' } }
|
|
41
|
+
* ```
|
|
32
42
|
*/
|
|
33
43
|
export const processInlineConfig = (config: CardSchema): CardSchema => {
|
|
34
44
|
const processedConfig: CardSchema = { ...config };
|
|
@@ -54,11 +64,13 @@ export const processInlineConfig = (config: CardSchema): CardSchema => {
|
|
|
54
64
|
};
|
|
55
65
|
|
|
56
66
|
/**
|
|
57
|
-
* Applies inline configuration to a card component
|
|
58
|
-
* Adds configured elements to the card in the correct order
|
|
67
|
+
* Applies inline configuration to a card component.
|
|
68
|
+
* Adds configured elements to the card in the correct order following
|
|
69
|
+
* Material Design layout guidelines. Handles media, header, content, and actions placement.
|
|
59
70
|
*
|
|
60
71
|
* @param {CardComponent} card - Card component to configure
|
|
61
72
|
* @param {CardSchema} config - Processed configuration
|
|
73
|
+
* @category Components
|
|
62
74
|
*/
|
|
63
75
|
export const applyInlineConfiguration = (card: CardComponent, config: CardSchema): void => {
|
|
64
76
|
// Add media (top position) if configured
|
|
@@ -116,19 +128,27 @@ export const applyInlineConfiguration = (card: CardComponent, config: CardSchema
|
|
|
116
128
|
};
|
|
117
129
|
|
|
118
130
|
/**
|
|
119
|
-
* Creates the base configuration for Card component
|
|
131
|
+
* Creates the base configuration for Card component.
|
|
132
|
+
* Merges user-provided configuration with default values,
|
|
133
|
+
* ensuring all required properties are set.
|
|
120
134
|
*
|
|
121
135
|
* @param {CardSchema} config - User provided configuration
|
|
122
136
|
* @returns {CardSchema} Complete configuration with defaults applied
|
|
137
|
+
* @category Components
|
|
138
|
+
*
|
|
123
139
|
*/
|
|
124
140
|
export const createBaseConfig = (config: CardSchema = {}): CardSchema =>
|
|
125
141
|
createComponentConfig(defaultConfig, config, 'card') as CardSchema;
|
|
126
142
|
|
|
127
143
|
/**
|
|
128
|
-
* Generates element configuration for the Card component
|
|
144
|
+
* Generates element configuration for the Card component.
|
|
145
|
+
* Sets up DOM attributes, accessibility features, and event forwarding
|
|
146
|
+
* based on the card's configuration.
|
|
129
147
|
*
|
|
130
148
|
* @param {CardSchema} config - Card configuration
|
|
131
149
|
* @returns {Object} Element configuration object for withElement
|
|
150
|
+
* @category Components
|
|
151
|
+
*
|
|
132
152
|
*/
|
|
133
153
|
export const getElementConfig = (config: CardSchema) => {
|
|
134
154
|
const isInteractive = config.interactive || config.clickable;
|
|
@@ -178,10 +198,13 @@ export const getElementConfig = (config: CardSchema) => {
|
|
|
178
198
|
};
|
|
179
199
|
|
|
180
200
|
/**
|
|
181
|
-
* Creates API configuration for the Card component
|
|
201
|
+
* Creates API configuration for the Card component.
|
|
202
|
+
* Prepares the configuration needed for the card's public API methods.
|
|
182
203
|
*
|
|
183
204
|
* @param {Object} comp - Component with lifecycle feature
|
|
184
205
|
* @returns {Object} API configuration object
|
|
206
|
+
* @category Components
|
|
207
|
+
*
|
|
185
208
|
*/
|
|
186
209
|
export const getApiConfig = (comp: any) => ({
|
|
187
210
|
lifecycle: {
|
|
@@ -190,7 +213,10 @@ export const getApiConfig = (comp: any) => ({
|
|
|
190
213
|
});
|
|
191
214
|
|
|
192
215
|
/**
|
|
193
|
-
* Card elevation levels
|
|
216
|
+
* Card elevation levels in density-independent pixels (dp).
|
|
217
|
+
* Following Material Design 3 elevation system guidelines.
|
|
218
|
+
*
|
|
219
|
+
* @category Components
|
|
194
220
|
*/
|
|
195
221
|
export const CARD_ELEVATION_LEVELS = {
|
|
196
222
|
LEVEL0: 0,
|
|
@@ -200,11 +226,15 @@ export const CARD_ELEVATION_LEVELS = {
|
|
|
200
226
|
};
|
|
201
227
|
|
|
202
228
|
/**
|
|
203
|
-
* Adds interactive behavior to card component
|
|
204
|
-
* Uses the
|
|
229
|
+
* Adds interactive behavior to card component.
|
|
230
|
+
* Uses the mtrl elevation system for proper elevation levels according to Material Design 3
|
|
231
|
+
* guidelines. Implements mouse, keyboard, and touch interactions with appropriate
|
|
232
|
+
* visual feedback and accessibility support.
|
|
205
233
|
*
|
|
206
234
|
* @param {BaseComponent} comp - Card component
|
|
207
235
|
* @returns {BaseComponent} Enhanced card component
|
|
236
|
+
* @category Components
|
|
237
|
+
*
|
|
208
238
|
*/
|
|
209
239
|
export const withInteractiveBehavior = (comp: BaseComponent): BaseComponent => {
|
|
210
240
|
const config = comp.config;
|