mtrl 0.2.5 → 0.2.7

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 (196) hide show
  1. package/index.ts +18 -0
  2. package/package.json +1 -1
  3. package/src/components/badge/_styles.scss +123 -115
  4. package/src/components/badge/api.ts +57 -59
  5. package/src/components/badge/badge.ts +16 -2
  6. package/src/components/badge/config.ts +65 -11
  7. package/src/components/badge/constants.ts +22 -12
  8. package/src/components/badge/features.ts +44 -40
  9. package/src/components/badge/types.ts +42 -30
  10. package/src/components/bottom-app-bar/_styles.scss +103 -0
  11. package/src/components/bottom-app-bar/bottom-app-bar.ts +196 -0
  12. package/src/components/bottom-app-bar/config.ts +73 -0
  13. package/src/components/bottom-app-bar/index.ts +11 -0
  14. package/src/components/bottom-app-bar/types.ts +108 -0
  15. package/src/components/button/_styles.scss +0 -66
  16. package/src/components/button/api.ts +5 -0
  17. package/src/components/button/button.ts +0 -2
  18. package/src/components/button/config.ts +5 -0
  19. package/src/components/button/constants.ts +0 -6
  20. package/src/components/button/index.ts +2 -2
  21. package/src/components/button/types.ts +7 -7
  22. package/src/components/card/_styles.scss +67 -25
  23. package/src/components/card/api.ts +54 -3
  24. package/src/components/card/card.ts +25 -6
  25. package/src/components/card/config.ts +189 -22
  26. package/src/components/card/constants.ts +20 -19
  27. package/src/components/card/content.ts +299 -2
  28. package/src/components/card/features.ts +158 -4
  29. package/src/components/card/index.ts +31 -9
  30. package/src/components/card/types.ts +166 -15
  31. package/src/components/checkbox/_styles.scss +0 -2
  32. package/src/components/chip/chip.ts +1 -9
  33. package/src/components/chip/constants.ts +0 -10
  34. package/src/components/chip/index.ts +1 -1
  35. package/src/components/chip/types.ts +1 -4
  36. package/src/components/datepicker/_styles.scss +358 -0
  37. package/src/components/datepicker/api.ts +272 -0
  38. package/src/components/datepicker/config.ts +144 -0
  39. package/src/components/datepicker/constants.ts +98 -0
  40. package/src/components/datepicker/datepicker.ts +346 -0
  41. package/src/components/datepicker/index.ts +9 -0
  42. package/src/components/datepicker/render.ts +452 -0
  43. package/src/components/datepicker/types.ts +268 -0
  44. package/src/components/datepicker/utils.ts +290 -0
  45. package/src/components/dialog/_styles.scss +174 -128
  46. package/src/components/dialog/api.ts +48 -13
  47. package/src/components/dialog/config.ts +9 -5
  48. package/src/components/dialog/dialog.ts +6 -3
  49. package/src/components/dialog/features.ts +290 -130
  50. package/src/components/dialog/types.ts +7 -4
  51. package/src/components/divider/_styles.scss +57 -0
  52. package/src/components/divider/config.ts +81 -0
  53. package/src/components/divider/divider.ts +37 -0
  54. package/src/components/divider/features.ts +207 -0
  55. package/src/components/divider/index.ts +5 -0
  56. package/src/components/divider/types.ts +55 -0
  57. package/src/components/extended-fab/_styles.scss +267 -0
  58. package/src/components/extended-fab/api.ts +141 -0
  59. package/src/components/extended-fab/config.ts +108 -0
  60. package/src/components/extended-fab/constants.ts +36 -0
  61. package/src/components/extended-fab/extended-fab.ts +125 -0
  62. package/src/components/extended-fab/index.ts +4 -0
  63. package/src/components/extended-fab/types.ts +287 -0
  64. package/src/components/fab/_styles.scss +225 -0
  65. package/src/components/fab/api.ts +97 -0
  66. package/src/components/fab/config.ts +94 -0
  67. package/src/components/fab/constants.ts +41 -0
  68. package/src/components/fab/fab.ts +67 -0
  69. package/src/components/fab/index.ts +4 -0
  70. package/src/components/fab/types.ts +234 -0
  71. package/src/components/navigation/_styles.scss +1 -0
  72. package/src/components/navigation/api.ts +78 -50
  73. package/src/components/navigation/features/items.ts +280 -0
  74. package/src/components/navigation/nav-item.ts +72 -23
  75. package/src/components/navigation/navigation.ts +54 -2
  76. package/src/components/navigation/types.ts +210 -188
  77. package/src/components/progress/_styles.scss +0 -65
  78. package/src/components/progress/config.ts +1 -2
  79. package/src/components/progress/constants.ts +0 -14
  80. package/src/components/progress/index.ts +1 -1
  81. package/src/components/progress/progress.ts +1 -4
  82. package/src/components/progress/types.ts +1 -4
  83. package/src/components/radios/_styles.scss +0 -45
  84. package/src/components/radios/api.ts +85 -60
  85. package/src/components/radios/config.ts +1 -2
  86. package/src/components/radios/constants.ts +0 -9
  87. package/src/components/radios/index.ts +1 -1
  88. package/src/components/radios/radio.ts +34 -11
  89. package/src/components/radios/radios.ts +2 -1
  90. package/src/components/radios/types.ts +1 -7
  91. package/src/components/search/_styles.scss +306 -0
  92. package/src/components/search/api.ts +203 -0
  93. package/src/components/search/config.ts +87 -0
  94. package/src/components/search/constants.ts +21 -0
  95. package/src/components/search/features/index.ts +4 -0
  96. package/src/components/search/features/search.ts +718 -0
  97. package/src/components/search/features/states.ts +165 -0
  98. package/src/components/search/features/structure.ts +198 -0
  99. package/src/components/search/index.ts +10 -0
  100. package/src/components/search/search.ts +52 -0
  101. package/src/components/search/types.ts +163 -0
  102. package/src/components/segmented-button/_styles.scss +117 -0
  103. package/src/components/segmented-button/config.ts +67 -0
  104. package/src/components/segmented-button/constants.ts +42 -0
  105. package/src/components/segmented-button/index.ts +4 -0
  106. package/src/components/segmented-button/segment.ts +155 -0
  107. package/src/components/segmented-button/segmented-button.ts +250 -0
  108. package/src/components/segmented-button/types.ts +219 -0
  109. package/src/components/slider/_styles.scss +221 -168
  110. package/src/components/slider/accessibility.md +59 -0
  111. package/src/components/slider/api.ts +41 -120
  112. package/src/components/slider/config.ts +51 -49
  113. package/src/components/slider/features/handlers.ts +495 -0
  114. package/src/components/slider/features/index.ts +1 -2
  115. package/src/components/slider/features/slider.ts +66 -84
  116. package/src/components/slider/features/states.ts +195 -0
  117. package/src/components/slider/features/structure.ts +141 -184
  118. package/src/components/slider/features/ui.ts +150 -201
  119. package/src/components/slider/index.ts +2 -11
  120. package/src/components/slider/slider.ts +9 -12
  121. package/src/components/slider/types.ts +39 -24
  122. package/src/components/switch/_styles.scss +0 -2
  123. package/src/components/tabs/_styles.scss +346 -154
  124. package/src/components/tabs/api.ts +178 -400
  125. package/src/components/tabs/config.ts +46 -52
  126. package/src/components/tabs/constants.ts +85 -8
  127. package/src/components/tabs/features.ts +403 -0
  128. package/src/components/tabs/index.ts +60 -3
  129. package/src/components/tabs/indicator.ts +285 -0
  130. package/src/components/tabs/responsive.ts +144 -0
  131. package/src/components/tabs/scroll-indicators.ts +149 -0
  132. package/src/components/tabs/state.ts +186 -0
  133. package/src/components/tabs/tab-api.ts +258 -0
  134. package/src/components/tabs/tab.ts +255 -0
  135. package/src/components/tabs/tabs.ts +50 -31
  136. package/src/components/tabs/types.ts +332 -128
  137. package/src/components/tabs/utils.ts +107 -0
  138. package/src/components/textfield/_styles.scss +0 -98
  139. package/src/components/textfield/config.ts +2 -3
  140. package/src/components/textfield/constants.ts +0 -14
  141. package/src/components/textfield/index.ts +2 -2
  142. package/src/components/textfield/textfield.ts +0 -2
  143. package/src/components/textfield/types.ts +1 -4
  144. package/src/components/timepicker/README.md +277 -0
  145. package/src/components/timepicker/_styles.scss +451 -0
  146. package/src/components/timepicker/api.ts +632 -0
  147. package/src/components/timepicker/clockdial.ts +482 -0
  148. package/src/components/timepicker/config.ts +130 -0
  149. package/src/components/timepicker/constants.ts +138 -0
  150. package/src/components/timepicker/index.ts +8 -0
  151. package/src/components/timepicker/render.ts +613 -0
  152. package/src/components/timepicker/timepicker.ts +117 -0
  153. package/src/components/timepicker/types.ts +336 -0
  154. package/src/components/timepicker/utils.ts +241 -0
  155. package/src/components/top-app-bar/_styles.scss +225 -0
  156. package/src/components/top-app-bar/config.ts +83 -0
  157. package/src/components/top-app-bar/index.ts +11 -0
  158. package/src/components/top-app-bar/top-app-bar.ts +316 -0
  159. package/src/components/top-app-bar/types.ts +140 -0
  160. package/src/core/build/_ripple.scss +6 -6
  161. package/src/core/build/ripple.ts +72 -95
  162. package/src/core/compose/component.ts +1 -1
  163. package/src/core/compose/features/badge.ts +79 -0
  164. package/src/core/compose/features/icon.ts +3 -1
  165. package/src/core/compose/features/index.ts +3 -1
  166. package/src/core/compose/features/ripple.ts +4 -1
  167. package/src/core/compose/features/textlabel.ts +26 -2
  168. package/src/core/dom/create.ts +5 -0
  169. package/src/index.ts +9 -0
  170. package/src/styles/abstract/_theme.scss +115 -3
  171. package/src/styles/themes/_autumn.scss +21 -0
  172. package/src/styles/themes/_base-theme.scss +61 -0
  173. package/src/styles/themes/_baseline.scss +58 -0
  174. package/src/styles/themes/_bluekhaki.scss +125 -0
  175. package/src/styles/themes/_brownbeige.scss +125 -0
  176. package/src/styles/themes/_browngreen.scss +125 -0
  177. package/src/styles/themes/_forest.scss +6 -0
  178. package/src/styles/themes/_greenbeige.scss +125 -0
  179. package/src/styles/themes/_material.scss +125 -0
  180. package/src/styles/themes/_ocean.scss +6 -0
  181. package/src/styles/themes/_sageivory.scss +125 -0
  182. package/src/styles/themes/_spring.scss +6 -0
  183. package/src/styles/themes/_summer.scss +5 -0
  184. package/src/styles/themes/_sunset.scss +5 -0
  185. package/src/styles/themes/_tealcaramel.scss +125 -0
  186. package/src/styles/themes/_winter.scss +6 -0
  187. package/src/components/card/actions.ts +0 -48
  188. package/src/components/card/header.ts +0 -88
  189. package/src/components/card/media.ts +0 -52
  190. package/src/components/navigation/features/items.js +0 -192
  191. package/src/components/slider/features/appearance.ts +0 -94
  192. package/src/components/slider/features/disabled.ts +0 -43
  193. package/src/components/slider/features/events.ts +0 -164
  194. package/src/components/slider/features/interactions.ts +0 -261
  195. package/src/components/slider/features/keyboard.ts +0 -112
  196. package/src/core/collection/adapters/mongodb.js +0 -232
