@feugene/granularity 0.46.0 → 0.47.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/README.md +3 -3
  2. package/dist/chunks/{x-circle-BCBURwyX.js → check-circle-Bnrb-CGJ.js} +8 -32
  3. package/dist/chunks/check-circle-Bnrb-CGJ.js.map +1 -0
  4. package/dist/chunks/{config-BqT6PMzO.js → config-B42iJ48O.js} +5 -1
  5. package/dist/chunks/{config-BqT6PMzO.js.map → config-B42iJ48O.js.map} +1 -1
  6. package/dist/chunks/{config-BGCyyXiD.js → config-BAse0laT.js} +5 -1
  7. package/dist/chunks/{config-BGCyyXiD.js.map → config-BAse0laT.js.map} +1 -1
  8. package/dist/chunks/{config-MmPym-Z7.js → config-BLP94dPY.js} +5 -1
  9. package/dist/chunks/{config-MmPym-Z7.js.map → config-BLP94dPY.js.map} +1 -1
  10. package/dist/chunks/{config-CjKpUcmy.js → config-Bdf1bt-m.js} +25 -16
  11. package/dist/chunks/config-Bdf1bt-m.js.map +1 -0
  12. package/dist/chunks/{config-CIkdsWUk.js → config-CIUU9ZpY.js} +4 -1
  13. package/dist/chunks/config-CIUU9ZpY.js.map +1 -0
  14. package/dist/chunks/{config-BhfNgyWL.js → config-DENqOoh0.js} +5 -1
  15. package/dist/chunks/config-DENqOoh0.js.map +1 -0
  16. package/dist/chunks/controlState-DoImKciE.js +35 -0
  17. package/dist/chunks/controlState-DoImKciE.js.map +1 -0
  18. package/dist/chunks/{en-DiHzFact.js → en-DjTnfTqM.js} +3 -1
  19. package/dist/chunks/en-DjTnfTqM.js.map +1 -0
  20. package/dist/chunks/{es-1ZL6NtkB.js → es-Bc_t3FI8.js} +3 -1
  21. package/dist/chunks/es-Bc_t3FI8.js.map +1 -0
  22. package/dist/chunks/{es-CeKkMxZ_.js → es-DIFzSXSZ.js} +3 -3
  23. package/dist/chunks/{es-CeKkMxZ_.js.map → es-DIFzSXSZ.js.map} +1 -1
  24. package/dist/chunks/{granular-provider-CsN_R9dB.js → granular-provider-AKukmYva.js} +6 -6
  25. package/dist/chunks/{granular-provider-CsN_R9dB.js.map → granular-provider-AKukmYva.js.map} +1 -1
  26. package/dist/chunks/{ru-Dr2RYn0P.js → ru-Bb-co59W.js} +3 -1
  27. package/dist/chunks/ru-Bb-co59W.js.map +1 -0
  28. package/dist/chunks/x-circle-BigSZy8m.js +26 -0
  29. package/dist/chunks/x-circle-BigSZy8m.js.map +1 -0
  30. package/dist/components/GrAlert/chunks/{GrAlert-D72y1IEh.js → GrAlert-CfEZghSY.js} +2 -1
  31. package/dist/components/GrAlert/chunks/{GrAlert-D72y1IEh.js.map → GrAlert-CfEZghSY.js.map} +1 -1
  32. package/dist/components/GrAlert/index.js +1 -1
  33. package/dist/components/GrAutocomplete/chunks/{GrAutocomplete-D396_JrW.js → GrAutocomplete-C-uovdv8.js} +320 -224
  34. package/dist/components/GrAutocomplete/chunks/GrAutocomplete-C-uovdv8.js.map +1 -0
  35. package/dist/components/GrAutocomplete/index.js +1 -1
  36. package/dist/components/GrAutocomplete/styles.css +1 -1
  37. package/dist/components/GrColorPicker/chunks/{GrColorPicker-9mTR-YZ_.js → GrColorPicker-BRM_4lyI.js} +1 -1
  38. package/dist/components/GrColorPicker/chunks/{GrColorPicker-9mTR-YZ_.js.map → GrColorPicker-BRM_4lyI.js.map} +1 -1
  39. package/dist/components/GrColorPicker/index.js +1 -1
  40. package/dist/components/GrCommandPalette/chunks/{GrCommandPalette-Ha4s3DMT.js.map → GrCommandPalette-BJHmkDQv.js.map} +1 -1
  41. package/dist/components/GrCommandPalette/index.js +1 -1
  42. package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-e15nFI8M.js → GrConfirmDialog-BzUQwbec.js} +1 -1
  43. package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-e15nFI8M.js.map → GrConfirmDialog-BzUQwbec.js.map} +1 -1
  44. package/dist/components/GrConfirmDialog/index.js +1 -1
  45. package/dist/components/GrDataTable/chunks/{GrDataTable-xNSmO_I-.js → GrDataTable-Dp9Fp_P5.js} +606 -499
  46. package/dist/components/GrDataTable/chunks/GrDataTable-Dp9Fp_P5.js.map +1 -0
  47. package/dist/components/GrDataTable/index.js +1 -1
  48. package/dist/components/GrDialogService/chunks/{GrDialogService-BmXiYmUp.js → GrDialogService-Dtq0ZCN5.js} +3 -3
  49. package/dist/components/GrDialogService/chunks/{GrDialogService-BmXiYmUp.js.map → GrDialogService-Dtq0ZCN5.js.map} +1 -1
  50. package/dist/components/GrDialogService/index.js +1 -1
  51. package/dist/components/GrFormField/chunks/GrFormField-DO61vxpS.js.map +1 -1
  52. package/dist/components/GrInput/chunks/{GrInput-TFeBm3gQ.js → GrInput-DV4gMWPR.js} +40 -11
  53. package/dist/components/GrInput/chunks/GrInput-DV4gMWPR.js.map +1 -0
  54. package/dist/components/GrInput/index.js +2 -2
  55. package/dist/components/GrInputTag/chunks/{GrInputTag-Ci8AO1ze.js → GrInputTag-CO0YU-ok.js} +30 -6
  56. package/dist/components/GrInputTag/chunks/GrInputTag-CO0YU-ok.js.map +1 -0
  57. package/dist/components/GrInputTag/index.js +2 -2
  58. package/dist/components/GrJsonViewer/chunks/{GrJsonViewer-C6q8dEEZ.js → GrJsonViewer-D7CyWzhT.js} +1 -1
  59. package/dist/components/GrJsonViewer/chunks/{GrJsonViewer-C6q8dEEZ.js.map → GrJsonViewer-D7CyWzhT.js.map} +1 -1
  60. package/dist/components/GrJsonViewer/index.js +1 -1
  61. package/dist/components/GrNumberInput/chunks/{GrNumberInput-CL5QhOmx.js → GrNumberInput-BI6-vkcs.js} +48 -16
  62. package/dist/components/GrNumberInput/chunks/GrNumberInput-BI6-vkcs.js.map +1 -0
  63. package/dist/components/GrNumberInput/index.js +2 -2
  64. package/dist/components/GrPagination/chunks/{GrPagination-DhbNZHEF.js → GrPagination-BbaF5eXk.js} +10 -7
  65. package/dist/components/GrPagination/chunks/GrPagination-BbaF5eXk.js.map +1 -0
  66. package/dist/components/GrPagination/index.js +2 -2
  67. package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-8RxQsOQ_.js → GrPromptDialog-BEL-QgwE.js} +3 -3
  68. package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-8RxQsOQ_.js.map → GrPromptDialog-BEL-QgwE.js.map} +1 -1
  69. package/dist/components/GrPromptDialog/index.js +1 -1
  70. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-NEEJZ8zi.js → GrResponseErrorBanner-Bdd5c07x.js} +1 -1
  71. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-NEEJZ8zi.js.map → GrResponseErrorBanner-Bdd5c07x.js.map} +1 -1
  72. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-ZvBvEQDZ.js → GrResponseErrorBanner-DySe1ym4.js} +1 -1
  73. package/dist/components/GrResponseErrorBanner/chunks/{GrResponseErrorBanner-ZvBvEQDZ.js.map → GrResponseErrorBanner-DySe1ym4.js.map} +1 -1
  74. package/dist/components/GrResponseErrorBanner/index.js +2 -2
  75. package/dist/components/GrSelect/chunks/{GrSelect-Do1iAyp1.js → GrSelect-0iI4wdR_.js} +3 -3
  76. package/dist/components/GrSelect/chunks/{GrSelect-Do1iAyp1.js.map → GrSelect-0iI4wdR_.js.map} +1 -1
  77. package/dist/components/GrSelect/index.js +1 -1
  78. package/dist/components/GrTextarea/chunks/{GrTextarea-BII3w61K.js → GrTextarea-Bfgc0DD2.js} +73 -32
  79. package/dist/components/GrTextarea/chunks/GrTextarea-Bfgc0DD2.js.map +1 -0
  80. package/dist/components/GrTextarea/index.js +2 -2
  81. package/dist/components/GrToaster/chunks/{GrToaster-D-sV-9of.js → GrToaster-CZixNk0l.js} +2 -1
  82. package/dist/components/GrToaster/chunks/{GrToaster-D-sV-9of.js.map → GrToaster-CZixNk0l.js.map} +1 -1
  83. package/dist/components/GrToaster/index.js +1 -1
  84. package/dist/components/GrTransfer/chunks/{GrTransfer-8FA78ny6.js → GrTransfer-DdfBUf35.js} +2 -2
  85. package/dist/components/GrTransfer/chunks/{GrTransfer-8FA78ny6.js.map → GrTransfer-DdfBUf35.js.map} +1 -1
  86. package/dist/components/GrTransfer/index.js +1 -1
  87. package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-DBu5nMGA.js → GrTreeSelect-B6KoDYiZ.js} +43 -18
  88. package/dist/components/GrTreeSelect/chunks/GrTreeSelect-B6KoDYiZ.js.map +1 -0
  89. package/dist/components/GrTreeSelect/index.js +2 -2
  90. package/dist/granular-provider-node.js +1 -1
  91. package/dist/granular-provider.js +1 -1
  92. package/dist/i18n/all.js +1 -1
  93. package/dist/i18n/index.js +1 -1
  94. package/dist/index.js +27 -27
  95. package/dist/types/components/GrAutocomplete/composables/useAutocompleteNavigation.d.ts +39 -0
  96. package/dist/types/components/GrAutocomplete/composables/useAutocompletePanel.d.ts +36 -0
  97. package/dist/types/components/GrAutocomplete/composables/useAutocompleteValues.d.ts +28 -0
  98. package/dist/types/components/GrAutocomplete/composables/useAutocompleteVirtual.d.ts +33 -0
  99. package/dist/types/components/GrAutocomplete/composables/useRemoteOptions.d.ts +33 -0
  100. package/dist/types/components/GrDataTable/GrDataTable.vue.d.ts +1 -1
  101. package/dist/types/components/GrDataTable/composables/useDataTableColumnOrder.d.ts +45 -0
  102. package/dist/types/components/GrDataTable/composables/useDataTableColumnWidths.d.ts +38 -0
  103. package/dist/types/components/GrDataTable/composables/useDataTableLayout.d.ts +29 -0
  104. package/dist/types/components/GrDataTable/composables/useDataTableRowKeys.d.ts +16 -0
  105. package/dist/types/components/GrDataTable/composables/useDataTableSelection.d.ts +32 -0
  106. package/dist/types/components/GrDataTable/composables/useDataTableSort.d.ts +37 -0
  107. package/dist/types/components/GrFormField/GrFormField.vue.d.ts +7 -1
  108. package/dist/types/components/GrPagination/GrPagination.vue.d.ts +17 -2
  109. package/dist/types/components/GrPagination/grPaginationStyles.d.ts +15 -6
  110. package/dist/types/components/GrPagination/index.d.ts +1 -1
  111. package/dist/types/components/shared/controlState.d.ts +36 -0
  112. package/dist/types/i18n/messages/en.d.ts +4 -0
  113. package/dist/types/i18n/messages/es.d.ts +4 -0
  114. package/dist/types/i18n/messages/ru.d.ts +4 -0
  115. package/dist/web-types.json +4 -3
  116. package/package.json +1 -1
  117. package/dist/chunks/config-BhfNgyWL.js.map +0 -1
  118. package/dist/chunks/config-CIkdsWUk.js.map +0 -1
  119. package/dist/chunks/config-CjKpUcmy.js.map +0 -1
  120. package/dist/chunks/en-DiHzFact.js.map +0 -1
  121. package/dist/chunks/es-1ZL6NtkB.js.map +0 -1
  122. package/dist/chunks/ru-Dr2RYn0P.js.map +0 -1
  123. package/dist/chunks/x-circle-BCBURwyX.js.map +0 -1
  124. package/dist/components/GrAutocomplete/chunks/GrAutocomplete-D396_JrW.js.map +0 -1
  125. package/dist/components/GrDataTable/chunks/GrDataTable-xNSmO_I-.js.map +0 -1
  126. package/dist/components/GrInput/chunks/GrInput-TFeBm3gQ.js.map +0 -1
  127. package/dist/components/GrInputTag/chunks/GrInputTag-Ci8AO1ze.js.map +0 -1
  128. package/dist/components/GrNumberInput/chunks/GrNumberInput-CL5QhOmx.js.map +0 -1
  129. package/dist/components/GrPagination/chunks/GrPagination-DhbNZHEF.js.map +0 -1
  130. package/dist/components/GrTextarea/chunks/GrTextarea-BII3w61K.js.map +0 -1
  131. package/dist/components/GrTreeSelect/chunks/GrTreeSelect-DBu5nMGA.js.map +0 -1
  132. package/dist/components/GrCommandPalette/chunks/{GrCommandPalette-Ha4s3DMT.js → GrCommandPalette-BJHmkDQv.js} +1 -1
