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
@@ -1,23 +1,25 @@
1
1
  // src/components/badge/config.ts
2
2
  import {
3
3
  createComponentConfig,
4
- createElementConfig,
5
- BaseComponentConfig
4
+ createElementConfig
6
5
  } from '../../core/config/component-config';
7
6
  import { BadgeConfig } from './types';
8
- import { BADGE_VARIANTS, BADGE_SIZES, BADGE_COLORS, BADGE_POSITIONS } from './constants';
7
+ import {
8
+ BADGE_VARIANTS,
9
+ BADGE_COLORS,
10
+ BADGE_POSITIONS,
11
+ BADGE_MAX_CHARACTERS
12
+ } from './constants';
9
13
 
10
14
  /**
11
15
  * Default configuration for the Badge component
12
16
  */
13
17
  export const defaultConfig: BadgeConfig = {
14
- variant: BADGE_VARIANTS.STANDARD,
15
- size: BADGE_SIZES.MEDIUM,
18
+ variant: BADGE_VARIANTS.LARGE,
16
19
  color: BADGE_COLORS.ERROR,
17
20
  position: BADGE_POSITIONS.TOP_RIGHT,
18
- content: '',
19
- visible: true,
20
- standalone: false
21
+ label: '',
22
+ visible: true
21
23
  };
22
24
 
23
25
  /**
@@ -37,14 +39,21 @@ export const getElementConfig = (config: BadgeConfig) => {
37
39
  // Create the attributes object
38
40
  const attrs: Record<string, any> = {};
39
41
 
40
- // Convert numeric content to string if needed
41
- const content = config.content !== undefined ? String(config.content) : '';
42
+ // For large badges, set appropriate ARIA attributes
43
+ if (config.variant !== BADGE_VARIANTS.SMALL) {
44
+ attrs.role = 'status';
45
+ }
46
+
47
+ // Format the label if needed
48
+ const formattedLabel = config.variant === BADGE_VARIANTS.SMALL
49
+ ? ''
50
+ : formatBadgeLabel(config.label || '', config.max);
42
51
 
43
52
  return createElementConfig(config, {
44
53
  tag: 'span',
45
54
  attrs,
46
55
  className: config.class,
47
- content: config.variant === BADGE_VARIANTS.DOT ? '' : content
56
+ text: formattedLabel // Use the formatted label
48
57
  });
49
58
  };
50
59
 
@@ -65,4 +74,49 @@ export const getApiConfig = (comp) => ({
65
74
  }
66
75
  });
67
76
 
77
+ /**
78
+ * Format a label
79
+ * - Max 4 characters including "+" for overflow
80
+ * - Add "+" for numeric values exceeding max
81
+ *
82
+ * @param {string|number} label - Original label
83
+ * @param {number} max - Maximum value before using "+"
84
+ * @returns {string} Formatted label
85
+ */
86
+ export const formatBadgeLabel = (label: string | number, max?: number): string => {
87
+ // Handle empty or undefined labels
88
+ if (label === undefined || label === null || label === '') {
89
+ return '';
90
+ }
91
+
92
+ let formattedLabel = String(label);
93
+
94
+ const numericLabel = Number(label);
95
+
96
+ // Apply max value formatting
97
+ if (max !== undefined && !isNaN(numericLabel) && numericLabel > max) {
98
+ formattedLabel = `${max}+`;
99
+ }
100
+
101
+ // Ensure label doesn't exceed max characters
102
+ if (formattedLabel.length > BADGE_MAX_CHARACTERS) {
103
+ // Try to preserve as much information as possible
104
+ // For large numbers, use abbreviated format with "+"
105
+ const numericValue = Number(label);
106
+ if (!isNaN(numericValue)) {
107
+ if (numericValue >= 1000) {
108
+ formattedLabel = '999+';
109
+ } else {
110
+ // For numbers under 1000 but still too long, truncate
111
+ formattedLabel = formattedLabel.substring(0, BADGE_MAX_CHARACTERS - 1) + '+';
112
+ }
113
+ } else {
114
+ // For non-numeric values, simply truncate
115
+ formattedLabel = formattedLabel.substring(0, BADGE_MAX_CHARACTERS);
116
+ }
117
+ }
118
+
119
+ return formattedLabel;
120
+ };
121
+
68
122
  export default defaultConfig;
