selective-ui 1.4.0 → 1.4.2

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.
Files changed (71) hide show
  1. package/dist/selective-ui.css +2 -2
  2. package/dist/selective-ui.css.map +1 -1
  3. package/dist/selective-ui.esm.js +407 -573
  4. package/dist/selective-ui.esm.js.map +1 -1
  5. package/dist/selective-ui.esm.min.js +2 -2
  6. package/dist/selective-ui.esm.min.js.br +0 -0
  7. package/dist/selective-ui.min.css +1 -1
  8. package/dist/selective-ui.min.css.br +0 -0
  9. package/dist/selective-ui.min.js +2 -2
  10. package/dist/selective-ui.min.js.br +0 -0
  11. package/dist/selective-ui.umd.js +409 -575
  12. package/dist/selective-ui.umd.js.map +1 -1
  13. package/package.json +12 -12
  14. package/src/css/views/option-view.css +2 -2
  15. package/src/ts/adapter/mixed-adapter.ts +149 -71
  16. package/src/ts/components/accessorybox.ts +14 -11
  17. package/src/ts/components/directive.ts +1 -1
  18. package/src/ts/components/option-handle.ts +12 -9
  19. package/src/ts/components/placeholder.ts +5 -5
  20. package/src/ts/components/popup/empty-state.ts +5 -5
  21. package/src/ts/components/popup/loading-state.ts +5 -5
  22. package/src/ts/components/popup/popup.ts +138 -76
  23. package/src/ts/components/searchbox.ts +17 -13
  24. package/src/ts/components/selectbox.ts +260 -84
  25. package/src/ts/core/base/adapter.ts +61 -14
  26. package/src/ts/core/base/fenwick.ts +3 -2
  27. package/src/ts/core/base/lifecycle.ts +14 -4
  28. package/src/ts/core/base/model.ts +17 -15
  29. package/src/ts/core/base/recyclerview.ts +7 -5
  30. package/src/ts/core/base/view.ts +10 -5
  31. package/src/ts/core/base/virtual-recyclerview.ts +178 -45
  32. package/src/ts/core/model-manager.ts +48 -21
  33. package/src/ts/core/search-controller.ts +174 -56
  34. package/src/ts/global.ts +5 -8
  35. package/src/ts/index.ts +2 -2
  36. package/src/ts/models/group-model.ts +33 -8
  37. package/src/ts/models/option-model.ts +88 -20
  38. package/src/ts/services/dataset-observer.ts +6 -3
  39. package/src/ts/services/ea-observer.ts +1 -1
  40. package/src/ts/services/effector.ts +22 -12
  41. package/src/ts/services/refresher.ts +14 -4
  42. package/src/ts/services/resize-observer.ts +24 -11
  43. package/src/ts/services/select-observer.ts +2 -2
  44. package/src/ts/types/components/popup.type.ts +18 -1
  45. package/src/ts/types/components/searchbox.type.ts +43 -30
  46. package/src/ts/types/components/state.box.type.ts +1 -1
  47. package/src/ts/types/core/base/adapter.type.ts +13 -5
  48. package/src/ts/types/core/base/lifecycle.type.ts +1 -2
  49. package/src/ts/types/core/base/model.type.ts +3 -3
  50. package/src/ts/types/core/base/recyclerview.type.ts +7 -5
  51. package/src/ts/types/core/base/view.type.ts +6 -6
  52. package/src/ts/types/core/base/virtual-recyclerview.type.ts +45 -46
  53. package/src/ts/types/core/search-controller.type.ts +18 -2
  54. package/src/ts/types/css.d.ts +1 -0
  55. package/src/ts/types/plugins/plugin.type.ts +2 -2
  56. package/src/ts/types/services/effector.type.ts +25 -25
  57. package/src/ts/types/services/resize-observer.type.ts +23 -12
  58. package/src/ts/types/utils/callback-scheduler.type.ts +2 -2
  59. package/src/ts/types/utils/ievents.type.ts +1 -1
  60. package/src/ts/types/utils/istorage.type.ts +62 -60
  61. package/src/ts/types/utils/libs.type.ts +19 -17
  62. package/src/ts/types/utils/selective.type.ts +6 -3
  63. package/src/ts/types/views/view.group.type.ts +9 -5
  64. package/src/ts/types/views/view.option.type.ts +39 -17
  65. package/src/ts/utils/callback-scheduler.ts +12 -7
  66. package/src/ts/utils/ievents.ts +12 -5
  67. package/src/ts/utils/istorage.ts +5 -3
  68. package/src/ts/utils/libs.ts +122 -43
  69. package/src/ts/utils/selective.ts +15 -8
  70. package/src/ts/views/group-view.ts +11 -9
  71. package/src/ts/views/option-view.ts +37 -18
@@ -1,4 +1,3 @@
1
-
2
1
  import { Libs } from "../utils/libs";
3
2
  import { Refresher } from "../services/refresher";