@@ -7,14 +7,14 @@ import { r as isComposingEvent } from "../../../chunks/keyboard-DE2yhz_b.js";
7
7
  import { t as loader_circle_default } from "../../../chunks/loader-circle-CfVLz7lb.js";
8
8
  import { useFloating } from "../../../composables/useFloating.js";
9
9
  import { useDismissible } from "../../../composables/useDismissible.js";
10
+ import { a as resolveSelectedOptions, t as filterOptions } from "../../../chunks/optionFilter-DYw9XPPx.js";
10
11
  import { useVirtualList } from "../../../composables/useVirtualList.js";
12
+ import { useComboboxNavigation } from "../../../composables/useComboboxNavigation.js";
11
13
  import { n as useGrFormFieldContext } from "../../../chunks/context-DdNIxa1w.js";
12
14
  import { useGrFormControl } from "../../../composables/useGrFormControl.js";
13
15
  import { t as useFocusWithin } from "../../../chunks/useFocusWithin-BwHE0rzm.js";
14
16
  import { t as useControlledOpen } from "../../../chunks/useControlledOpen-DV3SqLTP.js";
15
- import { useComboboxNavigation } from "../../../composables/useComboboxNavigation.js";
16
17
  import { useRovingFocus } from "../../../composables/useRovingFocus.js";
