@feugene/granularity 0.48.0 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (418) hide show
  1. package/README.md +3 -3
  2. package/dist/chunks/chevron-up-BhW6hi8L.js +23 -0
  3. package/dist/chunks/chevron-up-BhW6hi8L.js.map +1 -0
  4. package/dist/chunks/{config-E1cTyRVV.js → config-8n1VR0ju.js} +1 -1
  5. package/dist/chunks/{config-E1cTyRVV.js.map → config-8n1VR0ju.js.map} +1 -1
  6. package/dist/chunks/{config-2vrOFn2f.js → config-AKpLyIGD.js} +2 -2
  7. package/dist/chunks/{config-2vrOFn2f.js.map → config-AKpLyIGD.js.map} +1 -1
  8. package/dist/chunks/{config-DIDz_E5m.js → config-B34mkd53.js} +66 -1
  9. package/dist/chunks/config-B34mkd53.js.map +1 -0
  10. package/dist/chunks/{config-B5SBUa6u.js → config-B7qZqiUB.js} +28 -1
  11. package/dist/chunks/config-B7qZqiUB.js.map +1 -0
  12. package/dist/chunks/config-BBrPUEye.js +8 -0
  13. package/dist/chunks/config-BBrPUEye.js.map +1 -0
  14. package/dist/chunks/config-BBtBQE3s.js +108 -0
  15. package/dist/chunks/config-BBtBQE3s.js.map +1 -0
  16. package/dist/chunks/{config-CT4lP6S4.js → config-BOCzHqWh.js} +2 -2
  17. package/dist/chunks/{config-CT4lP6S4.js.map → config-BOCzHqWh.js.map} +1 -1
  18. package/dist/chunks/{config-iemgzS4x.js → config-BP1ktzwh.js} +2 -24
  19. package/dist/chunks/config-BP1ktzwh.js.map +1 -0
  20. package/dist/chunks/config-BTxmdRzT.js +28 -0
  21. package/dist/chunks/config-BTxmdRzT.js.map +1 -0
  22. package/dist/chunks/{config-CjWOTgLL.js → config-Bk52xd5l.js} +12 -5
  23. package/dist/chunks/config-Bk52xd5l.js.map +1 -0
  24. package/dist/chunks/{config-D3HOuHDe.js → config-C3SqBqSQ.js} +3 -1
  25. package/dist/chunks/config-C3SqBqSQ.js.map +1 -0
  26. package/dist/chunks/{config-2ZHRsdOc.js → config-C3uqd-sW.js} +1 -1
  27. package/dist/chunks/config-C3uqd-sW.js.map +1 -0
  28. package/dist/chunks/{config-BXRmsn3t.js → config-CPhcZzHi.js} +72 -10
  29. package/dist/chunks/config-CPhcZzHi.js.map +1 -0
  30. package/dist/chunks/config-CWtfxkM9.js.map +1 -1
  31. package/dist/chunks/{config--t2dxj0t.js → config-CmLTCmY9.js} +2 -2
  32. package/dist/chunks/{config--t2dxj0t.js.map → config-CmLTCmY9.js.map} +1 -1
  33. package/dist/chunks/{config-BAse0laT.js → config-CvtqB4ki.js} +8 -3
  34. package/dist/chunks/config-CvtqB4ki.js.map +1 -0
  35. package/dist/chunks/{config-BcXX7S7B.js → config-D-JgqV0J.js} +5 -1
  36. package/dist/chunks/{config-BcXX7S7B.js.map → config-D-JgqV0J.js.map} +1 -1
  37. package/dist/chunks/{config-BHLMTJaR.js → config-D1oVht-E.js} +8 -3
  38. package/dist/chunks/config-D1oVht-E.js.map +1 -0
  39. package/dist/chunks/{config-BscVxZR3.js → config-DF1ezU6y.js} +1 -1
  40. package/dist/chunks/{config-BscVxZR3.js.map → config-DF1ezU6y.js.map} +1 -1
  41. package/dist/chunks/{config-B42iJ48O.js → config-DG41PD9i.js} +13 -1
  42. package/dist/chunks/config-DG41PD9i.js.map +1 -0
  43. package/dist/chunks/{config-Bs1HwUcx.js → config-DPJ3jtiB.js} +12 -2
  44. package/dist/chunks/config-DPJ3jtiB.js.map +1 -0
  45. package/dist/chunks/{config-tNqtapcT.js → config-DpqjlCfB.js} +2 -2
  46. package/dist/chunks/{config-tNqtapcT.js.map → config-DpqjlCfB.js.map} +1 -1
  47. package/dist/chunks/{config-DNDgp9bB.js → config-DpzFoSIh.js} +64 -2
  48. package/dist/chunks/config-DpzFoSIh.js.map +1 -0
  49. package/dist/chunks/config-MUkhktTP.js +267 -0
  50. package/dist/chunks/config-MUkhktTP.js.map +1 -0
  51. package/dist/chunks/config-SPugeaHT.js +37 -0
  52. package/dist/chunks/config-SPugeaHT.js.map +1 -0
  53. package/dist/chunks/{en-Bxyn5lW7.js → en-mIFywnV2.js} +27 -7
  54. package/dist/chunks/en-mIFywnV2.js.map +1 -0
  55. package/dist/chunks/{es-Dtl-a7ui.js → es-CvthYwtB.js} +27 -7
  56. package/dist/chunks/es-CvthYwtB.js.map +1 -0
  57. package/dist/chunks/{es-Bj_vc18Z.js → es-DlGd6Mrj.js} +3 -3
  58. package/dist/chunks/{es-Bj_vc18Z.js.map → es-DlGd6Mrj.js.map} +1 -1
  59. package/dist/chunks/{generated-hELWB0gZ.js → generated-Cx4C7GRN.js} +126 -0
  60. package/dist/chunks/{generated-hELWB0gZ.js.map → generated-Cx4C7GRN.js.map} +1 -1
  61. package/dist/chunks/{grBadgeStyles-DV0DrAew.js → grBadgeStyles-D51AXbj5.js} +57 -1
  62. package/dist/chunks/grBadgeStyles-D51AXbj5.js.map +1 -0
  63. package/dist/chunks/{grChipStyles-DcDyxAL0.js → grChipStyles-CA9Wj1_E.js} +1 -1
  64. package/dist/chunks/{grChipStyles-DcDyxAL0.js.map → grChipStyles-CA9Wj1_E.js.map} +1 -1
  65. package/dist/chunks/{grPopoverStyles-CYAeO3Ov.js → grPopoverStyles-CncEkiPu.js} +1 -1
  66. package/dist/chunks/{grPopoverStyles-CYAeO3Ov.js.map → grPopoverStyles-CncEkiPu.js.map} +1 -1
  67. package/dist/chunks/{grSelectStyles-D9EQ-pgK.js → grSelectStyles-Cam-IG9s.js} +3 -2
  68. package/dist/chunks/grSelectStyles-Cam-IG9s.js.map +1 -0
  69. package/dist/chunks/{grSliderStyles-kaz6VXZ3.js → grSliderStyles-CqzV0hll.js} +1 -1
  70. package/dist/chunks/grSliderStyles-CqzV0hll.js.map +1 -0
  71. package/dist/chunks/{config-CbEbLyDE.js → grSortableListStyles-CxieDmpe.js} +1 -27
  72. package/dist/chunks/grSortableListStyles-CxieDmpe.js.map +1 -0
  73. package/dist/chunks/grTableStyles-CPSxDTOW.js +66 -0
  74. package/dist/chunks/grTableStyles-CPSxDTOW.js.map +1 -0
  75. package/dist/chunks/{config-CMNfZO7S.js → grTabsStyles-DIz2VdIm.js} +1 -36
  76. package/dist/chunks/grTabsStyles-DIz2VdIm.js.map +1 -0
  77. package/dist/chunks/grTooltipStyles-CtbGEEGV.js +24 -0
  78. package/dist/chunks/grTooltipStyles-CtbGEEGV.js.map +1 -0
  79. package/dist/chunks/{granular-provider-BOQp7N5o.js → granular-provider-cv5vaM1a.js} +26 -22
  80. package/dist/chunks/granular-provider-cv5vaM1a.js.map +1 -0
  81. package/dist/chunks/hotkeySequence-BTHIM_5A.js +46 -0
  82. package/dist/chunks/hotkeySequence-BTHIM_5A.js.map +1 -0
  83. package/dist/chunks/{keyboard-DE2yhz_b.js → keyboard-BiFSgWLt.js} +70 -1
  84. package/dist/chunks/keyboard-BiFSgWLt.js.map +1 -0
  85. package/dist/chunks/optionPanel-DvY7Tv_4.js +182 -0
  86. package/dist/chunks/optionPanel-DvY7Tv_4.js.map +1 -0
  87. package/dist/chunks/overlayListPanel-D91jBCHU.js +21 -0
  88. package/dist/chunks/overlayListPanel-D91jBCHU.js.map +1 -0
  89. package/dist/chunks/{overlayStack-DH4Z7am1.js → overlayStack-DCkCgXZP.js} +1 -1
  90. package/dist/chunks/{overlayStack-DH4Z7am1.js.map → overlayStack-DCkCgXZP.js.map} +1 -1
  91. package/dist/chunks/{overlayPanelSurface-BKeMhRx4.js → overlayTransition-C0FDMx7Q.js} +24 -24
  92. package/dist/chunks/overlayTransition-C0FDMx7Q.js.map +1 -0
  93. package/dist/chunks/{ru-hrB4I1u_.js → ru-CQKDR-kD.js} +27 -7
  94. package/dist/chunks/ru-CQKDR-kD.js.map +1 -0
  95. package/dist/chunks/{safelist-x8USecK8.js → safelist-CSfynUC1.js} +5 -1
  96. package/dist/chunks/safelist-CSfynUC1.js.map +1 -0
  97. package/dist/chunks/{useMenuItemsFocus-B7Bl_aFA.js → useMenuItemsFocus-C031blYS.js} +1 -1
  98. package/dist/chunks/{useMenuItemsFocus-B7Bl_aFA.js.map → useMenuItemsFocus-C031blYS.js.map} +1 -1
  99. package/dist/chunks/{useModalOverlay-ACRkflzx.js → useModalOverlay-CKCQkGdB.js} +1 -1
  100. package/dist/chunks/{useModalOverlay-ACRkflzx.js.map → useModalOverlay-CKCQkGdB.js.map} +1 -1
  101. package/dist/components/GrAutocomplete/chunks/{GrAutocomplete-C-uovdv8.js → GrAutocomplete-Cyr1-ENw.js} +183 -125
  102. package/dist/components/GrAutocomplete/chunks/GrAutocomplete-Cyr1-ENw.js.map +1 -0
  103. package/dist/components/GrAutocomplete/index.js +2 -2
  104. package/dist/components/GrAutocomplete/styles.css +1 -1
  105. package/dist/components/GrBadge/chunks/GrBadge-C42KLyUD.js +71 -0
  106. package/dist/components/GrBadge/chunks/GrBadge-C42KLyUD.js.map +1 -0
  107. package/dist/components/GrBadge/index.js +3 -3
  108. package/dist/components/GrBadge/styles.css +1 -1
  109. package/dist/components/GrCarousel/chunks/{GrCarousel-ByuughtI.js → GrCarousel-CBj-PEPB.js} +186 -37
  110. package/dist/components/GrCarousel/chunks/GrCarousel-CBj-PEPB.js.map +1 -0
  111. package/dist/components/GrCarousel/index.js +2 -2
  112. package/dist/components/GrCarousel/styles.css +1 -1
  113. package/dist/components/GrCheckbox/chunks/{GrCheckbox-Dp201frb.js → GrCheckbox-B4NJc7Ur.js} +2 -1
  114. package/dist/components/GrCheckbox/chunks/GrCheckbox-B4NJc7Ur.js.map +1 -0
  115. package/dist/components/GrCheckbox/index.js +1 -1
  116. package/dist/components/GrCheckboxGroup/chunks/{GrCheckboxGroup-IpqG5qwm.js → GrCheckboxGroup-qZHpNFCX.js} +1 -1
  117. package/dist/components/GrCheckboxGroup/chunks/{GrCheckboxGroup-IpqG5qwm.js.map → GrCheckboxGroup-qZHpNFCX.js.map} +1 -1
  118. package/dist/components/GrCheckboxGroup/index.js +1 -1
  119. package/dist/components/GrChip/chunks/{GrChip-CKqyzYcv.js → GrChip-DoyS1Dr4.js} +1 -1
  120. package/dist/components/GrChip/chunks/{GrChip-CKqyzYcv.js.map → GrChip-DoyS1Dr4.js.map} +1 -1
  121. package/dist/components/GrChip/index.js +2 -2
  122. package/dist/components/GrColorPicker/chunks/{GrColorPicker-BRM_4lyI.js → GrColorPicker-vGSgpUV9.js} +353 -38
  123. package/dist/components/GrColorPicker/chunks/GrColorPicker-vGSgpUV9.js.map +1 -0
  124. package/dist/components/GrColorPicker/index.js +2 -2
  125. package/dist/components/GrColorPicker/styles.css +1 -1
  126. package/dist/components/GrCommandPalette/chunks/{GrCommandPalette-BJHmkDQv.js → GrCommandPalette-CAHgj0Aa.js} +23 -7
  127. package/dist/components/GrCommandPalette/chunks/GrCommandPalette-CAHgj0Aa.js.map +1 -0
  128. package/dist/components/GrCommandPalette/index.js +1 -1
  129. package/dist/components/GrCommandPalette/styles.css +1 -1
  130. package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-BzUQwbec.js → GrConfirmDialog-dg021BMd.js} +1 -1
  131. package/dist/components/GrConfirmDialog/chunks/{GrConfirmDialog-BzUQwbec.js.map → GrConfirmDialog-dg021BMd.js.map} +1 -1
  132. package/dist/components/GrConfirmDialog/index.js +1 -1
  133. package/dist/components/GrContextMenu/chunks/{GrContextMenu-RpxMHQXH.js → GrContextMenu-bQ1Vvy2c.js} +3 -3
  134. package/dist/components/GrContextMenu/chunks/{GrContextMenu-RpxMHQXH.js.map → GrContextMenu-bQ1Vvy2c.js.map} +1 -1
  135. package/dist/components/GrContextMenu/index.js +1 -1
  136. package/dist/components/GrDataTable/chunks/{GrDataTable-DQxYYgQk.js → GrDataTable-Bb2jWnRG.js} +576 -136
  137. package/dist/components/GrDataTable/chunks/GrDataTable-Bb2jWnRG.js.map +1 -0
  138. package/dist/components/GrDataTable/index.js +2 -2
  139. package/dist/components/GrDelta/chunks/{GrDelta-CgTvfoIN.js → GrDelta-BSv1KdMy.js} +0 -0
  140. package/dist/components/GrDelta/chunks/{GrDelta-CgTvfoIN.js.map → GrDelta-BSv1KdMy.js.map} +1 -1
  141. package/dist/components/GrDelta/index.js +2 -2
  142. package/dist/components/GrDialog/chunks/{GrDialog-DDz_OEhk.js → GrDialog-C9Zu72jB.js} +1 -1
  143. package/dist/components/GrDialog/chunks/{GrDialog-DDz_OEhk.js.map → GrDialog-C9Zu72jB.js.map} +1 -1
  144. package/dist/components/GrDialog/index.js +1 -1
  145. package/dist/components/GrDialogService/chunks/{GrDialogService-Dtq0ZCN5.js → GrDialogService-DLBifO61.js} +2 -2
  146. package/dist/components/GrDialogService/chunks/{GrDialogService-Dtq0ZCN5.js.map → GrDialogService-DLBifO61.js.map} +1 -1
  147. package/dist/components/GrDialogService/index.js +1 -1
  148. package/dist/components/GrDrawer/chunks/{GrDrawer-CNpSMuN-.js → GrDrawer-DOcRTE8G.js} +1 -1
  149. package/dist/components/GrDrawer/chunks/{GrDrawer-CNpSMuN-.js.map → GrDrawer-DOcRTE8G.js.map} +1 -1
  150. package/dist/components/GrDrawer/index.js +1 -1
  151. package/dist/components/GrDropdown/chunks/{GrDropdown-cLZuZMEY.js → GrDropdown-kxwmgfSe.js} +2 -2
  152. package/dist/components/GrDropdown/chunks/{GrDropdown-cLZuZMEY.js.map → GrDropdown-kxwmgfSe.js.map} +1 -1
  153. package/dist/components/GrDropdown/index.js +2 -2
  154. package/dist/components/GrDropdownMenu/chunks/{GrDropdownMenu-Dxkz_ry4.js → GrDropdownMenu--VoK3VY0.js} +3 -34
  155. package/dist/components/GrDropdownMenu/chunks/GrDropdownMenu--VoK3VY0.js.map +1 -0
  156. package/dist/components/GrDropdownMenu/chunks/GrDropdownMenu-CkM3BFPL.js +34 -0
  157. package/dist/components/GrDropdownMenu/chunks/GrDropdownMenu-CkM3BFPL.js.map +1 -0
  158. package/dist/components/GrDropdownMenu/index.js +2 -1
  159. package/dist/components/GrEmptyState/chunks/{GrEmptyState-BbvwE-E0.js → GrEmptyState-Bz6-_ED4.js} +42 -6
  160. package/dist/components/GrEmptyState/chunks/GrEmptyState-Bz6-_ED4.js.map +1 -0
  161. package/dist/components/GrEmptyState/index.js +1 -1
  162. package/dist/components/GrFileUpload/chunks/{GrFileUpload-BwMR71zN.js → GrFileUpload-Bgdfnkd8.js} +5 -2
  163. package/dist/components/GrFileUpload/chunks/GrFileUpload-Bgdfnkd8.js.map +1 -0
  164. package/dist/components/GrFileUpload/index.js +1 -1
  165. package/dist/components/GrFormFile/chunks/{GrFormFile-Dlxx-9zi.js → GrFormFile-Ctq1isz-.js} +78 -11
  166. package/dist/components/GrFormFile/chunks/GrFormFile-Ctq1isz-.js.map +1 -0
  167. package/dist/components/GrFormFile/index.js +2 -2
  168. package/dist/components/GrFormFile/styles.css +1 -1
  169. package/dist/components/GrImageViewer/chunks/{GrImageViewer-DK-iVHHC.js → GrImageViewer-Bnql_dNP.js} +1 -1
  170. package/dist/components/GrImageViewer/chunks/{GrImageViewer-DK-iVHHC.js.map → GrImageViewer-Bnql_dNP.js.map} +1 -1
  171. package/dist/components/GrImageViewer/index.js +1 -1
  172. package/dist/components/GrInput/chunks/{GrInput-DV4gMWPR.js → GrInput-CoaFLpaU.js} +43 -22
  173. package/dist/components/GrInput/chunks/GrInput-CoaFLpaU.js.map +1 -0
  174. package/dist/components/GrInput/index.js +1 -1
  175. package/dist/components/GrInputTag/chunks/{GrInputTag-CO0YU-ok.js → GrInputTag-BzzNRBe3.js} +247 -20
  176. package/dist/components/GrInputTag/chunks/GrInputTag-BzzNRBe3.js.map +1 -0
  177. package/dist/components/GrInputTag/index.js +2 -2
  178. package/dist/components/GrJsonViewer/chunks/{GrJsonViewer-D7CyWzhT.js → GrJsonViewer-B6ZJ3GFH.js} +2 -2
  179. package/dist/components/GrJsonViewer/chunks/{GrJsonViewer-D7CyWzhT.js.map → GrJsonViewer-B6ZJ3GFH.js.map} +1 -1
  180. package/dist/components/GrJsonViewer/index.js +1 -1
  181. package/dist/components/GrKbd/chunks/{GrKbd-BNMeoaLV.js → GrKbd-D2rHDkQv.js} +42 -37
  182. package/dist/components/GrKbd/chunks/GrKbd-D2rHDkQv.js.map +1 -0
  183. package/dist/components/GrKbd/index.js +1 -1
  184. package/dist/components/GrModal/chunks/{GrModal-Cm0mtSXk.js → GrModal-SHb1U2qx.js} +1 -1
  185. package/dist/components/GrModal/chunks/{GrModal-Cm0mtSXk.js.map → GrModal-SHb1U2qx.js.map} +1 -1
  186. package/dist/components/GrModal/index.js +1 -1
  187. package/dist/components/GrNavbar/chunks/{GrNavbar-BRGuksiy.js → GrNavbar-IEIHC5Vt.js} +10 -4
  188. package/dist/components/GrNavbar/chunks/GrNavbar-IEIHC5Vt.js.map +1 -0
  189. package/dist/components/GrNavbar/index.js +2 -2
  190. package/dist/components/GrNumberInput/chunks/{GrNumberInput-BI6-vkcs.js → GrNumberInput-CmnUDaKi.js} +2 -22
  191. package/dist/components/GrNumberInput/chunks/{GrNumberInput-BI6-vkcs.js.map → GrNumberInput-CmnUDaKi.js.map} +1 -1
  192. package/dist/components/GrNumberInput/index.js +1 -1
  193. package/dist/components/GrOtpInput/chunks/GrOtpInput-B_Q-RDLw.js +419 -0
  194. package/dist/components/GrOtpInput/chunks/GrOtpInput-B_Q-RDLw.js.map +1 -0
  195. package/dist/components/GrOtpInput/index.js +3 -0
  196. package/dist/components/GrOtpInput/styles.css +1 -0
  197. package/dist/components/GrPagination/chunks/{GrPagination-BbaF5eXk.js → GrPagination-AMbn5D8I.js} +1 -1
  198. package/dist/components/GrPagination/chunks/{GrPagination-BbaF5eXk.js.map → GrPagination-AMbn5D8I.js.map} +1 -1
  199. package/dist/components/GrPagination/index.js +1 -1
  200. package/dist/components/GrPopover/chunks/{GrPopover-CcWvr1ZA.js → GrPopover-DjVxt8bf.js} +3 -3
  201. package/dist/components/GrPopover/chunks/{GrPopover-CcWvr1ZA.js.map → GrPopover-DjVxt8bf.js.map} +1 -1
  202. package/dist/components/GrPopover/index.js +2 -2
  203. package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-BEL-QgwE.js → GrPromptDialog-BhbIZP1f.js} +3 -3
  204. package/dist/components/GrPromptDialog/chunks/{GrPromptDialog-BEL-QgwE.js.map → GrPromptDialog-BhbIZP1f.js.map} +1 -1
  205. package/dist/components/GrPromptDialog/index.js +1 -1
  206. package/dist/components/GrSelect/chunks/{GrSelect-0iI4wdR_.js → GrSelect-B-ykrHpL.js} +26 -182
  207. package/dist/components/GrSelect/chunks/GrSelect-B-ykrHpL.js.map +1 -0
  208. package/dist/components/GrSelect/index.js +2 -2
  209. package/dist/components/GrSelect/styles.css +1 -1
  210. package/dist/components/GrSidebar/chunks/GrSidebar-jVvoLGDO.js +543 -0
  211. package/dist/components/GrSidebar/chunks/GrSidebar-jVvoLGDO.js.map +1 -0
  212. package/dist/components/GrSidebar/index.js +2 -2
  213. package/dist/components/GrSlider/chunks/{GrSlider-CO8N9SF6.js → GrSlider-DF2Cq0rV.js} +29 -4
  214. package/dist/components/GrSlider/chunks/GrSlider-DF2Cq0rV.js.map +1 -0
  215. package/dist/components/GrSlider/index.js +2 -2
  216. package/dist/components/GrSortableList/chunks/{GrSortableList-NKriuGm_.js → GrSortableList-ChH9nQBv.js} +1 -1
  217. package/dist/components/GrSortableList/chunks/{GrSortableList-NKriuGm_.js.map → GrSortableList-ChH9nQBv.js.map} +1 -1
  218. package/dist/components/GrSortableList/index.js +2 -2
  219. package/dist/components/GrSwitch/chunks/{GrSwitch-CriHWT2A.js → GrSwitch-D7X42uIA.js} +61 -7
  220. package/dist/components/GrSwitch/chunks/GrSwitch-D7X42uIA.js.map +1 -0
  221. package/dist/components/GrSwitch/index.js +2 -2
  222. package/dist/components/GrTabPanels/chunks/GrTabPanels-BDt5oVdd.js +30 -0
  223. package/dist/components/GrTabPanels/chunks/GrTabPanels-BDt5oVdd.js.map +1 -0
  224. package/dist/components/GrTabPanels/chunks/GrTabPanels-BJvAflnA.js +83 -0
  225. package/dist/components/GrTabPanels/chunks/GrTabPanels-BJvAflnA.js.map +1 -0
  226. package/dist/components/GrTabPanels/index.js +2 -1
  227. package/dist/components/GrTable/chunks/{GrTable-CKJ-HrsN.js → GrTable-BQitSDep.js} +52 -16
  228. package/dist/components/GrTable/chunks/GrTable-BQitSDep.js.map +1 -0
  229. package/dist/components/GrTable/index.js +2 -2
  230. package/dist/components/GrTabs/chunks/{GrTabs-s9RzC1WX.js → GrTabs-DVC6nfWB.js} +1 -1
  231. package/dist/components/GrTabs/chunks/{GrTabs-s9RzC1WX.js.map → GrTabs-DVC6nfWB.js.map} +1 -1
  232. package/dist/components/GrTabs/index.js +2 -2
  233. package/dist/components/GrTabsWithPanels/chunks/GrTabsWithPanels-BYtuzouj.js +98 -0
  234. package/dist/components/GrTabsWithPanels/chunks/GrTabsWithPanels-BYtuzouj.js.map +1 -0
  235. package/dist/components/GrTabsWithPanels/index.js +3 -0
  236. package/dist/components/GrTextarea/chunks/{GrTextarea-Bfgc0DD2.js → GrTextarea-BFwyqcHB.js} +22 -5
  237. package/dist/components/GrTextarea/chunks/GrTextarea-BFwyqcHB.js.map +1 -0
  238. package/dist/components/GrTextarea/index.js +1 -1
  239. package/dist/components/GrToaster/chunks/{GrToaster-CZixNk0l.js → GrToaster-OzT1VKcp.js} +163 -32
  240. package/dist/components/GrToaster/chunks/GrToaster-OzT1VKcp.js.map +1 -0
  241. package/dist/components/GrToaster/index.js +2 -2
  242. package/dist/components/GrToaster/styles.css +1 -1
  243. package/dist/components/GrTooltip/chunks/{GrTooltip-DkMMM0uq.js → GrTooltip-BDcFycvW.js} +26 -13
  244. package/dist/components/GrTooltip/chunks/GrTooltip-BDcFycvW.js.map +1 -0
  245. package/dist/components/GrTooltip/index.js +2 -2
  246. package/dist/components/GrTransfer/chunks/{GrTransfer-DdfBUf35.js → GrTransfer-CV7BL5UK.js} +114 -12
  247. package/dist/components/GrTransfer/chunks/GrTransfer-CV7BL5UK.js.map +1 -0
  248. package/dist/components/GrTransfer/index.js +1 -1
  249. package/dist/components/GrTransfer/styles.css +1 -1
  250. package/dist/components/GrTree/chunks/{GrTree-6yZrncJE.js → GrTree-DpgaP8hk.js} +39 -1
  251. package/dist/components/GrTree/chunks/GrTree-DpgaP8hk.js.map +1 -0
  252. package/dist/components/GrTree/index.js +1 -1
  253. package/dist/components/GrTree/styles.css +1 -1
  254. package/dist/components/GrTreeSections/chunks/{GrTreeSections-DcmDcLwj.js → GrTreeSections-BeOj__44.js} +1 -1
  255. package/dist/components/GrTreeSections/chunks/{GrTreeSections-DcmDcLwj.js.map → GrTreeSections-BeOj__44.js.map} +1 -1
  256. package/dist/components/GrTreeSections/index.js +1 -1
  257. package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-B6KoDYiZ.js → GrTreeSelect-BHq-T8wH.js} +113 -14
  258. package/dist/components/GrTreeSelect/chunks/GrTreeSelect-BHq-T8wH.js.map +1 -0
  259. package/dist/components/GrTreeSelect/index.js +2 -2
  260. package/dist/composables/useFloating.js +1 -1
  261. package/dist/composables/useHotkeys.js +89 -0
  262. package/dist/composables/useHotkeys.js.map +1 -0
  263. package/dist/composables/useOverlayLayer.js +1 -1
  264. package/dist/directives/hotkey.js +19 -46
  265. package/dist/directives/hotkey.js.map +1 -1
  266. package/dist/granular-provider-node.js +1 -1
  267. package/dist/granular-provider.js +1 -1
  268. package/dist/i18n/all.js +1 -1
  269. package/dist/i18n/index.js +1 -1
  270. package/dist/index.js +80 -71
  271. package/dist/theme.js +1 -1
  272. package/dist/tokens.js +1 -1
  273. package/dist/types/components/GrAutocomplete/GrAutocomplete.vue.d.ts +4 -4
  274. package/dist/types/components/GrAutocomplete/composables/useAutocompleteNavigation.d.ts +12 -3
  275. package/dist/types/components/GrAutocomplete/composables/useAutocompletePanel.d.ts +12 -2
  276. package/dist/types/components/GrAutocomplete/composables/useAutocompleteValues.d.ts +7 -4
  277. package/dist/types/components/GrAutocomplete/composables/useRemoteOptions.d.ts +4 -4
  278. package/dist/types/components/GrAutocomplete/grAutocompleteStyles.d.ts +15 -1
  279. package/dist/types/components/GrAutocomplete/index.d.ts +1 -1
  280. package/dist/types/components/GrBadge/GrBadge.vue.d.ts +15 -1
  281. package/dist/types/components/GrBadge/grBadgeStyles.d.ts +57 -0
  282. package/dist/types/components/GrBadge/index.d.ts +1 -1
  283. package/dist/types/components/GrCarousel/GrCarousel.vue.d.ts +29 -1
  284. package/dist/types/components/GrCarousel/composables/useCarouselSwipe.d.ts +5 -0
  285. package/dist/types/components/GrCarousel/grCarouselContext.d.ts +21 -0
  286. package/dist/types/components/GrCarousel/grCarouselStyles.d.ts +39 -9
  287. package/dist/types/components/GrCheckbox/GrCheckbox.vue.d.ts +13 -0
  288. package/dist/types/components/GrColorPicker/GrColorPicker.vue.d.ts +18 -2
  289. package/dist/types/components/GrColorPicker/color.d.ts +13 -1
  290. package/dist/types/components/GrColorPicker/colorArea.d.ts +59 -0
  291. package/dist/types/components/GrColorPicker/defaults.d.ts +3 -1
  292. package/dist/types/components/GrColorPicker/eyeDropper.d.ts +21 -0
  293. package/dist/types/components/GrColorPicker/grColorPickerStyles.d.ts +42 -0
  294. package/dist/types/components/GrCommandPalette/GrCommandPalette.vue.d.ts +10 -1
  295. package/dist/types/components/GrDataTable/GrDataTable.vue.d.ts +41 -1
  296. package/dist/types/components/GrDataTable/composables/useDataTableGridNavigation.d.ts +53 -0
  297. package/dist/types/components/GrDataTable/grDataTableStyles.d.ts +8 -0
  298. package/dist/types/components/GrDataTable/index.d.ts +1 -1
  299. package/dist/types/components/GrDelta/grDeltaStyles.d.ts +10 -3
  300. package/dist/types/components/GrEmptyState/GrEmptyState.vue.d.ts +11 -2
  301. package/dist/types/components/GrEmptyState/grEmptyStateStyles.d.ts +10 -0
  302. package/dist/types/components/GrEmptyState/index.d.ts +1 -1
  303. package/dist/types/components/GrFileUpload/GrFileUpload.vue.d.ts +2 -1
  304. package/dist/types/components/GrFormFile/GrFormFile.vue.d.ts +10 -0
  305. package/dist/types/components/GrInput/GrInput.vue.d.ts +15 -0
  306. package/dist/types/components/GrInputTag/GrInputTag.vue.d.ts +16 -0
  307. package/dist/types/components/GrInputTag/grInputTagStyles.d.ts +11 -0
  308. package/dist/types/components/GrKbd/GrKbd.vue.d.ts +14 -0
  309. package/dist/types/components/GrNavbar/GrNavbar.vue.d.ts +18 -0
  310. package/dist/types/components/GrNavbar/grNavbarStyles.d.ts +10 -1
  311. package/dist/types/components/GrNavbar/index.d.ts +1 -0
  312. package/dist/types/components/GrOtpInput/GrOtpInput.vue.d.ts +164 -0
  313. package/dist/types/components/GrOtpInput/config.d.ts +1 -0
  314. package/dist/types/components/GrOtpInput/defaults.d.ts +15 -0
  315. package/dist/types/components/GrOtpInput/grOtpInputStyles.d.ts +62 -0
  316. package/dist/types/components/GrOtpInput/index.d.ts +9 -0
  317. package/dist/types/components/GrOtpInput/otpValue.d.ts +71 -0
  318. package/dist/types/components/GrOtpInput/safelist.d.ts +7 -0
  319. package/dist/types/components/GrSelect/composables/useSelectPanelItems.d.ts +8 -34
  320. package/dist/types/components/GrSelect/composables/useSelectVirtualization.d.ts +7 -0
  321. package/dist/types/components/GrSelect/grSelectStyles.d.ts +1 -1
  322. package/dist/types/components/GrSidebar/GrSidebar.vue.d.ts +20 -0
  323. package/dist/types/components/GrSidebar/GrSidebarItem.vue.d.ts +39 -5
  324. package/dist/types/components/GrSidebar/grSidebarStyles.d.ts +32 -0
  325. package/dist/types/components/GrSidebar/index.d.ts +1 -1
  326. package/dist/types/components/GrSidebar/sidebarContext.d.ts +23 -1
  327. package/dist/types/components/GrSlider/GrSlider.vue.d.ts +39 -1
  328. package/dist/types/components/GrSlider/grSliderStyles.d.ts +1 -1
  329. package/dist/types/components/GrSwitch/GrSwitch.vue.d.ts +42 -4
  330. package/dist/types/components/GrSwitch/defaults.d.ts +2 -0
  331. package/dist/types/components/GrSwitch/grSwitchStyles.d.ts +129 -25
  332. package/dist/types/components/GrSwitch/index.d.ts +1 -1
  333. package/dist/types/components/GrSwitch/safelist.d.ts +4 -3
  334. package/dist/types/components/GrTabPanels/context.d.ts +6 -0
  335. package/dist/types/components/GrTable/GrTable.vue.d.ts +37 -0
  336. package/dist/types/components/GrTable/grTableStyles.d.ts +16 -7
  337. package/dist/types/components/GrTabsWithPanels/GrTabsWithPanels.vue.d.ts +77 -0
  338. package/dist/types/components/GrTabsWithPanels/config.d.ts +1 -0
  339. package/dist/types/components/GrTabsWithPanels/index.d.ts +4 -0
  340. package/dist/types/components/GrTextarea/GrTextarea.vue.d.ts +19 -1
  341. package/dist/types/components/GrToaster/GrToaster.vue.d.ts +12 -0
  342. package/dist/types/components/GrToaster/grToasterStyles.d.ts +26 -0
  343. package/dist/types/components/GrTooltip/GrTooltip.vue.d.ts +22 -0
  344. package/dist/types/components/GrTransfer/GrTransfer.vue.d.ts +23 -0
  345. package/dist/types/components/GrTreeSelect/grTreeSelectStyles.d.ts +1 -1
  346. package/dist/types/components/GrTreeSelect/grTreeSelectTypes.d.ts +20 -0
  347. package/dist/types/components/shared/hotkey.d.ts +8 -9
  348. package/dist/types/components/shared/optionPanel.d.ts +100 -0
  349. package/dist/types/components/shared/overlayListPanel.d.ts +18 -0
  350. package/dist/types/composables/useHotkeys.d.ts +43 -0
  351. package/dist/types/granular-provider/shared.d.ts +2 -0
  352. package/dist/types/i18n/messages/en.d.ts +32 -0
  353. package/dist/types/i18n/messages/es.d.ts +32 -0
  354. package/dist/types/i18n/messages/ru.d.ts +32 -0
  355. package/dist/types/index.d.ts +4 -0
  356. package/dist/types/internal/hotkeySequence.d.ts +22 -0
  357. package/dist/types/internal/keyboard.d.ts +45 -0
  358. package/dist/web-types.json +784 -101
  359. package/package.json +13 -1
  360. package/dist/chunks/config-2ZHRsdOc.js.map +0 -1
  361. package/dist/chunks/config-B42iJ48O.js.map +0 -1
  362. package/dist/chunks/config-B5SBUa6u.js.map +0 -1
  363. package/dist/chunks/config-BAse0laT.js.map +0 -1
  364. package/dist/chunks/config-BHLMTJaR.js.map +0 -1
  365. package/dist/chunks/config-BXRmsn3t.js.map +0 -1
  366. package/dist/chunks/config-Bs1HwUcx.js.map +0 -1
  367. package/dist/chunks/config-CMNfZO7S.js.map +0 -1
  368. package/dist/chunks/config-CbEbLyDE.js.map +0 -1
  369. package/dist/chunks/config-CjWOTgLL.js.map +0 -1
  370. package/dist/chunks/config-D3HOuHDe.js.map +0 -1
  371. package/dist/chunks/config-DIDz_E5m.js.map +0 -1
  372. package/dist/chunks/config-DNDgp9bB.js.map +0 -1
  373. package/dist/chunks/config-Yy67uWHY.js +0 -140
  374. package/dist/chunks/config-Yy67uWHY.js.map +0 -1
  375. package/dist/chunks/config-iemgzS4x.js.map +0 -1
  376. package/dist/chunks/en-Bxyn5lW7.js.map +0 -1
  377. package/dist/chunks/es-Dtl-a7ui.js.map +0 -1
  378. package/dist/chunks/grBadgeStyles-DV0DrAew.js.map +0 -1
  379. package/dist/chunks/grSelectStyles-D9EQ-pgK.js.map +0 -1
  380. package/dist/chunks/grSliderStyles-kaz6VXZ3.js.map +0 -1
  381. package/dist/chunks/grTableStyles-DkQPMfx9.js +0 -39
  382. package/dist/chunks/grTableStyles-DkQPMfx9.js.map +0 -1
  383. package/dist/chunks/granular-provider-BOQp7N5o.js.map +0 -1
  384. package/dist/chunks/keyboard-DE2yhz_b.js.map +0 -1
  385. package/dist/chunks/overlayPanelSurface-BKeMhRx4.js.map +0 -1
  386. package/dist/chunks/ru-hrB4I1u_.js.map +0 -1
  387. package/dist/chunks/safelist-x8USecK8.js.map +0 -1
  388. package/dist/components/GrAutocomplete/chunks/GrAutocomplete-C-uovdv8.js.map +0 -1
  389. package/dist/components/GrBadge/chunks/GrBadge-DBeQXEir.js +0 -47
  390. package/dist/components/GrBadge/chunks/GrBadge-DBeQXEir.js.map +0 -1
  391. package/dist/components/GrCarousel/chunks/GrCarousel-ByuughtI.js.map +0 -1
  392. package/dist/components/GrCheckbox/chunks/GrCheckbox-Dp201frb.js.map +0 -1
  393. package/dist/components/GrColorPicker/chunks/GrColorPicker-BRM_4lyI.js.map +0 -1
  394. package/dist/components/GrCommandPalette/chunks/GrCommandPalette-BJHmkDQv.js.map +0 -1
  395. package/dist/components/GrDataTable/chunks/GrDataTable-DQxYYgQk.js.map +0 -1
  396. package/dist/components/GrDropdownMenu/chunks/GrDropdownMenu-Dxkz_ry4.js.map +0 -1
  397. package/dist/components/GrEmptyState/chunks/GrEmptyState-BbvwE-E0.js.map +0 -1
  398. package/dist/components/GrFileUpload/chunks/GrFileUpload-BwMR71zN.js.map +0 -1
  399. package/dist/components/GrFormFile/chunks/GrFormFile-Dlxx-9zi.js.map +0 -1
  400. package/dist/components/GrInput/chunks/GrInput-DV4gMWPR.js.map +0 -1
  401. package/dist/components/GrInputTag/chunks/GrInputTag-CO0YU-ok.js.map +0 -1
  402. package/dist/components/GrKbd/chunks/GrKbd-BNMeoaLV.js.map +0 -1
  403. package/dist/components/GrNavbar/chunks/GrNavbar-BRGuksiy.js.map +0 -1
  404. package/dist/components/GrSelect/chunks/GrSelect-0iI4wdR_.js.map +0 -1
  405. package/dist/components/GrSidebar/chunks/GrSidebar-DoKLlHSw.js +0 -264
  406. package/dist/components/GrSidebar/chunks/GrSidebar-DoKLlHSw.js.map +0 -1
  407. package/dist/components/GrSlider/chunks/GrSlider-CO8N9SF6.js.map +0 -1
  408. package/dist/components/GrSwitch/chunks/GrSwitch-CriHWT2A.js.map +0 -1
  409. package/dist/components/GrTabPanels/chunks/GrTabPanels-5zsbqS1v.js +0 -92
  410. package/dist/components/GrTabPanels/chunks/GrTabPanels-5zsbqS1v.js.map +0 -1
  411. package/dist/components/GrTable/chunks/GrTable-CKJ-HrsN.js.map +0 -1
  412. package/dist/components/GrTextarea/chunks/GrTextarea-Bfgc0DD2.js.map +0 -1
  413. package/dist/components/GrToaster/chunks/GrToaster-CZixNk0l.js.map +0 -1
  414. package/dist/components/GrTooltip/chunks/GrTooltip-DkMMM0uq.js.map +0 -1
  415. package/dist/components/GrTransfer/chunks/GrTransfer-DdfBUf35.js.map +0 -1
  416. package/dist/components/GrTree/chunks/GrTree-6yZrncJE.js.map +0 -1
  417. package/dist/components/GrTreeSelect/chunks/GrTreeSelect-B6KoDYiZ.js.map +0 -1
  418. package/dist/types/components/GrAutocomplete/composables/useAutocompleteVirtual.d.ts +0 -33