4
3
  import { PlaceHolder } from "./placeholder";
@@ -23,11 +22,18 @@ import type { SelectiveOptions } from "../types/utils/selective.type";
23
22
  import { IEventToken, IEventCallback } from "../types/utils/ievents.type";
24
23
  import { MixedItem } from "../types/core/base/mixed-adapter.type";
25
24
  import { BinderMap } from "../types/utils/istorage.type";
26
- import { ContainerRuntime, SelectBoxAction, SelectBoxTags } from "../types/components/searchbox.type";
25
+ import {
26
+ ContainerRuntime,
27
+ SelectBoxAction,
28
+ SelectBoxTags,
29
+ } from "../types/components/searchbox.type";
27
30
  import { AjaxConfig } from "../types/core/search-controller.type";
28
31
  import { Selective } from "../utils/selective";
29
32
  import { VirtualRecyclerView } from "../core/base/virtual-recyclerview";
30
- import type { PluginContext, SelectivePlugin } from "../types/plugins/plugin.type";
33
+ import type {
34
+ PluginContext,
35
+ SelectivePlugin,
36
+ } from "../types/plugins/plugin.type";
31
37
 
32
38
  /**
33
39
  * SelectBox
@@ -97,7 +103,7 @@ export class SelectBox extends Lifecycle {
97
103
  * Created during {@link init} via {@link Libs.mountNode}, inserted into the DOM during {@link mount},
98
104
  * and removed during {@link destroy}.
99
105
  */
100
- private node: HTMLDivElement | null = null;
106
+ private node?: HTMLDivElement;
101
107
 
102
108
  /**
103
109
  * Parsed configuration (bound from the `<select>` element via binder map).
@@ -107,7 +113,7 @@ export class SelectBox extends Lifecycle {
107
113
  *
108
114
  * @internal
109
115
  */
110
- private options: SelectiveOptions | null = null;
116
+ private options?: SelectiveOptions;
111
117
 
112
118
  /**
113
119
  * Manager that owns model resources and bridges the Adapter ↔ RecyclerView pipeline.
@@ -117,7 +123,7 @@ export class SelectBox extends Lifecycle {
117
123
  *
118
124
  * @internal
119
125
  */
120
- private optionModelManager: ModelManager<MixedItem, MixedAdapter> | null = null;
126
+ private optionModelManager?: ModelManager<MixedItem, MixedAdapter>;
121
127
 
122
128
  /**
123
129
  * Whether the popup/list UI is currently open.
@@ -159,7 +165,7 @@ export class SelectBox extends Lifecycle {
159
165
  *
160
166
  * Used to locate the instance wrapper via `Selective.find(...)` and to close other open instances.
161
167
  */
162
- public Selective: Selective | null = null;
168
+ public Selective?: Selective;
163
169
 
164
170
  /**
165
171
  * Registered plugins for this SelectBox instance.
@@ -169,7 +175,7 @@ export class SelectBox extends Lifecycle {
169
175
  /**
170
176
  * Cached plugin context for this SelectBox instance.
171
177
  */
172
- private pluginContext: PluginContext<SelectBoxTags> | null = null;
178
+ private pluginContext?: PluginContext<SelectBoxTags>;
173
179
 
