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