ics-ui-kit 0.1.0-alpha.47 → 0.1.0-alpha.49

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 (198) hide show
  1. package/README.md +32 -32
  2. package/dist/AlertContext-CxjW1LVL.js.map +1 -1
  3. package/dist/AlertIcon-DQs4wtDT.js.map +1 -1
  4. package/dist/Button--ooZ8ALo.js.map +1 -1
  5. package/dist/ButtonBase-Sf-fcVor.js.map +1 -1
  6. package/dist/CarouselItem-DCAuGIKz.js.map +1 -1
  7. package/dist/{CheckboxField-DvsGq3kV.js → CheckboxField-BR2hWwTO.js} +2 -2
  8. package/dist/CheckboxField-BR2hWwTO.js.map +1 -0
  9. package/dist/{Command-BU9Ouar3.js → Command-C_iW2joV.js} +2 -2
  10. package/dist/Command-C_iW2joV.js.map +1 -0
  11. package/dist/ComponentVariantProvider-B0SFUaXB.js.map +1 -1
  12. package/dist/Description-BTPMlTT-.js.map +1 -1
  13. package/dist/Dialog-CkDUxZUj.js.map +1 -1
  14. package/dist/Divider-Dm2gjy8W.js.map +1 -1
  15. package/dist/EmptyState-DRKjscH-.js.map +1 -1
  16. package/dist/ErrorState-B26k67-z.js.map +1 -1
  17. package/dist/FeatureIcon-yM7FhAXa.js.map +1 -1
  18. package/dist/{Field-CdocNMjg.js → Field-DpbrZvvg.js} +2 -2
  19. package/dist/Field-DpbrZvvg.js.map +1 -0
  20. package/dist/{FieldLabel-DRwAhGMz.js → FieldLabel-saPDMPPr.js} +2 -2
  21. package/dist/FieldLabel-saPDMPPr.js.map +1 -0
  22. package/dist/FolderSvg-cw0DxNVy.js.map +1 -1
  23. package/dist/{FormFooterTemplate-1MNxzQ7J.js → FormFooterTemplate-DV4pN3b-.js} +2 -2
  24. package/dist/FormFooterTemplate-DV4pN3b-.js.map +1 -0
  25. package/dist/FormHeader-BA2dJOPS.js.map +1 -1
  26. package/dist/{FormStack-DbtLshF8.js → FormStack-D-0fK-Zy.js} +3 -3
  27. package/dist/FormStack-D-0fK-Zy.js.map +1 -0
  28. package/dist/HintState-BxrCAWqq.js.map +1 -1
  29. package/dist/Icon-DH3ev9GK.js.map +1 -1
  30. package/dist/IconButton-moydR8IU.js.map +1 -1
  31. package/dist/{IconTooltip-CibXkFmt.js → IconTooltip-BbswlF6Q.js} +3 -3
  32. package/dist/IconTooltip-BbswlF6Q.js.map +1 -0
  33. package/dist/ImagePlaceholder-B6mGYVx2.js.map +1 -1
  34. package/dist/ImagePreview-BIBDrLVV.js.map +1 -1
  35. package/dist/ImageUploader-C-_ZPptv.js.map +1 -1
  36. package/dist/Indicator-B75A1Vgp.js.map +1 -1
  37. package/dist/InputGroup-CmstXpkX.js.map +1 -1
  38. package/dist/InputOTP-B2e1nfSO.js.map +1 -1
  39. package/dist/Loader-BpHiL6W-.js.map +1 -1
  40. package/dist/MenuItem-pvsONHlh.js.map +1 -1
  41. package/dist/{MenuItemShortcut-CGbVYqRi.js → MenuItemShortcut-DK7VneTR.js} +2 -2
  42. package/dist/MenuItemShortcut-DK7VneTR.js.map +1 -0
  43. package/dist/MenuItemText-7uPl9P3z.js.map +1 -1
  44. package/dist/Overlay-CLw_hvAN.js.map +1 -1
  45. package/dist/{Popover-CkezMtEz.js → Popover-DmwXZwYd.js} +17 -17
  46. package/dist/Popover-DmwXZwYd.js.map +1 -0
  47. package/dist/RichButton-BuenN3bJ.js.map +1 -1
  48. package/dist/ScrollShadowContainer-ODG9ChxA.js.map +1 -1
  49. package/dist/{SearchSelectTag-D1bFK1ux.js → SearchSelectTag-Ce-Q9JGR.js} +2 -2
  50. package/dist/SearchSelectTag-Ce-Q9JGR.js.map +1 -0
  51. package/dist/{Select-Bfrb-J8s.js → Select-CWbLja8r.js} +195 -195
  52. package/dist/Select-CWbLja8r.js.map +1 -0
  53. package/dist/Sheet-Dx9mwcF6.js.map +1 -1
  54. package/dist/Shortcut-D8L15_ed.js +22 -0
  55. package/dist/Shortcut-D8L15_ed.js.map +1 -0
  56. package/dist/Skeleton-y6I-i9q5.js.map +1 -1
  57. package/dist/{Tag-DJuVSJh5.js → Tag-CofZF1d0.js} +6 -6
  58. package/dist/Tag-CofZF1d0.js.map +1 -0
  59. package/dist/Text-DeBE8AKl.js.map +1 -1
  60. package/dist/TextInput-DTzujp77.js.map +1 -1
  61. package/dist/{Toggle-CS29Nksd.js → Toggle-CCD2UHWr.js} +15 -13
  62. package/dist/Toggle-CCD2UHWr.js.map +1 -0
  63. package/dist/{Tooltip-Cm1-WEdA.js → Tooltip-BH_Jc6ub.js} +2 -2
  64. package/dist/Tooltip-BH_Jc6ub.js.map +1 -0
  65. package/dist/TriggerButton-a2ClSj7f.js +33 -0
  66. package/dist/TriggerButton-a2ClSj7f.js.map +1 -0
  67. package/dist/blocks/auth/otp-form.js +1 -1
  68. package/dist/blocks/auth/otp-form.js.map +1 -1
  69. package/dist/cn-dsXlqdJg.js.map +1 -1
  70. package/dist/components/alert-dialog.js.map +1 -1
  71. package/dist/components/alert.js.map +1 -1
  72. package/dist/components/avatar/Avatar.d.ts +1 -1
  73. package/dist/components/avatar/avatar-indicator/AvatarIndicator.d.ts +3 -1
  74. package/dist/components/avatar/avatar-label/AvatarLabel.d.ts +1 -1
  75. package/dist/components/avatar.js +110 -93
  76. package/dist/components/avatar.js.map +1 -1
  77. package/dist/components/badge.js.map +1 -1
  78. package/dist/components/breadcrumb.js.map +1 -1
  79. package/dist/components/button.js +1 -1
  80. package/dist/components/button.js.map +1 -1
  81. package/dist/components/calendar.js.map +1 -1
  82. package/dist/components/card.js.map +1 -1
  83. package/dist/components/carousel.js.map +1 -1
  84. package/dist/components/checkbox.js +1 -1
  85. package/dist/components/collapsible.js.map +1 -1
  86. package/dist/components/color-tile.js.map +1 -1
  87. package/dist/components/command.js +1 -1
  88. package/dist/components/container.js.map +1 -1
  89. package/dist/components/counter.js.map +1 -1
  90. package/dist/components/dialog.js +1 -1
  91. package/dist/components/dialog.js.map +1 -1
  92. package/dist/components/divider.js.map +1 -1
  93. package/dist/components/drawer.js +1 -1
  94. package/dist/components/drawer.js.map +1 -1
  95. package/dist/components/dropdown.js +2 -2
  96. package/dist/components/dropdown.js.map +1 -1
  97. package/dist/components/error-state.js.map +1 -1
  98. package/dist/components/field.js +1 -1
  99. package/dist/components/file-upload.js.map +1 -1
  100. package/dist/components/form.js +3 -3
  101. package/dist/components/form.js.map +1 -1
  102. package/dist/components/gallery.js.map +1 -1
  103. package/dist/components/icon-tooltip.js +1 -1
  104. package/dist/components/input.js.map +1 -1
  105. package/dist/components/label.js +1 -1
  106. package/dist/components/menu-item.js +1 -1
  107. package/dist/components/menu-item.js.map +1 -1
  108. package/dist/components/overflow-tooltip.js +1 -1
  109. package/dist/components/overflow-tooltip.js.map +1 -1
  110. package/dist/components/page-state.js.map +1 -1
  111. package/dist/components/popover.js +1 -1
  112. package/dist/components/portal-container.js.map +1 -1
  113. package/dist/components/progress-circle.js.map +1 -1
  114. package/dist/components/progress.js.map +1 -1
  115. package/dist/components/prose.js.map +1 -1
  116. package/dist/components/radio-group.js.map +1 -1
  117. package/dist/components/resizable.js.map +1 -1
  118. package/dist/components/scheduler.js +1 -1
  119. package/dist/components/scheduler.js.map +1 -1
  120. package/dist/components/search-select.js +4 -4
  121. package/dist/components/search-select.js.map +1 -1
  122. package/dist/components/select.js +1 -1
  123. package/dist/components/shortcut.js +1 -1
  124. package/dist/components/sidebar.js +71 -68
  125. package/dist/components/sidebar.js.map +1 -1
  126. package/dist/components/slider.js.map +1 -1
  127. package/dist/components/stepper.js.map +1 -1
  128. package/dist/components/switch.js +1 -1
  129. package/dist/components/switch.js.map +1 -1
  130. package/dist/components/system-state.js.map +1 -1
  131. package/dist/components/table.js.map +1 -1
  132. package/dist/components/tabs.js.map +1 -1
  133. package/dist/components/tag-input.js +2 -2
  134. package/dist/components/tag-input.js.map +1 -1
  135. package/dist/components/tag.js +1 -1
  136. package/dist/components/textarea.js.map +1 -1
  137. package/dist/components/toast.js.map +1 -1
  138. package/dist/components/toggle/Toggle.d.ts +8 -2
  139. package/dist/components/toggle-group.js +1 -1
  140. package/dist/components/toggle-group.js.map +1 -1
  141. package/dist/components/toggle.js +1 -1
  142. package/dist/components/toolbar.js.map +1 -1
  143. package/dist/components/tooltip.js +1 -1
  144. package/dist/downloadFile-yZV-aaO2.js.map +1 -1
  145. package/dist/font-inter.css +15 -15
  146. package/dist/font-menlo.css +15 -15
  147. package/dist/index-0ioNhtNM.js.map +1 -1
  148. package/dist/index-5Bhkapwi.js.map +1 -1
  149. package/dist/index-BGQepRFJ.js.map +1 -1
  150. package/dist/index-BGfrl8IX.js.map +1 -1
  151. package/dist/index-BNirMMl4.js.map +1 -1
  152. package/dist/index-BVqs-uqP.js.map +1 -1
  153. package/dist/index-BZPx6jYI.js.map +1 -1
  154. package/dist/index-BdXokVmb.js.map +1 -1
  155. package/dist/index-Bwf2hSw6.js.map +1 -1
  156. package/dist/index-C0UREtMP.js.map +1 -1
  157. package/dist/index-C3surxzg.js.map +1 -1
  158. package/dist/index-CCKe-Mpx.js.map +1 -1
  159. package/dist/index-CpDnqHCm.js.map +1 -1
  160. package/dist/index-DFZozV_h.js.map +1 -1
  161. package/dist/index-DG36Jang.js.map +1 -1
  162. package/dist/index-DfNPZZ8M.js.map +1 -1
  163. package/dist/index-DpXwz_9G.js.map +1 -1
  164. package/dist/index-Nzc5v6h6.js.map +1 -1
  165. package/dist/index-l1F44JQJ.js.map +1 -1
  166. package/dist/index.js.map +1 -1
  167. package/dist/inputBaseStyles-BZJgQP7O.js.map +1 -1
  168. package/dist/lib/utils.js.map +1 -1
  169. package/dist/styles-scoped.css +5846 -5832
  170. package/dist/styles.css +1949 -1935
  171. package/dist/types/css.d.ts +4 -4
  172. package/dist/useBreakpoints-wEcfJPHd.js.map +1 -1
  173. package/dist/useDebounce-BRah78CF.js.map +1 -1
  174. package/dist/useFileUpload-iDag0iqM.js.map +1 -1
  175. package/dist/useMergeRefs-qoKniYqT.js.map +1 -1
  176. package/dist/usePortalContainer-ae6EzS08.js.map +1 -1
  177. package/dist/vendors/tanstack/react-table.js.map +1 -1
  178. package/dist/zod-BMNoK3aM.js.map +1 -1
  179. package/package.json +172 -172
  180. package/dist/CheckboxField-DvsGq3kV.js.map +0 -1
  181. package/dist/Command-BU9Ouar3.js.map +0 -1
  182. package/dist/Field-CdocNMjg.js.map +0 -1
  183. package/dist/FieldLabel-DRwAhGMz.js.map +0 -1
  184. package/dist/FormFooterTemplate-1MNxzQ7J.js.map +0 -1
  185. package/dist/FormStack-DbtLshF8.js.map +0 -1
  186. package/dist/IconTooltip-CibXkFmt.js.map +0 -1
  187. package/dist/MenuItemShortcut-CGbVYqRi.js.map +0 -1
  188. package/dist/Popover-CkezMtEz.js.map +0 -1
  189. package/dist/SearchSelectTag-D1bFK1ux.js.map +0 -1
  190. package/dist/Select-Bfrb-J8s.js.map +0 -1
  191. package/dist/Shortcut-Cm4nUx2C.js +0 -22
  192. package/dist/Shortcut-Cm4nUx2C.js.map +0 -1
  193. package/dist/Tag-DJuVSJh5.js.map +0 -1
  194. package/dist/Toggle-CS29Nksd.js.map +0 -1
  195. package/dist/Tooltip-Cm1-WEdA.js.map +0 -1
  196. package/dist/TriggerButton-BzXO5wcQ.js +0 -33
  197. package/dist/TriggerButton-BzXO5wcQ.js.map +0 -1
  198. package/dist/design-tokens.source.json +0 -1
@@ -1,11 +1,11 @@
1
1
  import { jsx as e, jsxs as T, Fragment as B } from "react/jsx-runtime";
2
2
  import E, { useState as w, useCallback as x, useEffect as M, forwardRef as Z, useMemo as V, useRef as q } from "react";
3
3
  import { T as F } from "../index-BVqs-uqP.js";
4
- import { u as H, a as me, S as Se } from "../SearchSelectTag-D1bFK1ux.js";
5
- import { b as ge, f as ee, C as te, c as re, d as ve, h as ye } from "../Command-BU9Ouar3.js";
4
+ import { u as H, a as me, S as Se } from "../SearchSelectTag-Ce-Q9JGR.js";
5
+ import { b as ge, f as ee, C as te, c as re, d as ve, h as ye } from "../Command-C_iW2joV.js";
6
6
  import { I as K } from "../Icon-DH3ev9GK.js";
7
- import { b as be, P as j, a as _ } from "../Popover-CkezMtEz.js";
8
- import { C as Ce, s as Ne } from "../Select-Bfrb-J8s.js";
7
+ import { b as be, P as j, a as _ } from "../Popover-DmwXZwYd.js";
8
+ import { C as Ce, s as Ne } from "../Select-CWbLja8r.js";
9
9
  import { C as Oe } from "../chevron-down-CAOItu8X.js";
10
10
  import { C as ne } from "../check-CeyaOoZv.js";
11
11
  import { L as ae } from "../Loader-BpHiL6W-.js";
