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,115 @@
1
+ // src/components/chip/api.js
2
+
3
+ /**
4
+ * Enhances a chip 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 Chip component
10
+ */
11
+ export const withAPI = ({ disabled, lifecycle }) => (component) => ({
12
+ ...component,
13
+ element: component.element,
14
+
15
+ /**
16
+ * Gets the chip's value
17
+ * @returns {string} The chip's value attribute
18
+ */
19
+ getValue: () => component.element.getAttribute('data-value'),
20
+
21
+ /**
22
+ * Sets the chip's value
23
+ * @param {string} value - Value to set
24
+ * @returns {Object} The chip instance for chaining
25
+ */
26
+ setValue (value) {
27
+ component.element.setAttribute('data-value', value)
28
+ return this
29
+ },
30
+
31
+ /**
32
+ * Enables the chip
33
+ * @returns {Object} The chip instance for chaining
34
+ */
35
+ enable () {
36
+ disabled.enable()
37
+ component.element.setAttribute('aria-disabled', 'false')
38
+ return this
39
+ },
40
+
41
+ /**
42
+ * Disables the chip
43
+ * @returns {Object} The chip instance for chaining
44
+ */
45
+ disable () {
46
+ disabled.disable()
47
+ component.element.setAttribute('aria-disabled', 'true')
48
+ return this
49
+ },
50
+
51
+ /**
52
+ * Sets the chip's text content
53
+ * @param {string} content - Text content
54
+ * @returns {Object} The chip instance for chaining
55
+ */
56
+ setText (content) {
57
+ component.text.setText(content)
58
+ return this
59
+ },
60
+
61
+ /**
62
+ * Gets the chip's text content
63
+ * @returns {string} The chip's text content
64
+ */
65
+ getText () {
66
+ return component.text.getText()
67
+ },
68
+
69
+ /**
70
+ * Sets the chip's leading icon
71
+ * @param {string} icon - Icon HTML content
72
+ * @returns {Object} The chip instance for chaining
73
+ */
74
+ setIcon (icon) {
75
+ component.icon.setIcon(icon)
76
+ return this
77
+ },
78
+
79
+ /**
80
+ * Gets the chip's icon content
81
+ * @returns {string} The chip's icon HTML
82
+ */
83
+ getIcon () {
84
+ return component.icon.getIcon()
85
+ },
86
+
87
+ /**
88
+ * Sets the chip's trailing icon
89
+ * @param {string} icon - Icon HTML content
90
+ * @returns {Object} The chip instance for chaining
91
+ */
92
+ setTrailingIcon (icon) {
93
+ const trailingIconSelector = `.${component.getClass('chip')}-trailing-icon`
94
+ let trailingIconElement = component.element.querySelector(trailingIconSelector)
95
+
96
+ if (!trailingIconElement && icon) {
97
+ trailingIconElement = document.createElement('span')
98
+ trailingIconElement.className = `${component.getClass('chip')}-trailing-icon`
99
+ component.element.appendChild(trailingIconElement)
100
+ }
101
+
102
+ if (trailingIconElement) {
103
+ trailingIconElement.innerHTML = icon || ''
104
+ }
105
+
106
+ return this
107
+ },
108
+
109
+ /**
110
+ * Destroys the chip component and cleans up resources
111
+ */
112
+ destroy () {
113
+ lifecycle.destroy()
114
+ }
115
+ })
@@ -0,0 +1,225 @@
1
+ // src/components/chip/chip-set.js
2
+ import { PREFIX } from '../../core/config'
3
+ import createChip from './chip'
4
+
5
+ /**
6
+ * Creates a chip set container for grouping related chips
7
+ * @param {Object} config - ChipSet configuration
8
+ * @param {Array} [config.chips=[]] - Array of chip configurations to initialize
9
+ * @param {boolean} [config.scrollable=false] - Whether the chip set is horizontally scrollable
10
+ * @param {boolean} [config.vertical=false] - Whether the chip set is vertically stacked
11
+ * @param {string} [config.class] - Additional CSS classes
12
+ * @param {string} [config.selector] - CSS selector for filtering behavior
13
+ * @param {boolean} [config.multiSelect=false] - Whether multiple chips can be selected simultaneously
14
+ * @param {Function} [config.onChange] - Callback function when chip selection changes
15
+ * @returns {Object} ChipSet component instance
16
+ */
17
+ const createChipSet = (config = {}) => {
18
+ const {
19
+ chips = [],
20
+ scrollable = false,
21
+ vertical = false,
22
+ class: customClass,
23
+ selector = null,
24
+ multiSelect = false,
25
+ onChange = null
26
+ } = config
27
+
28
+ // Create container element
29
+ const element = document.createElement('div')
30
+ element.className = `${PREFIX}-chip-set`
31
+
32
+ if (customClass) {
33
+ element.classList.add(customClass)
34
+ }
35
+
36
+ if (scrollable) {
37
+ element.classList.add(`${PREFIX}-chip-set--scrollable`)
38
+ }
39
+
40
+ if (vertical) {
41
+ element.classList.add(`${PREFIX}-chip-set--vertical`)
42
+ }
43
+
44
+ // Store chip instances
45
+ const chipInstances = []
46
+
47
+ /**
48
+ * Updates chip selection states based on multiSelect configuration
49
+ * @param {Object} selectedChip - The chip that was clicked/selected
50
+ */
51
+ const handleSelection = (selectedChip) => {
52
+ if (!multiSelect) {
53
+ // Single selection mode - deselect all other chips
54
+ chipInstances.forEach(chip => {
55
+ if (chip !== selectedChip && chip.isSelected()) {
56
+ chip.setSelected(false)
57
+ }
58
+ })
59
+ }
60
+
61
+ // Call onChange callback if provided
62
+ if (typeof onChange === 'function') {
63
+ const selectedChips = chipInstances.filter(chip => chip.isSelected())
64
+ onChange(selectedChips, selectedChip)
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Adds a chip to the chip set
70
+ * @param {Object} chipConfig - Configuration for the chip
71
+ * @returns {Object} The created chip instance
72
+ */
73
+ const addChip = (chipConfig) => {
74
+ const chipInstance = createChip({
75
+ ...chipConfig,
76
+ onSelect: (chip) => {
77
+ handleSelection(chip)
78
+ if (chipConfig.onSelect) {
79
+ chipConfig.onSelect(chip)
80
+ }
81
+ }
82
+ })
83
+
84
+ element.appendChild(chipInstance.element)
85
+ chipInstances.push(chipInstance)
86
+
87
+ // Add click handler to toggle selection
88
+ chipInstance.element.addEventListener('click', () => {
89
+ if (!chipInstance.element.getAttribute('aria-disabled') === 'true') {
90
+ chipInstance.toggleSelected()
91
+ handleSelection(chipInstance)
92
+ }
93
+ })
94
+
95
+ return chipInstance
96
+ }
97
+
98
+ // Initialize with provided chips
99
+ chips.forEach(chipConfig => addChip(chipConfig))
100
+
101
+ return {
102
+ element,
103
+
104
+ /**
105
+ * Adds a new chip to the chip set
106
+ * @param {Object} chipConfig - Configuration for the chip
107
+ * @returns {Object} The chip set instance for chaining
108
+ */
109
+ addChip (chipConfig) {
110
+ addChip(chipConfig)
111
+ return this
112
+ },
113
+
114
+ /**
115
+ * Removes a chip from the chip set
116
+ * @param {Object|number} chipOrIndex - Chip instance or index to remove
117
+ * @returns {Object} The chip set instance for chaining
118
+ */
119
+ removeChip (chipOrIndex) {
120
+ const index = typeof chipOrIndex === 'number'
121
+ ? chipOrIndex
122
+ : chipInstances.indexOf(chipOrIndex)
123
+
124
+ if (index >= 0 && index < chipInstances.length) {
125
+ const chip = chipInstances[index]
126
+ chip.destroy()
127
+ chipInstances.splice(index, 1)
128
+ }
129
+
130
+ return this
131
+ },
132
+
133
+ /**
134
+ * Gets all chip instances in the set
135
+ * @returns {Array} Array of chip instances
136
+ */
137
+ getChips () {
138
+ return [...chipInstances]
139
+ },
140
+
141
+ /**
142
+ * Gets currently selected chips
143
+ * @returns {Array} Array of selected chip instances
144
+ */
145
+ getSelectedChips () {
146
+ return chipInstances.filter(chip => chip.isSelected())
147
+ },
148
+
149
+ /**
150
+ * Gets the values of selected chips
151
+ * @returns {Array} Array of selected chip values
152
+ */
153
+ getSelectedValues () {
154
+ return this.getSelectedChips().map(chip => chip.getValue())
155
+ },
156
+
157
+ /**
158
+ * Selects chips by their values
159
+ * @param {Array|string} values - Value or array of values to select
160
+ * @returns {Object} The chip set instance for chaining
161
+ */
162
+ selectByValue (values) {
163
+ const valueArray = Array.isArray(values) ? values : [values]
164
+
165
+ chipInstances.forEach(chip => {
166
+ const shouldSelect = valueArray.includes(chip.getValue())
167
+ if (shouldSelect !== chip.isSelected()) {
168
+ chip.setSelected(shouldSelect)
169
+ }
170
+ })
171
+
172
+ return this
173
+ },
174
+
175
+ /**
176
+ * Clears all selections
177
+ * @returns {Object} The chip set instance for chaining
178
+ */
179
+ clearSelection () {
180
+ chipInstances.forEach(chip => {
181
+ chip.setSelected(false)
182
+ })
183
+ return this
184
+ },
185
+
186
+ /**
187
+ * Sets the scrollable state of the chip set
188
+ * @param {boolean} isScrollable - Whether the chip set should be scrollable
189
+ * @returns {Object} The chip set instance for chaining
190
+ */
191
+ setScrollable (isScrollable) {
192
+ if (isScrollable) {
193
+ element.classList.add(`${PREFIX}-chip-set--scrollable`)
194
+ } else {
195
+ element.classList.remove(`${PREFIX}-chip-set--scrollable`)
196
+ }
197
+ return this
198
+ },
199
+
200
+ /**
201
+ * Sets the vertical layout state
202
+ * @param {boolean} isVertical - Whether the chip set should be vertically stacked
203
+ * @returns {Object} The chip set instance for chaining
204
+ */
205
+ setVertical (isVertical) {
206
+ if (isVertical) {
207
+ element.classList.add(`${PREFIX}-chip-set--vertical`)
208
+ } else {
209
+ element.classList.remove(`${PREFIX}-chip-set--vertical`)
210
+ }
211
+ return this
212
+ },
213
+
214
+ /**
215
+ * Destroys the chip set and all contained chips
216
+ */
217
+ destroy () {
218
+ chipInstances.forEach(chip => chip.destroy())
219
+ chipInstances.length = 0
220
+ element.remove()
221
+ }
222
+ }
223
+ }
224
+
225
+ export default createChipSet
@@ -0,0 +1,82 @@
1
+ // src/components/chip/chip.ts
2
+ import { pipe } from '../../core/compose';
3
+ import { createBase, withElement } from '../../core/compose/component';
4
+ import {
5
+ withEvents,
6
+ withText,
7
+ withIcon,
8
+ withVariant,
9
+ withSize,
10
+ withRipple,
11
+ withDisabled,
12
+ withLifecycle
13
+ } from '../../core/compose/features';
14
+ import { withAPI } from './api';
15
+ import { ChipConfig, ChipComponent, BaseComponent } from './types';
16
+ import { createBaseConfig, getElementConfig, getApiConfig } from './config';
17
+
18
+ /**
19
+ * Creates a new Chip component
20
+ * @param {ChipConfig} config - Chip configuration object
21
+ * @returns {ChipComponent} Chip component instance
22
+ */
23
+ const createChip = (config: ChipConfig = {}): ChipComponent => {
24
+ const baseConfig = createBaseConfig(config);
25
+
26
+ try {
27
+ const chip = pipe(
28
+ createBase,
29
+ withEvents(),
30
+ withElement(getElementConfig(baseConfig)),
31
+ withVariant(baseConfig),
32
+ withSize(baseConfig),
33
+ withText(baseConfig),
34
+ withIcon({
35
+ ...baseConfig,
36
+ position: 'start',
37
+ iconContent: config.leadingIcon || config.icon
38
+ }),
39
+ withDisabled(baseConfig),
40
+ withRipple(baseConfig),
41
+ withLifecycle(),
42
+ comp => withAPI(getApiConfig(comp))(comp)
43
+ )(baseConfig);
44
+
45
+ // Add trailing icon if provided
46
+ if (config.trailingIcon) {
47
+ const trailingIconElement = document.createElement('span');
48
+ trailingIconElement.className = `${baseConfig.prefix}-chip-trailing-icon`;
49
+ trailingIconElement.innerHTML = config.trailingIcon;
50
+ chip.element.appendChild(trailingIconElement);
51
+
52
+ // Add event listener for remove/close action if needed
53
+ if (config.onTrailingIconClick) {
54
+ trailingIconElement.addEventListener('click', (e) => {
55
+ e.stopPropagation();
56
+ config.onTrailingIconClick!(chip as ChipComponent);
57
+ });
58
+ }
59
+ }
60
+
61
+ // Initialize selected state if needed
62
+ if (config.selected) {
63
+ (chip as ChipComponent).setSelected(true);
64
+ }
65
+
66
+ // Handle selection callback
67
+ if (config.onSelect) {
68
+ chip.element.addEventListener('click', () => {
69
+ if (chip.element.getAttribute('aria-disabled') !== 'true') {
70
+ config.onSelect!(chip as ChipComponent);
71
+ }
72
+ });
73
+ }
74
+
75
+ return chip as ChipComponent;
76
+ } catch (error) {
77
+ console.error('Chip creation error:', error instanceof Error ? error.message : String(error));
78
+ throw new Error(`Failed to create chip: ${error instanceof Error ? error.message : String(error)}`);
79
+ }
80
+ };
81
+
82
+ export default createChip;
@@ -0,0 +1,92 @@
1
+ // src/components/chip/config.ts
2
+ import {
3
+ createComponentConfig,
4
+ createElementConfig,
5
+ BaseComponentConfig
6
+ } from '../../core/config/component-config';
7
+ import { ChipConfig, BaseComponent } from './types';
8
+ import { CHIP_VARIANTS } from './constants';
9
+
10
+ /**
11
+ * Default configuration for the Chip component
12
+ */
13
+ export const defaultConfig: ChipConfig = {
14
+ variant: CHIP_VARIANTS.FILLED,
15
+ ripple: true
16
+ };
17
+
18
+ /**
19
+ * Creates the base configuration for Chip component
20
+ * @param {ChipConfig} config - User provided configuration
21
+ * @returns {ChipConfig} Complete configuration with defaults applied
22
+ */
23
+ export const createBaseConfig = (config: ChipConfig = {}): ChipConfig =>
24
+ createComponentConfig(defaultConfig, config, 'chip') as ChipConfig;
25
+
26
+ /**
27
+ * Generates element configuration for the Chip component
28
+ * @param {ChipConfig} config - Chip configuration
29
+ * @returns {Object} Element configuration object for withElement
30
+ */
31
+ export const getElementConfig = (config: ChipConfig) => {
32
+ // Create the attributes object
33
+ const attrs: Record<string, any> = {
34
+ role: 'button',
35
+ tabindex: '0'
36
+ };
37
+
38
+ // Only add aria-disabled attribute if needed
39
+ if (config.disabled === true) {
40
+ attrs['aria-disabled'] = 'true';
41
+ }
42
+
43
+ // Add aria-selected if specified
44
+ if (config.selected === true) {
45
+ attrs['aria-selected'] = 'true';
46
+ } else if (config.selected === false) {
47
+ attrs['aria-selected'] = 'false';
48
+ }
49
+
50
+ // Define additional classes
51
+ const className = [
52
+ config.class,
53
+ config.selected ? `${config.prefix}-chip--selected` : null
54
+ ];
55
+
56
+ return createElementConfig(config, {
57
+ tag: 'div',
58
+ attrs,
59
+ className,
60
+ forwardEvents: {
61
+ click: (component: BaseComponent) => component.element.getAttribute('aria-disabled') !== 'true',
62
+ keydown: (component: BaseComponent, event: KeyboardEvent) => {
63
+ // Handle space and enter key for accessibility
64
+ if (event.key === ' ' || event.key === 'Enter') {
65
+ event.preventDefault();
66
+ component.element.click();
67
+ return true;
68
+ }
69
+ return false;
70
+ },
71
+ focus: true,
72
+ blur: true
73
+ }
74
+ });
75
+ };
76
+
77
+ /**
78
+ * Creates API configuration for the Chip component
79
+ * @param {BaseComponent} comp - Component with disabled and lifecycle features
80
+ * @returns {Object} API configuration object
81
+ */
82
+ export const getApiConfig = (comp: BaseComponent) => ({
83
+ disabled: {
84
+ enable: () => comp.disabled?.enable(),
85
+ disable: () => comp.disabled?.disable()
86
+ },
87
+ lifecycle: {
88
+ destroy: () => comp.lifecycle?.destroy?.()
89
+ }
90
+ });
91
+
92
+ export default defaultConfig;
@@ -0,0 +1,38 @@
1
+ // src/components/chip/constants.ts
2
+
3
+ /**
4
+ * Available variants for the Chip component
5
+ * @enum {string}
6
+ */
7
+ export const CHIP_VARIANTS = {
8
+ /** Standard filled chip with solid background */
9
+ FILLED: 'filled',
10
+
11
+ /** Outlined chip with transparent background and border */
12
+ OUTLINED: 'outlined',
13
+
14
+ /** Elevated chip with shadow */
15
+ ELEVATED: 'elevated',
16
+
17
+ /** Assist chip for suggesting actions */
18
+ ASSIST: 'assist',
19
+
20
+ /** Filter chip for filtering content */
21
+ FILTER: 'filter',
22
+
23
+ /** Input chip for representing user input */
24
+ INPUT: 'input',
25
+
26
+ /** Suggestion chip for presenting options */
27
+ SUGGESTION: 'suggestion'
28
+ } as const;
29
+
30
+ /**
31
+ * Available sizes for the Chip component
32
+ * @enum {string}
33
+ */
34
+ export const CHIP_SIZES = {
35
+ SMALL: 'small',
36
+ MEDIUM: 'medium',
37
+ LARGE: 'large'
38
+ } as const;
@@ -0,0 +1,4 @@
1
+ // src/components/chip/index.ts
2
+ export { default } from './chip'
3
+ export { CHIP_VARIANTS, CHIP_SIZES } from './constants'
4
+ export { ChipConfig, ChipComponent } from './types'