174
180
  /**
175
181
  * Creates a {@link SelectBox} bound to a native `<select>` element.
@@ -201,7 +207,10 @@ export class SelectBox extends Lifecycle {
201
207
  this.options.disabled = value;
202
208
  this.node.classList.toggle("disabled", value);
203
209
  this.node.setAttribute("aria-disabled", String(value));
204
- this.container.tags?.ViewPanel?.setAttribute("aria-disabled", String(value));
210
+ this.container.tags?.ViewPanel?.setAttribute(
211
+ "aria-disabled",
212
+ String(value),
213
+ );
205
214
  }
206
215
 
207
216
  /**
@@ -250,7 +259,7 @@ export class SelectBox extends Lifecycle {
250
259
  const bindedMap = Libs.getBinderMap<BinderMap>(select);
251
260
  this.options = bindedMap.options;
252
261
  this.Selective = Selective;
253
-
262
+
254
263
  this.init(select);
255
264
  }
256
265
 
@@ -290,15 +299,22 @@ export class SelectBox extends Lifecycle {
290
299
  const directive = new Directive();
291
300
  const searchbox = new SearchBox(options);
292
301
  const effector = Effector();
293
- const optionModelManager = new ModelManager<MixedItem, MixedAdapter>(options);
302
+ const optionModelManager = new ModelManager<MixedItem, MixedAdapter>(
303
+ options,
304
+ );
294
305
  const accessoryBox = new AccessoryBox(options);
295
- const searchController = new SearchController(select, optionModelManager, this);
306
+ const searchController = new SearchController(
307
+ select,
308
+ optionModelManager,
309
+ this,
310
+ );
296
311
 
297
312
  const selectObserver = new SelectObserver(select);
298
313
  const datasetObserver = new DatasetObserver(select);
299
314
 
300
315
  // ensure placeholder has id for aria-labelledby usage
301
- if (placeholder.node) placeholder.node.id = String(options.SEID_HOLDER ?? "");
316
+ if (placeholder.node)
317
+ placeholder.node.id = String(options.SEID_HOLDER ?? "");
302
318
 
303
319
  const container = Libs.mountNode<ContainerRuntime>(
304
320
  {
@@ -311,7 +327,11 @@ export class SelectBox extends Lifecycle {
311
327
  classList: "seui-view",
312
328
  tabIndex: 0,
313
329
  onkeydown: (e: KeyboardEvent) => {
314
- if (e.key === "Enter" || e.key === " " || e.key === "ArrowDown") {
330
+ if (
331
+ e.key === "Enter" ||
332
+ e.key === " " ||
333
+ e.key === "ArrowDown"
334
+ ) {
315
335
  e.preventDefault();
316
336
  this.getAction()?.open();
317
337
  }
@@ -326,7 +346,7 @@ export class SelectBox extends Lifecycle {
326
346
  },
327
347
  },
328
348
  },
329
- null
349
+ null,
330
350
  );
331
351
 
332
352
  this.container = container;
@@ -350,7 +370,9 @@ export class SelectBox extends Lifecycle {
350
370
  } else {
351
371
  optionModelManager.setupRecyclerView(RecyclerView);
352
372
  }
353
- optionModelManager.createModelResources(Libs.parseSelectToArray(select));
373
+ optionModelManager.createModelResources(
374
+ Libs.parseSelectToArray(select),
375
+ );
354
376
 
355
377
  optionModelManager.on("onUpdate", () => {
356
378
  container.popup?.triggerResize?.();
@@ -360,7 +382,7 @@ export class SelectBox extends Lifecycle {
360
382
 
361
383
  // Popup
362
384
  const popup = new Popup(select, options, optionModelManager);
363
- container.popup = popup
385
+ container.popup = popup;
364
386
  popup!.setupEffector(effector);
365
387
  popup!.setupInfiniteScroll(searchController, options);
366
388
 
@@ -377,8 +399,19 @@ export class SelectBox extends Lifecycle {
377
399
  accessoryBox.setRoot(container.tags.ViewPanel);
378
400
  accessoryBox.setModelManager(optionModelManager);
379
401
 
380
- this.setupEventHandlers(select, container, options, searchController, searchbox);
381
- this.setupObservers(selectObserver, datasetObserver, select, optionModelManager);
402
+ this.setupEventHandlers(
403
+ select,
404
+ container,
405
+ options,
406
+ searchController,
407
+ searchbox,
408
+ );
409
+ this.setupObservers(
410
+ selectObserver,
411
+ datasetObserver,
412
+ select,
413
+ optionModelManager,
414
+ );
382
415
 
383
416
  this.plugins = this.Selective?.getPlugins?.() ?? [];
384
417
  if (this.plugins.length) {
@@ -392,7 +425,9 @@ export class SelectBox extends Lifecycle {
392
425
  actions: this.getAction(),
393
426
  };
394
427
  this.pluginContext = pluginContext;
395
- this.runPluginHook("init", (plugin) => plugin.init?.(pluginContext));
428
+ this.runPluginHook("init", (plugin) =>
429
+ plugin.init?.(pluginContext),
430
+ );
396
431
  }
397
432
 
398
433
  // Initial states
@@ -427,12 +462,16 @@ export class SelectBox extends Lifecycle {
427
462
  select.parentNode?.insertBefore(this.node, select);
428
463
  this.node.insertBefore(select, container.tags.ViewPanel);
429
464
 
430
- container.tags.ViewPanel.addEventListener("mousedown", (e: MouseEvent) => {
431
- e.stopPropagation();
432
- e.preventDefault();
433
- });
465
+ container.tags.ViewPanel.addEventListener(
466
+ "mousedown",
467
+ (e: MouseEvent) => {
468
+ e.stopPropagation();
469
+ e.preventDefault();
470
+ },
471
+ );
434
472
 
435
473
  Refresher.resizeBox(select, container.tags.ViewPanel);
474
+ Refresher.resizeBox(select, this.node, true);
436
475
  select.classList.add("init");
437
476
 
438
477
  // initial mask
@@ -495,10 +534,10 @@ export class SelectBox extends Lifecycle {
495
534
  container: ContainerRuntime,
496
535
  options: SelectiveOptions,
497
536
  searchController: SearchController,
498
- searchbox: SearchBox
537
+ searchbox: SearchBox,
499
538
  ): void {
500
539
  const optionAdapter = container.popup!.optionAdapter;
501
- let hightlightTimer: ReturnType<typeof setTimeout> | null = null;
540
+ let hightlightTimer: NodeJS.Timeout | null = null;
502
541
 
503
542
  const searchHandle = (keyword: string, isTrigger: boolean) => {
504
543
  if (!isTrigger && keyword === "") {
@@ -510,7 +549,9 @@ export class SelectBox extends Lifecycle {
510
549
  .search(keyword)
511
550
  .then((result: any) => {
512
551
  clearTimeout(hightlightTimer!);
513
- Libs.callbackScheduler.clear(`sche_vis_proxy_${optionAdapter.adapterKey}`);
552
+ Libs.callbackScheduler.clear(
553
+ `sche_vis_proxy_${optionAdapter.adapterKey}`,
554
+ );
514
555
  Libs.callbackScheduler.on(
515
556
  `sche_vis_proxy_${optionAdapter.adapterKey}`,
516
557
  () => {
@@ -523,7 +564,7 @@ export class SelectBox extends Lifecycle {
523
564
  }, options.animationtime ?? 0);
524
565
  }
525
566
  },
526
- { debounce: 10 }
567
+ { debounce: 10 },
527
568
  );
528
569
  })
529
570
  .catch((error: unknown) => {
@@ -532,7 +573,7 @@ export class SelectBox extends Lifecycle {
532
573
  }
533
574
  };
534
575
 
535
- let searchHandleTimer: ReturnType<typeof setTimeout> | null = null;
576
+ let searchHandleTimer: NodeJS.Timeout | null = null;
536
577
 
537
578
  searchbox.onSearch = (keyword: string, isTrigger: boolean) => {
538
579
  if (!searchController.compareSearchTrigger(keyword)) return;
@@ -600,7 +641,7 @@ export class SelectBox extends Lifecycle {
600
641
  selectObserver: SelectObserver,
601
642
  datasetObserver: DatasetObserver,
602
643
  select: HTMLSelectElement,
603
- optionModelManager: ModelManager<MixedItem, MixedAdapter>
644
+ optionModelManager: ModelManager<MixedItem, MixedAdapter>,
604
645
  ): void {
605
646
  selectObserver.connect();
606
647
  selectObserver.onChanged = (sel) => {
@@ -727,7 +768,7 @@ export class SelectBox extends Lifecycle {
727
768
  *
728
769
  * @returns An action facade for controlling this instance, or `null` if not bound.
729
770
  */
