@treeui/vue 0.8.0 → 0.10.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 (545) hide show
  1. package/README.md +1 -1
  2. package/dist/components/TAccordion.cjs +2 -0
  3. package/dist/components/TAccordion.cjs.map +1 -0
  4. package/dist/components/TAccordion.js +7 -0
  5. package/dist/components/TAccordion.js.map +1 -0
  6. package/dist/components/TAccordion.vue_vue_type_script_setup_true_lang.cjs +2 -0
  7. package/dist/components/TAccordion.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  8. package/dist/components/TAccordion.vue_vue_type_script_setup_true_lang.js +97 -0
  9. package/dist/components/TAccordion.vue_vue_type_script_setup_true_lang.js.map +1 -0
  10. package/dist/components/TAccordionItem.cjs +2 -0
  11. package/dist/components/TAccordionItem.cjs.map +1 -0
  12. package/dist/components/TAccordionItem.js +7 -0
  13. package/dist/components/TAccordionItem.js.map +1 -0
  14. package/dist/components/TAccordionItem.vue_vue_type_script_setup_true_lang.cjs +2 -0
  15. package/dist/components/TAccordionItem.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  16. package/dist/components/TAccordionItem.vue_vue_type_script_setup_true_lang.js +83 -0
  17. package/dist/components/TAccordionItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
  18. package/dist/components/TAlert.cjs +2 -0
  19. package/dist/components/TAlert.cjs.map +1 -0
  20. package/dist/components/TAlert.js +7 -0
  21. package/dist/components/TAlert.js.map +1 -0
  22. package/dist/components/TAlert.vue_vue_type_script_setup_true_lang.cjs +2 -0
  23. package/dist/components/TAlert.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  24. package/dist/components/TAlert.vue_vue_type_script_setup_true_lang.js +57 -0
  25. package/dist/components/TAlert.vue_vue_type_script_setup_true_lang.js.map +1 -0
  26. package/dist/components/TAvatar.cjs +2 -0
  27. package/dist/components/TAvatar.cjs.map +1 -0
  28. package/dist/components/TAvatar.js +7 -0
  29. package/dist/components/TAvatar.js.map +1 -0
  30. package/dist/components/TAvatar.vue_vue_type_script_setup_true_lang.cjs +2 -0
  31. package/dist/components/TAvatar.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  32. package/dist/components/TAvatar.vue_vue_type_script_setup_true_lang.js +46 -0
  33. package/dist/components/TAvatar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  34. package/dist/components/TBadge.cjs +2 -0
  35. package/dist/components/TBadge.cjs.map +1 -0
  36. package/dist/components/TBadge.js +7 -0
  37. package/dist/components/TBadge.js.map +1 -0
  38. package/dist/components/TBadge.vue_vue_type_script_setup_true_lang.cjs +2 -0
  39. package/dist/components/TBadge.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  40. package/dist/components/TBadge.vue_vue_type_script_setup_true_lang.js +27 -0
  41. package/dist/components/TBadge.vue_vue_type_script_setup_true_lang.js.map +1 -0
  42. package/dist/components/TBreadcrumb.cjs +2 -0
  43. package/dist/components/TBreadcrumb.cjs.map +1 -0
  44. package/dist/components/TBreadcrumb.js +7 -0
  45. package/dist/components/TBreadcrumb.js.map +1 -0
  46. package/dist/components/TBreadcrumb.vue_vue_type_script_setup_true_lang.cjs +2 -0
  47. package/dist/components/TBreadcrumb.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  48. package/dist/components/TBreadcrumb.vue_vue_type_script_setup_true_lang.js +20 -0
  49. package/dist/components/TBreadcrumb.vue_vue_type_script_setup_true_lang.js.map +1 -0
  50. package/dist/components/TBreadcrumbItem.cjs +2 -0
  51. package/dist/components/TBreadcrumbItem.cjs.map +1 -0
  52. package/dist/components/TBreadcrumbItem.js +7 -0
  53. package/dist/components/TBreadcrumbItem.js.map +1 -0
  54. package/dist/components/TBreadcrumbItem.vue_vue_type_script_setup_true_lang.cjs +2 -0
  55. package/dist/components/TBreadcrumbItem.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  56. package/dist/components/TBreadcrumbItem.vue_vue_type_script_setup_true_lang.js +28 -0
  57. package/dist/components/TBreadcrumbItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
  58. package/dist/components/TButton.cjs +2 -0
  59. package/dist/components/TButton.cjs.map +1 -0
  60. package/dist/components/TButton.js +7 -0
  61. package/dist/components/TButton.js.map +1 -0
  62. package/dist/components/TButton.vue_vue_type_script_setup_true_lang.cjs +2 -0
  63. package/dist/components/TButton.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  64. package/dist/components/TButton.vue_vue_type_script_setup_true_lang.js +91 -0
  65. package/dist/components/TButton.vue_vue_type_script_setup_true_lang.js.map +1 -0
  66. package/dist/components/TCard.cjs +2 -0
  67. package/dist/components/TCard.cjs.map +1 -0
  68. package/dist/components/TCard.js +7 -0
  69. package/dist/components/TCard.js.map +1 -0
  70. package/dist/components/TCard.vue_vue_type_script_setup_true_lang.cjs +2 -0
  71. package/dist/components/TCard.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  72. package/dist/components/TCard.vue_vue_type_script_setup_true_lang.js +42 -0
  73. package/dist/components/TCard.vue_vue_type_script_setup_true_lang.js.map +1 -0
  74. package/dist/components/TCheckbox.cjs +2 -0
  75. package/dist/components/TCheckbox.cjs.map +1 -0
  76. package/dist/components/TCheckbox.js +7 -0
  77. package/dist/components/TCheckbox.js.map +1 -0
  78. package/dist/components/TCheckbox.vue_vue_type_script_setup_true_lang.cjs +2 -0
  79. package/dist/components/TCheckbox.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  80. package/dist/components/TCheckbox.vue_vue_type_script_setup_true_lang.js +106 -0
  81. package/dist/components/TCheckbox.vue_vue_type_script_setup_true_lang.js.map +1 -0
  82. package/dist/components/TCombobox.cjs +2 -0
  83. package/dist/components/TCombobox.cjs.map +1 -0
  84. package/dist/components/TCombobox.js +7 -0
  85. package/dist/components/TCombobox.js.map +1 -0
  86. package/dist/components/TCombobox.vue_vue_type_script_setup_true_lang.cjs +2 -0
  87. package/dist/components/TCombobox.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  88. package/dist/components/TCombobox.vue_vue_type_script_setup_true_lang.js +282 -0
  89. package/dist/components/TCombobox.vue_vue_type_script_setup_true_lang.js.map +1 -0
  90. package/dist/components/TConfirmDialog.cjs +2 -0
  91. package/dist/components/TConfirmDialog.cjs.map +1 -0
  92. package/dist/components/TConfirmDialog.js +7 -0
  93. package/dist/components/TConfirmDialog.js.map +1 -0
  94. package/dist/components/TConfirmDialog.vue_vue_type_script_setup_true_lang.cjs +2 -0
  95. package/dist/components/TConfirmDialog.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  96. package/dist/components/TConfirmDialog.vue_vue_type_script_setup_true_lang.js +145 -0
  97. package/dist/components/TConfirmDialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
  98. package/dist/components/TContainer.cjs +2 -0
  99. package/dist/components/TContainer.cjs.map +1 -0
  100. package/dist/components/TContainer.js +7 -0
  101. package/dist/components/TContainer.js.map +1 -0
  102. package/dist/components/TContainer.vue_vue_type_script_setup_true_lang.cjs +2 -0
  103. package/dist/components/TContainer.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  104. package/dist/components/TContainer.vue_vue_type_script_setup_true_lang.js +43 -0
  105. package/dist/components/TContainer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  106. package/dist/components/TContextMenu.cjs +2 -0
  107. package/dist/components/TContextMenu.cjs.map +1 -0
  108. package/dist/components/TContextMenu.js +7 -0
  109. package/dist/components/TContextMenu.js.map +1 -0
  110. package/dist/components/TContextMenu.vue_vue_type_script_setup_true_lang.cjs +2 -0
  111. package/dist/components/TContextMenu.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  112. package/dist/components/TContextMenu.vue_vue_type_script_setup_true_lang.js +149 -0
  113. package/dist/components/TContextMenu.vue_vue_type_script_setup_true_lang.js.map +1 -0
  114. package/dist/components/TDatePicker.cjs +2 -0
  115. package/dist/components/TDatePicker.cjs.map +1 -0
  116. package/dist/components/TDatePicker.js +7 -0
  117. package/dist/components/TDatePicker.js.map +1 -0
  118. package/dist/components/TDatePicker.vue_vue_type_script_setup_true_lang.cjs +2 -0
  119. package/dist/components/TDatePicker.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  120. package/dist/components/TDatePicker.vue_vue_type_script_setup_true_lang.js +305 -0
  121. package/dist/components/TDatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  122. package/dist/components/TDateTimePicker.cjs +2 -0
  123. package/dist/components/TDateTimePicker.cjs.map +1 -0
  124. package/dist/components/TDateTimePicker.js +7 -0
  125. package/dist/components/TDateTimePicker.js.map +1 -0
  126. package/dist/components/TDateTimePicker.vue_vue_type_script_setup_true_lang.cjs +2 -0
  127. package/dist/components/TDateTimePicker.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  128. package/dist/components/TDateTimePicker.vue_vue_type_script_setup_true_lang.js +409 -0
  129. package/dist/components/TDateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  130. package/dist/components/TDivider.cjs +2 -0
  131. package/dist/components/TDivider.cjs.map +1 -0
  132. package/dist/components/TDivider.js +7 -0
  133. package/dist/components/TDivider.js.map +1 -0
  134. package/dist/components/TDivider.vue_vue_type_script_setup_true_lang.cjs +2 -0
  135. package/dist/components/TDivider.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  136. package/dist/components/TDivider.vue_vue_type_script_setup_true_lang.js +30 -0
  137. package/dist/components/TDivider.vue_vue_type_script_setup_true_lang.js.map +1 -0
  138. package/dist/components/TDrawer.cjs +2 -0
  139. package/dist/components/TDrawer.cjs.map +1 -0
  140. package/dist/components/TDrawer.js +7 -0
  141. package/dist/components/TDrawer.js.map +1 -0
  142. package/dist/components/TDrawer.vue_vue_type_script_setup_true_lang.cjs +2 -0
  143. package/dist/components/TDrawer.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  144. package/dist/components/TDrawer.vue_vue_type_script_setup_true_lang.js +168 -0
  145. package/dist/components/TDrawer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  146. package/dist/components/TDropdown.cjs +2 -0
  147. package/dist/components/TDropdown.cjs.map +1 -0
  148. package/dist/components/TDropdown.js +7 -0
  149. package/dist/components/TDropdown.js.map +1 -0
  150. package/dist/components/TDropdown.vue.d.ts +3 -0
  151. package/dist/components/TDropdown.vue.d.ts.map +1 -1
  152. package/dist/components/TDropdown.vue_vue_type_script_setup_true_lang.cjs +2 -0
  153. package/dist/components/TDropdown.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  154. package/dist/components/TDropdown.vue_vue_type_script_setup_true_lang.js +176 -0
  155. package/dist/components/TDropdown.vue_vue_type_script_setup_true_lang.js.map +1 -0
  156. package/dist/components/TEmptyState.cjs +2 -0
  157. package/dist/components/TEmptyState.cjs.map +1 -0
  158. package/dist/components/TEmptyState.js +7 -0
  159. package/dist/components/TEmptyState.js.map +1 -0
  160. package/dist/components/TEmptyState.vue_vue_type_script_setup_true_lang.cjs +2 -0
  161. package/dist/components/TEmptyState.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  162. package/dist/components/TEmptyState.vue_vue_type_script_setup_true_lang.js +64 -0
  163. package/dist/components/TEmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -0
  164. package/dist/components/TFileUpload.cjs +2 -0
  165. package/dist/components/TFileUpload.cjs.map +1 -0
  166. package/dist/components/TFileUpload.js +7 -0
  167. package/dist/components/TFileUpload.js.map +1 -0
  168. package/dist/components/TFileUpload.vue_vue_type_script_setup_true_lang.cjs +2 -0
  169. package/dist/components/TFileUpload.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  170. package/dist/components/TFileUpload.vue_vue_type_script_setup_true_lang.js +284 -0
  171. package/dist/components/TFileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -0
  172. package/dist/components/TFormField.cjs +2 -0
  173. package/dist/components/TFormField.cjs.map +1 -0
  174. package/dist/components/TFormField.js +7 -0
  175. package/dist/components/TFormField.js.map +1 -0
  176. package/dist/components/TFormField.vue_vue_type_script_setup_true_lang.cjs +2 -0
  177. package/dist/components/TFormField.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  178. package/dist/components/TFormField.vue_vue_type_script_setup_true_lang.js +63 -0
  179. package/dist/components/TFormField.vue_vue_type_script_setup_true_lang.js.map +1 -0
  180. package/dist/components/TGrid.cjs +2 -0
  181. package/dist/components/TGrid.cjs.map +1 -0
  182. package/dist/components/TGrid.js +7 -0
  183. package/dist/components/TGrid.js.map +1 -0
  184. package/dist/components/TGrid.vue.d.ts +1 -1
  185. package/dist/components/TGrid.vue.d.ts.map +1 -1
  186. package/dist/components/TGrid.vue_vue_type_script_setup_true_lang.cjs +2 -0
  187. package/dist/components/TGrid.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  188. package/dist/components/TGrid.vue_vue_type_script_setup_true_lang.js +47 -0
  189. package/dist/components/TGrid.vue_vue_type_script_setup_true_lang.js.map +1 -0
  190. package/dist/components/TIcon.cjs +2 -0
  191. package/dist/components/TIcon.cjs.map +1 -0
  192. package/dist/components/TIcon.js +7 -0
  193. package/dist/components/TIcon.js.map +1 -0
  194. package/dist/components/TIcon.vue_vue_type_script_setup_true_lang.cjs +2 -0
  195. package/dist/components/TIcon.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  196. package/dist/components/TIcon.vue_vue_type_script_setup_true_lang.js +39 -0
  197. package/dist/components/TIcon.vue_vue_type_script_setup_true_lang.js.map +1 -0
  198. package/dist/components/TInput.cjs +2 -0
  199. package/dist/components/TInput.cjs.map +1 -0
  200. package/dist/components/TInput.js +7 -0
  201. package/dist/components/TInput.js.map +1 -0
  202. package/dist/components/TInput.vue_vue_type_script_setup_true_lang.cjs +2 -0
  203. package/dist/components/TInput.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  204. package/dist/components/TInput.vue_vue_type_script_setup_true_lang.js +80 -0
  205. package/dist/components/TInput.vue_vue_type_script_setup_true_lang.js.map +1 -0
  206. package/dist/components/TLink.cjs +2 -0
  207. package/dist/components/TLink.cjs.map +1 -0
  208. package/dist/components/TLink.js +7 -0
  209. package/dist/components/TLink.js.map +1 -0
  210. package/dist/components/TLink.vue_vue_type_script_setup_true_lang.cjs +2 -0
  211. package/dist/components/TLink.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  212. package/dist/components/TLink.vue_vue_type_script_setup_true_lang.js +47 -0
  213. package/dist/components/TLink.vue_vue_type_script_setup_true_lang.js.map +1 -0
  214. package/dist/components/TMarkdownEditor.cjs +2 -0
  215. package/dist/components/TMarkdownEditor.cjs.map +1 -0
  216. package/dist/components/TMarkdownEditor.js +7 -0
  217. package/dist/components/TMarkdownEditor.js.map +1 -0
  218. package/dist/components/TMarkdownEditor.vue_vue_type_script_setup_true_lang.cjs +12 -0
  219. package/dist/components/TMarkdownEditor.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  220. package/dist/components/TMarkdownEditor.vue_vue_type_script_setup_true_lang.js +315 -0
  221. package/dist/components/TMarkdownEditor.vue_vue_type_script_setup_true_lang.js.map +1 -0
  222. package/dist/components/TModal.cjs +2 -0
  223. package/dist/components/TModal.cjs.map +1 -0
  224. package/dist/components/TModal.js +7 -0
  225. package/dist/components/TModal.js.map +1 -0
  226. package/dist/components/TModal.vue_vue_type_script_setup_true_lang.cjs +2 -0
  227. package/dist/components/TModal.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  228. package/dist/components/TModal.vue_vue_type_script_setup_true_lang.js +163 -0
  229. package/dist/components/TModal.vue_vue_type_script_setup_true_lang.js.map +1 -0
  230. package/dist/components/TMultiSelect.cjs +2 -0
  231. package/dist/components/TMultiSelect.cjs.map +1 -0
  232. package/dist/components/TMultiSelect.js +7 -0
  233. package/dist/components/TMultiSelect.js.map +1 -0
  234. package/dist/components/TMultiSelect.vue_vue_type_script_setup_true_lang.cjs +2 -0
  235. package/dist/components/TMultiSelect.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  236. package/dist/components/TMultiSelect.vue_vue_type_script_setup_true_lang.js +282 -0
  237. package/dist/components/TMultiSelect.vue_vue_type_script_setup_true_lang.js.map +1 -0
  238. package/dist/components/TNavMenu.cjs +2 -0
  239. package/dist/components/TNavMenu.cjs.map +1 -0
  240. package/dist/components/TNavMenu.js +7 -0
  241. package/dist/components/TNavMenu.js.map +1 -0
  242. package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.cjs +2 -0
  243. package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  244. package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.js +151 -0
  245. package/dist/components/TNavMenu.vue_vue_type_script_setup_true_lang.js.map +1 -0
  246. package/dist/components/TNavbar.cjs +2 -0
  247. package/dist/components/TNavbar.cjs.map +1 -0
  248. package/dist/components/TNavbar.js +7 -0
  249. package/dist/components/TNavbar.js.map +1 -0
  250. package/dist/components/TNavbar.vue_vue_type_script_setup_true_lang.cjs +2 -0
  251. package/dist/components/TNavbar.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  252. package/dist/components/TNavbar.vue_vue_type_script_setup_true_lang.js +61 -0
  253. package/dist/components/TNavbar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  254. package/dist/components/TNumberInput.cjs +2 -0
  255. package/dist/components/TNumberInput.cjs.map +1 -0
  256. package/dist/components/TNumberInput.js +7 -0
  257. package/dist/components/TNumberInput.js.map +1 -0
  258. package/dist/components/TNumberInput.vue_vue_type_script_setup_true_lang.cjs +2 -0
  259. package/dist/components/TNumberInput.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  260. package/dist/components/TNumberInput.vue_vue_type_script_setup_true_lang.js +145 -0
  261. package/dist/components/TNumberInput.vue_vue_type_script_setup_true_lang.js.map +1 -0
  262. package/dist/components/TPagination.cjs +2 -0
  263. package/dist/components/TPagination.cjs.map +1 -0
  264. package/dist/components/TPagination.js +7 -0
  265. package/dist/components/TPagination.js.map +1 -0
  266. package/dist/components/TPagination.vue_vue_type_script_setup_true_lang.cjs +2 -0
  267. package/dist/components/TPagination.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  268. package/dist/components/TPagination.vue_vue_type_script_setup_true_lang.js +105 -0
  269. package/dist/components/TPagination.vue_vue_type_script_setup_true_lang.js.map +1 -0
  270. package/dist/components/TPopover.cjs +2 -0
  271. package/dist/components/TPopover.cjs.map +1 -0
  272. package/dist/components/TPopover.js +7 -0
  273. package/dist/components/TPopover.js.map +1 -0
  274. package/dist/components/TPopover.vue_vue_type_script_setup_true_lang.cjs +2 -0
  275. package/dist/components/TPopover.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  276. package/dist/components/TPopover.vue_vue_type_script_setup_true_lang.js +106 -0
  277. package/dist/components/TPopover.vue_vue_type_script_setup_true_lang.js.map +1 -0
  278. package/dist/components/TPricing.cjs +2 -0
  279. package/dist/components/TPricing.cjs.map +1 -0
  280. package/dist/components/TPricing.js +7 -0
  281. package/dist/components/TPricing.js.map +1 -0
  282. package/dist/components/TPricing.vue_vue_type_script_setup_true_lang.cjs +2 -0
  283. package/dist/components/TPricing.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  284. package/dist/components/TPricing.vue_vue_type_script_setup_true_lang.js +33 -0
  285. package/dist/components/TPricing.vue_vue_type_script_setup_true_lang.js.map +1 -0
  286. package/dist/components/TPricingCard.cjs +2 -0
  287. package/dist/components/TPricingCard.cjs.map +1 -0
  288. package/dist/components/TPricingCard.js +7 -0
  289. package/dist/components/TPricingCard.js.map +1 -0
  290. package/dist/components/TPricingCard.vue_vue_type_script_setup_true_lang.cjs +2 -0
  291. package/dist/components/TPricingCard.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  292. package/dist/components/TPricingCard.vue_vue_type_script_setup_true_lang.js +93 -0
  293. package/dist/components/TPricingCard.vue_vue_type_script_setup_true_lang.js.map +1 -0
  294. package/dist/components/TProgress.cjs +2 -0
  295. package/dist/components/TProgress.cjs.map +1 -0
  296. package/dist/components/TProgress.js +7 -0
  297. package/dist/components/TProgress.js.map +1 -0
  298. package/dist/components/TProgress.vue_vue_type_script_setup_true_lang.cjs +2 -0
  299. package/dist/components/TProgress.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  300. package/dist/components/TProgress.vue_vue_type_script_setup_true_lang.js +33 -0
  301. package/dist/components/TProgress.vue_vue_type_script_setup_true_lang.js.map +1 -0
  302. package/dist/components/TRadio.cjs +2 -0
  303. package/dist/components/TRadio.cjs.map +1 -0
  304. package/dist/components/TRadio.js +7 -0
  305. package/dist/components/TRadio.js.map +1 -0
  306. package/dist/components/TRadio.vue_vue_type_script_setup_true_lang.cjs +2 -0
  307. package/dist/components/TRadio.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  308. package/dist/components/TRadio.vue_vue_type_script_setup_true_lang.js +73 -0
  309. package/dist/components/TRadio.vue_vue_type_script_setup_true_lang.js.map +1 -0
  310. package/dist/components/TRadioGroup.cjs +2 -0
  311. package/dist/components/TRadioGroup.cjs.map +1 -0
  312. package/dist/components/TRadioGroup.js +7 -0
  313. package/dist/components/TRadioGroup.js.map +1 -0
  314. package/dist/components/TRadioGroup.vue_vue_type_script_setup_true_lang.cjs +2 -0
  315. package/dist/components/TRadioGroup.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  316. package/dist/components/TRadioGroup.vue_vue_type_script_setup_true_lang.js +46 -0
  317. package/dist/components/TRadioGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
  318. package/dist/components/TSelect.cjs +2 -0
  319. package/dist/components/TSelect.cjs.map +1 -0
  320. package/dist/components/TSelect.js +7 -0
  321. package/dist/components/TSelect.js.map +1 -0
  322. package/dist/components/TSelect.vue.d.ts +2 -0
  323. package/dist/components/TSelect.vue.d.ts.map +1 -1
  324. package/dist/components/TSelect.vue_vue_type_script_setup_true_lang.cjs +2 -0
  325. package/dist/components/TSelect.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  326. package/dist/components/TSelect.vue_vue_type_script_setup_true_lang.js +238 -0
  327. package/dist/components/TSelect.vue_vue_type_script_setup_true_lang.js.map +1 -0
  328. package/dist/components/TSelectableList.cjs +2 -0
  329. package/dist/components/TSelectableList.cjs.map +1 -0
  330. package/dist/components/TSelectableList.js +7 -0
  331. package/dist/components/TSelectableList.js.map +1 -0
  332. package/dist/components/TSelectableList.vue_vue_type_script_setup_true_lang.cjs +2 -0
  333. package/dist/components/TSelectableList.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  334. package/dist/components/TSelectableList.vue_vue_type_script_setup_true_lang.js +133 -0
  335. package/dist/components/TSelectableList.vue_vue_type_script_setup_true_lang.js.map +1 -0
  336. package/dist/components/TSidebar.cjs +2 -0
  337. package/dist/components/TSidebar.cjs.map +1 -0
  338. package/dist/components/TSidebar.js +7 -0
  339. package/dist/components/TSidebar.js.map +1 -0
  340. package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.cjs +2 -0
  341. package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  342. package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.js +98 -0
  343. package/dist/components/TSidebar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  344. package/dist/components/TSkeleton.cjs +2 -0
  345. package/dist/components/TSkeleton.cjs.map +1 -0
  346. package/dist/components/TSkeleton.js +7 -0
  347. package/dist/components/TSkeleton.js.map +1 -0
  348. package/dist/components/TSkeleton.vue_vue_type_script_setup_true_lang.cjs +2 -0
  349. package/dist/components/TSkeleton.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  350. package/dist/components/TSkeleton.vue_vue_type_script_setup_true_lang.js +25 -0
  351. package/dist/components/TSkeleton.vue_vue_type_script_setup_true_lang.js.map +1 -0
  352. package/dist/components/TSpinner.cjs +2 -0
  353. package/dist/components/TSpinner.cjs.map +1 -0
  354. package/dist/components/TSpinner.js +7 -0
  355. package/dist/components/TSpinner.js.map +1 -0
  356. package/dist/components/TSpinner.vue_vue_type_script_setup_true_lang.cjs +2 -0
  357. package/dist/components/TSpinner.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  358. package/dist/components/TSpinner.vue_vue_type_script_setup_true_lang.js +24 -0
  359. package/dist/components/TSpinner.vue_vue_type_script_setup_true_lang.js.map +1 -0
  360. package/dist/components/TStack.cjs +2 -0
  361. package/dist/components/TStack.cjs.map +1 -0
  362. package/dist/components/TStack.js +7 -0
  363. package/dist/components/TStack.js.map +1 -0
  364. package/dist/components/TStack.vue.d.ts +1 -1
  365. package/dist/components/TStack.vue.d.ts.map +1 -1
  366. package/dist/components/TStack.vue_vue_type_script_setup_true_lang.cjs +2 -0
  367. package/dist/components/TStack.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  368. package/dist/components/TStack.vue_vue_type_script_setup_true_lang.js +50 -0
  369. package/dist/components/TStack.vue_vue_type_script_setup_true_lang.js.map +1 -0
  370. package/dist/components/TStat.cjs +2 -0
  371. package/dist/components/TStat.cjs.map +1 -0
  372. package/dist/components/TStat.js +7 -0
  373. package/dist/components/TStat.js.map +1 -0
  374. package/dist/components/TStat.vue_vue_type_script_setup_true_lang.cjs +2 -0
  375. package/dist/components/TStat.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  376. package/dist/components/TStat.vue_vue_type_script_setup_true_lang.js +72 -0
  377. package/dist/components/TStat.vue_vue_type_script_setup_true_lang.js.map +1 -0
  378. package/dist/components/TSteps.cjs +2 -0
  379. package/dist/components/TSteps.cjs.map +1 -0
  380. package/dist/components/TSteps.js +7 -0
  381. package/dist/components/TSteps.js.map +1 -0
  382. package/dist/components/TSteps.vue_vue_type_script_setup_true_lang.cjs +2 -0
  383. package/dist/components/TSteps.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  384. package/dist/components/TSteps.vue_vue_type_script_setup_true_lang.js +83 -0
  385. package/dist/components/TSteps.vue_vue_type_script_setup_true_lang.js.map +1 -0
  386. package/dist/components/TSwitch.cjs +2 -0
  387. package/dist/components/TSwitch.cjs.map +1 -0
  388. package/dist/components/TSwitch.js +7 -0
  389. package/dist/components/TSwitch.js.map +1 -0
  390. package/dist/components/TSwitch.vue_vue_type_script_setup_true_lang.cjs +2 -0
  391. package/dist/components/TSwitch.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  392. package/dist/components/TSwitch.vue_vue_type_script_setup_true_lang.js +71 -0
  393. package/dist/components/TSwitch.vue_vue_type_script_setup_true_lang.js.map +1 -0
  394. package/dist/components/TTab.cjs +2 -0
  395. package/dist/components/TTab.cjs.map +1 -0
  396. package/dist/components/TTab.js +7 -0
  397. package/dist/components/TTab.js.map +1 -0
  398. package/dist/components/TTab.vue_vue_type_script_setup_true_lang.cjs +2 -0
  399. package/dist/components/TTab.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  400. package/dist/components/TTab.vue_vue_type_script_setup_true_lang.js +55 -0
  401. package/dist/components/TTab.vue_vue_type_script_setup_true_lang.js.map +1 -0
  402. package/dist/components/TTabList.cjs +2 -0
  403. package/dist/components/TTabList.cjs.map +1 -0
  404. package/dist/components/TTabList.js +7 -0
  405. package/dist/components/TTabList.js.map +1 -0
  406. package/dist/components/TTabList.vue_vue_type_script_setup_true_lang.cjs +2 -0
  407. package/dist/components/TTabList.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  408. package/dist/components/TTabList.vue_vue_type_script_setup_true_lang.js +73 -0
  409. package/dist/components/TTabList.vue_vue_type_script_setup_true_lang.js.map +1 -0
  410. package/dist/components/TTabPanel.cjs +2 -0
  411. package/dist/components/TTabPanel.cjs.map +1 -0
  412. package/dist/components/TTabPanel.js +7 -0
  413. package/dist/components/TTabPanel.js.map +1 -0
  414. package/dist/components/TTabPanel.vue_vue_type_script_setup_true_lang.cjs +2 -0
  415. package/dist/components/TTabPanel.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  416. package/dist/components/TTabPanel.vue_vue_type_script_setup_true_lang.js +24 -0
  417. package/dist/components/TTabPanel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  418. package/dist/components/TTable.cjs +2 -0
  419. package/dist/components/TTable.cjs.map +1 -0
  420. package/dist/components/TTable.js +7 -0
  421. package/dist/components/TTable.js.map +1 -0
  422. package/dist/components/TTable.vue_vue_type_script_setup_true_lang.cjs +2 -0
  423. package/dist/components/TTable.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  424. package/dist/components/TTable.vue_vue_type_script_setup_true_lang.js +118 -0
  425. package/dist/components/TTable.vue_vue_type_script_setup_true_lang.js.map +1 -0
  426. package/dist/components/TTabs.cjs +2 -0
  427. package/dist/components/TTabs.cjs.map +1 -0
  428. package/dist/components/TTabs.js +7 -0
  429. package/dist/components/TTabs.js.map +1 -0
  430. package/dist/components/TTabs.vue_vue_type_script_setup_true_lang.cjs +2 -0
  431. package/dist/components/TTabs.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  432. package/dist/components/TTabs.vue_vue_type_script_setup_true_lang.js +51 -0
  433. package/dist/components/TTabs.vue_vue_type_script_setup_true_lang.js.map +1 -0
  434. package/dist/components/TTag.cjs +2 -0
  435. package/dist/components/TTag.cjs.map +1 -0
  436. package/dist/components/TTag.js +7 -0
  437. package/dist/components/TTag.js.map +1 -0
  438. package/dist/components/TTag.vue_vue_type_script_setup_true_lang.cjs +2 -0
  439. package/dist/components/TTag.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  440. package/dist/components/TTag.vue_vue_type_script_setup_true_lang.js +60 -0
  441. package/dist/components/TTag.vue_vue_type_script_setup_true_lang.js.map +1 -0
  442. package/dist/components/TTextarea.cjs +2 -0
  443. package/dist/components/TTextarea.cjs.map +1 -0
  444. package/dist/components/TTextarea.js +7 -0
  445. package/dist/components/TTextarea.js.map +1 -0
  446. package/dist/components/TTextarea.vue_vue_type_script_setup_true_lang.cjs +2 -0
  447. package/dist/components/TTextarea.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  448. package/dist/components/TTextarea.vue_vue_type_script_setup_true_lang.js +81 -0
  449. package/dist/components/TTextarea.vue_vue_type_script_setup_true_lang.js.map +1 -0
  450. package/dist/components/TTimeline.cjs +2 -0
  451. package/dist/components/TTimeline.cjs.map +1 -0
  452. package/dist/components/TTimeline.js +7 -0
  453. package/dist/components/TTimeline.js.map +1 -0
  454. package/dist/components/TTimeline.vue_vue_type_script_setup_true_lang.cjs +2 -0
  455. package/dist/components/TTimeline.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  456. package/dist/components/TTimeline.vue_vue_type_script_setup_true_lang.js +58 -0
  457. package/dist/components/TTimeline.vue_vue_type_script_setup_true_lang.js.map +1 -0
  458. package/dist/components/TToast.cjs +2 -0
  459. package/dist/components/TToast.cjs.map +1 -0
  460. package/dist/components/TToast.js +7 -0
  461. package/dist/components/TToast.js.map +1 -0
  462. package/dist/components/TToast.vue_vue_type_script_setup_true_lang.cjs +2 -0
  463. package/dist/components/TToast.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  464. package/dist/components/TToast.vue_vue_type_script_setup_true_lang.js +50 -0
  465. package/dist/components/TToast.vue_vue_type_script_setup_true_lang.js.map +1 -0
  466. package/dist/components/TToastProvider.cjs +2 -0
  467. package/dist/components/TToastProvider.cjs.map +1 -0
  468. package/dist/components/TToastProvider.js +7 -0
  469. package/dist/components/TToastProvider.js.map +1 -0
  470. package/dist/components/TToastProvider.vue_vue_type_script_setup_true_lang.cjs +2 -0
  471. package/dist/components/TToastProvider.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  472. package/dist/components/TToastProvider.vue_vue_type_script_setup_true_lang.js +33 -0
  473. package/dist/components/TToastProvider.vue_vue_type_script_setup_true_lang.js.map +1 -0
  474. package/dist/components/TToggleGroup.cjs +2 -0
  475. package/dist/components/TToggleGroup.cjs.map +1 -0
  476. package/dist/components/TToggleGroup.js +7 -0
  477. package/dist/components/TToggleGroup.js.map +1 -0
  478. package/dist/components/TToggleGroup.vue_vue_type_script_setup_true_lang.cjs +2 -0
  479. package/dist/components/TToggleGroup.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  480. package/dist/components/TToggleGroup.vue_vue_type_script_setup_true_lang.js +119 -0
  481. package/dist/components/TToggleGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
  482. package/dist/components/TTooltip.cjs +2 -0
  483. package/dist/components/TTooltip.cjs.map +1 -0
  484. package/dist/components/TTooltip.js +7 -0
  485. package/dist/components/TTooltip.js.map +1 -0
  486. package/dist/components/TTooltip.vue_vue_type_script_setup_true_lang.cjs +2 -0
  487. package/dist/components/TTooltip.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  488. package/dist/components/TTooltip.vue_vue_type_script_setup_true_lang.js +75 -0
  489. package/dist/components/TTooltip.vue_vue_type_script_setup_true_lang.js.map +1 -0
  490. package/dist/components/TTreeView.cjs +2 -0
  491. package/dist/components/TTreeView.cjs.map +1 -0
  492. package/dist/components/TTreeView.js +7 -0
  493. package/dist/components/TTreeView.js.map +1 -0
  494. package/dist/components/TTreeView.vue_vue_type_script_setup_true_lang.cjs +2 -0
  495. package/dist/components/TTreeView.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  496. package/dist/components/TTreeView.vue_vue_type_script_setup_true_lang.js +161 -0
  497. package/dist/components/TTreeView.vue_vue_type_script_setup_true_lang.js.map +1 -0
  498. package/dist/components/TTreeViewItem.cjs +2 -0
  499. package/dist/components/TTreeViewItem.cjs.map +1 -0
  500. package/dist/components/TTreeViewItem.js +7 -0
  501. package/dist/components/TTreeViewItem.js.map +1 -0
  502. package/dist/components/TTreeViewItem.vue_vue_type_script_setup_true_lang.cjs +2 -0
  503. package/dist/components/TTreeViewItem.vue_vue_type_script_setup_true_lang.cjs.map +1 -0
  504. package/dist/components/TTreeViewItem.vue_vue_type_script_setup_true_lang.js +101 -0
  505. package/dist/components/TTreeViewItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
  506. package/dist/components/accordion.cjs +2 -0
  507. package/dist/components/accordion.cjs.map +1 -0
  508. package/dist/components/accordion.js +6 -0
  509. package/dist/components/accordion.js.map +1 -0
  510. package/dist/components/index.d.ts +1 -0
  511. package/dist/components/index.d.ts.map +1 -1
  512. package/dist/components/sidebar.cjs +2 -0
  513. package/dist/components/sidebar.cjs.map +1 -0
  514. package/dist/components/sidebar.js +6 -0
  515. package/dist/components/sidebar.js.map +1 -0
  516. package/dist/components/tabs-context.cjs +2 -0
  517. package/dist/components/tabs-context.cjs.map +1 -0
  518. package/dist/components/tabs-context.js +6 -0
  519. package/dist/components/tabs-context.js.map +1 -0
  520. package/dist/components/tree-view.cjs +2 -0
  521. package/dist/components/tree-view.cjs.map +1 -0
  522. package/dist/components/tree-view.js +6 -0
  523. package/dist/components/tree-view.js.map +1 -0
  524. package/dist/composables/useControllableOpen.cjs +2 -0
  525. package/dist/composables/useControllableOpen.cjs.map +1 -0
  526. package/dist/composables/useControllableOpen.js +15 -0
  527. package/dist/composables/useControllableOpen.js.map +1 -0
  528. package/dist/composables/useToast.cjs +2 -0
  529. package/dist/composables/useToast.cjs.map +1 -0
  530. package/dist/composables/useToast.js +41 -0
  531. package/dist/composables/useToast.js.map +1 -0
  532. package/dist/index.cjs +1 -12
  533. package/dist/index.js +66 -5992
  534. package/dist/plugin.cjs +2 -0
  535. package/dist/plugin.cjs.map +1 -0
  536. package/dist/plugin.js +135 -0
  537. package/dist/plugin.js.map +1 -0
  538. package/dist/style.css +1 -1
  539. package/dist/types/contracts.cjs +2 -0
  540. package/dist/types/contracts.cjs.map +1 -0
  541. package/dist/types/contracts.js +31 -0
  542. package/dist/types/contracts.js.map +1 -0
  543. package/package.json +2 -2
  544. package/dist/index.cjs.map +0 -1
  545. package/dist/index.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","names":["$slots","$slots","$slots","$slots","$slots","$slots","$slots","$slots","$slots","$slots","$slots","$slots","$slots","$slots","$slots","$slots","$slots","$slots","$slots","$slots","$slots","$slots","$slots","$slots"],"sources":["../src/components/accordion.ts","../src/components/TAccordion.vue","../src/components/TAccordion.vue","../src/components/TAccordionItem.vue","../src/components/TAccordionItem.vue","../src/components/TAlert.vue","../src/components/TAlert.vue","../src/components/TBadge.vue","../src/components/TBadge.vue","../src/components/TBreadcrumb.vue","../src/components/TBreadcrumb.vue","../src/components/TBreadcrumbItem.vue","../src/components/TBreadcrumbItem.vue","../src/components/TSpinner.vue","../src/components/TSpinner.vue","../src/components/TButton.vue","../src/components/TButton.vue","../src/components/TCard.vue","../src/components/TCard.vue","../src/components/TCheckbox.vue","../src/components/TCheckbox.vue","../src/composables/useControllableOpen.ts","../src/components/TCombobox.vue","../src/components/TCombobox.vue","../src/components/TModal.vue","../src/components/TModal.vue","../src/components/TConfirmDialog.vue","../src/components/TConfirmDialog.vue","../src/components/TContainer.vue","../src/components/TContainer.vue","../src/components/TContextMenu.vue","../src/components/TContextMenu.vue","../src/components/TDatePicker.vue","../src/components/TDatePicker.vue","../src/components/TDateTimePicker.vue","../src/components/TDateTimePicker.vue","../src/components/TDrawer.vue","../src/components/TDrawer.vue","../src/components/TDropdown.vue","../src/components/TDropdown.vue","../src/components/TEmptyState.vue","../src/components/TEmptyState.vue","../src/components/TFileUpload.vue","../src/components/TFileUpload.vue","../src/components/TMultiSelect.vue","../src/components/TMultiSelect.vue","../src/components/TGrid.vue","../src/components/TGrid.vue","../src/components/TNavbar.vue","../src/components/TNavbar.vue","../src/components/TLink.vue","../src/components/TLink.vue","../src/components/sidebar.ts","../src/components/TNavMenu.vue","../src/components/TNavMenu.vue","../src/components/TRadio.vue","../src/components/TRadio.vue","../src/components/TRadioGroup.vue","../src/components/TRadioGroup.vue","../src/components/TSelect.vue","../src/components/TSelect.vue","../src/components/TSidebar.vue","../src/components/TSidebar.vue","../src/components/TInput.vue","../src/components/TInput.vue","../src/components/TNumberInput.vue","../src/components/TNumberInput.vue","../src/components/TSelectableList.vue","../src/components/TSelectableList.vue","../src/components/TStack.vue","../src/components/TStack.vue","../src/components/tree-view.ts","../src/components/TTreeViewItem.vue","../src/components/TTreeViewItem.vue","../src/components/TTreeView.vue","../src/components/TTreeView.vue","../src/components/TSteps.vue","../src/components/TSteps.vue","../src/components/TToggleGroup.vue","../src/components/TToggleGroup.vue","../src/components/TTextarea.vue","../src/components/TTextarea.vue","../src/components/TSkeleton.vue","../src/components/TSkeleton.vue","../src/components/TStat.vue","../src/components/TStat.vue","../src/components/TSwitch.vue","../src/components/TSwitch.vue","../src/components/TTooltip.vue","../src/components/TTooltip.vue","../src/components/TFormField.vue","../src/components/TFormField.vue","../src/components/TPagination.vue","../src/components/TPagination.vue","../src/components/TPopover.vue","../src/components/TPopover.vue","../src/components/TProgress.vue","../src/components/TProgress.vue","../src/components/tabs-context.ts","../src/components/TTabs.vue","../src/components/TTabs.vue","../src/components/TTabList.vue","../src/components/TTabList.vue","../src/components/TTab.vue","../src/components/TTab.vue","../src/components/TTabPanel.vue","../src/components/TTabPanel.vue","../src/components/TToast.vue","../src/components/TToast.vue","../src/composables/useToast.ts","../src/components/TToastProvider.vue","../src/components/TToastProvider.vue","../src/components/TAvatar.vue","../src/components/TAvatar.vue","../src/components/TDivider.vue","../src/components/TDivider.vue","../src/components/TTable.vue","../src/components/TTable.vue","../src/components/TTag.vue","../src/components/TTag.vue","../src/components/TTimeline.vue","../src/components/TTimeline.vue","../src/components/TPricingCard.vue","../src/components/TPricingCard.vue","../src/components/TPricing.vue","../src/components/TPricing.vue","../src/components/TMarkdownEditor.vue","../src/components/TMarkdownEditor.vue","../src/components/TIcon.vue","../src/components/TIcon.vue","../src/plugin.ts","../src/types/contracts.ts"],"sourcesContent":["import type { InjectionKey } from 'vue';\n\nexport type AccordionType = 'single' | 'multiple';\n\nexport interface AccordionContext {\n type: AccordionType;\n disabled: boolean;\n collapsible: boolean;\n isItemOpen: (value: string) => boolean;\n toggleItem: (value: string) => void;\n registerTrigger: (value: string, el: HTMLElement) => void;\n unregisterTrigger: (value: string) => void;\n focusPrev: (value: string) => void;\n focusNext: (value: string) => void;\n focusFirst: () => void;\n focusLast: () => void;\n}\n\nexport const accordionInjectionKey: InjectionKey<AccordionContext> = Symbol('tree-accordion');\n","<script setup lang=\"ts\">\nimport { computed, provide, reactive } from 'vue';\nimport { type AccordionType, accordionInjectionKey } from './accordion';\n\nconst props = withDefaults(\n defineProps<{\n type?: AccordionType;\n modelValue?: string | string[];\n defaultValue?: string | string[];\n disabled?: boolean;\n collapsible?: boolean;\n }>(),\n {\n type: 'single',\n modelValue: undefined,\n defaultValue: undefined,\n disabled: false,\n collapsible: false,\n },\n);\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string | string[] | undefined): void;\n}>();\n\n// Internal uncontrolled state\nconst internalValue = computed<string[]>(() => {\n const def = props.defaultValue;\n if (def === undefined) return [];\n return Array.isArray(def) ? def : [def];\n});\n\nconst uncontrolledValue = reactive<Set<string>>(new Set(internalValue.value));\n\nconst isControlled = computed(() => props.modelValue !== undefined);\n\nconst openValues = computed<Set<string>>(() => {\n if (isControlled.value) {\n const mv = props.modelValue!;\n return new Set(Array.isArray(mv) ? mv : [mv]);\n }\n return uncontrolledValue;\n});\n\nfunction isItemOpen(value: string): boolean {\n return openValues.value.has(value);\n}\n\nfunction emitUpdate(values: Set<string>) {\n if (props.type === 'single') {\n const arr = [...values];\n emit('update:modelValue', arr.length > 0 ? arr[0] : undefined);\n } else {\n emit('update:modelValue', [...values]);\n }\n}\n\nfunction toggleItem(value: string) {\n const currentlyOpen = isItemOpen(value);\n\n if (props.type === 'single') {\n if (currentlyOpen) {\n if (props.collapsible) {\n if (!isControlled.value) {\n uncontrolledValue.delete(value);\n }\n emitUpdate(new Set());\n }\n } else {\n if (!isControlled.value) {\n uncontrolledValue.clear();\n uncontrolledValue.add(value);\n }\n emitUpdate(new Set([value]));\n }\n } else {\n // Multiple mode\n const next = new Set(openValues.value);\n if (currentlyOpen) {\n next.delete(value);\n } else {\n next.add(value);\n }\n if (!isControlled.value) {\n if (currentlyOpen) {\n uncontrolledValue.delete(value);\n } else {\n uncontrolledValue.add(value);\n }\n }\n emitUpdate(next);\n }\n}\n\n// Keyboard navigation between triggers\nconst triggerMap = new Map<string, HTMLElement>();\nconst triggerOrder: string[] = reactive([]);\n\nfunction registerTrigger(value: string, el: HTMLElement) {\n if (!triggerMap.has(value)) {\n triggerOrder.push(value);\n }\n triggerMap.set(value, el);\n}\n\nfunction unregisterTrigger(value: string) {\n triggerMap.delete(value);\n const idx = triggerOrder.indexOf(value);\n if (idx !== -1) triggerOrder.splice(idx, 1);\n}\n\nfunction getEnabledTriggers(): string[] {\n return triggerOrder.filter((v) => {\n const el = triggerMap.get(v);\n return el && !el.hasAttribute('disabled');\n });\n}\n\nfunction focusPrev(value: string) {\n const enabled = getEnabledTriggers();\n const idx = enabled.indexOf(value);\n const prev = idx > 0 ? idx - 1 : enabled.length - 1;\n triggerMap.get(enabled[prev])?.focus();\n}\n\nfunction focusNext(value: string) {\n const enabled = getEnabledTriggers();\n const idx = enabled.indexOf(value);\n const next = idx < enabled.length - 1 ? idx + 1 : 0;\n triggerMap.get(enabled[next])?.focus();\n}\n\nfunction focusFirst() {\n const enabled = getEnabledTriggers();\n if (enabled.length) triggerMap.get(enabled[0])?.focus();\n}\n\nfunction focusLast() {\n const enabled = getEnabledTriggers();\n if (enabled.length) triggerMap.get(enabled[enabled.length - 1])?.focus();\n}\n\nprovide(accordionInjectionKey, {\n type: props.type,\n disabled: props.disabled,\n collapsible: props.collapsible,\n isItemOpen,\n toggleItem,\n registerTrigger,\n unregisterTrigger,\n focusPrev,\n focusNext,\n focusFirst,\n focusLast,\n});\n</script>\n\n<template>\n <div class=\"t-accordion\">\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, provide, reactive } from 'vue';\nimport { type AccordionType, accordionInjectionKey } from './accordion';\n\nconst props = withDefaults(\n defineProps<{\n type?: AccordionType;\n modelValue?: string | string[];\n defaultValue?: string | string[];\n disabled?: boolean;\n collapsible?: boolean;\n }>(),\n {\n type: 'single',\n modelValue: undefined,\n defaultValue: undefined,\n disabled: false,\n collapsible: false,\n },\n);\n\nconst emit = defineEmits<{\n (e: 'update:modelValue', value: string | string[] | undefined): void;\n}>();\n\n// Internal uncontrolled state\nconst internalValue = computed<string[]>(() => {\n const def = props.defaultValue;\n if (def === undefined) return [];\n return Array.isArray(def) ? def : [def];\n});\n\nconst uncontrolledValue = reactive<Set<string>>(new Set(internalValue.value));\n\nconst isControlled = computed(() => props.modelValue !== undefined);\n\nconst openValues = computed<Set<string>>(() => {\n if (isControlled.value) {\n const mv = props.modelValue!;\n return new Set(Array.isArray(mv) ? mv : [mv]);\n }\n return uncontrolledValue;\n});\n\nfunction isItemOpen(value: string): boolean {\n return openValues.value.has(value);\n}\n\nfunction emitUpdate(values: Set<string>) {\n if (props.type === 'single') {\n const arr = [...values];\n emit('update:modelValue', arr.length > 0 ? arr[0] : undefined);\n } else {\n emit('update:modelValue', [...values]);\n }\n}\n\nfunction toggleItem(value: string) {\n const currentlyOpen = isItemOpen(value);\n\n if (props.type === 'single') {\n if (currentlyOpen) {\n if (props.collapsible) {\n if (!isControlled.value) {\n uncontrolledValue.delete(value);\n }\n emitUpdate(new Set());\n }\n } else {\n if (!isControlled.value) {\n uncontrolledValue.clear();\n uncontrolledValue.add(value);\n }\n emitUpdate(new Set([value]));\n }\n } else {\n // Multiple mode\n const next = new Set(openValues.value);\n if (currentlyOpen) {\n next.delete(value);\n } else {\n next.add(value);\n }\n if (!isControlled.value) {\n if (currentlyOpen) {\n uncontrolledValue.delete(value);\n } else {\n uncontrolledValue.add(value);\n }\n }\n emitUpdate(next);\n }\n}\n\n// Keyboard navigation between triggers\nconst triggerMap = new Map<string, HTMLElement>();\nconst triggerOrder: string[] = reactive([]);\n\nfunction registerTrigger(value: string, el: HTMLElement) {\n if (!triggerMap.has(value)) {\n triggerOrder.push(value);\n }\n triggerMap.set(value, el);\n}\n\nfunction unregisterTrigger(value: string) {\n triggerMap.delete(value);\n const idx = triggerOrder.indexOf(value);\n if (idx !== -1) triggerOrder.splice(idx, 1);\n}\n\nfunction getEnabledTriggers(): string[] {\n return triggerOrder.filter((v) => {\n const el = triggerMap.get(v);\n return el && !el.hasAttribute('disabled');\n });\n}\n\nfunction focusPrev(value: string) {\n const enabled = getEnabledTriggers();\n const idx = enabled.indexOf(value);\n const prev = idx > 0 ? idx - 1 : enabled.length - 1;\n triggerMap.get(enabled[prev])?.focus();\n}\n\nfunction focusNext(value: string) {\n const enabled = getEnabledTriggers();\n const idx = enabled.indexOf(value);\n const next = idx < enabled.length - 1 ? idx + 1 : 0;\n triggerMap.get(enabled[next])?.focus();\n}\n\nfunction focusFirst() {\n const enabled = getEnabledTriggers();\n if (enabled.length) triggerMap.get(enabled[0])?.focus();\n}\n\nfunction focusLast() {\n const enabled = getEnabledTriggers();\n if (enabled.length) triggerMap.get(enabled[enabled.length - 1])?.focus();\n}\n\nprovide(accordionInjectionKey, {\n type: props.type,\n disabled: props.disabled,\n collapsible: props.collapsible,\n isItemOpen,\n toggleItem,\n registerTrigger,\n unregisterTrigger,\n focusPrev,\n focusNext,\n focusFirst,\n focusLast,\n});\n</script>\n\n<template>\n <div class=\"t-accordion\">\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, inject, onMounted, onBeforeUnmount, ref, useId } from 'vue';\nimport { accordionInjectionKey } from './accordion';\n\nconst props = withDefaults(\n defineProps<{\n value: string;\n disabled?: boolean;\n }>(),\n {\n disabled: false,\n },\n);\n\nconst injected = inject(accordionInjectionKey);\n\nif (!injected) {\n throw new Error('[TreeUI] TAccordionItem must be used inside a TAccordion.');\n}\n\nconst ctx = injected;\n\nconst triggerId = useId();\nconst panelId = useId();\nconst triggerRef = ref<HTMLButtonElement | null>(null);\n\nconst isOpen = computed(() => ctx.isItemOpen(props.value));\nconst isDisabled = computed(() => props.disabled || ctx.disabled);\n\nconst itemClasses = computed(() => [\n 't-accordion__item',\n {\n 'is-open': isOpen.value,\n 'is-disabled': isDisabled.value,\n },\n]);\n\nfunction handleToggle() {\n if (isDisabled.value) return;\n ctx.toggleItem(props.value);\n}\n\nfunction handleKeydown(event: KeyboardEvent) {\n if (isDisabled.value) return;\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n ctx.focusNext(props.value);\n break;\n case 'ArrowUp':\n event.preventDefault();\n ctx.focusPrev(props.value);\n break;\n case 'Home':\n event.preventDefault();\n ctx.focusFirst();\n break;\n case 'End':\n event.preventDefault();\n ctx.focusLast();\n break;\n }\n}\n\nonMounted(() => {\n if (triggerRef.value) {\n ctx.registerTrigger(props.value, triggerRef.value);\n }\n});\n\nonBeforeUnmount(() => {\n ctx.unregisterTrigger(props.value);\n});\n</script>\n\n<template>\n <div :class=\"itemClasses\">\n <h3 class=\"t-accordion__heading\">\n <button\n :id=\"triggerId\"\n ref=\"triggerRef\"\n type=\"button\"\n class=\"t-accordion__trigger\"\n :aria-expanded=\"isOpen\"\n :aria-controls=\"panelId\"\n :disabled=\"isDisabled || undefined\"\n @click=\"handleToggle\"\n @keydown=\"handleKeydown\"\n >\n <slot\n name=\"trigger\"\n :open=\"isOpen\"\n >\n {{ value }}\n </slot>\n <svg\n class=\"t-accordion__icon\"\n :class=\"{ 'is-open': isOpen }\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </button>\n </h3>\n <div\n v-if=\"isOpen\"\n :id=\"panelId\"\n role=\"region\"\n :aria-labelledby=\"triggerId\"\n class=\"t-accordion__content\"\n >\n <div class=\"t-accordion__panel\">\n <slot />\n </div>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, inject, onMounted, onBeforeUnmount, ref, useId } from 'vue';\nimport { accordionInjectionKey } from './accordion';\n\nconst props = withDefaults(\n defineProps<{\n value: string;\n disabled?: boolean;\n }>(),\n {\n disabled: false,\n },\n);\n\nconst injected = inject(accordionInjectionKey);\n\nif (!injected) {\n throw new Error('[TreeUI] TAccordionItem must be used inside a TAccordion.');\n}\n\nconst ctx = injected;\n\nconst triggerId = useId();\nconst panelId = useId();\nconst triggerRef = ref<HTMLButtonElement | null>(null);\n\nconst isOpen = computed(() => ctx.isItemOpen(props.value));\nconst isDisabled = computed(() => props.disabled || ctx.disabled);\n\nconst itemClasses = computed(() => [\n 't-accordion__item',\n {\n 'is-open': isOpen.value,\n 'is-disabled': isDisabled.value,\n },\n]);\n\nfunction handleToggle() {\n if (isDisabled.value) return;\n ctx.toggleItem(props.value);\n}\n\nfunction handleKeydown(event: KeyboardEvent) {\n if (isDisabled.value) return;\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n ctx.focusNext(props.value);\n break;\n case 'ArrowUp':\n event.preventDefault();\n ctx.focusPrev(props.value);\n break;\n case 'Home':\n event.preventDefault();\n ctx.focusFirst();\n break;\n case 'End':\n event.preventDefault();\n ctx.focusLast();\n break;\n }\n}\n\nonMounted(() => {\n if (triggerRef.value) {\n ctx.registerTrigger(props.value, triggerRef.value);\n }\n});\n\nonBeforeUnmount(() => {\n ctx.unregisterTrigger(props.value);\n});\n</script>\n\n<template>\n <div :class=\"itemClasses\">\n <h3 class=\"t-accordion__heading\">\n <button\n :id=\"triggerId\"\n ref=\"triggerRef\"\n type=\"button\"\n class=\"t-accordion__trigger\"\n :aria-expanded=\"isOpen\"\n :aria-controls=\"panelId\"\n :disabled=\"isDisabled || undefined\"\n @click=\"handleToggle\"\n @keydown=\"handleKeydown\"\n >\n <slot\n name=\"trigger\"\n :open=\"isOpen\"\n >\n {{ value }}\n </slot>\n <svg\n class=\"t-accordion__icon\"\n :class=\"{ 'is-open': isOpen }\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </button>\n </h3>\n <div\n v-if=\"isOpen\"\n :id=\"panelId\"\n role=\"region\"\n :aria-labelledby=\"triggerId\"\n class=\"t-accordion__content\"\n >\n <div class=\"t-accordion__panel\">\n <slot />\n </div>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TSize } from '../types/contracts';\n\nexport type TAlertVariant = 'info' | 'success' | 'warning' | 'danger';\n\nconst props = withDefaults(\n defineProps<{\n variant?: TAlertVariant;\n size?: TSize;\n dismissible?: boolean;\n }>(),\n {\n variant: 'info',\n size: 'md',\n dismissible: false,\n },\n);\n\nconst emit = defineEmits<{\n (e: 'dismiss'): void;\n}>();\n\nconst classes = computed(() => [\n 't-alert',\n `t-alert--${props.variant}`,\n `t-alert--${props.size}`,\n]);\n\nfunction handleDismiss() {\n emit('dismiss');\n}\n</script>\n\n<template>\n <div\n :class=\"classes\"\n role=\"alert\"\n >\n <span\n v-if=\"$slots.icon\"\n class=\"t-alert__icon\"\n aria-hidden=\"true\"\n >\n <slot name=\"icon\" />\n </span>\n <div class=\"t-alert__content\">\n <slot />\n </div>\n <button\n v-if=\"dismissible\"\n type=\"button\"\n class=\"t-alert__dismiss\"\n aria-label=\"Dismiss\"\n @click=\"handleDismiss\"\n >\n <slot name=\"dismiss-icon\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </slot>\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TSize } from '../types/contracts';\n\nexport type TAlertVariant = 'info' | 'success' | 'warning' | 'danger';\n\nconst props = withDefaults(\n defineProps<{\n variant?: TAlertVariant;\n size?: TSize;\n dismissible?: boolean;\n }>(),\n {\n variant: 'info',\n size: 'md',\n dismissible: false,\n },\n);\n\nconst emit = defineEmits<{\n (e: 'dismiss'): void;\n}>();\n\nconst classes = computed(() => [\n 't-alert',\n `t-alert--${props.variant}`,\n `t-alert--${props.size}`,\n]);\n\nfunction handleDismiss() {\n emit('dismiss');\n}\n</script>\n\n<template>\n <div\n :class=\"classes\"\n role=\"alert\"\n >\n <span\n v-if=\"$slots.icon\"\n class=\"t-alert__icon\"\n aria-hidden=\"true\"\n >\n <slot name=\"icon\" />\n </span>\n <div class=\"t-alert__content\">\n <slot />\n </div>\n <button\n v-if=\"dismissible\"\n type=\"button\"\n class=\"t-alert__dismiss\"\n aria-label=\"Dismiss\"\n @click=\"handleDismiss\"\n >\n <slot name=\"dismiss-icon\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </slot>\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TSize, TVariant } from '../types/contracts';\n\nconst _treeBadgeTones = ['neutral', 'success', 'warning', 'danger', 'info'] as const;\n\nexport type TBadgeTone = (typeof _treeBadgeTones)[number];\n\nconst props = withDefaults(\n defineProps<{\n variant?: TVariant;\n size?: TSize;\n tone?: TBadgeTone;\n }>(),\n {\n variant: 'soft',\n size: 'md',\n tone: 'neutral',\n },\n);\n\nconst classes = computed(() => [\n 't-badge',\n `t-badge--${props.variant}`,\n `t-badge--${props.size}`,\n `t-badge--tone-${props.tone}`,\n]);\n</script>\n\n<template>\n <span :class=\"classes\">\n <span\n v-if=\"$slots.icon\"\n class=\"t-badge__icon\"\n aria-hidden=\"true\"\n >\n <slot name=\"icon\" />\n </span>\n <slot />\n </span>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TSize, TVariant } from '../types/contracts';\n\nconst _treeBadgeTones = ['neutral', 'success', 'warning', 'danger', 'info'] as const;\n\nexport type TBadgeTone = (typeof _treeBadgeTones)[number];\n\nconst props = withDefaults(\n defineProps<{\n variant?: TVariant;\n size?: TSize;\n tone?: TBadgeTone;\n }>(),\n {\n variant: 'soft',\n size: 'md',\n tone: 'neutral',\n },\n);\n\nconst classes = computed(() => [\n 't-badge',\n `t-badge--${props.variant}`,\n `t-badge--${props.size}`,\n `t-badge--tone-${props.tone}`,\n]);\n</script>\n\n<template>\n <span :class=\"classes\">\n <span\n v-if=\"$slots.icon\"\n class=\"t-badge__icon\"\n aria-hidden=\"true\"\n >\n <slot name=\"icon\" />\n </span>\n <slot />\n </span>\n</template>\n","<script setup lang=\"ts\">\nconst props = withDefaults(\n defineProps<{\n /**\n * Character or string used to visually separate breadcrumb items.\n */\n separator?: string;\n }>(),\n {\n separator: '/',\n },\n);\n</script>\n\n<template>\n <nav\n aria-label=\"Breadcrumb\"\n class=\"t-breadcrumb\"\n >\n <ol\n class=\"t-breadcrumb__list\"\n :style=\"{ '--tree-breadcrumb-separator': `'${props.separator}'` }\"\n >\n <slot />\n </ol>\n </nav>\n</template>\n","<script setup lang=\"ts\">\nconst props = withDefaults(\n defineProps<{\n /**\n * Character or string used to visually separate breadcrumb items.\n */\n separator?: string;\n }>(),\n {\n separator: '/',\n },\n);\n</script>\n\n<template>\n <nav\n aria-label=\"Breadcrumb\"\n class=\"t-breadcrumb\"\n >\n <ol\n class=\"t-breadcrumb__list\"\n :style=\"{ '--tree-breadcrumb-separator': `'${props.separator}'` }\"\n >\n <slot />\n </ol>\n </nav>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, getCurrentInstance, type Component } from 'vue';\n\nconst props = withDefaults(\n defineProps<{\n /**\n * URL the breadcrumb item links to. Omit for the current/last item.\n */\n href?: string;\n /**\n * Route target. When provided and vue-router is available, renders RouterLink.\n */\n to?: string | Record<string, unknown>;\n /**\n * Marks this item as the current page. Automatically set if it's the last item without href.\n */\n current?: boolean;\n }>(),\n {\n href: undefined,\n to: undefined,\n current: false,\n },\n);\n\nconst instance = getCurrentInstance();\n\nconst routerLinkComponent = computed<Component | null>(() => {\n if (!props.to) return null;\n\n return (instance?.appContext.components.RouterLink as Component | undefined) ?? null;\n});\n\nconst hasRouterLink = computed(() => {\n return Boolean(routerLinkComponent.value);\n});\n\nconst canRenderLink = computed(() => {\n if (props.href) return true;\n if (typeof props.to === 'string') return true;\n return Boolean(props.to && hasRouterLink.value);\n});\n\nconst isCurrent = computed(() => props.current || !canRenderLink.value);\n\nconst tag = computed<string | Component>(() => {\n if (props.to && routerLinkComponent.value) {\n return routerLinkComponent.value;\n }\n\n return 'a';\n});\n\nconst linkProps = computed(() => {\n if (props.to && hasRouterLink.value) {\n return { to: props.to };\n }\n\n return {\n href: props.href ?? (typeof props.to === 'string' ? props.to : undefined),\n };\n});\n</script>\n\n<template>\n <li class=\"t-breadcrumb__item\">\n <component\n :is=\"tag\"\n v-if=\"!isCurrent\"\n v-bind=\"linkProps\"\n class=\"t-breadcrumb__link\"\n >\n <slot />\n </component>\n <span\n v-else\n class=\"t-breadcrumb__current\"\n aria-current=\"page\"\n >\n <slot />\n </span>\n </li>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, getCurrentInstance, type Component } from 'vue';\n\nconst props = withDefaults(\n defineProps<{\n /**\n * URL the breadcrumb item links to. Omit for the current/last item.\n */\n href?: string;\n /**\n * Route target. When provided and vue-router is available, renders RouterLink.\n */\n to?: string | Record<string, unknown>;\n /**\n * Marks this item as the current page. Automatically set if it's the last item without href.\n */\n current?: boolean;\n }>(),\n {\n href: undefined,\n to: undefined,\n current: false,\n },\n);\n\nconst instance = getCurrentInstance();\n\nconst routerLinkComponent = computed<Component | null>(() => {\n if (!props.to) return null;\n\n return (instance?.appContext.components.RouterLink as Component | undefined) ?? null;\n});\n\nconst hasRouterLink = computed(() => {\n return Boolean(routerLinkComponent.value);\n});\n\nconst canRenderLink = computed(() => {\n if (props.href) return true;\n if (typeof props.to === 'string') return true;\n return Boolean(props.to && hasRouterLink.value);\n});\n\nconst isCurrent = computed(() => props.current || !canRenderLink.value);\n\nconst tag = computed<string | Component>(() => {\n if (props.to && routerLinkComponent.value) {\n return routerLinkComponent.value;\n }\n\n return 'a';\n});\n\nconst linkProps = computed(() => {\n if (props.to && hasRouterLink.value) {\n return { to: props.to };\n }\n\n return {\n href: props.href ?? (typeof props.to === 'string' ? props.to : undefined),\n };\n});\n</script>\n\n<template>\n <li class=\"t-breadcrumb__item\">\n <component\n :is=\"tag\"\n v-if=\"!isCurrent\"\n v-bind=\"linkProps\"\n class=\"t-breadcrumb__link\"\n >\n <slot />\n </component>\n <span\n v-else\n class=\"t-breadcrumb__current\"\n aria-current=\"page\"\n >\n <slot />\n </span>\n </li>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TSize } from '../types/contracts';\n\nconst props = withDefaults(\n defineProps<{\n size?: TSize;\n label?: string;\n }>(),\n {\n size: 'md',\n label: 'Loading',\n },\n);\n\nconst classes = computed(() => ['t-spinner', `t-spinner--${props.size}`]);\n</script>\n\n<template>\n <span\n :class=\"classes\"\n role=\"status\"\n :aria-label=\"label\"\n >\n <span\n class=\"t-spinner__ring\"\n aria-hidden=\"true\"\n />\n <span class=\"t-visually-hidden\">{{ label }}</span>\n </span>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TSize } from '../types/contracts';\n\nconst props = withDefaults(\n defineProps<{\n size?: TSize;\n label?: string;\n }>(),\n {\n size: 'md',\n label: 'Loading',\n },\n);\n\nconst classes = computed(() => ['t-spinner', `t-spinner--${props.size}`]);\n</script>\n\n<template>\n <span\n :class=\"classes\"\n role=\"status\"\n :aria-label=\"label\"\n >\n <span\n class=\"t-spinner__ring\"\n aria-hidden=\"true\"\n />\n <span class=\"t-visually-hidden\">{{ label }}</span>\n </span>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { tv } from '@treeui/utils';\nimport type { TSize, TVariant } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n variant?: TVariant;\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n type?: 'button' | 'submit' | 'reset';\n }>(),\n {\n as: 'button',\n variant: 'solid',\n size: 'md',\n disabled: false,\n loading: false,\n type: 'button',\n },\n);\n\nconst emit = defineEmits<{\n click: [event: MouseEvent];\n}>();\n\nconst buttonClass = tv({\n base: 't-button',\n variants: {\n variant: {\n solid: 't-button--solid',\n outline: 't-button--outline',\n ghost: 't-button--ghost',\n soft: 't-button--soft',\n danger: 't-button--danger',\n },\n size: {\n sm: 't-button--sm',\n md: 't-button--md',\n lg: 't-button--lg',\n },\n },\n});\n\nconst isNativeButton = computed(() => props.as === 'button');\nconst isDisabled = computed(() => props.disabled || props.loading);\nconst classes = computed(() =>\n buttonClass({\n variant: props.variant,\n size: props.size,\n class: {\n 'is-loading': props.loading,\n 'is-disabled': isDisabled.value,\n },\n }),\n);\n\nconst onClick = (event: MouseEvent) => {\n if (isDisabled.value) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n\n emit('click', event);\n};\n</script>\n\n<template>\n <component\n :is=\"as\"\n :type=\"isNativeButton ? type : undefined\"\n :class=\"classes\"\n :disabled=\"isNativeButton ? isDisabled : undefined\"\n :aria-disabled=\"!isNativeButton && isDisabled ? 'true' : undefined\"\n :aria-busy=\"loading || undefined\"\n :tabindex=\"!isNativeButton && isDisabled ? -1 : undefined\"\n @click=\"onClick\"\n >\n <span\n v-if=\"loading\"\n class=\"t-button__spinner\"\n >\n <TSpinner\n size=\"sm\"\n label=\"Loading\"\n />\n </span>\n <span\n v-if=\"$slots.icon\"\n class=\"t-button__icon\"\n aria-hidden=\"true\"\n >\n <slot name=\"icon\" />\n </span>\n <span class=\"t-button__label\">\n <slot />\n </span>\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { tv } from '@treeui/utils';\nimport type { TSize, TVariant } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n variant?: TVariant;\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n type?: 'button' | 'submit' | 'reset';\n }>(),\n {\n as: 'button',\n variant: 'solid',\n size: 'md',\n disabled: false,\n loading: false,\n type: 'button',\n },\n);\n\nconst emit = defineEmits<{\n click: [event: MouseEvent];\n}>();\n\nconst buttonClass = tv({\n base: 't-button',\n variants: {\n variant: {\n solid: 't-button--solid',\n outline: 't-button--outline',\n ghost: 't-button--ghost',\n soft: 't-button--soft',\n danger: 't-button--danger',\n },\n size: {\n sm: 't-button--sm',\n md: 't-button--md',\n lg: 't-button--lg',\n },\n },\n});\n\nconst isNativeButton = computed(() => props.as === 'button');\nconst isDisabled = computed(() => props.disabled || props.loading);\nconst classes = computed(() =>\n buttonClass({\n variant: props.variant,\n size: props.size,\n class: {\n 'is-loading': props.loading,\n 'is-disabled': isDisabled.value,\n },\n }),\n);\n\nconst onClick = (event: MouseEvent) => {\n if (isDisabled.value) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n\n emit('click', event);\n};\n</script>\n\n<template>\n <component\n :is=\"as\"\n :type=\"isNativeButton ? type : undefined\"\n :class=\"classes\"\n :disabled=\"isNativeButton ? isDisabled : undefined\"\n :aria-disabled=\"!isNativeButton && isDisabled ? 'true' : undefined\"\n :aria-busy=\"loading || undefined\"\n :tabindex=\"!isNativeButton && isDisabled ? -1 : undefined\"\n @click=\"onClick\"\n >\n <span\n v-if=\"loading\"\n class=\"t-button__spinner\"\n >\n <TSpinner\n size=\"sm\"\n label=\"Loading\"\n />\n </span>\n <span\n v-if=\"$slots.icon\"\n class=\"t-button__icon\"\n aria-hidden=\"true\"\n >\n <slot name=\"icon\" />\n </span>\n <span class=\"t-button__label\">\n <slot />\n </span>\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TCardVariant, TSize } from '../types/contracts';\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n variant?: TCardVariant;\n size?: TSize;\n title?: string;\n }>(),\n {\n as: 'section',\n variant: 'outline',\n size: 'md',\n title: undefined,\n },\n);\n\nconst classes = computed(() => [\n 't-card',\n `t-card--${props.variant}`,\n `t-card--${props.size}`,\n]);\n\nconst hasHeader = computed(() => !!props.title);\n</script>\n\n<template>\n <component\n :is=\"as\"\n :class=\"classes\"\n >\n <header\n v-if=\"$slots.header || hasHeader || $slots.actions\"\n class=\"t-card__header\"\n >\n <slot name=\"header\">\n <span\n v-if=\"title\"\n class=\"t-card__title\"\n >\n {{ title }}\n </span>\n <span\n v-if=\"$slots.actions\"\n class=\"t-card__actions\"\n >\n <slot name=\"actions\" />\n </span>\n </slot>\n </header>\n <div class=\"t-card__body\">\n <slot />\n </div>\n <footer\n v-if=\"$slots.footer\"\n class=\"t-card__footer\"\n >\n <slot name=\"footer\" />\n </footer>\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TCardVariant, TSize } from '../types/contracts';\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n variant?: TCardVariant;\n size?: TSize;\n title?: string;\n }>(),\n {\n as: 'section',\n variant: 'outline',\n size: 'md',\n title: undefined,\n },\n);\n\nconst classes = computed(() => [\n 't-card',\n `t-card--${props.variant}`,\n `t-card--${props.size}`,\n]);\n\nconst hasHeader = computed(() => !!props.title);\n</script>\n\n<template>\n <component\n :is=\"as\"\n :class=\"classes\"\n >\n <header\n v-if=\"$slots.header || hasHeader || $slots.actions\"\n class=\"t-card__header\"\n >\n <slot name=\"header\">\n <span\n v-if=\"title\"\n class=\"t-card__title\"\n >\n {{ title }}\n </span>\n <span\n v-if=\"$slots.actions\"\n class=\"t-card__actions\"\n >\n <slot name=\"actions\" />\n </span>\n </slot>\n </header>\n <div class=\"t-card__body\">\n <slot />\n </div>\n <footer\n v-if=\"$slots.footer\"\n class=\"t-card__footer\"\n >\n <slot name=\"footer\" />\n </footer>\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref, useAttrs, watch } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: boolean;\n size?: TSize;\n disabled?: boolean;\n indeterminate?: boolean;\n invalid?: boolean;\n }>(),\n {\n modelValue: false,\n size: 'md',\n disabled: false,\n indeterminate: false,\n invalid: false,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: boolean];\n}>();\n\nconst attrs = useAttrs();\nconst inputRef = ref<HTMLInputElement | null>(null);\n\nwatch(\n () => props.indeterminate,\n (val) => {\n if (inputRef.value) {\n inputRef.value.indeterminate = val;\n }\n },\n);\n\nwatch(inputRef, (el) => {\n if (el) {\n el.indeterminate = props.indeterminate;\n }\n});\n\nconst rootClasses = computed(() => [\n 't-checkbox',\n `t-checkbox--${props.size}`,\n {\n 'is-checked': props.modelValue,\n 'is-indeterminate': props.indeterminate,\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst inputAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst onChange = () => {\n emit('update:modelValue', !props.modelValue);\n};\n</script>\n\n<template>\n <label\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <input\n ref=\"inputRef\"\n v-bind=\"inputAttrs\"\n type=\"checkbox\"\n class=\"t-checkbox__input\"\n :checked=\"modelValue\"\n :disabled=\"disabled\"\n :aria-checked=\"indeterminate ? 'mixed' : modelValue\"\n :aria-invalid=\"invalid || undefined\"\n @change=\"onChange\"\n >\n <span\n class=\"t-checkbox__control\"\n aria-hidden=\"true\"\n >\n <svg\n v-if=\"modelValue && !indeterminate\"\n class=\"t-checkbox__icon\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <polyline points=\"3.5 8.5 6.5 11.5 12.5 4.5\" />\n </svg>\n <svg\n v-else-if=\"indeterminate\"\n class=\"t-checkbox__icon\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n >\n <line\n x1=\"4\"\n y1=\"8\"\n x2=\"12\"\n y2=\"8\"\n />\n </svg>\n </span>\n <span\n v-if=\"$slots.default\"\n class=\"t-checkbox__label\"\n >\n <slot />\n </span>\n </label>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref, useAttrs, watch } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: boolean;\n size?: TSize;\n disabled?: boolean;\n indeterminate?: boolean;\n invalid?: boolean;\n }>(),\n {\n modelValue: false,\n size: 'md',\n disabled: false,\n indeterminate: false,\n invalid: false,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: boolean];\n}>();\n\nconst attrs = useAttrs();\nconst inputRef = ref<HTMLInputElement | null>(null);\n\nwatch(\n () => props.indeterminate,\n (val) => {\n if (inputRef.value) {\n inputRef.value.indeterminate = val;\n }\n },\n);\n\nwatch(inputRef, (el) => {\n if (el) {\n el.indeterminate = props.indeterminate;\n }\n});\n\nconst rootClasses = computed(() => [\n 't-checkbox',\n `t-checkbox--${props.size}`,\n {\n 'is-checked': props.modelValue,\n 'is-indeterminate': props.indeterminate,\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst inputAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst onChange = () => {\n emit('update:modelValue', !props.modelValue);\n};\n</script>\n\n<template>\n <label\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <input\n ref=\"inputRef\"\n v-bind=\"inputAttrs\"\n type=\"checkbox\"\n class=\"t-checkbox__input\"\n :checked=\"modelValue\"\n :disabled=\"disabled\"\n :aria-checked=\"indeterminate ? 'mixed' : modelValue\"\n :aria-invalid=\"invalid || undefined\"\n @change=\"onChange\"\n >\n <span\n class=\"t-checkbox__control\"\n aria-hidden=\"true\"\n >\n <svg\n v-if=\"modelValue && !indeterminate\"\n class=\"t-checkbox__icon\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <polyline points=\"3.5 8.5 6.5 11.5 12.5 4.5\" />\n </svg>\n <svg\n v-else-if=\"indeterminate\"\n class=\"t-checkbox__icon\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n >\n <line\n x1=\"4\"\n y1=\"8\"\n x2=\"12\"\n y2=\"8\"\n />\n </svg>\n </span>\n <span\n v-if=\"$slots.default\"\n class=\"t-checkbox__label\"\n >\n <slot />\n </span>\n </label>\n</template>\n","import { computed, ref, type Ref } from 'vue';\n\nexport const useControllableOpen = (\n controlledValue: Ref<boolean | undefined>,\n defaultValue: boolean,\n onChange: (value: boolean) => void,\n) => {\n const uncontrolledValue = ref(defaultValue);\n\n const value = computed(() => controlledValue.value ?? uncontrolledValue.value);\n\n const setValue = (nextValue: boolean) => {\n if (nextValue === value.value) {\n return;\n }\n\n if (controlledValue.value === undefined) {\n uncontrolledValue.value = nextValue;\n }\n\n onChange(nextValue);\n };\n\n return {\n value,\n setValue,\n };\n};\n\n","<script setup lang=\"ts\">\nimport { createId, isEscapeKey } from '@treeui/utils';\nimport { computed, onBeforeUnmount, ref, toRef, useAttrs, watch } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TComboboxOption {\n label: string;\n value: string;\n description?: string;\n keywords?: string[];\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n options?: TComboboxOption[];\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n placeholder?: string;\n emptyText?: string;\n }>(),\n {\n modelValue: '',\n options: () => [],\n open: undefined,\n defaultOpen: false,\n size: 'md',\n disabled: false,\n loading: false,\n invalid: false,\n placeholder: '',\n emptyText: 'No results found.',\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n 'input-change': [value: string];\n}>();\n\ndefineSlots<{\n prefix?: () => unknown;\n option?: (props: {\n option: TComboboxOption;\n selected: boolean;\n active: boolean;\n }) => unknown;\n empty?: (props: { query: string }) => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst listboxId = createId('t-combobox');\nconst rootRef = ref<HTMLElement | null>(null);\nconst activeIndex = ref(-1);\nconst query = ref('');\n\nconst normalize = (value: string) => value.trim().toLowerCase();\nconst getOptionId = (value: string) => `${listboxId}-option-${value}`;\n\nconst selectedOption = computed(() =>\n props.options.find((option) => option.value === props.modelValue),\n);\n\nconst selectedLabel = computed(() => selectedOption.value?.label ?? '');\n\nconst inputAttrs = computed(() => {\n const { class: _class, style: _style, autocomplete, ...rest } = attrs;\n return {\n autocomplete: typeof autocomplete === 'string' ? autocomplete : 'off',\n ...rest,\n };\n});\n\nconst listboxLabel = computed(() =>\n typeof attrs['aria-label'] === 'string' ? attrs['aria-label'] : undefined,\n);\n\nconst listboxLabelledby = computed(() =>\n typeof attrs['aria-labelledby'] === 'string' ? attrs['aria-labelledby'] : undefined,\n);\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-combobox',\n `t-combobox--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst filteredOptions = computed(() => {\n const normalizedQuery = normalize(query.value);\n\n if (!normalizedQuery) {\n return props.options;\n }\n\n return props.options.filter((option) => {\n const fields = [\n option.label,\n option.description ?? '',\n ...(option.keywords ?? []),\n ];\n\n return fields.some((field) => field.toLowerCase().includes(normalizedQuery));\n });\n});\n\nconst enabledFilteredIndexes = computed(() =>\n filteredOptions.value.reduce<number[]>((indexes, option, index) => {\n if (!option.disabled) {\n indexes.push(index);\n }\n\n return indexes;\n }, []),\n);\n\nconst activeOption = computed(() =>\n activeIndex.value >= 0 ? filteredOptions.value[activeIndex.value] : undefined,\n);\n\nconst activeDescendant = computed(() =>\n isOpen.value && activeOption.value ? getOptionId(activeOption.value.value) : undefined,\n);\n\nconst syncQueryFromSelection = () => {\n query.value = selectedLabel.value;\n};\n\nconst setInitialActiveIndex = (fallback: 'first' | 'last' = 'first') => {\n const selectedIndex = filteredOptions.value.findIndex((option) =>\n option.value === props.modelValue && !option.disabled,\n );\n\n if (selectedIndex >= 0) {\n activeIndex.value = selectedIndex;\n return;\n }\n\n if (enabledFilteredIndexes.value.length === 0) {\n activeIndex.value = -1;\n return;\n }\n\n activeIndex.value =\n fallback === 'last'\n ? enabledFilteredIndexes.value[enabledFilteredIndexes.value.length - 1]\n : enabledFilteredIndexes.value[0];\n};\n\nconst moveActive = (direction: 1 | -1) => {\n if (enabledFilteredIndexes.value.length === 0) {\n activeIndex.value = -1;\n return;\n }\n\n const currentEnabledIndex = enabledFilteredIndexes.value.indexOf(activeIndex.value);\n\n if (currentEnabledIndex === -1) {\n activeIndex.value =\n direction === 1\n ? enabledFilteredIndexes.value[0]\n : enabledFilteredIndexes.value[enabledFilteredIndexes.value.length - 1];\n return;\n }\n\n const nextEnabledIndex = currentEnabledIndex + direction;\n\n if (nextEnabledIndex < 0 || nextEnabledIndex >= enabledFilteredIndexes.value.length) {\n return;\n }\n\n activeIndex.value = enabledFilteredIndexes.value[nextEnabledIndex];\n};\n\nconst openListbox = (fallback: 'first' | 'last' = 'first') => {\n if (props.disabled) {\n return;\n }\n\n setValue(true);\n setInitialActiveIndex(fallback);\n};\n\nconst commitPendingClear = () => {\n if (query.value.trim() !== '' || !props.modelValue) {\n return false;\n }\n\n emit('update:modelValue', '');\n return true;\n};\n\nconst closeListbox = (restoreSelection = false) => {\n setValue(false);\n activeIndex.value = -1;\n\n if (!restoreSelection) {\n return;\n }\n\n if (commitPendingClear()) {\n return;\n }\n\n if (selectedLabel.value && query.value !== selectedLabel.value) {\n query.value = selectedLabel.value;\n }\n};\n\nconst selectOption = (option: TComboboxOption) => {\n if (option.disabled) {\n return;\n }\n\n query.value = option.label;\n emit('update:modelValue', option.value);\n closeListbox(false);\n};\n\nconst onInput = (event: Event) => {\n query.value = (event.target as HTMLInputElement).value;\n emit('input-change', query.value);\n\n if (props.disabled) {\n return;\n }\n\n if (!isOpen.value) {\n openListbox('first');\n return;\n }\n\n setInitialActiveIndex('first');\n};\n\nconst onInputFocus = () => {\n openListbox('first');\n};\n\nconst onInputClick = () => {\n if (!isOpen.value) {\n openListbox('first');\n }\n};\n\nconst onInputKeydown = (event: KeyboardEvent) => {\n if (props.disabled) {\n return;\n }\n\n if (isEscapeKey(event)) {\n if (isOpen.value) {\n event.preventDefault();\n closeListbox(true);\n }\n\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n\n if (!isOpen.value) {\n openListbox('first');\n } else {\n moveActive(1);\n }\n break;\n case 'ArrowUp':\n event.preventDefault();\n\n if (!isOpen.value) {\n openListbox('last');\n } else {\n moveActive(-1);\n }\n break;\n case 'Enter':\n if (isOpen.value && activeOption.value && !activeOption.value.disabled) {\n event.preventDefault();\n selectOption(activeOption.value);\n }\n break;\n case 'Home':\n if (!isOpen.value) return;\n event.preventDefault();\n setInitialActiveIndex('first');\n break;\n case 'End':\n if (!isOpen.value) return;\n event.preventDefault();\n setInitialActiveIndex('last');\n break;\n case 'Tab':\n closeListbox(true);\n break;\n default:\n break;\n }\n};\n\nconst onOptionPointerEnter = (index: number) => {\n const option = filteredOptions.value[index];\n\n if (option && !option.disabled) {\n activeIndex.value = index;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) return;\n const target = event.target;\n if (!(target instanceof Node)) return;\n if (rootRef.value?.contains(target)) return;\n closeListbox(true);\n};\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n } else {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n }\n});\n\nwatch(\n () => props.modelValue,\n () => {\n if (!isOpen.value) {\n syncQueryFromSelection();\n }\n },\n { immediate: true },\n);\n\nwatch(\n () => props.options,\n () => {\n if (!isOpen.value) {\n syncQueryFromSelection();\n return;\n }\n\n setInitialActiveIndex('first');\n },\n { deep: true },\n);\n\nwatch(filteredOptions, () => {\n if (!isOpen.value) {\n return;\n }\n\n if (filteredOptions.value.length === 0) {\n activeIndex.value = -1;\n return;\n }\n\n const current = filteredOptions.value[activeIndex.value];\n\n if (!current || current.disabled) {\n setInitialActiveIndex('first');\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <div class=\"t-combobox__control\">\n <span\n v-if=\"$slots.prefix\"\n class=\"t-combobox__slot t-combobox__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n <input\n v-bind=\"inputAttrs\"\n class=\"t-combobox__input\"\n role=\"combobox\"\n type=\"text\"\n :value=\"query\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? listboxId : undefined\"\n :aria-expanded=\"isOpen\"\n :aria-activedescendant=\"activeDescendant\"\n :aria-invalid=\"invalid || undefined\"\n :aria-busy=\"loading || undefined\"\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n @input=\"onInput\"\n @focus=\"onInputFocus\"\n @click=\"onInputClick\"\n @keydown=\"onInputKeydown\"\n >\n <TSpinner\n v-if=\"loading\"\n size=\"sm\"\n label=\"Loading\"\n />\n <svg\n v-else\n class=\"t-combobox__indicator\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"4 6 8 10 12 6\" />\n </svg>\n </div>\n\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"listboxId\"\n role=\"listbox\"\n class=\"t-combobox__listbox\"\n :aria-label=\"listboxLabel\"\n :aria-labelledby=\"listboxLabelledby\"\n >\n <li\n v-if=\"filteredOptions.length === 0\"\n class=\"t-combobox__empty\"\n >\n <slot\n name=\"empty\"\n :query=\"query\"\n >\n {{ emptyText }}\n </slot>\n </li>\n\n <template v-else>\n <li\n v-for=\"(option, index) in filteredOptions\"\n :id=\"getOptionId(option.value)\"\n :key=\"option.value\"\n role=\"option\"\n class=\"t-combobox__option\"\n :class=\"{\n 'is-active': index === activeIndex,\n 'is-disabled': option.disabled,\n 'is-selected': option.value === modelValue,\n }\"\n :aria-selected=\"option.value === modelValue\"\n :aria-disabled=\"option.disabled || undefined\"\n @mouseenter=\"onOptionPointerEnter(index)\"\n @click=\"selectOption(option)\"\n >\n <slot\n name=\"option\"\n :option=\"option\"\n :selected=\"option.value === modelValue\"\n :active=\"index === activeIndex\"\n >\n <span class=\"t-combobox__option-copy\">\n <span class=\"t-combobox__option-label\">{{ option.label }}</span>\n <span\n v-if=\"option.description\"\n class=\"t-combobox__option-description\"\n >\n {{ option.description }}\n </span>\n </span>\n <svg\n v-if=\"option.value === modelValue\"\n class=\"t-combobox__check\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"3.5 8.5 6.5 11.5 12.5 4.5\" />\n </svg>\n </slot>\n </li>\n </template>\n </ul>\n </transition>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { createId, isEscapeKey } from '@treeui/utils';\nimport { computed, onBeforeUnmount, ref, toRef, useAttrs, watch } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TComboboxOption {\n label: string;\n value: string;\n description?: string;\n keywords?: string[];\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n options?: TComboboxOption[];\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n placeholder?: string;\n emptyText?: string;\n }>(),\n {\n modelValue: '',\n options: () => [],\n open: undefined,\n defaultOpen: false,\n size: 'md',\n disabled: false,\n loading: false,\n invalid: false,\n placeholder: '',\n emptyText: 'No results found.',\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n 'input-change': [value: string];\n}>();\n\ndefineSlots<{\n prefix?: () => unknown;\n option?: (props: {\n option: TComboboxOption;\n selected: boolean;\n active: boolean;\n }) => unknown;\n empty?: (props: { query: string }) => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst listboxId = createId('t-combobox');\nconst rootRef = ref<HTMLElement | null>(null);\nconst activeIndex = ref(-1);\nconst query = ref('');\n\nconst normalize = (value: string) => value.trim().toLowerCase();\nconst getOptionId = (value: string) => `${listboxId}-option-${value}`;\n\nconst selectedOption = computed(() =>\n props.options.find((option) => option.value === props.modelValue),\n);\n\nconst selectedLabel = computed(() => selectedOption.value?.label ?? '');\n\nconst inputAttrs = computed(() => {\n const { class: _class, style: _style, autocomplete, ...rest } = attrs;\n return {\n autocomplete: typeof autocomplete === 'string' ? autocomplete : 'off',\n ...rest,\n };\n});\n\nconst listboxLabel = computed(() =>\n typeof attrs['aria-label'] === 'string' ? attrs['aria-label'] : undefined,\n);\n\nconst listboxLabelledby = computed(() =>\n typeof attrs['aria-labelledby'] === 'string' ? attrs['aria-labelledby'] : undefined,\n);\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-combobox',\n `t-combobox--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst filteredOptions = computed(() => {\n const normalizedQuery = normalize(query.value);\n\n if (!normalizedQuery) {\n return props.options;\n }\n\n return props.options.filter((option) => {\n const fields = [\n option.label,\n option.description ?? '',\n ...(option.keywords ?? []),\n ];\n\n return fields.some((field) => field.toLowerCase().includes(normalizedQuery));\n });\n});\n\nconst enabledFilteredIndexes = computed(() =>\n filteredOptions.value.reduce<number[]>((indexes, option, index) => {\n if (!option.disabled) {\n indexes.push(index);\n }\n\n return indexes;\n }, []),\n);\n\nconst activeOption = computed(() =>\n activeIndex.value >= 0 ? filteredOptions.value[activeIndex.value] : undefined,\n);\n\nconst activeDescendant = computed(() =>\n isOpen.value && activeOption.value ? getOptionId(activeOption.value.value) : undefined,\n);\n\nconst syncQueryFromSelection = () => {\n query.value = selectedLabel.value;\n};\n\nconst setInitialActiveIndex = (fallback: 'first' | 'last' = 'first') => {\n const selectedIndex = filteredOptions.value.findIndex((option) =>\n option.value === props.modelValue && !option.disabled,\n );\n\n if (selectedIndex >= 0) {\n activeIndex.value = selectedIndex;\n return;\n }\n\n if (enabledFilteredIndexes.value.length === 0) {\n activeIndex.value = -1;\n return;\n }\n\n activeIndex.value =\n fallback === 'last'\n ? enabledFilteredIndexes.value[enabledFilteredIndexes.value.length - 1]\n : enabledFilteredIndexes.value[0];\n};\n\nconst moveActive = (direction: 1 | -1) => {\n if (enabledFilteredIndexes.value.length === 0) {\n activeIndex.value = -1;\n return;\n }\n\n const currentEnabledIndex = enabledFilteredIndexes.value.indexOf(activeIndex.value);\n\n if (currentEnabledIndex === -1) {\n activeIndex.value =\n direction === 1\n ? enabledFilteredIndexes.value[0]\n : enabledFilteredIndexes.value[enabledFilteredIndexes.value.length - 1];\n return;\n }\n\n const nextEnabledIndex = currentEnabledIndex + direction;\n\n if (nextEnabledIndex < 0 || nextEnabledIndex >= enabledFilteredIndexes.value.length) {\n return;\n }\n\n activeIndex.value = enabledFilteredIndexes.value[nextEnabledIndex];\n};\n\nconst openListbox = (fallback: 'first' | 'last' = 'first') => {\n if (props.disabled) {\n return;\n }\n\n setValue(true);\n setInitialActiveIndex(fallback);\n};\n\nconst commitPendingClear = () => {\n if (query.value.trim() !== '' || !props.modelValue) {\n return false;\n }\n\n emit('update:modelValue', '');\n return true;\n};\n\nconst closeListbox = (restoreSelection = false) => {\n setValue(false);\n activeIndex.value = -1;\n\n if (!restoreSelection) {\n return;\n }\n\n if (commitPendingClear()) {\n return;\n }\n\n if (selectedLabel.value && query.value !== selectedLabel.value) {\n query.value = selectedLabel.value;\n }\n};\n\nconst selectOption = (option: TComboboxOption) => {\n if (option.disabled) {\n return;\n }\n\n query.value = option.label;\n emit('update:modelValue', option.value);\n closeListbox(false);\n};\n\nconst onInput = (event: Event) => {\n query.value = (event.target as HTMLInputElement).value;\n emit('input-change', query.value);\n\n if (props.disabled) {\n return;\n }\n\n if (!isOpen.value) {\n openListbox('first');\n return;\n }\n\n setInitialActiveIndex('first');\n};\n\nconst onInputFocus = () => {\n openListbox('first');\n};\n\nconst onInputClick = () => {\n if (!isOpen.value) {\n openListbox('first');\n }\n};\n\nconst onInputKeydown = (event: KeyboardEvent) => {\n if (props.disabled) {\n return;\n }\n\n if (isEscapeKey(event)) {\n if (isOpen.value) {\n event.preventDefault();\n closeListbox(true);\n }\n\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n\n if (!isOpen.value) {\n openListbox('first');\n } else {\n moveActive(1);\n }\n break;\n case 'ArrowUp':\n event.preventDefault();\n\n if (!isOpen.value) {\n openListbox('last');\n } else {\n moveActive(-1);\n }\n break;\n case 'Enter':\n if (isOpen.value && activeOption.value && !activeOption.value.disabled) {\n event.preventDefault();\n selectOption(activeOption.value);\n }\n break;\n case 'Home':\n if (!isOpen.value) return;\n event.preventDefault();\n setInitialActiveIndex('first');\n break;\n case 'End':\n if (!isOpen.value) return;\n event.preventDefault();\n setInitialActiveIndex('last');\n break;\n case 'Tab':\n closeListbox(true);\n break;\n default:\n break;\n }\n};\n\nconst onOptionPointerEnter = (index: number) => {\n const option = filteredOptions.value[index];\n\n if (option && !option.disabled) {\n activeIndex.value = index;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) return;\n const target = event.target;\n if (!(target instanceof Node)) return;\n if (rootRef.value?.contains(target)) return;\n closeListbox(true);\n};\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n } else {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n }\n});\n\nwatch(\n () => props.modelValue,\n () => {\n if (!isOpen.value) {\n syncQueryFromSelection();\n }\n },\n { immediate: true },\n);\n\nwatch(\n () => props.options,\n () => {\n if (!isOpen.value) {\n syncQueryFromSelection();\n return;\n }\n\n setInitialActiveIndex('first');\n },\n { deep: true },\n);\n\nwatch(filteredOptions, () => {\n if (!isOpen.value) {\n return;\n }\n\n if (filteredOptions.value.length === 0) {\n activeIndex.value = -1;\n return;\n }\n\n const current = filteredOptions.value[activeIndex.value];\n\n if (!current || current.disabled) {\n setInitialActiveIndex('first');\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <div class=\"t-combobox__control\">\n <span\n v-if=\"$slots.prefix\"\n class=\"t-combobox__slot t-combobox__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n <input\n v-bind=\"inputAttrs\"\n class=\"t-combobox__input\"\n role=\"combobox\"\n type=\"text\"\n :value=\"query\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? listboxId : undefined\"\n :aria-expanded=\"isOpen\"\n :aria-activedescendant=\"activeDescendant\"\n :aria-invalid=\"invalid || undefined\"\n :aria-busy=\"loading || undefined\"\n aria-autocomplete=\"list\"\n aria-haspopup=\"listbox\"\n @input=\"onInput\"\n @focus=\"onInputFocus\"\n @click=\"onInputClick\"\n @keydown=\"onInputKeydown\"\n >\n <TSpinner\n v-if=\"loading\"\n size=\"sm\"\n label=\"Loading\"\n />\n <svg\n v-else\n class=\"t-combobox__indicator\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"4 6 8 10 12 6\" />\n </svg>\n </div>\n\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"listboxId\"\n role=\"listbox\"\n class=\"t-combobox__listbox\"\n :aria-label=\"listboxLabel\"\n :aria-labelledby=\"listboxLabelledby\"\n >\n <li\n v-if=\"filteredOptions.length === 0\"\n class=\"t-combobox__empty\"\n >\n <slot\n name=\"empty\"\n :query=\"query\"\n >\n {{ emptyText }}\n </slot>\n </li>\n\n <template v-else>\n <li\n v-for=\"(option, index) in filteredOptions\"\n :id=\"getOptionId(option.value)\"\n :key=\"option.value\"\n role=\"option\"\n class=\"t-combobox__option\"\n :class=\"{\n 'is-active': index === activeIndex,\n 'is-disabled': option.disabled,\n 'is-selected': option.value === modelValue,\n }\"\n :aria-selected=\"option.value === modelValue\"\n :aria-disabled=\"option.disabled || undefined\"\n @mouseenter=\"onOptionPointerEnter(index)\"\n @click=\"selectOption(option)\"\n >\n <slot\n name=\"option\"\n :option=\"option\"\n :selected=\"option.value === modelValue\"\n :active=\"index === activeIndex\"\n >\n <span class=\"t-combobox__option-copy\">\n <span class=\"t-combobox__option-label\">{{ option.label }}</span>\n <span\n v-if=\"option.description\"\n class=\"t-combobox__option-description\"\n >\n {{ option.description }}\n </span>\n </span>\n <svg\n v-if=\"option.value === modelValue\"\n class=\"t-combobox__check\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"3.5 8.5 6.5 11.5 12.5 4.5\" />\n </svg>\n </slot>\n </li>\n </template>\n </ul>\n </transition>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport {\n createId,\n focusFirst,\n focusLast,\n getFocusableElements,\n isEscapeKey,\n} from '@treeui/utils';\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport {\n computed,\n nextTick,\n onBeforeUnmount,\n ref,\n toRef,\n useAttrs,\n watch,\n} from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst CloseIcon = getTreeIcon('x');\n\nconst props = withDefaults(\n defineProps<{\n open?: boolean;\n defaultOpen?: boolean;\n disabled?: boolean;\n size?: TSize;\n title?: string;\n description?: string;\n closeOnEscape?: boolean;\n closeOnOverlay?: boolean;\n showCloseButton?: boolean;\n closeLabel?: string;\n id?: string;\n }>(),\n {\n open: undefined,\n defaultOpen: false,\n disabled: false,\n size: 'md',\n title: '',\n description: '',\n closeOnEscape: true,\n closeOnOverlay: true,\n showCloseButton: true,\n closeLabel: 'Close modal',\n id: undefined,\n },\n);\n\nconst emit = defineEmits<{\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\nconst attrs = useAttrs();\nconst modalId = props.id ?? createId('t-modal');\nconst titleId = `${modalId}-title`;\nconst descriptionId = `${modalId}-description`;\nconst rootRef = ref<HTMLElement | null>(null);\nconst surfaceRef = ref<HTMLElement | null>(null);\nconst previousFocusedElement = ref<HTMLElement | null>(null);\nconst hasHeaderContent = computed(() => Boolean(props.title || slots.header));\n\nconst slots = defineSlots<{\n default?: () => unknown;\n trigger?: () => unknown;\n header?: () => unknown;\n content?: () => unknown;\n footer?: () => unknown;\n}>();\n\nconst rootClasses = computed(() => ['t-modal', attrs.class]);\nconst rootStyle = computed(() => attrs.style);\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\nconst surfaceClasses = computed(() => [\n 't-modal__surface',\n `t-modal__surface--${props.size}`,\n]);\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst labelledBy = computed(() => (hasHeaderContent.value ? titleId : undefined));\nconst describedBy = computed(() => (props.description ? descriptionId : undefined));\n\nlet openOverlayCount = 0;\nlet previousBodyOverflow = '';\n\nconst lockBodyScroll = () => {\n if (typeof document === 'undefined') {\n return;\n }\n\n if (openOverlayCount === 0) {\n previousBodyOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n }\n\n openOverlayCount += 1;\n};\n\nconst unlockBodyScroll = () => {\n if (typeof document === 'undefined' || openOverlayCount === 0) {\n return;\n }\n\n openOverlayCount -= 1;\n\n if (openOverlayCount === 0) {\n document.body.style.overflow = previousBodyOverflow;\n }\n};\n\nconst focusSurface = () => {\n nextTick(() => {\n if (!surfaceRef.value) {\n return;\n }\n\n const focused = focusFirst(surfaceRef.value);\n if (!focused) {\n surfaceRef.value.focus();\n }\n });\n};\n\nconst openModal = () => {\n if (props.disabled) {\n return;\n }\n\n previousFocusedElement.value = document.activeElement as HTMLElement | null;\n setValue(true);\n};\n\nconst closeModal = () => {\n setValue(false);\n};\n\nconst onTriggerClick = (event: MouseEvent) => {\n if (props.disabled) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n\n if (event.defaultPrevented) {\n return;\n }\n\n openModal();\n};\n\nconst onOverlayClick = () => {\n if (!props.closeOnOverlay) {\n return;\n }\n\n closeModal();\n};\n\nconst onSurfaceClick = (event: MouseEvent) => {\n event.stopPropagation();\n};\n\nconst onKeydown = (event: KeyboardEvent) => {\n if (isEscapeKey(event) && props.closeOnEscape) {\n event.preventDefault();\n closeModal();\n return;\n }\n\n if (event.key !== 'Tab' || !surfaceRef.value) {\n return;\n }\n\n const focusable = getFocusableElements(surfaceRef.value);\n\n if (!focusable.length) {\n event.preventDefault();\n surfaceRef.value.focus();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const activeElement = document.activeElement as HTMLElement | null;\n\n if (event.shiftKey && activeElement === first) {\n event.preventDefault();\n focusLast(surfaceRef.value);\n }\n\n if (!event.shiftKey && activeElement === last) {\n event.preventDefault();\n focusFirst(surfaceRef.value);\n }\n};\n\nwatch(isOpen, (value, previousValue) => {\n if (value) {\n lockBodyScroll();\n focusSurface();\n return;\n }\n\n if (previousValue) {\n unlockBodyScroll();\n nextTick(() => {\n previousFocusedElement.value?.focus();\n });\n }\n});\n\nonBeforeUnmount(() => {\n if (isOpen.value) {\n unlockBodyScroll();\n }\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <span\n v-if=\"$slots.trigger\"\n class=\"t-modal__trigger\"\n v-bind=\"triggerAttrs\"\n :aria-disabled=\"disabled || undefined\"\n @click=\"onTriggerClick\"\n >\n <slot name=\"trigger\" />\n </span>\n\n <Teleport to=\"body\">\n <transition name=\"t-modal-fade\">\n <div\n v-if=\"isOpen\"\n class=\"t-modal__portal\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <div\n class=\"t-modal__backdrop\"\n aria-hidden=\"true\"\n @click=\"onOverlayClick\"\n />\n <div class=\"t-modal__positioner\">\n <div\n :id=\"modalId\"\n ref=\"surfaceRef\"\n :class=\"surfaceClasses\"\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-labelledby=\"labelledBy\"\n :aria-describedby=\"describedBy\"\n tabindex=\"-1\"\n @click=\"onSurfaceClick\"\n @keydown=\"onKeydown\"\n >\n <div\n v-if=\"hasHeaderContent || showCloseButton\"\n class=\"t-modal__topbar\"\n >\n <div\n v-if=\"hasHeaderContent\"\n :id=\"titleId\"\n class=\"t-modal__header\"\n >\n <slot name=\"header\">\n <h2 class=\"t-modal__title\">\n {{ title }}\n </h2>\n </slot>\n </div>\n <button\n v-if=\"showCloseButton\"\n type=\"button\"\n class=\"t-modal__close\"\n :aria-label=\"closeLabel\"\n @click=\"closeModal\"\n >\n <CloseIcon v-bind=\"treeIconDefaults\" />\n </button>\n </div>\n\n <p\n v-if=\"description\"\n :id=\"descriptionId\"\n class=\"t-modal__description\"\n >\n {{ description }}\n </p>\n\n <div class=\"t-modal__body\">\n <slot name=\"content\">\n <slot />\n </slot>\n </div>\n\n <div\n v-if=\"$slots.footer\"\n class=\"t-modal__footer\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n </div>\n </div>\n </transition>\n </Teleport>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport {\n createId,\n focusFirst,\n focusLast,\n getFocusableElements,\n isEscapeKey,\n} from '@treeui/utils';\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport {\n computed,\n nextTick,\n onBeforeUnmount,\n ref,\n toRef,\n useAttrs,\n watch,\n} from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst CloseIcon = getTreeIcon('x');\n\nconst props = withDefaults(\n defineProps<{\n open?: boolean;\n defaultOpen?: boolean;\n disabled?: boolean;\n size?: TSize;\n title?: string;\n description?: string;\n closeOnEscape?: boolean;\n closeOnOverlay?: boolean;\n showCloseButton?: boolean;\n closeLabel?: string;\n id?: string;\n }>(),\n {\n open: undefined,\n defaultOpen: false,\n disabled: false,\n size: 'md',\n title: '',\n description: '',\n closeOnEscape: true,\n closeOnOverlay: true,\n showCloseButton: true,\n closeLabel: 'Close modal',\n id: undefined,\n },\n);\n\nconst emit = defineEmits<{\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\nconst attrs = useAttrs();\nconst modalId = props.id ?? createId('t-modal');\nconst titleId = `${modalId}-title`;\nconst descriptionId = `${modalId}-description`;\nconst rootRef = ref<HTMLElement | null>(null);\nconst surfaceRef = ref<HTMLElement | null>(null);\nconst previousFocusedElement = ref<HTMLElement | null>(null);\nconst hasHeaderContent = computed(() => Boolean(props.title || slots.header));\n\nconst slots = defineSlots<{\n default?: () => unknown;\n trigger?: () => unknown;\n header?: () => unknown;\n content?: () => unknown;\n footer?: () => unknown;\n}>();\n\nconst rootClasses = computed(() => ['t-modal', attrs.class]);\nconst rootStyle = computed(() => attrs.style);\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\nconst surfaceClasses = computed(() => [\n 't-modal__surface',\n `t-modal__surface--${props.size}`,\n]);\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst labelledBy = computed(() => (hasHeaderContent.value ? titleId : undefined));\nconst describedBy = computed(() => (props.description ? descriptionId : undefined));\n\nlet openOverlayCount = 0;\nlet previousBodyOverflow = '';\n\nconst lockBodyScroll = () => {\n if (typeof document === 'undefined') {\n return;\n }\n\n if (openOverlayCount === 0) {\n previousBodyOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n }\n\n openOverlayCount += 1;\n};\n\nconst unlockBodyScroll = () => {\n if (typeof document === 'undefined' || openOverlayCount === 0) {\n return;\n }\n\n openOverlayCount -= 1;\n\n if (openOverlayCount === 0) {\n document.body.style.overflow = previousBodyOverflow;\n }\n};\n\nconst focusSurface = () => {\n nextTick(() => {\n if (!surfaceRef.value) {\n return;\n }\n\n const focused = focusFirst(surfaceRef.value);\n if (!focused) {\n surfaceRef.value.focus();\n }\n });\n};\n\nconst openModal = () => {\n if (props.disabled) {\n return;\n }\n\n previousFocusedElement.value = document.activeElement as HTMLElement | null;\n setValue(true);\n};\n\nconst closeModal = () => {\n setValue(false);\n};\n\nconst onTriggerClick = (event: MouseEvent) => {\n if (props.disabled) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n\n if (event.defaultPrevented) {\n return;\n }\n\n openModal();\n};\n\nconst onOverlayClick = () => {\n if (!props.closeOnOverlay) {\n return;\n }\n\n closeModal();\n};\n\nconst onSurfaceClick = (event: MouseEvent) => {\n event.stopPropagation();\n};\n\nconst onKeydown = (event: KeyboardEvent) => {\n if (isEscapeKey(event) && props.closeOnEscape) {\n event.preventDefault();\n closeModal();\n return;\n }\n\n if (event.key !== 'Tab' || !surfaceRef.value) {\n return;\n }\n\n const focusable = getFocusableElements(surfaceRef.value);\n\n if (!focusable.length) {\n event.preventDefault();\n surfaceRef.value.focus();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const activeElement = document.activeElement as HTMLElement | null;\n\n if (event.shiftKey && activeElement === first) {\n event.preventDefault();\n focusLast(surfaceRef.value);\n }\n\n if (!event.shiftKey && activeElement === last) {\n event.preventDefault();\n focusFirst(surfaceRef.value);\n }\n};\n\nwatch(isOpen, (value, previousValue) => {\n if (value) {\n lockBodyScroll();\n focusSurface();\n return;\n }\n\n if (previousValue) {\n unlockBodyScroll();\n nextTick(() => {\n previousFocusedElement.value?.focus();\n });\n }\n});\n\nonBeforeUnmount(() => {\n if (isOpen.value) {\n unlockBodyScroll();\n }\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <span\n v-if=\"$slots.trigger\"\n class=\"t-modal__trigger\"\n v-bind=\"triggerAttrs\"\n :aria-disabled=\"disabled || undefined\"\n @click=\"onTriggerClick\"\n >\n <slot name=\"trigger\" />\n </span>\n\n <Teleport to=\"body\">\n <transition name=\"t-modal-fade\">\n <div\n v-if=\"isOpen\"\n class=\"t-modal__portal\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <div\n class=\"t-modal__backdrop\"\n aria-hidden=\"true\"\n @click=\"onOverlayClick\"\n />\n <div class=\"t-modal__positioner\">\n <div\n :id=\"modalId\"\n ref=\"surfaceRef\"\n :class=\"surfaceClasses\"\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-labelledby=\"labelledBy\"\n :aria-describedby=\"describedBy\"\n tabindex=\"-1\"\n @click=\"onSurfaceClick\"\n @keydown=\"onKeydown\"\n >\n <div\n v-if=\"hasHeaderContent || showCloseButton\"\n class=\"t-modal__topbar\"\n >\n <div\n v-if=\"hasHeaderContent\"\n :id=\"titleId\"\n class=\"t-modal__header\"\n >\n <slot name=\"header\">\n <h2 class=\"t-modal__title\">\n {{ title }}\n </h2>\n </slot>\n </div>\n <button\n v-if=\"showCloseButton\"\n type=\"button\"\n class=\"t-modal__close\"\n :aria-label=\"closeLabel\"\n @click=\"closeModal\"\n >\n <CloseIcon v-bind=\"treeIconDefaults\" />\n </button>\n </div>\n\n <p\n v-if=\"description\"\n :id=\"descriptionId\"\n class=\"t-modal__description\"\n >\n {{ description }}\n </p>\n\n <div class=\"t-modal__body\">\n <slot name=\"content\">\n <slot />\n </slot>\n </div>\n\n <div\n v-if=\"$slots.footer\"\n class=\"t-modal__footer\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n </div>\n </div>\n </transition>\n </Teleport>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, toRef, useAttrs } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize, TVariant } from '../types/contracts';\nimport TButton from './TButton.vue';\nimport TModal from './TModal.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst slots = defineSlots<{\n trigger?: () => unknown;\n icon?: () => unknown;\n default?: () => unknown;\n actions?: (props: {\n confirm: () => void;\n cancel: () => void;\n loading: boolean;\n }) => unknown;\n}>();\n\nconst props = withDefaults(\n defineProps<{\n open?: boolean;\n defaultOpen?: boolean;\n disabled?: boolean;\n size?: TSize;\n title?: string;\n description?: string;\n confirmLabel?: string;\n cancelLabel?: string;\n confirmVariant?: TVariant;\n confirmDisabled?: boolean;\n cancelDisabled?: boolean;\n loading?: boolean;\n closeOnEscape?: boolean;\n closeOnOverlay?: boolean;\n showCloseButton?: boolean;\n closeLabel?: string;\n closeOnConfirm?: boolean;\n closeOnCancel?: boolean;\n }>(),\n {\n open: undefined,\n defaultOpen: false,\n disabled: false,\n size: 'sm',\n title: '',\n description: '',\n confirmLabel: 'Confirm',\n cancelLabel: 'Cancel',\n confirmVariant: 'danger',\n confirmDisabled: false,\n cancelDisabled: false,\n loading: false,\n closeOnEscape: true,\n closeOnOverlay: false,\n showCloseButton: false,\n closeLabel: 'Close dialog',\n closeOnConfirm: true,\n closeOnCancel: true,\n },\n);\n\nconst emit = defineEmits<{\n confirm: [];\n cancel: [];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\nconst attrs = useAttrs();\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst dialogClasses = computed(() => [\n 't-confirm-dialog',\n {\n 't-confirm-dialog--with-icon': Boolean(slots.icon),\n },\n]);\n\nconst hasBodyContent = computed(() => Boolean(slots.default));\n\nconst closeDialog = () => {\n setValue(false);\n};\n\nconst syncOpen = (value: boolean) => {\n setValue(value);\n};\n\nconst handleCancel = () => {\n if (props.cancelDisabled) {\n return;\n }\n\n emit('cancel');\n\n if (props.closeOnCancel) {\n closeDialog();\n }\n};\n\nconst handleConfirm = () => {\n if (props.confirmDisabled || props.loading) {\n return;\n }\n\n emit('confirm');\n\n if (props.closeOnConfirm) {\n closeDialog();\n }\n};\n</script>\n\n<template>\n <TModal\n v-bind=\"attrs\"\n :open=\"isOpen\"\n :disabled=\"disabled\"\n :size=\"size\"\n :title=\"title\"\n :description=\"description\"\n :close-on-escape=\"closeOnEscape\"\n :close-on-overlay=\"closeOnOverlay\"\n :show-close-button=\"showCloseButton\"\n :close-label=\"closeLabel\"\n @update:open=\"syncOpen\"\n >\n <template\n v-if=\"$slots.trigger\"\n #trigger\n >\n <slot name=\"trigger\" />\n </template>\n\n <template #content>\n <div :class=\"dialogClasses\">\n <div\n v-if=\"$slots.icon\"\n class=\"t-confirm-dialog__icon\"\n aria-hidden=\"true\"\n >\n <slot name=\"icon\" />\n </div>\n\n <div\n v-if=\"hasBodyContent\"\n class=\"t-confirm-dialog__body\"\n >\n <slot />\n </div>\n </div>\n </template>\n\n <template #footer>\n <slot\n name=\"actions\"\n :confirm=\"handleConfirm\"\n :cancel=\"handleCancel\"\n :loading=\"loading\"\n >\n <TButton\n variant=\"ghost\"\n :disabled=\"cancelDisabled\"\n @click=\"handleCancel\"\n >\n {{ cancelLabel }}\n </TButton>\n <TButton\n :variant=\"confirmVariant\"\n :loading=\"loading\"\n :disabled=\"confirmDisabled\"\n @click=\"handleConfirm\"\n >\n {{ confirmLabel }}\n </TButton>\n </slot>\n </template>\n </TModal>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, toRef, useAttrs } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize, TVariant } from '../types/contracts';\nimport TButton from './TButton.vue';\nimport TModal from './TModal.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst slots = defineSlots<{\n trigger?: () => unknown;\n icon?: () => unknown;\n default?: () => unknown;\n actions?: (props: {\n confirm: () => void;\n cancel: () => void;\n loading: boolean;\n }) => unknown;\n}>();\n\nconst props = withDefaults(\n defineProps<{\n open?: boolean;\n defaultOpen?: boolean;\n disabled?: boolean;\n size?: TSize;\n title?: string;\n description?: string;\n confirmLabel?: string;\n cancelLabel?: string;\n confirmVariant?: TVariant;\n confirmDisabled?: boolean;\n cancelDisabled?: boolean;\n loading?: boolean;\n closeOnEscape?: boolean;\n closeOnOverlay?: boolean;\n showCloseButton?: boolean;\n closeLabel?: string;\n closeOnConfirm?: boolean;\n closeOnCancel?: boolean;\n }>(),\n {\n open: undefined,\n defaultOpen: false,\n disabled: false,\n size: 'sm',\n title: '',\n description: '',\n confirmLabel: 'Confirm',\n cancelLabel: 'Cancel',\n confirmVariant: 'danger',\n confirmDisabled: false,\n cancelDisabled: false,\n loading: false,\n closeOnEscape: true,\n closeOnOverlay: false,\n showCloseButton: false,\n closeLabel: 'Close dialog',\n closeOnConfirm: true,\n closeOnCancel: true,\n },\n);\n\nconst emit = defineEmits<{\n confirm: [];\n cancel: [];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\nconst attrs = useAttrs();\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst dialogClasses = computed(() => [\n 't-confirm-dialog',\n {\n 't-confirm-dialog--with-icon': Boolean(slots.icon),\n },\n]);\n\nconst hasBodyContent = computed(() => Boolean(slots.default));\n\nconst closeDialog = () => {\n setValue(false);\n};\n\nconst syncOpen = (value: boolean) => {\n setValue(value);\n};\n\nconst handleCancel = () => {\n if (props.cancelDisabled) {\n return;\n }\n\n emit('cancel');\n\n if (props.closeOnCancel) {\n closeDialog();\n }\n};\n\nconst handleConfirm = () => {\n if (props.confirmDisabled || props.loading) {\n return;\n }\n\n emit('confirm');\n\n if (props.closeOnConfirm) {\n closeDialog();\n }\n};\n</script>\n\n<template>\n <TModal\n v-bind=\"attrs\"\n :open=\"isOpen\"\n :disabled=\"disabled\"\n :size=\"size\"\n :title=\"title\"\n :description=\"description\"\n :close-on-escape=\"closeOnEscape\"\n :close-on-overlay=\"closeOnOverlay\"\n :show-close-button=\"showCloseButton\"\n :close-label=\"closeLabel\"\n @update:open=\"syncOpen\"\n >\n <template\n v-if=\"$slots.trigger\"\n #trigger\n >\n <slot name=\"trigger\" />\n </template>\n\n <template #content>\n <div :class=\"dialogClasses\">\n <div\n v-if=\"$slots.icon\"\n class=\"t-confirm-dialog__icon\"\n aria-hidden=\"true\"\n >\n <slot name=\"icon\" />\n </div>\n\n <div\n v-if=\"hasBodyContent\"\n class=\"t-confirm-dialog__body\"\n >\n <slot />\n </div>\n </div>\n </template>\n\n <template #footer>\n <slot\n name=\"actions\"\n :confirm=\"handleConfirm\"\n :cancel=\"handleCancel\"\n :loading=\"loading\"\n >\n <TButton\n variant=\"ghost\"\n :disabled=\"cancelDisabled\"\n @click=\"handleCancel\"\n >\n {{ cancelLabel }}\n </TButton>\n <TButton\n :variant=\"confirmVariant\"\n :loading=\"loading\"\n :disabled=\"confirmDisabled\"\n @click=\"handleConfirm\"\n >\n {{ confirmLabel }}\n </TButton>\n </slot>\n </template>\n </TModal>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst _treeContainerSizes = ['sm', 'md', 'lg', 'xl', 'full'] as const;\n\nexport type TContainerSize = (typeof _treeContainerSizes)[number];\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n size?: TContainerSize;\n padded?: boolean;\n centered?: boolean;\n }>(),\n {\n as: 'div',\n size: 'lg',\n padded: true,\n centered: true,\n },\n);\n\nconst attrs = useAttrs();\n\nconst rootClasses = computed(() => [\n 't-container',\n `t-container--${props.size}`,\n {\n 'is-padded': props.padded,\n 'is-centered': props.centered,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <slot />\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst _treeContainerSizes = ['sm', 'md', 'lg', 'xl', 'full'] as const;\n\nexport type TContainerSize = (typeof _treeContainerSizes)[number];\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n size?: TContainerSize;\n padded?: boolean;\n centered?: boolean;\n }>(),\n {\n as: 'div',\n size: 'lg',\n padded: true,\n centered: true,\n },\n);\n\nconst attrs = useAttrs();\n\nconst rootClasses = computed(() => [\n 't-container',\n `t-container--${props.size}`,\n {\n 'is-padded': props.padded,\n 'is-centered': props.centered,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <slot />\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { createId, isActivationKey, isEscapeKey } from '@treeui/utils';\nimport { computed, nextTick, onBeforeUnmount, ref, toRef, watch } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\n\nexport interface TContextMenuItem {\n label: string;\n value: string;\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n items?: TContextMenuItem[];\n open?: boolean;\n defaultOpen?: boolean;\n disabled?: boolean;\n size?: TSize;\n }>(),\n {\n items: () => [],\n open: undefined,\n defaultOpen: false,\n disabled: false,\n size: 'md',\n },\n);\n\nconst emit = defineEmits<{\n select: [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\ndefineSlots<{\n default(): unknown;\n item(props: { item: TContextMenuItem; index: number }): unknown;\n}>();\n\nconst menuId = createId('t-context-menu');\nconst rootRef = ref<HTMLElement | null>(null);\nconst itemRefs = ref<Map<string, HTMLElement>>(new Map());\nconst focusedIndex = ref(-1);\nconst menuPosition = ref({ x: 0, y: 0 });\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-context-menu',\n `t-context-menu--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-open': isOpen.value,\n },\n]);\n\nconst enabledItems = computed(() => props.items.filter((i) => !i.disabled));\n\nconst openMenu = (x: number, y: number) => {\n if (props.disabled) return;\n menuPosition.value = { x, y };\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n setValue(true);\n nextTick(() => focusItem(focusedIndex.value));\n};\n\nconst closeMenu = (restoreFocus = false) => {\n setValue(false);\n focusedIndex.value = -1;\n if (restoreFocus) {\n nextTick(() => rootRef.value?.focus());\n }\n};\n\nconst selectItem = (item: TContextMenuItem) => {\n if (item.disabled) return;\n emit('select', item.value);\n closeMenu(true);\n};\n\nconst focusItem = (index: number) => {\n const item = props.items[index];\n if (!item) return;\n const el = itemRefs.value.get(item.value);\n el?.focus();\n};\n\nconst setItemRef = (el: Element | null, value: string) => {\n if (el instanceof HTMLElement) {\n itemRefs.value.set(value, el);\n } else {\n itemRefs.value.delete(value);\n }\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n let nextIndex = focusedIndex.value + direction;\n while (nextIndex >= 0 && nextIndex < props.items.length) {\n if (!props.items[nextIndex].disabled) {\n focusedIndex.value = nextIndex;\n focusItem(nextIndex);\n return;\n }\n nextIndex += direction;\n }\n};\n\nconst onContextMenu = (event: MouseEvent) => {\n if (props.disabled) return;\n event.preventDefault();\n openMenu(event.clientX, event.clientY);\n};\n\nconst onItemKeydown = (event: KeyboardEvent, item: TContextMenuItem) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeMenu(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectItem(item);\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(-1);\n break;\n case 'Home':\n event.preventDefault();\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n focusItem(focusedIndex.value);\n break;\n case 'End':\n event.preventDefault();\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[enabledItems.value.length - 1])\n : props.items.length - 1;\n focusItem(focusedIndex.value);\n break;\n default:\n break;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) return;\n const target = event.target;\n if (!(target instanceof Node)) return;\n const menuEl = document.getElementById(menuId);\n if (menuEl?.contains(target)) return;\n closeMenu();\n};\n\nconst onDocumentContextMenu = (event: MouseEvent) => {\n if (!isOpen.value) return;\n const target = event.target;\n if (!(target instanceof Node)) return;\n if (rootRef.value?.contains(target)) return;\n closeMenu();\n};\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n document.addEventListener('contextmenu', onDocumentContextMenu);\n } else {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n document.removeEventListener('contextmenu', onDocumentContextMenu);\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n document.removeEventListener('contextmenu', onDocumentContextMenu);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n @contextmenu=\"onContextMenu\"\n >\n <slot />\n <Teleport to=\"body\">\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"menuId\"\n role=\"menu\"\n class=\"t-context-menu__menu\"\n :class=\"`t-context-menu--${size}`\"\n :style=\"{ top: `${menuPosition.y}px`, left: `${menuPosition.x}px` }\"\n aria-label=\"Context menu\"\n >\n <li\n v-for=\"(item, index) in items\"\n :key=\"item.value\"\n :ref=\"(el) => setItemRef(el as Element | null, item.value)\"\n role=\"menuitem\"\n class=\"t-context-menu__item\"\n :class=\"{\n 'is-disabled': item.disabled,\n 'is-focused': index === focusedIndex,\n }\"\n :aria-disabled=\"item.disabled || undefined\"\n :tabindex=\"item.disabled ? -1 : 0\"\n @click=\"selectItem(item)\"\n @keydown=\"onItemKeydown($event, item)\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :index=\"index\"\n >\n {{ item.label }}\n </slot>\n </li>\n </ul>\n </transition>\n </Teleport>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { createId, isActivationKey, isEscapeKey } from '@treeui/utils';\nimport { computed, nextTick, onBeforeUnmount, ref, toRef, watch } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\n\nexport interface TContextMenuItem {\n label: string;\n value: string;\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n items?: TContextMenuItem[];\n open?: boolean;\n defaultOpen?: boolean;\n disabled?: boolean;\n size?: TSize;\n }>(),\n {\n items: () => [],\n open: undefined,\n defaultOpen: false,\n disabled: false,\n size: 'md',\n },\n);\n\nconst emit = defineEmits<{\n select: [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\ndefineSlots<{\n default(): unknown;\n item(props: { item: TContextMenuItem; index: number }): unknown;\n}>();\n\nconst menuId = createId('t-context-menu');\nconst rootRef = ref<HTMLElement | null>(null);\nconst itemRefs = ref<Map<string, HTMLElement>>(new Map());\nconst focusedIndex = ref(-1);\nconst menuPosition = ref({ x: 0, y: 0 });\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-context-menu',\n `t-context-menu--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-open': isOpen.value,\n },\n]);\n\nconst enabledItems = computed(() => props.items.filter((i) => !i.disabled));\n\nconst openMenu = (x: number, y: number) => {\n if (props.disabled) return;\n menuPosition.value = { x, y };\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n setValue(true);\n nextTick(() => focusItem(focusedIndex.value));\n};\n\nconst closeMenu = (restoreFocus = false) => {\n setValue(false);\n focusedIndex.value = -1;\n if (restoreFocus) {\n nextTick(() => rootRef.value?.focus());\n }\n};\n\nconst selectItem = (item: TContextMenuItem) => {\n if (item.disabled) return;\n emit('select', item.value);\n closeMenu(true);\n};\n\nconst focusItem = (index: number) => {\n const item = props.items[index];\n if (!item) return;\n const el = itemRefs.value.get(item.value);\n el?.focus();\n};\n\nconst setItemRef = (el: Element | null, value: string) => {\n if (el instanceof HTMLElement) {\n itemRefs.value.set(value, el);\n } else {\n itemRefs.value.delete(value);\n }\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n let nextIndex = focusedIndex.value + direction;\n while (nextIndex >= 0 && nextIndex < props.items.length) {\n if (!props.items[nextIndex].disabled) {\n focusedIndex.value = nextIndex;\n focusItem(nextIndex);\n return;\n }\n nextIndex += direction;\n }\n};\n\nconst onContextMenu = (event: MouseEvent) => {\n if (props.disabled) return;\n event.preventDefault();\n openMenu(event.clientX, event.clientY);\n};\n\nconst onItemKeydown = (event: KeyboardEvent, item: TContextMenuItem) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeMenu(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectItem(item);\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(-1);\n break;\n case 'Home':\n event.preventDefault();\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n focusItem(focusedIndex.value);\n break;\n case 'End':\n event.preventDefault();\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[enabledItems.value.length - 1])\n : props.items.length - 1;\n focusItem(focusedIndex.value);\n break;\n default:\n break;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) return;\n const target = event.target;\n if (!(target instanceof Node)) return;\n const menuEl = document.getElementById(menuId);\n if (menuEl?.contains(target)) return;\n closeMenu();\n};\n\nconst onDocumentContextMenu = (event: MouseEvent) => {\n if (!isOpen.value) return;\n const target = event.target;\n if (!(target instanceof Node)) return;\n if (rootRef.value?.contains(target)) return;\n closeMenu();\n};\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n document.addEventListener('contextmenu', onDocumentContextMenu);\n } else {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n document.removeEventListener('contextmenu', onDocumentContextMenu);\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n document.removeEventListener('contextmenu', onDocumentContextMenu);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n @contextmenu=\"onContextMenu\"\n >\n <slot />\n <Teleport to=\"body\">\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"menuId\"\n role=\"menu\"\n class=\"t-context-menu__menu\"\n :class=\"`t-context-menu--${size}`\"\n :style=\"{ top: `${menuPosition.y}px`, left: `${menuPosition.x}px` }\"\n aria-label=\"Context menu\"\n >\n <li\n v-for=\"(item, index) in items\"\n :key=\"item.value\"\n :ref=\"(el) => setItemRef(el as Element | null, item.value)\"\n role=\"menuitem\"\n class=\"t-context-menu__item\"\n :class=\"{\n 'is-disabled': item.disabled,\n 'is-focused': index === focusedIndex,\n }\"\n :aria-disabled=\"item.disabled || undefined\"\n :tabindex=\"item.disabled ? -1 : 0\"\n @click=\"selectItem(item)\"\n @keydown=\"onItemKeydown($event, item)\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :index=\"index\"\n >\n {{ item.label }}\n </slot>\n </li>\n </ul>\n </transition>\n </Teleport>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport {\n addDays,\n addMonths,\n createId,\n isActivationKey,\n isEscapeKey,\n isSameDay,\n parseDateValue,\n startOfDay,\n startOfMonth,\n startOfWeek,\n toDateValue,\n} from '@treeui/utils';\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport {\n type ComponentPublicInstance,\n computed,\n nextTick,\n onBeforeUnmount,\n ref,\n toRef,\n useAttrs,\n watch,\n} from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\ninterface CalendarCell {\n date: Date;\n dayLabel: number;\n disabled: boolean;\n inMonth: boolean;\n isFocused: boolean;\n isSelected: boolean;\n isToday: boolean;\n key: string;\n}\n\nconst CalendarIcon = getTreeIcon('calendar');\nconst ChevronLeftIcon = getTreeIcon('chevron-left');\nconst ChevronRightIcon = getTreeIcon('chevron-right');\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n disabled?: boolean;\n invalid?: boolean;\n placeholder?: string;\n locale?: string;\n min?: string;\n max?: string;\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n id?: string;\n }>(),\n {\n modelValue: '',\n open: undefined,\n defaultOpen: false,\n size: 'md',\n disabled: false,\n invalid: false,\n placeholder: 'Select date',\n locale: 'en-US',\n min: '',\n max: '',\n weekStartsOn: 0,\n id: undefined,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n select: [value: string];\n}>();\n\nconst attrs = useAttrs();\nconst today = startOfDay(new Date());\nconst selectedDate = computed(() => parseDateValue(props.modelValue));\nconst minDate = computed(() => parseDateValue(props.min));\nconst maxDate = computed(() => parseDateValue(props.max));\nconst calendarId = props.id ?? createId('t-date-picker');\nconst captionId = `${calendarId}-caption`;\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst dayRefs = new Map<string, HTMLButtonElement>();\nconst viewMonth = ref(startOfMonth(selectedDate.value ?? today));\nconst focusedDate = ref<Date>(selectedDate.value ?? today);\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, name: _name, ...rest } = attrs;\n return rest;\n});\n\nconst hiddenInputName = computed(() =>\n typeof attrs.name === 'string' ? attrs.name : undefined,\n);\n\nconst rootClasses = computed(() => [\n 't-date-picker',\n `t-date-picker--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst triggerText = computed(() => {\n if (!selectedDate.value) {\n return props.placeholder;\n }\n\n return new Intl.DateTimeFormat(props.locale, {\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n }).format(selectedDate.value);\n});\n\nconst monthLabel = computed(() =>\n new Intl.DateTimeFormat(props.locale, {\n month: 'long',\n year: 'numeric',\n }).format(viewMonth.value),\n);\n\nconst weekdayLabels = computed(() => {\n const formatter = new Intl.DateTimeFormat(props.locale, { weekday: 'short' });\n const weekBase = startOfWeek(new Date(2024, 0, 7), props.weekStartsOn);\n\n return Array.from({ length: 7 }, (_, index) =>\n formatter.format(addDays(weekBase, index)),\n );\n});\n\nconst isDateDisabled = (date: Date) => {\n if (props.disabled) {\n return true;\n }\n\n if (minDate.value && date < minDate.value) {\n return true;\n }\n\n if (maxDate.value && date > maxDate.value) {\n return true;\n }\n\n return false;\n};\n\nconst syncCalendarView = (date: Date) => {\n focusedDate.value = startOfDay(date);\n viewMonth.value = startOfMonth(date);\n};\n\nwatch(\n selectedDate,\n (value) => {\n if (value) {\n syncCalendarView(value);\n return;\n }\n\n if (!isOpen.value) {\n syncCalendarView(today);\n }\n },\n { immediate: true },\n);\n\nconst cells = computed(() => {\n const startDate = startOfWeek(startOfMonth(viewMonth.value), props.weekStartsOn);\n\n return Array.from({ length: 6 }, (_, weekIndex) =>\n Array.from({ length: 7 }, (_, dayIndex) => {\n const date = addDays(startDate, weekIndex * 7 + dayIndex);\n const key = toDateValue(date);\n\n return {\n date,\n dayLabel: date.getDate(),\n disabled: isDateDisabled(date),\n inMonth: date.getMonth() === viewMonth.value.getMonth(),\n isFocused: isSameDay(date, focusedDate.value),\n isSelected: isSameDay(date, selectedDate.value),\n isToday: isSameDay(date, today),\n key,\n } satisfies CalendarCell;\n }),\n );\n});\n\nconst canMovePrev = computed(() => {\n if (!minDate.value) {\n return true;\n }\n\n return startOfMonth(viewMonth.value) > startOfMonth(minDate.value);\n});\n\nconst canMoveNext = computed(() => {\n if (!maxDate.value) {\n return true;\n }\n\n return startOfMonth(viewMonth.value) < startOfMonth(maxDate.value);\n});\n\nconst focusCurrentDay = () => {\n const key = toDateValue(focusedDate.value);\n nextTick(() => {\n dayRefs.get(key)?.focus();\n });\n};\n\nconst setDayRef = (\n element: Element | ComponentPublicInstance | null,\n key: string,\n) => {\n if (element instanceof HTMLButtonElement) {\n dayRefs.set(key, element);\n return;\n }\n\n dayRefs.delete(key);\n};\n\nconst openCalendar = () => {\n if (props.disabled) {\n return;\n }\n\n syncCalendarView(selectedDate.value ?? focusedDate.value ?? today);\n setValue(true);\n focusCurrentDay();\n};\n\nconst closeCalendar = (restoreFocus = false) => {\n setValue(false);\n\n if (restoreFocus) {\n nextTick(() => {\n triggerRef.value?.focus();\n });\n }\n};\n\nconst toggleCalendar = () => {\n if (isOpen.value) {\n closeCalendar();\n return;\n }\n\n openCalendar();\n};\n\nconst moveCalendar = (direction: 1 | -1) => {\n const nextMonth = addMonths(viewMonth.value, direction);\n syncCalendarView(nextMonth);\n focusCurrentDay();\n};\n\nconst moveFocus = (nextDate: Date) => {\n if (isDateDisabled(nextDate)) {\n return;\n }\n\n syncCalendarView(nextDate);\n focusCurrentDay();\n};\n\nconst selectDate = (date: Date) => {\n if (isDateDisabled(date)) {\n return;\n }\n\n const normalizedDate = startOfDay(date);\n const value = toDateValue(normalizedDate);\n\n syncCalendarView(normalizedDate);\n emit('update:modelValue', value);\n emit('select', value);\n closeCalendar(true);\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) {\n return;\n }\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closeCalendar();\n return;\n }\n\n if (\n isActivationKey(event) ||\n event.key === 'ArrowDown' ||\n event.key === 'ArrowUp'\n ) {\n event.preventDefault();\n openCalendar();\n }\n};\n\nconst onDayKeydown = (event: KeyboardEvent, date: Date) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeCalendar(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectDate(date);\n return;\n }\n\n switch (event.key) {\n case 'ArrowLeft':\n event.preventDefault();\n moveFocus(addDays(date, -1));\n break;\n case 'ArrowRight':\n event.preventDefault();\n moveFocus(addDays(date, 1));\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(addDays(date, -7));\n break;\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(addDays(date, 7));\n break;\n case 'Home':\n event.preventDefault();\n moveFocus(startOfWeek(date, props.weekStartsOn));\n break;\n case 'End':\n event.preventDefault();\n moveFocus(addDays(startOfWeek(date, props.weekStartsOn), 6));\n break;\n case 'PageUp':\n event.preventDefault();\n moveFocus(addMonths(date, event.shiftKey ? -12 : -1));\n break;\n case 'PageDown':\n event.preventDefault();\n moveFocus(addMonths(date, event.shiftKey ? 12 : 1));\n break;\n default:\n break;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) {\n return;\n }\n\n const target = event.target;\n if (!(target instanceof Node)) {\n return;\n }\n\n if (rootRef.value?.contains(target)) {\n return;\n }\n\n closeCalendar();\n};\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n return;\n }\n\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <input\n v-if=\"hiddenInputName\"\n type=\"hidden\"\n :name=\"hiddenInputName\"\n :value=\"modelValue\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-date-picker__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? calendarId : undefined\"\n aria-haspopup=\"dialog\"\n :aria-expanded=\"isOpen\"\n :aria-invalid=\"invalid || undefined\"\n @click=\"toggleCalendar\"\n @keydown=\"onTriggerKeydown\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-date-picker__slot t-date-picker__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n <span\n class=\"t-date-picker__value\"\n :data-placeholder=\"selectedDate ? undefined : true\"\n >\n {{ triggerText }}\n </span>\n <span class=\"t-date-picker__slot t-date-picker__slot--suffix\">\n <slot name=\"suffix\">\n <CalendarIcon v-bind=\"treeIconDefaults\" />\n </slot>\n </span>\n </button>\n\n <transition name=\"t-fade\">\n <div\n v-if=\"isOpen && !disabled\"\n :id=\"calendarId\"\n class=\"t-date-picker__content\"\n role=\"dialog\"\n aria-modal=\"false\"\n :aria-labelledby=\"captionId\"\n >\n <div class=\"t-date-picker__header\">\n <button\n type=\"button\"\n class=\"t-date-picker__nav\"\n :disabled=\"!canMovePrev\"\n aria-label=\"Previous month\"\n @click=\"moveCalendar(-1)\"\n >\n <ChevronLeftIcon v-bind=\"treeIconDefaults\" />\n </button>\n <p\n :id=\"captionId\"\n class=\"t-date-picker__month\"\n >\n {{ monthLabel }}\n </p>\n <button\n type=\"button\"\n class=\"t-date-picker__nav\"\n :disabled=\"!canMoveNext\"\n aria-label=\"Next month\"\n @click=\"moveCalendar(1)\"\n >\n <ChevronRightIcon v-bind=\"treeIconDefaults\" />\n </button>\n </div>\n\n <div\n class=\"t-date-picker__weekdays\"\n aria-hidden=\"true\"\n >\n <span\n v-for=\"label in weekdayLabels\"\n :key=\"label\"\n class=\"t-date-picker__weekday\"\n >\n {{ label }}\n </span>\n </div>\n\n <div\n class=\"t-date-picker__grid\"\n role=\"grid\"\n :aria-labelledby=\"captionId\"\n >\n <div\n v-for=\"(week, weekIndex) in cells\"\n :key=\"weekIndex\"\n class=\"t-date-picker__row\"\n role=\"row\"\n >\n <div\n v-for=\"cell in week\"\n :key=\"cell.key\"\n class=\"t-date-picker__cell\"\n role=\"gridcell\"\n :aria-selected=\"cell.isSelected\"\n >\n <button\n :ref=\"(element) => setDayRef(element, cell.key)\"\n type=\"button\"\n class=\"t-date-picker__day\"\n :class=\"{\n 'is-muted': !cell.inMonth,\n 'is-selected': cell.isSelected,\n 'is-today': cell.isToday,\n }\"\n :data-date=\"cell.key\"\n :disabled=\"cell.disabled\"\n :tabindex=\"cell.isFocused ? 0 : -1\"\n :aria-current=\"cell.isToday ? 'date' : undefined\"\n :aria-label=\"cell.key\"\n @click=\"selectDate(cell.date)\"\n @keydown=\"onDayKeydown($event, cell.date)\"\n >\n {{ cell.dayLabel }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </transition>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport {\n addDays,\n addMonths,\n createId,\n isActivationKey,\n isEscapeKey,\n isSameDay,\n parseDateValue,\n startOfDay,\n startOfMonth,\n startOfWeek,\n toDateValue,\n} from '@treeui/utils';\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport {\n type ComponentPublicInstance,\n computed,\n nextTick,\n onBeforeUnmount,\n ref,\n toRef,\n useAttrs,\n watch,\n} from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\ninterface CalendarCell {\n date: Date;\n dayLabel: number;\n disabled: boolean;\n inMonth: boolean;\n isFocused: boolean;\n isSelected: boolean;\n isToday: boolean;\n key: string;\n}\n\nconst CalendarIcon = getTreeIcon('calendar');\nconst ChevronLeftIcon = getTreeIcon('chevron-left');\nconst ChevronRightIcon = getTreeIcon('chevron-right');\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n disabled?: boolean;\n invalid?: boolean;\n placeholder?: string;\n locale?: string;\n min?: string;\n max?: string;\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n id?: string;\n }>(),\n {\n modelValue: '',\n open: undefined,\n defaultOpen: false,\n size: 'md',\n disabled: false,\n invalid: false,\n placeholder: 'Select date',\n locale: 'en-US',\n min: '',\n max: '',\n weekStartsOn: 0,\n id: undefined,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n select: [value: string];\n}>();\n\nconst attrs = useAttrs();\nconst today = startOfDay(new Date());\nconst selectedDate = computed(() => parseDateValue(props.modelValue));\nconst minDate = computed(() => parseDateValue(props.min));\nconst maxDate = computed(() => parseDateValue(props.max));\nconst calendarId = props.id ?? createId('t-date-picker');\nconst captionId = `${calendarId}-caption`;\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst dayRefs = new Map<string, HTMLButtonElement>();\nconst viewMonth = ref(startOfMonth(selectedDate.value ?? today));\nconst focusedDate = ref<Date>(selectedDate.value ?? today);\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, name: _name, ...rest } = attrs;\n return rest;\n});\n\nconst hiddenInputName = computed(() =>\n typeof attrs.name === 'string' ? attrs.name : undefined,\n);\n\nconst rootClasses = computed(() => [\n 't-date-picker',\n `t-date-picker--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst triggerText = computed(() => {\n if (!selectedDate.value) {\n return props.placeholder;\n }\n\n return new Intl.DateTimeFormat(props.locale, {\n day: 'numeric',\n month: 'long',\n year: 'numeric',\n }).format(selectedDate.value);\n});\n\nconst monthLabel = computed(() =>\n new Intl.DateTimeFormat(props.locale, {\n month: 'long',\n year: 'numeric',\n }).format(viewMonth.value),\n);\n\nconst weekdayLabels = computed(() => {\n const formatter = new Intl.DateTimeFormat(props.locale, { weekday: 'short' });\n const weekBase = startOfWeek(new Date(2024, 0, 7), props.weekStartsOn);\n\n return Array.from({ length: 7 }, (_, index) =>\n formatter.format(addDays(weekBase, index)),\n );\n});\n\nconst isDateDisabled = (date: Date) => {\n if (props.disabled) {\n return true;\n }\n\n if (minDate.value && date < minDate.value) {\n return true;\n }\n\n if (maxDate.value && date > maxDate.value) {\n return true;\n }\n\n return false;\n};\n\nconst syncCalendarView = (date: Date) => {\n focusedDate.value = startOfDay(date);\n viewMonth.value = startOfMonth(date);\n};\n\nwatch(\n selectedDate,\n (value) => {\n if (value) {\n syncCalendarView(value);\n return;\n }\n\n if (!isOpen.value) {\n syncCalendarView(today);\n }\n },\n { immediate: true },\n);\n\nconst cells = computed(() => {\n const startDate = startOfWeek(startOfMonth(viewMonth.value), props.weekStartsOn);\n\n return Array.from({ length: 6 }, (_, weekIndex) =>\n Array.from({ length: 7 }, (_, dayIndex) => {\n const date = addDays(startDate, weekIndex * 7 + dayIndex);\n const key = toDateValue(date);\n\n return {\n date,\n dayLabel: date.getDate(),\n disabled: isDateDisabled(date),\n inMonth: date.getMonth() === viewMonth.value.getMonth(),\n isFocused: isSameDay(date, focusedDate.value),\n isSelected: isSameDay(date, selectedDate.value),\n isToday: isSameDay(date, today),\n key,\n } satisfies CalendarCell;\n }),\n );\n});\n\nconst canMovePrev = computed(() => {\n if (!minDate.value) {\n return true;\n }\n\n return startOfMonth(viewMonth.value) > startOfMonth(minDate.value);\n});\n\nconst canMoveNext = computed(() => {\n if (!maxDate.value) {\n return true;\n }\n\n return startOfMonth(viewMonth.value) < startOfMonth(maxDate.value);\n});\n\nconst focusCurrentDay = () => {\n const key = toDateValue(focusedDate.value);\n nextTick(() => {\n dayRefs.get(key)?.focus();\n });\n};\n\nconst setDayRef = (\n element: Element | ComponentPublicInstance | null,\n key: string,\n) => {\n if (element instanceof HTMLButtonElement) {\n dayRefs.set(key, element);\n return;\n }\n\n dayRefs.delete(key);\n};\n\nconst openCalendar = () => {\n if (props.disabled) {\n return;\n }\n\n syncCalendarView(selectedDate.value ?? focusedDate.value ?? today);\n setValue(true);\n focusCurrentDay();\n};\n\nconst closeCalendar = (restoreFocus = false) => {\n setValue(false);\n\n if (restoreFocus) {\n nextTick(() => {\n triggerRef.value?.focus();\n });\n }\n};\n\nconst toggleCalendar = () => {\n if (isOpen.value) {\n closeCalendar();\n return;\n }\n\n openCalendar();\n};\n\nconst moveCalendar = (direction: 1 | -1) => {\n const nextMonth = addMonths(viewMonth.value, direction);\n syncCalendarView(nextMonth);\n focusCurrentDay();\n};\n\nconst moveFocus = (nextDate: Date) => {\n if (isDateDisabled(nextDate)) {\n return;\n }\n\n syncCalendarView(nextDate);\n focusCurrentDay();\n};\n\nconst selectDate = (date: Date) => {\n if (isDateDisabled(date)) {\n return;\n }\n\n const normalizedDate = startOfDay(date);\n const value = toDateValue(normalizedDate);\n\n syncCalendarView(normalizedDate);\n emit('update:modelValue', value);\n emit('select', value);\n closeCalendar(true);\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) {\n return;\n }\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closeCalendar();\n return;\n }\n\n if (\n isActivationKey(event) ||\n event.key === 'ArrowDown' ||\n event.key === 'ArrowUp'\n ) {\n event.preventDefault();\n openCalendar();\n }\n};\n\nconst onDayKeydown = (event: KeyboardEvent, date: Date) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeCalendar(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectDate(date);\n return;\n }\n\n switch (event.key) {\n case 'ArrowLeft':\n event.preventDefault();\n moveFocus(addDays(date, -1));\n break;\n case 'ArrowRight':\n event.preventDefault();\n moveFocus(addDays(date, 1));\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(addDays(date, -7));\n break;\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(addDays(date, 7));\n break;\n case 'Home':\n event.preventDefault();\n moveFocus(startOfWeek(date, props.weekStartsOn));\n break;\n case 'End':\n event.preventDefault();\n moveFocus(addDays(startOfWeek(date, props.weekStartsOn), 6));\n break;\n case 'PageUp':\n event.preventDefault();\n moveFocus(addMonths(date, event.shiftKey ? -12 : -1));\n break;\n case 'PageDown':\n event.preventDefault();\n moveFocus(addMonths(date, event.shiftKey ? 12 : 1));\n break;\n default:\n break;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) {\n return;\n }\n\n const target = event.target;\n if (!(target instanceof Node)) {\n return;\n }\n\n if (rootRef.value?.contains(target)) {\n return;\n }\n\n closeCalendar();\n};\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n return;\n }\n\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <input\n v-if=\"hiddenInputName\"\n type=\"hidden\"\n :name=\"hiddenInputName\"\n :value=\"modelValue\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-date-picker__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? calendarId : undefined\"\n aria-haspopup=\"dialog\"\n :aria-expanded=\"isOpen\"\n :aria-invalid=\"invalid || undefined\"\n @click=\"toggleCalendar\"\n @keydown=\"onTriggerKeydown\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-date-picker__slot t-date-picker__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n <span\n class=\"t-date-picker__value\"\n :data-placeholder=\"selectedDate ? undefined : true\"\n >\n {{ triggerText }}\n </span>\n <span class=\"t-date-picker__slot t-date-picker__slot--suffix\">\n <slot name=\"suffix\">\n <CalendarIcon v-bind=\"treeIconDefaults\" />\n </slot>\n </span>\n </button>\n\n <transition name=\"t-fade\">\n <div\n v-if=\"isOpen && !disabled\"\n :id=\"calendarId\"\n class=\"t-date-picker__content\"\n role=\"dialog\"\n aria-modal=\"false\"\n :aria-labelledby=\"captionId\"\n >\n <div class=\"t-date-picker__header\">\n <button\n type=\"button\"\n class=\"t-date-picker__nav\"\n :disabled=\"!canMovePrev\"\n aria-label=\"Previous month\"\n @click=\"moveCalendar(-1)\"\n >\n <ChevronLeftIcon v-bind=\"treeIconDefaults\" />\n </button>\n <p\n :id=\"captionId\"\n class=\"t-date-picker__month\"\n >\n {{ monthLabel }}\n </p>\n <button\n type=\"button\"\n class=\"t-date-picker__nav\"\n :disabled=\"!canMoveNext\"\n aria-label=\"Next month\"\n @click=\"moveCalendar(1)\"\n >\n <ChevronRightIcon v-bind=\"treeIconDefaults\" />\n </button>\n </div>\n\n <div\n class=\"t-date-picker__weekdays\"\n aria-hidden=\"true\"\n >\n <span\n v-for=\"label in weekdayLabels\"\n :key=\"label\"\n class=\"t-date-picker__weekday\"\n >\n {{ label }}\n </span>\n </div>\n\n <div\n class=\"t-date-picker__grid\"\n role=\"grid\"\n :aria-labelledby=\"captionId\"\n >\n <div\n v-for=\"(week, weekIndex) in cells\"\n :key=\"weekIndex\"\n class=\"t-date-picker__row\"\n role=\"row\"\n >\n <div\n v-for=\"cell in week\"\n :key=\"cell.key\"\n class=\"t-date-picker__cell\"\n role=\"gridcell\"\n :aria-selected=\"cell.isSelected\"\n >\n <button\n :ref=\"(element) => setDayRef(element, cell.key)\"\n type=\"button\"\n class=\"t-date-picker__day\"\n :class=\"{\n 'is-muted': !cell.inMonth,\n 'is-selected': cell.isSelected,\n 'is-today': cell.isToday,\n }\"\n :data-date=\"cell.key\"\n :disabled=\"cell.disabled\"\n :tabindex=\"cell.isFocused ? 0 : -1\"\n :aria-current=\"cell.isToday ? 'date' : undefined\"\n :aria-label=\"cell.key\"\n @click=\"selectDate(cell.date)\"\n @keydown=\"onDayKeydown($event, cell.date)\"\n >\n {{ cell.dayLabel }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </transition>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport {\n addDays,\n addMonths,\n createId,\n isActivationKey,\n isEscapeKey,\n isSameDay,\n startOfDay,\n startOfMonth,\n startOfWeek,\n toDateValue,\n} from '@treeui/utils';\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport {\n type ComponentPublicInstance,\n computed,\n nextTick,\n onBeforeUnmount,\n ref,\n toRef,\n useAttrs,\n watch,\n} from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\ninterface CalendarCell {\n date: Date;\n dayLabel: number;\n disabled: boolean;\n inMonth: boolean;\n isFocused: boolean;\n isSelected: boolean;\n isToday: boolean;\n key: string;\n}\n\ninterface TimeOption {\n disabled: boolean;\n label: string;\n value: number;\n}\n\nconst CalendarIcon = getTreeIcon('calendar');\nconst ChevronLeftIcon = getTreeIcon('chevron-left');\nconst ChevronRightIcon = getTreeIcon('chevron-right');\n\nconst dateOnlyPattern = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\nconst dateTimePattern = /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2})(?::(\\d{2}))?$/;\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n placeholder?: string;\n locale?: string;\n min?: string;\n max?: string;\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n id?: string;\n step?: number;\n }>(),\n {\n modelValue: '',\n open: undefined,\n defaultOpen: false,\n size: 'md',\n disabled: false,\n loading: false,\n invalid: false,\n placeholder: 'Select date and time',\n locale: 'en-US',\n min: '',\n max: '',\n weekStartsOn: 0,\n id: undefined,\n step: 60,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n change: [value: string];\n select: [value: string];\n}>();\n\nconst attrs = useAttrs();\n\nconst cloneDate = (value: Date) => new Date(value.getTime());\n\nconst formatPart = (value: number) => `${value}`.padStart(2, '0');\n\nconst endOfDay = (date: Date) =>\n new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59, 999);\n\nconst parseBoundaryValue = (\n value: string | null | undefined,\n boundary: 'exact' | 'start' | 'end' = 'exact',\n) => {\n if (!value) {\n return null;\n }\n\n const dateOnlyMatch = value.match(dateOnlyPattern);\n if (dateOnlyMatch) {\n const [, yearToken, monthToken, dayToken] = dateOnlyMatch;\n const year = Number.parseInt(yearToken, 10);\n const month = Number.parseInt(monthToken, 10);\n const day = Number.parseInt(dayToken, 10);\n const hour = boundary === 'end' ? 23 : 0;\n const minute = boundary === 'end' ? 59 : 0;\n const second = boundary === 'end' ? 59 : 0;\n const millisecond = boundary === 'end' ? 999 : 0;\n const date = new Date(year, month - 1, day, hour, minute, second, millisecond);\n\n if (\n Number.isNaN(date.getTime()) ||\n date.getFullYear() !== year ||\n date.getMonth() !== month - 1 ||\n date.getDate() !== day\n ) {\n return null;\n }\n\n return date;\n }\n\n const dateTimeMatch = value.match(dateTimePattern);\n if (!dateTimeMatch) {\n return null;\n }\n\n const [, yearToken, monthToken, dayToken, hourToken, minuteToken, secondToken] =\n dateTimeMatch;\n const year = Number.parseInt(yearToken, 10);\n const month = Number.parseInt(monthToken, 10);\n const day = Number.parseInt(dayToken, 10);\n const hour = Number.parseInt(hourToken, 10);\n const minute = Number.parseInt(minuteToken, 10);\n const second = secondToken ? Number.parseInt(secondToken, 10) : 0;\n const date = new Date(year, month - 1, day, hour, minute, second, 0);\n\n if (\n Number.isNaN(date.getTime()) ||\n date.getFullYear() !== year ||\n date.getMonth() !== month - 1 ||\n date.getDate() !== day ||\n date.getHours() !== hour ||\n date.getMinutes() !== minute ||\n date.getSeconds() !== second\n ) {\n return null;\n }\n\n return date;\n};\n\nconst toDateTimeValue = (date: Date) =>\n `${toDateValue(date)}T${formatPart(date.getHours())}:${formatPart(date.getMinutes())}`;\n\nconst setDatePart = (source: Date, targetDate: Date) =>\n new Date(\n targetDate.getFullYear(),\n targetDate.getMonth(),\n targetDate.getDate(),\n source.getHours(),\n source.getMinutes(),\n 0,\n 0,\n );\n\nconst setTimePart = (source: Date, hour: number, minute: number) =>\n new Date(\n source.getFullYear(),\n source.getMonth(),\n source.getDate(),\n hour,\n minute,\n 0,\n 0,\n );\n\nconst resolveMinuteStep = (step: number) => {\n if (!Number.isFinite(step) || step <= 0 || step % 60 !== 0) {\n return 1;\n }\n\n const minuteStep = step / 60;\n return minuteStep >= 60 ? 1 : minuteStep;\n};\n\nconst today = startOfDay(new Date());\nconst selectedDateTime = computed(() => parseBoundaryValue(props.modelValue, 'exact'));\nconst minDateTime = computed(() => parseBoundaryValue(props.min, 'start'));\nconst maxDateTime = computed(() => parseBoundaryValue(props.max, 'end'));\nconst pickerId = props.id ?? createId('t-date-time-picker');\nconst captionId = `${pickerId}-caption`;\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst dayRefs = new Map<string, HTMLButtonElement>();\n\nconst clampToRange = (value: Date) => {\n let nextValue = cloneDate(value);\n\n if (minDateTime.value && nextValue < minDateTime.value) {\n nextValue = cloneDate(minDateTime.value);\n }\n\n if (maxDateTime.value && nextValue > maxDateTime.value) {\n nextValue = cloneDate(maxDateTime.value);\n }\n\n return nextValue;\n};\n\nconst createDefaultDraftDateTime = () => {\n const reference = new Date();\n const stepMilliseconds = Math.max(props.step, 60) * 1000;\n const rounded = new Date(Math.ceil(reference.getTime() / stepMilliseconds) * stepMilliseconds);\n\n rounded.setSeconds(0, 0);\n return clampToRange(rounded);\n};\n\nconst initialDateTime = selectedDateTime.value ?? createDefaultDraftDateTime();\nconst draftDateTime = ref(initialDateTime);\nconst focusedDate = ref(startOfDay(initialDateTime));\nconst viewMonth = ref(startOfMonth(initialDateTime));\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, name: _name, ...rest } = attrs;\n return rest;\n});\n\nconst hiddenInputName = computed(() =>\n typeof attrs.name === 'string' ? attrs.name : undefined,\n);\n\nconst rootClasses = computed(() => [\n 't-date-picker',\n 't-date-time-picker',\n `t-date-picker--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst triggerText = computed(() => {\n if (!selectedDateTime.value) {\n return props.placeholder;\n }\n\n return new Intl.DateTimeFormat(props.locale, {\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n month: 'long',\n year: 'numeric',\n }).format(selectedDateTime.value);\n});\n\nconst draftPreview = computed(() =>\n new Intl.DateTimeFormat(props.locale, {\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n month: 'long',\n year: 'numeric',\n }).format(draftDateTime.value),\n);\n\nconst monthLabel = computed(() =>\n new Intl.DateTimeFormat(props.locale, {\n month: 'long',\n year: 'numeric',\n }).format(viewMonth.value),\n);\n\nconst weekdayLabels = computed(() => {\n const formatter = new Intl.DateTimeFormat(props.locale, { weekday: 'short' });\n const weekBase = startOfWeek(new Date(2024, 0, 7), props.weekStartsOn);\n\n return Array.from({ length: 7 }, (_, index) =>\n formatter.format(addDays(weekBase, index)),\n );\n});\n\nconst minuteStep = computed(() => resolveMinuteStep(props.step));\n\nconst minuteValues = computed(() => {\n const values = new Set<number>();\n\n for (let minute = 0; minute < 60; minute += minuteStep.value) {\n values.add(minute);\n }\n\n values.add(draftDateTime.value.getMinutes());\n\n return [...values].sort((left, right) => left - right);\n});\n\nconst isDateDisabled = (date: Date) => {\n if (props.disabled) {\n return true;\n }\n\n const dayStart = startOfDay(date);\n const dayEnd = endOfDay(date);\n\n if (minDateTime.value && dayEnd < minDateTime.value) {\n return true;\n }\n\n if (maxDateTime.value && dayStart > maxDateTime.value) {\n return true;\n }\n\n return false;\n};\n\nconst isDateTimeDisabled = (value: Date) => {\n if (props.disabled) {\n return true;\n }\n\n if (minDateTime.value && value < minDateTime.value) {\n return true;\n }\n\n if (maxDateTime.value && value > maxDateTime.value) {\n return true;\n }\n\n return false;\n};\n\nconst syncCalendarView = (date: Date) => {\n focusedDate.value = startOfDay(date);\n viewMonth.value = startOfMonth(date);\n};\n\nconst syncDraftState = (dateTime: Date) => {\n const nextValue = clampToRange(dateTime);\n draftDateTime.value = nextValue;\n syncCalendarView(nextValue);\n};\n\nwatch(\n selectedDateTime,\n (value) => {\n if (isOpen.value) {\n return;\n }\n\n syncDraftState(value ?? createDefaultDraftDateTime());\n },\n { immediate: true },\n);\n\nconst draftDate = computed(() => startOfDay(draftDateTime.value));\n\nconst cells = computed(() => {\n const startDate = startOfWeek(startOfMonth(viewMonth.value), props.weekStartsOn);\n\n return Array.from({ length: 6 }, (_, weekIndex) =>\n Array.from({ length: 7 }, (_, dayIndex) => {\n const date = addDays(startDate, weekIndex * 7 + dayIndex);\n const key = toDateValue(date);\n\n return {\n date,\n dayLabel: date.getDate(),\n disabled: isDateDisabled(date),\n inMonth: date.getMonth() === viewMonth.value.getMonth(),\n isFocused: isSameDay(date, focusedDate.value),\n isSelected: isSameDay(date, draftDate.value),\n isToday: isSameDay(date, today),\n key,\n } satisfies CalendarCell;\n }),\n );\n});\n\nconst canMovePrev = computed(() => {\n if (!minDateTime.value) {\n return true;\n }\n\n return startOfMonth(viewMonth.value) > startOfMonth(minDateTime.value);\n});\n\nconst canMoveNext = computed(() => {\n if (!maxDateTime.value) {\n return true;\n }\n\n return startOfMonth(viewMonth.value) < startOfMonth(maxDateTime.value);\n});\n\nconst isTimeOptionEnabled = (hour: number, minute: number) => {\n const candidate = setTimePart(draftDateTime.value, hour, minute);\n return !isDateTimeDisabled(candidate);\n};\n\nconst hourOptions = computed<TimeOption[]>(() =>\n Array.from({ length: 24 }, (_, hour) => ({\n disabled: !minuteValues.value.some((minute) => isTimeOptionEnabled(hour, minute)),\n label: formatPart(hour),\n value: hour,\n })),\n);\n\nconst minuteOptions = computed<TimeOption[]>(() =>\n minuteValues.value.map((minute) => ({\n disabled: !isTimeOptionEnabled(draftDateTime.value.getHours(), minute),\n label: formatPart(minute),\n value: minute,\n })),\n);\n\nconst focusCurrentDay = () => {\n const key = toDateValue(focusedDate.value);\n nextTick(() => {\n dayRefs.get(key)?.focus();\n });\n};\n\nconst setDayRef = (\n element: Element | ComponentPublicInstance | null,\n key: string,\n) => {\n if (element instanceof HTMLButtonElement) {\n dayRefs.set(key, element);\n return;\n }\n\n dayRefs.delete(key);\n};\n\nconst openCalendar = () => {\n if (props.disabled) {\n return;\n }\n\n syncDraftState(selectedDateTime.value ?? createDefaultDraftDateTime());\n setValue(true);\n focusCurrentDay();\n};\n\nconst closeCalendar = (restoreFocus = false) => {\n setValue(false);\n\n if (restoreFocus) {\n nextTick(() => {\n triggerRef.value?.focus();\n });\n }\n};\n\nconst toggleCalendar = () => {\n if (isOpen.value) {\n closeCalendar();\n return;\n }\n\n openCalendar();\n};\n\nconst moveCalendar = (direction: 1 | -1) => {\n const nextMonth = addMonths(viewMonth.value, direction);\n syncCalendarView(nextMonth);\n focusCurrentDay();\n};\n\nconst moveFocus = (nextDate: Date) => {\n if (isDateDisabled(nextDate)) {\n return;\n }\n\n syncCalendarView(nextDate);\n focusCurrentDay();\n};\n\nconst selectDate = (date: Date) => {\n if (isDateDisabled(date)) {\n return;\n }\n\n const candidate = clampToRange(setDatePart(draftDateTime.value, date));\n draftDateTime.value = candidate;\n syncCalendarView(candidate);\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) {\n return;\n }\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closeCalendar();\n return;\n }\n\n if (\n isActivationKey(event) ||\n event.key === 'ArrowDown' ||\n event.key === 'ArrowUp'\n ) {\n event.preventDefault();\n openCalendar();\n }\n};\n\nconst onDayKeydown = (event: KeyboardEvent, date: Date) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeCalendar(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectDate(date);\n return;\n }\n\n switch (event.key) {\n case 'ArrowLeft':\n event.preventDefault();\n moveFocus(addDays(date, -1));\n break;\n case 'ArrowRight':\n event.preventDefault();\n moveFocus(addDays(date, 1));\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(addDays(date, -7));\n break;\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(addDays(date, 7));\n break;\n case 'Home':\n event.preventDefault();\n moveFocus(startOfWeek(date, props.weekStartsOn));\n break;\n case 'End':\n event.preventDefault();\n moveFocus(addDays(startOfWeek(date, props.weekStartsOn), 6));\n break;\n case 'PageUp':\n event.preventDefault();\n moveFocus(addMonths(date, event.shiftKey ? -12 : -1));\n break;\n case 'PageDown':\n event.preventDefault();\n moveFocus(addMonths(date, event.shiftKey ? 12 : 1));\n break;\n default:\n break;\n }\n};\n\nconst updateHour = (event: Event) => {\n const nextHour = Number.parseInt((event.target as HTMLSelectElement).value, 10);\n const currentMinute = draftDateTime.value.getMinutes();\n\n if (Number.isNaN(nextHour)) {\n return;\n }\n\n const availableMinutes = minuteValues.value.filter((minute) =>\n isTimeOptionEnabled(nextHour, minute),\n );\n\n if (!availableMinutes.length) {\n return;\n }\n\n const nextMinute = availableMinutes.includes(currentMinute)\n ? currentMinute\n : availableMinutes[0];\n\n draftDateTime.value = setTimePart(draftDateTime.value, nextHour, nextMinute);\n};\n\nconst updateMinute = (event: Event) => {\n const nextMinute = Number.parseInt((event.target as HTMLSelectElement).value, 10);\n const nextHour = draftDateTime.value.getHours();\n\n if (Number.isNaN(nextMinute) || !isTimeOptionEnabled(nextHour, nextMinute)) {\n return;\n }\n\n draftDateTime.value = setTimePart(draftDateTime.value, nextHour, nextMinute);\n};\n\nconst commitDraft = () => {\n const value = toDateTimeValue(draftDateTime.value);\n\n emit('update:modelValue', value);\n emit('change', value);\n emit('select', value);\n closeCalendar(true);\n};\n\nconst clearSelection = () => {\n emit('update:modelValue', '');\n emit('change', '');\n emit('select', '');\n closeCalendar(true);\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) {\n return;\n }\n\n const target = event.target;\n if (!(target instanceof Node)) {\n return;\n }\n\n if (rootRef.value?.contains(target)) {\n return;\n }\n\n closeCalendar();\n};\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n return;\n }\n\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <input\n v-if=\"hiddenInputName\"\n type=\"hidden\"\n :name=\"hiddenInputName\"\n :value=\"modelValue\"\n >\n\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-date-picker__trigger t-date-time-picker__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? pickerId : undefined\"\n aria-haspopup=\"dialog\"\n :aria-expanded=\"isOpen\"\n :aria-invalid=\"invalid || undefined\"\n @click=\"toggleCalendar\"\n @keydown=\"onTriggerKeydown\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-date-picker__slot t-date-picker__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n\n <span\n class=\"t-date-picker__value\"\n :data-placeholder=\"selectedDateTime ? undefined : true\"\n >\n {{ triggerText }}\n </span>\n\n <span class=\"t-date-picker__slot t-date-picker__slot--suffix\">\n <slot name=\"suffix\">\n <TSpinner\n v-if=\"loading\"\n size=\"sm\"\n label=\"Loading\"\n />\n <CalendarIcon\n v-else\n v-bind=\"treeIconDefaults\"\n />\n </slot>\n </span>\n </button>\n\n <transition name=\"t-fade\">\n <div\n v-if=\"isOpen && !disabled\"\n :id=\"pickerId\"\n class=\"t-date-picker__content t-date-time-picker__content\"\n role=\"dialog\"\n aria-modal=\"false\"\n :aria-labelledby=\"captionId\"\n >\n <div class=\"t-date-time-picker__calendar\">\n <div class=\"t-date-picker__header\">\n <button\n type=\"button\"\n class=\"t-date-picker__nav\"\n :disabled=\"!canMovePrev\"\n aria-label=\"Previous month\"\n @click=\"moveCalendar(-1)\"\n >\n <ChevronLeftIcon v-bind=\"treeIconDefaults\" />\n </button>\n\n <p\n :id=\"captionId\"\n class=\"t-date-picker__month\"\n >\n {{ monthLabel }}\n </p>\n\n <button\n type=\"button\"\n class=\"t-date-picker__nav\"\n :disabled=\"!canMoveNext\"\n aria-label=\"Next month\"\n @click=\"moveCalendar(1)\"\n >\n <ChevronRightIcon v-bind=\"treeIconDefaults\" />\n </button>\n </div>\n\n <div\n class=\"t-date-picker__weekdays\"\n aria-hidden=\"true\"\n >\n <span\n v-for=\"label in weekdayLabels\"\n :key=\"label\"\n class=\"t-date-picker__weekday\"\n >\n {{ label }}\n </span>\n </div>\n\n <div\n class=\"t-date-picker__grid\"\n role=\"grid\"\n :aria-labelledby=\"captionId\"\n >\n <div\n v-for=\"(week, weekIndex) in cells\"\n :key=\"weekIndex\"\n class=\"t-date-picker__row\"\n role=\"row\"\n >\n <div\n v-for=\"cell in week\"\n :key=\"cell.key\"\n class=\"t-date-picker__cell\"\n role=\"gridcell\"\n :aria-selected=\"cell.isSelected\"\n >\n <button\n :ref=\"(element) => setDayRef(element, cell.key)\"\n type=\"button\"\n class=\"t-date-picker__day\"\n :class=\"{\n 'is-muted': !cell.inMonth,\n 'is-selected': cell.isSelected,\n 'is-today': cell.isToday,\n }\"\n :data-date=\"cell.key\"\n :tabindex=\"cell.isFocused ? 0 : -1\"\n :disabled=\"cell.disabled\"\n :aria-pressed=\"cell.isSelected\"\n @click=\"selectDate(cell.date)\"\n @keydown=\"onDayKeydown($event, cell.date)\"\n >\n {{ cell.dayLabel }}\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"t-date-time-picker__summary\">\n <p class=\"t-date-time-picker__eyebrow\">\n Selected slot\n </p>\n <p class=\"t-date-time-picker__summary-value\">\n {{ draftPreview }}\n </p>\n </div>\n\n <div class=\"t-date-time-picker__time\">\n <label class=\"t-date-time-picker__time-field\">\n <span class=\"t-date-time-picker__time-label\">Hour</span>\n <select\n class=\"t-date-time-picker__select\"\n :value=\"draftDateTime.getHours()\"\n aria-label=\"Select hour\"\n @change=\"updateHour\"\n >\n <option\n v-for=\"option in hourOptions\"\n :key=\"option.value\"\n :value=\"option.value\"\n :disabled=\"option.disabled\"\n >\n {{ option.label }}\n </option>\n </select>\n </label>\n\n <label class=\"t-date-time-picker__time-field\">\n <span class=\"t-date-time-picker__time-label\">Minute</span>\n <select\n class=\"t-date-time-picker__select\"\n :value=\"draftDateTime.getMinutes()\"\n aria-label=\"Select minute\"\n @change=\"updateMinute\"\n >\n <option\n v-for=\"option in minuteOptions\"\n :key=\"option.value\"\n :value=\"option.value\"\n :disabled=\"option.disabled\"\n >\n {{ option.label }}\n </option>\n </select>\n </label>\n </div>\n\n <div class=\"t-date-time-picker__footer\">\n <button\n type=\"button\"\n class=\"t-button t-button--ghost t-button--sm\"\n @click=\"clearSelection\"\n >\n Clear\n </button>\n <button\n type=\"button\"\n class=\"t-button t-button--solid t-button--sm\"\n @click=\"commitDraft\"\n >\n Apply\n </button>\n </div>\n </div>\n </transition>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport {\n addDays,\n addMonths,\n createId,\n isActivationKey,\n isEscapeKey,\n isSameDay,\n startOfDay,\n startOfMonth,\n startOfWeek,\n toDateValue,\n} from '@treeui/utils';\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport {\n type ComponentPublicInstance,\n computed,\n nextTick,\n onBeforeUnmount,\n ref,\n toRef,\n useAttrs,\n watch,\n} from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\ninterface CalendarCell {\n date: Date;\n dayLabel: number;\n disabled: boolean;\n inMonth: boolean;\n isFocused: boolean;\n isSelected: boolean;\n isToday: boolean;\n key: string;\n}\n\ninterface TimeOption {\n disabled: boolean;\n label: string;\n value: number;\n}\n\nconst CalendarIcon = getTreeIcon('calendar');\nconst ChevronLeftIcon = getTreeIcon('chevron-left');\nconst ChevronRightIcon = getTreeIcon('chevron-right');\n\nconst dateOnlyPattern = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\nconst dateTimePattern = /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2})(?::(\\d{2}))?$/;\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n placeholder?: string;\n locale?: string;\n min?: string;\n max?: string;\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;\n id?: string;\n step?: number;\n }>(),\n {\n modelValue: '',\n open: undefined,\n defaultOpen: false,\n size: 'md',\n disabled: false,\n loading: false,\n invalid: false,\n placeholder: 'Select date and time',\n locale: 'en-US',\n min: '',\n max: '',\n weekStartsOn: 0,\n id: undefined,\n step: 60,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n change: [value: string];\n select: [value: string];\n}>();\n\nconst attrs = useAttrs();\n\nconst cloneDate = (value: Date) => new Date(value.getTime());\n\nconst formatPart = (value: number) => `${value}`.padStart(2, '0');\n\nconst endOfDay = (date: Date) =>\n new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59, 999);\n\nconst parseBoundaryValue = (\n value: string | null | undefined,\n boundary: 'exact' | 'start' | 'end' = 'exact',\n) => {\n if (!value) {\n return null;\n }\n\n const dateOnlyMatch = value.match(dateOnlyPattern);\n if (dateOnlyMatch) {\n const [, yearToken, monthToken, dayToken] = dateOnlyMatch;\n const year = Number.parseInt(yearToken, 10);\n const month = Number.parseInt(monthToken, 10);\n const day = Number.parseInt(dayToken, 10);\n const hour = boundary === 'end' ? 23 : 0;\n const minute = boundary === 'end' ? 59 : 0;\n const second = boundary === 'end' ? 59 : 0;\n const millisecond = boundary === 'end' ? 999 : 0;\n const date = new Date(year, month - 1, day, hour, minute, second, millisecond);\n\n if (\n Number.isNaN(date.getTime()) ||\n date.getFullYear() !== year ||\n date.getMonth() !== month - 1 ||\n date.getDate() !== day\n ) {\n return null;\n }\n\n return date;\n }\n\n const dateTimeMatch = value.match(dateTimePattern);\n if (!dateTimeMatch) {\n return null;\n }\n\n const [, yearToken, monthToken, dayToken, hourToken, minuteToken, secondToken] =\n dateTimeMatch;\n const year = Number.parseInt(yearToken, 10);\n const month = Number.parseInt(monthToken, 10);\n const day = Number.parseInt(dayToken, 10);\n const hour = Number.parseInt(hourToken, 10);\n const minute = Number.parseInt(minuteToken, 10);\n const second = secondToken ? Number.parseInt(secondToken, 10) : 0;\n const date = new Date(year, month - 1, day, hour, minute, second, 0);\n\n if (\n Number.isNaN(date.getTime()) ||\n date.getFullYear() !== year ||\n date.getMonth() !== month - 1 ||\n date.getDate() !== day ||\n date.getHours() !== hour ||\n date.getMinutes() !== minute ||\n date.getSeconds() !== second\n ) {\n return null;\n }\n\n return date;\n};\n\nconst toDateTimeValue = (date: Date) =>\n `${toDateValue(date)}T${formatPart(date.getHours())}:${formatPart(date.getMinutes())}`;\n\nconst setDatePart = (source: Date, targetDate: Date) =>\n new Date(\n targetDate.getFullYear(),\n targetDate.getMonth(),\n targetDate.getDate(),\n source.getHours(),\n source.getMinutes(),\n 0,\n 0,\n );\n\nconst setTimePart = (source: Date, hour: number, minute: number) =>\n new Date(\n source.getFullYear(),\n source.getMonth(),\n source.getDate(),\n hour,\n minute,\n 0,\n 0,\n );\n\nconst resolveMinuteStep = (step: number) => {\n if (!Number.isFinite(step) || step <= 0 || step % 60 !== 0) {\n return 1;\n }\n\n const minuteStep = step / 60;\n return minuteStep >= 60 ? 1 : minuteStep;\n};\n\nconst today = startOfDay(new Date());\nconst selectedDateTime = computed(() => parseBoundaryValue(props.modelValue, 'exact'));\nconst minDateTime = computed(() => parseBoundaryValue(props.min, 'start'));\nconst maxDateTime = computed(() => parseBoundaryValue(props.max, 'end'));\nconst pickerId = props.id ?? createId('t-date-time-picker');\nconst captionId = `${pickerId}-caption`;\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst dayRefs = new Map<string, HTMLButtonElement>();\n\nconst clampToRange = (value: Date) => {\n let nextValue = cloneDate(value);\n\n if (minDateTime.value && nextValue < minDateTime.value) {\n nextValue = cloneDate(minDateTime.value);\n }\n\n if (maxDateTime.value && nextValue > maxDateTime.value) {\n nextValue = cloneDate(maxDateTime.value);\n }\n\n return nextValue;\n};\n\nconst createDefaultDraftDateTime = () => {\n const reference = new Date();\n const stepMilliseconds = Math.max(props.step, 60) * 1000;\n const rounded = new Date(Math.ceil(reference.getTime() / stepMilliseconds) * stepMilliseconds);\n\n rounded.setSeconds(0, 0);\n return clampToRange(rounded);\n};\n\nconst initialDateTime = selectedDateTime.value ?? createDefaultDraftDateTime();\nconst draftDateTime = ref(initialDateTime);\nconst focusedDate = ref(startOfDay(initialDateTime));\nconst viewMonth = ref(startOfMonth(initialDateTime));\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, name: _name, ...rest } = attrs;\n return rest;\n});\n\nconst hiddenInputName = computed(() =>\n typeof attrs.name === 'string' ? attrs.name : undefined,\n);\n\nconst rootClasses = computed(() => [\n 't-date-picker',\n 't-date-time-picker',\n `t-date-picker--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst triggerText = computed(() => {\n if (!selectedDateTime.value) {\n return props.placeholder;\n }\n\n return new Intl.DateTimeFormat(props.locale, {\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n month: 'long',\n year: 'numeric',\n }).format(selectedDateTime.value);\n});\n\nconst draftPreview = computed(() =>\n new Intl.DateTimeFormat(props.locale, {\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n month: 'long',\n year: 'numeric',\n }).format(draftDateTime.value),\n);\n\nconst monthLabel = computed(() =>\n new Intl.DateTimeFormat(props.locale, {\n month: 'long',\n year: 'numeric',\n }).format(viewMonth.value),\n);\n\nconst weekdayLabels = computed(() => {\n const formatter = new Intl.DateTimeFormat(props.locale, { weekday: 'short' });\n const weekBase = startOfWeek(new Date(2024, 0, 7), props.weekStartsOn);\n\n return Array.from({ length: 7 }, (_, index) =>\n formatter.format(addDays(weekBase, index)),\n );\n});\n\nconst minuteStep = computed(() => resolveMinuteStep(props.step));\n\nconst minuteValues = computed(() => {\n const values = new Set<number>();\n\n for (let minute = 0; minute < 60; minute += minuteStep.value) {\n values.add(minute);\n }\n\n values.add(draftDateTime.value.getMinutes());\n\n return [...values].sort((left, right) => left - right);\n});\n\nconst isDateDisabled = (date: Date) => {\n if (props.disabled) {\n return true;\n }\n\n const dayStart = startOfDay(date);\n const dayEnd = endOfDay(date);\n\n if (minDateTime.value && dayEnd < minDateTime.value) {\n return true;\n }\n\n if (maxDateTime.value && dayStart > maxDateTime.value) {\n return true;\n }\n\n return false;\n};\n\nconst isDateTimeDisabled = (value: Date) => {\n if (props.disabled) {\n return true;\n }\n\n if (minDateTime.value && value < minDateTime.value) {\n return true;\n }\n\n if (maxDateTime.value && value > maxDateTime.value) {\n return true;\n }\n\n return false;\n};\n\nconst syncCalendarView = (date: Date) => {\n focusedDate.value = startOfDay(date);\n viewMonth.value = startOfMonth(date);\n};\n\nconst syncDraftState = (dateTime: Date) => {\n const nextValue = clampToRange(dateTime);\n draftDateTime.value = nextValue;\n syncCalendarView(nextValue);\n};\n\nwatch(\n selectedDateTime,\n (value) => {\n if (isOpen.value) {\n return;\n }\n\n syncDraftState(value ?? createDefaultDraftDateTime());\n },\n { immediate: true },\n);\n\nconst draftDate = computed(() => startOfDay(draftDateTime.value));\n\nconst cells = computed(() => {\n const startDate = startOfWeek(startOfMonth(viewMonth.value), props.weekStartsOn);\n\n return Array.from({ length: 6 }, (_, weekIndex) =>\n Array.from({ length: 7 }, (_, dayIndex) => {\n const date = addDays(startDate, weekIndex * 7 + dayIndex);\n const key = toDateValue(date);\n\n return {\n date,\n dayLabel: date.getDate(),\n disabled: isDateDisabled(date),\n inMonth: date.getMonth() === viewMonth.value.getMonth(),\n isFocused: isSameDay(date, focusedDate.value),\n isSelected: isSameDay(date, draftDate.value),\n isToday: isSameDay(date, today),\n key,\n } satisfies CalendarCell;\n }),\n );\n});\n\nconst canMovePrev = computed(() => {\n if (!minDateTime.value) {\n return true;\n }\n\n return startOfMonth(viewMonth.value) > startOfMonth(minDateTime.value);\n});\n\nconst canMoveNext = computed(() => {\n if (!maxDateTime.value) {\n return true;\n }\n\n return startOfMonth(viewMonth.value) < startOfMonth(maxDateTime.value);\n});\n\nconst isTimeOptionEnabled = (hour: number, minute: number) => {\n const candidate = setTimePart(draftDateTime.value, hour, minute);\n return !isDateTimeDisabled(candidate);\n};\n\nconst hourOptions = computed<TimeOption[]>(() =>\n Array.from({ length: 24 }, (_, hour) => ({\n disabled: !minuteValues.value.some((minute) => isTimeOptionEnabled(hour, minute)),\n label: formatPart(hour),\n value: hour,\n })),\n);\n\nconst minuteOptions = computed<TimeOption[]>(() =>\n minuteValues.value.map((minute) => ({\n disabled: !isTimeOptionEnabled(draftDateTime.value.getHours(), minute),\n label: formatPart(minute),\n value: minute,\n })),\n);\n\nconst focusCurrentDay = () => {\n const key = toDateValue(focusedDate.value);\n nextTick(() => {\n dayRefs.get(key)?.focus();\n });\n};\n\nconst setDayRef = (\n element: Element | ComponentPublicInstance | null,\n key: string,\n) => {\n if (element instanceof HTMLButtonElement) {\n dayRefs.set(key, element);\n return;\n }\n\n dayRefs.delete(key);\n};\n\nconst openCalendar = () => {\n if (props.disabled) {\n return;\n }\n\n syncDraftState(selectedDateTime.value ?? createDefaultDraftDateTime());\n setValue(true);\n focusCurrentDay();\n};\n\nconst closeCalendar = (restoreFocus = false) => {\n setValue(false);\n\n if (restoreFocus) {\n nextTick(() => {\n triggerRef.value?.focus();\n });\n }\n};\n\nconst toggleCalendar = () => {\n if (isOpen.value) {\n closeCalendar();\n return;\n }\n\n openCalendar();\n};\n\nconst moveCalendar = (direction: 1 | -1) => {\n const nextMonth = addMonths(viewMonth.value, direction);\n syncCalendarView(nextMonth);\n focusCurrentDay();\n};\n\nconst moveFocus = (nextDate: Date) => {\n if (isDateDisabled(nextDate)) {\n return;\n }\n\n syncCalendarView(nextDate);\n focusCurrentDay();\n};\n\nconst selectDate = (date: Date) => {\n if (isDateDisabled(date)) {\n return;\n }\n\n const candidate = clampToRange(setDatePart(draftDateTime.value, date));\n draftDateTime.value = candidate;\n syncCalendarView(candidate);\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) {\n return;\n }\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closeCalendar();\n return;\n }\n\n if (\n isActivationKey(event) ||\n event.key === 'ArrowDown' ||\n event.key === 'ArrowUp'\n ) {\n event.preventDefault();\n openCalendar();\n }\n};\n\nconst onDayKeydown = (event: KeyboardEvent, date: Date) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeCalendar(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectDate(date);\n return;\n }\n\n switch (event.key) {\n case 'ArrowLeft':\n event.preventDefault();\n moveFocus(addDays(date, -1));\n break;\n case 'ArrowRight':\n event.preventDefault();\n moveFocus(addDays(date, 1));\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(addDays(date, -7));\n break;\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(addDays(date, 7));\n break;\n case 'Home':\n event.preventDefault();\n moveFocus(startOfWeek(date, props.weekStartsOn));\n break;\n case 'End':\n event.preventDefault();\n moveFocus(addDays(startOfWeek(date, props.weekStartsOn), 6));\n break;\n case 'PageUp':\n event.preventDefault();\n moveFocus(addMonths(date, event.shiftKey ? -12 : -1));\n break;\n case 'PageDown':\n event.preventDefault();\n moveFocus(addMonths(date, event.shiftKey ? 12 : 1));\n break;\n default:\n break;\n }\n};\n\nconst updateHour = (event: Event) => {\n const nextHour = Number.parseInt((event.target as HTMLSelectElement).value, 10);\n const currentMinute = draftDateTime.value.getMinutes();\n\n if (Number.isNaN(nextHour)) {\n return;\n }\n\n const availableMinutes = minuteValues.value.filter((minute) =>\n isTimeOptionEnabled(nextHour, minute),\n );\n\n if (!availableMinutes.length) {\n return;\n }\n\n const nextMinute = availableMinutes.includes(currentMinute)\n ? currentMinute\n : availableMinutes[0];\n\n draftDateTime.value = setTimePart(draftDateTime.value, nextHour, nextMinute);\n};\n\nconst updateMinute = (event: Event) => {\n const nextMinute = Number.parseInt((event.target as HTMLSelectElement).value, 10);\n const nextHour = draftDateTime.value.getHours();\n\n if (Number.isNaN(nextMinute) || !isTimeOptionEnabled(nextHour, nextMinute)) {\n return;\n }\n\n draftDateTime.value = setTimePart(draftDateTime.value, nextHour, nextMinute);\n};\n\nconst commitDraft = () => {\n const value = toDateTimeValue(draftDateTime.value);\n\n emit('update:modelValue', value);\n emit('change', value);\n emit('select', value);\n closeCalendar(true);\n};\n\nconst clearSelection = () => {\n emit('update:modelValue', '');\n emit('change', '');\n emit('select', '');\n closeCalendar(true);\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) {\n return;\n }\n\n const target = event.target;\n if (!(target instanceof Node)) {\n return;\n }\n\n if (rootRef.value?.contains(target)) {\n return;\n }\n\n closeCalendar();\n};\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n return;\n }\n\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <input\n v-if=\"hiddenInputName\"\n type=\"hidden\"\n :name=\"hiddenInputName\"\n :value=\"modelValue\"\n >\n\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-date-picker__trigger t-date-time-picker__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? pickerId : undefined\"\n aria-haspopup=\"dialog\"\n :aria-expanded=\"isOpen\"\n :aria-invalid=\"invalid || undefined\"\n @click=\"toggleCalendar\"\n @keydown=\"onTriggerKeydown\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-date-picker__slot t-date-picker__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n\n <span\n class=\"t-date-picker__value\"\n :data-placeholder=\"selectedDateTime ? undefined : true\"\n >\n {{ triggerText }}\n </span>\n\n <span class=\"t-date-picker__slot t-date-picker__slot--suffix\">\n <slot name=\"suffix\">\n <TSpinner\n v-if=\"loading\"\n size=\"sm\"\n label=\"Loading\"\n />\n <CalendarIcon\n v-else\n v-bind=\"treeIconDefaults\"\n />\n </slot>\n </span>\n </button>\n\n <transition name=\"t-fade\">\n <div\n v-if=\"isOpen && !disabled\"\n :id=\"pickerId\"\n class=\"t-date-picker__content t-date-time-picker__content\"\n role=\"dialog\"\n aria-modal=\"false\"\n :aria-labelledby=\"captionId\"\n >\n <div class=\"t-date-time-picker__calendar\">\n <div class=\"t-date-picker__header\">\n <button\n type=\"button\"\n class=\"t-date-picker__nav\"\n :disabled=\"!canMovePrev\"\n aria-label=\"Previous month\"\n @click=\"moveCalendar(-1)\"\n >\n <ChevronLeftIcon v-bind=\"treeIconDefaults\" />\n </button>\n\n <p\n :id=\"captionId\"\n class=\"t-date-picker__month\"\n >\n {{ monthLabel }}\n </p>\n\n <button\n type=\"button\"\n class=\"t-date-picker__nav\"\n :disabled=\"!canMoveNext\"\n aria-label=\"Next month\"\n @click=\"moveCalendar(1)\"\n >\n <ChevronRightIcon v-bind=\"treeIconDefaults\" />\n </button>\n </div>\n\n <div\n class=\"t-date-picker__weekdays\"\n aria-hidden=\"true\"\n >\n <span\n v-for=\"label in weekdayLabels\"\n :key=\"label\"\n class=\"t-date-picker__weekday\"\n >\n {{ label }}\n </span>\n </div>\n\n <div\n class=\"t-date-picker__grid\"\n role=\"grid\"\n :aria-labelledby=\"captionId\"\n >\n <div\n v-for=\"(week, weekIndex) in cells\"\n :key=\"weekIndex\"\n class=\"t-date-picker__row\"\n role=\"row\"\n >\n <div\n v-for=\"cell in week\"\n :key=\"cell.key\"\n class=\"t-date-picker__cell\"\n role=\"gridcell\"\n :aria-selected=\"cell.isSelected\"\n >\n <button\n :ref=\"(element) => setDayRef(element, cell.key)\"\n type=\"button\"\n class=\"t-date-picker__day\"\n :class=\"{\n 'is-muted': !cell.inMonth,\n 'is-selected': cell.isSelected,\n 'is-today': cell.isToday,\n }\"\n :data-date=\"cell.key\"\n :tabindex=\"cell.isFocused ? 0 : -1\"\n :disabled=\"cell.disabled\"\n :aria-pressed=\"cell.isSelected\"\n @click=\"selectDate(cell.date)\"\n @keydown=\"onDayKeydown($event, cell.date)\"\n >\n {{ cell.dayLabel }}\n </button>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"t-date-time-picker__summary\">\n <p class=\"t-date-time-picker__eyebrow\">\n Selected slot\n </p>\n <p class=\"t-date-time-picker__summary-value\">\n {{ draftPreview }}\n </p>\n </div>\n\n <div class=\"t-date-time-picker__time\">\n <label class=\"t-date-time-picker__time-field\">\n <span class=\"t-date-time-picker__time-label\">Hour</span>\n <select\n class=\"t-date-time-picker__select\"\n :value=\"draftDateTime.getHours()\"\n aria-label=\"Select hour\"\n @change=\"updateHour\"\n >\n <option\n v-for=\"option in hourOptions\"\n :key=\"option.value\"\n :value=\"option.value\"\n :disabled=\"option.disabled\"\n >\n {{ option.label }}\n </option>\n </select>\n </label>\n\n <label class=\"t-date-time-picker__time-field\">\n <span class=\"t-date-time-picker__time-label\">Minute</span>\n <select\n class=\"t-date-time-picker__select\"\n :value=\"draftDateTime.getMinutes()\"\n aria-label=\"Select minute\"\n @change=\"updateMinute\"\n >\n <option\n v-for=\"option in minuteOptions\"\n :key=\"option.value\"\n :value=\"option.value\"\n :disabled=\"option.disabled\"\n >\n {{ option.label }}\n </option>\n </select>\n </label>\n </div>\n\n <div class=\"t-date-time-picker__footer\">\n <button\n type=\"button\"\n class=\"t-button t-button--ghost t-button--sm\"\n @click=\"clearSelection\"\n >\n Clear\n </button>\n <button\n type=\"button\"\n class=\"t-button t-button--solid t-button--sm\"\n @click=\"commitDraft\"\n >\n Apply\n </button>\n </div>\n </div>\n </transition>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport {\n createId,\n focusFirst,\n focusLast,\n getFocusableElements,\n isEscapeKey,\n} from '@treeui/utils';\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport {\n computed,\n nextTick,\n onBeforeUnmount,\n ref,\n toRef,\n useAttrs,\n watch,\n} from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TDrawerSide, TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst CloseIcon = getTreeIcon('x');\n\nconst props = withDefaults(\n defineProps<{\n open?: boolean;\n defaultOpen?: boolean;\n disabled?: boolean;\n size?: TSize;\n side?: TDrawerSide;\n title?: string;\n description?: string;\n closeOnEscape?: boolean;\n closeOnOverlay?: boolean;\n showCloseButton?: boolean;\n closeLabel?: string;\n id?: string;\n }>(),\n {\n open: undefined,\n defaultOpen: false,\n disabled: false,\n size: 'md',\n side: 'right',\n title: '',\n description: '',\n closeOnEscape: true,\n closeOnOverlay: true,\n showCloseButton: true,\n closeLabel: 'Close drawer',\n id: undefined,\n },\n);\n\nconst emit = defineEmits<{\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\nconst attrs = useAttrs();\nconst drawerId = props.id ?? createId('t-drawer');\nconst titleId = `${drawerId}-title`;\nconst descriptionId = `${drawerId}-description`;\nconst rootRef = ref<HTMLElement | null>(null);\nconst surfaceRef = ref<HTMLElement | null>(null);\nconst previousFocusedElement = ref<HTMLElement | null>(null);\nconst hasHeaderContent = computed(() => Boolean(props.title || slots.header));\n\nconst slots = defineSlots<{\n default?: () => unknown;\n trigger?: () => unknown;\n header?: () => unknown;\n content?: () => unknown;\n footer?: () => unknown;\n}>();\n\nconst rootClasses = computed(() => ['t-drawer', attrs.class]);\nconst rootStyle = computed(() => attrs.style);\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\nconst surfaceClasses = computed(() => [\n 't-drawer__surface',\n `t-drawer__surface--${props.size}`,\n `t-drawer__surface--${props.side}`,\n]);\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst labelledBy = computed(() => (hasHeaderContent.value ? titleId : undefined));\nconst describedBy = computed(() => (props.description ? descriptionId : undefined));\n\nlet openOverlayCount = 0;\nlet previousBodyOverflow = '';\n\nconst lockBodyScroll = () => {\n if (typeof document === 'undefined') {\n return;\n }\n\n if (openOverlayCount === 0) {\n previousBodyOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n }\n\n openOverlayCount += 1;\n};\n\nconst unlockBodyScroll = () => {\n if (typeof document === 'undefined' || openOverlayCount === 0) {\n return;\n }\n\n openOverlayCount -= 1;\n\n if (openOverlayCount === 0) {\n document.body.style.overflow = previousBodyOverflow;\n }\n};\n\nconst focusSurface = () => {\n nextTick(() => {\n if (!surfaceRef.value) {\n return;\n }\n\n const focused = focusFirst(surfaceRef.value);\n if (!focused) {\n surfaceRef.value.focus();\n }\n });\n};\n\nconst openDrawer = () => {\n if (props.disabled) {\n return;\n }\n\n previousFocusedElement.value = document.activeElement as HTMLElement | null;\n setValue(true);\n};\n\nconst closeDrawer = () => {\n setValue(false);\n};\n\nconst onTriggerClick = (event: MouseEvent) => {\n if (props.disabled) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n\n if (event.defaultPrevented) {\n return;\n }\n\n openDrawer();\n};\n\nconst onOverlayClick = () => {\n if (!props.closeOnOverlay) {\n return;\n }\n\n closeDrawer();\n};\n\nconst onSurfaceClick = (event: MouseEvent) => {\n event.stopPropagation();\n};\n\nconst onKeydown = (event: KeyboardEvent) => {\n if (isEscapeKey(event) && props.closeOnEscape) {\n event.preventDefault();\n closeDrawer();\n return;\n }\n\n if (event.key !== 'Tab' || !surfaceRef.value) {\n return;\n }\n\n const focusable = getFocusableElements(surfaceRef.value);\n\n if (!focusable.length) {\n event.preventDefault();\n surfaceRef.value.focus();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const activeElement = document.activeElement as HTMLElement | null;\n\n if (event.shiftKey && activeElement === first) {\n event.preventDefault();\n focusLast(surfaceRef.value);\n }\n\n if (!event.shiftKey && activeElement === last) {\n event.preventDefault();\n focusFirst(surfaceRef.value);\n }\n};\n\nwatch(isOpen, (value, previousValue) => {\n if (value) {\n lockBodyScroll();\n focusSurface();\n return;\n }\n\n if (previousValue) {\n unlockBodyScroll();\n nextTick(() => {\n previousFocusedElement.value?.focus();\n });\n }\n});\n\nonBeforeUnmount(() => {\n if (isOpen.value) {\n unlockBodyScroll();\n }\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <span\n v-if=\"$slots.trigger\"\n class=\"t-drawer__trigger\"\n v-bind=\"triggerAttrs\"\n :aria-disabled=\"disabled || undefined\"\n @click=\"onTriggerClick\"\n >\n <slot name=\"trigger\" />\n </span>\n\n <Teleport to=\"body\">\n <transition name=\"t-drawer-fade\">\n <div\n v-if=\"isOpen\"\n class=\"t-drawer__portal\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <div\n class=\"t-drawer__backdrop\"\n aria-hidden=\"true\"\n @click=\"onOverlayClick\"\n />\n <div\n :id=\"drawerId\"\n ref=\"surfaceRef\"\n :class=\"surfaceClasses\"\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-labelledby=\"labelledBy\"\n :aria-describedby=\"describedBy\"\n tabindex=\"-1\"\n @click=\"onSurfaceClick\"\n @keydown=\"onKeydown\"\n >\n <div\n v-if=\"hasHeaderContent || showCloseButton\"\n class=\"t-drawer__topbar\"\n >\n <div\n v-if=\"hasHeaderContent\"\n :id=\"titleId\"\n class=\"t-drawer__header\"\n >\n <slot name=\"header\">\n <h2 class=\"t-drawer__title\">\n {{ title }}\n </h2>\n </slot>\n </div>\n <button\n v-if=\"showCloseButton\"\n type=\"button\"\n class=\"t-drawer__close\"\n :aria-label=\"closeLabel\"\n @click=\"closeDrawer\"\n >\n <CloseIcon v-bind=\"treeIconDefaults\" />\n </button>\n </div>\n\n <p\n v-if=\"description\"\n :id=\"descriptionId\"\n class=\"t-drawer__description\"\n >\n {{ description }}\n </p>\n\n <div class=\"t-drawer__body\">\n <slot name=\"content\">\n <slot />\n </slot>\n </div>\n\n <div\n v-if=\"$slots.footer\"\n class=\"t-drawer__footer\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n </div>\n </transition>\n </Teleport>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport {\n createId,\n focusFirst,\n focusLast,\n getFocusableElements,\n isEscapeKey,\n} from '@treeui/utils';\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport {\n computed,\n nextTick,\n onBeforeUnmount,\n ref,\n toRef,\n useAttrs,\n watch,\n} from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TDrawerSide, TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst CloseIcon = getTreeIcon('x');\n\nconst props = withDefaults(\n defineProps<{\n open?: boolean;\n defaultOpen?: boolean;\n disabled?: boolean;\n size?: TSize;\n side?: TDrawerSide;\n title?: string;\n description?: string;\n closeOnEscape?: boolean;\n closeOnOverlay?: boolean;\n showCloseButton?: boolean;\n closeLabel?: string;\n id?: string;\n }>(),\n {\n open: undefined,\n defaultOpen: false,\n disabled: false,\n size: 'md',\n side: 'right',\n title: '',\n description: '',\n closeOnEscape: true,\n closeOnOverlay: true,\n showCloseButton: true,\n closeLabel: 'Close drawer',\n id: undefined,\n },\n);\n\nconst emit = defineEmits<{\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\nconst attrs = useAttrs();\nconst drawerId = props.id ?? createId('t-drawer');\nconst titleId = `${drawerId}-title`;\nconst descriptionId = `${drawerId}-description`;\nconst rootRef = ref<HTMLElement | null>(null);\nconst surfaceRef = ref<HTMLElement | null>(null);\nconst previousFocusedElement = ref<HTMLElement | null>(null);\nconst hasHeaderContent = computed(() => Boolean(props.title || slots.header));\n\nconst slots = defineSlots<{\n default?: () => unknown;\n trigger?: () => unknown;\n header?: () => unknown;\n content?: () => unknown;\n footer?: () => unknown;\n}>();\n\nconst rootClasses = computed(() => ['t-drawer', attrs.class]);\nconst rootStyle = computed(() => attrs.style);\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\nconst surfaceClasses = computed(() => [\n 't-drawer__surface',\n `t-drawer__surface--${props.size}`,\n `t-drawer__surface--${props.side}`,\n]);\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst labelledBy = computed(() => (hasHeaderContent.value ? titleId : undefined));\nconst describedBy = computed(() => (props.description ? descriptionId : undefined));\n\nlet openOverlayCount = 0;\nlet previousBodyOverflow = '';\n\nconst lockBodyScroll = () => {\n if (typeof document === 'undefined') {\n return;\n }\n\n if (openOverlayCount === 0) {\n previousBodyOverflow = document.body.style.overflow;\n document.body.style.overflow = 'hidden';\n }\n\n openOverlayCount += 1;\n};\n\nconst unlockBodyScroll = () => {\n if (typeof document === 'undefined' || openOverlayCount === 0) {\n return;\n }\n\n openOverlayCount -= 1;\n\n if (openOverlayCount === 0) {\n document.body.style.overflow = previousBodyOverflow;\n }\n};\n\nconst focusSurface = () => {\n nextTick(() => {\n if (!surfaceRef.value) {\n return;\n }\n\n const focused = focusFirst(surfaceRef.value);\n if (!focused) {\n surfaceRef.value.focus();\n }\n });\n};\n\nconst openDrawer = () => {\n if (props.disabled) {\n return;\n }\n\n previousFocusedElement.value = document.activeElement as HTMLElement | null;\n setValue(true);\n};\n\nconst closeDrawer = () => {\n setValue(false);\n};\n\nconst onTriggerClick = (event: MouseEvent) => {\n if (props.disabled) {\n event.preventDefault();\n event.stopPropagation();\n return;\n }\n\n if (event.defaultPrevented) {\n return;\n }\n\n openDrawer();\n};\n\nconst onOverlayClick = () => {\n if (!props.closeOnOverlay) {\n return;\n }\n\n closeDrawer();\n};\n\nconst onSurfaceClick = (event: MouseEvent) => {\n event.stopPropagation();\n};\n\nconst onKeydown = (event: KeyboardEvent) => {\n if (isEscapeKey(event) && props.closeOnEscape) {\n event.preventDefault();\n closeDrawer();\n return;\n }\n\n if (event.key !== 'Tab' || !surfaceRef.value) {\n return;\n }\n\n const focusable = getFocusableElements(surfaceRef.value);\n\n if (!focusable.length) {\n event.preventDefault();\n surfaceRef.value.focus();\n return;\n }\n\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const activeElement = document.activeElement as HTMLElement | null;\n\n if (event.shiftKey && activeElement === first) {\n event.preventDefault();\n focusLast(surfaceRef.value);\n }\n\n if (!event.shiftKey && activeElement === last) {\n event.preventDefault();\n focusFirst(surfaceRef.value);\n }\n};\n\nwatch(isOpen, (value, previousValue) => {\n if (value) {\n lockBodyScroll();\n focusSurface();\n return;\n }\n\n if (previousValue) {\n unlockBodyScroll();\n nextTick(() => {\n previousFocusedElement.value?.focus();\n });\n }\n});\n\nonBeforeUnmount(() => {\n if (isOpen.value) {\n unlockBodyScroll();\n }\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <span\n v-if=\"$slots.trigger\"\n class=\"t-drawer__trigger\"\n v-bind=\"triggerAttrs\"\n :aria-disabled=\"disabled || undefined\"\n @click=\"onTriggerClick\"\n >\n <slot name=\"trigger\" />\n </span>\n\n <Teleport to=\"body\">\n <transition name=\"t-drawer-fade\">\n <div\n v-if=\"isOpen\"\n class=\"t-drawer__portal\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <div\n class=\"t-drawer__backdrop\"\n aria-hidden=\"true\"\n @click=\"onOverlayClick\"\n />\n <div\n :id=\"drawerId\"\n ref=\"surfaceRef\"\n :class=\"surfaceClasses\"\n role=\"dialog\"\n aria-modal=\"true\"\n :aria-labelledby=\"labelledBy\"\n :aria-describedby=\"describedBy\"\n tabindex=\"-1\"\n @click=\"onSurfaceClick\"\n @keydown=\"onKeydown\"\n >\n <div\n v-if=\"hasHeaderContent || showCloseButton\"\n class=\"t-drawer__topbar\"\n >\n <div\n v-if=\"hasHeaderContent\"\n :id=\"titleId\"\n class=\"t-drawer__header\"\n >\n <slot name=\"header\">\n <h2 class=\"t-drawer__title\">\n {{ title }}\n </h2>\n </slot>\n </div>\n <button\n v-if=\"showCloseButton\"\n type=\"button\"\n class=\"t-drawer__close\"\n :aria-label=\"closeLabel\"\n @click=\"closeDrawer\"\n >\n <CloseIcon v-bind=\"treeIconDefaults\" />\n </button>\n </div>\n\n <p\n v-if=\"description\"\n :id=\"descriptionId\"\n class=\"t-drawer__description\"\n >\n {{ description }}\n </p>\n\n <div class=\"t-drawer__body\">\n <slot name=\"content\">\n <slot />\n </slot>\n </div>\n\n <div\n v-if=\"$slots.footer\"\n class=\"t-drawer__footer\"\n >\n <slot name=\"footer\" />\n </div>\n </div>\n </div>\n </transition>\n </Teleport>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { createId, isActivationKey, isEscapeKey } from '@treeui/utils';\nimport { computed, nextTick, onBeforeUnmount, ref, toRef, useAttrs, watch } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TDropdownItem {\n label: string;\n value: string;\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n items?: TDropdownItem[];\n open?: boolean;\n defaultOpen?: boolean;\n disabled?: boolean;\n size?: TSize;\n label?: string;\n }>(),\n {\n items: () => [],\n open: undefined,\n defaultOpen: false,\n disabled: false,\n size: 'md',\n label: '',\n },\n);\n\nconst emit = defineEmits<{\n select: [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\ndefineSlots<{\n trigger(props: { isOpen: boolean }): unknown;\n item(props: { item: TDropdownItem; index: number }): unknown;\n}>();\n\nconst attrs = useAttrs();\nconst menuId = createId('t-dropdown');\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst itemRefs = ref<Map<string, HTMLElement>>(new Map());\nconst focusedIndex = ref(-1);\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-dropdown',\n `t-dropdown--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst enabledItems = computed(() => props.items.filter((i) => !i.disabled));\n\nconst openMenu = () => {\n if (props.disabled) return;\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n setValue(true);\n nextTick(() => focusItem(focusedIndex.value));\n};\n\nconst closeMenu = (restoreFocus = false) => {\n setValue(false);\n focusedIndex.value = -1;\n if (restoreFocus) {\n nextTick(() => triggerRef.value?.focus());\n }\n};\n\nconst toggleMenu = () => {\n if (isOpen.value) {\n closeMenu();\n } else {\n openMenu();\n }\n};\n\nconst selectItem = (item: TDropdownItem) => {\n if (item.disabled) return;\n emit('select', item.value);\n closeMenu(true);\n};\n\nconst focusItem = (index: number) => {\n const item = props.items[index];\n if (!item) return;\n const el = itemRefs.value.get(item.value);\n el?.focus();\n};\n\nconst setItemRef = (el: Element | null, value: string) => {\n if (el instanceof HTMLElement) {\n itemRefs.value.set(value, el);\n } else {\n itemRefs.value.delete(value);\n }\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n let nextIndex = focusedIndex.value + direction;\n while (nextIndex >= 0 && nextIndex < props.items.length) {\n if (!props.items[nextIndex].disabled) {\n focusedIndex.value = nextIndex;\n focusItem(nextIndex);\n return;\n }\n nextIndex += direction;\n }\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) return;\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closeMenu();\n return;\n }\n\n if (isActivationKey(event) || event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n openMenu();\n }\n};\n\nconst onItemKeydown = (event: KeyboardEvent, item: TDropdownItem) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeMenu(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectItem(item);\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(-1);\n break;\n case 'Home':\n event.preventDefault();\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n focusItem(focusedIndex.value);\n break;\n case 'End':\n event.preventDefault();\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[enabledItems.value.length - 1])\n : props.items.length - 1;\n focusItem(focusedIndex.value);\n break;\n default:\n break;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) return;\n const target = event.target;\n if (!(target instanceof Node)) return;\n if (rootRef.value?.contains(target)) return;\n closeMenu();\n};\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n } else {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <span class=\"t-dropdown__trigger-wrapper\">\n <slot\n name=\"trigger\"\n :is-open=\"isOpen\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-dropdown__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? menuId : undefined\"\n aria-haspopup=\"menu\"\n :aria-expanded=\"isOpen\"\n @click=\"toggleMenu\"\n @keydown=\"onTriggerKeydown\"\n >\n <span class=\"t-dropdown__label\">{{ label }}</span>\n <svg\n class=\"t-dropdown__chevron\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"4 6 8 10 12 6\" />\n </svg>\n </button>\n </slot>\n </span>\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"menuId\"\n role=\"menu\"\n class=\"t-dropdown__menu\"\n :aria-label=\"label || undefined\"\n >\n <li\n v-for=\"(item, index) in items\"\n :key=\"item.value\"\n :ref=\"(el) => setItemRef(el as Element | null, item.value)\"\n role=\"menuitem\"\n class=\"t-dropdown__item\"\n :class=\"{\n 'is-disabled': item.disabled,\n 'is-focused': index === focusedIndex,\n }\"\n :aria-disabled=\"item.disabled || undefined\"\n :tabindex=\"item.disabled ? -1 : 0\"\n @click=\"selectItem(item)\"\n @keydown=\"onItemKeydown($event, item)\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :index=\"index\"\n >\n {{ item.label }}\n </slot>\n </li>\n </ul>\n </transition>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { createId, isActivationKey, isEscapeKey } from '@treeui/utils';\nimport { computed, nextTick, onBeforeUnmount, ref, toRef, useAttrs, watch } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TDropdownItem {\n label: string;\n value: string;\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n items?: TDropdownItem[];\n open?: boolean;\n defaultOpen?: boolean;\n disabled?: boolean;\n size?: TSize;\n label?: string;\n }>(),\n {\n items: () => [],\n open: undefined,\n defaultOpen: false,\n disabled: false,\n size: 'md',\n label: '',\n },\n);\n\nconst emit = defineEmits<{\n select: [value: string];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\ndefineSlots<{\n trigger(props: { isOpen: boolean }): unknown;\n item(props: { item: TDropdownItem; index: number }): unknown;\n}>();\n\nconst attrs = useAttrs();\nconst menuId = createId('t-dropdown');\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst itemRefs = ref<Map<string, HTMLElement>>(new Map());\nconst focusedIndex = ref(-1);\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-dropdown',\n `t-dropdown--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst enabledItems = computed(() => props.items.filter((i) => !i.disabled));\n\nconst openMenu = () => {\n if (props.disabled) return;\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n setValue(true);\n nextTick(() => focusItem(focusedIndex.value));\n};\n\nconst closeMenu = (restoreFocus = false) => {\n setValue(false);\n focusedIndex.value = -1;\n if (restoreFocus) {\n nextTick(() => triggerRef.value?.focus());\n }\n};\n\nconst toggleMenu = () => {\n if (isOpen.value) {\n closeMenu();\n } else {\n openMenu();\n }\n};\n\nconst selectItem = (item: TDropdownItem) => {\n if (item.disabled) return;\n emit('select', item.value);\n closeMenu(true);\n};\n\nconst focusItem = (index: number) => {\n const item = props.items[index];\n if (!item) return;\n const el = itemRefs.value.get(item.value);\n el?.focus();\n};\n\nconst setItemRef = (el: Element | null, value: string) => {\n if (el instanceof HTMLElement) {\n itemRefs.value.set(value, el);\n } else {\n itemRefs.value.delete(value);\n }\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n let nextIndex = focusedIndex.value + direction;\n while (nextIndex >= 0 && nextIndex < props.items.length) {\n if (!props.items[nextIndex].disabled) {\n focusedIndex.value = nextIndex;\n focusItem(nextIndex);\n return;\n }\n nextIndex += direction;\n }\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) return;\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closeMenu();\n return;\n }\n\n if (isActivationKey(event) || event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n openMenu();\n }\n};\n\nconst onItemKeydown = (event: KeyboardEvent, item: TDropdownItem) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeMenu(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectItem(item);\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(-1);\n break;\n case 'Home':\n event.preventDefault();\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[0])\n : 0;\n focusItem(focusedIndex.value);\n break;\n case 'End':\n event.preventDefault();\n focusedIndex.value = enabledItems.value.length > 0\n ? props.items.indexOf(enabledItems.value[enabledItems.value.length - 1])\n : props.items.length - 1;\n focusItem(focusedIndex.value);\n break;\n default:\n break;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) return;\n const target = event.target;\n if (!(target instanceof Node)) return;\n if (rootRef.value?.contains(target)) return;\n closeMenu();\n};\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n } else {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <span class=\"t-dropdown__trigger-wrapper\">\n <slot\n name=\"trigger\"\n :is-open=\"isOpen\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-dropdown__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? menuId : undefined\"\n aria-haspopup=\"menu\"\n :aria-expanded=\"isOpen\"\n @click=\"toggleMenu\"\n @keydown=\"onTriggerKeydown\"\n >\n <span class=\"t-dropdown__label\">{{ label }}</span>\n <svg\n class=\"t-dropdown__chevron\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"4 6 8 10 12 6\" />\n </svg>\n </button>\n </slot>\n </span>\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"menuId\"\n role=\"menu\"\n class=\"t-dropdown__menu\"\n :aria-label=\"label || undefined\"\n >\n <li\n v-for=\"(item, index) in items\"\n :key=\"item.value\"\n :ref=\"(el) => setItemRef(el as Element | null, item.value)\"\n role=\"menuitem\"\n class=\"t-dropdown__item\"\n :class=\"{\n 'is-disabled': item.disabled,\n 'is-focused': index === focusedIndex,\n }\"\n :aria-disabled=\"item.disabled || undefined\"\n :tabindex=\"item.disabled ? -1 : 0\"\n @click=\"selectItem(item)\"\n @keydown=\"onItemKeydown($event, item)\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :index=\"index\"\n >\n {{ item.label }}\n </slot>\n </li>\n </ul>\n </transition>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { createId } from '@treeui/utils';\nimport { computed, useAttrs } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst slots = defineSlots<{\n icon?: () => unknown;\n title?: () => unknown;\n description?: () => unknown;\n default?: () => unknown;\n actions?: () => unknown;\n}>();\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n size?: TSize;\n title?: string;\n description?: string;\n }>(),\n {\n as: 'section',\n size: 'md',\n title: '',\n description: '',\n },\n);\n\nconst attrs = useAttrs();\nconst emptyStateId = createId('t-empty-state');\nconst titleId = `${emptyStateId}-title`;\nconst descriptionId = `${emptyStateId}-description`;\n\nconst hasTitle = computed(() => Boolean(props.title || slots.title));\nconst hasDescription = computed(() => Boolean(props.description || slots.description));\n\nconst classes = computed(() => [\n 't-empty-state',\n `t-empty-state--${props.size}`,\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"classes\"\n :style=\"rootStyle\"\n :aria-labelledby=\"hasTitle ? titleId : undefined\"\n :aria-describedby=\"hasDescription ? descriptionId : undefined\"\n >\n <div\n v-if=\"$slots.icon\"\n class=\"t-empty-state__icon\"\n aria-hidden=\"true\"\n >\n <slot name=\"icon\" />\n </div>\n\n <div class=\"t-empty-state__content\">\n <h2\n v-if=\"hasTitle\"\n :id=\"titleId\"\n class=\"t-empty-state__title\"\n >\n <slot name=\"title\">\n {{ title }}\n </slot>\n </h2>\n\n <p\n v-if=\"hasDescription\"\n :id=\"descriptionId\"\n class=\"t-empty-state__description\"\n >\n <slot name=\"description\">\n {{ description }}\n </slot>\n </p>\n\n <div\n v-if=\"$slots.default\"\n class=\"t-empty-state__body\"\n >\n <slot />\n </div>\n\n <div\n v-if=\"$slots.actions\"\n class=\"t-empty-state__actions\"\n >\n <slot name=\"actions\" />\n </div>\n </div>\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { createId } from '@treeui/utils';\nimport { computed, useAttrs } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst slots = defineSlots<{\n icon?: () => unknown;\n title?: () => unknown;\n description?: () => unknown;\n default?: () => unknown;\n actions?: () => unknown;\n}>();\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n size?: TSize;\n title?: string;\n description?: string;\n }>(),\n {\n as: 'section',\n size: 'md',\n title: '',\n description: '',\n },\n);\n\nconst attrs = useAttrs();\nconst emptyStateId = createId('t-empty-state');\nconst titleId = `${emptyStateId}-title`;\nconst descriptionId = `${emptyStateId}-description`;\n\nconst hasTitle = computed(() => Boolean(props.title || slots.title));\nconst hasDescription = computed(() => Boolean(props.description || slots.description));\n\nconst classes = computed(() => [\n 't-empty-state',\n `t-empty-state--${props.size}`,\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"classes\"\n :style=\"rootStyle\"\n :aria-labelledby=\"hasTitle ? titleId : undefined\"\n :aria-describedby=\"hasDescription ? descriptionId : undefined\"\n >\n <div\n v-if=\"$slots.icon\"\n class=\"t-empty-state__icon\"\n aria-hidden=\"true\"\n >\n <slot name=\"icon\" />\n </div>\n\n <div class=\"t-empty-state__content\">\n <h2\n v-if=\"hasTitle\"\n :id=\"titleId\"\n class=\"t-empty-state__title\"\n >\n <slot name=\"title\">\n {{ title }}\n </slot>\n </h2>\n\n <p\n v-if=\"hasDescription\"\n :id=\"descriptionId\"\n class=\"t-empty-state__description\"\n >\n <slot name=\"description\">\n {{ description }}\n </slot>\n </p>\n\n <div\n v-if=\"$slots.default\"\n class=\"t-empty-state__body\"\n >\n <slot />\n </div>\n\n <div\n v-if=\"$slots.actions\"\n class=\"t-empty-state__actions\"\n >\n <slot name=\"actions\" />\n </div>\n </div>\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { createId, isActivationKey } from '@treeui/utils';\nimport { computed, onBeforeUnmount, onMounted, ref, useAttrs } from 'vue';\nimport type { TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport type TFileUploadRejectionReason =\n | 'file-invalid-type'\n | 'file-too-large'\n | 'too-many-files';\n\nexport interface TFileUploadRejection {\n file: File;\n reason: TFileUploadRejectionReason;\n message: string;\n}\n\nconst slots = defineSlots<{\n icon?: () => unknown;\n default?: (props: {\n files: File[];\n isDragActive: boolean;\n openFileDialog: () => void;\n clearFiles: () => void;\n }) => unknown;\n file?: (props: {\n file: File;\n index: number;\n removeFile: () => void;\n }) => unknown;\n actions?: (props: {\n files: File[];\n openFileDialog: () => void;\n clearFiles: () => void;\n }) => unknown;\n}>();\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: File[];\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n accept?: string;\n multiple?: boolean;\n maxFiles?: number | null;\n maxFileSize?: number | null;\n label?: string;\n description?: string;\n buttonLabel?: string;\n filesLabel?: string;\n paste?: boolean;\n drop?: boolean;\n showFileList?: boolean;\n }>(),\n {\n modelValue: () => [],\n size: 'md',\n disabled: false,\n loading: false,\n invalid: false,\n accept: '',\n multiple: true,\n label: 'Drop files here',\n description: 'Click to browse, drag and drop, or paste with Ctrl+V.',\n buttonLabel: 'Browse files',\n filesLabel: 'Selected files',\n maxFiles: null,\n maxFileSize: null,\n paste: true,\n drop: true,\n showFileList: true,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [files: File[]];\n 'files-accepted': [files: File[]];\n 'files-rejected': [rejections: TFileUploadRejection[]];\n}>();\n\nconst attrs = useAttrs();\nconst rootRef = ref<HTMLElement | null>(null);\nconst inputRef = ref<HTMLInputElement | null>(null);\nconst isDragActive = ref(false);\nconst isFocusedWithin = ref(false);\nconst dragDepth = ref(0);\nconst feedbackMessages = ref<string[]>([]);\n\nconst uploadId = createId('t-file-upload');\nconst descriptionId = `${uploadId}-description`;\nconst feedbackId = `${uploadId}-feedback`;\nconst filesId = `${uploadId}-files`;\n\nconst isUnavailable = computed(() => props.disabled || props.loading);\nconst hasFiles = computed(() => props.modelValue.length > 0);\nconst hasCustomBody = computed(() => Boolean(slots.default));\n\nconst effectiveMaxFiles = computed(() => {\n if (!props.multiple) {\n return 1;\n }\n\n if (typeof props.maxFiles !== 'number') {\n return Number.POSITIVE_INFINITY;\n }\n\n return Math.max(props.maxFiles, 0);\n});\n\nconst rootClasses = computed(() => [\n 't-file-upload',\n `t-file-upload--${props.size}`,\n {\n 'is-disabled': isUnavailable.value,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n 'is-drag-active': isDragActive.value,\n 'has-files': hasFiles.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst describedBy = computed(() => {\n const ids: string[] = [];\n\n if (props.description && !hasCustomBody.value) {\n ids.push(descriptionId);\n }\n\n if (feedbackMessages.value.length > 0) {\n ids.push(feedbackId);\n }\n\n if (props.showFileList && hasFiles.value) {\n ids.push(filesId);\n }\n\n return ids.length > 0 ? ids.join(' ') : undefined;\n});\n\nconst selectedFilesLabel = computed(() => `${props.filesLabel} (${props.modelValue.length})`);\n\nconst formatFileSize = (size: number) => {\n if (size < 1024) {\n return `${size} B`;\n }\n\n const units = ['KB', 'MB', 'GB'];\n let value = size / 1024;\n let unitIndex = 0;\n\n while (value >= 1024 && unitIndex < units.length - 1) {\n value /= 1024;\n unitIndex += 1;\n }\n\n const roundedValue = value >= 10 || Number.isInteger(value)\n ? Math.round(value)\n : Number(value.toFixed(1));\n\n return `${roundedValue} ${units[unitIndex]}`;\n};\n\nconst fileKey = (file: File, index: number) =>\n `${file.name}-${file.size}-${file.lastModified}-${index}`;\n\nconst matchesAccept = (file: File) => {\n if (!props.accept.trim()) {\n return true;\n }\n\n const tokens = props.accept\n .split(',')\n .map((token) => token.trim().toLowerCase())\n .filter(Boolean);\n\n const fileName = file.name.toLowerCase();\n const fileType = file.type.toLowerCase();\n\n return tokens.some((token) => {\n if (token.startsWith('.')) {\n return fileName.endsWith(token);\n }\n\n if (token.endsWith('/*')) {\n return fileType.startsWith(token.slice(0, -1));\n }\n\n return fileType === token;\n });\n};\n\nconst buildRejectionMessage = (\n file: File,\n reason: TFileUploadRejectionReason,\n) => {\n switch (reason) {\n case 'file-invalid-type':\n return `${file.name} is not an accepted file type.`;\n case 'file-too-large':\n return `${file.name} exceeds the ${formatFileSize(props.maxFileSize ?? 0)} limit.`;\n case 'too-many-files':\n return `You can only add up to ${effectiveMaxFiles.value} file${effectiveMaxFiles.value === 1 ? '' : 's'}.`;\n default:\n return `${file.name} could not be added.`;\n }\n};\n\nconst resetInputValue = () => {\n if (inputRef.value) {\n inputRef.value.value = '';\n }\n};\n\nconst openFileDialog = () => {\n if (isUnavailable.value) {\n return;\n }\n\n inputRef.value?.click();\n};\n\nconst emitFiles = (\n nextFiles: File[],\n acceptedFiles: File[],\n rejections: TFileUploadRejection[],\n) => {\n feedbackMessages.value = rejections.map((rejection) => rejection.message);\n\n if (rejections.length > 0) {\n emit('files-rejected', rejections);\n }\n\n if (acceptedFiles.length > 0) {\n emit('update:modelValue', nextFiles);\n emit('files-accepted', acceptedFiles);\n }\n};\n\nconst processFiles = (incomingFiles: File[]) => {\n if (isUnavailable.value || incomingFiles.length === 0) {\n return;\n }\n\n const nextFiles = props.multiple ? [...props.modelValue] : [];\n const acceptedFiles: File[] = [];\n const rejections: TFileUploadRejection[] = [];\n let remainingSlots = Number.isFinite(effectiveMaxFiles.value)\n ? Math.max(effectiveMaxFiles.value - nextFiles.length, 0)\n : Number.POSITIVE_INFINITY;\n\n for (const file of incomingFiles) {\n if (remainingSlots <= 0) {\n rejections.push({\n file,\n reason: 'too-many-files',\n message: buildRejectionMessage(file, 'too-many-files'),\n });\n continue;\n }\n\n if (!matchesAccept(file)) {\n rejections.push({\n file,\n reason: 'file-invalid-type',\n message: buildRejectionMessage(file, 'file-invalid-type'),\n });\n continue;\n }\n\n if (\n typeof props.maxFileSize === 'number' &&\n props.maxFileSize > 0 &&\n file.size > props.maxFileSize\n ) {\n rejections.push({\n file,\n reason: 'file-too-large',\n message: buildRejectionMessage(file, 'file-too-large'),\n });\n continue;\n }\n\n acceptedFiles.push(file);\n nextFiles.push(file);\n\n if (Number.isFinite(remainingSlots)) {\n remainingSlots -= 1;\n }\n }\n\n emitFiles(nextFiles, acceptedFiles, rejections);\n};\n\nconst removeFile = (index: number) => {\n if (isUnavailable.value) {\n return;\n }\n\n feedbackMessages.value = [];\n emit('update:modelValue', props.modelValue.filter((_, fileIndex) => fileIndex !== index));\n};\n\nconst clearFiles = () => {\n if (isUnavailable.value || !hasFiles.value) {\n return;\n }\n\n feedbackMessages.value = [];\n emit('update:modelValue', []);\n};\n\nconst hasTransferFiles = (dataTransfer?: DataTransfer | null) => {\n if (!dataTransfer) {\n return false;\n }\n\n return dataTransfer.files.length > 0 || Array.from(dataTransfer.types).includes('Files');\n};\n\nconst getClipboardFiles = (\n clipboardData?: Pick<DataTransfer, 'items'> | null,\n) => {\n if (!clipboardData?.items) {\n return [];\n }\n\n return Array.from(clipboardData.items)\n .map((item) => item.getAsFile?.() ?? null)\n .filter((file): file is File => file instanceof File);\n};\n\nconst onInputChange = (event: Event) => {\n const target = event.target as HTMLInputElement;\n processFiles(Array.from(target.files ?? []));\n resetInputValue();\n};\n\nconst onDropzoneKeydown = (event: KeyboardEvent) => {\n if (!isActivationKey(event) || isUnavailable.value) {\n return;\n }\n\n event.preventDefault();\n openFileDialog();\n};\n\nconst onFocusIn = () => {\n isFocusedWithin.value = true;\n};\n\nconst onFocusOut = (event: FocusEvent) => {\n const nextTarget = event.relatedTarget as Node | null;\n\n if (nextTarget && rootRef.value?.contains(nextTarget)) {\n return;\n }\n\n isFocusedWithin.value = false;\n};\n\nconst onPaste = (event: ClipboardEvent) => {\n if (!props.paste || isUnavailable.value) {\n return;\n }\n\n const clipboardFiles = getClipboardFiles(event.clipboardData);\n\n if (clipboardFiles.length === 0) {\n return;\n }\n\n event.preventDefault();\n processFiles(clipboardFiles);\n};\n\nconst onDocumentPaste = (event: Event) => {\n if (!isFocusedWithin.value || event.defaultPrevented) {\n return;\n }\n\n onPaste(event as ClipboardEvent);\n};\n\nconst onDragEnter = (event: DragEvent) => {\n if (!props.drop || isUnavailable.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n dragDepth.value += 1;\n isDragActive.value = true;\n};\n\nconst onDragOver = (event: DragEvent) => {\n if (!props.drop || isUnavailable.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'copy';\n }\n\n isDragActive.value = true;\n};\n\nconst onDragLeave = (event: DragEvent) => {\n if (!props.drop || isUnavailable.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n dragDepth.value = Math.max(dragDepth.value - 1, 0);\n\n if (dragDepth.value === 0) {\n isDragActive.value = false;\n }\n};\n\nconst onDrop = (event: DragEvent) => {\n if (!props.drop || isUnavailable.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n dragDepth.value = 0;\n isDragActive.value = false;\n processFiles(Array.from(event.dataTransfer?.files ?? []));\n};\n\nonMounted(() => {\n document.addEventListener('paste', onDocumentPaste);\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('paste', onDocumentPaste);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n @focusin=\"onFocusIn\"\n @focusout=\"onFocusOut\"\n @paste=\"onPaste\"\n >\n <input\n :id=\"uploadId\"\n ref=\"inputRef\"\n class=\"t-visually-hidden\"\n type=\"file\"\n :accept=\"accept || undefined\"\n :multiple=\"multiple\"\n :disabled=\"isUnavailable\"\n @change=\"onInputChange\"\n >\n\n <div\n class=\"t-file-upload__dropzone\"\n :aria-busy=\"loading || undefined\"\n :aria-controls=\"showFileList && hasFiles ? filesId : undefined\"\n :aria-describedby=\"describedBy\"\n :aria-disabled=\"isUnavailable || undefined\"\n :aria-invalid=\"invalid || undefined\"\n role=\"button\"\n :tabindex=\"isUnavailable ? -1 : 0\"\n @click=\"openFileDialog\"\n @keydown=\"onDropzoneKeydown\"\n @dragenter=\"onDragEnter\"\n @dragover=\"onDragOver\"\n @dragleave=\"onDragLeave\"\n @drop=\"onDrop\"\n >\n <div\n v-if=\"$slots.icon || !$slots.default\"\n class=\"t-file-upload__icon\"\n aria-hidden=\"true\"\n >\n <slot name=\"icon\">\n <span class=\"t-file-upload__icon-mark\">+</span>\n </slot>\n </div>\n\n <div class=\"t-file-upload__content\">\n <slot\n :files=\"modelValue\"\n :is-drag-active=\"isDragActive\"\n :open-file-dialog=\"openFileDialog\"\n :clear-files=\"clearFiles\"\n >\n <p class=\"t-file-upload__label\">\n {{ label }}\n </p>\n <p\n v-if=\"description\"\n :id=\"descriptionId\"\n class=\"t-file-upload__description\"\n >\n {{ description }}\n </p>\n <span class=\"t-file-upload__browse\">\n {{ buttonLabel }}\n </span>\n </slot>\n </div>\n\n <TSpinner\n v-if=\"loading\"\n class=\"t-file-upload__spinner\"\n size=\"sm\"\n label=\"Uploading files\"\n />\n </div>\n\n <ul\n v-if=\"feedbackMessages.length > 0\"\n :id=\"feedbackId\"\n class=\"t-file-upload__feedback\"\n aria-live=\"polite\"\n >\n <li\n v-for=\"message in feedbackMessages\"\n :key=\"message\"\n >\n {{ message }}\n </li>\n </ul>\n\n <div\n v-if=\"showFileList && hasFiles\"\n class=\"t-file-upload__files\"\n >\n <div class=\"t-file-upload__files-header\">\n <p\n :id=\"filesId\"\n class=\"t-file-upload__files-label\"\n >\n {{ selectedFilesLabel }}\n </p>\n\n <button\n class=\"t-file-upload__clear\"\n type=\"button\"\n :disabled=\"isUnavailable\"\n @click=\"clearFiles\"\n >\n Clear all\n </button>\n </div>\n\n <ul class=\"t-file-upload__list\">\n <li\n v-for=\"(file, index) in modelValue\"\n :key=\"fileKey(file, index)\"\n class=\"t-file-upload__file\"\n >\n <slot\n name=\"file\"\n :file=\"file\"\n :index=\"index\"\n :remove-file=\"() => removeFile(index)\"\n >\n <div class=\"t-file-upload__file-copy\">\n <p class=\"t-file-upload__file-name\">\n {{ file.name }}\n </p>\n <p class=\"t-file-upload__file-meta\">\n {{ formatFileSize(file.size) }}\n </p>\n </div>\n\n <button\n class=\"t-file-upload__remove\"\n type=\"button\"\n :disabled=\"isUnavailable\"\n :aria-label=\"`Remove ${file.name}`\"\n @click=\"removeFile(index)\"\n >\n Remove\n </button>\n </slot>\n </li>\n </ul>\n </div>\n\n <div\n v-if=\"$slots.actions\"\n class=\"t-file-upload__actions\"\n >\n <slot\n name=\"actions\"\n :files=\"modelValue\"\n :open-file-dialog=\"openFileDialog\"\n :clear-files=\"clearFiles\"\n />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { createId, isActivationKey } from '@treeui/utils';\nimport { computed, onBeforeUnmount, onMounted, ref, useAttrs } from 'vue';\nimport type { TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport type TFileUploadRejectionReason =\n | 'file-invalid-type'\n | 'file-too-large'\n | 'too-many-files';\n\nexport interface TFileUploadRejection {\n file: File;\n reason: TFileUploadRejectionReason;\n message: string;\n}\n\nconst slots = defineSlots<{\n icon?: () => unknown;\n default?: (props: {\n files: File[];\n isDragActive: boolean;\n openFileDialog: () => void;\n clearFiles: () => void;\n }) => unknown;\n file?: (props: {\n file: File;\n index: number;\n removeFile: () => void;\n }) => unknown;\n actions?: (props: {\n files: File[];\n openFileDialog: () => void;\n clearFiles: () => void;\n }) => unknown;\n}>();\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: File[];\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n accept?: string;\n multiple?: boolean;\n maxFiles?: number | null;\n maxFileSize?: number | null;\n label?: string;\n description?: string;\n buttonLabel?: string;\n filesLabel?: string;\n paste?: boolean;\n drop?: boolean;\n showFileList?: boolean;\n }>(),\n {\n modelValue: () => [],\n size: 'md',\n disabled: false,\n loading: false,\n invalid: false,\n accept: '',\n multiple: true,\n label: 'Drop files here',\n description: 'Click to browse, drag and drop, or paste with Ctrl+V.',\n buttonLabel: 'Browse files',\n filesLabel: 'Selected files',\n maxFiles: null,\n maxFileSize: null,\n paste: true,\n drop: true,\n showFileList: true,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [files: File[]];\n 'files-accepted': [files: File[]];\n 'files-rejected': [rejections: TFileUploadRejection[]];\n}>();\n\nconst attrs = useAttrs();\nconst rootRef = ref<HTMLElement | null>(null);\nconst inputRef = ref<HTMLInputElement | null>(null);\nconst isDragActive = ref(false);\nconst isFocusedWithin = ref(false);\nconst dragDepth = ref(0);\nconst feedbackMessages = ref<string[]>([]);\n\nconst uploadId = createId('t-file-upload');\nconst descriptionId = `${uploadId}-description`;\nconst feedbackId = `${uploadId}-feedback`;\nconst filesId = `${uploadId}-files`;\n\nconst isUnavailable = computed(() => props.disabled || props.loading);\nconst hasFiles = computed(() => props.modelValue.length > 0);\nconst hasCustomBody = computed(() => Boolean(slots.default));\n\nconst effectiveMaxFiles = computed(() => {\n if (!props.multiple) {\n return 1;\n }\n\n if (typeof props.maxFiles !== 'number') {\n return Number.POSITIVE_INFINITY;\n }\n\n return Math.max(props.maxFiles, 0);\n});\n\nconst rootClasses = computed(() => [\n 't-file-upload',\n `t-file-upload--${props.size}`,\n {\n 'is-disabled': isUnavailable.value,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n 'is-drag-active': isDragActive.value,\n 'has-files': hasFiles.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst describedBy = computed(() => {\n const ids: string[] = [];\n\n if (props.description && !hasCustomBody.value) {\n ids.push(descriptionId);\n }\n\n if (feedbackMessages.value.length > 0) {\n ids.push(feedbackId);\n }\n\n if (props.showFileList && hasFiles.value) {\n ids.push(filesId);\n }\n\n return ids.length > 0 ? ids.join(' ') : undefined;\n});\n\nconst selectedFilesLabel = computed(() => `${props.filesLabel} (${props.modelValue.length})`);\n\nconst formatFileSize = (size: number) => {\n if (size < 1024) {\n return `${size} B`;\n }\n\n const units = ['KB', 'MB', 'GB'];\n let value = size / 1024;\n let unitIndex = 0;\n\n while (value >= 1024 && unitIndex < units.length - 1) {\n value /= 1024;\n unitIndex += 1;\n }\n\n const roundedValue = value >= 10 || Number.isInteger(value)\n ? Math.round(value)\n : Number(value.toFixed(1));\n\n return `${roundedValue} ${units[unitIndex]}`;\n};\n\nconst fileKey = (file: File, index: number) =>\n `${file.name}-${file.size}-${file.lastModified}-${index}`;\n\nconst matchesAccept = (file: File) => {\n if (!props.accept.trim()) {\n return true;\n }\n\n const tokens = props.accept\n .split(',')\n .map((token) => token.trim().toLowerCase())\n .filter(Boolean);\n\n const fileName = file.name.toLowerCase();\n const fileType = file.type.toLowerCase();\n\n return tokens.some((token) => {\n if (token.startsWith('.')) {\n return fileName.endsWith(token);\n }\n\n if (token.endsWith('/*')) {\n return fileType.startsWith(token.slice(0, -1));\n }\n\n return fileType === token;\n });\n};\n\nconst buildRejectionMessage = (\n file: File,\n reason: TFileUploadRejectionReason,\n) => {\n switch (reason) {\n case 'file-invalid-type':\n return `${file.name} is not an accepted file type.`;\n case 'file-too-large':\n return `${file.name} exceeds the ${formatFileSize(props.maxFileSize ?? 0)} limit.`;\n case 'too-many-files':\n return `You can only add up to ${effectiveMaxFiles.value} file${effectiveMaxFiles.value === 1 ? '' : 's'}.`;\n default:\n return `${file.name} could not be added.`;\n }\n};\n\nconst resetInputValue = () => {\n if (inputRef.value) {\n inputRef.value.value = '';\n }\n};\n\nconst openFileDialog = () => {\n if (isUnavailable.value) {\n return;\n }\n\n inputRef.value?.click();\n};\n\nconst emitFiles = (\n nextFiles: File[],\n acceptedFiles: File[],\n rejections: TFileUploadRejection[],\n) => {\n feedbackMessages.value = rejections.map((rejection) => rejection.message);\n\n if (rejections.length > 0) {\n emit('files-rejected', rejections);\n }\n\n if (acceptedFiles.length > 0) {\n emit('update:modelValue', nextFiles);\n emit('files-accepted', acceptedFiles);\n }\n};\n\nconst processFiles = (incomingFiles: File[]) => {\n if (isUnavailable.value || incomingFiles.length === 0) {\n return;\n }\n\n const nextFiles = props.multiple ? [...props.modelValue] : [];\n const acceptedFiles: File[] = [];\n const rejections: TFileUploadRejection[] = [];\n let remainingSlots = Number.isFinite(effectiveMaxFiles.value)\n ? Math.max(effectiveMaxFiles.value - nextFiles.length, 0)\n : Number.POSITIVE_INFINITY;\n\n for (const file of incomingFiles) {\n if (remainingSlots <= 0) {\n rejections.push({\n file,\n reason: 'too-many-files',\n message: buildRejectionMessage(file, 'too-many-files'),\n });\n continue;\n }\n\n if (!matchesAccept(file)) {\n rejections.push({\n file,\n reason: 'file-invalid-type',\n message: buildRejectionMessage(file, 'file-invalid-type'),\n });\n continue;\n }\n\n if (\n typeof props.maxFileSize === 'number' &&\n props.maxFileSize > 0 &&\n file.size > props.maxFileSize\n ) {\n rejections.push({\n file,\n reason: 'file-too-large',\n message: buildRejectionMessage(file, 'file-too-large'),\n });\n continue;\n }\n\n acceptedFiles.push(file);\n nextFiles.push(file);\n\n if (Number.isFinite(remainingSlots)) {\n remainingSlots -= 1;\n }\n }\n\n emitFiles(nextFiles, acceptedFiles, rejections);\n};\n\nconst removeFile = (index: number) => {\n if (isUnavailable.value) {\n return;\n }\n\n feedbackMessages.value = [];\n emit('update:modelValue', props.modelValue.filter((_, fileIndex) => fileIndex !== index));\n};\n\nconst clearFiles = () => {\n if (isUnavailable.value || !hasFiles.value) {\n return;\n }\n\n feedbackMessages.value = [];\n emit('update:modelValue', []);\n};\n\nconst hasTransferFiles = (dataTransfer?: DataTransfer | null) => {\n if (!dataTransfer) {\n return false;\n }\n\n return dataTransfer.files.length > 0 || Array.from(dataTransfer.types).includes('Files');\n};\n\nconst getClipboardFiles = (\n clipboardData?: Pick<DataTransfer, 'items'> | null,\n) => {\n if (!clipboardData?.items) {\n return [];\n }\n\n return Array.from(clipboardData.items)\n .map((item) => item.getAsFile?.() ?? null)\n .filter((file): file is File => file instanceof File);\n};\n\nconst onInputChange = (event: Event) => {\n const target = event.target as HTMLInputElement;\n processFiles(Array.from(target.files ?? []));\n resetInputValue();\n};\n\nconst onDropzoneKeydown = (event: KeyboardEvent) => {\n if (!isActivationKey(event) || isUnavailable.value) {\n return;\n }\n\n event.preventDefault();\n openFileDialog();\n};\n\nconst onFocusIn = () => {\n isFocusedWithin.value = true;\n};\n\nconst onFocusOut = (event: FocusEvent) => {\n const nextTarget = event.relatedTarget as Node | null;\n\n if (nextTarget && rootRef.value?.contains(nextTarget)) {\n return;\n }\n\n isFocusedWithin.value = false;\n};\n\nconst onPaste = (event: ClipboardEvent) => {\n if (!props.paste || isUnavailable.value) {\n return;\n }\n\n const clipboardFiles = getClipboardFiles(event.clipboardData);\n\n if (clipboardFiles.length === 0) {\n return;\n }\n\n event.preventDefault();\n processFiles(clipboardFiles);\n};\n\nconst onDocumentPaste = (event: Event) => {\n if (!isFocusedWithin.value || event.defaultPrevented) {\n return;\n }\n\n onPaste(event as ClipboardEvent);\n};\n\nconst onDragEnter = (event: DragEvent) => {\n if (!props.drop || isUnavailable.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n dragDepth.value += 1;\n isDragActive.value = true;\n};\n\nconst onDragOver = (event: DragEvent) => {\n if (!props.drop || isUnavailable.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'copy';\n }\n\n isDragActive.value = true;\n};\n\nconst onDragLeave = (event: DragEvent) => {\n if (!props.drop || isUnavailable.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n dragDepth.value = Math.max(dragDepth.value - 1, 0);\n\n if (dragDepth.value === 0) {\n isDragActive.value = false;\n }\n};\n\nconst onDrop = (event: DragEvent) => {\n if (!props.drop || isUnavailable.value || !hasTransferFiles(event.dataTransfer)) {\n return;\n }\n\n event.preventDefault();\n dragDepth.value = 0;\n isDragActive.value = false;\n processFiles(Array.from(event.dataTransfer?.files ?? []));\n};\n\nonMounted(() => {\n document.addEventListener('paste', onDocumentPaste);\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('paste', onDocumentPaste);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n @focusin=\"onFocusIn\"\n @focusout=\"onFocusOut\"\n @paste=\"onPaste\"\n >\n <input\n :id=\"uploadId\"\n ref=\"inputRef\"\n class=\"t-visually-hidden\"\n type=\"file\"\n :accept=\"accept || undefined\"\n :multiple=\"multiple\"\n :disabled=\"isUnavailable\"\n @change=\"onInputChange\"\n >\n\n <div\n class=\"t-file-upload__dropzone\"\n :aria-busy=\"loading || undefined\"\n :aria-controls=\"showFileList && hasFiles ? filesId : undefined\"\n :aria-describedby=\"describedBy\"\n :aria-disabled=\"isUnavailable || undefined\"\n :aria-invalid=\"invalid || undefined\"\n role=\"button\"\n :tabindex=\"isUnavailable ? -1 : 0\"\n @click=\"openFileDialog\"\n @keydown=\"onDropzoneKeydown\"\n @dragenter=\"onDragEnter\"\n @dragover=\"onDragOver\"\n @dragleave=\"onDragLeave\"\n @drop=\"onDrop\"\n >\n <div\n v-if=\"$slots.icon || !$slots.default\"\n class=\"t-file-upload__icon\"\n aria-hidden=\"true\"\n >\n <slot name=\"icon\">\n <span class=\"t-file-upload__icon-mark\">+</span>\n </slot>\n </div>\n\n <div class=\"t-file-upload__content\">\n <slot\n :files=\"modelValue\"\n :is-drag-active=\"isDragActive\"\n :open-file-dialog=\"openFileDialog\"\n :clear-files=\"clearFiles\"\n >\n <p class=\"t-file-upload__label\">\n {{ label }}\n </p>\n <p\n v-if=\"description\"\n :id=\"descriptionId\"\n class=\"t-file-upload__description\"\n >\n {{ description }}\n </p>\n <span class=\"t-file-upload__browse\">\n {{ buttonLabel }}\n </span>\n </slot>\n </div>\n\n <TSpinner\n v-if=\"loading\"\n class=\"t-file-upload__spinner\"\n size=\"sm\"\n label=\"Uploading files\"\n />\n </div>\n\n <ul\n v-if=\"feedbackMessages.length > 0\"\n :id=\"feedbackId\"\n class=\"t-file-upload__feedback\"\n aria-live=\"polite\"\n >\n <li\n v-for=\"message in feedbackMessages\"\n :key=\"message\"\n >\n {{ message }}\n </li>\n </ul>\n\n <div\n v-if=\"showFileList && hasFiles\"\n class=\"t-file-upload__files\"\n >\n <div class=\"t-file-upload__files-header\">\n <p\n :id=\"filesId\"\n class=\"t-file-upload__files-label\"\n >\n {{ selectedFilesLabel }}\n </p>\n\n <button\n class=\"t-file-upload__clear\"\n type=\"button\"\n :disabled=\"isUnavailable\"\n @click=\"clearFiles\"\n >\n Clear all\n </button>\n </div>\n\n <ul class=\"t-file-upload__list\">\n <li\n v-for=\"(file, index) in modelValue\"\n :key=\"fileKey(file, index)\"\n class=\"t-file-upload__file\"\n >\n <slot\n name=\"file\"\n :file=\"file\"\n :index=\"index\"\n :remove-file=\"() => removeFile(index)\"\n >\n <div class=\"t-file-upload__file-copy\">\n <p class=\"t-file-upload__file-name\">\n {{ file.name }}\n </p>\n <p class=\"t-file-upload__file-meta\">\n {{ formatFileSize(file.size) }}\n </p>\n </div>\n\n <button\n class=\"t-file-upload__remove\"\n type=\"button\"\n :disabled=\"isUnavailable\"\n :aria-label=\"`Remove ${file.name}`\"\n @click=\"removeFile(index)\"\n >\n Remove\n </button>\n </slot>\n </li>\n </ul>\n </div>\n\n <div\n v-if=\"$slots.actions\"\n class=\"t-file-upload__actions\"\n >\n <slot\n name=\"actions\"\n :files=\"modelValue\"\n :open-file-dialog=\"openFileDialog\"\n :clear-files=\"clearFiles\"\n />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { getTreeIcon } from '@treeui/icons';\nimport { createId, getNextEnabledIndex, isEscapeKey } from '@treeui/utils';\nimport { computed, nextTick, onBeforeUnmount, ref, toRef, useAttrs, watch } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TMultiSelectOption {\n label: string;\n value: string;\n description?: string;\n keywords?: string[];\n disabled?: boolean;\n}\n\nconst ChevronDownIcon = getTreeIcon('chevron-down');\nconst CheckIcon = getTreeIcon('check');\nconst XIcon = getTreeIcon('x');\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string[];\n options?: TMultiSelectOption[];\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n placeholder?: string;\n emptyText?: string;\n maxVisibleTags?: number;\n }>(),\n {\n modelValue: () => [],\n options: () => [],\n open: undefined,\n defaultOpen: false,\n size: 'md',\n disabled: false,\n loading: false,\n invalid: false,\n placeholder: '',\n emptyText: 'No results found.',\n maxVisibleTags: 2,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string[]];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n 'input-change': [value: string];\n}>();\n\ndefineSlots<{\n prefix?: () => unknown;\n tag?: (props: { option: TMultiSelectOption; remove: () => void }) => unknown;\n option?: (props: {\n option: TMultiSelectOption;\n selected: boolean;\n active: boolean;\n }) => unknown;\n empty?: (props: { query: string }) => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst listboxId = createId('t-multi-select');\nconst rootRef = ref<HTMLElement | null>(null);\nconst inputRef = ref<HTMLInputElement | null>(null);\nconst query = ref('');\nconst activeIndex = ref(-1);\n\nconst inputAttrs = computed(() => {\n const { class: _class, style: _style, autocomplete, ...rest } = attrs;\n return {\n autocomplete: typeof autocomplete === 'string' ? autocomplete : 'off',\n ...rest,\n };\n});\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-multi-select',\n `t-multi-select--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst normalize = (value: string) => value.trim().toLowerCase();\n\nconst filteredOptions = computed(() => {\n const normalizedQuery = normalize(query.value);\n\n if (!normalizedQuery) {\n return props.options;\n }\n\n return props.options.filter((option) => {\n const fields = [option.label, option.description ?? '', ...(option.keywords ?? [])];\n return fields.some((field) => field.toLowerCase().includes(normalizedQuery));\n });\n});\n\nconst selectedOptions = computed(() =>\n props.options.filter((option) => props.modelValue.includes(option.value)),\n);\n\nconst visibleTags = computed(() => selectedOptions.value.slice(0, props.maxVisibleTags));\nconst hiddenTagCount = computed(() =>\n Math.max(selectedOptions.value.length - visibleTags.value.length, 0),\n);\n\nconst enabledFilteredOptions = computed(() => filteredOptions.value.filter((option) => !option.disabled));\n\nconst activeOption = computed(() =>\n activeIndex.value >= 0 ? filteredOptions.value[activeIndex.value] : undefined,\n);\n\nconst activeDescendant = computed(() =>\n isOpen.value && activeOption.value\n ? `${listboxId}-option-${activeOption.value.value}`\n : undefined,\n);\n\nconst inputPlaceholder = computed(() =>\n props.modelValue.length === 0 && !query.value ? props.placeholder : '',\n);\n\nconst isSelected = (value: string) => props.modelValue.includes(value);\n\nconst setInitialActiveIndex = (fallback: 'first' | 'last' = 'first') => {\n const selectedIndex = filteredOptions.value.findIndex(\n (option) => isSelected(option.value) && !option.disabled,\n );\n\n if (selectedIndex >= 0) {\n activeIndex.value = selectedIndex;\n return;\n }\n\n if (enabledFilteredOptions.value.length === 0) {\n activeIndex.value = -1;\n return;\n }\n\n const targetOption =\n fallback === 'last'\n ? enabledFilteredOptions.value[enabledFilteredOptions.value.length - 1]\n : enabledFilteredOptions.value[0];\n\n activeIndex.value = filteredOptions.value.findIndex(\n (option) => option.value === targetOption.value,\n );\n};\n\nconst openListbox = (fallback: 'first' | 'last' = 'first') => {\n if (props.disabled) {\n return;\n }\n\n setValue(true);\n setInitialActiveIndex(fallback);\n};\n\nconst closeListbox = () => {\n setValue(false);\n activeIndex.value = -1;\n};\n\nconst focusInput = () => {\n nextTick(() => inputRef.value?.focus());\n};\n\nconst updateValues = (nextValues: string[]) => {\n emit('update:modelValue', nextValues);\n};\n\nconst toggleOption = (option: TMultiSelectOption) => {\n if (props.disabled || option.disabled) {\n return;\n }\n\n const nextValues = isSelected(option.value)\n ? props.modelValue.filter((value) => value !== option.value)\n : [...props.modelValue, option.value];\n\n updateValues(nextValues);\n query.value = '';\n setInitialActiveIndex('first');\n focusInput();\n};\n\nconst removeValue = (value: string) => {\n if (props.disabled) {\n return;\n }\n\n updateValues(props.modelValue.filter((item) => item !== value));\n focusInput();\n};\n\nconst moveActive = (direction: 1 | -1) => {\n if (filteredOptions.value.length === 0) {\n activeIndex.value = -1;\n return;\n }\n\n const nextIndex = getNextEnabledIndex(activeIndex.value, filteredOptions.value, direction);\n activeIndex.value = nextIndex;\n};\n\nconst onInput = (event: Event) => {\n query.value = (event.target as HTMLInputElement).value;\n emit('input-change', query.value);\n\n if (!props.disabled && !isOpen.value) {\n openListbox('first');\n return;\n }\n\n setInitialActiveIndex('first');\n};\n\nconst onInputFocus = () => {\n openListbox('first');\n};\n\nconst onInputKeydown = (event: KeyboardEvent) => {\n if (props.disabled) {\n return;\n }\n\n if (event.key === 'Tab') {\n closeListbox();\n return;\n }\n\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeListbox();\n return;\n }\n\n if (event.key === 'Backspace' && !query.value && props.modelValue.length > 0) {\n event.preventDefault();\n removeValue(props.modelValue[props.modelValue.length - 1]);\n return;\n }\n\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n\n if (!isOpen.value) {\n openListbox('first');\n return;\n }\n\n moveActive(1);\n return;\n }\n\n if (event.key === 'ArrowUp') {\n event.preventDefault();\n\n if (!isOpen.value) {\n openListbox('last');\n return;\n }\n\n moveActive(-1);\n return;\n }\n\n if (event.key === 'Home' && isOpen.value) {\n event.preventDefault();\n setInitialActiveIndex('first');\n return;\n }\n\n if (event.key === 'End' && isOpen.value) {\n event.preventDefault();\n setInitialActiveIndex('last');\n return;\n }\n\n if (event.key === 'Enter' && activeOption.value) {\n event.preventDefault();\n toggleOption(activeOption.value);\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) {\n return;\n }\n\n const target = event.target;\n\n if (!(target instanceof Node)) {\n return;\n }\n\n if (rootRef.value?.contains(target)) {\n return;\n }\n\n closeListbox();\n};\n\nwatch(\n isOpen,\n (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n } else {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n }\n },\n);\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <div\n class=\"t-multi-select__control\"\n @click=\"focusInput\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-multi-select__slot\"\n >\n <slot name=\"prefix\" />\n </span>\n\n <div class=\"t-multi-select__values\">\n <span\n v-for=\"option in visibleTags\"\n :key=\"option.value\"\n class=\"t-multi-select__tag\"\n >\n <slot\n name=\"tag\"\n :option=\"option\"\n :remove=\"() => removeValue(option.value)\"\n >\n <span class=\"t-multi-select__tag-label\">{{ option.label }}</span>\n <button\n type=\"button\"\n class=\"t-multi-select__tag-remove\"\n :disabled=\"disabled\"\n aria-label=\"Remove selection\"\n @mousedown.prevent\n @click.stop=\"removeValue(option.value)\"\n >\n <XIcon :size=\"12\" />\n </button>\n </slot>\n </span>\n\n <span\n v-if=\"hiddenTagCount > 0\"\n class=\"t-multi-select__overflow\"\n >\n +{{ hiddenTagCount }}\n </span>\n\n <input\n ref=\"inputRef\"\n v-bind=\"inputAttrs\"\n :value=\"query\"\n type=\"text\"\n class=\"t-multi-select__input\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n :aria-expanded=\"isOpen\"\n :aria-controls=\"isOpen ? listboxId : undefined\"\n :aria-activedescendant=\"activeDescendant\"\n :aria-invalid=\"invalid || undefined\"\n :aria-busy=\"loading || undefined\"\n :disabled=\"disabled\"\n :placeholder=\"inputPlaceholder\"\n @focus=\"onInputFocus\"\n @input=\"onInput\"\n @keydown=\"onInputKeydown\"\n >\n </div>\n\n <TSpinner\n v-if=\"loading\"\n class=\"t-multi-select__indicator\"\n size=\"sm\"\n />\n <ChevronDownIcon\n v-else\n class=\"t-multi-select__indicator\"\n :size=\"16\"\n />\n </div>\n\n <Transition name=\"t-fade\">\n <ul\n v-if=\"isOpen\"\n :id=\"listboxId\"\n class=\"t-multi-select__listbox\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n >\n <li\n v-if=\"filteredOptions.length === 0\"\n class=\"t-multi-select__empty\"\n >\n <slot\n name=\"empty\"\n :query=\"query\"\n >\n {{ emptyText }}\n </slot>\n </li>\n\n <template v-else>\n <li\n v-for=\"(option, index) in filteredOptions\"\n :key=\"option.value\"\n >\n <button\n :id=\"`${listboxId}-option-${option.value}`\"\n type=\"button\"\n class=\"t-multi-select__option\"\n :class=\"{\n 'is-active': index === activeIndex,\n 'is-selected': isSelected(option.value),\n 'is-disabled': option.disabled,\n }\"\n role=\"option\"\n :aria-selected=\"isSelected(option.value)\"\n :aria-disabled=\"option.disabled || undefined\"\n :disabled=\"option.disabled\"\n @mousedown.prevent\n @click=\"toggleOption(option)\"\n >\n <slot\n name=\"option\"\n :option=\"option\"\n :selected=\"isSelected(option.value)\"\n :active=\"index === activeIndex\"\n >\n <span class=\"t-multi-select__option-copy\">\n <span class=\"t-multi-select__option-label\">{{ option.label }}</span>\n <span\n v-if=\"option.description\"\n class=\"t-multi-select__option-description\"\n >\n {{ option.description }}\n </span>\n </span>\n\n <span\n class=\"t-multi-select__check\"\n aria-hidden=\"true\"\n >\n <CheckIcon\n v-if=\"isSelected(option.value)\"\n :size=\"16\"\n />\n </span>\n </slot>\n </button>\n </li>\n </template>\n </ul>\n </Transition>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { getTreeIcon } from '@treeui/icons';\nimport { createId, getNextEnabledIndex, isEscapeKey } from '@treeui/utils';\nimport { computed, nextTick, onBeforeUnmount, ref, toRef, useAttrs, watch } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TMultiSelectOption {\n label: string;\n value: string;\n description?: string;\n keywords?: string[];\n disabled?: boolean;\n}\n\nconst ChevronDownIcon = getTreeIcon('chevron-down');\nconst CheckIcon = getTreeIcon('check');\nconst XIcon = getTreeIcon('x');\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string[];\n options?: TMultiSelectOption[];\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n placeholder?: string;\n emptyText?: string;\n maxVisibleTags?: number;\n }>(),\n {\n modelValue: () => [],\n options: () => [],\n open: undefined,\n defaultOpen: false,\n size: 'md',\n disabled: false,\n loading: false,\n invalid: false,\n placeholder: '',\n emptyText: 'No results found.',\n maxVisibleTags: 2,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string[]];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n 'input-change': [value: string];\n}>();\n\ndefineSlots<{\n prefix?: () => unknown;\n tag?: (props: { option: TMultiSelectOption; remove: () => void }) => unknown;\n option?: (props: {\n option: TMultiSelectOption;\n selected: boolean;\n active: boolean;\n }) => unknown;\n empty?: (props: { query: string }) => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst listboxId = createId('t-multi-select');\nconst rootRef = ref<HTMLElement | null>(null);\nconst inputRef = ref<HTMLInputElement | null>(null);\nconst query = ref('');\nconst activeIndex = ref(-1);\n\nconst inputAttrs = computed(() => {\n const { class: _class, style: _style, autocomplete, ...rest } = attrs;\n return {\n autocomplete: typeof autocomplete === 'string' ? autocomplete : 'off',\n ...rest,\n };\n});\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-multi-select',\n `t-multi-select--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst normalize = (value: string) => value.trim().toLowerCase();\n\nconst filteredOptions = computed(() => {\n const normalizedQuery = normalize(query.value);\n\n if (!normalizedQuery) {\n return props.options;\n }\n\n return props.options.filter((option) => {\n const fields = [option.label, option.description ?? '', ...(option.keywords ?? [])];\n return fields.some((field) => field.toLowerCase().includes(normalizedQuery));\n });\n});\n\nconst selectedOptions = computed(() =>\n props.options.filter((option) => props.modelValue.includes(option.value)),\n);\n\nconst visibleTags = computed(() => selectedOptions.value.slice(0, props.maxVisibleTags));\nconst hiddenTagCount = computed(() =>\n Math.max(selectedOptions.value.length - visibleTags.value.length, 0),\n);\n\nconst enabledFilteredOptions = computed(() => filteredOptions.value.filter((option) => !option.disabled));\n\nconst activeOption = computed(() =>\n activeIndex.value >= 0 ? filteredOptions.value[activeIndex.value] : undefined,\n);\n\nconst activeDescendant = computed(() =>\n isOpen.value && activeOption.value\n ? `${listboxId}-option-${activeOption.value.value}`\n : undefined,\n);\n\nconst inputPlaceholder = computed(() =>\n props.modelValue.length === 0 && !query.value ? props.placeholder : '',\n);\n\nconst isSelected = (value: string) => props.modelValue.includes(value);\n\nconst setInitialActiveIndex = (fallback: 'first' | 'last' = 'first') => {\n const selectedIndex = filteredOptions.value.findIndex(\n (option) => isSelected(option.value) && !option.disabled,\n );\n\n if (selectedIndex >= 0) {\n activeIndex.value = selectedIndex;\n return;\n }\n\n if (enabledFilteredOptions.value.length === 0) {\n activeIndex.value = -1;\n return;\n }\n\n const targetOption =\n fallback === 'last'\n ? enabledFilteredOptions.value[enabledFilteredOptions.value.length - 1]\n : enabledFilteredOptions.value[0];\n\n activeIndex.value = filteredOptions.value.findIndex(\n (option) => option.value === targetOption.value,\n );\n};\n\nconst openListbox = (fallback: 'first' | 'last' = 'first') => {\n if (props.disabled) {\n return;\n }\n\n setValue(true);\n setInitialActiveIndex(fallback);\n};\n\nconst closeListbox = () => {\n setValue(false);\n activeIndex.value = -1;\n};\n\nconst focusInput = () => {\n nextTick(() => inputRef.value?.focus());\n};\n\nconst updateValues = (nextValues: string[]) => {\n emit('update:modelValue', nextValues);\n};\n\nconst toggleOption = (option: TMultiSelectOption) => {\n if (props.disabled || option.disabled) {\n return;\n }\n\n const nextValues = isSelected(option.value)\n ? props.modelValue.filter((value) => value !== option.value)\n : [...props.modelValue, option.value];\n\n updateValues(nextValues);\n query.value = '';\n setInitialActiveIndex('first');\n focusInput();\n};\n\nconst removeValue = (value: string) => {\n if (props.disabled) {\n return;\n }\n\n updateValues(props.modelValue.filter((item) => item !== value));\n focusInput();\n};\n\nconst moveActive = (direction: 1 | -1) => {\n if (filteredOptions.value.length === 0) {\n activeIndex.value = -1;\n return;\n }\n\n const nextIndex = getNextEnabledIndex(activeIndex.value, filteredOptions.value, direction);\n activeIndex.value = nextIndex;\n};\n\nconst onInput = (event: Event) => {\n query.value = (event.target as HTMLInputElement).value;\n emit('input-change', query.value);\n\n if (!props.disabled && !isOpen.value) {\n openListbox('first');\n return;\n }\n\n setInitialActiveIndex('first');\n};\n\nconst onInputFocus = () => {\n openListbox('first');\n};\n\nconst onInputKeydown = (event: KeyboardEvent) => {\n if (props.disabled) {\n return;\n }\n\n if (event.key === 'Tab') {\n closeListbox();\n return;\n }\n\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeListbox();\n return;\n }\n\n if (event.key === 'Backspace' && !query.value && props.modelValue.length > 0) {\n event.preventDefault();\n removeValue(props.modelValue[props.modelValue.length - 1]);\n return;\n }\n\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n\n if (!isOpen.value) {\n openListbox('first');\n return;\n }\n\n moveActive(1);\n return;\n }\n\n if (event.key === 'ArrowUp') {\n event.preventDefault();\n\n if (!isOpen.value) {\n openListbox('last');\n return;\n }\n\n moveActive(-1);\n return;\n }\n\n if (event.key === 'Home' && isOpen.value) {\n event.preventDefault();\n setInitialActiveIndex('first');\n return;\n }\n\n if (event.key === 'End' && isOpen.value) {\n event.preventDefault();\n setInitialActiveIndex('last');\n return;\n }\n\n if (event.key === 'Enter' && activeOption.value) {\n event.preventDefault();\n toggleOption(activeOption.value);\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) {\n return;\n }\n\n const target = event.target;\n\n if (!(target instanceof Node)) {\n return;\n }\n\n if (rootRef.value?.contains(target)) {\n return;\n }\n\n closeListbox();\n};\n\nwatch(\n isOpen,\n (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n } else {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n }\n },\n);\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <div\n class=\"t-multi-select__control\"\n @click=\"focusInput\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-multi-select__slot\"\n >\n <slot name=\"prefix\" />\n </span>\n\n <div class=\"t-multi-select__values\">\n <span\n v-for=\"option in visibleTags\"\n :key=\"option.value\"\n class=\"t-multi-select__tag\"\n >\n <slot\n name=\"tag\"\n :option=\"option\"\n :remove=\"() => removeValue(option.value)\"\n >\n <span class=\"t-multi-select__tag-label\">{{ option.label }}</span>\n <button\n type=\"button\"\n class=\"t-multi-select__tag-remove\"\n :disabled=\"disabled\"\n aria-label=\"Remove selection\"\n @mousedown.prevent\n @click.stop=\"removeValue(option.value)\"\n >\n <XIcon :size=\"12\" />\n </button>\n </slot>\n </span>\n\n <span\n v-if=\"hiddenTagCount > 0\"\n class=\"t-multi-select__overflow\"\n >\n +{{ hiddenTagCount }}\n </span>\n\n <input\n ref=\"inputRef\"\n v-bind=\"inputAttrs\"\n :value=\"query\"\n type=\"text\"\n class=\"t-multi-select__input\"\n role=\"combobox\"\n aria-autocomplete=\"list\"\n :aria-expanded=\"isOpen\"\n :aria-controls=\"isOpen ? listboxId : undefined\"\n :aria-activedescendant=\"activeDescendant\"\n :aria-invalid=\"invalid || undefined\"\n :aria-busy=\"loading || undefined\"\n :disabled=\"disabled\"\n :placeholder=\"inputPlaceholder\"\n @focus=\"onInputFocus\"\n @input=\"onInput\"\n @keydown=\"onInputKeydown\"\n >\n </div>\n\n <TSpinner\n v-if=\"loading\"\n class=\"t-multi-select__indicator\"\n size=\"sm\"\n />\n <ChevronDownIcon\n v-else\n class=\"t-multi-select__indicator\"\n :size=\"16\"\n />\n </div>\n\n <Transition name=\"t-fade\">\n <ul\n v-if=\"isOpen\"\n :id=\"listboxId\"\n class=\"t-multi-select__listbox\"\n role=\"listbox\"\n aria-multiselectable=\"true\"\n >\n <li\n v-if=\"filteredOptions.length === 0\"\n class=\"t-multi-select__empty\"\n >\n <slot\n name=\"empty\"\n :query=\"query\"\n >\n {{ emptyText }}\n </slot>\n </li>\n\n <template v-else>\n <li\n v-for=\"(option, index) in filteredOptions\"\n :key=\"option.value\"\n >\n <button\n :id=\"`${listboxId}-option-${option.value}`\"\n type=\"button\"\n class=\"t-multi-select__option\"\n :class=\"{\n 'is-active': index === activeIndex,\n 'is-selected': isSelected(option.value),\n 'is-disabled': option.disabled,\n }\"\n role=\"option\"\n :aria-selected=\"isSelected(option.value)\"\n :aria-disabled=\"option.disabled || undefined\"\n :disabled=\"option.disabled\"\n @mousedown.prevent\n @click=\"toggleOption(option)\"\n >\n <slot\n name=\"option\"\n :option=\"option\"\n :selected=\"isSelected(option.value)\"\n :active=\"index === activeIndex\"\n >\n <span class=\"t-multi-select__option-copy\">\n <span class=\"t-multi-select__option-label\">{{ option.label }}</span>\n <span\n v-if=\"option.description\"\n class=\"t-multi-select__option-description\"\n >\n {{ option.description }}\n </span>\n </span>\n\n <span\n class=\"t-multi-select__check\"\n aria-hidden=\"true\"\n >\n <CheckIcon\n v-if=\"isSelected(option.value)\"\n :size=\"16\"\n />\n </span>\n </slot>\n </button>\n </li>\n </template>\n </ul>\n </Transition>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n columns?: number;\n minItemWidth?: string;\n gap?: string;\n rowGap?: string;\n align?: string;\n justify?: string;\n dense?: boolean;\n }>(),\n {\n as: 'div',\n columns: undefined,\n minItemWidth: '16rem',\n gap: 'var(--tree-space-4)',\n rowGap: undefined,\n align: 'stretch',\n justify: 'stretch',\n dense: false,\n },\n);\n\nconst attrs = useAttrs();\n\nconst rootClasses = computed(() => [\n 't-grid',\n {\n 'is-dense': props.dense,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => [\n {\n gap: props.gap,\n rowGap: props.rowGap ?? props.gap,\n alignItems: props.align,\n justifyItems: props.justify,\n gridTemplateColumns:\n typeof props.columns === 'number' && props.columns > 0\n ? `repeat(${props.columns}, minmax(0, 1fr))`\n : `repeat(auto-fit, minmax(min(${props.minItemWidth}, 100%), 1fr))`,\n gridAutoFlow: props.dense ? 'dense' : 'row',\n },\n attrs.style,\n]);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <slot />\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n columns?: number;\n minItemWidth?: string;\n gap?: string;\n rowGap?: string;\n align?: string;\n justify?: string;\n dense?: boolean;\n }>(),\n {\n as: 'div',\n columns: undefined,\n minItemWidth: '16rem',\n gap: 'var(--tree-space-4)',\n rowGap: undefined,\n align: 'stretch',\n justify: 'stretch',\n dense: false,\n },\n);\n\nconst attrs = useAttrs();\n\nconst rootClasses = computed(() => [\n 't-grid',\n {\n 'is-dense': props.dense,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => [\n {\n gap: props.gap,\n rowGap: props.rowGap ?? props.gap,\n alignItems: props.align,\n justifyItems: props.justify,\n gridTemplateColumns:\n typeof props.columns === 'number' && props.columns > 0\n ? `repeat(${props.columns}, minmax(0, 1fr))`\n : `repeat(auto-fit, minmax(min(${props.minItemWidth}, 100%), 1fr))`,\n gridAutoFlow: props.dense ? 'dense' : 'row',\n },\n attrs.style,\n]);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <slot />\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n size?: TSize;\n sticky?: boolean;\n bordered?: boolean;\n elevated?: boolean;\n }>(),\n {\n as: 'header',\n size: 'md',\n sticky: false,\n bordered: true,\n elevated: false,\n },\n);\n\nconst attrs = useAttrs();\n\nconst rootClasses = computed(() => [\n 't-navbar',\n `t-navbar--${props.size}`,\n {\n 'is-sticky': props.sticky,\n 'is-bordered': props.bordered,\n 'is-elevated': props.elevated,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <div class=\"t-navbar__inner\">\n <div\n v-if=\"$slots.start\"\n class=\"t-navbar__section t-navbar__section--start\"\n >\n <slot name=\"start\" />\n </div>\n\n <div\n v-if=\"$slots.default || $slots.center\"\n class=\"t-navbar__section t-navbar__section--center\"\n >\n <slot name=\"center\">\n <slot />\n </slot>\n </div>\n\n <div\n v-if=\"$slots.end\"\n class=\"t-navbar__section t-navbar__section--end\"\n >\n <slot name=\"end\" />\n </div>\n </div>\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n size?: TSize;\n sticky?: boolean;\n bordered?: boolean;\n elevated?: boolean;\n }>(),\n {\n as: 'header',\n size: 'md',\n sticky: false,\n bordered: true,\n elevated: false,\n },\n);\n\nconst attrs = useAttrs();\n\nconst rootClasses = computed(() => [\n 't-navbar',\n `t-navbar--${props.size}`,\n {\n 'is-sticky': props.sticky,\n 'is-bordered': props.bordered,\n 'is-elevated': props.elevated,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <div class=\"t-navbar__inner\">\n <div\n v-if=\"$slots.start\"\n class=\"t-navbar__section t-navbar__section--start\"\n >\n <slot name=\"start\" />\n </div>\n\n <div\n v-if=\"$slots.default || $slots.center\"\n class=\"t-navbar__section t-navbar__section--center\"\n >\n <slot name=\"center\">\n <slot />\n </slot>\n </div>\n\n <div\n v-if=\"$slots.end\"\n class=\"t-navbar__section t-navbar__section--end\"\n >\n <slot name=\"end\" />\n </div>\n </div>\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, getCurrentInstance, type Component } from 'vue';\n\nexport type TLinkVariant = 'default' | 'muted' | 'danger';\n\nconst props = withDefaults(\n defineProps<{\n to?: string | Record<string, unknown>;\n href?: string;\n external?: boolean;\n disabled?: boolean;\n variant?: TLinkVariant;\n }>(),\n {\n to: undefined,\n href: undefined,\n external: false,\n disabled: false,\n variant: 'default',\n },\n);\n\nconst instance = getCurrentInstance();\n\nconst routerLinkComponent = computed<Component | null>(() => {\n if (!props.to) return null;\n\n return (instance?.appContext.components.RouterLink as Component | undefined) ?? null;\n});\n\nconst hasRouterLink = computed(() => {\n return Boolean(routerLinkComponent.value);\n});\n\nconst tag = computed<string | Component>(() => {\n if (props.disabled) return 'span';\n if (props.to && routerLinkComponent.value) return routerLinkComponent.value;\n return 'a';\n});\n\nconst linkProps = computed(() => {\n if (props.disabled) return {};\n if (props.to && hasRouterLink.value) return { to: props.to };\n const href = props.href ?? (typeof props.to === 'string' ? props.to : undefined);\n return {\n href,\n ...(props.external ? { target: '_blank', rel: 'noopener noreferrer' } : {}),\n };\n});\n\nconst classes = computed(() => [\n 't-link',\n `t-link--${props.variant}`,\n {\n 'is-disabled': props.disabled,\n },\n]);\n</script>\n\n<template>\n <component\n :is=\"tag\"\n v-bind=\"linkProps\"\n :class=\"classes\"\n :aria-disabled=\"disabled || undefined\"\n :tabindex=\"disabled ? -1 : undefined\"\n >\n <slot />\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, getCurrentInstance, type Component } from 'vue';\n\nexport type TLinkVariant = 'default' | 'muted' | 'danger';\n\nconst props = withDefaults(\n defineProps<{\n to?: string | Record<string, unknown>;\n href?: string;\n external?: boolean;\n disabled?: boolean;\n variant?: TLinkVariant;\n }>(),\n {\n to: undefined,\n href: undefined,\n external: false,\n disabled: false,\n variant: 'default',\n },\n);\n\nconst instance = getCurrentInstance();\n\nconst routerLinkComponent = computed<Component | null>(() => {\n if (!props.to) return null;\n\n return (instance?.appContext.components.RouterLink as Component | undefined) ?? null;\n});\n\nconst hasRouterLink = computed(() => {\n return Boolean(routerLinkComponent.value);\n});\n\nconst tag = computed<string | Component>(() => {\n if (props.disabled) return 'span';\n if (props.to && routerLinkComponent.value) return routerLinkComponent.value;\n return 'a';\n});\n\nconst linkProps = computed(() => {\n if (props.disabled) return {};\n if (props.to && hasRouterLink.value) return { to: props.to };\n const href = props.href ?? (typeof props.to === 'string' ? props.to : undefined);\n return {\n href,\n ...(props.external ? { target: '_blank', rel: 'noopener noreferrer' } : {}),\n };\n});\n\nconst classes = computed(() => [\n 't-link',\n `t-link--${props.variant}`,\n {\n 'is-disabled': props.disabled,\n },\n]);\n</script>\n\n<template>\n <component\n :is=\"tag\"\n v-bind=\"linkProps\"\n :class=\"classes\"\n :aria-disabled=\"disabled || undefined\"\n :tabindex=\"disabled ? -1 : undefined\"\n >\n <slot />\n </component>\n</template>\n","import type { ComputedRef, InjectionKey } from 'vue';\n\nexport interface TSidebarContext {\n collapsed: ComputedRef<boolean>;\n}\n\nexport const treeSidebarInjectionKey: InjectionKey<TSidebarContext> =\n Symbol('tree-sidebar');\n","<script setup lang=\"ts\">\nimport { getNextEnabledIndex, isActivationKey } from '@treeui/utils';\nimport { computed, getCurrentInstance, inject, nextTick, ref, useAttrs, watch, type Component, type ComponentPublicInstance } from 'vue';\nimport type { TSize } from '../types/contracts';\nimport { treeSidebarInjectionKey } from './sidebar';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TNavMenuItem {\n label: string;\n value: string;\n shortLabel?: string;\n description?: string;\n icon?: Component;\n to?: string | Record<string, unknown>;\n badge?: string | number;\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n defaultValue?: string;\n items?: TNavMenuItem[];\n size?: TSize;\n collapsed?: boolean;\n disabled?: boolean;\n }>(),\n {\n modelValue: undefined,\n defaultValue: '',\n items: () => [],\n size: 'md',\n collapsed: undefined,\n disabled: false,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n select: [value: string, item: TNavMenuItem];\n}>();\n\ndefineSlots<{\n item?: (props: {\n item: TNavMenuItem;\n selected: boolean;\n focused: boolean;\n collapsed: boolean;\n }) => unknown;\n empty?: () => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst sidebar = inject(treeSidebarInjectionKey, null);\nconst internalValue = ref(props.defaultValue);\nconst itemRefs = ref<Map<string, HTMLElement>>(new Map());\nconst instance = getCurrentInstance();\n\nconst selectedValue = computed(() => props.modelValue ?? internalValue.value);\nconst resolvedCollapsed = computed(() => props.collapsed ?? sidebar?.collapsed.value ?? false);\n\nconst routerLinkComponent = computed<Component | null>(() => (\n (instance?.appContext.components.RouterLink as Component | undefined) ?? null\n));\n\nconst itemTag = (item: TNavMenuItem) => {\n if (item.to && routerLinkComponent.value) {\n return routerLinkComponent.value;\n }\n return 'button';\n};\n\nconst getInitialFocusedIndex = () => {\n const selectedIndex = props.items.findIndex((item) =>\n item.value === selectedValue.value && !item.disabled,\n );\n\n if (selectedIndex >= 0) {\n return selectedIndex;\n }\n\n return props.items.findIndex((item) => !item.disabled);\n};\n\nconst focusedIndex = ref(getInitialFocusedIndex());\n\nconst rootClasses = computed(() => [\n 't-nav-menu',\n `t-nav-menu--${props.size}`,\n {\n 'is-collapsed': resolvedCollapsed.value,\n 'is-disabled': props.disabled,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst isSelected = (value: string) => selectedValue.value === value;\n\nconst setItemRef = (element: Element | ComponentPublicInstance | null, value: string) => {\n const resolvedElement =\n element instanceof HTMLElement\n ? element\n : element && '$el' in element && element.$el instanceof HTMLElement\n ? element.$el\n : null;\n\n if (resolvedElement) {\n itemRefs.value.set(value, resolvedElement);\n } else {\n itemRefs.value.delete(value);\n }\n};\n\nconst focusItem = (index: number) => {\n const item = props.items[index];\n\n if (!item) {\n return;\n }\n\n focusedIndex.value = index;\n nextTick(() => itemRefs.value.get(item.value)?.focus());\n};\n\nconst selectItem = (item: TNavMenuItem) => {\n if (props.disabled || item.disabled) {\n return;\n }\n\n if (props.modelValue === undefined) {\n internalValue.value = item.value;\n }\n\n emit('update:modelValue', item.value);\n emit('select', item.value, item);\n};\n\nconst onItemKeydown = (event: KeyboardEvent, index: number) => {\n if (props.disabled) {\n return;\n }\n\n if (event.key === 'Home') {\n event.preventDefault();\n const firstIndex = props.items.findIndex((item) => !item.disabled);\n\n if (firstIndex >= 0) {\n focusItem(firstIndex);\n }\n\n return;\n }\n\n if (event.key === 'End') {\n event.preventDefault();\n const lastIndex = [...props.items].reverse().findIndex((item) => !item.disabled);\n\n if (lastIndex >= 0) {\n focusItem(props.items.length - 1 - lastIndex);\n }\n\n return;\n }\n\n if (event.key === 'ArrowDown' || event.key === 'ArrowRight') {\n event.preventDefault();\n const nextIndex = getNextEnabledIndex(index, props.items, 1);\n\n if (nextIndex >= 0) {\n focusItem(nextIndex);\n }\n\n return;\n }\n\n if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {\n event.preventDefault();\n const previousIndex = getNextEnabledIndex(index, props.items, -1);\n\n if (previousIndex >= 0) {\n focusItem(previousIndex);\n }\n\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectItem(props.items[index]);\n }\n};\n\nconst getTabIndex = (index: number) => (focusedIndex.value === index ? 0 : -1);\n\nwatch(\n () => [props.items, props.modelValue] as const,\n () => {\n const nextIndex = getInitialFocusedIndex();\n focusedIndex.value = nextIndex >= 0 ? nextIndex : -1;\n },\n { deep: true },\n);\n</script>\n\n<template>\n <nav\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <ul\n v-if=\"items.length > 0\"\n class=\"t-nav-menu__list\"\n >\n <li\n v-for=\"(item, index) in items\"\n :key=\"item.value\"\n class=\"t-nav-menu__entry\"\n >\n <component\n :is=\"itemTag(item)\"\n :ref=\"(element: Element | ComponentPublicInstance | null) => setItemRef(element, item.value)\"\n :type=\"item.to ? undefined : 'button'\"\n :to=\"item.to || undefined\"\n class=\"t-nav-menu__item\"\n :class=\"{\n 'is-selected': isSelected(item.value),\n 'is-disabled': disabled || item.disabled,\n }\"\n :disabled=\"(!item.to && (disabled || item.disabled)) || undefined\"\n :aria-disabled=\"(item.to && (disabled || item.disabled)) || undefined\"\n :aria-current=\"isSelected(item.value) ? 'page' : undefined\"\n :tabindex=\"disabled || item.disabled ? -1 : getTabIndex(index)\"\n :title=\"resolvedCollapsed ? item.label : undefined\"\n @click=\"selectItem(item)\"\n @keydown=\"onItemKeydown($event, index)\"\n @focus=\"focusedIndex = index\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :selected=\"isSelected(item.value)\"\n :focused=\"focusedIndex === index\"\n :collapsed=\"resolvedCollapsed\"\n >\n <component\n :is=\"item.icon\"\n v-if=\"item.icon\"\n class=\"t-nav-menu__icon\"\n aria-hidden=\"true\"\n />\n <span\n v-else\n class=\"t-nav-menu__marker\"\n aria-hidden=\"true\"\n >\n {{ (item.shortLabel ?? item.label.charAt(0)).toUpperCase() }}\n </span>\n\n <span class=\"t-nav-menu__copy\">\n <span class=\"t-nav-menu__label\">{{ item.label }}</span>\n <span\n v-if=\"item.description\"\n class=\"t-nav-menu__description\"\n >\n {{ item.description }}\n </span>\n </span>\n\n <span\n v-if=\"item.badge !== undefined && item.badge !== null\"\n class=\"t-nav-menu__badge\"\n >\n {{ item.badge }}\n </span>\n </slot>\n </component>\n </li>\n </ul>\n\n <div\n v-else\n class=\"t-nav-menu__empty\"\n >\n <slot name=\"empty\">\n No navigation items.\n </slot>\n </div>\n </nav>\n</template>\n","<script setup lang=\"ts\">\nimport { getNextEnabledIndex, isActivationKey } from '@treeui/utils';\nimport { computed, getCurrentInstance, inject, nextTick, ref, useAttrs, watch, type Component, type ComponentPublicInstance } from 'vue';\nimport type { TSize } from '../types/contracts';\nimport { treeSidebarInjectionKey } from './sidebar';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TNavMenuItem {\n label: string;\n value: string;\n shortLabel?: string;\n description?: string;\n icon?: Component;\n to?: string | Record<string, unknown>;\n badge?: string | number;\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n defaultValue?: string;\n items?: TNavMenuItem[];\n size?: TSize;\n collapsed?: boolean;\n disabled?: boolean;\n }>(),\n {\n modelValue: undefined,\n defaultValue: '',\n items: () => [],\n size: 'md',\n collapsed: undefined,\n disabled: false,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n select: [value: string, item: TNavMenuItem];\n}>();\n\ndefineSlots<{\n item?: (props: {\n item: TNavMenuItem;\n selected: boolean;\n focused: boolean;\n collapsed: boolean;\n }) => unknown;\n empty?: () => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst sidebar = inject(treeSidebarInjectionKey, null);\nconst internalValue = ref(props.defaultValue);\nconst itemRefs = ref<Map<string, HTMLElement>>(new Map());\nconst instance = getCurrentInstance();\n\nconst selectedValue = computed(() => props.modelValue ?? internalValue.value);\nconst resolvedCollapsed = computed(() => props.collapsed ?? sidebar?.collapsed.value ?? false);\n\nconst routerLinkComponent = computed<Component | null>(() => (\n (instance?.appContext.components.RouterLink as Component | undefined) ?? null\n));\n\nconst itemTag = (item: TNavMenuItem) => {\n if (item.to && routerLinkComponent.value) {\n return routerLinkComponent.value;\n }\n return 'button';\n};\n\nconst getInitialFocusedIndex = () => {\n const selectedIndex = props.items.findIndex((item) =>\n item.value === selectedValue.value && !item.disabled,\n );\n\n if (selectedIndex >= 0) {\n return selectedIndex;\n }\n\n return props.items.findIndex((item) => !item.disabled);\n};\n\nconst focusedIndex = ref(getInitialFocusedIndex());\n\nconst rootClasses = computed(() => [\n 't-nav-menu',\n `t-nav-menu--${props.size}`,\n {\n 'is-collapsed': resolvedCollapsed.value,\n 'is-disabled': props.disabled,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst isSelected = (value: string) => selectedValue.value === value;\n\nconst setItemRef = (element: Element | ComponentPublicInstance | null, value: string) => {\n const resolvedElement =\n element instanceof HTMLElement\n ? element\n : element && '$el' in element && element.$el instanceof HTMLElement\n ? element.$el\n : null;\n\n if (resolvedElement) {\n itemRefs.value.set(value, resolvedElement);\n } else {\n itemRefs.value.delete(value);\n }\n};\n\nconst focusItem = (index: number) => {\n const item = props.items[index];\n\n if (!item) {\n return;\n }\n\n focusedIndex.value = index;\n nextTick(() => itemRefs.value.get(item.value)?.focus());\n};\n\nconst selectItem = (item: TNavMenuItem) => {\n if (props.disabled || item.disabled) {\n return;\n }\n\n if (props.modelValue === undefined) {\n internalValue.value = item.value;\n }\n\n emit('update:modelValue', item.value);\n emit('select', item.value, item);\n};\n\nconst onItemKeydown = (event: KeyboardEvent, index: number) => {\n if (props.disabled) {\n return;\n }\n\n if (event.key === 'Home') {\n event.preventDefault();\n const firstIndex = props.items.findIndex((item) => !item.disabled);\n\n if (firstIndex >= 0) {\n focusItem(firstIndex);\n }\n\n return;\n }\n\n if (event.key === 'End') {\n event.preventDefault();\n const lastIndex = [...props.items].reverse().findIndex((item) => !item.disabled);\n\n if (lastIndex >= 0) {\n focusItem(props.items.length - 1 - lastIndex);\n }\n\n return;\n }\n\n if (event.key === 'ArrowDown' || event.key === 'ArrowRight') {\n event.preventDefault();\n const nextIndex = getNextEnabledIndex(index, props.items, 1);\n\n if (nextIndex >= 0) {\n focusItem(nextIndex);\n }\n\n return;\n }\n\n if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {\n event.preventDefault();\n const previousIndex = getNextEnabledIndex(index, props.items, -1);\n\n if (previousIndex >= 0) {\n focusItem(previousIndex);\n }\n\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectItem(props.items[index]);\n }\n};\n\nconst getTabIndex = (index: number) => (focusedIndex.value === index ? 0 : -1);\n\nwatch(\n () => [props.items, props.modelValue] as const,\n () => {\n const nextIndex = getInitialFocusedIndex();\n focusedIndex.value = nextIndex >= 0 ? nextIndex : -1;\n },\n { deep: true },\n);\n</script>\n\n<template>\n <nav\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <ul\n v-if=\"items.length > 0\"\n class=\"t-nav-menu__list\"\n >\n <li\n v-for=\"(item, index) in items\"\n :key=\"item.value\"\n class=\"t-nav-menu__entry\"\n >\n <component\n :is=\"itemTag(item)\"\n :ref=\"(element: Element | ComponentPublicInstance | null) => setItemRef(element, item.value)\"\n :type=\"item.to ? undefined : 'button'\"\n :to=\"item.to || undefined\"\n class=\"t-nav-menu__item\"\n :class=\"{\n 'is-selected': isSelected(item.value),\n 'is-disabled': disabled || item.disabled,\n }\"\n :disabled=\"(!item.to && (disabled || item.disabled)) || undefined\"\n :aria-disabled=\"(item.to && (disabled || item.disabled)) || undefined\"\n :aria-current=\"isSelected(item.value) ? 'page' : undefined\"\n :tabindex=\"disabled || item.disabled ? -1 : getTabIndex(index)\"\n :title=\"resolvedCollapsed ? item.label : undefined\"\n @click=\"selectItem(item)\"\n @keydown=\"onItemKeydown($event, index)\"\n @focus=\"focusedIndex = index\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :selected=\"isSelected(item.value)\"\n :focused=\"focusedIndex === index\"\n :collapsed=\"resolvedCollapsed\"\n >\n <component\n :is=\"item.icon\"\n v-if=\"item.icon\"\n class=\"t-nav-menu__icon\"\n aria-hidden=\"true\"\n />\n <span\n v-else\n class=\"t-nav-menu__marker\"\n aria-hidden=\"true\"\n >\n {{ (item.shortLabel ?? item.label.charAt(0)).toUpperCase() }}\n </span>\n\n <span class=\"t-nav-menu__copy\">\n <span class=\"t-nav-menu__label\">{{ item.label }}</span>\n <span\n v-if=\"item.description\"\n class=\"t-nav-menu__description\"\n >\n {{ item.description }}\n </span>\n </span>\n\n <span\n v-if=\"item.badge !== undefined && item.badge !== null\"\n class=\"t-nav-menu__badge\"\n >\n {{ item.badge }}\n </span>\n </slot>\n </component>\n </li>\n </ul>\n\n <div\n v-else\n class=\"t-nav-menu__empty\"\n >\n <slot name=\"empty\">\n No navigation items.\n </slot>\n </div>\n </nav>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, inject, useAttrs } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n value: string;\n disabled?: boolean;\n invalid?: boolean;\n size?: TSize;\n }>(),\n {\n disabled: false,\n invalid: false,\n size: undefined,\n },\n);\n\nconst group = inject<{\n modelValue: () => string | undefined;\n name: () => string | undefined;\n disabled: () => boolean;\n invalid: () => boolean;\n size: () => TSize;\n onChange: (value: string) => void;\n} | null>('t-radio-group', null);\n\nconst attrs = useAttrs();\n\nconst isChecked = computed(() => {\n return group ? group.modelValue() === props.value : false;\n});\n\nconst isDisabled = computed(() => props.disabled || (group?.disabled() ?? false));\nconst isInvalid = computed(() => props.invalid || (group?.invalid() ?? false));\nconst resolvedSize = computed(() => props.size ?? group?.size() ?? 'md');\n\nconst rootClasses = computed(() => [\n 't-radio',\n `t-radio--${resolvedSize.value}`,\n {\n 'is-checked': isChecked.value,\n 'is-disabled': isDisabled.value,\n 'is-invalid': isInvalid.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst inputAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst onChange = () => {\n if (group) {\n group.onChange(props.value);\n }\n};\n</script>\n\n<template>\n <label\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <input\n v-bind=\"inputAttrs\"\n type=\"radio\"\n class=\"t-radio__input\"\n :value=\"value\"\n :checked=\"isChecked\"\n :disabled=\"isDisabled\"\n :name=\"group?.name()\"\n :aria-checked=\"isChecked\"\n :aria-invalid=\"isInvalid || undefined\"\n @change=\"onChange\"\n >\n <span\n class=\"t-radio__control\"\n aria-hidden=\"true\"\n >\n <span\n v-if=\"isChecked\"\n class=\"t-radio__dot\"\n />\n </span>\n <span\n v-if=\"$slots.default\"\n class=\"t-radio__label\"\n >\n <slot />\n </span>\n </label>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, inject, useAttrs } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n value: string;\n disabled?: boolean;\n invalid?: boolean;\n size?: TSize;\n }>(),\n {\n disabled: false,\n invalid: false,\n size: undefined,\n },\n);\n\nconst group = inject<{\n modelValue: () => string | undefined;\n name: () => string | undefined;\n disabled: () => boolean;\n invalid: () => boolean;\n size: () => TSize;\n onChange: (value: string) => void;\n} | null>('t-radio-group', null);\n\nconst attrs = useAttrs();\n\nconst isChecked = computed(() => {\n return group ? group.modelValue() === props.value : false;\n});\n\nconst isDisabled = computed(() => props.disabled || (group?.disabled() ?? false));\nconst isInvalid = computed(() => props.invalid || (group?.invalid() ?? false));\nconst resolvedSize = computed(() => props.size ?? group?.size() ?? 'md');\n\nconst rootClasses = computed(() => [\n 't-radio',\n `t-radio--${resolvedSize.value}`,\n {\n 'is-checked': isChecked.value,\n 'is-disabled': isDisabled.value,\n 'is-invalid': isInvalid.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst inputAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst onChange = () => {\n if (group) {\n group.onChange(props.value);\n }\n};\n</script>\n\n<template>\n <label\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <input\n v-bind=\"inputAttrs\"\n type=\"radio\"\n class=\"t-radio__input\"\n :value=\"value\"\n :checked=\"isChecked\"\n :disabled=\"isDisabled\"\n :name=\"group?.name()\"\n :aria-checked=\"isChecked\"\n :aria-invalid=\"isInvalid || undefined\"\n @change=\"onChange\"\n >\n <span\n class=\"t-radio__control\"\n aria-hidden=\"true\"\n >\n <span\n v-if=\"isChecked\"\n class=\"t-radio__dot\"\n />\n </span>\n <span\n v-if=\"$slots.default\"\n class=\"t-radio__label\"\n >\n <slot />\n </span>\n </label>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, provide, useAttrs } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n name?: string;\n disabled?: boolean;\n invalid?: boolean;\n size?: TSize;\n }>(),\n {\n modelValue: undefined,\n name: undefined,\n disabled: false,\n invalid: false,\n size: 'md',\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n}>();\n\nconst attrs = useAttrs();\n\nprovide('t-radio-group', {\n modelValue: () => props.modelValue,\n name: () => props.name,\n disabled: () => props.disabled,\n invalid: () => props.invalid,\n size: () => props.size,\n onChange: (value: string) => {\n emit('update:modelValue', value);\n },\n});\n\nconst rootClasses = computed(() => [\n 't-radio-group',\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst groupAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n</script>\n\n<template>\n <div\n v-bind=\"groupAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n role=\"radiogroup\"\n >\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, provide, useAttrs } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n name?: string;\n disabled?: boolean;\n invalid?: boolean;\n size?: TSize;\n }>(),\n {\n modelValue: undefined,\n name: undefined,\n disabled: false,\n invalid: false,\n size: 'md',\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n}>();\n\nconst attrs = useAttrs();\n\nprovide('t-radio-group', {\n modelValue: () => props.modelValue,\n name: () => props.name,\n disabled: () => props.disabled,\n invalid: () => props.invalid,\n size: () => props.size,\n onChange: (value: string) => {\n emit('update:modelValue', value);\n },\n});\n\nconst rootClasses = computed(() => [\n 't-radio-group',\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst groupAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n</script>\n\n<template>\n <div\n v-bind=\"groupAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n role=\"radiogroup\"\n >\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { createId, isActivationKey, isEscapeKey } from '@treeui/utils';\nimport { computed, nextTick, onBeforeUnmount, ref, toRef, useAttrs, watch } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TSelectOption {\n label: string;\n value: string | number;\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string | number;\n options?: TSelectOption[];\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n placeholder?: string;\n }>(),\n {\n modelValue: '',\n options: () => [],\n open: undefined,\n defaultOpen: false,\n size: 'md',\n disabled: false,\n loading: false,\n invalid: false,\n placeholder: '',\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | number];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\nconst attrs = useAttrs();\nconst listboxId = createId('t-select');\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst optionRefs = ref<Map<string | number, HTMLElement>>(new Map());\nconst focusedIndex = ref(-1);\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-select',\n `t-select--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst selectedLabel = computed(() => {\n const opt = props.options.find((o) => o.value === props.modelValue);\n return opt?.label ?? '';\n});\n\nconst enabledOptions = computed(() =>\n props.options.filter((o) => !o.disabled),\n);\n\nconst openDropdown = () => {\n if (props.disabled) return;\n const selectedIdx = props.options.findIndex((o) => o.value === props.modelValue);\n focusedIndex.value = selectedIdx >= 0 ? selectedIdx : 0;\n setValue(true);\n nextTick(() => focusOption(focusedIndex.value));\n};\n\nconst closeDropdown = (restoreFocus = false) => {\n setValue(false);\n focusedIndex.value = -1;\n if (restoreFocus) {\n nextTick(() => triggerRef.value?.focus());\n }\n};\n\nconst toggleDropdown = () => {\n if (isOpen.value) {\n closeDropdown();\n } else {\n openDropdown();\n }\n};\n\nconst selectOption = (opt: TSelectOption) => {\n if (opt.disabled) return;\n emit('update:modelValue', opt.value);\n closeDropdown(true);\n};\n\nconst focusOption = (index: number) => {\n const opt = props.options[index];\n if (!opt) return;\n const el = optionRefs.value.get(opt.value);\n el?.focus();\n};\n\nconst setOptionRef = (el: Element | null, value: string | number) => {\n if (el instanceof HTMLElement) {\n optionRefs.value.set(value, el);\n } else {\n optionRefs.value.delete(value);\n }\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n let nextIndex = focusedIndex.value + direction;\n while (nextIndex >= 0 && nextIndex < props.options.length) {\n if (!props.options[nextIndex].disabled) {\n focusedIndex.value = nextIndex;\n focusOption(nextIndex);\n return;\n }\n nextIndex += direction;\n }\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) return;\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closeDropdown();\n return;\n }\n\n if (isActivationKey(event) || event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n openDropdown();\n }\n};\n\nconst onOptionKeydown = (event: KeyboardEvent, opt: TSelectOption, _index: number) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeDropdown(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectOption(opt);\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(-1);\n break;\n case 'Home':\n event.preventDefault();\n focusedIndex.value = enabledOptions.value.length > 0\n ? props.options.indexOf(enabledOptions.value[0])\n : 0;\n focusOption(focusedIndex.value);\n break;\n case 'End':\n event.preventDefault();\n focusedIndex.value = enabledOptions.value.length > 0\n ? props.options.indexOf(enabledOptions.value[enabledOptions.value.length - 1])\n : props.options.length - 1;\n focusOption(focusedIndex.value);\n break;\n default:\n break;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) return;\n const target = event.target;\n if (!(target instanceof Node)) return;\n if (rootRef.value?.contains(target)) return;\n closeDropdown();\n};\n\nconst hasSelection = computed(() =>\n props.modelValue !== '' && props.modelValue !== null && props.modelValue !== undefined,\n);\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n } else {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-select__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? listboxId : undefined\"\n aria-haspopup=\"listbox\"\n :aria-expanded=\"isOpen\"\n :aria-invalid=\"invalid || undefined\"\n :aria-busy=\"loading || undefined\"\n @click=\"toggleDropdown\"\n @keydown=\"onTriggerKeydown\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-select__slot t-select__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n <span\n class=\"t-select__value\"\n :data-placeholder=\"!hasSelection ? true : undefined\"\n >\n {{ selectedLabel || placeholder }}\n </span>\n <TSpinner\n v-if=\"loading\"\n size=\"sm\"\n label=\"Loading\"\n />\n <svg\n v-else\n class=\"t-select__chevron\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"4 6 8 10 12 6\" />\n </svg>\n </button>\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"listboxId\"\n role=\"listbox\"\n class=\"t-select__listbox\"\n :aria-label=\"typeof triggerAttrs['aria-label'] === 'string' ? triggerAttrs['aria-label'] : undefined\"\n >\n <li\n v-for=\"(opt, index) in options\"\n :key=\"opt.value\"\n :ref=\"(el) => setOptionRef(el as Element | null, opt.value)\"\n role=\"option\"\n class=\"t-select__option\"\n :class=\"{\n 'is-selected': opt.value === modelValue,\n 'is-disabled': opt.disabled,\n 'is-focused': index === focusedIndex,\n }\"\n :aria-selected=\"opt.value === modelValue\"\n :aria-disabled=\"opt.disabled || undefined\"\n :tabindex=\"opt.disabled ? -1 : 0\"\n @click=\"selectOption(opt)\"\n @keydown=\"onOptionKeydown($event, opt, index)\"\n >\n {{ opt.label }}\n <svg\n v-if=\"opt.value === modelValue\"\n class=\"t-select__check\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"3.5 8.5 6.5 11.5 12.5 4.5\" />\n </svg>\n </li>\n </ul>\n </transition>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { createId, isActivationKey, isEscapeKey } from '@treeui/utils';\nimport { computed, nextTick, onBeforeUnmount, ref, toRef, useAttrs, watch } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TSelectOption {\n label: string;\n value: string | number;\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string | number;\n options?: TSelectOption[];\n open?: boolean;\n defaultOpen?: boolean;\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n placeholder?: string;\n }>(),\n {\n modelValue: '',\n options: () => [],\n open: undefined,\n defaultOpen: false,\n size: 'md',\n disabled: false,\n loading: false,\n invalid: false,\n placeholder: '',\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | number];\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\nconst attrs = useAttrs();\nconst listboxId = createId('t-select');\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst optionRefs = ref<Map<string | number, HTMLElement>>(new Map());\nconst focusedIndex = ref(-1);\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-select',\n `t-select--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n 'is-open': isOpen.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst selectedLabel = computed(() => {\n const opt = props.options.find((o) => o.value === props.modelValue);\n return opt?.label ?? '';\n});\n\nconst enabledOptions = computed(() =>\n props.options.filter((o) => !o.disabled),\n);\n\nconst openDropdown = () => {\n if (props.disabled) return;\n const selectedIdx = props.options.findIndex((o) => o.value === props.modelValue);\n focusedIndex.value = selectedIdx >= 0 ? selectedIdx : 0;\n setValue(true);\n nextTick(() => focusOption(focusedIndex.value));\n};\n\nconst closeDropdown = (restoreFocus = false) => {\n setValue(false);\n focusedIndex.value = -1;\n if (restoreFocus) {\n nextTick(() => triggerRef.value?.focus());\n }\n};\n\nconst toggleDropdown = () => {\n if (isOpen.value) {\n closeDropdown();\n } else {\n openDropdown();\n }\n};\n\nconst selectOption = (opt: TSelectOption) => {\n if (opt.disabled) return;\n emit('update:modelValue', opt.value);\n closeDropdown(true);\n};\n\nconst focusOption = (index: number) => {\n const opt = props.options[index];\n if (!opt) return;\n const el = optionRefs.value.get(opt.value);\n el?.focus();\n};\n\nconst setOptionRef = (el: Element | null, value: string | number) => {\n if (el instanceof HTMLElement) {\n optionRefs.value.set(value, el);\n } else {\n optionRefs.value.delete(value);\n }\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n let nextIndex = focusedIndex.value + direction;\n while (nextIndex >= 0 && nextIndex < props.options.length) {\n if (!props.options[nextIndex].disabled) {\n focusedIndex.value = nextIndex;\n focusOption(nextIndex);\n return;\n }\n nextIndex += direction;\n }\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) return;\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closeDropdown();\n return;\n }\n\n if (isActivationKey(event) || event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n openDropdown();\n }\n};\n\nconst onOptionKeydown = (event: KeyboardEvent, opt: TSelectOption, _index: number) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closeDropdown(true);\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectOption(opt);\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n moveFocus(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n moveFocus(-1);\n break;\n case 'Home':\n event.preventDefault();\n focusedIndex.value = enabledOptions.value.length > 0\n ? props.options.indexOf(enabledOptions.value[0])\n : 0;\n focusOption(focusedIndex.value);\n break;\n case 'End':\n event.preventDefault();\n focusedIndex.value = enabledOptions.value.length > 0\n ? props.options.indexOf(enabledOptions.value[enabledOptions.value.length - 1])\n : props.options.length - 1;\n focusOption(focusedIndex.value);\n break;\n default:\n break;\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) return;\n const target = event.target;\n if (!(target instanceof Node)) return;\n if (rootRef.value?.contains(target)) return;\n closeDropdown();\n};\n\nconst hasSelection = computed(() =>\n props.modelValue !== '' && props.modelValue !== null && props.modelValue !== undefined,\n);\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n } else {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <button\n ref=\"triggerRef\"\n v-bind=\"triggerAttrs\"\n type=\"button\"\n class=\"t-select__trigger\"\n :disabled=\"disabled\"\n :aria-controls=\"isOpen ? listboxId : undefined\"\n aria-haspopup=\"listbox\"\n :aria-expanded=\"isOpen\"\n :aria-invalid=\"invalid || undefined\"\n :aria-busy=\"loading || undefined\"\n @click=\"toggleDropdown\"\n @keydown=\"onTriggerKeydown\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-select__slot t-select__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n <span\n class=\"t-select__value\"\n :data-placeholder=\"!hasSelection ? true : undefined\"\n >\n {{ selectedLabel || placeholder }}\n </span>\n <TSpinner\n v-if=\"loading\"\n size=\"sm\"\n label=\"Loading\"\n />\n <svg\n v-else\n class=\"t-select__chevron\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"4 6 8 10 12 6\" />\n </svg>\n </button>\n <transition name=\"t-fade\">\n <ul\n v-if=\"isOpen && !disabled\"\n :id=\"listboxId\"\n role=\"listbox\"\n class=\"t-select__listbox\"\n :aria-label=\"typeof triggerAttrs['aria-label'] === 'string' ? triggerAttrs['aria-label'] : undefined\"\n >\n <li\n v-for=\"(opt, index) in options\"\n :key=\"opt.value\"\n :ref=\"(el) => setOptionRef(el as Element | null, opt.value)\"\n role=\"option\"\n class=\"t-select__option\"\n :class=\"{\n 'is-selected': opt.value === modelValue,\n 'is-disabled': opt.disabled,\n 'is-focused': index === focusedIndex,\n }\"\n :aria-selected=\"opt.value === modelValue\"\n :aria-disabled=\"opt.disabled || undefined\"\n :tabindex=\"opt.disabled ? -1 : 0\"\n @click=\"selectOption(opt)\"\n @keydown=\"onOptionKeydown($event, opt, index)\"\n >\n {{ opt.label }}\n <svg\n v-if=\"opt.value === modelValue\"\n class=\"t-select__check\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <polyline points=\"3.5 8.5 6.5 11.5 12.5 4.5\" />\n </svg>\n </li>\n </ul>\n </transition>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { getTreeIcon } from '@treeui/icons';\nimport { computed, provide, toRef, useAttrs } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\nimport { treeSidebarInjectionKey } from './sidebar';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst _treeSidebarSides = ['left', 'right'] as const;\n\nexport type TSidebarSide = (typeof _treeSidebarSides)[number];\n\nconst ChevronLeftIcon = getTreeIcon('chevron-left');\nconst ChevronRightIcon = getTreeIcon('chevron-right');\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n collapsed?: boolean;\n defaultCollapsed?: boolean;\n collapsible?: boolean;\n size?: TSize;\n side?: TSidebarSide;\n sticky?: boolean;\n bordered?: boolean;\n width?: string;\n collapsedWidth?: string;\n collapseLabel?: string;\n expandLabel?: string;\n }>(),\n {\n as: 'aside',\n collapsed: undefined,\n defaultCollapsed: false,\n collapsible: true,\n size: 'md',\n side: 'left',\n sticky: false,\n bordered: true,\n width: '17.5rem',\n collapsedWidth: '4.75rem',\n collapseLabel: 'Collapse sidebar',\n expandLabel: 'Expand sidebar',\n },\n);\n\nconst emit = defineEmits<{\n 'update:collapsed': [value: boolean];\n 'collapse-change': [value: boolean];\n}>();\n\ndefineSlots<{\n header?: (props: { collapsed: boolean }) => unknown;\n default?: (props: { collapsed: boolean }) => unknown;\n footer?: (props: { collapsed: boolean }) => unknown;\n toggle?: (props: { collapsed: boolean }) => unknown;\n}>();\n\nconst attrs = useAttrs();\n\nconst { value: isCollapsed, setValue } = useControllableOpen(\n toRef(props, 'collapsed'),\n props.defaultCollapsed,\n (value) => {\n emit('update:collapsed', value);\n emit('collapse-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-sidebar',\n `t-sidebar--${props.size}`,\n `t-sidebar--${props.side}`,\n {\n 'is-collapsed': isCollapsed.value,\n 'is-sticky': props.sticky,\n 'is-bordered': props.bordered,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => [\n {\n '--tree-sidebar-width': props.width,\n '--tree-sidebar-collapsed-width': props.collapsedWidth,\n },\n attrs.style,\n]);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst toggleCollapsed = () => {\n if (!props.collapsible) {\n return;\n }\n\n setValue(!isCollapsed.value);\n};\n\nconst ToggleIcon = computed(() => {\n if (props.side === 'right') {\n return isCollapsed.value ? ChevronLeftIcon : ChevronRightIcon;\n }\n\n return isCollapsed.value ? ChevronRightIcon : ChevronLeftIcon;\n});\n\nconst toggleLabel = computed(() =>\n isCollapsed.value ? props.expandLabel : props.collapseLabel,\n);\n\nprovide(treeSidebarInjectionKey, {\n collapsed: computed(() => isCollapsed.value),\n});\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isCollapsed ? 'collapsed' : 'expanded'\"\n >\n <div\n v-if=\"$slots.header\"\n class=\"t-sidebar__header\"\n >\n <slot\n name=\"header\"\n :collapsed=\"isCollapsed\"\n />\n </div>\n\n <div class=\"t-sidebar__body\">\n <slot :collapsed=\"isCollapsed\" />\n </div>\n\n <div\n v-if=\"$slots.footer || collapsible\"\n class=\"t-sidebar__footer\"\n >\n <slot\n v-if=\"$slots.footer\"\n name=\"footer\"\n :collapsed=\"isCollapsed\"\n />\n\n <button\n v-if=\"collapsible\"\n type=\"button\"\n class=\"t-sidebar__toggle\"\n :aria-label=\"toggleLabel\"\n :aria-expanded=\"!isCollapsed\"\n @click=\"toggleCollapsed\"\n >\n <slot\n name=\"toggle\"\n :collapsed=\"isCollapsed\"\n >\n <component\n :is=\"ToggleIcon\"\n :size=\"16\"\n />\n <span v-if=\"!isCollapsed\">{{ toggleLabel }}</span>\n </slot>\n </button>\n </div>\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { getTreeIcon } from '@treeui/icons';\nimport { computed, provide, toRef, useAttrs } from 'vue';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TSize } from '../types/contracts';\nimport { treeSidebarInjectionKey } from './sidebar';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst _treeSidebarSides = ['left', 'right'] as const;\n\nexport type TSidebarSide = (typeof _treeSidebarSides)[number];\n\nconst ChevronLeftIcon = getTreeIcon('chevron-left');\nconst ChevronRightIcon = getTreeIcon('chevron-right');\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n collapsed?: boolean;\n defaultCollapsed?: boolean;\n collapsible?: boolean;\n size?: TSize;\n side?: TSidebarSide;\n sticky?: boolean;\n bordered?: boolean;\n width?: string;\n collapsedWidth?: string;\n collapseLabel?: string;\n expandLabel?: string;\n }>(),\n {\n as: 'aside',\n collapsed: undefined,\n defaultCollapsed: false,\n collapsible: true,\n size: 'md',\n side: 'left',\n sticky: false,\n bordered: true,\n width: '17.5rem',\n collapsedWidth: '4.75rem',\n collapseLabel: 'Collapse sidebar',\n expandLabel: 'Expand sidebar',\n },\n);\n\nconst emit = defineEmits<{\n 'update:collapsed': [value: boolean];\n 'collapse-change': [value: boolean];\n}>();\n\ndefineSlots<{\n header?: (props: { collapsed: boolean }) => unknown;\n default?: (props: { collapsed: boolean }) => unknown;\n footer?: (props: { collapsed: boolean }) => unknown;\n toggle?: (props: { collapsed: boolean }) => unknown;\n}>();\n\nconst attrs = useAttrs();\n\nconst { value: isCollapsed, setValue } = useControllableOpen(\n toRef(props, 'collapsed'),\n props.defaultCollapsed,\n (value) => {\n emit('update:collapsed', value);\n emit('collapse-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-sidebar',\n `t-sidebar--${props.size}`,\n `t-sidebar--${props.side}`,\n {\n 'is-collapsed': isCollapsed.value,\n 'is-sticky': props.sticky,\n 'is-bordered': props.bordered,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => [\n {\n '--tree-sidebar-width': props.width,\n '--tree-sidebar-collapsed-width': props.collapsedWidth,\n },\n attrs.style,\n]);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst toggleCollapsed = () => {\n if (!props.collapsible) {\n return;\n }\n\n setValue(!isCollapsed.value);\n};\n\nconst ToggleIcon = computed(() => {\n if (props.side === 'right') {\n return isCollapsed.value ? ChevronLeftIcon : ChevronRightIcon;\n }\n\n return isCollapsed.value ? ChevronRightIcon : ChevronLeftIcon;\n});\n\nconst toggleLabel = computed(() =>\n isCollapsed.value ? props.expandLabel : props.collapseLabel,\n);\n\nprovide(treeSidebarInjectionKey, {\n collapsed: computed(() => isCollapsed.value),\n});\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isCollapsed ? 'collapsed' : 'expanded'\"\n >\n <div\n v-if=\"$slots.header\"\n class=\"t-sidebar__header\"\n >\n <slot\n name=\"header\"\n :collapsed=\"isCollapsed\"\n />\n </div>\n\n <div class=\"t-sidebar__body\">\n <slot :collapsed=\"isCollapsed\" />\n </div>\n\n <div\n v-if=\"$slots.footer || collapsible\"\n class=\"t-sidebar__footer\"\n >\n <slot\n v-if=\"$slots.footer\"\n name=\"footer\"\n :collapsed=\"isCollapsed\"\n />\n\n <button\n v-if=\"collapsible\"\n type=\"button\"\n class=\"t-sidebar__toggle\"\n :aria-label=\"toggleLabel\"\n :aria-expanded=\"!isCollapsed\"\n @click=\"toggleCollapsed\"\n >\n <slot\n name=\"toggle\"\n :collapsed=\"isCollapsed\"\n >\n <component\n :is=\"ToggleIcon\"\n :size=\"16\"\n />\n <span v-if=\"!isCollapsed\">{{ toggleLabel }}</span>\n </slot>\n </button>\n </div>\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue';\nimport type { TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string | number;\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n type?: string;\n placeholder?: string;\n }>(),\n {\n modelValue: '',\n size: 'md',\n disabled: false,\n loading: false,\n invalid: false,\n type: 'text',\n placeholder: '',\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n}>();\n\nconst attrs = useAttrs();\n\nconst rootClasses = computed(() => [\n 't-input',\n `t-input--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst inputAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst stringValue = computed(() => `${props.modelValue ?? ''}`);\n\nconst onInput = (event: Event) => {\n emit('update:modelValue', (event.target as HTMLInputElement).value);\n};\n</script>\n\n<template>\n <label\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-input__slot t-input__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n <input\n v-bind=\"inputAttrs\"\n class=\"t-input__field\"\n :type=\"type\"\n :value=\"stringValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :aria-invalid=\"invalid || undefined\"\n @input=\"onInput\"\n >\n <TSpinner\n v-if=\"loading\"\n size=\"sm\"\n label=\"Loading\"\n />\n <span\n v-if=\"$slots.suffix\"\n class=\"t-input__slot t-input__slot--suffix\"\n >\n <slot name=\"suffix\" />\n </span>\n </label>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue';\nimport type { TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string | number;\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n type?: string;\n placeholder?: string;\n }>(),\n {\n modelValue: '',\n size: 'md',\n disabled: false,\n loading: false,\n invalid: false,\n type: 'text',\n placeholder: '',\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n}>();\n\nconst attrs = useAttrs();\n\nconst rootClasses = computed(() => [\n 't-input',\n `t-input--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst inputAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst stringValue = computed(() => `${props.modelValue ?? ''}`);\n\nconst onInput = (event: Event) => {\n emit('update:modelValue', (event.target as HTMLInputElement).value);\n};\n</script>\n\n<template>\n <label\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <span\n v-if=\"$slots.prefix\"\n class=\"t-input__slot t-input__slot--prefix\"\n >\n <slot name=\"prefix\" />\n </span>\n <input\n v-bind=\"inputAttrs\"\n class=\"t-input__field\"\n :type=\"type\"\n :value=\"stringValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :aria-invalid=\"invalid || undefined\"\n @input=\"onInput\"\n >\n <TSpinner\n v-if=\"loading\"\n size=\"sm\"\n label=\"Loading\"\n />\n <span\n v-if=\"$slots.suffix\"\n class=\"t-input__slot t-input__slot--suffix\"\n >\n <slot name=\"suffix\" />\n </span>\n </label>\n</template>\n","<script setup lang=\"ts\">\nimport { clamp } from '@treeui/utils';\nimport { computed, ref, useAttrs, watch } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: number | null;\n min?: number;\n max?: number;\n step?: number;\n size?: TSize;\n disabled?: boolean;\n invalid?: boolean;\n placeholder?: string;\n controls?: boolean;\n }>(),\n {\n modelValue: null,\n min: undefined,\n max: undefined,\n step: 1,\n size: 'md',\n disabled: false,\n invalid: false,\n placeholder: '',\n controls: true,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: number | null];\n}>();\n\nconst attrs = useAttrs();\nconst displayValue = ref(\n props.modelValue === null || props.modelValue === undefined ? '' : `${props.modelValue}`,\n);\n\nconst precision = computed(() => {\n const normalizedStep = `${props.step}`;\n const fractionalPart = normalizedStep.split('.')[1];\n return fractionalPart ? fractionalPart.length : 0;\n});\n\nconst rootClasses = computed(() => [\n 't-number-input',\n `t-number-input--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'has-controls': props.controls,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst inputAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst formatValue = (value: number | null | undefined) =>\n value === null || value === undefined ? '' : `${value}`;\n\nconst normalizeValue = (value: number) => {\n const clamped = clamp(\n value,\n props.min ?? Number.NEGATIVE_INFINITY,\n props.max ?? Number.POSITIVE_INFINITY,\n );\n\n return Number(clamped.toFixed(precision.value));\n};\n\nconst parseValue = (value: string) => {\n const normalized = value.trim().replace(',', '.');\n\n if (!normalized) {\n return null;\n }\n\n const parsed = Number(normalized);\n return Number.isNaN(parsed) ? null : parsed;\n};\n\nconst currentNumericValue = computed(() => {\n const parsed = parseValue(displayValue.value);\n return parsed ?? props.modelValue ?? null;\n});\n\nconst canDecrement = computed(() => {\n if (props.disabled) {\n return false;\n }\n\n if (props.min === undefined || currentNumericValue.value === null) {\n return true;\n }\n\n return normalizeValue(currentNumericValue.value) > props.min;\n});\n\nconst canIncrement = computed(() => {\n if (props.disabled) {\n return false;\n }\n\n if (props.max === undefined || currentNumericValue.value === null) {\n return true;\n }\n\n return normalizeValue(currentNumericValue.value) < props.max;\n});\n\nconst commitValue = (value: number | null) => {\n if (value === null) {\n displayValue.value = '';\n emit('update:modelValue', null);\n return;\n }\n\n const normalized = normalizeValue(value);\n displayValue.value = `${normalized}`;\n emit('update:modelValue', normalized);\n};\n\nconst stepValue = (direction: 1 | -1) => {\n if (props.disabled) {\n return;\n }\n\n let baseValue = currentNumericValue.value ?? 0;\n\n if (currentNumericValue.value === null) {\n if (direction === 1 && props.min !== undefined) {\n baseValue = props.min - props.step;\n }\n\n if (direction === -1 && props.max !== undefined) {\n baseValue = props.max + props.step;\n }\n }\n\n commitValue(baseValue + direction * props.step);\n};\n\nconst onInput = (event: Event) => {\n const nextValue = (event.target as HTMLInputElement).value;\n displayValue.value = nextValue;\n\n if (!nextValue.trim()) {\n emit('update:modelValue', null);\n return;\n }\n\n const parsedValue = parseValue(nextValue);\n\n if (parsedValue === null) {\n return;\n }\n\n emit('update:modelValue', normalizeValue(parsedValue));\n};\n\nconst onBlur = () => {\n if (!displayValue.value.trim()) {\n displayValue.value = '';\n return;\n }\n\n const parsedValue = parseValue(displayValue.value);\n\n if (parsedValue === null) {\n displayValue.value = formatValue(props.modelValue);\n return;\n }\n\n displayValue.value = `${normalizeValue(parsedValue)}`;\n};\n\nconst onKeydown = (event: KeyboardEvent) => {\n if (props.disabled) {\n return;\n }\n\n if (event.key === 'ArrowUp') {\n event.preventDefault();\n stepValue(1);\n return;\n }\n\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n stepValue(-1);\n return;\n }\n\n if (event.key === 'Home' && props.min !== undefined) {\n event.preventDefault();\n commitValue(props.min);\n return;\n }\n\n if (event.key === 'End' && props.max !== undefined) {\n event.preventDefault();\n commitValue(props.max);\n }\n};\n\nwatch(\n () => props.modelValue,\n (value) => {\n const nextDisplayValue = formatValue(value);\n\n if (nextDisplayValue !== displayValue.value) {\n displayValue.value = nextDisplayValue;\n }\n },\n);\n</script>\n\n<template>\n <div\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <button\n v-if=\"controls\"\n type=\"button\"\n class=\"t-number-input__stepper t-number-input__stepper--decrement\"\n :disabled=\"!canDecrement\"\n aria-label=\"Decrease value\"\n @click=\"stepValue(-1)\"\n >\n <span aria-hidden=\"true\">-</span>\n </button>\n\n <input\n v-bind=\"inputAttrs\"\n :value=\"displayValue\"\n type=\"text\"\n inputmode=\"decimal\"\n class=\"t-number-input__field\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :aria-invalid=\"invalid || undefined\"\n @input=\"onInput\"\n @blur=\"onBlur\"\n @keydown=\"onKeydown\"\n >\n\n <button\n v-if=\"controls\"\n type=\"button\"\n class=\"t-number-input__stepper t-number-input__stepper--increment\"\n :disabled=\"!canIncrement\"\n aria-label=\"Increase value\"\n @click=\"stepValue(1)\"\n >\n <span aria-hidden=\"true\">+</span>\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { clamp } from '@treeui/utils';\nimport { computed, ref, useAttrs, watch } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: number | null;\n min?: number;\n max?: number;\n step?: number;\n size?: TSize;\n disabled?: boolean;\n invalid?: boolean;\n placeholder?: string;\n controls?: boolean;\n }>(),\n {\n modelValue: null,\n min: undefined,\n max: undefined,\n step: 1,\n size: 'md',\n disabled: false,\n invalid: false,\n placeholder: '',\n controls: true,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: number | null];\n}>();\n\nconst attrs = useAttrs();\nconst displayValue = ref(\n props.modelValue === null || props.modelValue === undefined ? '' : `${props.modelValue}`,\n);\n\nconst precision = computed(() => {\n const normalizedStep = `${props.step}`;\n const fractionalPart = normalizedStep.split('.')[1];\n return fractionalPart ? fractionalPart.length : 0;\n});\n\nconst rootClasses = computed(() => [\n 't-number-input',\n `t-number-input--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'has-controls': props.controls,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst inputAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst formatValue = (value: number | null | undefined) =>\n value === null || value === undefined ? '' : `${value}`;\n\nconst normalizeValue = (value: number) => {\n const clamped = clamp(\n value,\n props.min ?? Number.NEGATIVE_INFINITY,\n props.max ?? Number.POSITIVE_INFINITY,\n );\n\n return Number(clamped.toFixed(precision.value));\n};\n\nconst parseValue = (value: string) => {\n const normalized = value.trim().replace(',', '.');\n\n if (!normalized) {\n return null;\n }\n\n const parsed = Number(normalized);\n return Number.isNaN(parsed) ? null : parsed;\n};\n\nconst currentNumericValue = computed(() => {\n const parsed = parseValue(displayValue.value);\n return parsed ?? props.modelValue ?? null;\n});\n\nconst canDecrement = computed(() => {\n if (props.disabled) {\n return false;\n }\n\n if (props.min === undefined || currentNumericValue.value === null) {\n return true;\n }\n\n return normalizeValue(currentNumericValue.value) > props.min;\n});\n\nconst canIncrement = computed(() => {\n if (props.disabled) {\n return false;\n }\n\n if (props.max === undefined || currentNumericValue.value === null) {\n return true;\n }\n\n return normalizeValue(currentNumericValue.value) < props.max;\n});\n\nconst commitValue = (value: number | null) => {\n if (value === null) {\n displayValue.value = '';\n emit('update:modelValue', null);\n return;\n }\n\n const normalized = normalizeValue(value);\n displayValue.value = `${normalized}`;\n emit('update:modelValue', normalized);\n};\n\nconst stepValue = (direction: 1 | -1) => {\n if (props.disabled) {\n return;\n }\n\n let baseValue = currentNumericValue.value ?? 0;\n\n if (currentNumericValue.value === null) {\n if (direction === 1 && props.min !== undefined) {\n baseValue = props.min - props.step;\n }\n\n if (direction === -1 && props.max !== undefined) {\n baseValue = props.max + props.step;\n }\n }\n\n commitValue(baseValue + direction * props.step);\n};\n\nconst onInput = (event: Event) => {\n const nextValue = (event.target as HTMLInputElement).value;\n displayValue.value = nextValue;\n\n if (!nextValue.trim()) {\n emit('update:modelValue', null);\n return;\n }\n\n const parsedValue = parseValue(nextValue);\n\n if (parsedValue === null) {\n return;\n }\n\n emit('update:modelValue', normalizeValue(parsedValue));\n};\n\nconst onBlur = () => {\n if (!displayValue.value.trim()) {\n displayValue.value = '';\n return;\n }\n\n const parsedValue = parseValue(displayValue.value);\n\n if (parsedValue === null) {\n displayValue.value = formatValue(props.modelValue);\n return;\n }\n\n displayValue.value = `${normalizeValue(parsedValue)}`;\n};\n\nconst onKeydown = (event: KeyboardEvent) => {\n if (props.disabled) {\n return;\n }\n\n if (event.key === 'ArrowUp') {\n event.preventDefault();\n stepValue(1);\n return;\n }\n\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n stepValue(-1);\n return;\n }\n\n if (event.key === 'Home' && props.min !== undefined) {\n event.preventDefault();\n commitValue(props.min);\n return;\n }\n\n if (event.key === 'End' && props.max !== undefined) {\n event.preventDefault();\n commitValue(props.max);\n }\n};\n\nwatch(\n () => props.modelValue,\n (value) => {\n const nextDisplayValue = formatValue(value);\n\n if (nextDisplayValue !== displayValue.value) {\n displayValue.value = nextDisplayValue;\n }\n },\n);\n</script>\n\n<template>\n <div\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <button\n v-if=\"controls\"\n type=\"button\"\n class=\"t-number-input__stepper t-number-input__stepper--decrement\"\n :disabled=\"!canDecrement\"\n aria-label=\"Decrease value\"\n @click=\"stepValue(-1)\"\n >\n <span aria-hidden=\"true\">-</span>\n </button>\n\n <input\n v-bind=\"inputAttrs\"\n :value=\"displayValue\"\n type=\"text\"\n inputmode=\"decimal\"\n class=\"t-number-input__field\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :aria-invalid=\"invalid || undefined\"\n @input=\"onInput\"\n @blur=\"onBlur\"\n @keydown=\"onKeydown\"\n >\n\n <button\n v-if=\"controls\"\n type=\"button\"\n class=\"t-number-input__stepper t-number-input__stepper--increment\"\n :disabled=\"!canIncrement\"\n aria-label=\"Increase value\"\n @click=\"stepValue(1)\"\n >\n <span aria-hidden=\"true\">+</span>\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { createId, getNextEnabledIndex, isActivationKey } from '@treeui/utils';\nimport { computed, nextTick, ref, useAttrs, watch, type ComponentPublicInstance } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TSelectableListItem {\n label: string;\n value: string;\n description?: string;\n meta?: string;\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n defaultValue?: string;\n items?: TSelectableListItem[];\n size?: TSize;\n disabled?: boolean;\n emptyText?: string;\n }>(),\n {\n modelValue: undefined,\n defaultValue: '',\n items: () => [],\n size: 'md',\n disabled: false,\n emptyText: 'No items available.',\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n}>();\n\ndefineSlots<{\n item?: (props: {\n item: TSelectableListItem;\n selected: boolean;\n focused: boolean;\n }) => unknown;\n empty?: () => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst baseId = createId('t-selectable-list');\nconst itemRefs = ref<Map<string, HTMLButtonElement>>(new Map());\nconst internalValue = ref(props.defaultValue);\n\nconst selectedValue = computed(() => props.modelValue ?? internalValue.value);\n\nconst getInitialFocusedIndex = () => {\n const selectedIndex = props.items.findIndex((item) =>\n item.value === selectedValue.value && !item.disabled,\n );\n\n if (selectedIndex >= 0) {\n return selectedIndex;\n }\n\n return props.items.findIndex((item) => !item.disabled);\n};\n\nconst focusedIndex = ref(getInitialFocusedIndex());\n\nconst rootClasses = computed(() => [\n 't-selectable-list',\n `t-selectable-list--${props.size}`,\n {\n 'is-disabled': props.disabled,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst isSelected = (value: string) => selectedValue.value === value;\n\nconst setItemRef = (element: Element | ComponentPublicInstance | null, value: string) => {\n const resolvedElement =\n element instanceof HTMLButtonElement\n ? element\n : element && '$el' in element && element.$el instanceof HTMLButtonElement\n ? element.$el\n : null;\n\n if (resolvedElement instanceof HTMLButtonElement) {\n itemRefs.value.set(value, resolvedElement);\n } else {\n itemRefs.value.delete(value);\n }\n};\n\nconst focusItem = (index: number) => {\n const item = props.items[index];\n\n if (!item) {\n return;\n }\n\n focusedIndex.value = index;\n nextTick(() => itemRefs.value.get(item.value)?.focus());\n};\n\nconst selectItem = (item: TSelectableListItem, focus = false) => {\n if (props.disabled || item.disabled) {\n return;\n }\n\n if (props.modelValue === undefined) {\n internalValue.value = item.value;\n }\n\n emit('update:modelValue', item.value);\n\n if (focus) {\n const index = props.items.findIndex((candidate) => candidate.value === item.value);\n\n if (index >= 0) {\n focusItem(index);\n }\n }\n};\n\nconst onItemKeydown = (event: KeyboardEvent, index: number) => {\n if (props.disabled) {\n return;\n }\n\n if (event.key === 'Home') {\n event.preventDefault();\n const firstIndex = props.items.findIndex((item) => !item.disabled);\n\n if (firstIndex >= 0) {\n selectItem(props.items[firstIndex], true);\n }\n\n return;\n }\n\n if (event.key === 'End') {\n event.preventDefault();\n const lastIndex = [...props.items].reverse().findIndex((item) => !item.disabled);\n\n if (lastIndex >= 0) {\n const resolvedIndex = props.items.length - 1 - lastIndex;\n selectItem(props.items[resolvedIndex], true);\n }\n\n return;\n }\n\n if (event.key === 'ArrowDown' || event.key === 'ArrowRight') {\n event.preventDefault();\n const nextIndex = getNextEnabledIndex(index, props.items, 1);\n\n if (nextIndex >= 0) {\n selectItem(props.items[nextIndex], true);\n }\n\n return;\n }\n\n if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {\n event.preventDefault();\n const previousIndex = getNextEnabledIndex(index, props.items, -1);\n\n if (previousIndex >= 0) {\n selectItem(props.items[previousIndex], true);\n }\n\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectItem(props.items[index], true);\n }\n};\n\nconst getTabIndex = (index: number) => (focusedIndex.value === index ? 0 : -1);\n\nwatch(\n () => [props.items, props.modelValue] as const,\n () => {\n const nextIndex = getInitialFocusedIndex();\n focusedIndex.value = nextIndex >= 0 ? nextIndex : -1;\n },\n { deep: true },\n);\n</script>\n\n<template>\n <div\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n role=\"listbox\"\n :aria-disabled=\"disabled || undefined\"\n >\n <template v-if=\"items.length > 0\">\n <button\n v-for=\"(item, index) in items\"\n :id=\"`${baseId}-${item.value}`\"\n :ref=\"(element) => setItemRef(element, item.value)\"\n :key=\"item.value\"\n type=\"button\"\n class=\"t-selectable-list__item\"\n :class=\"{\n 'is-selected': isSelected(item.value),\n 'is-disabled': disabled || item.disabled,\n }\"\n role=\"option\"\n :aria-selected=\"isSelected(item.value)\"\n :tabindex=\"disabled || item.disabled ? -1 : getTabIndex(index)\"\n :disabled=\"disabled || item.disabled\"\n @click=\"selectItem(item)\"\n @keydown=\"onItemKeydown($event, index)\"\n @focus=\"focusedIndex = index\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :selected=\"isSelected(item.value)\"\n :focused=\"focusedIndex === index\"\n >\n <span\n class=\"t-selectable-list__indicator\"\n aria-hidden=\"true\"\n />\n\n <span class=\"t-selectable-list__copy\">\n <span class=\"t-selectable-list__label\">{{ item.label }}</span>\n <span\n v-if=\"item.description\"\n class=\"t-selectable-list__description\"\n >\n {{ item.description }}\n </span>\n </span>\n\n <span\n v-if=\"item.meta\"\n class=\"t-selectable-list__meta\"\n >\n {{ item.meta }}\n </span>\n </slot>\n </button>\n </template>\n\n <div\n v-else\n class=\"t-selectable-list__empty\"\n >\n <slot name=\"empty\">\n {{ emptyText }}\n </slot>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { createId, getNextEnabledIndex, isActivationKey } from '@treeui/utils';\nimport { computed, nextTick, ref, useAttrs, watch, type ComponentPublicInstance } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TSelectableListItem {\n label: string;\n value: string;\n description?: string;\n meta?: string;\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n defaultValue?: string;\n items?: TSelectableListItem[];\n size?: TSize;\n disabled?: boolean;\n emptyText?: string;\n }>(),\n {\n modelValue: undefined,\n defaultValue: '',\n items: () => [],\n size: 'md',\n disabled: false,\n emptyText: 'No items available.',\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n}>();\n\ndefineSlots<{\n item?: (props: {\n item: TSelectableListItem;\n selected: boolean;\n focused: boolean;\n }) => unknown;\n empty?: () => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst baseId = createId('t-selectable-list');\nconst itemRefs = ref<Map<string, HTMLButtonElement>>(new Map());\nconst internalValue = ref(props.defaultValue);\n\nconst selectedValue = computed(() => props.modelValue ?? internalValue.value);\n\nconst getInitialFocusedIndex = () => {\n const selectedIndex = props.items.findIndex((item) =>\n item.value === selectedValue.value && !item.disabled,\n );\n\n if (selectedIndex >= 0) {\n return selectedIndex;\n }\n\n return props.items.findIndex((item) => !item.disabled);\n};\n\nconst focusedIndex = ref(getInitialFocusedIndex());\n\nconst rootClasses = computed(() => [\n 't-selectable-list',\n `t-selectable-list--${props.size}`,\n {\n 'is-disabled': props.disabled,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst isSelected = (value: string) => selectedValue.value === value;\n\nconst setItemRef = (element: Element | ComponentPublicInstance | null, value: string) => {\n const resolvedElement =\n element instanceof HTMLButtonElement\n ? element\n : element && '$el' in element && element.$el instanceof HTMLButtonElement\n ? element.$el\n : null;\n\n if (resolvedElement instanceof HTMLButtonElement) {\n itemRefs.value.set(value, resolvedElement);\n } else {\n itemRefs.value.delete(value);\n }\n};\n\nconst focusItem = (index: number) => {\n const item = props.items[index];\n\n if (!item) {\n return;\n }\n\n focusedIndex.value = index;\n nextTick(() => itemRefs.value.get(item.value)?.focus());\n};\n\nconst selectItem = (item: TSelectableListItem, focus = false) => {\n if (props.disabled || item.disabled) {\n return;\n }\n\n if (props.modelValue === undefined) {\n internalValue.value = item.value;\n }\n\n emit('update:modelValue', item.value);\n\n if (focus) {\n const index = props.items.findIndex((candidate) => candidate.value === item.value);\n\n if (index >= 0) {\n focusItem(index);\n }\n }\n};\n\nconst onItemKeydown = (event: KeyboardEvent, index: number) => {\n if (props.disabled) {\n return;\n }\n\n if (event.key === 'Home') {\n event.preventDefault();\n const firstIndex = props.items.findIndex((item) => !item.disabled);\n\n if (firstIndex >= 0) {\n selectItem(props.items[firstIndex], true);\n }\n\n return;\n }\n\n if (event.key === 'End') {\n event.preventDefault();\n const lastIndex = [...props.items].reverse().findIndex((item) => !item.disabled);\n\n if (lastIndex >= 0) {\n const resolvedIndex = props.items.length - 1 - lastIndex;\n selectItem(props.items[resolvedIndex], true);\n }\n\n return;\n }\n\n if (event.key === 'ArrowDown' || event.key === 'ArrowRight') {\n event.preventDefault();\n const nextIndex = getNextEnabledIndex(index, props.items, 1);\n\n if (nextIndex >= 0) {\n selectItem(props.items[nextIndex], true);\n }\n\n return;\n }\n\n if (event.key === 'ArrowUp' || event.key === 'ArrowLeft') {\n event.preventDefault();\n const previousIndex = getNextEnabledIndex(index, props.items, -1);\n\n if (previousIndex >= 0) {\n selectItem(props.items[previousIndex], true);\n }\n\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectItem(props.items[index], true);\n }\n};\n\nconst getTabIndex = (index: number) => (focusedIndex.value === index ? 0 : -1);\n\nwatch(\n () => [props.items, props.modelValue] as const,\n () => {\n const nextIndex = getInitialFocusedIndex();\n focusedIndex.value = nextIndex >= 0 ? nextIndex : -1;\n },\n { deep: true },\n);\n</script>\n\n<template>\n <div\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n role=\"listbox\"\n :aria-disabled=\"disabled || undefined\"\n >\n <template v-if=\"items.length > 0\">\n <button\n v-for=\"(item, index) in items\"\n :id=\"`${baseId}-${item.value}`\"\n :ref=\"(element) => setItemRef(element, item.value)\"\n :key=\"item.value\"\n type=\"button\"\n class=\"t-selectable-list__item\"\n :class=\"{\n 'is-selected': isSelected(item.value),\n 'is-disabled': disabled || item.disabled,\n }\"\n role=\"option\"\n :aria-selected=\"isSelected(item.value)\"\n :tabindex=\"disabled || item.disabled ? -1 : getTabIndex(index)\"\n :disabled=\"disabled || item.disabled\"\n @click=\"selectItem(item)\"\n @keydown=\"onItemKeydown($event, index)\"\n @focus=\"focusedIndex = index\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :selected=\"isSelected(item.value)\"\n :focused=\"focusedIndex === index\"\n >\n <span\n class=\"t-selectable-list__indicator\"\n aria-hidden=\"true\"\n />\n\n <span class=\"t-selectable-list__copy\">\n <span class=\"t-selectable-list__label\">{{ item.label }}</span>\n <span\n v-if=\"item.description\"\n class=\"t-selectable-list__description\"\n >\n {{ item.description }}\n </span>\n </span>\n\n <span\n v-if=\"item.meta\"\n class=\"t-selectable-list__meta\"\n >\n {{ item.meta }}\n </span>\n </slot>\n </button>\n </template>\n\n <div\n v-else\n class=\"t-selectable-list__empty\"\n >\n <slot name=\"empty\">\n {{ emptyText }}\n </slot>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst _treeStackDirections = ['vertical', 'horizontal'] as const;\n\nexport type TStackDirection = (typeof _treeStackDirections)[number];\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n direction?: TStackDirection;\n gap?: string;\n align?: string;\n justify?: string;\n wrap?: boolean;\n reverse?: boolean;\n }>(),\n {\n as: 'div',\n direction: 'vertical',\n gap: 'var(--tree-space-4)',\n align: 'stretch',\n justify: 'flex-start',\n wrap: false,\n reverse: false,\n },\n);\n\nconst attrs = useAttrs();\n\nconst rootClasses = computed(() => [\n 't-stack',\n `t-stack--${props.direction}`,\n {\n 'is-wrapping': props.wrap,\n 'is-reversed': props.reverse,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => [\n {\n gap: props.gap,\n alignItems: props.align,\n justifyContent: props.justify,\n },\n attrs.style,\n]);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <slot />\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst _treeStackDirections = ['vertical', 'horizontal'] as const;\n\nexport type TStackDirection = (typeof _treeStackDirections)[number];\n\nconst props = withDefaults(\n defineProps<{\n as?: string;\n direction?: TStackDirection;\n gap?: string;\n align?: string;\n justify?: string;\n wrap?: boolean;\n reverse?: boolean;\n }>(),\n {\n as: 'div',\n direction: 'vertical',\n gap: 'var(--tree-space-4)',\n align: 'stretch',\n justify: 'flex-start',\n wrap: false,\n reverse: false,\n },\n);\n\nconst attrs = useAttrs();\n\nconst rootClasses = computed(() => [\n 't-stack',\n `t-stack--${props.direction}`,\n {\n 'is-wrapping': props.wrap,\n 'is-reversed': props.reverse,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => [\n {\n gap: props.gap,\n alignItems: props.align,\n justifyContent: props.justify,\n },\n attrs.style,\n]);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n</script>\n\n<template>\n <component\n :is=\"as\"\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <slot />\n </component>\n</template>\n","import type { ComputedRef, InjectionKey, Ref } from 'vue';\n\nexport interface TTreeViewNode {\n id: string;\n label: string;\n description?: string;\n meta?: string;\n disabled?: boolean;\n children?: TTreeViewNode[];\n}\n\nexport const treeTreeViewSelectionModes = ['single', 'multiple'] as const;\n\nexport type TTreeViewSelectionMode = (typeof treeTreeViewSelectionModes)[number];\n\nexport interface TTreeViewRecord {\n node: TTreeViewNode;\n level: number;\n parentId?: string;\n}\n\nexport interface TTreeViewContext {\n baseId: string;\n disabled: ComputedRef<boolean>;\n selectionMode: ComputedRef<TTreeViewSelectionMode>;\n focusedId: Ref<string>;\n isExpanded: (id: string) => boolean;\n toggleExpanded: (id: string) => void;\n isSelected: (id: string) => boolean;\n toggleSelected: (id: string) => void;\n setFocusedId: (id: string, shouldFocus?: boolean) => void;\n onItemKeydown: (event: KeyboardEvent, id: string) => void;\n registerItem: (id: string, element: HTMLElement) => void;\n unregisterItem: (id: string) => void;\n}\n\nexport const treeTreeViewInjectionKey: InjectionKey<TTreeViewContext> =\n Symbol('tree-tree-view');\n","<script setup lang=\"ts\">\nimport { getTreeIcon } from '@treeui/icons';\nimport { computed, inject, type ComponentPublicInstance } from 'vue';\nimport { treeTreeViewInjectionKey, type TTreeViewNode } from './tree-view';\n\ndefineOptions({\n name: 'TTreeViewItem',\n});\n\nconst ChevronRightIcon = getTreeIcon('chevron-right');\nconst CheckIcon = getTreeIcon('check');\n\nconst props = defineProps<{\n node: TTreeViewNode;\n level: number;\n}>();\n\nconst ctx = inject(treeTreeViewInjectionKey);\n\nif (!ctx) {\n throw new Error('[TreeUI] TTreeView items must be rendered inside a TTreeView.');\n}\n\nconst hasChildren = computed(() => Boolean(props.node.children?.length));\nconst isExpanded = computed(() => (hasChildren.value ? ctx.isExpanded(props.node.id) : false));\nconst isSelected = computed(() => ctx.isSelected(props.node.id));\nconst isDisabled = computed(() => ctx.disabled.value || props.node.disabled);\nconst isFocused = computed(() => ctx.focusedId.value === props.node.id);\nconst itemId = computed(() => `${ctx.baseId}-${props.node.id}`);\n\nconst rowClasses = computed(() => ({\n 'is-expanded': isExpanded.value,\n 'is-selected': isSelected.value,\n 'is-disabled': isDisabled.value,\n 'is-focused': isFocused.value,\n}));\n\nconst setItemRef = (element: Element | ComponentPublicInstance | null) => {\n const resolvedElement =\n element instanceof HTMLElement\n ? element\n : element && '$el' in element && element.$el instanceof HTMLElement\n ? element.$el\n : null;\n\n if (resolvedElement instanceof HTMLElement) {\n ctx.registerItem(props.node.id, resolvedElement);\n } else {\n ctx.unregisterItem(props.node.id);\n }\n};\n\nconst onRowClick = () => {\n ctx.setFocusedId(props.node.id);\n ctx.toggleSelected(props.node.id);\n};\n\nconst onToggleClick = () => {\n if (isDisabled.value || !hasChildren.value) {\n return;\n }\n\n ctx.toggleExpanded(props.node.id);\n ctx.setFocusedId(props.node.id);\n};\n</script>\n\n<template>\n <li\n class=\"t-tree-view__node\"\n role=\"none\"\n >\n <div\n :id=\"itemId\"\n :ref=\"setItemRef\"\n class=\"t-tree-view__row\"\n :class=\"rowClasses\"\n :style=\"{ '--tree-tree-view-level': `${level}` }\"\n role=\"treeitem\"\n :aria-level=\"level\"\n :aria-expanded=\"hasChildren ? isExpanded : undefined\"\n :aria-selected=\"isSelected\"\n :aria-disabled=\"isDisabled || undefined\"\n :tabindex=\"isDisabled ? -1 : isFocused ? 0 : -1\"\n @click=\"onRowClick\"\n @keydown=\"ctx.onItemKeydown($event, node.id)\"\n @focus=\"ctx.setFocusedId(node.id)\"\n >\n <button\n v-if=\"hasChildren\"\n type=\"button\"\n class=\"t-tree-view__toggle\"\n :class=\"{ 'is-expanded': isExpanded }\"\n tabindex=\"-1\"\n :disabled=\"isDisabled\"\n :aria-label=\"isExpanded ? 'Collapse node' : 'Expand node'\"\n @click.stop=\"onToggleClick\"\n >\n <ChevronRightIcon :size=\"16\" />\n </button>\n\n <span\n v-else\n class=\"t-tree-view__spacer\"\n aria-hidden=\"true\"\n />\n\n <span\n class=\"t-tree-view__marker\"\n :class=\"{\n 'is-selected': isSelected,\n 'is-multiple': ctx.selectionMode.value === 'multiple',\n }\"\n aria-hidden=\"true\"\n >\n <CheckIcon\n v-if=\"ctx.selectionMode.value === 'multiple' && isSelected\"\n :size=\"14\"\n />\n </span>\n\n <span class=\"t-tree-view__copy\">\n <span class=\"t-tree-view__label\">{{ node.label }}</span>\n <span\n v-if=\"node.description\"\n class=\"t-tree-view__description\"\n >\n {{ node.description }}\n </span>\n </span>\n\n <span\n v-if=\"node.meta\"\n class=\"t-tree-view__meta\"\n >\n {{ node.meta }}\n </span>\n </div>\n\n <ul\n v-if=\"hasChildren && isExpanded\"\n class=\"t-tree-view__group\"\n role=\"group\"\n >\n <TTreeViewItem\n v-for=\"child in node.children\"\n :key=\"child.id\"\n :node=\"child\"\n :level=\"level + 1\"\n />\n </ul>\n </li>\n</template>\n","<script setup lang=\"ts\">\nimport { getTreeIcon } from '@treeui/icons';\nimport { computed, inject, type ComponentPublicInstance } from 'vue';\nimport { treeTreeViewInjectionKey, type TTreeViewNode } from './tree-view';\n\ndefineOptions({\n name: 'TTreeViewItem',\n});\n\nconst ChevronRightIcon = getTreeIcon('chevron-right');\nconst CheckIcon = getTreeIcon('check');\n\nconst props = defineProps<{\n node: TTreeViewNode;\n level: number;\n}>();\n\nconst ctx = inject(treeTreeViewInjectionKey);\n\nif (!ctx) {\n throw new Error('[TreeUI] TTreeView items must be rendered inside a TTreeView.');\n}\n\nconst hasChildren = computed(() => Boolean(props.node.children?.length));\nconst isExpanded = computed(() => (hasChildren.value ? ctx.isExpanded(props.node.id) : false));\nconst isSelected = computed(() => ctx.isSelected(props.node.id));\nconst isDisabled = computed(() => ctx.disabled.value || props.node.disabled);\nconst isFocused = computed(() => ctx.focusedId.value === props.node.id);\nconst itemId = computed(() => `${ctx.baseId}-${props.node.id}`);\n\nconst rowClasses = computed(() => ({\n 'is-expanded': isExpanded.value,\n 'is-selected': isSelected.value,\n 'is-disabled': isDisabled.value,\n 'is-focused': isFocused.value,\n}));\n\nconst setItemRef = (element: Element | ComponentPublicInstance | null) => {\n const resolvedElement =\n element instanceof HTMLElement\n ? element\n : element && '$el' in element && element.$el instanceof HTMLElement\n ? element.$el\n : null;\n\n if (resolvedElement instanceof HTMLElement) {\n ctx.registerItem(props.node.id, resolvedElement);\n } else {\n ctx.unregisterItem(props.node.id);\n }\n};\n\nconst onRowClick = () => {\n ctx.setFocusedId(props.node.id);\n ctx.toggleSelected(props.node.id);\n};\n\nconst onToggleClick = () => {\n if (isDisabled.value || !hasChildren.value) {\n return;\n }\n\n ctx.toggleExpanded(props.node.id);\n ctx.setFocusedId(props.node.id);\n};\n</script>\n\n<template>\n <li\n class=\"t-tree-view__node\"\n role=\"none\"\n >\n <div\n :id=\"itemId\"\n :ref=\"setItemRef\"\n class=\"t-tree-view__row\"\n :class=\"rowClasses\"\n :style=\"{ '--tree-tree-view-level': `${level}` }\"\n role=\"treeitem\"\n :aria-level=\"level\"\n :aria-expanded=\"hasChildren ? isExpanded : undefined\"\n :aria-selected=\"isSelected\"\n :aria-disabled=\"isDisabled || undefined\"\n :tabindex=\"isDisabled ? -1 : isFocused ? 0 : -1\"\n @click=\"onRowClick\"\n @keydown=\"ctx.onItemKeydown($event, node.id)\"\n @focus=\"ctx.setFocusedId(node.id)\"\n >\n <button\n v-if=\"hasChildren\"\n type=\"button\"\n class=\"t-tree-view__toggle\"\n :class=\"{ 'is-expanded': isExpanded }\"\n tabindex=\"-1\"\n :disabled=\"isDisabled\"\n :aria-label=\"isExpanded ? 'Collapse node' : 'Expand node'\"\n @click.stop=\"onToggleClick\"\n >\n <ChevronRightIcon :size=\"16\" />\n </button>\n\n <span\n v-else\n class=\"t-tree-view__spacer\"\n aria-hidden=\"true\"\n />\n\n <span\n class=\"t-tree-view__marker\"\n :class=\"{\n 'is-selected': isSelected,\n 'is-multiple': ctx.selectionMode.value === 'multiple',\n }\"\n aria-hidden=\"true\"\n >\n <CheckIcon\n v-if=\"ctx.selectionMode.value === 'multiple' && isSelected\"\n :size=\"14\"\n />\n </span>\n\n <span class=\"t-tree-view__copy\">\n <span class=\"t-tree-view__label\">{{ node.label }}</span>\n <span\n v-if=\"node.description\"\n class=\"t-tree-view__description\"\n >\n {{ node.description }}\n </span>\n </span>\n\n <span\n v-if=\"node.meta\"\n class=\"t-tree-view__meta\"\n >\n {{ node.meta }}\n </span>\n </div>\n\n <ul\n v-if=\"hasChildren && isExpanded\"\n class=\"t-tree-view__group\"\n role=\"group\"\n >\n <TTreeViewItem\n v-for=\"child in node.children\"\n :key=\"child.id\"\n :node=\"child\"\n :level=\"level + 1\"\n />\n </ul>\n </li>\n</template>\n","<script setup lang=\"ts\">\nimport { createId, isActivationKey } from '@treeui/utils';\nimport { computed, nextTick, provide, ref, useAttrs, watch } from 'vue';\nimport TTreeViewItem from './TTreeViewItem.vue';\nimport {\n treeTreeViewInjectionKey,\n type TTreeViewNode,\n type TTreeViewRecord,\n type TTreeViewSelectionMode,\n} from './tree-view';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string | string[];\n defaultValue?: string | string[];\n nodes?: TTreeViewNode[];\n selectionMode?: TTreeViewSelectionMode;\n expanded?: string[];\n defaultExpanded?: string[];\n disabled?: boolean;\n emptyText?: string;\n }>(),\n {\n modelValue: undefined,\n defaultValue: undefined,\n nodes: () => [],\n selectionMode: 'single',\n expanded: undefined,\n defaultExpanded: () => [],\n disabled: false,\n emptyText: 'No items available.',\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | string[] | undefined];\n 'update:expanded': [value: string[]];\n 'selection-change': [value: string | string[] | undefined];\n 'expanded-change': [value: string[]];\n}>();\n\nconst attrs = useAttrs();\nconst baseId = createId('t-tree-view');\nconst internalValue = ref<string | string[] | undefined>(props.defaultValue);\nconst internalExpanded = ref<string[]>(props.defaultExpanded);\nconst itemRefs = ref<Map<string, HTMLElement>>(new Map());\n\nconst rootClasses = computed(() => [\n 't-tree-view',\n {\n 'is-disabled': props.disabled,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst treeAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst selectedValues = computed(() => {\n const value = props.modelValue ?? internalValue.value;\n\n if (value === undefined || value === null || value === '') {\n return [] as string[];\n }\n\n return Array.isArray(value) ? value : [value];\n});\n\nconst expandedValues = computed(() => props.expanded ?? internalExpanded.value);\n\nconst updateSelection = (nextValues: string[]) => {\n if (props.selectionMode === 'multiple') {\n if (props.modelValue === undefined) {\n internalValue.value = nextValues;\n }\n\n emit('update:modelValue', nextValues);\n emit('selection-change', nextValues);\n return;\n }\n\n const nextValue = nextValues[0];\n\n if (props.modelValue === undefined) {\n internalValue.value = nextValue;\n }\n\n emit('update:modelValue', nextValue);\n emit('selection-change', nextValue);\n};\n\nconst updateExpanded = (nextValues: string[]) => {\n if (props.expanded === undefined) {\n internalExpanded.value = nextValues;\n }\n\n emit('update:expanded', nextValues);\n emit('expanded-change', nextValues);\n};\n\nconst isSelected = (id: string) => selectedValues.value.includes(id);\nconst isExpanded = (id: string) => expandedValues.value.includes(id);\n\nconst flattenNodes = (\n nodes: TTreeViewNode[],\n level = 1,\n parentId?: string,\n): TTreeViewRecord[] =>\n nodes.reduce<TTreeViewRecord[]>((records, node) => {\n records.push({\n node,\n level,\n parentId,\n });\n\n if (node.children?.length && isExpanded(node.id)) {\n records.push(...flattenNodes(node.children, level + 1, node.id));\n }\n\n return records;\n }, []);\n\nconst visibleNodes = computed(() => flattenNodes(props.nodes));\nconst enabledNodes = computed(() => visibleNodes.value.filter((record) => !record.node.disabled));\n\nconst getInitialFocusedId = () => {\n const selectedId = selectedValues.value.find((value) =>\n visibleNodes.value.some((record) => record.node.id === value && !record.node.disabled),\n );\n\n if (selectedId) {\n return selectedId;\n }\n\n return enabledNodes.value[0]?.node.id ?? '';\n};\n\nconst focusedId = ref(getInitialFocusedId());\n\nconst registerItem = (id: string, element: HTMLElement) => {\n itemRefs.value.set(id, element);\n};\n\nconst unregisterItem = (id: string) => {\n itemRefs.value.delete(id);\n};\n\nconst focusItem = (id: string) => {\n nextTick(() => itemRefs.value.get(id)?.focus());\n};\n\nconst setFocusedId = (id: string, shouldFocus = false) => {\n focusedId.value = id;\n\n if (shouldFocus) {\n focusItem(id);\n }\n};\n\nconst getVisibleRecord = (id: string) =>\n visibleNodes.value.find((record) => record.node.id === id);\n\nconst focusBoundary = (position: 'first' | 'last') => {\n const target =\n position === 'first' ? enabledNodes.value[0] : enabledNodes.value[enabledNodes.value.length - 1];\n\n if (target) {\n setFocusedId(target.node.id, true);\n }\n};\n\nconst focusAdjacent = (direction: 1 | -1) => {\n const currentIndex = enabledNodes.value.findIndex((record) => record.node.id === focusedId.value);\n\n if (currentIndex === -1) {\n focusBoundary(direction === 1 ? 'first' : 'last');\n return;\n }\n\n const nextIndex = currentIndex + direction;\n\n if (nextIndex < 0 || nextIndex >= enabledNodes.value.length) {\n return;\n }\n\n setFocusedId(enabledNodes.value[nextIndex].node.id, true);\n};\n\nconst toggleExpanded = (id: string) => {\n const nextValues = isExpanded(id)\n ? expandedValues.value.filter((value) => value !== id)\n : [...expandedValues.value, id];\n\n updateExpanded(nextValues);\n};\n\nconst toggleSelected = (id: string) => {\n const record = getVisibleRecord(id);\n\n if (!record || record.node.disabled || props.disabled) {\n return;\n }\n\n if (props.selectionMode === 'multiple') {\n const nextValues = isSelected(id)\n ? selectedValues.value.filter((value) => value !== id)\n : [...selectedValues.value, id];\n\n updateSelection(nextValues);\n return;\n }\n\n updateSelection([id]);\n};\n\nconst onItemKeydown = (event: KeyboardEvent, id: string) => {\n const record = getVisibleRecord(id);\n\n if (!record || record.node.disabled || props.disabled) {\n return;\n }\n\n const hasChildren = Boolean(record.node.children?.length);\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n focusAdjacent(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n focusAdjacent(-1);\n break;\n case 'ArrowRight':\n event.preventDefault();\n\n if (hasChildren && !isExpanded(id)) {\n toggleExpanded(id);\n return;\n }\n\n if (hasChildren) {\n const firstChild = visibleNodes.value.find(\n (item) => item.parentId === id && !item.node.disabled,\n );\n\n if (firstChild) {\n setFocusedId(firstChild.node.id, true);\n }\n }\n\n break;\n case 'ArrowLeft':\n event.preventDefault();\n\n if (hasChildren && isExpanded(id)) {\n toggleExpanded(id);\n return;\n }\n\n if (record.parentId) {\n setFocusedId(record.parentId, true);\n }\n\n break;\n case 'Home':\n event.preventDefault();\n focusBoundary('first');\n break;\n case 'End':\n event.preventDefault();\n focusBoundary('last');\n break;\n default:\n if (isActivationKey(event)) {\n event.preventDefault();\n toggleSelected(id);\n }\n break;\n }\n};\n\nwatch(\n () => [visibleNodes.value, props.modelValue] as const,\n () => {\n const focusedRecord = visibleNodes.value.find(\n (record) => record.node.id === focusedId.value && !record.node.disabled,\n );\n\n if (!focusedRecord) {\n focusedId.value = getInitialFocusedId();\n }\n },\n { deep: true, immediate: true },\n);\n\nprovide(treeTreeViewInjectionKey, {\n baseId,\n disabled: computed(() => props.disabled),\n selectionMode: computed(() => props.selectionMode),\n focusedId,\n isExpanded,\n toggleExpanded,\n isSelected,\n toggleSelected,\n setFocusedId,\n onItemKeydown,\n registerItem,\n unregisterItem,\n});\n</script>\n\n<template>\n <div\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <ul\n v-if=\"nodes.length > 0\"\n v-bind=\"treeAttrs\"\n class=\"t-tree-view__root\"\n role=\"tree\"\n :aria-multiselectable=\"selectionMode === 'multiple' || undefined\"\n >\n <TTreeViewItem\n v-for=\"node in nodes\"\n :key=\"node.id\"\n :node=\"node\"\n :level=\"1\"\n />\n </ul>\n\n <div\n v-else\n class=\"t-tree-view__empty\"\n >\n {{ emptyText }}\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { createId, isActivationKey } from '@treeui/utils';\nimport { computed, nextTick, provide, ref, useAttrs, watch } from 'vue';\nimport TTreeViewItem from './TTreeViewItem.vue';\nimport {\n treeTreeViewInjectionKey,\n type TTreeViewNode,\n type TTreeViewRecord,\n type TTreeViewSelectionMode,\n} from './tree-view';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string | string[];\n defaultValue?: string | string[];\n nodes?: TTreeViewNode[];\n selectionMode?: TTreeViewSelectionMode;\n expanded?: string[];\n defaultExpanded?: string[];\n disabled?: boolean;\n emptyText?: string;\n }>(),\n {\n modelValue: undefined,\n defaultValue: undefined,\n nodes: () => [],\n selectionMode: 'single',\n expanded: undefined,\n defaultExpanded: () => [],\n disabled: false,\n emptyText: 'No items available.',\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | string[] | undefined];\n 'update:expanded': [value: string[]];\n 'selection-change': [value: string | string[] | undefined];\n 'expanded-change': [value: string[]];\n}>();\n\nconst attrs = useAttrs();\nconst baseId = createId('t-tree-view');\nconst internalValue = ref<string | string[] | undefined>(props.defaultValue);\nconst internalExpanded = ref<string[]>(props.defaultExpanded);\nconst itemRefs = ref<Map<string, HTMLElement>>(new Map());\n\nconst rootClasses = computed(() => [\n 't-tree-view',\n {\n 'is-disabled': props.disabled,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst treeAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst selectedValues = computed(() => {\n const value = props.modelValue ?? internalValue.value;\n\n if (value === undefined || value === null || value === '') {\n return [] as string[];\n }\n\n return Array.isArray(value) ? value : [value];\n});\n\nconst expandedValues = computed(() => props.expanded ?? internalExpanded.value);\n\nconst updateSelection = (nextValues: string[]) => {\n if (props.selectionMode === 'multiple') {\n if (props.modelValue === undefined) {\n internalValue.value = nextValues;\n }\n\n emit('update:modelValue', nextValues);\n emit('selection-change', nextValues);\n return;\n }\n\n const nextValue = nextValues[0];\n\n if (props.modelValue === undefined) {\n internalValue.value = nextValue;\n }\n\n emit('update:modelValue', nextValue);\n emit('selection-change', nextValue);\n};\n\nconst updateExpanded = (nextValues: string[]) => {\n if (props.expanded === undefined) {\n internalExpanded.value = nextValues;\n }\n\n emit('update:expanded', nextValues);\n emit('expanded-change', nextValues);\n};\n\nconst isSelected = (id: string) => selectedValues.value.includes(id);\nconst isExpanded = (id: string) => expandedValues.value.includes(id);\n\nconst flattenNodes = (\n nodes: TTreeViewNode[],\n level = 1,\n parentId?: string,\n): TTreeViewRecord[] =>\n nodes.reduce<TTreeViewRecord[]>((records, node) => {\n records.push({\n node,\n level,\n parentId,\n });\n\n if (node.children?.length && isExpanded(node.id)) {\n records.push(...flattenNodes(node.children, level + 1, node.id));\n }\n\n return records;\n }, []);\n\nconst visibleNodes = computed(() => flattenNodes(props.nodes));\nconst enabledNodes = computed(() => visibleNodes.value.filter((record) => !record.node.disabled));\n\nconst getInitialFocusedId = () => {\n const selectedId = selectedValues.value.find((value) =>\n visibleNodes.value.some((record) => record.node.id === value && !record.node.disabled),\n );\n\n if (selectedId) {\n return selectedId;\n }\n\n return enabledNodes.value[0]?.node.id ?? '';\n};\n\nconst focusedId = ref(getInitialFocusedId());\n\nconst registerItem = (id: string, element: HTMLElement) => {\n itemRefs.value.set(id, element);\n};\n\nconst unregisterItem = (id: string) => {\n itemRefs.value.delete(id);\n};\n\nconst focusItem = (id: string) => {\n nextTick(() => itemRefs.value.get(id)?.focus());\n};\n\nconst setFocusedId = (id: string, shouldFocus = false) => {\n focusedId.value = id;\n\n if (shouldFocus) {\n focusItem(id);\n }\n};\n\nconst getVisibleRecord = (id: string) =>\n visibleNodes.value.find((record) => record.node.id === id);\n\nconst focusBoundary = (position: 'first' | 'last') => {\n const target =\n position === 'first' ? enabledNodes.value[0] : enabledNodes.value[enabledNodes.value.length - 1];\n\n if (target) {\n setFocusedId(target.node.id, true);\n }\n};\n\nconst focusAdjacent = (direction: 1 | -1) => {\n const currentIndex = enabledNodes.value.findIndex((record) => record.node.id === focusedId.value);\n\n if (currentIndex === -1) {\n focusBoundary(direction === 1 ? 'first' : 'last');\n return;\n }\n\n const nextIndex = currentIndex + direction;\n\n if (nextIndex < 0 || nextIndex >= enabledNodes.value.length) {\n return;\n }\n\n setFocusedId(enabledNodes.value[nextIndex].node.id, true);\n};\n\nconst toggleExpanded = (id: string) => {\n const nextValues = isExpanded(id)\n ? expandedValues.value.filter((value) => value !== id)\n : [...expandedValues.value, id];\n\n updateExpanded(nextValues);\n};\n\nconst toggleSelected = (id: string) => {\n const record = getVisibleRecord(id);\n\n if (!record || record.node.disabled || props.disabled) {\n return;\n }\n\n if (props.selectionMode === 'multiple') {\n const nextValues = isSelected(id)\n ? selectedValues.value.filter((value) => value !== id)\n : [...selectedValues.value, id];\n\n updateSelection(nextValues);\n return;\n }\n\n updateSelection([id]);\n};\n\nconst onItemKeydown = (event: KeyboardEvent, id: string) => {\n const record = getVisibleRecord(id);\n\n if (!record || record.node.disabled || props.disabled) {\n return;\n }\n\n const hasChildren = Boolean(record.node.children?.length);\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n focusAdjacent(1);\n break;\n case 'ArrowUp':\n event.preventDefault();\n focusAdjacent(-1);\n break;\n case 'ArrowRight':\n event.preventDefault();\n\n if (hasChildren && !isExpanded(id)) {\n toggleExpanded(id);\n return;\n }\n\n if (hasChildren) {\n const firstChild = visibleNodes.value.find(\n (item) => item.parentId === id && !item.node.disabled,\n );\n\n if (firstChild) {\n setFocusedId(firstChild.node.id, true);\n }\n }\n\n break;\n case 'ArrowLeft':\n event.preventDefault();\n\n if (hasChildren && isExpanded(id)) {\n toggleExpanded(id);\n return;\n }\n\n if (record.parentId) {\n setFocusedId(record.parentId, true);\n }\n\n break;\n case 'Home':\n event.preventDefault();\n focusBoundary('first');\n break;\n case 'End':\n event.preventDefault();\n focusBoundary('last');\n break;\n default:\n if (isActivationKey(event)) {\n event.preventDefault();\n toggleSelected(id);\n }\n break;\n }\n};\n\nwatch(\n () => [visibleNodes.value, props.modelValue] as const,\n () => {\n const focusedRecord = visibleNodes.value.find(\n (record) => record.node.id === focusedId.value && !record.node.disabled,\n );\n\n if (!focusedRecord) {\n focusedId.value = getInitialFocusedId();\n }\n },\n { deep: true, immediate: true },\n);\n\nprovide(treeTreeViewInjectionKey, {\n baseId,\n disabled: computed(() => props.disabled),\n selectionMode: computed(() => props.selectionMode),\n focusedId,\n isExpanded,\n toggleExpanded,\n isSelected,\n toggleSelected,\n setFocusedId,\n onItemKeydown,\n registerItem,\n unregisterItem,\n});\n</script>\n\n<template>\n <div\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <ul\n v-if=\"nodes.length > 0\"\n v-bind=\"treeAttrs\"\n class=\"t-tree-view__root\"\n role=\"tree\"\n :aria-multiselectable=\"selectionMode === 'multiple' || undefined\"\n >\n <TTreeViewItem\n v-for=\"node in nodes\"\n :key=\"node.id\"\n :node=\"node\"\n :level=\"1\"\n />\n </ul>\n\n <div\n v-else\n class=\"t-tree-view__empty\"\n >\n {{ emptyText }}\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport { computed, ref, useAttrs, watch } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TStepItem {\n label: string;\n value: string;\n description?: string;\n meta?: string;\n status?: TStepStatus;\n disabled?: boolean;\n}\n\nconst _treeStepStatuses = ['complete', 'current', 'upcoming', 'error'] as const;\nconst _treeStepOrientations = ['horizontal', 'vertical'] as const;\n\nexport type TStepStatus = (typeof _treeStepStatuses)[number];\nexport type TStepOrientation = (typeof _treeStepOrientations)[number];\n\nconst CheckIcon = getTreeIcon('check');\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n defaultValue?: string;\n items?: TStepItem[];\n size?: TSize;\n orientation?: TStepOrientation;\n interactive?: boolean;\n }>(),\n {\n modelValue: undefined,\n defaultValue: '',\n items: () => [],\n size: 'md',\n orientation: 'horizontal',\n interactive: false,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n}>();\n\ndefineSlots<{\n item?: (props: {\n item: TStepItem;\n index: number;\n status: TStepStatus;\n current: boolean;\n }) => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst internalValue = ref(props.defaultValue || props.items[0]?.value || '');\n\nconst activeValue = computed(() => props.modelValue ?? internalValue.value);\n\nconst currentIndex = computed(() => {\n const activeIndex = props.items.findIndex((item) => item.value === activeValue.value);\n return activeIndex >= 0 ? activeIndex : 0;\n});\n\nconst rootClasses = computed(() => [\n 't-steps',\n `t-steps--${props.size}`,\n `t-steps--${props.orientation}`,\n {\n 'is-interactive': props.interactive,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst resolveStatus = (item: TStepItem, index: number): TStepStatus => {\n if (item.status) {\n return item.status;\n }\n\n if (index < currentIndex.value) {\n return 'complete';\n }\n\n if (index === currentIndex.value) {\n return 'current';\n }\n\n return 'upcoming';\n};\n\nconst selectStep = (item: TStepItem) => {\n if (!props.interactive || item.disabled) {\n return;\n }\n\n if (props.modelValue === undefined) {\n internalValue.value = item.value;\n }\n\n emit('update:modelValue', item.value);\n};\n\nwatch(\n () => props.items,\n (items) => {\n const hasCurrentItem = items.some((item) => item.value === activeValue.value);\n\n if (!hasCurrentItem && items[0] && props.modelValue === undefined) {\n internalValue.value = items[0].value;\n }\n },\n { deep: true },\n);\n</script>\n\n<template>\n <ol\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <li\n v-for=\"(item, index) in items\"\n :key=\"item.value\"\n class=\"t-steps__item\"\n :class=\"`is-${resolveStatus(item, index)}`\"\n >\n <button\n type=\"button\"\n class=\"t-steps__button\"\n :class=\"{\n 'is-current': resolveStatus(item, index) === 'current',\n 'is-disabled': item.disabled,\n }\"\n :disabled=\"!interactive || item.disabled\"\n :aria-current=\"resolveStatus(item, index) === 'current' ? 'step' : undefined\"\n @click=\"selectStep(item)\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :index=\"index\"\n :status=\"resolveStatus(item, index)\"\n :current=\"resolveStatus(item, index) === 'current'\"\n >\n <span\n class=\"t-steps__indicator\"\n aria-hidden=\"true\"\n >\n <CheckIcon\n v-if=\"resolveStatus(item, index) === 'complete'\"\n v-bind=\"treeIconDefaults\"\n />\n <span v-else-if=\"resolveStatus(item, index) === 'error'\">!</span>\n <span v-else>{{ index + 1 }}</span>\n </span>\n\n <span class=\"t-steps__copy\">\n <span class=\"t-steps__label\">{{ item.label }}</span>\n <span\n v-if=\"item.description\"\n class=\"t-steps__description\"\n >\n {{ item.description }}\n </span>\n </span>\n\n <span\n v-if=\"item.meta\"\n class=\"t-steps__meta\"\n >\n {{ item.meta }}\n </span>\n </slot>\n </button>\n </li>\n </ol>\n</template>\n","<script setup lang=\"ts\">\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport { computed, ref, useAttrs, watch } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TStepItem {\n label: string;\n value: string;\n description?: string;\n meta?: string;\n status?: TStepStatus;\n disabled?: boolean;\n}\n\nconst _treeStepStatuses = ['complete', 'current', 'upcoming', 'error'] as const;\nconst _treeStepOrientations = ['horizontal', 'vertical'] as const;\n\nexport type TStepStatus = (typeof _treeStepStatuses)[number];\nexport type TStepOrientation = (typeof _treeStepOrientations)[number];\n\nconst CheckIcon = getTreeIcon('check');\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n defaultValue?: string;\n items?: TStepItem[];\n size?: TSize;\n orientation?: TStepOrientation;\n interactive?: boolean;\n }>(),\n {\n modelValue: undefined,\n defaultValue: '',\n items: () => [],\n size: 'md',\n orientation: 'horizontal',\n interactive: false,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n}>();\n\ndefineSlots<{\n item?: (props: {\n item: TStepItem;\n index: number;\n status: TStepStatus;\n current: boolean;\n }) => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst internalValue = ref(props.defaultValue || props.items[0]?.value || '');\n\nconst activeValue = computed(() => props.modelValue ?? internalValue.value);\n\nconst currentIndex = computed(() => {\n const activeIndex = props.items.findIndex((item) => item.value === activeValue.value);\n return activeIndex >= 0 ? activeIndex : 0;\n});\n\nconst rootClasses = computed(() => [\n 't-steps',\n `t-steps--${props.size}`,\n `t-steps--${props.orientation}`,\n {\n 'is-interactive': props.interactive,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst resolveStatus = (item: TStepItem, index: number): TStepStatus => {\n if (item.status) {\n return item.status;\n }\n\n if (index < currentIndex.value) {\n return 'complete';\n }\n\n if (index === currentIndex.value) {\n return 'current';\n }\n\n return 'upcoming';\n};\n\nconst selectStep = (item: TStepItem) => {\n if (!props.interactive || item.disabled) {\n return;\n }\n\n if (props.modelValue === undefined) {\n internalValue.value = item.value;\n }\n\n emit('update:modelValue', item.value);\n};\n\nwatch(\n () => props.items,\n (items) => {\n const hasCurrentItem = items.some((item) => item.value === activeValue.value);\n\n if (!hasCurrentItem && items[0] && props.modelValue === undefined) {\n internalValue.value = items[0].value;\n }\n },\n { deep: true },\n);\n</script>\n\n<template>\n <ol\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <li\n v-for=\"(item, index) in items\"\n :key=\"item.value\"\n class=\"t-steps__item\"\n :class=\"`is-${resolveStatus(item, index)}`\"\n >\n <button\n type=\"button\"\n class=\"t-steps__button\"\n :class=\"{\n 'is-current': resolveStatus(item, index) === 'current',\n 'is-disabled': item.disabled,\n }\"\n :disabled=\"!interactive || item.disabled\"\n :aria-current=\"resolveStatus(item, index) === 'current' ? 'step' : undefined\"\n @click=\"selectStep(item)\"\n >\n <slot\n name=\"item\"\n :item=\"item\"\n :index=\"index\"\n :status=\"resolveStatus(item, index)\"\n :current=\"resolveStatus(item, index) === 'current'\"\n >\n <span\n class=\"t-steps__indicator\"\n aria-hidden=\"true\"\n >\n <CheckIcon\n v-if=\"resolveStatus(item, index) === 'complete'\"\n v-bind=\"treeIconDefaults\"\n />\n <span v-else-if=\"resolveStatus(item, index) === 'error'\">!</span>\n <span v-else>{{ index + 1 }}</span>\n </span>\n\n <span class=\"t-steps__copy\">\n <span class=\"t-steps__label\">{{ item.label }}</span>\n <span\n v-if=\"item.description\"\n class=\"t-steps__description\"\n >\n {{ item.description }}\n </span>\n </span>\n\n <span\n v-if=\"item.meta\"\n class=\"t-steps__meta\"\n >\n {{ item.meta }}\n </span>\n </slot>\n </button>\n </li>\n </ol>\n</template>\n","<script setup lang=\"ts\">\nimport { createId, getNextEnabledIndex, isActivationKey } from '@treeui/utils';\nimport { computed, nextTick, ref, useAttrs, watch, type ComponentPublicInstance } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TToggleGroupOption {\n label: string;\n value: string;\n disabled?: boolean;\n}\n\nconst _treeToggleGroupSelectionModes = ['single', 'multiple'] as const;\nconst _treeToggleGroupVariants = ['outline', 'soft', 'solid'] as const;\n\nexport type TToggleGroupSelectionMode = (typeof _treeToggleGroupSelectionModes)[number];\nexport type TToggleGroupVariant = (typeof _treeToggleGroupVariants)[number];\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string | string[];\n options?: TToggleGroupOption[];\n selectionMode?: TToggleGroupSelectionMode;\n size?: TSize;\n variant?: TToggleGroupVariant;\n disabled?: boolean;\n }>(),\n {\n modelValue: undefined,\n options: () => [],\n selectionMode: 'single',\n size: 'md',\n variant: 'outline',\n disabled: false,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | string[] | undefined];\n}>();\n\ndefineSlots<{\n option?: (props: { option: TToggleGroupOption; selected: boolean }) => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst baseId = createId('t-toggle-group');\nconst buttonRefs = ref<Map<string, HTMLButtonElement>>(new Map());\n\nconst normalizedValues = computed(() =>\n props.selectionMode === 'multiple'\n ? Array.isArray(props.modelValue)\n ? props.modelValue\n : []\n : typeof props.modelValue === 'string' && props.modelValue\n ? [props.modelValue]\n : [],\n);\n\nconst getInitialFocusedIndex = () => {\n const selectedIndex = props.options.findIndex((option) =>\n normalizedValues.value.includes(option.value) && !option.disabled,\n );\n\n if (selectedIndex >= 0) {\n return selectedIndex;\n }\n\n return props.options.findIndex((option) => !option.disabled);\n};\n\nconst focusedIndex = ref(getInitialFocusedIndex());\n\nconst rootClasses = computed(() => [\n 't-toggle-group',\n `t-toggle-group--${props.size}`,\n `t-toggle-group--${props.variant}`,\n `t-toggle-group--${props.selectionMode}`,\n {\n 'is-disabled': props.disabled,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst isSelected = (value: string) => normalizedValues.value.includes(value);\n\nconst setButtonRef = (element: Element | ComponentPublicInstance | null, value: string) => {\n const resolvedElement =\n element instanceof HTMLButtonElement\n ? element\n : element && '$el' in element && element.$el instanceof HTMLButtonElement\n ? element.$el\n : null;\n\n if (resolvedElement instanceof HTMLButtonElement) {\n buttonRefs.value.set(value, resolvedElement);\n } else {\n buttonRefs.value.delete(value);\n }\n};\n\nconst focusOption = (index: number) => {\n const option = props.options[index];\n\n if (!option) {\n return;\n }\n\n focusedIndex.value = index;\n nextTick(() => buttonRefs.value.get(option.value)?.focus());\n};\n\nconst selectValue = (value: string) => {\n const option = props.options.find((item) => item.value === value);\n\n if (!option || option.disabled || props.disabled) {\n return;\n }\n\n if (props.selectionMode === 'multiple') {\n const nextValues = isSelected(value)\n ? normalizedValues.value.filter((item) => item !== value)\n : [...normalizedValues.value, value];\n\n emit('update:modelValue', nextValues);\n return;\n }\n\n emit('update:modelValue', value);\n};\n\nconst onOptionKeydown = (event: KeyboardEvent, index: number) => {\n if (props.disabled) {\n return;\n }\n\n if (event.key === 'Home') {\n event.preventDefault();\n const firstIndex = props.options.findIndex((option) => !option.disabled);\n\n if (firstIndex >= 0) {\n focusOption(firstIndex);\n\n if (props.selectionMode === 'single') {\n selectValue(props.options[firstIndex].value);\n }\n }\n\n return;\n }\n\n if (event.key === 'End') {\n event.preventDefault();\n const lastIndex = [...props.options].reverse().findIndex((option) => !option.disabled);\n\n if (lastIndex >= 0) {\n const resolvedIndex = props.options.length - 1 - lastIndex;\n focusOption(resolvedIndex);\n\n if (props.selectionMode === 'single') {\n selectValue(props.options[resolvedIndex].value);\n }\n }\n\n return;\n }\n\n if (\n event.key === 'ArrowRight' ||\n event.key === 'ArrowDown' ||\n event.key === 'ArrowLeft' ||\n event.key === 'ArrowUp'\n ) {\n event.preventDefault();\n const direction = event.key === 'ArrowRight' || event.key === 'ArrowDown' ? 1 : -1;\n const nextIndex = getNextEnabledIndex(index, props.options, direction as 1 | -1);\n\n if (nextIndex >= 0) {\n focusOption(nextIndex);\n\n if (props.selectionMode === 'single') {\n selectValue(props.options[nextIndex].value);\n }\n }\n\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectValue(props.options[index].value);\n }\n};\n\nconst getTabIndex = (index: number) => (focusedIndex.value === index ? 0 : -1);\n\nwatch(\n () => [props.modelValue, props.options] as const,\n () => {\n const nextIndex = getInitialFocusedIndex();\n focusedIndex.value = nextIndex >= 0 ? nextIndex : -1;\n },\n { deep: true },\n);\n</script>\n\n<template>\n <div\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :role=\"selectionMode === 'single' ? 'radiogroup' : 'group'\"\n >\n <button\n v-for=\"(option, index) in options\"\n :id=\"`${baseId}-${option.value}`\"\n :ref=\"(element) => setButtonRef(element, option.value)\"\n :key=\"option.value\"\n type=\"button\"\n class=\"t-toggle-group__item\"\n :class=\"{\n 'is-selected': isSelected(option.value),\n 'is-disabled': disabled || option.disabled,\n }\"\n :role=\"selectionMode === 'single' ? 'radio' : undefined\"\n :aria-checked=\"selectionMode === 'single' ? isSelected(option.value) : undefined\"\n :aria-pressed=\"selectionMode === 'multiple' ? isSelected(option.value) : undefined\"\n :tabindex=\"option.disabled || disabled ? -1 : getTabIndex(index)\"\n :disabled=\"disabled || option.disabled\"\n @click=\"selectValue(option.value)\"\n @keydown=\"onOptionKeydown($event, index)\"\n @focus=\"focusedIndex = index\"\n >\n <slot\n name=\"option\"\n :option=\"option\"\n :selected=\"isSelected(option.value)\"\n >\n {{ option.label }}\n </slot>\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { createId, getNextEnabledIndex, isActivationKey } from '@treeui/utils';\nimport { computed, nextTick, ref, useAttrs, watch, type ComponentPublicInstance } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport interface TToggleGroupOption {\n label: string;\n value: string;\n disabled?: boolean;\n}\n\nconst _treeToggleGroupSelectionModes = ['single', 'multiple'] as const;\nconst _treeToggleGroupVariants = ['outline', 'soft', 'solid'] as const;\n\nexport type TToggleGroupSelectionMode = (typeof _treeToggleGroupSelectionModes)[number];\nexport type TToggleGroupVariant = (typeof _treeToggleGroupVariants)[number];\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string | string[];\n options?: TToggleGroupOption[];\n selectionMode?: TToggleGroupSelectionMode;\n size?: TSize;\n variant?: TToggleGroupVariant;\n disabled?: boolean;\n }>(),\n {\n modelValue: undefined,\n options: () => [],\n selectionMode: 'single',\n size: 'md',\n variant: 'outline',\n disabled: false,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string | string[] | undefined];\n}>();\n\ndefineSlots<{\n option?: (props: { option: TToggleGroupOption; selected: boolean }) => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst baseId = createId('t-toggle-group');\nconst buttonRefs = ref<Map<string, HTMLButtonElement>>(new Map());\n\nconst normalizedValues = computed(() =>\n props.selectionMode === 'multiple'\n ? Array.isArray(props.modelValue)\n ? props.modelValue\n : []\n : typeof props.modelValue === 'string' && props.modelValue\n ? [props.modelValue]\n : [],\n);\n\nconst getInitialFocusedIndex = () => {\n const selectedIndex = props.options.findIndex((option) =>\n normalizedValues.value.includes(option.value) && !option.disabled,\n );\n\n if (selectedIndex >= 0) {\n return selectedIndex;\n }\n\n return props.options.findIndex((option) => !option.disabled);\n};\n\nconst focusedIndex = ref(getInitialFocusedIndex());\n\nconst rootClasses = computed(() => [\n 't-toggle-group',\n `t-toggle-group--${props.size}`,\n `t-toggle-group--${props.variant}`,\n `t-toggle-group--${props.selectionMode}`,\n {\n 'is-disabled': props.disabled,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst isSelected = (value: string) => normalizedValues.value.includes(value);\n\nconst setButtonRef = (element: Element | ComponentPublicInstance | null, value: string) => {\n const resolvedElement =\n element instanceof HTMLButtonElement\n ? element\n : element && '$el' in element && element.$el instanceof HTMLButtonElement\n ? element.$el\n : null;\n\n if (resolvedElement instanceof HTMLButtonElement) {\n buttonRefs.value.set(value, resolvedElement);\n } else {\n buttonRefs.value.delete(value);\n }\n};\n\nconst focusOption = (index: number) => {\n const option = props.options[index];\n\n if (!option) {\n return;\n }\n\n focusedIndex.value = index;\n nextTick(() => buttonRefs.value.get(option.value)?.focus());\n};\n\nconst selectValue = (value: string) => {\n const option = props.options.find((item) => item.value === value);\n\n if (!option || option.disabled || props.disabled) {\n return;\n }\n\n if (props.selectionMode === 'multiple') {\n const nextValues = isSelected(value)\n ? normalizedValues.value.filter((item) => item !== value)\n : [...normalizedValues.value, value];\n\n emit('update:modelValue', nextValues);\n return;\n }\n\n emit('update:modelValue', value);\n};\n\nconst onOptionKeydown = (event: KeyboardEvent, index: number) => {\n if (props.disabled) {\n return;\n }\n\n if (event.key === 'Home') {\n event.preventDefault();\n const firstIndex = props.options.findIndex((option) => !option.disabled);\n\n if (firstIndex >= 0) {\n focusOption(firstIndex);\n\n if (props.selectionMode === 'single') {\n selectValue(props.options[firstIndex].value);\n }\n }\n\n return;\n }\n\n if (event.key === 'End') {\n event.preventDefault();\n const lastIndex = [...props.options].reverse().findIndex((option) => !option.disabled);\n\n if (lastIndex >= 0) {\n const resolvedIndex = props.options.length - 1 - lastIndex;\n focusOption(resolvedIndex);\n\n if (props.selectionMode === 'single') {\n selectValue(props.options[resolvedIndex].value);\n }\n }\n\n return;\n }\n\n if (\n event.key === 'ArrowRight' ||\n event.key === 'ArrowDown' ||\n event.key === 'ArrowLeft' ||\n event.key === 'ArrowUp'\n ) {\n event.preventDefault();\n const direction = event.key === 'ArrowRight' || event.key === 'ArrowDown' ? 1 : -1;\n const nextIndex = getNextEnabledIndex(index, props.options, direction as 1 | -1);\n\n if (nextIndex >= 0) {\n focusOption(nextIndex);\n\n if (props.selectionMode === 'single') {\n selectValue(props.options[nextIndex].value);\n }\n }\n\n return;\n }\n\n if (isActivationKey(event)) {\n event.preventDefault();\n selectValue(props.options[index].value);\n }\n};\n\nconst getTabIndex = (index: number) => (focusedIndex.value === index ? 0 : -1);\n\nwatch(\n () => [props.modelValue, props.options] as const,\n () => {\n const nextIndex = getInitialFocusedIndex();\n focusedIndex.value = nextIndex >= 0 ? nextIndex : -1;\n },\n { deep: true },\n);\n</script>\n\n<template>\n <div\n v-bind=\"rootAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :role=\"selectionMode === 'single' ? 'radiogroup' : 'group'\"\n >\n <button\n v-for=\"(option, index) in options\"\n :id=\"`${baseId}-${option.value}`\"\n :ref=\"(element) => setButtonRef(element, option.value)\"\n :key=\"option.value\"\n type=\"button\"\n class=\"t-toggle-group__item\"\n :class=\"{\n 'is-selected': isSelected(option.value),\n 'is-disabled': disabled || option.disabled,\n }\"\n :role=\"selectionMode === 'single' ? 'radio' : undefined\"\n :aria-checked=\"selectionMode === 'single' ? isSelected(option.value) : undefined\"\n :aria-pressed=\"selectionMode === 'multiple' ? isSelected(option.value) : undefined\"\n :tabindex=\"option.disabled || disabled ? -1 : getTabIndex(index)\"\n :disabled=\"disabled || option.disabled\"\n @click=\"selectValue(option.value)\"\n @keydown=\"onOptionKeydown($event, index)\"\n @focus=\"focusedIndex = index\"\n >\n <slot\n name=\"option\"\n :option=\"option\"\n :selected=\"isSelected(option.value)\"\n >\n {{ option.label }}\n </slot>\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs, ref, watch, nextTick } from 'vue';\nimport type { TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n placeholder?: string;\n rows?: number;\n autoGrow?: boolean;\n }>(),\n {\n modelValue: '',\n size: 'md',\n disabled: false,\n loading: false,\n invalid: false,\n placeholder: '',\n rows: 3,\n autoGrow: false,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n}>();\n\nconst attrs = useAttrs();\nconst textareaRef = ref<HTMLTextAreaElement | null>(null);\n\nconst rootClasses = computed(() => [\n 't-textarea',\n `t-textarea--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst textareaAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst stringValue = computed(() => `${props.modelValue ?? ''}`);\n\nconst onInput = (event: Event) => {\n emit('update:modelValue', (event.target as HTMLTextAreaElement).value);\n};\n\nconst adjustHeight = () => {\n const el = textareaRef.value;\n if (!el || !props.autoGrow) return;\n el.style.height = 'auto';\n el.style.height = `${el.scrollHeight}px`;\n};\n\nwatch(\n () => props.modelValue,\n async () => {\n if (!props.autoGrow) return;\n await nextTick();\n adjustHeight();\n },\n);\n</script>\n\n<template>\n <label\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <textarea\n ref=\"textareaRef\"\n v-bind=\"textareaAttrs\"\n class=\"t-textarea__field\"\n :value=\"stringValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :rows=\"rows\"\n :aria-invalid=\"invalid || undefined\"\n @input=\"onInput\"\n />\n <TSpinner\n v-if=\"loading\"\n size=\"sm\"\n label=\"Loading\"\n />\n </label>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs, ref, watch, nextTick } from 'vue';\nimport type { TSize } from '../types/contracts';\nimport TSpinner from './TSpinner.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n size?: TSize;\n disabled?: boolean;\n loading?: boolean;\n invalid?: boolean;\n placeholder?: string;\n rows?: number;\n autoGrow?: boolean;\n }>(),\n {\n modelValue: '',\n size: 'md',\n disabled: false,\n loading: false,\n invalid: false,\n placeholder: '',\n rows: 3,\n autoGrow: false,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n}>();\n\nconst attrs = useAttrs();\nconst textareaRef = ref<HTMLTextAreaElement | null>(null);\n\nconst rootClasses = computed(() => [\n 't-textarea',\n `t-textarea--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n 'is-loading': props.loading,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst textareaAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst stringValue = computed(() => `${props.modelValue ?? ''}`);\n\nconst onInput = (event: Event) => {\n emit('update:modelValue', (event.target as HTMLTextAreaElement).value);\n};\n\nconst adjustHeight = () => {\n const el = textareaRef.value;\n if (!el || !props.autoGrow) return;\n el.style.height = 'auto';\n el.style.height = `${el.scrollHeight}px`;\n};\n\nwatch(\n () => props.modelValue,\n async () => {\n if (!props.autoGrow) return;\n await nextTick();\n adjustHeight();\n },\n);\n</script>\n\n<template>\n <label\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <textarea\n ref=\"textareaRef\"\n v-bind=\"textareaAttrs\"\n class=\"t-textarea__field\"\n :value=\"stringValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :rows=\"rows\"\n :aria-invalid=\"invalid || undefined\"\n @input=\"onInput\"\n />\n <TSpinner\n v-if=\"loading\"\n size=\"sm\"\n label=\"Loading\"\n />\n </label>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\nconst props = withDefaults(\n defineProps<{\n width?: string;\n height?: string;\n animation?: 'pulse' | 'wave' | 'none';\n }>(),\n {\n width: '100%',\n height: undefined,\n animation: 'pulse',\n },\n);\n\nconst classes = computed(() => [\n 't-skeleton',\n props.animation !== 'none' ? `t-skeleton--${props.animation}` : '',\n]);\n\nconst style = computed(() => ({\n width: props.width,\n height: props.height,\n}));\n</script>\n\n<template>\n <span\n :class=\"classes\"\n :style=\"style\"\n aria-hidden=\"true\"\n >\n <slot />\n </span>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\nconst props = withDefaults(\n defineProps<{\n width?: string;\n height?: string;\n animation?: 'pulse' | 'wave' | 'none';\n }>(),\n {\n width: '100%',\n height: undefined,\n animation: 'pulse',\n },\n);\n\nconst classes = computed(() => [\n 't-skeleton',\n props.animation !== 'none' ? `t-skeleton--${props.animation}` : '',\n]);\n\nconst style = computed(() => ({\n width: props.width,\n height: props.height,\n}));\n</script>\n\n<template>\n <span\n :class=\"classes\"\n :style=\"style\"\n aria-hidden=\"true\"\n >\n <slot />\n </span>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs, useSlots } from 'vue';\nimport TSkeleton from './TSkeleton.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst _treeStatTones = ['neutral', 'success', 'warning', 'danger', 'info'] as const;\nconst _treeStatTrendDirections = ['up', 'down', 'neutral'] as const;\n\nexport type TStatTone = (typeof _treeStatTones)[number];\nexport type TStatTrendDirection = (typeof _treeStatTrendDirections)[number];\n\nconst props = withDefaults(\n defineProps<{\n label?: string;\n value?: string | number;\n trend?: string;\n meta?: string;\n tone?: TStatTone;\n trendDirection?: TStatTrendDirection;\n loading?: boolean;\n }>(),\n {\n label: '',\n value: '',\n trend: '',\n meta: '',\n tone: 'neutral',\n trendDirection: 'neutral',\n loading: false,\n },\n);\n\ndefineSlots<{\n icon?: () => unknown;\n label?: () => unknown;\n value?: () => unknown;\n trend?: () => unknown;\n meta?: () => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst slots = useSlots();\n\nconst rootClasses = computed(() => [\n 't-stat',\n `t-stat--${props.tone}`,\n {\n 'has-icon': Boolean(slots.icon) && !props.loading,\n 'is-loading': props.loading,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst loadingAttrs = computed(() => ({\n ...rootAttrs.value,\n 'aria-busy': props.loading || undefined,\n}));\n\nconst hasValue = computed(() => props.value !== '' && props.value !== null && props.value !== undefined);\nconst hasTrend = computed(() => Boolean(slots.trend || props.trend));\nconst hasMeta = computed(() => Boolean(slots.meta || props.meta));\nconst hasLabel = computed(() => Boolean(slots.label || props.label));\n\nconst trendSymbol = computed(() => {\n if (props.trendDirection === 'up') {\n return '+';\n }\n\n if (props.trendDirection === 'down') {\n return '-';\n }\n\n return '•';\n});\n</script>\n\n<template>\n <div\n v-bind=\"loadingAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <template v-if=\"loading\">\n <div class=\"t-stat__loading\">\n <TSkeleton class=\"t-stat__loading-label\" />\n <TSkeleton class=\"t-stat__loading-value\" />\n <TSkeleton class=\"t-stat__loading-trend\" />\n </div>\n </template>\n <template v-else>\n <div\n v-if=\"$slots.icon\"\n class=\"t-stat__icon\"\n >\n <slot name=\"icon\" />\n </div>\n\n <div class=\"t-stat__body\">\n <div\n v-if=\"hasLabel || hasMeta\"\n class=\"t-stat__topline\"\n >\n <p\n v-if=\"hasLabel\"\n class=\"t-stat__label\"\n >\n <slot name=\"label\">\n {{ label }}\n </slot>\n </p>\n\n <p\n v-if=\"hasMeta\"\n class=\"t-stat__meta\"\n >\n <slot name=\"meta\">\n {{ meta }}\n </slot>\n </p>\n </div>\n\n <div class=\"t-stat__content\">\n <p\n v-if=\"hasValue || $slots.value\"\n class=\"t-stat__value\"\n >\n <slot name=\"value\">\n {{ value }}\n </slot>\n </p>\n\n <p\n v-if=\"hasTrend\"\n class=\"t-stat__trend\"\n >\n <slot name=\"trend\">\n <span\n class=\"t-stat__trend-indicator\"\n aria-hidden=\"true\"\n >\n {{ trendSymbol }}\n </span>\n <span>{{ trend }}</span>\n </slot>\n </p>\n </div>\n </div>\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs, useSlots } from 'vue';\nimport TSkeleton from './TSkeleton.vue';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst _treeStatTones = ['neutral', 'success', 'warning', 'danger', 'info'] as const;\nconst _treeStatTrendDirections = ['up', 'down', 'neutral'] as const;\n\nexport type TStatTone = (typeof _treeStatTones)[number];\nexport type TStatTrendDirection = (typeof _treeStatTrendDirections)[number];\n\nconst props = withDefaults(\n defineProps<{\n label?: string;\n value?: string | number;\n trend?: string;\n meta?: string;\n tone?: TStatTone;\n trendDirection?: TStatTrendDirection;\n loading?: boolean;\n }>(),\n {\n label: '',\n value: '',\n trend: '',\n meta: '',\n tone: 'neutral',\n trendDirection: 'neutral',\n loading: false,\n },\n);\n\ndefineSlots<{\n icon?: () => unknown;\n label?: () => unknown;\n value?: () => unknown;\n trend?: () => unknown;\n meta?: () => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst slots = useSlots();\n\nconst rootClasses = computed(() => [\n 't-stat',\n `t-stat--${props.tone}`,\n {\n 'has-icon': Boolean(slots.icon) && !props.loading,\n 'is-loading': props.loading,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst loadingAttrs = computed(() => ({\n ...rootAttrs.value,\n 'aria-busy': props.loading || undefined,\n}));\n\nconst hasValue = computed(() => props.value !== '' && props.value !== null && props.value !== undefined);\nconst hasTrend = computed(() => Boolean(slots.trend || props.trend));\nconst hasMeta = computed(() => Boolean(slots.meta || props.meta));\nconst hasLabel = computed(() => Boolean(slots.label || props.label));\n\nconst trendSymbol = computed(() => {\n if (props.trendDirection === 'up') {\n return '+';\n }\n\n if (props.trendDirection === 'down') {\n return '-';\n }\n\n return '•';\n});\n</script>\n\n<template>\n <div\n v-bind=\"loadingAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <template v-if=\"loading\">\n <div class=\"t-stat__loading\">\n <TSkeleton class=\"t-stat__loading-label\" />\n <TSkeleton class=\"t-stat__loading-value\" />\n <TSkeleton class=\"t-stat__loading-trend\" />\n </div>\n </template>\n <template v-else>\n <div\n v-if=\"$slots.icon\"\n class=\"t-stat__icon\"\n >\n <slot name=\"icon\" />\n </div>\n\n <div class=\"t-stat__body\">\n <div\n v-if=\"hasLabel || hasMeta\"\n class=\"t-stat__topline\"\n >\n <p\n v-if=\"hasLabel\"\n class=\"t-stat__label\"\n >\n <slot name=\"label\">\n {{ label }}\n </slot>\n </p>\n\n <p\n v-if=\"hasMeta\"\n class=\"t-stat__meta\"\n >\n <slot name=\"meta\">\n {{ meta }}\n </slot>\n </p>\n </div>\n\n <div class=\"t-stat__content\">\n <p\n v-if=\"hasValue || $slots.value\"\n class=\"t-stat__value\"\n >\n <slot name=\"value\">\n {{ value }}\n </slot>\n </p>\n\n <p\n v-if=\"hasTrend\"\n class=\"t-stat__trend\"\n >\n <slot name=\"trend\">\n <span\n class=\"t-stat__trend-indicator\"\n aria-hidden=\"true\"\n >\n {{ trendSymbol }}\n </span>\n <span>{{ trend }}</span>\n </slot>\n </p>\n </div>\n </div>\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: boolean;\n size?: TSize;\n disabled?: boolean;\n invalid?: boolean;\n }>(),\n {\n modelValue: false,\n size: 'md',\n disabled: false,\n invalid: false,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: boolean];\n}>();\n\nconst attrs = useAttrs();\n\nconst rootClasses = computed(() => [\n 't-switch',\n `t-switch--${props.size}`,\n {\n 'is-checked': props.modelValue,\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst inputAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst onChange = () => {\n emit('update:modelValue', !props.modelValue);\n};\n</script>\n\n<template>\n <label\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <input\n v-bind=\"inputAttrs\"\n type=\"checkbox\"\n role=\"switch\"\n class=\"t-switch__input\"\n :checked=\"modelValue\"\n :disabled=\"disabled\"\n :aria-checked=\"modelValue\"\n :aria-invalid=\"invalid || undefined\"\n @change=\"onChange\"\n >\n <span\n class=\"t-switch__track\"\n aria-hidden=\"true\"\n >\n <span class=\"t-switch__thumb\" />\n </span>\n <span\n v-if=\"$slots.default\"\n class=\"t-switch__label\"\n >\n <slot />\n </span>\n </label>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: boolean;\n size?: TSize;\n disabled?: boolean;\n invalid?: boolean;\n }>(),\n {\n modelValue: false,\n size: 'md',\n disabled: false,\n invalid: false,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: boolean];\n}>();\n\nconst attrs = useAttrs();\n\nconst rootClasses = computed(() => [\n 't-switch',\n `t-switch--${props.size}`,\n {\n 'is-checked': props.modelValue,\n 'is-disabled': props.disabled,\n 'is-invalid': props.invalid,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst inputAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst onChange = () => {\n emit('update:modelValue', !props.modelValue);\n};\n</script>\n\n<template>\n <label\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <input\n v-bind=\"inputAttrs\"\n type=\"checkbox\"\n role=\"switch\"\n class=\"t-switch__input\"\n :checked=\"modelValue\"\n :disabled=\"disabled\"\n :aria-checked=\"modelValue\"\n :aria-invalid=\"invalid || undefined\"\n @change=\"onChange\"\n >\n <span\n class=\"t-switch__track\"\n aria-hidden=\"true\"\n >\n <span class=\"t-switch__thumb\" />\n </span>\n <span\n v-if=\"$slots.default\"\n class=\"t-switch__label\"\n >\n <slot />\n </span>\n </label>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, toRef, useAttrs } from 'vue';\nimport { createId } from '@treeui/utils';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TTooltipSide } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n open?: boolean;\n defaultOpen?: boolean;\n disabled?: boolean;\n content?: string;\n side?: TTooltipSide;\n delay?: number;\n id?: string;\n }>(),\n {\n defaultOpen: false,\n disabled: false,\n content: '',\n side: 'top',\n delay: 80,\n id: undefined,\n },\n);\n\nconst emit = defineEmits<{\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\nconst attrs = useAttrs();\nconst contentId = props.id ?? createId('t-tooltip');\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\nconst rootClasses = computed(() => ['t-tooltip', attrs.class]);\nconst rootStyle = computed(() => attrs.style);\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nlet openTimer: ReturnType<typeof setTimeout> | undefined;\n\nconst clearOpenTimer = () => {\n if (openTimer) {\n clearTimeout(openTimer);\n openTimer = undefined;\n }\n};\n\nconst show = (immediate = false) => {\n if (props.disabled) {\n return;\n }\n\n clearOpenTimer();\n\n if (immediate) {\n setValue(true);\n return;\n }\n\n openTimer = setTimeout(() => {\n setValue(true);\n }, props.delay);\n};\n\nconst showOnFocus = () => {\n show(true);\n};\n\nconst showOnPointer = () => {\n show();\n};\n\nconst hide = () => {\n clearOpenTimer();\n setValue(false);\n};\n\nconst tooltipClasses = computed(() => [\n 't-tooltip__content',\n `t-tooltip__content--${props.side}`,\n]);\n\nonBeforeUnmount(clearOpenTimer);\n</script>\n\n<template>\n <span\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n @mouseenter=\"showOnPointer\"\n @mouseleave=\"hide\"\n @focus.capture=\"showOnFocus\"\n @blur.capture=\"hide\"\n >\n <span\n class=\"t-tooltip__trigger\"\n :aria-describedby=\"isOpen ? contentId : undefined\"\n v-bind=\"triggerAttrs\"\n >\n <slot name=\"trigger\">\n <slot />\n </slot>\n </span>\n <transition name=\"t-fade\">\n <span\n v-if=\"isOpen && !disabled\"\n :id=\"contentId\"\n role=\"tooltip\"\n :class=\"tooltipClasses\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <slot name=\"content\">\n {{ content }}\n </slot>\n </span>\n </transition>\n </span>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, toRef, useAttrs } from 'vue';\nimport { createId } from '@treeui/utils';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TTooltipSide } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n open?: boolean;\n defaultOpen?: boolean;\n disabled?: boolean;\n content?: string;\n side?: TTooltipSide;\n delay?: number;\n id?: string;\n }>(),\n {\n defaultOpen: false,\n disabled: false,\n content: '',\n side: 'top',\n delay: 80,\n id: undefined,\n },\n);\n\nconst emit = defineEmits<{\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\nconst attrs = useAttrs();\nconst contentId = props.id ?? createId('t-tooltip');\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\nconst rootClasses = computed(() => ['t-tooltip', attrs.class]);\nconst rootStyle = computed(() => attrs.style);\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nlet openTimer: ReturnType<typeof setTimeout> | undefined;\n\nconst clearOpenTimer = () => {\n if (openTimer) {\n clearTimeout(openTimer);\n openTimer = undefined;\n }\n};\n\nconst show = (immediate = false) => {\n if (props.disabled) {\n return;\n }\n\n clearOpenTimer();\n\n if (immediate) {\n setValue(true);\n return;\n }\n\n openTimer = setTimeout(() => {\n setValue(true);\n }, props.delay);\n};\n\nconst showOnFocus = () => {\n show(true);\n};\n\nconst showOnPointer = () => {\n show();\n};\n\nconst hide = () => {\n clearOpenTimer();\n setValue(false);\n};\n\nconst tooltipClasses = computed(() => [\n 't-tooltip__content',\n `t-tooltip__content--${props.side}`,\n]);\n\nonBeforeUnmount(clearOpenTimer);\n</script>\n\n<template>\n <span\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n @mouseenter=\"showOnPointer\"\n @mouseleave=\"hide\"\n @focus.capture=\"showOnFocus\"\n @blur.capture=\"hide\"\n >\n <span\n class=\"t-tooltip__trigger\"\n :aria-describedby=\"isOpen ? contentId : undefined\"\n v-bind=\"triggerAttrs\"\n >\n <slot name=\"trigger\">\n <slot />\n </slot>\n </span>\n <transition name=\"t-fade\">\n <span\n v-if=\"isOpen && !disabled\"\n :id=\"contentId\"\n role=\"tooltip\"\n :class=\"tooltipClasses\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <slot name=\"content\">\n {{ content }}\n </slot>\n </span>\n </transition>\n </span>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n label?: string;\n htmlFor?: string;\n error?: string;\n hint?: string;\n required?: boolean;\n disabled?: boolean;\n size?: TSize;\n }>(),\n {\n label: undefined,\n htmlFor: undefined,\n error: undefined,\n hint: undefined,\n required: false,\n disabled: false,\n size: 'md',\n },\n);\n\nconst attrs = useAttrs();\n\nconst hasError = computed(() => !!props.error || !!slots.error);\n\nconst slots = defineSlots<{\n default?: (props: Record<string, never>) => unknown;\n label?: (props: Record<string, never>) => unknown;\n error?: (props: Record<string, never>) => unknown;\n hint?: (props: Record<string, never>) => unknown;\n}>();\n\nconst rootClasses = computed(() => [\n 't-form-field',\n `t-form-field--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': hasError.value,\n 'is-required': props.required,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst fieldAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n</script>\n\n<template>\n <div\n v-bind=\"fieldAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <label\n v-if=\"label || $slots.label\"\n class=\"t-form-field__label\"\n :for=\"htmlFor\"\n >\n <slot name=\"label\">{{ label }}</slot>\n <span\n v-if=\"required\"\n class=\"t-form-field__required\"\n aria-hidden=\"true\"\n >*</span>\n </label>\n\n <div class=\"t-form-field__control\">\n <slot />\n </div>\n\n <p\n v-if=\"hasError\"\n class=\"t-form-field__error\"\n role=\"alert\"\n >\n <slot name=\"error\">\n {{ error }}\n </slot>\n </p>\n\n <p\n v-else-if=\"hint || $slots.hint\"\n class=\"t-form-field__hint\"\n >\n <slot name=\"hint\">\n {{ hint }}\n </slot>\n </p>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n label?: string;\n htmlFor?: string;\n error?: string;\n hint?: string;\n required?: boolean;\n disabled?: boolean;\n size?: TSize;\n }>(),\n {\n label: undefined,\n htmlFor: undefined,\n error: undefined,\n hint: undefined,\n required: false,\n disabled: false,\n size: 'md',\n },\n);\n\nconst attrs = useAttrs();\n\nconst hasError = computed(() => !!props.error || !!slots.error);\n\nconst slots = defineSlots<{\n default?: (props: Record<string, never>) => unknown;\n label?: (props: Record<string, never>) => unknown;\n error?: (props: Record<string, never>) => unknown;\n hint?: (props: Record<string, never>) => unknown;\n}>();\n\nconst rootClasses = computed(() => [\n 't-form-field',\n `t-form-field--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-invalid': hasError.value,\n 'is-required': props.required,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst fieldAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n</script>\n\n<template>\n <div\n v-bind=\"fieldAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <label\n v-if=\"label || $slots.label\"\n class=\"t-form-field__label\"\n :for=\"htmlFor\"\n >\n <slot name=\"label\">{{ label }}</slot>\n <span\n v-if=\"required\"\n class=\"t-form-field__required\"\n aria-hidden=\"true\"\n >*</span>\n </label>\n\n <div class=\"t-form-field__control\">\n <slot />\n </div>\n\n <p\n v-if=\"hasError\"\n class=\"t-form-field__error\"\n role=\"alert\"\n >\n <slot name=\"error\">\n {{ error }}\n </slot>\n </p>\n\n <p\n v-else-if=\"hint || $slots.hint\"\n class=\"t-form-field__hint\"\n >\n <slot name=\"hint\">\n {{ hint }}\n </slot>\n </p>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TSize } from '../types/contracts';\n\nconst props = withDefaults(\n defineProps<{\n /** Current active page (1-based) */\n modelValue?: number;\n /** Total number of pages */\n totalPages: number;\n /** Number of sibling pages shown around the current page */\n siblings?: number;\n /** Size variant */\n size?: TSize;\n /** Disable all controls */\n disabled?: boolean;\n /** Accessible label for the nav element */\n label?: string;\n }>(),\n {\n modelValue: 1,\n siblings: 1,\n size: 'md',\n disabled: false,\n label: 'Pagination',\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [page: number];\n}>();\n\ndefineSlots<{\n previous?: (props: Record<string, never>) => unknown;\n next?: (props: Record<string, never>) => unknown;\n}>();\n\nconst currentPage = computed(() =>\n Math.min(Math.max(1, props.modelValue), props.totalPages),\n);\n\nconst pages = computed(() => {\n const total = props.totalPages;\n const current = currentPage.value;\n const siblings = props.siblings;\n const items: (number | 'ellipsis')[] = [];\n\n const rangeStart = Math.max(2, current - siblings);\n const rangeEnd = Math.min(total - 1, current + siblings);\n\n // Always show page 1\n items.push(1);\n\n // Leading ellipsis\n if (rangeStart > 2) {\n items.push('ellipsis');\n }\n\n // Sibling pages\n for (let i = rangeStart; i <= rangeEnd; i++) {\n items.push(i);\n }\n\n // Trailing ellipsis\n if (rangeEnd < total - 1) {\n items.push('ellipsis');\n }\n\n // Always show last page (if more than 1 page)\n if (total > 1) {\n items.push(total);\n }\n\n return items;\n});\n\nconst classes = computed(() => [\n 't-pagination',\n `t-pagination--${props.size}`,\n { 'is-disabled': props.disabled },\n]);\n\nfunction goToPage(page: number) {\n if (props.disabled) return;\n const clamped = Math.min(Math.max(1, page), props.totalPages);\n if (clamped !== currentPage.value) {\n emit('update:modelValue', clamped);\n }\n}\n\nfunction onKeydown(event: KeyboardEvent, page: number) {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n goToPage(page);\n }\n}\n</script>\n\n<template>\n <nav\n :class=\"classes\"\n :aria-label=\"label\"\n >\n <ul class=\"t-pagination__list\">\n <!-- Previous button -->\n <li class=\"t-pagination__item\">\n <button\n class=\"t-pagination__button t-pagination__button--prev\"\n type=\"button\"\n :disabled=\"disabled || currentPage <= 1\"\n :aria-label=\"'Go to previous page'\"\n @click=\"goToPage(currentPage - 1)\"\n >\n <slot name=\"previous\">\n <svg\n class=\"t-pagination__icon\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M10 12L6 8l4-4\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </slot>\n </button>\n </li>\n\n <!-- Page items -->\n <li\n v-for=\"(page, index) in pages\"\n :key=\"page === 'ellipsis' ? `ellipsis-${index}` : page\"\n class=\"t-pagination__item\"\n >\n <span\n v-if=\"page === 'ellipsis'\"\n class=\"t-pagination__ellipsis\"\n aria-hidden=\"true\"\n >\n &hellip;\n </span>\n <button\n v-else\n class=\"t-pagination__button\"\n :class=\"{ 'is-active': page === currentPage }\"\n type=\"button\"\n :disabled=\"disabled\"\n :aria-label=\"`Go to page ${page}`\"\n :aria-current=\"page === currentPage ? 'page' : undefined\"\n @click=\"goToPage(page)\"\n @keydown=\"onKeydown($event, page)\"\n >\n {{ page }}\n </button>\n </li>\n\n <!-- Next button -->\n <li class=\"t-pagination__item\">\n <button\n class=\"t-pagination__button t-pagination__button--next\"\n type=\"button\"\n :disabled=\"disabled || currentPage >= totalPages\"\n :aria-label=\"'Go to next page'\"\n @click=\"goToPage(currentPage + 1)\"\n >\n <slot name=\"next\">\n <svg\n class=\"t-pagination__icon\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6 4l4 4-4 4\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </slot>\n </button>\n </li>\n </ul>\n </nav>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TSize } from '../types/contracts';\n\nconst props = withDefaults(\n defineProps<{\n /** Current active page (1-based) */\n modelValue?: number;\n /** Total number of pages */\n totalPages: number;\n /** Number of sibling pages shown around the current page */\n siblings?: number;\n /** Size variant */\n size?: TSize;\n /** Disable all controls */\n disabled?: boolean;\n /** Accessible label for the nav element */\n label?: string;\n }>(),\n {\n modelValue: 1,\n siblings: 1,\n size: 'md',\n disabled: false,\n label: 'Pagination',\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [page: number];\n}>();\n\ndefineSlots<{\n previous?: (props: Record<string, never>) => unknown;\n next?: (props: Record<string, never>) => unknown;\n}>();\n\nconst currentPage = computed(() =>\n Math.min(Math.max(1, props.modelValue), props.totalPages),\n);\n\nconst pages = computed(() => {\n const total = props.totalPages;\n const current = currentPage.value;\n const siblings = props.siblings;\n const items: (number | 'ellipsis')[] = [];\n\n const rangeStart = Math.max(2, current - siblings);\n const rangeEnd = Math.min(total - 1, current + siblings);\n\n // Always show page 1\n items.push(1);\n\n // Leading ellipsis\n if (rangeStart > 2) {\n items.push('ellipsis');\n }\n\n // Sibling pages\n for (let i = rangeStart; i <= rangeEnd; i++) {\n items.push(i);\n }\n\n // Trailing ellipsis\n if (rangeEnd < total - 1) {\n items.push('ellipsis');\n }\n\n // Always show last page (if more than 1 page)\n if (total > 1) {\n items.push(total);\n }\n\n return items;\n});\n\nconst classes = computed(() => [\n 't-pagination',\n `t-pagination--${props.size}`,\n { 'is-disabled': props.disabled },\n]);\n\nfunction goToPage(page: number) {\n if (props.disabled) return;\n const clamped = Math.min(Math.max(1, page), props.totalPages);\n if (clamped !== currentPage.value) {\n emit('update:modelValue', clamped);\n }\n}\n\nfunction onKeydown(event: KeyboardEvent, page: number) {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n goToPage(page);\n }\n}\n</script>\n\n<template>\n <nav\n :class=\"classes\"\n :aria-label=\"label\"\n >\n <ul class=\"t-pagination__list\">\n <!-- Previous button -->\n <li class=\"t-pagination__item\">\n <button\n class=\"t-pagination__button t-pagination__button--prev\"\n type=\"button\"\n :disabled=\"disabled || currentPage <= 1\"\n :aria-label=\"'Go to previous page'\"\n @click=\"goToPage(currentPage - 1)\"\n >\n <slot name=\"previous\">\n <svg\n class=\"t-pagination__icon\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M10 12L6 8l4-4\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </slot>\n </button>\n </li>\n\n <!-- Page items -->\n <li\n v-for=\"(page, index) in pages\"\n :key=\"page === 'ellipsis' ? `ellipsis-${index}` : page\"\n class=\"t-pagination__item\"\n >\n <span\n v-if=\"page === 'ellipsis'\"\n class=\"t-pagination__ellipsis\"\n aria-hidden=\"true\"\n >\n &hellip;\n </span>\n <button\n v-else\n class=\"t-pagination__button\"\n :class=\"{ 'is-active': page === currentPage }\"\n type=\"button\"\n :disabled=\"disabled\"\n :aria-label=\"`Go to page ${page}`\"\n :aria-current=\"page === currentPage ? 'page' : undefined\"\n @click=\"goToPage(page)\"\n @keydown=\"onKeydown($event, page)\"\n >\n {{ page }}\n </button>\n </li>\n\n <!-- Next button -->\n <li class=\"t-pagination__item\">\n <button\n class=\"t-pagination__button t-pagination__button--next\"\n type=\"button\"\n :disabled=\"disabled || currentPage >= totalPages\"\n :aria-label=\"'Go to next page'\"\n @click=\"goToPage(currentPage + 1)\"\n >\n <slot name=\"next\">\n <svg\n class=\"t-pagination__icon\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M6 4l4 4-4 4\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n </slot>\n </button>\n </li>\n </ul>\n </nav>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, nextTick, onBeforeUnmount, ref, toRef, useAttrs, watch } from 'vue';\nimport { createId, focusFirst, isEscapeKey } from '@treeui/utils';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TTooltipSide } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n open?: boolean;\n defaultOpen?: boolean;\n disabled?: boolean;\n side?: TTooltipSide;\n align?: 'start' | 'center' | 'end';\n id?: string;\n }>(),\n {\n open: undefined,\n defaultOpen: false,\n disabled: false,\n side: 'bottom',\n align: 'center',\n id: undefined,\n },\n);\n\nconst emit = defineEmits<{\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\ndefineSlots<{\n trigger(props: { isOpen: boolean }): unknown;\n default(): unknown;\n}>();\n\nconst attrs = useAttrs();\nconst contentId = props.id ?? createId('t-popover');\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst contentRef = ref<HTMLElement | null>(null);\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-popover',\n {\n 'is-open': isOpen.value,\n 'is-disabled': props.disabled,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst contentClasses = computed(() => [\n 't-popover__content',\n `t-popover__content--${props.side}`,\n `t-popover__content--align-${props.align}`,\n]);\n\nconst openPopover = () => {\n if (props.disabled) return;\n setValue(true);\n nextTick(() => {\n if (contentRef.value) {\n if (!focusFirst(contentRef.value)) {\n contentRef.value.focus();\n }\n }\n });\n};\n\nconst closePopover = (restoreFocus = false) => {\n setValue(false);\n if (restoreFocus) {\n nextTick(() => triggerRef.value?.focus());\n }\n};\n\nconst togglePopover = () => {\n if (isOpen.value) {\n closePopover();\n } else {\n openPopover();\n }\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) return;\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closePopover();\n }\n};\n\nconst onContentKeydown = (event: KeyboardEvent) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closePopover(true);\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) return;\n const target = event.target;\n if (!(target instanceof Node)) return;\n if (rootRef.value?.contains(target)) return;\n closePopover();\n};\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n } else {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <div\n class=\"t-popover__anchor\"\n @click=\"togglePopover\"\n @keydown=\"onTriggerKeydown\"\n >\n <slot\n name=\"trigger\"\n :is-open=\"isOpen\"\n >\n <button\n ref=\"triggerRef\"\n type=\"button\"\n class=\"t-popover__trigger\"\n :disabled=\"disabled\"\n :aria-expanded=\"isOpen\"\n :aria-controls=\"isOpen ? contentId : undefined\"\n aria-haspopup=\"dialog\"\n v-bind=\"triggerAttrs\"\n />\n </slot>\n </div>\n <transition name=\"t-popover-fade\">\n <div\n v-if=\"isOpen && !disabled\"\n :id=\"contentId\"\n ref=\"contentRef\"\n role=\"dialog\"\n :class=\"contentClasses\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n tabindex=\"-1\"\n @keydown=\"onContentKeydown\"\n >\n <slot />\n </div>\n </transition>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, nextTick, onBeforeUnmount, ref, toRef, useAttrs, watch } from 'vue';\nimport { createId, focusFirst, isEscapeKey } from '@treeui/utils';\nimport { useControllableOpen } from '../composables/useControllableOpen';\nimport type { TTooltipSide } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n open?: boolean;\n defaultOpen?: boolean;\n disabled?: boolean;\n side?: TTooltipSide;\n align?: 'start' | 'center' | 'end';\n id?: string;\n }>(),\n {\n open: undefined,\n defaultOpen: false,\n disabled: false,\n side: 'bottom',\n align: 'center',\n id: undefined,\n },\n);\n\nconst emit = defineEmits<{\n 'update:open': [value: boolean];\n 'open-change': [value: boolean];\n}>();\n\ndefineSlots<{\n trigger(props: { isOpen: boolean }): unknown;\n default(): unknown;\n}>();\n\nconst attrs = useAttrs();\nconst contentId = props.id ?? createId('t-popover');\nconst rootRef = ref<HTMLElement | null>(null);\nconst triggerRef = ref<HTMLButtonElement | null>(null);\nconst contentRef = ref<HTMLElement | null>(null);\n\nconst triggerAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst { value: isOpen, setValue } = useControllableOpen(\n toRef(props, 'open'),\n props.defaultOpen,\n (value) => {\n emit('update:open', value);\n emit('open-change', value);\n },\n);\n\nconst rootClasses = computed(() => [\n 't-popover',\n {\n 'is-open': isOpen.value,\n 'is-disabled': props.disabled,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst contentClasses = computed(() => [\n 't-popover__content',\n `t-popover__content--${props.side}`,\n `t-popover__content--align-${props.align}`,\n]);\n\nconst openPopover = () => {\n if (props.disabled) return;\n setValue(true);\n nextTick(() => {\n if (contentRef.value) {\n if (!focusFirst(contentRef.value)) {\n contentRef.value.focus();\n }\n }\n });\n};\n\nconst closePopover = (restoreFocus = false) => {\n setValue(false);\n if (restoreFocus) {\n nextTick(() => triggerRef.value?.focus());\n }\n};\n\nconst togglePopover = () => {\n if (isOpen.value) {\n closePopover();\n } else {\n openPopover();\n }\n};\n\nconst onTriggerKeydown = (event: KeyboardEvent) => {\n if (props.disabled) return;\n\n if (isEscapeKey(event) && isOpen.value) {\n event.preventDefault();\n closePopover();\n }\n};\n\nconst onContentKeydown = (event: KeyboardEvent) => {\n if (isEscapeKey(event)) {\n event.preventDefault();\n closePopover(true);\n }\n};\n\nconst onDocumentPointerDown = (event: PointerEvent) => {\n if (!isOpen.value) return;\n const target = event.target;\n if (!(target instanceof Node)) return;\n if (rootRef.value?.contains(target)) return;\n closePopover();\n};\n\nwatch(isOpen, (value) => {\n if (value) {\n document.addEventListener('pointerdown', onDocumentPointerDown);\n } else {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n }\n});\n\nonBeforeUnmount(() => {\n document.removeEventListener('pointerdown', onDocumentPointerDown);\n});\n</script>\n\n<template>\n <div\n ref=\"rootRef\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n >\n <div\n class=\"t-popover__anchor\"\n @click=\"togglePopover\"\n @keydown=\"onTriggerKeydown\"\n >\n <slot\n name=\"trigger\"\n :is-open=\"isOpen\"\n >\n <button\n ref=\"triggerRef\"\n type=\"button\"\n class=\"t-popover__trigger\"\n :disabled=\"disabled\"\n :aria-expanded=\"isOpen\"\n :aria-controls=\"isOpen ? contentId : undefined\"\n aria-haspopup=\"dialog\"\n v-bind=\"triggerAttrs\"\n />\n </slot>\n </div>\n <transition name=\"t-popover-fade\">\n <div\n v-if=\"isOpen && !disabled\"\n :id=\"contentId\"\n ref=\"contentRef\"\n role=\"dialog\"\n :class=\"contentClasses\"\n :data-state=\"isOpen ? 'open' : 'closed'\"\n tabindex=\"-1\"\n @keydown=\"onContentKeydown\"\n >\n <slot />\n </div>\n </transition>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TSize } from '../types/contracts';\n\nconst props = withDefaults(\n defineProps<{\n /** Current progress value (0–100). Omit for indeterminate. */\n value?: number;\n /** Maximum value. Defaults to 100. */\n max?: number;\n /** Size variant */\n size?: TSize;\n /** Accessible label */\n label?: string;\n }>(),\n {\n value: undefined,\n max: 100,\n size: 'md',\n label: 'Progress',\n },\n);\n\nconst isIndeterminate = computed(() => props.value === undefined || props.value === null);\n\nconst percentage = computed(() => {\n if (isIndeterminate.value) return 0;\n return Math.min(100, Math.max(0, (props.value! / props.max) * 100));\n});\n\nconst classes = computed(() => [\n 't-progress',\n `t-progress--${props.size}`,\n { 't-progress--indeterminate': isIndeterminate.value },\n]);\n</script>\n\n<template>\n <div\n :class=\"classes\"\n role=\"progressbar\"\n :aria-valuenow=\"isIndeterminate ? undefined : percentage\"\n :aria-valuemin=\"0\"\n :aria-valuemax=\"100\"\n :aria-label=\"label\"\n >\n <div class=\"t-progress__track\">\n <div\n class=\"t-progress__fill\"\n :style=\"isIndeterminate ? undefined : { width: `${percentage}%` }\"\n />\n </div>\n\n <span class=\"t-visually-hidden\">{{ label }}</span>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TSize } from '../types/contracts';\n\nconst props = withDefaults(\n defineProps<{\n /** Current progress value (0–100). Omit for indeterminate. */\n value?: number;\n /** Maximum value. Defaults to 100. */\n max?: number;\n /** Size variant */\n size?: TSize;\n /** Accessible label */\n label?: string;\n }>(),\n {\n value: undefined,\n max: 100,\n size: 'md',\n label: 'Progress',\n },\n);\n\nconst isIndeterminate = computed(() => props.value === undefined || props.value === null);\n\nconst percentage = computed(() => {\n if (isIndeterminate.value) return 0;\n return Math.min(100, Math.max(0, (props.value! / props.max) * 100));\n});\n\nconst classes = computed(() => [\n 't-progress',\n `t-progress--${props.size}`,\n { 't-progress--indeterminate': isIndeterminate.value },\n]);\n</script>\n\n<template>\n <div\n :class=\"classes\"\n role=\"progressbar\"\n :aria-valuenow=\"isIndeterminate ? undefined : percentage\"\n :aria-valuemin=\"0\"\n :aria-valuemax=\"100\"\n :aria-label=\"label\"\n >\n <div class=\"t-progress__track\">\n <div\n class=\"t-progress__fill\"\n :style=\"isIndeterminate ? undefined : { width: `${percentage}%` }\"\n />\n </div>\n\n <span class=\"t-visually-hidden\">{{ label }}</span>\n </div>\n</template>\n","import type { InjectionKey, Ref } from 'vue';\nimport type { TSize } from '../types/contracts';\n\nexport type TabsActivationMode = 'automatic' | 'manual';\n\nexport interface TabsContext {\n activeValue: Ref<string>;\n setActiveValue: (value: string) => void;\n size: Ref<TSize>;\n activationMode: Ref<TabsActivationMode>;\n disabled: Ref<boolean>;\n baseId: string;\n registerTab: (value: string) => void;\n unregisterTab: (value: string) => void;\n getTabValues: () => string[];\n isTabDisabled: (value: string) => boolean;\n setTabDisabled: (value: string, disabled: boolean) => void;\n}\n\nexport const TABS_INJECTION_KEY: InjectionKey<TabsContext> = Symbol('TTabs');\n","<script setup lang=\"ts\">\nimport { createId } from '@treeui/utils';\nimport { computed, provide, reactive, ref, toRef, watch } from 'vue';\nimport type { TSize } from '../types/contracts';\nimport type { TabsActivationMode } from './tabs-context';\nimport { TABS_INJECTION_KEY } from './tabs-context';\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n defaultValue?: string;\n size?: TSize;\n activationMode?: TabsActivationMode;\n disabled?: boolean;\n }>(),\n {\n modelValue: undefined,\n defaultValue: '',\n size: 'md',\n activationMode: 'automatic',\n disabled: false,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n}>();\n\nconst baseId = createId('t-tabs');\nconst internalValue = ref(props.defaultValue);\nconst tabOrder = ref<string[]>([]);\nconst disabledTabs: Record<string, boolean> = reactive({});\n\nconst activeValue = computed(() => props.modelValue ?? internalValue.value);\n\nconst setActiveValue = (value: string) => {\n if (value === activeValue.value) return;\n if (props.modelValue === undefined) {\n internalValue.value = value;\n }\n emit('update:modelValue', value);\n};\n\nconst registerTab = (value: string) => {\n if (!tabOrder.value.includes(value)) {\n tabOrder.value.push(value);\n }\n};\n\nconst unregisterTab = (value: string) => {\n const idx = tabOrder.value.indexOf(value);\n if (idx >= 0) tabOrder.value.splice(idx, 1);\n delete disabledTabs[value];\n};\n\nconst getTabValues = () => tabOrder.value;\n\nconst isTabDisabled = (value: string) => props.disabled || !!disabledTabs[value];\n\nconst setTabDisabled = (value: string, disabled: boolean) => {\n if (disabled) {\n disabledTabs[value] = true;\n } else {\n delete disabledTabs[value];\n }\n};\n\nwatch(\n () => props.modelValue,\n (val) => {\n if (val !== undefined) {\n internalValue.value = val;\n }\n },\n);\n\nprovide(TABS_INJECTION_KEY, {\n activeValue,\n setActiveValue,\n size: toRef(props, 'size'),\n activationMode: toRef(props, 'activationMode'),\n disabled: toRef(props, 'disabled'),\n baseId,\n registerTab,\n unregisterTab,\n getTabValues,\n isTabDisabled,\n setTabDisabled,\n});\n\nconst rootClasses = computed(() => [\n 't-tabs',\n `t-tabs--${props.size}`,\n]);\n</script>\n\n<template>\n <div :class=\"rootClasses\">\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { createId } from '@treeui/utils';\nimport { computed, provide, reactive, ref, toRef, watch } from 'vue';\nimport type { TSize } from '../types/contracts';\nimport type { TabsActivationMode } from './tabs-context';\nimport { TABS_INJECTION_KEY } from './tabs-context';\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n defaultValue?: string;\n size?: TSize;\n activationMode?: TabsActivationMode;\n disabled?: boolean;\n }>(),\n {\n modelValue: undefined,\n defaultValue: '',\n size: 'md',\n activationMode: 'automatic',\n disabled: false,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n}>();\n\nconst baseId = createId('t-tabs');\nconst internalValue = ref(props.defaultValue);\nconst tabOrder = ref<string[]>([]);\nconst disabledTabs: Record<string, boolean> = reactive({});\n\nconst activeValue = computed(() => props.modelValue ?? internalValue.value);\n\nconst setActiveValue = (value: string) => {\n if (value === activeValue.value) return;\n if (props.modelValue === undefined) {\n internalValue.value = value;\n }\n emit('update:modelValue', value);\n};\n\nconst registerTab = (value: string) => {\n if (!tabOrder.value.includes(value)) {\n tabOrder.value.push(value);\n }\n};\n\nconst unregisterTab = (value: string) => {\n const idx = tabOrder.value.indexOf(value);\n if (idx >= 0) tabOrder.value.splice(idx, 1);\n delete disabledTabs[value];\n};\n\nconst getTabValues = () => tabOrder.value;\n\nconst isTabDisabled = (value: string) => props.disabled || !!disabledTabs[value];\n\nconst setTabDisabled = (value: string, disabled: boolean) => {\n if (disabled) {\n disabledTabs[value] = true;\n } else {\n delete disabledTabs[value];\n }\n};\n\nwatch(\n () => props.modelValue,\n (val) => {\n if (val !== undefined) {\n internalValue.value = val;\n }\n },\n);\n\nprovide(TABS_INJECTION_KEY, {\n activeValue,\n setActiveValue,\n size: toRef(props, 'size'),\n activationMode: toRef(props, 'activationMode'),\n disabled: toRef(props, 'disabled'),\n baseId,\n registerTab,\n unregisterTab,\n getTabValues,\n isTabDisabled,\n setTabDisabled,\n});\n\nconst rootClasses = computed(() => [\n 't-tabs',\n `t-tabs--${props.size}`,\n]);\n</script>\n\n<template>\n <div :class=\"rootClasses\">\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { isActivationKey } from '@treeui/utils';\nimport { computed, inject, ref } from 'vue';\nimport { TABS_INJECTION_KEY } from './tabs-context';\n\nconst ctx = inject(TABS_INJECTION_KEY);\nif (!ctx) {\n throw new Error('TTabList must be used inside TTabs');\n}\n\nconst listRef = ref<HTMLElement | null>(null);\n\nconst getAllTabElements = (): HTMLElement[] => {\n if (!listRef.value) return [];\n return Array.from(\n listRef.value.querySelectorAll<HTMLElement>('[role=\"tab\"]'),\n );\n};\n\nconst getEnabledTabElements = (): HTMLElement[] => {\n return getAllTabElements().filter((el) => {\n const value = el.dataset.tabValue;\n return value ? !ctx.isTabDisabled(value) : false;\n });\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n const tabs = getEnabledTabElements();\n if (!tabs.length) return;\n\n const current = document.activeElement as HTMLElement;\n const currentIndex = tabs.indexOf(current);\n let nextIndex = currentIndex + direction;\n\n if (nextIndex < 0) nextIndex = tabs.length - 1;\n if (nextIndex >= tabs.length) nextIndex = 0;\n\n const nextTab = tabs[nextIndex];\n nextTab.focus();\n\n if (ctx.activationMode.value === 'automatic') {\n const value = nextTab.dataset.tabValue;\n if (value) ctx.setActiveValue(value);\n }\n};\n\nconst focusFirst = () => {\n const tabs = getEnabledTabElements();\n if (!tabs.length) return;\n tabs[0].focus();\n if (ctx.activationMode.value === 'automatic') {\n const value = tabs[0].dataset.tabValue;\n if (value) ctx.setActiveValue(value);\n }\n};\n\nconst focusLast = () => {\n const tabs = getEnabledTabElements();\n if (!tabs.length) return;\n const last = tabs[tabs.length - 1];\n last.focus();\n if (ctx.activationMode.value === 'automatic') {\n const value = last.dataset.tabValue;\n if (value) ctx.setActiveValue(value);\n }\n};\n\nconst onKeydown = (event: KeyboardEvent) => {\n switch (event.key) {\n case 'ArrowRight':\n event.preventDefault();\n moveFocus(1);\n break;\n case 'ArrowLeft':\n event.preventDefault();\n moveFocus(-1);\n break;\n case 'Home':\n event.preventDefault();\n focusFirst();\n break;\n case 'End':\n event.preventDefault();\n focusLast();\n break;\n default:\n if (ctx.activationMode.value === 'manual' && isActivationKey(event)) {\n event.preventDefault();\n const target = event.target as HTMLElement;\n const value = target.dataset?.tabValue;\n if (value) ctx.setActiveValue(value);\n }\n break;\n }\n};\n\nconst classes = computed(() => [\n 't-tabs__list',\n]);\n</script>\n\n<template>\n <div\n ref=\"listRef\"\n role=\"tablist\"\n aria-orientation=\"horizontal\"\n :class=\"classes\"\n @keydown=\"onKeydown\"\n >\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { isActivationKey } from '@treeui/utils';\nimport { computed, inject, ref } from 'vue';\nimport { TABS_INJECTION_KEY } from './tabs-context';\n\nconst ctx = inject(TABS_INJECTION_KEY);\nif (!ctx) {\n throw new Error('TTabList must be used inside TTabs');\n}\n\nconst listRef = ref<HTMLElement | null>(null);\n\nconst getAllTabElements = (): HTMLElement[] => {\n if (!listRef.value) return [];\n return Array.from(\n listRef.value.querySelectorAll<HTMLElement>('[role=\"tab\"]'),\n );\n};\n\nconst getEnabledTabElements = (): HTMLElement[] => {\n return getAllTabElements().filter((el) => {\n const value = el.dataset.tabValue;\n return value ? !ctx.isTabDisabled(value) : false;\n });\n};\n\nconst moveFocus = (direction: 1 | -1) => {\n const tabs = getEnabledTabElements();\n if (!tabs.length) return;\n\n const current = document.activeElement as HTMLElement;\n const currentIndex = tabs.indexOf(current);\n let nextIndex = currentIndex + direction;\n\n if (nextIndex < 0) nextIndex = tabs.length - 1;\n if (nextIndex >= tabs.length) nextIndex = 0;\n\n const nextTab = tabs[nextIndex];\n nextTab.focus();\n\n if (ctx.activationMode.value === 'automatic') {\n const value = nextTab.dataset.tabValue;\n if (value) ctx.setActiveValue(value);\n }\n};\n\nconst focusFirst = () => {\n const tabs = getEnabledTabElements();\n if (!tabs.length) return;\n tabs[0].focus();\n if (ctx.activationMode.value === 'automatic') {\n const value = tabs[0].dataset.tabValue;\n if (value) ctx.setActiveValue(value);\n }\n};\n\nconst focusLast = () => {\n const tabs = getEnabledTabElements();\n if (!tabs.length) return;\n const last = tabs[tabs.length - 1];\n last.focus();\n if (ctx.activationMode.value === 'automatic') {\n const value = last.dataset.tabValue;\n if (value) ctx.setActiveValue(value);\n }\n};\n\nconst onKeydown = (event: KeyboardEvent) => {\n switch (event.key) {\n case 'ArrowRight':\n event.preventDefault();\n moveFocus(1);\n break;\n case 'ArrowLeft':\n event.preventDefault();\n moveFocus(-1);\n break;\n case 'Home':\n event.preventDefault();\n focusFirst();\n break;\n case 'End':\n event.preventDefault();\n focusLast();\n break;\n default:\n if (ctx.activationMode.value === 'manual' && isActivationKey(event)) {\n event.preventDefault();\n const target = event.target as HTMLElement;\n const value = target.dataset?.tabValue;\n if (value) ctx.setActiveValue(value);\n }\n break;\n }\n};\n\nconst classes = computed(() => [\n 't-tabs__list',\n]);\n</script>\n\n<template>\n <div\n ref=\"listRef\"\n role=\"tablist\"\n aria-orientation=\"horizontal\"\n :class=\"classes\"\n @keydown=\"onKeydown\"\n >\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, inject, onBeforeUnmount, onMounted, watch } from 'vue';\nimport { TABS_INJECTION_KEY } from './tabs-context';\n\nconst props = withDefaults(\n defineProps<{\n value: string;\n disabled?: boolean;\n }>(),\n {\n disabled: false,\n },\n);\n\nconst ctx = inject(TABS_INJECTION_KEY);\nif (!ctx) {\n throw new Error('TTab must be used inside TTabs');\n}\n\nonMounted(() => {\n ctx.registerTab(props.value);\n ctx.setTabDisabled(props.value, props.disabled);\n});\n\nwatch(\n () => props.disabled,\n (val) => ctx.setTabDisabled(props.value, val),\n);\n\nonBeforeUnmount(() => {\n ctx.unregisterTab(props.value);\n});\n\nconst isActive = computed(() => ctx.activeValue.value === props.value);\nconst isDisabled = computed(() => ctx.isTabDisabled(props.value));\nconst tabId = computed(() => `${ctx.baseId}-tab-${props.value}`);\nconst panelId = computed(() => `${ctx.baseId}-panel-${props.value}`);\n\nconst onClick = () => {\n if (isDisabled.value) return;\n ctx.setActiveValue(props.value);\n};\n\nconst classes = computed(() => [\n 't-tabs__tab',\n `t-tabs__tab--${ctx.size.value}`,\n {\n 'is-active': isActive.value,\n 'is-disabled': isDisabled.value,\n },\n]);\n</script>\n\n<template>\n <button\n :id=\"tabId\"\n role=\"tab\"\n type=\"button\"\n :class=\"classes\"\n :aria-selected=\"isActive\"\n :aria-controls=\"panelId\"\n :tabindex=\"isActive ? 0 : -1\"\n :disabled=\"isDisabled || undefined\"\n :data-tab-value=\"value\"\n @click=\"onClick\"\n >\n <slot />\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, inject, onBeforeUnmount, onMounted, watch } from 'vue';\nimport { TABS_INJECTION_KEY } from './tabs-context';\n\nconst props = withDefaults(\n defineProps<{\n value: string;\n disabled?: boolean;\n }>(),\n {\n disabled: false,\n },\n);\n\nconst ctx = inject(TABS_INJECTION_KEY);\nif (!ctx) {\n throw new Error('TTab must be used inside TTabs');\n}\n\nonMounted(() => {\n ctx.registerTab(props.value);\n ctx.setTabDisabled(props.value, props.disabled);\n});\n\nwatch(\n () => props.disabled,\n (val) => ctx.setTabDisabled(props.value, val),\n);\n\nonBeforeUnmount(() => {\n ctx.unregisterTab(props.value);\n});\n\nconst isActive = computed(() => ctx.activeValue.value === props.value);\nconst isDisabled = computed(() => ctx.isTabDisabled(props.value));\nconst tabId = computed(() => `${ctx.baseId}-tab-${props.value}`);\nconst panelId = computed(() => `${ctx.baseId}-panel-${props.value}`);\n\nconst onClick = () => {\n if (isDisabled.value) return;\n ctx.setActiveValue(props.value);\n};\n\nconst classes = computed(() => [\n 't-tabs__tab',\n `t-tabs__tab--${ctx.size.value}`,\n {\n 'is-active': isActive.value,\n 'is-disabled': isDisabled.value,\n },\n]);\n</script>\n\n<template>\n <button\n :id=\"tabId\"\n role=\"tab\"\n type=\"button\"\n :class=\"classes\"\n :aria-selected=\"isActive\"\n :aria-controls=\"panelId\"\n :tabindex=\"isActive ? 0 : -1\"\n :disabled=\"isDisabled || undefined\"\n :data-tab-value=\"value\"\n @click=\"onClick\"\n >\n <slot />\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, inject } from 'vue';\nimport { TABS_INJECTION_KEY } from './tabs-context';\n\nconst props = defineProps<{\n value: string;\n}>();\n\nconst ctx = inject(TABS_INJECTION_KEY);\nif (!ctx) {\n throw new Error('TTabPanel must be used inside TTabs');\n}\n\nconst isActive = computed(() => ctx.activeValue.value === props.value);\nconst panelId = computed(() => `${ctx.baseId}-panel-${props.value}`);\nconst tabId = computed(() => `${ctx.baseId}-tab-${props.value}`);\n</script>\n\n<template>\n <div\n v-if=\"isActive\"\n :id=\"panelId\"\n role=\"tabpanel\"\n :aria-labelledby=\"tabId\"\n tabindex=\"0\"\n class=\"t-tabs__panel\"\n >\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, inject } from 'vue';\nimport { TABS_INJECTION_KEY } from './tabs-context';\n\nconst props = defineProps<{\n value: string;\n}>();\n\nconst ctx = inject(TABS_INJECTION_KEY);\nif (!ctx) {\n throw new Error('TTabPanel must be used inside TTabs');\n}\n\nconst isActive = computed(() => ctx.activeValue.value === props.value);\nconst panelId = computed(() => `${ctx.baseId}-panel-${props.value}`);\nconst tabId = computed(() => `${ctx.baseId}-tab-${props.value}`);\n</script>\n\n<template>\n <div\n v-if=\"isActive\"\n :id=\"panelId\"\n role=\"tabpanel\"\n :aria-labelledby=\"tabId\"\n tabindex=\"0\"\n class=\"t-tabs__panel\"\n >\n <slot />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { createId } from '@treeui/utils';\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport { computed } from 'vue';\nimport type { ToastItem } from '../composables/useToast';\n\nconst XIcon = getTreeIcon('x');\n\nconst iconMap = {\n info: getTreeIcon('info'),\n success: getTreeIcon('check'),\n warning: getTreeIcon('alert-circle'),\n danger: getTreeIcon('alert-circle'),\n} as const;\n\nconst props = withDefaults(\n defineProps<{\n toast: ToastItem;\n }>(),\n {},\n);\n\nconst emit = defineEmits<{\n close: [id: string];\n}>();\n\nconst toastId = createId('t-toast-item');\nconst titleId = `${toastId}-title`;\nconst descriptionId = `${toastId}-description`;\n\nconst classes = computed(() => [\n 't-toast',\n `t-toast--${props.toast.variant}`,\n]);\n\nconst StatusIcon = computed(() => iconMap[props.toast.variant]);\n\nfunction handleClose() {\n emit('close', props.toast.id);\n}\n</script>\n\n<template>\n <div\n :class=\"classes\"\n role=\"status\"\n :aria-labelledby=\"titleId\"\n :aria-describedby=\"toast.description ? descriptionId : undefined\"\n >\n <span\n class=\"t-toast__icon\"\n aria-hidden=\"true\"\n >\n <StatusIcon\n v-bind=\"treeIconDefaults\"\n :size=\"18\"\n />\n </span>\n <div class=\"t-toast__content\">\n <p\n :id=\"titleId\"\n class=\"t-toast__title\"\n >\n {{ toast.title }}\n </p>\n <p\n v-if=\"toast.description\"\n :id=\"descriptionId\"\n class=\"t-toast__description\"\n >\n {{ toast.description }}\n </p>\n </div>\n <button\n v-if=\"toast.closable\"\n type=\"button\"\n class=\"t-toast__close\"\n aria-label=\"Dismiss notification\"\n @click=\"handleClose\"\n >\n <XIcon\n v-bind=\"treeIconDefaults\"\n :size=\"16\"\n />\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { createId } from '@treeui/utils';\nimport { getTreeIcon, treeIconDefaults } from '@treeui/icons';\nimport { computed } from 'vue';\nimport type { ToastItem } from '../composables/useToast';\n\nconst XIcon = getTreeIcon('x');\n\nconst iconMap = {\n info: getTreeIcon('info'),\n success: getTreeIcon('check'),\n warning: getTreeIcon('alert-circle'),\n danger: getTreeIcon('alert-circle'),\n} as const;\n\nconst props = withDefaults(\n defineProps<{\n toast: ToastItem;\n }>(),\n {},\n);\n\nconst emit = defineEmits<{\n close: [id: string];\n}>();\n\nconst toastId = createId('t-toast-item');\nconst titleId = `${toastId}-title`;\nconst descriptionId = `${toastId}-description`;\n\nconst classes = computed(() => [\n 't-toast',\n `t-toast--${props.toast.variant}`,\n]);\n\nconst StatusIcon = computed(() => iconMap[props.toast.variant]);\n\nfunction handleClose() {\n emit('close', props.toast.id);\n}\n</script>\n\n<template>\n <div\n :class=\"classes\"\n role=\"status\"\n :aria-labelledby=\"titleId\"\n :aria-describedby=\"toast.description ? descriptionId : undefined\"\n >\n <span\n class=\"t-toast__icon\"\n aria-hidden=\"true\"\n >\n <StatusIcon\n v-bind=\"treeIconDefaults\"\n :size=\"18\"\n />\n </span>\n <div class=\"t-toast__content\">\n <p\n :id=\"titleId\"\n class=\"t-toast__title\"\n >\n {{ toast.title }}\n </p>\n <p\n v-if=\"toast.description\"\n :id=\"descriptionId\"\n class=\"t-toast__description\"\n >\n {{ toast.description }}\n </p>\n </div>\n <button\n v-if=\"toast.closable\"\n type=\"button\"\n class=\"t-toast__close\"\n aria-label=\"Dismiss notification\"\n @click=\"handleClose\"\n >\n <XIcon\n v-bind=\"treeIconDefaults\"\n :size=\"16\"\n />\n </button>\n </div>\n</template>\n","import { readonly, ref } from 'vue';\nimport { createId } from '@treeui/utils';\n\nexport type ToastVariant = 'info' | 'success' | 'warning' | 'danger';\n\nexport type ToastPosition =\n | 'top-right'\n | 'top-left'\n | 'bottom-right'\n | 'bottom-left'\n | 'top-center'\n | 'bottom-center';\n\nexport interface ToastOptions {\n title: string;\n description?: string;\n variant?: ToastVariant;\n duration?: number;\n closable?: boolean;\n}\n\nexport interface ToastItem extends Required<Pick<ToastOptions, 'title' | 'variant' | 'duration' | 'closable'>> {\n id: string;\n description?: string;\n}\n\nconst toasts = ref<ToastItem[]>([]);\nconst timers = new Map<string, ReturnType<typeof setTimeout>>();\n\nfunction add(options: ToastOptions): string {\n const id = createId('tree-toast');\n\n const item: ToastItem = {\n id,\n title: options.title,\n description: options.description,\n variant: options.variant ?? 'info',\n duration: options.duration ?? 5000,\n closable: options.closable ?? true,\n };\n\n toasts.value = [...toasts.value, item];\n\n if (item.duration > 0) {\n const timer = setTimeout(() => {\n remove(id);\n }, item.duration);\n timers.set(id, timer);\n }\n\n return id;\n}\n\nfunction remove(id: string) {\n const timer = timers.get(id);\n\n if (timer) {\n clearTimeout(timer);\n timers.delete(id);\n }\n\n toasts.value = toasts.value.filter((t) => t.id !== id);\n}\n\nfunction clear() {\n for (const timer of timers.values()) {\n clearTimeout(timer);\n }\n\n timers.clear();\n toasts.value = [];\n}\n\nexport function useToast() {\n return {\n toasts: readonly(toasts),\n add,\n remove,\n clear,\n };\n}\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { useToast, type ToastPosition } from '../composables/useToast';\nimport TToast from './TToast.vue';\n\nconst props = withDefaults(\n defineProps<{\n position?: ToastPosition;\n max?: number;\n }>(),\n {\n position: 'bottom-right',\n max: 5,\n },\n);\n\nconst { toasts, remove } = useToast();\n\nconst visibleToasts = computed(() =>\n toasts.value.slice(-props.max),\n);\n\nconst classes = computed(() => [\n 't-toast-provider',\n `t-toast-provider--${props.position}`,\n]);\n\nfunction handleClose(id: string) {\n remove(id);\n}\n</script>\n\n<template>\n <slot />\n\n <Teleport to=\"body\">\n <div\n :class=\"classes\"\n aria-live=\"polite\"\n aria-relevant=\"additions removals\"\n >\n <TransitionGroup name=\"t-toast\">\n <TToast\n v-for=\"toast in visibleToasts\"\n :key=\"toast.id\"\n :toast=\"toast\"\n @close=\"handleClose\"\n />\n </TransitionGroup>\n </div>\n </Teleport>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport { useToast, type ToastPosition } from '../composables/useToast';\nimport TToast from './TToast.vue';\n\nconst props = withDefaults(\n defineProps<{\n position?: ToastPosition;\n max?: number;\n }>(),\n {\n position: 'bottom-right',\n max: 5,\n },\n);\n\nconst { toasts, remove } = useToast();\n\nconst visibleToasts = computed(() =>\n toasts.value.slice(-props.max),\n);\n\nconst classes = computed(() => [\n 't-toast-provider',\n `t-toast-provider--${props.position}`,\n]);\n\nfunction handleClose(id: string) {\n remove(id);\n}\n</script>\n\n<template>\n <slot />\n\n <Teleport to=\"body\">\n <div\n :class=\"classes\"\n aria-live=\"polite\"\n aria-relevant=\"additions removals\"\n >\n <TransitionGroup name=\"t-toast\">\n <TToast\n v-for=\"toast in visibleToasts\"\n :key=\"toast.id\"\n :toast=\"toast\"\n @close=\"handleClose\"\n />\n </TransitionGroup>\n </div>\n </Teleport>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TSize } from '../types/contracts';\n\nexport type TAvatarStatus = 'online' | 'offline' | 'busy' | 'away';\n\nconst props = withDefaults(\n defineProps<{\n src?: string;\n alt?: string;\n initials?: string;\n size?: TSize;\n status?: TAvatarStatus;\n }>(),\n {\n src: undefined,\n alt: '',\n initials: undefined,\n size: 'md',\n status: undefined,\n },\n);\n\nconst classes = computed(() => [\n 't-avatar',\n `t-avatar--${props.size}`,\n]);\n\nconst computedInitials = computed(() => {\n if (props.initials) return props.initials;\n if (props.alt) {\n return props.alt\n .split(' ')\n .filter(Boolean)\n .map((w) => w[0])\n .slice(0, 2)\n .join('')\n .toUpperCase();\n }\n return '';\n});\n\nfunction onImgError(event: Event) {\n const target = event.target as HTMLImageElement;\n target.style.display = 'none';\n}\n</script>\n\n<template>\n <span\n :class=\"classes\"\n role=\"img\"\n :aria-label=\"alt || undefined\"\n >\n <img\n v-if=\"src\"\n :src=\"src\"\n :alt=\"alt\"\n class=\"t-avatar__image\"\n @error=\"onImgError\"\n >\n <span\n v-else\n class=\"t-avatar__initials\"\n aria-hidden=\"true\"\n >\n {{ computedInitials }}\n </span>\n <slot />\n <span\n v-if=\"status\"\n class=\"t-avatar__status\"\n :class=\"`t-avatar__status--${status}`\"\n :aria-label=\"status\"\n />\n </span>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TSize } from '../types/contracts';\n\nexport type TAvatarStatus = 'online' | 'offline' | 'busy' | 'away';\n\nconst props = withDefaults(\n defineProps<{\n src?: string;\n alt?: string;\n initials?: string;\n size?: TSize;\n status?: TAvatarStatus;\n }>(),\n {\n src: undefined,\n alt: '',\n initials: undefined,\n size: 'md',\n status: undefined,\n },\n);\n\nconst classes = computed(() => [\n 't-avatar',\n `t-avatar--${props.size}`,\n]);\n\nconst computedInitials = computed(() => {\n if (props.initials) return props.initials;\n if (props.alt) {\n return props.alt\n .split(' ')\n .filter(Boolean)\n .map((w) => w[0])\n .slice(0, 2)\n .join('')\n .toUpperCase();\n }\n return '';\n});\n\nfunction onImgError(event: Event) {\n const target = event.target as HTMLImageElement;\n target.style.display = 'none';\n}\n</script>\n\n<template>\n <span\n :class=\"classes\"\n role=\"img\"\n :aria-label=\"alt || undefined\"\n >\n <img\n v-if=\"src\"\n :src=\"src\"\n :alt=\"alt\"\n class=\"t-avatar__image\"\n @error=\"onImgError\"\n >\n <span\n v-else\n class=\"t-avatar__initials\"\n aria-hidden=\"true\"\n >\n {{ computedInitials }}\n </span>\n <slot />\n <span\n v-if=\"status\"\n class=\"t-avatar__status\"\n :class=\"`t-avatar__status--${status}`\"\n :aria-label=\"status\"\n />\n </span>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\nconst props = withDefaults(\n defineProps<{\n orientation?: 'horizontal' | 'vertical';\n decorative?: boolean;\n label?: string;\n }>(),\n {\n orientation: 'horizontal',\n decorative: true,\n label: undefined,\n },\n);\n\nconst classes = computed(() => [\n 't-divider',\n `t-divider--${props.orientation}`,\n]);\n</script>\n\n<template>\n <hr\n :class=\"classes\"\n :role=\"decorative ? 'none' : 'separator'\"\n :aria-orientation=\"!decorative ? orientation : undefined\"\n :aria-label=\"!decorative ? label : undefined\"\n >\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\n\nconst props = withDefaults(\n defineProps<{\n orientation?: 'horizontal' | 'vertical';\n decorative?: boolean;\n label?: string;\n }>(),\n {\n orientation: 'horizontal',\n decorative: true,\n label: undefined,\n },\n);\n\nconst classes = computed(() => [\n 't-divider',\n `t-divider--${props.orientation}`,\n]);\n</script>\n\n<template>\n <hr\n :class=\"classes\"\n :role=\"decorative ? 'none' : 'separator'\"\n :aria-orientation=\"!decorative ? orientation : undefined\"\n :aria-label=\"!decorative ? label : undefined\"\n >\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref } from 'vue';\nimport type { TSize } from '../types/contracts';\n\nexport type TTableColumn = {\n key: string;\n label: string;\n sortable?: boolean;\n align?: 'left' | 'center' | 'right';\n width?: string;\n};\n\nexport type TTableSortDirection = 'asc' | 'desc' | 'none';\n\nexport type TTableSortState = {\n key: string;\n direction: TTableSortDirection;\n};\n\nconst props = withDefaults(\n defineProps<{\n columns: TTableColumn[];\n rows: Record<string, unknown>[];\n size?: TSize;\n sortBy?: TTableSortState;\n }>(),\n {\n size: 'md',\n sortBy: undefined,\n },\n);\n\nconst emit = defineEmits<{\n (e: 'sort', state: TTableSortState): void;\n}>();\n\ndefineSlots<{\n [key: `cell-${string}`]: (props: { row: Record<string, unknown>; value: unknown }) => void;\n [key: `header-${string}`]: (props: { column: TTableColumn }) => void;\n empty: () => void;\n}>();\n\nconst internalSort = ref<TTableSortState | undefined>(undefined);\n\nconst currentSort = computed(() => props.sortBy ?? internalSort.value);\n\nconst classes = computed(() => [\n 't-table',\n `t-table--${props.size}`,\n]);\n\nconst sortedRows = computed(() => {\n const sort = currentSort.value;\n if (!sort || sort.direction === 'none') return props.rows;\n\n return [...props.rows].sort((a, b) => {\n const aVal = a[sort.key];\n const bVal = b[sort.key];\n\n if (aVal == null && bVal == null) return 0;\n if (aVal == null) return 1;\n if (bVal == null) return -1;\n\n const cmp =\n typeof aVal === 'number' && typeof bVal === 'number'\n ? aVal - bVal\n : String(aVal).localeCompare(String(bVal));\n\n return sort.direction === 'desc' ? -cmp : cmp;\n });\n});\n\nfunction handleSort(column: TTableColumn) {\n if (!column.sortable) return;\n\n const cur = currentSort.value;\n let direction: TTableSortDirection = 'asc';\n\n if (cur?.key === column.key) {\n if (cur.direction === 'asc') direction = 'desc';\n else if (cur.direction === 'desc') direction = 'none';\n else direction = 'asc';\n }\n\n const state: TTableSortState = { key: column.key, direction };\n internalSort.value = state;\n emit('sort', state);\n}\n\nfunction sortAriaSort(column: TTableColumn): 'none' | 'ascending' | 'descending' | undefined {\n if (!column.sortable) return undefined;\n const cur = currentSort.value;\n if (cur?.key !== column.key || cur.direction === 'none') return 'none';\n return cur.direction === 'asc' ? 'ascending' : 'descending';\n}\n\nfunction handleHeaderKeydown(event: KeyboardEvent, column: TTableColumn) {\n if (column.sortable && (event.key === 'Enter' || event.key === ' ')) {\n event.preventDefault();\n handleSort(column);\n }\n}\n</script>\n\n<template>\n <div class=\"t-table-wrapper\">\n <table\n :class=\"classes\"\n role=\"grid\"\n >\n <thead class=\"t-table__head\">\n <tr class=\"t-table__row\">\n <th\n v-for=\"column in columns\"\n :key=\"column.key\"\n class=\"t-table__header\"\n :class=\"[\n column.sortable ? 't-table__header--sortable' : '',\n column.align ? `t-table__header--${column.align}` : '',\n ]\"\n :style=\"column.width ? { width: column.width } : undefined\"\n :aria-sort=\"sortAriaSort(column)\"\n :tabindex=\"column.sortable ? 0 : undefined\"\n scope=\"col\"\n @click=\"handleSort(column)\"\n @keydown=\"handleHeaderKeydown($event, column)\"\n >\n <slot\n :name=\"`header-${column.key}`\"\n :column=\"column\"\n >\n <span class=\"t-table__header-content\">\n {{ column.label }}\n <span\n v-if=\"column.sortable\"\n class=\"t-table__sort-icon\"\n aria-hidden=\"true\"\n >\n <svg\n v-if=\"currentSort?.key === column.key && currentSort.direction === 'asc'\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"m18 15-6-6-6 6\" />\n </svg>\n <svg\n v-else-if=\"currentSort?.key === column.key && currentSort.direction === 'desc'\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n <svg\n v-else\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n style=\"opacity: 0.4\"\n >\n <path d=\"m7 15 5 5 5-5\" />\n <path d=\"m7 9 5-5 5 5\" />\n </svg>\n </span>\n </span>\n </slot>\n </th>\n </tr>\n </thead>\n <tbody class=\"t-table__body\">\n <tr\n v-if=\"sortedRows.length === 0\"\n class=\"t-table__row t-table__row--empty\"\n >\n <td\n :colspan=\"columns.length\"\n class=\"t-table__cell t-table__cell--empty\"\n >\n <slot name=\"empty\">\n No data available.\n </slot>\n </td>\n </tr>\n <tr\n v-for=\"(row, index) in sortedRows\"\n :key=\"index\"\n class=\"t-table__row\"\n >\n <td\n v-for=\"column in columns\"\n :key=\"column.key\"\n class=\"t-table__cell\"\n :class=\"column.align ? `t-table__cell--${column.align}` : ''\"\n >\n <slot\n :name=\"`cell-${column.key}`\"\n :row=\"row\"\n :value=\"row[column.key]\"\n >\n {{ row[column.key] ?? '' }}\n </slot>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref } from 'vue';\nimport type { TSize } from '../types/contracts';\n\nexport type TTableColumn = {\n key: string;\n label: string;\n sortable?: boolean;\n align?: 'left' | 'center' | 'right';\n width?: string;\n};\n\nexport type TTableSortDirection = 'asc' | 'desc' | 'none';\n\nexport type TTableSortState = {\n key: string;\n direction: TTableSortDirection;\n};\n\nconst props = withDefaults(\n defineProps<{\n columns: TTableColumn[];\n rows: Record<string, unknown>[];\n size?: TSize;\n sortBy?: TTableSortState;\n }>(),\n {\n size: 'md',\n sortBy: undefined,\n },\n);\n\nconst emit = defineEmits<{\n (e: 'sort', state: TTableSortState): void;\n}>();\n\ndefineSlots<{\n [key: `cell-${string}`]: (props: { row: Record<string, unknown>; value: unknown }) => void;\n [key: `header-${string}`]: (props: { column: TTableColumn }) => void;\n empty: () => void;\n}>();\n\nconst internalSort = ref<TTableSortState | undefined>(undefined);\n\nconst currentSort = computed(() => props.sortBy ?? internalSort.value);\n\nconst classes = computed(() => [\n 't-table',\n `t-table--${props.size}`,\n]);\n\nconst sortedRows = computed(() => {\n const sort = currentSort.value;\n if (!sort || sort.direction === 'none') return props.rows;\n\n return [...props.rows].sort((a, b) => {\n const aVal = a[sort.key];\n const bVal = b[sort.key];\n\n if (aVal == null && bVal == null) return 0;\n if (aVal == null) return 1;\n if (bVal == null) return -1;\n\n const cmp =\n typeof aVal === 'number' && typeof bVal === 'number'\n ? aVal - bVal\n : String(aVal).localeCompare(String(bVal));\n\n return sort.direction === 'desc' ? -cmp : cmp;\n });\n});\n\nfunction handleSort(column: TTableColumn) {\n if (!column.sortable) return;\n\n const cur = currentSort.value;\n let direction: TTableSortDirection = 'asc';\n\n if (cur?.key === column.key) {\n if (cur.direction === 'asc') direction = 'desc';\n else if (cur.direction === 'desc') direction = 'none';\n else direction = 'asc';\n }\n\n const state: TTableSortState = { key: column.key, direction };\n internalSort.value = state;\n emit('sort', state);\n}\n\nfunction sortAriaSort(column: TTableColumn): 'none' | 'ascending' | 'descending' | undefined {\n if (!column.sortable) return undefined;\n const cur = currentSort.value;\n if (cur?.key !== column.key || cur.direction === 'none') return 'none';\n return cur.direction === 'asc' ? 'ascending' : 'descending';\n}\n\nfunction handleHeaderKeydown(event: KeyboardEvent, column: TTableColumn) {\n if (column.sortable && (event.key === 'Enter' || event.key === ' ')) {\n event.preventDefault();\n handleSort(column);\n }\n}\n</script>\n\n<template>\n <div class=\"t-table-wrapper\">\n <table\n :class=\"classes\"\n role=\"grid\"\n >\n <thead class=\"t-table__head\">\n <tr class=\"t-table__row\">\n <th\n v-for=\"column in columns\"\n :key=\"column.key\"\n class=\"t-table__header\"\n :class=\"[\n column.sortable ? 't-table__header--sortable' : '',\n column.align ? `t-table__header--${column.align}` : '',\n ]\"\n :style=\"column.width ? { width: column.width } : undefined\"\n :aria-sort=\"sortAriaSort(column)\"\n :tabindex=\"column.sortable ? 0 : undefined\"\n scope=\"col\"\n @click=\"handleSort(column)\"\n @keydown=\"handleHeaderKeydown($event, column)\"\n >\n <slot\n :name=\"`header-${column.key}`\"\n :column=\"column\"\n >\n <span class=\"t-table__header-content\">\n {{ column.label }}\n <span\n v-if=\"column.sortable\"\n class=\"t-table__sort-icon\"\n aria-hidden=\"true\"\n >\n <svg\n v-if=\"currentSort?.key === column.key && currentSort.direction === 'asc'\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"m18 15-6-6-6 6\" />\n </svg>\n <svg\n v-else-if=\"currentSort?.key === column.key && currentSort.direction === 'desc'\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n <svg\n v-else\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n style=\"opacity: 0.4\"\n >\n <path d=\"m7 15 5 5 5-5\" />\n <path d=\"m7 9 5-5 5 5\" />\n </svg>\n </span>\n </span>\n </slot>\n </th>\n </tr>\n </thead>\n <tbody class=\"t-table__body\">\n <tr\n v-if=\"sortedRows.length === 0\"\n class=\"t-table__row t-table__row--empty\"\n >\n <td\n :colspan=\"columns.length\"\n class=\"t-table__cell t-table__cell--empty\"\n >\n <slot name=\"empty\">\n No data available.\n </slot>\n </td>\n </tr>\n <tr\n v-for=\"(row, index) in sortedRows\"\n :key=\"index\"\n class=\"t-table__row\"\n >\n <td\n v-for=\"column in columns\"\n :key=\"column.key\"\n class=\"t-table__cell\"\n :class=\"column.align ? `t-table__cell--${column.align}` : ''\"\n >\n <slot\n :name=\"`cell-${column.key}`\"\n :row=\"row\"\n :value=\"row[column.key]\"\n >\n {{ row[column.key] ?? '' }}\n </slot>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TSize } from '../types/contracts';\n\nexport type TTagVariant = 'solid' | 'outline' | 'soft';\n\nconst props = withDefaults(\n defineProps<{\n variant?: TTagVariant;\n size?: TSize;\n removable?: boolean;\n disabled?: boolean;\n }>(),\n {\n variant: 'soft',\n size: 'md',\n removable: false,\n disabled: false,\n },\n);\n\nconst emit = defineEmits<{\n (e: 'remove'): void;\n}>();\n\nconst classes = computed(() => [\n 't-tag',\n `t-tag--${props.variant}`,\n `t-tag--${props.size}`,\n props.disabled ? 'is-disabled' : '',\n]);\n\nfunction handleRemove() {\n if (props.disabled) return;\n emit('remove');\n}\n</script>\n\n<template>\n <span :class=\"classes\">\n <span\n v-if=\"$slots.icon\"\n class=\"t-tag__icon\"\n aria-hidden=\"true\"\n >\n <slot name=\"icon\" />\n </span>\n <span class=\"t-tag__label\">\n <slot />\n </span>\n <button\n v-if=\"removable\"\n type=\"button\"\n class=\"t-tag__remove\"\n :disabled=\"disabled\"\n aria-label=\"Remove\"\n @click=\"handleRemove\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n </span>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TSize } from '../types/contracts';\n\nexport type TTagVariant = 'solid' | 'outline' | 'soft';\n\nconst props = withDefaults(\n defineProps<{\n variant?: TTagVariant;\n size?: TSize;\n removable?: boolean;\n disabled?: boolean;\n }>(),\n {\n variant: 'soft',\n size: 'md',\n removable: false,\n disabled: false,\n },\n);\n\nconst emit = defineEmits<{\n (e: 'remove'): void;\n}>();\n\nconst classes = computed(() => [\n 't-tag',\n `t-tag--${props.variant}`,\n `t-tag--${props.size}`,\n props.disabled ? 'is-disabled' : '',\n]);\n\nfunction handleRemove() {\n if (props.disabled) return;\n emit('remove');\n}\n</script>\n\n<template>\n <span :class=\"classes\">\n <span\n v-if=\"$slots.icon\"\n class=\"t-tag__icon\"\n aria-hidden=\"true\"\n >\n <slot name=\"icon\" />\n </span>\n <span class=\"t-tag__label\">\n <slot />\n </span>\n <button\n v-if=\"removable\"\n type=\"button\"\n class=\"t-tag__remove\"\n :disabled=\"disabled\"\n aria-label=\"Remove\"\n @click=\"handleRemove\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n </button>\n </span>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport type TTimelineTone = 'neutral' | 'brand' | 'success' | 'warning' | 'danger';\n\nexport interface TTimelineItem {\n id?: string | number;\n title: string;\n description?: string;\n meta?: string;\n timestamp?: string;\n datetime?: string;\n tone?: TTimelineTone;\n}\n\nconst props = withDefaults(\n defineProps<{\n items?: TTimelineItem[];\n size?: TSize;\n }>(),\n {\n items: () => [],\n size: 'md',\n },\n);\n\ndefineSlots<{\n marker?: (props: { item: TTimelineItem; index: number }) => unknown;\n item?: (props: { item: TTimelineItem; index: number }) => unknown;\n}>();\n\nconst attrs = useAttrs();\n\nconst classes = computed(() => [\n 't-timeline',\n `t-timeline--${props.size}`,\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst normalizeTone = (tone?: TTimelineTone) => tone ?? 'neutral';\nconst itemKey = (item: TTimelineItem, index: number) => item.id ?? `${item.title}-${index}`;\n</script>\n\n<template>\n <ol\n v-bind=\"rootAttrs\"\n :class=\"classes\"\n :style=\"rootStyle\"\n >\n <li\n v-for=\"(item, index) in items\"\n :key=\"itemKey(item, index)\"\n class=\"t-timeline__item\"\n >\n <div class=\"t-timeline__rail\">\n <span\n v-if=\"index < items.length - 1\"\n class=\"t-timeline__line\"\n aria-hidden=\"true\"\n />\n <div\n class=\"t-timeline__marker\"\n :class=\"`t-timeline__marker--${normalizeTone(item.tone)}`\"\n aria-hidden=\"true\"\n >\n <slot\n name=\"marker\"\n :item=\"item\"\n :index=\"index\"\n />\n </div>\n </div>\n\n <div class=\"t-timeline__content\">\n <slot\n name=\"item\"\n :item=\"item\"\n :index=\"index\"\n >\n <div\n v-if=\"item.meta\"\n class=\"t-timeline__meta\"\n >\n {{ item.meta }}\n </div>\n\n <div class=\"t-timeline__header\">\n <p class=\"t-timeline__title\">\n {{ item.title }}\n </p>\n <time\n v-if=\"item.timestamp\"\n class=\"t-timeline__timestamp\"\n :datetime=\"item.datetime || undefined\"\n >\n {{ item.timestamp }}\n </time>\n </div>\n\n <p\n v-if=\"item.description\"\n class=\"t-timeline__description\"\n >\n {{ item.description }}\n </p>\n </slot>\n </div>\n </li>\n </ol>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useAttrs } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nexport type TTimelineTone = 'neutral' | 'brand' | 'success' | 'warning' | 'danger';\n\nexport interface TTimelineItem {\n id?: string | number;\n title: string;\n description?: string;\n meta?: string;\n timestamp?: string;\n datetime?: string;\n tone?: TTimelineTone;\n}\n\nconst props = withDefaults(\n defineProps<{\n items?: TTimelineItem[];\n size?: TSize;\n }>(),\n {\n items: () => [],\n size: 'md',\n },\n);\n\ndefineSlots<{\n marker?: (props: { item: TTimelineItem; index: number }) => unknown;\n item?: (props: { item: TTimelineItem; index: number }) => unknown;\n}>();\n\nconst attrs = useAttrs();\n\nconst classes = computed(() => [\n 't-timeline',\n `t-timeline--${props.size}`,\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst rootAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst normalizeTone = (tone?: TTimelineTone) => tone ?? 'neutral';\nconst itemKey = (item: TTimelineItem, index: number) => item.id ?? `${item.title}-${index}`;\n</script>\n\n<template>\n <ol\n v-bind=\"rootAttrs\"\n :class=\"classes\"\n :style=\"rootStyle\"\n >\n <li\n v-for=\"(item, index) in items\"\n :key=\"itemKey(item, index)\"\n class=\"t-timeline__item\"\n >\n <div class=\"t-timeline__rail\">\n <span\n v-if=\"index < items.length - 1\"\n class=\"t-timeline__line\"\n aria-hidden=\"true\"\n />\n <div\n class=\"t-timeline__marker\"\n :class=\"`t-timeline__marker--${normalizeTone(item.tone)}`\"\n aria-hidden=\"true\"\n >\n <slot\n name=\"marker\"\n :item=\"item\"\n :index=\"index\"\n />\n </div>\n </div>\n\n <div class=\"t-timeline__content\">\n <slot\n name=\"item\"\n :item=\"item\"\n :index=\"index\"\n >\n <div\n v-if=\"item.meta\"\n class=\"t-timeline__meta\"\n >\n {{ item.meta }}\n </div>\n\n <div class=\"t-timeline__header\">\n <p class=\"t-timeline__title\">\n {{ item.title }}\n </p>\n <time\n v-if=\"item.timestamp\"\n class=\"t-timeline__timestamp\"\n :datetime=\"item.datetime || undefined\"\n >\n {{ item.timestamp }}\n </time>\n </div>\n\n <p\n v-if=\"item.description\"\n class=\"t-timeline__description\"\n >\n {{ item.description }}\n </p>\n </slot>\n </div>\n </li>\n </ol>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TSize } from '../types/contracts';\nimport TButton from './TButton.vue';\nimport TBadge from './TBadge.vue';\n\nexport interface PricingFeature {\n text: string;\n included?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n title: string;\n description?: string;\n price: string | number;\n currency?: string;\n period?: string;\n features?: PricingFeature[];\n highlighted?: boolean;\n badge?: string;\n buttonText?: string;\n size?: TSize;\n disabled?: boolean;\n }>(),\n {\n description: undefined,\n currency: '$',\n period: undefined,\n features: () => [],\n highlighted: false,\n badge: undefined,\n buttonText: undefined,\n size: 'md',\n disabled: false,\n },\n);\n\nconst emit = defineEmits<{\n select: [];\n}>();\n\ndefineSlots<{\n header?: () => unknown;\n price?: () => unknown;\n features?: () => unknown;\n action?: () => unknown;\n badge?: () => unknown;\n}>();\n\nconst classes = computed(() => [\n 't-pricing-card',\n `t-pricing-card--${props.size}`,\n {\n 't-pricing-card--highlighted': props.highlighted,\n },\n]);\n\nconst onSelect = () => {\n if (!props.disabled) {\n emit('select');\n }\n};\n</script>\n\n<template>\n <article :class=\"classes\">\n <div\n v-if=\"badge || $slots.badge\"\n class=\"t-pricing-card__badge\"\n >\n <slot name=\"badge\">\n <TBadge\n variant=\"solid\"\n size=\"sm\"\n >\n {{ badge }}\n </TBadge>\n </slot>\n </div>\n\n <header class=\"t-pricing-card__header\">\n <slot name=\"header\">\n <h3 class=\"t-pricing-card__title\">\n {{ title }}\n </h3>\n <p\n v-if=\"description\"\n class=\"t-pricing-card__description\"\n >\n {{ description }}\n </p>\n </slot>\n </header>\n\n <div class=\"t-pricing-card__price\">\n <slot name=\"price\">\n <span class=\"t-pricing-card__currency\">{{ currency }}</span>\n <span class=\"t-pricing-card__amount\">{{ price }}</span>\n <span\n v-if=\"period\"\n class=\"t-pricing-card__period\"\n >{{ period }}</span>\n </slot>\n </div>\n\n <div\n v-if=\"features.length > 0 || $slots.features\"\n class=\"t-pricing-card__features\"\n >\n <slot name=\"features\">\n <ul\n class=\"t-pricing-card__feature-list\"\n role=\"list\"\n >\n <li\n v-for=\"(feature, index) in features\"\n :key=\"index\"\n class=\"t-pricing-card__feature-item\"\n :class=\"{ 't-pricing-card__feature-item--excluded': feature.included === false }\"\n >\n <span\n class=\"t-pricing-card__feature-icon\"\n aria-hidden=\"true\"\n >\n {{ feature.included === false ? '✕' : '✓' }}\n </span>\n <span>{{ feature.text }}</span>\n </li>\n </ul>\n </slot>\n </div>\n\n <footer\n v-if=\"buttonText || $slots.action\"\n class=\"t-pricing-card__action\"\n >\n <slot name=\"action\">\n <TButton\n :variant=\"highlighted ? 'solid' : 'outline'\"\n :size=\"size\"\n :disabled=\"disabled\"\n @click=\"onSelect\"\n >\n {{ buttonText }}\n </TButton>\n </slot>\n </footer>\n </article>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TSize } from '../types/contracts';\nimport TButton from './TButton.vue';\nimport TBadge from './TBadge.vue';\n\nexport interface PricingFeature {\n text: string;\n included?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n title: string;\n description?: string;\n price: string | number;\n currency?: string;\n period?: string;\n features?: PricingFeature[];\n highlighted?: boolean;\n badge?: string;\n buttonText?: string;\n size?: TSize;\n disabled?: boolean;\n }>(),\n {\n description: undefined,\n currency: '$',\n period: undefined,\n features: () => [],\n highlighted: false,\n badge: undefined,\n buttonText: undefined,\n size: 'md',\n disabled: false,\n },\n);\n\nconst emit = defineEmits<{\n select: [];\n}>();\n\ndefineSlots<{\n header?: () => unknown;\n price?: () => unknown;\n features?: () => unknown;\n action?: () => unknown;\n badge?: () => unknown;\n}>();\n\nconst classes = computed(() => [\n 't-pricing-card',\n `t-pricing-card--${props.size}`,\n {\n 't-pricing-card--highlighted': props.highlighted,\n },\n]);\n\nconst onSelect = () => {\n if (!props.disabled) {\n emit('select');\n }\n};\n</script>\n\n<template>\n <article :class=\"classes\">\n <div\n v-if=\"badge || $slots.badge\"\n class=\"t-pricing-card__badge\"\n >\n <slot name=\"badge\">\n <TBadge\n variant=\"solid\"\n size=\"sm\"\n >\n {{ badge }}\n </TBadge>\n </slot>\n </div>\n\n <header class=\"t-pricing-card__header\">\n <slot name=\"header\">\n <h3 class=\"t-pricing-card__title\">\n {{ title }}\n </h3>\n <p\n v-if=\"description\"\n class=\"t-pricing-card__description\"\n >\n {{ description }}\n </p>\n </slot>\n </header>\n\n <div class=\"t-pricing-card__price\">\n <slot name=\"price\">\n <span class=\"t-pricing-card__currency\">{{ currency }}</span>\n <span class=\"t-pricing-card__amount\">{{ price }}</span>\n <span\n v-if=\"period\"\n class=\"t-pricing-card__period\"\n >{{ period }}</span>\n </slot>\n </div>\n\n <div\n v-if=\"features.length > 0 || $slots.features\"\n class=\"t-pricing-card__features\"\n >\n <slot name=\"features\">\n <ul\n class=\"t-pricing-card__feature-list\"\n role=\"list\"\n >\n <li\n v-for=\"(feature, index) in features\"\n :key=\"index\"\n class=\"t-pricing-card__feature-item\"\n :class=\"{ 't-pricing-card__feature-item--excluded': feature.included === false }\"\n >\n <span\n class=\"t-pricing-card__feature-icon\"\n aria-hidden=\"true\"\n >\n {{ feature.included === false ? '✕' : '✓' }}\n </span>\n <span>{{ feature.text }}</span>\n </li>\n </ul>\n </slot>\n </div>\n\n <footer\n v-if=\"buttonText || $slots.action\"\n class=\"t-pricing-card__action\"\n >\n <slot name=\"action\">\n <TButton\n :variant=\"highlighted ? 'solid' : 'outline'\"\n :size=\"size\"\n :disabled=\"disabled\"\n @click=\"onSelect\"\n >\n {{ buttonText }}\n </TButton>\n </slot>\n </footer>\n </article>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TSize } from '../types/contracts';\nimport TPricingCard from './TPricingCard.vue';\nimport type { PricingFeature } from './TPricingCard.vue';\n\nexport interface PricingPlan {\n title: string;\n description?: string;\n price: string | number;\n currency?: string;\n period?: string;\n features?: PricingFeature[];\n highlighted?: boolean;\n badge?: string;\n buttonText?: string;\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n plans: PricingPlan[];\n size?: TSize;\n columns?: number;\n }>(),\n {\n size: 'md',\n columns: undefined,\n },\n);\n\nconst emit = defineEmits<{\n select: [plan: PricingPlan, index: number];\n}>();\n\nconst gridStyle = computed(() => {\n if (props.columns) {\n return { gridTemplateColumns: `repeat(${props.columns}, 1fr)` };\n }\n return { gridTemplateColumns: `repeat(${props.plans.length}, 1fr)` };\n});\n</script>\n\n<template>\n <div\n class=\"t-pricing\"\n :style=\"gridStyle\"\n role=\"list\"\n >\n <div\n v-for=\"(plan, index) in plans\"\n :key=\"index\"\n role=\"listitem\"\n >\n <slot\n name=\"plan\"\n :plan=\"plan\"\n :index=\"index\"\n >\n <TPricingCard\n v-bind=\"plan\"\n :size=\"size\"\n @select=\"emit('select', plan, index)\"\n />\n </slot>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from 'vue';\nimport type { TSize } from '../types/contracts';\nimport TPricingCard from './TPricingCard.vue';\nimport type { PricingFeature } from './TPricingCard.vue';\n\nexport interface PricingPlan {\n title: string;\n description?: string;\n price: string | number;\n currency?: string;\n period?: string;\n features?: PricingFeature[];\n highlighted?: boolean;\n badge?: string;\n buttonText?: string;\n disabled?: boolean;\n}\n\nconst props = withDefaults(\n defineProps<{\n plans: PricingPlan[];\n size?: TSize;\n columns?: number;\n }>(),\n {\n size: 'md',\n columns: undefined,\n },\n);\n\nconst emit = defineEmits<{\n select: [plan: PricingPlan, index: number];\n}>();\n\nconst gridStyle = computed(() => {\n if (props.columns) {\n return { gridTemplateColumns: `repeat(${props.columns}, 1fr)` };\n }\n return { gridTemplateColumns: `repeat(${props.plans.length}, 1fr)` };\n});\n</script>\n\n<template>\n <div\n class=\"t-pricing\"\n :style=\"gridStyle\"\n role=\"list\"\n >\n <div\n v-for=\"(plan, index) in plans\"\n :key=\"index\"\n role=\"listitem\"\n >\n <slot\n name=\"plan\"\n :plan=\"plan\"\n :index=\"index\"\n >\n <TPricingCard\n v-bind=\"plan\"\n :size=\"size\"\n @select=\"emit('select', plan, index)\"\n />\n </slot>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref, useAttrs, nextTick } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n size?: TSize;\n disabled?: boolean;\n placeholder?: string;\n uploadImage?: (file: File) => Promise<string>;\n }>(),\n {\n modelValue: '',\n size: 'md',\n disabled: false,\n placeholder: 'Write your markdown here...',\n uploadImage: undefined,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n 'image-upload': [file: File, url: string];\n 'image-upload-error': [file: File, error: Error];\n}>();\n\ndefineSlots<{\n toolbar?: () => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst textareaRef = ref<HTMLTextAreaElement | null>(null);\nconst isUploading = ref(false);\n\nconst rootClasses = computed(() => [\n 't-md-editor',\n `t-md-editor--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-uploading': isUploading.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst editorAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst stringValue = computed(() => `${props.modelValue ?? ''}`);\n\nconst onInput = (event: Event) => {\n emit('update:modelValue', (event.target as HTMLTextAreaElement).value);\n};\n\n/* ──────── Toolbar Actions ──────── */\n\nconst insertAtCursor = (before: string, after = '') => {\n const el = textareaRef.value;\n if (!el) return;\n\n const start = el.selectionStart;\n const end = el.selectionEnd;\n const text = stringValue.value;\n const selected = text.slice(start, end);\n\n const newText = text.slice(0, start) + before + selected + after + text.slice(end);\n emit('update:modelValue', newText);\n\n nextTick(() => {\n el.focus();\n const cursorPos = selected\n ? start + before.length + selected.length + after.length\n : start + before.length;\n el.setSelectionRange(cursorPos, cursorPos);\n });\n};\n\nconst insertHeading = (level: number) => {\n const prefix = '#'.repeat(level) + ' ';\n const el = textareaRef.value;\n if (!el) return;\n\n const start = el.selectionStart;\n const text = stringValue.value;\n\n // Find start of current line\n const lineStart = text.lastIndexOf('\\n', start - 1) + 1;\n const lineEnd = text.indexOf('\\n', start);\n const actualEnd = lineEnd === -1 ? text.length : lineEnd;\n const line = text.slice(lineStart, actualEnd);\n\n // Strip existing heading markers\n const stripped = line.replace(/^#{1,6}\\s*/, '');\n const newLine = prefix + stripped;\n\n const newText = text.slice(0, lineStart) + newLine + text.slice(actualEnd);\n emit('update:modelValue', newText);\n\n nextTick(() => {\n el.focus();\n el.setSelectionRange(lineStart + newLine.length, lineStart + newLine.length);\n });\n};\n\nconst insertBold = () => insertAtCursor('**', '**');\nconst insertItalic = () => insertAtCursor('_', '_');\nconst insertCode = () => insertAtCursor('`', '`');\nconst insertCodeBlock = () => insertAtCursor('\\n```\\n', '\\n```\\n');\nconst insertLink = () => insertAtCursor('[', '](url)');\nconst insertList = () => insertAtCursor('\\n- ');\nconst insertOrderedList = () => insertAtCursor('\\n1. ');\nconst insertQuote = () => insertAtCursor('\\n> ');\nconst insertHr = () => insertAtCursor('\\n---\\n');\n\n/* ──────── Markdown → HTML rendering ──────── */\n\nconst renderedHtml = computed(() => {\n return markdownToHtml(stringValue.value);\n});\n\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#039;');\n}\n\nfunction markdownToHtml(md: string): string {\n if (!md) return '';\n\n const lines = md.split('\\n');\n const html: string[] = [];\n let inCodeBlock = false;\n let inList = false;\n let inOrderedList = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Code blocks\n if (line.trim().startsWith('```')) {\n if (inCodeBlock) {\n html.push('</code></pre>');\n inCodeBlock = false;\n } else {\n inCodeBlock = true;\n html.push('<pre class=\"t-md-editor__code-block\"><code>');\n }\n continue;\n }\n\n if (inCodeBlock) {\n html.push(escapeHtml(line));\n html.push('\\n');\n continue;\n }\n\n // Close open lists if needed\n const isUnorderedListItem = /^[-*+]\\s/.test(line.trim());\n const isOrderedListItem = /^\\d+\\.\\s/.test(line.trim());\n\n if (inList && !isUnorderedListItem) {\n html.push('</ul>');\n inList = false;\n }\n if (inOrderedList && !isOrderedListItem) {\n html.push('</ol>');\n inOrderedList = false;\n }\n\n // Horizontal rule\n if (/^(-{3,}|_{3,}|\\*{3,})$/.test(line.trim())) {\n html.push('<hr class=\"t-md-editor__hr\" />');\n continue;\n }\n\n // Headings\n const headingMatch = line.match(/^(#{1,6})\\s+(.+)$/);\n if (headingMatch) {\n const level = headingMatch[1].length;\n html.push(`<h${level} class=\"t-md-editor__heading t-md-editor__heading--${level}\">${inlineMarkdown(escapeHtml(headingMatch[2]))}</h${level}>`);\n continue;\n }\n\n // Blockquote\n if (line.trim().startsWith('> ')) {\n html.push(`<blockquote class=\"t-md-editor__blockquote\">${inlineMarkdown(escapeHtml(line.trim().slice(2)))}</blockquote>`);\n continue;\n }\n\n // Unordered list\n if (isUnorderedListItem) {\n if (!inList) {\n html.push('<ul class=\"t-md-editor__list\">');\n inList = true;\n }\n html.push(`<li>${inlineMarkdown(escapeHtml(line.trim().slice(2)))}</li>`);\n continue;\n }\n\n // Ordered list\n if (isOrderedListItem) {\n if (!inOrderedList) {\n html.push('<ol class=\"t-md-editor__list t-md-editor__list--ordered\">');\n inOrderedList = true;\n }\n const content = line.trim().replace(/^\\d+\\.\\s/, '');\n html.push(`<li>${inlineMarkdown(escapeHtml(content))}</li>`);\n continue;\n }\n\n // Empty line\n if (line.trim() === '') {\n html.push('<br />');\n continue;\n }\n\n // Paragraph\n html.push(`<p class=\"t-md-editor__paragraph\">${inlineMarkdown(escapeHtml(line))}</p>`);\n }\n\n // Close any open blocks\n if (inCodeBlock) html.push('</code></pre>');\n if (inList) html.push('</ul>');\n if (inOrderedList) html.push('</ol>');\n\n return html.join('\\n');\n}\n\nfunction inlineMarkdown(text: string): string {\n // Images: ![alt](url)\n text = text.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, '<img src=\"$2\" alt=\"$1\" class=\"t-md-editor__image\" loading=\"lazy\" />');\n // Links: [text](url)\n text = text.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '<a href=\"$2\" target=\"_blank\" rel=\"noopener noreferrer\">$1</a>');\n // Bold: **text**\n text = text.replace(/\\*\\*(.+?)\\*\\*/g, '<strong>$1</strong>');\n // Italic: _text_ or *text*\n text = text.replace(/_(.+?)_/g, '<em>$1</em>');\n text = text.replace(/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, '<em>$1</em>');\n // Inline code: `text`\n text = text.replace(/`(.+?)`/g, '<code class=\"t-md-editor__inline-code\">$1</code>');\n // Strikethrough: ~~text~~\n text = text.replace(/~~(.+?)~~/g, '<del>$1</del>');\n return text;\n}\n\n/* ──────── Image paste / drop handling ──────── */\n\nconst handlePaste = async (event: ClipboardEvent) => {\n if (props.disabled) return;\n\n const items = event.clipboardData?.items;\n if (!items) return;\n\n for (const item of items) {\n if (item.type.startsWith('image/')) {\n event.preventDefault();\n const file = item.getAsFile();\n if (file) await processImageUpload(file);\n return;\n }\n }\n};\n\nconst handleDrop = async (event: DragEvent) => {\n if (props.disabled) return;\n\n const files = event.dataTransfer?.files;\n if (!files) return;\n\n for (const file of files) {\n if (file.type.startsWith('image/')) {\n event.preventDefault();\n await processImageUpload(file);\n }\n }\n};\n\nconst handleDragOver = (event: DragEvent) => {\n if (props.disabled) return;\n event.preventDefault();\n};\n\nconst processImageUpload = async (file: File) => {\n if (!props.uploadImage) {\n // Fallback: insert a placeholder with the file name\n insertAtCursor(`![${file.name}]()`);\n return;\n }\n\n // Insert uploading placeholder\n const placeholder = `![Uploading ${file.name}...]()`;\n insertAtCursor(placeholder);\n isUploading.value = true;\n\n try {\n const url = props.uploadImage(file);\n const resolvedUrl = url instanceof Promise ? await url : url;\n\n // Replace placeholder with actual URL\n const currentValue = stringValue.value;\n const newValue = currentValue.replace(placeholder, `![${file.name}](${resolvedUrl})`);\n emit('update:modelValue', newValue);\n emit('image-upload', file, resolvedUrl);\n } catch (err) {\n // Remove placeholder on error\n const currentValue = stringValue.value;\n const newValue = currentValue.replace(placeholder, '');\n emit('update:modelValue', newValue);\n emit('image-upload-error', file, err instanceof Error ? err : new Error(String(err)));\n } finally {\n isUploading.value = false;\n }\n};\n\n/* ──────── Keyboard shortcuts ──────── */\n\nconst handleKeydown = (event: KeyboardEvent) => {\n if (props.disabled) return;\n\n const mod = event.metaKey || event.ctrlKey;\n if (!mod) return;\n\n switch (event.key) {\n case 'b':\n event.preventDefault();\n insertBold();\n break;\n case 'i':\n event.preventDefault();\n insertItalic();\n break;\n case 'k':\n event.preventDefault();\n insertLink();\n break;\n case 'e':\n event.preventDefault();\n insertCode();\n break;\n }\n};\n\n</script>\n\n<template>\n <div\n v-bind=\"editorAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <!-- Toolbar -->\n <div\n class=\"t-md-editor__toolbar\"\n role=\"toolbar\"\n aria-label=\"Markdown formatting\"\n >\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Heading 1 (H1)\"\n :disabled=\"disabled\"\n @click=\"insertHeading(1)\"\n >\n H1\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Heading 2 (H2)\"\n :disabled=\"disabled\"\n @click=\"insertHeading(2)\"\n >\n H2\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Heading 3 (H3)\"\n :disabled=\"disabled\"\n @click=\"insertHeading(3)\"\n >\n H3\n </button>\n </div>\n\n <div\n class=\"t-md-editor__toolbar-divider\"\n role=\"separator\"\n />\n\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Bold (Ctrl+B)\"\n :disabled=\"disabled\"\n @click=\"insertBold\"\n >\n <strong>B</strong>\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Italic (Ctrl+I)\"\n :disabled=\"disabled\"\n @click=\"insertItalic\"\n >\n <em>I</em>\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Strikethrough\"\n :disabled=\"disabled\"\n @click=\"insertAtCursor('~~', '~~')\"\n >\n <del>S</del>\n </button>\n </div>\n\n <div\n class=\"t-md-editor__toolbar-divider\"\n role=\"separator\"\n />\n\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Inline code (Ctrl+E)\"\n :disabled=\"disabled\"\n @click=\"insertCode\"\n >\n &lt;/&gt;\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Code block\"\n :disabled=\"disabled\"\n @click=\"insertCodeBlock\"\n >\n { }\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Link (Ctrl+K)\"\n :disabled=\"disabled\"\n @click=\"insertLink\"\n >\n 🔗\n </button>\n </div>\n\n <div\n class=\"t-md-editor__toolbar-divider\"\n role=\"separator\"\n />\n\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Unordered list\"\n :disabled=\"disabled\"\n @click=\"insertList\"\n >\n •&nbsp;List\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Ordered list\"\n :disabled=\"disabled\"\n @click=\"insertOrderedList\"\n >\n 1.&nbsp;List\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Blockquote\"\n :disabled=\"disabled\"\n @click=\"insertQuote\"\n >\n &gt;\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Horizontal rule\"\n :disabled=\"disabled\"\n @click=\"insertHr\"\n >\n ―\n </button>\n </div>\n\n <slot name=\"toolbar\" />\n </div>\n\n <!-- Editor body -->\n <div class=\"t-md-editor__body\">\n <!-- Write pane -->\n <div\n class=\"t-md-editor__pane t-md-editor__pane--write\"\n >\n <textarea\n ref=\"textareaRef\"\n class=\"t-md-editor__textarea\"\n :value=\"stringValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :aria-label=\"placeholder\"\n @input=\"onInput\"\n @paste=\"handlePaste\"\n @drop=\"handleDrop\"\n @dragover=\"handleDragOver\"\n @keydown=\"handleKeydown\"\n />\n </div>\n\n <!-- Preview pane -->\n <div\n class=\"t-md-editor__pane t-md-editor__pane--preview\"\n aria-label=\"Markdown preview\"\n >\n <!-- eslint-disable vue/no-v-html -->\n <div\n class=\"t-md-editor__preview\"\n v-html=\"renderedHtml\"\n />\n <!-- eslint-enable vue/no-v-html -->\n </div>\n </div>\n\n <!-- Upload indicator -->\n <div\n v-if=\"isUploading\"\n class=\"t-md-editor__upload-bar\"\n role=\"status\"\n aria-live=\"polite\"\n >\n Uploading image…\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref, useAttrs, nextTick } from 'vue';\nimport type { TSize } from '../types/contracts';\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst props = withDefaults(\n defineProps<{\n modelValue?: string;\n size?: TSize;\n disabled?: boolean;\n placeholder?: string;\n uploadImage?: (file: File) => Promise<string>;\n }>(),\n {\n modelValue: '',\n size: 'md',\n disabled: false,\n placeholder: 'Write your markdown here...',\n uploadImage: undefined,\n },\n);\n\nconst emit = defineEmits<{\n 'update:modelValue': [value: string];\n 'image-upload': [file: File, url: string];\n 'image-upload-error': [file: File, error: Error];\n}>();\n\ndefineSlots<{\n toolbar?: () => unknown;\n}>();\n\nconst attrs = useAttrs();\nconst textareaRef = ref<HTMLTextAreaElement | null>(null);\nconst isUploading = ref(false);\n\nconst rootClasses = computed(() => [\n 't-md-editor',\n `t-md-editor--${props.size}`,\n {\n 'is-disabled': props.disabled,\n 'is-uploading': isUploading.value,\n },\n attrs.class,\n]);\n\nconst rootStyle = computed(() => attrs.style);\n\nconst editorAttrs = computed(() => {\n const { class: _class, style: _style, ...rest } = attrs;\n return rest;\n});\n\nconst stringValue = computed(() => `${props.modelValue ?? ''}`);\n\nconst onInput = (event: Event) => {\n emit('update:modelValue', (event.target as HTMLTextAreaElement).value);\n};\n\n/* ──────── Toolbar Actions ──────── */\n\nconst insertAtCursor = (before: string, after = '') => {\n const el = textareaRef.value;\n if (!el) return;\n\n const start = el.selectionStart;\n const end = el.selectionEnd;\n const text = stringValue.value;\n const selected = text.slice(start, end);\n\n const newText = text.slice(0, start) + before + selected + after + text.slice(end);\n emit('update:modelValue', newText);\n\n nextTick(() => {\n el.focus();\n const cursorPos = selected\n ? start + before.length + selected.length + after.length\n : start + before.length;\n el.setSelectionRange(cursorPos, cursorPos);\n });\n};\n\nconst insertHeading = (level: number) => {\n const prefix = '#'.repeat(level) + ' ';\n const el = textareaRef.value;\n if (!el) return;\n\n const start = el.selectionStart;\n const text = stringValue.value;\n\n // Find start of current line\n const lineStart = text.lastIndexOf('\\n', start - 1) + 1;\n const lineEnd = text.indexOf('\\n', start);\n const actualEnd = lineEnd === -1 ? text.length : lineEnd;\n const line = text.slice(lineStart, actualEnd);\n\n // Strip existing heading markers\n const stripped = line.replace(/^#{1,6}\\s*/, '');\n const newLine = prefix + stripped;\n\n const newText = text.slice(0, lineStart) + newLine + text.slice(actualEnd);\n emit('update:modelValue', newText);\n\n nextTick(() => {\n el.focus();\n el.setSelectionRange(lineStart + newLine.length, lineStart + newLine.length);\n });\n};\n\nconst insertBold = () => insertAtCursor('**', '**');\nconst insertItalic = () => insertAtCursor('_', '_');\nconst insertCode = () => insertAtCursor('`', '`');\nconst insertCodeBlock = () => insertAtCursor('\\n```\\n', '\\n```\\n');\nconst insertLink = () => insertAtCursor('[', '](url)');\nconst insertList = () => insertAtCursor('\\n- ');\nconst insertOrderedList = () => insertAtCursor('\\n1. ');\nconst insertQuote = () => insertAtCursor('\\n> ');\nconst insertHr = () => insertAtCursor('\\n---\\n');\n\n/* ──────── Markdown → HTML rendering ──────── */\n\nconst renderedHtml = computed(() => {\n return markdownToHtml(stringValue.value);\n});\n\nfunction escapeHtml(text: string): string {\n return text\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&#039;');\n}\n\nfunction markdownToHtml(md: string): string {\n if (!md) return '';\n\n const lines = md.split('\\n');\n const html: string[] = [];\n let inCodeBlock = false;\n let inList = false;\n let inOrderedList = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n // Code blocks\n if (line.trim().startsWith('```')) {\n if (inCodeBlock) {\n html.push('</code></pre>');\n inCodeBlock = false;\n } else {\n inCodeBlock = true;\n html.push('<pre class=\"t-md-editor__code-block\"><code>');\n }\n continue;\n }\n\n if (inCodeBlock) {\n html.push(escapeHtml(line));\n html.push('\\n');\n continue;\n }\n\n // Close open lists if needed\n const isUnorderedListItem = /^[-*+]\\s/.test(line.trim());\n const isOrderedListItem = /^\\d+\\.\\s/.test(line.trim());\n\n if (inList && !isUnorderedListItem) {\n html.push('</ul>');\n inList = false;\n }\n if (inOrderedList && !isOrderedListItem) {\n html.push('</ol>');\n inOrderedList = false;\n }\n\n // Horizontal rule\n if (/^(-{3,}|_{3,}|\\*{3,})$/.test(line.trim())) {\n html.push('<hr class=\"t-md-editor__hr\" />');\n continue;\n }\n\n // Headings\n const headingMatch = line.match(/^(#{1,6})\\s+(.+)$/);\n if (headingMatch) {\n const level = headingMatch[1].length;\n html.push(`<h${level} class=\"t-md-editor__heading t-md-editor__heading--${level}\">${inlineMarkdown(escapeHtml(headingMatch[2]))}</h${level}>`);\n continue;\n }\n\n // Blockquote\n if (line.trim().startsWith('> ')) {\n html.push(`<blockquote class=\"t-md-editor__blockquote\">${inlineMarkdown(escapeHtml(line.trim().slice(2)))}</blockquote>`);\n continue;\n }\n\n // Unordered list\n if (isUnorderedListItem) {\n if (!inList) {\n html.push('<ul class=\"t-md-editor__list\">');\n inList = true;\n }\n html.push(`<li>${inlineMarkdown(escapeHtml(line.trim().slice(2)))}</li>`);\n continue;\n }\n\n // Ordered list\n if (isOrderedListItem) {\n if (!inOrderedList) {\n html.push('<ol class=\"t-md-editor__list t-md-editor__list--ordered\">');\n inOrderedList = true;\n }\n const content = line.trim().replace(/^\\d+\\.\\s/, '');\n html.push(`<li>${inlineMarkdown(escapeHtml(content))}</li>`);\n continue;\n }\n\n // Empty line\n if (line.trim() === '') {\n html.push('<br />');\n continue;\n }\n\n // Paragraph\n html.push(`<p class=\"t-md-editor__paragraph\">${inlineMarkdown(escapeHtml(line))}</p>`);\n }\n\n // Close any open blocks\n if (inCodeBlock) html.push('</code></pre>');\n if (inList) html.push('</ul>');\n if (inOrderedList) html.push('</ol>');\n\n return html.join('\\n');\n}\n\nfunction inlineMarkdown(text: string): string {\n // Images: ![alt](url)\n text = text.replace(/!\\[([^\\]]*)\\]\\(([^)]+)\\)/g, '<img src=\"$2\" alt=\"$1\" class=\"t-md-editor__image\" loading=\"lazy\" />');\n // Links: [text](url)\n text = text.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '<a href=\"$2\" target=\"_blank\" rel=\"noopener noreferrer\">$1</a>');\n // Bold: **text**\n text = text.replace(/\\*\\*(.+?)\\*\\*/g, '<strong>$1</strong>');\n // Italic: _text_ or *text*\n text = text.replace(/_(.+?)_/g, '<em>$1</em>');\n text = text.replace(/(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)/g, '<em>$1</em>');\n // Inline code: `text`\n text = text.replace(/`(.+?)`/g, '<code class=\"t-md-editor__inline-code\">$1</code>');\n // Strikethrough: ~~text~~\n text = text.replace(/~~(.+?)~~/g, '<del>$1</del>');\n return text;\n}\n\n/* ──────── Image paste / drop handling ──────── */\n\nconst handlePaste = async (event: ClipboardEvent) => {\n if (props.disabled) return;\n\n const items = event.clipboardData?.items;\n if (!items) return;\n\n for (const item of items) {\n if (item.type.startsWith('image/')) {\n event.preventDefault();\n const file = item.getAsFile();\n if (file) await processImageUpload(file);\n return;\n }\n }\n};\n\nconst handleDrop = async (event: DragEvent) => {\n if (props.disabled) return;\n\n const files = event.dataTransfer?.files;\n if (!files) return;\n\n for (const file of files) {\n if (file.type.startsWith('image/')) {\n event.preventDefault();\n await processImageUpload(file);\n }\n }\n};\n\nconst handleDragOver = (event: DragEvent) => {\n if (props.disabled) return;\n event.preventDefault();\n};\n\nconst processImageUpload = async (file: File) => {\n if (!props.uploadImage) {\n // Fallback: insert a placeholder with the file name\n insertAtCursor(`![${file.name}]()`);\n return;\n }\n\n // Insert uploading placeholder\n const placeholder = `![Uploading ${file.name}...]()`;\n insertAtCursor(placeholder);\n isUploading.value = true;\n\n try {\n const url = props.uploadImage(file);\n const resolvedUrl = url instanceof Promise ? await url : url;\n\n // Replace placeholder with actual URL\n const currentValue = stringValue.value;\n const newValue = currentValue.replace(placeholder, `![${file.name}](${resolvedUrl})`);\n emit('update:modelValue', newValue);\n emit('image-upload', file, resolvedUrl);\n } catch (err) {\n // Remove placeholder on error\n const currentValue = stringValue.value;\n const newValue = currentValue.replace(placeholder, '');\n emit('update:modelValue', newValue);\n emit('image-upload-error', file, err instanceof Error ? err : new Error(String(err)));\n } finally {\n isUploading.value = false;\n }\n};\n\n/* ──────── Keyboard shortcuts ──────── */\n\nconst handleKeydown = (event: KeyboardEvent) => {\n if (props.disabled) return;\n\n const mod = event.metaKey || event.ctrlKey;\n if (!mod) return;\n\n switch (event.key) {\n case 'b':\n event.preventDefault();\n insertBold();\n break;\n case 'i':\n event.preventDefault();\n insertItalic();\n break;\n case 'k':\n event.preventDefault();\n insertLink();\n break;\n case 'e':\n event.preventDefault();\n insertCode();\n break;\n }\n};\n\n</script>\n\n<template>\n <div\n v-bind=\"editorAttrs\"\n :class=\"rootClasses\"\n :style=\"rootStyle\"\n >\n <!-- Toolbar -->\n <div\n class=\"t-md-editor__toolbar\"\n role=\"toolbar\"\n aria-label=\"Markdown formatting\"\n >\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Heading 1 (H1)\"\n :disabled=\"disabled\"\n @click=\"insertHeading(1)\"\n >\n H1\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Heading 2 (H2)\"\n :disabled=\"disabled\"\n @click=\"insertHeading(2)\"\n >\n H2\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Heading 3 (H3)\"\n :disabled=\"disabled\"\n @click=\"insertHeading(3)\"\n >\n H3\n </button>\n </div>\n\n <div\n class=\"t-md-editor__toolbar-divider\"\n role=\"separator\"\n />\n\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Bold (Ctrl+B)\"\n :disabled=\"disabled\"\n @click=\"insertBold\"\n >\n <strong>B</strong>\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Italic (Ctrl+I)\"\n :disabled=\"disabled\"\n @click=\"insertItalic\"\n >\n <em>I</em>\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Strikethrough\"\n :disabled=\"disabled\"\n @click=\"insertAtCursor('~~', '~~')\"\n >\n <del>S</del>\n </button>\n </div>\n\n <div\n class=\"t-md-editor__toolbar-divider\"\n role=\"separator\"\n />\n\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Inline code (Ctrl+E)\"\n :disabled=\"disabled\"\n @click=\"insertCode\"\n >\n &lt;/&gt;\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Code block\"\n :disabled=\"disabled\"\n @click=\"insertCodeBlock\"\n >\n { }\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Link (Ctrl+K)\"\n :disabled=\"disabled\"\n @click=\"insertLink\"\n >\n 🔗\n </button>\n </div>\n\n <div\n class=\"t-md-editor__toolbar-divider\"\n role=\"separator\"\n />\n\n <div class=\"t-md-editor__toolbar-group\">\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Unordered list\"\n :disabled=\"disabled\"\n @click=\"insertList\"\n >\n •&nbsp;List\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Ordered list\"\n :disabled=\"disabled\"\n @click=\"insertOrderedList\"\n >\n 1.&nbsp;List\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Blockquote\"\n :disabled=\"disabled\"\n @click=\"insertQuote\"\n >\n &gt;\n </button>\n <button\n type=\"button\"\n class=\"t-md-editor__toolbar-btn\"\n title=\"Horizontal rule\"\n :disabled=\"disabled\"\n @click=\"insertHr\"\n >\n ―\n </button>\n </div>\n\n <slot name=\"toolbar\" />\n </div>\n\n <!-- Editor body -->\n <div class=\"t-md-editor__body\">\n <!-- Write pane -->\n <div\n class=\"t-md-editor__pane t-md-editor__pane--write\"\n >\n <textarea\n ref=\"textareaRef\"\n class=\"t-md-editor__textarea\"\n :value=\"stringValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :aria-label=\"placeholder\"\n @input=\"onInput\"\n @paste=\"handlePaste\"\n @drop=\"handleDrop\"\n @dragover=\"handleDragOver\"\n @keydown=\"handleKeydown\"\n />\n </div>\n\n <!-- Preview pane -->\n <div\n class=\"t-md-editor__pane t-md-editor__pane--preview\"\n aria-label=\"Markdown preview\"\n >\n <!-- eslint-disable vue/no-v-html -->\n <div\n class=\"t-md-editor__preview\"\n v-html=\"renderedHtml\"\n />\n <!-- eslint-enable vue/no-v-html -->\n </div>\n </div>\n\n <!-- Upload indicator -->\n <div\n v-if=\"isUploading\"\n class=\"t-md-editor__upload-bar\"\n role=\"status\"\n aria-live=\"polite\"\n >\n Uploading image…\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, type Component } from 'vue';\nimport { getTreeIcon, treeIconDefaults, type TIconName } from '@treeui/icons';\n\nconst props = withDefaults(\n defineProps<{\n name: TIconName;\n size?: number | string;\n strokeWidth?: number | string;\n absoluteStrokeWidth?: boolean;\n label?: string;\n }>(),\n {\n size: treeIconDefaults.size,\n strokeWidth: treeIconDefaults.strokeWidth,\n absoluteStrokeWidth: treeIconDefaults.absoluteStrokeWidth,\n label: undefined,\n },\n);\n\nconst iconComponent = computed(() => getTreeIcon(props.name) as Component);\n</script>\n\n<template>\n <component\n :is=\"iconComponent\"\n class=\"t-icon\"\n :size=\"size\"\n :stroke-width=\"strokeWidth\"\n :absolute-stroke-width=\"absoluteStrokeWidth\"\n :role=\"label ? 'img' : undefined\"\n :aria-label=\"label || undefined\"\n :aria-hidden=\"label ? undefined : 'true'\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { computed, type Component } from 'vue';\nimport { getTreeIcon, treeIconDefaults, type TIconName } from '@treeui/icons';\n\nconst props = withDefaults(\n defineProps<{\n name: TIconName;\n size?: number | string;\n strokeWidth?: number | string;\n absoluteStrokeWidth?: boolean;\n label?: string;\n }>(),\n {\n size: treeIconDefaults.size,\n strokeWidth: treeIconDefaults.strokeWidth,\n absoluteStrokeWidth: treeIconDefaults.absoluteStrokeWidth,\n label: undefined,\n },\n);\n\nconst iconComponent = computed(() => getTreeIcon(props.name) as Component);\n</script>\n\n<template>\n <component\n :is=\"iconComponent\"\n class=\"t-icon\"\n :size=\"size\"\n :stroke-width=\"strokeWidth\"\n :absolute-stroke-width=\"absoluteStrokeWidth\"\n :role=\"label ? 'img' : undefined\"\n :aria-label=\"label || undefined\"\n :aria-hidden=\"label ? undefined : 'true'\"\n />\n</template>\n","import type { App, Plugin } from 'vue';\nimport {\n TAccordion,\n TAccordionItem,\n TAlert,\n TBadge,\n TBreadcrumb,\n TBreadcrumbItem,\n TButton,\n TCard,\n TCheckbox,\n TCombobox,\n TConfirmDialog,\n TContainer,\n TContextMenu,\n TDatePicker,\n TDateTimePicker,\n TDrawer,\n TDropdown,\n TEmptyState,\n TFileUpload,\n TFormField,\n TGrid,\n TAppBar,\n TInput,\n TLink,\n TNavMenu,\n TNavbar,\n TMultiSelect,\n TModal,\n TNumberInput,\n TPagination,\n TPopover,\n TProgress,\n TRadio,\n TRadioGroup,\n TSelectableList,\n TSelect,\n TSidebar,\n TSkeleton,\n TSpinner,\n TStack,\n TStat,\n TStepper,\n TSteps,\n TSwitch,\n TTextarea,\n TTabs,\n TTabList,\n TTab,\n TTabPanel,\n TToggleGroup,\n TToast,\n TToastProvider,\n TTooltip,\n TAvatar,\n TDivider,\n TTable,\n TTag,\n TTreeView,\n TTimeline,\n TPricing,\n TPricingCard,\n TMarkdownEditor,\n TIcon,\n} from './components';\n\nconst components = {\n TAccordion,\n TAccordionItem,\n TAlert,\n TBadge,\n TBreadcrumb,\n TBreadcrumbItem,\n TButton,\n TCard,\n TCheckbox,\n TCombobox,\n TConfirmDialog,\n TContainer,\n TContextMenu,\n TDatePicker,\n TDateTimePicker,\n TDrawer,\n TDropdown,\n TEmptyState,\n TFileUpload,\n TFormField,\n TGrid,\n TAppBar,\n TInput,\n TLink,\n TNavMenu,\n TNavbar,\n TMultiSelect,\n TModal,\n TNumberInput,\n TRadio,\n TRadioGroup,\n TSelectableList,\n TSelect,\n TSidebar,\n TSkeleton,\n TSpinner,\n TStack,\n TStat,\n TStepper,\n TSteps,\n TSwitch,\n TTextarea,\n TTabs,\n TTabList,\n TTab,\n TTabPanel,\n TToggleGroup,\n TToast,\n TToastProvider,\n TPagination,\n TPopover,\n TProgress,\n TTooltip,\n TAvatar,\n TDivider,\n TTable,\n TTag,\n TTreeView,\n TTimeline,\n TPricing,\n TPricingCard,\n TMarkdownEditor,\n TIcon,\n};\n\nexport const TreeUIPlugin: Plugin = {\n install(app: App) {\n Object.entries(components).forEach(([name, component]) => {\n app.component(name, component);\n });\n },\n};\n\nexport const install = TreeUIPlugin.install;\n","export const treeSizes = ['sm', 'md', 'lg'] as const;\nexport const treeVariants = ['solid', 'outline', 'ghost', 'soft', 'danger'] as const;\nexport const treeCardVariants = ['outline', 'soft', 'solid', 'inset'] as const;\nexport const treeTooltipSides = ['top', 'right', 'bottom', 'left'] as const;\nexport const treeDrawerSides = ['top', 'right', 'bottom', 'left'] as const;\n\nexport type TSize = (typeof treeSizes)[number];\nexport type TVariant = (typeof treeVariants)[number];\nexport type TCardVariant = (typeof treeCardVariants)[number];\nexport type TTooltipSide = (typeof treeTooltipSides)[number];\nexport type TDrawerSide = (typeof treeDrawerSides)[number];\n\n"],"mappings":"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"}