@stackline/react-multiselect-dropdown 17.0.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/dist/index.cjs ADDED
@@ -0,0 +1,2022 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ MultiSelectDropdown: () => MultiSelectDropdown,
24
+ ReactMultiSelectDropdown: () => ReactMultiSelectDropdown
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+
28
+ // src/MultiSelectDropdown.tsx
29
+ var import_react = require("react");
30
+ var import_react_dom = require("react-dom");
31
+
32
+ // src/styles.ts
33
+ var STYLE_ID = "stackline-react-multiselect-dropdown-styles";
34
+ var styles = `
35
+ .rmsd-root {
36
+ --rmsd-primary: #3f51b5;
37
+ --rmsd-primary-soft: rgba(63, 81, 181, 0.12);
38
+ --rmsd-bg: #ffffff;
39
+ --rmsd-surface: #f5f7fb;
40
+ --rmsd-surface-muted: #e8eaf6;
41
+ --rmsd-border: #c5cae9;
42
+ --rmsd-border-strong: #7986cb;
43
+ --rmsd-ink: #212121;
44
+ --rmsd-muted: #5f6368;
45
+ --rmsd-chip-bg: #e8eaf6;
46
+ --rmsd-chip-text: #303f9f;
47
+ --rmsd-chip-remove: #303f9f;
48
+ --rmsd-divider: rgba(125, 119, 134, 0.16);
49
+ --rmsd-section-bg: #f5f7fb;
50
+ --rmsd-focus: rgba(63, 81, 181, 0.32);
51
+ --rmsd-shadow: 0 1px 2px rgba(33, 33, 33, 0.16), 0 12px 32px rgba(63, 81, 181, 0.12);
52
+ --rmsd-shadow-soft: 0 1px 2px rgba(33, 33, 33, 0.12), 0 4px 12px rgba(33, 33, 33, 0.08);
53
+ position: relative;
54
+ display: block;
55
+ width: 100%;
56
+ color: var(--rmsd-ink);
57
+ font: inherit;
58
+ }
59
+
60
+ .rmsd-root *,
61
+ .rmsd-root *::before,
62
+ .rmsd-root *::after,
63
+ .rmsd-menu,
64
+ .rmsd-menu *,
65
+ .rmsd-menu *::before,
66
+ .rmsd-menu *::after {
67
+ box-sizing: border-box;
68
+ }
69
+
70
+ .rmsd-trigger {
71
+ position: relative;
72
+ display: flex;
73
+ align-items: center;
74
+ flex-wrap: wrap;
75
+ width: 100%;
76
+ min-height: 56px;
77
+ gap: 8px;
78
+ border: 1px solid var(--rmsd-border);
79
+ border-radius: 18px;
80
+ background-color: var(--rmsd-bg);
81
+ color: var(--rmsd-ink);
82
+ padding: 11px 54px 11px 16px;
83
+ box-shadow: var(--rmsd-shadow-soft);
84
+ text-align: left;
85
+ cursor: pointer;
86
+ line-height: 1.45;
87
+ transition: border-color 160ms ease, box-shadow 160ms ease, background-color 160ms ease, transform 160ms ease;
88
+ }
89
+
90
+ .rmsd-trigger:hover {
91
+ border-color: var(--rmsd-border-strong);
92
+ }
93
+
94
+ .rmsd-root[data-open="true"] .rmsd-trigger,
95
+ .rmsd-trigger:focus-visible {
96
+ outline: none;
97
+ border-color: var(--rmsd-primary);
98
+ box-shadow: 0 0 0 3px var(--rmsd-focus), var(--rmsd-shadow-soft);
99
+ }
100
+
101
+ .rmsd-trigger.rmsd-disabled {
102
+ cursor: not-allowed;
103
+ opacity: 0.68;
104
+ }
105
+
106
+ .rmsd-value {
107
+ display: flex;
108
+ flex: 1 1 auto;
109
+ min-width: 0;
110
+ align-items: center;
111
+ gap: 8px;
112
+ flex-wrap: wrap;
113
+ }
114
+
115
+ .rmsd-placeholder,
116
+ .rmsd-single-value {
117
+ min-width: 0;
118
+ color: var(--rmsd-muted);
119
+ font-size: 0.95rem;
120
+ overflow: hidden;
121
+ text-overflow: ellipsis;
122
+ white-space: nowrap;
123
+ }
124
+
125
+ .rmsd-single-value {
126
+ color: var(--rmsd-ink);
127
+ font-weight: 500;
128
+ }
129
+
130
+ .rmsd-badge-list {
131
+ display: flex;
132
+ flex: 1 1 auto;
133
+ min-width: 0;
134
+ align-items: center;
135
+ gap: 8px;
136
+ flex-wrap: wrap;
137
+ }
138
+
139
+ .rmsd-badge {
140
+ position: relative;
141
+ display: inline-block;
142
+ vertical-align: middle;
143
+ min-height: 32px;
144
+ max-width: 100%;
145
+ border-radius: 999px;
146
+ background-color: var(--rmsd-chip-bg);
147
+ color: var(--rmsd-chip-text);
148
+ padding: 6px 30px 6px 12px;
149
+ box-shadow: inset 0 0 0 1px rgba(103, 80, 164, 0.08);
150
+ line-height: 1.35;
151
+ white-space: normal;
152
+ overflow-wrap: anywhere;
153
+ }
154
+
155
+ .rmsd-badge-label {
156
+ display: inline-flex;
157
+ align-items: center;
158
+ min-width: 0;
159
+ max-width: 100%;
160
+ line-height: 1.3;
161
+ font-weight: 500;
162
+ white-space: normal;
163
+ overflow-wrap: anywhere;
164
+ }
165
+
166
+ .rmsd-badge-remove,
167
+ .rmsd-clear,
168
+ .rmsd-search-clear,
169
+ .rmsd-arrow-button,
170
+ .rmsd-group-action {
171
+ appearance: none;
172
+ border: 0;
173
+ background: transparent;
174
+ color: inherit;
175
+ cursor: pointer;
176
+ font: inherit;
177
+ padding: 0;
178
+ }
179
+
180
+ .rmsd-badge-remove {
181
+ position: absolute;
182
+ top: 50%;
183
+ right: 10px;
184
+ display: inline-grid;
185
+ width: 16px;
186
+ height: 16px;
187
+ place-items: center;
188
+ transform: translateY(-50%);
189
+ color: var(--rmsd-chip-remove);
190
+ font-size: 12px;
191
+ line-height: 1;
192
+ }
193
+
194
+ .rmsd-overflow {
195
+ display: inline-flex;
196
+ align-items: center;
197
+ justify-content: center;
198
+ min-width: 0;
199
+ min-height: 0;
200
+ color: var(--rmsd-muted);
201
+ font-size: 0.8rem;
202
+ font-weight: 600;
203
+ }
204
+
205
+ .rmsd-root.rmsd-has-overflow:not(.skin-classic) .rmsd-trigger {
206
+ padding-right: 104px;
207
+ }
208
+
209
+ .rmsd-root.rmsd-has-overflow:not(.skin-classic):not(.rmsd-has-clear) .rmsd-trigger {
210
+ padding-right: 74px;
211
+ }
212
+
213
+ .rmsd-root.rmsd-has-overflow:not(.skin-classic) .rmsd-overflow {
214
+ position: absolute;
215
+ top: 50%;
216
+ right: 76px;
217
+ transform: translateY(-50%);
218
+ z-index: 1;
219
+ }
220
+
221
+ .rmsd-root.rmsd-has-overflow:not(.skin-classic):not(.rmsd-has-clear) .rmsd-overflow {
222
+ right: 42px;
223
+ }
224
+
225
+ .rmsd-actions {
226
+ position: absolute;
227
+ top: 50%;
228
+ right: 16px;
229
+ display: inline-flex;
230
+ align-items: center;
231
+ gap: 6px;
232
+ transform: translateY(-50%);
233
+ }
234
+
235
+ .rmsd-clear {
236
+ display: inline-grid;
237
+ width: 20px;
238
+ height: 20px;
239
+ place-items: center;
240
+ border-radius: 999px;
241
+ color: var(--rmsd-muted);
242
+ font-size: 14px;
243
+ line-height: 1;
244
+ }
245
+
246
+ .rmsd-icon {
247
+ display: block;
248
+ width: 100%;
249
+ height: 100%;
250
+ fill: currentColor;
251
+ }
252
+
253
+ .rmsd-badge-remove .rmsd-icon {
254
+ width: 10px;
255
+ height: 10px;
256
+ }
257
+
258
+ .rmsd-clear .rmsd-icon {
259
+ width: 12px;
260
+ height: 12px;
261
+ }
262
+
263
+ .rmsd-search-clear .rmsd-icon {
264
+ width: 18px;
265
+ height: 18px;
266
+ }
267
+
268
+ .rmsd-arrow-button {
269
+ display: inline-grid;
270
+ width: 20px;
271
+ height: 20px;
272
+ place-items: center;
273
+ border-radius: 999px;
274
+ color: var(--rmsd-muted);
275
+ }
276
+
277
+ .rmsd-arrow-button:disabled {
278
+ cursor: not-allowed;
279
+ }
280
+
281
+ .rmsd-badge-remove:focus-visible,
282
+ .rmsd-clear:focus-visible,
283
+ .rmsd-search-clear:focus-visible,
284
+ .rmsd-arrow-button:focus-visible,
285
+ .rmsd-group-action:focus-visible,
286
+ .rmsd-inline-button:focus-visible {
287
+ outline: 3px solid var(--rmsd-focus);
288
+ outline-offset: 2px;
289
+ }
290
+
291
+ .rmsd-arrow {
292
+ display: inline-flex;
293
+ width: 100%;
294
+ height: 100%;
295
+ line-height: 0;
296
+ }
297
+
298
+ .rmsd-arrow .rmsd-icon {
299
+ display: block;
300
+ width: 100%;
301
+ height: 100%;
302
+ fill: currentColor;
303
+ }
304
+
305
+ .rmsd-menu {
306
+ position: absolute;
307
+ left: 0;
308
+ z-index: 99999;
309
+ width: 100%;
310
+ border: 1px solid var(--rmsd-border);
311
+ border-radius: 22px;
312
+ background-color: var(--rmsd-bg);
313
+ box-shadow: var(--rmsd-shadow);
314
+ overflow: hidden;
315
+ }
316
+
317
+ .rmsd-menu.rmsd-body-overlay {
318
+ position: fixed;
319
+ right: auto;
320
+ top: auto;
321
+ bottom: auto;
322
+ max-width: calc(100vw - 16px);
323
+ z-index: 100000;
324
+ }
325
+
326
+ .rmsd-menu.rmsd-bottom {
327
+ top: calc(100% + 8px);
328
+ }
329
+
330
+ .rmsd-menu.rmsd-top {
331
+ bottom: calc(100% + 8px);
332
+ }
333
+
334
+ .rmsd-menu.rmsd-body-overlay.rmsd-bottom,
335
+ .rmsd-menu.rmsd-body-overlay.rmsd-top {
336
+ top: auto;
337
+ bottom: auto;
338
+ }
339
+
340
+ .rmsd-toolbar {
341
+ display: grid;
342
+ gap: 0;
343
+ padding: 0;
344
+ background-color: var(--rmsd-bg);
345
+ }
346
+
347
+ .rmsd-search-shell {
348
+ position: relative;
349
+ min-height: 52px;
350
+ border-bottom: 1px solid var(--rmsd-divider);
351
+ background-color: var(--rmsd-bg);
352
+ }
353
+
354
+ .rmsd-search-icon {
355
+ position: absolute;
356
+ top: 50%;
357
+ left: 16px;
358
+ width: 18px;
359
+ height: 18px;
360
+ color: var(--rmsd-muted);
361
+ fill: currentColor;
362
+ pointer-events: none;
363
+ transform: translateY(-50%);
364
+ }
365
+
366
+ .rmsd-search-input {
367
+ width: 100%;
368
+ min-height: 52px;
369
+ border: 0;
370
+ border-radius: 0;
371
+ background-color: var(--rmsd-bg);
372
+ color: var(--rmsd-ink);
373
+ font: inherit;
374
+ padding: 0 44px 0 48px;
375
+ }
376
+
377
+ .rmsd-search-input:focus {
378
+ outline: none;
379
+ box-shadow: inset 0 0 0 2px var(--rmsd-primary);
380
+ }
381
+
382
+ .rmsd-search-clear {
383
+ position: absolute;
384
+ top: 50%;
385
+ right: 16px;
386
+ display: inline-grid;
387
+ width: 18px;
388
+ height: 18px;
389
+ place-items: center;
390
+ transform: translateY(-50%);
391
+ border-radius: 999px;
392
+ color: var(--rmsd-muted);
393
+ }
394
+
395
+ .rmsd-bulk-actions {
396
+ display: block;
397
+ align-items: center;
398
+ padding: 0;
399
+ border-bottom: 1px solid var(--rmsd-divider);
400
+ background: var(--rmsd-section-bg);
401
+ }
402
+
403
+ .rmsd-inline-button {
404
+ display: flex;
405
+ align-items: center;
406
+ gap: 10px;
407
+ width: 100%;
408
+ min-height: 39px;
409
+ border: 0;
410
+ border-radius: 0;
411
+ background: transparent;
412
+ color: var(--rmsd-ink);
413
+ cursor: pointer;
414
+ font: inherit;
415
+ font-weight: 500;
416
+ padding: 10px 14px;
417
+ text-align: left;
418
+ }
419
+
420
+ .rmsd-inline-button:hover {
421
+ background-color: var(--rmsd-surface);
422
+ }
423
+
424
+ .rmsd-inline-button:disabled {
425
+ opacity: 0.58;
426
+ cursor: not-allowed;
427
+ }
428
+
429
+ .rmsd-add-button {
430
+ justify-content: center;
431
+ border-top: 1px solid var(--rmsd-divider);
432
+ color: var(--rmsd-primary);
433
+ font-weight: 700;
434
+ }
435
+
436
+ .rmsd-list {
437
+ max-height: 300px;
438
+ overflow: auto;
439
+ padding: 8px;
440
+ background: var(--rmsd-bg);
441
+ scrollbar-width: thin;
442
+ scrollbar-color: rgba(125, 119, 134, 0.34) transparent;
443
+ }
444
+
445
+ .rmsd-list:focus {
446
+ outline: none;
447
+ }
448
+
449
+ .rmsd-menu ::-webkit-scrollbar {
450
+ width: 10px;
451
+ }
452
+
453
+ .rmsd-menu ::-webkit-scrollbar-thumb {
454
+ background: rgba(125, 119, 134, 0.34);
455
+ border: 2px solid transparent;
456
+ border-radius: 999px;
457
+ background-clip: padding-box;
458
+ }
459
+
460
+ .rmsd-menu ::-webkit-scrollbar-track {
461
+ background: transparent;
462
+ }
463
+
464
+ .rmsd-option {
465
+ display: flex;
466
+ align-items: center;
467
+ gap: 10px;
468
+ min-height: 0;
469
+ margin: 4px;
470
+ padding: 12px 14px;
471
+ border-radius: 14px;
472
+ background: transparent;
473
+ color: inherit;
474
+ text-align: left;
475
+ cursor: pointer;
476
+ line-height: 1.35;
477
+ }
478
+
479
+ .rmsd-option:hover {
480
+ background-color: var(--rmsd-surface);
481
+ }
482
+
483
+ .rmsd-option:focus-visible {
484
+ outline: 3px solid var(--rmsd-focus);
485
+ outline-offset: 1px;
486
+ }
487
+
488
+ .rmsd-option.rmsd-selected {
489
+ background-color: var(--rmsd-primary-soft);
490
+ color: var(--rmsd-primary);
491
+ }
492
+
493
+ .rmsd-option.rmsd-disabled {
494
+ opacity: 0.54;
495
+ cursor: not-allowed;
496
+ }
497
+
498
+ .rmsd-checkbox {
499
+ position: relative;
500
+ box-sizing: content-box;
501
+ flex: 0 0 auto;
502
+ width: 18px;
503
+ height: 18px;
504
+ margin-top: 0;
505
+ border: 2px solid var(--rmsd-border-strong);
506
+ border-radius: 6px;
507
+ background-color: var(--rmsd-bg);
508
+ }
509
+
510
+ .rmsd-checkbox[data-checked="true"] {
511
+ border-color: var(--rmsd-primary);
512
+ background-color: var(--rmsd-primary);
513
+ }
514
+
515
+ .rmsd-checkbox[data-checked="true"]::after {
516
+ box-sizing: content-box;
517
+ content: "";
518
+ position: absolute;
519
+ top: 50%;
520
+ left: 50%;
521
+ width: 8px;
522
+ height: 4px;
523
+ margin-top: 0;
524
+ border-color: #fff;
525
+ border-style: solid;
526
+ border-width: 0 0 2px 2px;
527
+ transform: translate(-50%, -58%) rotate(-45deg);
528
+ transform-origin: 50%;
529
+ }
530
+
531
+ .rmsd-option-body {
532
+ min-width: 0;
533
+ flex: 1;
534
+ }
535
+
536
+ .rmsd-option-label {
537
+ font-weight: 500;
538
+ }
539
+
540
+ .rmsd-option-hint {
541
+ display: block;
542
+ margin-top: 3px;
543
+ color: var(--rmsd-muted);
544
+ font-size: 12px;
545
+ }
546
+
547
+ .rmsd-group {
548
+ margin-bottom: 8px;
549
+ }
550
+
551
+ .rmsd-group:last-child {
552
+ margin-bottom: 0;
553
+ }
554
+
555
+ .rmsd-group-header {
556
+ display: flex;
557
+ align-items: center;
558
+ justify-content: space-between;
559
+ gap: 8px;
560
+ padding: 9px 10px;
561
+ color: var(--rmsd-muted);
562
+ font-size: 12px;
563
+ font-weight: 800;
564
+ letter-spacing: 0.08em;
565
+ text-transform: uppercase;
566
+ }
567
+
568
+ .rmsd-group-action {
569
+ color: var(--rmsd-primary);
570
+ font-size: 12px;
571
+ font-weight: 800;
572
+ }
573
+
574
+ .rmsd-state {
575
+ padding: 18px 12px;
576
+ text-align: center;
577
+ color: var(--rmsd-muted);
578
+ }
579
+
580
+ .theme-material,
581
+ .skin-material {
582
+ --rmsd-primary: #3f51b5;
583
+ --rmsd-primary-soft: rgba(63, 81, 181, 0.12);
584
+ --rmsd-bg: #ffffff;
585
+ --rmsd-surface: #f5f7fb;
586
+ --rmsd-surface-muted: #e8eaf6;
587
+ --rmsd-border: #c5cae9;
588
+ --rmsd-border-strong: #7986cb;
589
+ --rmsd-ink: #212121;
590
+ --rmsd-muted: #5f6368;
591
+ --rmsd-chip-bg: #e8eaf6;
592
+ --rmsd-chip-text: #303f9f;
593
+ --rmsd-chip-remove: #303f9f;
594
+ --rmsd-divider: rgba(125, 119, 134, 0.16);
595
+ --rmsd-section-bg: #f5f7fb;
596
+ --rmsd-focus: rgba(63, 81, 181, 0.32);
597
+ --rmsd-shadow: 0 1px 2px rgba(33, 33, 33, 0.16), 0 12px 32px rgba(63, 81, 181, 0.12);
598
+ --rmsd-shadow-soft: 0 1px 2px rgba(33, 33, 33, 0.12), 0 4px 12px rgba(33, 33, 33, 0.08);
599
+ }
600
+
601
+ .theme-material .rmsd-trigger,
602
+ .skin-material .rmsd-trigger {
603
+ min-height: 56px;
604
+ border-radius: 18px;
605
+ padding: 11px 54px 11px 16px;
606
+ }
607
+
608
+ .theme-material .rmsd-menu,
609
+ .skin-material .rmsd-menu,
610
+ .rmsd-menu.theme-material,
611
+ .rmsd-menu.skin-material {
612
+ border-radius: 22px;
613
+ }
614
+
615
+ .theme-material .rmsd-option,
616
+ .skin-material .rmsd-option {
617
+ border-radius: 14px;
618
+ margin: 4px;
619
+ padding: 12px 14px;
620
+ }
621
+
622
+ .theme-dark,
623
+ .skin-dark {
624
+ --rmsd-primary: #8ab4f8;
625
+ --rmsd-primary-soft: rgba(138, 180, 248, 0.18);
626
+ --rmsd-bg: #151a23;
627
+ --rmsd-surface: #202736;
628
+ --rmsd-surface-muted: #111722;
629
+ --rmsd-border: #384456;
630
+ --rmsd-border-strong: #8ab4f8;
631
+ --rmsd-ink: #edf2f7;
632
+ --rmsd-muted: #aab6c5;
633
+ --rmsd-chip-bg: #263247;
634
+ --rmsd-chip-text: #d7e6ff;
635
+ --rmsd-chip-remove: #d7e6ff;
636
+ --rmsd-divider: rgba(170, 182, 197, 0.18);
637
+ --rmsd-section-bg: #202736;
638
+ --rmsd-focus: rgba(138, 180, 248, 0.34);
639
+ --rmsd-shadow: 0 20px 50px rgba(0, 0, 0, 0.42);
640
+ --rmsd-shadow-soft: 0 1px 2px rgba(0, 0, 0, 0.45), 0 10px 24px rgba(0, 0, 0, 0.28);
641
+ }
642
+
643
+ .theme-custom,
644
+ .skin-custom {
645
+ --rmsd-primary: var(--stackline-ms-primary, #0f766e);
646
+ --rmsd-primary-soft: var(--stackline-ms-primary-soft, rgba(15, 118, 110, 0.14));
647
+ --rmsd-bg: var(--stackline-ms-surface, #ffffff);
648
+ --rmsd-surface: var(--stackline-ms-surface-soft, #ecfdf5);
649
+ --rmsd-surface-muted: var(--stackline-ms-surface-muted, #d1fae5);
650
+ --rmsd-border: var(--stackline-ms-outline, #99f6e4);
651
+ --rmsd-border-strong: var(--stackline-ms-outline-strong, #0f766e);
652
+ --rmsd-ink: var(--stackline-ms-on-surface, #102a2a);
653
+ --rmsd-muted: var(--stackline-ms-on-surface-muted, #47615f);
654
+ --rmsd-chip-bg: var(--stackline-ms-chip-bg, #ccfbf1);
655
+ --rmsd-chip-text: var(--stackline-ms-chip-text, #115e59);
656
+ --rmsd-chip-remove: var(--stackline-ms-chip-remove, #115e59);
657
+ --rmsd-divider: var(--stackline-ms-divider, rgba(15, 118, 110, 0.18));
658
+ --rmsd-section-bg: var(--stackline-ms-section-bg, #ecfdf5);
659
+ --rmsd-focus: var(--stackline-ms-focus, rgba(15, 118, 110, 0.28));
660
+ --rmsd-shadow: var(--stackline-ms-shadow, 0 18px 42px rgba(15, 118, 110, 0.15));
661
+ --rmsd-shadow-soft: var(--stackline-ms-shadow-soft, 0 1px 2px rgba(15, 118, 110, 0.16), 0 8px 18px rgba(15, 118, 110, 0.09));
662
+ }
663
+
664
+ .theme-brand,
665
+ .skin-brand {
666
+ --stackline-ms-primary: #7c3aed;
667
+ --stackline-ms-primary-soft: rgba(124, 58, 237, 0.14);
668
+ --stackline-ms-surface: #ffffff;
669
+ --stackline-ms-surface-soft: #f5f3ff;
670
+ --stackline-ms-surface-muted: #ede9fe;
671
+ --stackline-ms-outline: #c4b5fd;
672
+ --stackline-ms-outline-strong: #7c3aed;
673
+ --stackline-ms-on-surface: #22183f;
674
+ --stackline-ms-on-surface-muted: #6b5d80;
675
+ --stackline-ms-chip-bg: #ede9fe;
676
+ --stackline-ms-chip-text: #5b21b6;
677
+ --stackline-ms-chip-remove: #5b21b6;
678
+ --stackline-ms-divider: rgba(124, 58, 237, 0.16);
679
+ --stackline-ms-section-bg: #f5f3ff;
680
+ }
681
+
682
+ .theme-classic,
683
+ .skin-classic {
684
+ --rmsd-primary: #0079fe;
685
+ --rmsd-primary-soft: #e9f4ff;
686
+ --rmsd-bg: #ffffff;
687
+ --rmsd-surface: #f5f5f5;
688
+ --rmsd-surface-muted: #e9f4ff;
689
+ --rmsd-border: #cccccc;
690
+ --rmsd-border-strong: #0079fe;
691
+ --rmsd-ink: #333333;
692
+ --rmsd-muted: #333333;
693
+ --rmsd-chip-bg: #0079fe;
694
+ --rmsd-chip-text: #ffffff;
695
+ --rmsd-chip-remove: #ffffff;
696
+ --rmsd-focus: rgba(0, 121, 254, 0.26);
697
+ --rmsd-divider: #cccccc;
698
+ --rmsd-section-bg: #ffffff;
699
+ --rmsd-shadow: 0 1px 5px #959595;
700
+ --rmsd-shadow-soft: 0 1px 5px #959595;
701
+ color: #333333;
702
+ }
703
+
704
+ .theme-classic .rmsd-trigger,
705
+ .skin-classic .rmsd-trigger {
706
+ flex-wrap: nowrap;
707
+ gap: 6px;
708
+ min-height: 42px;
709
+ border-radius: 3px;
710
+ padding: 10px 68px 10px 10px;
711
+ border: 1px solid #cccccc;
712
+ background: #ffffff;
713
+ box-shadow: 0 1px 5px #959595;
714
+ color: #333333;
715
+ font-size: 14px;
716
+ line-height: 1.35;
717
+ }
718
+
719
+ .theme-classic .rmsd-trigger:hover,
720
+ .skin-classic .rmsd-trigger:hover,
721
+ .theme-classic[data-open="true"] .rmsd-trigger,
722
+ .skin-classic[data-open="true"] .rmsd-trigger {
723
+ border-color: #cccccc;
724
+ box-shadow: 0 1px 5px #959595;
725
+ }
726
+
727
+ .theme-classic .rmsd-trigger.rmsd-disabled,
728
+ .skin-classic .rmsd-trigger.rmsd-disabled {
729
+ background: #cccccc;
730
+ opacity: 1;
731
+ }
732
+
733
+ .theme-classic .rmsd-placeholder,
734
+ .theme-classic .rmsd-single-value,
735
+ .skin-classic .rmsd-placeholder,
736
+ .skin-classic .rmsd-single-value {
737
+ color: #333333;
738
+ font-size: 14px;
739
+ }
740
+
741
+ .theme-classic .rmsd-value,
742
+ .theme-classic .rmsd-badge-list,
743
+ .skin-classic .rmsd-value,
744
+ .skin-classic .rmsd-badge-list {
745
+ align-items: center;
746
+ gap: 4px;
747
+ flex-wrap: wrap;
748
+ min-width: 0;
749
+ }
750
+
751
+ .theme-classic .rmsd-badge,
752
+ .skin-classic .rmsd-badge {
753
+ display: inline-block;
754
+ min-height: 0;
755
+ margin: 2px 0 0;
756
+ border-radius: 2px;
757
+ padding: 2px 24px 2px 6px;
758
+ box-shadow: none;
759
+ color: #ffffff;
760
+ line-height: 1.4;
761
+ }
762
+
763
+ .theme-classic .rmsd-badge-label,
764
+ .skin-classic .rmsd-badge-label {
765
+ display: inline;
766
+ color: #ffffff;
767
+ font-size: 14px;
768
+ font-weight: 400;
769
+ line-height: 1.4;
770
+ }
771
+
772
+ .theme-classic .rmsd-badge-remove,
773
+ .skin-classic .rmsd-badge-remove {
774
+ right: 5px;
775
+ width: 14px;
776
+ height: 14px;
777
+ color: #ffffff;
778
+ }
779
+
780
+ .theme-classic .rmsd-badge-remove .rmsd-icon,
781
+ .skin-classic .rmsd-badge-remove .rmsd-icon {
782
+ width: 9px;
783
+ height: 9px;
784
+ }
785
+
786
+ .theme-classic .rmsd-overflow,
787
+ .skin-classic .rmsd-overflow {
788
+ color: #333333;
789
+ font-size: 14px;
790
+ font-weight: 400;
791
+ }
792
+
793
+ .theme-classic .rmsd-actions,
794
+ .skin-classic .rmsd-actions {
795
+ right: 10px;
796
+ gap: 12px;
797
+ }
798
+
799
+ .theme-classic .rmsd-clear,
800
+ .skin-classic .rmsd-clear {
801
+ width: 18px;
802
+ height: 18px;
803
+ color: #333333;
804
+ }
805
+
806
+ .theme-classic .rmsd-clear .rmsd-icon,
807
+ .skin-classic .rmsd-clear .rmsd-icon {
808
+ width: 11px;
809
+ height: 11px;
810
+ }
811
+
812
+ .theme-classic .rmsd-arrow-button,
813
+ .skin-classic .rmsd-arrow-button {
814
+ width: 20px;
815
+ height: 20px;
816
+ color: #333333;
817
+ }
818
+
819
+ .theme-classic .rmsd-menu,
820
+ .skin-classic .rmsd-menu,
821
+ .rmsd-menu.theme-classic,
822
+ .rmsd-menu.skin-classic {
823
+ overflow: visible;
824
+ border: 1px solid #cccccc;
825
+ border-radius: 3px;
826
+ background: #ffffff;
827
+ box-shadow: 0 1px 5px #959595;
828
+ }
829
+
830
+ .rmsd-menu.theme-classic.rmsd-bottom,
831
+ .rmsd-menu.skin-classic.rmsd-bottom {
832
+ top: calc(100% + 14px);
833
+ }
834
+
835
+ .rmsd-menu.theme-classic.rmsd-top,
836
+ .rmsd-menu.skin-classic.rmsd-top {
837
+ bottom: calc(100% + 14px);
838
+ }
839
+
840
+ .rmsd-menu.rmsd-body-overlay.rmsd-bottom,
841
+ .rmsd-menu.rmsd-body-overlay.rmsd-top {
842
+ bottom: auto;
843
+ }
844
+
845
+ .rmsd-menu.theme-classic::before,
846
+ .rmsd-menu.theme-classic::after,
847
+ .rmsd-menu.skin-classic::before,
848
+ .rmsd-menu.skin-classic::after {
849
+ content: "";
850
+ position: absolute;
851
+ left: 15px;
852
+ width: 0;
853
+ height: 0;
854
+ border-right: 13px solid transparent;
855
+ border-left: 13px solid transparent;
856
+ }
857
+
858
+ .rmsd-menu.theme-classic.rmsd-bottom::before,
859
+ .rmsd-menu.skin-classic.rmsd-bottom::before {
860
+ top: -15px;
861
+ border-bottom: 15px solid #cccccc;
862
+ }
863
+
864
+ .rmsd-menu.theme-classic.rmsd-bottom::after,
865
+ .rmsd-menu.skin-classic.rmsd-bottom::after {
866
+ top: -14px;
867
+ border-bottom: 15px solid #ffffff;
868
+ }
869
+
870
+ .rmsd-menu.theme-classic.rmsd-top::before,
871
+ .rmsd-menu.skin-classic.rmsd-top::before {
872
+ bottom: -15px;
873
+ border-top: 15px solid #cccccc;
874
+ }
875
+
876
+ .rmsd-menu.theme-classic.rmsd-top::after,
877
+ .rmsd-menu.skin-classic.rmsd-top::after {
878
+ bottom: -14px;
879
+ border-top: 15px solid #ffffff;
880
+ }
881
+
882
+ .theme-classic .rmsd-toolbar,
883
+ .skin-classic .rmsd-toolbar,
884
+ .rmsd-menu.theme-classic .rmsd-toolbar,
885
+ .rmsd-menu.skin-classic .rmsd-toolbar {
886
+ gap: 0;
887
+ padding: 0;
888
+ background: #ffffff;
889
+ }
890
+
891
+ .theme-classic .rmsd-search-shell,
892
+ .skin-classic .rmsd-search-shell,
893
+ .rmsd-menu.theme-classic .rmsd-search-shell,
894
+ .rmsd-menu.skin-classic .rmsd-search-shell {
895
+ min-height: 35px;
896
+ border-bottom: 1px solid #cccccc;
897
+ background: #ffffff;
898
+ }
899
+
900
+ .theme-classic .rmsd-search-icon,
901
+ .skin-classic .rmsd-search-icon,
902
+ .rmsd-menu.theme-classic .rmsd-search-icon,
903
+ .rmsd-menu.skin-classic .rmsd-search-icon {
904
+ left: 13px;
905
+ width: 18px;
906
+ height: 18px;
907
+ }
908
+
909
+ .theme-classic .rmsd-search-input,
910
+ .skin-classic .rmsd-search-input,
911
+ .rmsd-menu.theme-classic .rmsd-search-input,
912
+ .rmsd-menu.skin-classic .rmsd-search-input {
913
+ min-height: 35px;
914
+ height: 35px;
915
+ padding: 0 35px;
916
+ border: 0;
917
+ color: #333333;
918
+ }
919
+
920
+ .theme-classic .rmsd-search-input:focus,
921
+ .skin-classic .rmsd-search-input:focus,
922
+ .rmsd-menu.theme-classic .rmsd-search-input:focus,
923
+ .rmsd-menu.skin-classic .rmsd-search-input:focus {
924
+ box-shadow: none;
925
+ }
926
+
927
+ .theme-classic .rmsd-search-clear,
928
+ .skin-classic .rmsd-search-clear,
929
+ .rmsd-menu.theme-classic .rmsd-search-clear,
930
+ .rmsd-menu.skin-classic .rmsd-search-clear {
931
+ right: 13px;
932
+ }
933
+
934
+ .theme-classic .rmsd-bulk-actions,
935
+ .skin-classic .rmsd-bulk-actions,
936
+ .rmsd-menu.theme-classic .rmsd-bulk-actions,
937
+ .rmsd-menu.skin-classic .rmsd-bulk-actions {
938
+ border-top: 0;
939
+ border-bottom: 1px solid #cccccc;
940
+ background: #ffffff;
941
+ }
942
+
943
+ .theme-classic .rmsd-inline-button,
944
+ .skin-classic .rmsd-inline-button,
945
+ .rmsd-menu.theme-classic .rmsd-inline-button,
946
+ .rmsd-menu.skin-classic .rmsd-inline-button {
947
+ min-height: 35px;
948
+ border-radius: 0;
949
+ color: #333333;
950
+ font-weight: 400;
951
+ padding: 10px;
952
+ }
953
+
954
+ .theme-classic .rmsd-inline-button:hover,
955
+ .skin-classic .rmsd-inline-button:hover,
956
+ .rmsd-menu.theme-classic .rmsd-inline-button:hover,
957
+ .rmsd-menu.skin-classic .rmsd-inline-button:hover {
958
+ background: #f5f5f5;
959
+ }
960
+
961
+ .theme-classic .rmsd-list,
962
+ .skin-classic .rmsd-list,
963
+ .rmsd-menu.theme-classic .rmsd-list,
964
+ .rmsd-menu.skin-classic .rmsd-list {
965
+ margin: 0;
966
+ padding: 0;
967
+ background: #ffffff;
968
+ }
969
+
970
+ .theme-classic .rmsd-option,
971
+ .skin-classic .rmsd-option,
972
+ .rmsd-menu.theme-classic .rmsd-option,
973
+ .rmsd-menu.skin-classic .rmsd-option {
974
+ border-radius: 0;
975
+ margin: 0;
976
+ padding: 10px;
977
+ color: #333333;
978
+ line-height: 1.35;
979
+ }
980
+
981
+ .theme-classic .rmsd-option:hover,
982
+ .skin-classic .rmsd-option:hover,
983
+ .rmsd-menu.theme-classic .rmsd-option:hover,
984
+ .rmsd-menu.skin-classic .rmsd-option:hover {
985
+ background: #f5f5f5;
986
+ }
987
+
988
+ .theme-classic .rmsd-option.rmsd-selected,
989
+ .skin-classic .rmsd-option.rmsd-selected,
990
+ .rmsd-menu.theme-classic .rmsd-option.rmsd-selected,
991
+ .rmsd-menu.skin-classic .rmsd-option.rmsd-selected {
992
+ background: #e9f4ff;
993
+ color: #333333;
994
+ }
995
+
996
+ .theme-classic .rmsd-checkbox,
997
+ .skin-classic .rmsd-checkbox,
998
+ .rmsd-menu.theme-classic .rmsd-checkbox,
999
+ .rmsd-menu.skin-classic .rmsd-checkbox {
1000
+ width: 14px;
1001
+ height: 14px;
1002
+ border: 2px solid #0079fe;
1003
+ border-radius: 0;
1004
+ background: #ffffff;
1005
+ }
1006
+
1007
+ .theme-classic .rmsd-checkbox[data-checked="true"],
1008
+ .skin-classic .rmsd-checkbox[data-checked="true"],
1009
+ .rmsd-menu.theme-classic .rmsd-checkbox[data-checked="true"],
1010
+ .rmsd-menu.skin-classic .rmsd-checkbox[data-checked="true"] {
1011
+ border-color: #0079fe;
1012
+ background: #0079fe;
1013
+ }
1014
+
1015
+ .theme-classic .rmsd-checkbox[data-checked="true"]::after,
1016
+ .skin-classic .rmsd-checkbox[data-checked="true"]::after,
1017
+ .rmsd-menu.theme-classic .rmsd-checkbox[data-checked="true"]::after,
1018
+ .rmsd-menu.skin-classic .rmsd-checkbox[data-checked="true"]::after {
1019
+ top: 50%;
1020
+ left: 50%;
1021
+ width: 8px;
1022
+ height: 3px;
1023
+ margin-top: 0;
1024
+ border-width: 0 0 3px 3px;
1025
+ transform: translate(-50%, -58%) rotate(-45deg);
1026
+ }
1027
+
1028
+ .theme-classic .rmsd-option-label,
1029
+ .skin-classic .rmsd-option-label,
1030
+ .rmsd-menu.theme-classic .rmsd-option-label,
1031
+ .rmsd-menu.skin-classic .rmsd-option-label {
1032
+ color: #000000;
1033
+ font-weight: 300;
1034
+ }
1035
+
1036
+ .theme-classic .rmsd-group-header,
1037
+ .skin-classic .rmsd-group-header,
1038
+ .rmsd-menu.theme-classic .rmsd-group-header,
1039
+ .rmsd-menu.skin-classic .rmsd-group-header {
1040
+ color: #000000;
1041
+ font-size: 14px;
1042
+ font-weight: 700;
1043
+ letter-spacing: 0;
1044
+ text-transform: capitalize;
1045
+ }
1046
+
1047
+ .custom-class-example {
1048
+ --rmsd-primary: #0f766e;
1049
+ --rmsd-primary-soft: #ccfbf1;
1050
+ --rmsd-bg: #f8fffd;
1051
+ --rmsd-surface: #ecfdf5;
1052
+ --rmsd-border: #99f6e4;
1053
+ --rmsd-border-strong: #0f766e;
1054
+ }
1055
+
1056
+ @media (max-width: 720px) {
1057
+ .rmsd-trigger {
1058
+ align-items: flex-start;
1059
+ padding-right: 54px;
1060
+ }
1061
+ }
1062
+ `;
1063
+ function ensureDropdownStyles() {
1064
+ if (typeof document === "undefined") {
1065
+ return;
1066
+ }
1067
+ if (document.getElementById(STYLE_ID)) {
1068
+ return;
1069
+ }
1070
+ const tag = document.createElement("style");
1071
+ tag.id = STYLE_ID;
1072
+ tag.textContent = styles;
1073
+ document.head.appendChild(tag);
1074
+ }
1075
+
1076
+ // src/MultiSelectDropdown.tsx
1077
+ var import_jsx_runtime = require("react/jsx-runtime");
1078
+ var DEFAULT_SETTINGS = {
1079
+ singleSelection: false,
1080
+ text: "Select",
1081
+ enableCheckAll: true,
1082
+ selectAllText: "Select All",
1083
+ unSelectAllText: "Unselect All",
1084
+ filterSelectAllText: "Select filtered",
1085
+ filterUnSelectAllText: "Unselect filtered",
1086
+ enableFilterSelectAll: true,
1087
+ enableSearchFilter: false,
1088
+ searchBy: [],
1089
+ maxHeight: 300,
1090
+ badgeShowLimit: Number.MAX_SAFE_INTEGER,
1091
+ classes: "",
1092
+ limitSelection: 0,
1093
+ disabled: false,
1094
+ searchPlaceholderText: "Search",
1095
+ groupBy: "",
1096
+ showCheckbox: true,
1097
+ noDataLabel: "No Data Available",
1098
+ searchAutofocus: true,
1099
+ lazyLoading: false,
1100
+ labelKey: "itemName",
1101
+ primaryKey: "id",
1102
+ position: "bottom",
1103
+ autoPosition: true,
1104
+ loading: false,
1105
+ selectGroup: false,
1106
+ addNewItemOnFilter: false,
1107
+ addNewButtonText: "Add",
1108
+ escapeToClose: true,
1109
+ clearAll: true,
1110
+ closeDropDownOnSelection: false,
1111
+ tagToBody: false,
1112
+ appendToBody: false,
1113
+ theme: "",
1114
+ skin: "classic",
1115
+ ariaLabel: "Multiselect dropdown",
1116
+ listboxAriaLabel: "Dropdown options",
1117
+ searchAriaLabel: "Search options",
1118
+ clearSearchAriaLabel: "Clear search",
1119
+ clearAllAriaLabel: "Clear selected options",
1120
+ removeItemAriaLabel: "Remove selected option",
1121
+ openDropdownAriaLabel: "Open dropdown",
1122
+ closeDropdownAriaLabel: "Close dropdown",
1123
+ loadingText: "Loading options"
1124
+ };
1125
+ var useClientLayoutEffect = typeof window === "undefined" ? import_react.useEffect : import_react.useLayoutEffect;
1126
+ function StacklineIcon({ name, className = "rmsd-icon" }) {
1127
+ if (name === "remove") {
1128
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className, viewBox: "0 0 47.971 47.971", focusable: "false", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M28.228,23.986L47.092,5.122c1.172-1.171,1.172-3.071,0-4.242c-1.172-1.172-3.07-1.172-4.242,0L23.986,19.744L5.121,0.88c-1.172-1.172-3.07-1.172-4.242,0c-1.172,1.171-1.172,3.071,0,4.242l18.865,18.864L0.879,42.85c-1.172,1.171-1.172,3.071,0,4.242C1.465,47.677,2.233,47.97,3,47.97s1.535-0.293,2.121-0.879l18.865-18.864L42.85,47.091c0.586,0.586,1.354,0.879,2.121,0.879s1.535-0.293,2.121-0.879c1.172-1.171,1.172-3.071,0-4.242L28.228,23.986z" }) });
1129
+ }
1130
+ if (name === "clear") {
1131
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className, viewBox: "0 0 51.976 51.976", focusable: "false", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M44.373,7.603c-10.137-10.137-26.632-10.138-36.77,0c-10.138,10.138-10.137,26.632,0,36.77s26.632,10.138,36.77,0C54.51,34.235,54.51,17.74,44.373,7.603z M36.241,36.241c-0.781,0.781-2.047,0.781-2.828,0l-7.425-7.425l-7.778,7.778c-0.781,0.781-2.047,0.781-2.828,0c-0.781-0.781-0.781-2.047,0-2.828l7.778-7.778l-7.425-7.425c-0.781-0.781-0.781-2.048,0-2.828c0.781-0.781,2.047-0.781,2.828,0l7.425,7.425l7.071-7.071c0.781-0.781,2.047-0.781,2.828,0c0.781,0.781,0.781,2.047,0,2.828l-7.071,7.071l7.425,7.425C37.022,34.194,37.022,35.46,36.241,36.241z" }) });
1132
+ }
1133
+ if (name === "search") {
1134
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className, viewBox: "0 0 615.52 615.52", focusable: "false", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M602.531,549.736l-184.31-185.368c26.679-37.72,42.528-83.729,42.528-133.548C460.75,103.35,357.997,0,231.258,0C104.518,0,1.765,103.35,1.765,230.82c0,127.47,102.753,230.82,229.493,230.82c49.53,0,95.271-15.944,132.78-42.777l184.31,185.366c7.482,7.521,17.292,11.291,27.102,11.291c9.812,0,19.62-3.77,27.083-11.291C617.496,589.188,617.496,564.777,602.531,549.736z M355.9,319.763l-15.042,21.273L319.7,356.174c-26.083,18.658-56.667,28.526-88.442,28.526c-84.365,0-152.995-69.035-152.995-153.88c0-84.846,68.63-153.88,152.995-153.88s152.996,69.034,152.996,153.88C384.271,262.769,374.462,293.526,355.9,319.763z" }) });
1135
+ }
1136
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { className, viewBox: "0 0 612 612", focusable: "false", "aria-hidden": "true", children: name === "angle-up" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M604.501,440.509L325.398,134.956c-5.331-5.357-12.423-7.627-19.386-7.27c-6.989-0.357-14.056,1.913-19.387,7.27L7.499,440.509c-9.999,10.024-9.999,26.298,0,36.323s26.223,10.024,36.222,0l262.293-287.164L568.28,476.832c9.999,10.024,26.222,10.024,36.221,0C614.5,466.809,614.5,450.534,604.501,440.509z" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M604.501,134.782c-9.999-10.05-26.222-10.05-36.221,0L306.014,422.558L43.721,134.782c-9.999-10.05-26.223-10.05-36.222,0s-9.999,26.35,0,36.399l279.103,306.241c5.331,5.357,12.422,7.652,19.386,7.296c6.988,0.356,14.055-1.939,19.386-7.296l279.128-306.268C614.5,161.106,614.5,144.832,604.501,134.782z" }) });
1137
+ }
1138
+ function isPrimitiveItem(item) {
1139
+ return typeof item === "string" || typeof item === "number" || typeof item === "boolean";
1140
+ }
1141
+ function getLabel(item, settings) {
1142
+ if (isPrimitiveItem(item)) {
1143
+ return String(item);
1144
+ }
1145
+ const keys = [settings.labelKey, "itemName", "name", "label", "title", "value"].filter(Boolean);
1146
+ for (const key of keys) {
1147
+ if (key && item[key] != null) {
1148
+ return String(item[key]);
1149
+ }
1150
+ }
1151
+ return JSON.stringify(item);
1152
+ }
1153
+ function getPrimaryValue(item, settings) {
1154
+ if (isPrimitiveItem(item)) {
1155
+ return String(item);
1156
+ }
1157
+ const keys = [settings.primaryKey, "id", "value", "key"].filter(Boolean);
1158
+ for (const key of keys) {
1159
+ if (key && item[key] != null) {
1160
+ return String(item[key]);
1161
+ }
1162
+ }
1163
+ return getLabel(item, settings);
1164
+ }
1165
+ function itemMatchesQuery(item, query, settings) {
1166
+ if (!query.trim()) {
1167
+ return true;
1168
+ }
1169
+ const needle = query.trim().toLowerCase();
1170
+ const haystack = /* @__PURE__ */ new Set();
1171
+ haystack.add(getLabel(item, settings).toLowerCase());
1172
+ if (!isPrimitiveItem(item)) {
1173
+ const searchKeys = settings.searchBy.length ? settings.searchBy : [settings.labelKey];
1174
+ for (const key of searchKeys) {
1175
+ if (key && item[key] != null) {
1176
+ haystack.add(String(item[key]).toLowerCase());
1177
+ }
1178
+ }
1179
+ }
1180
+ for (const value of haystack) {
1181
+ if (value.includes(needle)) {
1182
+ return true;
1183
+ }
1184
+ }
1185
+ return false;
1186
+ }
1187
+ function getGroupName(item, settings) {
1188
+ if (!settings.groupBy) {
1189
+ return "";
1190
+ }
1191
+ if (typeof settings.groupBy === "function") {
1192
+ return settings.groupBy(item);
1193
+ }
1194
+ if (!isPrimitiveItem(item)) {
1195
+ const groupKey = settings.groupBy;
1196
+ const objectItem = item;
1197
+ if (groupKey in objectItem) {
1198
+ return String(objectItem[groupKey] ?? "");
1199
+ }
1200
+ }
1201
+ return "";
1202
+ }
1203
+ function mergeUniqueItems(base, extra, settings) {
1204
+ const bucket = /* @__PURE__ */ new Map();
1205
+ for (const item of [...base, ...extra]) {
1206
+ bucket.set(getPrimaryValue(item, settings), item);
1207
+ }
1208
+ return Array.from(bucket.values());
1209
+ }
1210
+ function createItemFromQuery(query, settings, sample) {
1211
+ if (sample && !isPrimitiveItem(sample)) {
1212
+ return {
1213
+ [settings.primaryKey]: query.toLowerCase().replace(/\s+/g, "-"),
1214
+ [settings.labelKey]: query
1215
+ };
1216
+ }
1217
+ return query;
1218
+ }
1219
+ function isDisabledItem(item) {
1220
+ return !isPrimitiveItem(item) && Boolean(item.disabled);
1221
+ }
1222
+ function buildGroups(items, settings) {
1223
+ if (!settings.groupBy) {
1224
+ return [];
1225
+ }
1226
+ const map = /* @__PURE__ */ new Map();
1227
+ for (const item of items) {
1228
+ const groupName = getGroupName(item, settings) || "Ungrouped";
1229
+ const current = map.get(groupName) || [];
1230
+ current.push(item);
1231
+ map.set(groupName, current);
1232
+ }
1233
+ return Array.from(map.entries()).map(([name, groupedItems]) => ({
1234
+ name,
1235
+ items: groupedItems
1236
+ }));
1237
+ }
1238
+ function useControllableSelection(controlledValue, defaultValue, onChange) {
1239
+ const [internalValue, setInternalValue] = (0, import_react.useState)(defaultValue ?? []);
1240
+ const isControlled = controlledValue !== void 0;
1241
+ const value = isControlled ? controlledValue : internalValue;
1242
+ const setValue = (nextValue) => {
1243
+ if (!isControlled) {
1244
+ setInternalValue(nextValue);
1245
+ }
1246
+ onChange?.(nextValue);
1247
+ };
1248
+ return [value, setValue];
1249
+ }
1250
+ function sanitizeId(value) {
1251
+ return value.replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 56) || "option";
1252
+ }
1253
+ function normalizeSkinName(value) {
1254
+ return sanitizeId(value.toLowerCase()) || "classic";
1255
+ }
1256
+ function getVisibleBadgeLimit(selectedCount, rawLimit) {
1257
+ if (!Number.isFinite(rawLimit)) {
1258
+ return selectedCount;
1259
+ }
1260
+ const limit = Math.max(0, Math.floor(rawLimit));
1261
+ return Math.min(selectedCount, limit);
1262
+ }
1263
+ function InnerMultiSelectDropdown({
1264
+ data,
1265
+ settings: incomingSettings,
1266
+ loading,
1267
+ className,
1268
+ style,
1269
+ selectedItems: controlledSelectedItems,
1270
+ defaultSelectedItems,
1271
+ onChange,
1272
+ onSelect,
1273
+ onDeSelect,
1274
+ onSelectAll,
1275
+ onDeSelectAll,
1276
+ onOpen,
1277
+ onClose,
1278
+ onScrollToEnd,
1279
+ onFilterSelectAll,
1280
+ onFilterDeSelectAll,
1281
+ onAddFilterNewItem,
1282
+ onGroupSelect,
1283
+ onGroupDeSelect,
1284
+ renderItem,
1285
+ renderBadge,
1286
+ renderSearch,
1287
+ renderEmptyState
1288
+ }, ref) {
1289
+ ensureDropdownStyles();
1290
+ const settings = { ...DEFAULT_SETTINGS, ...incomingSettings };
1291
+ const [selectedItems, setSelectedItems] = useControllableSelection(
1292
+ controlledSelectedItems,
1293
+ defaultSelectedItems,
1294
+ onChange
1295
+ );
1296
+ const [isOpen, setIsOpen] = (0, import_react.useState)(false);
1297
+ const [filter, setFilter] = (0, import_react.useState)("");
1298
+ const [addedItems, setAddedItems] = (0, import_react.useState)([]);
1299
+ const [activeDescendantId, setActiveDescendantId] = (0, import_react.useState)(null);
1300
+ const [bodyMenuStyle, setBodyMenuStyle] = (0, import_react.useState)();
1301
+ const [bodyListMaxHeight, setBodyListMaxHeight] = (0, import_react.useState)();
1302
+ const [effectivePosition, setEffectivePosition] = (0, import_react.useState)(
1303
+ settings.position === "top" ? "top" : "bottom"
1304
+ );
1305
+ const rootRef = (0, import_react.useRef)(null);
1306
+ const triggerRef = (0, import_react.useRef)(null);
1307
+ const menuRef = (0, import_react.useRef)(null);
1308
+ const searchRef = (0, import_react.useRef)(null);
1309
+ const listRef = (0, import_react.useRef)(null);
1310
+ const lastScrollHeightRef = (0, import_react.useRef)(0);
1311
+ const pendingFocusRef = (0, import_react.useRef)(null);
1312
+ const instanceIdRef = (0, import_react.useRef)(`rmsd-${Math.random().toString(36).slice(2)}`);
1313
+ const allItems = (0, import_react.useMemo)(
1314
+ () => mergeUniqueItems(data, addedItems, settings),
1315
+ [addedItems, data, settings]
1316
+ );
1317
+ const filteredItems = (0, import_react.useMemo)(
1318
+ () => allItems.filter((item) => itemMatchesQuery(item, filter, settings)),
1319
+ [allItems, filter, settings]
1320
+ );
1321
+ const groupedItems = (0, import_react.useMemo)(() => buildGroups(filteredItems, settings), [filteredItems, settings]);
1322
+ const listboxId = `${instanceIdRef.current}-listbox`;
1323
+ const getOptionId = (item, index, prefix) => `${instanceIdRef.current}-${prefix}-${index}-${sanitizeId(getPrimaryValue(item, settings))}`;
1324
+ const isSelected = (item) => selectedItems.some(
1325
+ (selectedItem) => getPrimaryValue(selectedItem, settings) === getPrimaryValue(item, settings)
1326
+ );
1327
+ const selectableItems = filteredItems.filter((item) => !isDisabledItem(item));
1328
+ const limitReached = Boolean(settings.limitSelection) && selectedItems.length >= settings.limitSelection;
1329
+ const shouldAppendToBody = Boolean(settings.appendToBody || settings.tagToBody);
1330
+ const getOptionElements = () => Array.from(
1331
+ listRef.current?.querySelectorAll('[data-rmsd-option="true"]:not([aria-disabled="true"])') ?? []
1332
+ );
1333
+ const focusOptionByIndex = (index) => {
1334
+ const options = getOptionElements();
1335
+ if (!options.length) {
1336
+ return;
1337
+ }
1338
+ const boundedIndex = Math.max(0, Math.min(index, options.length - 1));
1339
+ const option = options[boundedIndex];
1340
+ option.focus();
1341
+ setActiveDescendantId(option.id || null);
1342
+ option.scrollIntoView({ block: "nearest" });
1343
+ };
1344
+ const focusFirstOption = () => focusOptionByIndex(0);
1345
+ const focusLastOption = () => focusOptionByIndex(getOptionElements().length - 1);
1346
+ const updateSelection = (nextItems) => {
1347
+ setSelectedItems(nextItems);
1348
+ };
1349
+ const openDropdown = (focusTarget = "search") => {
1350
+ if (settings.disabled) {
1351
+ return;
1352
+ }
1353
+ pendingFocusRef.current = focusTarget;
1354
+ setIsOpen((current) => {
1355
+ if (!current) {
1356
+ onOpen?.();
1357
+ }
1358
+ return true;
1359
+ });
1360
+ };
1361
+ const closeDropdown = (returnFocus = false) => {
1362
+ setIsOpen((current) => {
1363
+ if (current) {
1364
+ onClose?.();
1365
+ }
1366
+ return false;
1367
+ });
1368
+ setActiveDescendantId(null);
1369
+ setBodyMenuStyle(void 0);
1370
+ setBodyListMaxHeight(void 0);
1371
+ if (returnFocus) {
1372
+ window.setTimeout(() => triggerRef.current?.focus(), 0);
1373
+ }
1374
+ };
1375
+ const clearSelection = () => {
1376
+ const previousItems = selectedItems;
1377
+ updateSelection([]);
1378
+ onDeSelectAll?.(previousItems);
1379
+ };
1380
+ const toggleDropdown = () => {
1381
+ if (isOpen) {
1382
+ closeDropdown();
1383
+ } else {
1384
+ openDropdown("search");
1385
+ }
1386
+ };
1387
+ const removeItem = (item) => {
1388
+ const nextItems = selectedItems.filter(
1389
+ (selectedItem) => getPrimaryValue(selectedItem, settings) !== getPrimaryValue(item, settings)
1390
+ );
1391
+ updateSelection(nextItems);
1392
+ onDeSelect?.(item);
1393
+ };
1394
+ const selectItem = (item) => {
1395
+ if (settings.disabled || isDisabledItem(item)) {
1396
+ return;
1397
+ }
1398
+ if (isSelected(item)) {
1399
+ removeItem(item);
1400
+ return;
1401
+ }
1402
+ if (settings.singleSelection) {
1403
+ updateSelection([item]);
1404
+ onSelect?.(item);
1405
+ closeDropdown(true);
1406
+ return;
1407
+ }
1408
+ if (settings.limitSelection && selectedItems.length >= settings.limitSelection) {
1409
+ return;
1410
+ }
1411
+ const nextItems = [...selectedItems, item];
1412
+ updateSelection(nextItems);
1413
+ onSelect?.(item);
1414
+ if (settings.closeDropDownOnSelection) {
1415
+ closeDropdown(true);
1416
+ }
1417
+ };
1418
+ const selectAllItems = (items, filteredSelection = false) => {
1419
+ if (settings.singleSelection) {
1420
+ return;
1421
+ }
1422
+ const currentIds = new Set(selectedItems.map((item) => getPrimaryValue(item, settings)));
1423
+ const remainingCapacity = settings.limitSelection ? Math.max(settings.limitSelection - selectedItems.length, 0) : Number.MAX_SAFE_INTEGER;
1424
+ const nextItemsToAdd = items.filter((item) => !currentIds.has(getPrimaryValue(item, settings))).filter((item) => !isDisabledItem(item)).slice(0, remainingCapacity);
1425
+ const nextItems = [...selectedItems, ...nextItemsToAdd];
1426
+ updateSelection(nextItems);
1427
+ if (filteredSelection) {
1428
+ onFilterSelectAll?.(nextItemsToAdd);
1429
+ } else {
1430
+ onSelectAll?.(nextItems);
1431
+ }
1432
+ };
1433
+ const deSelectAllItems = (items, filteredSelection = false) => {
1434
+ const ids = new Set(items.map((item) => getPrimaryValue(item, settings)));
1435
+ const nextItems = selectedItems.filter((item) => !ids.has(getPrimaryValue(item, settings)));
1436
+ updateSelection(nextItems);
1437
+ if (filteredSelection) {
1438
+ onFilterDeSelectAll?.(items);
1439
+ } else {
1440
+ onDeSelectAll?.(items);
1441
+ }
1442
+ };
1443
+ const handleAddFilterNewItem = async () => {
1444
+ const query = filter.trim();
1445
+ if (!query) {
1446
+ return;
1447
+ }
1448
+ const result = await onAddFilterNewItem?.(query);
1449
+ const nextItem = result === void 0 ? createItemFromQuery(query, settings, data[0]) : result;
1450
+ setAddedItems((currentItems) => mergeUniqueItems(currentItems, [nextItem], settings));
1451
+ if (settings.singleSelection) {
1452
+ updateSelection([nextItem]);
1453
+ } else {
1454
+ updateSelection(mergeUniqueItems(selectedItems, [nextItem], settings));
1455
+ }
1456
+ setFilter("");
1457
+ };
1458
+ const toggleGroup = (groupName, items) => {
1459
+ const groupItems = items.filter((item) => !isDisabledItem(item));
1460
+ const allSelected = groupItems.length > 0 && groupItems.every((item) => isSelected(item));
1461
+ if (allSelected) {
1462
+ deSelectAllItems(groupItems, false);
1463
+ onGroupDeSelect?.(groupName, groupItems);
1464
+ return;
1465
+ }
1466
+ selectAllItems(groupItems, false);
1467
+ onGroupSelect?.(groupName, groupItems);
1468
+ };
1469
+ const handleListScroll = () => {
1470
+ if (!listRef.current || !onScrollToEnd) {
1471
+ return;
1472
+ }
1473
+ const { scrollHeight, scrollTop, clientHeight } = listRef.current;
1474
+ if (scrollHeight === lastScrollHeightRef.current && scrollTop + clientHeight < scrollHeight - 12) {
1475
+ return;
1476
+ }
1477
+ if (scrollTop + clientHeight >= scrollHeight - 12) {
1478
+ lastScrollHeightRef.current = scrollHeight;
1479
+ onScrollToEnd({ scrollTop, scrollHeight, clientHeight });
1480
+ }
1481
+ };
1482
+ const resolveDropdownPosition = (triggerRect, menuHeight) => {
1483
+ const preferredPosition = settings.position === "top" ? "top" : "bottom";
1484
+ if (!settings.autoPosition || typeof window === "undefined" || typeof document === "undefined") {
1485
+ return preferredPosition;
1486
+ }
1487
+ const viewportHeight = window.innerHeight || document.documentElement.clientHeight;
1488
+ const spaceOnTop = triggerRect.top;
1489
+ const spaceOnBottom = viewportHeight - triggerRect.bottom;
1490
+ const topHasMeaningfullyMoreRoom = spaceOnTop > spaceOnBottom + 48;
1491
+ if (spaceOnBottom < menuHeight && topHasMeaningfullyMoreRoom && menuHeight < spaceOnTop) {
1492
+ return "top";
1493
+ }
1494
+ return "bottom";
1495
+ };
1496
+ (0, import_react.useEffect)(() => {
1497
+ if (!isOpen) {
1498
+ return;
1499
+ }
1500
+ const handlePointerDown = (event) => {
1501
+ const target = event.target;
1502
+ if (!rootRef.current?.contains(target) && !menuRef.current?.contains(target)) {
1503
+ closeDropdown();
1504
+ }
1505
+ };
1506
+ const handleKeyDown = (event) => {
1507
+ if (event.key === "Escape" && settings.escapeToClose) {
1508
+ closeDropdown(true);
1509
+ }
1510
+ };
1511
+ document.addEventListener("mousedown", handlePointerDown);
1512
+ document.addEventListener("touchstart", handlePointerDown);
1513
+ document.addEventListener("keydown", handleKeyDown);
1514
+ return () => {
1515
+ document.removeEventListener("mousedown", handlePointerDown);
1516
+ document.removeEventListener("touchstart", handlePointerDown);
1517
+ document.removeEventListener("keydown", handleKeyDown);
1518
+ };
1519
+ }, [isOpen, settings.escapeToClose]);
1520
+ const updateBodyMenuPosition = () => {
1521
+ if (!shouldAppendToBody || !triggerRef.current || typeof window === "undefined") {
1522
+ return;
1523
+ }
1524
+ const gap = 8;
1525
+ const viewportPadding = 8;
1526
+ const triggerRect = triggerRef.current.getBoundingClientRect();
1527
+ const menuHeight = menuRef.current?.offsetHeight ?? 0;
1528
+ const listHeight = listRef.current?.offsetHeight ?? Math.min(settings.maxHeight, menuHeight);
1529
+ const nonListHeight = Math.max(0, menuHeight - listHeight);
1530
+ const resolvedPosition = resolveDropdownPosition(triggerRect, menuHeight);
1531
+ const availableHeight = resolvedPosition === "top" ? Math.max(0, triggerRect.top - gap - viewportPadding) : Math.max(0, window.innerHeight - triggerRect.bottom - gap - viewportPadding);
1532
+ const nextListMaxHeight = menuHeight > 0 ? Math.max(0, Math.min(settings.maxHeight, availableHeight - nonListHeight)) : settings.maxHeight;
1533
+ const positionedMenuHeight = nonListHeight + nextListMaxHeight;
1534
+ const preferredTop = resolvedPosition === "top" ? triggerRect.top - positionedMenuHeight - gap : triggerRect.bottom + gap;
1535
+ const top = resolvedPosition === "top" ? Math.max(viewportPadding, preferredTop) : preferredTop;
1536
+ setEffectivePosition((current) => current === resolvedPosition ? current : resolvedPosition);
1537
+ setBodyListMaxHeight((current) => current === nextListMaxHeight ? current : nextListMaxHeight);
1538
+ const maxWidth = Math.max(0, window.innerWidth - viewportPadding * 2);
1539
+ const width = Math.min(triggerRect.width, maxWidth);
1540
+ const left = Math.min(Math.max(viewportPadding, triggerRect.left), window.innerWidth - width - viewportPadding);
1541
+ setBodyMenuStyle({
1542
+ position: "fixed",
1543
+ top,
1544
+ left,
1545
+ width,
1546
+ maxWidth,
1547
+ zIndex: 1e5
1548
+ });
1549
+ };
1550
+ const updateLocalMenuPosition = () => {
1551
+ if (!triggerRef.current || !menuRef.current || shouldAppendToBody) {
1552
+ return;
1553
+ }
1554
+ setBodyListMaxHeight((current) => current === void 0 ? current : void 0);
1555
+ const triggerRect = triggerRef.current.getBoundingClientRect();
1556
+ const menuHeight = menuRef.current.offsetHeight;
1557
+ const resolvedPosition = resolveDropdownPosition(triggerRect, menuHeight);
1558
+ setEffectivePosition((current) => current === resolvedPosition ? current : resolvedPosition);
1559
+ };
1560
+ useClientLayoutEffect(() => {
1561
+ if (!isOpen) {
1562
+ return;
1563
+ }
1564
+ if (shouldAppendToBody) {
1565
+ updateBodyMenuPosition();
1566
+ return;
1567
+ }
1568
+ updateLocalMenuPosition();
1569
+ }, [
1570
+ isOpen,
1571
+ shouldAppendToBody,
1572
+ settings.position,
1573
+ settings.autoPosition,
1574
+ settings.maxHeight,
1575
+ filteredItems.length,
1576
+ selectedItems.length,
1577
+ filter
1578
+ ]);
1579
+ (0, import_react.useEffect)(() => {
1580
+ if (!isOpen || !shouldAppendToBody || typeof window === "undefined") {
1581
+ return;
1582
+ }
1583
+ const update = () => updateBodyMenuPosition();
1584
+ const rafUpdate = () => window.requestAnimationFrame(update);
1585
+ window.addEventListener("resize", rafUpdate);
1586
+ window.addEventListener("scroll", rafUpdate, true);
1587
+ const observer = typeof ResizeObserver !== "undefined" && menuRef.current ? new ResizeObserver(rafUpdate) : null;
1588
+ if (observer && menuRef.current) {
1589
+ observer.observe(menuRef.current);
1590
+ }
1591
+ return () => {
1592
+ window.removeEventListener("resize", rafUpdate);
1593
+ window.removeEventListener("scroll", rafUpdate, true);
1594
+ observer?.disconnect();
1595
+ };
1596
+ }, [
1597
+ isOpen,
1598
+ shouldAppendToBody,
1599
+ settings.position,
1600
+ settings.autoPosition,
1601
+ settings.maxHeight,
1602
+ filteredItems.length,
1603
+ selectedItems.length
1604
+ ]);
1605
+ (0, import_react.useEffect)(() => {
1606
+ if (!isOpen) {
1607
+ return;
1608
+ }
1609
+ const pendingFocus = pendingFocusRef.current;
1610
+ pendingFocusRef.current = null;
1611
+ window.setTimeout(() => {
1612
+ if (pendingFocus === "first") {
1613
+ focusFirstOption();
1614
+ return;
1615
+ }
1616
+ if (pendingFocus === "last") {
1617
+ focusLastOption();
1618
+ return;
1619
+ }
1620
+ if (settings.enableSearchFilter && settings.searchAutofocus) {
1621
+ searchRef.current?.focus();
1622
+ }
1623
+ }, 0);
1624
+ }, [isOpen, filteredItems.length, settings.enableSearchFilter, settings.searchAutofocus]);
1625
+ (0, import_react.useEffect)(() => {
1626
+ lastScrollHeightRef.current = 0;
1627
+ }, [filteredItems.length]);
1628
+ (0, import_react.useImperativeHandle)(
1629
+ ref,
1630
+ () => ({
1631
+ openDropdown: () => openDropdown("search"),
1632
+ closeDropdown: () => closeDropdown(),
1633
+ clearSelection,
1634
+ focusSearch: () => {
1635
+ openDropdown("search");
1636
+ window.setTimeout(() => searchRef.current?.focus(), 0);
1637
+ },
1638
+ selectAll: () => selectAllItems(selectableItems),
1639
+ deSelectAll: () => deSelectAllItems(selectedItems),
1640
+ getSelectedItems: () => selectedItems
1641
+ }),
1642
+ [selectableItems, selectedItems]
1643
+ );
1644
+ const selectedCount = selectedItems.length;
1645
+ const visibleBadgeLimit = getVisibleBadgeLimit(selectedCount, settings.badgeShowLimit);
1646
+ const visibleBadges = settings.singleSelection ? selectedItems : selectedItems.slice(0, visibleBadgeLimit);
1647
+ const hiddenBadgeCount = settings.singleSelection ? 0 : Math.max(selectedCount - visibleBadges.length, 0);
1648
+ const hasFilteredResults = filteredItems.length > 0;
1649
+ const allFilteredSelected = selectableItems.length > 0 && selectableItems.every((item) => isSelected(item));
1650
+ const hasBulkActions = settings.enableCheckAll && !settings.singleSelection || Boolean(settings.addNewItemOnFilter && filter.trim());
1651
+ const skinName = normalizeSkinName(String(settings.skin || settings.theme || "classic"));
1652
+ const skinFallbackClass = ["classic", "material", "dark", "custom"].includes(skinName) ? "" : "theme-custom";
1653
+ const rootClassName = [
1654
+ "rmsd-root",
1655
+ `skin-${skinName}`,
1656
+ `theme-${skinName}`,
1657
+ skinFallbackClass,
1658
+ isOpen ? "rmsd-open" : "",
1659
+ hiddenBadgeCount > 0 ? "rmsd-has-overflow" : "",
1660
+ settings.clearAll && selectedItems.length > 0 && !settings.disabled ? "rmsd-has-clear" : "",
1661
+ effectivePosition === "top" ? "rmsd-opens-up" : "rmsd-opens-down",
1662
+ settings.classes,
1663
+ className
1664
+ ].filter(Boolean).join(" ");
1665
+ const getRemoveItemAriaLabel = (item) => {
1666
+ if (typeof settings.removeItemAriaLabel === "function") {
1667
+ return settings.removeItemAriaLabel(item);
1668
+ }
1669
+ return `${settings.removeItemAriaLabel}: ${getLabel(item, settings)}`;
1670
+ };
1671
+ const getTriggerAriaLabel = () => {
1672
+ if (!selectedItems.length) {
1673
+ return settings.ariaLabel;
1674
+ }
1675
+ return `${settings.ariaLabel}: ${selectedItems.map((item) => getLabel(item, settings)).join(", ")}`;
1676
+ };
1677
+ const stopInlineKey = (event) => {
1678
+ if (event.key === "Enter" || event.key === " ") {
1679
+ event.stopPropagation();
1680
+ }
1681
+ };
1682
+ const handleTriggerKeyDown = (event) => {
1683
+ if (settings.disabled) {
1684
+ return;
1685
+ }
1686
+ if (event.key === "Enter" || event.key === " ") {
1687
+ event.preventDefault();
1688
+ toggleDropdown();
1689
+ return;
1690
+ }
1691
+ if (event.key === "ArrowDown") {
1692
+ event.preventDefault();
1693
+ if (!isOpen) {
1694
+ openDropdown("first");
1695
+ } else {
1696
+ focusFirstOption();
1697
+ }
1698
+ return;
1699
+ }
1700
+ if (event.key === "ArrowUp") {
1701
+ event.preventDefault();
1702
+ if (!isOpen) {
1703
+ openDropdown("last");
1704
+ } else {
1705
+ focusLastOption();
1706
+ }
1707
+ return;
1708
+ }
1709
+ if (event.key === "Escape" && isOpen) {
1710
+ event.preventDefault();
1711
+ closeDropdown(true);
1712
+ }
1713
+ };
1714
+ const handleArrowButtonKeyDown = (event) => {
1715
+ if (event.key === "Enter" || event.key === " ") {
1716
+ event.preventDefault();
1717
+ event.stopPropagation();
1718
+ toggleDropdown();
1719
+ return;
1720
+ }
1721
+ if (event.key === "ArrowDown") {
1722
+ event.preventDefault();
1723
+ event.stopPropagation();
1724
+ openDropdown("first");
1725
+ return;
1726
+ }
1727
+ if (event.key === "ArrowUp") {
1728
+ event.preventDefault();
1729
+ event.stopPropagation();
1730
+ openDropdown("last");
1731
+ }
1732
+ };
1733
+ const handleSearchKeyDown = (event) => {
1734
+ if (event.key === "ArrowDown") {
1735
+ event.preventDefault();
1736
+ focusFirstOption();
1737
+ return;
1738
+ }
1739
+ if (event.key === "Escape" && settings.escapeToClose) {
1740
+ event.preventDefault();
1741
+ closeDropdown(true);
1742
+ }
1743
+ };
1744
+ const handleOptionKeyDown = (event, item, optionIndex) => {
1745
+ if (event.key === "Enter" || event.key === " ") {
1746
+ event.preventDefault();
1747
+ selectItem(item);
1748
+ return;
1749
+ }
1750
+ if (event.key === "ArrowDown") {
1751
+ event.preventDefault();
1752
+ const nextIndex = optionIndex + 1;
1753
+ const options = getOptionElements();
1754
+ if (nextIndex < options.length) {
1755
+ focusOptionByIndex(nextIndex);
1756
+ } else if (settings.lazyLoading) {
1757
+ handleListScroll();
1758
+ }
1759
+ return;
1760
+ }
1761
+ if (event.key === "ArrowUp") {
1762
+ event.preventDefault();
1763
+ if (optionIndex > 0) {
1764
+ focusOptionByIndex(optionIndex - 1);
1765
+ } else if (settings.enableSearchFilter) {
1766
+ searchRef.current?.focus();
1767
+ } else {
1768
+ triggerRef.current?.focus();
1769
+ }
1770
+ return;
1771
+ }
1772
+ if (event.key === "Home") {
1773
+ event.preventDefault();
1774
+ focusFirstOption();
1775
+ return;
1776
+ }
1777
+ if (event.key === "End") {
1778
+ event.preventDefault();
1779
+ focusLastOption();
1780
+ return;
1781
+ }
1782
+ if (event.key === "Escape" && settings.escapeToClose) {
1783
+ event.preventDefault();
1784
+ closeDropdown(true);
1785
+ }
1786
+ };
1787
+ const renderItemNode = (item) => {
1788
+ const context = {
1789
+ item,
1790
+ label: getLabel(item, settings),
1791
+ selected: isSelected(item),
1792
+ disabled: settings.disabled || isDisabledItem(item) || !isSelected(item) && limitReached,
1793
+ query: filter,
1794
+ toggle: () => selectItem(item),
1795
+ remove: () => removeItem(item)
1796
+ };
1797
+ return renderItem ? renderItem(item, context) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "rmsd-option-body", children: [
1798
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "rmsd-option-label", children: context.label }),
1799
+ !isPrimitiveItem(item) && item.caption ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "rmsd-option-hint", children: String(item.caption) }) : null
1800
+ ] });
1801
+ };
1802
+ const renderBadgeNode = (item) => {
1803
+ const context = {
1804
+ item,
1805
+ label: getLabel(item, settings),
1806
+ selected: true,
1807
+ disabled: settings.disabled || isDisabledItem(item),
1808
+ query: filter,
1809
+ toggle: () => selectItem(item),
1810
+ remove: () => removeItem(item)
1811
+ };
1812
+ return renderBadge ? renderBadge(item, context) : context.label;
1813
+ };
1814
+ let optionCursor = -1;
1815
+ const renderOption = (item, prefix, localIndex) => {
1816
+ const selected = isSelected(item);
1817
+ const disabled = settings.disabled || isDisabledItem(item) || limitReached && !selected;
1818
+ optionCursor += 1;
1819
+ const optionIndex = optionCursor;
1820
+ const optionId = getOptionId(item, localIndex, prefix);
1821
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1822
+ "div",
1823
+ {
1824
+ id: optionId,
1825
+ className: `rmsd-option${selected ? " rmsd-selected" : ""}${disabled ? " rmsd-disabled" : ""}`,
1826
+ role: "option",
1827
+ "aria-selected": selected,
1828
+ "aria-disabled": disabled,
1829
+ tabIndex: disabled ? -1 : 0,
1830
+ "data-rmsd-option": "true",
1831
+ onFocus: () => setActiveDescendantId(optionId),
1832
+ onClick: () => {
1833
+ if (!disabled) {
1834
+ selectItem(item);
1835
+ }
1836
+ },
1837
+ onKeyDown: (event) => handleOptionKeyDown(event, item, optionIndex),
1838
+ children: [
1839
+ settings.showCheckbox ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "rmsd-checkbox", "data-checked": selected, "aria-hidden": "true" }) : null,
1840
+ renderItemNode(item)
1841
+ ]
1842
+ },
1843
+ `${prefix}-${getPrimaryValue(item, settings)}-${localIndex}`
1844
+ );
1845
+ };
1846
+ const handleTriggerClick = (event) => {
1847
+ if (event.target.closest("button")) {
1848
+ return;
1849
+ }
1850
+ toggleDropdown();
1851
+ };
1852
+ const menu = isOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1853
+ "div",
1854
+ {
1855
+ ref: menuRef,
1856
+ className: `rmsd-menu rmsd-${effectivePosition} skin-${skinName} theme-${skinName}${skinFallbackClass ? ` ${skinFallbackClass}` : ""}${shouldAppendToBody ? " rmsd-body-overlay" : ""}`,
1857
+ style: shouldAppendToBody ? bodyMenuStyle : void 0,
1858
+ onMouseDown: (event) => event.stopPropagation(),
1859
+ onTouchStart: (event) => event.stopPropagation(),
1860
+ children: [
1861
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "rmsd-toolbar", children: [
1862
+ hasBulkActions ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "rmsd-bulk-actions", children: [
1863
+ settings.enableCheckAll && !settings.singleSelection ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1864
+ "button",
1865
+ {
1866
+ type: "button",
1867
+ className: "rmsd-inline-button rmsd-select-all-button",
1868
+ onClick: () => allFilteredSelected ? deSelectAllItems(selectableItems, Boolean(filter.trim())) : selectAllItems(selectableItems, Boolean(filter.trim())),
1869
+ disabled: settings.disabled || selectableItems.length === 0,
1870
+ children: [
1871
+ settings.showCheckbox ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "rmsd-checkbox", "data-checked": allFilteredSelected, "aria-hidden": "true" }) : null,
1872
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: allFilteredSelected ? filter.trim() ? settings.filterUnSelectAllText : settings.unSelectAllText : filter.trim() ? settings.filterSelectAllText : settings.selectAllText })
1873
+ ]
1874
+ }
1875
+ ) : null,
1876
+ settings.addNewItemOnFilter && filter.trim() ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { type: "button", className: "rmsd-inline-button rmsd-add-button", onClick: handleAddFilterNewItem, children: [
1877
+ settings.addNewButtonText,
1878
+ ' "',
1879
+ filter.trim(),
1880
+ '"'
1881
+ ] }) : null
1882
+ ] }) : null,
1883
+ settings.enableSearchFilter ? renderSearch ? renderSearch({ query: filter, setQuery: setFilter, closeDropdown: () => closeDropdown() }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "rmsd-search-shell", children: [
1884
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StacklineIcon, { name: "search", className: "rmsd-search-icon" }),
1885
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1886
+ "input",
1887
+ {
1888
+ ref: searchRef,
1889
+ className: "rmsd-search-input",
1890
+ value: filter,
1891
+ onChange: (event) => setFilter(event.target.value),
1892
+ onKeyDown: handleSearchKeyDown,
1893
+ placeholder: settings.searchPlaceholderText,
1894
+ "aria-label": settings.searchAriaLabel
1895
+ }
1896
+ ),
1897
+ filter ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1898
+ "button",
1899
+ {
1900
+ type: "button",
1901
+ className: "rmsd-search-clear",
1902
+ "aria-label": settings.clearSearchAriaLabel,
1903
+ onKeyDown: stopInlineKey,
1904
+ onClick: () => setFilter(""),
1905
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StacklineIcon, { name: "clear" })
1906
+ }
1907
+ ) : null
1908
+ ] }) : null
1909
+ ] }),
1910
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1911
+ "div",
1912
+ {
1913
+ className: "rmsd-list",
1914
+ ref: listRef,
1915
+ style: { maxHeight: shouldAppendToBody ? bodyListMaxHeight ?? settings.maxHeight : settings.maxHeight },
1916
+ onScroll: settings.lazyLoading ? handleListScroll : void 0,
1917
+ id: listboxId,
1918
+ role: "listbox",
1919
+ "aria-label": settings.listboxAriaLabel,
1920
+ "aria-multiselectable": !settings.singleSelection,
1921
+ children: loading ?? settings.loading ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "rmsd-state", role: "status", children: settings.loadingText }) : groupedItems.length > 0 ? groupedItems.map((group, groupIndex) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "rmsd-group", role: "group", "aria-label": group.name, children: [
1922
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "rmsd-group-header", children: [
1923
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
1924
+ group.name,
1925
+ " \xB7 ",
1926
+ group.items.length
1927
+ ] }),
1928
+ settings.selectGroup && !settings.singleSelection ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: "rmsd-group-action", onClick: () => toggleGroup(group.name, group.items), children: group.items.filter((item) => !isDisabledItem(item)).every((item) => isSelected(item)) ? "Unselect" : "Select" }) : null
1929
+ ] }),
1930
+ group.items.map((item, index) => renderOption(item, `group-${groupIndex}`, index))
1931
+ ] }, group.name)) : hasFilteredResults ? filteredItems.map((item, index) => renderOption(item, "item", index)) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "rmsd-state", children: renderEmptyState ? renderEmptyState(filter) : settings.noDataLabel })
1932
+ }
1933
+ )
1934
+ ]
1935
+ }
1936
+ ) : null;
1937
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: rootClassName, style, ref: rootRef, "data-open": isOpen, children: [
1938
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
1939
+ "div",
1940
+ {
1941
+ ref: triggerRef,
1942
+ className: `rmsd-trigger${settings.disabled ? " rmsd-disabled" : ""}`,
1943
+ onClick: handleTriggerClick,
1944
+ onKeyDown: handleTriggerKeyDown,
1945
+ tabIndex: settings.disabled ? -1 : 0,
1946
+ role: "combobox",
1947
+ "aria-expanded": isOpen,
1948
+ "aria-haspopup": "listbox",
1949
+ "aria-controls": listboxId,
1950
+ "aria-disabled": settings.disabled,
1951
+ "aria-activedescendant": activeDescendantId || void 0,
1952
+ "aria-label": getTriggerAriaLabel(),
1953
+ children: [
1954
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "rmsd-value", children: selectedItems.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "rmsd-placeholder", children: settings.text }) : settings.singleSelection ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "rmsd-single-value", children: getLabel(selectedItems[0], settings) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1955
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "rmsd-badge-list", children: visibleBadges.map((item) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "rmsd-badge", children: [
1956
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "rmsd-badge-label", children: renderBadgeNode(item) }),
1957
+ !settings.disabled ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1958
+ "button",
1959
+ {
1960
+ type: "button",
1961
+ className: "rmsd-badge-remove",
1962
+ "aria-label": getRemoveItemAriaLabel(item),
1963
+ onKeyDown: stopInlineKey,
1964
+ onClick: (event) => {
1965
+ event.stopPropagation();
1966
+ removeItem(item);
1967
+ },
1968
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StacklineIcon, { name: "remove" })
1969
+ }
1970
+ ) : null
1971
+ ] }, getPrimaryValue(item, settings))) }),
1972
+ hiddenBadgeCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "rmsd-overflow", children: [
1973
+ "+",
1974
+ hiddenBadgeCount
1975
+ ] }) : null
1976
+ ] }) }),
1977
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "rmsd-actions", children: [
1978
+ settings.clearAll && selectedItems.length > 0 && !settings.disabled ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1979
+ "button",
1980
+ {
1981
+ type: "button",
1982
+ className: "rmsd-clear",
1983
+ "aria-label": settings.clearAllAriaLabel,
1984
+ onKeyDown: stopInlineKey,
1985
+ onClick: (event) => {
1986
+ event.stopPropagation();
1987
+ clearSelection();
1988
+ },
1989
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StacklineIcon, { name: "remove" })
1990
+ }
1991
+ ) : null,
1992
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1993
+ "button",
1994
+ {
1995
+ type: "button",
1996
+ className: "rmsd-arrow-button",
1997
+ disabled: settings.disabled,
1998
+ "aria-label": isOpen ? settings.closeDropdownAriaLabel : settings.openDropdownAriaLabel,
1999
+ "aria-expanded": isOpen,
2000
+ "aria-controls": listboxId,
2001
+ onKeyDown: handleArrowButtonKeyDown,
2002
+ onClick: (event) => {
2003
+ event.stopPropagation();
2004
+ toggleDropdown();
2005
+ },
2006
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "rmsd-arrow", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StacklineIcon, { name: isOpen ? "angle-up" : "angle-down" }) })
2007
+ }
2008
+ )
2009
+ ] })
2010
+ ]
2011
+ }
2012
+ ),
2013
+ shouldAppendToBody && menu && typeof document !== "undefined" ? (0, import_react_dom.createPortal)(menu, document.body) : menu
2014
+ ] });
2015
+ }
2016
+ var ReactMultiSelectDropdown = (0, import_react.forwardRef)(InnerMultiSelectDropdown);
2017
+ var MultiSelectDropdown = ReactMultiSelectDropdown;
2018
+ // Annotate the CommonJS export names for ESM import in node:
2019
+ 0 && (module.exports = {
2020
+ MultiSelectDropdown,
2021
+ ReactMultiSelectDropdown
2022
+ });