mtrl 0.1.3 → 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 (224) 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 → _styles.scss} +79 -7
  12. package/src/components/card/{actions.js → actions.ts} +15 -18
  13. package/src/components/card/{api.js → api.ts} +33 -33
  14. package/src/components/card/card.ts +41 -0
  15. package/src/components/card/config.ts +99 -0
  16. package/src/components/card/{constants.js → constants.ts} +11 -10
  17. package/src/components/card/{content.js → content.ts} +15 -18
  18. package/src/components/card/{features.js → features.ts} +104 -94
  19. package/src/components/card/{header.js → header.ts} +21 -25
  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} +3 -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/card/card.js +0 -102
  138. package/src/components/card/config.js +0 -16
  139. package/src/components/card/index.js +0 -7
  140. package/src/components/card/media.js +0 -56
  141. package/src/components/checkbox/api.js +0 -45
  142. package/src/components/checkbox/checkbox.js +0 -96
  143. package/src/components/checkbox/index.js +0 -2
  144. package/src/components/container/api.js +0 -42
  145. package/src/components/container/container.js +0 -45
  146. package/src/components/container/index.js +0 -2
  147. package/src/components/container/styles.scss +0 -66
  148. package/src/components/list/index.js +0 -2
  149. package/src/components/list/list-item.js +0 -147
  150. package/src/components/list/list.js +0 -267
  151. package/src/components/menu/api.js +0 -117
  152. package/src/components/menu/constants.js +0 -42
  153. package/src/components/menu/features/items-manager.js +0 -375
  154. package/src/components/menu/features/keyboard-navigation.js +0 -129
  155. package/src/components/menu/features/positioning.js +0 -125
  156. package/src/components/menu/index.js +0 -2
  157. package/src/components/menu/menu-item.js +0 -41
  158. package/src/components/menu/menu.js +0 -54
  159. package/src/components/navigation/api.js +0 -43
  160. package/src/components/navigation/index.js +0 -2
  161. package/src/components/navigation/nav-item.js +0 -137
  162. package/src/components/navigation/navigation.js +0 -55
  163. package/src/components/snackbar/api.js +0 -125
  164. package/src/components/snackbar/features.js +0 -69
  165. package/src/components/snackbar/index.js +0 -2
  166. package/src/components/snackbar/position.js +0 -63
  167. package/src/components/snackbar/queue.js +0 -74
  168. package/src/components/snackbar/snackbar.js +0 -70
  169. package/src/components/switch/api.js +0 -44
  170. package/src/components/switch/index.js +0 -2
  171. package/src/components/switch/switch.js +0 -71
  172. package/src/components/textfield/api.js +0 -49
  173. package/src/components/textfield/index.js +0 -2
  174. package/src/components/textfield/textfield.js +0 -68
  175. package/src/core/build/_ripple.scss +0 -79
  176. package/src/core/build/constants.js +0 -51
  177. package/src/core/build/icon.js +0 -78
  178. package/src/core/build/ripple.js +0 -159
  179. package/src/core/build/text.js +0 -54
  180. package/src/core/compose/base.js +0 -8
  181. package/src/core/compose/component.js +0 -225
  182. package/src/core/compose/features/checkable.js +0 -114
  183. package/src/core/compose/features/disabled.js +0 -64
  184. package/src/core/compose/features/events.js +0 -48
  185. package/src/core/compose/features/icon.js +0 -33
  186. package/src/core/compose/features/index.js +0 -20
  187. package/src/core/compose/features/input.js +0 -100
  188. package/src/core/compose/features/lifecycle.js +0 -69
  189. package/src/core/compose/features/position.js +0 -60
  190. package/src/core/compose/features/ripple.js +0 -32
  191. package/src/core/compose/features/size.js +0 -9
  192. package/src/core/compose/features/style.js +0 -12
  193. package/src/core/compose/features/text.js +0 -17
  194. package/src/core/compose/features/textinput.js +0 -114
  195. package/src/core/compose/features/textlabel.js +0 -28
  196. package/src/core/compose/features/track.js +0 -49
  197. package/src/core/compose/features/variant.js +0 -9
  198. package/src/core/compose/features/withEvents.js +0 -67
  199. package/src/core/compose/index.js +0 -16
  200. package/src/core/config.js +0 -140
  201. package/src/core/dom/classes.js +0 -70
  202. package/src/core/dom/create.js +0 -132
  203. package/src/core/dom/events.js +0 -175
  204. package/src/core/dom/index.js +0 -5
  205. package/src/core/dom/utils.js +0 -22
  206. package/src/core/index.js +0 -23
  207. package/src/core/state/disabled.js +0 -51
  208. package/src/core/state/emitter.js +0 -63
  209. package/src/core/state/events.js +0 -29
  210. package/src/core/state/index.js +0 -6
  211. package/src/core/state/lifecycle.js +0 -64
  212. package/src/core/state/store.js +0 -112
  213. package/src/core/utils/index.js +0 -39
  214. package/src/core/utils/object.js +0 -22
  215. package/src/core/utils/validate.js +0 -37
  216. /package/src/components/checkbox/{styles.scss → _styles.scss} +0 -0
  217. /package/src/components/checkbox/{constants.js → constants.ts} +0 -0
  218. /package/src/components/list/{styles.scss → _styles.scss} +0 -0
  219. /package/src/components/menu/{styles.scss → _styles.scss} +0 -0
  220. /package/src/components/navigation/{styles.scss → _styles.scss} +0 -0
  221. /package/src/components/snackbar/{styles.scss → _styles.scss} +0 -0
  222. /package/src/components/switch/{styles.scss → _styles.scss} +0 -0
  223. /package/src/components/switch/{constants.js → constants.ts} +0 -0
  224. /package/src/components/textfield/{styles.scss → _styles.scss} +0 -0
