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.
Files changed (220) hide show
  1. package/README.md +70 -22
  2. package/index.ts +33 -0
  3. package/package.json +14 -5
  4. package/src/components/button/{styles.scss → _styles.scss} +2 -2
  5. package/src/components/button/api.ts +89 -0
  6. package/src/components/button/button.ts +50 -0
  7. package/src/components/button/config.ts +75 -0
  8. package/src/components/button/constants.ts +17 -0
  9. package/src/components/button/index.ts +4 -0
  10. package/src/components/button/types.ts +118 -0
  11. package/src/components/card/_styles.scss +359 -0
  12. package/src/components/card/actions.ts +48 -0
  13. package/src/components/card/api.ts +102 -0
  14. package/src/components/card/card.ts +41 -0
  15. package/src/components/card/config.ts +99 -0
  16. package/src/components/card/constants.ts +69 -0
  17. package/src/components/card/content.ts +48 -0
  18. package/src/components/card/features.ts +228 -0
  19. package/src/components/card/header.ts +88 -0
  20. package/src/components/card/index.ts +19 -0
  21. package/src/components/card/media.ts +52 -0
  22. package/src/components/card/types.ts +174 -0
  23. package/src/components/checkbox/api.ts +82 -0
  24. package/src/components/checkbox/checkbox.ts +75 -0
  25. package/src/components/checkbox/config.ts +90 -0
  26. package/src/components/checkbox/index.ts +4 -0
  27. package/src/components/checkbox/types.ts +146 -0
  28. package/src/components/chip/_styles.scss +372 -0
  29. package/src/components/chip/api.ts +115 -0
  30. package/src/components/chip/chip-set.ts +225 -0
  31. package/src/components/chip/chip.ts +82 -0
  32. package/src/components/chip/config.ts +92 -0
  33. package/src/components/chip/constants.ts +38 -0
  34. package/src/components/chip/index.ts +4 -0
  35. package/src/components/chip/types.ts +172 -0
  36. package/src/components/list/api.ts +72 -0
  37. package/src/components/list/config.ts +43 -0
  38. package/src/components/list/{constants.js → constants.ts} +34 -7
  39. package/src/components/list/features.ts +224 -0
  40. package/src/components/list/index.ts +14 -0
  41. package/src/components/list/list-item.ts +120 -0
  42. package/src/components/list/list.ts +37 -0
  43. package/src/components/list/types.ts +179 -0
  44. package/src/components/list/utils.ts +47 -0
  45. package/src/components/menu/api.ts +119 -0
  46. package/src/components/menu/config.ts +54 -0
  47. package/src/components/menu/constants.ts +154 -0
  48. package/src/components/menu/features/items-manager.ts +457 -0
  49. package/src/components/menu/features/keyboard-navigation.ts +133 -0
  50. package/src/components/menu/features/positioning.ts +127 -0
  51. package/src/components/menu/features/{visibility.js → visibility.ts} +66 -64
  52. package/src/components/menu/index.ts +14 -0
  53. package/src/components/menu/menu-item.ts +43 -0
  54. package/src/components/menu/menu.ts +53 -0
  55. package/src/components/menu/types.ts +178 -0
  56. package/src/components/navigation/api.ts +79 -0
  57. package/src/components/navigation/config.ts +61 -0
  58. package/src/components/navigation/{constants.js → constants.ts} +10 -10
  59. package/src/components/navigation/index.ts +14 -0
  60. package/src/components/navigation/nav-item.ts +148 -0
  61. package/src/components/navigation/navigation.ts +50 -0
  62. package/src/components/navigation/types.ts +212 -0
  63. package/src/components/progress/_styles.scss +204 -0
  64. package/src/components/progress/api.ts +179 -0
  65. package/src/components/progress/config.ts +124 -0
  66. package/src/components/progress/constants.ts +43 -0
  67. package/src/components/progress/index.ts +5 -0
  68. package/src/components/progress/progress.ts +163 -0
  69. package/src/components/progress/types.ts +102 -0
  70. package/src/components/snackbar/api.ts +162 -0
  71. package/src/components/snackbar/config.ts +62 -0
  72. package/src/components/snackbar/{constants.js → constants.ts} +21 -4
  73. package/src/components/snackbar/features.ts +76 -0
  74. package/src/components/snackbar/index.ts +4 -0
  75. package/src/components/snackbar/position.ts +71 -0
  76. package/src/components/snackbar/queue.ts +76 -0
  77. package/src/components/snackbar/snackbar.ts +60 -0
  78. package/src/components/snackbar/types.ts +58 -0
  79. package/src/components/switch/api.ts +77 -0
  80. package/src/components/switch/config.ts +74 -0
  81. package/src/components/switch/index.ts +4 -0
  82. package/src/components/switch/switch.ts +52 -0
  83. package/src/components/switch/types.ts +142 -0
  84. package/src/components/textfield/api.ts +72 -0
  85. package/src/components/textfield/config.ts +54 -0
  86. package/src/components/textfield/{constants.js → constants.ts} +38 -5
  87. package/src/components/textfield/index.ts +4 -0
  88. package/src/components/textfield/textfield.ts +50 -0
  89. package/src/components/textfield/types.ts +139 -0
  90. package/src/core/compose/base.ts +43 -0
  91. package/src/core/compose/component.ts +247 -0
  92. package/src/core/compose/features/checkable.ts +155 -0
  93. package/src/core/compose/features/disabled.ts +116 -0
  94. package/src/core/compose/features/events.ts +65 -0
  95. package/src/core/compose/features/icon.ts +67 -0
  96. package/src/core/compose/features/index.ts +35 -0
  97. package/src/core/compose/features/input.ts +174 -0
  98. package/src/core/compose/features/lifecycle.ts +139 -0
  99. package/src/core/compose/features/position.ts +94 -0
  100. package/src/core/compose/features/ripple.ts +55 -0
  101. package/src/core/compose/features/size.ts +29 -0
  102. package/src/core/compose/features/style.ts +31 -0
  103. package/src/core/compose/features/text.ts +44 -0
  104. package/src/core/compose/features/textinput.ts +225 -0
  105. package/src/core/compose/features/textlabel.ts +92 -0
  106. package/src/core/compose/features/track.ts +84 -0
  107. package/src/core/compose/features/variant.ts +29 -0
  108. package/src/core/compose/features/withEvents.ts +137 -0
  109. package/src/core/compose/index.ts +54 -0
  110. package/src/core/compose/{pipe.js → pipe.ts} +16 -11
  111. package/src/core/config/component-config.ts +136 -0
  112. package/src/core/config.ts +211 -0
  113. package/src/core/dom/{attributes.js → attributes.ts} +11 -11
  114. package/src/core/dom/classes.ts +60 -0
  115. package/src/core/dom/create.ts +188 -0
  116. package/src/core/dom/events.ts +209 -0
  117. package/src/core/dom/index.ts +10 -0
  118. package/src/core/dom/utils.ts +97 -0
  119. package/src/core/index.ts +111 -0
  120. package/src/core/state/disabled.ts +81 -0
  121. package/src/core/state/emitter.ts +94 -0
  122. package/src/core/state/events.ts +88 -0
  123. package/src/core/state/index.ts +16 -0
  124. package/src/core/state/lifecycle.ts +131 -0
  125. package/src/core/state/store.ts +197 -0
  126. package/src/core/utils/index.ts +45 -0
  127. package/src/core/utils/{mobile.js → mobile.ts} +48 -24
  128. package/src/core/utils/object.ts +41 -0
  129. package/src/core/utils/validate.ts +234 -0
  130. package/src/{index.js → index.ts} +4 -2
  131. package/index.js +0 -11
  132. package/src/components/button/api.js +0 -54
  133. package/src/components/button/button.js +0 -81
  134. package/src/components/button/config.js +0 -10
  135. package/src/components/button/constants.js +0 -63
  136. package/src/components/button/index.js +0 -2
  137. package/src/components/checkbox/api.js +0 -45
  138. package/src/components/checkbox/checkbox.js +0 -96
  139. package/src/components/checkbox/index.js +0 -2
  140. package/src/components/container/api.js +0 -42
  141. package/src/components/container/container.js +0 -45
  142. package/src/components/container/index.js +0 -2
  143. package/src/components/container/styles.scss +0 -66
  144. package/src/components/list/index.js +0 -2
  145. package/src/components/list/list-item.js +0 -147
  146. package/src/components/list/list.js +0 -267
  147. package/src/components/menu/api.js +0 -117
  148. package/src/components/menu/constants.js +0 -42
  149. package/src/components/menu/features/items-manager.js +0 -375
  150. package/src/components/menu/features/keyboard-navigation.js +0 -129
  151. package/src/components/menu/features/positioning.js +0 -125
  152. package/src/components/menu/index.js +0 -2
  153. package/src/components/menu/menu-item.js +0 -41
  154. package/src/components/menu/menu.js +0 -54
  155. package/src/components/navigation/api.js +0 -43
  156. package/src/components/navigation/index.js +0 -2
  157. package/src/components/navigation/nav-item.js +0 -137
  158. package/src/components/navigation/navigation.js +0 -55
  159. package/src/components/snackbar/api.js +0 -125
  160. package/src/components/snackbar/features.js +0 -69
  161. package/src/components/snackbar/index.js +0 -2
  162. package/src/components/snackbar/position.js +0 -63
  163. package/src/components/snackbar/queue.js +0 -74
  164. package/src/components/snackbar/snackbar.js +0 -70
  165. package/src/components/switch/api.js +0 -44
  166. package/src/components/switch/index.js +0 -2
  167. package/src/components/switch/switch.js +0 -71
  168. package/src/components/textfield/api.js +0 -49
  169. package/src/components/textfield/index.js +0 -2
  170. package/src/components/textfield/textfield.js +0 -68
  171. package/src/core/build/_ripple.scss +0 -79
  172. package/src/core/build/constants.js +0 -51
  173. package/src/core/build/icon.js +0 -78
  174. package/src/core/build/ripple.js +0 -159
  175. package/src/core/build/text.js +0 -54
  176. package/src/core/compose/base.js +0 -8
  177. package/src/core/compose/component.js +0 -225
  178. package/src/core/compose/features/checkable.js +0 -114
  179. package/src/core/compose/features/disabled.js +0 -64
  180. package/src/core/compose/features/events.js +0 -48
  181. package/src/core/compose/features/icon.js +0 -33
  182. package/src/core/compose/features/index.js +0 -20
  183. package/src/core/compose/features/input.js +0 -100
  184. package/src/core/compose/features/lifecycle.js +0 -69
  185. package/src/core/compose/features/position.js +0 -60
  186. package/src/core/compose/features/ripple.js +0 -32
  187. package/src/core/compose/features/size.js +0 -9
  188. package/src/core/compose/features/style.js +0 -12
  189. package/src/core/compose/features/text.js +0 -17
  190. package/src/core/compose/features/textinput.js +0 -114
  191. package/src/core/compose/features/textlabel.js +0 -28
  192. package/src/core/compose/features/track.js +0 -49
  193. package/src/core/compose/features/variant.js +0 -9
  194. package/src/core/compose/features/withEvents.js +0 -67
  195. package/src/core/compose/index.js +0 -16
  196. package/src/core/config.js +0 -140
  197. package/src/core/dom/classes.js +0 -70
  198. package/src/core/dom/create.js +0 -132
  199. package/src/core/dom/events.js +0 -175
  200. package/src/core/dom/index.js +0 -5
  201. package/src/core/dom/utils.js +0 -22
  202. package/src/core/index.js +0 -23
  203. package/src/core/state/disabled.js +0 -51
  204. package/src/core/state/emitter.js +0 -63
  205. package/src/core/state/events.js +0 -29
  206. package/src/core/state/index.js +0 -6
  207. package/src/core/state/lifecycle.js +0 -64
  208. package/src/core/state/store.js +0 -112
  209. package/src/core/utils/index.js +0 -39
  210. package/src/core/utils/object.js +0 -22
  211. package/src/core/utils/validate.js +0 -37
  212. /package/src/components/checkbox/{styles.scss → _styles.scss} +0 -0
  213. /package/src/components/checkbox/{constants.js → constants.ts} +0 -0
  214. /package/src/components/list/{styles.scss → _styles.scss} +0 -0
  215. /package/src/components/menu/{styles.scss → _styles.scss} +0 -0
  216. /package/src/components/navigation/{styles.scss → _styles.scss} +0 -0
  217. /package/src/components/snackbar/{styles.scss → _styles.scss} +0 -0
  218. /package/src/components/switch/{styles.scss → _styles.scss} +0 -0
  219. /package/src/components/switch/{constants.js → constants.ts} +0 -0
  220. /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.js
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 createContainer } from './components/container'
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,10 +0,0 @@
1
- // src/components/button/config.js
2
-
3
- import { PREFIX } from '../../core/config'
4
-
5
- const defaultConfig = {
6
- componentName: 'button',
7
- prefix: PREFIX
8
- }
9
-
10
- export default defaultConfig
@@ -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,2 +0,0 @@
1
- // src/components/button/index.js
2
- export { default } from './button.js'
@@ -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,2 +0,0 @@
1
- // src/components/checkbox/index.js
2
- export { default } from './checkbox.js'
@@ -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
- })