@@ -1,30 +1,40 @@
1
1
  // src/components/badge/constants.ts
2
2
 
3
+ /**
4
+ * Badge variants
5
+ * - SMALL: Simple dot badge (6dp diameter)
6
+ * - LARGE: Numbered badge (16dp height)
7
+ */
3
8
  export const BADGE_VARIANTS = {
4
- STANDARD: 'standard',
5
- DOT: 'dot',
6
- OUTLINED: 'outlined'
7
- }
8
-
9
- export const BADGE_SIZES = {
10
9
  SMALL: 'small',
11
- MEDIUM: 'medium',
12
10
  LARGE: 'large'
13
- }
11
+ } as const;
14
12
 
13
+ /**
14
+ * Badge colors
15
+ * ERROR is the default
16
+ */
15
17
  export const BADGE_COLORS = {
18
+ ERROR: 'error', // Default
16
19
  PRIMARY: 'primary',
17
20
  SECONDARY: 'secondary',
18
21
  TERTIARY: 'tertiary',
19
- ERROR: 'error',
20
22
  SUCCESS: 'success',
21
23
  WARNING: 'warning',
22
24
  INFO: 'info'
23
- }
25
+ } as const;
24
26
 
27
+ /**
28
+ * Badge positions relative to its container
29
+ */
25
30
  export const BADGE_POSITIONS = {
26
- TOP_RIGHT: 'top-right',
31
+ TOP_RIGHT: 'top-right', // Default
27
32
  TOP_LEFT: 'top-left',
28
33
  BOTTOM_RIGHT: 'bottom-right',
29
34
  BOTTOM_LEFT: 'bottom-left'
30
- }
35
+ } as const;
36
+
37
+ /**
38
+ * Maximum character count for badge labels
39
+ */
40
+ export const BADGE_MAX_CHARACTERS = 4;
@@ -1,6 +1,11 @@
1
1
  // src/components/badge/features.ts
2
- import { BADGE_VARIANTS, BADGE_SIZES, BADGE_COLORS, BADGE_POSITIONS } from './constants';
2
+ import {
3
+ BADGE_VARIANTS,
4
+ BADGE_COLORS,
5
+ BADGE_POSITIONS
6
+ } from './constants';
3
7
  import { BadgeConfig } from './types';
8
+ import { formatBadgeLabel } from './config';
4
9
 
5
10
  /**
6
11
  * Higher-order function that adds visibility control features to a component
@@ -64,15 +69,24 @@ export const withVisibility = () => component => {
64
69
  */