@@ -1,60 +0,0 @@
1
- // src/core/compose/features/position.js
2
-
3
- /**
4
- * Available position values
5
- */
6
- export const POSITIONS = {
7
- LEFT: 'left',
8
- RIGHT: 'right',
9
- TOP: 'top',
10
- BOTTOM: 'bottom',
11
- START: 'start',
12
- END: 'end',
13
- CENTER: 'center'
14
- }
15
-
16
- /**
17
- * Adds positioning functionality to a component
18
- * @param {Object} config - Component configuration
19
- * @param {string} config.position - Position value
20
- * @param {string} [config.prefix='mtrl'] - CSS class prefix
21
- * @param {string} [config.componentName] - Component name for class generation
22
- * @returns {Function} Component transformer
23
- */
24
- export const withPosition = (config) => (component) => {
25
- if (!config.position || !component.element) return component
26
-
27
- const position = POSITIONS[config.position.toUpperCase()] || config.position
28
- const className = `${config.prefix}-${config.componentName}--${position}`
29
-
30
- component.element.classList.add(className)
31
-
32
- return {
33
- ...component,
34
- position: {
35
- /**
36
- * Sets the component's position
37
- * @param {string} newPosition - New position value
38
- * @returns {Object} Component instance
39
- */
40
- setPosition (newPosition) {
41
- const oldPosition = position
42
- const oldClassName = `${config.prefix}-${config.componentName}--${oldPosition}`
43
- const newClassName = `${config.prefix}-${config.componentName}--${newPosition}`
44
-
45
- component.element.classList.remove(oldClassName)
46
- component.element.classList.add(newClassName)
47
-
48
- return this
49
- },
50
-
51
- /**
52
- * Gets the current position
53
- * @returns {string} Current position
54
- */
55
- getPosition () {
56
- return position
57
- }
58
- }
59
- }
60
- }
@@ -1,32 +0,0 @@
1
- // src/core/compose/features/with-ripple.js
2
-
3
- import { createRipple } from '../../build/ripple'
4
-
5
- /**
6
- * Higher-order function that adds ripple effect functionality
7
- * @param {Object} config - Feature configuration
8
- * @param {boolean} [config.ripple] - Enable/disable ripple effect
9
- * @param {Object} [config.rippleConfig] - Ripple animation configuration
10
- * @returns {Function} Component enhancer
11
- */
12
- export const withRipple = (config = {}) => (component) => {
13
- if (!config.ripple) return component
14
-
15
- const rippleInstance = createRipple(config.rippleConfig)
16
-
17
- return {
18
- ...component,
19
- ripple: rippleInstance,
20
- lifecycle: {
21
- ...component.lifecycle,
22
- mount: () => {
23
- component.lifecycle.mount()
24
- rippleInstance.mount(component.element)
25
- },
26
- destroy: () => {
27
- rippleInstance.unmount(component.element)
28
- component.lifecycle.destroy()
29
- }
30
- }
31
- }
32
- }
@@ -1,9 +0,0 @@
1
- // src/core/compose/features/variant.js
2
- export const withSize = config => component => {
3
- if (config.size && component.element) {
4
- // Use config.componentName since we know it's there
5
- const className = `${config.prefix}-${config.componentName}--${config.size}`
6
- component.element.classList.add(className)
7
- }
8
- return component
9
- }
@@ -1,12 +0,0 @@
1
- // src/core/compose/features/style.js
2
- export const withStyle = (config = {}) => (layout) => {
3
- if (config.variant) {
4
- layout.element.classList.add(`${layout.getClass('button')}--${config.variant}`)
5
- }
6
-
7
- if (config.size) {
8
- layout.element.classList.add(`${layout.getClass('button')}--${config.size}`)
9
- }
10
-
11
- return layout
12
- }
@@ -1,17 +0,0 @@
1
- import { createText } from '../../../core/build/text'
2
-
3
- export const withText = (config = {}) => (component) => {
4
- const text = createText(component.element, {
5
- prefix: config.prefix,
6
- type: 'button'
7
- })
8
-
9
- if (config.text) {
10
- text.setText(config.text)
11
- }
12
-
13
- return {
14
- ...component,
15
- text
16
- }
17
- }
@@ -1,114 +0,0 @@
1
- // src/core/compose/features/textinput.js
2
- /**
3
- * Enhances a component with text input functionality
4
- * @param {Object} config - Text input configuration
5
- * @param {string} [config.type] - Input type (text, password, etc.)
6
- * @param {boolean} [config.multiline] - Whether to use textarea
7
- * @returns {Function} Component enhancer
8
- */
9
- export const withTextInput = (config = {}) => (component) => {
10
- const input = document.createElement(config.type === 'multiline' ? 'textarea' : 'input')
11
- input.className = `${component.getClass('textfield')}-input`
12
-
13
- // Set input attributes
14
- const attributes = {
15
- type: config.type === 'multiline' ? null : (config.type || 'text'),
16
- name: config.name,
17
- required: config.required,
18
- disabled: config.disabled,
19
- maxLength: config.maxLength,
20
- pattern: config.pattern,
21
- autocomplete: config.autocomplete,
22
- value: config.value || ''
23
- }
24
-
25
- Object.entries(attributes).forEach(([key, value]) => {
26
- if (value !== null && value !== undefined) {
27
- input.setAttribute(key, value)
28
- }
29
- })
30
-
31
- // Handle input state changes
32
- const updateInputState = () => {
33
- const isEmpty = !input.value
34
- component.element.classList.toggle(`${component.getClass('textfield')}--empty`, isEmpty)
35
- return isEmpty
36
- }
37
-
38
- // Detect autofill using input events instead of animation
39
- // This is more compatible with our testing environment
40
- const handleAutofill = () => {
41
- // Check for webkit autofill background
42
- const isAutofilled =
43
- input.matches(':-webkit-autofill') ||
44
- // For Firefox and other browsers
45
- (window.getComputedStyle(input).backgroundColor === 'rgb(250, 255, 189)' ||
46
- window.getComputedStyle(input).backgroundColor === 'rgb(232, 240, 254)')
47
-
48
- if (isAutofilled) {
49
- component.element.classList.remove(`${component.getClass('textfield')}--empty`)
50
- component.emit('input', { value: input.value, isEmpty: false, isAutofilled: true })
51
- }
52
- }
53
-
54
- // Event listeners
55
- input.addEventListener('focus', () => {
56
- component.element.classList.add(`${component.getClass('textfield')}--focused`)
57
- component.emit('focus', { isEmpty: updateInputState() })
58
- // Also check for autofill on focus
59
- setTimeout(handleAutofill, 100)
60
- })
61
-
62
- input.addEventListener('blur', () => {
63
- component.element.classList.remove(`${component.getClass('textfield')}--focused`)
64
- component.emit('blur', { isEmpty: updateInputState() })
65
- })
66
-
67
- input.addEventListener('input', () => {
68
- component.emit('input', {
69
- value: input.value,
70
- isEmpty: updateInputState(),
71
- isAutofilled: false
72
- })
73
- })
74
-
75
- // Initial state
76
- updateInputState()
77
-
78
- component.element.appendChild(input)
79
-
80
- // Cleanup
81
- if (component.lifecycle) {
82
- const originalDestroy = component.lifecycle.destroy
83
- component.lifecycle.destroy = () => {
84
- input.remove()
85
- if (originalDestroy) {
86
- originalDestroy.call(component.lifecycle)
87
- }
88
- }
89
- }
90
-
91
- return {
92
- ...component,
93
- input,
94
- setValue (value) {
95
- input.value = value || ''
96
- updateInputState()
97
- return this
98
- },
99
- getValue () {
100
- return input.value
101
- },
102
- setAttribute (name, value) {
103
- input.setAttribute(name, value)
104
- return this
105
- },
106
- getAttribute (name) {
107
- return input.getAttribute(name)
108
- },
109
- removeAttribute (name) {
110
- input.removeAttribute(name)
111
- return this
112
- }
113
- }
114
- }
@@ -1,28 +0,0 @@
1
- // src/core/compose/features/textlabel.js
2
-
3
- export const withTextLabel = (config = {}) => (component) => {
4
- if (!config.label) return component
5
-
6
- const labelElement = document.createElement('label')
7
- labelElement.className = `${config.prefix}-${config.componentName}-label`
8
- labelElement.textContent = config.label
9
-
10
- // Insert label after input for proper z-index stacking
11
- component.element.appendChild(labelElement)
12
-
13
- return {
14
- ...component,
15
- label: {
16
- setText (text) {
17
- labelElement.textContent = text
18
- return this
19
- },
20
- getText () {
21
- return labelElement.textContent
22
- },
23
- getElement () {
24
- return labelElement
25
- }
26
- }
27
- }
28
- }
@@ -1,49 +0,0 @@
1
- // src/core/compose/features/track.js
2
- /**
3
- * @module core/compose/features
4
- */
5
-
6
- /**
7
- * Default checkmark icon SVG
8
- * @memberof module:core/compose/features
9
- * @private
10
- */
11
- const DEFAULT_ICON = `
12
- <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
13
- <polyline points="20 6 9 17 4 12"></polyline>
14
- </svg>`
15
-
16
- /**
17
- * Adds track and thumb elements to a component
18
- * @memberof module:core/compose/features
19
- * @function withTrack
20
- * @param {Object} config - Track configuration
21
- * @param {string} config.prefix - Class prefix
22
- * @param {string} config.componentName - Component name
23
- * @param {string} [config.icon] - Custom icon HTML or 'none'
24
- * @returns {Function} Component transformer
25
- */
26
- export const withTrack = (config) => (component) => {
27
- const track = document.createElement('span')
28
- track.className = `${config.prefix}-${config.componentName}-track`
29
-
30
- const thumb = document.createElement('span')
31
- thumb.className = `${config.prefix}-${config.componentName}-thumb`
32
- track.appendChild(thumb)
33
-
34
- // Add icon inside thumb if provided or use default
35
- if (config.icon !== 'none') {
36
- const icon = document.createElement('span')
37
- icon.className = `${config.prefix}-${config.componentName}-thumb-icon`
38
- icon.innerHTML = config.icon || DEFAULT_ICON
39
- thumb.appendChild(icon)
40
- }
41
-
42
- component.element.appendChild(track)
43
-
44
- return {
45
- ...component,
46
- track,
47
- thumb
48
- }
49
- }
@@ -1,9 +0,0 @@
1
- // src/core/compose/features/variant.js
2
- export const withVariant = config => component => {
3
- if (config.variant && component.element) {
4
- // Use config.componentName since we know it's there
5
- const className = `${config.prefix}-${config.componentName}--${config.variant}`
6
- component.element.classList.add(className)
7
- }
8
- return component
9
- }
@@ -1,67 +0,0 @@
1
- // src/core/compose/features/withEvents.js
2
- import { createEventManager } from '../../state/events'
3
-
4
- /**
5
- * Adds event handling capabilities to a component
6
- * @param {HTMLElement} [target] - Optional custom event target
7
- * @returns {Function} Component enhancer
8
- */
9
- export const withEvents = (target) => (component) => {
10
- const events = createEventManager(target || component.element)
11
-
12
- // Enhanced event methods
13
- const enhancedEvents = {
14
- /**
15
- * Add multiple event listeners at once
16
- * @param {Object} listeners - Map of event types to handlers
17
- */
18
- addListeners (listeners) {
19
- Object.entries(listeners).forEach(([event, handler]) => {
20
- events.on(event, handler)
21
- })
22
- return this
23
- },
24
-
25
- /**
26
- * Remove multiple event listeners at once
27
- * @param {Object} listeners - Map of event types to handlers
28
- */
29
- removeListeners (listeners) {
30
- Object.entries(listeners).forEach(([event, handler]) => {
31
- events.off(event, handler)
32
- })
33
- return this
34
- },
35
-
36
- /**
37
- * One-time event handler
38
- * @param {string} event - Event name
39
- * @param {Function} handler - Event handler
40
- */
41
- once (event, handler) {
42
- const wrappedHandler = (e) => {
43
- handler(e)
44
- events.off(event, wrappedHandler)
45
- }
46
- events.on(event, wrappedHandler)
47
- return this
48
- }
49
- }
50
-
51
- // Add lifecycle integration
52
- if (component.lifecycle) {
53
- const originalDestroy = component.lifecycle.destroy
54
- component.lifecycle.destroy = () => {
55
- events.destroy()
56
- originalDestroy?.call(component.lifecycle)
57
- }
58
- }
59
-
60
- return {
61
- ...component,
62
- events,
63
- on: events.on.bind(events),
64
- off: events.off.bind(events),
65
- ...enhancedEvents
66
- }
67
- }
@@ -1,16 +0,0 @@
1
- // src/core/compose/index.js
2
- /**
3
- * @module core/compose
4
- * @description Core composition utilities for creating and combining components
5
- */
6
- export { pipe, compose, transform } from './pipe'
7
- export {
8
- withEvents,
9
- withIcon,
10
- withSize,
11
- withPosition,
12
- withText,
13
- withVariant,
14
- withTextInput
15
- } from './features'
16
- export { createBase, withElement } from './component' // Add this line
@@ -1,140 +0,0 @@
1
- // src/core/config.js
2
-
3
- /**
4
- * Library prefix used for all components
5
- */
6
- export const PREFIX = 'mtrl'
7
-
8
- export const getComponentClass = (type) => `${PREFIX}-${type}`
9
- export const getModifierClass = (baseClass, modifier) => `${baseClass}--${modifier}`
10
- export const getElementClass = (baseClass, element) => `${baseClass}-${element}`
11
-
12
- /**
13
- * Component type identifiers
14
- * @enum {string}
15
- */
16
- export const COMPONENTS = {
17
- BUTTON: 'button',
18
- TEXTFIELD: 'textfield',
19
- CONTAINER: 'container',
20
- SNACKBAR: 'snackbar',
21
- SWITCH: 'switch'
22
- }
23
-
24
- /**
25
- * Theme configuration
26
- * @typedef {Object} ThemeConfig
27
- * @property {string} name - Theme name
28
- * @property {Object} variables - Theme CSS variables
29
- * @property {Object} variants - Theme variants
30
- */
31
-
32
- /**
33
- * Creates a component configuration object
34
- * @param {string} type - Component type from COMPONENT_TYPES
35
- * @returns {Object} Component configuration interface
36
- */
37
- export const createComponentConfig = (type) => {
38
- const baseClass = `${PREFIX}-${type}`
39
-
40
- // Create the base config object
41
- const config = {
42
- prefix: PREFIX,
43
- type,
44
- baseClass,
45
-
46
- // Class name generators
47
- getClass: () => baseClass,
48
- getModifierClass: (modifier) => `${baseClass}--${modifier}`,
49
- getElementClass: (element) => `${baseClass}-${element}`,
50
-
51
- // Theme support
52
- withTheme: (theme) => ({
53
- ...config,
54
- theme,
55
- getThemeClass: (variant) => `${baseClass}--theme-${theme}-${variant}`
56
- }),
57
-
58
- // Variant support
59
- withVariants: (...variants) => ({
60
- ...config,
61
- variants,
62
- hasVariant: (variant) => variants.includes(variant),
63
- getVariantClass: (variant) =>
64
- variants.includes(variant) ? `${baseClass}--${variant}` : null
65
- }),
66
-
67
- // State support
68
- withStates: (...states) => ({
69
- ...config,
70
- states,
71
- getStateClass: (state) =>
72
- states.includes(state) ? `${baseClass}--state-${state}` : null
73
- })
74
- }
75
-
76
- return config
77
- }
78
-
79
- /**
80
- * Common component states
81
- * @enum {string}
82
- */
83
- export const STATES = {
84
- DISABLED: 'disabled',
85
- FOCUSED: 'focused',
86
- ACTIVE: 'active',
87
- LOADING: 'loading',
88
- ERROR: 'error'
89
- }
90
-
91
- /**
92
- * CSS class generation utilities
93
- */
94
- export const classNames = {
95
- /**
96
- * Creates a BEM-style class name
97
- * @param {string} block - Block name
98
- * @param {string} [element] - Element name
99
- * @param {string} [modifier] - Modifier name
100
- * @returns {string} BEM class name
101
- */
102
- bem: (block, element, modifier) => {
103
- let className = block
104
- if (element) className += `-${element}`
105
- if (modifier) className += `--${modifier}`
106
- return className
107
- },
108
-
109
- /**
110
- * Joins class names, filtering out falsy values
111
- * @param {...string} classes - Class names to join
112
- * @returns {string} Joined class names
113
- */
114
- join: (...classes) => classes.filter(Boolean).join(' ')
115
- }
116
-
117
- /**
118
- * Creates a themed component configuration
119
- * @param {string} type - Component type
120
- * @param {ThemeConfig} theme - Theme configuration
121
- */
122
- export const createThemedComponent = (type, theme) => {
123
- const config = createComponentConfig(type)
124
-
125
- return {
126
- ...config,
127
- theme,
128
-
129
- // Theme-specific class generators
130
- getThemeClass: (variant) =>
131
- `${config.getClass()}--theme-${theme.name}${variant ? `-${variant}` : ''}`,
132
-
133
- // Theme CSS variables
134
- getCssVariables: () =>
135
- Object.entries(theme.variables).reduce((acc, [key, value]) => ({
136
- ...acc,
137
- [`--${PREFIX}-${type}-${key}`]: value
138
- }), {})
139
- }
140
- }
@@ -1,70 +0,0 @@
1
- // src/core/dom/classes.js
2
- /**
3
- * @module core/dom
4
- * @description DOM manipulation utilities
5
- */
6
-
7
- import { normalizeClasses } from '../utils'
8
- /**
9
- * Adds multiple classes to an element
10
- * @memberof module:core/dom
11
- * @function addClass
12
- * @param {HTMLElement} element - Target element
13
- * @param {...string} classes - Classes to add
14
- * @returns {HTMLElement} Modified element
15
- */
16
-
17
- /**
18
- * Adds multiple classes to an element
19
- * @param {HTMLElement} element - Target element
20
- * @param {...string} classes - Classes to add
21
- * @returns {HTMLElement} Modified element
22
- */
23
- export const addClass = (element, ...classes) => {
24
- const normalizedClasses = normalizeClasses(...classes)
25
- if (normalizedClasses.length) {
26
- element.classList.add(...normalizedClasses)
27
- }
28
- return element
29
- }
30
-
31
- /**
32
- * Removes multiple classes from an element
33
- * @memberof module:core/dom
34
- * @function removeClass
35
- * @param {HTMLElement} element - Target element
36
- * @param {...string} classes - Classes to remove
37
- * @returns {HTMLElement} Modified element
38
- */
39
- export const removeClass = (element, ...classes) => {
40
- const normalizedClasses = normalizeClasses(...classes)
41
- if (normalizedClasses.length) {
42
- element.classList.remove(...normalizedClasses)
43
- }
44
- return element
45
- }
46
-
47
- /**
48
- * Toggles multiple classes on an element
49
- * @param {HTMLElement} element - Target element
50
- * @param {...string} classes - Classes to toggle
51
- * @returns {HTMLElement} Modified element
52
- */
53
- export const toggleClass = (element, ...classes) => {
54
- const normalizedClasses = normalizeClasses(...classes)
55
- normalizedClasses.forEach(cls => {
56
- element.classList.toggle(cls)
57
- })
58
- return element
59
- }
60
-
61
- /**
62
- * Checks if an element has all specified classes
63
- * @param {HTMLElement} element - Target element
64
- * @param {...string} classes - Classes to check
65
- * @returns {boolean} True if element has all specified classes
66
- */
67
- export const hasClass = (element, ...classes) => {
68
- const normalizedClasses = normalizeClasses(...classes)
69
- return normalizedClasses.every(cls => element.classList.contains(cls))
70
- }