@@ -3,6 +3,9 @@ import { PREFIX } from '../../core/config';
3
3
  import { createElement } from '../../core/dom/create';
4
4
  import { BaseComponent, CardComponent, LoadingFeature, ExpandableFeature, SwipeableFeature } from './types';
5
5
 
6
+ import { createCardHeader, createCardContent, createCardMedia, createCardActions } from './content';
7
+ import { BaseComponent, CardComponent, CardHeaderConfig, CardContentConfig, CardMediaConfig, CardActionsConfig, CardSchema, ButtonConfig } from './types';
8
+
6
9
  interface LoadingConfig {
7
10
  initialState?: boolean;
8
11
  }
@@ -20,8 +23,21 @@ interface SwipeableConfig {
20
23
 
21
24
  /**
22
25
  * Higher-order function to add loading state to a card
26
+ *
23
27
  * @param {LoadingConfig} config - Loading state configuration
24
28
  * @returns {Function} Card component enhancer
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * // Create a card with loading state
33
+ * const card = pipe(
34
+ * createCard,
35
+ * withLoading({ initialState: true })
36
+ * )();
37
+ *
38
+ * // Toggle loading state
39
+ * setTimeout(() => card.loading.setLoading(false), 2000);
40
+ * ```
25
41
  */
26
42
  export const withLoading = (config: LoadingConfig = {}) => (component: BaseComponent): BaseComponent & { loading: LoadingFeature } => {
27
43
  const initialState = config.initialState || false;
@@ -36,7 +52,12 @@ export const withLoading = (config: LoadingConfig = {}) => (component: BaseCompo
36
52
  loadingElement = createElement({
37
53
  tag: 'div',
38
54
  className: `${PREFIX}-card-loading-overlay`,
39
- container: component.element
55
+ container: component.element,
56
+ attrs: {
57
+ 'role': 'progressbar',
58
+ 'aria-busy': 'true',
59
+ 'aria-label': 'Loading'
60
+ }
40
61
  });
41
62
 
42
63
  // Add spinner
@@ -47,11 +68,13 @@ export const withLoading = (config: LoadingConfig = {}) => (component: BaseCompo
47
68
  });
48
69
 
49
70
  component.element.classList.add(`${PREFIX}-card--state-loading`);
71
+ component.element.setAttribute('aria-busy', 'true');
50
72
  } else if (!loading && loadingElement) {
51
73
  // Remove loading overlay
52
74
  loadingElement.remove();
53
75
  loadingElement = null;
54
76
  component.element.classList.remove(`${PREFIX}-card--state-loading`);
77
+ component.element.setAttribute('aria-busy', 'false');
55
78
  }
56
79
  }