@@ -1 +0,0 @@
1
- {"version":3,"file":"GrSelect-0iI4wdR_.js","names":[],"sources":["../../../../src/components/GrSelect/composables/useSelectPanelItems.ts","../../../../src/components/GrSelect/composables/useSelectNavigation.ts","../../../../src/components/GrSelect/composables/useSelectVirtualization.ts","../../../../src/components/GrSelect/selectValue.ts","../../../../src/components/GrSelect/composables/useSelectValues.ts","../../../../src/components/GrSelect/GrSelect.vue","../../../../src/components/GrSelect/GrSelect.vue"],"sourcesContent":["import type { ComputedRef } from 'vue'\nimport { computed } from 'vue'\n\nimport { matchesOptionQuery, normalizeOptionQuery } from '../../shared/optionFilter'\nimport type {\n GrSelectOption,\n GrSelectOptionGroup,\n GrSelectOptionOrGroup,\n GrSelectValue,\n} from '../grSelectStyles'\n\n/**\n * Элемент рендера панели: либо заголовок группы, либо опция.\n * Группировка сохраняется, фильтрация по запросу скрывает пустые группы.\n */\nexport type GrSelectPanelItem<TValue extends GrSelectValue>\n = | { kind: 'group', label: string, key: string }\n /** `groupKey` связывает опцию с заголовком её группы для скринридера. */\n | { kind: 'option', option: GrSelectOption<TValue>, key: string, groupKey?: string }\n\nexport type GrSelectPanelOptionRow<TValue extends GrSelectValue> = {\n option: GrSelectOption<TValue>\n key: string\n index: number\n}\n\nexport type GrSelectPanelRow<TValue extends GrSelectValue>\n = | {\n kind: 'group'\n label: string\n key: string\n options: GrSelectPanelOptionRow<TValue>[]\n /**\n * Есть ли в этой отрисовке видимый заголовок. При виртуализации окно может\n * начаться серединой группы: обёртка нужна всё равно, а заголовка нет —\n * имя тогда идёт в `aria-label`.\n */\n labelVisible?: boolean\n /** Позиция заголовка в `panelItems` — по ней его замеряет виртуализатор. */\n labelIndex?: number\n }\n | ({ kind: 'option' } & GrSelectPanelOptionRow<TValue>)\n\n/**\n * Состав панели `GrSelect`: плоский набор строк, их группировка и признак\n * «набранное можно добавить».\n *\n * Отвечает только на вопрос «что показывать в списке». Окно виртуализации,\n * клавиатура и вид — не здесь.\n */\nexport interface UseSelectPanelItemsOptions<TValue extends GrSelectValue> {\n optionsResolved: ComputedRef<GrSelectOptionOrGroup<TValue>[]>\n flatOptions: ComputedRef<GrSelectOption<TValue>[]>\n isOptionGroup: (item: GrSelectOptionOrGroup<TValue>) => item is GrSelectOptionGroup<TValue>\n modelSingle: ComputedRef<TValue | ''>\n selectedValues: ComputedRef<TValue[]>\n hasModelInOptions: ComputedRef<boolean>\n sameValue: (a: unknown, b: unknown) => boolean\n /** Текст поиска: он же кандидат в кастомные значения. */\n query: () => string\n allowCustomValue: () => boolean\n filterable: () => boolean\n multiple: () => boolean\n isPanelView: () => boolean\n}\n\nexport interface SelectPanelItems<TValue extends GrSelectValue> {\n panelItems: ComputedRef<GrSelectPanelItem<TValue>[]>\n panelRows: ComputedRef<GrSelectPanelRow<TValue>[]>\n canAddCustom: ComputedRef<boolean>\n}\n\nexport function useSelectPanelItems<TValue extends GrSelectValue>(\n options: UseSelectPanelItemsOptions<TValue>,\n): SelectPanelItems<TValue> {\n const panelItems = computed<GrSelectPanelItem<TValue>[]>(() => {\n const q = (options.allowCustomValue() || options.filterable()) ? normalizeOptionQuery(options.query()) : ''\n const items: GrSelectPanelItem<TValue>[] = []\n\n // Опция для кастомного значения, которого нет в options (single).\n if (options.allowCustomValue() && !options.multiple()\n && options.modelSingle.value !== '' && !options.hasModelInOptions.value) {\n const value = options.modelSingle.value\n const custom: GrSelectOption<TValue> = { value, label: String(value) }\n if (matchesOptionQuery(custom, q)) {\n items.push({ kind: 'option', option: custom, key: `__custom__${String(custom.value)}` })\n }\n }\n\n options.optionsResolved.value.forEach((item, index) => {\n if (options.isOptionGroup(item)) {\n const matched = item.options.filter(o => matchesOptionQuery(o, q))\n if (!matched.length)\n return\n const groupKey = `__group__${index}`\n items.push({ kind: 'group', label: item.label, key: groupKey })\n for (const option of matched) {\n // Ключ с индексом группы — одинаковое `value` в разных группах больше не даёт дубликат.\n items.push({ kind: 'option', option, key: `${index}:${String(option.value)}`, groupKey })\n }\n return\n }\n\n if (matchesOptionQuery(item, q)) {\n items.push({ kind: 'option', option: item, key: `${index}:${String(item.value)}` })\n }\n })\n\n return items\n })\n\n /**\n * Строки панели для рендера: заголовок группы больше не сосед опций, а их\n * контейнер. Прямыми потомками `role=\"listbox\"` обязаны быть только опции, а\n * заголовок даёт имя группе через `aria-labelledby`.\n *\n * `index` — позиция опции в `panelItems`: из неё строится `id`, поэтому он не\n * зависит от значения (значение с пробелом дало бы невалидный `id`).\n */\n const panelRows = computed<GrSelectPanelRow<TValue>[]>(() => {\n const rows: GrSelectPanelRow<TValue>[] = []\n let currentGroup: Extract<GrSelectPanelRow<TValue>, { kind: 'group' }> | undefined\n\n panelItems.value.forEach((item, index) => {\n if (item.kind === 'group') {\n currentGroup = { kind: 'group', label: item.label, key: item.key, options: [] }\n rows.push(currentGroup)\n return\n }\n\n const row: GrSelectPanelOptionRow<TValue> = { option: item.option, key: item.key, index }\n\n if (item.groupKey && currentGroup && currentGroup.key === item.groupKey) {\n currentGroup.options.push(row)\n return\n }\n\n currentGroup = undefined\n rows.push({ kind: 'option', ...row })\n })\n\n return rows\n })\n\n const canAddCustom = computed(() => {\n if (!options.allowCustomValue())\n return false\n if (!options.isPanelView())\n return false\n // Кастомное значение набирается текстом, поэтому оно строковое —\n // при числовом `TValue` эта ветка неприменима (см. docs/components.md).\n const v = options.query().trim() as TValue\n if (!v)\n return false\n\n if (options.multiple()) {\n if (options.selectedValues.value.some(selected => options.sameValue(selected, v)))\n return false\n return !options.flatOptions.value.some(o => options.sameValue(o.value, v))\n }\n\n if (options.sameValue(v, options.modelSingle.value))\n return false\n return !options.flatOptions.value.some(o => options.sameValue(o.value, v))\n })\n\n return { panelItems, panelRows, canAddCustom }\n}\n","import type { ComputedRef, Ref } from 'vue'\nimport { computed, nextTick } from 'vue'\n\nimport { useTypeahead } from '../../../composables/internal/useTypeahead'\nimport { useComboboxNavigation } from '../../../composables/useComboboxNavigation'\nimport { isComposingEvent } from '../../../internal/keyboard'\nimport type { GrSelectOption, GrSelectValue } from '../grSelectStyles'\nimport type { GrSelectPanelItem } from './useSelectPanelItems'\n\n/**\n * Клавиатура ходит и по опциям, и по строке «Add …» (как в `GrAutocomplete`):\n * иначе при непустом списке Enter не мог бы выбрать подсвеченную опцию, а при\n * активной опции — закоммитить произвольное значение.\n */\nexport type GrSelectNavigableItem<TValue extends GrSelectValue>\n = | { kind: 'add' }\n | { kind: 'option', value: TValue, index: number }\n\nexport interface UseSelectNavigationOptions<TValue extends GrSelectValue> {\n panelItems: ComputedRef<GrSelectPanelItem<TValue>[]>\n flatOptions: ComputedRef<GrSelectOption<TValue>[]>\n canAddCustom: ComputedRef<boolean>\n sameValue: (a: unknown, b: unknown) => boolean\n isSelected: (value: TValue) => boolean\n\n open: Ref<boolean>\n locked: ComputedRef<boolean>\n showSearchInput: ComputedRef<boolean>\n virtualEnabled: ComputedRef<boolean>\n addOffset: ComputedRef<number>\n\n listboxId: string\n optionDomId: (index: number) => string\n /** Подвинуть окно виртуализации к строке набора. */\n scrollVirtualToIndex: (index: number) => void\n\n /** Действия выбора: они трогают модель и эмиты, поэтому живут в компоненте. */\n openDropdown: () => void\n closeDropdown: () => void\n addCustom: () => void\n toggleValue: (value: TValue) => void\n}\n\nexport interface SelectNavigation<TValue extends GrSelectValue> {\n navigableItems: ComputedRef<GrSelectNavigableItem<TValue>[]>\n /** Индекс активного элемента: пишется и снаружи — строка «Add …» подсвечивается наведением. */\n activeIndex: Ref<number>\n activeItem: ComputedRef<GrSelectNavigableItem<TValue> | undefined>\n addOptionDomId: ComputedRef<string>\n activeValue: ComputedRef<TValue | undefined>\n activeDescendantId: ComputedRef<string | undefined>\n triggerActiveDescendant: ComputedRef<string | undefined>\n searchActiveDescendant: ComputedRef<string | undefined>\n onOptionHover: (panelIndex: number) => void\n onComboKeydown: (event: KeyboardEvent) => void\n initActiveIndex: () => void\n resetActive: () => void\n}\n\nexport function useSelectNavigation<TValue extends GrSelectValue>(\n options: UseSelectNavigationOptions<TValue>,\n): SelectNavigation<TValue> {\n const navigableItems = computed<GrSelectNavigableItem<TValue>[]>(() => {\n const items: GrSelectNavigableItem<TValue>[] = options.canAddCustom.value ? [{ kind: 'add' }] : []\n\n options.panelItems.value.forEach((item, index) => {\n if (item.kind === 'option' && !item.option.disabled)\n items.push({ kind: 'option', value: item.option.value, index })\n })\n\n return items\n })\n\n const addOptionDomId = computed(() => `${options.listboxId}-add`)\n\n /** Прокрутка к активному: у виртуализации окно, затем доводка `scrollIntoView`. */\n async function scrollActiveIntoView(item: GrSelectNavigableItem<TValue>): Promise<void> {\n // Вне окна активной опции в DOM нет: `getElementById` вернул бы `null`,\n // прокрутка не случилась бы, а `aria-activedescendant` указал бы в пустоту.\n if (options.virtualEnabled.value)\n options.scrollVirtualToIndex(item.kind === 'add' ? 0 : item.index + options.addOffset.value)\n\n await nextTick()\n const id = item.kind === 'add' ? addOptionDomId.value : options.optionDomId(item.index)\n document.getElementById(id)?.scrollIntoView?.({ block: 'nearest' })\n }\n\n const {\n activeIndex,\n activeItem,\n activeDescendantId,\n setActive,\n init: initActiveIndex,\n reset: resetActive,\n handleNavigationKeys,\n } = useComboboxNavigation<GrSelectNavigableItem<TValue>>({\n items: () => navigableItems.value,\n open: () => options.open.value,\n idOf: item => (item.kind === 'add' ? addOptionDomId.value : options.optionDomId(item.index)),\n initialIndex: () => navigableItems.value.findIndex(item => item.kind === 'option' && options.isSelected(item.value)),\n scrollTo: item => scrollActiveIntoView(item),\n })\n\n const activeValue = computed(() => (activeItem.value?.kind === 'option' ? activeItem.value.value : undefined))\n\n /** Navigable-индекс по позиции в `panelItems`: O(1) на hover вместо O(n). */\n const navigableIndexByPanelIndex = computed(() => {\n const map = new Map<number, number>()\n navigableItems.value.forEach((item, navIndex) => {\n if (item.kind === 'option')\n map.set(item.index, navIndex)\n })\n return map\n })\n\n function onOptionHover(panelIndex: number): void {\n const next = navigableIndexByPanelIndex.value.get(panelIndex)\n if (next !== undefined && next !== activeIndex.value)\n activeIndex.value = next\n }\n\n /**\n * `aria-activedescendant` работает только на элементе, который держит фокус.\n * С полем поиска фокус уходит в него, поэтому связка с активной опцией живёт\n * там же; на триггере она осталась бы немой.\n */\n const triggerActiveDescendant = computed(() => (\n options.showSearchInput.value ? undefined : activeDescendantId.value\n ))\n const searchActiveDescendant = computed(() => (\n options.showSearchInput.value ? activeDescendantId.value : undefined\n ))\n\n /**\n * Подпись опции по значению.\n *\n * Мапой, а не `find` по списку: typeahead опрашивает подпись на каждом шаге\n * обхода, и линейный поиск внутри цикла давал квадрат по числу опций — на\n * длинных списках это чувствовалось прямо во время набора.\n */\n const labelByItem = computed(() => {\n const byValue = new Map<unknown, string>()\n for (const option of options.flatOptions.value)\n byValue.set(option.value, option.label)\n\n return byValue\n })\n\n function labelOf(item: GrSelectNavigableItem<TValue>): string {\n if (item.kind !== 'option')\n return ''\n\n const direct = labelByItem.value.get(item.value)\n if (direct !== undefined)\n return direct\n\n // `sameValue` умеет сравнивать объекты по ключу — на такой список Map по\n // ссылке не ложится, и остаётся честный перебор.\n return options.flatOptions.value\n .find(option => options.sameValue(option.value, item.value))\n ?.label ?? ''\n }\n\n const typeahead = useTypeahead<GrSelectNavigableItem<TValue>>({\n items: () => navigableItems.value,\n textOf: labelOf,\n // Поиск идёт от активной опции, а не с начала списка (APG): повторная буква\n // ведёт к следующему совпадению.\n currentIndex: () => activeIndex.value,\n onMatch: (_item, index) => setActive(index),\n })\n\n function onComboKeydown(event: KeyboardEvent): void {\n // Клавиша во время IME-композиции принадлежит композиции: Enter коммитит её,\n // Esc отменяет, стрелки ходят по кандидатам.\n if (isComposingEvent(event))\n return\n if (options.locked.value)\n return\n\n if (!options.open.value) {\n if (['ArrowDown', 'ArrowUp', 'Enter', ' '].includes(event.key)) {\n event.preventDefault()\n options.openDropdown()\n }\n return\n }\n\n if (handleNavigationKeys(event))\n return\n\n switch (event.key) {\n case 'Enter': {\n event.preventDefault()\n // Активный элемент сильнее `canAddCustom`: пользователь подсветил опцию\n // стрелками — Enter обязан выбрать её, а не добавить набранный запрос.\n const item = activeItem.value\n if (item?.kind === 'add')\n options.addCustom()\n else if (item?.kind === 'option')\n options.toggleValue(item.value)\n else if (options.canAddCustom.value)\n options.addCustom()\n break\n }\n case 'Tab':\n options.closeDropdown()\n break\n default:\n // typeahead — только когда нет поля ввода (иначе мешает вводу в search/custom-инпут).\n if (!options.showSearchInput.value && event.key.length === 1\n && !event.metaKey && !event.ctrlKey && !event.altKey) {\n typeahead.type(event.key)\n }\n }\n }\n\n return {\n navigableItems,\n activeIndex,\n activeItem,\n addOptionDomId,\n activeValue,\n activeDescendantId,\n triggerActiveDescendant,\n searchActiveDescendant,\n onOptionHover,\n onComboKeydown,\n initActiveIndex,\n resetActive,\n }\n}\n","import type { ComputedRef, Ref } from 'vue'\nimport { computed } from 'vue'\n\nimport { useVirtualList } from '../../../composables/useVirtualList'\nimport type { GrSelectValue } from '../grSelectStyles'\nimport type { GrSelectPanelItem, GrSelectPanelOptionRow, GrSelectPanelRow } from './useSelectPanelItems'\n\n/**\n * Виртуализация панели `GrSelect`.\n *\n * Набор — `[«Add …»?] + panelItems`, то есть заголовки групп идут в нём наравне\n * с опциями: на экране они занимают такую же строку. Вложенную структуру групп\n * рендер пересобирает уже из окна.\n */\n\n/** Оценки высоты строк: опция крупнее заголовка группы. Уточняются замером. */\nconst OPTION_SIZE_ESTIMATE = 36\nconst GROUP_LABEL_SIZE_ESTIMATE = 28\n\nexport interface UseSelectVirtualizationOptions<TValue extends GrSelectValue> {\n panelItems: ComputedRef<GrSelectPanelItem<TValue>[]>\n panelRows: ComputedRef<GrSelectPanelRow<TValue>[]>\n canAddCustom: ComputedRef<boolean>\n /** Контейнер списка: по нему считается окно и замеряются строки. */\n listboxEl: Ref<HTMLElement | null>\n enabled: () => boolean\n maxHeight: () => number\n}\n\nexport interface SelectVirtualization<TValue extends GrSelectValue> {\n virtualEnabled: ComputedRef<boolean>\n /** Сдвиг набора: строка «Add …» стоит перед опциями. */\n addOffset: ComputedRef<number>\n scrollToIndex: (index: number) => void\n /** Замер строки: оценка высоты уточняется по реальному узлу. */\n measure: (index: number, el: Element | null) => void\n /** ARIA набора для опции; вне виртуализации набор виден по DOM. */\n optionSetProps: (index: number) => Record<string, number> | undefined\n addOptionSetProps: ComputedRef<Record<string, number> | undefined>\n showAddOption: ComputedRef<boolean>\n renderedPanelRows: ComputedRef<GrSelectPanelRow<TValue>[]>\n listboxStyle: ComputedRef<Record<string, string>>\n}\n\nexport function useSelectVirtualization<TValue extends GrSelectValue>(\n options: UseSelectVirtualizationOptions<TValue>,\n): SelectVirtualization<TValue> {\n const virtualEnabled = computed(() => options.enabled())\n const addOffset = computed(() => (options.canAddCustom.value ? 1 : 0))\n const virtualCount = computed(() => options.panelItems.value.length + addOffset.value)\n\n const virtualizer = useVirtualList({\n container: options.listboxEl,\n count: () => (virtualEnabled.value ? virtualCount.value : 0),\n // Фильтрация пересобирает набор строк — замеры прошлого набора невалидны.\n source: () => options.panelItems.value,\n itemSize: (index) => {\n const item = options.panelItems.value[index - addOffset.value]\n return item?.kind === 'group' ? GROUP_LABEL_SIZE_ESTIMATE : OPTION_SIZE_ESTIMATE\n },\n // Панель закрыта — контейнера в раскладке нет, `clientHeight` нулевой.\n viewportSize: () => options.maxHeight(),\n })\n\n /**\n * Позиция и размер набора для каждой опции.\n *\n * Набор — не весь список: опция внутри `role=\"group\"` принадлежит набору своей\n * группы, и `aria-posinset` отсчитывается от неё. Опции вне групп вместе с\n * кнопкой «Add …» образуют набор уровня listbox'а.\n */\n const optionSets = computed(() => {\n const sizes = new Map<string, number>()\n const positions = new Map<number, { setKey: string, posInSet: number }>()\n const ROOT = '__root__'\n\n let rootCount = options.canAddCustom.value ? 1 : 0\n\n options.panelItems.value.forEach((item, index) => {\n if (item.kind === 'group')\n return\n\n const setKey = item.groupKey ?? ROOT\n const next = (sizes.get(setKey) ?? (setKey === ROOT ? rootCount : 0)) + 1\n sizes.set(setKey, next)\n positions.set(index, { setKey, posInSet: next })\n if (setKey === ROOT)\n rootCount = next\n })\n\n if (options.canAddCustom.value && !sizes.has(ROOT))\n sizes.set(ROOT, rootCount)\n\n return { sizes, positions, ROOT }\n })\n\n /** ARIA набора: объявляем только при виртуализации — иначе набор виден по DOM. */\n function optionSetProps(index: number): Record<string, number> | undefined {\n if (!virtualEnabled.value)\n return undefined\n\n const position = optionSets.value.positions.get(index)\n if (!position)\n return undefined\n\n return {\n 'aria-setsize': optionSets.value.sizes.get(position.setKey) ?? 1,\n 'aria-posinset': position.posInSet,\n }\n }\n\n /** ARIA для кнопки «Add …»: она первая в наборе уровня listbox'а. */\n const addOptionSetProps = computed<Record<string, number> | undefined>(() => {\n if (!virtualEnabled.value)\n return undefined\n return {\n 'aria-setsize': optionSets.value.sizes.get(optionSets.value.ROOT) ?? 1,\n 'aria-posinset': 1,\n }\n })\n\n /** Метка группы по её ключу: окно может начаться ниже заголовка. */\n const groupLabels = computed(() => {\n const labels = new Map<string, string>()\n for (const item of options.panelItems.value) {\n if (item.kind === 'group')\n labels.set(item.key, item.label)\n }\n return labels\n })\n\n /** Виден ли «Add …»: вне окна его рисовать нельзя — он элемент набора. */\n const showAddOption = computed(() => {\n if (!options.canAddCustom.value)\n return false\n return !virtualEnabled.value || virtualizer.range.value.start === 0\n })\n\n /**\n * Строки к отрисовке. При виртуализации группы пересобираются из среза\n * `panelItems`: группа, начатая выше окна, всё равно открывается — иначе её\n * опции оказались бы прямыми детьми listbox'а и потеряли имя набора.\n */\n const renderedPanelRows = computed<GrSelectPanelRow<TValue>[]>(() => {\n if (!virtualEnabled.value)\n return options.panelRows.value\n\n const items = options.panelItems.value\n const { start, end } = virtualizer.range.value\n const from = Math.max(0, start - addOffset.value)\n const to = Math.min(items.length, Math.max(0, end - addOffset.value))\n\n const rows: GrSelectPanelRow<TValue>[] = []\n let currentGroup: Extract<GrSelectPanelRow<TValue>, { kind: 'group' }> | undefined\n\n for (let index = from; index < to; index++) {\n const item = items[index]\n\n if (item.kind === 'group') {\n currentGroup = {\n kind: 'group',\n label: item.label,\n key: item.key,\n options: [],\n labelVisible: true,\n labelIndex: index,\n }\n rows.push(currentGroup)\n continue\n }\n\n const row: GrSelectPanelOptionRow<TValue> = { option: item.option, key: item.key, index }\n\n if (item.groupKey) {\n if (!currentGroup || currentGroup.key !== item.groupKey) {\n currentGroup = {\n kind: 'group',\n label: groupLabels.value.get(item.groupKey) ?? '',\n key: item.groupKey,\n options: [],\n labelVisible: false,\n }\n rows.push(currentGroup)\n }\n currentGroup.options.push(row)\n continue\n }\n\n currentGroup = undefined\n rows.push({ kind: 'option', ...row })\n }\n\n return rows\n })\n\n const listboxStyle = computed(() => {\n const base: Record<string, string> = { maxHeight: `${options.maxHeight()}px` }\n if (!virtualEnabled.value)\n return base\n\n return {\n ...base,\n ...virtualizer.spacerStyle.value,\n }\n })\n\n return {\n virtualEnabled,\n addOffset,\n scrollToIndex: index => virtualizer.scrollToIndex(index),\n measure: (index, el) => virtualizer.measure(index, el),\n optionSetProps,\n addOptionSetProps,\n showAddOption,\n renderedPanelRows,\n listboxStyle,\n }\n}\n","/**\n * Сравнение значений `GrSelect` — чистая арифметика без Vue и без пропов.\n *\n * Вынесено отдельным модулем, потому что от состояния компонента здесь не\n * зависит ничего: только само значение и имя поля-идентификатора. Тестируется\n * напрямую, без монтирования.\n */\n\n/**\n * Ключ значения: для объектов — поле `valueKey`, иначе само значение строкой.\n * Через него идут все сравнения — `===` для объектов означал бы сравнение\n * ссылок, а модель обычно приходит снаружи отдельной копией.\n */\nexport function selectValueKey(value: unknown, valueKey?: string): string {\n if (value !== null && typeof value === 'object') {\n const own = valueKey ? (value as Record<string, unknown>)[valueKey] : undefined\n\n if (own === undefined && __GR_DEV__) {\n console.warn(\n '[granularity] GrSelect: объектные значения требуют `valueKey` с именем поля-идентификатора; '\n + 'без него опции неотличимы друг от друга.',\n )\n }\n\n return String(own ?? JSON.stringify(value))\n }\n\n return String(value)\n}\n\n/**\n * `0` — валидное значение, поэтому «пусто» проверяется явно, а не через falsy:\n * прежняя проверка `if (!value)` теряла ноль вместе с пустой строкой.\n */\nexport function isEmptySelectValue(value: unknown): boolean {\n return value === undefined || value === null || value === ''\n}\n\n/** Модель к массиву: скаляр становится набором из одного, пустое — пустым. */\nexport function toSelectArray<TValue>(value: TValue | TValue[] | ''): TValue[] {\n if (Array.isArray(value))\n return value\n if (isEmptySelectValue(value))\n return []\n return [value as TValue]\n}\n","import type { ComputedRef } from 'vue'\nimport { computed } from 'vue'\n\nimport { resolveSelectedOptions } from '../../shared/optionFilter'\nimport type {\n GrSelectModelValue,\n GrSelectOption,\n GrSelectOptionGroup,\n GrSelectOptionOrGroup,\n GrSelectValue,\n} from '../grSelectStyles'\nimport { isEmptySelectValue, selectValueKey, toSelectArray } from '../selectValue'\n\n/**\n * Значение и опции `GrSelect`: плоский список, выбранное, подпись триггера.\n *\n * Здесь живёт всё, что отвечает на вопрос «что выбрано и как это назвать», и\n * ничего про панель, клавиатуру и вид. Сравнения идут через ключ значения\n * (`selectValue.ts`), а не через `===`: модель приходит снаружи отдельной\n * копией, и объекты по ссылке не совпали бы ни с одной опцией.\n */\nexport interface UseSelectValuesOptions<TValue extends GrSelectValue> {\n modelValue: () => GrSelectModelValue<TValue>\n options: () => GrSelectOptionOrGroup<TValue>[] | undefined\n multiple: () => boolean\n /** Имя поля-идентификатора для объектных значений. */\n valueKey: () => string | undefined\n placeholder: () => string | undefined\n}\n\nexport interface SelectValues<TValue extends GrSelectValue> {\n optionsResolved: ComputedRef<GrSelectOptionOrGroup<TValue>[]>\n /** Плоский список всех опций (группы «развёрнуты»). */\n flatOptions: ComputedRef<GrSelectOption<TValue>[]>\n isOptionGroup: (item: GrSelectOptionOrGroup<TValue>) => item is GrSelectOptionGroup<TValue>\n keyOf: (value: unknown) => string\n sameValue: (a: unknown, b: unknown) => boolean\n modelSingle: ComputedRef<TValue | ''>\n modelMultiple: ComputedRef<TValue[]>\n selectedValues: ComputedRef<TValue[]>\n hasSelection: ComputedRef<boolean>\n /** Восстанавливает типизированное значение из строки, пришедшей из DOM. */\n fromDomValue: (raw: string) => TValue\n selectedOptions: ComputedRef<GrSelectOption<TValue>[]>\n hasModelInOptions: ComputedRef<boolean>\n displayLabel: ComputedRef<string>\n displayText: ComputedRef<string>\n}\n\nexport function useSelectValues<TValue extends GrSelectValue>(\n options: UseSelectValuesOptions<TValue>,\n): SelectValues<TValue> {\n const optionsResolved = computed<GrSelectOptionOrGroup<TValue>[]>(() => options.options() ?? [])\n\n function isOptionGroup(item: GrSelectOptionOrGroup<TValue>): item is GrSelectOptionGroup<TValue> {\n return Array.isArray((item as GrSelectOptionGroup).options)\n }\n\n const flatOptions = computed<GrSelectOption<TValue>[]>(() => {\n const result: GrSelectOption<TValue>[] = []\n for (const item of optionsResolved.value) {\n if (isOptionGroup(item))\n result.push(...item.options)\n else result.push(item)\n }\n return result\n })\n\n function keyOf(value: unknown): string {\n return selectValueKey(value, options.valueKey())\n }\n\n function sameValue(a: unknown, b: unknown): boolean {\n return keyOf(a) === keyOf(b)\n }\n\n const modelSingle = computed<TValue | ''>(() => {\n const model = options.modelValue()\n const raw = Array.isArray(model) ? model[0] : model\n return isEmptySelectValue(raw) ? '' : (raw as TValue)\n })\n\n const modelMultiple = computed(() => toSelectArray<TValue>(options.modelValue()))\n\n const selectedValues = computed(() => {\n if (options.multiple())\n return modelMultiple.value\n return isEmptySelectValue(modelSingle.value) ? [] : [modelSingle.value as TValue]\n })\n\n const hasSelection = computed(() => selectedValues.value.length > 0)\n\n /**\n * Нативный `<select>` хранит в `option.value` строку, поэтому значение,\n * вернувшееся из DOM, нужно восстановить в исходный тип. Карта строится по\n * опциям: ключ значения — ключ карты, само значение — результат.\n */\n const valueByDomKey = computed<Map<string, TValue>>(() => {\n const map = new Map<string, TValue>()\n for (const option of flatOptions.value) map.set(keyOf(option.value), option.value)\n return map\n })\n\n function fromDomValue(raw: string): TValue {\n const known = valueByDomKey.value.get(raw)\n if (known !== undefined)\n return known\n // Значения нет среди опций — это `allowCustomValue`, а он по природе строковый.\n return raw as TValue\n }\n\n const selectedOptions = computed<GrSelectOption<TValue>[]>(() =>\n resolveSelectedOptions(selectedValues.value, flatOptions.value, keyOf),\n )\n\n const hasModelInOptions = computed(() => {\n if (options.multiple())\n return false\n return flatOptions.value.some(o => sameValue(o.value, modelSingle.value))\n })\n\n const displayLabel = computed<string>(() => {\n if (options.multiple()) {\n if (!selectedValues.value.length)\n return ''\n return selectedValues.value\n .map(v => flatOptions.value.find(o => sameValue(o.value, v))?.label ?? keyOf(v))\n .join(', ')\n }\n\n return flatOptions.value.find(o => sameValue(o.value, modelSingle.value))?.label ?? String(modelSingle.value)\n })\n\n const displayText = computed(() => {\n if (hasSelection.value)\n return displayLabel.value\n return options.placeholder() ?? ''\n })\n\n return {\n optionsResolved,\n flatOptions,\n isOptionGroup,\n keyOf,\n sameValue,\n modelSingle,\n modelMultiple,\n selectedValues,\n hasSelection,\n fromDomValue,\n selectedOptions,\n hasModelInOptions,\n displayLabel,\n displayText,\n }\n}\n","<script setup lang=\"ts\" generic=\"TValue extends GrSelectValue = string\">\nimport { computed, nextTick, ref, useId, useSlots, watch } from 'vue'\n\nimport { usePortalTarget } from '../../composables/usePortalTarget'\n\nimport { useGrComponentProp, useGrComponentSize, useGrThemeAttrs } from '../GrConfigProvider/context'\n\nimport type { GrBadgeRadius, GrBadgeSize, GrBadgeTone } from '../GrBadge/grBadgeStyles'\nimport GrChip from '../GrChip/GrChip.vue'\nimport { chipSizeForBadgeScale } from '../GrChip/grChipStyles'\nimport GrInput from '../GrInput/GrInput.vue'\nimport { vClickOutside } from '../../directives'\nimport { useFloating } from '../../composables/useFloating'\nimport { useDismissible } from '../../composables/useDismissible'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport { useGrFormFieldContext } from '../GrFormField/context'\nimport { panelPopTransition } from '../shared/overlayTransition'\nimport { useGrFormControl } from '../../composables/useGrFormControl'\nimport { useFocusWithin } from '../../composables/internal/useFocusWithin'\nimport { useControlAddons } from '../../composables/internal/useControlAddons'\nimport { useControlledOpen } from '../../composables/internal/useControlledOpen'\nimport { useSelectPanelItems } from './composables/useSelectPanelItems'\nimport { useSelectNavigation } from './composables/useSelectNavigation'\nimport { useSelectVirtualization } from './composables/useSelectVirtualization'\nimport { useSelectValues } from './composables/useSelectValues'\nimport { isEmptySelectValue } from './selectValue'\n\nimport {\n defaultBaseClass,\n grSelectLinkNativeLabelClass,\n grSelectLinkNativeOverlayClass,\n grSelectNativeClass,\n grSelectOptionClass,\n grSelectPanelClasses,\n grSelectTriggerClass,\n linkBaseClass,\n type GrSelectState,\n type GrSelectModelValue,\n type GrSelectValue,\n type GrSelectOption,\n type GrSelectOptionOrGroup,\n type GrSelectOptionsView,\n type GrSelectSize,\n type GrSelectUnderline,\n type GrSelectVariant,\n type GrSelectView,\n} from './grSelectStyles'\n\nimport IconCheck from '~icons/lucide/check'\nimport IconChevronDown from '~icons/lucide/chevron-down'\nimport IconLoaderCircle from '~icons/lucide/loader-circle'\nimport IconX from '~icons/lucide/x'\n\nexport type {\n GrSelectModelValue,\n GrSelectOption,\n GrSelectOptionGroup,\n GrSelectOptionOrGroup,\n GrSelectOptionsView,\n GrSelectSize,\n GrSelectState,\n GrSelectUnderline,\n GrSelectValue,\n GrSelectVariant,\n GrSelectView,\n} from './grSelectStyles'\n\n/**\n * Пропсы публичного GR-примитива «Select».\n */\nexport interface GrSelectProps<TValue extends GrSelectValue = string> {\n modelValue: GrSelectModelValue<TValue>\n /** Список опций. Поддерживает плоский массив опций и группы опций (`{ label, options }`). */\n options?: GrSelectOptionOrGroup<TValue>[]\n disabled?: boolean\n /** Только для чтения: значение видно и уходит в форму, но не меняется. */\n readonly?: boolean\n /** Визуальное и ARIA-состояние ошибки. */\n invalid?: boolean\n /**\n * Визуальный оттенок рамки: `default | success | warning | danger`. `invalid`\n * сильнее — ошибка перекрывает любую другую подсветку. В `view=\"link\"` рамки\n * нет, и состояние туда не применяется.\n */\n state?: GrSelectState\n /**\n * Имя поля-идентификатора, когда значения опций — объекты. Без него объекты\n * сравнивались бы по ссылке, и пришедшая снаружи копия с тем же `id` не\n * совпала бы ни с одной опцией.\n */\n valueKey?: string\n /** Обязательное поле (`aria-required`). */\n required?: boolean\n ariaLabel?: string\n view?: GrSelectView\n size?: GrSelectSize\n /** Placeholder (показывается, когда значение не выбрано). */\n placeholder?: string\n /** Multiple selection. */\n multiple?: boolean\n /**\n * Вид чипов выбранных значений в режиме `multiple`. Чип — это `GrBadge`: своя\n * плашка на светлой теме почти не отличалась от фона поля.\n */\n tagTone?: GrBadgeTone\n tagDark?: boolean\n tagSize?: GrBadgeSize\n tagRadius?: GrBadgeRadius\n /** Как отображать список опций: нативный `<select>` или кастомная панель. */\n optionsView?: GrSelectOptionsView\n /** Разрешает ввод/выбор значения, которого нет в `options`. */\n allowCustomValue?: boolean\n /**\n * Поиск/фильтрация опций по вводу (независимо от `allowCustomValue`). Показывает\n * поле поиска над списком и фильтрует опции. Работает только в `optionsView=\"panel\"`\n * (при `native` панель форсится автоматически).\n */\n filterable?: boolean\n /** Placeholder поля поиска (`filterable`). i18n: fallback `gr.select.searchPlaceholder`. */\n filterPlaceholder?: string\n /**\n * Текст поиска как контролируемое значение (`v-model:search`). Без него\n * `loading` был декоративным: набранное пользователем наружу не выходило, и\n * сходить за опциями на сервер было не с чем.\n */\n search?: string\n /**\n * Состояние загрузки: вместо списка опций панель показывает индикатор загрузки.\n * Полезно для удалённой подгрузки опций. Форсит `optionsView=\"panel\"`.\n */\n loading?: boolean\n /** Текст индикатора загрузки. i18n: fallback `gr.select.loading`. */\n loadingText?: string\n /** Текст пустого результата фильтрации. i18n: fallback `gr.select.noResults`. */\n noResultsText?: string\n /**\n * Режим тегов для `multiple`: выбранные значения показываются как удаляемые\n * chips в триггере (вместо строки «a, b, c»). Форсит `optionsView=\"panel\"`.\n */\n tags?: boolean\n /** Placeholder для инпута кастомного значения (только в `optionsView=\"panel\"`). i18n-friendly: если не задан — берётся из адаптера перевода (`gr.select.customValuePlaceholder`), иначе — встроенный fallback. */\n customValuePlaceholder?: string\n /** Максимальная высота панели (только в `optionsView=\"panel\"`). */\n dropdownMaxHeight?: number\n /**\n * Виртуализация панели: в DOM живёт только окно вокруг вьюпорта. Высоту окна\n * задаёт `dropdownMaxHeight`.\n *\n * Только для `optionsView=\"panel\"`: у нативного `<select>` панели нет вовсе.\n * Несовместим с `view=\"link\"` — там ширина панели равна ширине отрисованной\n * опции и прыгала бы при прокрутке.\n */\n virtual?: boolean\n /** Закрывать панель после выбора (только в `optionsView=\"panel\"`). */\n closeOnSelect?: boolean\n /** Сколько chips показать до сворачивания в «+N» (только `tags`). */\n maxTagCount?: number\n /** Разрешает очистку выбранного значения. */\n clearable?: boolean\n /** i18n-label для кнопки очистки (`aria-label`). */\n clearLabel?: string\n /**\n * Цвет/вариант ссылки для `view=\"link\"` (аналогично `GrLink`).\n * В `view=\"default\"` не используется.\n */\n variant?: GrSelectVariant\n /**\n * Подчёркивание для `view=\"link\"` (аналогично `GrLink`).\n * В `view=\"default\"` не используется.\n */\n underline?: GrSelectUnderline\n /**\n * Контролируемое состояние панели (`v-model:open`). Без пропа панель ведёт\n * себя сама (uncontrolled), с ним — слушайте `update:open` и меняйте проп.\n * Только для `optionsView=\"panel\"`: у нативного `<select>` панель браузерная.\n */\n open?: boolean\n /**\n * Имя для нативной формы: в native-режиме уходит на сам `<select>`, в\n * panel-режиме значения сериализуются hidden-инпутами (ключ — `keyOf`).\n */\n name?: string\n /**\n * Ширины аддонов `prefix`/`suffix` — общий контракт контролов пакета\n * (`docs/form-controls.md`). Аддоны живут в панельном триггере: внутрь\n * нативного `<select>` разметку положить нельзя.\n */\n prefixMinWidth?: string\n prefixMaxWidth?: string\n suffixMinWidth?: string\n suffixMaxWidth?: string\n prefixFixed?: boolean\n suffixFixed?: boolean\n}\n\nexport interface GrSelectEmits<TValue extends GrSelectValue = string> {\n (e: 'update:modelValue', value: GrSelectModelValue<TValue>): void\n /** Значение изменилось — тот же payload, что у `update:modelValue`. */\n (e: 'change', value: GrSelectModelValue<TValue>): void\n /** Значение снято кнопкой очистки. */\n (e: 'clear'): void\n /** Панель открылась/закрылась (`v-model:open`). */\n (e: 'update:open', value: boolean): void\n /** Текст поиска как контролируемое значение (`v-model:search`). */\n (e: 'update:search', value: string): void\n (e: 'focus', event: FocusEvent): void\n (e: 'blur', event: FocusEvent): void\n /** Пользователь набрал запрос — сигнал сходить за опциями. */\n (e: 'search', value: string): void\n}\n\nconst props = withDefaults(\n defineProps<GrSelectProps<TValue>>(),\n {\n options: undefined,\n disabled: false,\n readonly: false,\n invalid: false,\n state: 'default',\n valueKey: undefined,\n required: false,\n ariaLabel: undefined,\n view: 'default',\n size: undefined,\n\n placeholder: undefined,\n multiple: false,\n tagTone: 'neutral',\n tagDark: false,\n tagSize: 'sm',\n tagRadius: 'round',\n\n optionsView: 'native',\n allowCustomValue: false,\n filterable: false,\n filterPlaceholder: undefined,\n search: undefined,\n loading: false,\n loadingText: undefined,\n noResultsText: undefined,\n tags: false,\n customValuePlaceholder: undefined,\n dropdownMaxHeight: 280,\n virtual: false,\n closeOnSelect: true,\n maxTagCount: undefined,\n clearable: undefined,\n clearLabel: undefined,\n variant: undefined,\n underline: undefined,\n open: undefined,\n name: undefined,\n prefixMinWidth: undefined,\n prefixMaxWidth: undefined,\n suffixMinWidth: undefined,\n suffixMaxWidth: undefined,\n prefixFixed: false,\n suffixFixed: false,\n },\n)\n\n// Эффективный размер: локальный проп → `GrConfigProvider` → дефолт компонента.\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrSelect' })\nconst resolvedVariant = useGrComponentProp('GrSelect', 'variant', () => props.variant, 'primary')\nconst resolvedUnderline = useGrComponentProp('GrSelect', 'underline', () => props.underline, 'auto')\nconst resolvedClearable = useGrComponentProp('GrSelect', 'clearable', () => props.clearable, false)\n\nconst { t } = useGranularityTranslations()\n\nconst resolvedCustomValuePlaceholder = computed(() => {\n return props.customValuePlaceholder ?? t('gr.select.customValuePlaceholder', 'Add value…')\n})\n\nconst resolvedClearLabel = computed(() => props.clearLabel ?? t('gr.common.clear', 'Clear'))\nconst resolvedFilterPlaceholder = computed(() => props.filterPlaceholder ?? t('gr.select.searchPlaceholder', 'Search…'))\nconst resolvedLoadingText = computed(() => props.loadingText ?? t('gr.select.loading', 'Loading…'))\nconst resolvedNoResultsText = computed(() => props.noResultsText ?? t('gr.select.noResults', 'No results'))\n// В search-инпуте: при allowCustomValue — «Add value…», иначе (чистый filterable) — «Search…».\nconst resolvedSearchPlaceholder = computed(() =>\n props.allowCustomValue ? resolvedCustomValuePlaceholder.value : resolvedFilterPlaceholder.value,\n)\n\nconst baseClassName = computed(() => props.view === 'link' ? linkBaseClass : defaultBaseClass)\n\nconst rootClass = computed(() => props.view === 'link' ? 'relative inline-block align-baseline' : 'relative w-full')\n\nconst emit = defineEmits<GrSelectEmits<TValue>>()\ndefineSlots<{\n /** Собственные `<option>` для нативного режима. */\n default?: () => any\n /** Аддон слева в панельном триггере (в нативном режиме недоступен). */\n prefix?: () => any\n /** Аддон справа в панельном триггере, перед крестиком и шевроном. */\n suffix?: () => any\n /** Отображение значения в триггере вместо текста по умолчанию. */\n value?: (props: {\n selectedOptions: GrSelectOption<TValue>[]\n selectedValues: TValue[]\n displayLabel: string\n placeholder?: string\n hasSelection: boolean\n }) => any\n /** Строка списка вместо подписи опции. */\n option?: (props: { option: GrSelectOption<TValue>, selected: boolean }) => any\n /** Содержимое панели, пока едут опции. */\n loading?: () => any\n /** Содержимое панели, когда подходящих опций нет. */\n empty?: () => any\n}>()\n\n// Fallback из контекста `GrFormField` (id/aria-describedby/invalid/required)\n// для связки с лейблом и сообщением об ошибке.\nconst field = useGrFormFieldContext()\nconst resolvedId = computed(() => field?.id.value)\nconst {\n disabled: isDisabled,\n invalid: isInvalid,\n required: isRequired,\n readonly: isReadonly,\n} = useGrFormControl(() => props)\n\nconst nativeSelectEl = ref<HTMLSelectElement | null>(null)\nconst triggerButtonEl = ref<HTMLElement | null>(null)\n\n// Виджет зависит от режима: нативный `<select>` или кастомный триггер панели.\nfunction focus(): void {\n (nativeSelectEl.value ?? triggerButtonEl.value)?.focus()\n}\n\nfunction blur(): void {\n (nativeSelectEl.value ?? triggerButtonEl.value)?.blur()\n}\n\ndefineExpose({ focus, blur })\nconst describedBy = computed(() => field?.describedById.value)\n\nconst {\n optionsResolved,\n flatOptions,\n isOptionGroup,\n keyOf,\n sameValue,\n modelSingle,\n selectedValues,\n hasSelection,\n fromDomValue,\n selectedOptions,\n hasModelInOptions,\n displayLabel,\n displayText,\n} = useSelectValues<TValue>({\n modelValue: () => props.modelValue,\n options: () => props.options,\n multiple: () => props.multiple,\n valueKey: () => props.valueKey,\n placeholder: () => props.placeholder,\n})\n\nconst ADDON_MIN_WIDTH_BY_SIZE: Record<GrSelectSize, string> = {\n xs: '2rem',\n sm: '2.25rem',\n md: '2.5rem',\n lg: '3rem',\n}\n\n/**\n * Триггер панельного режима — флекс-строка, поэтому аддоны встают её соседями,\n * а не поверх поля: резервировать место паддингом не нужно.\n */\nconst {\n hasPrefix,\n hasSuffix,\n prefixEl,\n suffixEl,\n prefixLen,\n prefixStyle,\n suffixStyle,\n} = useControlAddons(() => props, {\n defaultMinWidth: () => ADDON_MIN_WIDTH_BY_SIZE[resolvedSize.value],\n paddingX: () => '0px',\n})\n\n// Нативный `<select multiple>` — это многострочный listbox, а не поповер. В режиме\n// `view=\"link\"` он рендерится невидимым overlay'ем, из-за чего multiple-вариант «не\n// открывается» (клик по невидимому listbox'у ничего не показывает). Для этой\n// неподдерживаемой комбинации форсим кастомную панель, которая корректно открывается.\nconst effectiveOptionsView = computed<GrSelectOptionsView>(() => {\n if (props.view === 'link' && props.multiple && props.optionsView === 'native')\n return 'panel'\n // Поиск/загрузка/теги невозможны в нативном `<select>` — форсим кастомную панель.\n if ((props.filterable || props.loading || props.tags) && props.optionsView === 'native')\n return 'panel'\n return props.optionsView\n})\n\n// Поле поиска в панели: показываем при `filterable` ИЛИ `allowCustomValue`.\nconst showSearchInput = computed(() =>\n (props.filterable || props.allowCustomValue) && effectiveOptionsView.value === 'panel',\n)\n\n// Показывать chips вместо строки «a, b, c» (только multiple + tags).\nconst showTags = computed(() => props.multiple && props.tags && effectiveOptionsView.value === 'panel')\n\nconst nativeCustomOptionVisible = computed(() => {\n if (!props.allowCustomValue)\n return false\n if (effectiveOptionsView.value !== 'native')\n return false\n if (props.multiple)\n return false\n if (!props.options)\n return false\n if (modelSingle.value === '')\n return false\n return !hasModelInOptions.value\n})\n\n/**\n * Текст поиска: контролируемый `search` сильнее внутреннего состояния. Каждое\n * изменение уходит наружу — без этого `loading` не с чем было связать.\n */\nconst internalSearch = ref('')\nconst customValue = computed<string>({\n get: () => props.search ?? internalSearch.value,\n set: (next) => {\n internalSearch.value = next\n emit('update:search', next)\n emit('search', next)\n },\n})\n\n// Имя `open` сохранено: все читатели — шаблон, watch, `useDismissible`/\n// `useFloating` — работают с computed-Ref как раньше.\nconst { open, setOpen } = useControlledOpen(\n () => props.open,\n next => emit('update:open', next),\n)\n\nconst rootEl = ref<HTMLElement | null>(null)\nconst panelEl = ref<HTMLElement | null>(null)\nconst listboxEl = ref<HTMLElement | null>(null)\n\n// Панель телепортирована в `body`, то есть лежит вне корня, но для пользователя\n// она часть контрола: без неё уход фокуса в панель читался бы как `blur`.\nconst { onFocusIn, onFocusOut } = useFocusWithin(rootEl, {\n enter: event => emit('focus', event),\n leave: event => emit('blur', event),\n containers: () => [panelEl.value],\n})\nconst customInputRef = ref<InstanceType<typeof GrInput> | null>(null)\nconst clickOutsideExclude = [() => panelEl.value]\n\n// Для `view='link'` ширина триггера = ширине выбранной опции (`inline-block w-auto`),\n// поэтому панель растёт по контенту (`matchWidth: 'min'` → `width: max-content` +\n// `min-width` от триггера), а не сжимается до неё. Для `view='default'` панель точно\n// повторяет ширину триггера (`matchWidth: true`).\nconst { floatingStyle, update: updateFloatingPosition } = useFloating(rootEl, panelEl, open, {\n placement: 'bottom-start',\n matchWidth: () => (props.view === 'link' ? 'min' : true),\n zIndexVar: '--gr-z-dropdown',\n})\n\nfunction closeDropdown(): void {\n setOpen(false)\n}\n\nconst locked = computed(() => isDisabled.value || isReadonly.value)\n\nfunction toggleDropdown(): void {\n if (locked.value)\n return\n setOpen(!open.value)\n}\n\nuseDismissible(open, closeDropdown)\n\n// `view` определяет режим `matchWidth` (см. выше) — пересчитываем позицию/ширину\n// панели, если он меняется, пока панель открыта.\nwatch(\n () => props.view,\n () => {\n if (open.value)\n updateFloatingPosition()\n },\n)\n\nconst panelClasses = computed(() => {\n return grSelectPanelClasses\n})\n\nconst { panelItems, panelRows, canAddCustom } = useSelectPanelItems<TValue>({\n optionsResolved,\n flatOptions,\n isOptionGroup,\n modelSingle,\n selectedValues,\n hasModelInOptions,\n sameValue,\n query: () => customValue.value,\n allowCustomValue: () => props.allowCustomValue,\n filterable: () => props.filterable,\n multiple: () => props.multiple,\n isPanelView: () => effectiveOptionsView.value === 'panel',\n})\n\nfunction emitValue(value: GrSelectModelValue<TValue>): void {\n if (isReadonly.value)\n return\n\n emit('update:modelValue', value)\n emit('change', value)\n}\n\nfunction isSelected(value: TValue): boolean {\n return selectedValues.value.some(selected => sameValue(selected, value))\n}\n\nfunction isOptionDisabled(value: TValue): boolean {\n return flatOptions.value.find(o => sameValue(o.value, value))?.disabled === true\n}\n\nfunction selectValue(value: TValue): void {\n emitValue(value)\n if (props.closeOnSelect) {\n closeDropdown()\n }\n}\n\nfunction toggleValue(value: TValue): void {\n if (isOptionDisabled(value))\n return\n\n if (!props.multiple) {\n selectValue(value)\n return\n }\n\n const next = selectedValues.value.slice()\n const idx = next.findIndex(selected => sameValue(selected, value))\n if (idx >= 0) {\n next.splice(idx, 1)\n }\n else {\n next.push(value)\n }\n\n emitValue(next)\n if (props.closeOnSelect) {\n closeDropdown()\n }\n}\n\nfunction addCustom(): void {\n // Кастомное значение набирается текстом, поэтому оно строковое —\n // при числовом `TValue` эта ветка неприменима (см. docs/components.md).\n const v = customValue.value.trim() as TValue\n if (!v)\n return\n toggleValue(v)\n}\n\n// Удаление одного значения из multiple-выбора (клик по «×» на chip).\nfunction removeValue(value: TValue): void {\n if (locked.value)\n return\n if (!props.multiple)\n return\n // Кнопка чипа держит объект из `options`, модель — свою копию: сравнение\n // только через ключ, `!==` не удалил бы ничего.\n emitValue(selectedValues.value.filter(v => !sameValue(v, value)))\n}\n\nconst visibleTagOptions = computed(() => {\n const limit = props.maxTagCount\n if (limit === undefined || limit < 0)\n return selectedOptions.value\n return selectedOptions.value.slice(0, limit)\n})\n\n/**\n * Проп `tagSize` объявлен по шкале бейджа и остаётся публичным контрактом:\n * ступени чипа сдвинуты, и перевод держит кегль тем же.\n */\nconst chipSize = computed(() => chipSizeForBadgeScale(props.tagSize))\n\nconst hiddenTagCount = computed(() => selectedOptions.value.length - visibleTagOptions.value.length)\n\nfunction tagRemoveLabel(option: GrSelectOption<TValue>): string {\n return t('gr.select.removeTag', 'Remove {label}', { label: option.label })\n}\n\n// ————— Клавиатурная навигация комбобокса (WAI-ARIA, aria-activedescendant).\nconst listboxId = useId()\n\n/**\n * Id опции строится от позиции в списке: значение с пробелом дало бы невалидный\n * `id`, а `aria-activedescendant` — два токена вместо одной ссылки.\n */\nfunction optionDomId(index: number): string {\n return `${listboxId}-opt-${index}`\n}\n\n/** Заголовок группы читается вместе с опцией — через `aria-describedby`. */\nfunction groupLabelId(groupKey: string): string {\n return `${listboxId}-${groupKey}`\n}\n\nconst {\n virtualEnabled,\n addOffset,\n scrollToIndex: scrollVirtualToIndex,\n measure: measureVirtualRow,\n optionSetProps,\n addOptionSetProps,\n showAddOption,\n renderedPanelRows,\n listboxStyle,\n} = useSelectVirtualization<TValue>({\n panelItems,\n panelRows,\n canAddCustom,\n listboxEl,\n enabled: () => props.virtual && effectiveOptionsView.value === 'panel',\n maxHeight: () => props.dropdownMaxHeight,\n})\n\nif (__GR_DEV__) {\n const slots = useSlots()\n\n watch(\n () => [Boolean(slots.prefix || slots.suffix), effectiveOptionsView.value] as const,\n ([hasAddon, view]) => {\n if (hasAddon && view !== 'panel') {\n console.warn(\n '[granularity] GrSelect: слоты `prefix`/`suffix` работают только с '\n + '`optionsView=\"panel\"` — внутрь нативного `<select>` разметку положить нельзя.',\n )\n }\n },\n { immediate: true },\n )\n\n watch(\n () => [props.virtual, effectiveOptionsView.value, props.view] as const,\n ([virtual, view, appearance]) => {\n if (!virtual)\n return\n\n if (view !== 'panel') {\n console.warn(\n '[granularity] GrSelect: `virtual` работает только с `optionsView=\"panel\"` — '\n + 'у нативного `<select>` своей панели нет, и виртуализировать нечего.',\n )\n }\n else if (appearance === 'link') {\n console.warn(\n '[granularity] GrSelect: `virtual` не сочетается с `view=\"link\"` — ширина панели '\n + 'там равна ширине отрисованной опции и будет прыгать при прокрутке.',\n )\n }\n },\n { immediate: true },\n )\n}\n\n/** При `loading` списка в DOM нет — ссылаться на него нельзя. */\nconst listboxIdIfRendered = computed(() => (open.value && !props.loading ? listboxId : undefined))\n\nfunction openDropdown(): void {\n if (locked.value || open.value)\n return\n setOpen(true)\n}\n\nconst {\n activeIndex,\n activeItem,\n activeValue,\n addOptionDomId,\n triggerActiveDescendant,\n searchActiveDescendant,\n onOptionHover,\n onComboKeydown,\n initActiveIndex,\n resetActive,\n} = useSelectNavigation<TValue>({\n panelItems,\n flatOptions,\n canAddCustom,\n sameValue,\n isSelected,\n open,\n locked,\n showSearchInput,\n virtualEnabled,\n addOffset,\n listboxId,\n optionDomId,\n scrollVirtualToIndex,\n openDropdown,\n closeDropdown,\n addCustom,\n toggleValue,\n})\n\nwatch(\n open,\n async (isOpen, wasOpen) => {\n if (!isOpen) {\n internalSearch.value = ''\n resetActive()\n\n // Панель с полем поиска забирает фокус себе; на закрытии поле исчезает, и\n // без возврата фокус уезжает на `<body>` — клавиатурный пользователь\n // оказывается в начале документа. Возвращаем только если фокус ещё внутри\n // панели: пользователь мог уйти дальше сам.\n //\n // `wasOpen` отсекает первый вызов (`immediate: true`): на сервере DOM нет,\n // да и красть фокус при монтировании компонент не должен.\n if (wasOpen) {\n const active = document.activeElement\n if (active instanceof HTMLElement && panelEl.value?.contains(active))\n focus()\n }\n\n return\n }\n\n initActiveIndex()\n\n if (showSearchInput.value) {\n await nextTick()\n customInputRef.value?.focus()\n }\n },\n { immediate: true },\n)\n\nconst showNativeChevron = computed(() => {\n return effectiveOptionsView.value === 'native' && props.view !== 'link' && !props.multiple\n})\n\nconst nativeClearOptionVisible = computed(() => {\n if (!resolvedClearable.value)\n return false\n if (effectiveOptionsView.value !== 'native')\n return false\n if (props.multiple)\n return false\n if (!props.options)\n return true\n return !flatOptions.value.some(o => isEmptySelectValue(o.value))\n})\n\nconst panelClearVisible = computed(() => {\n if (!resolvedClearable.value)\n return false\n if (effectiveOptionsView.value !== 'panel')\n return false\n if (props.view === 'link')\n return false\n return hasSelection.value\n})\n\nconst nativeClassName = computed(() => {\n return grSelectNativeClass({\n view: props.view,\n size: resolvedSize.value,\n disabled: isDisabled.value,\n variant: resolvedVariant.value,\n underline: resolvedUnderline.value,\n showNativeChevron: showNativeChevron.value,\n state: props.state,\n invalid: isInvalid.value,\n })\n})\n\n/**\n * `view=\"link\"` в native-режиме: ширина обёртки должна определяться выбранной опцией,\n * а не самой длинной (как делает браузер по умолчанию). Поэтому рендерим прозрачный\n * `<select>`-overlay поверх видимого `<span>` с меткой — overlay принимает клики/клавиатуру,\n * span задаёт ширину компонента в закрытом состоянии.\n */\nconst isLinkNative = computed(() => props.view === 'link' && effectiveOptionsView.value === 'native')\n\nconst linkNativeLabelClassName = computed(() => grSelectLinkNativeLabelClass({\n size: resolvedSize.value,\n variant: resolvedVariant.value,\n underline: resolvedUnderline.value,\n disabled: isDisabled.value,\n}))\n\nconst linkNativeDisplayText = computed(() => {\n return displayText.value || props.placeholder || '\\u00A0'\n})\n\nconst triggerClassName = computed(() => {\n return grSelectTriggerClass({\n view: props.view,\n optionsView: effectiveOptionsView.value,\n size: resolvedSize.value,\n disabled: isDisabled.value,\n variant: resolvedVariant.value,\n underline: resolvedUnderline.value,\n state: props.state,\n invalid: isInvalid.value,\n })\n})\n\nfunction onChange(e: Event): void {\n const el = e.target as HTMLSelectElement\n\n // Нативного `readonly` у `<select>` нет: браузер уже переключил значение —\n // возвращаем DOM к модели, иначе форма отправит непринятое (приём GrCheckbox).\n if (isReadonly.value) {\n if (props.multiple) {\n for (const option of el.options) option.selected = isSelected(fromDomValue(option.value))\n }\n else {\n el.value = modelSingle.value === '' ? '' : keyOf(modelSingle.value)\n }\n return\n }\n\n // Только через `emitValue`: он единственный источник пары\n // `update:modelValue` + `change`, и канал события обязан быть один на оба\n // режима отрисовки. Прямой `emit` отсюда оставил бы `change` без нативного\n // пути — молча, потому что объявленный emit уходит из `$attrs`.\n emitValue(\n props.multiple\n ? Array.from(el.selectedOptions, o => fromDomValue(o.value))\n // Пустая строка — это «очистить», а не значение: восстанавливать её не нужно.\n : ((el.value === '' ? '' : fromDomValue(el.value)) as TValue),\n )\n}\n\nfunction clearSelection(): void {\n if (locked.value)\n return\n emitValue((props.multiple ? [] : '') as GrSelectModelValue<TValue>)\n emit('clear')\n}\n\n// Телепорт включается только ПОСЛЕ монтирования: иначе первый клиентский\n// рендер не совпадает с серверным и ломается гидрация (см. композабл).\nconst { target: portalTarget, enabled: teleportEnabled } = usePortalTarget()\n\n// Тема поддерева на телепортированную панель: в DOM она уезжает в `body`, то\n// есть вне обёртки провайдера, и `data-theme` с неё не наследуется. В дереве\n// компонентов панель остаётся внутри — `inject` доходит, и тему она ставит себе\n// сама.\nconst themeAttrs = useGrThemeAttrs()\n</script>\n\n<template>\n <div\n v-if=\"effectiveOptionsView === 'native'\"\n data-gr-select\n :class=\"rootClass\"\n @focusin=\"onFocusIn\"\n @focusout=\"onFocusOut\"\n >\n <!--\n Выбор задаём per-option через `:selected` (а не `:value` на `<select>`):\n для `<select multiple>` биндинг `:value` массивом не работает — DOM не\n отражает программное изменение модели. `onChange` читает выбор из DOM.\n -->\n <select\n :id=\"resolvedId\"\n ref=\"nativeSelectEl\"\n data-gr-select-native\n :name=\"name\"\n :multiple=\"multiple\"\n :disabled=\"isDisabled\"\n :aria-label=\"ariaLabel\"\n :aria-invalid=\"isInvalid ? 'true' : undefined\"\n :aria-describedby=\"describedBy\"\n :aria-required=\"isRequired ? 'true' : undefined\"\n :aria-readonly=\"isReadonly ? 'true' : undefined\"\n :class=\"isLinkNative ? grSelectLinkNativeOverlayClass : [baseClassName, nativeClassName]\"\n @change=\"onChange\"\n >\n <option v-if=\"nativeClearOptionVisible\" value=\"\" :selected=\"!multiple && modelSingle === ''\">\n {{ placeholder || t('gr.select.clearOption', 'None') }}\n </option>\n\n <slot>\n <option v-if=\"nativeCustomOptionVisible\" :value=\"keyOf(modelSingle)\" :selected=\"!multiple\">\n {{ modelSingle }}\n </option>\n <template v-for=\"(item, index) in optionsResolved\" :key=\"index\">\n <optgroup v-if=\"isOptionGroup(item)\" :label=\"item.label\">\n <option\n v-for=\"opt in item.options\"\n :key=\"`${index}:${keyOf(opt.value)}`\"\n :value=\"keyOf(opt.value)\"\n :selected=\"isSelected(opt.value)\"\n :disabled=\"opt.disabled\"\n >\n {{ opt.label }}\n </option>\n </optgroup>\n <option\n v-else\n :value=\"keyOf(item.value)\"\n :selected=\"isSelected(item.value)\"\n :disabled=\"item.disabled\"\n >\n {{ item.label }}\n </option>\n </template>\n </slot>\n </select>\n\n <span\n v-if=\"isLinkNative\"\n data-gr-select-link-label\n aria-hidden=\"true\"\n :class=\"linkNativeLabelClassName\"\n >{{ linkNativeDisplayText }}</span>\n\n <span\n v-if=\"showNativeChevron\"\n data-testid=\"gr-select-chevron\"\n class=\"absolute top-1/2 -translate-y-1/2 right-3 flex items-center text-[var(--gr-muted-fg)] pointer-events-none\"\n >\n <IconChevronDown class=\"block h-4 w-4\" aria-hidden=\"true\" />\n </span>\n </div>\n\n <div\n v-else\n ref=\"rootEl\"\n v-click-outside=\"{ handler: closeDropdown, enabled: open, exclude: clickOutsideExclude }\"\n data-gr-select\n :class=\"rootClass\"\n >\n <!-- Нативная форма: панельный режим сериализуется hidden-инпутами по keyOf. -->\n <template v-if=\"name\">\n <input\n v-for=\"value in selectedValues\"\n :key=\"`hidden-${keyOf(value)}`\"\n type=\"hidden\"\n :name=\"name\"\n :value=\"keyOf(value)\"\n >\n </template>\n <button\n :id=\"resolvedId\"\n ref=\"triggerButtonEl\"\n data-testid=\"gr-select-trigger\"\n data-gr-select-trigger\n type=\"button\"\n :disabled=\"isDisabled\"\n :aria-label=\"ariaLabel\"\n :aria-invalid=\"isInvalid ? 'true' : undefined\"\n :aria-describedby=\"describedBy\"\n :aria-required=\"isRequired ? 'true' : undefined\"\n :aria-readonly=\"isReadonly ? 'true' : undefined\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n :aria-controls=\"listboxIdIfRendered\"\n :aria-activedescendant=\"triggerActiveDescendant\"\n :aria-expanded=\"open ? 'true' : 'false'\"\n :aria-busy=\"loading ? 'true' : undefined\"\n :class=\"[baseClassName, triggerClassName]\"\n @click=\"toggleDropdown\"\n @keydown=\"onComboKeydown\"\n >\n <span\n v-if=\"hasPrefix\"\n ref=\"prefixEl\"\n data-gr-select-prefix\n class=\"shrink-0 inline-flex items-center justify-center text-[var(--gr-muted-fg)] select-none truncate\"\n :style=\"prefixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"prefix\" />\n </span>\n\n <span class=\"min-w-0 flex-1\">\n <slot\n name=\"value\"\n :selected-options=\"selectedOptions\"\n :selected-values=\"selectedValues\"\n :display-label=\"displayLabel\"\n :placeholder=\"placeholder\"\n :has-selection=\"hasSelection\"\n >\n <span\n class=\"block truncate\"\n :class=\"!hasSelection ? 'text-[var(--gr-muted-fg)]' : ''\"\n >\n {{ showTags && hasSelection ? '' : displayText }}\n </span>\n </slot>\n </span>\n\n <span\n v-if=\"hasSuffix\"\n ref=\"suffixEl\"\n data-gr-select-suffix\n class=\"shrink-0 inline-flex items-center justify-center text-[var(--gr-muted-fg)] select-none truncate\"\n :style=\"suffixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"suffix\" />\n </span>\n\n <!-- Место под кнопку очистки: она лежит абсолютом поверх триггера. -->\n <span\n v-if=\"panelClearVisible\"\n class=\"shrink-0 h-4 w-6\"\n aria-hidden=\"true\"\n />\n\n <!-- Шеврон виден всегда: без него поле с выбранным значением переставало\n выглядеть выпадающим списком. -->\n <span\n data-testid=\"gr-select-chevron\"\n class=\"shrink-0 flex items-center text-[var(--gr-muted-fg)] pointer-events-none\"\n >\n <IconChevronDown class=\"block h-4 w-4\" aria-hidden=\"true\" />\n </span>\n </button>\n\n <!--\n Чипы живут РЯДОМ с кнопкой-комбобоксом, а не внутри неё: `role=\"combobox\"`\n объявляет потомков презентационными, и крестик внутри был недостижим с\n клавиатуры (axe: `nested-interactive`).\n -->\n <div\n v-if=\"showTags && hasSelection\"\n data-gr-select-tags\n class=\"pointer-events-none absolute inset-y-0 left-0 flex max-w-[calc(100%-4rem)] flex-wrap items-center gap-1 px-3 py-1.5\"\n :style=\"{ left: hasPrefix ? prefixLen : undefined }\"\n >\n <GrChip\n v-for=\"opt in visibleTagOptions\"\n :key=\"keyOf(opt.value)\"\n data-gr-select-tag\n class=\"pointer-events-auto\"\n :tone=\"opt.tone ?? tagTone\"\n :dark=\"opt.dark ?? tagDark\"\n :size=\"chipSize\"\n :radius=\"tagRadius\"\n :closable=\"!isDisabled && !isReadonly\"\n :remove-label=\"tagRemoveLabel(opt)\"\n @remove=\"removeValue(opt.value)\"\n >\n <span class=\"truncate\">{{ opt.label }}</span>\n </GrChip>\n\n <GrChip\n v-if=\"hiddenTagCount > 0\"\n data-gr-select-tag-rest\n class=\"pointer-events-auto\"\n :tone=\"tagTone\"\n :dark=\"tagDark\"\n :size=\"chipSize\"\n :radius=\"tagRadius\"\n >\n +{{ hiddenTagCount }}\n </GrChip>\n </div>\n\n <button\n v-if=\"panelClearVisible\"\n data-testid=\"gr-select-clear\"\n data-gr-select-clear\n type=\"button\"\n class=\"absolute top-1/2 right-8 h-6 w-6 -translate-y-1/2 inline-flex items-center justify-center rounded-[var(--gr-radius-md)] text-[var(--gr-muted-fg)] hover:bg-[color-mix(in_srgb,var(--gr-muted)_25%,transparent)] hover:text-[var(--gr-fg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]\"\n :disabled=\"isDisabled\"\n :aria-label=\"resolvedClearLabel\"\n @click.stop=\"clearSelection\"\n >\n <IconX class=\"inline-block h-4 w-4\" aria-hidden=\"true\" />\n </button>\n\n <teleport :to=\"portalTarget\" :disabled=\"!teleportEnabled\">\n <transition\n :enter-active-class=\"panelPopTransition.enter\"\n :enter-from-class=\"panelPopTransition.enterFrom\"\n :enter-to-class=\"panelPopTransition.enterTo\"\n :leave-active-class=\"panelPopTransition.leave\"\n :leave-from-class=\"panelPopTransition.leaveFrom\"\n :leave-to-class=\"panelPopTransition.leaveTo\"\n >\n <div\n v-show=\"open\"\n ref=\"panelEl\"\n data-testid=\"gr-select-panel\"\n v-bind=\"themeAttrs\"\n data-gr-select-panel\n data-gr-overlay-root\n :style=\"floatingStyle\"\n >\n <div :class=\"panelClasses\">\n <div v-if=\"showSearchInput\" class=\"p-2 border-b border-[var(--gr-brd)]\">\n <GrInput\n ref=\"customInputRef\"\n v-model=\"customValue\"\n data-testid=\"gr-select-custom-input\"\n data-gr-select-search\n type=\"text\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n :aria-expanded=\"open ? 'true' : 'false'\"\n :aria-controls=\"listboxIdIfRendered\"\n :aria-activedescendant=\"searchActiveDescendant\"\n :placeholder=\"resolvedSearchPlaceholder\"\n :loading=\"loading\"\n size=\"sm\"\n @keydown=\"onComboKeydown\"\n />\n </div>\n\n <!-- Состояние загрузки: вместо списка — индикатор. -->\n <div\n v-if=\"loading\"\n data-gr-select-loading\n class=\"flex items-center justify-center gap-2 px-3 py-4 text-[length:var(--gr-text-sm)] leading-[var(--gr-leading-sm)] text-[var(--gr-muted-fg)]\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <slot name=\"loading\">\n <IconLoaderCircle class=\"block h-4 w-4 animate-spin\" aria-hidden=\"true\" />\n <span>{{ resolvedLoadingText }}</span>\n </slot>\n </div>\n\n <div\n v-else\n :id=\"listboxId\"\n ref=\"listboxEl\"\n data-gr-select-listbox\n :data-gr-virtual=\"virtualEnabled ? '' : undefined\"\n class=\"p-1 overflow-auto\"\n :class=\"virtualEnabled ? 'flex flex-col' : ''\"\n :style=\"listboxStyle\"\n role=\"listbox\"\n :aria-multiselectable=\"multiple ? 'true' : undefined\"\n >\n <!--\n Прямые потомки listbox — только опции и группы: роль объявляет\n остальных недопустимыми детьми (`aria-required-children`).\n `mousedown.prevent` держит фокус на триггере или в поле поиска —\n контракт combobox с `aria-activedescendant`.\n -->\n <button\n v-if=\"showAddOption\"\n :id=\"addOptionDomId\"\n data-testid=\"gr-select-add-option\"\n data-gr-select-add-option\n type=\"button\"\n role=\"option\"\n aria-selected=\"false\"\n tabindex=\"-1\"\n v-bind=\"addOptionSetProps\"\n :class=\"grSelectOptionClass({ view, disabled: false, active: activeItem?.kind === 'add' })\"\n @mousedown.prevent\n @click=\"addCustom\"\n @mousemove=\"activeIndex = 0\"\n >\n {{ t('gr.select.addOption', 'Add \"{value}\"', { value: customValue.trim() }) }}\n </button>\n\n <template v-for=\"row in renderedPanelRows\" :key=\"row.key\">\n <!--\n Группа: заголовок внутри неё и даёт ей имя. При виртуализации\n окно может начаться ниже заголовка — тогда его в DOM нет, и\n имя группы идёт напрямую в `aria-label`.\n -->\n <div\n v-if=\"row.kind === 'group'\"\n data-gr-select-group\n role=\"group\"\n :class=\"virtualEnabled ? 'flex flex-col' : ''\"\n :aria-labelledby=\"virtualEnabled ? undefined : groupLabelId(row.key)\"\n :aria-label=\"virtualEnabled ? row.label : undefined\"\n >\n <div\n v-if=\"row.labelVisible !== false\"\n :id=\"groupLabelId(row.key)\"\n :ref=\"(el) => virtualEnabled && row.labelIndex !== undefined && measureVirtualRow(row.labelIndex + addOffset, el as Element | null)\"\n data-gr-select-group-label\n role=\"presentation\"\n class=\"px-3 pt-2 pb-1 text-[length:var(--gr-text-xs)] leading-[var(--gr-leading-xs)] font-semibold uppercase tracking-wide text-[var(--gr-muted-fg)]\" :class=\"[\n view === 'link' ? 'block min-w-full w-max whitespace-nowrap' : '',\n ]\"\n >\n {{ row.label }}\n </div>\n\n <button\n v-for=\"child in row.options\"\n :id=\"optionDomId(child.index)\"\n :key=\"child.key\"\n :ref=\"(el) => virtualEnabled && measureVirtualRow(child.index + addOffset, el as Element | null)\"\n data-gr-select-option\n type=\"button\"\n role=\"option\"\n tabindex=\"-1\"\n v-bind=\"optionSetProps(child.index)\"\n :disabled=\"child.option.disabled\"\n :aria-selected=\"isSelected(child.option.value) ? 'true' : 'false'\"\n :aria-disabled=\"child.option.disabled ? 'true' : undefined\"\n :class=\"grSelectOptionClass({\n view,\n disabled: !!child.option.disabled,\n active: activeValue === child.option.value,\n })\"\n @mousedown.prevent\n @click=\"toggleValue(child.option.value)\"\n @mousemove=\"onOptionHover(child.index)\"\n >\n <slot name=\"option\" :option=\"child.option\" :selected=\"isSelected(child.option.value)\">\n <span class=\"flex items-center gap-2 min-w-0\">\n <span class=\"inline-block h-4 w-4 shrink-0\" aria-hidden=\"true\">\n <IconCheck\n v-if=\"isSelected(child.option.value)\"\n class=\"block h-4 w-4 text-[var(--gr-primary-text)]\"\n />\n </span>\n <span class=\"truncate\">{{ child.option.label }}</span>\n </span>\n </slot>\n </button>\n </div>\n\n <button\n v-else\n :id=\"optionDomId(row.index)\"\n :ref=\"(el) => virtualEnabled && measureVirtualRow(row.index + addOffset, el as Element | null)\"\n data-gr-select-option\n type=\"button\"\n role=\"option\"\n tabindex=\"-1\"\n v-bind=\"optionSetProps(row.index)\"\n :disabled=\"row.option.disabled\"\n :aria-selected=\"isSelected(row.option.value) ? 'true' : 'false'\"\n :aria-disabled=\"row.option.disabled ? 'true' : undefined\"\n :class=\"grSelectOptionClass({\n view,\n disabled: !!row.option.disabled,\n active: activeValue === row.option.value,\n })\"\n @mousedown.prevent\n @click=\"toggleValue(row.option.value)\"\n @mousemove=\"onOptionHover(row.index)\"\n >\n <slot name=\"option\" :option=\"row.option\" :selected=\"isSelected(row.option.value)\">\n <span class=\"flex items-center gap-2 min-w-0\">\n <span class=\"inline-block h-4 w-4 shrink-0\" aria-hidden=\"true\">\n <IconCheck\n v-if=\"isSelected(row.option.value)\"\n class=\"block h-4 w-4 text-[var(--gr-primary-text)]\"\n />\n </span>\n <span class=\"truncate\">{{ row.option.label }}</span>\n </span>\n </slot>\n </button>\n </template>\n </div>\n\n <!--\n Пустой результат живёт вне listbox — и объявляется, а не молчит:\n `aria-label` на generic-элементе диктор игнорирует.\n -->\n <div\n v-if=\"!loading && !panelItems.length && !canAddCustom\"\n data-gr-select-empty\n class=\"px-3 py-4 text-center text-[length:var(--gr-text-sm)] leading-[var(--gr-leading-sm)] text-[var(--gr-muted-fg)]\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <slot name=\"empty\">\n {{ resolvedNoResultsText }}\n </slot>\n </div>\n </div>\n </div>\n </transition>\n </teleport>\n </div>\n</template>\n\n<style scoped>\n/*\n * Распорки виртуальной панели.\n *\n * Не `padding` контейнера: `max-height` меряет ту же коробку. Не обёртка внутри\n * listbox'а: прямыми потомками роли обязаны быть только опции и группы. Не\n * отступы крайних строк: при прыжке прокрутки строки заменяются целиком, и\n * распорка исчезла бы вместе с ними.\n *\n * Псевдоэлементы не узлы DOM: размонтировать нечего, детьми роли не считаются,\n * а высота приезжает переменными в том же патче, что и строки.\n */\n[data-gr-virtual]::before,\n[data-gr-virtual]::after {\n content: '';\n display: block;\n flex: none;\n}\n\n[data-gr-virtual]::before {\n height: var(--gr-virtual-before, 0px);\n}\n\n[data-gr-virtual]::after {\n height: var(--gr-virtual-after, 0px);\n}\n</style>\n","<script setup lang=\"ts\" generic=\"TValue extends GrSelectValue = string\">\nimport { computed, nextTick, ref, useId, useSlots, watch } from 'vue'\n\nimport { usePortalTarget } from '../../composables/usePortalTarget'\n\nimport { useGrComponentProp, useGrComponentSize, useGrThemeAttrs } from '../GrConfigProvider/context'\n\nimport type { GrBadgeRadius, GrBadgeSize, GrBadgeTone } from '../GrBadge/grBadgeStyles'\nimport GrChip from '../GrChip/GrChip.vue'\nimport { chipSizeForBadgeScale } from '../GrChip/grChipStyles'\nimport GrInput from '../GrInput/GrInput.vue'\nimport { vClickOutside } from '../../directives'\nimport { useFloating } from '../../composables/useFloating'\nimport { useDismissible } from '../../composables/useDismissible'\nimport { useGranularityTranslations } from '../../internal/granularityI18n'\nimport { useGrFormFieldContext } from '../GrFormField/context'\nimport { panelPopTransition } from '../shared/overlayTransition'\nimport { useGrFormControl } from '../../composables/useGrFormControl'\nimport { useFocusWithin } from '../../composables/internal/useFocusWithin'\nimport { useControlAddons } from '../../composables/internal/useControlAddons'\nimport { useControlledOpen } from '../../composables/internal/useControlledOpen'\nimport { useSelectPanelItems } from './composables/useSelectPanelItems'\nimport { useSelectNavigation } from './composables/useSelectNavigation'\nimport { useSelectVirtualization } from './composables/useSelectVirtualization'\nimport { useSelectValues } from './composables/useSelectValues'\nimport { isEmptySelectValue } from './selectValue'\n\nimport {\n defaultBaseClass,\n grSelectLinkNativeLabelClass,\n grSelectLinkNativeOverlayClass,\n grSelectNativeClass,\n grSelectOptionClass,\n grSelectPanelClasses,\n grSelectTriggerClass,\n linkBaseClass,\n type GrSelectState,\n type GrSelectModelValue,\n type GrSelectValue,\n type GrSelectOption,\n type GrSelectOptionOrGroup,\n type GrSelectOptionsView,\n type GrSelectSize,\n type GrSelectUnderline,\n type GrSelectVariant,\n type GrSelectView,\n} from './grSelectStyles'\n\nimport IconCheck from '~icons/lucide/check'\nimport IconChevronDown from '~icons/lucide/chevron-down'\nimport IconLoaderCircle from '~icons/lucide/loader-circle'\nimport IconX from '~icons/lucide/x'\n\nexport type {\n GrSelectModelValue,\n GrSelectOption,\n GrSelectOptionGroup,\n GrSelectOptionOrGroup,\n GrSelectOptionsView,\n GrSelectSize,\n GrSelectState,\n GrSelectUnderline,\n GrSelectValue,\n GrSelectVariant,\n GrSelectView,\n} from './grSelectStyles'\n\n/**\n * Пропсы публичного GR-примитива «Select».\n */\nexport interface GrSelectProps<TValue extends GrSelectValue = string> {\n modelValue: GrSelectModelValue<TValue>\n /** Список опций. Поддерживает плоский массив опций и группы опций (`{ label, options }`). */\n options?: GrSelectOptionOrGroup<TValue>[]\n disabled?: boolean\n /** Только для чтения: значение видно и уходит в форму, но не меняется. */\n readonly?: boolean\n /** Визуальное и ARIA-состояние ошибки. */\n invalid?: boolean\n /**\n * Визуальный оттенок рамки: `default | success | warning | danger`. `invalid`\n * сильнее — ошибка перекрывает любую другую подсветку. В `view=\"link\"` рамки\n * нет, и состояние туда не применяется.\n */\n state?: GrSelectState\n /**\n * Имя поля-идентификатора, когда значения опций — объекты. Без него объекты\n * сравнивались бы по ссылке, и пришедшая снаружи копия с тем же `id` не\n * совпала бы ни с одной опцией.\n */\n valueKey?: string\n /** Обязательное поле (`aria-required`). */\n required?: boolean\n ariaLabel?: string\n view?: GrSelectView\n size?: GrSelectSize\n /** Placeholder (показывается, когда значение не выбрано). */\n placeholder?: string\n /** Multiple selection. */\n multiple?: boolean\n /**\n * Вид чипов выбранных значений в режиме `multiple`. Чип — это `GrBadge`: своя\n * плашка на светлой теме почти не отличалась от фона поля.\n */\n tagTone?: GrBadgeTone\n tagDark?: boolean\n tagSize?: GrBadgeSize\n tagRadius?: GrBadgeRadius\n /** Как отображать список опций: нативный `<select>` или кастомная панель. */\n optionsView?: GrSelectOptionsView\n /** Разрешает ввод/выбор значения, которого нет в `options`. */\n allowCustomValue?: boolean\n /**\n * Поиск/фильтрация опций по вводу (независимо от `allowCustomValue`). Показывает\n * поле поиска над списком и фильтрует опции. Работает только в `optionsView=\"panel\"`\n * (при `native` панель форсится автоматически).\n */\n filterable?: boolean\n /** Placeholder поля поиска (`filterable`). i18n: fallback `gr.select.searchPlaceholder`. */\n filterPlaceholder?: string\n /**\n * Текст поиска как контролируемое значение (`v-model:search`). Без него\n * `loading` был декоративным: набранное пользователем наружу не выходило, и\n * сходить за опциями на сервер было не с чем.\n */\n search?: string\n /**\n * Состояние загрузки: вместо списка опций панель показывает индикатор загрузки.\n * Полезно для удалённой подгрузки опций. Форсит `optionsView=\"panel\"`.\n */\n loading?: boolean\n /** Текст индикатора загрузки. i18n: fallback `gr.select.loading`. */\n loadingText?: string\n /** Текст пустого результата фильтрации. i18n: fallback `gr.select.noResults`. */\n noResultsText?: string\n /**\n * Режим тегов для `multiple`: выбранные значения показываются как удаляемые\n * chips в триггере (вместо строки «a, b, c»). Форсит `optionsView=\"panel\"`.\n */\n tags?: boolean\n /** Placeholder для инпута кастомного значения (только в `optionsView=\"panel\"`). i18n-friendly: если не задан — берётся из адаптера перевода (`gr.select.customValuePlaceholder`), иначе — встроенный fallback. */\n customValuePlaceholder?: string\n /** Максимальная высота панели (только в `optionsView=\"panel\"`). */\n dropdownMaxHeight?: number\n /**\n * Виртуализация панели: в DOM живёт только окно вокруг вьюпорта. Высоту окна\n * задаёт `dropdownMaxHeight`.\n *\n * Только для `optionsView=\"panel\"`: у нативного `<select>` панели нет вовсе.\n * Несовместим с `view=\"link\"` — там ширина панели равна ширине отрисованной\n * опции и прыгала бы при прокрутке.\n */\n virtual?: boolean\n /** Закрывать панель после выбора (только в `optionsView=\"panel\"`). */\n closeOnSelect?: boolean\n /** Сколько chips показать до сворачивания в «+N» (только `tags`). */\n maxTagCount?: number\n /** Разрешает очистку выбранного значения. */\n clearable?: boolean\n /** i18n-label для кнопки очистки (`aria-label`). */\n clearLabel?: string\n /**\n * Цвет/вариант ссылки для `view=\"link\"` (аналогично `GrLink`).\n * В `view=\"default\"` не используется.\n */\n variant?: GrSelectVariant\n /**\n * Подчёркивание для `view=\"link\"` (аналогично `GrLink`).\n * В `view=\"default\"` не используется.\n */\n underline?: GrSelectUnderline\n /**\n * Контролируемое состояние панели (`v-model:open`). Без пропа панель ведёт\n * себя сама (uncontrolled), с ним — слушайте `update:open` и меняйте проп.\n * Только для `optionsView=\"panel\"`: у нативного `<select>` панель браузерная.\n */\n open?: boolean\n /**\n * Имя для нативной формы: в native-режиме уходит на сам `<select>`, в\n * panel-режиме значения сериализуются hidden-инпутами (ключ — `keyOf`).\n */\n name?: string\n /**\n * Ширины аддонов `prefix`/`suffix` — общий контракт контролов пакета\n * (`docs/form-controls.md`). Аддоны живут в панельном триггере: внутрь\n * нативного `<select>` разметку положить нельзя.\n */\n prefixMinWidth?: string\n prefixMaxWidth?: string\n suffixMinWidth?: string\n suffixMaxWidth?: string\n prefixFixed?: boolean\n suffixFixed?: boolean\n}\n\nexport interface GrSelectEmits<TValue extends GrSelectValue = string> {\n (e: 'update:modelValue', value: GrSelectModelValue<TValue>): void\n /** Значение изменилось — тот же payload, что у `update:modelValue`. */\n (e: 'change', value: GrSelectModelValue<TValue>): void\n /** Значение снято кнопкой очистки. */\n (e: 'clear'): void\n /** Панель открылась/закрылась (`v-model:open`). */\n (e: 'update:open', value: boolean): void\n /** Текст поиска как контролируемое значение (`v-model:search`). */\n (e: 'update:search', value: string): void\n (e: 'focus', event: FocusEvent): void\n (e: 'blur', event: FocusEvent): void\n /** Пользователь набрал запрос — сигнал сходить за опциями. */\n (e: 'search', value: string): void\n}\n\nconst props = withDefaults(\n defineProps<GrSelectProps<TValue>>(),\n {\n options: undefined,\n disabled: false,\n readonly: false,\n invalid: false,\n state: 'default',\n valueKey: undefined,\n required: false,\n ariaLabel: undefined,\n view: 'default',\n size: undefined,\n\n placeholder: undefined,\n multiple: false,\n tagTone: 'neutral',\n tagDark: false,\n tagSize: 'sm',\n tagRadius: 'round',\n\n optionsView: 'native',\n allowCustomValue: false,\n filterable: false,\n filterPlaceholder: undefined,\n search: undefined,\n loading: false,\n loadingText: undefined,\n noResultsText: undefined,\n tags: false,\n customValuePlaceholder: undefined,\n dropdownMaxHeight: 280,\n virtual: false,\n closeOnSelect: true,\n maxTagCount: undefined,\n clearable: undefined,\n clearLabel: undefined,\n variant: undefined,\n underline: undefined,\n open: undefined,\n name: undefined,\n prefixMinWidth: undefined,\n prefixMaxWidth: undefined,\n suffixMinWidth: undefined,\n suffixMaxWidth: undefined,\n prefixFixed: false,\n suffixFixed: false,\n },\n)\n\n// Эффективный размер: локальный проп → `GrConfigProvider` → дефолт компонента.\nconst resolvedSize = useGrComponentSize(() => props.size, { component: 'GrSelect' })\nconst resolvedVariant = useGrComponentProp('GrSelect', 'variant', () => props.variant, 'primary')\nconst resolvedUnderline = useGrComponentProp('GrSelect', 'underline', () => props.underline, 'auto')\nconst resolvedClearable = useGrComponentProp('GrSelect', 'clearable', () => props.clearable, false)\n\nconst { t } = useGranularityTranslations()\n\nconst resolvedCustomValuePlaceholder = computed(() => {\n return props.customValuePlaceholder ?? t('gr.select.customValuePlaceholder', 'Add value…')\n})\n\nconst resolvedClearLabel = computed(() => props.clearLabel ?? t('gr.common.clear', 'Clear'))\nconst resolvedFilterPlaceholder = computed(() => props.filterPlaceholder ?? t('gr.select.searchPlaceholder', 'Search…'))\nconst resolvedLoadingText = computed(() => props.loadingText ?? t('gr.select.loading', 'Loading…'))\nconst resolvedNoResultsText = computed(() => props.noResultsText ?? t('gr.select.noResults', 'No results'))\n// В search-инпуте: при allowCustomValue — «Add value…», иначе (чистый filterable) — «Search…».\nconst resolvedSearchPlaceholder = computed(() =>\n props.allowCustomValue ? resolvedCustomValuePlaceholder.value : resolvedFilterPlaceholder.value,\n)\n\nconst baseClassName = computed(() => props.view === 'link' ? linkBaseClass : defaultBaseClass)\n\nconst rootClass = computed(() => props.view === 'link' ? 'relative inline-block align-baseline' : 'relative w-full')\n\nconst emit = defineEmits<GrSelectEmits<TValue>>()\ndefineSlots<{\n /** Собственные `<option>` для нативного режима. */\n default?: () => any\n /** Аддон слева в панельном триггере (в нативном режиме недоступен). */\n prefix?: () => any\n /** Аддон справа в панельном триггере, перед крестиком и шевроном. */\n suffix?: () => any\n /** Отображение значения в триггере вместо текста по умолчанию. */\n value?: (props: {\n selectedOptions: GrSelectOption<TValue>[]\n selectedValues: TValue[]\n displayLabel: string\n placeholder?: string\n hasSelection: boolean\n }) => any\n /** Строка списка вместо подписи опции. */\n option?: (props: { option: GrSelectOption<TValue>, selected: boolean }) => any\n /** Содержимое панели, пока едут опции. */\n loading?: () => any\n /** Содержимое панели, когда подходящих опций нет. */\n empty?: () => any\n}>()\n\n// Fallback из контекста `GrFormField` (id/aria-describedby/invalid/required)\n// для связки с лейблом и сообщением об ошибке.\nconst field = useGrFormFieldContext()\nconst resolvedId = computed(() => field?.id.value)\nconst {\n disabled: isDisabled,\n invalid: isInvalid,\n required: isRequired,\n readonly: isReadonly,\n} = useGrFormControl(() => props)\n\nconst nativeSelectEl = ref<HTMLSelectElement | null>(null)\nconst triggerButtonEl = ref<HTMLElement | null>(null)\n\n// Виджет зависит от режима: нативный `<select>` или кастомный триггер панели.\nfunction focus(): void {\n (nativeSelectEl.value ?? triggerButtonEl.value)?.focus()\n}\n\nfunction blur(): void {\n (nativeSelectEl.value ?? triggerButtonEl.value)?.blur()\n}\n\ndefineExpose({ focus, blur })\nconst describedBy = computed(() => field?.describedById.value)\n\nconst {\n optionsResolved,\n flatOptions,\n isOptionGroup,\n keyOf,\n sameValue,\n modelSingle,\n selectedValues,\n hasSelection,\n fromDomValue,\n selectedOptions,\n hasModelInOptions,\n displayLabel,\n displayText,\n} = useSelectValues<TValue>({\n modelValue: () => props.modelValue,\n options: () => props.options,\n multiple: () => props.multiple,\n valueKey: () => props.valueKey,\n placeholder: () => props.placeholder,\n})\n\nconst ADDON_MIN_WIDTH_BY_SIZE: Record<GrSelectSize, string> = {\n xs: '2rem',\n sm: '2.25rem',\n md: '2.5rem',\n lg: '3rem',\n}\n\n/**\n * Триггер панельного режима — флекс-строка, поэтому аддоны встают её соседями,\n * а не поверх поля: резервировать место паддингом не нужно.\n */\nconst {\n hasPrefix,\n hasSuffix,\n prefixEl,\n suffixEl,\n prefixLen,\n prefixStyle,\n suffixStyle,\n} = useControlAddons(() => props, {\n defaultMinWidth: () => ADDON_MIN_WIDTH_BY_SIZE[resolvedSize.value],\n paddingX: () => '0px',\n})\n\n// Нативный `<select multiple>` — это многострочный listbox, а не поповер. В режиме\n// `view=\"link\"` он рендерится невидимым overlay'ем, из-за чего multiple-вариант «не\n// открывается» (клик по невидимому listbox'у ничего не показывает). Для этой\n// неподдерживаемой комбинации форсим кастомную панель, которая корректно открывается.\nconst effectiveOptionsView = computed<GrSelectOptionsView>(() => {\n if (props.view === 'link' && props.multiple && props.optionsView === 'native')\n return 'panel'\n // Поиск/загрузка/теги невозможны в нативном `<select>` — форсим кастомную панель.\n if ((props.filterable || props.loading || props.tags) && props.optionsView === 'native')\n return 'panel'\n return props.optionsView\n})\n\n// Поле поиска в панели: показываем при `filterable` ИЛИ `allowCustomValue`.\nconst showSearchInput = computed(() =>\n (props.filterable || props.allowCustomValue) && effectiveOptionsView.value === 'panel',\n)\n\n// Показывать chips вместо строки «a, b, c» (только multiple + tags).\nconst showTags = computed(() => props.multiple && props.tags && effectiveOptionsView.value === 'panel')\n\nconst nativeCustomOptionVisible = computed(() => {\n if (!props.allowCustomValue)\n return false\n if (effectiveOptionsView.value !== 'native')\n return false\n if (props.multiple)\n return false\n if (!props.options)\n return false\n if (modelSingle.value === '')\n return false\n return !hasModelInOptions.value\n})\n\n/**\n * Текст поиска: контролируемый `search` сильнее внутреннего состояния. Каждое\n * изменение уходит наружу — без этого `loading` не с чем было связать.\n */\nconst internalSearch = ref('')\nconst customValue = computed<string>({\n get: () => props.search ?? internalSearch.value,\n set: (next) => {\n internalSearch.value = next\n emit('update:search', next)\n emit('search', next)\n },\n})\n\n// Имя `open` сохранено: все читатели — шаблон, watch, `useDismissible`/\n// `useFloating` — работают с computed-Ref как раньше.\nconst { open, setOpen } = useControlledOpen(\n () => props.open,\n next => emit('update:open', next),\n)\n\nconst rootEl = ref<HTMLElement | null>(null)\nconst panelEl = ref<HTMLElement | null>(null)\nconst listboxEl = ref<HTMLElement | null>(null)\n\n// Панель телепортирована в `body`, то есть лежит вне корня, но для пользователя\n// она часть контрола: без неё уход фокуса в панель читался бы как `blur`.\nconst { onFocusIn, onFocusOut } = useFocusWithin(rootEl, {\n enter: event => emit('focus', event),\n leave: event => emit('blur', event),\n containers: () => [panelEl.value],\n})\nconst customInputRef = ref<InstanceType<typeof GrInput> | null>(null)\nconst clickOutsideExclude = [() => panelEl.value]\n\n// Для `view='link'` ширина триггера = ширине выбранной опции (`inline-block w-auto`),\n// поэтому панель растёт по контенту (`matchWidth: 'min'` → `width: max-content` +\n// `min-width` от триггера), а не сжимается до неё. Для `view='default'` панель точно\n// повторяет ширину триггера (`matchWidth: true`).\nconst { floatingStyle, update: updateFloatingPosition } = useFloating(rootEl, panelEl, open, {\n placement: 'bottom-start',\n matchWidth: () => (props.view === 'link' ? 'min' : true),\n zIndexVar: '--gr-z-dropdown',\n})\n\nfunction closeDropdown(): void {\n setOpen(false)\n}\n\nconst locked = computed(() => isDisabled.value || isReadonly.value)\n\nfunction toggleDropdown(): void {\n if (locked.value)\n return\n setOpen(!open.value)\n}\n\nuseDismissible(open, closeDropdown)\n\n// `view` определяет режим `matchWidth` (см. выше) — пересчитываем позицию/ширину\n// панели, если он меняется, пока панель открыта.\nwatch(\n () => props.view,\n () => {\n if (open.value)\n updateFloatingPosition()\n },\n)\n\nconst panelClasses = computed(() => {\n return grSelectPanelClasses\n})\n\nconst { panelItems, panelRows, canAddCustom } = useSelectPanelItems<TValue>({\n optionsResolved,\n flatOptions,\n isOptionGroup,\n modelSingle,\n selectedValues,\n hasModelInOptions,\n sameValue,\n query: () => customValue.value,\n allowCustomValue: () => props.allowCustomValue,\n filterable: () => props.filterable,\n multiple: () => props.multiple,\n isPanelView: () => effectiveOptionsView.value === 'panel',\n})\n\nfunction emitValue(value: GrSelectModelValue<TValue>): void {\n if (isReadonly.value)\n return\n\n emit('update:modelValue', value)\n emit('change', value)\n}\n\nfunction isSelected(value: TValue): boolean {\n return selectedValues.value.some(selected => sameValue(selected, value))\n}\n\nfunction isOptionDisabled(value: TValue): boolean {\n return flatOptions.value.find(o => sameValue(o.value, value))?.disabled === true\n}\n\nfunction selectValue(value: TValue): void {\n emitValue(value)\n if (props.closeOnSelect) {\n closeDropdown()\n }\n}\n\nfunction toggleValue(value: TValue): void {\n if (isOptionDisabled(value))\n return\n\n if (!props.multiple) {\n selectValue(value)\n return\n }\n\n const next = selectedValues.value.slice()\n const idx = next.findIndex(selected => sameValue(selected, value))\n if (idx >= 0) {\n next.splice(idx, 1)\n }\n else {\n next.push(value)\n }\n\n emitValue(next)\n if (props.closeOnSelect) {\n closeDropdown()\n }\n}\n\nfunction addCustom(): void {\n // Кастомное значение набирается текстом, поэтому оно строковое —\n // при числовом `TValue` эта ветка неприменима (см. docs/components.md).\n const v = customValue.value.trim() as TValue\n if (!v)\n return\n toggleValue(v)\n}\n\n// Удаление одного значения из multiple-выбора (клик по «×» на chip).\nfunction removeValue(value: TValue): void {\n if (locked.value)\n return\n if (!props.multiple)\n return\n // Кнопка чипа держит объект из `options`, модель — свою копию: сравнение\n // только через ключ, `!==` не удалил бы ничего.\n emitValue(selectedValues.value.filter(v => !sameValue(v, value)))\n}\n\nconst visibleTagOptions = computed(() => {\n const limit = props.maxTagCount\n if (limit === undefined || limit < 0)\n return selectedOptions.value\n return selectedOptions.value.slice(0, limit)\n})\n\n/**\n * Проп `tagSize` объявлен по шкале бейджа и остаётся публичным контрактом:\n * ступени чипа сдвинуты, и перевод держит кегль тем же.\n */\nconst chipSize = computed(() => chipSizeForBadgeScale(props.tagSize))\n\nconst hiddenTagCount = computed(() => selectedOptions.value.length - visibleTagOptions.value.length)\n\nfunction tagRemoveLabel(option: GrSelectOption<TValue>): string {\n return t('gr.select.removeTag', 'Remove {label}', { label: option.label })\n}\n\n// ————— Клавиатурная навигация комбобокса (WAI-ARIA, aria-activedescendant).\nconst listboxId = useId()\n\n/**\n * Id опции строится от позиции в списке: значение с пробелом дало бы невалидный\n * `id`, а `aria-activedescendant` — два токена вместо одной ссылки.\n */\nfunction optionDomId(index: number): string {\n return `${listboxId}-opt-${index}`\n}\n\n/** Заголовок группы читается вместе с опцией — через `aria-describedby`. */\nfunction groupLabelId(groupKey: string): string {\n return `${listboxId}-${groupKey}`\n}\n\nconst {\n virtualEnabled,\n addOffset,\n scrollToIndex: scrollVirtualToIndex,\n measure: measureVirtualRow,\n optionSetProps,\n addOptionSetProps,\n showAddOption,\n renderedPanelRows,\n listboxStyle,\n} = useSelectVirtualization<TValue>({\n panelItems,\n panelRows,\n canAddCustom,\n listboxEl,\n enabled: () => props.virtual && effectiveOptionsView.value === 'panel',\n maxHeight: () => props.dropdownMaxHeight,\n})\n\nif (__GR_DEV__) {\n const slots = useSlots()\n\n watch(\n () => [Boolean(slots.prefix || slots.suffix), effectiveOptionsView.value] as const,\n ([hasAddon, view]) => {\n if (hasAddon && view !== 'panel') {\n console.warn(\n '[granularity] GrSelect: слоты `prefix`/`suffix` работают только с '\n + '`optionsView=\"panel\"` — внутрь нативного `<select>` разметку положить нельзя.',\n )\n }\n },\n { immediate: true },\n )\n\n watch(\n () => [props.virtual, effectiveOptionsView.value, props.view] as const,\n ([virtual, view, appearance]) => {\n if (!virtual)\n return\n\n if (view !== 'panel') {\n console.warn(\n '[granularity] GrSelect: `virtual` работает только с `optionsView=\"panel\"` — '\n + 'у нативного `<select>` своей панели нет, и виртуализировать нечего.',\n )\n }\n else if (appearance === 'link') {\n console.warn(\n '[granularity] GrSelect: `virtual` не сочетается с `view=\"link\"` — ширина панели '\n + 'там равна ширине отрисованной опции и будет прыгать при прокрутке.',\n )\n }\n },\n { immediate: true },\n )\n}\n\n/** При `loading` списка в DOM нет — ссылаться на него нельзя. */\nconst listboxIdIfRendered = computed(() => (open.value && !props.loading ? listboxId : undefined))\n\nfunction openDropdown(): void {\n if (locked.value || open.value)\n return\n setOpen(true)\n}\n\nconst {\n activeIndex,\n activeItem,\n activeValue,\n addOptionDomId,\n triggerActiveDescendant,\n searchActiveDescendant,\n onOptionHover,\n onComboKeydown,\n initActiveIndex,\n resetActive,\n} = useSelectNavigation<TValue>({\n panelItems,\n flatOptions,\n canAddCustom,\n sameValue,\n isSelected,\n open,\n locked,\n showSearchInput,\n virtualEnabled,\n addOffset,\n listboxId,\n optionDomId,\n scrollVirtualToIndex,\n openDropdown,\n closeDropdown,\n addCustom,\n toggleValue,\n})\n\nwatch(\n open,\n async (isOpen, wasOpen) => {\n if (!isOpen) {\n internalSearch.value = ''\n resetActive()\n\n // Панель с полем поиска забирает фокус себе; на закрытии поле исчезает, и\n // без возврата фокус уезжает на `<body>` — клавиатурный пользователь\n // оказывается в начале документа. Возвращаем только если фокус ещё внутри\n // панели: пользователь мог уйти дальше сам.\n //\n // `wasOpen` отсекает первый вызов (`immediate: true`): на сервере DOM нет,\n // да и красть фокус при монтировании компонент не должен.\n if (wasOpen) {\n const active = document.activeElement\n if (active instanceof HTMLElement && panelEl.value?.contains(active))\n focus()\n }\n\n return\n }\n\n initActiveIndex()\n\n if (showSearchInput.value) {\n await nextTick()\n customInputRef.value?.focus()\n }\n },\n { immediate: true },\n)\n\nconst showNativeChevron = computed(() => {\n return effectiveOptionsView.value === 'native' && props.view !== 'link' && !props.multiple\n})\n\nconst nativeClearOptionVisible = computed(() => {\n if (!resolvedClearable.value)\n return false\n if (effectiveOptionsView.value !== 'native')\n return false\n if (props.multiple)\n return false\n if (!props.options)\n return true\n return !flatOptions.value.some(o => isEmptySelectValue(o.value))\n})\n\nconst panelClearVisible = computed(() => {\n if (!resolvedClearable.value)\n return false\n if (effectiveOptionsView.value !== 'panel')\n return false\n if (props.view === 'link')\n return false\n return hasSelection.value\n})\n\nconst nativeClassName = computed(() => {\n return grSelectNativeClass({\n view: props.view,\n size: resolvedSize.value,\n disabled: isDisabled.value,\n variant: resolvedVariant.value,\n underline: resolvedUnderline.value,\n showNativeChevron: showNativeChevron.value,\n state: props.state,\n invalid: isInvalid.value,\n })\n})\n\n/**\n * `view=\"link\"` в native-режиме: ширина обёртки должна определяться выбранной опцией,\n * а не самой длинной (как делает браузер по умолчанию). Поэтому рендерим прозрачный\n * `<select>`-overlay поверх видимого `<span>` с меткой — overlay принимает клики/клавиатуру,\n * span задаёт ширину компонента в закрытом состоянии.\n */\nconst isLinkNative = computed(() => props.view === 'link' && effectiveOptionsView.value === 'native')\n\nconst linkNativeLabelClassName = computed(() => grSelectLinkNativeLabelClass({\n size: resolvedSize.value,\n variant: resolvedVariant.value,\n underline: resolvedUnderline.value,\n disabled: isDisabled.value,\n}))\n\nconst linkNativeDisplayText = computed(() => {\n return displayText.value || props.placeholder || '\\u00A0'\n})\n\nconst triggerClassName = computed(() => {\n return grSelectTriggerClass({\n view: props.view,\n optionsView: effectiveOptionsView.value,\n size: resolvedSize.value,\n disabled: isDisabled.value,\n variant: resolvedVariant.value,\n underline: resolvedUnderline.value,\n state: props.state,\n invalid: isInvalid.value,\n })\n})\n\nfunction onChange(e: Event): void {\n const el = e.target as HTMLSelectElement\n\n // Нативного `readonly` у `<select>` нет: браузер уже переключил значение —\n // возвращаем DOM к модели, иначе форма отправит непринятое (приём GrCheckbox).\n if (isReadonly.value) {\n if (props.multiple) {\n for (const option of el.options) option.selected = isSelected(fromDomValue(option.value))\n }\n else {\n el.value = modelSingle.value === '' ? '' : keyOf(modelSingle.value)\n }\n return\n }\n\n // Только через `emitValue`: он единственный источник пары\n // `update:modelValue` + `change`, и канал события обязан быть один на оба\n // режима отрисовки. Прямой `emit` отсюда оставил бы `change` без нативного\n // пути — молча, потому что объявленный emit уходит из `$attrs`.\n emitValue(\n props.multiple\n ? Array.from(el.selectedOptions, o => fromDomValue(o.value))\n // Пустая строка — это «очистить», а не значение: восстанавливать её не нужно.\n : ((el.value === '' ? '' : fromDomValue(el.value)) as TValue),\n )\n}\n\nfunction clearSelection(): void {\n if (locked.value)\n return\n emitValue((props.multiple ? [] : '') as GrSelectModelValue<TValue>)\n emit('clear')\n}\n\n// Телепорт включается только ПОСЛЕ монтирования: иначе первый клиентский\n// рендер не совпадает с серверным и ломается гидрация (см. композабл).\nconst { target: portalTarget, enabled: teleportEnabled } = usePortalTarget()\n\n// Тема поддерева на телепортированную панель: в DOM она уезжает в `body`, то\n// есть вне обёртки провайдера, и `data-theme` с неё не наследуется. В дереве\n// компонентов панель остаётся внутри — `inject` доходит, и тему она ставит себе\n// сама.\nconst themeAttrs = useGrThemeAttrs()\n</script>\n\n<template>\n <div\n v-if=\"effectiveOptionsView === 'native'\"\n data-gr-select\n :class=\"rootClass\"\n @focusin=\"onFocusIn\"\n @focusout=\"onFocusOut\"\n >\n <!--\n Выбор задаём per-option через `:selected` (а не `:value` на `<select>`):\n для `<select multiple>` биндинг `:value` массивом не работает — DOM не\n отражает программное изменение модели. `onChange` читает выбор из DOM.\n -->\n <select\n :id=\"resolvedId\"\n ref=\"nativeSelectEl\"\n data-gr-select-native\n :name=\"name\"\n :multiple=\"multiple\"\n :disabled=\"isDisabled\"\n :aria-label=\"ariaLabel\"\n :aria-invalid=\"isInvalid ? 'true' : undefined\"\n :aria-describedby=\"describedBy\"\n :aria-required=\"isRequired ? 'true' : undefined\"\n :aria-readonly=\"isReadonly ? 'true' : undefined\"\n :class=\"isLinkNative ? grSelectLinkNativeOverlayClass : [baseClassName, nativeClassName]\"\n @change=\"onChange\"\n >\n <option v-if=\"nativeClearOptionVisible\" value=\"\" :selected=\"!multiple && modelSingle === ''\">\n {{ placeholder || t('gr.select.clearOption', 'None') }}\n </option>\n\n <slot>\n <option v-if=\"nativeCustomOptionVisible\" :value=\"keyOf(modelSingle)\" :selected=\"!multiple\">\n {{ modelSingle }}\n </option>\n <template v-for=\"(item, index) in optionsResolved\" :key=\"index\">\n <optgroup v-if=\"isOptionGroup(item)\" :label=\"item.label\">\n <option\n v-for=\"opt in item.options\"\n :key=\"`${index}:${keyOf(opt.value)}`\"\n :value=\"keyOf(opt.value)\"\n :selected=\"isSelected(opt.value)\"\n :disabled=\"opt.disabled\"\n >\n {{ opt.label }}\n </option>\n </optgroup>\n <option\n v-else\n :value=\"keyOf(item.value)\"\n :selected=\"isSelected(item.value)\"\n :disabled=\"item.disabled\"\n >\n {{ item.label }}\n </option>\n </template>\n </slot>\n </select>\n\n <span\n v-if=\"isLinkNative\"\n data-gr-select-link-label\n aria-hidden=\"true\"\n :class=\"linkNativeLabelClassName\"\n >{{ linkNativeDisplayText }}</span>\n\n <span\n v-if=\"showNativeChevron\"\n data-testid=\"gr-select-chevron\"\n class=\"absolute top-1/2 -translate-y-1/2 right-3 flex items-center text-[var(--gr-muted-fg)] pointer-events-none\"\n >\n <IconChevronDown class=\"block h-4 w-4\" aria-hidden=\"true\" />\n </span>\n </div>\n\n <div\n v-else\n ref=\"rootEl\"\n v-click-outside=\"{ handler: closeDropdown, enabled: open, exclude: clickOutsideExclude }\"\n data-gr-select\n :class=\"rootClass\"\n >\n <!-- Нативная форма: панельный режим сериализуется hidden-инпутами по keyOf. -->\n <template v-if=\"name\">\n <input\n v-for=\"value in selectedValues\"\n :key=\"`hidden-${keyOf(value)}`\"\n type=\"hidden\"\n :name=\"name\"\n :value=\"keyOf(value)\"\n >\n </template>\n <button\n :id=\"resolvedId\"\n ref=\"triggerButtonEl\"\n data-testid=\"gr-select-trigger\"\n data-gr-select-trigger\n type=\"button\"\n :disabled=\"isDisabled\"\n :aria-label=\"ariaLabel\"\n :aria-invalid=\"isInvalid ? 'true' : undefined\"\n :aria-describedby=\"describedBy\"\n :aria-required=\"isRequired ? 'true' : undefined\"\n :aria-readonly=\"isReadonly ? 'true' : undefined\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n :aria-controls=\"listboxIdIfRendered\"\n :aria-activedescendant=\"triggerActiveDescendant\"\n :aria-expanded=\"open ? 'true' : 'false'\"\n :aria-busy=\"loading ? 'true' : undefined\"\n :class=\"[baseClassName, triggerClassName]\"\n @click=\"toggleDropdown\"\n @keydown=\"onComboKeydown\"\n >\n <span\n v-if=\"hasPrefix\"\n ref=\"prefixEl\"\n data-gr-select-prefix\n class=\"shrink-0 inline-flex items-center justify-center text-[var(--gr-muted-fg)] select-none truncate\"\n :style=\"prefixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"prefix\" />\n </span>\n\n <span class=\"min-w-0 flex-1\">\n <slot\n name=\"value\"\n :selected-options=\"selectedOptions\"\n :selected-values=\"selectedValues\"\n :display-label=\"displayLabel\"\n :placeholder=\"placeholder\"\n :has-selection=\"hasSelection\"\n >\n <span\n class=\"block truncate\"\n :class=\"!hasSelection ? 'text-[var(--gr-muted-fg)]' : ''\"\n >\n {{ showTags && hasSelection ? '' : displayText }}\n </span>\n </slot>\n </span>\n\n <span\n v-if=\"hasSuffix\"\n ref=\"suffixEl\"\n data-gr-select-suffix\n class=\"shrink-0 inline-flex items-center justify-center text-[var(--gr-muted-fg)] select-none truncate\"\n :style=\"suffixStyle\"\n aria-hidden=\"true\"\n >\n <slot name=\"suffix\" />\n </span>\n\n <!-- Место под кнопку очистки: она лежит абсолютом поверх триггера. -->\n <span\n v-if=\"panelClearVisible\"\n class=\"shrink-0 h-4 w-6\"\n aria-hidden=\"true\"\n />\n\n <!-- Шеврон виден всегда: без него поле с выбранным значением переставало\n выглядеть выпадающим списком. -->\n <span\n data-testid=\"gr-select-chevron\"\n class=\"shrink-0 flex items-center text-[var(--gr-muted-fg)] pointer-events-none\"\n >\n <IconChevronDown class=\"block h-4 w-4\" aria-hidden=\"true\" />\n </span>\n </button>\n\n <!--\n Чипы живут РЯДОМ с кнопкой-комбобоксом, а не внутри неё: `role=\"combobox\"`\n объявляет потомков презентационными, и крестик внутри был недостижим с\n клавиатуры (axe: `nested-interactive`).\n -->\n <div\n v-if=\"showTags && hasSelection\"\n data-gr-select-tags\n class=\"pointer-events-none absolute inset-y-0 left-0 flex max-w-[calc(100%-4rem)] flex-wrap items-center gap-1 px-3 py-1.5\"\n :style=\"{ left: hasPrefix ? prefixLen : undefined }\"\n >\n <GrChip\n v-for=\"opt in visibleTagOptions\"\n :key=\"keyOf(opt.value)\"\n data-gr-select-tag\n class=\"pointer-events-auto\"\n :tone=\"opt.tone ?? tagTone\"\n :dark=\"opt.dark ?? tagDark\"\n :size=\"chipSize\"\n :radius=\"tagRadius\"\n :closable=\"!isDisabled && !isReadonly\"\n :remove-label=\"tagRemoveLabel(opt)\"\n @remove=\"removeValue(opt.value)\"\n >\n <span class=\"truncate\">{{ opt.label }}</span>\n </GrChip>\n\n <GrChip\n v-if=\"hiddenTagCount > 0\"\n data-gr-select-tag-rest\n class=\"pointer-events-auto\"\n :tone=\"tagTone\"\n :dark=\"tagDark\"\n :size=\"chipSize\"\n :radius=\"tagRadius\"\n >\n +{{ hiddenTagCount }}\n </GrChip>\n </div>\n\n <button\n v-if=\"panelClearVisible\"\n data-testid=\"gr-select-clear\"\n data-gr-select-clear\n type=\"button\"\n class=\"absolute top-1/2 right-8 h-6 w-6 -translate-y-1/2 inline-flex items-center justify-center rounded-[var(--gr-radius-md)] text-[var(--gr-muted-fg)] hover:bg-[color-mix(in_srgb,var(--gr-muted)_25%,transparent)] hover:text-[var(--gr-fg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--gr-ring)]\"\n :disabled=\"isDisabled\"\n :aria-label=\"resolvedClearLabel\"\n @click.stop=\"clearSelection\"\n >\n <IconX class=\"inline-block h-4 w-4\" aria-hidden=\"true\" />\n </button>\n\n <teleport :to=\"portalTarget\" :disabled=\"!teleportEnabled\">\n <transition\n :enter-active-class=\"panelPopTransition.enter\"\n :enter-from-class=\"panelPopTransition.enterFrom\"\n :enter-to-class=\"panelPopTransition.enterTo\"\n :leave-active-class=\"panelPopTransition.leave\"\n :leave-from-class=\"panelPopTransition.leaveFrom\"\n :leave-to-class=\"panelPopTransition.leaveTo\"\n >\n <div\n v-show=\"open\"\n ref=\"panelEl\"\n data-testid=\"gr-select-panel\"\n v-bind=\"themeAttrs\"\n data-gr-select-panel\n data-gr-overlay-root\n :style=\"floatingStyle\"\n >\n <div :class=\"panelClasses\">\n <div v-if=\"showSearchInput\" class=\"p-2 border-b border-[var(--gr-brd)]\">\n <GrInput\n ref=\"customInputRef\"\n v-model=\"customValue\"\n data-testid=\"gr-select-custom-input\"\n data-gr-select-search\n type=\"text\"\n role=\"combobox\"\n aria-haspopup=\"listbox\"\n :aria-expanded=\"open ? 'true' : 'false'\"\n :aria-controls=\"listboxIdIfRendered\"\n :aria-activedescendant=\"searchActiveDescendant\"\n :placeholder=\"resolvedSearchPlaceholder\"\n :loading=\"loading\"\n size=\"sm\"\n @keydown=\"onComboKeydown\"\n />\n </div>\n\n <!-- Состояние загрузки: вместо списка — индикатор. -->\n <div\n v-if=\"loading\"\n data-gr-select-loading\n class=\"flex items-center justify-center gap-2 px-3 py-4 text-[length:var(--gr-text-sm)] leading-[var(--gr-leading-sm)] text-[var(--gr-muted-fg)]\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <slot name=\"loading\">\n <IconLoaderCircle class=\"block h-4 w-4 animate-spin\" aria-hidden=\"true\" />\n <span>{{ resolvedLoadingText }}</span>\n </slot>\n </div>\n\n <div\n v-else\n :id=\"listboxId\"\n ref=\"listboxEl\"\n data-gr-select-listbox\n :data-gr-virtual=\"virtualEnabled ? '' : undefined\"\n class=\"p-1 overflow-auto\"\n :class=\"virtualEnabled ? 'flex flex-col' : ''\"\n :style=\"listboxStyle\"\n role=\"listbox\"\n :aria-multiselectable=\"multiple ? 'true' : undefined\"\n >\n <!--\n Прямые потомки listbox — только опции и группы: роль объявляет\n остальных недопустимыми детьми (`aria-required-children`).\n `mousedown.prevent` держит фокус на триггере или в поле поиска —\n контракт combobox с `aria-activedescendant`.\n -->\n <button\n v-if=\"showAddOption\"\n :id=\"addOptionDomId\"\n data-testid=\"gr-select-add-option\"\n data-gr-select-add-option\n type=\"button\"\n role=\"option\"\n aria-selected=\"false\"\n tabindex=\"-1\"\n v-bind=\"addOptionSetProps\"\n :class=\"grSelectOptionClass({ view, disabled: false, active: activeItem?.kind === 'add' })\"\n @mousedown.prevent\n @click=\"addCustom\"\n @mousemove=\"activeIndex = 0\"\n >\n {{ t('gr.select.addOption', 'Add \"{value}\"', { value: customValue.trim() }) }}\n </button>\n\n <template v-for=\"row in renderedPanelRows\" :key=\"row.key\">\n <!--\n Группа: заголовок внутри неё и даёт ей имя. При виртуализации\n окно может начаться ниже заголовка — тогда его в DOM нет, и\n имя группы идёт напрямую в `aria-label`.\n -->\n <div\n v-if=\"row.kind === 'group'\"\n data-gr-select-group\n role=\"group\"\n :class=\"virtualEnabled ? 'flex flex-col' : ''\"\n :aria-labelledby=\"virtualEnabled ? undefined : groupLabelId(row.key)\"\n :aria-label=\"virtualEnabled ? row.label : undefined\"\n >\n <div\n v-if=\"row.labelVisible !== false\"\n :id=\"groupLabelId(row.key)\"\n :ref=\"(el) => virtualEnabled && row.labelIndex !== undefined && measureVirtualRow(row.labelIndex + addOffset, el as Element | null)\"\n data-gr-select-group-label\n role=\"presentation\"\n class=\"px-3 pt-2 pb-1 text-[length:var(--gr-text-xs)] leading-[var(--gr-leading-xs)] font-semibold uppercase tracking-wide text-[var(--gr-muted-fg)]\" :class=\"[\n view === 'link' ? 'block min-w-full w-max whitespace-nowrap' : '',\n ]\"\n >\n {{ row.label }}\n </div>\n\n <button\n v-for=\"child in row.options\"\n :id=\"optionDomId(child.index)\"\n :key=\"child.key\"\n :ref=\"(el) => virtualEnabled && measureVirtualRow(child.index + addOffset, el as Element | null)\"\n data-gr-select-option\n type=\"button\"\n role=\"option\"\n tabindex=\"-1\"\n v-bind=\"optionSetProps(child.index)\"\n :disabled=\"child.option.disabled\"\n :aria-selected=\"isSelected(child.option.value) ? 'true' : 'false'\"\n :aria-disabled=\"child.option.disabled ? 'true' : undefined\"\n :class=\"grSelectOptionClass({\n view,\n disabled: !!child.option.disabled,\n active: activeValue === child.option.value,\n })\"\n @mousedown.prevent\n @click=\"toggleValue(child.option.value)\"\n @mousemove=\"onOptionHover(child.index)\"\n >\n <slot name=\"option\" :option=\"child.option\" :selected=\"isSelected(child.option.value)\">\n <span class=\"flex items-center gap-2 min-w-0\">\n <span class=\"inline-block h-4 w-4 shrink-0\" aria-hidden=\"true\">\n <IconCheck\n v-if=\"isSelected(child.option.value)\"\n class=\"block h-4 w-4 text-[var(--gr-primary-text)]\"\n />\n </span>\n <span class=\"truncate\">{{ child.option.label }}</span>\n </span>\n </slot>\n </button>\n </div>\n\n <button\n v-else\n :id=\"optionDomId(row.index)\"\n :ref=\"(el) => virtualEnabled && measureVirtualRow(row.index + addOffset, el as Element | null)\"\n data-gr-select-option\n type=\"button\"\n role=\"option\"\n tabindex=\"-1\"\n v-bind=\"optionSetProps(row.index)\"\n :disabled=\"row.option.disabled\"\n :aria-selected=\"isSelected(row.option.value) ? 'true' : 'false'\"\n :aria-disabled=\"row.option.disabled ? 'true' : undefined\"\n :class=\"grSelectOptionClass({\n view,\n disabled: !!row.option.disabled,\n active: activeValue === row.option.value,\n })\"\n @mousedown.prevent\n @click=\"toggleValue(row.option.value)\"\n @mousemove=\"onOptionHover(row.index)\"\n >\n <slot name=\"option\" :option=\"row.option\" :selected=\"isSelected(row.option.value)\">\n <span class=\"flex items-center gap-2 min-w-0\">\n <span class=\"inline-block h-4 w-4 shrink-0\" aria-hidden=\"true\">\n <IconCheck\n v-if=\"isSelected(row.option.value)\"\n class=\"block h-4 w-4 text-[var(--gr-primary-text)]\"\n />\n </span>\n <span class=\"truncate\">{{ row.option.label }}</span>\n </span>\n </slot>\n </button>\n </template>\n </div>\n\n <!--\n Пустой результат живёт вне listbox — и объявляется, а не молчит:\n `aria-label` на generic-элементе диктор игнорирует.\n -->\n <div\n v-if=\"!loading && !panelItems.length && !canAddCustom\"\n data-gr-select-empty\n class=\"px-3 py-4 text-center text-[length:var(--gr-text-sm)] leading-[var(--gr-leading-sm)] text-[var(--gr-muted-fg)]\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <slot name=\"empty\">\n {{ resolvedNoResultsText }}\n </slot>\n </div>\n </div>\n </div>\n </transition>\n </teleport>\n </div>\n</template>\n\n<style scoped>\n/*\n * Распорки виртуальной панели.\n *\n * Не `padding` контейнера: `max-height` меряет ту же коробку. Не обёртка внутри\n * listbox'а: прямыми потомками роли обязаны быть только опции и группы. Не\n * отступы крайних строк: при прыжке прокрутки строки заменяются целиком, и\n * распорка исчезла бы вместе с ними.\n *\n * Псевдоэлементы не узлы DOM: размонтировать нечего, детьми роли не считаются,\n * а высота приезжает переменными в том же патче, что и строки.\n */\n[data-gr-virtual]::before,\n[data-gr-virtual]::after {\n content: '';\n display: block;\n flex: none;\n}\n\n[data-gr-virtual]::before {\n height: var(--gr-virtual-before, 0px);\n}\n\n[data-gr-virtual]::after {\n height: var(--gr-virtual-after, 0px);\n}\n</style>\n"],"mappings":"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"}