frappe-ui 1.0.0-beta.2 → 1.0.0-beta.21

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 (692) hide show
  1. package/experimental/FloatingWindow/FloatingWindow.cy.ts +328 -0
  2. package/experimental/FloatingWindow/FloatingWindow.vue +303 -0
  3. package/experimental/FloatingWindow/index.ts +8 -0
  4. package/experimental/FloatingWindow/types.ts +31 -0
  5. package/experimental/FloatingWindow/useFloatingWindow.ts +236 -0
  6. package/experimental/MultiEmailInput/MultiEmailInput.cy.ts +155 -0
  7. package/experimental/MultiEmailInput/MultiEmailInput.vue +472 -0
  8. package/experimental/MultiEmailInput/index.ts +17 -0
  9. package/experimental/MultiEmailInput/stories/AsyncSuggestions.vue +54 -0
  10. package/experimental/MultiEmailInput/stories/Basic.vue +18 -0
  11. package/experimental/MultiEmailInput/stories/CustomChip.vue +39 -0
  12. package/experimental/MultiEmailInput/stories/Labeling.vue +28 -0
  13. package/experimental/MultiEmailInput/types.ts +138 -0
  14. package/experimental/MultiEmailInput/utils.ts +60 -0
  15. package/experimental.ts +12 -0
  16. package/frappe/Billing/SignupBanner.vue +1 -1
  17. package/frappe/Billing/TrialBanner.vue +1 -1
  18. package/frappe/DataImport/DataImport.vue +1 -1
  19. package/frappe/DataImport/DataImportList.vue +1 -1
  20. package/frappe/DataImport/ImportSteps.vue +6 -6
  21. package/frappe/DataImport/MappingStep.vue +1 -1
  22. package/frappe/DataImport/PreviewStep.vue +9 -9
  23. package/frappe/DataImport/TemplateModal.vue +1 -1
  24. package/frappe/DataImport/UploadStep.vue +5 -5
  25. package/frappe/Filter/Filter.vue +1 -1
  26. package/frappe/Help/HelpModal.vue +1 -1
  27. package/frappe/Link/stories/Suffix.vue +2 -2
  28. package/frappe/Onboarding/GettingStartedBanner.vue +1 -1
  29. package/frappe/drive/components/AppSwitcher.vue +1 -1
  30. package/frappe/drive/components/InfoDialog.vue +3 -3
  31. package/frappe/drive/components/MoveDialog.vue +2 -2
  32. package/frappe/drive/components/Select/Select.vue +2 -2
  33. package/frappe/drive/components/ShareDialog.vue +1 -1
  34. package/frappe/telemetry/index.ts +88 -14
  35. package/frappe/telemetry/pulse.ts +78 -164
  36. package/frappe/telemetry/telemetry.test.ts +13 -79
  37. package/icons/IconPicker.vue +1 -1
  38. package/package.json +104 -34
  39. package/src/components/Alert/Alert.md +4 -0
  40. package/src/components/Alert/Alert.vue +4 -4
  41. package/src/components/Autocomplete/Autocomplete.vue +6 -6
  42. package/src/components/Avatar/Avatar.md +4 -0
  43. package/src/components/Avatar/Avatar.vue +23 -4
  44. package/src/components/Badge/Badge.api.md +1 -1
  45. package/src/components/Badge/Badge.cy.ts +34 -16
  46. package/src/components/Badge/Badge.md +20 -4
  47. package/src/components/Badge/Badge.vue +60 -45
  48. package/src/components/Badge/stories/CallMeta.vue +35 -0
  49. package/src/components/Badge/stories/EventStatus.vue +16 -0
  50. package/src/components/Badge/stories/ListStatus.vue +91 -0
  51. package/src/components/Badge/stories/Reactions.vue +33 -0
  52. package/src/components/Badge/stories/RowTags.vue +39 -0
  53. package/src/components/Badge/types.ts +1 -2
  54. package/src/components/BottomSheet/BottomSheet.api.md +57 -0
  55. package/src/components/BottomSheet/BottomSheet.vue +232 -0
  56. package/src/components/BottomSheet/index.ts +6 -0
  57. package/src/components/BottomSheet/types.ts +23 -0
  58. package/src/components/Breadcrumbs/Breadcrumbs.md +4 -0
  59. package/src/components/Breadcrumbs/Breadcrumbs.vue +3 -3
  60. package/src/components/Button/Button.api.md +37 -32
  61. package/src/components/Button/Button.cy.ts +18 -2
  62. package/src/components/Button/Button.md +20 -8
  63. package/src/components/Button/Button.vue +304 -284
  64. package/src/components/Button/stories/InlineActions.vue +10 -0
  65. package/src/components/Button/stories/LiveClassCard.vue +34 -0
  66. package/src/components/Button/stories/SectionAction.vue +17 -0
  67. package/src/components/Button/stories/SectionControls.vue +28 -0
  68. package/src/components/Button/stories/SelectionToolbar.vue +20 -0
  69. package/src/components/Button/stories/StackedActions.vue +10 -0
  70. package/src/components/Button/types.ts +38 -32
  71. package/src/components/Calendar/Calendar.api.md +16 -16
  72. package/src/components/Calendar/Calendar.vue +100 -73
  73. package/src/components/Calendar/CalendarDaily.vue +21 -20
  74. package/src/components/Calendar/CalendarMonthEvent.vue +30 -9
  75. package/src/components/Calendar/CalendarMonthly.vue +60 -39
  76. package/src/components/Calendar/CalendarTimeMarker.vue +9 -8
  77. package/src/components/Calendar/CalendarWeekDayEvent.vue +98 -42
  78. package/src/components/Calendar/CalendarWeekly.vue +77 -41
  79. package/src/components/Calendar/EventModalContent.vue +32 -16
  80. package/src/components/Calendar/NewEventModal.vue +19 -16
  81. package/src/components/Calendar/ShowMoreCalendarEvent.vue +11 -17
  82. package/src/components/Calendar/{calendarUtils.js → calendarUtils.ts} +76 -52
  83. package/src/components/Calendar/composables/{useCalendarData.js → useCalendarData.ts} +23 -11
  84. package/src/components/Calendar/composables/{useEventModal.js → useEventModal.ts} +16 -12
  85. package/src/components/Calendar/index.ts +12 -2
  86. package/src/components/Calendar/stories/CustomHeader.vue +1 -1
  87. package/src/components/Calendar/types.ts +106 -0
  88. package/src/components/Calendar/{useEventBase.js → useEventBase.ts} +40 -26
  89. package/src/components/Card.vue +2 -2
  90. package/src/components/Charts/ECharts.vue +1 -1
  91. package/src/components/Charts/NumberChart.vue +7 -7
  92. package/src/components/Charts/eChartOptions.ts +28 -13
  93. package/src/components/Checkbox/Checkbox.api.md +6 -0
  94. package/src/components/Checkbox/Checkbox.cy.ts +10 -2
  95. package/src/components/Checkbox/Checkbox.md +28 -0
  96. package/src/components/Checkbox/Checkbox.vue +9 -22
  97. package/src/components/Checkbox/stories/Group.vue +27 -0
  98. package/src/components/Checkbox/stories/HorizontalGroup.vue +24 -0
  99. package/src/components/Checkbox/stories/SettingRow.vue +23 -0
  100. package/src/components/Checkbox/stories/WithDescription.vue +27 -0
  101. package/src/components/Checkbox/types.ts +7 -0
  102. package/src/components/CodeEditor/CodeEditor.api.md +139 -0
  103. package/src/components/CodeEditor/CodeEditor.cy.ts +160 -0
  104. package/src/components/CodeEditor/CodeEditor.md +104 -0
  105. package/src/components/CodeEditor/CodeEditor.vue +556 -0
  106. package/src/components/CodeEditor/CodePreview.test.ts +49 -0
  107. package/src/components/CodeEditor/CodePreview.vue +45 -0
  108. package/src/components/CodeEditor/index.ts +17 -0
  109. package/src/components/CodeEditor/languages.ts +63 -0
  110. package/src/components/CodeEditor/stories/Default.vue +16 -0
  111. package/src/components/CodeEditor/stories/Labeling.vue +25 -0
  112. package/src/components/CodeEditor/stories/MaxHeight.vue +24 -0
  113. package/src/components/CodeEditor/stories/Preview.vue +36 -0
  114. package/src/components/CodeEditor/stories/Sizes.vue +15 -0
  115. package/src/components/CodeEditor/stories/Variants.vue +13 -0
  116. package/src/components/CodeEditor/theme.ts +272 -0
  117. package/src/components/CodeEditor/types.ts +69 -0
  118. package/src/components/Combobox/Combobox.api.md +19 -20
  119. package/src/components/Combobox/Combobox.cy.ts +54 -14
  120. package/src/components/Combobox/Combobox.md +4 -0
  121. package/src/components/Combobox/Combobox.vue +233 -247
  122. package/src/components/Combobox/ComboboxResults.vue +1 -1
  123. package/src/components/Combobox/stories/Clearable.vue +2 -2
  124. package/src/components/Combobox/stories/CreateNew.vue +1 -1
  125. package/src/components/Combobox/stories/Footer.vue +10 -2
  126. package/src/components/Combobox/stories/InDialog.vue +1 -1
  127. package/src/components/Combobox/types.ts +8 -29
  128. package/src/components/CommandPalette/CommandPaletteItem.vue +1 -1
  129. package/src/components/ContextMenu/ContextMenu.api.md +52 -0
  130. package/src/components/ContextMenu/ContextMenu.cy.ts +191 -0
  131. package/src/components/ContextMenu/ContextMenu.md +25 -0
  132. package/src/components/ContextMenu/ContextMenu.vue +106 -0
  133. package/src/components/ContextMenu/index.ts +2 -0
  134. package/src/components/ContextMenu/stories/FileList.vue +105 -0
  135. package/src/components/ContextMenu/stories/Groups.vue +95 -0
  136. package/src/components/ContextMenu/stories/Simple.vue +72 -0
  137. package/src/components/ContextMenu/types.ts +39 -0
  138. package/src/components/DatePicker/CalendarPanel.vue +128 -86
  139. package/src/components/DatePicker/DatePicker.vue +3 -9
  140. package/src/components/DatePicker/DateRangePicker.vue +4 -8
  141. package/src/components/DatePicker/DateTimePicker.cy.ts +4 -2
  142. package/src/components/DatePicker/DateTimePicker.vue +3 -9
  143. package/src/components/DatePicker/composables.ts +15 -37
  144. package/src/components/DatePicker/stories/Range.vue +1 -1
  145. package/src/components/DatePicker/types.ts +1 -1
  146. package/src/components/DesktopShell/DesktopShell.api.md +40 -0
  147. package/src/components/DesktopShell/DesktopShell.cy.ts +39 -0
  148. package/src/components/DesktopShell/DesktopShell.md +31 -0
  149. package/src/components/DesktopShell/DesktopShell.vue +81 -0
  150. package/src/components/DesktopShell/index.ts +3 -0
  151. package/src/components/DesktopShell/stories/Default.vue +97 -0
  152. package/src/components/DesktopShell/types.ts +2 -0
  153. package/src/components/Dialog/Dialog.api.md +7 -8
  154. package/src/components/Dialog/Dialog.md +4 -0
  155. package/src/components/Dialog/Dialog.vue +8 -7
  156. package/src/components/Dialog/stories/CommandPalette.vue +1 -1
  157. package/src/components/Dialog/stories/Wizard.vue +1 -1
  158. package/src/components/Dialogs.vue +11 -9
  159. package/src/components/Divider/Divider.api.md +1 -1
  160. package/src/components/Divider/Divider.md +4 -0
  161. package/src/components/Dropdown/Dropdown.api.md +10 -35
  162. package/src/components/Dropdown/Dropdown.md +10 -6
  163. package/src/components/Dropdown/Dropdown.vue +33 -47
  164. package/src/components/Dropdown/stories/{05_KebabMenu.vue → KebabMenu.vue} +3 -1
  165. package/src/components/Dropdown/stories/{06_UserMenu.vue → UserMenu.vue} +1 -1
  166. package/src/components/Dropdown/types.ts +25 -189
  167. package/src/components/Duration/Duration.api.md +92 -0
  168. package/src/components/Duration/Duration.cy.ts +183 -0
  169. package/src/components/Duration/Duration.md +98 -0
  170. package/src/components/Duration/Duration.vue +114 -0
  171. package/src/components/Duration/duration.ts +185 -0
  172. package/src/components/Duration/index.ts +8 -0
  173. package/src/components/Duration/stories/Default.vue +10 -0
  174. package/src/components/Duration/stories/Formats.vue +16 -0
  175. package/src/components/Duration/stories/RealWorld.vue +50 -0
  176. package/src/components/Duration/stories/Sizes.vue +15 -0
  177. package/src/components/Duration/stories/States.vue +21 -0
  178. package/src/components/Duration/types.ts +52 -0
  179. package/src/components/ErrorMessage/ErrorMessage.cy.ts +1 -1
  180. package/src/components/ErrorMessage/ErrorMessage.md +4 -0
  181. package/src/components/ErrorMessage/ErrorMessage.vue +1 -1
  182. package/src/components/FileUploader/FileUploader.api.md +36 -11
  183. package/src/components/FileUploader/FileUploader.cy.ts +66 -0
  184. package/src/components/FileUploader/FileUploader.md +4 -1
  185. package/src/components/FileUploader/FileUploader.vue +147 -106
  186. package/src/components/FileUploader/index.ts +6 -0
  187. package/src/components/FileUploader/types.ts +43 -0
  188. package/src/components/FormControl/FormControl.api.md +3 -4
  189. package/src/components/FormControl/FormControl.md +4 -0
  190. package/src/components/FormControl/stories/RealForm.vue +3 -3
  191. package/src/components/FormLabel.vue +5 -8
  192. package/src/components/HoverCard/HoverCard.api.md +100 -0
  193. package/src/components/HoverCard/HoverCard.cy.ts +103 -0
  194. package/src/components/HoverCard/HoverCard.md +52 -0
  195. package/src/components/HoverCard/HoverCard.vue +91 -0
  196. package/src/components/HoverCard/index.ts +2 -0
  197. package/src/components/HoverCard/stories/Arrow.vue +28 -0
  198. package/src/components/HoverCard/stories/Delays.vue +16 -0
  199. package/src/components/HoverCard/stories/Example.vue +28 -0
  200. package/src/components/HoverCard/types.ts +47 -0
  201. package/src/components/Icon/Icon.cy.ts +78 -0
  202. package/src/components/Icon/Icon.vue +50 -0
  203. package/src/components/Icon/index.ts +1 -0
  204. package/src/components/InputLabeling/InputDescription.vue +1 -1
  205. package/src/components/InputLabeling/InputError.vue +1 -1
  206. package/src/components/InputLabeling/InputLabel.vue +21 -7
  207. package/src/components/InputLabeling/RequiredIndicator.vue +1 -1
  208. package/src/components/ItemListRow/ItemListRow.vue +1 -1
  209. package/src/components/ItemListRow/stories/RowStates.vue +1 -1
  210. package/src/components/KeyboardShortcut.vue +4 -8
  211. package/src/components/KeyboardShortcutsModal/KeyboardShortcutsModal.api.md +22 -14
  212. package/src/components/KeyboardShortcutsModal/KeyboardShortcutsModal.vue +2 -2
  213. package/src/components/ListFilter/ListFilter.api.md +5 -6
  214. package/src/components/ListFilter/ListFilter.vue +161 -57
  215. package/src/components/ListFilter/NestedPopover.vue +17 -10
  216. package/src/components/ListFilter/SearchComplete.vue +31 -38
  217. package/src/components/ListItem.vue +1 -1
  218. package/src/components/ListView/ListEmptyState.vue +1 -1
  219. package/src/components/ListView/ListGroupHeader.vue +2 -2
  220. package/src/components/ListView/ListRow.vue +1 -1
  221. package/src/components/ListView/ListSelectBanner.vue +1 -1
  222. package/src/components/ListView/ListView.api.md +322 -6
  223. package/src/components/ListView/index.ts +25 -0
  224. package/src/components/ListView/stories/CustomList.vue +1 -1
  225. package/src/components/ListView/stories/GroupedRows.vue +1 -1
  226. package/src/components/LoadingIndicator.vue +13 -22
  227. package/src/components/LoadingText.vue +3 -13
  228. package/src/components/{Dropdown/DropdownMenuList.vue → Menu/Menu.vue} +110 -75
  229. package/src/components/{Dropdown/DropdownMenuItemContent.vue → Menu/MenuItemContent.vue} +23 -33
  230. package/src/components/{Dropdown/DropdownRenderContent.vue → Menu/MenuRenderContent.vue} +1 -1
  231. package/src/components/Menu/types.ts +225 -0
  232. package/src/components/{Dropdown → Menu}/utils.ts +36 -40
  233. package/src/components/MobileNav/MobileNav.api.md +70 -0
  234. package/src/components/MobileNav/MobileNav.cy.ts +89 -0
  235. package/src/components/MobileNav/MobileNav.md +34 -0
  236. package/src/components/MobileNav/MobileNav.vue +15 -0
  237. package/src/components/MobileNav/MobileNavItem.vue +125 -0
  238. package/src/components/MobileNav/index.ts +4 -0
  239. package/src/components/MobileNav/stories/Default.vue +40 -0
  240. package/src/components/MobileNav/types.ts +33 -0
  241. package/src/components/MobileShell/MobileShell.api.md +23 -0
  242. package/src/components/MobileShell/MobileShell.cy.ts +25 -0
  243. package/src/components/MobileShell/MobileShell.md +24 -0
  244. package/src/components/MobileShell/MobileShell.vue +41 -0
  245. package/src/components/MobileShell/index.ts +3 -0
  246. package/src/components/MobileShell/stories/Default.vue +75 -0
  247. package/src/components/MobileShell/types.ts +7 -0
  248. package/src/components/MonthPicker/MonthPicker.cy.ts +16 -0
  249. package/src/components/MonthPicker/MonthPicker.vue +19 -8
  250. package/src/components/MultiSelect/MultiSelect.api.md +3 -4
  251. package/src/components/MultiSelect/MultiSelect.md +42 -10
  252. package/src/components/MultiSelect/MultiSelect.vue +199 -227
  253. package/src/components/MultiSelect/MultiSelectResults.vue +1 -1
  254. package/src/components/MultiSelect/stories/Members.vue +1 -1
  255. package/src/components/MultiSelect/stories/TagsTrigger.vue +3 -3
  256. package/src/components/MultiSelect/types.ts +3 -3
  257. package/src/components/PageHeader/PageHeader.api.md +112 -0
  258. package/src/components/PageHeader/PageHeader.cy.ts +68 -0
  259. package/src/components/PageHeader/PageHeader.md +25 -0
  260. package/src/components/PageHeader/PageHeader.vue +13 -0
  261. package/src/components/PageHeader/PageHeaderBackButton.vue +29 -0
  262. package/src/components/PageHeader/PageHeaderBase.vue +51 -0
  263. package/src/components/PageHeader/PageHeaderMobile.vue +68 -0
  264. package/src/components/PageHeader/PageHeaderMobileTitle.vue +16 -0
  265. package/src/components/PageHeader/PageHeaderTarget.vue +13 -0
  266. package/src/components/PageHeader/PageHeaderTitle.vue +12 -0
  267. package/src/components/PageHeader/index.ts +7 -0
  268. package/src/components/PageHeader/stories/Default.vue +19 -0
  269. package/src/components/PageHeader/stories/Mobile.vue +24 -0
  270. package/src/components/PageHeader/target.ts +19 -0
  271. package/src/components/PageHeader/types.ts +19 -0
  272. package/src/components/Password/Password.md +4 -0
  273. package/src/components/Password/Password.vue +2 -2
  274. package/src/components/Popover/Popover.api.md +126 -42
  275. package/src/components/Popover/Popover.cy.ts +425 -41
  276. package/src/components/Popover/Popover.md +99 -4
  277. package/src/components/Popover/Popover.vue +288 -215
  278. package/src/components/Popover/index.ts +8 -1
  279. package/src/components/Popover/stories/Arrow.vue +16 -0
  280. package/src/components/Popover/stories/Bare.vue +20 -0
  281. package/src/components/Popover/stories/Click.vue +7 -4
  282. package/src/components/Popover/stories/Controlled.vue +22 -0
  283. package/src/components/Popover/stories/Dismissible.vue +19 -0
  284. package/src/components/Popover/stories/MatchTriggerWidth.vue +16 -0
  285. package/src/components/Popover/stories/SideAlign.vue +17 -0
  286. package/src/components/Popover/types.ts +101 -23
  287. package/src/components/Progress/Progress.cy.ts +2 -2
  288. package/src/components/Progress/Progress.md +4 -0
  289. package/src/components/Progress/Progress.vue +4 -4
  290. package/src/components/Rail/Rail.api.md +91 -0
  291. package/src/components/Rail/Rail.cy.ts +84 -0
  292. package/src/components/Rail/Rail.md +30 -0
  293. package/src/components/Rail/Rail.vue +16 -0
  294. package/src/components/Rail/RailItem.vue +134 -0
  295. package/src/components/Rail/RailItemBadge.vue +64 -0
  296. package/src/components/Rail/index.ts +2 -0
  297. package/src/components/Rail/stories/Default.vue +44 -0
  298. package/src/components/Rail/types.ts +37 -0
  299. package/src/components/Rating/Rating.md +4 -0
  300. package/src/components/Rating/Rating.vue +5 -8
  301. package/src/components/Rating/stories/CustomSlot.vue +2 -2
  302. package/src/components/ScrollArea/ScrollArea.api.md +59 -0
  303. package/src/components/ScrollArea/ScrollArea.vue +46 -0
  304. package/src/components/ScrollArea/ScrollBar.vue +101 -0
  305. package/src/components/ScrollArea/index.ts +2 -0
  306. package/src/components/Select/Select.cy.ts +16 -15
  307. package/src/components/Select/Select.md +4 -0
  308. package/src/components/Select/Select.vue +217 -203
  309. package/src/components/Select/stories/Example.vue +4 -3
  310. package/src/components/Select/stories/States.vue +1 -1
  311. package/src/components/Select/stories/TriggerSlots.vue +2 -2
  312. package/src/components/Select/utils.ts +4 -3
  313. package/src/components/SettingsDialog/SettingsBody.vue +23 -0
  314. package/src/components/SettingsDialog/SettingsContent.vue +7 -0
  315. package/src/components/SettingsDialog/SettingsDialog.api.md +273 -0
  316. package/src/components/SettingsDialog/SettingsDialog.cy.ts +126 -0
  317. package/src/components/SettingsDialog/SettingsDialog.md +43 -0
  318. package/src/components/SettingsDialog/SettingsDialog.vue +76 -0
  319. package/src/components/SettingsDialog/SettingsHeader.vue +36 -0
  320. package/src/components/SettingsDialog/SettingsNavGroup.vue +20 -0
  321. package/src/components/SettingsDialog/SettingsNavItem.vue +33 -0
  322. package/src/components/SettingsDialog/SettingsPanel.cy.ts +77 -0
  323. package/src/components/SettingsDialog/SettingsPanel.vue +26 -0
  324. package/src/components/SettingsDialog/SettingsRow.vue +52 -0
  325. package/src/components/SettingsDialog/SettingsSidebar.vue +16 -0
  326. package/src/components/SettingsDialog/index.ts +10 -0
  327. package/src/components/SettingsDialog/stories/Default.vue +99 -0
  328. package/src/components/SettingsDialog/stories/PanelBasic.vue +52 -0
  329. package/src/components/SettingsDialog/stories/panels/NotificationsPanel.vue +57 -0
  330. package/src/components/SettingsDialog/stories/panels/PreferencesPanel.vue +57 -0
  331. package/src/components/SettingsDialog/stories/panels/ProfilePanel.vue +38 -0
  332. package/src/components/SettingsDialog/stories/panels/UsersPanel.vue +83 -0
  333. package/src/components/SettingsDialog/types.ts +21 -0
  334. package/src/components/Sidebar/Sidebar.api.md +124 -65
  335. package/src/components/Sidebar/Sidebar.cy.ts +127 -76
  336. package/src/components/Sidebar/Sidebar.md +47 -3
  337. package/src/components/Sidebar/Sidebar.vue +64 -56
  338. package/src/components/Sidebar/SidebarCollapseToggle.vue +23 -0
  339. package/src/components/Sidebar/SidebarHeader.vue +76 -52
  340. package/src/components/Sidebar/SidebarItem.vue +159 -95
  341. package/src/components/Sidebar/SidebarItemIcon.vue +25 -0
  342. package/src/components/Sidebar/SidebarLabel.vue +34 -0
  343. package/src/components/Sidebar/SidebarSection.vue +29 -14
  344. package/src/components/Sidebar/index.ts +13 -2
  345. package/src/components/Sidebar/stories/Collapsed.vue +40 -0
  346. package/src/components/Sidebar/stories/Default.vue +153 -0
  347. package/src/components/Sidebar/stories/Legacy.vue +36 -0
  348. package/src/components/Sidebar/types.ts +105 -20
  349. package/src/components/Skeleton/Skeleton.cy.ts +21 -0
  350. package/src/components/Skeleton/Skeleton.md +21 -0
  351. package/src/components/Skeleton/Skeleton.vue +6 -0
  352. package/src/components/Skeleton/index.ts +1 -0
  353. package/src/components/Skeleton/stories/Card.vue +12 -0
  354. package/src/components/Skeleton/stories/List.vue +15 -0
  355. package/src/components/Skeleton/stories/Text.vue +11 -0
  356. package/src/components/Slider/Slider.api.md +1 -1
  357. package/src/components/Slider/Slider.cy.ts +29 -0
  358. package/src/components/Slider/Slider.md +10 -0
  359. package/src/components/Slider/Slider.vue +37 -9
  360. package/src/components/Slider/stories/NegativeValues.vue +12 -0
  361. package/src/components/Slider/types.ts +1 -1
  362. package/src/components/Spinner/Spinner.api.md +32 -0
  363. package/src/components/Spinner/Spinner.cy.ts +87 -0
  364. package/src/components/Spinner/Spinner.md +21 -0
  365. package/src/components/Spinner/Spinner.vue +168 -0
  366. package/src/components/Spinner/index.ts +2 -0
  367. package/src/components/Spinner/stories/InContext.vue +49 -0
  368. package/src/components/Spinner/stories/Sizes.vue +12 -0
  369. package/src/components/Spinner/stories/Themes.vue +10 -0
  370. package/src/components/Spinner/stories/Track.vue +12 -0
  371. package/src/components/Spinner/types.ts +14 -0
  372. package/src/components/Switch/Switch.md +4 -0
  373. package/src/components/Switch/Switch.vue +6 -23
  374. package/src/components/TabButtons/Pill.vue +161 -0
  375. package/src/components/TabButtons/TabButtons.api.md +52 -2
  376. package/src/components/TabButtons/TabButtons.cy.ts +18 -5
  377. package/src/components/TabButtons/TabButtons.md +49 -0
  378. package/src/components/TabButtons/TabButtons.vue +207 -109
  379. package/src/components/TabButtons/index.ts +11 -1
  380. package/src/components/TabButtons/pillTypes.ts +43 -0
  381. package/src/components/TabButtons/stories/PrefixSuffix.vue +65 -0
  382. package/src/components/TabButtons/stories/Sizes.vue +26 -0
  383. package/src/components/TabButtons/stories/Variants.vue +40 -0
  384. package/src/components/TabButtons/stories/Vertical.vue +64 -0
  385. package/src/components/TabButtons/types.ts +49 -0
  386. package/src/components/Tabs/Tabs.md +4 -0
  387. package/src/components/Tabs/Tabs.vue +1 -1
  388. package/src/components/TextEditor/TextEditor.cy.ts +1 -1
  389. package/src/components/TextEditor/TextEditor.md +3 -0
  390. package/src/components/TextEditor/TextEditor.vue +7 -4
  391. package/src/components/TextEditor/components/CodeBlockComponent.vue +4 -194
  392. package/src/components/TextEditor/components/FontColor.vue +1 -1
  393. package/src/components/TextEditor/components/LinkPopup.vue +1 -1
  394. package/src/components/TextEditor/components/MediaNodeView.vue +17 -17
  395. package/src/components/TextEditor/components/MentionList.vue +1 -1
  396. package/src/components/TextEditor/components/TextEditorBubbleMenu.vue +14 -5
  397. package/src/components/TextEditor/components/TextEditorFixedMenu.vue +3 -3
  398. package/src/components/TextEditor/components/{Menu.vue → TextEditorMenu.vue} +3 -3
  399. package/src/components/TextEditor/extensions/iframe/InsertIframe.vue +2 -2
  400. package/src/components/TextEditor/extensions/iframe/iframe-extension.ts +62 -19
  401. package/src/components/TextEditor/extensions/image-group/ImageGroupNodeView.vue +1 -1
  402. package/src/components/TextEditor/extensions/image-group/ImageGroupUploadDialog.vue +4 -4
  403. package/src/components/TextEditor/extensions/suggestion/SuggestionList.vue +1 -1
  404. package/src/components/TextEditor/extensions/toc-node/TocNodeView.vue +1 -1
  405. package/src/components/TextEditor/hljs-github.css +197 -0
  406. package/src/components/TextEditor/index.ts +13 -0
  407. package/src/components/TextInput/TextInput.cy.ts +8 -3
  408. package/src/components/TextInput/TextInput.md +4 -0
  409. package/src/components/TextInput/TextInput.vue +11 -15
  410. package/src/components/TextInput/stories/Slots.vue +1 -1
  411. package/src/components/Textarea/Textarea.cy.ts +1 -1
  412. package/src/components/Textarea/Textarea.md +4 -0
  413. package/src/components/Textarea/Textarea.vue +11 -15
  414. package/src/components/ThemeSwitcher/ThemePreview.vue +74 -0
  415. package/src/components/ThemeSwitcher/ThemeSwitcher.api.md +82 -0
  416. package/src/components/ThemeSwitcher/ThemeSwitcher.cy.ts +101 -0
  417. package/src/components/ThemeSwitcher/ThemeSwitcher.md +70 -0
  418. package/src/components/ThemeSwitcher/ThemeSwitcher.vue +145 -0
  419. package/src/components/ThemeSwitcher/index.ts +2 -0
  420. package/src/components/ThemeSwitcher/previews/PreviewWindow.vue +74 -0
  421. package/src/components/ThemeSwitcher/stories/Branded.vue +12 -0
  422. package/src/components/ThemeSwitcher/stories/Default.vue +7 -0
  423. package/src/components/ThemeSwitcher/stories/Menu.vue +53 -0
  424. package/src/components/ThemeSwitcher/stories/Toggle.vue +25 -0
  425. package/src/components/ThemeSwitcher/types.ts +35 -0
  426. package/src/components/TimePicker/TimePicker.api.md +67 -15
  427. package/src/components/TimePicker/TimePicker.cy.ts +130 -14
  428. package/src/components/TimePicker/TimePicker.md +6 -0
  429. package/src/components/TimePicker/TimePicker.vue +74 -19
  430. package/src/components/TimePicker/stories/Labeling.vue +21 -0
  431. package/src/components/TimePicker/stories/Range.vue +1 -1
  432. package/src/components/TimePicker/stories/SizesAndVariants.vue +23 -0
  433. package/src/components/TimePicker/stories/TwentyFour.vue +1 -1
  434. package/src/components/TimePicker/types.ts +15 -3
  435. package/src/components/TimePicker/utils.ts +82 -21
  436. package/src/components/Toast/Toast.md +1 -1
  437. package/src/components/Toast/Toast.sanitize.test.ts +50 -0
  438. package/src/components/Toast/Toast.test.ts +5 -0
  439. package/src/components/Toast/Toast.vue +7 -7
  440. package/src/components/Toast/ToastProvider.vue +18 -9
  441. package/src/components/Toast/stories/CustomIcon.vue +1 -1
  442. package/src/components/Toast/toast.ts +32 -8
  443. package/src/components/Tooltip/Tooltip.api.md +43 -5
  444. package/src/components/Tooltip/Tooltip.cy.ts +48 -0
  445. package/src/components/Tooltip/Tooltip.md +10 -0
  446. package/src/components/Tooltip/Tooltip.vue +20 -5
  447. package/src/components/Tooltip/TooltipBubble.vue +2 -2
  448. package/src/components/Tooltip/TooltipProvider.vue +53 -0
  449. package/src/components/Tooltip/index.ts +1 -0
  450. package/src/components/Tooltip/stories/Group.vue +22 -0
  451. package/src/components/Tooltip/stories/Slots.vue +2 -2
  452. package/src/components/Tooltip/types.ts +1 -1
  453. package/src/components/Tree/Tree.api.md +76 -18
  454. package/src/components/Tree/Tree.md +144 -2
  455. package/src/components/Tree/Tree.vue +276 -97
  456. package/src/components/Tree/TreeItem.vue +263 -0
  457. package/src/components/Tree/index.ts +9 -1
  458. package/src/components/Tree/stories/DragDrop.vue +94 -0
  459. package/src/components/Tree/stories/Example.vue +11 -34
  460. package/src/components/Tree/stories/ExpandAll.vue +48 -0
  461. package/src/components/Tree/stories/Guides.vue +49 -0
  462. package/src/components/Tree/stories/ListView.vue +74 -0
  463. package/src/components/Tree/tree.cy.ts +218 -90
  464. package/src/components/Tree/types.ts +114 -24
  465. package/src/components/Tree/useTreeDragDrop.ts +203 -0
  466. package/src/components/Tree/useTreeKeyboard.ts +109 -0
  467. package/src/components/VueGridLayout/Layout.vue +1 -1
  468. package/src/components/shared/picker/PickerShell.vue +20 -15
  469. package/src/components/shared/popover/PopoverPanel.vue +67 -0
  470. package/src/components/shared/popover/popoverPanel.css +102 -0
  471. package/src/components/shared/selection/utils.ts +6 -6
  472. package/src/composables/useAutofocusOnOpen.ts +2 -0
  473. package/src/composables/useScreenSize.ts +46 -0
  474. package/src/composables/useScrollContainer.ts +108 -0
  475. package/src/composables/useShortcut.ts +3 -0
  476. package/src/data-fetching/docStore.test.ts +74 -0
  477. package/src/data-fetching/docStore.ts +18 -7
  478. package/src/data-fetching/useCall/types.ts +1 -0
  479. package/src/data-fetching/useCall/useCall.test.ts +43 -0
  480. package/src/data-fetching/useCall/useCall.ts +17 -4
  481. package/src/data-fetching/useDoc/useDoc.test.ts +61 -2
  482. package/src/data-fetching/useDoc/useDoc.ts +35 -15
  483. package/src/data-fetching/useDoctype/useDoctype.ts +6 -5
  484. package/src/data-fetching/useFrappeFetch.ts +17 -4
  485. package/src/data-fetching/useList/types.ts +1 -0
  486. package/src/data-fetching/useList/useList.test.ts +40 -0
  487. package/src/data-fetching/useList/useList.ts +20 -13
  488. package/src/data-fetching/useNewDoc/useNewDoc.ts +9 -5
  489. package/src/directives/focus.ts +3 -3
  490. package/src/index.ts +105 -74
  491. package/src/mocks/handlers.ts +8 -0
  492. package/src/molecules/editor/Editor.cy.ts +6 -1
  493. package/src/molecules/editor/EditorBubbleMenu.vue +1 -1
  494. package/src/molecules/editor/EditorContent.vue +50 -9
  495. package/src/molecules/editor/EditorFixedMenu.vue +2 -1
  496. package/src/molecules/editor/EditorFloatingMenu.vue +1 -1
  497. package/src/molecules/editor/EditorTableMenu.vue +303 -0
  498. package/src/molecules/editor/MenuItems.vue +81 -69
  499. package/src/molecules/editor/commands.ts +10 -2
  500. package/src/molecules/editor/components/AttachmentNodeView.vue +115 -0
  501. package/src/molecules/editor/components/EditorDropZone.vue +105 -0
  502. package/src/molecules/editor/components/EditorPopover.vue +89 -0
  503. package/src/molecules/editor/components/MediaNodeView.vue +156 -49
  504. package/src/molecules/editor/components/MediaResizeHandles.vue +38 -0
  505. package/src/molecules/editor/components/MediaToolbar.vue +108 -54
  506. package/src/molecules/editor/components/TableContextMenu.vue +144 -0
  507. package/src/molecules/editor/components/UploadProgressIndicator.vue +33 -0
  508. package/src/molecules/editor/components/VideoControls.vue +208 -0
  509. package/src/molecules/editor/components/font-color/ColorSwatchGrid.vue +3 -5
  510. package/src/molecules/editor/components/font-color/fontColorController.ts +28 -23
  511. package/src/molecules/editor/components/font-color/swatches.ts +1 -1
  512. package/src/molecules/editor/components/media-node-view-controller.ts +4 -4
  513. package/src/molecules/editor/components/media-node-view-utils.test.ts +0 -13
  514. package/src/molecules/editor/components/media-node-view-utils.ts +0 -10
  515. package/src/molecules/editor/components/table-color/tableCellColorController.ts +80 -0
  516. package/src/molecules/editor/components/table-size-picker/TableSizePicker.vue +92 -0
  517. package/src/molecules/editor/components/table-size-picker/tableSizePickerController.ts +40 -0
  518. package/src/molecules/editor/composables/useEditorFileDrop.ts +117 -0
  519. package/src/molecules/editor/composables/useFloatingPopup.ts +46 -2
  520. package/src/molecules/editor/composables/useNodeViewResize.test.ts +60 -11
  521. package/src/molecules/editor/composables/useNodeViewResize.ts +80 -21
  522. package/src/molecules/editor/composables/useTableCellColorState.ts +78 -0
  523. package/src/molecules/editor/composables/useWindowFileDragging.ts +68 -0
  524. package/src/molecules/editor/extensions/attachment/attachment-engine.ts +250 -0
  525. package/src/molecules/editor/extensions/attachment/attachment-extension.ts +248 -0
  526. package/src/molecules/editor/extensions/attachment/attachment.flow.test.ts +80 -0
  527. package/src/molecules/editor/extensions/attachment/attachment.roundtrip.test.ts +50 -0
  528. package/src/molecules/editor/extensions/attachment/index.ts +5 -0
  529. package/src/molecules/editor/extensions/code-block/CodeBlockComponent.css +16 -26
  530. package/src/molecules/editor/extensions/code-block/CodeBlockComponent.vue +107 -22
  531. package/src/molecules/editor/extensions/content-paste/content-paste-extension.ts +5 -3
  532. package/src/molecules/editor/extensions/iframe/IframeInsertDialog.vue +34 -7
  533. package/src/molecules/editor/extensions/iframe/IframeNodeView.vue +54 -48
  534. package/src/molecules/editor/extensions/iframe/iframe-allowlist.ts +33 -4
  535. package/src/molecules/editor/extensions/iframe/iframe-commands.ts +49 -5
  536. package/src/molecules/editor/extensions/iframe/iframe-embed-utils.ts +30 -0
  537. package/src/molecules/editor/extensions/iframe/iframe-extension.ts +4 -4
  538. package/src/molecules/editor/extensions/iframe/iframeInsertDialogController.ts +12 -1
  539. package/src/molecules/editor/extensions/iframe/index.ts +4 -4
  540. package/src/molecules/editor/extensions/iframe/useIframeDialog.ts +25 -13
  541. package/src/molecules/editor/extensions/image/image-extension.ts +29 -11
  542. package/src/molecules/editor/extensions/image-group/ImageGroupGrid.vue +27 -11
  543. package/src/molecules/editor/extensions/image-group/ImageGroupGridCell.vue +55 -11
  544. package/src/molecules/editor/extensions/image-group/ImageGroupNodeView.vue +64 -31
  545. package/src/molecules/editor/extensions/image-group/ImageGroupUploadDialog.vue +84 -40
  546. package/src/molecules/editor/extensions/image-group/image-group-extension.ts +4 -3
  547. package/src/molecules/editor/extensions/image-group/useImageGroupDialog.ts +116 -17
  548. package/src/molecules/editor/extensions/link/LinkEditorPopup.vue +214 -71
  549. package/src/molecules/editor/extensions/link/link-click-plugin.ts +10 -15
  550. package/src/molecules/editor/extensions/link/link-commands.ts +24 -3
  551. package/src/molecules/editor/extensions/link/link-extension.ts +11 -2
  552. package/src/molecules/editor/extensions/link/link-popup-controller.test.ts +49 -0
  553. package/src/molecules/editor/extensions/link/link-popup-controller.ts +67 -2
  554. package/src/molecules/editor/extensions/link/link-shortcut-plugin.ts +7 -2
  555. package/src/molecules/editor/extensions/media-drop/media-drop-extension.ts +177 -0
  556. package/src/molecules/editor/extensions/shared/media-dimensions.ts +36 -3
  557. package/src/molecules/editor/extensions/shared/media-node-ops.ts +17 -0
  558. package/src/molecules/editor/extensions/shared/media-plugin.test.ts +60 -0
  559. package/src/molecules/editor/extensions/shared/media-plugin.ts +7 -37
  560. package/src/molecules/editor/extensions/shared/media-upload-engine.test.ts +39 -2
  561. package/src/molecules/editor/extensions/shared/media-upload-engine.ts +104 -10
  562. package/src/molecules/editor/extensions/shared/media-upload-state.ts +55 -0
  563. package/src/molecules/editor/extensions/shared/media-upload-types.ts +52 -1
  564. package/src/molecules/editor/extensions/shared/suggestion-helpers.ts +20 -0
  565. package/src/molecules/editor/extensions/shared/suggestion-types.ts +7 -0
  566. package/src/molecules/editor/extensions/shared/upload-types.ts +1 -0
  567. package/src/molecules/editor/extensions/slash-commands/slash-commands-extension.test.ts +38 -0
  568. package/src/molecules/editor/extensions/slash-commands/slash-commands-extension.ts +119 -55
  569. package/src/molecules/editor/extensions/suggestion/SuggestionList.vue +62 -22
  570. package/src/molecules/editor/extensions/suggestion/SuggestionListItem.vue +1 -1
  571. package/src/molecules/editor/extensions/suggestion/createSuggestionExtension.ts +4 -0
  572. package/src/molecules/editor/extensions/table/drag-scroll.ts +154 -0
  573. package/src/molecules/editor/extensions/table/table-cell-color.ts +188 -0
  574. package/src/molecules/editor/extensions/table/table-navigation.ts +560 -0
  575. package/src/molecules/editor/extensions/table/table-selection-overlay.ts +137 -0
  576. package/src/molecules/editor/extensions/toc-node/TocNodeView.vue +1 -1
  577. package/src/molecules/editor/extensions/toc-node/toc-render.ts +7 -3
  578. package/src/molecules/editor/extensions/video/video-extension.ts +72 -5
  579. package/src/molecules/editor/extensions.ts +176 -8
  580. package/src/molecules/editor/index.ts +9 -4
  581. package/src/molecules/editor/kits.test.ts +21 -1
  582. package/src/molecules/editor/kits.ts +56 -33
  583. package/src/molecules/editor/menu.test.ts +3 -1
  584. package/src/molecules/editor/menu.ts +180 -18
  585. package/src/molecules/editor/stories/Comment.vue +4 -4
  586. package/src/molecules/editor/stories/Inline.vue +1 -1
  587. package/src/molecules/editor/stories/Primitives.vue +1 -1
  588. package/src/molecules/editor/stories/RichText.vue +1 -1
  589. package/src/molecules/editor/style.css +80 -3
  590. package/src/molecules/editor/useEditor.test.ts +4 -0
  591. package/src/molecules/editor/useEditor.ts +7 -3
  592. package/src/molecules/list/List.cy.ts +626 -0
  593. package/src/molecules/list/List.vue +93 -0
  594. package/src/molecules/list/ListCell.vue +15 -0
  595. package/src/molecules/list/ListGroup.vue +40 -0
  596. package/src/molecules/list/ListHeader.vue +62 -0
  597. package/src/molecules/list/ListHeaderCell.vue +26 -0
  598. package/src/molecules/list/ListHeaderCellSort.vue +106 -0
  599. package/src/molecules/list/ListRow.vue +55 -0
  600. package/src/molecules/list/ListRowBase.vue +103 -0
  601. package/src/molecules/list/ListRows.vue +120 -0
  602. package/src/molecules/list/index.ts +24 -0
  603. package/src/molecules/list/list-context.ts +44 -0
  604. package/src/molecules/list/list.api.md +276 -0
  605. package/src/molecules/list/list.md +119 -0
  606. package/src/molecules/list/stories/Columns.vue +103 -0
  607. package/src/molecules/list/stories/Feed.vue +105 -0
  608. package/src/molecules/list/stories/Virtual.vue +31 -0
  609. package/src/molecules/list/style.css +173 -0
  610. package/src/molecules/list/types.ts +82 -0
  611. package/src/molecules/list/useVirtualRows.ts +80 -0
  612. package/src/resources/documentResource.d.ts +28 -0
  613. package/src/resources/documentResource.js +32 -4
  614. package/src/resources/documentResource.test.ts +111 -0
  615. package/src/resources/listResource.d.ts +33 -0
  616. package/src/resources/plugin.d.ts +7 -0
  617. package/src/resources/resources.d.ts +35 -0
  618. package/src/utils/{call.js → call.ts} +50 -9
  619. package/src/utils/config.ts +16 -1
  620. package/src/utils/confirmDialog.d.ts +17 -0
  621. package/src/utils/debounce.ts +6 -7
  622. package/src/utils/dialog.cy.ts +9 -9
  623. package/src/utils/fileSize.ts +36 -0
  624. package/src/utils/fileUploadHandler.ts +46 -6
  625. package/src/utils/frappeRequest.test.ts +79 -0
  626. package/src/utils/{frappeRequest.js → frappeRequest.ts} +76 -13
  627. package/src/utils/pageMeta.ts +1 -1
  628. package/src/utils/plugin.ts +58 -0
  629. package/src/utils/{request.js → request.ts} +28 -3
  630. package/src/utils/{socketio.js → socketio.ts} +11 -1
  631. package/src/utils/theme.ts +48 -57
  632. package/src/utils/useFileUpload.ts +80 -23
  633. package/tailwind/audit-token-drift.cjs +176 -0
  634. package/tailwind/colorPalette.js +69 -8
  635. package/tailwind/colors.json +1115 -397
  636. package/tailwind/figma-tokens-to-theme.js +364 -0
  637. package/tailwind/generated/colors.json +1217 -0
  638. package/tailwind/generated/effects.json +41 -0
  639. package/tailwind/generated/radius.json +20 -0
  640. package/tailwind/generated/typography.json +479 -0
  641. package/tailwind/migrate-tokens-v2.js +453 -0
  642. package/tailwind/migrate-tokens-v2.test.js +55 -0
  643. package/tailwind/plugin.js +220 -15
  644. package/tailwind/preset.js +15 -0
  645. package/tailwind/tokens.js +35 -37
  646. package/tsconfig.base.json +2 -2
  647. package/vitepress/components/Docs/CommandPalette.vue +214 -0
  648. package/vitepress/components/Docs/Demo.vue +60 -0
  649. package/vitepress/components/Docs/EmitsTable.vue +99 -0
  650. package/vitepress/components/Docs/MobileNavSheet.vue +148 -0
  651. package/vitepress/components/Docs/OnThisPage.vue +74 -0
  652. package/vitepress/components/Docs/PrevNextBtns.vue +58 -0
  653. package/vitepress/components/Docs/PropsTable.vue +185 -0
  654. package/vitepress/components/Docs/Search.vue +34 -0
  655. package/vitepress/components/Docs/Sidebar.vue +91 -0
  656. package/vitepress/components/Docs/SlotsTable.vue +99 -0
  657. package/vitepress/components/Docs/index.ts +13 -0
  658. package/vitepress/components/Docs/sidebarList.ts +33 -0
  659. package/vitepress/components/Layout.vue +58 -0
  660. package/vitepress/components/Navbar.vue +126 -0
  661. package/vitepress/components/index.ts +3 -0
  662. package/vitepress/composables/index.ts +3 -0
  663. package/vitepress/composables/useTheme.ts +39 -0
  664. package/vitepress/css/fonts/Inter-Italic.var.woff2 +0 -0
  665. package/vitepress/css/fonts/Inter.var.woff2 +0 -0
  666. package/vitepress/css/style.css +198 -0
  667. package/vitepress/index.d.ts +23 -0
  668. package/vitepress/index.node.ts +175 -0
  669. package/vitepress/index.ts +17 -0
  670. package/vitepress/plugins/colocatedComponentDocs.ts +164 -0
  671. package/vitepress/plugins/componentTransformer.ts +286 -0
  672. package/vitepress/plugins/index.ts +12 -0
  673. package/vitepress/state.ts +10 -0
  674. package/vitepress/theme/index.ts +21 -0
  675. package/frappe/telemetry/utils.ts +0 -15
  676. package/src/components/Badge/stories/Themes.vue +0 -10
  677. package/src/components/Badge/stories/Variants.vue +0 -10
  678. package/src/components/Button/stories/Icons.vue +0 -27
  679. package/src/components/Button/stories/Sizes.vue +0 -11
  680. package/src/components/Button/stories/Themes.vue +0 -10
  681. package/src/components/Button/stories/Variants.vue +0 -10
  682. package/src/components/Popover/stories/Hover.vue +0 -14
  683. package/src/components/Resource.vue +0 -21
  684. package/src/components/Sidebar/stories/Example.vue +0 -76
  685. package/src/components/Spinner.vue +0 -3
  686. package/src/components/TabButtons/TabButtons.story.vue +0 -22
  687. package/src/utils/plugin.js +0 -24
  688. /package/src/components/Dropdown/stories/{02_Shortcuts.vue → Shortcuts.vue} +0 -0
  689. /package/src/components/Dropdown/stories/{01_Simple.vue → Simple.vue} +0 -0
  690. /package/src/components/Dropdown/stories/{03_Submenus.vue → Submenus.vue} +0 -0
  691. /package/src/components/Dropdown/stories/{04_Switches.vue → Switches.vue} +0 -0
  692. /package/src/components/{Dropdown/DropdownRenderContentAsChild.vue → Menu/MenuRenderContentAsChild.vue} +0 -0
