mtrl 0.1.2 → 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 +359 -0
- package/src/components/card/actions.ts +48 -0
- package/src/components/card/api.ts +102 -0
- package/src/components/card/card.ts +41 -0
- package/src/components/card/config.ts +99 -0
- package/src/components/card/constants.ts +69 -0
- package/src/components/card/content.ts +48 -0
- package/src/components/card/features.ts +228 -0
- package/src/components/card/header.ts +88 -0
- 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} +4 -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/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,234 @@
|
|
|
1
|
+
// src/core/utils/validate.ts
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Validation rule interface
|
|
5
|
+
*/
|
|
6
|
+
export interface ValidationRule {
|
|
7
|
+
/**
|
|
8
|
+
* Whether field is required
|
|
9
|
+
*/
|
|
10
|
+
required?: boolean;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Expected data type
|
|
14
|
+
*/
|
|
15
|
+
type?: string;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Minimum value for numbers
|
|
19
|
+
*/
|
|
20
|
+
minimum?: number;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Maximum value for numbers
|
|
24
|
+
*/
|
|
25
|
+
maximum?: number;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Regular expression pattern for strings
|
|
29
|
+
*/
|
|
30
|
+
pattern?: string | RegExp;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Allowed values (enum)
|
|
34
|
+
*/
|
|
35
|
+
enum?: any[];
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Minimum string length
|
|
39
|
+
*/
|
|
40
|
+
minLength?: number;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Maximum string length
|
|
44
|
+
*/
|
|
45
|
+
maxLength?: number;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Default value
|
|
49
|
+
*/
|
|
50
|
+
default?: any;
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Custom validator function
|
|
54
|
+
*/
|
|
55
|
+
validator?: (value: any) => boolean | string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Validation schema type
|
|
60
|
+
*/
|
|
61
|
+
export type ValidationSchema = Record<string, ValidationRule>;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Validates configuration object against schema
|
|
65
|
+
*
|
|
66
|
+
* @param config - Configuration to validate
|
|
67
|
+
* @param schema - Validation schema
|
|
68
|
+
* @throws Error if validation fails
|
|
69
|
+
*/
|
|
70
|
+
export const validateConfig = (
|
|
71
|
+
config: Record<string, any>,
|
|
72
|
+
schema: ValidationSchema
|
|
73
|
+
): void => {
|
|
74
|
+
const errors: string[] = [];
|
|
75
|
+
|
|
76
|
+
Object.entries(schema).forEach(([key, rule]) => {
|
|
77
|
+
// Check required fields
|
|
78
|
+
if (rule.required && config[key] === undefined) {
|
|
79
|
+
errors.push(`Missing required field: ${key}`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (config[key] !== undefined) {
|
|
83
|
+
// Check type if value exists
|
|
84
|
+
if (rule.type) {
|
|
85
|
+
const actualType = typeof config[key];
|
|
86
|
+
if (actualType !== rule.type) {
|
|
87
|
+
errors.push(`Invalid type for ${key}: expected ${rule.type}, got ${actualType}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Check numbers
|
|
92
|
+
if (typeof config[key] === 'number') {
|
|
93
|
+
if (rule.minimum !== undefined && config[key] < rule.minimum) {
|
|
94
|
+
errors.push(`Value for ${key} is too small: minimum is ${rule.minimum}`);
|
|
95
|
+
}
|
|
96
|
+
if (rule.maximum !== undefined && config[key] > rule.maximum) {
|
|
97
|
+
errors.push(`Value for ${key} is too large: maximum is ${rule.maximum}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Check strings
|
|
102
|
+
if (typeof config[key] === 'string') {
|
|
103
|
+
if (rule.minLength !== undefined && config[key].length < rule.minLength) {
|
|
104
|
+
errors.push(`String for ${key} is too short: minimum length is ${rule.minLength}`);
|
|
105
|
+
}
|
|
106
|
+
if (rule.maxLength !== undefined && config[key].length > rule.maxLength) {
|
|
107
|
+
errors.push(`String for ${key} is too long: maximum length is ${rule.maxLength}`);
|
|
108
|
+
}
|
|
109
|
+
if (rule.pattern) {
|
|
110
|
+
const pattern = rule.pattern instanceof RegExp
|
|
111
|
+
? rule.pattern
|
|
112
|
+
: new RegExp(rule.pattern);
|
|
113
|
+
|
|
114
|
+
if (!pattern.test(config[key])) {
|
|
115
|
+
errors.push(`Invalid format for ${key}: must match pattern ${pattern}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Check allowed values
|
|
121
|
+
if (rule.enum) {
|
|
122
|
+
if (!rule.enum.includes(config[key])) {
|
|
123
|
+
errors.push(`Invalid value for ${key}. Must be one of: ${rule.enum.join(', ')}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Custom validator
|
|
128
|
+
if (rule.validator) {
|
|
129
|
+
const result = rule.validator(config[key]);
|
|
130
|
+
if (result === false) {
|
|
131
|
+
errors.push(`Invalid value for ${key}`);
|
|
132
|
+
} else if (typeof result === 'string') {
|
|
133
|
+
errors.push(result);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
if (errors.length > 0) {
|
|
140
|
+
throw new Error(`Configuration validation failed:\n${errors.join('\n')}`);
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Validates a single value against a rule
|
|
146
|
+
*
|
|
147
|
+
* @param value - Value to validate
|
|
148
|
+
* @param rule - Validation rule
|
|
149
|
+
* @returns Validation result (true if valid, error message if invalid)
|
|
150
|
+
*/
|
|
151
|
+
export const validateValue = (
|
|
152
|
+
value: any,
|
|
153
|
+
rule: ValidationRule
|
|
154
|
+
): true | string => {
|
|
155
|
+
// Check required
|
|
156
|
+
if (rule.required && value === undefined) {
|
|
157
|
+
return 'Value is required';
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (value !== undefined) {
|
|
161
|
+
// Check type
|
|
162
|
+
if (rule.type && typeof value !== rule.type) {
|
|
163
|
+
return `Expected ${rule.type}, got ${typeof value}`;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Check numbers
|
|
167
|
+
if (typeof value === 'number') {
|
|
168
|
+
if (rule.minimum !== undefined && value < rule.minimum) {
|
|
169
|
+
return `Value is too small: minimum is ${rule.minimum}`;
|
|
170
|
+
}
|
|
171
|
+
if (rule.maximum !== undefined && value > rule.maximum) {
|
|
172
|
+
return `Value is too large: maximum is ${rule.maximum}`;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Check strings
|
|
177
|
+
if (typeof value === 'string') {
|
|
178
|
+
if (rule.minLength !== undefined && value.length < rule.minLength) {
|
|
179
|
+
return `String is too short: minimum length is ${rule.minLength}`;
|
|
180
|
+
}
|
|
181
|
+
if (rule.maxLength !== undefined && value.length > rule.maxLength) {
|
|
182
|
+
return `String is too long: maximum length is ${rule.maxLength}`;
|
|
183
|
+
}
|
|
184
|
+
if (rule.pattern) {
|
|
185
|
+
const pattern = rule.pattern instanceof RegExp
|
|
186
|
+
? rule.pattern
|
|
187
|
+
: new RegExp(rule.pattern);
|
|
188
|
+
|
|
189
|
+
if (!pattern.test(value)) {
|
|
190
|
+
return `Invalid format: must match pattern ${pattern}`;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Check allowed values
|
|
196
|
+
if (rule.enum && !rule.enum.includes(value)) {
|
|
197
|
+
return `Invalid value. Must be one of: ${rule.enum.join(', ')}`;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Custom validator
|
|
201
|
+
if (rule.validator) {
|
|
202
|
+
const result = rule.validator(value);
|
|
203
|
+
if (result === false) {
|
|
204
|
+
return 'Invalid value';
|
|
205
|
+
} else if (typeof result === 'string') {
|
|
206
|
+
return result;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return true;
|
|
212
|
+
};
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Applies default values from schema to config
|
|
216
|
+
*
|
|
217
|
+
* @param config - Configuration object
|
|
218
|
+
* @param schema - Validation schema with defaults
|
|
219
|
+
* @returns Configuration with defaults applied
|
|
220
|
+
*/
|
|
221
|
+
export const applyDefaults = <T extends Record<string, any>>(
|
|
222
|
+
config: T,
|
|
223
|
+
schema: ValidationSchema
|
|
224
|
+
): T => {
|
|
225
|
+
const result = { ...config };
|
|
226
|
+
|
|
227
|
+
Object.entries(schema).forEach(([key, rule]) => {
|
|
228
|
+
if (result[key] === undefined && rule.default !== undefined) {
|
|
229
|
+
result[key] = rule.default;
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
return result;
|
|
234
|
+
};
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
// src/index.
|
|
1
|
+
// src/index.ts
|
|
2
2
|
export { createElement } from './core/dom/create'
|
|
3
3
|
export { default as createLayout } from './core/layout'
|
|
4
4
|
export { default as createButton } from './components/button'
|
|
5
|
+
export { default as createCard } from './components/card'
|
|
5
6
|
export { default as createCheckbox } from './components/checkbox'
|
|
6
|
-
export { default as
|
|
7
|
+
export { default as createChip } from './components/chip'
|
|
7
8
|
export { default as createMenu } from './components/menu'
|
|
8
9
|
export { default as createNavigation } from './components/navigation'
|
|
10
|
+
export { default as createProgress } from './components/progress'
|
|
9
11
|
export { default as createSnackbar } from './components/snackbar'
|
|
10
12
|
export { default as createSwitch } from './components/switch'
|
|
11
13
|
export { default as createTextfield } from './components/textfield'
|
package/index.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
// index.js
|
|
2
|
-
import {
|
|
3
|
-
createLayout,
|
|
4
|
-
createElement,
|
|
5
|
-
createButton, createCheckbox, createTextfield, createSwitch, createContainer, createList, createSnackbar, createNavigation, createMenu
|
|
6
|
-
} from './src/index.js'
|
|
7
|
-
|
|
8
|
-
export {
|
|
9
|
-
createLayout,
|
|
10
|
-
createElement, createButton, createCheckbox, createTextfield, createSwitch, createContainer, createList, createSnackbar, createNavigation, createMenu
|
|
11
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
// src/components/button/api.js
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Enhances a button component with API methods
|
|
5
|
-
* @param {Object} options - API configuration options
|
|
6
|
-
* @param {Object} options.disabled - Object containing enable/disable methods
|
|
7
|
-
* @param {Object} options.lifecycle - Object containing lifecycle methods
|
|
8
|
-
* @returns {Function} Higher-order function that adds API methods to component
|
|
9
|
-
* @internal This is an internal utility for the Button component
|
|
10
|
-
*/
|
|
11
|
-
export const withAPI = ({ disabled, lifecycle }) => (component) => ({
|
|
12
|
-
...component,
|
|
13
|
-
element: component.element,
|
|
14
|
-
getValue: () => component.element.value,
|
|
15
|
-
setValue (value) {
|
|
16
|
-
component.element.value = value
|
|
17
|
-
return this
|
|
18
|
-
},
|
|
19
|
-
enable () {
|
|
20
|
-
disabled.enable()
|
|
21
|
-
return this
|
|
22
|
-
},
|
|
23
|
-
disable () {
|
|
24
|
-
disabled.disable()
|
|
25
|
-
return this
|
|
26
|
-
},
|
|
27
|
-
setText (content) {
|
|
28
|
-
component.text.setText(content)
|
|
29
|
-
this.updateCircularStyle()
|
|
30
|
-
return this
|
|
31
|
-
},
|
|
32
|
-
getText () {
|
|
33
|
-
return component.text.getText()
|
|
34
|
-
},
|
|
35
|
-
setIcon (icon) {
|
|
36
|
-
component.icon.setIcon(icon)
|
|
37
|
-
this.updateCircularStyle()
|
|
38
|
-
return this
|
|
39
|
-
},
|
|
40
|
-
getIcon () {
|
|
41
|
-
return component.icon.getIcon()
|
|
42
|
-
},
|
|
43
|
-
destroy () {
|
|
44
|
-
lifecycle.destroy()
|
|
45
|
-
},
|
|
46
|
-
updateCircularStyle () {
|
|
47
|
-
const hasText = component.text.getElement()
|
|
48
|
-
if (!hasText && component.icon.getElement()) {
|
|
49
|
-
component.element.classList.add(`${component.getClass('button')}--circular`)
|
|
50
|
-
} else {
|
|
51
|
-
component.element.classList.remove(`${component.getClass('button')}--circular`)
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
})
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
// src/components/button/button.js
|
|
2
|
-
import { PREFIX } from '../../core/config'
|
|
3
|
-
import { pipe } from '../../core/compose'
|
|
4
|
-
import { createBase, withElement } from '../../core/compose/component'
|
|
5
|
-
import {
|
|
6
|
-
withEvents,
|
|
7
|
-
withText,
|
|
8
|
-
withIcon,
|
|
9
|
-
withVariant,
|
|
10
|
-
withSize,
|
|
11
|
-
withRipple,
|
|
12
|
-
withDisabled,
|
|
13
|
-
withLifecycle
|
|
14
|
-
} from '../../core/compose/features'
|
|
15
|
-
import { withAPI } from './api'
|
|
16
|
-
import { BUTTON_VARIANTS } from './constants'
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Creates a new Button component
|
|
20
|
-
* @param {Object} config - Button configuration object
|
|
21
|
-
* @param {string} [config.variant='filled'] - Button variant (filled, tonal, outlined, elevated, text)
|
|
22
|
-
* @param {string} [config.size] - Button size (small, medium, large)
|
|
23
|
-
* @param {boolean} [config.disabled] - Whether the button is initially disabled
|
|
24
|
-
* @param {string} [config.text] - Initial button text content
|
|
25
|
-
* @param {string} [config.icon] - Initial button icon HTML content
|
|
26
|
-
* @param {string} [config.class] - Additional CSS classes
|
|
27
|
-
* @param {string} [config.value] - Button value attribute
|
|
28
|
-
*/
|
|
29
|
-
const createButton = (config = {}) => {
|
|
30
|
-
const baseConfig = {
|
|
31
|
-
...config,
|
|
32
|
-
variant: config.variant || BUTTON_VARIANTS.FILLED,
|
|
33
|
-
componentName: 'button',
|
|
34
|
-
prefix: PREFIX
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
try {
|
|
38
|
-
const button = pipe(
|
|
39
|
-
createBase,
|
|
40
|
-
withEvents(),
|
|
41
|
-
withElement({
|
|
42
|
-
tag: 'button',
|
|
43
|
-
componentName: 'button',
|
|
44
|
-
attrs: {
|
|
45
|
-
type: config.type || 'button',
|
|
46
|
-
disabled: config.disabled,
|
|
47
|
-
value: config.value
|
|
48
|
-
},
|
|
49
|
-
className: config.class,
|
|
50
|
-
forwardEvents: {
|
|
51
|
-
click: (component) => !component.element.disabled,
|
|
52
|
-
focus: true,
|
|
53
|
-
blur: true
|
|
54
|
-
}
|
|
55
|
-
}),
|
|
56
|
-
withVariant(baseConfig),
|
|
57
|
-
withSize(baseConfig),
|
|
58
|
-
withText(baseConfig),
|
|
59
|
-
withIcon(baseConfig),
|
|
60
|
-
withDisabled(baseConfig),
|
|
61
|
-
withRipple(baseConfig),
|
|
62
|
-
withLifecycle(),
|
|
63
|
-
comp => withAPI({
|
|
64
|
-
disabled: {
|
|
65
|
-
enable: () => comp.disabled.enable(),
|
|
66
|
-
disable: () => comp.disabled.disable()
|
|
67
|
-
},
|
|
68
|
-
lifecycle: {
|
|
69
|
-
destroy: () => comp.lifecycle.destroy()
|
|
70
|
-
}
|
|
71
|
-
})(comp)
|
|
72
|
-
)(baseConfig)
|
|
73
|
-
|
|
74
|
-
return button
|
|
75
|
-
} catch (error) {
|
|
76
|
-
console.error('Button creation error:', error)
|
|
77
|
-
throw new Error(`Failed to create button: ${error.message}`)
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export default createButton
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
// src/components/button/constants.js
|
|
2
|
-
|
|
3
|
-
import { RIPPLE_SCHEMA } from '../../core/build/constants'
|
|
4
|
-
|
|
5
|
-
export const BUTTON_VARIANTS = {
|
|
6
|
-
FILLED: 'filled',
|
|
7
|
-
TONAL: 'tonal',
|
|
8
|
-
OUTLINED: 'outlined',
|
|
9
|
-
ELEVATED: 'elevated',
|
|
10
|
-
TEXT: 'text'
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export const BUTTON_SIZES = {
|
|
14
|
-
SMALL: 'small',
|
|
15
|
-
MEDIUM: 'medium',
|
|
16
|
-
LARGE: 'large'
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Validation schema for button configuration
|
|
21
|
-
*/
|
|
22
|
-
export const BUTTON_SCHEMA = {
|
|
23
|
-
variant: {
|
|
24
|
-
type: 'string',
|
|
25
|
-
enum: Object.values(BUTTON_VARIANTS),
|
|
26
|
-
required: false
|
|
27
|
-
},
|
|
28
|
-
size: {
|
|
29
|
-
type: 'string',
|
|
30
|
-
enum: Object.values(BUTTON_SIZES),
|
|
31
|
-
required: false
|
|
32
|
-
},
|
|
33
|
-
disabled: {
|
|
34
|
-
type: 'boolean',
|
|
35
|
-
required: false
|
|
36
|
-
},
|
|
37
|
-
text: {
|
|
38
|
-
type: 'string',
|
|
39
|
-
required: false
|
|
40
|
-
},
|
|
41
|
-
icon: {
|
|
42
|
-
type: 'string',
|
|
43
|
-
required: false
|
|
44
|
-
},
|
|
45
|
-
class: {
|
|
46
|
-
type: 'string',
|
|
47
|
-
required: false
|
|
48
|
-
},
|
|
49
|
-
value: {
|
|
50
|
-
type: 'string',
|
|
51
|
-
required: false
|
|
52
|
-
},
|
|
53
|
-
ripple: {
|
|
54
|
-
type: 'boolean',
|
|
55
|
-
required: false,
|
|
56
|
-
default: true
|
|
57
|
-
},
|
|
58
|
-
rippleConfig: {
|
|
59
|
-
type: 'object',
|
|
60
|
-
required: false,
|
|
61
|
-
properties: RIPPLE_SCHEMA
|
|
62
|
-
}
|
|
63
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
// src/components/checkbox/api.js
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Enhances checkbox component with API methods
|
|
5
|
-
* @param {Object} options - API configuration
|
|
6
|
-
* @param {Object} options.disabled - Disabled state handlers
|
|
7
|
-
* @param {Object} options.lifecycle - Lifecycle handlers
|
|
8
|
-
* @param {Object} options.checkable - Checked state handlers
|
|
9
|
-
*/
|
|
10
|
-
export const withAPI = ({ disabled, lifecycle, checkable }) => (component) => ({
|
|
11
|
-
...component,
|
|
12
|
-
element: component.element,
|
|
13
|
-
|
|
14
|
-
// Value management
|
|
15
|
-
getValue: component.getValue,
|
|
16
|
-
setValue (value) {
|
|
17
|
-
component.setValue(value)
|
|
18
|
-
return this
|
|
19
|
-
},
|
|
20
|
-
|
|
21
|
-
// State management
|
|
22
|
-
check: checkable.check,
|
|
23
|
-
uncheck: checkable.uncheck,
|
|
24
|
-
toggle: checkable.toggle,
|
|
25
|
-
isChecked: checkable.isChecked,
|
|
26
|
-
setIndeterminate: component.setIndeterminate,
|
|
27
|
-
|
|
28
|
-
// Label management
|
|
29
|
-
setLabel (text) {
|
|
30
|
-
component.text?.setText(text)
|
|
31
|
-
return this
|
|
32
|
-
},
|
|
33
|
-
getLabel () {
|
|
34
|
-
return component.text?.getText() || ''
|
|
35
|
-
},
|
|
36
|
-
|
|
37
|
-
// Event handling
|
|
38
|
-
on: component.on,
|
|
39
|
-
off: component.off,
|
|
40
|
-
|
|
41
|
-
// State management
|
|
42
|
-
enable: disabled.enable,
|
|
43
|
-
disable: disabled.disable,
|
|
44
|
-
destroy: lifecycle.destroy
|
|
45
|
-
})
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
// src/components/checkbox/checkbox.js
|
|
2
|
-
|
|
3
|
-
import { PREFIX } from '../../core/config'
|
|
4
|
-
import { pipe } from '../../core/compose'
|
|
5
|
-
import { createBase, withElement } from '../../core/compose/component'
|
|
6
|
-
import {
|
|
7
|
-
withEvents,
|
|
8
|
-
withTextLabel,
|
|
9
|
-
withDisabled,
|
|
10
|
-
withLifecycle,
|
|
11
|
-
withInput,
|
|
12
|
-
withCheckable
|
|
13
|
-
} from '../../core/compose/features'
|
|
14
|
-
import { withAPI } from './api'
|
|
15
|
-
import { CHECKBOX_VARIANTS } from './constants'
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Adds check icon to checkbox
|
|
19
|
-
* @param {Object} config - Component configuration
|
|
20
|
-
*/
|
|
21
|
-
const withCheckIcon = (config) => (component) => {
|
|
22
|
-
const icon = document.createElement('span')
|
|
23
|
-
icon.className = `${config.prefix}-checkbox-icon`
|
|
24
|
-
icon.innerHTML = `
|
|
25
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="currentColor">
|
|
26
|
-
<path d="M9.55 14.6L6.35 11.4l-1.9 1.9L9.55 18.4l10.9-10.9-1.9-1.9z"/>
|
|
27
|
-
</svg>
|
|
28
|
-
`
|
|
29
|
-
|
|
30
|
-
component.element.appendChild(icon)
|
|
31
|
-
return component
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Creates a new Checkbox component
|
|
36
|
-
* @param {Object} config - Checkbox configuration
|
|
37
|
-
* @param {string} [config.name] - Input name attribute
|
|
38
|
-
* @param {boolean} [config.checked] - Initial checked state
|
|
39
|
-
* @param {boolean} [config.indeterminate] - Initial indeterminate state
|
|
40
|
-
* @param {boolean} [config.required] - Whether input is required
|
|
41
|
-
* @param {boolean} [config.disabled] - Whether checkbox is disabled
|
|
42
|
-
* @param {string} [config.value] - Input value attribute
|
|
43
|
-
* @param {string} [config.label] - Label text
|
|
44
|
-
* @param {string} [config.labelPosition='end'] - Label position (start/end)
|
|
45
|
-
* @param {string} [config.variant='filled'] - Visual variant
|
|
46
|
-
* @param {string} [config.class] - Additional CSS classes
|
|
47
|
-
*/
|
|
48
|
-
const createCheckbox = (config = {}) => {
|
|
49
|
-
const baseConfig = {
|
|
50
|
-
...config,
|
|
51
|
-
componentName: 'checkbox',
|
|
52
|
-
prefix: PREFIX,
|
|
53
|
-
variant: config.variant || CHECKBOX_VARIANTS.FILLED
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const enhancedWithCheckable = (component) => {
|
|
57
|
-
const enhanced = withCheckable(baseConfig)(component)
|
|
58
|
-
|
|
59
|
-
// Add indeterminate state handling
|
|
60
|
-
if (config.indeterminate) {
|
|
61
|
-
enhanced.input.indeterminate = true
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
enhanced.setIndeterminate = (state) => {
|
|
65
|
-
enhanced.input.indeterminate = state
|
|
66
|
-
enhanced.element.classList.toggle(`${PREFIX}-checkbox--indeterminate`, state)
|
|
67
|
-
return enhanced
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return enhanced
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return pipe(
|
|
74
|
-
createBase,
|
|
75
|
-
withEvents(),
|
|
76
|
-
withElement({
|
|
77
|
-
tag: 'div',
|
|
78
|
-
componentName: 'checkbox',
|
|
79
|
-
className: config.class,
|
|
80
|
-
interactive: true
|
|
81
|
-
}),
|
|
82
|
-
withInput(baseConfig),
|
|
83
|
-
withCheckIcon(baseConfig),
|
|
84
|
-
withTextLabel(baseConfig),
|
|
85
|
-
enhancedWithCheckable,
|
|
86
|
-
withDisabled(baseConfig), // Pass the baseConfig to withDisabled
|
|
87
|
-
withLifecycle(),
|
|
88
|
-
comp => withAPI({
|
|
89
|
-
disabled: comp.disabled,
|
|
90
|
-
lifecycle: comp.lifecycle,
|
|
91
|
-
checkable: comp.checkable
|
|
92
|
-
})(comp)
|
|
93
|
-
)(baseConfig)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
export default createCheckbox
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
// src/components/container/api.js
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Enhances container component with API methods
|
|
5
|
-
* @param {Object} options - API configuration
|
|
6
|
-
* @param {Object} options.lifecycle - Lifecycle handlers
|
|
7
|
-
*/
|
|
8
|
-
export const withAPI = ({ lifecycle }) => (component) => ({
|
|
9
|
-
...component,
|
|
10
|
-
element: component.element,
|
|
11
|
-
|
|
12
|
-
// Attribute management
|
|
13
|
-
get (prop) {
|
|
14
|
-
return component.element.getAttribute(prop)
|
|
15
|
-
},
|
|
16
|
-
set (prop, value) {
|
|
17
|
-
value === null
|
|
18
|
-
? component.element.removeAttribute(prop)
|
|
19
|
-
: component.element.setAttribute(prop, value)
|
|
20
|
-
return this
|
|
21
|
-
},
|
|
22
|
-
|
|
23
|
-
// Content management
|
|
24
|
-
setContent (content) {
|
|
25
|
-
if (content instanceof Node) {
|
|
26
|
-
component.element.appendChild(content)
|
|
27
|
-
} else {
|
|
28
|
-
component.element.innerHTML = content
|
|
29
|
-
}
|
|
30
|
-
return this
|
|
31
|
-
},
|
|
32
|
-
getContent () {
|
|
33
|
-
return component.element.innerHTML
|
|
34
|
-
},
|
|
35
|
-
|
|
36
|
-
// Event handling
|
|
37
|
-
on: component.on,
|
|
38
|
-
off: component.off,
|
|
39
|
-
|
|
40
|
-
// Lifecycle
|
|
41
|
-
destroy: lifecycle.destroy
|
|
42
|
-
})
|