@keenmate/pure-admin-core 1.0.0-rc01
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 +172 -0
- package/dist/css/main.css +11542 -0
- package/dist/fonts/Delivery/Delivery_W_Bd.woff2 +0 -0
- package/dist/fonts/Delivery/Delivery_W_BdIt.woff2 +0 -0
- package/dist/fonts/Delivery/Delivery_W_CdBlk.woff2 +0 -0
- package/dist/fonts/Delivery/Delivery_W_CdLt.woff2 +0 -0
- package/dist/fonts/Delivery/Delivery_W_It.woff2 +0 -0
- package/dist/fonts/Delivery/Delivery_W_Lt.woff2 +0 -0
- package/dist/fonts/Delivery/Delivery_W_LtIt.woff2 +0 -0
- package/dist/fonts/Delivery/Delivery_W_Rg.woff2 +0 -0
- package/dist/fonts/google/3y976aknfjLm_3lMKjiMgmUUYBs04Y8UH-qVHQ.woff2 +0 -0
- package/dist/fonts/google/3y976aknfjLm_3lMKjiMgmUUYBs04Y8UH-qVHQ.woff2.1 +0 -0
- package/dist/fonts/google/3y976aknfjLm_3lMKjiMgmUUYBs04Y8UH-qVHQ.woff2.2 +0 -0
- package/dist/fonts/google/3y976aknfjLm_3lMKjiMgmUUYBs04Y8VH-qVHQ.woff2 +0 -0
- package/dist/fonts/google/3y976aknfjLm_3lMKjiMgmUUYBs04Y8VH-qVHQ.woff2.1 +0 -0
- package/dist/fonts/google/3y976aknfjLm_3lMKjiMgmUUYBs04Y8VH-qVHQ.woff2.2 +0 -0
- package/dist/fonts/google/3y976aknfjLm_3lMKjiMgmUUYBs04Y8bH-o.woff2 +0 -0
- package/dist/fonts/google/3y976aknfjLm_3lMKjiMgmUUYBs04Y8bH-o.woff2.1 +0 -0
- package/dist/fonts/google/3y976aknfjLm_3lMKjiMgmUUYBs04Y8fH-qVHQ.woff2 +0 -0
- package/dist/fonts/google/3y976aknfjLm_3lMKjiMgmUUYBs04Y8fH-qVHQ.woff2.1 +0 -0
- package/dist/fonts/google/3y976aknfjLm_3lMKjiMgmUUYBs04Y8fH-qVHQ.woff2.2 +0 -0
- package/dist/fonts/google/6aez4K2oVqwIvtE2H68T.woff2 +0 -0
- package/dist/fonts/google/6aez4K2oVqwIvtU2Hw.woff2 +0 -0
- package/dist/fonts/google/6aez4K2oVqwIvtY2H68T.woff2 +0 -0
- package/dist/fonts/google/6aez4K2oVqwIvtg2H68T.woff2 +0 -0
- package/dist/fonts/google/6aez4K2oVqwIvto2H68T.woff2 +0 -0
- package/dist/fonts/google/6aez4K2oVqwIvts2H68T.woff2 +0 -0
- package/dist/fonts/google/7Auup_AqnyWWAxW2Wk3swUz56MS91Eww8SX21nejog.woff2 +0 -0
- package/dist/fonts/google/7Auup_AqnyWWAxW2Wk3swUz56MS91Eww8SX21nijogp5.woff2 +0 -0
- package/dist/fonts/google/7Auup_AqnyWWAxW2Wk3swUz56MS91Eww8SX21nmjogp5.woff2 +0 -0
- package/dist/fonts/google/PN_xRfK9oXHga0XdZ8g_vT0.woff2 +0 -0
- package/dist/fonts/google/PN_xRfK9oXHga0XdZsg_.woff2 +0 -0
- package/dist/fonts/google/PN_xRfK9oXHga0XdaMg_vT0.woff2 +0 -0
- package/dist/fonts/google/TK3tWkYFABsmjsphPho.woff2 +0 -0
- package/dist/fonts/google/TK3tWkYFABsmjspuPho7vA.woff2 +0 -0
- package/dist/fonts/google/TK3tWkYFABsmjspvPho7vA.woff2 +0 -0
- package/dist/fonts/google/dg45_pLmvrkcOkBnKsOzXyGWTBcmg-X6VjTYJwQj.woff2 +0 -0
- package/dist/fonts/google/dg45_pLmvrkcOkBnKsOzXyGWTBcmg-X6VjXYJwQj.woff2 +0 -0
- package/dist/fonts/google/dg45_pLmvrkcOkBnKsOzXyGWTBcmg-X6Vj_YJwQj.woff2 +0 -0
- package/dist/fonts/google/dg45_pLmvrkcOkBnKsOzXyGWTBcmg-X6VjbYJwQj.woff2 +0 -0
- package/dist/fonts/google/dg45_pLmvrkcOkBnKsOzXyGWTBcmg-X6VjvYJw.woff2 +0 -0
- package/dist/fonts/google/fonts-tracklist.txt +48 -0
- package/dist/fonts/google/vEFO2_JTCgwQ5ejvMV0O96D01E8J0tJXHKbBjM4.woff2 +0 -0
- package/dist/fonts/google/vEFO2_JTCgwQ5ejvMV0O96D01E8J0tJXHKbOjM7sfA.woff2 +0 -0
- package/dist/fonts/google/vEFO2_JTCgwQ5ejvMV0O96D01E8J0tJXHKbPjM7sfA.woff2 +0 -0
- package/dist/fonts/google/wEOhEADFm8hSaQTFG18FErVhsC9x-tarUfLtrftV.woff2 +0 -0
- package/dist/fonts/google/wEOhEADFm8hSaQTFG18FErVhsC9x-tarUfXtrftV.woff2 +0 -0
- package/dist/fonts/google/wEOhEADFm8hSaQTFG18FErVhsC9x-tarUfbtrQ.woff2 +0 -0
- package/dist/fonts/google/wEOhEADFm8hSaQTFG18FErVhsC9x-tarUfjtrftV.woff2 +0 -0
- package/dist/fonts/google/wEOhEADFm8hSaQTFG18FErVhsC9x-tarUfntrftV.woff2 +0 -0
- package/dist/fonts/google/wEOhEADFm8hSaQTFG18FErVhsC9x-tarUfrtrftV.woff2 +0 -0
- package/dist/fonts/google/wEOhEADFm8hSaQTFG18FErVhsC9x-tarUfvtrftV.woff2 +0 -0
- package/dist/fonts/google/xn7_YHE41ni1AdIRqAuZuw1Bx9mbZk79FN_B-bnBeA.woff2 +0 -0
- package/dist/fonts/google/xn7_YHE41ni1AdIRqAuZuw1Bx9mbZk79FN_C-bk.woff2 +0 -0
- package/dist/fonts/google/xn7_YHE41ni1AdIRqAuZuw1Bx9mbZk79FN_G-bnBeA.woff2 +0 -0
- package/dist/fonts/google/xn7_YHE41ni1AdIRqAuZuw1Bx9mbZk79FN_M-bnBeA.woff2 +0 -0
- package/dist/fonts/google/xn7_YHE41ni1AdIRqAuZuw1Bx9mbZk79FN_N-bnBeA.woff2 +0 -0
- package/dist/fonts/google/xn7_YHE41ni1AdIRqAuZuw1Bx9mbZk79FN_P-bnBeA.woff2 +0 -0
- package/package.json +60 -0
- package/snippets/alerts.html +281 -0
- package/snippets/badges.html +212 -0
- package/snippets/buttons.html +287 -0
- package/snippets/cards.html +393 -0
- package/snippets/checkbox-lists.html +490 -0
- package/snippets/code.html +225 -0
- package/snippets/command-palette.html +210 -0
- package/snippets/comparison.html +428 -0
- package/snippets/customization.html +142 -0
- package/snippets/forms.html +477 -0
- package/snippets/grid.html +338 -0
- package/snippets/layout.html +598 -0
- package/snippets/lists.html +232 -0
- package/snippets/loaders.html +183 -0
- package/snippets/manifest.json +388 -0
- package/snippets/modal-dialogs.html +411 -0
- package/snippets/modals.html +310 -0
- package/snippets/popconfirm.html +253 -0
- package/snippets/profile.html +264 -0
- package/snippets/tables.html +317 -0
- package/snippets/tabs.html +930 -0
- package/snippets/timeline.html +364 -0
- package/snippets/toasts.html +154 -0
- package/snippets/tooltips.html +411 -0
- package/snippets/typography.html +101 -0
- package/snippets/utilities.html +595 -0
- package/snippets/virtual-scroll.html +322 -0
- package/snippets/web-daterangepicker.html +634 -0
- package/snippets/web-multiselect.html +362 -0
- package/src/scss/.claude/settings.local.json +11 -0
- package/src/scss/_base-css-variables.scss +348 -0
- package/src/scss/_core.scss +99 -0
- package/src/scss/_fonts.scss +67 -0
- package/src/scss/_purecss-grid-responsive.scss +138 -0
- package/src/scss/_purecss-grid.scss +58 -0
- package/src/scss/_variables.scss +14 -0
- package/src/scss/core-components/_alerts.scss +212 -0
- package/src/scss/core-components/_badges.scss +16 -0
- package/src/scss/core-components/_base.scss +124 -0
- package/src/scss/core-components/_buttons.scss +473 -0
- package/src/scss/core-components/_cards.scss +285 -0
- package/src/scss/core-components/_checkbox-lists.scss +289 -0
- package/src/scss/core-components/_code.scss +141 -0
- package/src/scss/core-components/_command-palette.scss +518 -0
- package/src/scss/core-components/_comparison.scss +172 -0
- package/src/scss/core-components/_file-selector.scss +780 -0
- package/src/scss/core-components/_forms.scss +16 -0
- package/src/scss/core-components/_grid.scss +264 -0
- package/src/scss/core-components/_layout.scss +15 -0
- package/src/scss/core-components/_lists.scss +211 -0
- package/src/scss/core-components/_loaders.scss +277 -0
- package/src/scss/core-components/_logic-tree.scss +280 -0
- package/src/scss/core-components/_modals.scss +209 -0
- package/src/scss/core-components/_notifications.scss +253 -0
- package/src/scss/core-components/_pagers.scss +141 -0
- package/src/scss/core-components/_popconfirm.scss +170 -0
- package/src/scss/core-components/_profile.scss +281 -0
- package/src/scss/core-components/_settings-panel.scss +128 -0
- package/src/scss/core-components/_statistics.scss +200 -0
- package/src/scss/core-components/_tables.scss +555 -0
- package/src/scss/core-components/_tabs.scss +438 -0
- package/src/scss/core-components/_timeline.scss +589 -0
- package/src/scss/core-components/_toasts.scss +281 -0
- package/src/scss/core-components/_tooltips.scss +503 -0
- package/src/scss/core-components/_utilities.scss +241 -0
- package/src/scss/core-components/_web-components-theme.scss +294 -0
- package/src/scss/core-components/badges/_badge-base.scss +131 -0
- package/src/scss/core-components/badges/_badge-group.scss +25 -0
- package/src/scss/core-components/badges/_composite-badge-variants.scss +396 -0
- package/src/scss/core-components/badges/_composite-badge.scss +70 -0
- package/src/scss/core-components/badges/_index.scss +10 -0
- package/src/scss/core-components/badges/_labels.scss +155 -0
- package/src/scss/core-components/forms/_checkboxes-radios.scss +205 -0
- package/src/scss/core-components/forms/_form-inputs.scss +100 -0
- package/src/scss/core-components/forms/_form-layout.scss +66 -0
- package/src/scss/core-components/forms/_form-states.scss +89 -0
- package/src/scss/core-components/forms/_index.scss +12 -0
- package/src/scss/core-components/forms/_input-groups.scss +149 -0
- package/src/scss/core-components/forms/_input-wrapper.scss +89 -0
- package/src/scss/core-components/forms/_query-editor.scss +313 -0
- package/src/scss/core-components/layout/_index.scss +11 -0
- package/src/scss/core-components/layout/_layout-container.scss +105 -0
- package/src/scss/core-components/layout/_layout-responsive.scss +100 -0
- package/src/scss/core-components/layout/_navbar-elements.scss +238 -0
- package/src/scss/core-components/layout/_navbar.scss +71 -0
- package/src/scss/core-components/layout/_sidebar-states.scss +228 -0
- package/src/scss/core-components/layout/_sidebar.scss +177 -0
- package/src/scss/main.scss +7 -0
- package/src/scss/themes/_dark-base.scss +207 -0
- package/src/scss/themes/audi-light.scss +311 -0
- package/src/scss/themes/audi.scss +288 -0
- package/src/scss/themes/corporate.scss +203 -0
- package/src/scss/themes/dark-blue.scss +152 -0
- package/src/scss/themes/dark-green.scss +156 -0
- package/src/scss/themes/dark-red.scss +160 -0
- package/src/scss/themes/dark.scss +145 -0
- package/src/scss/themes/express.scss +281 -0
- package/src/scss/themes/minimal.scss +121 -0
- package/src/scss/utilities.scss +481 -0
- package/src/scss/variables/_base.scss +81 -0
- package/src/scss/variables/_colors.scss +148 -0
- package/src/scss/variables/_components.scss +509 -0
- package/src/scss/variables/_index.scss +13 -0
- package/src/scss/variables/_layout.scss +65 -0
- package/src/scss/variables/_spacing.scss +66 -0
- package/src/scss/variables/_system.scss +80 -0
- package/src/scss/variables/_typography.scss +37 -0
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
<!-- Web Multiselect Component
|
|
2
|
+
Advanced multiselect web component from @keenmate/web-multiselect
|
|
3
|
+
Framework-agnostic, TypeScript-based web component with excellent performance
|
|
4
|
+
Repository: https://github.com/keenmate/web-multiselect
|
|
5
|
+
Package: npm install @keenmate/web-multiselect
|
|
6
|
+
-->
|
|
7
|
+
|
|
8
|
+
<!-- ========================================
|
|
9
|
+
BASIC USAGE
|
|
10
|
+
======================================== -->
|
|
11
|
+
|
|
12
|
+
<!-- Declarative (No JavaScript Needed) -->
|
|
13
|
+
<web-multiselect placeholder="Select options...">
|
|
14
|
+
<option value="js" selected>JavaScript</option>
|
|
15
|
+
<option value="ts">TypeScript</option>
|
|
16
|
+
<option value="python">Python</option>
|
|
17
|
+
<option value="java">Java</option>
|
|
18
|
+
</web-multiselect>
|
|
19
|
+
|
|
20
|
+
<!-- Single Select Mode -->
|
|
21
|
+
<web-multiselect placeholder="Select one..." multiple="false">
|
|
22
|
+
<option value="opt1">Option 1</option>
|
|
23
|
+
<option value="opt2" selected>Option 2</option>
|
|
24
|
+
<option value="opt3">Option 3</option>
|
|
25
|
+
</web-multiselect>
|
|
26
|
+
|
|
27
|
+
<!-- ========================================
|
|
28
|
+
DISPLAY MODES
|
|
29
|
+
======================================== -->
|
|
30
|
+
|
|
31
|
+
<!-- Pills Mode (Default) - Individual badges -->
|
|
32
|
+
<web-multiselect badges-display-mode="pills" placeholder="Select...">
|
|
33
|
+
<option value="1" selected>Option 1</option>
|
|
34
|
+
<option value="2" selected>Option 2</option>
|
|
35
|
+
</web-multiselect>
|
|
36
|
+
|
|
37
|
+
<!-- Count Mode - "X selected" counter -->
|
|
38
|
+
<web-multiselect badges-display-mode="count" placeholder="Select...">
|
|
39
|
+
<option value="1" selected>Option 1</option>
|
|
40
|
+
<option value="2" selected>Option 2</option>
|
|
41
|
+
</web-multiselect>
|
|
42
|
+
|
|
43
|
+
<!-- Compact Mode - First item + "+X more" -->
|
|
44
|
+
<web-multiselect badges-display-mode="compact" placeholder="Select...">
|
|
45
|
+
<option value="1" selected>First</option>
|
|
46
|
+
<option value="2" selected>Second</option>
|
|
47
|
+
<option value="3" selected>Third</option>
|
|
48
|
+
</web-multiselect>
|
|
49
|
+
|
|
50
|
+
<!-- Partial Mode - Limited badges + "+X more" -->
|
|
51
|
+
<web-multiselect badges-display-mode="partial" placeholder="Select...">
|
|
52
|
+
<option value="1" selected>Alpha</option>
|
|
53
|
+
<option value="2" selected>Beta</option>
|
|
54
|
+
<option value="3" selected>Gamma</option>
|
|
55
|
+
</web-multiselect>
|
|
56
|
+
|
|
57
|
+
<!-- None Mode - Minimal UI, no badges -->
|
|
58
|
+
<web-multiselect badges-display-mode="none" placeholder="Select...">
|
|
59
|
+
<option value="1" selected>Option A</option>
|
|
60
|
+
<option value="2" selected>Option B</option>
|
|
61
|
+
</web-multiselect>
|
|
62
|
+
|
|
63
|
+
<!-- ========================================
|
|
64
|
+
SEARCH & FILTER
|
|
65
|
+
======================================== -->
|
|
66
|
+
|
|
67
|
+
<!-- Search Mode: Filter (hides non-matching) -->
|
|
68
|
+
<web-multiselect search-enabled="true" search-mode="filter" placeholder="Search...">
|
|
69
|
+
<option value="apple">Apple</option>
|
|
70
|
+
<option value="banana">Banana</option>
|
|
71
|
+
<option value="cherry">Cherry</option>
|
|
72
|
+
</web-multiselect>
|
|
73
|
+
|
|
74
|
+
<!-- Search Mode: Navigate (jumps to matches, keeps all visible) -->
|
|
75
|
+
<web-multiselect search-enabled="true" search-mode="navigate" placeholder="Search...">
|
|
76
|
+
<option value="argentina">Argentina</option>
|
|
77
|
+
<option value="brazil">Brazil</option>
|
|
78
|
+
<option value="canada">Canada</option>
|
|
79
|
+
</web-multiselect>
|
|
80
|
+
|
|
81
|
+
<!-- ========================================
|
|
82
|
+
GROUPED OPTIONS
|
|
83
|
+
======================================== -->
|
|
84
|
+
|
|
85
|
+
<web-multiselect placeholder="Select technologies...">
|
|
86
|
+
<optgroup label="Frontend">
|
|
87
|
+
<option value="react">React</option>
|
|
88
|
+
<option value="vue">Vue</option>
|
|
89
|
+
<option value="angular">Angular</option>
|
|
90
|
+
</optgroup>
|
|
91
|
+
<optgroup label="Backend">
|
|
92
|
+
<option value="nodejs">Node.js</option>
|
|
93
|
+
<option value="django">Django</option>
|
|
94
|
+
<option value="laravel">Laravel</option>
|
|
95
|
+
</optgroup>
|
|
96
|
+
</web-multiselect>
|
|
97
|
+
|
|
98
|
+
<!-- ========================================
|
|
99
|
+
DISABLED OPTIONS
|
|
100
|
+
======================================== -->
|
|
101
|
+
|
|
102
|
+
<web-multiselect placeholder="Some options disabled...">
|
|
103
|
+
<option value="enabled1">Available Option</option>
|
|
104
|
+
<option value="disabled1" disabled>Unavailable Option</option>
|
|
105
|
+
<option value="enabled2">Available Option 2</option>
|
|
106
|
+
</web-multiselect>
|
|
107
|
+
|
|
108
|
+
<!-- ========================================
|
|
109
|
+
VIRTUAL SCROLLING (Large Datasets)
|
|
110
|
+
======================================== -->
|
|
111
|
+
|
|
112
|
+
<web-multiselect id="large-dataset" search-enabled="true" placeholder="Search 10,000 items...">
|
|
113
|
+
<!-- Options added via JavaScript for large datasets -->
|
|
114
|
+
</web-multiselect>
|
|
115
|
+
|
|
116
|
+
<script>
|
|
117
|
+
// Populate large dataset
|
|
118
|
+
const select = document.getElementById('large-dataset');
|
|
119
|
+
for (let i = 1; i <= 10000; i++) {
|
|
120
|
+
const option = document.createElement('option');
|
|
121
|
+
option.value = `item${i}`;
|
|
122
|
+
option.textContent = `Item ${i}`;
|
|
123
|
+
select.appendChild(option);
|
|
124
|
+
}
|
|
125
|
+
</script>
|
|
126
|
+
|
|
127
|
+
<!-- ========================================
|
|
128
|
+
RTL (RIGHT-TO-LEFT) SUPPORT
|
|
129
|
+
======================================== -->
|
|
130
|
+
|
|
131
|
+
<!-- Arabic -->
|
|
132
|
+
<web-multiselect placeholder="اختر خيارات..." dir="rtl" badges-position="right">
|
|
133
|
+
<option value="1">الخيار الأول</option>
|
|
134
|
+
<option value="2">الخيار الثاني</option>
|
|
135
|
+
<option value="3">الخيار الثالث</option>
|
|
136
|
+
</web-multiselect>
|
|
137
|
+
|
|
138
|
+
<!-- Hebrew -->
|
|
139
|
+
<web-multiselect placeholder="בחר אפשרויות..." dir="rtl" badges-position="right">
|
|
140
|
+
<option value="1">אפשרות 1</option>
|
|
141
|
+
<option value="2">אפשרות 2</option>
|
|
142
|
+
<option value="3">אפשרות 3</option>
|
|
143
|
+
</web-multiselect>
|
|
144
|
+
|
|
145
|
+
<!-- ========================================
|
|
146
|
+
PROGRAMMATIC CONTROL (JavaScript API)
|
|
147
|
+
======================================== -->
|
|
148
|
+
|
|
149
|
+
<web-multiselect id="controlled" placeholder="Controlled...">
|
|
150
|
+
<option value="red">Red</option>
|
|
151
|
+
<option value="green">Green</option>
|
|
152
|
+
<option value="blue">Blue</option>
|
|
153
|
+
</web-multiselect>
|
|
154
|
+
|
|
155
|
+
<script>
|
|
156
|
+
const controlled = document.getElementById('controlled');
|
|
157
|
+
|
|
158
|
+
// Set selected values
|
|
159
|
+
controlled.setSelected(['red', 'blue']);
|
|
160
|
+
|
|
161
|
+
// Get selected values
|
|
162
|
+
const values = controlled.getValue(); // ['red', 'blue']
|
|
163
|
+
const selected = controlled.getSelected(); // [{value: 'red', label: 'Red'}, ...]
|
|
164
|
+
|
|
165
|
+
// Listen for changes
|
|
166
|
+
controlled.addEventListener('change', (e) => {
|
|
167
|
+
console.log('Selected:', e.detail.selectedValues);
|
|
168
|
+
console.log('Options:', e.detail.selectedOptions);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// Clear selection
|
|
172
|
+
controlled.setSelected([]);
|
|
173
|
+
</script>
|
|
174
|
+
|
|
175
|
+
<!-- ========================================
|
|
176
|
+
PROGRAMMATIC OPTIONS (JavaScript)
|
|
177
|
+
======================================== -->
|
|
178
|
+
|
|
179
|
+
<web-multiselect id="dynamic"></web-multiselect>
|
|
180
|
+
|
|
181
|
+
<script>
|
|
182
|
+
const dynamic = document.getElementById('dynamic');
|
|
183
|
+
|
|
184
|
+
// Set options programmatically
|
|
185
|
+
dynamic.options = [
|
|
186
|
+
{ value: 'js', label: 'JavaScript', icon: '🟨' },
|
|
187
|
+
{ value: 'ts', label: 'TypeScript', icon: '🔷' },
|
|
188
|
+
{ value: 'py', label: 'Python', icon: '🐍' }
|
|
189
|
+
];
|
|
190
|
+
|
|
191
|
+
// Or with custom properties
|
|
192
|
+
dynamic.valueMember = 'id';
|
|
193
|
+
dynamic.displayValueMember = 'name';
|
|
194
|
+
dynamic.iconMember = 'emoji';
|
|
195
|
+
|
|
196
|
+
dynamic.options = [
|
|
197
|
+
{ id: '1', name: 'React', emoji: '⚛️' },
|
|
198
|
+
{ id: '2', name: 'Vue', emoji: '💚' },
|
|
199
|
+
{ id: '3', name: 'Svelte', emoji: '🧡' }
|
|
200
|
+
];
|
|
201
|
+
</script>
|
|
202
|
+
|
|
203
|
+
<!-- ========================================
|
|
204
|
+
FORM INTEGRATION
|
|
205
|
+
======================================== -->
|
|
206
|
+
|
|
207
|
+
<form id="myForm">
|
|
208
|
+
<web-multiselect name="technologies" placeholder="Select technologies...">
|
|
209
|
+
<option value="react">React</option>
|
|
210
|
+
<option value="vue">Vue</option>
|
|
211
|
+
<option value="angular">Angular</option>
|
|
212
|
+
</web-multiselect>
|
|
213
|
+
|
|
214
|
+
<button type="submit">Submit</button>
|
|
215
|
+
</form>
|
|
216
|
+
|
|
217
|
+
<script>
|
|
218
|
+
document.getElementById('myForm').addEventListener('submit', (e) => {
|
|
219
|
+
e.preventDefault();
|
|
220
|
+
const formData = new FormData(e.target);
|
|
221
|
+
const technologies = formData.getAll('technologies');
|
|
222
|
+
console.log('Selected technologies:', technologies);
|
|
223
|
+
});
|
|
224
|
+
</script>
|
|
225
|
+
|
|
226
|
+
<!-- ========================================
|
|
227
|
+
AVAILABLE ATTRIBUTES
|
|
228
|
+
======================================== -->
|
|
229
|
+
|
|
230
|
+
<!--
|
|
231
|
+
Core Attributes:
|
|
232
|
+
- placeholder: Placeholder text
|
|
233
|
+
- multiple: "true" (default) or "false" for single-select
|
|
234
|
+
- badges-display-mode: "pills" | "count" | "compact" | "partial" | "none"
|
|
235
|
+
- badges-position: "bottom" | "top" | "left" | "right"
|
|
236
|
+
- dir: "ltr" (default) | "rtl"
|
|
237
|
+
- disabled: Disable the component
|
|
238
|
+
|
|
239
|
+
Search:
|
|
240
|
+
- search-enabled: "true" | "false" (default)
|
|
241
|
+
- search-mode: "filter" | "navigate"
|
|
242
|
+
- search-placeholder: Placeholder for search input
|
|
243
|
+
- min-search-length: Minimum characters before search
|
|
244
|
+
|
|
245
|
+
Display:
|
|
246
|
+
- show-checkboxes: Show checkboxes for options
|
|
247
|
+
- partial-display-limit: Number of badges to show in partial mode
|
|
248
|
+
|
|
249
|
+
Virtual Scrolling:
|
|
250
|
+
- virtual-scroll-enabled: "true" | "false" (auto-enabled for large datasets)
|
|
251
|
+
- virtual-scroll-buffer: Number of items to render outside viewport
|
|
252
|
+
- option-height: Height of each option in pixels
|
|
253
|
+
-->
|
|
254
|
+
|
|
255
|
+
<!-- ========================================
|
|
256
|
+
CSS THEMING (150+ Variables)
|
|
257
|
+
======================================== -->
|
|
258
|
+
|
|
259
|
+
<style>
|
|
260
|
+
/* Override CSS custom properties to match your theme */
|
|
261
|
+
:root {
|
|
262
|
+
/* Colors */
|
|
263
|
+
--ml-accent-color: #007bff;
|
|
264
|
+
--ml-text-primary: #2c3e50;
|
|
265
|
+
--ml-text-secondary: #6c757d;
|
|
266
|
+
--ml-bg-primary: #f8f9fa;
|
|
267
|
+
--ml-border-color: #e1e5e9;
|
|
268
|
+
|
|
269
|
+
/* Input */
|
|
270
|
+
--ml-input-bg: #ffffff;
|
|
271
|
+
--ml-input-border: #ced4da;
|
|
272
|
+
--ml-input-padding-v: 0.5rem;
|
|
273
|
+
--ml-input-padding-h: 0.75rem;
|
|
274
|
+
--ml-input-font-size: 0.875rem;
|
|
275
|
+
--ml-input-border-radius: 4px;
|
|
276
|
+
--ml-input-focus-border: #007bff;
|
|
277
|
+
|
|
278
|
+
/* Dropdown */
|
|
279
|
+
--ml-dropdown-bg: #ffffff;
|
|
280
|
+
--ml-dropdown-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
|
281
|
+
--ml-dropdown-max-height: 300px;
|
|
282
|
+
|
|
283
|
+
/* Options */
|
|
284
|
+
--ml-option-padding-v: 0.5rem;
|
|
285
|
+
--ml-option-padding-h: 0.75rem;
|
|
286
|
+
--ml-option-hover-bg: #f8f9fa;
|
|
287
|
+
--ml-option-selected-bg: rgba(0, 123, 255, 0.05);
|
|
288
|
+
--ml-option-selected-color: #007bff;
|
|
289
|
+
|
|
290
|
+
/* Badges */
|
|
291
|
+
--ml-badge-bg: #007bff;
|
|
292
|
+
--ml-badge-text: #ffffff;
|
|
293
|
+
--ml-badge-padding-v: 0.125rem;
|
|
294
|
+
--ml-badge-padding-h: 0.5rem;
|
|
295
|
+
--ml-badge-font-size: 0.75rem;
|
|
296
|
+
--ml-badge-border-radius: 2px;
|
|
297
|
+
--ml-badge-gap: 0.5rem;
|
|
298
|
+
|
|
299
|
+
/* Animations */
|
|
300
|
+
--ml-transition-duration: 0.15s;
|
|
301
|
+
--ml-timing-function: ease;
|
|
302
|
+
}
|
|
303
|
+
</style>
|
|
304
|
+
|
|
305
|
+
<!-- ========================================
|
|
306
|
+
TYPESCRIPT TYPES
|
|
307
|
+
======================================== -->
|
|
308
|
+
|
|
309
|
+
<!--
|
|
310
|
+
TypeScript usage:
|
|
311
|
+
|
|
312
|
+
import '@keenmate/web-multiselect';
|
|
313
|
+
import type { MultiSelectElement, MultiSelectOption } from '@keenmate/web-multiselect';
|
|
314
|
+
|
|
315
|
+
const select = document.querySelector<MultiSelectElement>('web-multiselect');
|
|
316
|
+
|
|
317
|
+
if (select) {
|
|
318
|
+
// Type-safe API
|
|
319
|
+
select.options = [
|
|
320
|
+
{ value: 'js', label: 'JavaScript' },
|
|
321
|
+
{ value: 'ts', label: 'TypeScript' }
|
|
322
|
+
];
|
|
323
|
+
|
|
324
|
+
select.addEventListener('change', (e: CustomEvent<{
|
|
325
|
+
selectedValues: string[];
|
|
326
|
+
selectedOptions: MultiSelectOption[];
|
|
327
|
+
}>) => {
|
|
328
|
+
console.log(e.detail.selectedValues);
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
-->
|
|
332
|
+
|
|
333
|
+
<!-- ========================================
|
|
334
|
+
KEY FEATURES
|
|
335
|
+
======================================== -->
|
|
336
|
+
|
|
337
|
+
<!--
|
|
338
|
+
✅ Virtual Scrolling: Handles 15,000+ options efficiently
|
|
339
|
+
✅ Search: Filter or navigate modes with async support
|
|
340
|
+
✅ Display Modes: Pills, count, compact, partial, none
|
|
341
|
+
✅ Keyboard Navigation: Full arrow key support
|
|
342
|
+
✅ RTL Support: Arabic, Hebrew, Persian, etc.
|
|
343
|
+
✅ Grouped Options: Optgroup support with labels
|
|
344
|
+
✅ Disabled Options: Per-option disable state
|
|
345
|
+
✅ Form Integration: Native form submission support
|
|
346
|
+
✅ Framework Agnostic: Works with any framework or vanilla JS
|
|
347
|
+
✅ TypeScript: Full type definitions included
|
|
348
|
+
✅ Accessible: ARIA-friendly with focus management
|
|
349
|
+
✅ Customizable: 150+ CSS variables for theming
|
|
350
|
+
✅ Zero Dependencies: Only requires @floating-ui/dom for positioning
|
|
351
|
+
-->
|
|
352
|
+
|
|
353
|
+
<!-- ========================================
|
|
354
|
+
RESOURCES
|
|
355
|
+
======================================== -->
|
|
356
|
+
|
|
357
|
+
<!--
|
|
358
|
+
npm Package: @keenmate/web-multiselect
|
|
359
|
+
Repository: https://github.com/keenmate/web-multiselect
|
|
360
|
+
Documentation: See package README and ../../web-multiselect/ai/ for AI instructions
|
|
361
|
+
Pure Admin Integration: src/scss/core-components/_web-components-theme.scss
|
|
362
|
+
-->
|