57
80
 
@@ -68,10 +91,61 @@ export const withLoading = (config: LoadingConfig = {}) => (component: BaseCompo
68
91
  };
69
92
  };
70
93
 
94
+ /**
95
+ * Higher-order function to add elevation to a card based on its variant
96
+ *
97
+ * Sets the initial elevation CSS variable according to Material Design 3 guidelines:
98
+ * - Elevated variant: 1dp elevation
99
+ * - Filled and outlined variants: 0dp elevation
100
+ *
101
+ * @param {BaseComponent} component - Card component
102
+ * @returns {BaseComponent} Card component with elevation applied
103
+ * @example
104
+ * ```typescript
105
+ * // Apply elevation in the composition chain
106
+ * const card = pipe(
107
+ * createBase,
108
+ * withElement(config),
109
+ * withElevation
110
+ * )(baseConfig);
111
+ * ```
112
+ */
113
+ export const withElevation = (component: BaseComponent): BaseComponent => {
114
+ const config = component.config;
115
+
116
+ // Set initial elevation based on variant
117
+ if (config.variant === 'elevated') {
118
+ component.element.style.setProperty('--card-elevation', '1');
119
+ } else {
120
+ component.element.style.setProperty('--card-elevation', '0');
121
+ }
122
+
123
+ return component;
124
+ };
125
+
71
126
  /**
72
127
  * Higher-order function to add expandable behavior to a card
128
+ *
73
129
  * @param {ExpandableConfig} config - Expandable configuration
74
130
  * @returns {Function} Card component enhancer
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * // Create a card with expandable content
135
+ * const expandableContent = document.createElement('div');
136
+ * expandableContent.textContent = 'Additional content that can be expanded';
137
+ *
138
+ * const card = pipe(
139
+ * createCard,
140
+ * withExpandable({
141
+ * initialExpanded: false,
142
+ * expandableContent
143
+ * })
144
+ * )();
145
+ *
146
+ * // Later toggle the expanded state
147
+ * card.expandable.toggleExpanded();
148
+ * ```
75
149
  */