@@ -0,0 +1,203 @@
1
+ import { computed, reactive, type Ref } from 'vue'
2
+ import type {
3
+ DropInfo,
4
+ DropPosition,
5
+ MoveContext,
6
+ TreeKey,
7
+ TreeNode,
8
+ } from './types'
9
+
10
+ interface DragDropOptions {
11
+ keyOf: (node: TreeNode) => TreeKey
12
+ childrenOf: (node: TreeNode) => TreeNode[]
13
+ /** Siblings of a node — a parent's children, or the roots for top level. */
14
+ siblingsOf: (parent: TreeNode | null) => TreeNode[]
15
+ labelOf: (node: TreeNode) => string
16
+ disabled: Ref<boolean>
17
+ /** Live predicate gating a hovered drop target. */
18
+ move?: (ctx: MoveContext) => boolean
19
+ /** A drag was picked up. */
20
+ emitDragStart: (node: TreeNode) => void
21
+ /** A drag finished — `info` on a committed move, `null` on cancel. */
22
+ emitDragEnd: (info: DropInfo | null) => void
23
+ /** Announce drag state changes to assistive tech. */
24
+ announce: (message: string) => void
25
+ }
26
+
27
+ interface DragState {
28
+ source: TreeNode | null
29
+ sourceParent: TreeNode | null
30
+ target: TreeNode | null
31
+ position: DropPosition | null
32
+ x: number
33
+ y: number
34
+ }
35
+
36
+ /**
37
+ * Owns the live drag state and resolves + validates drops for the tree.
38
+ * Pure logic — it never mutates `nodes`; it hands the caller a `DropInfo` via
39
+ * `drag-end` and lets them persist and update the model.
40
+ */
41
+ export function useTreeDragDrop(options: DragDropOptions) {
42
+ const { keyOf, childrenOf, siblingsOf, disabled, move } = options
43
+
44
+ const state = reactive<DragState>({
45
+ source: null,
46
+ sourceParent: null,
47
+ target: null,
48
+ position: null,
49
+ x: 0,
50
+ y: 0,
51
+ })
52
+
53
+ // Resolved on a valid drop, emitted on the following `dragend`.
54
+ let pending: DropInfo | null = null
55
+
56
+ function isDescendant(node: TreeNode, key: TreeKey): boolean {
57
+ const stack = [...childrenOf(node)]
58
+ while (stack.length) {
59
+ const current = stack.pop() as TreeNode
60
+ if (keyOf(current) === key) return true
61
+ stack.push(...childrenOf(current))
62
+ }
63
+ return false
64
+ }
65
+
66
+ /** Resolve where the cursor sits within a row into a drop position. */
67
+ function resolvePosition(e: DragEvent): DropPosition {
68
+ const row = e.currentTarget as HTMLElement
69
+ const rect = row.getBoundingClientRect()
70
+ const offset = e.clientY - rect.top
71
+ if (offset < rect.height * 0.25) return 'before'
72
+ if (offset > rect.height * 0.75) return 'after'
73
+ return 'inside'
74
+ }
75
+
76
+ /** Whether a drop of `source` onto `target` at `position` is permitted. */
77
+ function isValidDrop(
78
+ source: TreeNode,
79
+ target: TreeNode,
80
+ position: DropPosition,
81
+ ): boolean {
82
+ const sourceKey = keyOf(source)
83
+ const targetKey = keyOf(target)
84
+ if (sourceKey === targetKey) return false
85
+ if (isDescendant(source, targetKey)) return false
86
+ // Re-parenting onto the node's current parent is a no-op.
87
+ if (
88
+ position === 'inside' &&
89
+ state.sourceParent &&
90
+ keyOf(state.sourceParent) === targetKey
91
+ )
92
+ return false
93
+ if (move && !move({ node: source, target, position })) return false
94
+ return true
95
+ }
96
+
97
+ function onDragStart(
98
+ e: DragEvent,
99
+ node: TreeNode,
100
+ parent: TreeNode | null,
101
+ ): void {
102
+ if (disabled.value) return
103
+ state.source = node
104
+ state.sourceParent = parent
105
+ pending = null
106
+ if (e.dataTransfer) {
107
+ e.dataTransfer.effectAllowed = 'move'
108
+ e.dataTransfer.setData('text/plain', String(keyOf(node)))
109
+ }
110
+ options.emitDragStart(node)
111
+ options.announce(`Picked up ${options.labelOf(node)}`)
112
+ }
113
+
114
+ function onDragOver(e: DragEvent, node: TreeNode): void {
115
+ if (!state.source || disabled.value) return
116
+ const position = resolvePosition(e)
117
+ state.x = e.clientX
118
+ state.y = e.clientY
119
+ if (isValidDrop(state.source, node, position)) {
120
+ state.target = node
121
+ state.position = position
122
+ if (e.dataTransfer) e.dataTransfer.dropEffect = 'move'
123
+ } else {
124
+ state.target = null
125
+ state.position = null
126
+ if (e.dataTransfer) e.dataTransfer.dropEffect = 'none'
127
+ }
128
+ }
129
+
130
+ function onDragLeave(node: TreeNode): void {
131
+ if (state.target && keyOf(state.target) === keyOf(node)) {
132
+ state.target = null
133
+ state.position = null
134
+ }
135
+ }
136
+
137
+ function onDrop(target: TreeNode, targetParent: TreeNode | null): void {
138
+ const source = state.source
139
+ const position = state.position
140
+ if (!source || !position || !state.target) return
141
+ if (keyOf(state.target) !== keyOf(target)) return
142
+
143
+ const from = state.sourceParent ? keyOf(state.sourceParent) : null
144
+ const oldSiblings = siblingsOf(state.sourceParent)
145
+ const oldIndex = oldSiblings.findIndex((n) => keyOf(n) === keyOf(source))
146
+
147
+ let to: TreeKey | null
148
+ let newIndex: number
149
+
150
+ if (position === 'inside') {
151
+ to = keyOf(target)
152
+ newIndex = childrenOf(target).length
153
+ } else {
154
+ to = targetParent ? keyOf(targetParent) : null
155
+ const siblings = siblingsOf(targetParent)
156
+ const targetIndex = siblings.findIndex((n) => keyOf(n) === keyOf(target))
157
+ let insertIndex = position === 'before' ? targetIndex : targetIndex + 1
158
+ // When reordering within the same parent, the source still occupies a
159
+ // slot in `siblings`. Removing it first shifts later positions down by
160
+ // one, so the reported `newIndex` is the final post-removal position.
161
+ if (from === to && oldIndex > -1 && oldIndex < insertIndex)
162
+ insertIndex -= 1
163
+ newIndex = insertIndex
164
+ }
165
+
166
+ pending = { node: source, from, to, position, oldIndex, newIndex }
167
+ options.announce(`Moved ${options.labelOf(source)}`)
168
+ }
169
+
170
+ function reset(): void {
171
+ state.source = null
172
+ state.sourceParent = null
173
+ state.target = null
174
+ state.position = null
175
+ }
176
+
177
+ function onDragEnd(): void {
178
+ if (!pending && state.source) options.announce('Cancelled move')
179
+ options.emitDragEnd(pending)
180
+ pending = null
181
+ reset()
182
+ }
183
+
184
+ const dragSourceKey = computed(() =>
185
+ state.source ? keyOf(state.source) : null,
186
+ )
187
+ const dropTargetKey = computed(() =>
188
+ state.target ? keyOf(state.target) : null,
189
+ )
190
+ const dropPosition = computed(() => state.position)
191
+
192
+ return {
193
+ state,
194
+ dragSourceKey,
195
+ dropTargetKey,
196
+ dropPosition,
197
+ onDragStart,
198
+ onDragOver,
199
+ onDragLeave,
200
+ onDrop,
201
+ onDragEnd,
202
+ }
203
+ }
@@ -0,0 +1,109 @@
1
+ import type { Ref } from 'vue'
2
+ import type { TreeKey, TreeNode } from './types'
3
+
4
+ /** One visible (un-collapsed) row, in render order. */
5
+ export interface FlatNode {
6
+ key: TreeKey
7
+ node: TreeNode
8
+ parentKey: TreeKey | null
9
+ level: number
10
+ hasChildren: boolean
11
+ expanded: boolean
12
+ }
13
+
14
+ interface KeyboardOptions {
15
+ /** Visible rows in render order; recomputed as expansion changes. */
16
+ flat: Ref<FlatNode[]>
17
+ focusedKey: Ref<TreeKey | null>
18
+ labelOf: (node: TreeNode) => string
19
+ focus: (key: TreeKey) => void
20
+ expand: (node: TreeNode) => void
21
+ collapse: (node: TreeNode) => void
22
+ toggle: (node: TreeNode) => void
23
+ }
24
+
25
+ /**
26
+ * Roving-focus keyboard navigation for the tree, following the WAI-ARIA
27
+ * Tree View pattern (P12). Operates on the flattened list of visible rows.
28
+ */
29
+ export function useTreeKeyboard(options: KeyboardOptions) {
30
+ const { flat, focusedKey, focus, expand, collapse, toggle } = options
31
+
32
+ let typeahead = ''
33
+ let typeaheadTimer: ReturnType<typeof setTimeout> | null = null
34
+
35
+ const indexOfFocused = () =>
36
+ flat.value.findIndex((f) => f.key === focusedKey.value)
37
+
38
+ function focusAt(index: number): void {
39
+ const item = flat.value[index]
40
+ if (item) focus(item.key)
41
+ }
42
+
43
+ function moveToParent(current: FlatNode): void {
44
+ if (current.parentKey == null) return
45
+ focus(current.parentKey)
46
+ }
47
+
48
+ function typeaheadSearch(char: string): void {
49
+ if (typeaheadTimer) clearTimeout(typeaheadTimer)
50
+ typeahead += char.toLowerCase()
51
+ typeaheadTimer = setTimeout(() => (typeahead = ''), 500)
52
+
53
+ const start = Math.max(indexOfFocused(), 0)
54
+ const ordered = [
55
+ ...flat.value.slice(start + 1),
56
+ ...flat.value.slice(0, start + 1),
57
+ ]
58
+ const match = ordered.find((f) =>
59
+ options.labelOf(f.node).toLowerCase().startsWith(typeahead),
60
+ )
61
+ if (match) focus(match.key)
62
+ }
63
+
64
+ function onKeydown(e: KeyboardEvent): void {
65
+ const index = indexOfFocused()
66
+ const current = flat.value[index]
67
+ if (!current && !['Home', 'End'].includes(e.key)) return
68
+
69
+ switch (e.key) {
70
+ case 'ArrowDown':
71
+ e.preventDefault()
72
+ focusAt(Math.min(index + 1, flat.value.length - 1))
73
+ break
74
+ case 'ArrowUp':
75
+ e.preventDefault()
76
+ focusAt(Math.max(index - 1, 0))
77
+ break
78
+ case 'ArrowRight':
79
+ e.preventDefault()
80
+ if (current.hasChildren && !current.expanded) expand(current.node)
81
+ else if (current.hasChildren && current.expanded) focusAt(index + 1)
82
+ break
83
+ case 'ArrowLeft':
84
+ e.preventDefault()
85
+ if (current.hasChildren && current.expanded) collapse(current.node)
86
+ else moveToParent(current)
87
+ break
88
+ case 'Home':
89
+ e.preventDefault()
90
+ focusAt(0)
91
+ break
92
+ case 'End':
93
+ e.preventDefault()
94
+ focusAt(flat.value.length - 1)
95
+ break
96
+ case 'Enter':
97
+ case ' ':
98
+ e.preventDefault()
99
+ toggle(current.node)
100
+ break
101
+ default:
102
+ if (e.key.length === 1 && !e.metaKey && !e.ctrlKey && !e.altKey) {
103
+ typeaheadSearch(e.key)
104
+ }
105
+ }
106
+ }
107
+
108
+ return { onKeydown }
109
+ }
@@ -31,7 +31,7 @@
31
31
  :max-w="l.maxW"
