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
|
@@ -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
|
package/src/core/config.js
DELETED
|
@@ -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
|
-
}
|
package/src/core/dom/classes.js
DELETED
|
@@ -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
|
-
}
|