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.
- package/README.md +70 -22
- package/index.ts +33 -0
- package/package.json +14 -5
- package/src/components/button/{styles.scss → _styles.scss} +2 -2
- package/src/components/button/api.ts +89 -0
- package/src/components/button/button.ts +50 -0
- package/src/components/button/config.ts +75 -0
- package/src/components/button/constants.ts +17 -0
- package/src/components/button/index.ts +4 -0
- package/src/components/button/types.ts +118 -0
- package/src/components/card/{styles.scss → _styles.scss} +79 -7
- package/src/components/card/{actions.js → actions.ts} +15 -18
- package/src/components/card/{api.js → api.ts} +33 -33
- package/src/components/card/card.ts +41 -0
- package/src/components/card/config.ts +99 -0
- package/src/components/card/{constants.js → constants.ts} +11 -10
- package/src/components/card/{content.js → content.ts} +15 -18
- package/src/components/card/{features.js → features.ts} +104 -94
- package/src/components/card/{header.js → header.ts} +21 -25
- package/src/components/card/index.ts +19 -0
- package/src/components/card/media.ts +52 -0
- package/src/components/card/types.ts +174 -0
- package/src/components/checkbox/api.ts +82 -0
- package/src/components/checkbox/checkbox.ts +75 -0
- package/src/components/checkbox/config.ts +90 -0
- package/src/components/checkbox/index.ts +4 -0
- package/src/components/checkbox/types.ts +146 -0
- package/src/components/chip/_styles.scss +372 -0
- package/src/components/chip/api.ts +115 -0
- package/src/components/chip/chip-set.ts +225 -0
- package/src/components/chip/chip.ts +82 -0
- package/src/components/chip/config.ts +92 -0
- package/src/components/chip/constants.ts +38 -0
- package/src/components/chip/index.ts +4 -0
- package/src/components/chip/types.ts +172 -0
- package/src/components/list/api.ts +72 -0
- package/src/components/list/config.ts +43 -0
- package/src/components/list/{constants.js → constants.ts} +34 -7
- package/src/components/list/features.ts +224 -0
- package/src/components/list/index.ts +14 -0
- package/src/components/list/list-item.ts +120 -0
- package/src/components/list/list.ts +37 -0
- package/src/components/list/types.ts +179 -0
- package/src/components/list/utils.ts +47 -0
- package/src/components/menu/api.ts +119 -0
- package/src/components/menu/config.ts +54 -0
- package/src/components/menu/constants.ts +154 -0
- package/src/components/menu/features/items-manager.ts +457 -0
- package/src/components/menu/features/keyboard-navigation.ts +133 -0
- package/src/components/menu/features/positioning.ts +127 -0
- package/src/components/menu/features/{visibility.js → visibility.ts} +66 -64
- package/src/components/menu/index.ts +14 -0
- package/src/components/menu/menu-item.ts +43 -0
- package/src/components/menu/menu.ts +53 -0
- package/src/components/menu/types.ts +178 -0
- package/src/components/navigation/api.ts +79 -0
- package/src/components/navigation/config.ts +61 -0
- package/src/components/navigation/{constants.js → constants.ts} +10 -10
- package/src/components/navigation/index.ts +14 -0
- package/src/components/navigation/nav-item.ts +148 -0
- package/src/components/navigation/navigation.ts +50 -0
- package/src/components/navigation/types.ts +212 -0
- package/src/components/progress/_styles.scss +204 -0
- package/src/components/progress/api.ts +179 -0
- package/src/components/progress/config.ts +124 -0
- package/src/components/progress/constants.ts +43 -0
- package/src/components/progress/index.ts +5 -0
- package/src/components/progress/progress.ts +163 -0
- package/src/components/progress/types.ts +102 -0
- package/src/components/snackbar/api.ts +162 -0
- package/src/components/snackbar/config.ts +62 -0
- package/src/components/snackbar/{constants.js → constants.ts} +21 -4
- package/src/components/snackbar/features.ts +76 -0
- package/src/components/snackbar/index.ts +4 -0
- package/src/components/snackbar/position.ts +71 -0
- package/src/components/snackbar/queue.ts +76 -0
- package/src/components/snackbar/snackbar.ts +60 -0
- package/src/components/snackbar/types.ts +58 -0
- package/src/components/switch/api.ts +77 -0
- package/src/components/switch/config.ts +74 -0
- package/src/components/switch/index.ts +4 -0
- package/src/components/switch/switch.ts +52 -0
- package/src/components/switch/types.ts +142 -0
- package/src/components/textfield/api.ts +72 -0
- package/src/components/textfield/config.ts +54 -0
- package/src/components/textfield/{constants.js → constants.ts} +38 -5
- package/src/components/textfield/index.ts +4 -0
- package/src/components/textfield/textfield.ts +50 -0
- package/src/components/textfield/types.ts +139 -0
- package/src/core/compose/base.ts +43 -0
- package/src/core/compose/component.ts +247 -0
- package/src/core/compose/features/checkable.ts +155 -0
- package/src/core/compose/features/disabled.ts +116 -0
- package/src/core/compose/features/events.ts +65 -0
- package/src/core/compose/features/icon.ts +67 -0
- package/src/core/compose/features/index.ts +35 -0
- package/src/core/compose/features/input.ts +174 -0
- package/src/core/compose/features/lifecycle.ts +139 -0
- package/src/core/compose/features/position.ts +94 -0
- package/src/core/compose/features/ripple.ts +55 -0
- package/src/core/compose/features/size.ts +29 -0
- package/src/core/compose/features/style.ts +31 -0
- package/src/core/compose/features/text.ts +44 -0
- package/src/core/compose/features/textinput.ts +225 -0
- package/src/core/compose/features/textlabel.ts +92 -0
- package/src/core/compose/features/track.ts +84 -0
- package/src/core/compose/features/variant.ts +29 -0
- package/src/core/compose/features/withEvents.ts +137 -0
- package/src/core/compose/index.ts +54 -0
- package/src/core/compose/{pipe.js → pipe.ts} +16 -11
- package/src/core/config/component-config.ts +136 -0
- package/src/core/config.ts +211 -0
- package/src/core/dom/{attributes.js → attributes.ts} +11 -11
- package/src/core/dom/classes.ts +60 -0
- package/src/core/dom/create.ts +188 -0
- package/src/core/dom/events.ts +209 -0
- package/src/core/dom/index.ts +10 -0
- package/src/core/dom/utils.ts +97 -0
- package/src/core/index.ts +111 -0
- package/src/core/state/disabled.ts +81 -0
- package/src/core/state/emitter.ts +94 -0
- package/src/core/state/events.ts +88 -0
- package/src/core/state/index.ts +16 -0
- package/src/core/state/lifecycle.ts +131 -0
- package/src/core/state/store.ts +197 -0
- package/src/core/utils/index.ts +45 -0
- package/src/core/utils/{mobile.js → mobile.ts} +48 -24
- package/src/core/utils/object.ts +41 -0
- package/src/core/utils/validate.ts +234 -0
- package/src/{index.js → index.ts} +3 -2
- package/index.js +0 -11
- package/src/components/button/api.js +0 -54
- package/src/components/button/button.js +0 -81
- package/src/components/button/config.js +0 -10
- package/src/components/button/constants.js +0 -63
- package/src/components/button/index.js +0 -2
- package/src/components/card/card.js +0 -102
- package/src/components/card/config.js +0 -16
- package/src/components/card/index.js +0 -7
- package/src/components/card/media.js +0 -56
- package/src/components/checkbox/api.js +0 -45
- package/src/components/checkbox/checkbox.js +0 -96
- package/src/components/checkbox/index.js +0 -2
- package/src/components/container/api.js +0 -42
- package/src/components/container/container.js +0 -45
- package/src/components/container/index.js +0 -2
- package/src/components/container/styles.scss +0 -66
- package/src/components/list/index.js +0 -2
- package/src/components/list/list-item.js +0 -147
- package/src/components/list/list.js +0 -267
- package/src/components/menu/api.js +0 -117
- package/src/components/menu/constants.js +0 -42
- package/src/components/menu/features/items-manager.js +0 -375
- package/src/components/menu/features/keyboard-navigation.js +0 -129
- package/src/components/menu/features/positioning.js +0 -125
- package/src/components/menu/index.js +0 -2
- package/src/components/menu/menu-item.js +0 -41
- package/src/components/menu/menu.js +0 -54
- package/src/components/navigation/api.js +0 -43
- package/src/components/navigation/index.js +0 -2
- package/src/components/navigation/nav-item.js +0 -137
- package/src/components/navigation/navigation.js +0 -55
- package/src/components/snackbar/api.js +0 -125
- package/src/components/snackbar/features.js +0 -69
- package/src/components/snackbar/index.js +0 -2
- package/src/components/snackbar/position.js +0 -63
- package/src/components/snackbar/queue.js +0 -74
- package/src/components/snackbar/snackbar.js +0 -70
- package/src/components/switch/api.js +0 -44
- package/src/components/switch/index.js +0 -2
- package/src/components/switch/switch.js +0 -71
- package/src/components/textfield/api.js +0 -49
- package/src/components/textfield/index.js +0 -2
- package/src/components/textfield/textfield.js +0 -68
- package/src/core/build/_ripple.scss +0 -79
- package/src/core/build/constants.js +0 -51
- package/src/core/build/icon.js +0 -78
- package/src/core/build/ripple.js +0 -159
- package/src/core/build/text.js +0 -54
- package/src/core/compose/base.js +0 -8
- package/src/core/compose/component.js +0 -225
- package/src/core/compose/features/checkable.js +0 -114
- package/src/core/compose/features/disabled.js +0 -64
- package/src/core/compose/features/events.js +0 -48
- package/src/core/compose/features/icon.js +0 -33
- package/src/core/compose/features/index.js +0 -20
- package/src/core/compose/features/input.js +0 -100
- package/src/core/compose/features/lifecycle.js +0 -69
- package/src/core/compose/features/position.js +0 -60
- package/src/core/compose/features/ripple.js +0 -32
- package/src/core/compose/features/size.js +0 -9
- package/src/core/compose/features/style.js +0 -12
- package/src/core/compose/features/text.js +0 -17
- package/src/core/compose/features/textinput.js +0 -114
- package/src/core/compose/features/textlabel.js +0 -28
- package/src/core/compose/features/track.js +0 -49
- package/src/core/compose/features/variant.js +0 -9
- package/src/core/compose/features/withEvents.js +0 -67
- package/src/core/compose/index.js +0 -16
- package/src/core/config.js +0 -140
- package/src/core/dom/classes.js +0 -70
- package/src/core/dom/create.js +0 -132
- package/src/core/dom/events.js +0 -175
- package/src/core/dom/index.js +0 -5
- package/src/core/dom/utils.js +0 -22
- package/src/core/index.js +0 -23
- package/src/core/state/disabled.js +0 -51
- package/src/core/state/emitter.js +0 -63
- package/src/core/state/events.js +0 -29
- package/src/core/state/index.js +0 -6
- package/src/core/state/lifecycle.js +0 -64
- package/src/core/state/store.js +0 -112
- package/src/core/utils/index.js +0 -39
- package/src/core/utils/object.js +0 -22
- package/src/core/utils/validate.js +0 -37
- /package/src/components/checkbox/{styles.scss → _styles.scss} +0 -0
- /package/src/components/checkbox/{constants.js → constants.ts} +0 -0
- /package/src/components/list/{styles.scss → _styles.scss} +0 -0
- /package/src/components/menu/{styles.scss → _styles.scss} +0 -0
- /package/src/components/navigation/{styles.scss → _styles.scss} +0 -0
- /package/src/components/snackbar/{styles.scss → _styles.scss} +0 -0
- /package/src/components/switch/{styles.scss → _styles.scss} +0 -0
- /package/src/components/switch/{constants.js → constants.ts} +0 -0
- /package/src/components/textfield/{styles.scss → _styles.scss} +0 -0
package/src/core/dom/create.js
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
// src/core/dom/create.js
|
|
2
|
-
/**
|
|
3
|
-
* @module core/dom
|
|
4
|
-
* @description DOM manipulation utilities
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { setAttributes } from './attributes'
|
|
8
|
-
import { normalizeClasses } from '../utils'
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Creates a DOM element with the specified options
|
|
12
|
-
* @memberof module:core/dom
|
|
13
|
-
* @param {Object} options - Element creation options
|
|
14
|
-
* @param {string} [options.tag='div'] - HTML tag name
|
|
15
|
-
* @param {HTMLElement} [options.container] - Container to append element to
|
|
16
|
-
* @param {string} [options.html] - Inner HTML content
|
|
17
|
-
* @param {string} [options.text] - Text content
|
|
18
|
-
* @param {string} [options.id] - Element ID
|
|
19
|
-
* @param {Object} [options.data] - Dataset attributes
|
|
20
|
-
* @param {string|string[]} [options.className] - CSS classes
|
|
21
|
-
* @param {Object} [options.attrs] - HTML attributes
|
|
22
|
-
* @param {Object} [options.forwardEvents] - Events to forward when component has emit method
|
|
23
|
-
* @param {Function} [options.onCreate] - Callback after element creation
|
|
24
|
-
* @returns {HTMLElement} Created element
|
|
25
|
-
*/
|
|
26
|
-
export const createElement = (options = {}) => {
|
|
27
|
-
const {
|
|
28
|
-
tag = 'div',
|
|
29
|
-
container = null,
|
|
30
|
-
html = '',
|
|
31
|
-
text = '',
|
|
32
|
-
id = '',
|
|
33
|
-
data = {},
|
|
34
|
-
className,
|
|
35
|
-
attrs = {},
|
|
36
|
-
forwardEvents = {},
|
|
37
|
-
onCreate,
|
|
38
|
-
context,
|
|
39
|
-
...rest
|
|
40
|
-
} = options
|
|
41
|
-
|
|
42
|
-
const element = document.createElement(tag)
|
|
43
|
-
|
|
44
|
-
// Handle content
|
|
45
|
-
if (html) element.innerHTML = html
|
|
46
|
-
if (text) element.textContent = text
|
|
47
|
-
if (id) element.id = id
|
|
48
|
-
|
|
49
|
-
// Handle classes
|
|
50
|
-
if (className) {
|
|
51
|
-
const normalizedClasses = normalizeClasses(className)
|
|
52
|
-
if (normalizedClasses.length) {
|
|
53
|
-
element.classList.add(...normalizedClasses)
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Handle data attributes
|
|
58
|
-
Object.entries(data).forEach(([key, value]) => {
|
|
59
|
-
element.dataset[key] = value
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
// Handle all other attributes
|
|
63
|
-
const allAttrs = { ...attrs, ...rest }
|
|
64
|
-
Object.entries(allAttrs).forEach(([key, value]) => {
|
|
65
|
-
if (value != null) element.setAttribute(key, value)
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
// Handle event forwarding if context has emit method
|
|
69
|
-
if (context?.emit && forwardEvents) {
|
|
70
|
-
Object.entries(forwardEvents).forEach(([nativeEvent, eventConfig]) => {
|
|
71
|
-
const shouldForward = typeof eventConfig === 'function'
|
|
72
|
-
? eventConfig
|
|
73
|
-
: () => true
|
|
74
|
-
|
|
75
|
-
element.addEventListener(nativeEvent, (event) => {
|
|
76
|
-
if (shouldForward({ ...context, element }, event)) {
|
|
77
|
-
context.emit(nativeEvent, { event })
|
|
78
|
-
}
|
|
79
|
-
})
|
|
80
|
-
})
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Append to container if provided
|
|
84
|
-
if (container) {
|
|
85
|
-
container.appendChild(element)
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (typeof onCreate === 'function') {
|
|
89
|
-
onCreate(element, context)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return element
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Higher-order function to add attributes to an element
|
|
97
|
-
* @param {Object} attrs - Attributes to add
|
|
98
|
-
* @returns {Function} Element transformer
|
|
99
|
-
*/
|
|
100
|
-
export const withAttributes = (attrs) => (element) => {
|
|
101
|
-
setAttributes(element, attrs)
|
|
102
|
-
return element
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Higher-order function to add classes to an element
|
|
107
|
-
* @memberof module:core/dom
|
|
108
|
-
* @param {...string} classes - Classes to add
|
|
109
|
-
* @returns {Function} Element transformer
|
|
110
|
-
*/
|
|
111
|
-
export const withClasses = (...classes) => (element) => {
|
|
112
|
-
const normalizedClasses = normalizeClasses(...classes)
|
|
113
|
-
if (normalizedClasses.length) {
|
|
114
|
-
element.classList.add(...normalizedClasses)
|
|
115
|
-
}
|
|
116
|
-
return element
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Higher-order function to add content to an element
|
|
121
|
-
* @memberof module:core/dom
|
|
122
|
-
* @param {Node|string} content - Content to add
|
|
123
|
-
* @returns {Function} Element transformer
|
|
124
|
-
*/
|
|
125
|
-
export const withContent = (content) => (element) => {
|
|
126
|
-
if (content instanceof Node) {
|
|
127
|
-
element.appendChild(content)
|
|
128
|
-
} else {
|
|
129
|
-
element.textContent = content
|
|
130
|
-
}
|
|
131
|
-
return element
|
|
132
|
-
}
|
package/src/core/dom/events.js
DELETED
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
// src/core/state/events.js
|
|
2
|
-
/**
|
|
3
|
-
* @module core/dom
|
|
4
|
-
* @description DOM manipulation utilities
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Creates an event manager to handle DOM events with enhanced functionality.
|
|
9
|
-
* Provides a robust interface for managing event listeners with error handling,
|
|
10
|
-
* cleanup, and lifecycle management.
|
|
11
|
-
*
|
|
12
|
-
* @param {HTMLElement} element - DOM element to attach events to
|
|
13
|
-
* @returns {Object} Event manager interface with the following methods:
|
|
14
|
-
*
|
|
15
|
-
* @property {Function} on - Adds an event listener with options
|
|
16
|
-
* @property {Function} off - Removes an event listener
|
|
17
|
-
* @property {Function} pause - Temporarily disables all event listeners
|
|
18
|
-
* @property {Function} resume - Re-enables all event listeners
|
|
19
|
-
* @property {Function} destroy - Removes all event listeners and cleans up
|
|
20
|
-
* @property {Function} getHandlers - Gets all active handlers
|
|
21
|
-
* @property {Function} hasHandler - Checks if a specific handler exists
|
|
22
|
-
*
|
|
23
|
-
* @example
|
|
24
|
-
* const manager = createEventManager(myElement);
|
|
25
|
-
*
|
|
26
|
-
* // Add a listener
|
|
27
|
-
* manager.on('click', (e) => console.log('clicked'), { capture: true });
|
|
28
|
-
*
|
|
29
|
-
* // Remove a listener
|
|
30
|
-
* manager.off('click', myHandler);
|
|
31
|
-
*
|
|
32
|
-
* // Pause all events
|
|
33
|
-
* manager.pause();
|
|
34
|
-
*
|
|
35
|
-
* // Resume all events
|
|
36
|
-
* manager.resume();
|
|
37
|
-
*
|
|
38
|
-
* // Cleanup
|
|
39
|
-
* manager.destroy();
|
|
40
|
-
*/
|
|
41
|
-
export const createEventManager = (element) => {
|
|
42
|
-
// Store handlers with their metadata
|
|
43
|
-
const handlers = new Map()
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Private helper to create a unique handler identifier
|
|
47
|
-
* @memberof module:core/dom
|
|
48
|
-
* @private
|
|
49
|
-
* @param {string} event - Event name
|
|
50
|
-
* @param {Function} handler - Event handler
|
|
51
|
-
* @returns {string} Unique identifier
|
|
52
|
-
*/
|
|
53
|
-
const createHandlerId = (event, handler) =>
|
|
54
|
-
`${event}_${handler.toString()}`
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Wraps an event handler with error boundary and logging
|
|
58
|
-
* @memberof module:core/dom
|
|
59
|
-
* @private
|
|
60
|
-
* @param {Function} handler - Original event handler
|
|
61
|
-
* @param {string} event - Event name for error context
|
|
62
|
-
* @returns {Function} Enhanced handler with error boundary
|
|
63
|
-
*/
|
|
64
|
-
const enhanceHandler = (handler, event) => (e) => {
|
|
65
|
-
try {
|
|
66
|
-
handler(e)
|
|
67
|
-
} catch (error) {
|
|
68
|
-
console.error(`Error in ${event} handler:`, error)
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Safely removes event listener
|
|
74
|
-
* @memberof module:core/dom
|
|
75
|
-
* @param {string} event - Event name
|
|
76
|
-
* @param {Function} handler - Event handler
|
|
77
|
-
*/
|
|
78
|
-
const safeRemoveListener = (event, handler) => {
|
|
79
|
-
try {
|
|
80
|
-
element.removeEventListener(event, handler)
|
|
81
|
-
} catch (error) {
|
|
82
|
-
console.warn(`Failed to remove ${event} listener:`, error)
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return {
|
|
87
|
-
/**
|
|
88
|
-
* Adds an event listener with options
|
|
89
|
-
* @memberof module:core/dom
|
|
90
|
-
* @param {string} event - Event name
|
|
91
|
-
* @param {Function} handler - Event handler
|
|
92
|
-
* @param {Object} [options] - addEventListener options
|
|
93
|
-
*/
|
|
94
|
-
on (event, handler, options = {}) {
|
|
95
|
-
const enhanced = enhanceHandler(handler, event)
|
|
96
|
-
const id = createHandlerId(event, handler)
|
|
97
|
-
|
|
98
|
-
handlers.set(id, {
|
|
99
|
-
original: handler,
|
|
100
|
-
enhanced,
|
|
101
|
-
event,
|
|
102
|
-
options
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
element.addEventListener(event, enhanced, options)
|
|
106
|
-
return this
|
|
107
|
-
},
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Removes an event listener
|
|
111
|
-
* @memberof module:core/dom
|
|
112
|
-
* @param {string} event - Event name
|
|
113
|
-
* @param {Function} handler - Event handler
|
|
114
|
-
*/
|
|
115
|
-
off (event, handler) {
|
|
116
|
-
const id = createHandlerId(event, handler)
|
|
117
|
-
const stored = handlers.get(id)
|
|
118
|
-
|
|
119
|
-
if (stored) {
|
|
120
|
-
safeRemoveListener(event, stored.enhanced)
|
|
121
|
-
handlers.delete(id)
|
|
122
|
-
}
|
|
123
|
-
return this
|
|
124
|
-
},
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Temporarily disables all event listeners
|
|
128
|
-
*/
|
|
129
|
-
pause () {
|
|
130
|
-
handlers.forEach(({ enhanced, event, options }) => {
|
|
131
|
-
safeRemoveListener(event, enhanced)
|
|
132
|
-
})
|
|
133
|
-
return this
|
|
134
|
-
},
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Re-enables all event listeners
|
|
138
|
-
*/
|
|
139
|
-
resume () {
|
|
140
|
-
handlers.forEach(({ enhanced, event, options }) => {
|
|
141
|
-
element.addEventListener(event, enhanced, options)
|
|
142
|
-
})
|
|
143
|
-
return this
|
|
144
|
-
},
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Removes all event listeners and cleans up
|
|
148
|
-
*/
|
|
149
|
-
destroy () {
|
|
150
|
-
handlers.forEach(({ enhanced, event }) => {
|
|
151
|
-
safeRemoveListener(event, enhanced)
|
|
152
|
-
})
|
|
153
|
-
handlers.clear()
|
|
154
|
-
},
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Gets all active handlers
|
|
158
|
-
* @returns {Map} Map of active handlers
|
|
159
|
-
*/
|
|
160
|
-
getHandlers () {
|
|
161
|
-
return new Map(handlers)
|
|
162
|
-
},
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Checks if a specific handler exists
|
|
166
|
-
* @param {string} event - Event name
|
|
167
|
-
* @param {Function} handler - Event handler
|
|
168
|
-
* @returns {boolean} Whether handler exists
|
|
169
|
-
*/
|
|
170
|
-
hasHandler (event, handler) {
|
|
171
|
-
const id = createHandlerId(event, handler)
|
|
172
|
-
return handlers.has(id)
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
package/src/core/dom/index.js
DELETED
package/src/core/dom/utils.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Normalizes class names input by handling various formats:
|
|
3
|
-
* - String with space-separated classes
|
|
4
|
-
* - Array of strings
|
|
5
|
-
* - Mixed array of strings and space-separated classes
|
|
6
|
-
* @param {...(string|string[])} classes - Classes to normalize
|
|
7
|
-
* @returns {string[]} Array of unique, non-empty class names
|
|
8
|
-
*/
|
|
9
|
-
export const normalizeClasses = (...classes) => {
|
|
10
|
-
return [...new Set(
|
|
11
|
-
classes
|
|
12
|
-
.flat()
|
|
13
|
-
.reduce((acc, cls) => {
|
|
14
|
-
if (typeof cls === 'string') {
|
|
15
|
-
// Split space-separated classes and add them individually
|
|
16
|
-
acc.push(...cls.split(/\s+/))
|
|
17
|
-
}
|
|
18
|
-
return acc
|
|
19
|
-
}, [])
|
|
20
|
-
.filter(Boolean) // Remove empty strings
|
|
21
|
-
)]
|
|
22
|
-
}
|
package/src/core/index.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
// src/core/index.js
|
|
2
|
-
/**
|
|
3
|
-
* @module core
|
|
4
|
-
* @description Core utilities and building blocks for the component system
|
|
5
|
-
*/
|
|
6
|
-
// Build
|
|
7
|
-
export { createText } from './build/text'
|
|
8
|
-
export { createIcon } from './build/icon'
|
|
9
|
-
|
|
10
|
-
// Classes management
|
|
11
|
-
export { addClass, removeClass } from './dom/classes'
|
|
12
|
-
|
|
13
|
-
// State Management
|
|
14
|
-
export { createDisabled } from './state/disabled'
|
|
15
|
-
export { createEventManager } from './state/events'
|
|
16
|
-
export { createLifecycle } from './state/lifecycle'
|
|
17
|
-
export { createEmitter } from './state/emitter'
|
|
18
|
-
|
|
19
|
-
// Composition Utilities
|
|
20
|
-
export { pipe, compose, transform } from './compose'
|
|
21
|
-
|
|
22
|
-
// General Utilities
|
|
23
|
-
export { classNames } from './utils'
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
// src/core/state/disabled.js
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Creates a controller for managing the disabled state of an element
|
|
5
|
-
* @param {HTMLElement} element - The element to control
|
|
6
|
-
* @returns {Object} Disabled state controller
|
|
7
|
-
*/
|
|
8
|
-
export const createDisabled = (element) => {
|
|
9
|
-
return {
|
|
10
|
-
/**
|
|
11
|
-
* Enables the element
|
|
12
|
-
* @returns {Object} The controller instance for chaining
|
|
13
|
-
*/
|
|
14
|
-
enable () {
|
|
15
|
-
element.disabled = false
|
|
16
|
-
element.removeAttribute('disabled')
|
|
17
|
-
return this
|
|
18
|
-
},
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Disables the element
|
|
22
|
-
* @returns {Object} The controller instance for chaining
|
|
23
|
-
*/
|
|
24
|
-
disable () {
|
|
25
|
-
element.disabled = true
|
|
26
|
-
element.setAttribute('disabled', 'true')
|
|
27
|
-
return this
|
|
28
|
-
},
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Toggles the disabled state
|
|
32
|
-
* @returns {Object} The controller instance for chaining
|
|
33
|
-
*/
|
|
34
|
-
toggle () {
|
|
35
|
-
if (element.disabled) {
|
|
36
|
-
this.enable()
|
|
37
|
-
} else {
|
|
38
|
-
this.disable()
|
|
39
|
-
}
|
|
40
|
-
return this
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Checks if the element is disabled
|
|
45
|
-
* @returns {boolean} True if the element is disabled
|
|
46
|
-
*/
|
|
47
|
-
isDisabled () {
|
|
48
|
-
return element.disabled === true
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
// src/core/state/emitter.js
|
|
2
|
-
/**
|
|
3
|
-
* @module core/state
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Creates an event emitter with subscription management
|
|
8
|
-
* @memberof module:core/state
|
|
9
|
-
* @function createEmitter
|
|
10
|
-
* @returns {Object} Event emitter interface
|
|
11
|
-
* @property {Function} on - Subscribe to an event
|
|
12
|
-
* @property {Function} off - Unsubscribe from an event
|
|
13
|
-
* @property {Function} emit - Emit an event
|
|
14
|
-
* @property {Function} clear - Clear all subscriptions
|
|
15
|
-
* @example
|
|
16
|
-
* const emitter = createEmitter()
|
|
17
|
-
* const unsubscribe = emitter.on('change', (data) => console.log(data))
|
|
18
|
-
* emitter.emit('change', { value: 42 })
|
|
19
|
-
* unsubscribe()
|
|
20
|
-
*/
|
|
21
|
-
export const createEmitter = () => {
|
|
22
|
-
const events = new Map()
|
|
23
|
-
|
|
24
|
-
return {
|
|
25
|
-
/**
|
|
26
|
-
* Subscribe to an event
|
|
27
|
-
* @param {string} event - Event name
|
|
28
|
-
* @param {Function} callback - Event handler
|
|
29
|
-
* @returns {Function} Unsubscribe function
|
|
30
|
-
*/
|
|
31
|
-
on: (event, callback) => {
|
|
32
|
-
const callbacks = events.get(event) || []
|
|
33
|
-
events.set(event, [...callbacks, callback])
|
|
34
|
-
|
|
35
|
-
return () => {
|
|
36
|
-
const callbacks = events.get(event) || []
|
|
37
|
-
events.set(event, callbacks.filter(cb => cb !== callback))
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
|
-
|
|
41
|
-
off (event, callback) {
|
|
42
|
-
const callbacks = events.get(event) || []
|
|
43
|
-
events.set(event, callbacks.filter(cb => cb !== callback))
|
|
44
|
-
},
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Emit an event
|
|
48
|
-
* @param {string} event - Event name
|
|
49
|
-
* @param {...any} args - Event arguments
|
|
50
|
-
*/
|
|
51
|
-
emit: (event, ...args) => {
|
|
52
|
-
const callbacks = events.get(event) || []
|
|
53
|
-
callbacks.forEach(cb => cb(...args))
|
|
54
|
-
},
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Clear all event listeners
|
|
58
|
-
*/
|
|
59
|
-
clear: () => {
|
|
60
|
-
events.clear()
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
package/src/core/state/events.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
// src/core/state/events.js
|
|
2
|
-
export const createEventManager = (element) => {
|
|
3
|
-
const handlers = new Map()
|
|
4
|
-
|
|
5
|
-
return {
|
|
6
|
-
on (event, handler) {
|
|
7
|
-
element.addEventListener(event, handler)
|
|
8
|
-
handlers.set(handler, event)
|
|
9
|
-
return this
|
|
10
|
-
},
|
|
11
|
-
|
|
12
|
-
off (event, handler) {
|
|
13
|
-
element.removeEventListener(event, handler)
|
|
14
|
-
handlers.delete(handler)
|
|
15
|
-
return this
|
|
16
|
-
},
|
|
17
|
-
|
|
18
|
-
destroy () {
|
|
19
|
-
handlers.forEach((event, handler) => {
|
|
20
|
-
element.removeEventListener(event, handler)
|
|
21
|
-
})
|
|
22
|
-
handlers.clear()
|
|
23
|
-
},
|
|
24
|
-
|
|
25
|
-
getHandlers () {
|
|
26
|
-
return handlers
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
package/src/core/state/index.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
// src/core/state/lifecycle.js
|
|
2
|
-
import { createEmitter } from './emitter'
|
|
3
|
-
|
|
4
|
-
export const createLifecycle = (element, managers = {}) => {
|
|
5
|
-
let mounted = false
|
|
6
|
-
const emitter = createEmitter()
|
|
7
|
-
|
|
8
|
-
return {
|
|
9
|
-
// Mount/Unmount state management
|
|
10
|
-
onMount: (handler) => emitter.on('mount', handler),
|
|
11
|
-
onUnmount: (handler) => emitter.on('unmount', handler),
|
|
12
|
-
|
|
13
|
-
mount: () => {
|
|
14
|
-
if (!mounted) {
|
|
15
|
-
mounted = true
|
|
16
|
-
emitter.emit('mount')
|
|
17
|
-
}
|
|
18
|
-
},
|
|
19
|
-
|
|
20
|
-
unmount: () => {
|
|
21
|
-
if (mounted) {
|
|
22
|
-
mounted = false
|
|
23
|
-
emitter.emit('unmount')
|
|
24
|
-
emitter.clear()
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
|
|
28
|
-
isMounted: () => mounted,
|
|
29
|
-
|
|
30
|
-
// Cleanup and destruction
|
|
31
|
-
destroy() {
|
|
32
|
-
// First trigger unmount
|
|
33
|
-
if (mounted) {
|
|
34
|
-
this.unmount()
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Clean up all event listeners
|
|
38
|
-
if (managers.events) {
|
|
39
|
-
managers.events.destroy()
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Clean up text element
|
|
43
|
-
if (managers.text) {
|
|
44
|
-
const textElement = managers.text.getElement()
|
|
45
|
-
if (textElement) {
|
|
46
|
-
textElement.remove()
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// Clean up icon element
|
|
51
|
-
if (managers.icon) {
|
|
52
|
-
const iconElement = managers.icon.getElement()
|
|
53
|
-
if (iconElement) {
|
|
54
|
-
iconElement.remove()
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Remove the main element
|
|
59
|
-
if (element) {
|
|
60
|
-
element.remove()
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
package/src/core/state/store.js
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
// src/core/state/store.js
|
|
2
|
-
import { createEmitter } from './emitter'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Creates a state store with support for derived state and middleware
|
|
6
|
-
* @template T
|
|
7
|
-
* @param {T} initialState - Initial state object
|
|
8
|
-
* @param {Object} [options] - Store options
|
|
9
|
-
* @param {Function[]} [options.middleware] - Middleware functions
|
|
10
|
-
* @returns {Object} State store interface
|
|
11
|
-
*/
|
|
12
|
-
export const createStore = (initialState = {}, options = {}) => {
|
|
13
|
-
let state = { ...initialState }
|
|
14
|
-
const emitter = createEmitter()
|
|
15
|
-
const derivedStates = new Map()
|
|
16
|
-
const middleware = options.middleware || []
|
|
17
|
-
|
|
18
|
-
const notifyListeners = (newState, oldState) => {
|
|
19
|
-
emitter.emit('change', newState, oldState)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const applyMiddleware = (newState, oldState) => {
|
|
23
|
-
return middleware.reduce((state, fn) => fn(state, oldState), newState)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return {
|
|
27
|
-
/**
|
|
28
|
-
* Get current state including derived values
|
|
29
|
-
* @returns {T} Current state
|
|
30
|
-
*/
|
|
31
|
-
getState: () => {
|
|
32
|
-
const derivedValues = {}
|
|
33
|
-
derivedStates.forEach((compute, key) => {
|
|
34
|
-
derivedValues[key] = compute(state)
|
|
35
|
-
})
|
|
36
|
-
return { ...state, ...derivedValues }
|
|
37
|
-
},
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Update state
|
|
41
|
-
* @param {Object|Function} update - State update or updater function
|
|
42
|
-
*/
|
|
43
|
-
setState: (update) => {
|
|
44
|
-
const oldState = { ...state }
|
|
45
|
-
const newState = typeof update === 'function'
|
|
46
|
-
? update(state)
|
|
47
|
-
: { ...state, ...update }
|
|
48
|
-
|
|
49
|
-
state = applyMiddleware(newState, oldState)
|
|
50
|
-
notifyListeners(state, oldState)
|
|
51
|
-
},
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Subscribe to state changes
|
|
55
|
-
* @param {Function} listener - Change listener
|
|
56
|
-
* @returns {Function} Unsubscribe function
|
|
57
|
-
*/
|
|
58
|
-
subscribe: (listener) => emitter.on('change', listener),
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Create a derived state value
|
|
62
|
-
* @param {string} key - Derived state key
|
|
63
|
-
* @param {Function} computation - Function to compute derived value
|
|
64
|
-
* @returns {Function} Function to remove derived state
|
|
65
|
-
*/
|
|
66
|
-
derive: (key, computation) => {
|
|
67
|
-
derivedStates.set(key, computation)
|
|
68
|
-
return () => {
|
|
69
|
-
derivedStates.delete(key)
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Select a specific slice of state
|
|
75
|
-
* @param {Function} selector - State selector function
|
|
76
|
-
* @returns {any} Selected state
|
|
77
|
-
*/
|
|
78
|
-
select: (selector) => selector(state),
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Reset state to initial values
|
|
82
|
-
*/
|
|
83
|
-
reset: () => {
|
|
84
|
-
state = { ...initialState }
|
|
85
|
-
notifyListeners(state, null)
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Example middleware
|
|
91
|
-
export const loggingMiddleware = (newState, oldState) => {
|
|
92
|
-
console.log('State change:', {
|
|
93
|
-
old: oldState,
|
|
94
|
-
new: newState,
|
|
95
|
-
diff: Object.keys(newState).reduce((acc, key) => {
|
|
96
|
-
if (newState[key] !== oldState[key]) {
|
|
97
|
-
acc[key] = { from: oldState[key], to: newState[key] }
|
|
98
|
-
}
|
|
99
|
-
return acc
|
|
100
|
-
}, {})
|
|
101
|
-
})
|
|
102
|
-
return newState
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Example derived state
|
|
106
|
-
export const deriveFiltered = (predicate) => (state) =>
|
|
107
|
-
Object.keys(state).reduce((acc, key) => {
|
|
108
|
-
if (predicate(state[key], key)) {
|
|
109
|
-
acc[key] = state[key]
|
|
110
|
-
}
|
|
111
|
-
return acc
|
|
112
|
-
}, {})
|