@alfalab/core-components-select 19.1.10 → 19.2.0-alfasans

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 (257) hide show
  1. package/components/arrow/index.css +4 -4
  2. package/components/arrow/index.module.css.js +1 -1
  3. package/components/base-checkmark/index.css +9 -9
  4. package/components/base-checkmark/index.module.css.js +1 -1
  5. package/components/base-option/index.css +19 -17
  6. package/components/base-option/index.module.css.js +1 -1
  7. package/components/base-select/Component.js +36 -49
  8. package/components/base-select/Component.js.map +1 -1
  9. package/components/base-select/index.css +70 -20
  10. package/components/base-select/index.module.css.js +1 -1
  11. package/components/base-select/index.module.css.js.map +1 -1
  12. package/components/base-select/mobile.css +12 -11
  13. package/components/base-select/mobile.module.css.js +1 -1
  14. package/components/base-select/mobile.module.css.js.map +1 -1
  15. package/components/checkmark/index.css +11 -11
  16. package/components/checkmark/index.module.css.js +1 -1
  17. package/components/checkmark-mobile/index.css +6 -6
  18. package/components/checkmark-mobile/index.module.css.js +1 -1
  19. package/components/clear-button/index.css +4 -4
  20. package/components/clear-button/index.module.css.js +1 -1
  21. package/components/field/index.css +22 -18
  22. package/components/field/index.module.css.js +1 -1
  23. package/components/footer/index.css +4 -4
  24. package/components/footer/index.module.css.js +1 -1
  25. package/components/optgroup/index.css +8 -7
  26. package/components/optgroup/index.module.css.js +1 -1
  27. package/components/option/desktop/index.css +28 -22
  28. package/components/option/desktop/index.module.css.js +1 -1
  29. package/components/option/desktop/index.module.css.js.map +1 -1
  30. package/components/option/mobile/index.css +25 -19
  31. package/components/option/mobile/index.module.css.js +1 -1
  32. package/components/option/mobile/index.module.css.js.map +1 -1
  33. package/components/options-list/Component.d.ts +4 -0
  34. package/components/options-list/Component.js +32 -53
  35. package/components/options-list/Component.js.map +1 -1
  36. package/components/options-list/index.css +13 -33
  37. package/components/options-list/index.module.css.js +1 -1
  38. package/components/options-list/index.module.css.js.map +1 -1
  39. package/components/search/index.css +1 -1
  40. package/components/search/index.module.css.js +1 -1
  41. package/components/virtual-options-list/Component.d.ts +4 -0
  42. package/components/virtual-options-list/Component.js +61 -48
  43. package/components/virtual-options-list/Component.js.map +1 -1
  44. package/cssm/components/base-option/index.module.css +5 -3
  45. package/cssm/components/base-select/Component.js +36 -49
  46. package/cssm/components/base-select/Component.js.map +1 -1
  47. package/cssm/components/base-select/index.module.css +61 -11
  48. package/cssm/components/base-select/mobile.module.css +1 -0
  49. package/cssm/components/field/index.module.css +9 -5
  50. package/cssm/components/optgroup/index.module.css +4 -3
  51. package/cssm/components/option/desktop/index.module.css +9 -3
  52. package/cssm/components/option/mobile/index.module.css +9 -3
  53. package/cssm/components/options-list/Component.d.ts +4 -0
  54. package/cssm/components/options-list/Component.js +32 -53
  55. package/cssm/components/options-list/Component.js.map +1 -1
  56. package/cssm/components/options-list/index.module.css +6 -26
  57. package/cssm/components/virtual-options-list/Component.d.ts +4 -0
  58. package/cssm/components/virtual-options-list/Component.js +61 -48
  59. package/cssm/components/virtual-options-list/Component.js.map +1 -1
  60. package/cssm/presets/useSelectWithApply/hook.d.ts +12 -0
  61. package/cssm/presets/useSelectWithApply/options-list-with-apply/Component.d.ts +4 -0
  62. package/cssm/presets/useSelectWithApply/options-list-with-apply/footer/index.module.css +0 -5
  63. package/cssm/presets/useSelectWithApply/options-list-with-apply/header/index.module.css +9 -6
  64. package/cssm/shared/index.js +0 -1
  65. package/cssm/shared/index.js.map +1 -1
  66. package/cssm/typings.d.ts +21 -1
  67. package/cssm/utils.d.ts +1 -6
  68. package/cssm/utils.js +19 -28
  69. package/cssm/utils.js.map +1 -1
  70. package/esm/components/arrow/index.css +4 -4
  71. package/esm/components/arrow/index.module.css.js +1 -1
  72. package/esm/components/base-checkmark/index.css +9 -9
  73. package/esm/components/base-checkmark/index.module.css.js +1 -1
  74. package/esm/components/base-option/index.css +19 -17
  75. package/esm/components/base-option/index.module.css.js +1 -1
  76. package/esm/components/base-select/Component.js +37 -50
  77. package/esm/components/base-select/Component.js.map +1 -1
  78. package/esm/components/base-select/index.css +70 -20
  79. package/esm/components/base-select/index.module.css.js +1 -1
  80. package/esm/components/base-select/index.module.css.js.map +1 -1
  81. package/esm/components/base-select/mobile.css +12 -11
  82. package/esm/components/base-select/mobile.module.css.js +1 -1
  83. package/esm/components/base-select/mobile.module.css.js.map +1 -1
  84. package/esm/components/checkmark/index.css +11 -11
  85. package/esm/components/checkmark/index.module.css.js +1 -1
  86. package/esm/components/checkmark-mobile/index.css +6 -6
  87. package/esm/components/checkmark-mobile/index.module.css.js +1 -1
  88. package/esm/components/clear-button/index.css +4 -4
  89. package/esm/components/clear-button/index.module.css.js +1 -1
  90. package/esm/components/field/index.css +22 -18
  91. package/esm/components/field/index.module.css.js +1 -1
  92. package/esm/components/footer/index.css +4 -4
  93. package/esm/components/footer/index.module.css.js +1 -1
  94. package/esm/components/optgroup/index.css +8 -7
  95. package/esm/components/optgroup/index.module.css.js +1 -1
  96. package/esm/components/option/desktop/index.css +28 -22
  97. package/esm/components/option/desktop/index.module.css.js +1 -1
  98. package/esm/components/option/desktop/index.module.css.js.map +1 -1
  99. package/esm/components/option/mobile/index.css +25 -19
  100. package/esm/components/option/mobile/index.module.css.js +1 -1
  101. package/esm/components/option/mobile/index.module.css.js.map +1 -1
  102. package/esm/components/options-list/Component.d.ts +4 -0
  103. package/esm/components/options-list/Component.js +33 -54
  104. package/esm/components/options-list/Component.js.map +1 -1
  105. package/esm/components/options-list/index.css +13 -33
  106. package/esm/components/options-list/index.module.css.js +1 -1
  107. package/esm/components/options-list/index.module.css.js.map +1 -1
  108. package/esm/components/search/index.css +1 -1
  109. package/esm/components/search/index.module.css.js +1 -1
  110. package/esm/components/virtual-options-list/Component.d.ts +4 -0
  111. package/esm/components/virtual-options-list/Component.js +63 -49
  112. package/esm/components/virtual-options-list/Component.js.map +1 -1
  113. package/esm/mobile/modal.mobile.css +1 -1
  114. package/esm/mobile/modal.mobile.module.css.js +1 -1
  115. package/esm/presets/useSelectWithApply/hook.d.ts +12 -0
  116. package/esm/presets/useSelectWithApply/options-list-with-apply/Component.d.ts +4 -0
  117. package/esm/presets/useSelectWithApply/options-list-with-apply/footer/index.css +2 -7
  118. package/esm/presets/useSelectWithApply/options-list-with-apply/footer/index.module.css.js +1 -1
  119. package/esm/presets/useSelectWithApply/options-list-with-apply/footer/index.module.css.js.map +1 -1
  120. package/esm/presets/useSelectWithApply/options-list-with-apply/header/index.css +12 -9
  121. package/esm/presets/useSelectWithApply/options-list-with-apply/header/index.module.css.js +1 -1
  122. package/esm/presets/useSelectWithApply/options-list-with-apply/header/index.module.css.js.map +1 -1
  123. package/esm/presets/useSelectWithLoading/index.css +1 -1
  124. package/esm/presets/useSelectWithLoading/index.module.css.js +1 -1
  125. package/esm/shared/index.js +1 -1
  126. package/esm/typings.d.ts +21 -1
  127. package/esm/utils.d.ts +1 -6
  128. package/esm/utils.js +21 -29
  129. package/esm/utils.js.map +1 -1
  130. package/mobile/modal.mobile.css +1 -1
  131. package/mobile/modal.mobile.module.css.js +1 -1
  132. package/modern/components/arrow/index.css +4 -4
  133. package/modern/components/arrow/index.module.css.js +1 -1
  134. package/modern/components/base-checkmark/index.css +9 -9
  135. package/modern/components/base-checkmark/index.module.css.js +1 -1
  136. package/modern/components/base-option/index.css +19 -17
  137. package/modern/components/base-option/index.module.css.js +1 -1
  138. package/modern/components/base-select/Component.js +34 -47
  139. package/modern/components/base-select/Component.js.map +1 -1
  140. package/modern/components/base-select/index.css +70 -20
  141. package/modern/components/base-select/index.module.css.js +1 -1
  142. package/modern/components/base-select/index.module.css.js.map +1 -1
  143. package/modern/components/base-select/mobile.css +12 -11
  144. package/modern/components/base-select/mobile.module.css.js +1 -1
  145. package/modern/components/base-select/mobile.module.css.js.map +1 -1
  146. package/modern/components/checkmark/index.css +11 -11
  147. package/modern/components/checkmark/index.module.css.js +1 -1
  148. package/modern/components/checkmark-mobile/index.css +6 -6
  149. package/modern/components/checkmark-mobile/index.module.css.js +1 -1
  150. package/modern/components/clear-button/index.css +4 -4
  151. package/modern/components/clear-button/index.module.css.js +1 -1
  152. package/modern/components/field/index.css +22 -18
  153. package/modern/components/field/index.module.css.js +1 -1
  154. package/modern/components/footer/index.css +4 -4
  155. package/modern/components/footer/index.module.css.js +1 -1
  156. package/modern/components/optgroup/index.css +8 -7
  157. package/modern/components/optgroup/index.module.css.js +1 -1
  158. package/modern/components/option/desktop/index.css +28 -22
  159. package/modern/components/option/desktop/index.module.css.js +1 -1
  160. package/modern/components/option/desktop/index.module.css.js.map +1 -1
  161. package/modern/components/option/mobile/index.css +25 -19
  162. package/modern/components/option/mobile/index.module.css.js +1 -1
  163. package/modern/components/option/mobile/index.module.css.js.map +1 -1
  164. package/modern/components/options-list/Component.d.ts +4 -0
  165. package/modern/components/options-list/Component.js +29 -49
  166. package/modern/components/options-list/Component.js.map +1 -1
  167. package/modern/components/options-list/index.css +13 -33
  168. package/modern/components/options-list/index.module.css.js +1 -1
  169. package/modern/components/options-list/index.module.css.js.map +1 -1
  170. package/modern/components/search/index.css +1 -1
  171. package/modern/components/search/index.module.css.js +1 -1
  172. package/modern/components/virtual-options-list/Component.d.ts +4 -0
  173. package/modern/components/virtual-options-list/Component.js +59 -45
  174. package/modern/components/virtual-options-list/Component.js.map +1 -1
  175. package/modern/mobile/modal.mobile.css +1 -1
  176. package/modern/mobile/modal.mobile.module.css.js +1 -1
  177. package/modern/presets/useSelectWithApply/hook.d.ts +12 -0
  178. package/modern/presets/useSelectWithApply/options-list-with-apply/Component.d.ts +4 -0
  179. package/modern/presets/useSelectWithApply/options-list-with-apply/footer/index.css +2 -7
  180. package/modern/presets/useSelectWithApply/options-list-with-apply/footer/index.module.css.js +1 -1
  181. package/modern/presets/useSelectWithApply/options-list-with-apply/footer/index.module.css.js.map +1 -1
  182. package/modern/presets/useSelectWithApply/options-list-with-apply/header/index.css +12 -9
  183. package/modern/presets/useSelectWithApply/options-list-with-apply/header/index.module.css.js +1 -1
  184. package/modern/presets/useSelectWithApply/options-list-with-apply/header/index.module.css.js.map +1 -1
  185. package/modern/presets/useSelectWithLoading/index.css +1 -1
  186. package/modern/presets/useSelectWithLoading/index.module.css.js +1 -1
  187. package/modern/shared/index.js +1 -1
  188. package/modern/typings.d.ts +21 -1
  189. package/modern/utils.d.ts +1 -6
  190. package/modern/utils.js +21 -29
  191. package/modern/utils.js.map +1 -1
  192. package/moderncssm/components/base-option/index.module.css +2 -1
  193. package/moderncssm/components/base-select/Component.js +34 -47
  194. package/moderncssm/components/base-select/Component.js.map +1 -1
  195. package/moderncssm/components/base-select/index.module.css +67 -9
  196. package/moderncssm/components/base-select/mobile.module.css +1 -0
  197. package/moderncssm/components/field/index.module.css +6 -3
  198. package/moderncssm/components/optgroup/index.module.css +1 -1
  199. package/moderncssm/components/option/desktop/index.module.css +5 -1
  200. package/moderncssm/components/option/mobile/index.module.css +5 -1
  201. package/moderncssm/components/options-list/Component.d.ts +4 -0
  202. package/moderncssm/components/options-list/Component.js +29 -49
  203. package/moderncssm/components/options-list/Component.js.map +1 -1
  204. package/moderncssm/components/options-list/index.module.css +7 -32
  205. package/moderncssm/components/virtual-options-list/Component.d.ts +4 -0
  206. package/moderncssm/components/virtual-options-list/Component.js +59 -45
  207. package/moderncssm/components/virtual-options-list/Component.js.map +1 -1
  208. package/moderncssm/presets/useSelectWithApply/hook.d.ts +12 -0
  209. package/moderncssm/presets/useSelectWithApply/options-list-with-apply/Component.d.ts +4 -0
  210. package/moderncssm/presets/useSelectWithApply/options-list-with-apply/footer/index.module.css +0 -4
  211. package/moderncssm/presets/useSelectWithApply/options-list-with-apply/header/index.module.css +8 -6
  212. package/moderncssm/shared/index.js +1 -1
  213. package/moderncssm/typings.d.ts +21 -1
  214. package/moderncssm/utils.d.ts +1 -6
  215. package/moderncssm/utils.js +21 -29
  216. package/moderncssm/utils.js.map +1 -1
  217. package/package.json +15 -16
  218. package/presets/useSelectWithApply/hook.d.ts +12 -0
  219. package/presets/useSelectWithApply/options-list-with-apply/Component.d.ts +4 -0
  220. package/presets/useSelectWithApply/options-list-with-apply/footer/index.css +2 -7
  221. package/presets/useSelectWithApply/options-list-with-apply/footer/index.module.css.js +1 -1
  222. package/presets/useSelectWithApply/options-list-with-apply/footer/index.module.css.js.map +1 -1
  223. package/presets/useSelectWithApply/options-list-with-apply/header/index.css +12 -9
  224. package/presets/useSelectWithApply/options-list-with-apply/header/index.module.css.js +1 -1
  225. package/presets/useSelectWithApply/options-list-with-apply/header/index.module.css.js.map +1 -1
  226. package/presets/useSelectWithLoading/index.css +1 -1
  227. package/presets/useSelectWithLoading/index.module.css.js +1 -1
  228. package/shared/index.js +0 -1
  229. package/shared/index.js.map +1 -1
  230. package/src/components/base-select/Component.tsx +41 -55
  231. package/src/components/base-select/index.module.css +60 -8
  232. package/src/components/base-select/mobile.module.css +1 -0
  233. package/src/components/option/index.module.css +4 -0
  234. package/src/components/options-list/Component.tsx +54 -97
  235. package/src/components/options-list/index.module.css +7 -31
  236. package/src/components/virtual-options-list/Component.tsx +95 -72
  237. package/src/presets/useSelectWithApply/options-list-with-apply/footer/index.module.css +0 -4
  238. package/src/presets/useSelectWithApply/options-list-with-apply/header/index.module.css +4 -4
  239. package/src/typings.ts +26 -0
  240. package/src/utils.ts +30 -34
  241. package/src/vars.css +3 -0
  242. package/typings.d.ts +21 -1
  243. package/utils.d.ts +1 -6
  244. package/utils.js +19 -28
  245. package/utils.js.map +1 -1
  246. package/components/virtual-options-list/index.css +0 -83
  247. package/components/virtual-options-list/index.module.css.js +0 -8
  248. package/components/virtual-options-list/index.module.css.js.map +0 -1
  249. package/cssm/components/virtual-options-list/index.module.css +0 -83
  250. package/esm/components/virtual-options-list/index.css +0 -83
  251. package/esm/components/virtual-options-list/index.module.css.js +0 -6
  252. package/esm/components/virtual-options-list/index.module.css.js.map +0 -1
  253. package/modern/components/virtual-options-list/index.css +0 -83
  254. package/modern/components/virtual-options-list/index.module.css.js +0 -6
  255. package/modern/components/virtual-options-list/index.module.css.js.map +0 -1
  256. package/moderncssm/components/virtual-options-list/index.module.css +0 -81
  257. package/src/components/virtual-options-list/index.module.css +0 -77