32
32
  :max-h="l.maxH"
33
33
  >
34
- <pre class="h-full w-full rounded bg-surface-white p-4 shadow">{{
34
+ <pre class="h-full w-full rounded bg-surface-base p-4 shadow">{{
35
35
  {
36
36
  i: l.i,
37
37
  x: l.x,
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <PopoverRoot v-model:open="open">
3
3
  <PopoverAnchor :reference="anchorEl" as-child>
4
- <div @keydown.down.prevent="onArrowDown">
4
+ <div v-bind="$attrs" @keydown.down.prevent="onArrowDown">
5
5
  <slot name="trigger" v-bind="triggerSlotProps">
6
6
  <slot name="target" v-bind="triggerSlotProps">
7
7
  <TextInput
@@ -44,7 +44,6 @@
44
44
  <PopoverPortal>
45
45
  <PopoverContent
46
46
  data-slot="content"
47
- data-selection
48
47
  class="z-[100]"
49
48
  :side="side"
50
49
  :align="align"
@@ -52,15 +51,14 @@
52
51
  @open-auto-focus.prevent
53
52
  @interact-outside="onInteractOutside"
54
53
  >
55
- <div
56
- ref="popoverContentRef"
57
- data-slot="content-body"
58
- :data-motion="motion"
54
+ <PopoverPanel
55
+ ref="popoverPanelRef"
56
+ :motion="motion"
59
57
  :class="contentClass"
60
- style="transform-origin: var(--reka-popover-content-transform-origin)"
58
+ class="origin-[var(--reka-popover-content-transform-origin)]"
61
59
  >
62
60
  <slot :close="closePopover" />
63
- </div>
61
+ </PopoverPanel>
64
62
  </PopoverContent>
65
63
  </PopoverPortal>
66
64
  </PopoverRoot>
@@ -76,10 +74,10 @@ import {
76
74
  } from 'reka-ui'
77
75
  import { TextInput } from '../../TextInput'
78
76
  import LucideChevronDown from '~icons/lucide/chevron-down'
77
+ import PopoverPanel from '../popover/PopoverPanel.vue'
79
78
  import { usePopoverMotion } from '../../../composables/usePopoverMotion'
80
79
  import type { InputSize, InputVariant } from '../../../composables/inputTypes'
81
80
  import type { FrappeUIError } from '../../../composables/useInputLabeling'
82
- import '../selection/popoverMotion.css'
83
81
 
84
82
  interface Props {
85
83
  // Positioning — already resolved by caller from side/align/placement.
@@ -107,7 +105,9 @@ interface Props {
107
105
  // Display label exposed via trigger slot props for caller-rendered triggers.
108
106
  displayLabel?: string
109
107
 
110
- // Tailwind class string for the popover content body wrapper.
108
+ // Extra Tailwind classes (layout/sizing such as `w-56`/`w-fit`) merged onto
109
+ // the `PopoverPanel` shell. The elevated shell itself (rounded/bg/shadow/ring)
110
+ // is owned by `PopoverPanel`, so callers no longer pass those here.
111
111
  contentClass?: string
112
112
  }
113
113
 
@@ -145,6 +145,8 @@ const slots = defineSlots<{
145
145
  default?: (props: { close: () => void }) => any
146
146
  }>()
147
147
 
148
+ defineOptions({ inheritAttrs: false })
149
+
148
150
  const open = defineModel<boolean>('open', { default: false })
149
151
  const inputValue = defineModel<string>('inputValue', { default: '' })
150
152
  const typing = defineModel<boolean>('typing', { default: false })
@@ -159,7 +161,12 @@ interface TriggerSlotProps {
159
161
  // Anchor the popover at the input element itself (not the labeling wrapper),
160
162
  // so it sits below the input rather than below the description text.
161
163
  const textInputRef = ref<{ el: HTMLElement | null } | null>(null)
162
- const popoverContentRef = ref<HTMLElement | null>(null)
164
+ const popoverPanelRef = ref<{ $el: HTMLElement } | null>(null)
165
+
166
+ // PopoverPanel renders a single root <div>, so its `$el` is the panel element
167
+ // we test focus containment against (Esc / selection should restore trigger
168
+ // focus; click-outside should not).
169
+ const panelEl = computed(() => popoverPanelRef.value?.$el ?? null)
163
170
 
164
171
  const anchorEl = computed(() => {
165
172
  if (slots.trigger || slots.target) return undefined
@@ -208,7 +215,7 @@ function onClick(e: MouseEvent) {
208
215
  function onBlur(e: FocusEvent) {
209
216
  // Clicks inside the popover panel re-focus options; treat those as still-focused.
210
217
  const next = e.relatedTarget as Node | null
211
- if (next && popoverContentRef.value?.contains(next)) return
218
+ if (next && panelEl.value?.contains(next)) return
212
219
  emit('blur')
213
220
  typing.value = false
214
221
  }
@@ -246,9 +253,7 @@ watch(open, (val, prev) => {
246
253
  // Restore focus to the trigger input if the popover content had focus
247
254
  // (Esc, date selection in auto-close mode). Click-outside leaves focus
248
255
  // on the clicked element, so we skip in that case.
249
- const hadFocusInside = popoverContentRef.value?.contains(
250
- document.activeElement,
251
- )
256
+ const hadFocusInside = panelEl.value?.contains(document.activeElement)
252
257
  emit('close')
253
258
  if (hadFocusInside) {
254
259
  nextTick(() => textInputRef.value?.el?.focus())
@@ -0,0 +1,67 @@
1
+ <template>
2
+ <div
3
+ data-slot="content-body"
4
+ data-panel
5
+ :data-motion="motion"
6
+ :data-state="state"
7
+ :class="shellClass"
8
+ >
9
+ <slot />
10
+ </div>
11
+ </template>
12
+
13
+ <script setup lang="ts">
14
+ /**
15
+ * Shared floating-panel shell for popover-style surfaces (Popover, Select,
16
+ * Combobox, DatePicker, TimePicker, …).
17
+ *
18
+ * It owns ONLY two things:
19
+ * 1. the visual shell — `rounded-lg bg-surface-elevation-2 shadow-2xl
20
+ * ring-1 ring-black ring-opacity-5` — matching what the selection family
21
+ * renders today, plus the `data-slot="content-body"` hook, and
22
+ * 2. the open/close motion wiring (`data-motion` + the co-located
23
+ * `popoverPanel.css`, supporting both the `animated` scale-from-trigger
24
+ * rhythm and the `instant` keyboard/Dropdown rhythm).
25
+ *
26
+ * It owns NO behavior and NO reka root: render it INSIDE a reka
27
+ * `PopoverContent` / `SelectContent` / `ComboboxContent` / `DropdownMenuContent`
28
+ * (or directly). Each consumer keeps its own reka `*Root`, `*Portal`,
29
+ * `*Content`, `FocusScope` and a11y wiring, and renders its contents in the
30
+ * default slot.
31
+ *
32
+ * It is a thin pass-through: Vue auto-merges any `class`/`style`/attrs onto the
33
+ * single root, so consumers add layout (flex/grid/divide/min-w) and the
34
+ * per-primitive `transform-origin` without losing the shell classes.
35
+ */
36
+ import './popoverPanel.css'
37
+
38
+ withDefaults(
39
+ defineProps<{
40
+ /**
41
+ * Open/close rhythm:
42
+ * - `'animated'` (default): pointer opens → scale-from-trigger entrance.
43
+ * - `'instant'`: keyboard / programmatic opens → ~80ms opacity fade only.
44
+ * Drive this from `usePopoverMotion(open).motion`.
45
+ */
46
+ motion?: 'animated' | 'instant'
47
+ /**
48
+ * The reka content's `data-state`, forwarded onto the panel element so the
49
+ * co-located motion CSS is self-contained. Omit when the parent reka
50
+ * `*Content` already exposes `data-state` and you rely on reka's own state
51
+ * (the motion CSS matches an ancestor `[data-state]` too).
52
+ */
53
+ state?: 'open' | 'closed'
54
+ }>(),
55
+ {
56
+ motion: 'animated',
57
+ },
58
+ )
59
+
60
+ defineSlots<{ default?: () => any }>()
61
+
62
+ // The standard elevated floating-panel shell. Kept verbatim in sync with the
63
+ // selection family's `content-body` so every popover surface shares one look.
64
+ // Consumer `class` (layout, transform-origin) auto-merges after this.
65
+ const shellClass =
66
+ 'overflow-hidden rounded-lg bg-surface-elevation-2 shadow-2xl ring-1 ring-black ring-opacity-5 will-change-[opacity,transform]'
67
+ </script>
@@ -0,0 +1,102 @@
1
+ /*
2
+ * Open/close motion for the shared `PopoverPanel` shell. Imported once by
3
+ * `PopoverPanel.vue` so it is deduped at build time — consumers never import
4
+ * it directly.
5
+ *
6
+ * Every selector is gated on the compound `[data-slot='content-body'][data-panel]`
7
+ * so this stylesheet only applies to `PopoverPanel` instances and cannot leak
8
+ * onto other popovers sharing the `data-slot` hooks (e.g. Dropdown's
9
+ * `.menu-content`, or the legacy selection `popoverMotion.css`).
10
+ *
11
+ * `data-state` is read from one of two places, so the panel is drop-in for
12
+ * either wiring style:
13
+ * 1. the panel element itself, when the consumer passes the `state` prop
14
+ * (fully self-contained — preferred for new code), or
15
+ * 2. an ancestor reka `*Content` carrying `data-state`, when the consumer
16
+ * omits `state` and relies on reka's own state (matches how the legacy
17
+ * selection stylesheet worked).
18
+ * `data-motion` always lives on the panel element.
19
+ *
20
+ * `transform-origin` is intentionally NOT set here — each consumer owns it
21
+ * (Popover uses `--reka-popover-content-transform-origin`, Select the
22
+ * `--reka-select-*` var, Combobox the `--reka-combobox-*` var) by passing it
23
+ * through `class`/`style` on the panel.
24
+ *
25
+ * Two rhythms, selected by `data-motion`:
26
+ * - `animated` — scale-from-trigger entrance (pointer opens), 180ms enter /
27
+ * 140ms exit.
28
+ * - `instant` — keyboard / programmatic opens skip the scale + translate; a
29
+ * ~80ms opacity fade still runs on open to mask reka's 1-frame
30
+ * position-settle after mount, and no animation on close.
31
+ */
32
+
33
+ [data-slot='content-body'][data-panel] {
34
+ animation-fill-mode: both;
35
+ }
36
+
37
+ [data-slot='content-body'][data-panel][data-motion='animated'] {
38
+ backface-visibility: hidden;
39
+ }
40
+
41
+ /* (1) state on the panel itself (via the `state` prop) */
42
+ [data-slot='content-body'][data-panel][data-motion='animated'][data-state='open'],
43
+ /* (2) state on an ancestor reka *Content */
44
+ [data-state='open']
45
+ [data-slot='content-body'][data-panel][data-motion='animated'] {
46
+ animation: popover-panel-enter 180ms cubic-bezier(0.23, 1, 0.32, 1);
47
+ }
48
+
49
+ [data-slot='content-body'][data-panel][data-motion='animated'][data-state='closed'],
50
+ [data-state='closed']
51
+ [data-slot='content-body'][data-panel][data-motion='animated'] {
52
+ animation: popover-panel-exit 140ms cubic-bezier(0.23, 1, 0.32, 1);
53
+ }
54
+
55
+ [data-slot='content-body'][data-panel][data-motion='instant'][data-state='open'],
56
+ [data-state='open']
57
+ [data-slot='content-body'][data-panel][data-motion='instant'] {
58
+ animation: popover-panel-instant-fade 80ms linear;
59
+ }
60
+
61
+ [data-slot='content-body'][data-panel][data-motion='instant'][data-state='closed'],
62
+ [data-state='closed']
63
+ [data-slot='content-body'][data-panel][data-motion='instant'] {
64
+ animation: none;
65
+ }
66
+
67
+ @keyframes popover-panel-enter {
68
+ from {
69
+ opacity: 0;
70
+ transform: translateY(2px) scale(0.97);
71
+ }
72
+ to {
73
+ opacity: 1;
74
+ transform: translateY(0) scale(1);
75
+ }
76
+ }
77
+
78
+ @keyframes popover-panel-exit {
79
+ from {
80
+ opacity: 1;
81
+ transform: translateY(0) scale(1);
82
+ }
83
+ to {
84
+ opacity: 0;
85
+ transform: translateY(1px) scale(0.985);
86
+ }
87
+ }
88
+
89
+ @keyframes popover-panel-instant-fade {
90
+ from {
91
+ opacity: 0;
92
+ }
93
+ to {
94
+ opacity: 1;
95
+ }
96
+ }
97
+
98
+ @media (prefers-reduced-motion: reduce) {
99
+ [data-slot='content-body'][data-panel] {
100
+ animation-duration: 0ms !important;
101
+ }
102
+ }
@@ -25,7 +25,7 @@ export function inputFontSizeClasses(size: SelectionSize) {
25
25
  sm: 'text-base',
26
26
  md: 'text-base',
27
27
  lg: 'text-lg',
28
- xl: 'text-xl',
28
+ xl: 'text-2xl',
29
29
  }[size]
30
30
  }
31
31
 
@@ -56,9 +56,9 @@ export function triggerVariantClasses(
56
56
 
57
57
  return {
58
58
  subtle:
59
- 'border border-[--surface-gray-2] bg-surface-gray-2 hover:border-outline-gray-modals hover:bg-surface-gray-3',
59
+ 'border border-[--surface-gray-2] bg-surface-gray-2 hover:border-outline-elevation-2 hover:bg-surface-gray-3',
60
60
  outline:
61
- 'border border-outline-gray-2 bg-surface-white hover:border-outline-gray-3',
61
+ 'border border-outline-gray-2 bg-surface-base hover:border-outline-gray-3',
62
62
  ghost:
63
63
  'border border-transparent bg-transparent hover:bg-surface-gray-3 focus-within:bg-surface-gray-3',
64
64
  }[variant]
@@ -70,13 +70,13 @@ export function triggerVariantClasses(
70
70
  * on the trigger itself.
71
71
  */
72
72
  export const triggerBaseClassesFocusVisible =
73
- 'relative inline-flex items-center gap-2 text-left text-ink-gray-7 outline-none transition-[background-color,border-color,box-shadow] duration-150 ease-[cubic-bezier(0.23,1,0.32,1)] focus-visible:ring-2 data-[state=open]:ring-2 ring-outline-gray-3'
73
+ 'relative inline-flex items-center gap-2 text-left text-ink-gray-7 transition-[background-color,border-color,box-shadow] duration-150 ease-[cubic-bezier(0.23,1,0.32,1)] data-[state=open]:focus-ring'
74
74
 
75
75
  export const triggerBaseClassesFocusWithin =
76
- 'relative inline-flex items-center gap-2 text-left text-ink-gray-7 outline-none transition-[background-color,border-color,box-shadow] duration-150 ease-[cubic-bezier(0.23,1,0.32,1)] focus-within:ring-2 data-[state=open]:ring-2 ring-outline-gray-3'
76
+ 'relative inline-flex items-center gap-2 text-left text-ink-gray-7 outline-none transition-[background-color,border-color,box-shadow] duration-150 ease-[cubic-bezier(0.23,1,0.32,1)] focus-within:focus-ring data-[state=open]:focus-ring'
77
77
 
78
78
  export const itemClasses =
79
- 'select-none rounded border-0 text-base text-ink-gray-9 transition-colors duration-100 ease-out data-[disabled]:text-ink-gray-4 data-[highlighted]:bg-surface-gray-2 data-[state=checked]:bg-surface-gray-3 data-[highlighted]:data-[state=checked]:bg-surface-gray-4'
79
+ 'select-none rounded border-0 text-base text-ink-gray-9 transition-colors duration-100 ease-out data-[disabled]:text-ink-gray-4 data-[highlighted]:bg-surface-alpha-gray-2 data-[state=checked]:bg-surface-gray-3 data-[highlighted]:data-[state=checked]:bg-surface-gray-4'
80
80
 
81
81
  /**
82
82
  * Case-insensitive substring match against an option's label and value.
@@ -41,6 +41,8 @@ export function useAutofocusOnOpen(
41
41
  isOpen: MaybeRefOrGetter<boolean>,
42
42
  getContainer: () => HTMLElement | null | undefined,
43
43
  ) {
44
+ if (typeof window === 'undefined') return
45
+
44
46
  watch(
45
47
  () => toValue(isOpen),
46
48
  async (open) => {
@@ -0,0 +1,46 @@
1
+ import { computed, onMounted, onUnmounted, reactive, type ComputedRef } from 'vue'
2
+
3
+ const hasWindow = typeof window !== 'undefined'
4
+
5
+ export interface ScreenSize {
6
+ width: number
7
+ height: number
8
+ }
9
+
10
+ /**
11
+ * Reactive viewport size, updated on window resize.
12
+ *
13
+ * Falls back to a desktop-ish size when there's no window (SSR / non-browser
14
+ * test env) so a `useIsMobile()` derived from it doesn't flash the mobile
15
+ * layout before hydration.
16
+ */
17
+ export function useScreenSize(): ScreenSize {
18
+ const size = reactive<ScreenSize>({
19
+ width: hasWindow ? window.innerWidth : 1024,
20
+ height: hasWindow ? window.innerHeight : 768,
21
+ })
22
+
23
+ const onResize = () => {
24
+ size.width = window.innerWidth
25
+ size.height = window.innerHeight
26
+ }
27
+
28
+ onMounted(() => {
29
+ if (hasWindow) window.addEventListener('resize', onResize)
30
+ })
31
+ onUnmounted(() => {
32
+ if (hasWindow) window.removeEventListener('resize', onResize)
33
+ })
34
+
35
+ return size
36
+ }
37
+
38
+ /**
39
+ * Whether the viewport is narrower than `breakpoint` (default 640px — Tailwind's
40
+ * `sm`). Reactive; apps typically use it to choose between a desktop and a
41
+ * mobile shell.
42
+ */
43
+ export function useIsMobile(breakpoint = 640): ComputedRef<boolean> {
44
+ const size = useScreenSize()
45
+ return computed(() => size.width < breakpoint)
46
+ }