@keenmate/web-multiselect 1.0.0-rc02
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/LICENSE +21 -0
- package/README.md +562 -0
- package/dist/index.d.ts +26 -0
- package/dist/multiselect.d.ts +117 -0
- package/dist/multiselect.js +2231 -0
- package/dist/multiselect.umd.js +46 -0
- package/dist/style.css +1 -0
- package/dist/types.d.ts +187 -0
- package/dist/web-component.d.ts +103 -0
- package/package.json +75 -0
- package/src/scss/_base.scss +41 -0
- package/src/scss/_debug.scss +60 -0
- package/src/scss/_input-dropdown.scss +177 -0
- package/src/scss/_modifiers.scss +95 -0
- package/src/scss/_options.scss +175 -0
- package/src/scss/_pills-display.scss +218 -0
- package/src/scss/_tooltips-popover.scss +114 -0
- package/src/scss/_variables.scss +453 -0
- package/src/scss/main.scss +24 -0
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@keenmate/web-multiselect",
|
|
3
|
+
"version": "1.0.0-rc02",
|
|
4
|
+
"description": "Lightweight multiselect web component with typeahead search, rich content support, and excellent keyboard navigation",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/multiselect.umd.js",
|
|
7
|
+
"module": "./dist/multiselect.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"style": "./dist/style.css",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/multiselect.js",
|
|
14
|
+
"require": "./dist/multiselect.umd.js",
|
|
15
|
+
"default": "./dist/multiselect.js"
|
|
16
|
+
},
|
|
17
|
+
"./style.css": "./dist/style.css",
|
|
18
|
+
"./scss": "./src/scss/_multiselect.scss",
|
|
19
|
+
"./dist/*": "./dist/*",
|
|
20
|
+
"./src/scss/*": "./src/scss/*",
|
|
21
|
+
"./package.json": "./package.json"
|
|
22
|
+
},
|
|
23
|
+
"sideEffects": [
|
|
24
|
+
"./dist/multiselect.js",
|
|
25
|
+
"./dist/multiselect.umd.js",
|
|
26
|
+
"*.css"
|
|
27
|
+
],
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"src/scss"
|
|
31
|
+
],
|
|
32
|
+
"scripts": {
|
|
33
|
+
"dev": "vite",
|
|
34
|
+
"build": "npm run clean:dist && tsc && vite build",
|
|
35
|
+
"build:types": "tsc",
|
|
36
|
+
"build:full": "npm run build",
|
|
37
|
+
"preview": "vite preview",
|
|
38
|
+
"package": "npm run build && npm pack",
|
|
39
|
+
"publish:dry": "npm run build && npm publish --dry-run",
|
|
40
|
+
"clean": "rimraf dist *.tgz",
|
|
41
|
+
"clean:dist": "rimraf dist"
|
|
42
|
+
},
|
|
43
|
+
"keywords": [
|
|
44
|
+
"multiselect",
|
|
45
|
+
"multi-select",
|
|
46
|
+
"select",
|
|
47
|
+
"dropdown",
|
|
48
|
+
"typeahead",
|
|
49
|
+
"autocomplete",
|
|
50
|
+
"web-component",
|
|
51
|
+
"custom-element",
|
|
52
|
+
"search",
|
|
53
|
+
"filter",
|
|
54
|
+
"keenmate"
|
|
55
|
+
],
|
|
56
|
+
"author": "Keenmate",
|
|
57
|
+
"license": "MIT",
|
|
58
|
+
"repository": {
|
|
59
|
+
"type": "git",
|
|
60
|
+
"url": "git+https://github.com/keenmate/web-multiselect.git"
|
|
61
|
+
},
|
|
62
|
+
"homepage": "https://github.com/keenmate/web-multiselect#readme",
|
|
63
|
+
"bugs": {
|
|
64
|
+
"url": "https://github.com/keenmate/web-multiselect/issues"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"rimraf": "^5.0.5",
|
|
68
|
+
"sass-embedded": "^1.93.3",
|
|
69
|
+
"typescript": "^5.3.3",
|
|
70
|
+
"vite": "^5.0.8"
|
|
71
|
+
},
|
|
72
|
+
"dependencies": {
|
|
73
|
+
"@floating-ui/dom": "^1.5.3"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// ==============================================================================
|
|
2
|
+
// BASE STYLES
|
|
3
|
+
// ==============================================================================
|
|
4
|
+
// Foundation styles: FOUC prevention and layout containers
|
|
5
|
+
|
|
6
|
+
@use 'variables' as *;
|
|
7
|
+
|
|
8
|
+
// ==============================================================================
|
|
9
|
+
// FOUC PREVENTION
|
|
10
|
+
// ==============================================================================
|
|
11
|
+
// Prevent Flash of Unstyled Content by hiding undefined custom elements
|
|
12
|
+
// Keep element visible to prevent layout shift, but hide any text content
|
|
13
|
+
multi-select:not(:defined) {
|
|
14
|
+
display: block;
|
|
15
|
+
min-height: 2.5rem;
|
|
16
|
+
color: transparent !important;
|
|
17
|
+
background: transparent;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// ==============================================================================
|
|
21
|
+
// LAYOUT CONTAINERS
|
|
22
|
+
// ==============================================================================
|
|
23
|
+
|
|
24
|
+
// Wrapper (contains multiselect + pills)
|
|
25
|
+
.ml-wrapper {
|
|
26
|
+
display: flex;
|
|
27
|
+
flex-direction: column; // Default: pills above/below input
|
|
28
|
+
align-items: stretch;
|
|
29
|
+
|
|
30
|
+
// Inline layout for left/right positioning
|
|
31
|
+
&--inline {
|
|
32
|
+
flex-direction: row;
|
|
33
|
+
align-items: flex-start;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Main container
|
|
38
|
+
.ml {
|
|
39
|
+
position: relative;
|
|
40
|
+
width: 100%;
|
|
41
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// ==============================================================================
|
|
2
|
+
// DEBUG INFO PANEL
|
|
3
|
+
// ==============================================================================
|
|
4
|
+
// Debug information display for development and troubleshooting
|
|
5
|
+
|
|
6
|
+
@use 'variables' as *;
|
|
7
|
+
|
|
8
|
+
.ml-debug-info {
|
|
9
|
+
margin-top: $ml-spacing-xs;
|
|
10
|
+
padding: $ml-spacing-xs;
|
|
11
|
+
background-color: $ml-color-neutral-lightest;
|
|
12
|
+
border: 1px solid $ml-color-neutral-light;
|
|
13
|
+
border-radius: $ml-border-radius;
|
|
14
|
+
font-size: $ml-font-size-xs;
|
|
15
|
+
color: $ml-color-neutral-darkest;
|
|
16
|
+
|
|
17
|
+
details {
|
|
18
|
+
summary {
|
|
19
|
+
cursor: pointer;
|
|
20
|
+
font-weight: $ml-font-weight-semibold;
|
|
21
|
+
color: $ml-color-accent-dark;
|
|
22
|
+
user-select: none;
|
|
23
|
+
padding: $ml-spacing-xs;
|
|
24
|
+
border-radius: $ml-border-radius-sm;
|
|
25
|
+
|
|
26
|
+
&:hover {
|
|
27
|
+
background-color: $ml-color-neutral-lighter;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
&:focus {
|
|
31
|
+
outline: 2px solid $ml-color-accent-base;
|
|
32
|
+
outline-offset: 2px;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.ml-debug-stats {
|
|
38
|
+
display: flex;
|
|
39
|
+
flex-direction: column;
|
|
40
|
+
gap: $ml-spacing-xs;
|
|
41
|
+
margin-top: $ml-spacing-xs;
|
|
42
|
+
padding: $ml-spacing-xs;
|
|
43
|
+
background-color: $ml-color-white;
|
|
44
|
+
border-radius: $ml-border-radius-sm;
|
|
45
|
+
|
|
46
|
+
span {
|
|
47
|
+
display: flex;
|
|
48
|
+
justify-content: space-between;
|
|
49
|
+
padding: 2px 4px;
|
|
50
|
+
font-family: monospace;
|
|
51
|
+
font-size: $ml-font-size-2xs;
|
|
52
|
+
|
|
53
|
+
&::before {
|
|
54
|
+
content: '•';
|
|
55
|
+
margin-right: $ml-spacing-xs;
|
|
56
|
+
color: $ml-color-accent-base;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
// ==============================================================================
|
|
2
|
+
// INPUT & DROPDOWN COMPONENTS
|
|
3
|
+
// ==============================================================================
|
|
4
|
+
// Input field, toggle icon, count badge, floating hint, dropdown container, and actions
|
|
5
|
+
|
|
6
|
+
@use 'variables' as *;
|
|
7
|
+
|
|
8
|
+
// ==============================================================================
|
|
9
|
+
// INPUT COMPONENT
|
|
10
|
+
// ==============================================================================
|
|
11
|
+
|
|
12
|
+
// Input wrapper
|
|
13
|
+
.ml__input-wrapper {
|
|
14
|
+
position: relative;
|
|
15
|
+
display: flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Search input
|
|
20
|
+
.ml__input {
|
|
21
|
+
width: 100%;
|
|
22
|
+
padding: var(--ml-input-padding, $ml-input-padding);
|
|
23
|
+
padding-right: var(--ml-input-padding-right, $ml-input-padding-right); // Space for dropdown icon
|
|
24
|
+
font-size: var(--ml-input-font-size, $ml-input-font-size);
|
|
25
|
+
border: var(--ml-input-border-style, $ml-input-border-style);
|
|
26
|
+
border-radius: var(--ml-input-border-radius, $ml-input-border-radius);
|
|
27
|
+
background: var(--ml-input-bg, $ml-input-bg);
|
|
28
|
+
color: var(--ml-input-text, $ml-input-text);
|
|
29
|
+
transition: border-color var(--ml-transition-fast, $ml-transition-fast) var(--ml-easing-snappy, $ml-easing-snappy);
|
|
30
|
+
|
|
31
|
+
&:focus {
|
|
32
|
+
outline: none;
|
|
33
|
+
border-color: var(--ml-input-focus-border-color, $ml-input-focus-border-color);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
&::placeholder {
|
|
37
|
+
color: var(--ml-input-placeholder-color, $ml-input-placeholder-color);
|
|
38
|
+
opacity: 0; // Initially hidden until component is ready
|
|
39
|
+
transition: opacity var(--ml-transition-fast, $ml-transition-fast) var(--ml-easing-snappy, $ml-easing-snappy);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Show placeholder only after component is fully initialized
|
|
43
|
+
:host([data-ready]) &::placeholder {
|
|
44
|
+
opacity: var(--ml-placeholder-opacity, $ml-placeholder-opacity);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// ==============================================================================
|
|
49
|
+
// TOGGLE ICON
|
|
50
|
+
// ==============================================================================
|
|
51
|
+
|
|
52
|
+
// Dropdown toggle icon
|
|
53
|
+
.ml__toggle {
|
|
54
|
+
position: absolute;
|
|
55
|
+
right: var(--ml-toggle-right, $ml-toggle-right);
|
|
56
|
+
top: 50%;
|
|
57
|
+
transform: var(--ml-transform-center-y, $ml-transform-center-y);
|
|
58
|
+
pointer-events: none;
|
|
59
|
+
color: var(--ml-toggle-color, $ml-toggle-color);
|
|
60
|
+
transition: transform var(--ml-transition-fast, $ml-transition-fast) var(--ml-easing-snappy, $ml-easing-snappy);
|
|
61
|
+
|
|
62
|
+
.ml--open & {
|
|
63
|
+
transform: var(--ml-transform-center-y, $ml-transform-center-y) rotate(var(--ml-transform-rotate-180, $ml-transform-rotate-180));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ==============================================================================
|
|
68
|
+
// COUNT BADGE (IN INPUT)
|
|
69
|
+
// ==============================================================================
|
|
70
|
+
|
|
71
|
+
// Count badge (appears next to toggle icon)
|
|
72
|
+
.ml__count-badge {
|
|
73
|
+
position: absolute;
|
|
74
|
+
right: var(--ml-count-badge-offset, $ml-count-badge-offset); // Space for toggle icon
|
|
75
|
+
top: 50%;
|
|
76
|
+
transform: var(--ml-transform-center-y, $ml-transform-center-y);
|
|
77
|
+
padding: var(--ml-count-badge-padding, $ml-count-badge-padding);
|
|
78
|
+
background: var(--ml-count-badge-bg, $ml-count-badge-bg);
|
|
79
|
+
color: var(--ml-count-badge-color, $ml-count-badge-color);
|
|
80
|
+
font-size: var(--ml-count-badge-font-size, $ml-count-badge-font-size);
|
|
81
|
+
font-weight: var(--ml-count-badge-font-weight, $ml-count-badge-font-weight);
|
|
82
|
+
border-radius: var(--ml-count-badge-border-radius, $ml-count-badge-border-radius);
|
|
83
|
+
cursor: pointer;
|
|
84
|
+
transition: all var(--ml-transition-fast, $ml-transition-fast) var(--ml-easing-snappy, $ml-easing-snappy);
|
|
85
|
+
|
|
86
|
+
&:hover {
|
|
87
|
+
background: var(--ml-count-badge-bg-hover, $ml-count-badge-bg-hover);
|
|
88
|
+
transform: var(--ml-transform-center-y, $ml-transform-center-y)
|
|
89
|
+
scale(var(--ml-transform-scale-hover, $ml-transform-scale-hover));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// ==============================================================================
|
|
94
|
+
// FLOATING HINT
|
|
95
|
+
// ==============================================================================
|
|
96
|
+
|
|
97
|
+
// Floating search hint (appears above input)
|
|
98
|
+
.ml__hint {
|
|
99
|
+
display: none;
|
|
100
|
+
position: absolute;
|
|
101
|
+
z-index: var(--ml-z-index-popover, $ml-z-index-popover);
|
|
102
|
+
padding: var(--ml-hint-padding, $ml-hint-padding);
|
|
103
|
+
background: var(--ml-hint-bg, $ml-hint-bg);
|
|
104
|
+
border: var(--ml-hint-border, $ml-hint-border);
|
|
105
|
+
border-radius: var(--ml-hint-border-radius, $ml-hint-border-radius);
|
|
106
|
+
box-shadow: var(--ml-hint-box-shadow, $ml-hint-box-shadow);
|
|
107
|
+
font-size: var(--ml-hint-font-size, $ml-hint-font-size);
|
|
108
|
+
color: var(--ml-hint-color, $ml-hint-color);
|
|
109
|
+
line-height: var(--ml-line-height-relaxed, $ml-line-height-relaxed);
|
|
110
|
+
max-width: 100%;
|
|
111
|
+
|
|
112
|
+
&--visible {
|
|
113
|
+
display: block;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// ==============================================================================
|
|
118
|
+
// DROPDOWN CONTAINER
|
|
119
|
+
// ==============================================================================
|
|
120
|
+
|
|
121
|
+
// Floating dropdown (appears below input)
|
|
122
|
+
.ml__dropdown {
|
|
123
|
+
display: none;
|
|
124
|
+
position: absolute;
|
|
125
|
+
z-index: var(--ml-z-index-dropdown, $ml-z-index-dropdown);
|
|
126
|
+
background: var(--ml-dropdown-bg, $ml-dropdown-bg);
|
|
127
|
+
border: var(--ml-dropdown-border, $ml-dropdown-border);
|
|
128
|
+
border-radius: var(--ml-dropdown-border-radius, $ml-dropdown-border-radius);
|
|
129
|
+
box-shadow: var(--ml-dropdown-box-shadow, $ml-dropdown-box-shadow);
|
|
130
|
+
max-height: var(--ml-dropdown-max-height, $ml-dropdown-max-height);
|
|
131
|
+
overflow-y: auto;
|
|
132
|
+
color: var(--ml-dropdown-color, $ml-dropdown-color);
|
|
133
|
+
|
|
134
|
+
&--visible {
|
|
135
|
+
display: block;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// ==============================================================================
|
|
140
|
+
// DROPDOWN ACTIONS
|
|
141
|
+
// ==============================================================================
|
|
142
|
+
|
|
143
|
+
// Dropdown actions (Select All / Clear All)
|
|
144
|
+
.ml__actions {
|
|
145
|
+
display: flex;
|
|
146
|
+
gap: var(--ml-actions-gap, $ml-actions-gap);
|
|
147
|
+
padding: var(--ml-actions-padding, $ml-actions-padding);
|
|
148
|
+
border-bottom: var(--ml-actions-border-bottom, $ml-actions-border-bottom);
|
|
149
|
+
|
|
150
|
+
&--sticky {
|
|
151
|
+
position: sticky;
|
|
152
|
+
top: 0;
|
|
153
|
+
z-index: var(--ml-z-index-sticky, $ml-z-index-sticky);
|
|
154
|
+
background: var(--ml-actions-bg, $ml-actions-bg);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.ml__action-btn {
|
|
159
|
+
flex: 1;
|
|
160
|
+
padding: var(--ml-action-btn-padding, $ml-action-btn-padding);
|
|
161
|
+
font-size: var(--ml-action-btn-font-size, $ml-action-btn-font-size);
|
|
162
|
+
border: var(--ml-action-btn-border, $ml-action-btn-border);
|
|
163
|
+
border-radius: var(--ml-action-btn-border-radius, $ml-action-btn-border-radius);
|
|
164
|
+
background: var(--ml-action-btn-bg, $ml-action-btn-bg);
|
|
165
|
+
color: var(--ml-action-btn-color, $ml-action-btn-color);
|
|
166
|
+
cursor: pointer;
|
|
167
|
+
transition: all var(--ml-transition-fast, $ml-transition-fast) var(--ml-easing-snappy, $ml-easing-snappy);
|
|
168
|
+
|
|
169
|
+
&:hover {
|
|
170
|
+
background: var(--ml-action-btn-bg-hover, $ml-action-btn-bg-hover);
|
|
171
|
+
border-color: var(--ml-action-btn-border-color-hover, $ml-action-btn-border-color-hover);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
&:active {
|
|
175
|
+
transform: scale(var(--ml-transform-scale-active, $ml-transform-scale-active));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// ==============================================================================
|
|
2
|
+
// MODIFIERS & VARIANTS
|
|
3
|
+
// ==============================================================================
|
|
4
|
+
// Size variants (xs, sm, lg, xl) and state modifiers (disabled, no-checkboxes)
|
|
5
|
+
|
|
6
|
+
@use 'variables' as *;
|
|
7
|
+
|
|
8
|
+
// ==============================================================================
|
|
9
|
+
// SIZE VARIANTS
|
|
10
|
+
// ==============================================================================
|
|
11
|
+
|
|
12
|
+
.ml--xs {
|
|
13
|
+
.ml__input {
|
|
14
|
+
font-size: var(--ml-font-size-xs, $ml-font-size-xs);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.ml__option {
|
|
18
|
+
padding: var(--ml-spacing-xs, $ml-spacing-xs) var(--ml-spacing-sm, $ml-spacing-sm);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.ml__option-title {
|
|
22
|
+
font-size: var(--ml-font-size-xs, $ml-font-size-xs);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.ml__pill {
|
|
26
|
+
font-size: var(--ml-font-size-2xs, $ml-font-size-2xs);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.ml--sm {
|
|
31
|
+
.ml__input {
|
|
32
|
+
font-size: var(--ml-font-size-xs, $ml-font-size-xs);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.ml__option-title {
|
|
36
|
+
font-size: var(--ml-font-size-xs, $ml-font-size-xs);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.ml--lg {
|
|
41
|
+
.ml__input {
|
|
42
|
+
font-size: var(--ml-font-size-base, $ml-font-size-base);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.ml__option-title {
|
|
46
|
+
font-size: var(--ml-font-size-base, $ml-font-size-base);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.ml__pill {
|
|
50
|
+
font-size: var(--ml-font-size-sm, $ml-font-size-sm);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.ml--xl {
|
|
55
|
+
.ml__input {
|
|
56
|
+
font-size: var(--ml-font-size-lg, $ml-font-size-lg);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.ml__option-title {
|
|
60
|
+
font-size: var(--ml-font-size-lg, $ml-font-size-lg);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.ml__pill {
|
|
64
|
+
font-size: var(--ml-font-size-base, $ml-font-size-base);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// ==============================================================================
|
|
69
|
+
// STATE MODIFIERS
|
|
70
|
+
// ==============================================================================
|
|
71
|
+
|
|
72
|
+
// Disabled state
|
|
73
|
+
.ml--disabled {
|
|
74
|
+
.ml__input {
|
|
75
|
+
opacity: var(--ml-disabled-input-opacity, $ml-disabled-input-opacity);
|
|
76
|
+
cursor: not-allowed;
|
|
77
|
+
background: var(--ml-input-bg-disabled, $ml-input-bg-disabled);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.ml__toggle {
|
|
81
|
+
opacity: var(--ml-disabled-input-opacity, $ml-disabled-input-opacity);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// No checkboxes modifier (for simple select mode)
|
|
86
|
+
.ml--no-checkboxes {
|
|
87
|
+
.ml__option {
|
|
88
|
+
gap: 0; // Remove gap since there's no checkbox
|
|
89
|
+
padding-left: var(--ml-option-padding-h, $ml-option-padding-h); // Adjust padding
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.ml__option-content {
|
|
93
|
+
padding-left: 0; // No extra padding needed
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
// ==============================================================================
|
|
2
|
+
// OPTIONS & CONTENT
|
|
3
|
+
// ==============================================================================
|
|
4
|
+
// Options list, groups, checkbox, option content, icons, text, and states
|
|
5
|
+
|
|
6
|
+
@use 'variables' as *;
|
|
7
|
+
|
|
8
|
+
// ==============================================================================
|
|
9
|
+
// OPTIONS CONTAINER
|
|
10
|
+
// ==============================================================================
|
|
11
|
+
|
|
12
|
+
// Options container
|
|
13
|
+
.ml__options {
|
|
14
|
+
padding: var(--ml-options-padding, $ml-options-padding);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// ==============================================================================
|
|
18
|
+
// GROUPS
|
|
19
|
+
// ==============================================================================
|
|
20
|
+
|
|
21
|
+
// Group
|
|
22
|
+
.ml__group {
|
|
23
|
+
& + & {
|
|
24
|
+
border-top: var(--ml-group-border-top, $ml-group-border-top);
|
|
25
|
+
margin-top: var(--ml-group-margin-top, $ml-group-margin-top);
|
|
26
|
+
padding-top: var(--ml-group-padding-top, $ml-group-padding-top);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Group label
|
|
31
|
+
.ml__group-label {
|
|
32
|
+
padding: var(--ml-group-label-padding, $ml-group-label-padding);
|
|
33
|
+
font-size: var(--ml-group-label-font-size, $ml-group-label-font-size);
|
|
34
|
+
font-weight: var(--ml-group-label-font-weight, $ml-group-label-font-weight);
|
|
35
|
+
color: var(--ml-group-label-color, $ml-group-label-color);
|
|
36
|
+
text-transform: var(--ml-group-label-transform, $ml-group-label-transform);
|
|
37
|
+
letter-spacing: var(--ml-group-label-letter-spacing, $ml-group-label-letter-spacing);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// ==============================================================================
|
|
41
|
+
// INDIVIDUAL OPTION
|
|
42
|
+
// ==============================================================================
|
|
43
|
+
|
|
44
|
+
// Individual option
|
|
45
|
+
.ml__option {
|
|
46
|
+
display: flex;
|
|
47
|
+
align-items: flex-start;
|
|
48
|
+
gap: var(--ml-option-gap, $ml-option-gap);
|
|
49
|
+
padding: var(--ml-option-padding, $ml-option-padding);
|
|
50
|
+
cursor: pointer;
|
|
51
|
+
transition: background-color var(--ml-transition-fast, $ml-transition-fast) var(--ml-easing-snappy, $ml-easing-snappy);
|
|
52
|
+
|
|
53
|
+
&:hover {
|
|
54
|
+
background: var(--ml-option-bg-hover, $ml-option-bg-hover);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
&--focused {
|
|
58
|
+
background: var(--ml-option-bg-focused, $ml-option-bg-focused);
|
|
59
|
+
outline: var(--ml-option-outline-focused, $ml-option-outline-focused);
|
|
60
|
+
outline-offset: var(--ml-option-focus-outline-offset, $ml-option-focus-outline-offset);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
&--selected {
|
|
64
|
+
background: var(--ml-option-bg-selected, $ml-option-bg-selected);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
&--disabled {
|
|
68
|
+
opacity: var(--ml-disabled-opacity, $ml-disabled-opacity);
|
|
69
|
+
cursor: not-allowed;
|
|
70
|
+
|
|
71
|
+
&:hover {
|
|
72
|
+
background: var(--ml-option-bg, $ml-option-bg);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ==============================================================================
|
|
78
|
+
// CHECKBOX
|
|
79
|
+
// ==============================================================================
|
|
80
|
+
|
|
81
|
+
// Checkbox
|
|
82
|
+
.ml__checkbox {
|
|
83
|
+
flex-shrink: 0;
|
|
84
|
+
margin-top: var(--ml-checkbox-margin-top, $ml-checkbox-margin-top); // Align with first line of text
|
|
85
|
+
cursor: pointer;
|
|
86
|
+
|
|
87
|
+
.ml__option--disabled & {
|
|
88
|
+
cursor: not-allowed;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// ==============================================================================
|
|
93
|
+
// OPTION CONTENT
|
|
94
|
+
// ==============================================================================
|
|
95
|
+
|
|
96
|
+
// Option content (rich content wrapper)
|
|
97
|
+
.ml__option-content {
|
|
98
|
+
flex: 1;
|
|
99
|
+
display: flex;
|
|
100
|
+
align-items: flex-start;
|
|
101
|
+
gap: var(--ml-option-content-gap, $ml-option-content-gap);
|
|
102
|
+
min-width: 0; // Allow text truncation
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Option icon/SVG
|
|
106
|
+
.ml__option-icon {
|
|
107
|
+
flex-shrink: 0;
|
|
108
|
+
width: var(--ml-option-icon-size, $ml-option-icon-size);
|
|
109
|
+
height: var(--ml-option-icon-size, $ml-option-icon-size);
|
|
110
|
+
display: flex;
|
|
111
|
+
align-items: center;
|
|
112
|
+
justify-content: center;
|
|
113
|
+
font-size: var(--ml-option-icon-font-size, $ml-option-icon-font-size);
|
|
114
|
+
|
|
115
|
+
svg {
|
|
116
|
+
width: 100%;
|
|
117
|
+
height: 100%;
|
|
118
|
+
fill: currentColor;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Option text container
|
|
123
|
+
.ml__option-text {
|
|
124
|
+
flex: 1;
|
|
125
|
+
min-width: 0;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Option title/main text
|
|
129
|
+
.ml__option-title {
|
|
130
|
+
font-size: var(--ml-option-title-font-size, $ml-option-title-font-size);
|
|
131
|
+
color: var(--ml-option-title-color, $ml-option-title-color);
|
|
132
|
+
line-height: var(--ml-line-height-relaxed, $ml-line-height-relaxed);
|
|
133
|
+
|
|
134
|
+
// Highlight matched text
|
|
135
|
+
mark {
|
|
136
|
+
background: var(--ml-option-mark-bg, $ml-option-mark-bg);
|
|
137
|
+
color: var(--ml-option-mark-color, $ml-option-mark-color);
|
|
138
|
+
font-weight: var(--ml-option-mark-font-weight, $ml-option-mark-font-weight);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Option subtitle (multiline support)
|
|
143
|
+
.ml__option-subtitle {
|
|
144
|
+
margin-top: var(--ml-option-subtitle-margin-top, $ml-option-subtitle-margin-top);
|
|
145
|
+
font-size: var(--ml-option-subtitle-font-size, $ml-option-subtitle-font-size);
|
|
146
|
+
color: var(--ml-option-subtitle-color, $ml-option-subtitle-color);
|
|
147
|
+
line-height: var(--ml-option-subtitle-line-height, $ml-option-subtitle-line-height);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// ==============================================================================
|
|
151
|
+
// STATES
|
|
152
|
+
// ==============================================================================
|
|
153
|
+
|
|
154
|
+
// Empty state
|
|
155
|
+
.ml__empty {
|
|
156
|
+
padding: var(--ml-empty-padding, $ml-empty-padding);
|
|
157
|
+
text-align: center;
|
|
158
|
+
font-size: var(--ml-empty-font-size, $ml-empty-font-size);
|
|
159
|
+
color: var(--ml-empty-color, $ml-empty-color);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Loading state
|
|
163
|
+
.ml__loader {
|
|
164
|
+
display: flex;
|
|
165
|
+
flex-direction: column;
|
|
166
|
+
align-items: center;
|
|
167
|
+
justify-content: center;
|
|
168
|
+
padding: var(--ml-loader-padding, $ml-loader-padding);
|
|
169
|
+
gap: var(--ml-loader-gap, $ml-loader-gap);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.ml__loading-text {
|
|
173
|
+
font-size: var(--ml-loading-text-font-size, $ml-loading-text-font-size);
|
|
174
|
+
color: var(--ml-loading-text-color, $ml-loading-text-color);
|
|
175
|
+
}
|