@elrayes/dual-listbox 0.3.1 → 0.3.3

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 CHANGED
@@ -79,8 +79,10 @@ var DualListBox = class {
79
79
  const themeBase = mergeTheme(defaultTheme, GLOBAL_THEME);
80
80
  const theme = mergeTheme(themeBase, options.theme);
81
81
  this.settings = { ...this.defaults, ...options, theme };
82
+ this.originalData = [...this.settings.dataArray];
82
83
  this.groups = this.buildGroups(this.settings.dataArray);
83
84
  this.selectedGroups = this.buildGroups(this.settings.selectedItems);
85
+ this.sortAllGroups();
84
86
  this.removeDuplicatesFromLeft();
85
87
  this.render();
86
88
  this.bindEvents();
@@ -103,14 +105,32 @@ var DualListBox = class {
103
105
  }
104
106
  return id;
105
107
  }
108
+ sortAllGroups() {
109
+ [this.groups, this.selectedGroups].forEach((groupSet) => {
110
+ Object.keys(groupSet).forEach((groupName) => {
111
+ this.sortGroup(groupSet[groupName]);
112
+ });
113
+ });
114
+ }
115
+ sortGroup(group) {
116
+ group.sort((a, b) => {
117
+ const valA = String(a[this.settings.valueName]);
118
+ const valB = String(b[this.settings.valueName]);
119
+ const indexA = this.originalData.findIndex(
120
+ (item) => String(item[this.settings.valueName]) === valA
121
+ );
122
+ const indexB = this.originalData.findIndex(
123
+ (item) => String(item[this.settings.valueName]) === valB
124
+ );
125
+ return indexA - indexB;
126
+ });
127
+ }
106
128
  buildGroups(dataArray) {
107
129
  const groups = {};
108
130
  dataArray.forEach((item) => {
109
131
  const group = item[this.settings.groupName] || "Ungrouped";
110
132
  if (!groups[group]) groups[group] = [];
111
- if (!groups[group].some((existing) => existing[this.settings.valueName] === item[this.settings.valueName])) {
112
- groups[group].push(item);
113
- }
133
+ groups[group].push(item);
114
134
  });
115
135
  return groups;
116
136
  }