76
150
  export const withExpandable = (config: ExpandableConfig = {}) => (component: BaseComponent): BaseComponent & { expandable: ExpandableFeature } => {
77
151
  const initialExpanded = config.initialExpanded || false;
@@ -85,7 +159,8 @@ export const withExpandable = (config: ExpandableConfig = {}) => (component: Bas
85
159
  className: `${PREFIX}-card-expand-button`,
86
160
  attrs: {
87
161
  'aria-expanded': isExpanded ? 'true' : 'false',
88
- 'aria-label': isExpanded ? 'Collapse' : 'Expand'
162
+ 'aria-label': isExpanded ? 'Collapse content' : 'Expand content',
163
+ 'aria-controls': expandableContent?.id || `${component.element.id || 'card'}-expandable-content`
89
164
  }
90
165
  }) as HTMLButtonElement;
91
166
 
@@ -98,7 +173,10 @@ export const withExpandable = (config: ExpandableConfig = {}) => (component: Bas
98
173
  const newActionsContainer = createElement({
99
174
  tag: 'div',
100
175
  className: `${PREFIX}-card-actions`,
101
- container: component.element
176
+ container: component.element,
177
+ attrs: {
178
+ 'role': 'group'
179
+ }
102
180
  });
103
181
  newActionsContainer.appendChild(expandButton);
104
182
  }