@@ -1 +1 @@
1
- {"version":3,"file":"search-select.js","sources":["../../src/hooks/useSearchSelect.ts","../../src/components/search-select/components/SearchSelectTextValue.tsx","../../src/components/search-select/components/SearchSelectPlaceholder.tsx","../../src/components/search-select/components/SearchSelectTrigger.tsx","../../src/components/search-select/search-select/components/SearchSelectContent.tsx","../../src/components/search-select/search-select/components/SearchSelectInput.tsx","../../src/components/search-select/search-select/SearchSelect.tsx","../../src/components/search-select/search-select/components/LoadMoreTrigger.tsx","../../src/components/search-select/search-select/utils/fuzzyFilter.ts","../../src/components/search-select/search-select/LazySearchSelect.tsx","../../src/components/search-select/search-select/components/SearchSelectSeparator.tsx","../../src/components/search-select/async-search-select/hooks/useAsyncDataLoader.ts","../../src/components/search-select/async-search-select/components/AsyncSearchSelectContent.tsx","../../src/components/search-select/async-search-select/components/AsyncSearchSelectPopoverContent.tsx","../../src/components/search-select/async-search-select/AsyncSearchSelect.tsx","../../src/components/search-select/multi-select/MultiSelect.tsx"],"sourcesContent":["import { useCallback, useState, useEffect } from \"react\";\r\nimport { useControllableState } from \"./useControllableState\";\r\n\r\nexport interface SearchSelectOption {\r\n\t/** Уникальный идентификатор опции */\r\n\tvalue: string | number;\r\n\t/** Отображаемый текст */\r\n\tlabel: string;\r\n\t/** Состояние отключения опции */\r\n\tdisabled?: boolean;\r\n}\r\n\r\ninterface UseSearchSelectProps<T extends SearchSelectOption = SearchSelectOption> {\r\n\t/** Список опций */\r\n\toptions: T[];\r\n\t/** Текущее выбранное значение (controlled режим) */\r\n\tvalue?: T[\"value\"];\r\n\t/** Значение по умолчанию (uncontrolled режим) */\r\n\tdefaultValue?: T[\"value\"];\r\n\t/** Callback при выборе опции */\r\n\tonChange?: (value: T[\"value\"], option: T) => void;\r\n\t/**\r\n\t * Значение по умолчанию для выбранной опции. Используется, когда выбранная опция\r\n\t * отсутствует в текущем списке options. Это может произойти при изменении фильтра\r\n\t * или при использовании виртуальной (ленивой) загрузки данных.\r\n\t * */\r\n\tvalueOption?: T;\r\n}\r\n\r\nexport const useSearchSelect = <T extends SearchSelectOption = SearchSelectOption>({\r\n\toptions,\r\n\tvalue,\r\n\tdefaultValue,\r\n\tonChange,\r\n\tvalueOption\r\n}: UseSearchSelectProps<T>) => {\r\n\t// Сохраняем выбранную опцию отдельно, чтобы она не терялась при фильтрации\r\n\tconst [selectedOption, setSelectedOption] = useState<T | undefined>(undefined);\r\n\r\n\tconst memoizedOnChange = useCallback(\r\n\t\t(newValue: T[\"value\"] | undefined) => {\r\n\t\t\tif (newValue !== undefined) {\r\n\t\t\t\tconst option = options.find((option) => option.value === newValue) || selectedOption;\r\n\t\t\t\tif (option && option.value === newValue) {\r\n\t\t\t\t\tsetSelectedOption(option);\r\n\t\t\t\t\tonChange?.(newValue, option);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t},\r\n\t\t[onChange, options, selectedOption]\r\n\t);\r\n\r\n\tconst [selectedValue, setSelectedValue] = useControllableState<T[\"value\"] | undefined>({\r\n\t\tvalue,\r\n\t\tdefaultValue,\r\n\t\tonChange: memoizedOnChange\r\n\t});\r\n\r\n\t// Синхронизируем selectedOption с selectedValue при изменении selectedValue или options\r\n\tuseEffect(() => {\r\n\t\tif (selectedValue !== undefined) {\r\n\t\t\t// Если selectedOption уже соответствует selectedValue, ничего не делаем\r\n\t\t\tif (selectedOption && selectedOption.value === selectedValue) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// Ищем опцию в текущих options\r\n\t\t\tconst currentOption = options.find((option) => option.value === selectedValue);\r\n\t\t\tif (currentOption) {\r\n\t\t\t\tsetSelectedOption(currentOption);\r\n\t\t\t} else if (valueOption && valueOption.value === selectedValue) {\r\n\t\t\t\tsetSelectedOption(valueOption);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\tsetSelectedOption(undefined);\r\n\t\t}\r\n\t}, [selectedValue, options, selectedOption, valueOption]);\r\n\r\n\tconst setSelectedByLabel = useCallback(\r\n\t\t(label: string) => {\r\n\t\t\t// CommandItem работает с label, а не с value, поэтому нужно найти опцию по label\r\n\t\t\tconst option = options.find((option) => option.label === label);\r\n\t\t\tif (option) {\r\n\t\t\t\tsetSelectedValue(option.value);\r\n\t\t\t}\r\n\t\t},\r\n\t\t[setSelectedValue, options]\r\n\t);\r\n\r\n\treturn {\r\n\t\tselectedValue,\r\n\t\tselectedOption,\r\n\t\tsetSelectedByLabel,\r\n\t\tsetSelectedValue\r\n\t};\r\n};\r\n","import React from \"react\";\r\nimport { tv } from \"tailwind-variants\";\r\n\r\nconst searchSelectTextValueStyles = tv({\r\n\tbase: \"self-center pl-1.5\"\r\n});\r\n\r\ninterface SearchSelectTextValueProps {\r\n\tchildren: React.ReactNode;\r\n\tclassName?: string;\r\n}\r\n\r\nexport const SearchSelectTextValue: React.FC<SearchSelectTextValueProps> = ({ children, className }) => {\r\n\treturn <span className={searchSelectTextValueStyles({ className })}>{children}</span>;\r\n};\r\n","import React from \"react\";\r\nimport { tv } from \"tailwind-variants\";\r\n\r\nconst searchSelectPlaceholderStyles = tv({\r\n\tbase: \"pointer-events-none self-center pl-1.5 text-muted\"\r\n});\r\n\r\ninterface SearchSelectPlaceholderProps {\r\n\tchildren: React.ReactNode;\r\n\tclassName?: string;\r\n}\r\n\r\nexport const SearchSelectPlaceholder: React.FC<SearchSelectPlaceholderProps> = ({ children, className }) => {\r\n\treturn <span className={searchSelectPlaceholderStyles({ className })}>{children}</span>;\r\n};\r\n","import { Icon } from \"@/components/icon/Icon\";\r\nimport { selectTriggerStyles } from \"@/components/select/Select\";\r\nimport { ChevronDownIcon } from \"lucide-react\";\r\nimport React from \"react\";\r\nimport { tv } from \"tailwind-variants\";\r\nimport { SearchSelectPlaceholder } from \"./SearchSelectPlaceholder\";\r\nimport { ClearButton } from \"@/components/input/components/clear-button/ClearButton\";\r\n\r\nconst searchSelectTriggerStyles = tv({\r\n\textend: selectTriggerStyles,\r\n\tbase: \"group/search-select-trigger min-h-10 items-start py-1.5 pl-1.5 pr-3 lg:min-h-9 lg:py-1.5 lg:pl-1.5 lg:pr-2.5\",\r\n\tslots: {\r\n\t\tbuttonWrapper: \"ml-auto flex gap-2 pl-2.5\",\r\n\t\ticonWrapper: \"min-h-[1.375rem]\",\r\n\t\tstartIcon: \"flex min-h-[1.375rem] items-center pl-1.5 pr-0.5 text-muted\",\r\n\t\tclearButton: \"h-auto p-0\"\r\n\t}\r\n});\r\n\r\ninterface SearchSelectTriggerProps extends React.ComponentPropsWithoutRef<\"button\"> {\r\n\t/** Состояние отключения */\r\n\tdisabled?: boolean;\r\n\t/** Состояние ошибки */\r\n\tinvalid?: boolean;\r\n\t/** Текст placeholder */\r\n\tplaceholder?: string;\r\n\t/** Состояние открытия. Используется для проставления accessibility аттрибутов */\r\n\topen?: boolean;\r\n\t/** Иконка, отображаемая в начале текстового поля */\r\n\tstartIcon?: React.ReactNode;\r\n\t/** Callback при очистке значения */\r\n\tonClear?: () => void;\r\n}\r\n\r\n/**\r\n * Компонент отображения триггера для SearchSelect.\r\n * Выполняет роль кнопки, которая открывает Popover с опциями.\r\n * Может отображать значение или placeholder в зависимости от наличия дочерних элементов.\r\n * Не содержит сам триггер, а только стилизует кнопку.\r\n */\r\nexport const SearchSelectTrigger = React.forwardRef<HTMLButtonElement, SearchSelectTriggerProps>(\r\n\t({ className, children, disabled, open, invalid, placeholder, startIcon, onClear, ...props }, ref) => {\r\n\t\tconst styles = searchSelectTriggerStyles({ disabled, invalid });\r\n\r\n\t\treturn (\r\n\t\t\t<button\r\n\t\t\t\t{...props}\r\n\t\t\t\tdisabled={disabled}\r\n\t\t\t\tclassName={styles.base({ className })}\r\n\t\t\t\tref={ref}\r\n\t\t\t\trole=\"combobox\"\r\n\t\t\t\taria-expanded={open}\r\n\t\t\t\taria-invalid={invalid}\r\n\t\t\t\taria-haspopup=\"listbox\"\r\n\t\t\t>\r\n\t\t\t\t{startIcon && <div className={styles.startIcon()}>{startIcon}</div>}\r\n\t\t\t\t{children !== undefined ? children : <SearchSelectPlaceholder>{placeholder}</SearchSelectPlaceholder>}\r\n\t\t\t\t<div className={styles.buttonWrapper()}>\r\n\t\t\t\t\t{onClear && (\r\n\t\t\t\t\t\t<div className={styles.iconWrapper()}>\r\n\t\t\t\t\t\t\t<ClearButton\r\n\t\t\t\t\t\t\t\tclassName={styles.clearButton()}\r\n\t\t\t\t\t\t\t\tonClear={onClear}\r\n\t\t\t\t\t\t\t\tonPointerDown={(e) => {\r\n\t\t\t\t\t\t\t\t\te.stopPropagation();\r\n\t\t\t\t\t\t\t\t\te.preventDefault();\r\n\t\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t\t\tonKeyDown={(e) => {\r\n\t\t\t\t\t\t\t\t\tif (e.key === \"Enter\") {\r\n\t\t\t\t\t\t\t\t\t\tonClear();\r\n\t\t\t\t\t\t\t\t\t\te.stopPropagation();\r\n\t\t\t\t\t\t\t\t\t\te.preventDefault();\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t}}\r\n\t\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t)}\r\n\t\t\t\t\t{!disabled && (\r\n\t\t\t\t\t\t<div className={styles.iconWrapper()}>\r\n\t\t\t\t\t\t\t<Icon icon={ChevronDownIcon} className={styles.icon()} />\r\n\t\t\t\t\t\t</div>\r\n\t\t\t\t\t)}\r\n\t\t\t\t</div>\r\n\t\t\t</button>\r\n\t\t);\r\n\t}\r\n);\r\n\r\nSearchSelectTrigger.displayName = \"SearchSelectTrigger\";\r\n","import { PopoverContent } from \"@/components/popover\";\r\nimport React, { ComponentPropsWithoutRef } from \"react\";\r\nimport { tv } from \"tailwind-variants\";\r\n\r\ntype SearchSelectContentProps = ComponentPropsWithoutRef<typeof PopoverContent>;\r\n\r\nconst searchSelectContentStyles = tv({\r\n\tbase: \"w-full min-w-[var(--radix-popper-anchor-width)] border-secondary-border p-0\"\r\n});\r\n\r\n/**\r\n * Контейнер содержимого для SearchSelect.\r\n * Обертка вокруг PopoverContent с настроенными стилями и интеграцией с Command.\r\n * Планируется рефакторинг для вынесения input логики.\r\n */\r\nexport const SearchSelectContent = React.forwardRef<React.ElementRef<typeof PopoverContent>, SearchSelectContentProps>(\r\n\t({ className, children, ...props }, ref) => {\r\n\t\treturn (\r\n\t\t\t<PopoverContent ref={ref} className={searchSelectContentStyles({ className })} align=\"start\" {...props}>\r\n\t\t\t\t{children}\r\n\t\t\t</PopoverContent>\r\n\t\t);\r\n\t}\r\n);\r\n\r\nSearchSelectContent.displayName = \"SearchSelectContent\";\r\n","import { CommandInput } from \"@/components/command/Command\";\r\nimport { Command as CommandPrimitive } from \"cmdk\";\r\nimport React from \"react\";\r\n\r\nexport const SearchSelectInput = React.forwardRef<\r\n\tReact.ElementRef<typeof CommandPrimitive.Input>,\r\n\tReact.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>\r\n>(({ placeholder = \"Find\", ...props }, ref) => {\r\n\treturn <CommandInput ref={ref} placeholder={placeholder} {...props} />;\r\n});\r\n\r\nSearchSelectInput.displayName = \"SearchSelectInput\";\r\n","import { CheckIcon } from \"lucide-react\";\r\nimport { ComponentPropsWithoutRef, forwardRef, useCallback, useMemo, useState } from \"react\";\r\nimport { tv } from \"tailwind-variants\";\r\nimport { SearchSelectOption, useSearchSelect } from \"../../../hooks/useSearchSelect\";\r\nimport { Command, CommandEmpty, CommandItem, CommandList } from \"../../command/Command\";\r\nimport { Icon } from \"../../icon/Icon\";\r\nimport { Popover, PopoverTrigger } from \"../../popover\";\r\nimport { SearchSelectTextValue } from \"../components/SearchSelectTextValue\";\r\nimport { SearchSelectTrigger } from \"../components/SearchSelectTrigger\";\r\nimport { SearchSelectContent } from \"./components/SearchSelectContent\";\r\nimport { SearchSelectInput } from \"./components/SearchSelectInput\";\r\n\r\nconst searchSelectStyles = tv({ base: \"\" });\r\n\r\nexport type RenderOptionProps<T extends SearchSelectOption = SearchSelectOption> = {\r\n\t/** Отображаемая опция */\r\n\toption: T;\r\n} & (RenderOptionInTriggerProps | RenderOptionInListProps);\r\n\r\nexport type RenderOptionInTriggerProps = {\r\n\t/** Тип рендера. Если `trigger`, то опция рендерится в триггере в качестве текущего значения компонента. */\r\n\ttype: \"trigger\";\r\n};\r\n\r\nexport type RenderOptionInListProps = {\r\n\t/** Тип рендера. Если `list`, то опция рендерится в списке опций. */\r\n\ttype: \"list\";\r\n\t/** Выбрана ли опция в данный момент */\r\n\tisSelected: boolean;\r\n\t/** Отключена ли опция */\r\n\tisDisabled: boolean;\r\n\t/** Текущий поисковый запрос для подсветки совпадений */\r\n\tsearchQuery: string;\r\n\t/** Индекс элемента в списке */\r\n\tindex: number;\r\n};\r\n\r\ntype PopoverProps = ComponentPropsWithoutRef<typeof Popover>;\r\nexport interface SearchSelectProps<T extends SearchSelectOption = SearchSelectOption>\r\n\textends Omit<PopoverProps, \"children\"> {\r\n\t/** Идентификатор поля в форме. Позволяет связать компонент с полем формы. */\r\n\tid?: string;\r\n\t/** Событие blur */\r\n\tonBlur?: (e: React.FocusEvent<HTMLButtonElement>) => void;\r\n\t/** Дополнительные классы для контейнера */\r\n\tclassName?: string;\r\n\t/** Список опций */\r\n\toptions: T[];\r\n\t/** Значение по умолчанию для выбранной опции. Используется, когда выбранная опция\r\n\t * отсутствует в текущем списке options. Это может произойти при изменении фильтра\r\n\t * или при использовании виртуальной (ленивой) загрузки данных.\r\n\t * */\r\n\tvalueOption?: T;\r\n\t/**\r\n\t * Кастомная функция рендера опции.\r\n\t * Используется для отображения как в trigger (type: \"trigger\"), так и в списке (type: \"list\").\r\n\t */\r\n\trenderOption?: (props: RenderOptionProps<T>) => React.ReactNode;\r\n\t/** Текст placeholder, отображается когда ничего не выбрано */\r\n\tplaceholder?: string;\r\n\t/** Текущее выбранное значение (controlled режим) */\r\n\tvalue?: T[\"value\"];\r\n\t/** Значение по умолчанию (uncontrolled режим) */\r\n\tdefaultValue?: T[\"value\"];\r\n\t/** Callback при выборе опции */\r\n\tonChange?: (value: T[\"value\"], option: T) => void;\r\n\t/** Callback при очистке значения */\r\n\tonClear?: () => void;\r\n\t/** Состояние отключения */\r\n\tdisabled?: boolean;\r\n\t/** Состояние ошибки */\r\n\tinvalid?: boolean;\r\n\t/** Текст placeholder для поиска */\r\n\tsearchPlaceholder?: string;\r\n\t/** Текст для пустого состояния */\r\n\temptyText?: string;\r\n\t/** Использовать встроенную фильтрацию cmdk. По умолчанию true */\r\n\tshouldFilter?: boolean;\r\n\t/** Контент, отображаемый в конце списка (например, для триггера загрузки) */\r\n\tfooterContent?: React.ReactNode;\r\n\t/** Callback при изменении поискового запроса */\r\n\tonSearchChange?: (value: string) => void;\r\n\t/** Callback при изменении состояния открытия */\r\n\tonOpenChange?: (open: boolean) => void;\r\n\t/** Иконка, отображаемая в начале поля */\r\n\tstartIcon?: React.ReactNode;\r\n\t/** Скрыть поле поиска */\r\n\thideSearch?: boolean;\r\n}\r\n\r\nexport const SearchSelect = forwardRef(\r\n\t<T extends SearchSelectOption = SearchSelectOption>(\r\n\t\tprops: SearchSelectProps<T>,\r\n\t\tref: React.ForwardedRef<HTMLButtonElement>\r\n\t) => {\r\n\t\tconst {\r\n\t\t\tid,\r\n\t\t\tclassName,\r\n\t\t\toptions,\r\n\t\t\tvalueOption,\r\n\t\t\trenderOption,\r\n\t\t\tplaceholder = \"Выберите значение\",\r\n\t\t\tvalue,\r\n\t\t\tdefaultValue,\r\n\t\t\tonBlur,\r\n\t\t\tonChange,\r\n\t\t\tonClear,\r\n\t\t\tdisabled,\r\n\t\t\tinvalid,\r\n\t\t\tsearchPlaceholder = \"Найти\",\r\n\t\t\temptyText = \"Результатов не найдено\",\r\n\t\t\tshouldFilter = true,\r\n\t\t\tfooterContent,\r\n\t\t\tonSearchChange,\r\n\t\t\tonOpenChange,\r\n\t\t\tstartIcon,\r\n\t\t\thideSearch,\r\n\t\t\t...popoverProps\r\n\t\t} = props;\r\n\r\n\t\tconst [open, setOpen] = useState(false);\r\n\t\tconst [searchQuery, setSearchQuery] = useState(\"\");\r\n\r\n\t\tconst { selectedValue, selectedOption, setSelectedByLabel } = useSearchSelect({\r\n\t\t\toptions,\r\n\t\t\tvalue,\r\n\t\t\tdefaultValue,\r\n\t\t\tvalueOption,\r\n\t\t\tonChange\r\n\t\t});\r\n\r\n\t\tconst handleSelect = useCallback(\r\n\t\t\t(label: string) => {\r\n\t\t\t\tsetSelectedByLabel(label);\r\n\t\t\t\tsetOpen(false);\r\n\t\t\t},\r\n\t\t\t[setSelectedByLabel, setOpen]\r\n\t\t);\r\n\r\n\t\tconst handleSearchChange = useCallback(\r\n\t\t\t(value: string) => {\r\n\t\t\t\tsetSearchQuery(value);\r\n\t\t\t\tonSearchChange?.(value);\r\n\t\t\t},\r\n\t\t\t[onSearchChange]\r\n\t\t);\r\n\r\n\t\tconst handleOpenChange = useCallback(\r\n\t\t\t(open: boolean) => {\r\n\t\t\t\tsetOpen(open);\r\n\t\t\t\tonOpenChange?.(open);\r\n\t\t\t},\r\n\t\t\t[onOpenChange]\r\n\t\t);\r\n\r\n\t\tconst displayValue = useMemo(() => {\r\n\t\t\tif (!selectedOption) return undefined;\r\n\t\t\tif (renderOption) {\r\n\t\t\t\tconst item = renderOption({ option: selectedOption, type: \"trigger\" });\r\n\t\t\t\tif (item !== undefined) {\r\n\t\t\t\t\treturn item;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn <SearchSelectTextValue>{selectedOption.label}</SearchSelectTextValue>;\r\n\t\t}, [selectedOption, renderOption]);\r\n\r\n\t\tconst renderedOptions = useMemo(() => {\r\n\t\t\treturn options.map((option, index) => {\r\n\t\t\t\tconst isDisabled = option.disabled ?? false;\r\n\t\t\t\tconst isSelected = selectedValue === option.value;\r\n\r\n\t\t\t\tconst renderOptionItem = () => {\r\n\t\t\t\t\tif (renderOption) {\r\n\t\t\t\t\t\tconst customRender = renderOption({\r\n\t\t\t\t\t\t\toption,\r\n\t\t\t\t\t\t\ttype: \"list\",\r\n\t\t\t\t\t\t\tisSelected,\r\n\t\t\t\t\t\t\tisDisabled,\r\n\t\t\t\t\t\t\tsearchQuery,\r\n\t\t\t\t\t\t\tindex\r\n\t\t\t\t\t\t});\r\n\t\t\t\t\t\tif (customRender !== undefined) {\r\n\t\t\t\t\t\t\treturn customRender;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\treturn (\r\n\t\t\t\t\t\t<>\r\n\t\t\t\t\t\t\t{option.label}\r\n\t\t\t\t\t\t\t{isSelected && <Icon icon={CheckIcon} className=\"ml-auto\" />}\r\n\t\t\t\t\t\t</>\r\n\t\t\t\t\t);\r\n\t\t\t\t};\r\n\r\n\t\t\t\treturn (\r\n\t\t\t\t\t<CommandItem\r\n\t\t\t\t\t\tkey={option.value}\r\n\t\t\t\t\t\tvalue={option.label}\r\n\t\t\t\t\t\tonSelect={isDisabled ? undefined : handleSelect}\r\n\t\t\t\t\t\tdisabled={isDisabled}\r\n\t\t\t\t\t>\r\n\t\t\t\t\t\t{renderOptionItem()}\r\n\t\t\t\t\t</CommandItem>\r\n\t\t\t\t);\r\n\t\t\t});\r\n\t\t}, [options, selectedValue, handleSelect, renderOption, searchQuery]);\r\n\r\n\t\treturn (\r\n\t\t\t<Popover {...popoverProps} open={open} onOpenChange={handleOpenChange}>\r\n\t\t\t\t<div className={searchSelectStyles({ className })}>\r\n\t\t\t\t\t<PopoverTrigger asChild>\r\n\t\t\t\t\t\t<SearchSelectTrigger\r\n\t\t\t\t\t\t\tonClear={onClear}\r\n\t\t\t\t\t\t\tdisabled={disabled}\r\n\t\t\t\t\t\t\tinvalid={invalid}\r\n\t\t\t\t\t\t\topen={open}\r\n\t\t\t\t\t\t\tplaceholder={placeholder}\r\n\t\t\t\t\t\t\tid={id}\r\n\t\t\t\t\t\t\tonBlur={onBlur}\r\n\t\t\t\t\t\t\tref={ref}\r\n\t\t\t\t\t\t\tstartIcon={startIcon}\r\n\t\t\t\t\t\t>\r\n\t\t\t\t\t\t\t{displayValue}\r\n\t\t\t\t\t\t</SearchSelectTrigger>\r\n\t\t\t\t\t</PopoverTrigger>\r\n\t\t\t\t\t<SearchSelectContent>\r\n\t\t\t\t\t\t<Command shouldFilter={shouldFilter}>\r\n\t\t\t\t\t\t\t{!hideSearch && (\r\n\t\t\t\t\t\t\t\t<SearchSelectInput placeholder={searchPlaceholder} onValueChange={handleSearchChange} />\r\n\t\t\t\t\t\t\t)}\r\n\t\t\t\t\t\t\t<CommandList key={`list-${searchQuery}`} className=\"p-1\">\r\n\t\t\t\t\t\t\t\t{renderedOptions}\r\n\t\t\t\t\t\t\t\t<CommandEmpty>{emptyText}</CommandEmpty>\r\n\t\t\t\t\t\t\t\t{footerContent}\r\n\t\t\t\t\t\t\t</CommandList>\r\n\t\t\t\t\t\t</Command>\r\n\t\t\t\t\t</SearchSelectContent>\r\n\t\t\t\t</div>\r\n\t\t\t</Popover>\r\n\t\t);\r\n\t}\r\n) as (<T extends SearchSelectOption = SearchSelectOption>(\r\n\tprops: SearchSelectProps<T> & { ref?: React.ForwardedRef<HTMLButtonElement> }\r\n) => React.ReactElement) & { displayName?: string };\r\n\r\nSearchSelect.displayName = \"SearchSelect\";\r\n","import { Loader } from \"@/components/loader\";\r\nimport React, { useEffect, useRef } from \"react\";\r\nimport { tv } from \"tailwind-variants\";\r\n\r\nconst loadMoreTriggerStyles = tv({\r\n\tbase: \"py-2 text-center text-sm text-muted-foreground\"\r\n});\r\n\r\nexport interface LoadMoreTriggerProps {\r\n\t/** Callback, который вызывается когда триггер становится видимым */\r\n\tonLoad: () => void;\r\n\t/** Есть ли еще элементы для загрузки */\r\n\thasMore: boolean;\r\n\t/** Текст индикатора загрузки */\r\n\tloadingText?: string;\r\n\t/** Дополнительные CSS классы */\r\n\tclassName?: string;\r\n}\r\n\r\n/**\r\n * Компонент для автоматической загрузки дополнительных элементов при прокрутке.\r\n * Отображает индикатор загрузки и автоматически вызывает `onLoad` когда пользователь\r\n * доскроллит до этого элемента.\r\n */\r\nexport const LoadMoreTrigger = React.forwardRef<HTMLDivElement, LoadMoreTriggerProps>(\r\n\t({ onLoad, hasMore, loadingText = \"Загрузка...\", className }, ref) => {\r\n\t\tconst triggerRef = useRef<HTMLDivElement>(null);\r\n\t\tconst styles = loadMoreTriggerStyles({ className });\r\n\r\n\t\tReact.useImperativeHandle(ref, () => triggerRef.current as HTMLDivElement);\r\n\r\n\t\tuseEffect(() => {\r\n\t\t\tconst trigger = triggerRef.current;\r\n\t\t\tif (!trigger || !hasMore) return;\r\n\r\n\t\t\tconst observer = new IntersectionObserver(\r\n\t\t\t\t([entry]) => {\r\n\t\t\t\t\tif (entry.isIntersecting) {\r\n\t\t\t\t\t\tonLoad();\r\n\t\t\t\t\t}\r\n\t\t\t\t},\r\n\t\t\t\t{ rootMargin: \"50px\" }\r\n\t\t\t);\r\n\r\n\t\t\tobserver.observe(trigger);\r\n\r\n\t\t\treturn () => {\r\n\t\t\t\tobserver.disconnect();\r\n\t\t\t};\r\n\t\t}, [onLoad, hasMore]);\r\n\r\n\t\tif (!hasMore) return null;\r\n\r\n\t\treturn (\r\n\t\t\t<div ref={triggerRef} className={styles}>\r\n\t\t\t\t<Loader className=\"flex-row\">{loadingText}</Loader>\r\n\t\t\t</div>\r\n\t\t);\r\n\t}\r\n);\r\n\r\nLoadMoreTrigger.displayName = \"LoadMoreTrigger\";\r\n","/**\r\n * Простой fuzzy filter для поиска\r\n * Возвращает число от 0 до 3, где большее число означает лучшее совпадение\r\n */\r\nexport const defaultFuzzyFilter = (value: string, search: string): number => {\r\n\tif (!search.trim()) return 1; // Пустой поиск - показываем все\r\n\r\n\tconst valueLower = value.toLowerCase().trim();\r\n\tconst searchLower = search.toLowerCase().trim();\r\n\r\n\t// Точное совпадение с началом - наивысший приоритет\r\n\tif (valueLower.startsWith(searchLower)) return 3;\r\n\r\n\t// Содержит подстроку - высокий приоритет\r\n\tif (valueLower.includes(searchLower)) return 2;\r\n\r\n\t// Fuzzy match - проверяем, что все символы поиска есть в правильном порядке\r\n\tlet searchIndex = 0;\r\n\tfor (let i = 0; i < valueLower.length && searchIndex < searchLower.length; i++) {\r\n\t\tif (valueLower[i] === searchLower[searchIndex]) {\r\n\t\t\tsearchIndex++;\r\n\t\t}\r\n\t}\r\n\r\n\t// Если нашли все символы поиска в правильном порядке - низкий приоритет\r\n\treturn searchIndex === searchLower.length ? 1 : 0;\r\n};\r\n\r\n/**\r\n * Тип функции фильтрации\r\n */\r\nexport type FilterFunction = (value: string, search: string) => number;\r\n","import { forwardRef, useCallback, useEffect, useMemo, useState } from \"react\";\r\nimport { SearchSelect, SearchSelectProps } from \"./SearchSelect\";\r\nimport { SearchSelectOption } from \"../../../hooks/useSearchSelect\";\r\nimport { LoadMoreTrigger } from \"./components/LoadMoreTrigger\";\r\nimport { defaultFuzzyFilter, FilterFunction } from \"./utils/fuzzyFilter\";\r\n\r\nexport interface LazySearchSelectProps<T extends SearchSelectOption = SearchSelectOption>\r\n\textends Omit<\r\n\t\tSearchSelectProps<T>,\r\n\t\t\"options\" | \"shouldFilter\" | \"footerContent\" | \"onSearchChange\" | \"valueOption\"\r\n\t> {\r\n\t/** Полный список опций */\r\n\toptions: T[];\r\n\t/** Количество элементов на странице */\r\n\tpageSize?: number;\r\n\t/** Кастомная функция фильтрации. По умолчанию используется встроенный fuzzy search */\r\n\tfilter?: FilterFunction;\r\n}\r\n\r\nexport const LazySearchSelect = forwardRef<HTMLButtonElement, LazySearchSelectProps>(\r\n\t<T extends SearchSelectOption = SearchSelectOption>(\r\n\t\tprops: LazySearchSelectProps<T>,\r\n\t\tref: React.ForwardedRef<HTMLButtonElement>\r\n\t) => {\r\n\t\tconst {\r\n\t\t\toptions,\r\n\t\t\tpageSize = 50,\r\n\t\t\tfilter = defaultFuzzyFilter,\r\n\t\t\tdefaultValue,\r\n\t\t\tvalue,\r\n\t\t\t...searchSelectProps\r\n\t\t} = props;\r\n\r\n\t\tconst [visibleCount, setVisibleCount] = useState(pageSize);\r\n\t\tconst [searchQuery, setSearchQuery] = useState(\"\");\r\n\t\tconst [valueOption, setValueOption] = useState<T | undefined>(undefined);\r\n\r\n\t\t// При изменении поиска сбрасываем счетчик видимых элементов\r\n\t\tuseEffect(() => setVisibleCount(pageSize), [searchQuery, pageSize]);\r\n\r\n\t\tuseEffect(() => {\r\n\t\t\tconst currentValue = value || defaultValue;\r\n\t\t\tif (currentValue && !valueOption) {\r\n\t\t\t\tsetValueOption(options.find((option) => option.value === currentValue));\r\n\t\t\t}\r\n\t\t}, [defaultValue, value, options, valueOption]);\r\n\r\n\t\t// Фильтрация и ограничение элементов\r\n\t\tconst { visibleOptions, hasMoreItems } = useMemo(() => {\r\n\t\t\t// Сначала фильтруем и ранжируем по поисковому запросу\r\n\t\t\tconst filteredAndRanked = searchQuery\r\n\t\t\t\t? options\r\n\t\t\t\t\t\t.map((option) => ({\r\n\t\t\t\t\t\t\toption,\r\n\t\t\t\t\t\t\tscore: filter(option.label, searchQuery)\r\n\t\t\t\t\t\t}))\r\n\t\t\t\t\t\t.filter(({ score }) => score > 0) // Убираем элементы с нулевым скором\r\n\t\t\t\t\t\t.sort((a, b) => b.score - a.score) // Сортируем по убыванию скора\r\n\t\t\t\t\t\t.map(({ option }) => option)\r\n\t\t\t\t: options;\r\n\r\n\t\t\t// Затем ограничиваем количество видимых элементов\r\n\t\t\tconst visible = filteredAndRanked.slice(0, visibleCount);\r\n\t\t\tconst hasMore = visibleCount < filteredAndRanked.length;\r\n\r\n\t\t\treturn {\r\n\t\t\t\tvisibleOptions: visible,\r\n\t\t\t\thasMoreItems: hasMore\r\n\t\t\t};\r\n\t\t}, [options, searchQuery, visibleCount, filter]);\r\n\r\n\t\t// Обработчик загрузки следующей порции\r\n\t\tconst handleLoadMore = useCallback(() => {\r\n\t\t\tsetVisibleCount((prev) => prev + pageSize);\r\n\t\t}, [pageSize]);\r\n\r\n\t\tconst handleSearchChange = useCallback((value: string) => {\r\n\t\t\tsetSearchQuery(value);\r\n\t\t}, []);\r\n\r\n\t\t// Сброс поиска при открытии\r\n\t\tconst handleOpenChange = useCallback(\r\n\t\t\t(open: boolean) => {\r\n\t\t\t\tif (open && searchQuery) setSearchQuery(\"\");\r\n\t\t\t},\r\n\t\t\t[searchQuery, setSearchQuery]\r\n\t\t);\r\n\r\n\t\treturn (\r\n\t\t\t<SearchSelect<T>\r\n\t\t\t\t{...searchSelectProps}\r\n\t\t\t\tref={ref}\r\n\t\t\t\toptions={visibleOptions}\r\n\t\t\t\tvalue={value}\r\n\t\t\t\tdefaultValue={defaultValue}\r\n\t\t\t\tvalueOption={valueOption}\r\n\t\t\t\tshouldFilter={false}\r\n\t\t\t\tfooterContent={<LoadMoreTrigger onLoad={handleLoadMore} hasMore={hasMoreItems} />}\r\n\t\t\t\tonSearchChange={handleSearchChange}\r\n\t\t\t\tonOpenChange={handleOpenChange}\r\n\t\t\t/>\r\n\t\t);\r\n\t}\r\n) as (<T extends SearchSelectOption = SearchSelectOption>(\r\n\tprops: LazySearchSelectProps<T> & { ref?: React.ForwardedRef<HTMLButtonElement> }\r\n) => React.ReactElement) & { displayName?: string };\r\n\r\nLazySearchSelect.displayName = \"LazySearchSelect\";\r\n","import React from \"react\";\r\nimport { CommandSeparator } from \"@/components/command/Command\";\r\nimport { ComponentPropsWithoutRef } from \"react\";\r\nimport { Command as CommandPrimitive } from \"cmdk\";\r\n\r\ntype SearchSelectSeparatorProps = ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>;\r\n\r\n/**\r\n * Разделитель для SearchSelect.\r\n * Простая обертка вокруг CommandSeparator.\r\n */\r\nexport const SearchSelectSeparator = React.forwardRef<\r\n\tReact.ElementRef<typeof CommandPrimitive.Separator>,\r\n\tSearchSelectSeparatorProps\r\n>((props, ref) => {\r\n\treturn <CommandSeparator ref={ref} {...props} />;\r\n});\r\n\r\nSearchSelectSeparator.displayName = \"SearchSelectSeparator\";\r\n","import { useCallback, useEffect, useRef, useState } from \"react\";\r\n\r\nexport type LoadingState = \"idle\" | \"loading\" | \"success\" | \"error\";\r\n\r\nexport interface LoadOptionsParams {\r\n\tsearchQuery: string;\r\n\tsignal?: AbortSignal;\r\n}\r\n\r\nexport interface LoadOptionsResult<T> {\r\n\toptions: T[];\r\n}\r\n\r\ninterface UseAsyncDataLoaderOptions<T> {\r\n\t/** Функция загрузки данных */\r\n\tloadOptions: (params: LoadOptionsParams) => Promise<LoadOptionsResult<T>>;\r\n}\r\n\r\ninterface UseAsyncDataLoaderReturn<T> {\r\n\t/** Текущие загруженные элементы */\r\n\toptions: T[];\r\n\t/** Состояние загрузки */\r\n\tloadingState: LoadingState;\r\n\t/** Текст ошибки, если загрузка не удалась */\r\n\terror: string | null;\r\n\t/** Функция загрузки данных */\r\n\tloadData: (query: string) => Promise<void>;\r\n\t/** Функция отмены текущих запросов */\r\n\tcancelRequests: () => void;\r\n}\r\n\r\n/**\r\n * Хук для асинхронной загрузки данных с защитой от race conditions\r\n *\r\n * Решает следующие проблемы:\r\n * - Race conditions при быстром вводе пользователя\r\n * - Мерцание интерфейса из-за множественных запросов\r\n * - Неправильный порядок получения ответов от сервера\r\n * - Обработка отмены запросов при размонтировании компонента\r\n *\r\n * @example\r\n * ```tsx\r\n * const { options, loadingState, loadData } = useAsyncDataLoader({\r\n * loadOptions: async ({ searchQuery }) => {\r\n * const response = await fetch(`/api/search?q=${searchQuery}`);\r\n * return response.json();\r\n * }\r\n * });\r\n *\r\n * // Загрузить данные\r\n * loadData(\"search query\");\r\n * ```\r\n */\r\nexport const useAsyncDataLoader = <T>({ loadOptions }: UseAsyncDataLoaderOptions<T>): UseAsyncDataLoaderReturn<T> => {\r\n\tconst [options, setItems] = useState<T[]>([]);\r\n\tconst [loadingState, setLoadingState] = useState<LoadingState>(\"idle\");\r\n\tconst [error, setError] = useState<string | null>(null);\r\n\r\n\t// Refs для управления race conditions\r\n\tconst abortControllerRef = useRef<AbortController | null>(null);\r\n\tconst requestSequenceRef = useRef(0);\r\n\r\n\t// Функция для отмены предыдущих запросов\r\n\tconst cancelRequests = useCallback(() => {\r\n\t\tif (abortControllerRef.current) {\r\n\t\t\tabortControllerRef.current.abort();\r\n\t\t}\r\n\t}, []);\r\n\r\n\t// Основная функция загрузки данных\r\n\tconst loadData = useCallback(\r\n\t\tasync (query: string) => {\r\n\t\t\t// Отменяем предыдущие запросы\r\n\t\t\tcancelRequests();\r\n\r\n\t\t\t// Увеличиваем sequence для отслеживания порядка\r\n\t\t\tconst currentSequence = ++requestSequenceRef.current;\r\n\r\n\t\t\t// Создаем новый AbortController\r\n\t\t\tconst abortController = new AbortController();\r\n\t\t\tabortControllerRef.current = abortController;\r\n\r\n\t\t\tsetLoadingState(\"loading\");\r\n\t\t\tsetError(null);\r\n\r\n\t\t\ttry {\r\n\t\t\t\tconst result = await loadOptions({\r\n\t\t\t\t\tsearchQuery: query,\r\n\t\t\t\t\tsignal: abortController.signal\r\n\t\t\t\t});\r\n\r\n\t\t\t\t// Проверяем, что запрос еще актуален\r\n\t\t\t\tif (currentSequence !== requestSequenceRef.current) return;\r\n\r\n\t\t\t\tsetItems(result.options);\r\n\t\t\t\tsetLoadingState(\"success\");\r\n\t\t\t} catch (err) {\r\n\t\t\t\t// Игнорируем AbortError - это нормальная отмена\r\n\t\t\t\tif (err instanceof Error && err.name === \"AbortError\") return;\r\n\t\t\t\tif (currentSequence !== requestSequenceRef.current) return;\r\n\r\n\t\t\t\tsetError(err instanceof Error ? err.message : \"Неизвестная ошибка\");\r\n\t\t\t\tsetLoadingState(\"error\");\r\n\t\t\t}\r\n\t\t},\r\n\t\t[loadOptions, cancelRequests]\r\n\t);\r\n\r\n\t// Cleanup при размонтировании компонента\r\n\tuseEffect(() => {\r\n\t\treturn () => cancelRequests();\r\n\t}, [cancelRequests]);\r\n\r\n\treturn {\r\n\t\toptions,\r\n\t\tloadingState,\r\n\t\terror,\r\n\t\tloadData,\r\n\t\tcancelRequests\r\n\t};\r\n};\r\n","import { EmptyState } from \"@/components/empty-state\";\r\nimport { ErrorState } from \"@/components/error-state\";\r\nimport { HintState } from \"@/components/hint-state\";\r\nimport { Loader } from \"@/components/loader\";\r\nimport { CheckIcon } from \"lucide-react\";\r\nimport { useMemo, useCallback } from \"react\";\r\nimport { CommandItem } from \"../../../command/Command\";\r\nimport { Icon } from \"../../../icon/Icon\";\r\nimport type { LoadingState, RenderOptionProps, SearchSelectOption } from \"../types\";\r\nimport React from \"react\";\r\n\r\ninterface AsyncSearchSelectContentProps<T extends SearchSelectOption = SearchSelectOption> {\r\n\t/** Текущие опции для отображения */\r\n\toptions: T[];\r\n\t/** Состояние загрузки */\r\n\tloadingState: LoadingState;\r\n\t/** Текст ошибки, если есть */\r\n\terror: string | null;\r\n\t/** Функция проверки выбранности элемента */\r\n\tisSelected?: (value: T) => boolean;\r\n\t/** Текущий поисковый запрос */\r\n\tsearchQuery: string;\r\n\t/** Режим загрузки */\r\n\tloadMode: \"auto\" | \"input\";\r\n\t/** Минимальная длина запроса для режима input */\r\n\tminInputLength: number;\r\n\t/** Функция обработки выбора опции */\r\n\tonSelect: (label: string) => void;\r\n\t/** Кастомная функция рендера опции */\r\n\trenderOption?: (props: RenderOptionProps<T>) => React.ReactNode;\r\n\t/** Текст во время загрузки */\r\n\tloadingText: string;\r\n\t/** Текст при ошибке загрузки */\r\n\terrorText: string;\r\n\t/** Текст подсказки для ввода */\r\n\tinputHintText: string;\r\n\t/** Текст для пустого состояния */\r\n\temptyText: string;\r\n}\r\n\r\n/**\r\n * Компонент для рендера содержимого AsyncSearchSelect\r\n *\r\n * Отвечает за отображение разных состояний:\r\n * - Загрузка\r\n * - Ошибка\r\n * - Подсказка для ввода\r\n * - Пустое состояние\r\n * - Список опций\r\n */\r\nexport const AsyncSearchSelectContent = <T extends SearchSelectOption = SearchSelectOption>({\r\n\toptions,\r\n\tloadingState,\r\n\terror,\r\n\tisSelected,\r\n\tsearchQuery,\r\n\tloadMode,\r\n\tminInputLength,\r\n\tonSelect,\r\n\trenderOption,\r\n\tloadingText,\r\n\terrorText,\r\n\tinputHintText,\r\n\temptyText\r\n}: AsyncSearchSelectContentProps<T>) => {\r\n\t// Мемоизируем опции с предвычисленным состоянием выбранности\r\n\tconst optionsWithSelection = useMemo(() => {\r\n\t\treturn options.map((option, index) => ({\r\n\t\t\toption,\r\n\t\t\tindex,\r\n\t\t\tisSelected: isSelected?.(option) ?? false,\r\n\t\t\tisDisabled: option.disabled ?? false\r\n\t\t}));\r\n\t}, [options, isSelected]);\r\n\r\n\tconst renderOptionItem = useCallback(\r\n\t\t({\r\n\t\t\toption,\r\n\t\t\tisSelected: selected,\r\n\t\t\tisDisabled: disabled,\r\n\t\t\tindex\r\n\t\t}: {\r\n\t\t\toption: T;\r\n\t\t\tisSelected: boolean;\r\n\t\t\tisDisabled: boolean;\r\n\t\t\tindex: number;\r\n\t\t}) => {\r\n\t\t\tif (renderOption) {\r\n\t\t\t\tconst customRender = renderOption({\r\n\t\t\t\t\toption,\r\n\t\t\t\t\ttype: \"list\",\r\n\t\t\t\t\tisSelected: selected,\r\n\t\t\t\t\tisDisabled: disabled,\r\n\t\t\t\t\tsearchQuery,\r\n\t\t\t\t\tindex\r\n\t\t\t\t});\r\n\t\t\t\tif (customRender !== undefined) {\r\n\t\t\t\t\treturn customRender;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn (\r\n\t\t\t\t<>\r\n\t\t\t\t\t{option.label}\r\n\t\t\t\t\t{selected && <Icon icon={CheckIcon} className=\"ml-auto\" />}\r\n\t\t\t\t</>\r\n\t\t\t);\r\n\t\t},\r\n\t\t[renderOption, searchQuery]\r\n\t);\r\n\r\n\t// Состояние ошибки\r\n\tif (loadingState === \"error\") {\r\n\t\treturn <ErrorState className=\"py-6\">{error || errorText}</ErrorState>;\r\n\t}\r\n\r\n\t// Состояние загрузки\r\n\tif (loadingState === \"loading\") {\r\n\t\treturn <Loader className=\"py-6\">{loadingText}</Loader>;\r\n\t}\r\n\r\n\t// Подсказка для режима input\r\n\tif (loadMode === \"input\" && searchQuery.length < minInputLength) {\r\n\t\treturn <HintState className=\"py-6\">{inputHintText}</HintState>;\r\n\t}\r\n\r\n\t// Пустое состояние\r\n\tif (options.length === 0 && loadingState === \"success\") {\r\n\t\treturn <EmptyState className=\"py-6\">{emptyText}</EmptyState>;\r\n\t}\r\n\r\n\t// Список опций\r\n\treturn (\r\n\t\t<>\r\n\t\t\t{optionsWithSelection.map(({ option, index, isSelected: selected, isDisabled: disabled }) => (\r\n\t\t\t\t<CommandItem\r\n\t\t\t\t\tkey={option.value}\r\n\t\t\t\t\tvalue={option.label}\r\n\t\t\t\t\tonSelect={disabled ? undefined : onSelect}\r\n\t\t\t\t\tdisabled={disabled}\r\n\t\t\t\t>\r\n\t\t\t\t\t{renderOptionItem({\r\n\t\t\t\t\t\toption,\r\n\t\t\t\t\t\tisSelected: selected,\r\n\t\t\t\t\t\tisDisabled: disabled,\r\n\t\t\t\t\t\tindex\r\n\t\t\t\t\t})}\r\n\t\t\t\t</CommandItem>\r\n\t\t\t))}\r\n\t\t</>\r\n\t);\r\n};\r\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\r\nimport { useDebounce } from \"../../../../hooks/useDebounce\";\r\nimport { Command, CommandList } from \"../../../command/Command\";\r\nimport { SearchSelectInput } from \"../../search-select/components/SearchSelectInput\";\r\nimport { useAsyncDataLoader } from \"../hooks/useAsyncDataLoader\";\r\nimport type { AsyncSearchSelectProps, SearchSelectOption } from \"../types\";\r\nimport { AsyncSearchSelectContent } from \"./AsyncSearchSelectContent\";\r\n\r\ninterface AsyncSearchSelectPopoverContentProps<T extends SearchSelectOption = SearchSelectOption>\r\n\textends Pick<\r\n\t\tAsyncSearchSelectProps<T>,\r\n\t\t| \"loadOptions\"\r\n\t\t| \"loadMode\"\r\n\t\t| \"minInputLength\"\r\n\t\t| \"debounceMs\"\r\n\t\t| \"searchPlaceholder\"\r\n\t\t| \"loadingText\"\r\n\t\t| \"errorText\"\r\n\t\t| \"inputHintText\"\r\n\t\t| \"emptyText\"\r\n\t\t| \"renderOption\"\r\n\t\t| \"hideSearch\"\r\n\t> {\r\n\tonSelect: (value: T | null) => void;\r\n\tisSelected?: (value: T) => boolean;\r\n}\r\n\r\nexport const AsyncSearchSelectPopoverContent = <T extends SearchSelectOption = SearchSelectOption>(\r\n\tprops: AsyncSearchSelectPopoverContentProps<T>\r\n) => {\r\n\tconst {\r\n\t\tloadOptions,\r\n\t\tloadMode = \"auto\",\r\n\t\tminInputLength = 3,\r\n\t\tdebounceMs = 300,\r\n\t\tsearchPlaceholder = \"Найти\",\r\n\t\tloadingText = \"Загружаем...\",\r\n\t\terrorText = \"Ошибка загрузки\",\r\n\t\tinputHintText = \"Введите текст для поиска\",\r\n\t\temptyText = \"Результатов не найдено\",\r\n\t\trenderOption,\r\n\t\tonSelect,\r\n\t\tisSelected,\r\n\t\thideSearch\r\n\t} = props;\r\n\r\n\tconst [searchQuery, setSearchQuery] = useState(\"\");\r\n\r\n\t// Дебаунсированный поисковый запрос для загрузки данных\r\n\tconst debouncedSearchQuery = useDebounce(searchQuery, debounceMs);\r\n\r\n\tconst { options, loadingState, error, loadData } = useAsyncDataLoader<T>({\r\n\t\tloadOptions\r\n\t});\r\n\r\n\tconst shouldLoad = useMemo(() => {\r\n\t\tif (loadMode === \"auto\") return true;\r\n\t\tif (loadMode === \"input\") return debouncedSearchQuery.length >= minInputLength;\r\n\t\treturn false;\r\n\t}, [loadMode, debouncedSearchQuery, minInputLength]);\r\n\r\n\t// Загрузка при изменении условий\r\n\tuseEffect(() => {\r\n\t\tif (shouldLoad) loadData(debouncedSearchQuery);\r\n\t}, [shouldLoad, debouncedSearchQuery, loadData]);\r\n\r\n\tconst handleSelect = useCallback(\r\n\t\t(label: string) => {\r\n\t\t\tonSelect(options.find((option) => option.label === label) || null);\r\n\t\t},\r\n\t\t[onSelect, options]\r\n\t);\r\n\r\n\treturn (\r\n\t\t<Command shouldFilter={false}>\r\n\t\t\t{!hideSearch && <SearchSelectInput placeholder={searchPlaceholder} onValueChange={setSearchQuery} />}\r\n\t\t\t<CommandList key={`list-${debouncedSearchQuery}`} className=\"p-1\">\r\n\t\t\t\t<AsyncSearchSelectContent\r\n\t\t\t\t\toptions={options}\r\n\t\t\t\t\tloadingState={loadingState}\r\n\t\t\t\t\terror={error}\r\n\t\t\t\t\tisSelected={isSelected}\r\n\t\t\t\t\tsearchQuery={debouncedSearchQuery}\r\n\t\t\t\t\tloadMode={loadMode}\r\n\t\t\t\t\tminInputLength={minInputLength}\r\n\t\t\t\t\tonSelect={handleSelect}\r\n\t\t\t\t\trenderOption={renderOption}\r\n\t\t\t\t\tloadingText={loadingText}\r\n\t\t\t\t\terrorText={errorText}\r\n\t\t\t\t\tinputHintText={inputHintText}\r\n\t\t\t\t\temptyText={emptyText}\r\n\t\t\t\t/>\r\n\t\t\t</CommandList>\r\n\t\t</Command>\r\n\t);\r\n};\r\n","import { useControllableState } from \"@/hooks/useControllableState\";\r\nimport { useCallback, useMemo, useState } from \"react\";\r\nimport { Popover, PopoverTrigger } from \"../../popover\";\r\nimport { SearchSelectTextValue } from \"../components/SearchSelectTextValue\";\r\nimport { SearchSelectTrigger } from \"../components/SearchSelectTrigger\";\r\nimport { SearchSelectContent } from \"../search-select/components/SearchSelectContent\";\r\nimport { AsyncSearchSelectPopoverContent } from \"./components/AsyncSearchSelectPopoverContent\";\r\nimport type { AsyncSearchSelectProps, SearchSelectOption } from \"./types\";\r\n\r\nexport const AsyncSearchSelect = <T extends SearchSelectOption = SearchSelectOption>(\r\n\tprops: AsyncSearchSelectProps<T>\r\n) => {\r\n\tconst {\r\n\t\trenderOption,\r\n\t\tplaceholder = \"Выберите значение\",\r\n\t\tvalue,\r\n\t\tdefaultValue,\r\n\t\tdisabled,\r\n\t\tinvalid,\r\n\t\tonChange,\r\n\t\tstartIcon,\r\n\t\tonClear,\r\n\t\t...popoverProps\r\n\t} = props;\r\n\r\n\tconst [open, setOpen] = useState(false);\r\n\r\n\tconst [currentOption, setCurrentOption] = useControllableState<T>({\r\n\t\tvalue,\r\n\t\tdefaultValue,\r\n\t\tonChange\r\n\t});\r\n\r\n\tconst displayValue = useMemo(() => {\r\n\t\tif (!currentOption) return undefined;\r\n\t\tif (renderOption) {\r\n\t\t\tconst item = renderOption({ option: currentOption, type: \"trigger\" });\r\n\t\t\tif (item !== undefined) {\r\n\t\t\t\treturn item;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn <SearchSelectTextValue>{currentOption.label}</SearchSelectTextValue>;\r\n\t}, [currentOption, renderOption]);\r\n\r\n\tconst onSelect = useCallback(\r\n\t\t(option: T | null) => {\r\n\t\t\tif (option) setCurrentOption(option);\r\n\t\t\tsetOpen(false);\r\n\t\t},\r\n\t\t[setCurrentOption, setOpen]\r\n\t);\r\n\r\n\tconst isSelected = useCallback(\r\n\t\t(option: T) => {\r\n\t\t\treturn currentOption?.value === option.value;\r\n\t\t},\r\n\t\t[currentOption]\r\n\t);\r\n\r\n\treturn (\r\n\t\t<Popover {...popoverProps} open={open} onOpenChange={setOpen}>\r\n\t\t\t<PopoverTrigger asChild>\r\n\t\t\t\t<SearchSelectTrigger\r\n\t\t\t\t\tplaceholder={placeholder}\r\n\t\t\t\t\tdisabled={disabled}\r\n\t\t\t\t\tinvalid={invalid}\r\n\t\t\t\t\topen={open}\r\n\t\t\t\t\tstartIcon={startIcon}\r\n\t\t\t\t\tonClear={onClear}\r\n\t\t\t\t>\r\n\t\t\t\t\t{displayValue}\r\n\t\t\t\t</SearchSelectTrigger>\r\n\t\t\t</PopoverTrigger>\r\n\t\t\t<SearchSelectContent>\r\n\t\t\t\t<AsyncSearchSelectPopoverContent {...props} onSelect={onSelect} isSelected={isSelected} />\r\n\t\t\t</SearchSelectContent>\r\n\t\t</Popover>\r\n\t);\r\n};\r\n","import { useControllableState } from \"@/hooks/useControllableState\";\r\nimport { useItemsKeyboardNavigation } from \"@/hooks/useItemsKeyboardNavigation\";\r\nimport { PopoverProps } from \"@radix-ui/react-popover\";\r\nimport { useCallback, useMemo, useState } from \"react\";\r\nimport { SearchSelectOption } from \"../../../hooks/useSearchSelect\";\r\nimport { Popover, PopoverTrigger } from \"../../popover\";\r\nimport { AsyncSearchSelectPopoverContent } from \"../async-search-select/components/AsyncSearchSelectPopoverContent\";\r\nimport { LoadOptionsParams, LoadOptionsResult } from \"../async-search-select/types\";\r\nimport { SearchSelectTag } from \"../components/SearchSelectTag\";\r\nimport { SearchSelectTrigger } from \"../components/SearchSelectTrigger\";\r\nimport { SearchSelectContent } from \"../search-select/components/SearchSelectContent\";\r\n\r\n/**\r\n * Пропсы для рендера опции в trigger (кнопке)\r\n */\r\nexport type RenderOptionInTriggerProps = {\r\n\ttype: \"trigger\";\r\n\tonClose?: () => void;\r\n};\r\n\r\n/**\r\n * Пропсы для рендера опции в списке\r\n */\r\nexport type RenderOptionInListProps = {\r\n\ttype: \"list\";\r\n\t/** Выбрана ли опция в данный момент */\r\n\tisSelected: boolean;\r\n\t/** Отключена ли опция */\r\n\tisDisabled: boolean;\r\n\t/** Текущий поисковый запрос для подсветки совпадений */\r\n\tsearchQuery: string;\r\n\t/** Индекс элемента в списке */\r\n\tindex: number;\r\n};\r\n\r\n/**\r\n * Объединенный тип для рендера опции\r\n */\r\nexport type RenderOptionProps<T extends SearchSelectOption = SearchSelectOption> = {\r\n\toption: T;\r\n} & (RenderOptionInTriggerProps | RenderOptionInListProps);\r\n\r\nexport interface MultiSelectProps<T extends SearchSelectOption = SearchSelectOption> {\r\n\t/** Дополнительные классы для контейнера */\r\n\tclassName?: string;\r\n\t/** Флаг для отключения компонента */\r\n\tdisabled?: boolean;\r\n\t/** Текст placeholder, отображается когда ничего не выбрано */\r\n\tplaceholder?: string;\r\n\t/** Текущие выбранные опции (controlled режим) */\r\n\tvalue?: T[];\r\n\t/** Опции по умолчанию (uncontrolled режим) */\r\n\tdefaultValue?: T[];\r\n\t/** Callback при изменении выбранных опций */\r\n\tonChange?: (options: T[]) => void;\r\n\t/** Callback при очистке значения */\r\n\tonClear?: () => void;\r\n\t/** Оставлять поповер открытым после выбора элемента */\r\n\tkeepOpenOnSelect?: boolean;\r\n\t/** Обработчик клика по названию выбранного тега */\r\n\tonLabelClick?: (option: T) => void;\r\n\t/** Функция загрузки опций */\r\n\tloadOptions: (params: LoadOptionsParams) => Promise<LoadOptionsResult<T>>;\r\n\t/** Режим загрузки опций */\r\n\tloadMode?: \"auto\" | \"input\";\r\n\t/** Минимальное количество символов для начала загрузки (только для режима \"input\") */\r\n\tminInputLength?: number;\r\n\t/** Задержка перед отправкой запроса в миллисекундах (debounce) */\r\n\tdebounceMs?: number;\r\n\t/** Текст подсказки для режима \"input\", когда пользователь еще не ввел символы */\r\n\tinputHintText?: string;\r\n\t/** Текст во время загрузки */\r\n\tloadingText?: string;\r\n\t/** Текст при ошибке загрузки */\r\n\terrorText?: string;\r\n\t/** Кастомная функция рендера опции */\r\n\trenderOption?: (props: RenderOptionProps<T>) => React.ReactNode;\r\n\t/** Текст placeholder для поиска */\r\n\tsearchPlaceholder?: string;\r\n\t/** Текст для пустого состояния */\r\n\temptyText?: string;\r\n\t/** Дополнительные пропсы для Popover */\r\n\tpopoverProps?: PopoverProps;\r\n\t/** Состояние ошибки */\r\n\tinvalid?: boolean;\r\n\t/** Иконка, отображаемая в начале поля */\r\n\tstartIcon?: React.ReactNode;\r\n\t/** Скрыть поле поиска */\r\n\thideSearch?: boolean;\r\n}\r\n\r\n/**\r\n * Компонент для множественного выбора элементов из списка\r\n */\r\nexport const MultiSelect = <T extends SearchSelectOption = SearchSelectOption>(props: MultiSelectProps<T>) => {\r\n\tconst {\r\n\t\tclassName,\r\n\t\tplaceholder = \"Выберите значение\",\r\n\t\tvalue,\r\n\t\tdefaultValue,\r\n\t\tonChange,\r\n\t\tdisabled,\r\n\t\tinvalid,\r\n\t\tkeepOpenOnSelect = true,\r\n\t\tonClear,\r\n\t\tonLabelClick,\r\n\t\trenderOption,\r\n\t\tstartIcon,\r\n\t\t...popoverProps\r\n\t} = props;\r\n\r\n\tconst [open, setOpen] = useState(false);\r\n\r\n\tconst [selectedOptions, setSelectedOptions] = useControllableState<T[]>({\r\n\t\tvalue,\r\n\t\tdefaultValue,\r\n\t\tonChange\r\n\t});\r\n\r\n\tconst onSelect = useCallback(\r\n\t\t(option: T | null) => {\r\n\t\t\tif (option) {\r\n\t\t\t\tconst isAlreadySelected = selectedOptions?.find((o) => o.value === option.value);\r\n\t\t\t\tif (isAlreadySelected) {\r\n\t\t\t\t\tsetSelectedOptions((prev) => {\r\n\t\t\t\t\t\treturn prev?.filter((o) => o.value !== option.value) || [];\r\n\t\t\t\t\t});\r\n\t\t\t\t} else {\r\n\t\t\t\t\tsetSelectedOptions((prev) => {\r\n\t\t\t\t\t\treturn [...(prev || []), option];\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (!keepOpenOnSelect) {\r\n\t\t\t\tsetOpen(false);\r\n\t\t\t}\r\n\t\t},\r\n\t\t[selectedOptions, keepOpenOnSelect, setSelectedOptions, setOpen]\r\n\t);\r\n\r\n\tconst handleClose = useCallback(\r\n\t\t(option: T) => {\r\n\t\t\tconst isSelected = selectedOptions?.find((o) => o.value === option.value);\r\n\t\t\tif (isSelected) {\r\n\t\t\t\tsetSelectedOptions((prev) => {\r\n\t\t\t\t\treturn prev?.filter((o) => o.value !== option.value) || [];\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t},\r\n\t\t[selectedOptions, setSelectedOptions]\r\n\t);\r\n\r\n\tconst isSelected = useCallback(\r\n\t\t(option: T) => {\r\n\t\t\treturn selectedOptions?.some((selectedOption) => selectedOption.value === option.value) ?? false;\r\n\t\t},\r\n\t\t[selectedOptions]\r\n\t);\r\n\r\n\tconst { handleKeyDown, isFocused } = useItemsKeyboardNavigation({\r\n\t\titems: selectedOptions || [],\r\n\t\tonEnter: onLabelClick,\r\n\t\tonDelete: handleClose\r\n\t});\r\n\r\n\tconst displayValue = useMemo(() => {\r\n\t\tif (!selectedOptions || selectedOptions.length === 0) return undefined;\r\n\r\n\t\treturn selectedOptions.map((option, index) => {\r\n\t\t\tif (renderOption) {\r\n\t\t\t\tconst item = renderOption({\r\n\t\t\t\t\toption,\r\n\t\t\t\t\ttype: \"trigger\",\r\n\t\t\t\t\tonClose: () => {\r\n\t\t\t\t\t\thandleClose(option);\r\n\t\t\t\t\t}\r\n\t\t\t\t});\r\n\t\t\t\tif (item !== undefined) {\r\n\t\t\t\t\treturn item;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\treturn (\r\n\t\t\t\t<SearchSelectTag\r\n\t\t\t\t\tkey={option.value}\r\n\t\t\t\t\tonLabelClick={(e) => {\r\n\t\t\t\t\t\te.preventDefault();\r\n\t\t\t\t\t\tonLabelClick?.(option);\r\n\t\t\t\t\t}}\r\n\t\t\t\t\tonClose={(e) => {\r\n\t\t\t\t\t\te.preventDefault();\r\n\t\t\t\t\t\thandleClose(option);\r\n\t\t\t\t\t}}\r\n\t\t\t\t\tisFocused={isFocused(index)}\r\n\t\t\t\t>\r\n\t\t\t\t\t{option.label}\r\n\t\t\t\t</SearchSelectTag>\r\n\t\t\t);\r\n\t\t});\r\n\t}, [selectedOptions, renderOption, handleClose, onLabelClick, isFocused]);\r\n\r\n\treturn (\r\n\t\t<div className={className}>\r\n\t\t\t<Popover open={open} onOpenChange={setOpen} {...popoverProps}>\r\n\t\t\t\t<PopoverTrigger asChild>\r\n\t\t\t\t\t<SearchSelectTrigger\r\n\t\t\t\t\t\tonKeyDown={handleKeyDown}\r\n\t\t\t\t\t\tdisabled={disabled}\r\n\t\t\t\t\t\topen={open}\r\n\t\t\t\t\t\tplaceholder={placeholder}\r\n\t\t\t\t\t\tinvalid={invalid}\r\n\t\t\t\t\t\tstartIcon={startIcon}\r\n\t\t\t\t\t\tonClear={onClear}\r\n\t\t\t\t\t\tclassName=\"h-auto !py-[0.3125rem] lg:h-auto\"\r\n\t\t\t\t\t>\r\n\t\t\t\t\t\t{displayValue && <div className=\"flex flex-wrap gap-1.5 lg:gap-1\">{displayValue}</div>}\r\n\t\t\t\t\t</SearchSelectTrigger>\r\n\t\t\t\t</PopoverTrigger>\r\n\t\t\t\t<SearchSelectContent>\r\n\t\t\t\t\t<AsyncSearchSelectPopoverContent {...props} onSelect={onSelect} isSelected={isSelected} />\r\n\t\t\t\t</SearchSelectContent>\r\n\t\t\t</Popover>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nMultiSelect.displayName = \"MultiSelect\";\r\n"],"names":["useSearchSelect","options","value","defaultValue","onChange","valueOption","selectedOption","setSelectedOption","useState","memoizedOnChange","useCallback","newValue","option","selectedValue","setSelectedValue","useControllableState","useEffect","currentOption","setSelectedByLabel","label","searchSelectTextValueStyles","tv","SearchSelectTextValue","children","className","jsx","searchSelectPlaceholderStyles","SearchSelectPlaceholder","searchSelectTriggerStyles","selectTriggerStyles","SearchSelectTrigger","React","disabled","open","invalid","placeholder","startIcon","onClear","props","ref","styles","jsxs","ClearButton","e","Icon","ChevronDownIcon","searchSelectContentStyles","SearchSelectContent","PopoverContent","SearchSelectInput","CommandInput","searchSelectStyles","SearchSelect","forwardRef","id","renderOption","onBlur","searchPlaceholder","emptyText","shouldFilter","footerContent","onSearchChange","onOpenChange","hideSearch","popoverProps","setOpen","searchQuery","setSearchQuery","handleSelect","handleSearchChange","handleOpenChange","displayValue","useMemo","item","renderedOptions","index","isDisabled","isSelected","renderOptionItem","customRender","Fragment","CheckIcon","CommandItem","Popover","PopoverTrigger","Command","CommandList","CommandEmpty","loadMoreTriggerStyles","LoadMoreTrigger","onLoad","hasMore","loadingText","triggerRef","useRef","trigger","observer","entry","Loader","defaultFuzzyFilter","search","valueLower","searchLower","searchIndex","i","LazySearchSelect","pageSize","filter","searchSelectProps","visibleCount","setVisibleCount","setValueOption","currentValue","visibleOptions","hasMoreItems","filteredAndRanked","score","a","b","visible","handleLoadMore","prev","SearchSelectSeparator","CommandSeparator","useAsyncDataLoader","loadOptions","setItems","loadingState","setLoadingState","error","setError","abortControllerRef","requestSequenceRef","cancelRequests","loadData","query","currentSequence","abortController","result","err","AsyncSearchSelectContent","loadMode","minInputLength","onSelect","errorText","inputHintText","optionsWithSelection","selected","ErrorState","HintState","EmptyState","AsyncSearchSelectPopoverContent","debounceMs","debouncedSearchQuery","useDebounce","shouldLoad","AsyncSearchSelect","setCurrentOption","MultiSelect","keepOpenOnSelect","onLabelClick","selectedOptions","setSelectedOptions","isAlreadySelected","o","handleClose","handleKeyDown","isFocused","useItemsKeyboardNavigation","SearchSelectTag"],"mappings":"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"}
1
+ {"version":3,"file":"search-select.js","sources":["../../src/hooks/useSearchSelect.ts","../../src/components/search-select/components/SearchSelectTextValue.tsx","../../src/components/search-select/components/SearchSelectPlaceholder.tsx","../../src/components/search-select/components/SearchSelectTrigger.tsx","../../src/components/search-select/search-select/components/SearchSelectContent.tsx","../../src/components/search-select/search-select/components/SearchSelectInput.tsx","../../src/components/search-select/search-select/SearchSelect.tsx","../../src/components/search-select/search-select/components/LoadMoreTrigger.tsx","../../src/components/search-select/search-select/utils/fuzzyFilter.ts","../../src/components/search-select/search-select/LazySearchSelect.tsx","../../src/components/search-select/search-select/components/SearchSelectSeparator.tsx","../../src/components/search-select/async-search-select/hooks/useAsyncDataLoader.ts","../../src/components/search-select/async-search-select/components/AsyncSearchSelectContent.tsx","../../src/components/search-select/async-search-select/components/AsyncSearchSelectPopoverContent.tsx","../../src/components/search-select/async-search-select/AsyncSearchSelect.tsx","../../src/components/search-select/multi-select/MultiSelect.tsx"],"sourcesContent":["import { useCallback, useState, useEffect } from \"react\";\nimport { useControllableState } from \"./useControllableState\";\n\nexport interface SearchSelectOption {\n\t/** Уникальный идентификатор опции */\n\tvalue: string | number;\n\t/** Отображаемый текст */\n\tlabel: string;\n\t/** Состояние отключения опции */\n\tdisabled?: boolean;\n}\n\ninterface UseSearchSelectProps<T extends SearchSelectOption = SearchSelectOption> {\n\t/** Список опций */\n\toptions: T[];\n\t/** Текущее выбранное значение (controlled режим) */\n\tvalue?: T[\"value\"];\n\t/** Значение по умолчанию (uncontrolled режим) */\n\tdefaultValue?: T[\"value\"];\n\t/** Callback при выборе опции */\n\tonChange?: (value: T[\"value\"], option: T) => void;\n\t/**\n\t * Значение по умолчанию для выбранной опции. Используется, когда выбранная опция\n\t * отсутствует в текущем списке options. Это может произойти при изменении фильтра\n\t * или при использовании виртуальной (ленивой) загрузки данных.\n\t * */\n\tvalueOption?: T;\n}\n\nexport const useSearchSelect = <T extends SearchSelectOption = SearchSelectOption>({\n\toptions,\n\tvalue,\n\tdefaultValue,\n\tonChange,\n\tvalueOption\n}: UseSearchSelectProps<T>) => {\n\t// Сохраняем выбранную опцию отдельно, чтобы она не терялась при фильтрации\n\tconst [selectedOption, setSelectedOption] = useState<T | undefined>(undefined);\n\n\tconst memoizedOnChange = useCallback(\n\t\t(newValue: T[\"value\"] | undefined) => {\n\t\t\tif (newValue !== undefined) {\n\t\t\t\tconst option = options.find((option) => option.value === newValue) || selectedOption;\n\t\t\t\tif (option && option.value === newValue) {\n\t\t\t\t\tsetSelectedOption(option);\n\t\t\t\t\tonChange?.(newValue, option);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t[onChange, options, selectedOption]\n\t);\n\n\tconst [selectedValue, setSelectedValue] = useControllableState<T[\"value\"] | undefined>({\n\t\tvalue,\n\t\tdefaultValue,\n\t\tonChange: memoizedOnChange\n\t});\n\n\t// Синхронизируем selectedOption с selectedValue при изменении selectedValue или options\n\tuseEffect(() => {\n\t\tif (selectedValue !== undefined) {\n\t\t\t// Если selectedOption уже соответствует selectedValue, ничего не делаем\n\t\t\tif (selectedOption && selectedOption.value === selectedValue) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Ищем опцию в текущих options\n\t\t\tconst currentOption = options.find((option) => option.value === selectedValue);\n\t\t\tif (currentOption) {\n\t\t\t\tsetSelectedOption(currentOption);\n\t\t\t} else if (valueOption && valueOption.value === selectedValue) {\n\t\t\t\tsetSelectedOption(valueOption);\n\t\t\t}\n\t\t} else {\n\t\t\tsetSelectedOption(undefined);\n\t\t}\n\t}, [selectedValue, options, selectedOption, valueOption]);\n\n\tconst setSelectedByLabel = useCallback(\n\t\t(label: string) => {\n\t\t\t// CommandItem работает с label, а не с value, поэтому нужно найти опцию по label\n\t\t\tconst option = options.find((option) => option.label === label);\n\t\t\tif (option) {\n\t\t\t\tsetSelectedValue(option.value);\n\t\t\t}\n\t\t},\n\t\t[setSelectedValue, options]\n\t);\n\n\treturn {\n\t\tselectedValue,\n\t\tselectedOption,\n\t\tsetSelectedByLabel,\n\t\tsetSelectedValue\n\t};\n};\n","import React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nconst searchSelectTextValueStyles = tv({\n\tbase: \"self-center pl-1.5\"\n});\n\ninterface SearchSelectTextValueProps {\n\tchildren: React.ReactNode;\n\tclassName?: string;\n}\n\nexport const SearchSelectTextValue: React.FC<SearchSelectTextValueProps> = ({ children, className }) => {\n\treturn <span className={searchSelectTextValueStyles({ className })}>{children}</span>;\n};\n","import React from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nconst searchSelectPlaceholderStyles = tv({\n\tbase: \"pointer-events-none self-center pl-1.5 text-muted\"\n});\n\ninterface SearchSelectPlaceholderProps {\n\tchildren: React.ReactNode;\n\tclassName?: string;\n}\n\nexport const SearchSelectPlaceholder: React.FC<SearchSelectPlaceholderProps> = ({ children, className }) => {\n\treturn <span className={searchSelectPlaceholderStyles({ className })}>{children}</span>;\n};\n","import { Icon } from \"@/components/icon/Icon\";\nimport { selectTriggerStyles } from \"@/components/select/Select\";\nimport { ChevronDownIcon } from \"lucide-react\";\nimport React from \"react\";\nimport { tv } from \"tailwind-variants\";\nimport { SearchSelectPlaceholder } from \"./SearchSelectPlaceholder\";\nimport { ClearButton } from \"@/components/input/components/clear-button/ClearButton\";\n\nconst searchSelectTriggerStyles = tv({\n\textend: selectTriggerStyles,\n\tbase: \"group/search-select-trigger min-h-10 items-start py-1.5 pl-1.5 pr-3 lg:min-h-9 lg:py-1.5 lg:pl-1.5 lg:pr-2.5\",\n\tslots: {\n\t\tbuttonWrapper: \"ml-auto flex gap-2 pl-2.5\",\n\t\ticonWrapper: \"min-h-[1.375rem]\",\n\t\tstartIcon: \"flex min-h-[1.375rem] items-center pl-1.5 pr-0.5 text-muted\",\n\t\tclearButton: \"h-auto p-0\"\n\t}\n});\n\ninterface SearchSelectTriggerProps extends React.ComponentPropsWithoutRef<\"button\"> {\n\t/** Состояние отключения */\n\tdisabled?: boolean;\n\t/** Состояние ошибки */\n\tinvalid?: boolean;\n\t/** Текст placeholder */\n\tplaceholder?: string;\n\t/** Состояние открытия. Используется для проставления accessibility аттрибутов */\n\topen?: boolean;\n\t/** Иконка, отображаемая в начале текстового поля */\n\tstartIcon?: React.ReactNode;\n\t/** Callback при очистке значения */\n\tonClear?: () => void;\n}\n\n/**\n * Компонент отображения триггера для SearchSelect.\n * Выполняет роль кнопки, которая открывает Popover с опциями.\n * Может отображать значение или placeholder в зависимости от наличия дочерних элементов.\n * Не содержит сам триггер, а только стилизует кнопку.\n */\nexport const SearchSelectTrigger = React.forwardRef<HTMLButtonElement, SearchSelectTriggerProps>(\n\t({ className, children, disabled, open, invalid, placeholder, startIcon, onClear, ...props }, ref) => {\n\t\tconst styles = searchSelectTriggerStyles({ disabled, invalid });\n\n\t\treturn (\n\t\t\t<button\n\t\t\t\t{...props}\n\t\t\t\tdisabled={disabled}\n\t\t\t\tclassName={styles.base({ className })}\n\t\t\t\tref={ref}\n\t\t\t\trole=\"combobox\"\n\t\t\t\taria-expanded={open}\n\t\t\t\taria-invalid={invalid}\n\t\t\t\taria-haspopup=\"listbox\"\n\t\t\t>\n\t\t\t\t{startIcon && <div className={styles.startIcon()}>{startIcon}</div>}\n\t\t\t\t{children !== undefined ? children : <SearchSelectPlaceholder>{placeholder}</SearchSelectPlaceholder>}\n\t\t\t\t<div className={styles.buttonWrapper()}>\n\t\t\t\t\t{onClear && (\n\t\t\t\t\t\t<div className={styles.iconWrapper()}>\n\t\t\t\t\t\t\t<ClearButton\n\t\t\t\t\t\t\t\tclassName={styles.clearButton()}\n\t\t\t\t\t\t\t\tonClear={onClear}\n\t\t\t\t\t\t\t\tonPointerDown={(e) => {\n\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\t\t\t\t\tif (e.key === \"Enter\") {\n\t\t\t\t\t\t\t\t\t\tonClear();\n\t\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t\t{!disabled && (\n\t\t\t\t\t\t<div className={styles.iconWrapper()}>\n\t\t\t\t\t\t\t<Icon icon={ChevronDownIcon} className={styles.icon()} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t</button>\n\t\t);\n\t}\n);\n\nSearchSelectTrigger.displayName = \"SearchSelectTrigger\";\n","import { PopoverContent } from \"@/components/popover\";\nimport React, { ComponentPropsWithoutRef } from \"react\";\nimport { tv } from \"tailwind-variants\";\n\ntype SearchSelectContentProps = ComponentPropsWithoutRef<typeof PopoverContent>;\n\nconst searchSelectContentStyles = tv({\n\tbase: \"w-full min-w-[var(--radix-popper-anchor-width)] border-secondary-border p-0\"\n});\n\n/**\n * Контейнер содержимого для SearchSelect.\n * Обертка вокруг PopoverContent с настроенными стилями и интеграцией с Command.\n * Планируется рефакторинг для вынесения input логики.\n */\nexport const SearchSelectContent = React.forwardRef<React.ElementRef<typeof PopoverContent>, SearchSelectContentProps>(\n\t({ className, children, ...props }, ref) => {\n\t\treturn (\n\t\t\t<PopoverContent ref={ref} className={searchSelectContentStyles({ className })} align=\"start\" {...props}>\n\t\t\t\t{children}\n\t\t\t</PopoverContent>\n\t\t);\n\t}\n);\n\nSearchSelectContent.displayName = \"SearchSelectContent\";\n","import { CommandInput } from \"@/components/command/Command\";\nimport { Command as CommandPrimitive } from \"cmdk\";\nimport React from \"react\";\n\nexport const SearchSelectInput = React.forwardRef<\n\tReact.ElementRef<typeof CommandPrimitive.Input>,\n\tReact.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>\n>(({ placeholder = \"Find\", ...props }, ref) => {\n\treturn <CommandInput ref={ref} placeholder={placeholder} {...props} />;\n});\n\nSearchSelectInput.displayName = \"SearchSelectInput\";\n","import { CheckIcon } from \"lucide-react\";\nimport { ComponentPropsWithoutRef, forwardRef, useCallback, useMemo, useState } from \"react\";\nimport { tv } from \"tailwind-variants\";\nimport { SearchSelectOption, useSearchSelect } from \"../../../hooks/useSearchSelect\";\nimport { Command, CommandEmpty, CommandItem, CommandList } from \"../../command/Command\";\nimport { Icon } from \"../../icon/Icon\";\nimport { Popover, PopoverTrigger } from \"../../popover\";\nimport { SearchSelectTextValue } from \"../components/SearchSelectTextValue\";\nimport { SearchSelectTrigger } from \"../components/SearchSelectTrigger\";\nimport { SearchSelectContent } from \"./components/SearchSelectContent\";\nimport { SearchSelectInput } from \"./components/SearchSelectInput\";\n\nconst searchSelectStyles = tv({ base: \"\" });\n\nexport type RenderOptionProps<T extends SearchSelectOption = SearchSelectOption> = {\n\t/** Отображаемая опция */\n\toption: T;\n} & (RenderOptionInTriggerProps | RenderOptionInListProps);\n\nexport type RenderOptionInTriggerProps = {\n\t/** Тип рендера. Если `trigger`, то опция рендерится в триггере в качестве текущего значения компонента. */\n\ttype: \"trigger\";\n};\n\nexport type RenderOptionInListProps = {\n\t/** Тип рендера. Если `list`, то опция рендерится в списке опций. */\n\ttype: \"list\";\n\t/** Выбрана ли опция в данный момент */\n\tisSelected: boolean;\n\t/** Отключена ли опция */\n\tisDisabled: boolean;\n\t/** Текущий поисковый запрос для подсветки совпадений */\n\tsearchQuery: string;\n\t/** Индекс элемента в списке */\n\tindex: number;\n};\n\ntype PopoverProps = ComponentPropsWithoutRef<typeof Popover>;\nexport interface SearchSelectProps<T extends SearchSelectOption = SearchSelectOption>\n\textends Omit<PopoverProps, \"children\"> {\n\t/** Идентификатор поля в форме. Позволяет связать компонент с полем формы. */\n\tid?: string;\n\t/** Событие blur */\n\tonBlur?: (e: React.FocusEvent<HTMLButtonElement>) => void;\n\t/** Дополнительные классы для контейнера */\n\tclassName?: string;\n\t/** Список опций */\n\toptions: T[];\n\t/** Значение по умолчанию для выбранной опции. Используется, когда выбранная опция\n\t * отсутствует в текущем списке options. Это может произойти при изменении фильтра\n\t * или при использовании виртуальной (ленивой) загрузки данных.\n\t * */\n\tvalueOption?: T;\n\t/**\n\t * Кастомная функция рендера опции.\n\t * Используется для отображения как в trigger (type: \"trigger\"), так и в списке (type: \"list\").\n\t */\n\trenderOption?: (props: RenderOptionProps<T>) => React.ReactNode;\n\t/** Текст placeholder, отображается когда ничего не выбрано */\n\tplaceholder?: string;\n\t/** Текущее выбранное значение (controlled режим) */\n\tvalue?: T[\"value\"];\n\t/** Значение по умолчанию (uncontrolled режим) */\n\tdefaultValue?: T[\"value\"];\n\t/** Callback при выборе опции */\n\tonChange?: (value: T[\"value\"], option: T) => void;\n\t/** Callback при очистке значения */\n\tonClear?: () => void;\n\t/** Состояние отключения */\n\tdisabled?: boolean;\n\t/** Состояние ошибки */\n\tinvalid?: boolean;\n\t/** Текст placeholder для поиска */\n\tsearchPlaceholder?: string;\n\t/** Текст для пустого состояния */\n\temptyText?: string;\n\t/** Использовать встроенную фильтрацию cmdk. По умолчанию true */\n\tshouldFilter?: boolean;\n\t/** Контент, отображаемый в конце списка (например, для триггера загрузки) */\n\tfooterContent?: React.ReactNode;\n\t/** Callback при изменении поискового запроса */\n\tonSearchChange?: (value: string) => void;\n\t/** Callback при изменении состояния открытия */\n\tonOpenChange?: (open: boolean) => void;\n\t/** Иконка, отображаемая в начале поля */\n\tstartIcon?: React.ReactNode;\n\t/** Скрыть поле поиска */\n\thideSearch?: boolean;\n}\n\nexport const SearchSelect = forwardRef(\n\t<T extends SearchSelectOption = SearchSelectOption>(\n\t\tprops: SearchSelectProps<T>,\n\t\tref: React.ForwardedRef<HTMLButtonElement>\n\t) => {\n\t\tconst {\n\t\t\tid,\n\t\t\tclassName,\n\t\t\toptions,\n\t\t\tvalueOption,\n\t\t\trenderOption,\n\t\t\tplaceholder = \"Выберите значение\",\n\t\t\tvalue,\n\t\t\tdefaultValue,\n\t\t\tonBlur,\n\t\t\tonChange,\n\t\t\tonClear,\n\t\t\tdisabled,\n\t\t\tinvalid,\n\t\t\tsearchPlaceholder = \"Найти\",\n\t\t\temptyText = \"Результатов не найдено\",\n\t\t\tshouldFilter = true,\n\t\t\tfooterContent,\n\t\t\tonSearchChange,\n\t\t\tonOpenChange,\n\t\t\tstartIcon,\n\t\t\thideSearch,\n\t\t\t...popoverProps\n\t\t} = props;\n\n\t\tconst [open, setOpen] = useState(false);\n\t\tconst [searchQuery, setSearchQuery] = useState(\"\");\n\n\t\tconst { selectedValue, selectedOption, setSelectedByLabel } = useSearchSelect({\n\t\t\toptions,\n\t\t\tvalue,\n\t\t\tdefaultValue,\n\t\t\tvalueOption,\n\t\t\tonChange\n\t\t});\n\n\t\tconst handleSelect = useCallback(\n\t\t\t(label: string) => {\n\t\t\t\tsetSelectedByLabel(label);\n\t\t\t\tsetOpen(false);\n\t\t\t},\n\t\t\t[setSelectedByLabel, setOpen]\n\t\t);\n\n\t\tconst handleSearchChange = useCallback(\n\t\t\t(value: string) => {\n\t\t\t\tsetSearchQuery(value);\n\t\t\t\tonSearchChange?.(value);\n\t\t\t},\n\t\t\t[onSearchChange]\n\t\t);\n\n\t\tconst handleOpenChange = useCallback(\n\t\t\t(open: boolean) => {\n\t\t\t\tsetOpen(open);\n\t\t\t\tonOpenChange?.(open);\n\t\t\t},\n\t\t\t[onOpenChange]\n\t\t);\n\n\t\tconst displayValue = useMemo(() => {\n\t\t\tif (!selectedOption) return undefined;\n\t\t\tif (renderOption) {\n\t\t\t\tconst item = renderOption({ option: selectedOption, type: \"trigger\" });\n\t\t\t\tif (item !== undefined) {\n\t\t\t\t\treturn item;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn <SearchSelectTextValue>{selectedOption.label}</SearchSelectTextValue>;\n\t\t}, [selectedOption, renderOption]);\n\n\t\tconst renderedOptions = useMemo(() => {\n\t\t\treturn options.map((option, index) => {\n\t\t\t\tconst isDisabled = option.disabled ?? false;\n\t\t\t\tconst isSelected = selectedValue === option.value;\n\n\t\t\t\tconst renderOptionItem = () => {\n\t\t\t\t\tif (renderOption) {\n\t\t\t\t\t\tconst customRender = renderOption({\n\t\t\t\t\t\t\toption,\n\t\t\t\t\t\t\ttype: \"list\",\n\t\t\t\t\t\t\tisSelected,\n\t\t\t\t\t\t\tisDisabled,\n\t\t\t\t\t\t\tsearchQuery,\n\t\t\t\t\t\t\tindex\n\t\t\t\t\t\t});\n\t\t\t\t\t\tif (customRender !== undefined) {\n\t\t\t\t\t\t\treturn customRender;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t{option.label}\n\t\t\t\t\t\t\t{isSelected && <Icon icon={CheckIcon} className=\"ml-auto\" />}\n\t\t\t\t\t\t</>\n\t\t\t\t\t);\n\t\t\t\t};\n\n\t\t\t\treturn (\n\t\t\t\t\t<CommandItem\n\t\t\t\t\t\tkey={option.value}\n\t\t\t\t\t\tvalue={option.label}\n\t\t\t\t\t\tonSelect={isDisabled ? undefined : handleSelect}\n\t\t\t\t\t\tdisabled={isDisabled}\n\t\t\t\t\t>\n\t\t\t\t\t\t{renderOptionItem()}\n\t\t\t\t\t</CommandItem>\n\t\t\t\t);\n\t\t\t});\n\t\t}, [options, selectedValue, handleSelect, renderOption, searchQuery]);\n\n\t\treturn (\n\t\t\t<Popover {...popoverProps} open={open} onOpenChange={handleOpenChange}>\n\t\t\t\t<div className={searchSelectStyles({ className })}>\n\t\t\t\t\t<PopoverTrigger asChild>\n\t\t\t\t\t\t<SearchSelectTrigger\n\t\t\t\t\t\t\tonClear={onClear}\n\t\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\t\tinvalid={invalid}\n\t\t\t\t\t\t\topen={open}\n\t\t\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\t\t\tid={id}\n\t\t\t\t\t\t\tonBlur={onBlur}\n\t\t\t\t\t\t\tref={ref}\n\t\t\t\t\t\t\tstartIcon={startIcon}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{displayValue}\n\t\t\t\t\t\t</SearchSelectTrigger>\n\t\t\t\t\t</PopoverTrigger>\n\t\t\t\t\t<SearchSelectContent>\n\t\t\t\t\t\t<Command shouldFilter={shouldFilter}>\n\t\t\t\t\t\t\t{!hideSearch && (\n\t\t\t\t\t\t\t\t<SearchSelectInput placeholder={searchPlaceholder} onValueChange={handleSearchChange} />\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t<CommandList key={`list-${searchQuery}`} className=\"p-1\">\n\t\t\t\t\t\t\t\t{renderedOptions}\n\t\t\t\t\t\t\t\t<CommandEmpty>{emptyText}</CommandEmpty>\n\t\t\t\t\t\t\t\t{footerContent}\n\t\t\t\t\t\t\t</CommandList>\n\t\t\t\t\t\t</Command>\n\t\t\t\t\t</SearchSelectContent>\n\t\t\t\t</div>\n\t\t\t</Popover>\n\t\t);\n\t}\n) as (<T extends SearchSelectOption = SearchSelectOption>(\n\tprops: SearchSelectProps<T> & { ref?: React.ForwardedRef<HTMLButtonElement> }\n) => React.ReactElement) & { displayName?: string };\n\nSearchSelect.displayName = \"SearchSelect\";\n","import { Loader } from \"@/components/loader\";\nimport React, { useEffect, useRef } from \"react\";\nimport { tv } from \"tailwind-variants\";\n\nconst loadMoreTriggerStyles = tv({\n\tbase: \"py-2 text-center text-sm text-muted-foreground\"\n});\n\nexport interface LoadMoreTriggerProps {\n\t/** Callback, который вызывается когда триггер становится видимым */\n\tonLoad: () => void;\n\t/** Есть ли еще элементы для загрузки */\n\thasMore: boolean;\n\t/** Текст индикатора загрузки */\n\tloadingText?: string;\n\t/** Дополнительные CSS классы */\n\tclassName?: string;\n}\n\n/**\n * Компонент для автоматической загрузки дополнительных элементов при прокрутке.\n * Отображает индикатор загрузки и автоматически вызывает `onLoad` когда пользователь\n * доскроллит до этого элемента.\n */\nexport const LoadMoreTrigger = React.forwardRef<HTMLDivElement, LoadMoreTriggerProps>(\n\t({ onLoad, hasMore, loadingText = \"Загрузка...\", className }, ref) => {\n\t\tconst triggerRef = useRef<HTMLDivElement>(null);\n\t\tconst styles = loadMoreTriggerStyles({ className });\n\n\t\tReact.useImperativeHandle(ref, () => triggerRef.current as HTMLDivElement);\n\n\t\tuseEffect(() => {\n\t\t\tconst trigger = triggerRef.current;\n\t\t\tif (!trigger || !hasMore) return;\n\n\t\t\tconst observer = new IntersectionObserver(\n\t\t\t\t([entry]) => {\n\t\t\t\t\tif (entry.isIntersecting) {\n\t\t\t\t\t\tonLoad();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ rootMargin: \"50px\" }\n\t\t\t);\n\n\t\t\tobserver.observe(trigger);\n\n\t\t\treturn () => {\n\t\t\t\tobserver.disconnect();\n\t\t\t};\n\t\t}, [onLoad, hasMore]);\n\n\t\tif (!hasMore) return null;\n\n\t\treturn (\n\t\t\t<div ref={triggerRef} className={styles}>\n\t\t\t\t<Loader className=\"flex-row\">{loadingText}</Loader>\n\t\t\t</div>\n\t\t);\n\t}\n);\n\nLoadMoreTrigger.displayName = \"LoadMoreTrigger\";\n","/**\n * Простой fuzzy filter для поиска\n * Возвращает число от 0 до 3, где большее число означает лучшее совпадение\n */\nexport const defaultFuzzyFilter = (value: string, search: string): number => {\n\tif (!search.trim()) return 1; // Пустой поиск - показываем все\n\n\tconst valueLower = value.toLowerCase().trim();\n\tconst searchLower = search.toLowerCase().trim();\n\n\t// Точное совпадение с началом - наивысший приоритет\n\tif (valueLower.startsWith(searchLower)) return 3;\n\n\t// Содержит подстроку - высокий приоритет\n\tif (valueLower.includes(searchLower)) return 2;\n\n\t// Fuzzy match - проверяем, что все символы поиска есть в правильном порядке\n\tlet searchIndex = 0;\n\tfor (let i = 0; i < valueLower.length && searchIndex < searchLower.length; i++) {\n\t\tif (valueLower[i] === searchLower[searchIndex]) {\n\t\t\tsearchIndex++;\n\t\t}\n\t}\n\n\t// Если нашли все символы поиска в правильном порядке - низкий приоритет\n\treturn searchIndex === searchLower.length ? 1 : 0;\n};\n\n/**\n * Тип функции фильтрации\n */\nexport type FilterFunction = (value: string, search: string) => number;\n","import { forwardRef, useCallback, useEffect, useMemo, useState } from \"react\";\nimport { SearchSelect, SearchSelectProps } from \"./SearchSelect\";\nimport { SearchSelectOption } from \"../../../hooks/useSearchSelect\";\nimport { LoadMoreTrigger } from \"./components/LoadMoreTrigger\";\nimport { defaultFuzzyFilter, FilterFunction } from \"./utils/fuzzyFilter\";\n\nexport interface LazySearchSelectProps<T extends SearchSelectOption = SearchSelectOption>\n\textends Omit<\n\t\tSearchSelectProps<T>,\n\t\t\"options\" | \"shouldFilter\" | \"footerContent\" | \"onSearchChange\" | \"valueOption\"\n\t> {\n\t/** Полный список опций */\n\toptions: T[];\n\t/** Количество элементов на странице */\n\tpageSize?: number;\n\t/** Кастомная функция фильтрации. По умолчанию используется встроенный fuzzy search */\n\tfilter?: FilterFunction;\n}\n\nexport const LazySearchSelect = forwardRef<HTMLButtonElement, LazySearchSelectProps>(\n\t<T extends SearchSelectOption = SearchSelectOption>(\n\t\tprops: LazySearchSelectProps<T>,\n\t\tref: React.ForwardedRef<HTMLButtonElement>\n\t) => {\n\t\tconst {\n\t\t\toptions,\n\t\t\tpageSize = 50,\n\t\t\tfilter = defaultFuzzyFilter,\n\t\t\tdefaultValue,\n\t\t\tvalue,\n\t\t\t...searchSelectProps\n\t\t} = props;\n\n\t\tconst [visibleCount, setVisibleCount] = useState(pageSize);\n\t\tconst [searchQuery, setSearchQuery] = useState(\"\");\n\t\tconst [valueOption, setValueOption] = useState<T | undefined>(undefined);\n\n\t\t// При изменении поиска сбрасываем счетчик видимых элементов\n\t\tuseEffect(() => setVisibleCount(pageSize), [searchQuery, pageSize]);\n\n\t\tuseEffect(() => {\n\t\t\tconst currentValue = value || defaultValue;\n\t\t\tif (currentValue && !valueOption) {\n\t\t\t\tsetValueOption(options.find((option) => option.value === currentValue));\n\t\t\t}\n\t\t}, [defaultValue, value, options, valueOption]);\n\n\t\t// Фильтрация и ограничение элементов\n\t\tconst { visibleOptions, hasMoreItems } = useMemo(() => {\n\t\t\t// Сначала фильтруем и ранжируем по поисковому запросу\n\t\t\tconst filteredAndRanked = searchQuery\n\t\t\t\t? options\n\t\t\t\t\t\t.map((option) => ({\n\t\t\t\t\t\t\toption,\n\t\t\t\t\t\t\tscore: filter(option.label, searchQuery)\n\t\t\t\t\t\t}))\n\t\t\t\t\t\t.filter(({ score }) => score > 0) // Убираем элементы с нулевым скором\n\t\t\t\t\t\t.sort((a, b) => b.score - a.score) // Сортируем по убыванию скора\n\t\t\t\t\t\t.map(({ option }) => option)\n\t\t\t\t: options;\n\n\t\t\t// Затем ограничиваем количество видимых элементов\n\t\t\tconst visible = filteredAndRanked.slice(0, visibleCount);\n\t\t\tconst hasMore = visibleCount < filteredAndRanked.length;\n\n\t\t\treturn {\n\t\t\t\tvisibleOptions: visible,\n\t\t\t\thasMoreItems: hasMore\n\t\t\t};\n\t\t}, [options, searchQuery, visibleCount, filter]);\n\n\t\t// Обработчик загрузки следующей порции\n\t\tconst handleLoadMore = useCallback(() => {\n\t\t\tsetVisibleCount((prev) => prev + pageSize);\n\t\t}, [pageSize]);\n\n\t\tconst handleSearchChange = useCallback((value: string) => {\n\t\t\tsetSearchQuery(value);\n\t\t}, []);\n\n\t\t// Сброс поиска при открытии\n\t\tconst handleOpenChange = useCallback(\n\t\t\t(open: boolean) => {\n\t\t\t\tif (open && searchQuery) setSearchQuery(\"\");\n\t\t\t},\n\t\t\t[searchQuery, setSearchQuery]\n\t\t);\n\n\t\treturn (\n\t\t\t<SearchSelect<T>\n\t\t\t\t{...searchSelectProps}\n\t\t\t\tref={ref}\n\t\t\t\toptions={visibleOptions}\n\t\t\t\tvalue={value}\n\t\t\t\tdefaultValue={defaultValue}\n\t\t\t\tvalueOption={valueOption}\n\t\t\t\tshouldFilter={false}\n\t\t\t\tfooterContent={<LoadMoreTrigger onLoad={handleLoadMore} hasMore={hasMoreItems} />}\n\t\t\t\tonSearchChange={handleSearchChange}\n\t\t\t\tonOpenChange={handleOpenChange}\n\t\t\t/>\n\t\t);\n\t}\n) as (<T extends SearchSelectOption = SearchSelectOption>(\n\tprops: LazySearchSelectProps<T> & { ref?: React.ForwardedRef<HTMLButtonElement> }\n) => React.ReactElement) & { displayName?: string };\n\nLazySearchSelect.displayName = \"LazySearchSelect\";\n","import React from \"react\";\nimport { CommandSeparator } from \"@/components/command/Command\";\nimport { ComponentPropsWithoutRef } from \"react\";\nimport { Command as CommandPrimitive } from \"cmdk\";\n\ntype SearchSelectSeparatorProps = ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>;\n\n/**\n * Разделитель для SearchSelect.\n * Простая обертка вокруг CommandSeparator.\n */\nexport const SearchSelectSeparator = React.forwardRef<\n\tReact.ElementRef<typeof CommandPrimitive.Separator>,\n\tSearchSelectSeparatorProps\n>((props, ref) => {\n\treturn <CommandSeparator ref={ref} {...props} />;\n});\n\nSearchSelectSeparator.displayName = \"SearchSelectSeparator\";\n","import { useCallback, useEffect, useRef, useState } from \"react\";\n\nexport type LoadingState = \"idle\" | \"loading\" | \"success\" | \"error\";\n\nexport interface LoadOptionsParams {\n\tsearchQuery: string;\n\tsignal?: AbortSignal;\n}\n\nexport interface LoadOptionsResult<T> {\n\toptions: T[];\n}\n\ninterface UseAsyncDataLoaderOptions<T> {\n\t/** Функция загрузки данных */\n\tloadOptions: (params: LoadOptionsParams) => Promise<LoadOptionsResult<T>>;\n}\n\ninterface UseAsyncDataLoaderReturn<T> {\n\t/** Текущие загруженные элементы */\n\toptions: T[];\n\t/** Состояние загрузки */\n\tloadingState: LoadingState;\n\t/** Текст ошибки, если загрузка не удалась */\n\terror: string | null;\n\t/** Функция загрузки данных */\n\tloadData: (query: string) => Promise<void>;\n\t/** Функция отмены текущих запросов */\n\tcancelRequests: () => void;\n}\n\n/**\n * Хук для асинхронной загрузки данных с защитой от race conditions\n *\n * Решает следующие проблемы:\n * - Race conditions при быстром вводе пользователя\n * - Мерцание интерфейса из-за множественных запросов\n * - Неправильный порядок получения ответов от сервера\n * - Обработка отмены запросов при размонтировании компонента\n *\n * @example\n * ```tsx\n * const { options, loadingState, loadData } = useAsyncDataLoader({\n * loadOptions: async ({ searchQuery }) => {\n * const response = await fetch(`/api/search?q=${searchQuery}`);\n * return response.json();\n * }\n * });\n *\n * // Загрузить данные\n * loadData(\"search query\");\n * ```\n */\nexport const useAsyncDataLoader = <T>({ loadOptions }: UseAsyncDataLoaderOptions<T>): UseAsyncDataLoaderReturn<T> => {\n\tconst [options, setItems] = useState<T[]>([]);\n\tconst [loadingState, setLoadingState] = useState<LoadingState>(\"idle\");\n\tconst [error, setError] = useState<string | null>(null);\n\n\t// Refs для управления race conditions\n\tconst abortControllerRef = useRef<AbortController | null>(null);\n\tconst requestSequenceRef = useRef(0);\n\n\t// Функция для отмены предыдущих запросов\n\tconst cancelRequests = useCallback(() => {\n\t\tif (abortControllerRef.current) {\n\t\t\tabortControllerRef.current.abort();\n\t\t}\n\t}, []);\n\n\t// Основная функция загрузки данных\n\tconst loadData = useCallback(\n\t\tasync (query: string) => {\n\t\t\t// Отменяем предыдущие запросы\n\t\t\tcancelRequests();\n\n\t\t\t// Увеличиваем sequence для отслеживания порядка\n\t\t\tconst currentSequence = ++requestSequenceRef.current;\n\n\t\t\t// Создаем новый AbortController\n\t\t\tconst abortController = new AbortController();\n\t\t\tabortControllerRef.current = abortController;\n\n\t\t\tsetLoadingState(\"loading\");\n\t\t\tsetError(null);\n\n\t\t\ttry {\n\t\t\t\tconst result = await loadOptions({\n\t\t\t\t\tsearchQuery: query,\n\t\t\t\t\tsignal: abortController.signal\n\t\t\t\t});\n\n\t\t\t\t// Проверяем, что запрос еще актуален\n\t\t\t\tif (currentSequence !== requestSequenceRef.current) return;\n\n\t\t\t\tsetItems(result.options);\n\t\t\t\tsetLoadingState(\"success\");\n\t\t\t} catch (err) {\n\t\t\t\t// Игнорируем AbortError - это нормальная отмена\n\t\t\t\tif (err instanceof Error && err.name === \"AbortError\") return;\n\t\t\t\tif (currentSequence !== requestSequenceRef.current) return;\n\n\t\t\t\tsetError(err instanceof Error ? err.message : \"Неизвестная ошибка\");\n\t\t\t\tsetLoadingState(\"error\");\n\t\t\t}\n\t\t},\n\t\t[loadOptions, cancelRequests]\n\t);\n\n\t// Cleanup при размонтировании компонента\n\tuseEffect(() => {\n\t\treturn () => cancelRequests();\n\t}, [cancelRequests]);\n\n\treturn {\n\t\toptions,\n\t\tloadingState,\n\t\terror,\n\t\tloadData,\n\t\tcancelRequests\n\t};\n};\n","import { EmptyState } from \"@/components/empty-state\";\nimport { ErrorState } from \"@/components/error-state\";\nimport { HintState } from \"@/components/hint-state\";\nimport { Loader } from \"@/components/loader\";\nimport { CheckIcon } from \"lucide-react\";\nimport { useMemo, useCallback } from \"react\";\nimport { CommandItem } from \"../../../command/Command\";\nimport { Icon } from \"../../../icon/Icon\";\nimport type { LoadingState, RenderOptionProps, SearchSelectOption } from \"../types\";\nimport React from \"react\";\n\ninterface AsyncSearchSelectContentProps<T extends SearchSelectOption = SearchSelectOption> {\n\t/** Текущие опции для отображения */\n\toptions: T[];\n\t/** Состояние загрузки */\n\tloadingState: LoadingState;\n\t/** Текст ошибки, если есть */\n\terror: string | null;\n\t/** Функция проверки выбранности элемента */\n\tisSelected?: (value: T) => boolean;\n\t/** Текущий поисковый запрос */\n\tsearchQuery: string;\n\t/** Режим загрузки */\n\tloadMode: \"auto\" | \"input\";\n\t/** Минимальная длина запроса для режима input */\n\tminInputLength: number;\n\t/** Функция обработки выбора опции */\n\tonSelect: (label: string) => void;\n\t/** Кастомная функция рендера опции */\n\trenderOption?: (props: RenderOptionProps<T>) => React.ReactNode;\n\t/** Текст во время загрузки */\n\tloadingText: string;\n\t/** Текст при ошибке загрузки */\n\terrorText: string;\n\t/** Текст подсказки для ввода */\n\tinputHintText: string;\n\t/** Текст для пустого состояния */\n\temptyText: string;\n}\n\n/**\n * Компонент для рендера содержимого AsyncSearchSelect\n *\n * Отвечает за отображение разных состояний:\n * - Загрузка\n * - Ошибка\n * - Подсказка для ввода\n * - Пустое состояние\n * - Список опций\n */\nexport const AsyncSearchSelectContent = <T extends SearchSelectOption = SearchSelectOption>({\n\toptions,\n\tloadingState,\n\terror,\n\tisSelected,\n\tsearchQuery,\n\tloadMode,\n\tminInputLength,\n\tonSelect,\n\trenderOption,\n\tloadingText,\n\terrorText,\n\tinputHintText,\n\temptyText\n}: AsyncSearchSelectContentProps<T>) => {\n\t// Мемоизируем опции с предвычисленным состоянием выбранности\n\tconst optionsWithSelection = useMemo(() => {\n\t\treturn options.map((option, index) => ({\n\t\t\toption,\n\t\t\tindex,\n\t\t\tisSelected: isSelected?.(option) ?? false,\n\t\t\tisDisabled: option.disabled ?? false\n\t\t}));\n\t}, [options, isSelected]);\n\n\tconst renderOptionItem = useCallback(\n\t\t({\n\t\t\toption,\n\t\t\tisSelected: selected,\n\t\t\tisDisabled: disabled,\n\t\t\tindex\n\t\t}: {\n\t\t\toption: T;\n\t\t\tisSelected: boolean;\n\t\t\tisDisabled: boolean;\n\t\t\tindex: number;\n\t\t}) => {\n\t\t\tif (renderOption) {\n\t\t\t\tconst customRender = renderOption({\n\t\t\t\t\toption,\n\t\t\t\t\ttype: \"list\",\n\t\t\t\t\tisSelected: selected,\n\t\t\t\t\tisDisabled: disabled,\n\t\t\t\t\tsearchQuery,\n\t\t\t\t\tindex\n\t\t\t\t});\n\t\t\t\tif (customRender !== undefined) {\n\t\t\t\t\treturn customRender;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn (\n\t\t\t\t<>\n\t\t\t\t\t{option.label}\n\t\t\t\t\t{selected && <Icon icon={CheckIcon} className=\"ml-auto\" />}\n\t\t\t\t</>\n\t\t\t);\n\t\t},\n\t\t[renderOption, searchQuery]\n\t);\n\n\t// Состояние ошибки\n\tif (loadingState === \"error\") {\n\t\treturn <ErrorState className=\"py-6\">{error || errorText}</ErrorState>;\n\t}\n\n\t// Состояние загрузки\n\tif (loadingState === \"loading\") {\n\t\treturn <Loader className=\"py-6\">{loadingText}</Loader>;\n\t}\n\n\t// Подсказка для режима input\n\tif (loadMode === \"input\" && searchQuery.length < minInputLength) {\n\t\treturn <HintState className=\"py-6\">{inputHintText}</HintState>;\n\t}\n\n\t// Пустое состояние\n\tif (options.length === 0 && loadingState === \"success\") {\n\t\treturn <EmptyState className=\"py-6\">{emptyText}</EmptyState>;\n\t}\n\n\t// Список опций\n\treturn (\n\t\t<>\n\t\t\t{optionsWithSelection.map(({ option, index, isSelected: selected, isDisabled: disabled }) => (\n\t\t\t\t<CommandItem\n\t\t\t\t\tkey={option.value}\n\t\t\t\t\tvalue={option.label}\n\t\t\t\t\tonSelect={disabled ? undefined : onSelect}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t>\n\t\t\t\t\t{renderOptionItem({\n\t\t\t\t\t\toption,\n\t\t\t\t\t\tisSelected: selected,\n\t\t\t\t\t\tisDisabled: disabled,\n\t\t\t\t\t\tindex\n\t\t\t\t\t})}\n\t\t\t\t</CommandItem>\n\t\t\t))}\n\t\t</>\n\t);\n};\n","import { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useDebounce } from \"../../../../hooks/useDebounce\";\nimport { Command, CommandList } from \"../../../command/Command\";\nimport { SearchSelectInput } from \"../../search-select/components/SearchSelectInput\";\nimport { useAsyncDataLoader } from \"../hooks/useAsyncDataLoader\";\nimport type { AsyncSearchSelectProps, SearchSelectOption } from \"../types\";\nimport { AsyncSearchSelectContent } from \"./AsyncSearchSelectContent\";\n\ninterface AsyncSearchSelectPopoverContentProps<T extends SearchSelectOption = SearchSelectOption>\n\textends Pick<\n\t\tAsyncSearchSelectProps<T>,\n\t\t| \"loadOptions\"\n\t\t| \"loadMode\"\n\t\t| \"minInputLength\"\n\t\t| \"debounceMs\"\n\t\t| \"searchPlaceholder\"\n\t\t| \"loadingText\"\n\t\t| \"errorText\"\n\t\t| \"inputHintText\"\n\t\t| \"emptyText\"\n\t\t| \"renderOption\"\n\t\t| \"hideSearch\"\n\t> {\n\tonSelect: (value: T | null) => void;\n\tisSelected?: (value: T) => boolean;\n}\n\nexport const AsyncSearchSelectPopoverContent = <T extends SearchSelectOption = SearchSelectOption>(\n\tprops: AsyncSearchSelectPopoverContentProps<T>\n) => {\n\tconst {\n\t\tloadOptions,\n\t\tloadMode = \"auto\",\n\t\tminInputLength = 3,\n\t\tdebounceMs = 300,\n\t\tsearchPlaceholder = \"Найти\",\n\t\tloadingText = \"Загружаем...\",\n\t\terrorText = \"Ошибка загрузки\",\n\t\tinputHintText = \"Введите текст для поиска\",\n\t\temptyText = \"Результатов не найдено\",\n\t\trenderOption,\n\t\tonSelect,\n\t\tisSelected,\n\t\thideSearch\n\t} = props;\n\n\tconst [searchQuery, setSearchQuery] = useState(\"\");\n\n\t// Дебаунсированный поисковый запрос для загрузки данных\n\tconst debouncedSearchQuery = useDebounce(searchQuery, debounceMs);\n\n\tconst { options, loadingState, error, loadData } = useAsyncDataLoader<T>({\n\t\tloadOptions\n\t});\n\n\tconst shouldLoad = useMemo(() => {\n\t\tif (loadMode === \"auto\") return true;\n\t\tif (loadMode === \"input\") return debouncedSearchQuery.length >= minInputLength;\n\t\treturn false;\n\t}, [loadMode, debouncedSearchQuery, minInputLength]);\n\n\t// Загрузка при изменении условий\n\tuseEffect(() => {\n\t\tif (shouldLoad) loadData(debouncedSearchQuery);\n\t}, [shouldLoad, debouncedSearchQuery, loadData]);\n\n\tconst handleSelect = useCallback(\n\t\t(label: string) => {\n\t\t\tonSelect(options.find((option) => option.label === label) || null);\n\t\t},\n\t\t[onSelect, options]\n\t);\n\n\treturn (\n\t\t<Command shouldFilter={false}>\n\t\t\t{!hideSearch && <SearchSelectInput placeholder={searchPlaceholder} onValueChange={setSearchQuery} />}\n\t\t\t<CommandList key={`list-${debouncedSearchQuery}`} className=\"p-1\">\n\t\t\t\t<AsyncSearchSelectContent\n\t\t\t\t\toptions={options}\n\t\t\t\t\tloadingState={loadingState}\n\t\t\t\t\terror={error}\n\t\t\t\t\tisSelected={isSelected}\n\t\t\t\t\tsearchQuery={debouncedSearchQuery}\n\t\t\t\t\tloadMode={loadMode}\n\t\t\t\t\tminInputLength={minInputLength}\n\t\t\t\t\tonSelect={handleSelect}\n\t\t\t\t\trenderOption={renderOption}\n\t\t\t\t\tloadingText={loadingText}\n\t\t\t\t\terrorText={errorText}\n\t\t\t\t\tinputHintText={inputHintText}\n\t\t\t\t\temptyText={emptyText}\n\t\t\t\t/>\n\t\t\t</CommandList>\n\t\t</Command>\n\t);\n};\n","import { useControllableState } from \"@/hooks/useControllableState\";\nimport { useCallback, useMemo, useState } from \"react\";\nimport { Popover, PopoverTrigger } from \"../../popover\";\nimport { SearchSelectTextValue } from \"../components/SearchSelectTextValue\";\nimport { SearchSelectTrigger } from \"../components/SearchSelectTrigger\";\nimport { SearchSelectContent } from \"../search-select/components/SearchSelectContent\";\nimport { AsyncSearchSelectPopoverContent } from \"./components/AsyncSearchSelectPopoverContent\";\nimport type { AsyncSearchSelectProps, SearchSelectOption } from \"./types\";\n\nexport const AsyncSearchSelect = <T extends SearchSelectOption = SearchSelectOption>(\n\tprops: AsyncSearchSelectProps<T>\n) => {\n\tconst {\n\t\trenderOption,\n\t\tplaceholder = \"Выберите значение\",\n\t\tvalue,\n\t\tdefaultValue,\n\t\tdisabled,\n\t\tinvalid,\n\t\tonChange,\n\t\tstartIcon,\n\t\tonClear,\n\t\t...popoverProps\n\t} = props;\n\n\tconst [open, setOpen] = useState(false);\n\n\tconst [currentOption, setCurrentOption] = useControllableState<T>({\n\t\tvalue,\n\t\tdefaultValue,\n\t\tonChange\n\t});\n\n\tconst displayValue = useMemo(() => {\n\t\tif (!currentOption) return undefined;\n\t\tif (renderOption) {\n\t\t\tconst item = renderOption({ option: currentOption, type: \"trigger\" });\n\t\t\tif (item !== undefined) {\n\t\t\t\treturn item;\n\t\t\t}\n\t\t}\n\t\treturn <SearchSelectTextValue>{currentOption.label}</SearchSelectTextValue>;\n\t}, [currentOption, renderOption]);\n\n\tconst onSelect = useCallback(\n\t\t(option: T | null) => {\n\t\t\tif (option) setCurrentOption(option);\n\t\t\tsetOpen(false);\n\t\t},\n\t\t[setCurrentOption, setOpen]\n\t);\n\n\tconst isSelected = useCallback(\n\t\t(option: T) => {\n\t\t\treturn currentOption?.value === option.value;\n\t\t},\n\t\t[currentOption]\n\t);\n\n\treturn (\n\t\t<Popover {...popoverProps} open={open} onOpenChange={setOpen}>\n\t\t\t<PopoverTrigger asChild>\n\t\t\t\t<SearchSelectTrigger\n\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\tinvalid={invalid}\n\t\t\t\t\topen={open}\n\t\t\t\t\tstartIcon={startIcon}\n\t\t\t\t\tonClear={onClear}\n\t\t\t\t>\n\t\t\t\t\t{displayValue}\n\t\t\t\t</SearchSelectTrigger>\n\t\t\t</PopoverTrigger>\n\t\t\t<SearchSelectContent>\n\t\t\t\t<AsyncSearchSelectPopoverContent {...props} onSelect={onSelect} isSelected={isSelected} />\n\t\t\t</SearchSelectContent>\n\t\t</Popover>\n\t);\n};\n","import { useControllableState } from \"@/hooks/useControllableState\";\nimport { useItemsKeyboardNavigation } from \"@/hooks/useItemsKeyboardNavigation\";\nimport { PopoverProps } from \"@radix-ui/react-popover\";\nimport { useCallback, useMemo, useState } from \"react\";\nimport { SearchSelectOption } from \"../../../hooks/useSearchSelect\";\nimport { Popover, PopoverTrigger } from \"../../popover\";\nimport { AsyncSearchSelectPopoverContent } from \"../async-search-select/components/AsyncSearchSelectPopoverContent\";\nimport { LoadOptionsParams, LoadOptionsResult } from \"../async-search-select/types\";\nimport { SearchSelectTag } from \"../components/SearchSelectTag\";\nimport { SearchSelectTrigger } from \"../components/SearchSelectTrigger\";\nimport { SearchSelectContent } from \"../search-select/components/SearchSelectContent\";\n\n/**\n * Пропсы для рендера опции в trigger (кнопке)\n */\nexport type RenderOptionInTriggerProps = {\n\ttype: \"trigger\";\n\tonClose?: () => void;\n};\n\n/**\n * Пропсы для рендера опции в списке\n */\nexport type RenderOptionInListProps = {\n\ttype: \"list\";\n\t/** Выбрана ли опция в данный момент */\n\tisSelected: boolean;\n\t/** Отключена ли опция */\n\tisDisabled: boolean;\n\t/** Текущий поисковый запрос для подсветки совпадений */\n\tsearchQuery: string;\n\t/** Индекс элемента в списке */\n\tindex: number;\n};\n\n/**\n * Объединенный тип для рендера опции\n */\nexport type RenderOptionProps<T extends SearchSelectOption = SearchSelectOption> = {\n\toption: T;\n} & (RenderOptionInTriggerProps | RenderOptionInListProps);\n\nexport interface MultiSelectProps<T extends SearchSelectOption = SearchSelectOption> {\n\t/** Дополнительные классы для контейнера */\n\tclassName?: string;\n\t/** Флаг для отключения компонента */\n\tdisabled?: boolean;\n\t/** Текст placeholder, отображается когда ничего не выбрано */\n\tplaceholder?: string;\n\t/** Текущие выбранные опции (controlled режим) */\n\tvalue?: T[];\n\t/** Опции по умолчанию (uncontrolled режим) */\n\tdefaultValue?: T[];\n\t/** Callback при изменении выбранных опций */\n\tonChange?: (options: T[]) => void;\n\t/** Callback при очистке значения */\n\tonClear?: () => void;\n\t/** Оставлять поповер открытым после выбора элемента */\n\tkeepOpenOnSelect?: boolean;\n\t/** Обработчик клика по названию выбранного тега */\n\tonLabelClick?: (option: T) => void;\n\t/** Функция загрузки опций */\n\tloadOptions: (params: LoadOptionsParams) => Promise<LoadOptionsResult<T>>;\n\t/** Режим загрузки опций */\n\tloadMode?: \"auto\" | \"input\";\n\t/** Минимальное количество символов для начала загрузки (только для режима \"input\") */\n\tminInputLength?: number;\n\t/** Задержка перед отправкой запроса в миллисекундах (debounce) */\n\tdebounceMs?: number;\n\t/** Текст подсказки для режима \"input\", когда пользователь еще не ввел символы */\n\tinputHintText?: string;\n\t/** Текст во время загрузки */\n\tloadingText?: string;\n\t/** Текст при ошибке загрузки */\n\terrorText?: string;\n\t/** Кастомная функция рендера опции */\n\trenderOption?: (props: RenderOptionProps<T>) => React.ReactNode;\n\t/** Текст placeholder для поиска */\n\tsearchPlaceholder?: string;\n\t/** Текст для пустого состояния */\n\temptyText?: string;\n\t/** Дополнительные пропсы для Popover */\n\tpopoverProps?: PopoverProps;\n\t/** Состояние ошибки */\n\tinvalid?: boolean;\n\t/** Иконка, отображаемая в начале поля */\n\tstartIcon?: React.ReactNode;\n\t/** Скрыть поле поиска */\n\thideSearch?: boolean;\n}\n\n/**\n * Компонент для множественного выбора элементов из списка\n */\nexport const MultiSelect = <T extends SearchSelectOption = SearchSelectOption>(props: MultiSelectProps<T>) => {\n\tconst {\n\t\tclassName,\n\t\tplaceholder = \"Выберите значение\",\n\t\tvalue,\n\t\tdefaultValue,\n\t\tonChange,\n\t\tdisabled,\n\t\tinvalid,\n\t\tkeepOpenOnSelect = true,\n\t\tonClear,\n\t\tonLabelClick,\n\t\trenderOption,\n\t\tstartIcon,\n\t\t...popoverProps\n\t} = props;\n\n\tconst [open, setOpen] = useState(false);\n\n\tconst [selectedOptions, setSelectedOptions] = useControllableState<T[]>({\n\t\tvalue,\n\t\tdefaultValue,\n\t\tonChange\n\t});\n\n\tconst onSelect = useCallback(\n\t\t(option: T | null) => {\n\t\t\tif (option) {\n\t\t\t\tconst isAlreadySelected = selectedOptions?.find((o) => o.value === option.value);\n\t\t\t\tif (isAlreadySelected) {\n\t\t\t\t\tsetSelectedOptions((prev) => {\n\t\t\t\t\t\treturn prev?.filter((o) => o.value !== option.value) || [];\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tsetSelectedOptions((prev) => {\n\t\t\t\t\t\treturn [...(prev || []), option];\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!keepOpenOnSelect) {\n\t\t\t\tsetOpen(false);\n\t\t\t}\n\t\t},\n\t\t[selectedOptions, keepOpenOnSelect, setSelectedOptions, setOpen]\n\t);\n\n\tconst handleClose = useCallback(\n\t\t(option: T) => {\n\t\t\tconst isSelected = selectedOptions?.find((o) => o.value === option.value);\n\t\t\tif (isSelected) {\n\t\t\t\tsetSelectedOptions((prev) => {\n\t\t\t\t\treturn prev?.filter((o) => o.value !== option.value) || [];\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[selectedOptions, setSelectedOptions]\n\t);\n\n\tconst isSelected = useCallback(\n\t\t(option: T) => {\n\t\t\treturn selectedOptions?.some((selectedOption) => selectedOption.value === option.value) ?? false;\n\t\t},\n\t\t[selectedOptions]\n\t);\n\n\tconst { handleKeyDown, isFocused } = useItemsKeyboardNavigation({\n\t\titems: selectedOptions || [],\n\t\tonEnter: onLabelClick,\n\t\tonDelete: handleClose\n\t});\n\n\tconst displayValue = useMemo(() => {\n\t\tif (!selectedOptions || selectedOptions.length === 0) return undefined;\n\n\t\treturn selectedOptions.map((option, index) => {\n\t\t\tif (renderOption) {\n\t\t\t\tconst item = renderOption({\n\t\t\t\t\toption,\n\t\t\t\t\ttype: \"trigger\",\n\t\t\t\t\tonClose: () => {\n\t\t\t\t\t\thandleClose(option);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tif (item !== undefined) {\n\t\t\t\t\treturn item;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn (\n\t\t\t\t<SearchSelectTag\n\t\t\t\t\tkey={option.value}\n\t\t\t\t\tonLabelClick={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tonLabelClick?.(option);\n\t\t\t\t\t}}\n\t\t\t\t\tonClose={(e) => {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\thandleClose(option);\n\t\t\t\t\t}}\n\t\t\t\t\tisFocused={isFocused(index)}\n\t\t\t\t>\n\t\t\t\t\t{option.label}\n\t\t\t\t</SearchSelectTag>\n\t\t\t);\n\t\t});\n\t}, [selectedOptions, renderOption, handleClose, onLabelClick, isFocused]);\n\n\treturn (\n\t\t<div className={className}>\n\t\t\t<Popover open={open} onOpenChange={setOpen} {...popoverProps}>\n\t\t\t\t<PopoverTrigger asChild>\n\t\t\t\t\t<SearchSelectTrigger\n\t\t\t\t\t\tonKeyDown={handleKeyDown}\n\t\t\t\t\t\tdisabled={disabled}\n\t\t\t\t\t\topen={open}\n\t\t\t\t\t\tplaceholder={placeholder}\n\t\t\t\t\t\tinvalid={invalid}\n\t\t\t\t\t\tstartIcon={startIcon}\n\t\t\t\t\t\tonClear={onClear}\n\t\t\t\t\t\tclassName=\"h-auto !py-[0.3125rem] lg:h-auto\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{displayValue && <div className=\"flex flex-wrap gap-1.5 lg:gap-1\">{displayValue}</div>}\n\t\t\t\t\t</SearchSelectTrigger>\n\t\t\t\t</PopoverTrigger>\n\t\t\t\t<SearchSelectContent>\n\t\t\t\t\t<AsyncSearchSelectPopoverContent {...props} onSelect={onSelect} isSelected={isSelected} />\n\t\t\t\t</SearchSelectContent>\n\t\t\t</Popover>\n\t\t</div>\n\t);\n};\n\nMultiSelect.displayName = \"MultiSelect\";\n"],"names":["useSearchSelect","options","value","defaultValue","onChange","valueOption","selectedOption","setSelectedOption","useState","memoizedOnChange","useCallback","newValue","option","selectedValue","setSelectedValue","useControllableState","useEffect","currentOption","setSelectedByLabel","label","searchSelectTextValueStyles","tv","SearchSelectTextValue","children","className","jsx","searchSelectPlaceholderStyles","SearchSelectPlaceholder","searchSelectTriggerStyles","selectTriggerStyles","SearchSelectTrigger","React","disabled","open","invalid","placeholder","startIcon","onClear","props","ref","styles","jsxs","ClearButton","e","Icon","ChevronDownIcon","searchSelectContentStyles","SearchSelectContent","PopoverContent","SearchSelectInput","CommandInput","searchSelectStyles","SearchSelect","forwardRef","id","renderOption","onBlur","searchPlaceholder","emptyText","shouldFilter","footerContent","onSearchChange","onOpenChange","hideSearch","popoverProps","setOpen","searchQuery","setSearchQuery","handleSelect","handleSearchChange","handleOpenChange","displayValue","useMemo","item","renderedOptions","index","isDisabled","isSelected","renderOptionItem","customRender","Fragment","CheckIcon","CommandItem","Popover","PopoverTrigger","Command","CommandList","CommandEmpty","loadMoreTriggerStyles","LoadMoreTrigger","onLoad","hasMore","loadingText","triggerRef","useRef","trigger","observer","entry","Loader","defaultFuzzyFilter","search","valueLower","searchLower","searchIndex","i","LazySearchSelect","pageSize","filter","searchSelectProps","visibleCount","setVisibleCount","setValueOption","currentValue","visibleOptions","hasMoreItems","filteredAndRanked","score","a","b","visible","handleLoadMore","prev","SearchSelectSeparator","CommandSeparator","useAsyncDataLoader","loadOptions","setItems","loadingState","setLoadingState","error","setError","abortControllerRef","requestSequenceRef","cancelRequests","loadData","query","currentSequence","abortController","result","err","AsyncSearchSelectContent","loadMode","minInputLength","onSelect","errorText","inputHintText","optionsWithSelection","selected","ErrorState","HintState","EmptyState","AsyncSearchSelectPopoverContent","debounceMs","debouncedSearchQuery","useDebounce","shouldLoad","AsyncSearchSelect","setCurrentOption","MultiSelect","keepOpenOnSelect","onLabelClick","selectedOptions","setSelectedOptions","isAlreadySelected","o","handleClose","handleKeyDown","isFocused","useItemsKeyboardNavigation","SearchSelectTag"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { S as l, d as a, a as c, f as S, l as s, k as o, e as r, j as n, i as p, h as i, g as m, c as u, b as I } from "../Select-Bfrb-J8s.js";
1
+ import { S as l, d as a, a as c, f as S, l as s, k as o, e as r, j as n, i as p, h as i, g as m, c as u, b as I } from "../Select-CWbLja8r.js";
2
2
  export {
3
3
  l as Select,
4
4
  a as SelectContent,
@@ -1,4 +1,4 @@
1
- import { S as t } from "../Shortcut-Cm4nUx2C.js";
1
+ import { S as t } from "../Shortcut-D8L15_ed.js";
2
2
  export {
3
3
  t as Shortcut
4
4
  };