730
- public getAction(): SelectBoxAction | null {
771
+ public getAction?(): SelectBoxAction {
731
772
  const container = this.container;
732
773
  const superThis = this;
733
774
  const getInstance = () => {
@@ -764,7 +805,11 @@ export class SelectBox extends Lifecycle {
764
805
  get value() {
765
806
  const item_list = this.valueArray as string[];
766
807
  const valLength = item_list.length;
767
- return valLength > 1 ? item_list : valLength === 0 ? "" : item_list[0];
808
+ return valLength > 1
809
+ ? item_list
810
+ : valLength === 0
811
+ ? ""
812
+ : item_list[0];
768
813
  },
769
814
 
770
815
  get valueArray() {
@@ -792,7 +837,7 @@ export class SelectBox extends Lifecycle {
792
837
  get mask() {
793
838
  const item_list: string[] = [];
794
839
  superThis.getModelOption(true).forEach((m) => {
795
- item_list.push(m.text);
840
+ item_list.push(m.mask);
796
841
  });
797
842
  return item_list;
798
843
  },
@@ -803,7 +848,11 @@ export class SelectBox extends Lifecycle {
803
848
  item_list.push(m.text);
804
849
  });
805
850
  const valLength = item_list.length;
806
- return valLength > 1 ? item_list : valLength === 0 ? "" : item_list[0];
851
+ return valLength > 1
852
+ ? item_list
853
+ : valLength === 0
854
+ ? ""
855
+ : item_list[0];
807
856
  },
808
857
 
809
858
  get isOpen() {
@@ -814,10 +863,16 @@ export class SelectBox extends Lifecycle {
814
863
  return container.view.parentElement;
815
864
  },
816
865
 
817
- valueDataset(_evtToken?: IEventCallback, strDataset: string = null, isArray: boolean = false) {
866
+ valueDataset(
867
+ _evtToken?: IEventCallback,
868
+ strDataset: string = null,
869
+ isArray: boolean = false,
870
+ ) {
818
871
  var item_list = [];
819
872
  superThis.getModelOption(true).forEach((m) => {
820
- item_list.push(strDataset ? m.dataset[strDataset] : m.dataset);
873
+ item_list.push(
874
+ strDataset ? m.dataset[strDataset] : m.dataset,
875
+ );
821
876
  });
822
877
 
823
878
  if (!isArray) {
@@ -833,13 +888,21 @@ export class SelectBox extends Lifecycle {
833
888
 
834
889
  selectAll(_evtToken?: IEventCallback, trigger: boolean = true) {
835
890
  if (bindedOptions.multiple && bindedOptions.maxSelected > 0) {
836
- if (superThis.getModelOption().length > bindedOptions.maxSelected) return;
891
+ if (
892
+ superThis.getModelOption().length >
893
+ bindedOptions.maxSelected
894
+ )
895
+ return;
837
896
  }
838
897
 
839
- if (this.disabled || this.readonly || !bindedOptions.multiple) return;
898
+ if (this.disabled || this.readonly || !bindedOptions.multiple)
899
+ return;
840
900
 
841
901
  if (trigger) {
842
- const beforeChangeToken = iEvents.callEvent([getInstance()], ...bindedOptions.on.beforeChange);
902
+ const beforeChangeToken = iEvents.callEvent(
903
+ [getInstance()],
904
+ ...bindedOptions.on.beforeChange,
905
+ );
843
906
  if (beforeChangeToken.isCancel) return;
844
907
  superThis.oldValue = this.value;
845
908
  }
@@ -852,10 +915,14 @@ export class SelectBox extends Lifecycle {
852
915
  },
853
916
 
854
917
  deSelectAll(_evtToken?: IEventCallback, trigger: boolean = true) {
855
- if (this.disabled || this.readonly || !bindedOptions.multiple) return;
918
+ if (this.disabled || this.readonly || !bindedOptions.multiple)
919
+ return;
856
920
 
857
921
  if (trigger) {
858
- const beforeChangeToken = iEvents.callEvent([getInstance()], ...bindedOptions.on.beforeChange);
922
+ const beforeChangeToken = iEvents.callEvent(
923
+ [getInstance()],
924
+ ...bindedOptions.on.beforeChange,
925
+ );
859
926
  if (beforeChangeToken.isCancel) return;
860
927
  superThis.oldValue = this.value;
861
928
  }
@@ -867,14 +934,22 @@ export class SelectBox extends Lifecycle {
867
934
  this.change(false, trigger);
868
935
  },
869
936
 
870
- deSelectByDataset(_evtToken?: IEventCallback, dataset?: any, trigger: boolean = true) {
937
+ deSelectByDataset(
938
+ _evtToken?: IEventCallback,
939
+ dataset?: any,
940
+ trigger: boolean = true,
941
+ ) {
871
942
  if (dataset) {
872
- superThis.getModelOption().forEach(optionModel => {
943
+ superThis.getModelOption().forEach((optionModel) => {
873
944
  if (optionModel.dataset) {
874
945
  for (let searchKey in dataset) {
875
946
  let value = dataset[searchKey];
876
947
  !Array.isArray(value) && (value = [value]);
877
- if (value.includes(optionModel.dataset[searchKey])) {
948
+ if (
949
+ value.includes(
950
+ optionModel.dataset[searchKey],
951
+ )
952
+ ) {
878
953
  optionModel.selectedNonTrigger = false;
879
954
  }
880
955
  }
@@ -884,19 +959,28 @@ export class SelectBox extends Lifecycle {
884
959
  }
885
960
  },
886
961
 
887
- setValue(_evtToken: IEventCallback | null = null, value: any, trigger: boolean = true, force: boolean = false) {
962
+ setValue(
963
+ _evtToken?: IEventCallback,
964
+ value?: any,
965
+ trigger: boolean = true,
966
+ force: boolean = false,
967
+ ) {
888
968
  if (!Array.isArray(value)) value = [value];
889
969
  value = value.filter((v: any) => v !== "" && v != null);
890
970
 
891
971
  if (value.length === 0) {
892
- superThis.getModelOption().forEach((m) => (m.selectedNonTrigger = false));
972
+ superThis
973
+ .getModelOption()
974
+ .forEach((m) => (m.selectedNonTrigger = false));
893
975
  this.change(false, trigger);
894
976
  return;
895
977
  }
896
978
 
897
979
  if (bindedOptions.multiple && bindedOptions.maxSelected > 0) {
898
980
  if (value.length > bindedOptions.maxSelected) {
899
- console.warn(`Cannot select more than ${bindedOptions.maxSelected} items`);
981
+ console.warn(
982
+ `Cannot select more than ${bindedOptions.maxSelected} items`,
983
+ );
900
984
  return;
901
985
  }
902
986
  }
@@ -905,33 +989,59 @@ export class SelectBox extends Lifecycle {
905
989
 
906
990
  // AJAX: load missing values
907
991
  if (container.searchController?.isAjax?.()) {
908
- const { missing } = container.searchController.checkMissingValues(value);
992
+ container.searchController.resetPagination();
993
+ superThis.hasLoadedOnce = false;
994
+
995
+ const { missing } =
996
+ container.searchController.checkMissingValues(value);
909
997
 
910
998
  if (missing.length > 0) {
911
999
  (async () => {
912
- if (bindedOptions.loadingfield) container.popup?.showLoading?.();
1000
+ if (bindedOptions.loadingfield)
1001
+ container.popup?.showLoading?.();
913
1002
 
914
1003
  try {
915
- container.searchController.resetPagination();
916
- const result = await container.searchController.loadByValues(missing);
1004
+ const result =
1005
+ await container.searchController.loadByValues(
1006
+ missing,
1007
+ );
917
1008
  if (result.success && result.items.length > 0) {
918
1009
  result.items.forEach((it: any) => {
919
- if (missing.includes(it.value) || missing.includes(it.text)) it.selected = true;
1010
+ if (
1011
+ missing.includes(it.value) ||
1012
+ missing.includes(it.text)
1013
+ )
1014
+ it.selected = true;
920
1015
  });
921
1016
 
922
- container.searchController.applyAjaxResult?.(result.items, false, false);
923
-
1017
+ container.searchController.applyAjaxResult?.(
1018
+ result.items,
1019
+ false,
1020
+ false,
1021
+ );
1022
+
924
1023
  setTimeout(() => {
925
1024
  container.searchController.resetPagination();
926
1025
  this.change(false, trigger);
927
1026
  }, 200);
928
1027
  } else if (missing.length > 0) {
929
- console.warn(`Could not load ${missing.length} values:`, missing);
1028
+ console.warn(
1029
+ `Could not load ${missing.length} values:`,
1030
+ missing,
1031
+ );
1032
+ setTimeout(() => {
1033
+ container.searchController.resetPagination();
1034
+ this.change(false, trigger);
1035
+ }, 200);
930
1036
  }
931
1037
  } catch (error) {
932
- console.error("Error loading missing values:", error);
1038
+ console.error(
1039
+ "Error loading missing values:",
1040
+ error,
1041
+ );
933
1042
  } finally {
934
- if (bindedOptions.loadingfield) container.popup?.hideLoading?.();
1043
+ if (bindedOptions.loadingfield)
1044
+ container.popup?.hideLoading?.();
935
1045
  }
936
1046
  })();
937
1047
  return;
@@ -939,7 +1049,10 @@ export class SelectBox extends Lifecycle {
939
1049
  }
940
1050
 
941
1051
  if (trigger) {
942
- const beforeChangeToken = iEvents.callEvent([getInstance()], ...bindedOptions.on.beforeChange);
1052
+ const beforeChangeToken = iEvents.callEvent(
1053
+ [getInstance()],
1054
+ ...bindedOptions.on.beforeChange,
1055
+ );
943
1056
  if (beforeChangeToken.isCancel) return;
944
1057
  superThis.oldValue = this.value;
945
1058
  }
@@ -956,18 +1069,24 @@ export class SelectBox extends Lifecycle {
956
1069
  },
957
1070
 
958
1071
  load() {
959
- if ((!superThis.hasLoadedOnce || superThis.isBeforeSearch) && bindedOptions?.ajax) {
1072
+ if (
1073
+ (!superThis.hasLoadedOnce || superThis.isBeforeSearch) &&
1074
+ bindedOptions?.ajax
1075
+ ) {
960
1076
  container.searchController.resetPagination();
961
1077
  container.popup.showLoading();
962
1078
  superThis.hasLoadedOnce = true;
963
1079
  superThis.isBeforeSearch = false;
964
1080
 
965
1081
  setTimeout(() => {
966
- if (!container.popup || !container.searchController) return;
1082
+ if (!container.popup || !container.searchController)
1083
+ return;
967
1084
  container.searchController
968
1085
  .search("")
969
1086
  .then(() => container.popup?.triggerResize?.())
970
- .catch((err: unknown) => console.error("Initial ajax load error:", err));
1087
+ .catch((err: unknown) =>
1088
+ console.error("Initial ajax load error:", err),
1089
+ );
971
1090
  }, bindedOptions.animationtime);
972
1091
  container.popup.load();
973
1092
  } else {
@@ -988,7 +1107,10 @@ export class SelectBox extends Lifecycle {
988
1107
  return;
989
1108
  }
990
1109
 
991
- const beforeShowToken = iEvents.callEvent([getInstance()], ...bindedOptions.on.beforeShow);
1110
+ const beforeShowToken = iEvents.callEvent(
1111
+ [getInstance()],
1112
+ ...bindedOptions.on.beforeShow,
1113
+ );
992
1114
  if (beforeShowToken.isCancel) {
993
1115
  return;
994
1116
  }
@@ -1005,15 +1127,30 @@ export class SelectBox extends Lifecycle {
1005
1127
  }
1006
1128
 
1007
1129
  this.load();
1008
- container.popup.open(null, !container.popup.loadingState.isVisible);
1130
+ container.popup.open(
1131
+ () => {
1132
+ setTimeout(() => {
1133
+ if (selectedOption) {
1134
+ adapter.setHighlight(selectedOption, bindedOptions.autoscroll);
1135
+ }
1136
+ }, 100);
1137
+ },
1138
+ !container.popup.loadingState.isVisible,
1139
+ );
1009
1140
 
1010
1141
  container.searchbox.show();
1011
1142
 
1012
1143
  const ViewPanel: HTMLElement = container.tags.ViewPanel;
1013
1144
  ViewPanel.setAttribute("aria-expanded", "true");
1014
- ViewPanel.setAttribute("aria-controls", bindedOptions.SEID_LIST);
1145
+ ViewPanel.setAttribute(
1146
+ "aria-controls",
1147
+ bindedOptions.SEID_LIST,
1148
+ );
1015
1149
  ViewPanel.setAttribute("aria-haspopup", "listbox");
1016
- ViewPanel.setAttribute("aria-labelledby", bindedOptions.SEID_HOLDER);
1150
+ ViewPanel.setAttribute(
1151
+ "aria-labelledby",
1152
+ bindedOptions.SEID_HOLDER,
1153
+ );
1017
1154
 
1018
1155
  if (bindedOptions.multiple) {
1019
1156
  ViewPanel.setAttribute("aria-multiselectable", "true");
@@ -1021,7 +1158,9 @@ export class SelectBox extends Lifecycle {
1021
1158
 
1022
1159
  iEvents.callEvent([getInstance()], ...bindedOptions.on.show);
1023
1160
  if (superThis.pluginContext) {
1024
- superThis.runPluginHook("onOpen", (plugin) => plugin.onOpen?.(superThis.pluginContext));
1161
+ superThis.runPluginHook("onOpen", (plugin) =>
1162
+ plugin.onOpen?.(superThis.pluginContext),
1163
+ );
1025
1164
  }
1026
1165
  return;
1027
1166
  },
@@ -1029,7 +1168,10 @@ export class SelectBox extends Lifecycle {
1029
1168
  close() {
1030
1169
  if (!superThis.isOpen) return;
1031
1170
 
1032
- const beforeCloseToken = iEvents.callEvent([getInstance()], ...bindedOptions.on.beforeClose);
1171
+ const beforeCloseToken = iEvents.callEvent(
1172
+ [getInstance()],
1173
+ ...bindedOptions.on.beforeClose,
1174
+ );
1033
1175
  if (beforeCloseToken.isCancel) return;
1034
1176
 
1035
1177
  superThis.isOpen = false;
@@ -1044,7 +1186,9 @@ export class SelectBox extends Lifecycle {
1044
1186
 
1045
1187
  iEvents.callEvent([getInstance()], ...bindedOptions.on.close);
1046
1188
  if (superThis.pluginContext) {
1047
- superThis.runPluginHook("onClose", (plugin) => plugin.onClose?.(superThis.pluginContext));
1189
+ superThis.runPluginHook("onClose", (plugin) =>
1190
+ plugin.onClose?.(superThis.pluginContext),
1191
+ );
1048
1192
  }
1049
1193
  return;
1050
1194
  },
@@ -1054,10 +1198,15 @@ export class SelectBox extends Lifecycle {
1054
1198
  else this.open();
1055
1199
  },
1056
1200
 
1057
- change(_evtToken: IEventCallback | null = null, canTrigger: boolean = true) {
1201
+ change(_evtToken?: IEventCallback, canTrigger: boolean = true) {
1058
1202
  if (canTrigger) {
1059
- if (bindedOptions.multiple && bindedOptions.maxSelected > 0) {
1060
- if (this.valueArray.length > bindedOptions.maxSelected) {
1203
+ if (
1204
+ bindedOptions.multiple &&
1205
+ bindedOptions.maxSelected > 0
1206
+ ) {
1207
+ if (
1208
+ this.valueArray.length > bindedOptions.maxSelected
1209
+ ) {
1061
1210
  this.setValue(null, this.oldValue, false, true);
1062
1211
  }
1063
1212
  }
@@ -1067,7 +1216,10 @@ export class SelectBox extends Lifecycle {
1067
1216
  return;
1068
1217
  }
1069
1218
 
1070
- const beforeChangeToken = iEvents.callEvent([getInstance(), this.value], ...bindedOptions.on.beforeChange);
1219
+ const beforeChangeToken = iEvents.callEvent(
1220
+ [getInstance(), this.value],
1221
+ ...bindedOptions.on.beforeChange,
1222
+ );
1071
1223
  if (beforeChangeToken.isCancel) {
1072
1224
  this.setValue(null, this.oldValue, false);
1073
1225
  return;
@@ -1078,8 +1230,12 @@ export class SelectBox extends Lifecycle {
1078
1230
  container.accessorybox.setModelData(this.valueOptions);
1079
1231
 
1080
1232
  if (canTrigger) {
1081
- if (container.targetElement) iEvents.trigger(container.targetElement, "change");
1082
- iEvents.callEvent([getInstance(), this.value], ...bindedOptions.on.change);
1233
+ if (container.targetElement)
1234
+ iEvents.trigger(container.targetElement, "change");
1235
+ iEvents.callEvent(
1236
+ [getInstance(), this.value],
1237
+ ...bindedOptions.on.change,
1238
+ );
1083
1239
 
1084
1240
  if (superThis.options?.autoclose) this.close();
1085
1241
  }
@@ -1090,9 +1246,15 @@ export class SelectBox extends Lifecycle {
1090
1246
  }
1091
1247
 
1092
1248
  if (superThis.pluginContext && superThis.optionModelManager) {
1093
- const resources = superThis.optionModelManager.getResources();
1249
+ const resources =
1250
+ superThis.optionModelManager.getResources();
1094
1251
  superThis.runPluginHook("onChange", (plugin) =>
1095
- plugin.onChange?.(this.value, resources.modelList, resources.adapter, superThis.pluginContext)
1252
+ plugin.onChange?.(
1253
+ this.value,
1254
+ resources.modelList,
1255
+ resources.adapter,
1256
+ superThis.pluginContext,
1257
+ ),
1096
1258
  );
1097
1259
  }
1098
1260
  },
@@ -1100,7 +1262,10 @@ export class SelectBox extends Lifecycle {
1100
1262
  refreshMask() {
1101
1263
  let mask = bindedOptions.placeholder;
1102
1264
 
1103
- if (!bindedOptions.multiple && superThis.getModelOption().length > 0) {
1265
+ if (
1266
+ !bindedOptions.multiple &&
1267
+ superThis.getModelOption().length > 0
1268
+ ) {
1104
1269
  mask = this.mask[0];
1105
1270
  }
1106
1271
 
@@ -1110,7 +1275,11 @@ export class SelectBox extends Lifecycle {
1110
1275
  container.searchbox.setPlaceHolder(mask);
1111
1276
  },
1112
1277
 
1113
- on(_evtToken: IEventCallback, evtName: string, handle: (...args: any[]) => any) {
1278
+ on(
1279
+ _evtToken: IEventCallback,
1280
+ evtName: string,
1281
+ handle: (...args: any[]) => any,
1282
+ ) {
1114
1283
  if (!bindedOptions.on[evtName]) bindedOptions.on[evtName] = [];
1115
1284
  bindedOptions.on[evtName].push(handle);
1116
1285
  },
@@ -1136,7 +1305,9 @@ export class SelectBox extends Lifecycle {
1136
1305
  .search("")
1137
1306
  .then(() => {
1138
1307
  container.popup?.triggerResize?.();
1139
- resove(getInstance());
1308
+ setTimeout(() => {
1309
+ resove(getInstance());
1310
+ }, 60);
1140
1311
  })
1141
1312
  .catch((err: unknown) => {
1142
1313
  console.error("Initial ajax load error:", err);
@@ -1183,7 +1354,7 @@ export class SelectBox extends Lifecycle {
1183
1354
  private createSymProp(
1184
1355
  obj: Record<string, any>,
1185
1356
  prop: "disabled" | "readonly" | "visible",
1186
- privateProp: "isDisabled" | "isReadOnly" | "isVisible"
1357
+ privateProp: "isDisabled" | "isReadOnly" | "isVisible",
1187
1358
  ): void {
1188
1359
  const superThis = this;
1189
1360
 
@@ -1194,7 +1365,8 @@ export class SelectBox extends Lifecycle {
1194
1365
  set(value: any) {
1195
1366
  superThis[privateProp] = !!value;
1196
1367
  if (superThis.container?.targetElement?.dataset) {
1197
- superThis.container.targetElement.dataset[prop] = String(!!value);
1368
+ superThis.container.targetElement.dataset[prop] =
1369
+ String(!!value);
1198
1370
  }
1199
1371
  },
1200
1372
  enumerable: true,
@@ -1223,7 +1395,7 @@ export class SelectBox extends Lifecycle {
1223
1395
  * @returns A flat array of option models (possibly filtered).
1224
1396
  * @internal
1225
1397
  */
1226
- private getModelOption(isSelected: boolean | null = null): OptionModel[] {
1398
+ private getModelOption(isSelected?: boolean): OptionModel[] {
1227
1399
  if (!this.optionModelManager) return [];
1228
1400
 
1229
1401
  const { modelList } = this.optionModelManager.getResources();
@@ -1233,7 +1405,8 @@ export class SelectBox extends Lifecycle {
1233
1405
  if (m instanceof OptionModel) {
1234
1406
  flatOptions.push(m);
1235
1407
  } else if (m instanceof GroupModel) {
1236
- if (Array.isArray(m.items) && m.items.length) flatOptions.push(...m.items);
1408
+ if (Array.isArray(m.items) && m.items.length)
1409
+ flatOptions.push(...m.items);
1237
1410
  }
1238
1411
  }
1239
1412
 
@@ -1253,7 +1426,10 @@ export class SelectBox extends Lifecycle {
1253
1426
  * @param runner - Hook invocation handler.
1254
1427
  * @internal
1255
1428
  */
1256
- private runPluginHook(hook: string, runner: (plugin: SelectivePlugin) => void): void {
1429
+ private runPluginHook(
1430
+ hook: string,
1431
+ runner: (plugin: SelectivePlugin) => void,
1432
+ ): void {
1257
1433
  if (!this.plugins.length) return;
1258
1434
 
1259
1435
  this.plugins.forEach((plugin) => {