@@ -106,9 +184,19 @@ export const withExpandable = (config: ExpandableConfig = {}) => (component: Bas
106
184
  // Set initial state
107
185
  if (expandableContent) {
108
186
  expandableContent.classList.add(`${PREFIX}-card-expandable-content`);
187
+
188
+ // Ensure the expandable content has an ID for ARIA controls
189
+ if (!expandableContent.id) {
190
+ expandableContent.id = `${component.element.id || 'card'}-expandable-content`;
191
+ }
192
+
109
193
  if (!initialExpanded) {
110
194
  expandableContent.style.display = 'none';
195
+ expandableContent.setAttribute('aria-hidden', 'true');
196
+ } else {
197
+ expandableContent.setAttribute('aria-hidden', 'false');
111
198
  }
199
+
112
200
  component.element.appendChild(expandableContent);
113
201
  }
114
202
 
@@ -118,10 +206,11 @@ export const withExpandable = (config: ExpandableConfig = {}) => (component: Bas
118
206
 
119
207
  if (expandableContent) {
120
208
  expandableContent.style.display = expanded ? 'block' : 'none';
209
+ expandableContent.setAttribute('aria-hidden', expanded ? 'false' : 'true');
121
210
  }
122
211
 
123
212
  expandButton.setAttribute('aria-expanded', expanded ? 'true' : 'false');
124
- expandButton.setAttribute('aria-label', expanded ? 'Collapse' : 'Expand');
213
+ expandButton.setAttribute('aria-label', expanded ? 'Collapse content' : 'Expand content');
125
214
 
126
215
  if (expanded) {
127
216
  component.element.classList.add(`${PREFIX}-card--expanded`);
@@ -143,6 +232,14 @@ export const withExpandable = (config: ExpandableConfig = {}) => (component: Bas
143
232
  toggleExpanded();
144
233
  });
145
234
 
235
+ // Add keyboard handler for accessibility
236
+ expandButton.addEventListener('keydown', (e: KeyboardEvent) => {
237
+ if (e.key === 'Enter' || e.key === ' ') {
238
+ e.preventDefault();
239
+ toggleExpanded();
240
+ }
241
+ });
242
+
146
243
  return {
147
244
  ...component,
148
245
  expandable: {
@@ -155,13 +252,70 @@ export const withExpandable = (config: ExpandableConfig = {}) => (component: Bas
155
252
 
156
253
  /**
157
254
  * Higher-order function to add swipeable behavior to a card
255
+ *
158
256
  * @param {SwipeableConfig} config - Swipeable configuration
159
257
  * @returns {Function} Card component enhancer
258
+ *
259
+ * @example
260
+ * ```typescript
261
+ * // Create a swipeable card
262
+ * const card = pipe(
263
+ * createCard,
264
+ * withSwipeable({
265
+ * threshold: 100,
266
+ * onSwipeLeft: (card) => console.log('Swiped left'),
267
+ * onSwipeRight: (card) => console.log('Swiped right')
268
+ * })
269
+ * )({ variant: CardVariant.ELEVATED });
270
+ * ```
160
271
  */
161
272
  export const withSwipeable = (config: SwipeableConfig = {}) => (component: BaseComponent): BaseComponent & { swipeable: SwipeableFeature } => {
162
273
  const threshold = config.threshold || 100;
163
274
  let startX = 0;
164
275
  let currentX = 0;
276
+
277
+ // Add accessibility information for swipeable cards
278
+ component.element.setAttribute('aria-description', 'Swipeable card. Swipe left or right to perform actions.');
279
+
280
+ // Create hidden buttons for keyboard accessibility
281
+ const leftActionButton = createElement({
282
+ tag: 'button',
283
+ className: `${PREFIX}-card-swipe-left-action`,
284
+ text: 'Swipe Left Action',
285
+ container: component.element,
286
+ attrs: {
287
+ 'aria-label': 'Perform swipe left action',
288
+ 'style': 'position: absolute; left: -9999px; top: -9999px; visibility: hidden;' // Visually hidden but accessible
289
+ }
290
+ }) as HTMLButtonElement;
291
+
292
+ const rightActionButton = createElement({
293
+ tag: 'button',
294
+ className: `${PREFIX}-card-swipe-right-action`,
295
+ text: 'Swipe Right Action',
296
+ container: component.element,
297
+ attrs: {
298
+ 'aria-label': 'Perform swipe right action',
299
+ 'style': 'position: absolute; left: -9999px; top: -9999px; visibility: hidden;' // Visually hidden but accessible
300
+ }
301
+ }) as HTMLButtonElement;
302
+
303
+ // Add keyboard handlers to the hidden buttons
304
+ leftActionButton.addEventListener('click', () => {
305
+ if (config.onSwipeLeft) {
306
+ component.element.style.transform = 'translateX(-100%)';
307
+ component.element.style.transition = 'transform 0.3s ease';
308
+ config.onSwipeLeft(component as CardComponent);
309
+ }
310
+ });
311
+
312
+ rightActionButton.addEventListener('click', () => {
313
+ if (config.onSwipeRight) {
314
+ component.element.style.transform = 'translateX(100%)';
315
+ component.element.style.transition = 'transform 0.3s ease';
316
+ config.onSwipeRight(component as CardComponent);
317
+ }
318
+ });
165
319
 
166
320
  function handleTouchStart(e: TouchEvent): void {
167
321
  startX = e.touches[0].clientX;
@@ -1,9 +1,32 @@
1
1
  // src/components/card/index.ts
2
- export { default } from './card'
3
- export { createCardContent } from './content'
4
- export { createCardHeader } from './header'
5
- export { createCardActions } from './actions'
6
- export { createCardMedia } from './media'
2
+ import defaultCreateCard from './card';
3
+
4
+ /**
5
+ * Card Component Module
6
+ *
7
+ * This module exports the Card components and related utilities following
8
+ * Material Design 3 specifications.
9
+ */
10
+
11
+ // Add default export
12
+ export default defaultCreateCard;
13
+
14
+ // Export components from content file where they are now merged
15
+ export {
16
+ createCardContent,
17
+ createCardHeader,
18
+ createCardActions,
19
+ createCardMedia
20
+ } from './content';
21
+
22
+ // Other exports
23
+ export {
24
+ withLoading,
25
+ withExpandable,
26
+ withSwipeable,
27
+ withElevation
28
+ } from './features';
29
+
7
30
  export {
8
31
  CardVariant,
9
32
  CardElevation,
@@ -12,8 +35,7 @@ export {
12
35
  CardContentConfig,
13
36
  CardActionsConfig,
14
37
  CardMediaConfig,
38
+ CardAriaAttributes,
15
39
  CardComponent
16
- } from './types'
17
-
18
- // Export constants for backward compatibility
19
- export { CARD_VARIANTS, CARD_ELEVATIONS, CARD_SCHEMA } from './constants'
40
+ } from './types';
41
+ export { CARD_VARIANTS, CARD_ELEVATIONS, CARD_WIDTHS, CARD_CORNER_RADIUS } from './constants';
@@ -1,174 +1,325 @@
1
1
  // src/components/card/types.ts
2
-
3
2
  /**
4
- * Card variant types following Material Design 3
3
+ * Card variant types following Material Design 3 specifications
4
+ * @enum {string}
5
5
  */
6
6
  export enum CardVariant {
7
+ /** Elevated card with shadow */
7
8
  ELEVATED = 'elevated',
9
+ /** Filled card with higher surface container color */
8
10
  FILLED = 'filled',
11
+ /** Outlined card with border */
9
12
  OUTLINED = 'outlined'
10
13
  }
11
14
 
12
15
  /**
13
- * Card elevation levels
16
+ * Card elevation levels based on MD3 guidelines
17
+ * @enum {number}
14
18
  */
15
19
  export enum CardElevation {
16
- RESTING = 1,
17
- HOVERED = 2,
18
- DRAGGED = 4
20
+ /** No elevation (for filled and outlined variants) */
21
+ LEVEL0 = 0,
22
+ /** Default elevation for elevated cards */
23
+ LEVEL1 = 1,
24
+ /** Elevation for hovered state */
25
+ LEVEL2 = 2,
26
+ /** Elevation for dragged state */
27
+ LEVEL4 = 4
28
+ }
29
+
30
+ /**
31
+ * Button configuration interface for buttons shorthand
32
+ * @interface ButtonConfig
33
+ */
34
+ export interface ButtonConfig {
35
+ /** Button text */
36
+ text?: string;
37
+ /** Button variant */
38
+ variant?: string;
39
+ /** Button icon */
40
+ icon?: string;
41
+ /** Additional button properties */
42
+ [key: string]: any;
19
43
  }
20
44
 
21
45
  /**
22
- * Interface for card configuration
46
+ * Card configuration interface
47
+ * @interface CardSchema
23
48
  */
24
49
  export interface CardSchema {
50
+ /** Card variant type (elevated, filled, outlined) */
25
51
  variant?: CardVariant;
52
+ /** Whether the card is interactive */
26
53
  interactive?: boolean;
54
+ /** Whether the card should take full width */
27
55
  fullWidth?: boolean;
56
+ /** Whether the card is clickable (with ripple effect) */
28
57
  clickable?: boolean;
58
+ /** Whether the card is draggable */
29
59
  draggable?: boolean;
60
+ /** Additional CSS class(es) */
30
61
  class?: string;
62
+ /** Header configuration */
31
63
  headerConfig?: CardHeaderConfig;
64
+ /** Content configuration */
32
65
  contentConfig?: CardContentConfig;
66
+ /** Actions configuration */
33
67
  actionsConfig?: CardActionsConfig;
68
+ /** Media configuration */
34
69
  mediaConfig?: CardMediaConfig;
70
+ /** ARIA attributes for accessibility */
71
+ aria?: CardAriaAttributes;
72
+
73
+ // New inline configuration options
74
+ /** Inline header configuration (alternative to headerConfig) */
75
+ header?: CardHeaderConfig;
76
+ /** Inline content configuration (alternative to contentConfig) */
77
+ content?: CardContentConfig;
78
+ /** Inline media configuration (alternative to mediaConfig) */
79
+ media?: CardMediaConfig;
80
+ /** Inline actions configuration (alternative to actionsConfig) */
81
+ actions?: CardActionsConfig;
82
+ /** Simple buttons array for actions (will be converted to actionsConfig) */
83
+ buttons?: ButtonConfig[];
84
+
85
+ /** Internal component name */
86
+ componentName?: string;
87
+ /** CSS class prefix */
88
+ prefix?: string;
89
+ /** Callback executed after component creation */
90
+ afterCreation?: (component: BaseComponent) => void;
91
+ }
92
+
93
+ /**
94
+ * ARIA attributes for card accessibility
95
+ * @interface CardAriaAttributes
96
+ */
97
+ export interface CardAriaAttributes {
98
+ /** ARIA label */
99
+ label?: string;
100
+ /** ARIA labelledby */
101
+ labelledby?: string;
102
+ /** ARIA describedby */
103
+ describedby?: string;
104
+ /** ARIA role (default is 'region' for non-interactive, 'button' for interactive) */
105
+ role?: string;
106
+ /** Additional ARIA attributes as key-value pairs */
107
+ [key: string]: string | undefined;
35
108
  }
36
109
 
37
110
  /**
38
- * Interface for card header configuration
111
+ * Card header configuration
112
+ * @interface CardHeaderConfig
39
113
  */
40
114
  export interface CardHeaderConfig {
115
+ /** Header title text */
41
116
  title?: string;
117
+ /** Header subtitle text */
42
118
  subtitle?: string;
119
+ /** Avatar element or HTML string */
43
120
  avatar?: HTMLElement | string;
121
+ /** Action element or HTML string */
44
122
  action?: HTMLElement | string;
123
+ /** Additional CSS class(es) */
45
124
  class?: string;
46
125
  }
47
126
 
48
127
  /**
49
- * Interface for card content configuration
128
+ * Card content configuration
129
+ * @interface CardContentConfig
50
130
  */
51
131
  export interface CardContentConfig {
132
+ /** Text content */
52
133
  text?: string;
134
+ /** HTML content */
53
135
  html?: string;
136
+ /** Child elements */
54
137
  children?: HTMLElement[];
138
+ /** Whether to add padding (true by default) */
55
139
  padding?: boolean;
140
+ /** Additional CSS class(es) */
56
141
  class?: string;
57
142
  }
58
143
 
59
144
  /**
60
- * Interface for card actions configuration
145
+ * Card actions configuration
146
+ * @interface CardActionsConfig
61
147
  */
62
148
  export interface CardActionsConfig {
149
+ /** Action elements */
63
150
  actions?: HTMLElement[];
151
+ /** Whether actions should be full-bleed */
64
152
  fullBleed?: boolean;
153
+ /** Whether actions should be stacked vertically */
65
154
  vertical?: boolean;
155
+ /** Horizontal alignment */
66
156
  align?: 'start' | 'center' | 'end' | 'space-between';
157
+ /** Additional CSS class(es) */
67
158
  class?: string;
68
159
  }
69
160
 
70
161
  /**
71
- * Interface for card media configuration
162
+ * Card media configuration
163
+ * @interface CardMediaConfig
72
164
  */
73
165
  export interface CardMediaConfig {
166
+ /** Image source URL */
74
167
  src?: string;
168
+ /** Image alt text (required for accessibility) */
75
169
  alt?: string;
170
+ /** Custom element instead of image */
76
171
  element?: HTMLElement;
172
+ /** Aspect ratio */
77
173
  aspectRatio?: '16:9' | '4:3' | '1:1' | string;
174
+ /** Whether media should use object-fit: contain */
78
175
  contain?: boolean;
176
+ /** Additional CSS class(es) */
79
177
  class?: string;
178
+ /**
179
+ * Position of the media in the card
180
+ * - 'top': Media appears at the top of the card (default)
181
+ * - 'bottom': Media appears after the content
182
+ */
183
+ position?: 'top' | 'bottom';
80
184
  }
81
185
 
82
186
  /**
83
187
  * Base component interface
188
+ * @interface BaseComponent
84
189
  */
85
190
  export interface BaseComponent {
191
+ /** The DOM element */
86
192
  element: HTMLElement;
193
+ /** Get class name with prefix */
87
194
  getClass: (name?: string) => string;
195
+ /** Get modifier class */
88
196
  getModifierClass: (base: string, modifier: string) => string;
197
+ /** Get element class */
89
198
  getElementClass: (base: string, element: string) => string;
199
+ /** Add CSS class(es) */
90
200
  addClass: (...classes: string[]) => BaseComponent;
201
+ /** Emit an event */
91
202
  emit?: (event: string, data?: any) => void;
203
+ /** Component configuration */
92
204
  config: CardComponentConfig;
205
+ /** Touch state for touch interactions */
93
206
  touchState?: TouchState;
207
+ /** Update touch state */
94
208
  updateTouchState?: (event: TouchEvent | MouseEvent, status: 'start' | 'end') => void;
209
+ /** Component lifecycle methods */
95
210
  lifecycle?: ComponentLifecycle;
96
211
  }
97
212
 
98
213
  /**
99
- * Touch state interface
214
+ * Touch state interface for touch interactions
215
+ * @interface TouchState
100
216
  */
101
217
  export interface TouchState {
218
+ /** Timestamp when touch started */
102
219
  startTime: number;
220
+ /** Starting position */
103
221
  startPosition: { x: number; y: number };
222
+ /** Whether touch is active */
104
223
  isTouching: boolean;
224
+ /** Current touch target */
105
225
  activeTarget: EventTarget | null;
106
226
  }
107
227
 
108
228
  /**
109
229
  * Component lifecycle interface
230
+ * @interface ComponentLifecycle
110
231
  */
111
232
  export interface ComponentLifecycle {
233
+ /** Called when component is mounted to DOM */
112
234
  mount?: () => void;
235
+ /** Called when component is updated */
113
236
  update?: () => void;
237
+ /** Called when component is destroyed */
114
238
  destroy: () => void;
115
239
  }
116
240
 
117
241
  /**
118
242
  * Card component configuration
243
+ * @interface CardComponentConfig
244
+ * @extends CardSchema
119
245
  */
120
246
  export interface CardComponentConfig extends CardSchema {
247
+ /** Component name */
121
248
  componentName: string;
249
+ /** CSS class prefix */
122
250
  prefix: string;
123
251
  }
124
252
 
125
253
  /**
126
- * Card component interface
254
+ * Card component interface with methods
255
+ * @interface CardComponent
256
+ * @extends BaseComponent
127
257
  */
128
258
  export interface CardComponent extends BaseComponent {
129
- // Card-specific methods
259
+ /** Add content to the card */
130
260
  addContent: (contentElement: HTMLElement) => CardComponent;
261
+ /** Set the card header */
131
262
  setHeader: (headerElement: HTMLElement) => CardComponent;
263
+ /** Add media to the card */
132
264
  addMedia: (mediaElement: HTMLElement, position?: 'top' | 'bottom') => CardComponent;
265
+ /** Set the card actions */
133
266
  setActions: (actionsElement: HTMLElement) => CardComponent;
267
+ /** Make the card draggable */
134
268
  makeDraggable: (dragStartCallback?: (event: DragEvent) => void) => CardComponent;
269
+ /** Set focus to the card */
270
+ focus: () => CardComponent;
271
+ /** Destroy the card and clean up resources */
135
272
  destroy: () => void;
136
273
 
137
- // Optional feature interfaces
274
+ /** Optional loading feature */
138
275
  loading?: LoadingFeature;
276
+ /** Optional expandable feature */
139
277
  expandable?: ExpandableFeature;
278
+ /** Optional swipeable feature */
140
279
  swipeable?: SwipeableFeature;
141
280
  }
142
281
 
143
282
  /**
144
283
  * Loading feature interface
284
+ * @interface LoadingFeature
145
285
  */
146
286
  export interface LoadingFeature {
287
+ /** Check if loading state is active */
147
288
  isLoading: () => boolean;
289
+ /** Set loading state */
148
290
  setLoading: (loading: boolean) => void;
149
291
  }
150
292
 
151
293
  /**
152
294
  * Expandable feature interface
295
+ * @interface ExpandableFeature
153
296
  */
154
297
  export interface ExpandableFeature {
298
+ /** Check if expanded state is active */
155
299
  isExpanded: () => boolean;
300
+ /** Set expanded state */
156
301
  setExpanded: (expanded: boolean) => void;
302
+ /** Toggle expanded state */
157
303
  toggleExpanded: () => void;
158
304
  }
159
305
 
160
306
  /**
161
307
  * Swipeable feature interface
308
+ * @interface SwipeableFeature
162
309
  */
163
310
  export interface SwipeableFeature {
311
+ /** Reset swipe position */
164
312
  reset: () => void;
165
313
  }
166
314
 
167
315
  /**
168
316
  * API options interface
317
+ * @interface ApiOptions
169
318
  */
170
319
  export interface ApiOptions {
320
+ /** Lifecycle methods */
171
321
  lifecycle: {
322
+ /** Destroy callback */
172
323
  destroy: () => void;
173
324
  };
174
325
  }
@@ -70,8 +70,6 @@ $component: '#{base.$prefix}-checkbox';
70
70
 
71
71
  // Label position variants
72
72
  &--label-start {
73
- flex-direction: row-reverse;
74
-
75
73
  .#{$component}-label {
76
74
  margin-left: 0;
77
75
  margin-right: 12px;
@@ -7,19 +7,17 @@ import {
7
7
  withText,
8
8
  withIcon,
9
9
  withVariant,
10
- withSize,
11
10
  withRipple,
12
11
  withDisabled,
13
12
  withLifecycle
14
13
  } from '../../core/compose/features'
15
14
  import { withAPI } from './api'
16
- import { CHIP_VARIANTS, CHIP_SIZES } from './constants'
15
+ import { CHIP_VARIANTS } from './constants'
17
16
 
18
17
  /**
19
18
  * Creates a new Chip component
20
19
  * @param {Object} config - Chip configuration
21
20
  * @param {string} [config.variant='filled'] - Chip variant
22
- * @param {string} [config.size='medium'] - Chip size
23
21
  * @param {boolean} [config.selected=false] - Whether the chip is initially selected
24
22
  * @param {boolean} [config.disabled=false] - Whether the chip is initially disabled
25
23
  * @param {string} [config.text] - Chip text content
@@ -37,7 +35,6 @@ const createChip = (config = {}) => {
37
35
  const baseConfig = {
38
36
  ...config,
39
37
  variant: config.variant || CHIP_VARIANTS.FILLED,
40
- size: config.size || CHIP_SIZES.MEDIUM,
41
38
  componentName: 'chip',
42
39
  prefix: PREFIX,
43
40
  ripple: config.ripple !== false
@@ -76,11 +73,6 @@ const createChip = (config = {}) => {
76
73
  chip.element.classList.add(`${chip.getClass('chip')}--${config.variant}`)
77
74
  }
78
75
 
79
- // Manually add the size class
80
- if (config.size) {
81
- chip.element.classList.add(`${chip.getClass('chip')}--${config.size}`)
82
- }
83
-
84
76
  // Add ripple if enabled
85
77
  if (config.ripple) {
86
78
  withRipple(baseConfig)(chip)