17
- import { a as resolveSelectedOptions, t as filterOptions } from "../../../chunks/optionFilter-DYw9XPPx.js";
18
18
  import { t as useControlAddons } from "../../../chunks/useControlAddons-asUr10Pf.js";
19
19
  import { d as chipSizeForBadgeScale } from "../../../chunks/grChipStyles-DcDyxAL0.js";
20
20
  import { t as GrChip_default } from "../../GrChip/chunks/GrChip-CKqyzYcv.js";
@@ -24,7 +24,262 @@ import { t as check_default } from "../../../chunks/check-BZI24Qs4.js";
24
24
  import { t as chevron_down_default } from "../../../chunks/chevron-down-CQS2OG_s.js";
25
25
  import { t as _plugin_vue_export_helper_default } from "../../../chunks/_plugin-vue_export-helper-BOaGB7Aw.js";
26
26
  import { Fragment, Teleport, Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeProps, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, openBlock, ref, renderList, renderSlot, shallowRef, toDisplayString, unref, useId, vShow, watch, withCtx, withDirectives, withModifiers } from "vue";
27
- import '../styles.css';//#region src/components/GrAutocomplete/GrAutocomplete.vue?vue&type=script&setup=true&lang.ts
27
+ import '../styles.css';//#region src/components/GrAutocomplete/composables/useRemoteOptions.ts
28
+ function useRemoteOptions(options) {
29
+ const remoteOptions = shallowRef([]);
30
+ const remoteAnswered = ref(false);
31
+ const remoteLoading = ref(false);
32
+ let searchTimer = null;
33
+ let searchSeq = 0;
34
+ let inflight = null;
35
+ function isAbortError(error) {
36
+ return error instanceof Error && error.name === "AbortError";
37
+ }
38
+ async function runFetch(query) {
39
+ const fetchOptions = options.fetchOptions();
40
+ if (!fetchOptions) return;
41
+ inflight?.abort();
42
+ const controller = new AbortController();
43
+ inflight = controller;
44
+ const seq = ++searchSeq;
45
+ remoteLoading.value = true;
46
+ try {
47
+ const result = await fetchOptions(query, controller.signal);
48
+ if (seq !== searchSeq) return;
49
+ remoteOptions.value = result;
50
+ remoteAnswered.value = true;
51
+ } catch (error) {
52
+ if (seq !== searchSeq || isAbortError(error)) return;
53
+ remoteOptions.value = [];
54
+ remoteAnswered.value = true;
55
+ options.onSearchError(error);
56
+ } finally {
57
+ if (seq === searchSeq) remoteLoading.value = false;
58
+ }
59
+ }
60
+ function scheduleSearch(value) {
61
+ if (searchTimer) clearTimeout(searchTimer);
62
+ searchTimer = setTimeout(() => {
63
+ if (options.minQueryLength() > 0 && value.trim().length < options.minQueryLength()) return;
64
+ options.onSearch(value.trim());
65
+ runFetch(value.trim());
66
+ }, options.debounce());
67
+ }
68
+ /**
69
+ * Снять запланированный и летящий запрос. Инкремент `searchSeq` обязателен
70
+ * вместе со снятием `remoteLoading`: после него `finally` в `runFetch` считает
71
+ * себя устаревшим и флаг не тронет — спиннер остался бы навсегда.
72
+ */
73
+ function cancelSearch() {
74
+ if (searchTimer) clearTimeout(searchTimer);
75
+ searchTimer = null;
76
+ inflight?.abort();
77
+ inflight = null;
78
+ searchSeq += 1;
79
+ remoteLoading.value = false;
80
+ }
81
+ /**
82
+ * Подпись состава стартового списка. Сравнивать идентичность массива нельзя:
83
+ * инлайн-литерал `:options="[...]"` пересоздаётся каждым ререндером родителя —
84
+ * в том числе тем, который вызвал сам компонент своим `update:modelValue`, —
85
+ * и remote-результаты исчезали бы прямо посреди выбора.
86
+ */
87
+ function optionsSignature(list) {
88
+ return (list ?? []).map((o) => `${String(o.value)}\u0000${o.label}`).join("");
89
+ }
90
+ watch(() => optionsSignature(options.options()), () => {
91
+ if (!options.fetchOptions()) return;
92
+ cancelSearch();
93
+ remoteAnswered.value = false;
94
+ remoteOptions.value = [];
95
+ });
96
+ onBeforeUnmount(cancelSearch);
97
+ return {
98
+ remoteOptions,
99
+ remoteAnswered,
100
+ remoteLoading,
101
+ scheduleSearch,
102
+ cancelSearch
103
+ };
104
+ }
105
+ //#endregion
106
+ //#region src/components/GrAutocomplete/composables/useAutocompleteValues.ts
107
+ function useAutocompleteValues(options) {
108
+ const optionsResolved = computed(() => options.fetchOptions() && options.remoteAnswered.value ? options.remoteOptions.value : options.options() ?? []);
109
+ /** `0` — валидное значение, поэтому «пусто» проверяется явно, а не через falsy. */
110
+ function isEmptyValue(value) {
111
+ return value === void 0 || value === null || value === "";
112
+ }
113
+ function toArray(value) {
114
+ if (Array.isArray(value)) return value;
115
+ if (isEmptyValue(value)) return [];
116
+ return [value];
117
+ }
118
+ const modelSingle = computed(() => {
119
+ const model = options.modelValue();
120
+ const raw = Array.isArray(model) ? model[0] : model;
121
+ return isEmptyValue(raw) ? "" : raw;
122
+ });
123
+ const selectedValues = computed(() => options.multiple() ? toArray(options.modelValue()) : isEmptyValue(modelSingle.value) ? [] : [modelSingle.value]);
124
+ const hasSelection = computed(() => selectedValues.value.length > 0);
125
+ function labelFor(value) {
126
+ return optionsResolved.value.find((o) => o.value === value)?.label ?? String(value);
127
+ }
128
+ return {
129
+ optionsResolved,
130
+ isEmptyValue,
131
+ modelSingle,
132
+ selectedValues,
133
+ hasSelection,
134
+ labelFor,
135
+ selectedOptions: computed(() => resolveSelectedOptions(selectedValues.value, optionsResolved.value)),
136
+ singleSelectedLabel: computed(() => options.multiple() || isEmptyValue(modelSingle.value) ? "" : labelFor(modelSingle.value))
137
+ };
138
+ }
139
+ //#endregion
140
+ //#region src/components/GrAutocomplete/composables/useAutocompletePanel.ts
141
+ function useAutocompletePanel(options) {
142
+ const searchQuery = computed(() => {
143
+ if (!options.filterable() || options.fetchOptions()) return "";
144
+ if (!options.multiple() && !options.dirty.value) return "";
145
+ return options.query.value.trim();
146
+ });
147
+ const filteredOptions = computed(() => filterOptions(options.optionsResolved.value, searchQuery.value, options.filter()));
148
+ const belowMinQuery = computed(() => options.minQueryLength() > 0 && options.query.value.trim().length < options.minQueryLength());
149
+ /**
150
+ * Опции к показу и навигации. Ниже `minQueryLength` — пусто: список ещё
151
+ * относится к прошлому запросу, показывать его под подсказкой «введите ещё N»
152
+ * значит дезинформировать.
153
+ */
154
+ const effectiveOptions = computed(() => belowMinQuery.value ? [] : filteredOptions.value);
155
+ const canAddCustom = computed(() => {
156
+ if (!options.allowCustomValue()) return false;
157
+ const v = options.query.value.trim();
158
+ if (!v) return false;
159
+ if (options.multiple() && options.selectedValues.value.includes(v)) return false;
160
+ if (!options.multiple() && v === options.modelSingle.value) return false;
161
+ return !options.optionsResolved.value.some((o) => o.value === v || o.label === v);
162
+ });
163
+ return {
164
+ searchQuery,
165
+ belowMinQuery,
166
+ effectiveOptions,
167
+ canAddCustom,
168
+ showEmpty: computed(() => !options.isLoading.value && effectiveOptions.value.length === 0 && !canAddCustom.value)
169
+ };
170
+ }
171
+ //#endregion
172
+ //#region src/components/GrAutocomplete/composables/useAutocompleteVirtual.ts
173
+ /** Оценка высоты опции: `py-2` вокруг строки кегля `sm`. Уточняется замером. */
174
+ var OPTION_SIZE_ESTIMATE = 36;
175
+ function useAutocompleteVirtual(options) {
176
+ const addOffset = computed(() => options.canAddCustom.value ? 1 : 0);
177
+ const virtualCount = computed(() => options.effectiveOptions.value.length + addOffset.value);
178
+ const virtualizer = useVirtualList({
179
+ container: options.listboxEl,
180
+ count: () => options.virtual() ? virtualCount.value : 0,
181
+ source: () => options.effectiveOptions.value,
182
+ itemSize: OPTION_SIZE_ESTIMATE,
183
+ viewportSize: () => options.dropdownMaxHeight()
184
+ });
185
+ /** Виден ли «Add …»: вне виртуального окна его рисовать нельзя — он элемент набора. */
186
+ const showAddOption = computed(() => {
187
+ if (!options.canAddCustom.value) return false;
188
+ return !options.virtual() || virtualizer.range.value.start === 0;
189
+ });
190
+ /** Опции к отрисовке вместе с их абсолютным индексом в `effectiveOptions`. */
191
+ const renderedOptions = computed(() => {
192
+ const all = options.effectiveOptions.value;
193
+ if (!options.virtual()) return all.map((option, index) => ({
194
+ option,
195
+ index
196
+ }));
197
+ const { start, end } = virtualizer.range.value;
198
+ const from = Math.max(0, start - addOffset.value);
199
+ const to = Math.max(0, end - addOffset.value);
200
+ return all.slice(from, to).map((option, offset) => ({
201
+ option,
202
+ index: from + offset
203
+ }));
204
+ });
205
+ /**
206
+ * Размер набора и позиция в нём объявляются только при виртуализации: в обычном
207
+ * режиме диктор выводит их из DOM, а при неполном наборе получил бы «3 из 15»
208
+ * на списке в десять тысяч.
209
+ */
210
+ function optionSetProps(virtualIndex) {
211
+ if (!options.virtual()) return void 0;
212
+ return {
213
+ "aria-setsize": virtualCount.value,
214
+ "aria-posinset": virtualIndex + 1
215
+ };
216
+ }
217
+ return {
218
+ addOffset,
219
+ virtualCount,
220
+ virtualizer,
221
+ showAddOption,
222
+ renderedOptions,
223
+ optionSetProps,
224
+ listboxStyle: computed(() => {
225
+ const base = { maxHeight: `${options.dropdownMaxHeight()}px` };
226
+ if (!options.virtual()) return base;
227
+ return {
228
+ ...base,
229
+ ...virtualizer.spacerStyle.value
230
+ };
231
+ })
232
+ };
233
+ }
234
+ //#endregion
235
+ //#region src/components/GrAutocomplete/composables/useAutocompleteNavigation.ts
236
+ function useAutocompleteNavigation(options) {
237
+ const navigableItems = computed(() => {
238
+ const items = options.canAddCustom.value ? [{ kind: "add" }] : [];
239
+ options.effectiveOptions.value.forEach((option, index) => {
240
+ if (!option.disabled) items.push({
241
+ kind: "option",
242
+ option,
243
+ index
244
+ });
245
+ });
246
+ return items;
247
+ });
248
+ function isSelected(value) {
249
+ return options.selectedValues.value.includes(value);
250
+ }
251
+ function navigableIndexOf(value) {
252
+ return navigableItems.value.findIndex((item) => item.kind === "option" && item.option.value === value);
253
+ }
254
+ /** Прокрутка к активному: сперва окно виртуального списка, затем доводка. */
255
+ async function scrollActiveIntoView(item) {
256
+ if (options.virtual()) options.scrollToIndex(item.kind === "add" ? 0 : item.index + options.addOffset.value);
257
+ await nextTick();
258
+ const id = item.kind === "add" ? options.addOptionDomId.value : options.optionDomId(item.index);
259
+ document.getElementById(id)?.scrollIntoView?.({ block: "nearest" });
260
+ }
261
+ const { activeIndex, activeItem, activeDescendantId, init: initActiveIndex, reset: resetActive, handleNavigationKeys } = useComboboxNavigation({
262
+ items: () => navigableItems.value,
263
+ open: () => options.open.value,
264
+ idOf: (item) => item.kind === "add" ? options.addOptionDomId.value : options.optionDomId(item.index),
265
+ initialIndex: () => navigableItems.value.findIndex((item) => item.kind === "option" && isSelected(item.option.value)),
266
+ scrollTo: (item) => scrollActiveIntoView(item)
267
+ });
268
+ return {
269
+ navigableItems,
270
+ isSelected,
271
+ navigableIndexOf,
272
+ activeIndex,
273
+ activeItem,
274
+ activeDescendantId,
275
+ activeValue: computed(() => activeItem.value?.kind === "option" ? activeItem.value.option.value : void 0),
276
+ initActiveIndex,
277
+ resetActive,
278
+ handleNavigationKeys
279
+ };
280
+ }
281
+ //#endregion
282
+ //#region src/components/GrAutocomplete/GrAutocomplete.vue?vue&type=script&setup=true&lang.ts
28
283
  var _hoisted_1 = { class: "truncate" };