65
70
  export const withVariant = (config: BadgeConfig) => component => {
66
71
  // Get variant from config with fallback to default
67
- const variant = config.variant || BADGE_VARIANTS.STANDARD;
68
-
69
- // Apply variant class if not standard variant
70
- if (variant !== BADGE_VARIANTS.STANDARD) {
71
- component.element.classList.add(`${component.getClass('badge')}--${variant}`);
72
+ const variant = config.variant || BADGE_VARIANTS.LARGE;
73
+
74
+ // Apply variant class
75
+ component.element.classList.add(`${component.getClass('badge')}--${variant}`);
76
+
77
+ // Small badges (dot variant) don't have text
78
+ if (variant === BADGE_VARIANTS.SMALL) {
79
+ component.element.textContent = '';
80
+ component.element.setAttribute('aria-hidden', 'true');
81
+ } else {
82
+ // Add accessibility for large badges
83
+ component.element.setAttribute('role', 'status');
72
84
 
73
- // Clear content if dot variant
74
- if (variant === BADGE_VARIANTS.DOT) {
75
- component.element.textContent = '';
85
+ // Set the label if available and variant is large
86
+ if (config.label !== undefined && config.label !== '') {
87
+ // Format the label according to max value
88
+ const formattedLabel = formatBadgeLabel(config.label, config.max);
89
+ component.element.textContent = formattedLabel;
76
90
  }
77
91
  }
78
92
 
@@ -94,40 +108,22 @@ export const withColor = (config: BadgeConfig) => component => {
94
108
  return component;
95
109
  };
96
110
 
97
- /**
98
- * Higher-order function that adds size features to a badge component
99
- * @param {BadgeConfig} config - Badge configuration
100
- * @returns {Function} Component enhancer with size features
101
- */
102
- export const withSize = (config: BadgeConfig) => component => {
103
- // Get size from config with fallback to default
104
- const size = config.size || BADGE_SIZES.MEDIUM;
105
-
106
- // Apply size class if not medium (default)
107
- if (size !== BADGE_SIZES.MEDIUM) {
108
- component.element.classList.add(`${component.getClass('badge')}--${size}`);
109
- }
110
-
111
- return component;
112
- };
113
-
114
111
  /**
115
112
  * Higher-order function that adds positioning features to a badge component
116
113
  * @param {BadgeConfig} config - Badge configuration
117
114
  * @returns {Function} Component enhancer with positioning features
118
115
  */
119
116
  export const withPosition = (config: BadgeConfig) => component => {
120
- // Skip for standalone badges
121
- if (config.standalone) {
122
- return component;
123
- }
124
-
125
117
  // Get position from config with fallback to default
126
118
  const position = config.position || BADGE_POSITIONS.TOP_RIGHT;
127
119
 
128
- // Apply position class and positioned class
120
+ // Apply position class
129
121
  component.element.classList.add(`${component.getClass('badge')}--${position}`);
130
- component.element.classList.add(`${component.getClass('badge')}--positioned`);
122
+
123
+ // If there's a target, add positioned class
124
+ if (config.target) {
125
+ component.element.classList.add(`${component.getClass('badge')}--positioned`);
126
+ }
131
127
 
132
128
  return component;
133
129
  };
@@ -138,8 +134,8 @@ export const withPosition = (config: BadgeConfig) => component => {
138
134
  * @returns {Function} Component enhancer with max value features
139
135
  */
140
136
  export const withMax = (config: BadgeConfig) => component => {
141
- // Skip if no max is defined
142
- if (config.max === undefined) {
137
+ // Skip if no max is defined or for small badges
138
+ if (config.max === undefined || config.variant === BADGE_VARIANTS.SMALL) {
143
139
  return component;
144
140
  }
145
141
 
@@ -147,9 +143,14 @@ export const withMax = (config: BadgeConfig) => component => {
147
143
  component.config.max = config.max;
148
144
 
149
145
  // Apply max formatting if needed
150
- if (typeof config.content === 'number' && config.content > config.max) {
151
- component.element.textContent = String(config.max);
152
- component.element.classList.add(`${component.getClass('badge')}--max`);
146
+ if (config.label !== undefined && config.label !== '') {
147
+ const formattedLabel = formatBadgeLabel(config.label, config.max);
148
+ component.element.textContent = formattedLabel;
149
+
150
+ // Add overflow class if label was truncated
151
+ if (typeof config.label === 'number' && config.label > config.max) {
152
+ component.element.classList.add(`${component.getClass('badge')}--overflow`);
153
+ }
153
154
  }
154
155
 
155
156
  return component;
@@ -161,8 +162,8 @@ export const withMax = (config: BadgeConfig) => component => {
161
162
  * @returns {Function} Component enhancer with attachment features
162
163
  */
163
164
  export const withAttachment = (config: BadgeConfig) => component => {
164
- // Skip for standalone badges or if no target is provided
165
- if (config.standalone || !config.target) {
165
+ // Skip if no target is provided
166
+ if (!config.target) {
166
167
  return component;
167
168
  }
168
169
 
@@ -170,6 +171,9 @@ export const withAttachment = (config: BadgeConfig) => component => {
170
171
  const wrapper = document.createElement('div');
171
172
  wrapper.classList.add(component.getClass('badge-wrapper'));
172
173
 
174
+ // Make sure positioning context is correct
175
+ wrapper.style.position = 'relative';
176
+
173
177
  // Replace the target with the wrapper
174
178
  const parent = config.target.parentNode;
175
179
  if (parent) {
@@ -1,43 +1,58 @@
1
1
  // src/components/badge/types.ts
2
- import { BADGE_VARIANTS, BADGE_SIZES, BADGE_COLORS, BADGE_POSITIONS } from './constants';
2
+ import { BADGE_VARIANTS, BADGE_COLORS, BADGE_POSITIONS } from './constants';
3
3
 
4
4
  /**
5
5
  * Configuration interface for the Badge component
6
+ * Following Material Design 3 specifications
6
7
  */
7
8
  export interface BadgeConfig {
8
- /** Badge variant (standard, dot, outlined) */
9
- variant?: keyof typeof BADGE_VARIANTS | BADGE_VARIANTS;
10
-
11
- /** Badge size (small, medium, large) */
12
- size?: keyof typeof BADGE_SIZES | BADGE_SIZES;
13
-
14
- /** Badge color (primary, secondary, tertiary, error, success, warning, info) */
15
- color?: keyof typeof BADGE_COLORS | BADGE_COLORS;
16
-
17
- /** Badge position relative to its container (top-right, top-left, bottom-right, bottom-left) */
18
- position?: keyof typeof BADGE_POSITIONS | BADGE_POSITIONS;
19
-
20
- /** Text content inside the badge */
21
- content?: string | number;
22
-
23
- /** Maximum value to display (shows "{max}+" if content exceeds max) */
9
+ /**
10
+ * Badge variant (small dot or large numbered)
11
+ * Small badge (6dp) or Large badge (16dp height)
12
+ */
13
+ variant?: keyof typeof BADGE_VARIANTS | (typeof BADGE_VARIANTS)[keyof typeof BADGE_VARIANTS];
14
+
15
+ /**
16
+ * Badge color (error is default)
17
+ */
18
+ color?: keyof typeof BADGE_COLORS | (typeof BADGE_COLORS)[keyof typeof BADGE_COLORS];
19
+
20
+ /**
21
+ * Badge position relative to its container
22
+ */
23
+ position?: keyof typeof BADGE_POSITIONS | (typeof BADGE_POSITIONS)[keyof typeof BADGE_POSITIONS];
24
+
25
+ /**
26
+ * Text label inside the badge (for large badges)
27
+ * Up to 4 characters, with "+" for overflow
28
+ */
29
+ label?: string | number;
30
+
31
+ /**
32
+ * Maximum value to display (shows "{max}+" if label exceeds max)
33
+ * Usually 999+ for large numbers
34
+ */
24
35
  max?: number;
25
36
 
26
37
  /** Whether the badge should be visible */
27
38
  visible?: boolean;
28
39
 
29
- /** Whether the badge should be standalone (not attached to another element) */
30
- standalone?: boolean;
31
-
32
40
  /** Target element to which badge will be attached */
33
41
  target?: HTMLElement;
34
42
 
35
43
  /** Additional CSS classes */
36
44
  class?: string;
45
+
46
+ /** CSS class prefix */
47
+ prefix?: string;
48
+
49
+ /** Component name */
50
+ componentName?: string;
37
51
  }
38
52
 
39
53
  /**
40
54
  * Badge component interface
55
+ * Following Material Design 3 specifications
41
56
  */
42
57
  export interface BadgeComponent {
43
58
  /** Badge element */
@@ -46,11 +61,11 @@ export interface BadgeComponent {
46
61
  /** Badge wrapper element (if badge is attached to target) */
47
62
  wrapper?: HTMLElement;
48
63
 
49
- /** Sets badge text content */
50
- setContent: (content: string | number) => BadgeComponent;
64
+ /** Sets badge text label */
65
+ setLabel: (label: string | number) => BadgeComponent;
51
66
 
52
- /** Gets badge text content */
53
- getContent: () => string;
67
+ /** Gets badge text label */
68
+ getLabel: () => string;
54
69
 
55
70
  /** Shows the badge */
56
71
  show: () => BadgeComponent;
@@ -68,16 +83,13 @@ export interface BadgeComponent {
68
83
  setMax: (max: number) => BadgeComponent;
69
84
 
70
85
  /** Sets badge color */
71
- setColor: (color: keyof typeof BADGE_COLORS | BADGE_COLORS) => BadgeComponent;
86
+ setColor: (color: keyof typeof BADGE_COLORS | (typeof BADGE_COLORS)[keyof typeof BADGE_COLORS]) => BadgeComponent;
72
87
 
73
88
  /** Sets badge variant */
74
- setVariant: (variant: keyof typeof BADGE_VARIANTS | BADGE_VARIANTS) => BadgeComponent;
75
-
76
- /** Sets badge size */
77
- setSize: (size: keyof typeof BADGE_SIZES | BADGE_SIZES) => BadgeComponent;
89
+ setVariant: (variant: keyof typeof BADGE_VARIANTS | (typeof BADGE_VARIANTS)[keyof typeof BADGE_VARIANTS]) => BadgeComponent;
78
90
 
79
91
  /** Sets badge position */
80
- setPosition: (position: keyof typeof BADGE_POSITIONS | BADGE_POSITIONS) => BadgeComponent;
92
+ setPosition: (position: keyof typeof BADGE_POSITIONS | (typeof BADGE_POSITIONS)[keyof typeof BADGE_POSITIONS]) => BadgeComponent;
81
93
 
82
94
  /** Attaches badge to a target element */
83
95
  attachTo: (target: HTMLElement) => BadgeComponent;
@@ -0,0 +1,103 @@
1
+ // src/components/bottom-app-bar/styles.scss
2
+ @use 'sass:map';
3
+ @use '../../styles/abstract/base' as base;
4
+ @use '../../styles/abstract/variables' as v;
5
+ @use '../../styles/abstract/functions' as f;
6
+ @use '../../styles/abstract/mixins' as m;
7
+ @use '../../styles/abstract/theme' as t;
8
+
9
+ $component: '#{base.$prefix}-bottom-app-bar';
10
+
11
+ .#{$component} {
12
+ // Core Properties
13
+ position: absolute;
14
+ bottom: 0;
15
+ left: 0;
16
+ right: 0;
17
+ z-index: f.get-z-index('fixed');
18
+ display: flex;
19
+ align-items: center;
20
+ justify-content: space-between;
21
+ height: 80px; // Default height as per specs
22
+ padding: 12px 16px 12px 4px; // top/bottom 12px, right 16px, left 4px
23
+ background-color: t.color('surface-container');
24
+
25
+ // Apply material elevation
26
+ @include m.elevation(2);
27
+
28
+ // Apply border radius at the top
29
+ border-top-left-radius: t.shape('medium');
30
+ border-top-right-radius: t.shape('medium');
31
+
32
+ // Add transition for smooth animations
33
+ transition: transform 0.3s ease-in-out;
34
+
35
+ // Actions container on the left side
36
+ &-actions {
37
+ display: flex;
38
+ align-items: center;
39
+ gap: 4px; // Small gap between action buttons
40
+ height: 100%;
41
+
42
+ // Icon buttons should have consistent sizing
43
+ > * {
44
+ flex-shrink: 0;
45
+ }
46
+ }
47
+
48
+ // FAB container on the right side
49
+ &-fab-container {
50
+ display: flex;
51
+ align-items: center;
52
+ justify-content: center;
53
+ margin-left: auto;
54
+ }
55
+
56
+ // Adjustment for when FAB is present - use the specified height
57
+ &--with-fab {
58
+ height: 72px;
59
+ }
60
+
61
+ // Adjustment for when FAB is centered
62
+ &--fab-center {
63
+ .#{$component}-fab-container {
64
+ position: absolute;
65
+ left: 50%;
66
+ transform: translateX(-50%);
67
+ }
68
+ }
69
+
70
+ // Hidden state - moved off-screen
71
+ &--hidden {
72
+ transform: translateY(100%);
73
+ }
74
+
75
+ // RTL Support
76
+ [dir="rtl"] & {
77
+ padding: 12px 4px 12px 16px;
78
+
79
+ &-actions {
80
+ flex-direction: row-reverse;
81
+ }
82
+
83
+ &-fab-container {
84
+ margin-right: auto;
85
+ margin-left: initial;
86
+ }
87
+ }
88
+
89
+ // // Media query to hide on large screens
90
+ // @media (min-width: map.get(v.$breakpoints, 'lg')) {
91
+ // display: none;
92
+ // }
93
+
94
+ // Reduced motion support
95
+ @include m.reduced-motion {
96
+ transition-duration: 0.01ms;
97
+ }
98
+
99
+ // High contrast mode support
100
+ @include m.high-contrast {
101
+ border-top: 1px solid currentColor;
102
+ }
103
+ }