@@ -1,5 +1,5 @@
1
1
  import { useState, isValidElement, cloneElement, useRef, useEffect } from 'react';
2
- import { useIsMounted, fnUtils, getDataTestId } from '@alfalab/core-components-shared/moderncssm';
2
+ import { useIsMounted, getElementWindow, fnUtils, getDataTestId } from '@alfalab/core-components-shared/moderncssm';
3
3
  import { useLayoutEffect_SAFE_FOR_SSR } from '@alfalab/hooks';
4
4
  import { DEFAULT_SEPARATOR } from './consts.js';
5
5
 
@@ -71,21 +71,21 @@ function processOptions(options, selected = [], filterFn = () => true, filterGro
71
71
  return { filteredOptions, flatOptions, selectedOptions };
72
72
  }
73
73
  // copy-paste of original `useVisibleOptions` before https://github.com/core-ds/core-components/pull/1368
74
- function useVirtualVisibleOptions({ visibleOptions, listRef, styleTargetRef = listRef, open, invalidate, options, size, actualOptionsCount, }) {
75
- useEffect(() => {
74
+ function useVirtualVisibleOptions({ visibleOptions, listRef, open, invalidate, options, size, actualOptionsCount, }) {
75
+ const [height, setHeight] = useState();
76
+ useLayoutEffect_SAFE_FOR_SSR(() => {
76
77
  const measureOptionHeight = (element) => typeof size === 'number' ? Math.min(element.clientHeight, size) : element.clientHeight;
77
78
  const list = listRef.current;
78
- const styleTarget = styleTargetRef.current;
79
- if (open && list && styleTarget && visibleOptions > 0) {
79
+ if (open && list && visibleOptions > 0) {
80
80
  const childCount = list.children.length;
81
81
  const optionsNodes = [].slice.call(list.children, 0, visibleOptions + 1);
82
- let height = optionsNodes
82
+ let nextHeight = optionsNodes
83
83
  .slice(0, visibleOptions)
84
84
  .reduce((acc, child) => acc + measureOptionHeight(child), 0);
85
85
  if (visibleOptions < childCount) {
86
86
  const lastVisibleOptionHeight = measureOptionHeight(optionsNodes[optionsNodes.length - 1]);
87
87
  // Если кол-во опций больше visibleOptions на 1, то показываем все опции, иначе добавляем половинку
88
- height += Math.round(childCount - visibleOptions === 1
88
+ nextHeight += Math.round(childCount - visibleOptions === 1
89
89
  ? lastVisibleOptionHeight
90
90
  : lastVisibleOptionHeight / 2);
91
91
  }
@@ -93,24 +93,20 @@ function useVirtualVisibleOptions({ visibleOptions, listRef, styleTargetRef = li
93
93
  actualOptionsCount &&
94
94
  typeof size === 'number') {
95
95
  const actualCount = (options ?? []).reduce((sum, option) => sum + 1 + (isGroup(option) ? option.options.length : 0), 0);
96
- height =
96
+ nextHeight =
97
97
  Math.min(actualCount === 0 ? /** empty placeholder */ 1 : actualCount, visibleOptions) * size;
98
98
  if (visibleOptions < actualCount) {
99
- height += size / 2;
99
+ nextHeight += size / 2;
100
100
  }
101
101
  }
102
- styleTarget.style.height = `${height}px`;
102
+ const win = getElementWindow(list);
103
+ nextHeight += ['::before', '::after']
104
+ .map((pseudo) => parseFloat(win.getComputedStyle(list, pseudo).paddingTop) || 0)
105
+ .reduce((a, b) => a + b);
106
+ setHeight(nextHeight);
103
107
  }
104
- }, [
105
- actualOptionsCount,
106
- listRef,
107
- open,
108
- options,
109
- size,
110
- styleTargetRef,
111
- visibleOptions,
112
- invalidate,
113
- ]);
108
+ }, [actualOptionsCount, listRef, open, options, size, visibleOptions, invalidate]);
109
+ return height;
114
110
  }
115
111
  function useVisibleOptions({ visibleOptions, listRef, open, options, size, actualOptionsCount, }) {
116
112
  const [, runIfMounted] = useIsMounted();
@@ -142,6 +138,10 @@ function useVisibleOptions({ visibleOptions, listRef, open, options, size, actua
142
138
  measuredHeight += size / 2;
143
139
  }
144
140
  }
141
+ const win = getElementWindow(list);
142
+ measuredHeight += ['::before', '::after']
143
+ .map((pseudo) => parseFloat(win.getComputedStyle(list, pseudo).paddingTop) || 0)
144
+ .reduce((a, b) => a + b);
145
145
  setHeight(measuredHeight);
146
146
  setMeasured(true);
147
147
  return () => {
@@ -175,14 +175,6 @@ function usePrevious(value) {
175
175
  }, [value]);
176
176
  return ref.current;
177
177
  }
178
- // TODO: перенести
179
- const lastIndexOf = (array, predicate) => {
180
- for (let i = array.length - 1; i >= 0; i--) {
181
- if (predicate(array[i]))
182
- return i;
183
- }
184
- return -1;
185
- };
186
178
  function getSelectTestIds(dataTestId) {
187
179
  return {
188
180
  select: dataTestId,
@@ -213,5 +205,5 @@ function getSelectTestIds(dataTestId) {
213
205
  };
214
206
  }
215
207
 
216
- export { defaultAccessor, defaultFilterFn, defaultGroupAccessor, getSelectTestIds, isGroup, isOptionShape, joinOptions, lastIndexOf, processOptions, usePrevious, useVirtualVisibleOptions, useVisibleOptions };
208
+ export { defaultAccessor, defaultFilterFn, defaultGroupAccessor, getSelectTestIds, isGroup, isOptionShape, joinOptions, processOptions, usePrevious, useVirtualVisibleOptions, useVisibleOptions };
217
209
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../src/utils.ts"],"sourcesContent":["import {\n cloneElement,\n isValidElement,\n type ReactNode,\n type RefObject,\n useEffect,\n useRef,\n useState,\n} from 'react';\n\nimport { fnUtils, getDataTestId, useIsMounted } from '@alfalab/core-components-shared';\nimport { useLayoutEffect_SAFE_FOR_SSR } from '@alfalab/hooks';\n\nimport { DEFAULT_SEPARATOR } from './consts';\nimport {\n type BaseSelectProps,\n type GroupShape,\n type OptionShape,\n type OptionsListProps,\n} from './typings';\n\nexport const isGroup = (item: OptionShape | GroupShape): item is GroupShape =>\n Object.prototype.hasOwnProperty.call(item, 'options');\n\nexport const isOptionShape = (item: OptionShape | string | null): item is OptionShape =>\n !!item && Object.prototype.hasOwnProperty.call(item, 'key');\n\nexport const joinOptions = ({\n selected,\n selectedMultiple,\n valueSeparator = DEFAULT_SEPARATOR,\n}: {\n selected?: OptionShape;\n selectedMultiple?: OptionShape[];\n valueSeparator?: string;\n}) => {\n const options = selectedMultiple || (selected ? [selected] : []);\n\n if (!options.length) return null;\n\n return options.reduce((acc: Array<ReactNode | string>, option: OptionShape, index: number) => {\n if (isValidElement(option.content)) {\n acc.push(cloneElement(option.content, { key: option.key }));\n } else {\n acc.push(option.content);\n }\n\n if (index < options.length - 1) acc.push(valueSeparator);\n\n return acc;\n }, []);\n};\n\n// За один проход делает список пунктов меню плоским и находит выбранные пункты по ключу\nexport function processOptions(\n options: BaseSelectProps['options'],\n selected: BaseSelectProps['selected'] = [],\n filterFn: (option: OptionShape | GroupShape) => boolean = () => true,\n filterGroup = false,\n) {\n const flatOptions: OptionShape[] = [];\n const filteredOptions: BaseSelectProps['options'] = [];\n\n const selectedArray = Array.isArray(selected) ? selected : [selected];\n const selectedOptions = selectedArray.filter(isOptionShape);\n const selectedKeys = selectedArray.filter(\n (option): option is string => typeof option === 'string',\n );\n\n const isSelected = (option: OptionShape) => selectedKeys.includes(option.key);\n\n const process = (option: OptionShape | GroupShape) => {\n const isGroupOption = isGroup(option);\n\n if (!isGroupOption && isSelected(option)) {\n selectedOptions.push(option);\n }\n\n if (!filterFn(option)) return false;\n\n if (isGroupOption) {\n if (filterGroup) {\n Array.prototype.push.apply(flatOptions, option.options);\n }\n } else {\n flatOptions.push(option);\n }\n\n return true;\n };\n\n options.forEach((option) => {\n if (isGroup(option)) {\n const group: GroupShape = {\n ...option,\n options: [],\n };\n\n option.options.forEach((groupOption) => {\n const matched = process(groupOption);\n\n if (matched) group.options.push(groupOption);\n });\n\n if (group.options.length) {\n filteredOptions.push(group);\n\n return;\n }\n\n if (!filterGroup) return;\n }\n const matched = process(option);\n\n if (matched) filteredOptions.push(option);\n });\n\n return { filteredOptions, flatOptions, selectedOptions };\n}\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\ntype useVisibleOptionsArgs = {\n /**\n * Количество видимых пунктов\n */\n visibleOptions: number;\n\n /**\n * Реф на контейнер с пунтами меню\n */\n listRef: RefObject<HTMLElement>;\n\n /**\n * Реф на контейнер, которому нужно установить высоту\n */\n styleTargetRef?: RefObject<HTMLElement>;\n\n /**\n * Флаг открытия меню\n */\n open?: boolean;\n\n /**\n * Позволяет вызвать пересчет высоты\n */\n invalidate?: unknown;\n\n /**\n * Список вариантов выбора\n */\n options?: Array<OptionShape | GroupShape>;\n\n /**\n * Максимальный размер варианта выбора\n */\n size?: Extract<OptionsListProps['size'], number>;\n\n /**\n * Учитывать действительное число вариантов выбора\n */\n actualOptionsCount?: boolean;\n};\n\n// copy-paste of original `useVisibleOptions` before https://github.com/core-ds/core-components/pull/1368\nexport function useVirtualVisibleOptions({\n visibleOptions,\n listRef,\n styleTargetRef = listRef,\n open,\n invalidate,\n options,\n size,\n actualOptionsCount,\n}: useVisibleOptionsArgs) {\n useEffect(() => {\n const measureOptionHeight = (element: HTMLElement) =>\n typeof size === 'number' ? Math.min(element.clientHeight, size) : element.clientHeight;\n\n const list = listRef.current;\n const styleTarget = styleTargetRef.current;\n\n if (open && list && styleTarget && visibleOptions > 0) {\n const childCount = list.children.length;\n const optionsNodes = ([] as HTMLElement[]).slice.call(\n list.children,\n 0,\n visibleOptions + 1,\n );\n\n let height = optionsNodes\n .slice(0, visibleOptions)\n .reduce((acc, child) => acc + measureOptionHeight(child), 0);\n\n if (visibleOptions < childCount) {\n const lastVisibleOptionHeight = measureOptionHeight(\n optionsNodes[optionsNodes.length - 1],\n );\n\n // Если кол-во опций больше visibleOptions на 1, то показываем все опции, иначе добавляем половинку\n height += Math.round(\n childCount - visibleOptions === 1\n ? lastVisibleOptionHeight\n : lastVisibleOptionHeight / 2,\n );\n } else if (\n visibleOptions > childCount &&\n actualOptionsCount &&\n typeof size === 'number'\n ) {\n const actualCount = (options ?? []).reduce(\n (sum, option) => sum + 1 + (isGroup(option) ? option.options.length : 0),\n 0,\n );\n\n height =\n Math.min(\n actualCount === 0 ? /** empty placeholder */ 1 : actualCount,\n visibleOptions,\n ) * size;\n\n if (visibleOptions < actualCount) {\n height += size / 2;\n }\n }\n\n styleTarget.style.height = `${height}px`;\n }\n }, [\n actualOptionsCount,\n listRef,\n open,\n options,\n size,\n styleTargetRef,\n visibleOptions,\n invalidate,\n ]);\n}\n\nexport function useVisibleOptions({\n visibleOptions,\n listRef,\n open,\n options,\n size,\n actualOptionsCount,\n}: useVisibleOptionsArgs) {\n const [, runIfMounted] = useIsMounted();\n const [measured, setMeasured] = useState(false);\n const [height, setHeight] = useState<number | undefined>();\n\n useLayoutEffect_SAFE_FOR_SSR(() => {\n const measureOptionHeight = (element: HTMLElement) =>\n typeof size === 'number' ? Math.min(element.clientHeight, size) : element.clientHeight;\n\n const list = listRef.current;\n\n if (open && list && visibleOptions > 0) {\n const childCount = list.children.length;\n const optionsNodes = ([] as HTMLElement[]).slice.call(\n list.children,\n 0,\n visibleOptions + 1,\n );\n\n let measuredHeight = optionsNodes\n .slice(0, visibleOptions)\n .reduce((acc, child) => acc + measureOptionHeight(child), 0);\n\n if (visibleOptions < childCount) {\n const lastVisibleOptionHeight = measureOptionHeight(\n optionsNodes[optionsNodes.length - 1],\n );\n\n // Если кол-во опций больше visibleOptions на 1, то показываем все опции, иначе добавляем половинку\n measuredHeight += Math.round(\n childCount - visibleOptions === 1\n ? lastVisibleOptionHeight\n : lastVisibleOptionHeight / 2,\n );\n } else if (\n visibleOptions > childCount &&\n actualOptionsCount &&\n typeof size === 'number'\n ) {\n const actualCount = (options ?? []).reduce(\n (sum, option) => sum + 1 + (isGroup(option) ? option.options.length : 0),\n 0,\n );\n\n measuredHeight =\n Math.min(\n actualCount === 0 ? /** empty placeholder */ 1 : actualCount,\n visibleOptions,\n ) * size;\n\n if (visibleOptions < actualCount) {\n measuredHeight += size / 2;\n }\n }\n\n setHeight(measuredHeight);\n\n setMeasured(true);\n\n return () => {\n runIfMounted(() => setMeasured(false));\n };\n }\n\n return fnUtils.noop;\n }, [actualOptionsCount, listRef, open, options, size, visibleOptions, runIfMounted]);\n\n return [measured, height] as const;\n}\n\nexport function defaultFilterFn(optionText: string, search: string) {\n if (!search) return true;\n\n return optionText.toLowerCase().includes(search.toLowerCase());\n}\n\nexport function defaultGroupAccessor(option: GroupShape) {\n return option.label;\n}\n\nexport function defaultAccessor(option: OptionShape) {\n if (typeof option.content === 'string') return option.content;\n if (typeof option.value === 'string') return option.value;\n\n return option.key;\n}\n\n// TODO: перенести\nexport function usePrevious<T>(value: T) {\n const ref = useRef<T>();\n\n useEffect(() => {\n ref.current = value;\n }, [value]);\n\n return ref.current;\n}\n\n// TODO: перенести\nexport const lastIndexOf = <T>(array: T[], predicate: (item: T) => boolean) => {\n for (let i = array.length - 1; i >= 0; i--) {\n if (predicate(array[i])) return i;\n }\n\n return -1;\n};\n\nexport function getSelectTestIds(dataTestId: string) {\n return {\n select: dataTestId,\n option: getDataTestId(dataTestId, 'option'),\n optionsList: getDataTestId(dataTestId, 'options-list'),\n clearButton: getDataTestId(dataTestId, 'options-list-clear'),\n applyButton: getDataTestId(dataTestId, 'options-list-apply'),\n field: getDataTestId(dataTestId, 'field'),\n fieldFormControl: getDataTestId(dataTestId, 'field-form-control'),\n fieldLeftAddons: getDataTestId(dataTestId, 'field-form-control-left-addons'),\n fieldRightAddons: getDataTestId(dataTestId, 'field-form-control-right-addons'),\n fieldError: getDataTestId(dataTestId, 'field-form-control-error-message'),\n fieldHint: getDataTestId(dataTestId, 'field-form-control-hint'),\n fieldClearIcon: getDataTestId(dataTestId, 'field-clear-icon'),\n searchInput: getDataTestId(dataTestId, 'search'),\n searchFormControl: getDataTestId(dataTestId, 'search-form-control'),\n searchInner: getDataTestId(dataTestId, 'search-form-control-inner'),\n searchLeftAddons: getDataTestId(dataTestId, 'search-form-control-left-addons'),\n searchRightAddons: getDataTestId(dataTestId, 'search-form-control-right-addons'),\n searchError: getDataTestId(dataTestId, 'search-form-control-error-message'),\n searchHint: getDataTestId(dataTestId, 'search-form-control-hint'),\n\n bottomSheet: getDataTestId(dataTestId, 'bottom-sheet'),\n bottomSheetHeader: getDataTestId(dataTestId, 'bottom-sheet-header'),\n bottomSheetContent: getDataTestId(dataTestId, 'bottom-sheet-content'),\n\n modal: getDataTestId(dataTestId, 'modal'),\n modalHeader: getDataTestId(dataTestId, 'modal-header'),\n modalContent: getDataTestId(dataTestId, 'modal-content'),\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sources":["../src/utils.ts"],"sourcesContent":["import {\n cloneElement,\n isValidElement,\n type ReactNode,\n type RefObject,\n useEffect,\n useRef,\n useState,\n} from 'react';\n\nimport {\n fnUtils,\n getDataTestId,\n getElementWindow,\n useIsMounted,\n} from '@alfalab/core-components-shared';\nimport { useLayoutEffect_SAFE_FOR_SSR } from '@alfalab/hooks';\n\nimport { DEFAULT_SEPARATOR } from './consts';\nimport {\n type BaseSelectProps,\n type GroupShape,\n type OptionShape,\n type OptionsListProps,\n} from './typings';\n\nexport const isGroup = (item: OptionShape | GroupShape): item is GroupShape =>\n Object.prototype.hasOwnProperty.call(item, 'options');\n\nexport const isOptionShape = (item: OptionShape | string | null): item is OptionShape =>\n !!item && Object.prototype.hasOwnProperty.call(item, 'key');\n\nexport const joinOptions = ({\n selected,\n selectedMultiple,\n valueSeparator = DEFAULT_SEPARATOR,\n}: {\n selected?: OptionShape;\n selectedMultiple?: OptionShape[];\n valueSeparator?: string;\n}) => {\n const options = selectedMultiple || (selected ? [selected] : []);\n\n if (!options.length) return null;\n\n return options.reduce((acc: Array<ReactNode | string>, option: OptionShape, index: number) => {\n if (isValidElement(option.content)) {\n acc.push(cloneElement(option.content, { key: option.key }));\n } else {\n acc.push(option.content);\n }\n\n if (index < options.length - 1) acc.push(valueSeparator);\n\n return acc;\n }, []);\n};\n\n// За один проход делает список пунктов меню плоским и находит выбранные пункты по ключу\nexport function processOptions(\n options: BaseSelectProps['options'],\n selected: BaseSelectProps['selected'] = [],\n filterFn: (option: OptionShape | GroupShape) => boolean = () => true,\n filterGroup = false,\n) {\n const flatOptions: OptionShape[] = [];\n const filteredOptions: BaseSelectProps['options'] = [];\n\n const selectedArray = Array.isArray(selected) ? selected : [selected];\n const selectedOptions = selectedArray.filter(isOptionShape);\n const selectedKeys = selectedArray.filter(\n (option): option is string => typeof option === 'string',\n );\n\n const isSelected = (option: OptionShape) => selectedKeys.includes(option.key);\n\n const process = (option: OptionShape | GroupShape) => {\n const isGroupOption = isGroup(option);\n\n if (!isGroupOption && isSelected(option)) {\n selectedOptions.push(option);\n }\n\n if (!filterFn(option)) return false;\n\n if (isGroupOption) {\n if (filterGroup) {\n Array.prototype.push.apply(flatOptions, option.options);\n }\n } else {\n flatOptions.push(option);\n }\n\n return true;\n };\n\n options.forEach((option) => {\n if (isGroup(option)) {\n const group: GroupShape = {\n ...option,\n options: [],\n };\n\n option.options.forEach((groupOption) => {\n const matched = process(groupOption);\n\n if (matched) group.options.push(groupOption);\n });\n\n if (group.options.length) {\n filteredOptions.push(group);\n\n return;\n }\n\n if (!filterGroup) return;\n }\n const matched = process(option);\n\n if (matched) filteredOptions.push(option);\n });\n\n return { filteredOptions, flatOptions, selectedOptions };\n}\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\ntype useVisibleOptionsArgs = {\n /**\n * Количество видимых пунктов\n */\n visibleOptions: number;\n\n /**\n * Реф на контейнер с пунтами меню\n */\n listRef: RefObject<HTMLElement>;\n\n /**\n * Флаг открытия меню\n */\n open?: boolean;\n\n /**\n * Позволяет вызвать пересчет высоты\n */\n invalidate?: unknown;\n\n /**\n * Список вариантов выбора\n */\n options?: Array<OptionShape | GroupShape>;\n\n /**\n * Максимальный размер варианта выбора\n */\n size?: Extract<OptionsListProps['size'], number>;\n\n /**\n * Учитывать действительное число вариантов выбора\n */\n actualOptionsCount?: boolean;\n};\n\n// copy-paste of original `useVisibleOptions` before https://github.com/core-ds/core-components/pull/1368\nexport function useVirtualVisibleOptions({\n visibleOptions,\n listRef,\n open,\n invalidate,\n options,\n size,\n actualOptionsCount,\n}: useVisibleOptionsArgs) {\n const [height, setHeight] = useState<number>();\n\n useLayoutEffect_SAFE_FOR_SSR(() => {\n const measureOptionHeight = (element: HTMLElement) =>\n typeof size === 'number' ? Math.min(element.clientHeight, size) : element.clientHeight;\n\n const list = listRef.current;\n\n if (open && list && visibleOptions > 0) {\n const childCount = list.children.length;\n const optionsNodes = ([] as HTMLElement[]).slice.call(\n list.children,\n 0,\n visibleOptions + 1,\n );\n\n let nextHeight = optionsNodes\n .slice(0, visibleOptions)\n .reduce((acc, child) => acc + measureOptionHeight(child), 0);\n\n if (visibleOptions < childCount) {\n const lastVisibleOptionHeight = measureOptionHeight(\n optionsNodes[optionsNodes.length - 1],\n );\n\n // Если кол-во опций больше visibleOptions на 1, то показываем все опции, иначе добавляем половинку\n nextHeight += Math.round(\n childCount - visibleOptions === 1\n ? lastVisibleOptionHeight\n : lastVisibleOptionHeight / 2,\n );\n } else if (\n visibleOptions > childCount &&\n actualOptionsCount &&\n typeof size === 'number'\n ) {\n const actualCount = (options ?? []).reduce(\n (sum, option) => sum + 1 + (isGroup(option) ? option.options.length : 0),\n 0,\n );\n\n nextHeight =\n Math.min(\n actualCount === 0 ? /** empty placeholder */ 1 : actualCount,\n visibleOptions,\n ) * size;\n\n if (visibleOptions < actualCount) {\n nextHeight += size / 2;\n }\n }\n\n const win = getElementWindow(list);\n\n nextHeight += ['::before', '::after']\n .map((pseudo) => parseFloat(win.getComputedStyle(list, pseudo).paddingTop) || 0)\n .reduce((a, b) => a + b);\n\n setHeight(nextHeight);\n }\n }, [actualOptionsCount, listRef, open, options, size, visibleOptions, invalidate]);\n\n return height;\n}\n\nexport function useVisibleOptions({\n visibleOptions,\n listRef,\n open,\n options,\n size,\n actualOptionsCount,\n}: useVisibleOptionsArgs) {\n const [, runIfMounted] = useIsMounted();\n const [measured, setMeasured] = useState(false);\n const [height, setHeight] = useState<number | undefined>();\n\n useLayoutEffect_SAFE_FOR_SSR(() => {\n const measureOptionHeight = (element: HTMLElement) =>\n typeof size === 'number' ? Math.min(element.clientHeight, size) : element.clientHeight;\n\n const list = listRef.current;\n\n if (open && list && visibleOptions > 0) {\n const childCount = list.children.length;\n const optionsNodes = ([] as HTMLElement[]).slice.call(\n list.children,\n 0,\n visibleOptions + 1,\n );\n\n let measuredHeight = optionsNodes\n .slice(0, visibleOptions)\n .reduce((acc, child) => acc + measureOptionHeight(child), 0);\n\n if (visibleOptions < childCount) {\n const lastVisibleOptionHeight = measureOptionHeight(\n optionsNodes[optionsNodes.length - 1],\n );\n\n // Если кол-во опций больше visibleOptions на 1, то показываем все опции, иначе добавляем половинку\n measuredHeight += Math.round(\n childCount - visibleOptions === 1\n ? lastVisibleOptionHeight\n : lastVisibleOptionHeight / 2,\n );\n } else if (\n visibleOptions > childCount &&\n actualOptionsCount &&\n typeof size === 'number'\n ) {\n const actualCount = (options ?? []).reduce(\n (sum, option) => sum + 1 + (isGroup(option) ? option.options.length : 0),\n 0,\n );\n\n measuredHeight =\n Math.min(\n actualCount === 0 ? /** empty placeholder */ 1 : actualCount,\n visibleOptions,\n ) * size;\n\n if (visibleOptions < actualCount) {\n measuredHeight += size / 2;\n }\n }\n\n const win = getElementWindow(list);\n\n measuredHeight += ['::before', '::after']\n .map((pseudo) => parseFloat(win.getComputedStyle(list, pseudo).paddingTop) || 0)\n .reduce((a, b) => a + b);\n\n setHeight(measuredHeight);\n\n setMeasured(true);\n\n return () => {\n runIfMounted(() => setMeasured(false));\n };\n }\n\n return fnUtils.noop;\n }, [actualOptionsCount, listRef, open, options, size, visibleOptions, runIfMounted]);\n\n return [measured, height] as const;\n}\n\nexport function defaultFilterFn(optionText: string, search: string) {\n if (!search) return true;\n\n return optionText.toLowerCase().includes(search.toLowerCase());\n}\n\nexport function defaultGroupAccessor(option: GroupShape) {\n return option.label;\n}\n\nexport function defaultAccessor(option: OptionShape) {\n if (typeof option.content === 'string') return option.content;\n if (typeof option.value === 'string') return option.value;\n\n return option.key;\n}\n\n// TODO: перенести\nexport function usePrevious<T>(value: T) {\n const ref = useRef<T>();\n\n useEffect(() => {\n ref.current = value;\n }, [value]);\n\n return ref.current;\n}\n\nexport function getSelectTestIds(dataTestId: string) {\n return {\n select: dataTestId,\n option: getDataTestId(dataTestId, 'option'),\n optionsList: getDataTestId(dataTestId, 'options-list'),\n clearButton: getDataTestId(dataTestId, 'options-list-clear'),\n applyButton: getDataTestId(dataTestId, 'options-list-apply'),\n field: getDataTestId(dataTestId, 'field'),\n fieldFormControl: getDataTestId(dataTestId, 'field-form-control'),\n fieldLeftAddons: getDataTestId(dataTestId, 'field-form-control-left-addons'),\n fieldRightAddons: getDataTestId(dataTestId, 'field-form-control-right-addons'),\n fieldError: getDataTestId(dataTestId, 'field-form-control-error-message'),\n fieldHint: getDataTestId(dataTestId, 'field-form-control-hint'),\n fieldClearIcon: getDataTestId(dataTestId, 'field-clear-icon'),\n searchInput: getDataTestId(dataTestId, 'search'),\n searchFormControl: getDataTestId(dataTestId, 'search-form-control'),\n searchInner: getDataTestId(dataTestId, 'search-form-control-inner'),\n searchLeftAddons: getDataTestId(dataTestId, 'search-form-control-left-addons'),\n searchRightAddons: getDataTestId(dataTestId, 'search-form-control-right-addons'),\n searchError: getDataTestId(dataTestId, 'search-form-control-error-message'),\n searchHint: getDataTestId(dataTestId, 'search-form-control-hint'),\n\n bottomSheet: getDataTestId(dataTestId, 'bottom-sheet'),\n bottomSheetHeader: getDataTestId(dataTestId, 'bottom-sheet-header'),\n bottomSheetContent: getDataTestId(dataTestId, 'bottom-sheet-content'),\n\n modal: getDataTestId(dataTestId, 'modal'),\n modalHeader: getDataTestId(dataTestId, 'modal-header'),\n modalContent: getDataTestId(dataTestId, 'modal-content'),\n };\n}\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alfalab/core-components-select",
3
- "version": "19.1.10",
3
+ "version": "19.2.0-alfasans",
4
4
  "description": "Select component",
5
5
  "keywords": [],
6
6
  "license": "MIT",
@@ -13,21 +13,20 @@
13
13
  "build": "rollup -c ../../tools/rollup/rollup.config.mjs --silent"
14
14
  },
15
15
  "dependencies": {
16
- "@alfalab/core-components-base-modal": "^7.1.6",
17
- "@alfalab/core-components-bottom-sheet": "^8.1.10",
18
- "@alfalab/core-components-button": "^13.2.0",
19
- "@alfalab/core-components-checkbox": "^6.2.2",
20
- "@alfalab/core-components-form-control": "^14.0.7",
21
- "@alfalab/core-components-input": "^17.1.8",
22
- "@alfalab/core-components-modal": "^11.0.13",
23
- "@alfalab/core-components-mq": "^6.0.5",
24
- "@alfalab/core-components-popover": "^8.0.5",
25
- "@alfalab/core-components-scrollbar": "^5.0.4",
26
- "@alfalab/core-components-shared": "^2.2.1",
27
- "@alfalab/core-components-skeleton": "^7.0.4",
16
+ "@alfalab/core-components-base-modal": "7.1.7-alfasans",
17
+ "@alfalab/core-components-bottom-sheet": "8.1.11-alfasans",
18
+ "@alfalab/core-components-button": "13.2.1-alfasans",
19
+ "@alfalab/core-components-checkbox": "6.2.3-alfasans",
20
+ "@alfalab/core-components-form-control": "14.0.8-alfasans",
21
+ "@alfalab/core-components-input": "17.1.9-alfasans",
22
+ "@alfalab/core-components-modal": "11.0.14-alfasans",
23
+ "@alfalab/core-components-mq": "6.0.6-alfasans",
24
+ "@alfalab/core-components-popover": "8.1.0-alfasans",
25
+ "@alfalab/core-components-scrollbar-private": "0.0.1-alfasans",
26
+ "@alfalab/core-components-shared": "2.2.2-alfasans",
27
+ "@alfalab/core-components-skeleton": "7.0.4-alfasans",
28
28
  "@alfalab/hooks": "^1.17.0",
29
29
  "@alfalab/icons-glyph": "^2.260.0",
30
- "@juggle/resize-observer": "^3.3.1",
31
30
  "classnames": "^2.5.1",
32
31
  "compute-scroll-into-view": "^3.1.0",
33
32
  "downshift": "8.4.0",
@@ -45,6 +44,6 @@
45
44
  "access": "public",
46
45
  "directory": "dist"
47
46
  },
48
- "themesVersion": "15.1.0",
49
- "varsVersion": "11.1.0"
47
+ "themesVersion": "15.2.0-alfasans",
48
+ "varsVersion": "11.1.0-alfasans"
50
49
  }
@@ -94,6 +94,10 @@ export declare function useSelectWithApply({ options, selected, onChange, onSele
94
94
  search?: string;
95
95
  multiple?: boolean;
96
96
  limitDynamicOptionGroupSize?: BaseSelectProps["limitDynamicOptionGroupSize"];
97
+ scrollableNodeClassName?: string;
98
+ contentNodeClassName?: string;
99
+ listNodeClassName?: string;
100
+ ctrlRef?: import("react").Ref<import("../../typings").OptionsListController>;
97
101
  } & {
98
102
  showClear?: boolean;
99
103
  onClose?: () => void;
@@ -139,6 +143,10 @@ export declare function useSelectWithApply({ options, selected, onChange, onSele
139
143
  search?: string;
140
144
  multiple?: boolean;
141
145
  limitDynamicOptionGroupSize?: BaseSelectProps["limitDynamicOptionGroupSize"];
146
+ scrollableNodeClassName?: string;
147
+ contentNodeClassName?: string;
148
+ listNodeClassName?: string;
149
+ ctrlRef?: import("react").Ref<import("../../typings").OptionsListController>;
142
150
  } & import("react").RefAttributes<HTMLDivElement>> | undefined;
143
151
  showClear: boolean;
144
152
  onClear: () => void;
@@ -203,6 +211,10 @@ export declare function useSelectWithApply({ options, selected, onChange, onSele
203
211
  search?: string;
204
212
  multiple?: boolean;
205
213
  limitDynamicOptionGroupSize?: BaseSelectProps["limitDynamicOptionGroupSize"];
214
+ scrollableNodeClassName?: string;
215
+ contentNodeClassName?: string;
216
+ listNodeClassName?: string;
217
+ ctrlRef?: import("react").Ref<import("../../typings").OptionsListController>;
206
218
  } & import("react").RefAttributes<HTMLDivElement>> | undefined;
207
219
  optionsListProps: unknown;
208
220
  showClear: boolean;
@@ -35,6 +35,10 @@ export declare const OptionsListWithApply: React.ForwardRefExoticComponent<Pick<
35
35
  search?: string;
36
36
  multiple?: boolean;
37
37
  limitDynamicOptionGroupSize?: import("../../../typings").BaseSelectProps["limitDynamicOptionGroupSize"];
38
+ scrollableNodeClassName?: string;
39
+ contentNodeClassName?: string;
40
+ listNodeClassName?: string;
41
+ ctrlRef?: React.Ref<import("../../../typings").OptionsListController>;
38
42
  } & {
39
43
  showClear?: boolean;
40
44
  onClose?: () => void;
@@ -4,22 +4,17 @@
4
4
  :root {
5
5
  --gap-xs: 8px;
6
6
  --gap-s: 12px;
7
- --gap-m: 16px;
8
7
  --gap-8: var(--gap-xs);
9
8
  --gap-12: var(--gap-s);
10
- --gap-16: var(--gap-m);
11
9
  }
12
10
  :root {
13
11
  --select-option-list-footer-button-gap: var(--gap-8);
14
12
  }
15
- .select__footer_1mxu2 {
13
+ .select__footer_1bdq6 {
16
14
  background-color: var(--color-light-base-bg-primary);
17
15
  padding: var(--gap-12);
18
16
  outline: none;
19
17
  }
20
- .select__footer_1mxu2.select__size-72_1mxu2 {
21
- padding: var(--gap-12) var(--gap-16);
22
- }
23
- .select__footer_1mxu2 > .select__button_1mxu2 + .select__button_1mxu2 {
18
+ .select__footer_1bdq6 > .select__button_1bdq6 + .select__button_1bdq6 {
24
19
  margin-left: var(--select-option-list-footer-button-gap);
25
20
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  require('./index.css');
4
4
 
5
- var styles = {"footer":"select__footer_1mxu2","size-72":"select__size-72_1mxu2","button":"select__button_1mxu2"};
5
+ var styles = {"footer":"select__footer_1bdq6","button":"select__button_1bdq6"};
6
6
 
7
7
  module.exports = styles;
8
8
  //# sourceMappingURL=index.module.css.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.module.css.js","sources":["../../../../src/presets/useSelectWithApply/options-list-with-apply/footer/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/index.css';\n@import './vars.css';\n\n.footer {\n background-color: var(--color-light-base-bg-primary);\n padding: var(--gap-12);\n outline: none;\n\n &.size-72 {\n padding: var(--gap-12) var(--gap-16);\n }\n\n & > .button + .button {\n margin-left: var(--select-option-list-footer-button-gap);\n }\n}\n"],"names":[],"mappings":";;;;AAEgB,aAAe,CAAC,QAAQ,CAAC,sBAAsB,CAAC,SAAS,CAAC,uBAAuB,CAAC,QAAQ,CAAC,sBAAsB,CAAC;;;;"}
1
+ {"version":3,"file":"index.module.css.js","sources":["../../../../src/presets/useSelectWithApply/options-list-with-apply/footer/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/index.css';\n@import './vars.css';\n\n.footer {\n background-color: var(--color-light-base-bg-primary);\n padding: var(--gap-12);\n outline: none;\n\n & > .button + .button {\n margin-left: var(--select-option-list-footer-button-gap);\n }\n}\n"],"names":[],"mappings":";;;;AAEgB,aAAe,CAAC,QAAQ,CAAC,sBAAsB,CAAC,QAAQ,CAAC,sBAAsB,CAAC;;;;"}
@@ -1,21 +1,24 @@
1
1
  :root {
2
2
  --gap-xs: 8px;
3
3
  --gap-s: 12px;
4
- --gap-m: 16px;
4
+ --gap-0: 0px;
5
5
  --gap-8: var(--gap-xs);
6
6
  --gap-12: var(--gap-s);
7
- --gap-16: var(--gap-m);
8
7
  }
9
- .select__desktop_icdp3 {
10
- padding: var(--gap-12);
8
+ :root {
9
+ --select-options-list-top-padding: var(--gap-0);
10
+ --select-options-list-right-padding: var(--gap-0);
11
+ --select-options-list-left-padding: var(--gap-0);
12
+ }
13
+ .select__desktop_1h94k {
14
+ padding: calc(var(--gap-12) + var(--select-options-list-top-padding))
15
+ calc(var(--gap-12) + var(--select-options-list-right-padding)) var(--gap-12)
16
+ calc(var(--gap-12) + var(--select-options-list-left-padding));
11
17
  }
12
- .select__desktop_icdp3.select__size-72_icdp3 {
13
- padding-left: var(--gap-16);
14
- }
15
- .select__mobile_icdp3 {
18
+ .select__mobile_1h94k {
16
19
  padding: var(--gap-12) var(--gap-12) var(--gap-12) var(--gap-8);
17
20
  }
18
- .select__positionAfter_icdp3 {
21
+ .select__positionAfter_1h94k {
19
22
  margin-left: 0;
20
23
  margin-left: initial;
21
24
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  require('./index.css');
4
4
 
5
- var styles = {"desktop":"select__desktop_icdp3","size-72":"select__size-72_icdp3","mobile":"select__mobile_icdp3","positionAfter":"select__positionAfter_icdp3"};
5
+ var styles = {"desktop":"select__desktop_1h94k","mobile":"select__mobile_1h94k","positionAfter":"select__positionAfter_1h94k"};
6
6
 
7
7
  module.exports = styles;
8
8
  //# sourceMappingURL=index.module.css.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.module.css.js","sources":["../../../../src/presets/useSelectWithApply/options-list-with-apply/header/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/index.css';\n\n.desktop {\n padding: var(--gap-12);\n &.size-72 {\n padding-left: var(--gap-16);\n }\n}\n\n.mobile {\n padding: var(--gap-12) var(--gap-12) var(--gap-12) var(--gap-8);\n}\n\n.positionAfter {\n margin-left: unset;\n}\n"],"names":[],"mappings":";;;;AAEgB,aAAe,CAAC,SAAS,CAAC,uBAAuB,CAAC,SAAS,CAAC,uBAAuB,CAAC,QAAQ,CAAC,sBAAsB,CAAC,eAAe,CAAC,6BAA6B,CAAC;;;;"}
1
+ {"version":3,"file":"index.module.css.js","sources":["../../../../src/presets/useSelectWithApply/options-list-with-apply/header/index.module.css"],"sourcesContent":["@import '@alfalab/core-components-vars/src/index.css';\n@import '../../../../vars.css';\n\n.desktop {\n padding: calc(var(--gap-12) + var(--select-options-list-top-padding))\n calc(var(--gap-12) + var(--select-options-list-right-padding)) var(--gap-12)\n calc(var(--gap-12) + var(--select-options-list-left-padding));\n}\n\n.mobile {\n padding: var(--gap-12) var(--gap-12) var(--gap-12) var(--gap-8);\n}\n\n.positionAfter {\n margin-left: unset;\n}\n"],"names":[],"mappings":";;;;AAEgB,aAAe,CAAC,SAAS,CAAC,uBAAuB,CAAC,QAAQ,CAAC,sBAAsB,CAAC,eAAe,CAAC,6BAA6B,CAAC;;;;"}
@@ -1,4 +1,4 @@
1
- .select__skeleton_11n6n {
1
+ .select__skeleton_gcqox {
2
2
  position: absolute;
3
3
  top: 50%;
4
4
  transform: translateY(-50%);
@@ -2,7 +2,7 @@
2
2
 
3
3
  require('./index.css');
4
4
 
5
- var styles = {"skeleton":"select__skeleton_11n6n"};
5
+ var styles = {"skeleton":"select__skeleton_gcqox"};
6
6
 
7
7
  module.exports = styles;
8
8
  //# sourceMappingURL=index.module.css.js.map
package/shared/index.js CHANGED
@@ -31,7 +31,6 @@ exports.getSelectTestIds = utils.getSelectTestIds;
31
31
  exports.isGroup = utils.isGroup;
32
32
  exports.isOptionShape = utils.isOptionShape;
33
33
  exports.joinOptions = utils.joinOptions;
34
- exports.lastIndexOf = utils.lastIndexOf;
35
34
  exports.processOptions = utils.processOptions;
36
35
  exports.usePrevious = utils.usePrevious;
37
36
  exports.useVirtualVisibleOptions = utils.useVirtualVisibleOptions;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -12,7 +12,6 @@ import React, {
12
12
  useRef,
13
13
  } from 'react';
14
14
  import mergeRefs from 'react-merge-refs';
15
- import { ResizeObserver as ResizeObserverPolyfill } from '@juggle/resize-observer';
16
15
  import cn from 'classnames';
17
16
  import { compute } from 'compute-scroll-into-view';
18
17
  import {
@@ -22,12 +21,12 @@ import {
22
21
  type UseMultipleSelectionState,
23
22
  } from 'downshift';
24
23
 
25
- import { fnUtils, getDataTestId, isClient } from '@alfalab/core-components-shared';
26
- import { useLayoutEffect_SAFE_FOR_SSR } from '@alfalab/hooks';
24
+ import { getDataTestId, isClient } from '@alfalab/core-components-shared';
27
25
 
28
26
  import {
29
27
  type AnyObject,
30
28
  type OptionShape,
29
+ type OptionsListController,
31
30
  type OptionsListProps,
32
31
  type SearchProps,
33
32
  } from '../../typings';
@@ -125,14 +124,13 @@ export const BaseSelect = forwardRef<unknown, ComponentProps>(
125
124
  environment = isClient() ? window : undefined,
126
125
  } = props;
127
126
  const shouldSearchBlurRef = useRef(true);
128
- const rootRef = useRef<HTMLDivElement>(null);
129
127
  const fieldRef = useRef<HTMLInputElement>(null);
130
128
  const listRef = useRef<HTMLDivElement>(null);
131
129
  const initiatorRef = useRef<OptionShape | null>(null);
132
130
  const searchRef = useRef<HTMLInputElement>(null);
133
131
  const scrollableContainerRef = useRef<HTMLDivElement>(null);
134
132
  const onOpenRef = useRef(onOpen);
135
-
133
+ const optionsListCtrlRef = useRef<OptionsListController>(null);
136
134
  const [searchState, setSearchState] = React.useState('');
137
135
 
138
136
  const [search, setSearch] =
@@ -169,20 +167,29 @@ export const BaseSelect = forwardRef<unknown, ComponentProps>(
169
167
 
170
168
  const scrollIntoView = (node: HTMLElement) => {
171
169
  if (!node || view === 'mobile') return;
170
+ const optionsListCtrl = optionsListCtrlRef.current;
172
171
 
173
- requestAnimationFrame(() => {
174
- const actions = compute(node, {
175
- boundary: listRef.current,
176
- block: 'nearest',
177
- scrollMode: 'if-needed',
178
- });
172
+ if (optionsListCtrl) {
173
+ const dataIndex = node.getAttribute('data-index');
174
+
175
+ if (dataIndex) {
176
+ optionsListCtrl.scrollToIndex(Number(dataIndex));
177
+ }
178
+ } else {
179
+ requestAnimationFrame(() => {
180
+ const actions = compute(node, {
181
+ boundary: listRef.current,
182
+ block: 'nearest',
183
+ scrollMode: 'if-needed',
184
+ });
179
185
 
180
- actions.forEach((action) => {
181
- const { el, top } = action;
186
+ actions.forEach((action) => {
187
+ const { el, top } = action;
182
188
 
183
- el.scrollTop = top;
189
+ el.scrollTop = top;
190
+ });
184
191
  });
185
- });
192
+ }
186
193
  };
187
194
 
188
195
  const useMultipleSelectionProps: UseMultipleSelectionProps<OptionShape> = {
@@ -459,6 +466,7 @@ export const BaseSelect = forwardRef<unknown, ComponentProps>(
459
466
  ...(optionProps as object),
460
467
  mobile: view === 'mobile',
461
468
  className: cn(optionClassName, {
469
+ [styles.option]: view === 'desktop',
462
470
  [mobileStyles.option]: view === 'mobile',
463
471
  }),
464
472
  innerProps: getItemProps({
@@ -472,6 +480,7 @@ export const BaseSelect = forwardRef<unknown, ComponentProps>(
472
480
  shouldSearchBlurRef.current = true;
473
481
  fieldRef.current?.focus();
474
482
  },
483
+ 'data-index': index,
475
484
  }),
476
485
  multiple,
477
486
  index,
@@ -494,43 +503,6 @@ export const BaseSelect = forwardRef<unknown, ComponentProps>(
494
503
  // eslint-disable-next-line react-hooks/exhaustive-deps
495
504
  }, []);
496
505
 
497
- const calcOptionsListWidth = useCallback(() => {
498
- if (view === 'desktop' && listRef.current) {
499
- const widthAttr = optionsListWidth === 'field' ? 'width' : 'minWidth';
500
-
501
- const optionsListMinWidth = rootRef.current
502
- ? rootRef.current.getBoundingClientRect().width
503
- : 0;
504
-
505
- listRef.current.removeAttribute('style');
506
- listRef.current.style[widthAttr] = `${optionsListMinWidth}px`;
507
- }
508
- }, [view, optionsListWidth]);
509
-
510
- useEffect(() => {
511
- if (view === 'desktop') {
512
- const ResizeObserver = window.ResizeObserver || ResizeObserverPolyfill;
513
- const observer = new ResizeObserver(calcOptionsListWidth);
514
-
515
- if (rootRef.current) {
516
- observer.observe(rootRef.current);
517
- }
518
-
519
- return () => {
520
- observer.disconnect();
521
- };
522
- }
523
-
524
- return fnUtils.noop;
525
- }, [view, calcOptionsListWidth, open, optionsListWidth]);
526
-
527
- useLayoutEffect_SAFE_FOR_SSR(calcOptionsListWidth, [
528
- open,
529
- optionsListWidth,
530
- filteredOptions,
531
- selectedItems,
532
- ]);
533
-
534
506
  const renderValue = () =>
535
507
  selectedItems.map((option) => (
536
508
  <input type='hidden' name={name} value={option.key} key={option.key} />
@@ -641,20 +613,33 @@ export const BaseSelect = forwardRef<unknown, ComponentProps>(
641
613
  optionsListClassName,
642
614
  view === 'mobile' && mobileStyles.optionsListWrapper,
643
615
  view === 'desktop' && styles.optionsListWrapper,
616
+ {
617
+ [styles.matchContent]:
618
+ view === 'desktop' && optionsListWidth === 'content',
619
+ },
644
620
  )}
645
621
  >
646
622
  <OptionsList
647
623
  {...listProps}
624
+ ctrlRef={optionsListCtrlRef}
648
625
  ref={view === 'desktop' ? listProps.ref : scrollableContainerRef}
649
626
  setHighlightedIndex={view === 'desktop' ? setHighlightedIndex : undefined}
650
627
  className={cn(
651
- { [mobileStyles.optionsList]: view === 'mobile' },
628
+ {
629
+ [mobileStyles.optionsList]: view === 'mobile',
630
+ },
652
631
  listProps.className,
653
632
  )}
654
633
  scrollbarClassName={cn(
655
- { [mobileStyles.scrollbar]: view === 'mobile' },
634
+ {
635
+ [styles.scrollbar]: view === 'desktop',
636
+ [mobileStyles.scrollbar]: view === 'mobile',
637
+ },
656
638
  listProps.scrollbarClassName,
657
639
  )}
640
+ scrollableNodeClassName={cn({ [styles.scrollable]: view === 'desktop' })}
641
+ contentNodeClassName={cn({ [styles.content]: view === 'desktop' })}
642
+ listNodeClassName={cn({ [styles.list]: view === 'desktop' })}
658
643
  optionsListWidth={optionsListWidth}
659
644
  flatOptions={flatOptions}
660
645
  highlightedIndex={highlightedIndex}
@@ -699,6 +684,8 @@ export const BaseSelect = forwardRef<unknown, ComponentProps>(
699
684
  popperClassName={cn(styles.popoverInner, popperClassName)}
700
685
  update={updatePopover}
701
686
  zIndex={zIndexPopover}
687
+ useAnchorWidth={true}
688
+ widthProp={optionsListWidth === 'field' ? 'width' : 'minWidth'}
702
689
  >
703
690
  {renderOptionsList()}
704
691
  </Popover>
@@ -825,7 +812,6 @@ export const BaseSelect = forwardRef<unknown, ComponentProps>(
825
812
  aria-haspopup='listbox'
826
813
  role={inputProps.role}
827
814
  className={cn(styles.component, { [styles.block]: block }, className)}
828
- ref={rootRef}
829
815
  onKeyDown={disabled ? undefined : handleFieldKeyDown}
830
816
  tabIndex={-1}
831
817
  data-test-id={getDataTestId(dataTestId)}