29
284
  var _hoisted_2 = [
30
285
  "id",
@@ -87,7 +342,6 @@ var _hoisted_15 = {
87
342
  key: 2,
88
343
  "data-gr-autocomplete-empty": ""
89
344
  };
90
- var OPTION_SIZE_ESTIMATE = 36;
91
345
  //#endregion
92
346
  //#region src/components/GrAutocomplete/GrAutocomplete.vue
93
347
  var GrAutocomplete_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineComponent({
@@ -225,47 +479,23 @@ var GrAutocomplete_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
225
479
  const { disabled: isDisabled, invalid: isInvalid, required: isRequired, readonly: isReadonly } = useGrFormControl(() => props);
226
480
  const describedBy = computed(() => field?.describedById.value);
227
481
  const locked = computed(() => isDisabled.value || isReadonly.value);
228
- const remoteOptions = shallowRef([]);
229
- const remoteAnswered = ref(false);
230
- const remoteLoading = ref(false);
231
- const optionsResolved = computed(() => props.fetchOptions && remoteAnswered.value ? remoteOptions.value : props.options ?? []);
232
- /**
233
- * Подпись состава стартового списка. Сравнивать идентичность массива нельзя:
234
- * инлайн-литерал `:options="[...]"` пересоздаётся каждым ререндером родителя —
235
- * в том числе тем, который вызвал сам компонент своим `update:modelValue`, —
236
- * и remote-результаты исчезали бы прямо посреди выбора.
237
- */
238
- function optionsSignature(options) {
239
- return (options ?? []).map((o) => `${String(o.value)}\u0000${o.label}`).join("");
240
- }
241
- watch(() => optionsSignature(props.options), () => {
242
- if (!props.fetchOptions) return;
243
- cancelSearch();
244
- remoteAnswered.value = false;
245
- remoteOptions.value = [];
482
+ const { remoteOptions, remoteAnswered, remoteLoading, scheduleSearch } = useRemoteOptions({
483
+ fetchOptions: () => props.fetchOptions,
484
+ options: () => props.options,
485
+ debounce: () => props.debounce,
486
+ minQueryLength: () => props.minQueryLength,
487
+ onSearch: (value) => emit("search", value),
488
+ onSearchError: (error) => emit("searchError", error)
246
489
  });
247
- const isLoading = computed(() => props.loading || remoteLoading.value);
248
- /** `0` валидное значение, поэтому «пусто» проверяется явно, а не через falsy. */
249
- function isEmptyValue(value) {
250
- return value === void 0 || value === null || value === "";
251
- }
252
- function toArray(value) {
253
- if (Array.isArray(value)) return value;
254
- if (isEmptyValue(value)) return [];
255
- return [value];
256
- }
257
- const modelSingle = computed(() => {
258
- const raw = Array.isArray(props.modelValue) ? props.modelValue[0] : props.modelValue;
259
- return isEmptyValue(raw) ? "" : raw;
490
+ const { optionsResolved, modelSingle, selectedValues, hasSelection, selectedOptions, singleSelectedLabel } = useAutocompleteValues({
491
+ modelValue: () => props.modelValue,
492
+ options: () => props.options,
493
+ multiple: () => props.multiple,
494
+ fetchOptions: () => props.fetchOptions,
495
+ remoteOptions,
496
+ remoteAnswered
260
497
  });
261
- const selectedValues = computed(() => props.multiple ? toArray(props.modelValue) : isEmptyValue(modelSingle.value) ? [] : [modelSingle.value]);
262
- const hasSelection = computed(() => selectedValues.value.length > 0);
263
- function labelFor(value) {
264
- return optionsResolved.value.find((o) => o.value === value)?.label ?? String(value);
265
- }
266
- /** Опции выбранных значений (для chips в multiple). Неизвестные значения показываем как есть. */
267
- const selectedOptions = computed(() => resolveSelectedOptions(selectedValues.value, optionsResolved.value));
268
- const singleSelectedLabel = computed(() => props.multiple || isEmptyValue(modelSingle.value) ? "" : labelFor(modelSingle.value));
498
+ const isLoading = computed(() => props.loading || remoteLoading.value);
269
499
  const query = ref("");
270
500
  const dirty = ref(false);
271
501
  const { open, setOpen } = useControlledOpen(() => props.open, (next) => emit("update:open", next));
@@ -297,28 +527,20 @@ var GrAutocomplete_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
297
527
  zIndexVar: "--gr-z-dropdown"
298
528
  });
299
529
  useDismissible(open, closeDropdown);
300
- const searchQuery = computed(() => {
301
- if (!props.filterable || props.fetchOptions) return "";
302
- if (!props.multiple && !dirty.value) return "";
303
- return query.value.trim();
530
+ const { belowMinQuery, effectiveOptions, canAddCustom, showEmpty } = useAutocompletePanel({
531
+ optionsResolved,
532
+ query,
533
+ dirty,
534
+ filterable: () => props.filterable,
535
+ filter: () => props.filter,
536
+ fetchOptions: () => props.fetchOptions,
537
+ multiple: () => props.multiple,
538
+ minQueryLength: () => props.minQueryLength,
539
+ allowCustomValue: () => props.allowCustomValue,
540
+ selectedValues,
541
+ modelSingle,
542
+ isLoading
304
543
  });
305
- const filteredOptions = computed(() => filterOptions(optionsResolved.value, searchQuery.value, props.filter));
306
- const belowMinQuery = computed(() => props.minQueryLength > 0 && query.value.trim().length < props.minQueryLength);
307
- /**
308
- * Опции к показу и навигации. Ниже `minQueryLength` — пусто: список ещё
309
- * относится к прошлому запросу, показывать его под подсказкой «введите ещё N»
310
- * значит дезинформировать.
311
- */
312
- const effectiveOptions = computed(() => belowMinQuery.value ? [] : filteredOptions.value);
313
- const canAddCustom = computed(() => {
314
- if (!props.allowCustomValue) return false;
315
- const v = query.value.trim();
316
- if (!v) return false;
317
- if (props.multiple && selectedValues.value.includes(v)) return false;
318
- if (!props.multiple && v === modelSingle.value) return false;
319
- return !optionsResolved.value.some((o) => o.value === v || o.label === v);
320
- });
321
- const showEmpty = computed(() => !isLoading.value && effectiveOptions.value.length === 0 && !canAddCustom.value);
322
544
  const listboxId = useId();
323
545
  /**
324
546
  * Id опции строится от позиции, а не от значения: значение с пробелом дало бы
@@ -329,100 +551,24 @@ var GrAutocomplete_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
329
551
  return `${listboxId}-opt-${index}`;
330
552
  }
331
553
  const addOptionDomId = computed(() => `${listboxId}-add`);
332
- /**
333
- * Виртуализация панели.
334
- *
335
- * Набор — `[«Add …»?] + filteredOptions`, тот же, по которому ходит клавиатура
336
- * (`navigableItems` ниже). Иначе верхняя распорка вытолкнула бы строку «Add …»
337
- * вниз: она отрисована внутри listbox'а первой и является полноценной опцией.
338
- */
339
- /** Оценка высоты опции: `py-2` вокруг строки кегля `sm`. Уточняется замером. */
340
- const addOffset = computed(() => canAddCustom.value ? 1 : 0);
341
- const virtualCount = computed(() => effectiveOptions.value.length + addOffset.value);
342
- const virtualizer = useVirtualList({
343
- container: listboxEl,
344
- count: () => props.virtual ? virtualCount.value : 0,
345
- source: () => effectiveOptions.value,
346
- itemSize: OPTION_SIZE_ESTIMATE,
347
- viewportSize: () => props.dropdownMaxHeight
348
- });
349
- /** Виден ли «Add …»: вне виртуального окна его рисовать нельзя — он элемент набора. */
350
- const showAddOption = computed(() => {
351
- if (!canAddCustom.value) return false;
352
- return !props.virtual || virtualizer.range.value.start === 0;
353
- });
354
- /** Опции к отрисовке вместе с их абсолютным индексом в `filteredOptions`. */
355
- const renderedOptions = computed(() => {
356
- const all = effectiveOptions.value;
357
- if (!props.virtual) return all.map((option, index) => ({
358
- option,
359
- index
360
- }));
361
- const { start, end } = virtualizer.range.value;
362
- const from = Math.max(0, start - addOffset.value);
363
- const to = Math.max(0, end - addOffset.value);
364
- return all.slice(from, to).map((option, offset) => ({
365
- option,
366
- index: from + offset
367
- }));
368
- });
369
- /**
370
- * Размер набора и позиция в нём объявляются только при виртуализации: в обычном
371
- * режиме диктор выводит их из DOM, а при неполном наборе получил бы «3 из 15»
372
- * на списке в десять тысяч.
373
- */
374
- function optionSetProps(virtualIndex) {
375
- if (!props.virtual) return void 0;
376
- return {
377
- "aria-setsize": virtualCount.value,
378
- "aria-posinset": virtualIndex + 1
379
- };
380
- }
381
- const listboxStyle = computed(() => {
382
- const base = { maxHeight: `${props.dropdownMaxHeight}px` };
383
- if (!props.virtual) return base;
384
- return {
385
- ...base,
386
- ...virtualizer.spacerStyle.value
387
- };
388
- });
389
- /**
390
- * Клавиатурная навигация ходит и по опциям, и по варианту «добавить своё»:
391
- * иначе при непустом списке Enter всегда уходил бы в активную опцию, и
392
- * закоммитить произвольное значение с клавиатуры было бы нечем.
393
- */
394
- const navigableItems = computed(() => {
395
- const items = canAddCustom.value ? [{ kind: "add" }] : [];
396
- effectiveOptions.value.forEach((option, index) => {
397
- if (!option.disabled) items.push({
398
- kind: "option",
399
- option,
400
- index
401
- });
402
- });
403
- return items;
554
+ const { addOffset, virtualizer, showAddOption, renderedOptions, optionSetProps, listboxStyle } = useAutocompleteVirtual({
555
+ listboxEl,
556
+ effectiveOptions,
557
+ canAddCustom,
558
+ virtual: () => props.virtual,
559
+ dropdownMaxHeight: () => props.dropdownMaxHeight
404
560
  });
405
- function isSelected(value) {
406
- return selectedValues.value.includes(value);
407
- }
408
- function navigableIndexOf(value) {
409
- return navigableItems.value.findIndex((item) => item.kind === "option" && item.option.value === value);
410
- }
411
- /** Прокрутка к активному: сперва окно виртуального списка, затем доводка. */
412
- async function scrollActiveIntoView(item) {
413
- if (props.virtual) virtualizer.scrollToIndex(item.kind === "add" ? 0 : item.index + addOffset.value);
414
- await nextTick();
415
- const id = item.kind === "add" ? addOptionDomId.value : optionDomId(item.index);
416
- document.getElementById(id)?.scrollIntoView?.({ block: "nearest" });
417
- }
418
- const { activeIndex, activeItem, activeDescendantId, init: initActiveIndex, reset: resetActive, handleNavigationKeys } = useComboboxNavigation({
419
- items: () => navigableItems.value,
420
- open: () => open.value,
421
- idOf: (item) => item.kind === "add" ? addOptionDomId.value : optionDomId(item.index),
422
- initialIndex: () => navigableItems.value.findIndex((item) => item.kind === "option" && isSelected(item.option.value)),
423
- scrollTo: (item) => scrollActiveIntoView(item)
561
+ const { isSelected, navigableIndexOf, activeIndex, activeItem, activeDescendantId, activeValue, initActiveIndex, resetActive, handleNavigationKeys } = useAutocompleteNavigation({
562
+ effectiveOptions,
563
+ canAddCustom,
564
+ selectedValues,
565
+ open,
566
+ virtual: () => props.virtual,
567
+ addOffset,
568
+ scrollToIndex: (index) => virtualizer.scrollToIndex(index),
569
+ optionDomId,
570
+ addOptionDomId
424
571
  });
425
- const activeValue = computed(() => activeItem.value?.kind === "option" ? activeItem.value.option.value : void 0);
426
572
  function openDropdown() {
427
573
  if (locked.value || open.value) return;
428
574
  setOpen(true);
@@ -433,56 +579,6 @@ var GrAutocomplete_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
433
579
  function focusInput() {
434
580
  inputEl.value?.focus();
435
581
  }
436
- let searchTimer = null;
437
- let searchSeq = 0;
438
- let inflight = null;
439
- function isAbortError(error) {
440
- return error instanceof Error && error.name === "AbortError";
441
- }
442
- async function runFetch(query) {
443
- const fetchOptions = props.fetchOptions;
444
- if (!fetchOptions) return;
445
- inflight?.abort();
446
- const controller = new AbortController();
447
- inflight = controller;
448
- const seq = ++searchSeq;
449
- remoteLoading.value = true;
450
- try {
451
- const result = await fetchOptions(query, controller.signal);
452
- if (seq !== searchSeq) return;
453
- remoteOptions.value = result;
454
- remoteAnswered.value = true;
455
- } catch (error) {
456
- if (seq !== searchSeq || isAbortError(error)) return;
457
- remoteOptions.value = [];
458
- remoteAnswered.value = true;
459
- emit("searchError", error);
460
- } finally {
461
- if (seq === searchSeq) remoteLoading.value = false;
462
- }
463
- }
464
- function scheduleSearch(value) {
465
- if (searchTimer) clearTimeout(searchTimer);
466
- searchTimer = setTimeout(() => {
467
- if (props.minQueryLength > 0 && value.trim().length < props.minQueryLength) return;
468
- emit("search", value.trim());
469
- runFetch(value.trim());
470
- }, props.debounce);
471
- }
472
- /**
473
- * Снять запланированный и летящий запрос. Инкремент `searchSeq` обязателен
474
- * вместе со снятием `remoteLoading`: после него `finally` в `runFetch` считает
475
- * себя устаревшим и флаг не тронет — спиннер остался бы навсегда.
476
- */
477
- function cancelSearch() {
478
- if (searchTimer) clearTimeout(searchTimer);
479
- searchTimer = null;
480
- inflight?.abort();
481
- inflight = null;
482
- searchSeq += 1;
483
- remoteLoading.value = false;
484
- }
485
- onBeforeUnmount(cancelSearch);
486
582
  function onInput(event) {
487
583
  const value = event.target.value;
488
584
  query.value = value;
@@ -666,7 +762,7 @@ var GrAutocomplete_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
666
762
  class: "inline-flex shrink-0 items-center justify-center text-[var(--gr-muted-fg)]",
667
763
  style: normalizeStyle(unref(prefixStyle))
668
764
  }, [renderSlot(_ctx.$slots, "prefix", {}, void 0, true)], 4)) : createCommentVNode("", true),
669
- __props.multiple ? (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(selectedOptions.value, (option, chipIndex) => {
765
+ __props.multiple ? (openBlock(true), createElementBlock(Fragment, { key: 1 }, renderList(unref(selectedOptions), (option, chipIndex) => {
670
766
  return openBlock(), createBlock(GrChip_default, {
671
767
  key: option.value,
672
768
  ref_for: true,
@@ -707,7 +803,7 @@ var GrAutocomplete_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
707
803
  role: "combobox",
708
804
  value: query.value,
709
805
  disabled: unref(isDisabled),
710
- placeholder: hasSelection.value && __props.multiple ? void 0 : __props.placeholder,
806
+ placeholder: unref(hasSelection) && __props.multiple ? void 0 : __props.placeholder,
711
807
  "aria-label": __props.ariaLabel,
712
808
  "aria-invalid": unref(isInvalid) ? "true" : void 0,
713
809
  "aria-describedby": describedBy.value,
@@ -751,7 +847,7 @@ var GrAutocomplete_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
751
847
  "aria-hidden": "true"
752
848
  })]))
753
849
  ], 34),
754
- __props.name ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(selectedValues.value, (value) => {
850
+ __props.name ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(unref(selectedValues), (value) => {
755
851
  return openBlock(), createElementBlock("input", {
756
852
  key: `hidden-${String(value)}`,
757
853
  type: "hidden",
@@ -778,7 +874,7 @@ var GrAutocomplete_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
778
874
  "data-gr-autocomplete-panel": "",
779
875
  "data-gr-overlay-root": "",
780
876
  style: unref(floatingStyle)
781
- }), [createElementVNode("div", { class: normalizeClass(unref(autocompletePanelClasses)) }, [showAddOption.value || renderedOptions.value.length ? (openBlock(), createElementBlock("div", {
877
+ }), [createElementVNode("div", { class: normalizeClass(unref(autocompletePanelClasses)) }, [unref(showAddOption) || unref(renderedOptions).length ? (openBlock(), createElementBlock("div", {
782
878
  key: 0,
783
879
  id: unref(listboxId),
784
880
  ref_key: "listboxEl",
@@ -786,17 +882,17 @@ var GrAutocomplete_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
786
882
  "data-gr-autocomplete-listbox": "",
787
883
  "data-gr-virtual": __props.virtual ? "" : void 0,
788
884
  class: normalizeClass(["p-1 overflow-auto", __props.virtual ? "flex flex-col" : ""]),
789
- style: normalizeStyle(listboxStyle.value),
885
+ style: normalizeStyle(unref(listboxStyle)),
790
886
  role: "listbox",
791
887
  "aria-multiselectable": __props.multiple ? "true" : void 0
792
- }, [showAddOption.value ? (openBlock(), createElementBlock("button", mergeProps({
888
+ }, [unref(showAddOption) ? (openBlock(), createElementBlock("button", mergeProps({
793
889
  key: 0,
794
890
  id: addOptionDomId.value,
795
891
  type: "button",
796
892
  role: "option",
797
893
  "aria-selected": "false",
798
894
  tabindex: "-1"
799
- }, optionSetProps(0), {
895
+ }, unref(optionSetProps)(0), {
800
896
  "data-testid": "gr-autocomplete-add-option",
801
897
  "data-gr-autocomplete-add-option": "",
802
898
  class: unref(autocompleteOptionClass)({
@@ -806,35 +902,35 @@ var GrAutocomplete_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
806
902
  onMousedown: _cache[0] || (_cache[0] = withModifiers(() => {}, ["prevent"])),
807
903
  onClick: commitCustom,
808
904
  onMousemove: _cache[1] || (_cache[1] = ($event) => activeIndex.value = 0)
809
- }), toDisplayString(unref(t)("gr.autocomplete.addOption", "Add \"{value}\"", { value: query.value.trim() })), 17, _hoisted_8)) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(renderedOptions.value, ({ option, index: optionIndex }) => {
905
+ }), toDisplayString(unref(t)("gr.autocomplete.addOption", "Add \"{value}\"", { value: query.value.trim() })), 17, _hoisted_8)) : createCommentVNode("", true), (openBlock(true), createElementBlock(Fragment, null, renderList(unref(renderedOptions), ({ option, index: optionIndex }) => {
810
906
  return openBlock(), createElementBlock("button", mergeProps({
811
907
  id: optionDomId(optionIndex),
812
908
  key: option.value,
813
909
  ref_for: true,
814
- ref: (el) => __props.virtual && unref(virtualizer).measure(optionIndex + addOffset.value, el),
910
+ ref: (el) => __props.virtual && unref(virtualizer).measure(optionIndex + unref(addOffset), el),
815
911
  "data-gr-autocomplete-option": "",
816
912
  type: "button",
817
913
  role: "option",
818
914
  tabindex: "-1"
819
- }, { ref_for: true }, optionSetProps(optionIndex + addOffset.value), {
915
+ }, { ref_for: true }, unref(optionSetProps)(optionIndex + unref(addOffset)), {
820
916
  disabled: option.disabled,
821
- "aria-selected": isSelected(option.value) ? "true" : "false",
917
+ "aria-selected": unref(isSelected)(option.value) ? "true" : "false",
822
918
  "aria-disabled": option.disabled ? "true" : void 0,
823
919
  class: unref(autocompleteOptionClass)({
824
920
  disabled: !!option.disabled,
825
- active: activeValue.value === option.value
921
+ active: unref(activeValue) === option.value
826
922
  }),
827
923
  onMousedown: _cache[2] || (_cache[2] = withModifiers(() => {}, ["prevent"])),
828
924
  onClick: ($event) => chooseOption(option),
829
- onMousemove: ($event) => activeIndex.value = navigableIndexOf(option.value)
925
+ onMousemove: ($event) => activeIndex.value = unref(navigableIndexOf)(option.value)
830
926
  }), [renderSlot(_ctx.$slots, "option", {
831
927
  option,
832
- selected: isSelected(option.value)
833
- }, () => [createElementVNode("span", _hoisted_10, [createElementVNode("span", _hoisted_11, [isSelected(option.value) ? (openBlock(), createBlock(unref(check_default), {
928
+ selected: unref(isSelected)(option.value)
929
+ }, () => [createElementVNode("span", _hoisted_10, [createElementVNode("span", _hoisted_11, [unref(isSelected)(option.value) ? (openBlock(), createBlock(unref(check_default), {
834
930
  key: 0,
835
931
  class: "block h-4 w-4 text-[var(--gr-primary-text)]"
836
932
  })) : createCommentVNode("", true)]), createElementVNode("span", _hoisted_12, toDisplayString(option.label), 1)])], true)], 16, _hoisted_9);
837
- }), 128))], 14, _hoisted_7)) : createCommentVNode("", true), isLoading.value || belowMinQuery.value || showEmpty.value ? (openBlock(), createElementBlock("div", {
933
+ }), 128))], 14, _hoisted_7)) : createCommentVNode("", true), isLoading.value || unref(belowMinQuery) || unref(showEmpty) ? (openBlock(), createElementBlock("div", {
838
934
  key: 1,
839
935
  "data-gr-autocomplete-status": "",
840
936
  role: "status",
@@ -843,7 +939,7 @@ var GrAutocomplete_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
843
939
  }, [isLoading.value ? (openBlock(), createElementBlock("span", _hoisted_13, [renderSlot(_ctx.$slots, "loading", {}, () => [createVNode(unref(loader_circle_default), {
844
940
  class: "block h-4 w-4 animate-spin",
845
941
  "aria-hidden": "true"
846
- }), createElementVNode("span", null, toDisplayString(resolvedLoadingText.value), 1)], true)])) : belowMinQuery.value ? (openBlock(), createElementBlock("span", _hoisted_14, toDisplayString(resolvedTypeMoreText.value), 1)) : (openBlock(), createElementBlock("span", _hoisted_15, [renderSlot(_ctx.$slots, "empty", {}, () => [createTextVNode(toDisplayString(resolvedNoResultsText.value), 1)], true)]))], 2)) : createCommentVNode("", true)], 2)], 16), [[vShow, unref(open)]])]),
942
+ }), createElementVNode("span", null, toDisplayString(resolvedLoadingText.value), 1)], true)])) : unref(belowMinQuery) ? (openBlock(), createElementBlock("span", _hoisted_14, toDisplayString(resolvedTypeMoreText.value), 1)) : (openBlock(), createElementBlock("span", _hoisted_15, [renderSlot(_ctx.$slots, "empty", {}, () => [createTextVNode(toDisplayString(resolvedNoResultsText.value), 1)], true)]))], 2)) : createCommentVNode("", true)], 2)], 16), [[vShow, unref(open)]])]),
847
943
  _: 3
848
944
  }, 8, [
849
945
  "enter-active-class",
@@ -860,6 +956,6 @@ var GrAutocomplete_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/*
860
956
  }]]);
861
957
  };
862
958
  }
863
- }), [["__scopeId", "data-v-34ca5aa5"]]);
959
+ }), [["__scopeId", "data-v-c4989846"]]);
864
960
  //#endregion
865
961
  export { GrAutocomplete_default as t };