@@ -119,7 +139,7 @@ var DualListBox = class {
119
139
  if (this.groups[group]) {
120
140
  this.selectedGroups[group].forEach((selectedItem) => {
121
141
  this.groups[group] = this.groups[group].filter(
122
- (item) => item[this.settings.valueName] !== selectedItem[this.settings.valueName]
142
+ (item) => String(item[this.settings.valueName]) !== String(selectedItem[this.settings.valueName])
123
143
  );
124
144
  });
125
145
  if (this.settings.hideEmptyGroups) {
@@ -140,7 +160,7 @@ var DualListBox = class {
140
160
  <div class="${t.card}">
141
161
  <div class="${t.cardHeader}">${this.settings.tabNameText}</div>
142
162
  <div class="${t.cardBody}">
143
- <input id="dual_listbox_${this.instanceId}_left_search" type="text" class="${t.searchInput}" data-side="left" placeholder="${this.settings.searchPlaceholderText}">
163
+ <input id="dual_listbox_${this.instanceId}_left_search" type="text" class="${t.searchInput} dual-listbox-search" data-side="left" placeholder="${this.settings.searchPlaceholderText}">
144
164
  <div class="dual-listbox-content">
145
165
  ${this.generateGroupedListHTML("left")}
146
166
  </div>
@@ -152,14 +172,14 @@ var DualListBox = class {
152
172
  </div>
153
173
  </div>
154
174
  <div class="${t.colCenter}">
155
- <button class="${t.btn} dual-listbox-include ${t.btnInclude}" disabled>${this.settings.includeButtonText}</button>
156
- <button class="${t.btn} dual-listbox-exclude ${t.btnExclude}" disabled>${this.settings.excludeButtonText}</button>
175
+ <button type="button" class="${t.btn} dual-listbox-include ${t.btnInclude}" disabled>${this.settings.includeButtonText}</button>
176
+ <button type="button" class="${t.btn} dual-listbox-exclude ${t.btnExclude}" disabled>${this.settings.excludeButtonText}</button>
157
177
  </div>
158
178
  <div class="${t.colRight}" id="dual_listbox_${this.instanceId}_right_side">
159
179
  <div class="${t.card}">
160
180
  <div class="${t.cardHeader}">${this.settings.rightTabNameText}</div>
161
181
  <div class="${t.cardBody}">
162
- <input id="dual_listbox_${this.instanceId}_right_search" type="text" class="${t.searchInput}" data-side="right" placeholder="${this.settings.searchPlaceholderText}">
182
+ <input id="dual_listbox_${this.instanceId}_right_search" type="text" class="${t.searchInput} dual-listbox-search" data-side="right" placeholder="${this.settings.searchPlaceholderText}">
163
183
  <div class="dual-listbox-content">
164
184
  ${this.generateGroupedListHTML("right")}
165
185
  </div>
@@ -284,9 +304,10 @@ var DualListBox = class {
284
304
  const fromContainer = contents[fromSide === "left" ? 0 : 1];
285
305
  const selectedLis = Array.from(fromContainer.querySelectorAll(".item-select:checked")).map((inp) => inp.closest("li"));
286
306
  selectedLis.forEach((li) => {
287
- var _a;
288
307
  const value = String(li.getAttribute("data-value"));
289
308
  const group = String(li.getAttribute("data-group"));
309
+ const originalItem = this.originalData.find((item) => String(item[this.settings.valueName]) === value);
310
+ if (!originalItem) return;
290
311
  if (fromGroups[group]) {
291
312
  fromGroups[group] = fromGroups[group].filter((i) => String(i[this.settings.valueName]) !== value);
292
313
  if (fromGroups[group].length === 0 && (this.settings.hideEmptyGroups || fromSide !== "left")) {
@@ -294,12 +315,10 @@ var DualListBox = class {
294
315
  }
295
316
  }
296
317
  if (!toGroups[group]) toGroups[group] = [];
297
- const label = ((_a = li.querySelector("label")) == null ? void 0 : _a.textContent) || "";
298
- toGroups[group].push({
299
- [this.settings.itemName]: label,
300
- [this.settings.valueName]: value,
301
- [this.settings.groupName]: group
302
- });
318
+ if (!toGroups[group].some((i) => String(i[this.settings.valueName]) === value)) {
319
+ toGroups[group].push(originalItem);
320
+ }
321
+ this.sortGroup(toGroups[group]);
303
322
  });
304
323
  this.render();
305
324
  }
@@ -347,10 +366,7 @@ var DualListBox = class {
347
366
  console.error("Parent form not found!");
348
367
  return;
349
368
  }
350
- const selectedValues = [];
351
- Object.values(this.selectedGroups).forEach((items) => {
352
- items.forEach((item) => selectedValues.push(item[this.settings.valueName]));
353
- });
369
+ const selectedValues = this.selectedArray;
354
370
  Array.from(this.formEl.querySelectorAll(`input[name="${this.settings.inputName}[]"]`)).forEach((el) => el.remove());
355
371
  selectedValues.forEach((value) => {
356
372
  const input = document.createElement("input");
@@ -362,26 +378,26 @@ var DualListBox = class {
362
378
  }
363
379
  getSelectedValues() {
364
380
  return new Promise((resolve) => {
365
- const selectedValues = [];
366
- Object.keys(this.selectedGroups).forEach((groupName) => {
367
- this.selectedGroups[groupName].forEach((item) => {
368
- selectedValues.push(item[this.settings.valueName]);
369
- });
370
- });
371
- resolve(selectedValues);
381
+ resolve(this.selectedArray);
372
382
  });
373
383
  }
374
384
  get selected() {
375
385
  return this.selectedGroups;
376
386
  }
377
387
  get selectedArray() {
378
- let selectedValues = [];
379
- Object.keys(this.selectedGroups).forEach((groupName) => {
380
- this.selectedGroups[groupName].forEach((item) => {
381
- selectedValues.push(item[this.settings.valueName]);
382
- });
388
+ const selectedValues = [];
389
+ this.originalData.forEach((item) => {
390
+ const val = item[this.settings.valueName];
391
+ const group = item[this.settings.groupName] || "Ungrouped";
392
+ if (this.selectedGroups[group]) {
393
+ const isSelected = this.selectedGroups[group].some(
394
+ (i) => String(i[this.settings.valueName]) === String(val)
395
+ );
396
+ if (isSelected) {
397
+ selectedValues.push(val);
398
+ }
399
+ }
383
400
  });
384
- selectedValues = [...new Set(selectedValues)];
385
401
  return selectedValues;
386
402
  }
387
403
  get unselected() {
@@ -392,34 +408,27 @@ var DualListBox = class {
392
408
  }
393
409
  // New API methods: return arrays without duplicates
394
410
  getSelectedItems() {
395
- const map = /* @__PURE__ */ new Map();
396
- Object.values(this.selectedGroups).forEach((items) => {
397
- items.forEach((item) => {
398
- const key = String(item[this.settings.valueName]);
399
- if (!map.has(key)) map.set(key, item);
400
- });
411
+ const selected = [];
412
+ const values = this.selectedArray.map(String);
413
+ this.originalData.forEach((item) => {
414
+ if (values.includes(String(item[this.settings.valueName]))) {
415
+ selected.push(item);
416
+ }
401
417
  });
402
- return Array.from(map.values());
418
+ return selected;
403
419
  }
404
420
  getUnselectedItems() {
405
- const map = /* @__PURE__ */ new Map();
406
- Object.values(this.groups).forEach((items) => {
407
- items.forEach((item) => {
408
- const key = String(item[this.settings.valueName]);
409
- if (!map.has(key)) map.set(key, item);
410
- });
421
+ const unselected = [];
422
+ const selectedValues = this.selectedArray.map(String);
423
+ this.originalData.forEach((item) => {
424
+ if (!selectedValues.includes(String(item[this.settings.valueName]))) {
425
+ unselected.push(item);
426
+ }
411
427
  });
412
- return Array.from(map.values());
428
+ return unselected;
413
429
  }
414
430
  getAllItems() {
415
- const map = /* @__PURE__ */ new Map();
416
- Object.values(this.groups).forEach((items) => {
417
- items.forEach((item) => map.set(String(item[this.settings.valueName]), item));
418
- });
419
- Object.values(this.selectedGroups).forEach((items) => {
420
- items.forEach((item) => map.set(String(item[this.settings.valueName]), item));
421
- });
422
- return Array.from(map.values());
431
+ return [...this.originalData];
423
432
  }
424
433
  getSettings() {
425
434
  return this.settings;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/themePresets.ts","../src/lib/DualListBox.ts"],"names":["_a"],"mappings":"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","file":"index.cjs","sourcesContent":["import { DualListBoxTheme } from './types';\n\nexport const defaultTheme: DualListBoxTheme = {\n container: 'dual-listbox',\n row: 'row mb-3',\n colLeft: 'col-md-5',\n colCenter: 'col-md-2 d-flex justify-content-center flex-column gap-3',\n colRight: 'col-md-5',\n card: 'card h-100',\n cardHeader: 'card-header',\n cardBody: 'card-body',\n cardFooter: 'card-footer text-center',\n searchInput: 'form-control mb-3 dual-listbox-search',\n listGroup: 'list-group',\n listItem: 'list-group-item py-1 border-0',\n formCheck: 'form-check',\n formCheckInput: 'form-check-input',\n formCheckLabel: 'form-check-label',\n btn: 'btn btn-light w-100',\n btnInclude: '',\n btnExclude: '',\n};\n\nexport const bootstrapTheme: DualListBoxTheme = { ...defaultTheme };\n\nexport const tailwindTheme: DualListBoxTheme = {\n container: 'dual-listbox tw',\n row: 'grid grid-cols-1 md:grid-cols-5 gap-3',\n colLeft: 'md:col-span-2',\n colCenter: 'md:col-span-1 flex flex-col justify-center gap-3',\n colRight: 'md:col-span-2',\n card: 'h-full border rounded shadow-sm bg-white',\n cardHeader: 'px-4 py-2 border-b font-medium',\n cardBody: 'p-4',\n cardFooter: 'px-4 py-2 border-t text-center',\n searchInput: 'w-full mb-3 border rounded px-3 py-2 dual-listbox-search',\n listGroup: 'space-y-1',\n listItem: 'py-1',\n formCheck: 'flex items-center gap-2',\n formCheckInput: 'h-4 w-4',\n formCheckLabel: '',\n btn: 'w-full border rounded px-3 py-2 bg-gray-100 hover:bg-gray-200',\n btnInclude: 'mb-2',\n btnExclude: '',\n};\n","import type {DualListBoxItem, DualListBoxOptions, DualListBoxTheme} from './types';\nimport {defaultTheme} from './themePresets';\n\nfunction mergeTheme(base: DualListBoxTheme, override?: Partial<DualListBoxTheme>): DualListBoxTheme {\n return {...base, ...(override || {})} as DualListBoxTheme;\n}\n\n// Global theme state (module-level)\nlet GLOBAL_THEME: DualListBoxTheme = {...defaultTheme};\n\n/**\n * Set the global default theme for all new DualListBox instances.\n * Instance option `theme` still has highest priority.\n */\nexport function useTheme(theme: Partial<DualListBoxTheme> | DualListBoxTheme) {\n GLOBAL_THEME = mergeTheme(defaultTheme, theme as Partial<DualListBoxTheme>);\n}\n\n// Back-compat alias for older code that might call DualListBox.setTheme(...)\n// We will attach a static setTheme on the class after its definition.\n\nexport class DualListBox {\n private rootEl: Element;\n private formEl: HTMLFormElement | null;\n\n private instanceId: string;\n\n private defaults: Required<Omit<DualListBoxOptions, 'theme'>> & { theme: DualListBoxTheme };\n private settings: Required<DualListBoxOptions> & { theme: DualListBoxTheme };\n\n private groups: Record<string, DualListBoxItem[]> = {};\n private selectedGroups: Record<string, DualListBoxItem[]> = {};\n\n constructor(element: Element | string, options: DualListBoxOptions = {}) {\n this.rootEl = typeof element === 'string' ? (document.querySelector(element) as Element) : (element as Element);\n if (!this.rootEl) throw new Error('DualListBox root element not found');\n this.formEl = (this.rootEl.closest('form') as HTMLFormElement) || null;\n this.instanceId = this.generateInstanceId();\n this.defaults = {\n itemName: 'item',\n groupName: 'group',\n valueName: 'value',\n inputName: 'selectedItems',\n tabNameText: 'Available Items',\n rightTabNameText: 'Selected Items',\n searchPlaceholderText: 'Search...',\n includeButtonText: 'Include >>',\n excludeButtonText: '<< Exclude',\n dataArray: [],\n selectedItems: [],\n hideEmptyGroups: false,\n submitForm: true,\n onSubmit: null,\n theme: defaultTheme,\n } as any;\n\n // Effective theme precedence: options.theme > GLOBAL_THEME > defaultTheme\n const themeBase = mergeTheme(defaultTheme, GLOBAL_THEME);\n const theme = mergeTheme(themeBase, options.theme);\n this.settings = {...(this.defaults as any), ...(options as any), theme};\n\n this.groups = this.buildGroups(this.settings.dataArray);\n this.selectedGroups = this.buildGroups(this.settings.selectedItems);\n\n this.removeDuplicatesFromLeft();\n this.render();\n this.bindEvents();\n\n if (this.formEl) {\n this.formEl.addEventListener('submit', (event) => {\n if (typeof this.settings.onSubmit === 'function') {\n event.preventDefault();\n this.settings.onSubmit(this.selected, this.unselected, this.allItems, this.selectedArray);\n } else if (this.settings.submitForm) {\n this.appendSelectedGroupsOnSubmit();\n }\n });\n }\n }\n\n private generateInstanceId() {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let id = '';\n for (let i = 0; i < 36; i++) {\n id += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return id;\n }\n\n private buildGroups(dataArray: DualListBoxItem[]) {\n const groups: Record<string, DualListBoxItem[]> = {};\n dataArray.forEach((item) => {\n const group = (item as any)[this.settings.groupName] || 'Ungrouped';\n if (!groups[group]) groups[group] = [];\n if (!groups[group].some((existing) => (existing as any)[this.settings.valueName] === (item as any)[this.settings.valueName])) {\n groups[group].push(item);\n }\n });\n return groups;\n }\n\n private removeDuplicatesFromLeft() {\n Object.keys(this.selectedGroups).forEach((group) => {\n if (this.groups[group]) {\n this.selectedGroups[group].forEach((selectedItem) => {\n this.groups[group] = this.groups[group].filter(\n (item) => (item as any)[this.settings.valueName] !== (selectedItem as any)[this.settings.valueName]\n );\n });\n if (this.settings.hideEmptyGroups) {\n if (!this.groups[group].length) {\n delete this.groups[group];\n }\n }\n }\n });\n this.render();\n }\n\n private render() {\n const t = this.settings.theme;\n const template = `\n <div class=\"${t.container}\" id=\"dual_listbox_${this.instanceId}\">\n <div class=\"${t.row}\">\n <div class=\"${t.colLeft}\" id=\"dual_listbox_${this.instanceId}_left_side\">\n <div class=\"${t.card}\">\n <div class=\"${t.cardHeader}\">${this.settings.tabNameText}</div>\n <div class=\"${t.cardBody}\">\n <input id=\"dual_listbox_${this.instanceId}_left_search\" type=\"text\" class=\"${t.searchInput}\" data-side=\"left\" placeholder=\"${this.settings.searchPlaceholderText}\">\n <div class=\"dual-listbox-content\">\n ${this.generateGroupedListHTML('left')}\n </div>\n </div>\n <div class=\"${t.cardFooter}\">\n <input type=\"checkbox\" class=\"${t.formCheckInput} dual-listbox-select-all-left\" disabled>\n <label class=\"${t.formCheckLabel}\">Select All (<span class=\"dual-listbox-left-selected\">0</span>/<span class=\"dual-listbox-left-total\">0</span>)</label>\n </div>\n </div>\n </div>\n <div class=\"${t.colCenter}\">\n <button class=\"${t.btn} dual-listbox-include ${t.btnInclude}\" disabled>${this.settings.includeButtonText}</button>\n <button class=\"${t.btn} dual-listbox-exclude ${t.btnExclude}\" disabled>${this.settings.excludeButtonText}</button>\n </div>\n <div class=\"${t.colRight}\" id=\"dual_listbox_${this.instanceId}_right_side\">\n <div class=\"${t.card}\">\n <div class=\"${t.cardHeader}\">${this.settings.rightTabNameText}</div>\n <div class=\"${t.cardBody}\">\n <input id=\"dual_listbox_${this.instanceId}_right_search\" type=\"text\" class=\"${t.searchInput}\" data-side=\"right\" placeholder=\"${this.settings.searchPlaceholderText}\">\n <div class=\"dual-listbox-content\">\n ${this.generateGroupedListHTML('right')}\n </div>\n </div>\n <div class=\"${t.cardFooter}\">\n <input type=\"checkbox\" class=\"${t.formCheckInput} dual-listbox-select-all-right\" disabled>\n <label class=\"${t.formCheckLabel}\">Select All (<span class=\"dual-listbox-right-selected\">0</span>/<span class=\"dual-listbox-right-total\">0</span>)</label>\n </div>\n </div>\n </div>\n </div>\n </div>`;\n this.rootEl.innerHTML = template;\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n }\n\n private generateGroupedListHTML(side: 'left' | 'right') {\n const t = this.settings.theme;\n const groups = side === 'left' ? this.groups : this.selectedGroups;\n let html = '';\n const keys = Object.keys(groups);\n keys.forEach((groupName, index) => {\n const items = groups[groupName];\n const totalItems = items.length;\n const isGroupEmpty = totalItems === 0;\n const groupSelectAllInput = `group_${groupName}_${side}`;\n const isLast = index === keys.length - 1;\n html += `\n <div class=\"dual-listbox-group${!isLast ? ' mb-3' : ''}\">\n <div class=\"group-header mb-2\">\n <div class=\"${t.formCheck}\">\n <input id=\"${groupSelectAllInput}\" type=\"checkbox\" class=\"${t.formCheckInput} group-select-all\" ${isGroupEmpty ? 'checked disabled' : ''}>\n <label for=\"${groupSelectAllInput}\" class=\"${t.formCheckLabel}\">${groupName}</label>\n </div>\n </div>`;\n if (!isGroupEmpty) {\n html += `<ul class=\"${t.listGroup}\">`;\n items.forEach((item) => {\n const val = (item as any)[this.settings.valueName];\n const name = (item as any)[this.settings.itemName];\n html += `\n <li class=\"${t.listItem}\" data-value=\"${val}\" data-group=\"${groupName}\">\n <div class=\"${t.formCheck}\">\n <input id=\"${groupName}_${val}\" type=\"checkbox\" class=\"${t.formCheckInput} item-select\" />\n <label for=\"${groupName}_${val}\" class=\"${t.formCheckLabel}\">${name}</label>\n </div>\n </li>`;\n });\n html += `</ul>`;\n }\n html += `</div>`;\n });\n return html;\n }\n\n private updateSelectAllInfo(side: 'left' | 'right') {\n const idx = side === 'left' ? 0 : 1;\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const content = contents[idx] as Element;\n const selectAll = this.rootEl.querySelector<HTMLInputElement>(`.dual-listbox-select-all-${side}`);\n const totalItems = content ? content.querySelectorAll('.item-select').length : 0;\n const selectedItems = content ? content.querySelectorAll('.item-select:checked').length : 0;\n const selSpan = this.rootEl.querySelector(`.dual-listbox-${side}-selected`);\n const totalSpan = this.rootEl.querySelector(`.dual-listbox-${side}-total`);\n if (selSpan) selSpan.textContent = String(selectedItems);\n if (totalSpan) totalSpan.textContent = String(totalItems);\n if (selectAll) {\n if (totalItems === 0) {\n selectAll.disabled = true;\n selectAll.checked = true;\n } else {\n selectAll.disabled = false;\n selectAll.checked = selectedItems === totalItems;\n }\n }\n\n // Enable/disable include/exclude buttons based on selections\n const includeBtn = this.rootEl.querySelector<HTMLButtonElement>('.dual-listbox-include');\n const excludeBtn = this.rootEl.querySelector<HTMLButtonElement>('.dual-listbox-exclude');\n const leftContent = contents[0] as Element | undefined;\n const rightContent = contents[1] as Element | undefined;\n const leftChecked = leftContent ? leftContent.querySelectorAll('.item-select:checked').length : 0;\n const rightChecked = rightContent ? rightContent.querySelectorAll('.item-select:checked').length : 0;\n if (includeBtn) includeBtn.disabled = leftChecked === 0;\n if (excludeBtn) excludeBtn.disabled = rightChecked === 0;\n }\n\n private bindEvents() {\n this.rootEl.addEventListener('click', (e) => {\n const target = e.target as HTMLElement;\n if (target.closest('.dual-listbox-include')) {\n this.moveItems('left', 'right');\n } else if (target.closest('.dual-listbox-exclude')) {\n this.moveItems('right', 'left');\n }\n });\n this.rootEl.addEventListener('change', (e) => {\n const target = e.target as HTMLInputElement;\n if (target.matches('.dual-listbox-select-all-left')) {\n this.toggleSelectAll('left', target.checked);\n } else if (target.matches('.dual-listbox-select-all-right')) {\n this.toggleSelectAll('right', target.checked);\n } else if (target.matches('.group-select-all')) {\n const groupEl = target.closest('.dual-listbox-group') as Element;\n groupEl?.querySelectorAll<HTMLInputElement>('.item-select').forEach((inp) => (inp.checked = target.checked));\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n } else if (target.matches('.item-select')) {\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n }\n });\n this.rootEl.addEventListener('input', (e) => {\n const target = e.target as HTMLInputElement;\n if (target.matches('.dual-listbox-search')) {\n const side = (target.getAttribute('data-side') as 'left' | 'right') || 'left';\n const searchTerm = target.value || '';\n this.searchItems(side, searchTerm);\n }\n });\n }\n\n private moveItems(fromSide: 'left' | 'right', toSide: 'left' | 'right') {\n const fromGroups = fromSide === 'left' ? this.groups : this.selectedGroups;\n const toGroups = toSide === 'left' ? this.groups : this.selectedGroups;\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const fromContainer = contents[fromSide === 'left' ? 0 : 1] as Element;\n const selectedLis = Array.from(fromContainer.querySelectorAll<HTMLInputElement>('.item-select:checked')).map((inp) => inp.closest('li') as HTMLLIElement);\n selectedLis.forEach((li) => {\n const value = String(li.getAttribute('data-value'));\n const group = String(li.getAttribute('data-group'));\n if (fromGroups[group]) {\n fromGroups[group] = fromGroups[group].filter((i) => String((i as any)[this.settings.valueName]) !== value);\n if (fromGroups[group].length === 0 && (this.settings.hideEmptyGroups || fromSide !== 'left')) {\n delete (fromGroups as any)[group];\n }\n }\n if (!toGroups[group]) toGroups[group] = [];\n const label = li.querySelector('label')?.textContent || '';\n toGroups[group].push({\n [this.settings.itemName]: label,\n [this.settings.valueName]: value,\n [this.settings.groupName]: group,\n } as any);\n });\n this.render();\n }\n\n private toggleSelectAll(side: 'left' | 'right', isChecked: boolean) {\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const content = contents[side === 'left' ? 0 : 1] as Element;\n content?.querySelectorAll<HTMLInputElement>('.group-select-all').forEach((inp) => (inp.checked = isChecked));\n content?.querySelectorAll<HTMLInputElement>('.item-select').forEach((inp) => (inp.checked = isChecked));\n this.updateSelectAllInfo(side);\n }\n\n private searchItems(side: 'left' | 'right', searchTerm: string) {\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const container = contents[side === 'left' ? 0 : 1] as HTMLElement;\n const searchText = (searchTerm || '').toLowerCase();\n container?.querySelectorAll<HTMLElement>('.dual-listbox-group').forEach((groupEl) => {\n const groupName = (groupEl.querySelector('.group-header')?.textContent || '').toLowerCase();\n const items = groupEl.querySelectorAll<HTMLElement>('li');\n let showGroup = false;\n if (groupName.includes(searchText)) {\n groupEl.style.display = '';\n items.forEach((li) => (li.style.display = ''));\n showGroup = true;\n } else {\n items.forEach((li) => {\n const itemText = (li.querySelector('label')?.textContent || '').toLowerCase();\n if (itemText.includes(searchText)) {\n li.style.display = '';\n showGroup = true;\n } else {\n li.style.display = 'none';\n }\n });\n groupEl.style.display = showGroup ? '' : 'none';\n }\n });\n if (!searchText) {\n container?.querySelectorAll<HTMLElement>('.dual-listbox-group').forEach((g) => (g.style.display = ''));\n container?.querySelectorAll<HTMLElement>('li').forEach((li) => (li.style.display = ''));\n }\n }\n\n private appendSelectedGroupsOnSubmit() {\n if (!this.formEl) {\n console.error('Parent form not found!');\n return;\n }\n const selectedValues: (string | number)[] = [];\n Object.values(this.selectedGroups).forEach((items) => {\n items.forEach((item) => selectedValues.push((item as any)[this.settings.valueName]));\n });\n // remove existing\n Array.from(this.formEl.querySelectorAll(`input[name=\"${this.settings.inputName}[]\"]`)).forEach((el) => el.remove());\n // append new\n selectedValues.forEach((value) => {\n const input = document.createElement('input');\n input.type = 'hidden';\n input.name = `${this.settings.inputName}[]`;\n input.value = String(value);\n this.formEl!.appendChild(input);\n });\n }\n\n getSelectedValues(): Promise<(string | number)[]> {\n return new Promise((resolve) => {\n const selectedValues: (string | number)[] = [];\n Object.keys(this.selectedGroups).forEach((groupName) => {\n this.selectedGroups[groupName].forEach((item) => {\n selectedValues.push((item as any)[this.settings.valueName]);\n });\n });\n resolve(selectedValues);\n });\n }\n\n get selected() {\n return this.selectedGroups;\n }\n\n get selectedArray() {\n let selectedValues: (string | number)[] = [];\n Object.keys(this.selectedGroups).forEach((groupName) => {\n this.selectedGroups[groupName].forEach((item) => {\n selectedValues.push((item as any)[this.settings.valueName]);\n });\n });\n selectedValues = [...new Set(selectedValues)];\n return selectedValues;\n }\n\n get unselected() {\n return this.groups;\n }\n\n get allItems() {\n return this.settings.dataArray;\n }\n\n // New API methods: return arrays without duplicates\n getSelectedItems(): DualListBoxItem[] {\n const map = new Map<string, DualListBoxItem>();\n Object.values(this.selectedGroups).forEach((items) => {\n items.forEach((item) => {\n const key = String((item as any)[this.settings.valueName]);\n if (!map.has(key)) map.set(key, item);\n });\n });\n return Array.from(map.values());\n }\n\n getUnselectedItems(): DualListBoxItem[] {\n const map = new Map<string, DualListBoxItem>();\n Object.values(this.groups).forEach((items) => {\n items.forEach((item) => {\n const key = String((item as any)[this.settings.valueName]);\n if (!map.has(key)) map.set(key, item);\n });\n });\n return Array.from(map.values());\n }\n\n getAllItems(): DualListBoxItem[] {\n const map = new Map<string, DualListBoxItem>();\n // include current left and right to reflect UI state\n Object.values(this.groups).forEach((items) => {\n items.forEach((item) => map.set(String((item as any)[this.settings.valueName]), item));\n });\n Object.values(this.selectedGroups).forEach((items) => {\n items.forEach((item) => map.set(String((item as any)[this.settings.valueName]), item));\n });\n return Array.from(map.values());\n }\n\n getSettings(): Required<DualListBoxOptions> & { theme: DualListBoxTheme } {\n return this.settings;\n }\n}\n\nexport function initDualListBox(selector: string | Element, options: DualListBoxOptions = {}) {\n return new DualListBox(selector, options);\n}\n\n// Attach back-compat static setTheme to the class\n// so existing code using DualListBox.setTheme(...) keeps working.\n(DualListBox as any).setTheme = (theme: Partial<DualListBoxTheme> | DualListBoxTheme) => useTheme(theme);\n"]}
1
+ {"version":3,"sources":["../src/lib/themePresets.ts","../src/lib/DualListBox.ts"],"names":["_a"],"mappings":"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","file":"index.cjs","sourcesContent":["import { DualListBoxTheme } from './types';\n\nexport const defaultTheme: DualListBoxTheme = {\n container: 'dual-listbox',\n row: 'row mb-3',\n colLeft: 'col-md-5',\n colCenter: 'col-md-2 d-flex justify-content-center flex-column gap-3',\n colRight: 'col-md-5',\n card: 'card h-100',\n cardHeader: 'card-header',\n cardBody: 'card-body',\n cardFooter: 'card-footer text-center',\n searchInput: 'form-control mb-3 dual-listbox-search',\n listGroup: 'list-group',\n listItem: 'list-group-item py-1 border-0',\n formCheck: 'form-check',\n formCheckInput: 'form-check-input',\n formCheckLabel: 'form-check-label',\n btn: 'btn btn-light w-100',\n btnInclude: '',\n btnExclude: '',\n};\n\nexport const bootstrapTheme: DualListBoxTheme = { ...defaultTheme };\n\nexport const tailwindTheme: DualListBoxTheme = {\n container: 'dual-listbox tw',\n row: 'grid grid-cols-1 md:grid-cols-5 gap-3',\n colLeft: 'md:col-span-2',\n colCenter: 'md:col-span-1 flex flex-col justify-center gap-3',\n colRight: 'md:col-span-2',\n card: 'h-full border rounded shadow-sm bg-white',\n cardHeader: 'px-4 py-2 border-b font-medium',\n cardBody: 'p-4',\n cardFooter: 'px-4 py-2 border-t text-center',\n searchInput: 'w-full mb-3 border rounded px-3 py-2 dual-listbox-search',\n listGroup: 'space-y-1',\n listItem: 'py-1',\n formCheck: 'flex items-center gap-2',\n formCheckInput: 'h-4 w-4',\n formCheckLabel: '',\n btn: 'w-full border rounded px-3 py-2 bg-gray-100 hover:bg-gray-200',\n btnInclude: 'mb-2',\n btnExclude: '',\n};\n","import type {DualListBoxItem, DualListBoxOptions, DualListBoxTheme} from './types';\nimport {defaultTheme} from './themePresets';\n\nfunction mergeTheme(base: DualListBoxTheme, override?: Partial<DualListBoxTheme>): DualListBoxTheme {\n return {...base, ...(override || {})} as DualListBoxTheme;\n}\n\n// Global theme state (module-level)\nlet GLOBAL_THEME: DualListBoxTheme = {...defaultTheme};\n\n/**\n * Set the global default theme for all new DualListBox instances.\n * Instance option `theme` still has highest priority.\n */\nexport function useTheme(theme: Partial<DualListBoxTheme> | DualListBoxTheme) {\n GLOBAL_THEME = mergeTheme(defaultTheme, theme as Partial<DualListBoxTheme>);\n}\n\n// Back-compat alias for older code that might call DualListBox.setTheme(...)\n// We will attach a static setTheme on the class after its definition.\n\nexport class DualListBox {\n private rootEl: Element;\n private formEl: HTMLFormElement | null;\n\n private instanceId: string;\n private originalData: DualListBoxItem[];\n\n private defaults: Required<Omit<DualListBoxOptions, 'theme'>> & { theme: DualListBoxTheme };\n private settings: Required<DualListBoxOptions> & { theme: DualListBoxTheme };\n\n private groups: Record<string, DualListBoxItem[]> = {};\n private selectedGroups: Record<string, DualListBoxItem[]> = {};\n\n constructor(element: Element | string, options: DualListBoxOptions = {}) {\n this.rootEl = typeof element === 'string' ? (document.querySelector(element) as Element) : (element as Element);\n if (!this.rootEl) throw new Error('DualListBox root element not found');\n this.formEl = (this.rootEl.closest('form') as HTMLFormElement) || null;\n this.instanceId = this.generateInstanceId();\n this.defaults = {\n itemName: 'item',\n groupName: 'group',\n valueName: 'value',\n inputName: 'selectedItems',\n tabNameText: 'Available Items',\n rightTabNameText: 'Selected Items',\n searchPlaceholderText: 'Search...',\n includeButtonText: 'Include >>',\n excludeButtonText: '<< Exclude',\n dataArray: [],\n selectedItems: [],\n hideEmptyGroups: false,\n submitForm: true,\n onSubmit: null,\n theme: defaultTheme,\n } as any;\n\n // Effective theme precedence: options.theme > GLOBAL_THEME > defaultTheme\n const themeBase = mergeTheme(defaultTheme, GLOBAL_THEME);\n const theme = mergeTheme(themeBase, options.theme);\n this.settings = {...(this.defaults as any), ...(options as any), theme};\n\n this.originalData = [...this.settings.dataArray];\n this.groups = this.buildGroups(this.settings.dataArray);\n this.selectedGroups = this.buildGroups(this.settings.selectedItems);\n\n // Sort initial groups based on originalData order\n this.sortAllGroups();\n\n this.removeDuplicatesFromLeft();\n this.render();\n this.bindEvents();\n\n if (this.formEl) {\n this.formEl.addEventListener('submit', (event) => {\n if (typeof this.settings.onSubmit === 'function') {\n event.preventDefault();\n this.settings.onSubmit(this.selected, this.unselected, this.allItems, this.selectedArray);\n } else if (this.settings.submitForm) {\n this.appendSelectedGroupsOnSubmit();\n }\n });\n }\n }\n\n private generateInstanceId() {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let id = '';\n for (let i = 0; i < 36; i++) {\n id += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return id;\n }\n\n private sortAllGroups() {\n [this.groups, this.selectedGroups].forEach((groupSet) => {\n Object.keys(groupSet).forEach((groupName) => {\n this.sortGroup(groupSet[groupName]);\n });\n });\n }\n\n private sortGroup(group: DualListBoxItem[]) {\n group.sort((a, b) => {\n const valA = String((a as any)[this.settings.valueName]);\n const valB = String((b as any)[this.settings.valueName]);\n const indexA = this.originalData.findIndex(\n (item) => String((item as any)[this.settings.valueName]) === valA\n );\n const indexB = this.originalData.findIndex(\n (item) => String((item as any)[this.settings.valueName]) === valB\n );\n return indexA - indexB;\n });\n }\n\n private buildGroups(dataArray: DualListBoxItem[]) {\n const groups: Record<string, DualListBoxItem[]> = {};\n dataArray.forEach((item) => {\n const group = (item as any)[this.settings.groupName] || 'Ungrouped';\n if (!groups[group]) groups[group] = [];\n groups[group].push(item);\n });\n return groups;\n }\n\n private removeDuplicatesFromLeft() {\n Object.keys(this.selectedGroups).forEach((group) => {\n if (this.groups[group]) {\n this.selectedGroups[group].forEach((selectedItem) => {\n this.groups[group] = this.groups[group].filter(\n (item) => String((item as any)[this.settings.valueName]) !== String((selectedItem as any)[this.settings.valueName])\n );\n });\n if (this.settings.hideEmptyGroups) {\n if (!this.groups[group].length) {\n delete this.groups[group];\n }\n }\n }\n });\n this.render();\n }\n\n private render() {\n const t = this.settings.theme;\n const template = `\n <div class=\"${t.container}\" id=\"dual_listbox_${this.instanceId}\">\n <div class=\"${t.row}\">\n <div class=\"${t.colLeft}\" id=\"dual_listbox_${this.instanceId}_left_side\">\n <div class=\"${t.card}\">\n <div class=\"${t.cardHeader}\">${this.settings.tabNameText}</div>\n <div class=\"${t.cardBody}\">\n <input id=\"dual_listbox_${this.instanceId}_left_search\" type=\"text\" class=\"${t.searchInput} dual-listbox-search\" data-side=\"left\" placeholder=\"${this.settings.searchPlaceholderText}\">\n <div class=\"dual-listbox-content\">\n ${this.generateGroupedListHTML('left')}\n </div>\n </div>\n <div class=\"${t.cardFooter}\">\n <input type=\"checkbox\" class=\"${t.formCheckInput} dual-listbox-select-all-left\" disabled>\n <label class=\"${t.formCheckLabel}\">Select All (<span class=\"dual-listbox-left-selected\">0</span>/<span class=\"dual-listbox-left-total\">0</span>)</label>\n </div>\n </div>\n </div>\n <div class=\"${t.colCenter}\">\n <button type=\"button\" class=\"${t.btn} dual-listbox-include ${t.btnInclude}\" disabled>${this.settings.includeButtonText}</button>\n <button type=\"button\" class=\"${t.btn} dual-listbox-exclude ${t.btnExclude}\" disabled>${this.settings.excludeButtonText}</button>\n </div>\n <div class=\"${t.colRight}\" id=\"dual_listbox_${this.instanceId}_right_side\">\n <div class=\"${t.card}\">\n <div class=\"${t.cardHeader}\">${this.settings.rightTabNameText}</div>\n <div class=\"${t.cardBody}\">\n <input id=\"dual_listbox_${this.instanceId}_right_search\" type=\"text\" class=\"${t.searchInput} dual-listbox-search\" data-side=\"right\" placeholder=\"${this.settings.searchPlaceholderText}\">\n <div class=\"dual-listbox-content\">\n ${this.generateGroupedListHTML('right')}\n </div>\n </div>\n <div class=\"${t.cardFooter}\">\n <input type=\"checkbox\" class=\"${t.formCheckInput} dual-listbox-select-all-right\" disabled>\n <label class=\"${t.formCheckLabel}\">Select All (<span class=\"dual-listbox-right-selected\">0</span>/<span class=\"dual-listbox-right-total\">0</span>)</label>\n </div>\n </div>\n </div>\n </div>\n </div>`;\n this.rootEl.innerHTML = template;\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n }\n\n private generateGroupedListHTML(side: 'left' | 'right') {\n const t = this.settings.theme;\n const groups = side === 'left' ? this.groups : this.selectedGroups;\n let html = '';\n const keys = Object.keys(groups);\n keys.forEach((groupName, index) => {\n const items = groups[groupName];\n const totalItems = items.length;\n const isGroupEmpty = totalItems === 0;\n const groupSelectAllInput = `group_${groupName}_${side}`;\n const isLast = index === keys.length - 1;\n html += `\n <div class=\"dual-listbox-group${!isLast ? ' mb-3' : ''}\">\n <div class=\"group-header mb-2\">\n <div class=\"${t.formCheck}\">\n <input id=\"${groupSelectAllInput}\" type=\"checkbox\" class=\"${t.formCheckInput} group-select-all\" ${isGroupEmpty ? 'checked disabled' : ''}>\n <label for=\"${groupSelectAllInput}\" class=\"${t.formCheckLabel}\">${groupName}</label>\n </div>\n </div>`;\n if (!isGroupEmpty) {\n html += `<ul class=\"${t.listGroup}\">`;\n items.forEach((item) => {\n const val = (item as any)[this.settings.valueName];\n const name = (item as any)[this.settings.itemName];\n html += `\n <li class=\"${t.listItem}\" data-value=\"${val}\" data-group=\"${groupName}\">\n <div class=\"${t.formCheck}\">\n <input id=\"${groupName}_${val}\" type=\"checkbox\" class=\"${t.formCheckInput} item-select\" />\n <label for=\"${groupName}_${val}\" class=\"${t.formCheckLabel}\">${name}</label>\n </div>\n </li>`;\n });\n html += `</ul>`;\n }\n html += `</div>`;\n });\n return html;\n }\n\n private updateSelectAllInfo(side: 'left' | 'right') {\n const idx = side === 'left' ? 0 : 1;\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const content = contents[idx] as Element;\n const selectAll = this.rootEl.querySelector<HTMLInputElement>(`.dual-listbox-select-all-${side}`);\n const totalItems = content ? content.querySelectorAll('.item-select').length : 0;\n const selectedItems = content ? content.querySelectorAll('.item-select:checked').length : 0;\n const selSpan = this.rootEl.querySelector(`.dual-listbox-${side}-selected`);\n const totalSpan = this.rootEl.querySelector(`.dual-listbox-${side}-total`);\n if (selSpan) selSpan.textContent = String(selectedItems);\n if (totalSpan) totalSpan.textContent = String(totalItems);\n if (selectAll) {\n if (totalItems === 0) {\n selectAll.disabled = true;\n selectAll.checked = true;\n } else {\n selectAll.disabled = false;\n selectAll.checked = selectedItems === totalItems;\n }\n }\n\n // Enable/disable include/exclude buttons based on selections\n const includeBtn = this.rootEl.querySelector<HTMLButtonElement>('.dual-listbox-include');\n const excludeBtn = this.rootEl.querySelector<HTMLButtonElement>('.dual-listbox-exclude');\n const leftContent = contents[0] as Element | undefined;\n const rightContent = contents[1] as Element | undefined;\n const leftChecked = leftContent ? leftContent.querySelectorAll('.item-select:checked').length : 0;\n const rightChecked = rightContent ? rightContent.querySelectorAll('.item-select:checked').length : 0;\n if (includeBtn) includeBtn.disabled = leftChecked === 0;\n if (excludeBtn) excludeBtn.disabled = rightChecked === 0;\n }\n\n private bindEvents() {\n this.rootEl.addEventListener('click', (e) => {\n const target = e.target as HTMLElement;\n if (target.closest('.dual-listbox-include')) {\n this.moveItems('left', 'right');\n } else if (target.closest('.dual-listbox-exclude')) {\n this.moveItems('right', 'left');\n }\n });\n this.rootEl.addEventListener('change', (e) => {\n const target = e.target as HTMLInputElement;\n if (target.matches('.dual-listbox-select-all-left')) {\n this.toggleSelectAll('left', target.checked);\n } else if (target.matches('.dual-listbox-select-all-right')) {\n this.toggleSelectAll('right', target.checked);\n } else if (target.matches('.group-select-all')) {\n const groupEl = target.closest('.dual-listbox-group') as Element;\n groupEl?.querySelectorAll<HTMLInputElement>('.item-select').forEach((inp) => (inp.checked = target.checked));\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n } else if (target.matches('.item-select')) {\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n }\n });\n this.rootEl.addEventListener('input', (e) => {\n const target = e.target as HTMLInputElement;\n if (target.matches('.dual-listbox-search')) {\n const side = (target.getAttribute('data-side') as 'left' | 'right') || 'left';\n const searchTerm = target.value || '';\n this.searchItems(side, searchTerm);\n }\n });\n }\n\n private moveItems(fromSide: 'left' | 'right', toSide: 'left' | 'right') {\n const fromGroups = fromSide === 'left' ? this.groups : this.selectedGroups;\n const toGroups = toSide === 'left' ? this.groups : this.selectedGroups;\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const fromContainer = contents[fromSide === 'left' ? 0 : 1] as Element;\n const selectedLis = Array.from(fromContainer.querySelectorAll<HTMLInputElement>('.item-select:checked')).map((inp) => inp.closest('li') as HTMLLIElement);\n \n selectedLis.forEach((li) => {\n const value = String(li.getAttribute('data-value'));\n const group = String(li.getAttribute('data-group'));\n \n // Find original item to preserve all properties\n const originalItem = this.originalData.find(item => String((item as any)[this.settings.valueName]) === value);\n if (!originalItem) return;\n\n if (fromGroups[group]) {\n fromGroups[group] = fromGroups[group].filter((i) => String((i as any)[this.settings.valueName]) !== value);\n if (fromGroups[group].length === 0 && (this.settings.hideEmptyGroups || fromSide !== 'left')) {\n delete (fromGroups as any)[group];\n }\n }\n if (!toGroups[group]) toGroups[group] = [];\n \n // Avoid duplicates\n if (!toGroups[group].some(i => String((i as any)[this.settings.valueName]) === value)) {\n toGroups[group].push(originalItem);\n }\n\n // Sort toGroups[group] based on originalData order\n this.sortGroup(toGroups[group]);\n });\n this.render();\n }\n\n private toggleSelectAll(side: 'left' | 'right', isChecked: boolean) {\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const content = contents[side === 'left' ? 0 : 1] as Element;\n content?.querySelectorAll<HTMLInputElement>('.group-select-all').forEach((inp) => (inp.checked = isChecked));\n content?.querySelectorAll<HTMLInputElement>('.item-select').forEach((inp) => (inp.checked = isChecked));\n this.updateSelectAllInfo(side);\n }\n\n private searchItems(side: 'left' | 'right', searchTerm: string) {\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const container = contents[side === 'left' ? 0 : 1] as HTMLElement;\n const searchText = (searchTerm || '').toLowerCase();\n container?.querySelectorAll<HTMLElement>('.dual-listbox-group').forEach((groupEl) => {\n const groupName = (groupEl.querySelector('.group-header')?.textContent || '').toLowerCase();\n const items = groupEl.querySelectorAll<HTMLElement>('li');\n let showGroup = false;\n if (groupName.includes(searchText)) {\n groupEl.style.display = '';\n items.forEach((li) => (li.style.display = ''));\n showGroup = true;\n } else {\n items.forEach((li) => {\n const itemText = (li.querySelector('label')?.textContent || '').toLowerCase();\n if (itemText.includes(searchText)) {\n li.style.display = '';\n showGroup = true;\n } else {\n li.style.display = 'none';\n }\n });\n groupEl.style.display = showGroup ? '' : 'none';\n }\n });\n if (!searchText) {\n container?.querySelectorAll<HTMLElement>('.dual-listbox-group').forEach((g) => (g.style.display = ''));\n container?.querySelectorAll<HTMLElement>('li').forEach((li) => (li.style.display = ''));\n }\n }\n\n private appendSelectedGroupsOnSubmit() {\n if (!this.formEl) {\n console.error('Parent form not found!');\n return;\n }\n const selectedValues: (string | number)[] = this.selectedArray;\n // remove existing\n Array.from(this.formEl.querySelectorAll(`input[name=\"${this.settings.inputName}[]\"]`)).forEach((el) => el.remove());\n // append new\n selectedValues.forEach((value) => {\n const input = document.createElement('input');\n input.type = 'hidden';\n input.name = `${this.settings.inputName}[]`;\n input.value = String(value);\n this.formEl!.appendChild(input);\n });\n }\n\n getSelectedValues(): Promise<(string | number)[]> {\n return new Promise((resolve) => {\n resolve(this.selectedArray);\n });\n }\n\n get selected() {\n return this.selectedGroups;\n }\n\n get selectedArray() {\n const selectedValues: (string | number)[] = [];\n this.originalData.forEach((item) => {\n const val = (item as any)[this.settings.valueName];\n const group = (item as any)[this.settings.groupName] || 'Ungrouped';\n if (this.selectedGroups[group]) {\n const isSelected = this.selectedGroups[group].some(\n (i) => String((i as any)[this.settings.valueName]) === String(val)\n );\n if (isSelected) {\n selectedValues.push(val);\n }\n }\n });\n return selectedValues;\n }\n\n get unselected() {\n return this.groups;\n }\n\n get allItems() {\n return this.settings.dataArray;\n }\n\n // New API methods: return arrays without duplicates\n getSelectedItems(): DualListBoxItem[] {\n const selected: DualListBoxItem[] = [];\n const values = this.selectedArray.map(String);\n this.originalData.forEach((item) => {\n if (values.includes(String((item as any)[this.settings.valueName]))) {\n selected.push(item);\n }\n });\n return selected;\n }\n\n getUnselectedItems(): DualListBoxItem[] {\n const unselected: DualListBoxItem[] = [];\n const selectedValues = this.selectedArray.map(String);\n this.originalData.forEach((item) => {\n if (!selectedValues.includes(String((item as any)[this.settings.valueName]))) {\n unselected.push(item);\n }\n });\n return unselected;\n }\n\n getAllItems(): DualListBoxItem[] {\n return [...this.originalData];\n }\n\n getSettings(): Required<DualListBoxOptions> & { theme: DualListBoxTheme } {\n return this.settings;\n }\n}\n\nexport function initDualListBox(selector: string | Element, options: DualListBoxOptions = {}) {\n return new DualListBox(selector, options);\n}\n\n// Attach back-compat static setTheme to the class\n// so existing code using DualListBox.setTheme(...) keeps working.\n(DualListBox as any).setTheme = (theme: Partial<DualListBoxTheme> | DualListBoxTheme) => useTheme(theme);\n"]}
package/dist/index.d.ts CHANGED
@@ -49,12 +49,15 @@ declare class DualListBox {
49
49
  private rootEl;
50
50
  private formEl;
51
51
  private instanceId;
52
+ private originalData;
52
53
  private defaults;
53
54
  private settings;
54
55
  private groups;
55
56
  private selectedGroups;
56
57
  constructor(element: Element | string, options?: DualListBoxOptions);
57
58
  private generateInstanceId;
59
+ private sortAllGroups;
60
+ private sortGroup;
58
61
  private buildGroups;
59
62
  private removeDuplicatesFromLeft;
60
63
  private render;
package/dist/index.mjs CHANGED
@@ -77,8 +77,10 @@ var DualListBox = class {
77
77
  const themeBase = mergeTheme(defaultTheme, GLOBAL_THEME);
78
78
  const theme = mergeTheme(themeBase, options.theme);
79
79
  this.settings = { ...this.defaults, ...options, theme };
80
+ this.originalData = [...this.settings.dataArray];
80
81
  this.groups = this.buildGroups(this.settings.dataArray);
81
82
  this.selectedGroups = this.buildGroups(this.settings.selectedItems);
83
+ this.sortAllGroups();
82
84
  this.removeDuplicatesFromLeft();
83
85
  this.render();
84
86
  this.bindEvents();
@@ -101,14 +103,32 @@ var DualListBox = class {
101
103
  }
102
104
  return id;
103
105
  }
106
+ sortAllGroups() {
107
+ [this.groups, this.selectedGroups].forEach((groupSet) => {
108
+ Object.keys(groupSet).forEach((groupName) => {
109
+ this.sortGroup(groupSet[groupName]);
110
+ });
111
+ });
112
+ }
113
+ sortGroup(group) {
114
+ group.sort((a, b) => {
115
+ const valA = String(a[this.settings.valueName]);
116
+ const valB = String(b[this.settings.valueName]);
117
+ const indexA = this.originalData.findIndex(
118
+ (item) => String(item[this.settings.valueName]) === valA
119
+ );
120
+ const indexB = this.originalData.findIndex(
121
+ (item) => String(item[this.settings.valueName]) === valB
122
+ );
123
+ return indexA - indexB;
124
+ });
125
+ }
104
126
  buildGroups(dataArray) {
105
127
  const groups = {};
106
128
  dataArray.forEach((item) => {
107
129
  const group = item[this.settings.groupName] || "Ungrouped";
108
130
  if (!groups[group]) groups[group] = [];
109
- if (!groups[group].some((existing) => existing[this.settings.valueName] === item[this.settings.valueName])) {
110
- groups[group].push(item);
111
- }
131
+ groups[group].push(item);
112
132
  });
113
133
  return groups;
114
134
  }
@@ -117,7 +137,7 @@ var DualListBox = class {
117
137
  if (this.groups[group]) {
118
138
  this.selectedGroups[group].forEach((selectedItem) => {
119
139
  this.groups[group] = this.groups[group].filter(
120
- (item) => item[this.settings.valueName] !== selectedItem[this.settings.valueName]
140
+ (item) => String(item[this.settings.valueName]) !== String(selectedItem[this.settings.valueName])
121
141
  );
122
142
  });
123
143
  if (this.settings.hideEmptyGroups) {
@@ -138,7 +158,7 @@ var DualListBox = class {
138
158
  <div class="${t.card}">
139
159
  <div class="${t.cardHeader}">${this.settings.tabNameText}</div>
140
160
  <div class="${t.cardBody}">
141
- <input id="dual_listbox_${this.instanceId}_left_search" type="text" class="${t.searchInput}" data-side="left" placeholder="${this.settings.searchPlaceholderText}">
161
+ <input id="dual_listbox_${this.instanceId}_left_search" type="text" class="${t.searchInput} dual-listbox-search" data-side="left" placeholder="${this.settings.searchPlaceholderText}">
142
162
  <div class="dual-listbox-content">
143
163
  ${this.generateGroupedListHTML("left")}
144
164
  </div>
@@ -150,14 +170,14 @@ var DualListBox = class {
150
170
  </div>
151
171
  </div>
152
172
  <div class="${t.colCenter}">
153
- <button class="${t.btn} dual-listbox-include ${t.btnInclude}" disabled>${this.settings.includeButtonText}</button>
154
- <button class="${t.btn} dual-listbox-exclude ${t.btnExclude}" disabled>${this.settings.excludeButtonText}</button>
173
+ <button type="button" class="${t.btn} dual-listbox-include ${t.btnInclude}" disabled>${this.settings.includeButtonText}</button>
174
+ <button type="button" class="${t.btn} dual-listbox-exclude ${t.btnExclude}" disabled>${this.settings.excludeButtonText}</button>
155
175
  </div>
156
176
  <div class="${t.colRight}" id="dual_listbox_${this.instanceId}_right_side">
157
177
  <div class="${t.card}">
158
178
  <div class="${t.cardHeader}">${this.settings.rightTabNameText}</div>
159
179
  <div class="${t.cardBody}">
160
- <input id="dual_listbox_${this.instanceId}_right_search" type="text" class="${t.searchInput}" data-side="right" placeholder="${this.settings.searchPlaceholderText}">
180
+ <input id="dual_listbox_${this.instanceId}_right_search" type="text" class="${t.searchInput} dual-listbox-search" data-side="right" placeholder="${this.settings.searchPlaceholderText}">
161
181
  <div class="dual-listbox-content">
162
182
  ${this.generateGroupedListHTML("right")}
163
183
  </div>
@@ -282,9 +302,10 @@ var DualListBox = class {
282
302
  const fromContainer = contents[fromSide === "left" ? 0 : 1];
283
303
  const selectedLis = Array.from(fromContainer.querySelectorAll(".item-select:checked")).map((inp) => inp.closest("li"));
284
304
  selectedLis.forEach((li) => {
285
- var _a;
286
305
  const value = String(li.getAttribute("data-value"));
287
306
  const group = String(li.getAttribute("data-group"));
307
+ const originalItem = this.originalData.find((item) => String(item[this.settings.valueName]) === value);
308
+ if (!originalItem) return;
288
309
  if (fromGroups[group]) {
289
310
  fromGroups[group] = fromGroups[group].filter((i) => String(i[this.settings.valueName]) !== value);
290
311
  if (fromGroups[group].length === 0 && (this.settings.hideEmptyGroups || fromSide !== "left")) {
@@ -292,12 +313,10 @@ var DualListBox = class {
292
313
  }
293
314
  }
294
315
  if (!toGroups[group]) toGroups[group] = [];
295
- const label = ((_a = li.querySelector("label")) == null ? void 0 : _a.textContent) || "";
296
- toGroups[group].push({
297
- [this.settings.itemName]: label,
298
- [this.settings.valueName]: value,
299
- [this.settings.groupName]: group
300
- });
316
+ if (!toGroups[group].some((i) => String(i[this.settings.valueName]) === value)) {
317
+ toGroups[group].push(originalItem);
318
+ }
319
+ this.sortGroup(toGroups[group]);
301
320
  });
302
321
  this.render();
303
322
  }
@@ -345,10 +364,7 @@ var DualListBox = class {
345
364
  console.error("Parent form not found!");
346
365
  return;
347
366
  }
348
- const selectedValues = [];
349
- Object.values(this.selectedGroups).forEach((items) => {
350
- items.forEach((item) => selectedValues.push(item[this.settings.valueName]));
351
- });
367
+ const selectedValues = this.selectedArray;
352
368
  Array.from(this.formEl.querySelectorAll(`input[name="${this.settings.inputName}[]"]`)).forEach((el) => el.remove());
353
369
  selectedValues.forEach((value) => {
354
370
  const input = document.createElement("input");
@@ -360,26 +376,26 @@ var DualListBox = class {
360
376
  }
361
377
  getSelectedValues() {
362
378
  return new Promise((resolve) => {
363
- const selectedValues = [];
364
- Object.keys(this.selectedGroups).forEach((groupName) => {
365
- this.selectedGroups[groupName].forEach((item) => {
366
- selectedValues.push(item[this.settings.valueName]);
367
- });
368
- });
369
- resolve(selectedValues);
379
+ resolve(this.selectedArray);
370
380
  });
371
381
  }
372
382
  get selected() {
373
383
  return this.selectedGroups;
374
384
  }
375
385
  get selectedArray() {
376
- let selectedValues = [];
377
- Object.keys(this.selectedGroups).forEach((groupName) => {
378
- this.selectedGroups[groupName].forEach((item) => {
379
- selectedValues.push(item[this.settings.valueName]);
380
- });
386
+ const selectedValues = [];
387
+ this.originalData.forEach((item) => {
388
+ const val = item[this.settings.valueName];
389
+ const group = item[this.settings.groupName] || "Ungrouped";
390
+ if (this.selectedGroups[group]) {
391
+ const isSelected = this.selectedGroups[group].some(
392
+ (i) => String(i[this.settings.valueName]) === String(val)
393
+ );
394
+ if (isSelected) {
395
+ selectedValues.push(val);
396
+ }
397
+ }
381
398
  });
382
- selectedValues = [...new Set(selectedValues)];
383
399
  return selectedValues;
384
400
  }
385
401
  get unselected() {
@@ -390,34 +406,27 @@ var DualListBox = class {
390
406
  }
391
407
  // New API methods: return arrays without duplicates
392
408
  getSelectedItems() {
393
- const map = /* @__PURE__ */ new Map();
394
- Object.values(this.selectedGroups).forEach((items) => {
395
- items.forEach((item) => {
396
- const key = String(item[this.settings.valueName]);
397
- if (!map.has(key)) map.set(key, item);
398
- });
409
+ const selected = [];
410
+ const values = this.selectedArray.map(String);
411
+ this.originalData.forEach((item) => {
412
+ if (values.includes(String(item[this.settings.valueName]))) {
413
+ selected.push(item);
414
+ }
399
415
  });
400
- return Array.from(map.values());
416
+ return selected;
401
417
  }
402
418
  getUnselectedItems() {
403
- const map = /* @__PURE__ */ new Map();
404
- Object.values(this.groups).forEach((items) => {
405
- items.forEach((item) => {
406
- const key = String(item[this.settings.valueName]);
407
- if (!map.has(key)) map.set(key, item);
408
- });
419
+ const unselected = [];
420
+ const selectedValues = this.selectedArray.map(String);
421
+ this.originalData.forEach((item) => {
422
+ if (!selectedValues.includes(String(item[this.settings.valueName]))) {
423
+ unselected.push(item);
424
+ }
409
425
  });
410
- return Array.from(map.values());
426
+ return unselected;
411
427
  }
412
428
  getAllItems() {
413
- const map = /* @__PURE__ */ new Map();
414
- Object.values(this.groups).forEach((items) => {
415
- items.forEach((item) => map.set(String(item[this.settings.valueName]), item));
416
- });
417
- Object.values(this.selectedGroups).forEach((items) => {
418
- items.forEach((item) => map.set(String(item[this.settings.valueName]), item));
419
- });
420
- return Array.from(map.values());
429
+ return [...this.originalData];
421
430
  }
422
431
  getSettings() {
423
432
  return this.settings;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/themePresets.ts","../src/lib/DualListBox.ts"],"names":["_a"],"mappings":"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","file":"index.mjs","sourcesContent":["import { DualListBoxTheme } from './types';\n\nexport const defaultTheme: DualListBoxTheme = {\n container: 'dual-listbox',\n row: 'row mb-3',\n colLeft: 'col-md-5',\n colCenter: 'col-md-2 d-flex justify-content-center flex-column gap-3',\n colRight: 'col-md-5',\n card: 'card h-100',\n cardHeader: 'card-header',\n cardBody: 'card-body',\n cardFooter: 'card-footer text-center',\n searchInput: 'form-control mb-3 dual-listbox-search',\n listGroup: 'list-group',\n listItem: 'list-group-item py-1 border-0',\n formCheck: 'form-check',\n formCheckInput: 'form-check-input',\n formCheckLabel: 'form-check-label',\n btn: 'btn btn-light w-100',\n btnInclude: '',\n btnExclude: '',\n};\n\nexport const bootstrapTheme: DualListBoxTheme = { ...defaultTheme };\n\nexport const tailwindTheme: DualListBoxTheme = {\n container: 'dual-listbox tw',\n row: 'grid grid-cols-1 md:grid-cols-5 gap-3',\n colLeft: 'md:col-span-2',\n colCenter: 'md:col-span-1 flex flex-col justify-center gap-3',\n colRight: 'md:col-span-2',\n card: 'h-full border rounded shadow-sm bg-white',\n cardHeader: 'px-4 py-2 border-b font-medium',\n cardBody: 'p-4',\n cardFooter: 'px-4 py-2 border-t text-center',\n searchInput: 'w-full mb-3 border rounded px-3 py-2 dual-listbox-search',\n listGroup: 'space-y-1',\n listItem: 'py-1',\n formCheck: 'flex items-center gap-2',\n formCheckInput: 'h-4 w-4',\n formCheckLabel: '',\n btn: 'w-full border rounded px-3 py-2 bg-gray-100 hover:bg-gray-200',\n btnInclude: 'mb-2',\n btnExclude: '',\n};\n","import type {DualListBoxItem, DualListBoxOptions, DualListBoxTheme} from './types';\nimport {defaultTheme} from './themePresets';\n\nfunction mergeTheme(base: DualListBoxTheme, override?: Partial<DualListBoxTheme>): DualListBoxTheme {\n return {...base, ...(override || {})} as DualListBoxTheme;\n}\n\n// Global theme state (module-level)\nlet GLOBAL_THEME: DualListBoxTheme = {...defaultTheme};\n\n/**\n * Set the global default theme for all new DualListBox instances.\n * Instance option `theme` still has highest priority.\n */\nexport function useTheme(theme: Partial<DualListBoxTheme> | DualListBoxTheme) {\n GLOBAL_THEME = mergeTheme(defaultTheme, theme as Partial<DualListBoxTheme>);\n}\n\n// Back-compat alias for older code that might call DualListBox.setTheme(...)\n// We will attach a static setTheme on the class after its definition.\n\nexport class DualListBox {\n private rootEl: Element;\n private formEl: HTMLFormElement | null;\n\n private instanceId: string;\n\n private defaults: Required<Omit<DualListBoxOptions, 'theme'>> & { theme: DualListBoxTheme };\n private settings: Required<DualListBoxOptions> & { theme: DualListBoxTheme };\n\n private groups: Record<string, DualListBoxItem[]> = {};\n private selectedGroups: Record<string, DualListBoxItem[]> = {};\n\n constructor(element: Element | string, options: DualListBoxOptions = {}) {\n this.rootEl = typeof element === 'string' ? (document.querySelector(element) as Element) : (element as Element);\n if (!this.rootEl) throw new Error('DualListBox root element not found');\n this.formEl = (this.rootEl.closest('form') as HTMLFormElement) || null;\n this.instanceId = this.generateInstanceId();\n this.defaults = {\n itemName: 'item',\n groupName: 'group',\n valueName: 'value',\n inputName: 'selectedItems',\n tabNameText: 'Available Items',\n rightTabNameText: 'Selected Items',\n searchPlaceholderText: 'Search...',\n includeButtonText: 'Include >>',\n excludeButtonText: '<< Exclude',\n dataArray: [],\n selectedItems: [],\n hideEmptyGroups: false,\n submitForm: true,\n onSubmit: null,\n theme: defaultTheme,\n } as any;\n\n // Effective theme precedence: options.theme > GLOBAL_THEME > defaultTheme\n const themeBase = mergeTheme(defaultTheme, GLOBAL_THEME);\n const theme = mergeTheme(themeBase, options.theme);\n this.settings = {...(this.defaults as any), ...(options as any), theme};\n\n this.groups = this.buildGroups(this.settings.dataArray);\n this.selectedGroups = this.buildGroups(this.settings.selectedItems);\n\n this.removeDuplicatesFromLeft();\n this.render();\n this.bindEvents();\n\n if (this.formEl) {\n this.formEl.addEventListener('submit', (event) => {\n if (typeof this.settings.onSubmit === 'function') {\n event.preventDefault();\n this.settings.onSubmit(this.selected, this.unselected, this.allItems, this.selectedArray);\n } else if (this.settings.submitForm) {\n this.appendSelectedGroupsOnSubmit();\n }\n });\n }\n }\n\n private generateInstanceId() {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let id = '';\n for (let i = 0; i < 36; i++) {\n id += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return id;\n }\n\n private buildGroups(dataArray: DualListBoxItem[]) {\n const groups: Record<string, DualListBoxItem[]> = {};\n dataArray.forEach((item) => {\n const group = (item as any)[this.settings.groupName] || 'Ungrouped';\n if (!groups[group]) groups[group] = [];\n if (!groups[group].some((existing) => (existing as any)[this.settings.valueName] === (item as any)[this.settings.valueName])) {\n groups[group].push(item);\n }\n });\n return groups;\n }\n\n private removeDuplicatesFromLeft() {\n Object.keys(this.selectedGroups).forEach((group) => {\n if (this.groups[group]) {\n this.selectedGroups[group].forEach((selectedItem) => {\n this.groups[group] = this.groups[group].filter(\n (item) => (item as any)[this.settings.valueName] !== (selectedItem as any)[this.settings.valueName]\n );\n });\n if (this.settings.hideEmptyGroups) {\n if (!this.groups[group].length) {\n delete this.groups[group];\n }\n }\n }\n });\n this.render();\n }\n\n private render() {\n const t = this.settings.theme;\n const template = `\n <div class=\"${t.container}\" id=\"dual_listbox_${this.instanceId}\">\n <div class=\"${t.row}\">\n <div class=\"${t.colLeft}\" id=\"dual_listbox_${this.instanceId}_left_side\">\n <div class=\"${t.card}\">\n <div class=\"${t.cardHeader}\">${this.settings.tabNameText}</div>\n <div class=\"${t.cardBody}\">\n <input id=\"dual_listbox_${this.instanceId}_left_search\" type=\"text\" class=\"${t.searchInput}\" data-side=\"left\" placeholder=\"${this.settings.searchPlaceholderText}\">\n <div class=\"dual-listbox-content\">\n ${this.generateGroupedListHTML('left')}\n </div>\n </div>\n <div class=\"${t.cardFooter}\">\n <input type=\"checkbox\" class=\"${t.formCheckInput} dual-listbox-select-all-left\" disabled>\n <label class=\"${t.formCheckLabel}\">Select All (<span class=\"dual-listbox-left-selected\">0</span>/<span class=\"dual-listbox-left-total\">0</span>)</label>\n </div>\n </div>\n </div>\n <div class=\"${t.colCenter}\">\n <button class=\"${t.btn} dual-listbox-include ${t.btnInclude}\" disabled>${this.settings.includeButtonText}</button>\n <button class=\"${t.btn} dual-listbox-exclude ${t.btnExclude}\" disabled>${this.settings.excludeButtonText}</button>\n </div>\n <div class=\"${t.colRight}\" id=\"dual_listbox_${this.instanceId}_right_side\">\n <div class=\"${t.card}\">\n <div class=\"${t.cardHeader}\">${this.settings.rightTabNameText}</div>\n <div class=\"${t.cardBody}\">\n <input id=\"dual_listbox_${this.instanceId}_right_search\" type=\"text\" class=\"${t.searchInput}\" data-side=\"right\" placeholder=\"${this.settings.searchPlaceholderText}\">\n <div class=\"dual-listbox-content\">\n ${this.generateGroupedListHTML('right')}\n </div>\n </div>\n <div class=\"${t.cardFooter}\">\n <input type=\"checkbox\" class=\"${t.formCheckInput} dual-listbox-select-all-right\" disabled>\n <label class=\"${t.formCheckLabel}\">Select All (<span class=\"dual-listbox-right-selected\">0</span>/<span class=\"dual-listbox-right-total\">0</span>)</label>\n </div>\n </div>\n </div>\n </div>\n </div>`;\n this.rootEl.innerHTML = template;\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n }\n\n private generateGroupedListHTML(side: 'left' | 'right') {\n const t = this.settings.theme;\n const groups = side === 'left' ? this.groups : this.selectedGroups;\n let html = '';\n const keys = Object.keys(groups);\n keys.forEach((groupName, index) => {\n const items = groups[groupName];\n const totalItems = items.length;\n const isGroupEmpty = totalItems === 0;\n const groupSelectAllInput = `group_${groupName}_${side}`;\n const isLast = index === keys.length - 1;\n html += `\n <div class=\"dual-listbox-group${!isLast ? ' mb-3' : ''}\">\n <div class=\"group-header mb-2\">\n <div class=\"${t.formCheck}\">\n <input id=\"${groupSelectAllInput}\" type=\"checkbox\" class=\"${t.formCheckInput} group-select-all\" ${isGroupEmpty ? 'checked disabled' : ''}>\n <label for=\"${groupSelectAllInput}\" class=\"${t.formCheckLabel}\">${groupName}</label>\n </div>\n </div>`;\n if (!isGroupEmpty) {\n html += `<ul class=\"${t.listGroup}\">`;\n items.forEach((item) => {\n const val = (item as any)[this.settings.valueName];\n const name = (item as any)[this.settings.itemName];\n html += `\n <li class=\"${t.listItem}\" data-value=\"${val}\" data-group=\"${groupName}\">\n <div class=\"${t.formCheck}\">\n <input id=\"${groupName}_${val}\" type=\"checkbox\" class=\"${t.formCheckInput} item-select\" />\n <label for=\"${groupName}_${val}\" class=\"${t.formCheckLabel}\">${name}</label>\n </div>\n </li>`;\n });\n html += `</ul>`;\n }\n html += `</div>`;\n });\n return html;\n }\n\n private updateSelectAllInfo(side: 'left' | 'right') {\n const idx = side === 'left' ? 0 : 1;\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const content = contents[idx] as Element;\n const selectAll = this.rootEl.querySelector<HTMLInputElement>(`.dual-listbox-select-all-${side}`);\n const totalItems = content ? content.querySelectorAll('.item-select').length : 0;\n const selectedItems = content ? content.querySelectorAll('.item-select:checked').length : 0;\n const selSpan = this.rootEl.querySelector(`.dual-listbox-${side}-selected`);\n const totalSpan = this.rootEl.querySelector(`.dual-listbox-${side}-total`);\n if (selSpan) selSpan.textContent = String(selectedItems);\n if (totalSpan) totalSpan.textContent = String(totalItems);\n if (selectAll) {\n if (totalItems === 0) {\n selectAll.disabled = true;\n selectAll.checked = true;\n } else {\n selectAll.disabled = false;\n selectAll.checked = selectedItems === totalItems;\n }\n }\n\n // Enable/disable include/exclude buttons based on selections\n const includeBtn = this.rootEl.querySelector<HTMLButtonElement>('.dual-listbox-include');\n const excludeBtn = this.rootEl.querySelector<HTMLButtonElement>('.dual-listbox-exclude');\n const leftContent = contents[0] as Element | undefined;\n const rightContent = contents[1] as Element | undefined;\n const leftChecked = leftContent ? leftContent.querySelectorAll('.item-select:checked').length : 0;\n const rightChecked = rightContent ? rightContent.querySelectorAll('.item-select:checked').length : 0;\n if (includeBtn) includeBtn.disabled = leftChecked === 0;\n if (excludeBtn) excludeBtn.disabled = rightChecked === 0;\n }\n\n private bindEvents() {\n this.rootEl.addEventListener('click', (e) => {\n const target = e.target as HTMLElement;\n if (target.closest('.dual-listbox-include')) {\n this.moveItems('left', 'right');\n } else if (target.closest('.dual-listbox-exclude')) {\n this.moveItems('right', 'left');\n }\n });\n this.rootEl.addEventListener('change', (e) => {\n const target = e.target as HTMLInputElement;\n if (target.matches('.dual-listbox-select-all-left')) {\n this.toggleSelectAll('left', target.checked);\n } else if (target.matches('.dual-listbox-select-all-right')) {\n this.toggleSelectAll('right', target.checked);\n } else if (target.matches('.group-select-all')) {\n const groupEl = target.closest('.dual-listbox-group') as Element;\n groupEl?.querySelectorAll<HTMLInputElement>('.item-select').forEach((inp) => (inp.checked = target.checked));\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n } else if (target.matches('.item-select')) {\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n }\n });\n this.rootEl.addEventListener('input', (e) => {\n const target = e.target as HTMLInputElement;\n if (target.matches('.dual-listbox-search')) {\n const side = (target.getAttribute('data-side') as 'left' | 'right') || 'left';\n const searchTerm = target.value || '';\n this.searchItems(side, searchTerm);\n }\n });\n }\n\n private moveItems(fromSide: 'left' | 'right', toSide: 'left' | 'right') {\n const fromGroups = fromSide === 'left' ? this.groups : this.selectedGroups;\n const toGroups = toSide === 'left' ? this.groups : this.selectedGroups;\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const fromContainer = contents[fromSide === 'left' ? 0 : 1] as Element;\n const selectedLis = Array.from(fromContainer.querySelectorAll<HTMLInputElement>('.item-select:checked')).map((inp) => inp.closest('li') as HTMLLIElement);\n selectedLis.forEach((li) => {\n const value = String(li.getAttribute('data-value'));\n const group = String(li.getAttribute('data-group'));\n if (fromGroups[group]) {\n fromGroups[group] = fromGroups[group].filter((i) => String((i as any)[this.settings.valueName]) !== value);\n if (fromGroups[group].length === 0 && (this.settings.hideEmptyGroups || fromSide !== 'left')) {\n delete (fromGroups as any)[group];\n }\n }\n if (!toGroups[group]) toGroups[group] = [];\n const label = li.querySelector('label')?.textContent || '';\n toGroups[group].push({\n [this.settings.itemName]: label,\n [this.settings.valueName]: value,\n [this.settings.groupName]: group,\n } as any);\n });\n this.render();\n }\n\n private toggleSelectAll(side: 'left' | 'right', isChecked: boolean) {\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const content = contents[side === 'left' ? 0 : 1] as Element;\n content?.querySelectorAll<HTMLInputElement>('.group-select-all').forEach((inp) => (inp.checked = isChecked));\n content?.querySelectorAll<HTMLInputElement>('.item-select').forEach((inp) => (inp.checked = isChecked));\n this.updateSelectAllInfo(side);\n }\n\n private searchItems(side: 'left' | 'right', searchTerm: string) {\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const container = contents[side === 'left' ? 0 : 1] as HTMLElement;\n const searchText = (searchTerm || '').toLowerCase();\n container?.querySelectorAll<HTMLElement>('.dual-listbox-group').forEach((groupEl) => {\n const groupName = (groupEl.querySelector('.group-header')?.textContent || '').toLowerCase();\n const items = groupEl.querySelectorAll<HTMLElement>('li');\n let showGroup = false;\n if (groupName.includes(searchText)) {\n groupEl.style.display = '';\n items.forEach((li) => (li.style.display = ''));\n showGroup = true;\n } else {\n items.forEach((li) => {\n const itemText = (li.querySelector('label')?.textContent || '').toLowerCase();\n if (itemText.includes(searchText)) {\n li.style.display = '';\n showGroup = true;\n } else {\n li.style.display = 'none';\n }\n });\n groupEl.style.display = showGroup ? '' : 'none';\n }\n });\n if (!searchText) {\n container?.querySelectorAll<HTMLElement>('.dual-listbox-group').forEach((g) => (g.style.display = ''));\n container?.querySelectorAll<HTMLElement>('li').forEach((li) => (li.style.display = ''));\n }\n }\n\n private appendSelectedGroupsOnSubmit() {\n if (!this.formEl) {\n console.error('Parent form not found!');\n return;\n }\n const selectedValues: (string | number)[] = [];\n Object.values(this.selectedGroups).forEach((items) => {\n items.forEach((item) => selectedValues.push((item as any)[this.settings.valueName]));\n });\n // remove existing\n Array.from(this.formEl.querySelectorAll(`input[name=\"${this.settings.inputName}[]\"]`)).forEach((el) => el.remove());\n // append new\n selectedValues.forEach((value) => {\n const input = document.createElement('input');\n input.type = 'hidden';\n input.name = `${this.settings.inputName}[]`;\n input.value = String(value);\n this.formEl!.appendChild(input);\n });\n }\n\n getSelectedValues(): Promise<(string | number)[]> {\n return new Promise((resolve) => {\n const selectedValues: (string | number)[] = [];\n Object.keys(this.selectedGroups).forEach((groupName) => {\n this.selectedGroups[groupName].forEach((item) => {\n selectedValues.push((item as any)[this.settings.valueName]);\n });\n });\n resolve(selectedValues);\n });\n }\n\n get selected() {\n return this.selectedGroups;\n }\n\n get selectedArray() {\n let selectedValues: (string | number)[] = [];\n Object.keys(this.selectedGroups).forEach((groupName) => {\n this.selectedGroups[groupName].forEach((item) => {\n selectedValues.push((item as any)[this.settings.valueName]);\n });\n });\n selectedValues = [...new Set(selectedValues)];\n return selectedValues;\n }\n\n get unselected() {\n return this.groups;\n }\n\n get allItems() {\n return this.settings.dataArray;\n }\n\n // New API methods: return arrays without duplicates\n getSelectedItems(): DualListBoxItem[] {\n const map = new Map<string, DualListBoxItem>();\n Object.values(this.selectedGroups).forEach((items) => {\n items.forEach((item) => {\n const key = String((item as any)[this.settings.valueName]);\n if (!map.has(key)) map.set(key, item);\n });\n });\n return Array.from(map.values());\n }\n\n getUnselectedItems(): DualListBoxItem[] {\n const map = new Map<string, DualListBoxItem>();\n Object.values(this.groups).forEach((items) => {\n items.forEach((item) => {\n const key = String((item as any)[this.settings.valueName]);\n if (!map.has(key)) map.set(key, item);\n });\n });\n return Array.from(map.values());\n }\n\n getAllItems(): DualListBoxItem[] {\n const map = new Map<string, DualListBoxItem>();\n // include current left and right to reflect UI state\n Object.values(this.groups).forEach((items) => {\n items.forEach((item) => map.set(String((item as any)[this.settings.valueName]), item));\n });\n Object.values(this.selectedGroups).forEach((items) => {\n items.forEach((item) => map.set(String((item as any)[this.settings.valueName]), item));\n });\n return Array.from(map.values());\n }\n\n getSettings(): Required<DualListBoxOptions> & { theme: DualListBoxTheme } {\n return this.settings;\n }\n}\n\nexport function initDualListBox(selector: string | Element, options: DualListBoxOptions = {}) {\n return new DualListBox(selector, options);\n}\n\n// Attach back-compat static setTheme to the class\n// so existing code using DualListBox.setTheme(...) keeps working.\n(DualListBox as any).setTheme = (theme: Partial<DualListBoxTheme> | DualListBoxTheme) => useTheme(theme);\n"]}
1
+ {"version":3,"sources":["../src/lib/themePresets.ts","../src/lib/DualListBox.ts"],"names":["_a"],"mappings":";AAEO,IAAM,YAAA,GAAiC;AAAA,EAC5C,SAAA,EAAW,cAAA;AAAA,EACX,GAAA,EAAK,UAAA;AAAA,EACL,OAAA,EAAS,UAAA;AAAA,EACT,SAAA,EAAW,0DAAA;AAAA,EACX,QAAA,EAAU,UAAA;AAAA,EACV,IAAA,EAAM,YAAA;AAAA,EACN,UAAA,EAAY,aAAA;AAAA,EACZ,QAAA,EAAU,WAAA;AAAA,EACV,UAAA,EAAY,yBAAA;AAAA,EACZ,WAAA,EAAa,uCAAA;AAAA,EACb,SAAA,EAAW,YAAA;AAAA,EACX,QAAA,EAAU,+BAAA;AAAA,EACV,SAAA,EAAW,YAAA;AAAA,EACX,cAAA,EAAgB,kBAAA;AAAA,EAChB,cAAA,EAAgB,kBAAA;AAAA,EAChB,GAAA,EAAK,qBAAA;AAAA,EACL,UAAA,EAAY,EAAA;AAAA,EACZ,UAAA,EAAY;AACd;AAEO,IAAM,cAAA,GAAmC,EAAE,GAAG,YAAA;AAE9C,IAAM,aAAA,GAAkC;AAAA,EAC7C,SAAA,EAAW,iBAAA;AAAA,EACX,GAAA,EAAK,uCAAA;AAAA,EACL,OAAA,EAAS,eAAA;AAAA,EACT,SAAA,EAAW,kDAAA;AAAA,EACX,QAAA,EAAU,eAAA;AAAA,EACV,IAAA,EAAM,0CAAA;AAAA,EACN,UAAA,EAAY,gCAAA;AAAA,EACZ,QAAA,EAAU,KAAA;AAAA,EACV,UAAA,EAAY,gCAAA;AAAA,EACZ,WAAA,EAAa,0DAAA;AAAA,EACb,SAAA,EAAW,WAAA;AAAA,EACX,QAAA,EAAU,MAAA;AAAA,EACV,SAAA,EAAW,yBAAA;AAAA,EACX,cAAA,EAAgB,SAAA;AAAA,EAChB,cAAA,EAAgB,EAAA;AAAA,EAChB,GAAA,EAAK,+DAAA;AAAA,EACL,UAAA,EAAY,MAAA;AAAA,EACZ,UAAA,EAAY;AACd;;;ACzCA,SAAS,UAAA,CAAW,MAAwB,QAAA,EAAwD;AAChG,EAAA,OAAO,EAAC,GAAG,IAAA,EAAM,GAAI,QAAA,IAAY,EAAC,EAAE;AACxC;AAGA,IAAI,YAAA,GAAiC,EAAC,GAAG,YAAA,EAAY;AAM9C,SAAS,SAAS,KAAA,EAAqD;AAC1E,EAAA,YAAA,GAAe,UAAA,CAAW,cAAc,KAAkC,CAAA;AAC9E;AAKO,IAAM,cAAN,MAAkB;AAAA,EAarB,WAAA,CAAY,OAAA,EAA2B,OAAA,GAA8B,EAAC,EAAG;AAHzE,IAAA,IAAA,CAAQ,SAA4C,EAAC;AACrD,IAAA,IAAA,CAAQ,iBAAoD,EAAC;AAGzD,IAAA,IAAA,CAAK,SAAS,OAAO,OAAA,KAAY,WAAY,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA,GAAiB,OAAA;AAC5F,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,EAAQ,MAAM,IAAI,MAAM,oCAAoC,CAAA;AACtE,IAAA,IAAA,CAAK,MAAA,GAAU,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,IAAyB,IAAA;AAClE,IAAA,IAAA,CAAK,UAAA,GAAa,KAAK,kBAAA,EAAmB;AAC1C,IAAA,IAAA,CAAK,QAAA,GAAW;AAAA,MACZ,QAAA,EAAU,MAAA;AAAA,MACV,SAAA,EAAW,OAAA;AAAA,MACX,SAAA,EAAW,OAAA;AAAA,MACX,SAAA,EAAW,eAAA;AAAA,MACX,WAAA,EAAa,iBAAA;AAAA,MACb,gBAAA,EAAkB,gBAAA;AAAA,MAClB,qBAAA,EAAuB,WAAA;AAAA,MACvB,iBAAA,EAAmB,YAAA;AAAA,MACnB,iBAAA,EAAmB,YAAA;AAAA,MACnB,WAAW,EAAC;AAAA,MACZ,eAAe,EAAC;AAAA,MAChB,eAAA,EAAiB,KAAA;AAAA,MACjB,UAAA,EAAY,IAAA;AAAA,MACZ,QAAA,EAAU,IAAA;AAAA,MACV,KAAA,EAAO;AAAA,KACX;AAGA,IAAA,MAAM,SAAA,GAAY,UAAA,CAAW,YAAA,EAAc,YAAY,CAAA;AACvD,IAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,SAAA,EAAW,OAAA,CAAQ,KAAK,CAAA;AACjD,IAAA,IAAA,CAAK,WAAW,EAAC,GAAI,KAAK,QAAA,EAAkB,GAAI,SAAiB,KAAA,EAAK;AAEtE,IAAA,IAAA,CAAK,YAAA,GAAe,CAAC,GAAG,IAAA,CAAK,SAAS,SAAS,CAAA;AAC/C,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA,CAAK,WAAA,CAAY,IAAA,CAAK,SAAS,SAAS,CAAA;AACtD,IAAA,IAAA,CAAK,cAAA,GAAiB,IAAA,CAAK,WAAA,CAAY,IAAA,CAAK,SAAS,aAAa,CAAA;AAGlE,IAAA,IAAA,CAAK,aAAA,EAAc;AAEnB,IAAA,IAAA,CAAK,wBAAA,EAAyB;AAC9B,IAAA,IAAA,CAAK,MAAA,EAAO;AACZ,IAAA,IAAA,CAAK,UAAA,EAAW;AAEhB,IAAA,IAAI,KAAK,MAAA,EAAQ;AACb,MAAA,IAAA,CAAK,MAAA,CAAO,gBAAA,CAAiB,QAAA,EAAU,CAAC,KAAA,KAAU;AAC9C,QAAA,IAAI,OAAO,IAAA,CAAK,QAAA,CAAS,QAAA,KAAa,UAAA,EAAY;AAC9C,UAAA,KAAA,CAAM,cAAA,EAAe;AACrB,UAAA,IAAA,CAAK,QAAA,CAAS,SAAS,IAAA,CAAK,QAAA,EAAU,KAAK,UAAA,EAAY,IAAA,CAAK,QAAA,EAAU,IAAA,CAAK,aAAa,CAAA;AAAA,QAC5F,CAAA,MAAA,IAAW,IAAA,CAAK,QAAA,CAAS,UAAA,EAAY;AACjC,UAAA,IAAA,CAAK,4BAAA,EAA6B;AAAA,QACtC;AAAA,MACJ,CAAC,CAAA;AAAA,IACL;AAAA,EACJ;AAAA,EAEQ,kBAAA,GAAqB;AACzB,IAAA,MAAM,KAAA,GAAQ,gEAAA;AACd,IAAA,IAAI,EAAA,GAAK,EAAA;AACT,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,EAAA,EAAI,CAAA,EAAA,EAAK;AACzB,MAAA,EAAA,IAAM,KAAA,CAAM,OAAO,IAAA,CAAK,KAAA,CAAM,KAAK,MAAA,EAAO,GAAI,KAAA,CAAM,MAAM,CAAC,CAAA;AAAA,IAC/D;AACA,IAAA,OAAO,EAAA;AAAA,EACX;AAAA,EAEQ,aAAA,GAAgB;AACpB,IAAA,CAAC,KAAK,MAAA,EAAQ,IAAA,CAAK,cAAc,CAAA,CAAE,OAAA,CAAQ,CAAC,QAAA,KAAa;AACrD,MAAA,MAAA,CAAO,IAAA,CAAK,QAAQ,CAAA,CAAE,OAAA,CAAQ,CAAC,SAAA,KAAc;AACzC,QAAA,IAAA,CAAK,SAAA,CAAU,QAAA,CAAS,SAAS,CAAC,CAAA;AAAA,MACtC,CAAC,CAAA;AAAA,IACL,CAAC,CAAA;AAAA,EACL;AAAA,EAEQ,UAAU,KAAA,EAA0B;AACxC,IAAA,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM;AACjB,MAAA,MAAM,OAAO,MAAA,CAAQ,CAAA,CAAU,IAAA,CAAK,QAAA,CAAS,SAAS,CAAC,CAAA;AACvD,MAAA,MAAM,OAAO,MAAA,CAAQ,CAAA,CAAU,IAAA,CAAK,QAAA,CAAS,SAAS,CAAC,CAAA;AACvD,MAAA,MAAM,MAAA,GAAS,KAAK,YAAA,CAAa,SAAA;AAAA,QAC7B,CAAC,SAAS,MAAA,CAAQ,IAAA,CAAa,KAAK,QAAA,CAAS,SAAS,CAAC,CAAA,KAAM;AAAA,OACjE;AACA,MAAA,MAAM,MAAA,GAAS,KAAK,YAAA,CAAa,SAAA;AAAA,QAC7B,CAAC,SAAS,MAAA,CAAQ,IAAA,CAAa,KAAK,QAAA,CAAS,SAAS,CAAC,CAAA,KAAM;AAAA,OACjE;AACA,MAAA,OAAO,MAAA,GAAS,MAAA;AAAA,IACpB,CAAC,CAAA;AAAA,EACL;AAAA,EAEQ,YAAY,SAAA,EAA8B;AAC9C,IAAA,MAAM,SAA4C,EAAC;AACnD,IAAA,SAAA,CAAU,OAAA,CAAQ,CAAC,IAAA,KAAS;AACxB,MAAA,MAAM,KAAA,GAAS,IAAA,CAAa,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA,IAAK,WAAA;AACxD,MAAA,IAAI,CAAC,MAAA,CAAO,KAAK,GAAG,MAAA,CAAO,KAAK,IAAI,EAAC;AACrC,MAAA,MAAA,CAAO,KAAK,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAAA,IAC3B,CAAC,CAAA;AACD,IAAA,OAAO,MAAA;AAAA,EACX;AAAA,EAEQ,wBAAA,GAA2B;AAC/B,IAAA,MAAA,CAAO,KAAK,IAAA,CAAK,cAAc,CAAA,CAAE,OAAA,CAAQ,CAAC,KAAA,KAAU;AAChD,MAAA,IAAI,IAAA,CAAK,MAAA,CAAO,KAAK,CAAA,EAAG;AACpB,QAAA,IAAA,CAAK,cAAA,CAAe,KAAK,CAAA,CAAE,OAAA,CAAQ,CAAC,YAAA,KAAiB;AACjD,UAAA,IAAA,CAAK,OAAO,KAAK,CAAA,GAAI,IAAA,CAAK,MAAA,CAAO,KAAK,CAAA,CAAE,MAAA;AAAA,YACpC,CAAC,IAAA,KAAS,MAAA,CAAQ,IAAA,CAAa,KAAK,QAAA,CAAS,SAAS,CAAC,CAAA,KAAM,MAAA,CAAQ,YAAA,CAAqB,IAAA,CAAK,QAAA,CAAS,SAAS,CAAC;AAAA,WACtH;AAAA,QACJ,CAAC,CAAA;AACD,QAAA,IAAI,IAAA,CAAK,SAAS,eAAA,EAAiB;AAC/B,UAAA,IAAI,CAAC,IAAA,CAAK,MAAA,CAAO,KAAK,EAAE,MAAA,EAAQ;AAC5B,YAAA,OAAO,IAAA,CAAK,OAAO,KAAK,CAAA;AAAA,UAC5B;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ,CAAC,CAAA;AACD,IAAA,IAAA,CAAK,MAAA,EAAO;AAAA,EAChB;AAAA,EAEQ,MAAA,GAAS;AACb,IAAA,MAAM,CAAA,GAAI,KAAK,QAAA,CAAS,KAAA;AACxB,IAAA,MAAM,QAAA,GAAW;AAAA,kBAAA,EACL,CAAA,CAAE,SAAS,CAAA,mBAAA,EAAsB,IAAA,CAAK,UAAU,CAAA;AAAA,oBAAA,EAC9C,EAAE,GAAG,CAAA;AAAA,sBAAA,EACH,CAAA,CAAE,OAAO,CAAA,mBAAA,EAAsB,IAAA,CAAK,UAAU,CAAA;AAAA,wBAAA,EAC5C,EAAE,IAAI,CAAA;AAAA,0BAAA,EACJ,CAAA,CAAE,UAAU,CAAA,EAAA,EAAK,IAAA,CAAK,SAAS,WAAW,CAAA;AAAA,0BAAA,EAC1C,EAAE,QAAQ,CAAA;AAAA,wCAAA,EACI,IAAA,CAAK,UAAU,CAAA,iCAAA,EAAoC,CAAA,CAAE,WAAW,CAAA,oDAAA,EAAuD,IAAA,CAAK,SAAS,qBAAqB,CAAA;AAAA;AAAA,kBAAA,EAEhL,IAAA,CAAK,uBAAA,CAAwB,MAAM,CAAC;AAAA;AAAA;AAAA,0BAAA,EAG5B,EAAE,UAAU,CAAA;AAAA,8CAAA,EACQ,EAAE,cAAc,CAAA;AAAA,8BAAA,EAChC,EAAE,cAAc,CAAA;AAAA;AAAA;AAAA;AAAA,sBAAA,EAIxB,EAAE,SAAS,CAAA;AAAA,yCAAA,EACQ,CAAA,CAAE,GAAG,CAAA,sBAAA,EAAyB,CAAA,CAAE,UAAU,CAAA,WAAA,EAAc,IAAA,CAAK,SAAS,iBAAiB,CAAA;AAAA,yCAAA,EACvF,CAAA,CAAE,GAAG,CAAA,sBAAA,EAAyB,CAAA,CAAE,UAAU,CAAA,WAAA,EAAc,IAAA,CAAK,SAAS,iBAAiB,CAAA;AAAA;AAAA,sBAAA,EAE1G,CAAA,CAAE,QAAQ,CAAA,mBAAA,EAAsB,IAAA,CAAK,UAAU,CAAA;AAAA,wBAAA,EAC7C,EAAE,IAAI,CAAA;AAAA,0BAAA,EACJ,CAAA,CAAE,UAAU,CAAA,EAAA,EAAK,IAAA,CAAK,SAAS,gBAAgB,CAAA;AAAA,0BAAA,EAC/C,EAAE,QAAQ,CAAA;AAAA,wCAAA,EACI,IAAA,CAAK,UAAU,CAAA,kCAAA,EAAqC,CAAA,CAAE,WAAW,CAAA,qDAAA,EAAwD,IAAA,CAAK,SAAS,qBAAqB,CAAA;AAAA;AAAA,kBAAA,EAElL,IAAA,CAAK,uBAAA,CAAwB,OAAO,CAAC;AAAA;AAAA;AAAA,0BAAA,EAG7B,EAAE,UAAU,CAAA;AAAA,8CAAA,EACQ,EAAE,cAAc,CAAA;AAAA,8BAAA,EAChC,EAAE,cAAc,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAAA,CAAA;AAMxC,IAAA,IAAA,CAAK,OAAO,SAAA,GAAY,QAAA;AACxB,IAAA,IAAA,CAAK,oBAAoB,MAAM,CAAA;AAC/B,IAAA,IAAA,CAAK,oBAAoB,OAAO,CAAA;AAAA,EACpC;AAAA,EAEQ,wBAAwB,IAAA,EAAwB;AACpD,IAAA,MAAM,CAAA,GAAI,KAAK,QAAA,CAAS,KAAA;AACxB,IAAA,MAAM,MAAA,GAAS,IAAA,KAAS,MAAA,GAAS,IAAA,CAAK,SAAS,IAAA,CAAK,cAAA;AACpD,IAAA,IAAI,IAAA,GAAO,EAAA;AACX,IAAA,MAAM,IAAA,GAAO,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA;AAC/B,IAAA,IAAA,CAAK,OAAA,CAAQ,CAAC,SAAA,EAAW,KAAA,KAAU;AAC/B,MAAA,MAAM,KAAA,GAAQ,OAAO,SAAS,CAAA;AAC9B,MAAA,MAAM,aAAa,KAAA,CAAM,MAAA;AACzB,MAAA,MAAM,eAAe,UAAA,KAAe,CAAA;AACpC,MAAA,MAAM,mBAAA,GAAsB,CAAA,MAAA,EAAS,SAAS,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA;AACtD,MAAA,MAAM,MAAA,GAAS,KAAA,KAAU,IAAA,CAAK,MAAA,GAAS,CAAA;AACvC,MAAA,IAAA,IAAQ;AAAA,sCAAA,EACoB,CAAC,MAAA,GAAS,OAAA,GAAU,EAAE,CAAA;AAAA;AAAA,wBAAA,EAEpC,EAAE,SAAS,CAAA;AAAA,yBAAA,EACV,mBAAmB,CAAA,yBAAA,EAA4B,CAAA,CAAE,cAAc,CAAA,mBAAA,EAAsB,YAAA,GAAe,qBAAqB,EAAE,CAAA;AAAA,0BAAA,EAC1H,mBAAmB,CAAA,SAAA,EAAY,CAAA,CAAE,cAAc,KAAK,SAAS,CAAA;AAAA;AAAA,gBAAA,CAAA;AAG7E,MAAA,IAAI,CAAC,YAAA,EAAc;AACf,QAAA,IAAA,IAAQ,CAAA,WAAA,EAAc,EAAE,SAAS,CAAA,EAAA,CAAA;AACjC,QAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,IAAA,KAAS;AACpB,UAAA,MAAM,GAAA,GAAO,IAAA,CAAa,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA;AACjD,UAAA,MAAM,IAAA,GAAQ,IAAA,CAAa,IAAA,CAAK,QAAA,CAAS,QAAQ,CAAA;AACjD,UAAA,IAAA,IAAQ;AAAA,uBAAA,EACH,CAAA,CAAE,QAAQ,CAAA,cAAA,EAAiB,GAAG,iBAAiB,SAAS,CAAA;AAAA,0BAAA,EACrD,EAAE,SAAS,CAAA;AAAA,2BAAA,EACV,SAAS,CAAA,CAAA,EAAI,GAAG,CAAA,yBAAA,EAA4B,EAAE,cAAc,CAAA;AAAA,4BAAA,EAC3D,SAAS,CAAA,CAAA,EAAI,GAAG,YAAY,CAAA,CAAE,cAAc,KAAK,IAAI,CAAA;AAAA;AAAA,iBAAA,CAAA;AAAA,QAGnE,CAAC,CAAA;AACD,QAAA,IAAA,IAAQ,CAAA,KAAA,CAAA;AAAA,MACZ;AACA,MAAA,IAAA,IAAQ,CAAA,MAAA,CAAA;AAAA,IACZ,CAAC,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACX;AAAA,EAEQ,oBAAoB,IAAA,EAAwB;AAChD,IAAA,MAAM,GAAA,GAAM,IAAA,KAAS,MAAA,GAAS,CAAA,GAAI,CAAA;AAClC,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,gBAAA,CAAiB,uBAAuB,CAAA;AACrE,IAAA,MAAM,OAAA,GAAU,SAAS,GAAG,CAAA;AAC5B,IAAA,MAAM,YAAY,IAAA,CAAK,MAAA,CAAO,aAAA,CAAgC,CAAA,yBAAA,EAA4B,IAAI,CAAA,CAAE,CAAA;AAChG,IAAA,MAAM,aAAa,OAAA,GAAU,OAAA,CAAQ,gBAAA,CAAiB,cAAc,EAAE,MAAA,GAAS,CAAA;AAC/E,IAAA,MAAM,gBAAgB,OAAA,GAAU,OAAA,CAAQ,gBAAA,CAAiB,sBAAsB,EAAE,MAAA,GAAS,CAAA;AAC1F,IAAA,MAAM,UAAU,IAAA,CAAK,MAAA,CAAO,aAAA,CAAc,CAAA,cAAA,EAAiB,IAAI,CAAA,SAAA,CAAW,CAAA;AAC1E,IAAA,MAAM,YAAY,IAAA,CAAK,MAAA,CAAO,aAAA,CAAc,CAAA,cAAA,EAAiB,IAAI,CAAA,MAAA,CAAQ,CAAA;AACzE,IAAA,IAAI,OAAA,EAAS,OAAA,CAAQ,WAAA,GAAc,MAAA,CAAO,aAAa,CAAA;AACvD,IAAA,IAAI,SAAA,EAAW,SAAA,CAAU,WAAA,GAAc,MAAA,CAAO,UAAU,CAAA;AACxD,IAAA,IAAI,SAAA,EAAW;AACX,MAAA,IAAI,eAAe,CAAA,EAAG;AAClB,QAAA,SAAA,CAAU,QAAA,GAAW,IAAA;AACrB,QAAA,SAAA,CAAU,OAAA,GAAU,IAAA;AAAA,MACxB,CAAA,MAAO;AACH,QAAA,SAAA,CAAU,QAAA,GAAW,KAAA;AACrB,QAAA,SAAA,CAAU,UAAU,aAAA,KAAkB,UAAA;AAAA,MAC1C;AAAA,IACJ;AAGA,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,MAAA,CAAO,aAAA,CAAiC,uBAAuB,CAAA;AACvF,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,MAAA,CAAO,aAAA,CAAiC,uBAAuB,CAAA;AACvF,IAAA,MAAM,WAAA,GAAc,SAAS,CAAC,CAAA;AAC9B,IAAA,MAAM,YAAA,GAAe,SAAS,CAAC,CAAA;AAC/B,IAAA,MAAM,cAAc,WAAA,GAAc,WAAA,CAAY,gBAAA,CAAiB,sBAAsB,EAAE,MAAA,GAAS,CAAA;AAChG,IAAA,MAAM,eAAe,YAAA,GAAe,YAAA,CAAa,gBAAA,CAAiB,sBAAsB,EAAE,MAAA,GAAS,CAAA;AACnG,IAAA,IAAI,UAAA,EAAY,UAAA,CAAW,QAAA,GAAW,WAAA,KAAgB,CAAA;AACtD,IAAA,IAAI,UAAA,EAAY,UAAA,CAAW,QAAA,GAAW,YAAA,KAAiB,CAAA;AAAA,EAC3D;AAAA,EAEQ,UAAA,GAAa;AACjB,IAAA,IAAA,CAAK,MAAA,CAAO,gBAAA,CAAiB,OAAA,EAAS,CAAC,CAAA,KAAM;AACzC,MAAA,MAAM,SAAS,CAAA,CAAE,MAAA;AACjB,MAAA,IAAI,MAAA,CAAO,OAAA,CAAQ,uBAAuB,CAAA,EAAG;AACzC,QAAA,IAAA,CAAK,SAAA,CAAU,QAAQ,OAAO,CAAA;AAAA,MAClC,CAAA,MAAA,IAAW,MAAA,CAAO,OAAA,CAAQ,uBAAuB,CAAA,EAAG;AAChD,QAAA,IAAA,CAAK,SAAA,CAAU,SAAS,MAAM,CAAA;AAAA,MAClC;AAAA,IACJ,CAAC,CAAA;AACD,IAAA,IAAA,CAAK,MAAA,CAAO,gBAAA,CAAiB,QAAA,EAAU,CAAC,CAAA,KAAM;AAC1C,MAAA,MAAM,SAAS,CAAA,CAAE,MAAA;AACjB,MAAA,IAAI,MAAA,CAAO,OAAA,CAAQ,+BAA+B,CAAA,EAAG;AACjD,QAAA,IAAA,CAAK,eAAA,CAAgB,MAAA,EAAQ,MAAA,CAAO,OAAO,CAAA;AAAA,MAC/C,CAAA,MAAA,IAAW,MAAA,CAAO,OAAA,CAAQ,gCAAgC,CAAA,EAAG;AACzD,QAAA,IAAA,CAAK,eAAA,CAAgB,OAAA,EAAS,MAAA,CAAO,OAAO,CAAA;AAAA,MAChD,CAAA,MAAA,IAAW,MAAA,CAAO,OAAA,CAAQ,mBAAmB,CAAA,EAAG;AAC5C,QAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,CAAQ,qBAAqB,CAAA;AACpD,QAAA,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAS,iBAAmC,cAAA,CAAA,CAAgB,OAAA,CAAQ,CAAC,GAAA,KAAS,GAAA,CAAI,UAAU,MAAA,CAAO,OAAA,CAAA;AACnG,QAAA,IAAA,CAAK,oBAAoB,MAAM,CAAA;AAC/B,QAAA,IAAA,CAAK,oBAAoB,OAAO,CAAA;AAAA,MACpC,CAAA,MAAA,IAAW,MAAA,CAAO,OAAA,CAAQ,cAAc,CAAA,EAAG;AACvC,QAAA,IAAA,CAAK,oBAAoB,MAAM,CAAA;AAC/B,QAAA,IAAA,CAAK,oBAAoB,OAAO,CAAA;AAAA,MACpC;AAAA,IACJ,CAAC,CAAA;AACD,IAAA,IAAA,CAAK,MAAA,CAAO,gBAAA,CAAiB,OAAA,EAAS,CAAC,CAAA,KAAM;AACzC,MAAA,MAAM,SAAS,CAAA,CAAE,MAAA;AACjB,MAAA,IAAI,MAAA,CAAO,OAAA,CAAQ,sBAAsB,CAAA,EAAG;AACxC,QAAA,MAAM,IAAA,GAAQ,MAAA,CAAO,YAAA,CAAa,WAAW,CAAA,IAA0B,MAAA;AACvE,QAAA,MAAM,UAAA,GAAa,OAAO,KAAA,IAAS,EAAA;AACnC,QAAA,IAAA,CAAK,WAAA,CAAY,MAAM,UAAU,CAAA;AAAA,MACrC;AAAA,IACJ,CAAC,CAAA;AAAA,EACL;AAAA,EAEQ,SAAA,CAAU,UAA4B,MAAA,EAA0B;AACpE,IAAA,MAAM,UAAA,GAAa,QAAA,KAAa,MAAA,GAAS,IAAA,CAAK,SAAS,IAAA,CAAK,cAAA;AAC5D,IAAA,MAAM,QAAA,GAAW,MAAA,KAAW,MAAA,GAAS,IAAA,CAAK,SAAS,IAAA,CAAK,cAAA;AACxD,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,gBAAA,CAAiB,uBAAuB,CAAA;AACrE,IAAA,MAAM,aAAA,GAAgB,QAAA,CAAS,QAAA,KAAa,MAAA,GAAS,IAAI,CAAC,CAAA;AAC1D,IAAA,MAAM,WAAA,GAAc,KAAA,CAAM,IAAA,CAAK,aAAA,CAAc,iBAAmC,sBAAsB,CAAC,CAAA,CAAE,GAAA,CAAI,CAAC,GAAA,KAAQ,GAAA,CAAI,OAAA,CAAQ,IAAI,CAAkB,CAAA;AAExJ,IAAA,WAAA,CAAY,OAAA,CAAQ,CAAC,EAAA,KAAO;AACxB,MAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,EAAA,CAAG,YAAA,CAAa,YAAY,CAAC,CAAA;AAClD,MAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,EAAA,CAAG,YAAA,CAAa,YAAY,CAAC,CAAA;AAGlD,MAAA,MAAM,YAAA,GAAe,IAAA,CAAK,YAAA,CAAa,IAAA,CAAK,CAAA,IAAA,KAAQ,MAAA,CAAQ,IAAA,CAAa,IAAA,CAAK,QAAA,CAAS,SAAS,CAAC,CAAA,KAAM,KAAK,CAAA;AAC5G,MAAA,IAAI,CAAC,YAAA,EAAc;AAEnB,MAAA,IAAI,UAAA,CAAW,KAAK,CAAA,EAAG;AACnB,QAAA,UAAA,CAAW,KAAK,CAAA,GAAI,UAAA,CAAW,KAAK,EAAE,MAAA,CAAO,CAAC,CAAA,KAAM,MAAA,CAAQ,EAAU,IAAA,CAAK,QAAA,CAAS,SAAS,CAAC,MAAM,KAAK,CAAA;AACzG,QAAA,IAAI,UAAA,CAAW,KAAK,CAAA,CAAE,MAAA,KAAW,MAAM,IAAA,CAAK,QAAA,CAAS,eAAA,IAAmB,QAAA,KAAa,MAAA,CAAA,EAAS;AAC1F,UAAA,OAAQ,WAAmB,KAAK,CAAA;AAAA,QACpC;AAAA,MACJ;AACA,MAAA,IAAI,CAAC,QAAA,CAAS,KAAK,GAAG,QAAA,CAAS,KAAK,IAAI,EAAC;AAGzC,MAAA,IAAI,CAAC,QAAA,CAAS,KAAK,CAAA,CAAE,KAAK,CAAA,CAAA,KAAK,MAAA,CAAQ,CAAA,CAAU,IAAA,CAAK,QAAA,CAAS,SAAS,CAAC,CAAA,KAAM,KAAK,CAAA,EAAG;AACnF,QAAA,QAAA,CAAS,KAAK,CAAA,CAAE,IAAA,CAAK,YAAY,CAAA;AAAA,MACrC;AAGA,MAAA,IAAA,CAAK,SAAA,CAAU,QAAA,CAAS,KAAK,CAAC,CAAA;AAAA,IAClC,CAAC,CAAA;AACD,IAAA,IAAA,CAAK,MAAA,EAAO;AAAA,EAChB;AAAA,EAEQ,eAAA,CAAgB,MAAwB,SAAA,EAAoB;AAChE,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,gBAAA,CAAiB,uBAAuB,CAAA;AACrE,IAAA,MAAM,OAAA,GAAU,QAAA,CAAS,IAAA,KAAS,MAAA,GAAS,IAAI,CAAC,CAAA;AAChD,IAAA,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAS,iBAAmC,mBAAA,CAAA,CAAqB,OAAA,CAAQ,CAAC,GAAA,KAAS,IAAI,OAAA,GAAU,SAAA,CAAA;AACjG,IAAA,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAS,iBAAmC,cAAA,CAAA,CAAgB,OAAA,CAAQ,CAAC,GAAA,KAAS,IAAI,OAAA,GAAU,SAAA,CAAA;AAC5F,IAAA,IAAA,CAAK,oBAAoB,IAAI,CAAA;AAAA,EACjC;AAAA,EAEQ,WAAA,CAAY,MAAwB,UAAA,EAAoB;AAC5D,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,gBAAA,CAAiB,uBAAuB,CAAA;AACrE,IAAA,MAAM,SAAA,GAAY,QAAA,CAAS,IAAA,KAAS,MAAA,GAAS,IAAI,CAAC,CAAA;AAClD,IAAA,MAAM,UAAA,GAAA,CAAc,UAAA,IAAc,EAAA,EAAI,WAAA,EAAY;AAClD,IAAA,SAAA,IAAA,IAAA,GAAA,MAAA,GAAA,SAAA,CAAW,gBAAA,CAA8B,qBAAA,CAAA,CAAuB,OAAA,CAAQ,CAAC,OAAA,KAAY;AAtV7F,MAAA,IAAA,EAAA;AAuVY,MAAA,MAAM,SAAA,GAAA,CAAA,CAAA,CAAa,aAAQ,aAAA,CAAc,eAAe,MAArC,IAAA,GAAA,MAAA,GAAA,EAAA,CAAwC,WAAA,KAAe,IAAI,WAAA,EAAY;AAC1F,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,gBAAA,CAA8B,IAAI,CAAA;AACxD,MAAA,IAAI,SAAA,GAAY,KAAA;AAChB,MAAA,IAAI,SAAA,CAAU,QAAA,CAAS,UAAU,CAAA,EAAG;AAChC,QAAA,OAAA,CAAQ,MAAM,OAAA,GAAU,EAAA;AACxB,QAAA,KAAA,CAAM,QAAQ,CAAC,EAAA,KAAQ,EAAA,CAAG,KAAA,CAAM,UAAU,EAAG,CAAA;AAC7C,QAAA,SAAA,GAAY,IAAA;AAAA,MAChB,CAAA,MAAO;AACH,QAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,EAAA,KAAO;AA/VtC,UAAA,IAAAA,GAAAA;AAgWoB,UAAA,MAAM,QAAA,GAAA,CAAA,CAAA,CAAYA,GAAAA,GAAA,EAAA,CAAG,aAAA,CAAc,OAAO,MAAxB,IAAA,GAAA,MAAA,GAAAA,GAAAA,CAA2B,WAAA,KAAe,EAAA,EAAI,WAAA,EAAY;AAC5E,UAAA,IAAI,QAAA,CAAS,QAAA,CAAS,UAAU,CAAA,EAAG;AAC/B,YAAA,EAAA,CAAG,MAAM,OAAA,GAAU,EAAA;AACnB,YAAA,SAAA,GAAY,IAAA;AAAA,UAChB,CAAA,MAAO;AACH,YAAA,EAAA,CAAG,MAAM,OAAA,GAAU,MAAA;AAAA,UACvB;AAAA,QACJ,CAAC,CAAA;AACD,QAAA,OAAA,CAAQ,KAAA,CAAM,OAAA,GAAU,SAAA,GAAY,EAAA,GAAK,MAAA;AAAA,MAC7C;AAAA,IACJ,CAAA,CAAA;AACA,IAAA,IAAI,CAAC,UAAA,EAAY;AACb,MAAA,SAAA,IAAA,IAAA,GAAA,MAAA,GAAA,SAAA,CAAW,iBAA8B,qBAAA,CAAA,CAAuB,OAAA,CAAQ,CAAC,CAAA,KAAO,CAAA,CAAE,MAAM,OAAA,GAAU,EAAA,CAAA;AAClG,MAAA,SAAA,IAAA,IAAA,GAAA,MAAA,GAAA,SAAA,CAAW,iBAA8B,IAAA,CAAA,CAAM,OAAA,CAAQ,CAAC,EAAA,KAAQ,EAAA,CAAG,MAAM,OAAA,GAAU,EAAA,CAAA;AAAA,IACvF;AAAA,EACJ;AAAA,EAEQ,4BAAA,GAA+B;AACnC,IAAA,IAAI,CAAC,KAAK,MAAA,EAAQ;AACd,MAAA,OAAA,CAAQ,MAAM,wBAAwB,CAAA;AACtC,MAAA;AAAA,IACJ;AACA,IAAA,MAAM,iBAAsC,IAAA,CAAK,aAAA;AAEjD,IAAA,KAAA,CAAM,KAAK,IAAA,CAAK,MAAA,CAAO,gBAAA,CAAiB,CAAA,YAAA,EAAe,KAAK,QAAA,CAAS,SAAS,CAAA,IAAA,CAAM,CAAC,EAAE,OAAA,CAAQ,CAAC,EAAA,KAAO,EAAA,CAAG,QAAQ,CAAA;AAElH,IAAA,cAAA,CAAe,OAAA,CAAQ,CAAC,KAAA,KAAU;AAC9B,MAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,aAAA,CAAc,OAAO,CAAA;AAC5C,MAAA,KAAA,CAAM,IAAA,GAAO,QAAA;AACb,MAAA,KAAA,CAAM,IAAA,GAAO,CAAA,EAAG,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA,EAAA,CAAA;AACvC,MAAA,KAAA,CAAM,KAAA,GAAQ,OAAO,KAAK,CAAA;AAC1B,MAAA,IAAA,CAAK,MAAA,CAAQ,YAAY,KAAK,CAAA;AAAA,IAClC,CAAC,CAAA;AAAA,EACL;AAAA,EAEA,iBAAA,GAAkD;AAC9C,IAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY;AAC5B,MAAA,OAAA,CAAQ,KAAK,aAAa,CAAA;AAAA,IAC9B,CAAC,CAAA;AAAA,EACL;AAAA,EAEA,IAAI,QAAA,GAAW;AACX,IAAA,OAAO,IAAA,CAAK,cAAA;AAAA,EAChB;AAAA,EAEA,IAAI,aAAA,GAAgB;AAChB,IAAA,MAAM,iBAAsC,EAAC;AAC7C,IAAA,IAAA,CAAK,YAAA,CAAa,OAAA,CAAQ,CAAC,IAAA,KAAS;AAChC,MAAA,MAAM,GAAA,GAAO,IAAA,CAAa,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA;AACjD,MAAA,MAAM,KAAA,GAAS,IAAA,CAAa,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA,IAAK,WAAA;AACxD,MAAA,IAAI,IAAA,CAAK,cAAA,CAAe,KAAK,CAAA,EAAG;AAC5B,QAAA,MAAM,UAAA,GAAa,IAAA,CAAK,cAAA,CAAe,KAAK,CAAA,CAAE,IAAA;AAAA,UAC1C,CAAC,CAAA,KAAM,MAAA,CAAQ,CAAA,CAAU,IAAA,CAAK,SAAS,SAAS,CAAC,CAAA,KAAM,MAAA,CAAO,GAAG;AAAA,SACrE;AACA,QAAA,IAAI,UAAA,EAAY;AACZ,UAAA,cAAA,CAAe,KAAK,GAAG,CAAA;AAAA,QAC3B;AAAA,MACJ;AAAA,IACJ,CAAC,CAAA;AACD,IAAA,OAAO,cAAA;AAAA,EACX;AAAA,EAEA,IAAI,UAAA,GAAa;AACb,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EAChB;AAAA,EAEA,IAAI,QAAA,GAAW;AACX,IAAA,OAAO,KAAK,QAAA,CAAS,SAAA;AAAA,EACzB;AAAA;AAAA,EAGA,gBAAA,GAAsC;AAClC,IAAA,MAAM,WAA8B,EAAC;AACrC,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,MAAM,CAAA;AAC5C,IAAA,IAAA,CAAK,YAAA,CAAa,OAAA,CAAQ,CAAC,IAAA,KAAS;AAChC,MAAA,IAAI,MAAA,CAAO,SAAS,MAAA,CAAQ,IAAA,CAAa,KAAK,QAAA,CAAS,SAAS,CAAC,CAAC,CAAA,EAAG;AACjE,QAAA,QAAA,CAAS,KAAK,IAAI,CAAA;AAAA,MACtB;AAAA,IACJ,CAAC,CAAA;AACD,IAAA,OAAO,QAAA;AAAA,EACX;AAAA,EAEA,kBAAA,GAAwC;AACpC,IAAA,MAAM,aAAgC,EAAC;AACvC,IAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,aAAA,CAAc,GAAA,CAAI,MAAM,CAAA;AACpD,IAAA,IAAA,CAAK,YAAA,CAAa,OAAA,CAAQ,CAAC,IAAA,KAAS;AAChC,MAAA,IAAI,CAAC,cAAA,CAAe,QAAA,CAAS,MAAA,CAAQ,IAAA,CAAa,KAAK,QAAA,CAAS,SAAS,CAAC,CAAC,CAAA,EAAG;AAC1E,QAAA,UAAA,CAAW,KAAK,IAAI,CAAA;AAAA,MACxB;AAAA,IACJ,CAAC,CAAA;AACD,IAAA,OAAO,UAAA;AAAA,EACX;AAAA,EAEA,WAAA,GAAiC;AAC7B,IAAA,OAAO,CAAC,GAAG,IAAA,CAAK,YAAY,CAAA;AAAA,EAChC;AAAA,EAEA,WAAA,GAA0E;AACtE,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EAChB;AACJ;AAEO,SAAS,eAAA,CAAgB,QAAA,EAA4B,OAAA,GAA8B,EAAC,EAAG;AAC1F,EAAA,OAAO,IAAI,WAAA,CAAY,QAAA,EAAU,OAAO,CAAA;AAC5C;AAIC,WAAA,CAAoB,QAAA,GAAW,CAAC,KAAA,KAAwD,QAAA,CAAS,KAAK,CAAA","file":"index.mjs","sourcesContent":["import { DualListBoxTheme } from './types';\n\nexport const defaultTheme: DualListBoxTheme = {\n container: 'dual-listbox',\n row: 'row mb-3',\n colLeft: 'col-md-5',\n colCenter: 'col-md-2 d-flex justify-content-center flex-column gap-3',\n colRight: 'col-md-5',\n card: 'card h-100',\n cardHeader: 'card-header',\n cardBody: 'card-body',\n cardFooter: 'card-footer text-center',\n searchInput: 'form-control mb-3 dual-listbox-search',\n listGroup: 'list-group',\n listItem: 'list-group-item py-1 border-0',\n formCheck: 'form-check',\n formCheckInput: 'form-check-input',\n formCheckLabel: 'form-check-label',\n btn: 'btn btn-light w-100',\n btnInclude: '',\n btnExclude: '',\n};\n\nexport const bootstrapTheme: DualListBoxTheme = { ...defaultTheme };\n\nexport const tailwindTheme: DualListBoxTheme = {\n container: 'dual-listbox tw',\n row: 'grid grid-cols-1 md:grid-cols-5 gap-3',\n colLeft: 'md:col-span-2',\n colCenter: 'md:col-span-1 flex flex-col justify-center gap-3',\n colRight: 'md:col-span-2',\n card: 'h-full border rounded shadow-sm bg-white',\n cardHeader: 'px-4 py-2 border-b font-medium',\n cardBody: 'p-4',\n cardFooter: 'px-4 py-2 border-t text-center',\n searchInput: 'w-full mb-3 border rounded px-3 py-2 dual-listbox-search',\n listGroup: 'space-y-1',\n listItem: 'py-1',\n formCheck: 'flex items-center gap-2',\n formCheckInput: 'h-4 w-4',\n formCheckLabel: '',\n btn: 'w-full border rounded px-3 py-2 bg-gray-100 hover:bg-gray-200',\n btnInclude: 'mb-2',\n btnExclude: '',\n};\n","import type {DualListBoxItem, DualListBoxOptions, DualListBoxTheme} from './types';\nimport {defaultTheme} from './themePresets';\n\nfunction mergeTheme(base: DualListBoxTheme, override?: Partial<DualListBoxTheme>): DualListBoxTheme {\n return {...base, ...(override || {})} as DualListBoxTheme;\n}\n\n// Global theme state (module-level)\nlet GLOBAL_THEME: DualListBoxTheme = {...defaultTheme};\n\n/**\n * Set the global default theme for all new DualListBox instances.\n * Instance option `theme` still has highest priority.\n */\nexport function useTheme(theme: Partial<DualListBoxTheme> | DualListBoxTheme) {\n GLOBAL_THEME = mergeTheme(defaultTheme, theme as Partial<DualListBoxTheme>);\n}\n\n// Back-compat alias for older code that might call DualListBox.setTheme(...)\n// We will attach a static setTheme on the class after its definition.\n\nexport class DualListBox {\n private rootEl: Element;\n private formEl: HTMLFormElement | null;\n\n private instanceId: string;\n private originalData: DualListBoxItem[];\n\n private defaults: Required<Omit<DualListBoxOptions, 'theme'>> & { theme: DualListBoxTheme };\n private settings: Required<DualListBoxOptions> & { theme: DualListBoxTheme };\n\n private groups: Record<string, DualListBoxItem[]> = {};\n private selectedGroups: Record<string, DualListBoxItem[]> = {};\n\n constructor(element: Element | string, options: DualListBoxOptions = {}) {\n this.rootEl = typeof element === 'string' ? (document.querySelector(element) as Element) : (element as Element);\n if (!this.rootEl) throw new Error('DualListBox root element not found');\n this.formEl = (this.rootEl.closest('form') as HTMLFormElement) || null;\n this.instanceId = this.generateInstanceId();\n this.defaults = {\n itemName: 'item',\n groupName: 'group',\n valueName: 'value',\n inputName: 'selectedItems',\n tabNameText: 'Available Items',\n rightTabNameText: 'Selected Items',\n searchPlaceholderText: 'Search...',\n includeButtonText: 'Include >>',\n excludeButtonText: '<< Exclude',\n dataArray: [],\n selectedItems: [],\n hideEmptyGroups: false,\n submitForm: true,\n onSubmit: null,\n theme: defaultTheme,\n } as any;\n\n // Effective theme precedence: options.theme > GLOBAL_THEME > defaultTheme\n const themeBase = mergeTheme(defaultTheme, GLOBAL_THEME);\n const theme = mergeTheme(themeBase, options.theme);\n this.settings = {...(this.defaults as any), ...(options as any), theme};\n\n this.originalData = [...this.settings.dataArray];\n this.groups = this.buildGroups(this.settings.dataArray);\n this.selectedGroups = this.buildGroups(this.settings.selectedItems);\n\n // Sort initial groups based on originalData order\n this.sortAllGroups();\n\n this.removeDuplicatesFromLeft();\n this.render();\n this.bindEvents();\n\n if (this.formEl) {\n this.formEl.addEventListener('submit', (event) => {\n if (typeof this.settings.onSubmit === 'function') {\n event.preventDefault();\n this.settings.onSubmit(this.selected, this.unselected, this.allItems, this.selectedArray);\n } else if (this.settings.submitForm) {\n this.appendSelectedGroupsOnSubmit();\n }\n });\n }\n }\n\n private generateInstanceId() {\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let id = '';\n for (let i = 0; i < 36; i++) {\n id += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return id;\n }\n\n private sortAllGroups() {\n [this.groups, this.selectedGroups].forEach((groupSet) => {\n Object.keys(groupSet).forEach((groupName) => {\n this.sortGroup(groupSet[groupName]);\n });\n });\n }\n\n private sortGroup(group: DualListBoxItem[]) {\n group.sort((a, b) => {\n const valA = String((a as any)[this.settings.valueName]);\n const valB = String((b as any)[this.settings.valueName]);\n const indexA = this.originalData.findIndex(\n (item) => String((item as any)[this.settings.valueName]) === valA\n );\n const indexB = this.originalData.findIndex(\n (item) => String((item as any)[this.settings.valueName]) === valB\n );\n return indexA - indexB;\n });\n }\n\n private buildGroups(dataArray: DualListBoxItem[]) {\n const groups: Record<string, DualListBoxItem[]> = {};\n dataArray.forEach((item) => {\n const group = (item as any)[this.settings.groupName] || 'Ungrouped';\n if (!groups[group]) groups[group] = [];\n groups[group].push(item);\n });\n return groups;\n }\n\n private removeDuplicatesFromLeft() {\n Object.keys(this.selectedGroups).forEach((group) => {\n if (this.groups[group]) {\n this.selectedGroups[group].forEach((selectedItem) => {\n this.groups[group] = this.groups[group].filter(\n (item) => String((item as any)[this.settings.valueName]) !== String((selectedItem as any)[this.settings.valueName])\n );\n });\n if (this.settings.hideEmptyGroups) {\n if (!this.groups[group].length) {\n delete this.groups[group];\n }\n }\n }\n });\n this.render();\n }\n\n private render() {\n const t = this.settings.theme;\n const template = `\n <div class=\"${t.container}\" id=\"dual_listbox_${this.instanceId}\">\n <div class=\"${t.row}\">\n <div class=\"${t.colLeft}\" id=\"dual_listbox_${this.instanceId}_left_side\">\n <div class=\"${t.card}\">\n <div class=\"${t.cardHeader}\">${this.settings.tabNameText}</div>\n <div class=\"${t.cardBody}\">\n <input id=\"dual_listbox_${this.instanceId}_left_search\" type=\"text\" class=\"${t.searchInput} dual-listbox-search\" data-side=\"left\" placeholder=\"${this.settings.searchPlaceholderText}\">\n <div class=\"dual-listbox-content\">\n ${this.generateGroupedListHTML('left')}\n </div>\n </div>\n <div class=\"${t.cardFooter}\">\n <input type=\"checkbox\" class=\"${t.formCheckInput} dual-listbox-select-all-left\" disabled>\n <label class=\"${t.formCheckLabel}\">Select All (<span class=\"dual-listbox-left-selected\">0</span>/<span class=\"dual-listbox-left-total\">0</span>)</label>\n </div>\n </div>\n </div>\n <div class=\"${t.colCenter}\">\n <button type=\"button\" class=\"${t.btn} dual-listbox-include ${t.btnInclude}\" disabled>${this.settings.includeButtonText}</button>\n <button type=\"button\" class=\"${t.btn} dual-listbox-exclude ${t.btnExclude}\" disabled>${this.settings.excludeButtonText}</button>\n </div>\n <div class=\"${t.colRight}\" id=\"dual_listbox_${this.instanceId}_right_side\">\n <div class=\"${t.card}\">\n <div class=\"${t.cardHeader}\">${this.settings.rightTabNameText}</div>\n <div class=\"${t.cardBody}\">\n <input id=\"dual_listbox_${this.instanceId}_right_search\" type=\"text\" class=\"${t.searchInput} dual-listbox-search\" data-side=\"right\" placeholder=\"${this.settings.searchPlaceholderText}\">\n <div class=\"dual-listbox-content\">\n ${this.generateGroupedListHTML('right')}\n </div>\n </div>\n <div class=\"${t.cardFooter}\">\n <input type=\"checkbox\" class=\"${t.formCheckInput} dual-listbox-select-all-right\" disabled>\n <label class=\"${t.formCheckLabel}\">Select All (<span class=\"dual-listbox-right-selected\">0</span>/<span class=\"dual-listbox-right-total\">0</span>)</label>\n </div>\n </div>\n </div>\n </div>\n </div>`;\n this.rootEl.innerHTML = template;\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n }\n\n private generateGroupedListHTML(side: 'left' | 'right') {\n const t = this.settings.theme;\n const groups = side === 'left' ? this.groups : this.selectedGroups;\n let html = '';\n const keys = Object.keys(groups);\n keys.forEach((groupName, index) => {\n const items = groups[groupName];\n const totalItems = items.length;\n const isGroupEmpty = totalItems === 0;\n const groupSelectAllInput = `group_${groupName}_${side}`;\n const isLast = index === keys.length - 1;\n html += `\n <div class=\"dual-listbox-group${!isLast ? ' mb-3' : ''}\">\n <div class=\"group-header mb-2\">\n <div class=\"${t.formCheck}\">\n <input id=\"${groupSelectAllInput}\" type=\"checkbox\" class=\"${t.formCheckInput} group-select-all\" ${isGroupEmpty ? 'checked disabled' : ''}>\n <label for=\"${groupSelectAllInput}\" class=\"${t.formCheckLabel}\">${groupName}</label>\n </div>\n </div>`;\n if (!isGroupEmpty) {\n html += `<ul class=\"${t.listGroup}\">`;\n items.forEach((item) => {\n const val = (item as any)[this.settings.valueName];\n const name = (item as any)[this.settings.itemName];\n html += `\n <li class=\"${t.listItem}\" data-value=\"${val}\" data-group=\"${groupName}\">\n <div class=\"${t.formCheck}\">\n <input id=\"${groupName}_${val}\" type=\"checkbox\" class=\"${t.formCheckInput} item-select\" />\n <label for=\"${groupName}_${val}\" class=\"${t.formCheckLabel}\">${name}</label>\n </div>\n </li>`;\n });\n html += `</ul>`;\n }\n html += `</div>`;\n });\n return html;\n }\n\n private updateSelectAllInfo(side: 'left' | 'right') {\n const idx = side === 'left' ? 0 : 1;\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const content = contents[idx] as Element;\n const selectAll = this.rootEl.querySelector<HTMLInputElement>(`.dual-listbox-select-all-${side}`);\n const totalItems = content ? content.querySelectorAll('.item-select').length : 0;\n const selectedItems = content ? content.querySelectorAll('.item-select:checked').length : 0;\n const selSpan = this.rootEl.querySelector(`.dual-listbox-${side}-selected`);\n const totalSpan = this.rootEl.querySelector(`.dual-listbox-${side}-total`);\n if (selSpan) selSpan.textContent = String(selectedItems);\n if (totalSpan) totalSpan.textContent = String(totalItems);\n if (selectAll) {\n if (totalItems === 0) {\n selectAll.disabled = true;\n selectAll.checked = true;\n } else {\n selectAll.disabled = false;\n selectAll.checked = selectedItems === totalItems;\n }\n }\n\n // Enable/disable include/exclude buttons based on selections\n const includeBtn = this.rootEl.querySelector<HTMLButtonElement>('.dual-listbox-include');\n const excludeBtn = this.rootEl.querySelector<HTMLButtonElement>('.dual-listbox-exclude');\n const leftContent = contents[0] as Element | undefined;\n const rightContent = contents[1] as Element | undefined;\n const leftChecked = leftContent ? leftContent.querySelectorAll('.item-select:checked').length : 0;\n const rightChecked = rightContent ? rightContent.querySelectorAll('.item-select:checked').length : 0;\n if (includeBtn) includeBtn.disabled = leftChecked === 0;\n if (excludeBtn) excludeBtn.disabled = rightChecked === 0;\n }\n\n private bindEvents() {\n this.rootEl.addEventListener('click', (e) => {\n const target = e.target as HTMLElement;\n if (target.closest('.dual-listbox-include')) {\n this.moveItems('left', 'right');\n } else if (target.closest('.dual-listbox-exclude')) {\n this.moveItems('right', 'left');\n }\n });\n this.rootEl.addEventListener('change', (e) => {\n const target = e.target as HTMLInputElement;\n if (target.matches('.dual-listbox-select-all-left')) {\n this.toggleSelectAll('left', target.checked);\n } else if (target.matches('.dual-listbox-select-all-right')) {\n this.toggleSelectAll('right', target.checked);\n } else if (target.matches('.group-select-all')) {\n const groupEl = target.closest('.dual-listbox-group') as Element;\n groupEl?.querySelectorAll<HTMLInputElement>('.item-select').forEach((inp) => (inp.checked = target.checked));\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n } else if (target.matches('.item-select')) {\n this.updateSelectAllInfo('left');\n this.updateSelectAllInfo('right');\n }\n });\n this.rootEl.addEventListener('input', (e) => {\n const target = e.target as HTMLInputElement;\n if (target.matches('.dual-listbox-search')) {\n const side = (target.getAttribute('data-side') as 'left' | 'right') || 'left';\n const searchTerm = target.value || '';\n this.searchItems(side, searchTerm);\n }\n });\n }\n\n private moveItems(fromSide: 'left' | 'right', toSide: 'left' | 'right') {\n const fromGroups = fromSide === 'left' ? this.groups : this.selectedGroups;\n const toGroups = toSide === 'left' ? this.groups : this.selectedGroups;\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const fromContainer = contents[fromSide === 'left' ? 0 : 1] as Element;\n const selectedLis = Array.from(fromContainer.querySelectorAll<HTMLInputElement>('.item-select:checked')).map((inp) => inp.closest('li') as HTMLLIElement);\n \n selectedLis.forEach((li) => {\n const value = String(li.getAttribute('data-value'));\n const group = String(li.getAttribute('data-group'));\n \n // Find original item to preserve all properties\n const originalItem = this.originalData.find(item => String((item as any)[this.settings.valueName]) === value);\n if (!originalItem) return;\n\n if (fromGroups[group]) {\n fromGroups[group] = fromGroups[group].filter((i) => String((i as any)[this.settings.valueName]) !== value);\n if (fromGroups[group].length === 0 && (this.settings.hideEmptyGroups || fromSide !== 'left')) {\n delete (fromGroups as any)[group];\n }\n }\n if (!toGroups[group]) toGroups[group] = [];\n \n // Avoid duplicates\n if (!toGroups[group].some(i => String((i as any)[this.settings.valueName]) === value)) {\n toGroups[group].push(originalItem);\n }\n\n // Sort toGroups[group] based on originalData order\n this.sortGroup(toGroups[group]);\n });\n this.render();\n }\n\n private toggleSelectAll(side: 'left' | 'right', isChecked: boolean) {\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const content = contents[side === 'left' ? 0 : 1] as Element;\n content?.querySelectorAll<HTMLInputElement>('.group-select-all').forEach((inp) => (inp.checked = isChecked));\n content?.querySelectorAll<HTMLInputElement>('.item-select').forEach((inp) => (inp.checked = isChecked));\n this.updateSelectAllInfo(side);\n }\n\n private searchItems(side: 'left' | 'right', searchTerm: string) {\n const contents = this.rootEl.querySelectorAll('.dual-listbox-content');\n const container = contents[side === 'left' ? 0 : 1] as HTMLElement;\n const searchText = (searchTerm || '').toLowerCase();\n container?.querySelectorAll<HTMLElement>('.dual-listbox-group').forEach((groupEl) => {\n const groupName = (groupEl.querySelector('.group-header')?.textContent || '').toLowerCase();\n const items = groupEl.querySelectorAll<HTMLElement>('li');\n let showGroup = false;\n if (groupName.includes(searchText)) {\n groupEl.style.display = '';\n items.forEach((li) => (li.style.display = ''));\n showGroup = true;\n } else {\n items.forEach((li) => {\n const itemText = (li.querySelector('label')?.textContent || '').toLowerCase();\n if (itemText.includes(searchText)) {\n li.style.display = '';\n showGroup = true;\n } else {\n li.style.display = 'none';\n }\n });\n groupEl.style.display = showGroup ? '' : 'none';\n }\n });\n if (!searchText) {\n container?.querySelectorAll<HTMLElement>('.dual-listbox-group').forEach((g) => (g.style.display = ''));\n container?.querySelectorAll<HTMLElement>('li').forEach((li) => (li.style.display = ''));\n }\n }\n\n private appendSelectedGroupsOnSubmit() {\n if (!this.formEl) {\n console.error('Parent form not found!');\n return;\n }\n const selectedValues: (string | number)[] = this.selectedArray;\n // remove existing\n Array.from(this.formEl.querySelectorAll(`input[name=\"${this.settings.inputName}[]\"]`)).forEach((el) => el.remove());\n // append new\n selectedValues.forEach((value) => {\n const input = document.createElement('input');\n input.type = 'hidden';\n input.name = `${this.settings.inputName}[]`;\n input.value = String(value);\n this.formEl!.appendChild(input);\n });\n }\n\n getSelectedValues(): Promise<(string | number)[]> {\n return new Promise((resolve) => {\n resolve(this.selectedArray);\n });\n }\n\n get selected() {\n return this.selectedGroups;\n }\n\n get selectedArray() {\n const selectedValues: (string | number)[] = [];\n this.originalData.forEach((item) => {\n const val = (item as any)[this.settings.valueName];\n const group = (item as any)[this.settings.groupName] || 'Ungrouped';\n if (this.selectedGroups[group]) {\n const isSelected = this.selectedGroups[group].some(\n (i) => String((i as any)[this.settings.valueName]) === String(val)\n );\n if (isSelected) {\n selectedValues.push(val);\n }\n }\n });\n return selectedValues;\n }\n\n get unselected() {\n return this.groups;\n }\n\n get allItems() {\n return this.settings.dataArray;\n }\n\n // New API methods: return arrays without duplicates\n getSelectedItems(): DualListBoxItem[] {\n const selected: DualListBoxItem[] = [];\n const values = this.selectedArray.map(String);\n this.originalData.forEach((item) => {\n if (values.includes(String((item as any)[this.settings.valueName]))) {\n selected.push(item);\n }\n });\n return selected;\n }\n\n getUnselectedItems(): DualListBoxItem[] {\n const unselected: DualListBoxItem[] = [];\n const selectedValues = this.selectedArray.map(String);\n this.originalData.forEach((item) => {\n if (!selectedValues.includes(String((item as any)[this.settings.valueName]))) {\n unselected.push(item);\n }\n });\n return unselected;\n }\n\n getAllItems(): DualListBoxItem[] {\n return [...this.originalData];\n }\n\n getSettings(): Required<DualListBoxOptions> & { theme: DualListBoxTheme } {\n return this.settings;\n }\n}\n\nexport function initDualListBox(selector: string | Element, options: DualListBoxOptions = {}) {\n return new DualListBox(selector, options);\n}\n\n// Attach back-compat static setTheme to the class\n// so existing code using DualListBox.setTheme(...) keeps working.\n(DualListBox as any).setTheme = (theme: Partial<DualListBoxTheme> | DualListBoxTheme) => useTheme(theme);\n"]}
package/package.json CHANGED
@@ -1,6 +1,9 @@
1
1
  {
2
2
  "name": "@elrayes/dual-listbox",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
4
7
  "type": "module",
5
8
  "description": "A zero-dependency (vanilla JS) dual list box with grouping, search, select-all, theming (Bootstrap/Tailwind), and TypeScript types.",
6
9
  "main": "./dist/index.cjs",