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,23 @@
1
+ // Combined type surface for `frappe-ui/vitepress`.
2
+ //
3
+ // At runtime the package resolves to two different files by export condition:
4
+ // `index.node.ts` (the Node config builder) for VitePress' config loader, and
5
+ // `index.ts` (the browser barrel: theme + components) for Vue code. TypeScript,
6
+ // however, doesn't apply the `node` condition — it would otherwise only ever
7
+ // see the browser half and flag `defineDocsConfig` as missing in config files.
8
+ //
9
+ // This declaration (wired as the `types` condition) merges both surfaces so
10
+ // editors resolve the full API regardless of context. The node-only names are
11
+ // disjoint from the browser names, so there are no `export *` collisions.
12
+ export * from './index'
13
+ export {
14
+ defineDocsConfig,
15
+ syncColocatedComponentDocs,
16
+ colocatedComponentDocs,
17
+ componentTransformer,
18
+ createComponentTransformer,
19
+ } from './index.node'
20
+ export type {
21
+ DefineDocsConfigOptions,
22
+ DocsThemeConfig,
23
+ } from './index.node'
@@ -0,0 +1,175 @@
1
+ import path from 'node:path'
2
+ import fs from 'node:fs'
3
+ import { fileURLToPath } from 'node:url'
4
+ import { defineConfig, type DefaultTheme, type UserConfig } from 'vitepress'
5
+ import { transformerStyleToClass } from '@shikijs/transformers'
6
+ // @ts-ignore — JS package without bundled types
7
+ import { lucideIcons } from 'frappe-ui/vite'
8
+
9
+ import { createComponentTransformer } from './plugins/componentTransformer.ts'
10
+ import colocatedComponentDocs from './plugins/colocatedComponentDocs.ts'
11
+ import type { SidebarSection } from './components/Docs/sidebarList.ts'
12
+
13
+ // frappe-ui package root — this file lives at <root>/vitepress/index.node.ts.
14
+ const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
15
+
16
+ type HeadConfig = NonNullable<UserConfig['head']>[number]
17
+
18
+ // Extends the default theme with the extra fields the shared Sidebar reads.
19
+ export interface DocsThemeConfig extends DefaultTheme.Config {
20
+ name?: string
21
+ version?: string
22
+ githubUrl?: string
23
+ sections?: SidebarSection[]
24
+ }
25
+
26
+ export interface DefineDocsConfigOptions {
27
+ // Consumer project root (the docs dir). Drives every absolute path:
28
+ // vite resolve.alias, plugin sourceRoots, shiki cache.
29
+ rootDir: string
30
+ name: string
31
+ description: string
32
+ base?: string
33
+ githubUrl?: string
34
+ logo?: string
35
+ version?: string
36
+ // Data-driven IA tree rendered by the shared Sidebar.
37
+ sidebar: SidebarSection[]
38
+ // Merged with generated OG/Twitter defaults.
39
+ head?: HeadConfig[]
40
+ // Absolute source roots for component story/types snippet resolution.
41
+ sourceRoots?: string[]
42
+ // Opt-in: generate @include proxy pages for colocated component docs.
43
+ // `true` uses rootDir defaults; pass options to customize. Off by default
44
+ // since most consumers don't have the frappe-ui component/frappe layout.
45
+ colocatedDocs?: Parameters<typeof colocatedComponentDocs>[0] | boolean
46
+ // Extra resolve.alias entries (merged over rootDir-relative defaults).
47
+ alias?: Record<string, string>
48
+ // Hook for extra markdown-it plugins.
49
+ markdownConfig?: (md: any) => void
50
+ }
51
+
52
+ function generatedHead(name: string, description: string): HeadConfig[] {
53
+ return [
54
+ ['meta', { property: 'og:type', content: 'website' }],
55
+ ['meta', { property: 'og:site_name', content: name }],
56
+ ['meta', { property: 'og:title', content: name }],
57
+ ['meta', { property: 'og:description', content: description }],
58
+ ['meta', { name: 'twitter:card', content: 'summary_large_image' }],
59
+ ['meta', { name: 'twitter:title', content: name }],
60
+ ['meta', { name: 'twitter:description', content: description }],
61
+ ]
62
+ }
63
+
64
+ export function defineDocsConfig(
65
+ options: DefineDocsConfigOptions,
66
+ ): UserConfig<DocsThemeConfig> {
67
+ const {
68
+ rootDir,
69
+ name,
70
+ description,
71
+ base = '/',
72
+ githubUrl,
73
+ logo,
74
+ version,
75
+ sidebar,
76
+ head = [],
77
+ sourceRoots = [],
78
+ colocatedDocs = false,
79
+ alias = {},
80
+ markdownConfig,
81
+ } = options
82
+
83
+ const isDev = process.env.NODE_ENV !== 'production'
84
+
85
+ // transformerStyleToClass turns shiki inline styles into classes; its CSS
86
+ // is collected and injected via transformHead below.
87
+ const toClass = transformerStyleToClass({ classPrefix: 's_' })
88
+
89
+ return defineConfig<DocsThemeConfig>({
90
+ base,
91
+ srcDir: 'content',
92
+ cleanUrls: true,
93
+ lastUpdated: true,
94
+ title: name,
95
+ description,
96
+ head: [...generatedHead(name, description), ...head],
97
+ markdown: {
98
+ theme: { dark: 'tokyo-night', light: 'github-light' },
99
+ // In dev, transformerStyleToClass flushes only at buildEnd, so let
100
+ // shiki emit inline --shiki-light/dark vars instead.
101
+ codeTransformers: isDev ? [] : [toClass],
102
+ config(md) {
103
+ md.use(createComponentTransformer({ sourceRoots }))
104
+ markdownConfig?.(md)
105
+ },
106
+ },
107
+ themeConfig: {
108
+ // Consumed by the shared Sidebar/Navbar (SSR-safe; no package.json read).
109
+ name,
110
+ logo,
111
+ version,
112
+ githubUrl,
113
+ sidebar,
114
+ sections: sidebar,
115
+ // Enables VitePress' local search index, rendered by the shared Search.
116
+ search: { provider: 'local' },
117
+ },
118
+ vite: {
119
+ plugins: [
120
+ lucideIcons(),
121
+ ...(colocatedDocs
122
+ ? [
123
+ colocatedComponentDocs(
124
+ colocatedDocs === true ? { rootDir } : colocatedDocs,
125
+ ),
126
+ ]
127
+ : []),
128
+ ],
129
+ resolve: {
130
+ alias: {
131
+ '@/components': path.resolve(rootDir, 'components'),
132
+ // Force Vite (client + SSR) to resolve the bare `frappe-ui/vitepress`
133
+ // specifier to the browser barrel — never the Node config entry this
134
+ // file lives in. This sidesteps SSR export-condition ambiguity: the
135
+ // `node` condition only ever serves VitePress' Node config loader.
136
+ 'frappe-ui/vitepress': path.resolve(packageRoot, 'vitepress/index.ts'),
137
+ ...alias,
138
+ },
139
+ },
140
+ // frappe-ui is often a symlink resolving outside the project root (e.g.
141
+ // bundled fonts/assets); allow the dev server to serve from its real dir.
142
+ server: {
143
+ fs: {
144
+ allow: [rootDir, fs.realpathSync(packageRoot)],
145
+ },
146
+ },
147
+ // The shared theme renders frappe-ui during SSR. Bundle frappe-ui and
148
+ // its ESM-only deps (which use extensionless imports Node can't resolve
149
+ // when externalized) into the server build.
150
+ ssr: {
151
+ noExternal: ['frappe-ui', 'dayjs'],
152
+ },
153
+ },
154
+ // Inject shiki's collected CSS into each page's <head>; the production
155
+ // CSS bundle is finalized before markdown runs, so this side-steps timing.
156
+ transformHead: () => {
157
+ const css = toClass.getCSS()
158
+ if (!css) return []
159
+ return [['style', { 'data-shiki': '' }, css]]
160
+ },
161
+ })
162
+ }
163
+
164
+ export type {
165
+ SidebarSection,
166
+ SidebarItem,
167
+ } from './components/Docs/sidebarList.ts'
168
+ export { isActiveLink, getSidebarList } from './components/Docs/sidebarList.ts'
169
+
170
+ // Re-exports for convenience. Explicit .ts extensions keep this entry
171
+ // loadable when externalized by VitePress' Node-based config loader.
172
+ // Vue SFCs are intentionally omitted here — Node can't evaluate them. The
173
+ // browser barrel (index.ts, the `default` export condition) re-exports the
174
+ // components/theme for Vue code.
175
+ export * from './plugins/index.ts'
@@ -0,0 +1,17 @@
1
+ // Browser / SSR barrel for the reusable VitePress docs theme — the
2
+ // `frappe-ui/vitepress` entry as seen by Vue code (theme, components,
3
+ // composables). It pulls in Vue SFCs, so it can only be evaluated by Vite,
4
+ // never by Node's config loader.
5
+ //
6
+ // The config builder (`defineDocsConfig`) lives in the sibling
7
+ // `index.node.ts`, exposed through the package's `node` export condition.
8
+ // Named exports only. Importing `theme` also loads the stylesheet as a side
9
+ // effect (via ./theme), so consumers don't need a separate style.css import.
10
+ export { theme } from './theme'
11
+
12
+ // Shared components (Layout, CommandPalette, Search, Sidebar, …) plus the
13
+ // `isActiveLink` / `getSidebarList` helpers and Sidebar* types.
14
+ export * from './components'
15
+ // Theme composables (useTheme / setTheme).
16
+ export * from './composables'
17
+ export { state } from './state'
@@ -0,0 +1,164 @@
1
+ import fs from 'node:fs'
2
+ import path from 'node:path'
3
+ import type { Plugin, ViteDevServer } from 'vite'
4
+
5
+ // Author-facing layout: each component owns its docs:
6
+ // src/components/Button/Button.md (hand-written)
7
+ // src/components/Button/Button.api.md (auto-generated by propsgen)
8
+ // frappe/Link/Link.md (Frappe-integrated controls)
9
+ //
10
+ // VitePress wants every page under its srcDir (`docs/content`). Instead of
11
+ // reshaping srcDir or rewrites, this plugin keeps a thin proxy file at
12
+ // docs/content/docs/components/<name>.md
13
+ // docs/content/docs/frappe/<name>.md
14
+ // that simply `@include`s the colocated source. The proxy is auto-managed
15
+ // — never edit it by hand.
16
+
17
+ export interface SourceRootMap {
18
+ // Absolute dir holding `<Component>/<Component>.md` source files.
19
+ sourceDir: string
20
+ // Absolute dir where proxy `<name>.md` files are written.
21
+ proxyDir: string
22
+ }
23
+
24
+ export interface ColocatedComponentDocsOptions {
25
+ // Pairs of source/proxy dirs. Takes precedence over `rootDir` defaults.
26
+ sourceRoots?: SourceRootMap[]
27
+ // Consumer project root. Defaults the proxy dirs to
28
+ // `<rootDir>/content/docs/{components,frappe}` and source dirs to
29
+ // `<rootDir>/../src/components` and `<rootDir>/../frappe`.
30
+ rootDir?: string
31
+ }
32
+
33
+ function rootDirRoots(rootDir: string): SourceRootMap[] {
34
+ return [
35
+ {
36
+ sourceDir: path.resolve(rootDir, '../src/components'),
37
+ proxyDir: path.resolve(rootDir, 'content/docs/components'),
38
+ },
39
+ {
40
+ sourceDir: path.resolve(rootDir, '../frappe'),
41
+ proxyDir: path.resolve(rootDir, 'content/docs/frappe'),
42
+ },
43
+ ]
44
+ }
45
+
46
+ function resolveRoots(options: ColocatedComponentDocsOptions): SourceRootMap[] {
47
+ if (options.sourceRoots && options.sourceRoots.length) return options.sourceRoots
48
+ if (options.rootDir) return rootDirRoots(options.rootDir)
49
+ // No legacy in-repo fallback: warn rather than resolve into nonexistent paths.
50
+ console.warn(
51
+ '[colocatedComponentDocs] no sourceRoots or rootDir provided — skipping proxy generation.',
52
+ )
53
+ return []
54
+ }
55
+
56
+ const PROXY_HEADER =
57
+ '<!-- AUTO-GENERATED by colocatedComponentDocs — do not edit. Source: '
58
+
59
+ interface Entry {
60
+ name: string // 'Button'
61
+ source: string // absolute path to src/components/Button/Button.md
62
+ proxy: string // absolute path to docs/content/docs/components/button.md
63
+ proxyDir: string // absolute path to the proxy root that owns this entry
64
+ }
65
+
66
+ function discover(sourceDir: string, proxyDir: string): Entry[] {
67
+ if (!fs.existsSync(sourceDir)) return []
68
+ const entries: Entry[] = []
69
+ for (const name of fs.readdirSync(sourceDir)) {
70
+ const source = path.join(sourceDir, name, `${name}.md`)
71
+ if (!fs.existsSync(source)) continue
72
+ entries.push({
73
+ name,
74
+ source,
75
+ proxy: path.join(proxyDir, `${name.toLowerCase()}.md`),
76
+ proxyDir,
77
+ })
78
+ }
79
+ return entries
80
+ }
81
+
82
+ function proxyContent(entry: Entry) {
83
+ const includePath = path
84
+ .relative(path.dirname(entry.proxy), entry.source)
85
+ .split(path.sep)
86
+ .join('/')
87
+ const sourceRel = path
88
+ .relative(entry.proxyDir, entry.source)
89
+ .split(path.sep)
90
+ .join('/')
91
+ return `${PROXY_HEADER}${sourceRel} -->\n<!-- @include: ${includePath} -->\n`
92
+ }
93
+
94
+ function isManagedProxy(filePath: string) {
95
+ if (!fs.existsSync(filePath)) return false
96
+ const first = fs.readFileSync(filePath, 'utf-8').split('\n', 1)[0] ?? ''
97
+ return first.startsWith(PROXY_HEADER)
98
+ }
99
+
100
+ function writeIfChanged(filePath: string, content: string) {
101
+ if (fs.existsSync(filePath)) {
102
+ const current = fs.readFileSync(filePath, 'utf-8')
103
+ if (current === content) return false
104
+ }
105
+ fs.mkdirSync(path.dirname(filePath), { recursive: true })
106
+ fs.writeFileSync(filePath, content, 'utf-8')
107
+ return true
108
+ }
109
+
110
+ export function syncColocatedComponentDocs(
111
+ options: ColocatedComponentDocsOptions = {},
112
+ ) {
113
+ const roots = resolveRoots(options)
114
+ const allEntries: Entry[] = []
115
+
116
+ for (const { sourceDir, proxyDir } of roots) {
117
+ const entries = discover(sourceDir, proxyDir)
118
+ allEntries.push(...entries)
119
+ const expected = new Set(entries.map((e) => e.proxy))
120
+
121
+ for (const entry of entries) {
122
+ writeIfChanged(entry.proxy, proxyContent(entry))
123
+ }
124
+
125
+ // Remove orphan proxies — only those we created (header check), so
126
+ // hand-written legacy pages like badge.md, legacy.md stay untouched.
127
+ if (fs.existsSync(proxyDir)) {
128
+ for (const name of fs.readdirSync(proxyDir)) {
129
+ const filePath = path.join(proxyDir, name)
130
+ if (expected.has(filePath)) continue
131
+ if (isManagedProxy(filePath)) fs.unlinkSync(filePath)
132
+ }
133
+ }
134
+ }
135
+
136
+ return allEntries
137
+ }
138
+
139
+ export default function colocatedComponentDocs(
140
+ options: ColocatedComponentDocsOptions = {},
141
+ ): Plugin {
142
+ const roots = resolveRoots(options)
143
+ const syncAll = () => syncColocatedComponentDocs(options)
144
+ return {
145
+ name: 'colocated-component-docs',
146
+ enforce: 'pre',
147
+ buildStart() {
148
+ syncAll()
149
+ },
150
+ configureServer(server: ViteDevServer) {
151
+ syncAll()
152
+ const onChange = (file: string) => {
153
+ const matchesRoot = roots.some(({ sourceDir }) =>
154
+ file.startsWith(sourceDir),
155
+ )
156
+ if (!matchesRoot) return
157
+ if (!file.endsWith('.md')) return
158
+ syncAll()
159
+ }
160
+ server.watcher.on('add', onChange)
161
+ server.watcher.on('unlink', onChange)
162
+ },
163
+ }
164
+ }
@@ -0,0 +1,286 @@
1
+ import type { MarkdownEnv, MarkdownRenderer } from 'vitepress'
2
+ import type StateCore from 'markdown-it/lib/rules_core/state_core'
3
+ import { existsSync } from 'node:fs'
4
+ import { dirname, isAbsolute, resolve } from 'node:path'
5
+ import {
6
+ baseParse,
7
+ NodeTypes,
8
+ type AttributeNode,
9
+ type DirectiveNode,
10
+ type ElementNode,
11
+ type SimpleExpressionNode,
12
+ type TextNode,
13
+ } from '@vue/compiler-dom'
14
+
15
+ export interface ComponentTransformerOptions {
16
+ // Absolute source root dirs, each holding `<Component>/stories/*.vue` and
17
+ // `<Component>/types.ts`. When omitted, defaults resolve relative to each
18
+ // markdown file (backward compatible with the in-repo docs layout).
19
+ sourceRoots?: string[]
20
+ }
21
+
22
+ // Resolve configured source roots; empty when no sourceRoots are provided
23
+ // (callers warn rather than silently resolve into nonexistent legacy paths).
24
+ function getRoots(mdDir: string, sourceRoots?: string[]): string[] {
25
+ if (sourceRoots && sourceRoots.length) {
26
+ return sourceRoots.map((r) => (isAbsolute(r) ? r : resolve(mdDir, r)))
27
+ }
28
+ return []
29
+ }
30
+
31
+ function warnMissingRoots(tag: string, mdPath: string) {
32
+ console.warn(
33
+ `[componentTransformer] <${tag}> in ${mdPath} but no sourceRoots configured — skipping. Pass sourceRoots to defineDocsConfig.`,
34
+ )
35
+ }
36
+
37
+ function resolveSourcePath(roots: string[], relativePath: string): string {
38
+ for (const root of roots) {
39
+ const candidate = resolve(root, relativePath)
40
+ if (existsSync(candidate)) return candidate
41
+ }
42
+ return resolve(roots[0], relativePath)
43
+ }
44
+
45
+ interface ParsedTag {
46
+ /** Static attributes: `foo="bar"` */
47
+ attrs: Record<string, string>
48
+ /** Bound attributes: `:foo="expr"` — value is the expression text */
49
+ binds: Record<string, string>
50
+ }
51
+
52
+ function parseSingleTag(source: string, tagName: string): ParsedTag | null {
53
+ let ast
54
+ try {
55
+ ast = baseParse(source)
56
+ } catch {
57
+ return null
58
+ }
59
+ for (const child of ast.children) {
60
+ if (child.type !== NodeTypes.ELEMENT) continue
61
+ const element = child as ElementNode
62
+ if (element.tag !== tagName) continue
63
+
64
+ const attrs: Record<string, string> = {}
65
+ const binds: Record<string, string> = {}
66
+ for (const prop of element.props) {
67
+ if (prop.type === NodeTypes.ATTRIBUTE) {
68
+ const attr = prop as AttributeNode
69
+ attrs[attr.name] = (attr.value as TextNode | undefined)?.content ?? ''
70
+ } else if (prop.type === NodeTypes.DIRECTIVE) {
71
+ const dir = prop as DirectiveNode
72
+ if (
73
+ dir.name === 'bind' &&
74
+ dir.arg?.type === NodeTypes.SIMPLE_EXPRESSION
75
+ ) {
76
+ const argName = (dir.arg as SimpleExpressionNode).content
77
+ const expr = (dir.exp as SimpleExpressionNode | undefined)?.content
78
+ binds[argName] = expr ?? ''
79
+ }
80
+ }
81
+ }
82
+ return { attrs, binds }
83
+ }
84
+ return null
85
+ }
86
+
87
+ function getPreviewParts(name: string) {
88
+ const separatorIndex = name.indexOf('-')
89
+ if (separatorIndex === -1) {
90
+ return { componentName: name, storyFileName: name }
91
+ }
92
+ return {
93
+ componentName: name.slice(0, separatorIndex),
94
+ storyFileName: name.slice(separatorIndex + 1),
95
+ }
96
+ }
97
+
98
+ function getStoryImportName(storyFileName: string) {
99
+ const normalized = storyFileName.replace(/[^a-zA-Z0-9_$]+/g, ' ')
100
+ const pascal = normalized
101
+ .split(' ')
102
+ .filter(Boolean)
103
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
104
+ .join('')
105
+ return /^[A-Za-z_$]/.test(pascal) ? pascal : `Story${pascal}`
106
+ }
107
+
108
+ function applyImports(state: StateCore, imports: string[]) {
109
+ if (imports.length === 0) return
110
+ const combined = imports.join('\n')
111
+ const scriptIdx = state.tokens.findIndex(
112
+ (t) => t.type === 'html_block' && /<script\s+setup>/.test(t.content),
113
+ )
114
+ if (scriptIdx === -1) {
115
+ const token = new state.Token('html_block', '', 0)
116
+ token.content = `<script setup>\n${combined}\n</script>\n`
117
+ // Unshifting earlier would shift every other token's index — do it
118
+ // after the main transform loop so its `tokenIdx` values stay valid.
119
+ state.tokens.unshift(token)
120
+ } else {
121
+ state.tokens[scriptIdx].content = state.tokens[scriptIdx].content.replace(
122
+ '</script>',
123
+ `${combined}\n</script>`,
124
+ )
125
+ }
126
+ }
127
+
128
+ function getStoryPath(
129
+ roots: string[],
130
+ componentName: string,
131
+ storyFileName: string,
132
+ ) {
133
+ const moleculeName =
134
+ componentName.charAt(0).toLowerCase() + componentName.slice(1)
135
+ const candidates: string[] = []
136
+ for (const root of roots) {
137
+ candidates.push(
138
+ resolve(root, componentName, 'stories', `${storyFileName}.vue`),
139
+ )
140
+ candidates.push(
141
+ resolve(root, moleculeName, 'stories', `${storyFileName}.vue`),
142
+ )
143
+ }
144
+ return candidates.find((candidate) => existsSync(candidate)) ?? candidates[0]
145
+ }
146
+
147
+ function transformPreview(
148
+ state: StateCore,
149
+ tokenIdx: number,
150
+ tag: ParsedTag,
151
+ roots: string[],
152
+ ): string | null {
153
+ const name = tag.attrs.name
154
+ if (!name) return null
155
+
156
+ const csr = tag.attrs.csr === 'true'
157
+ const { componentName, storyFileName } = getPreviewParts(name)
158
+ const storyImportName = getStoryImportName(storyFileName)
159
+ const componentPath = getStoryPath(roots, componentName, storyFileName)
160
+
161
+ // Forward every static attr except `csr`, which this plugin consumes
162
+ // itself (it's not a Vue prop). `name` is still a prop on the Demo
163
+ // component so it gets forwarded along with the rest.
164
+ const forwardedStatic = Object.entries(tag.attrs)
165
+ .filter(([key]) => key !== 'csr')
166
+ .map(([key, value]) => ` ${key}="${value}"`)
167
+ .join('')
168
+ const forwardedBinds = Object.entries(tag.binds)
169
+ .map(([key, expr]) => ` :${key}="${expr}"`)
170
+ .join('')
171
+
172
+ const openWrap = csr ? '<ClientOnly>' : ''
173
+ const closeWrap = csr ? '</ClientOnly>' : ''
174
+
175
+ state.tokens[tokenIdx].content =
176
+ `${openWrap}<ComponentPreview${forwardedStatic}${forwardedBinds}><${storyImportName} /><template #code>`
177
+
178
+ const code = new state.Token('fence', 'code', 0)
179
+ code.info = 'vue'
180
+ code.content = `<<< ${componentPath}`
181
+ // @ts-ignore snippets plugin reads `src` for the absolute path (Token lacks the field in types)
182
+ code.src = [componentPath]
183
+
184
+ const close = new state.Token('html_inline', '', 0)
185
+ close.content = `</template></ComponentPreview>${closeWrap}`
186
+
187
+ state.tokens.splice(tokenIdx + 1, 0, code, close)
188
+
189
+ return `import ${storyImportName} from '${componentPath}'`
190
+ }
191
+
192
+ function transformPropsTable(
193
+ state: StateCore,
194
+ tokenIdx: number,
195
+ tag: ParsedTag,
196
+ roots: string[],
197
+ ) {
198
+ const name = tag.attrs.name
199
+ const dataExpr = tag.binds.data
200
+ if (!name || !dataExpr) return
201
+
202
+ // The optional `folder` attribute lets a sub-component (e.g.
203
+ // DateTimePicker, which lives inside the DatePicker folder) point at
204
+ // the correct `types.ts`. When omitted, the folder matches `name`.
205
+ const componentFolder = tag.attrs.folder || name
206
+ const typesPath = resolveSourcePath(roots, `${componentFolder}/types.ts`)
207
+
208
+ state.tokens[tokenIdx].content =
209
+ `<PropsTable name="${name}" :data="${dataExpr}"><template #code>`
210
+
211
+ const code = new state.Token('fence', 'code', 0)
212
+ code.info = 'typescript'
213
+ code.content = `<<< ${typesPath}`
214
+ // @ts-ignore snippets plugin reads `src` for the absolute path (Token lacks the field in types)
215
+ code.src = [typesPath]
216
+
217
+ const close = new state.Token('html_inline', '', 0)
218
+ close.content = `</template></PropsTable>`
219
+
220
+ state.tokens.splice(tokenIdx + 1, 0, code, close)
221
+ }
222
+
223
+ function install(md: MarkdownRenderer, options: ComponentTransformerOptions) {
224
+ md.core.ruler.after('inline', 'component-preview', (state) => {
225
+ const env = state.env as MarkdownEnv
226
+ // VitePress calls parseInline with an empty env (e.g. title inference);
227
+ // there's nothing to transform without a source path.
228
+ const mdPath = env.realPath ?? env.path
229
+ if (!mdPath) return
230
+ const mdDir = dirname(mdPath)
231
+ const roots = getRoots(mdDir, options.sourceRoots)
232
+ const imports: string[] = []
233
+
234
+ // Walk in reverse so splicing in new tokens doesn't shift indices
235
+ // we haven't visited yet.
236
+ for (let i = state.tokens.length - 1; i >= 0; i--) {
237
+ const token = state.tokens[i]
238
+ if (token.type !== 'html_block' && token.type !== 'html_inline') continue
239
+
240
+ // Cheap text prefilter — Vue's parser is fast but no point invoking
241
+ // it on tokens that clearly don't contain our tags.
242
+ if (token.content.includes('<ComponentPreview')) {
243
+ const tag = parseSingleTag(token.content, 'ComponentPreview')
244
+ if (tag) {
245
+ if (!roots.length) {
246
+ warnMissingRoots('ComponentPreview', mdPath)
247
+ continue
248
+ }
249
+ const importStmt = transformPreview(state, i, tag, roots)
250
+ if (importStmt) imports.push(importStmt)
251
+ }
252
+ } else if (token.content.includes('<PropsTable')) {
253
+ const tag = parseSingleTag(token.content, 'PropsTable')
254
+ if (tag) {
255
+ if (!roots.length) {
256
+ warnMissingRoots('PropsTable', mdPath)
257
+ continue
258
+ }
259
+ transformPropsTable(state, i, tag, roots)
260
+ }
261
+ }
262
+ }
263
+
264
+ applyImports(state, imports)
265
+ })
266
+ }
267
+
268
+ // Factory: returns a markdown-it plugin bound to the given source roots.
269
+ export function createComponentTransformer(
270
+ options: ComponentTransformerOptions = {},
271
+ ) {
272
+ return (md: MarkdownRenderer) => install(md, options)
273
+ }
274
+
275
+ // Backward compatible: usable directly as `md.use(componentTransformer)`
276
+ // (first arg is the renderer) or as a factory `componentTransformer(opts)`.
277
+ export default function componentTransformer(
278
+ mdOrOptions?: MarkdownRenderer | ComponentTransformerOptions,
279
+ ) {
280
+ if (mdOrOptions && 'core' in (mdOrOptions as MarkdownRenderer)) {
281
+ return install(mdOrOptions as MarkdownRenderer, {})
282
+ }
283
+ return createComponentTransformer(
284
+ (mdOrOptions as ComponentTransformerOptions) ?? {},
285
+ )
286
+ }
@@ -0,0 +1,12 @@
1
+ export {
2
+ default as componentTransformer,
3
+ createComponentTransformer,
4
+ type ComponentTransformerOptions,
5
+ } from './componentTransformer.ts'
6
+
7
+ export {
8
+ default as colocatedComponentDocs,
9
+ syncColocatedComponentDocs,
10
+ type ColocatedComponentDocsOptions,
11
+ type SourceRootMap,
12
+ } from './colocatedComponentDocs.ts'
@@ -0,0 +1,10 @@
1
+ import { reactive } from 'vue'
2
+ import type { SidebarSection } from './components/Docs/sidebarList'
3
+
4
+ // Shared cross-component UI state for the docs layout.
5
+ export const state = reactive({
6
+ mobsidebar: false,
7
+ mobnavbar: false,
8
+ searchDialog: false,
9
+ sidebarList: [] as SidebarSection[],
10
+ })