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,44 @@
1
+ import { inject, provide, type ComputedRef, type InjectionKey, type Ref } from 'vue'
2
+ import type { ListDivider } from './types'
3
+
4
+ // Everything a List provides to its descendants. Internal — the public
5
+ // contract is the components' props/models and the CSS hooks
6
+ // (`--list-columns`, `--list-gap`, data-slot/data-state attributes).
7
+ export interface ListContext {
8
+ divider: ComputedRef<ListDivider>
9
+ selectable: ComputedRef<boolean>
10
+ rowHeight: ComputedRef<number | undefined>
11
+
12
+ // Header presence drives ARIA roles: list/listitem without a header,
13
+ // table/row/columnheader/cell with one.
14
+ hasHeader: Ref<boolean>
15
+
16
+ isSelected: (value: string) => boolean
17
+ toggleSelection: (value: string) => void
18
+
19
+ // Header select-all. <ListRows> feeds the full selectable universe via
20
+ // `setAllValues` — it holds the complete `items` array even when the rows are
21
+ // virtualized, so the header checkbox can reflect/toggle "all" without every
22
+ // row being mounted. `selectAllState` drives the header checkbox's
23
+ // checked/indeterminate/empty rendering.
24
+ setAllValues: (values: string[]) => void
25
+ selectAllState: ComputedRef<'none' | 'some' | 'all'>
26
+ toggleSelectAll: () => void
27
+
28
+ // Single "active" row (v-model:active) — the one currently open/highlighted,
29
+ // separate from the checkbox `selection` set. `activatable` is true only when
30
+ // the List actually binds v-model:active, so plain navigation lists opt out.
31
+ activatable: ComputedRef<boolean>
32
+ isActive: (value: string) => boolean
33
+ activate: (value: string) => void
34
+ }
35
+
36
+ const listContextKey: InjectionKey<ListContext> = Symbol('frappe-ui:list')
37
+
38
+ export function provideListContext(context: ListContext) {
39
+ provide(listContextKey, context)
40
+ }
41
+
42
+ export function useListContext() {
43
+ return inject(listContextKey, null)
44
+ }
@@ -0,0 +1,276 @@
1
+ <!-- Auto Generated by scripts/propsgen.ts -->
2
+ <script setup>
3
+ import PropsTable from '@/components/Docs/PropsTable.vue'
4
+ import SlotsTable from '@/components/Docs/SlotsTable.vue'
5
+ import EmitsTable from '@/components/Docs/EmitsTable.vue'
6
+
7
+ const listProps = [
8
+ {
9
+ name: 'columns',
10
+ description: 'Grid track sizes, written to the `--list-columns` CSS var shared by the\nheader and every row. Defaults to the feed template\n`[\'auto\', \'minmax(0,1fr)\', \'auto\']` (leading media, content, trailing).\nTable-style lists must pass deterministic track sizes — `auto` tracks\nsize independently per row.',
11
+ required: false,
12
+ type: 'string[]'
13
+ },
14
+ {
15
+ name: 'divider',
16
+ description: 'Divider treatment between rows: `inset` starts at the content column\n(the text edge), `full` spans all columns. Defaults to `inset` with the\ndefault feed template, `full` when `columns` is set.',
17
+ required: false,
18
+ type: 'ListDivider'
19
+ },
20
+ {
21
+ name: 'selectable',
22
+ description: 'Reveals the animated checkbox column and switches row click from\nnavigate to toggle. Selected values surface via `v-model:selection`.',
23
+ required: false,
24
+ type: 'boolean'
25
+ },
26
+ {
27
+ name: 'rowHeight',
28
+ description: 'Fixed row height in px (sets `--list-row-height`). Required for\nvirtualization; without it rows size to their content. Responsive\nheights are non-virtual — set them with classes on the rows instead.',
29
+ required: false,
30
+ type: 'number'
31
+ },
32
+ {
33
+ name: 'selection',
34
+ description: '',
35
+ required: false,
36
+ type: 'string[]',
37
+ default: '[]'
38
+ },
39
+ {
40
+ name: 'active',
41
+ description: '',
42
+ required: false,
43
+ type: 'string'
44
+ }
45
+ ]
46
+
47
+ const listSlots = [
48
+ {
49
+ name: 'default',
50
+ description: '',
51
+ type: '{}'
52
+ }
53
+ ]
54
+
55
+ const listEmits = [
56
+ {
57
+ name: 'update:selection',
58
+ description: 'Fired when the selection changes.',
59
+ type: '[value: string[]]'
60
+ },
61
+ {
62
+ name: 'update:active',
63
+ description: 'Fired when the active changes.',
64
+ type: '[value: string | undefined]'
65
+ }
66
+ ]
67
+
68
+ const listRowProps = [
69
+ {
70
+ name: 'to',
71
+ description: 'Renders the row as a RouterLink. Without `to`, a row with a click\nlistener renders as a button; otherwise a plain div.',
72
+ required: false,
73
+ type: 'string | kt | Tt'
74
+ },
75
+ {
76
+ name: 'value',
77
+ description: 'Row key — the `selection` key when `selectable` and the `v-model:active`\nkey. Required whenever the list uses either.',
78
+ required: false,
79
+ type: 'string'
80
+ },
81
+ {
82
+ name: 'onClick',
83
+ description: 'Fired when the row is activated, unless selection mode claims the click.',
84
+ required: false,
85
+ type: '((event: MouseEvent) => void)'
86
+ }
87
+ ]
88
+
89
+ const listRowSlots = [
90
+ {
91
+ name: 'default',
92
+ description: '',
93
+ type: '{}'
94
+ }
95
+ ]
96
+
97
+ const listCellSlots = [
98
+ {
99
+ name: 'default',
100
+ description: '',
101
+ type: '{}'
102
+ }
103
+ ]
104
+
105
+ const listHeaderSlots = [
106
+ {
107
+ name: 'default',
108
+ description: '',
109
+ type: '{}'
110
+ }
111
+ ]
112
+
113
+ const listHeaderCellSlots = [
114
+ {
115
+ name: 'default',
116
+ description: 'Column label.',
117
+ type: 'any'
118
+ },
119
+ {
120
+ name: 'prefix',
121
+ description: 'Leading adornment, rendered before the label.',
122
+ type: 'any'
123
+ },
124
+ {
125
+ name: 'suffix',
126
+ description: 'Trailing adornment, rendered after the label.',
127
+ type: 'any'
128
+ }
129
+ ]
130
+
131
+ const listHeaderCellSortProps = [
132
+ {
133
+ name: 'direction',
134
+ description: 'Active sort direction for this column, `null`/omitted when inactive.\nThe cell is controlled — sort state and toggle rules are app-owned:\nupdate whatever drives your ordering in the `click` handler.',
135
+ required: false,
136
+ type: 'ListSortDirection | null'
137
+ },
138
+ {
139
+ name: 'align',
140
+ description: 'Horizontal alignment of the header content. `\'end\'` right-aligns the cell\n(for numeric/right-aligned columns) *and* moves the sort glyph to the\nleading side, so the label stays flush with the column\'s right edge and\nlines up with the values below. Defaults to `\'start\'`.',
141
+ required: false,
142
+ type: '"start" | "end"'
143
+ }
144
+ ]
145
+
146
+ const listHeaderCellSortSlots = [
147
+ {
148
+ name: 'default',
149
+ description: 'Column label.',
150
+ type: 'any'
151
+ },
152
+ {
153
+ name: 'prefix',
154
+ description: 'Leading adornment, rendered before the label.',
155
+ type: '{ direction: "desc" | "asc" | null; }'
156
+ },
157
+ {
158
+ name: 'suffix',
159
+ description: 'Sort glyph. Optional — the cell renders a built-in arrow from `direction`\nby default. Provide this to override (e.g. a custom lucide span). The cell\nowns the reveal: an inactive column\'s glyph shows on hover.',
160
+ type: '{ direction: "desc" | "asc" | null; }'
161
+ }
162
+ ]
163
+
164
+ const listHeaderCellSortEmits = [
165
+ {
166
+ name: 'click',
167
+ description: '',
168
+ type: '[event: MouseEvent]'
169
+ }
170
+ ]
171
+
172
+ const listRowsProps = [
173
+ {
174
+ name: 'items',
175
+ description: 'Items to iterate — one default-slot render per item.',
176
+ required: true,
177
+ type: 'T[]'
178
+ },
179
+ {
180
+ name: 'rowKey',
181
+ description: 'How to derive a row\'s identity. A string reads that property off the item;\na function computes it. Drives the render `:key`, the header select-all\nuniverse, and the scoped `value` slot prop. Defaults to the item\'s `name`,\nthen `id`, then the index.',
182
+ required: false,
183
+ type: 'string | ((item: T, index: number) => PropertyKey)'
184
+ },
185
+ {
186
+ name: 'virtual',
187
+ description: 'Window the rows (vueuse useVirtualList) so only rows near the viewport\nmount. `itemHeight` defaults to the List\'s `rowHeight`; the scroll\ncontainer is the nearest scrollable ancestor.',
188
+ required: false,
189
+ type: 'boolean | ListVirtualOptions'
190
+ }
191
+ ]
192
+
193
+ const listRowsSlots = [
194
+ {
195
+ name: 'default',
196
+ description: '',
197
+ type: '{ item: T; index: number; value: string; }'
198
+ }
199
+ ]
200
+
201
+ const listGroupProps = [
202
+ {
203
+ name: 'label',
204
+ description: 'Section label shown in the group header. Overridden by the #header slot.',
205
+ required: false,
206
+ type: 'string'
207
+ },
208
+ {
209
+ name: 'sticky',
210
+ description: 'Pin the group header to the top of the scroll container while its rows\nscroll under it. Off by default.',
211
+ required: false,
212
+ type: 'boolean'
213
+ }
214
+ ]
215
+
216
+ const listGroupSlots = [
217
+ {
218
+ name: 'default',
219
+ description: 'The group\'s rows — `<ListRow>` elements.',
220
+ type: 'any'
221
+ },
222
+ {
223
+ name: 'header',
224
+ description: 'Replaces the header content (the label).',
225
+ type: 'any'
226
+ }
227
+ ]
228
+ </script>
229
+
230
+ ## API Reference
231
+
232
+ ### List
233
+
234
+ <PropsTable folder="list" name="List" :data="listProps"/>
235
+
236
+ <SlotsTable :data="listSlots"/>
237
+
238
+ <EmitsTable :data="listEmits"/>
239
+
240
+ ### ListRow
241
+
242
+ <PropsTable folder="list" name="ListRow" :data="listRowProps"/>
243
+
244
+ <SlotsTable :data="listRowSlots"/>
245
+
246
+ ### ListCell
247
+
248
+ <SlotsTable :data="listCellSlots"/>
249
+
250
+ ### ListHeader
251
+
252
+ <SlotsTable :data="listHeaderSlots"/>
253
+
254
+ ### ListHeaderCell
255
+
256
+ <SlotsTable :data="listHeaderCellSlots"/>
257
+
258
+ ### ListHeaderCellSort
259
+
260
+ <PropsTable folder="list" name="ListHeaderCellSort" :data="listHeaderCellSortProps"/>
261
+
262
+ <SlotsTable :data="listHeaderCellSortSlots"/>
263
+
264
+ <EmitsTable :data="listHeaderCellSortEmits"/>
265
+
266
+ ### ListRows
267
+
268
+ <PropsTable folder="list" name="ListRows" :data="listRowsProps"/>
269
+
270
+ <SlotsTable :data="listRowsSlots"/>
271
+
272
+ ### ListGroup
273
+
274
+ <PropsTable folder="list" name="ListGroup" :data="listGroupProps"/>
275
+
276
+ <SlotsTable :data="listGroupSlots"/>
@@ -0,0 +1,119 @@
1
+ # List
2
+
3
+ Composition-based list primitives under the `frappe-ui/list` subpath. Every list
4
+ surface is one column grid: a feed row is just the default column template, a
5
+ table is an explicit one. The family owns geometry — columns, dividers, hover
6
+ surfaces, selection and sort chrome — and nothing readable: cell contents
7
+ (typography, avatars, badges, unread emphasis) are entirely app-authored.
8
+
9
+ Not to be confused with the config-driven `ListView` in the main entry — that
10
+ stays untouched; import from `frappe-ui/list` for this family.
11
+
12
+ ## Feed mode
13
+
14
+ The default template (`auto`, `minmax(0,1fr)`, `auto`) fits leading media,
15
+ content, and a right-aligned trailing cell. Rows with `to` render as
16
+ RouterLinks, rows with a click listener as buttons. `selectable` reveals the
17
+ animated checkbox column and switches row click from navigate to toggle;
18
+ selected values surface through `v-model:selection`. When a `ListHeader` is
19
+ present, a select-all checkbox appears in it automatically — checked when every
20
+ row is selected, mixed when only some are, and toggling all rows on or off. It
21
+ reasons over the full `ListRows` items, so it covers virtualized rows too.
22
+ `ListRows` resolves each row's identity once and exposes it as the scoped
23
+ `value` prop. The identity defaults to the item's `name`/`id`; pass `row-key` (a
24
+ field name or `(item, index) => key`) when the row should use a different field.
25
+
26
+ Dividers default to `inset`: they start at the content column (the text edge) by
27
+ construction, never render above the first row, and hide around a hovered row so
28
+ the rounded hover surface floats free.
29
+
30
+ <ComponentPreview name="List-Feed" />
31
+
32
+ ## Active row
33
+
34
+ A master–detail list (a mail inbox, a file browser) tracks one open row. Bind
35
+ `v-model:active` to a row `value` and the List owns the rest: it highlights that
36
+ row and hides the dividers hugging it — above and below — so its rounded surface
37
+ floats free, like a hovered row but persistent. Clicking a row sets `active`;
38
+ unlike `selectable`, activation is additive, so the row's own `@click` and `to`
39
+ navigation still run. It's single-select and independent of the multi-select
40
+ checkbox `selection` — and works in feed or column mode.
41
+
42
+ ```vue
43
+ <List v-model:active="openId">
44
+ <ListRows :items="threads" v-slot="{ value }">
45
+ <ListRow :value="value">…</ListRow>
46
+ </ListRows>
47
+ </List>
48
+ ```
49
+
50
+ ## Column mode
51
+
52
+ Pass explicit `columns` (deterministic track sizes — `auto` tracks size
53
+ independently per row) and a `ListHeader`. Header and rows share one
54
+ `--list-columns` template, so they can never drift.
55
+
56
+ `ListHeaderCell` is a plain label with optional `#prefix` / `#suffix`
57
+ adornments. Sortable columns use `ListHeaderCellSort` instead — a controlled
58
+ sort button: you hand it the active `direction` (`asc` / `desc` / `null`) and
59
+ update your own sort state in its `click` handler. Your code owns the state,
60
+ toggle rules, direction glyphs (via the scoped `#suffix="{ direction }"` slot),
61
+ and whether ordering happens client-side or through `useList` orderBy. The cell
62
+ keeps only the behavioral chrome: a real button, `aria-sort`, the tooltip, and
63
+ revealing an inactive column's suffix on hover. Both variants render the same
64
+ `data-slot="list-header-cell"` geometry, so mixing them in one header is
65
+ seamless.
66
+
67
+ <ComponentPreview name="List-Columns" />
68
+
69
+ ## Virtual rows
70
+
71
+ `ListRows` iterates items through its scoped slot; with `virtual`, only rows
72
+ near the viewport mount. The scoped slot receives `{ item, index, value }`,
73
+ where `value` is the string row identity used by select-all and active-row
74
+ state. The scroll container is the nearest scrollable ancestor — the list
75
+ windows against an app-owned scroll area (a settings body, the page) and keeps
76
+ its scrollbar. `itemHeight` defaults to the List's `rowHeight`. The underlying
77
+ composable, `useVirtualRows`, is exported for exotic cases.
78
+
79
+ <ComponentPreview name="List-Virtual" csr="true" />
80
+
81
+ ## Styling hooks
82
+
83
+ `--list-columns` and `--list-gap` (default `0.5rem`) are public hooks on the
84
+ List — override them with plain classes, responsively if needed. People-style
85
+ lists collapse to a feed on mobile with no dedicated API:
86
+
87
+ ```vue
88
+ <List
89
+ :columns="['minmax(8rem,1fr)', '5.5rem', '5.5rem']"
90
+ class="max-sm:[--list-columns:auto_minmax(0,1fr)_auto]"
91
+ >
92
+ ```
93
+
94
+ with `max-sm:hidden` on the numeric cells and the `ListHeader`.
95
+
96
+ For `--list-gap` and `--list-row-padding-x` (the content inset shared by
97
+ interactive rows — default `0.75rem` — and the column header, so setting it on
98
+ the `List` aligns both), the frappe-ui Tailwind preset ships spacing-scale
99
+ utilities — `list-gap-*` and `list-row-px-*` — so the usual authoring form is
100
+ `max-sm:list-gap-3 sm:list-gap-4` rather than raw `[--list-gap:0.75rem]`
101
+ properties. Both forms hit the same CSS vars.
102
+
103
+ Cells (and plain header cells) are flex containers with `items-center` — align
104
+ content with justify utilities (`class="justify-end"` for numeric columns),
105
+ responsively if needed. For sortable numeric headers, use
106
+ `<ListHeaderCellSort align="end">` so the sort glyph moves to the leading side
107
+ and the label stays flush with the column edge.
108
+
109
+ Slots for CSS targeting:
110
+ `data-slot="list | list-header | list-header-cell | list-row | list-cell | list-row-checkbox | list-divider"`.
111
+ State: `data-state="selected"` (checkbox selection), `data-active` (+
112
+ `aria-current`, the `v-model:active` row) and `data-interactive` on rows,
113
+ `data-sort` on the active header cell.
114
+
115
+ Accessibility follows header presence: `role="list"` / `"listitem"` without a
116
+ `ListHeader`, `table` / `row` / `columnheader` / `cell` (plus `aria-sort`) with
117
+ one.
118
+
119
+ <!-- @include: ./list.api.md -->
@@ -0,0 +1,103 @@
1
+ <script setup lang="ts">
2
+ import { computed, ref } from 'vue'
3
+ import { Avatar, Button } from 'frappe-ui'
4
+ import {
5
+ List,
6
+ ListRow,
7
+ ListCell,
8
+ ListHeader,
9
+ ListHeaderCell,
10
+ ListHeaderCellSort,
11
+ ListRows,
12
+ } from 'frappe-ui/list'
13
+
14
+ const members = [
15
+ { name: 'Rosa Diaz', email: 'rosa@example.com', role: 'Admin', since: '2021-06' },
16
+ { name: 'Jake Peralta', email: 'jake@example.com', role: 'Member', since: '2022-01' },
17
+ { name: 'Amy Santiago', email: 'amy@example.com', role: 'Admin', since: '2020-11' },
18
+ { name: 'Terry Jeffords', email: 'terry@example.com', role: 'Member', since: '2023-03' },
19
+ { name: 'Raymond Holt', email: 'holt@example.com', role: 'Guest', since: '2024-08' },
20
+ ]
21
+
22
+ // Sort state, toggle rules, comparator, and direction icons are all app
23
+ // code — the header cells only render the chrome for whatever `direction`
24
+ // you hand them.
25
+ type Field = 'name' | 'role' | 'since'
26
+
27
+ function sortIcon(direction: 'asc' | 'desc' | null) {
28
+ if (!direction) return 'lucide-arrow-up-down'
29
+ return direction === 'asc' ? 'lucide-arrow-up' : 'lucide-arrow-down'
30
+ }
31
+ const sortField = ref<Field>('name')
32
+ const sortDirection = ref<'asc' | 'desc'>('asc')
33
+
34
+ function toggleSort(field: Field, firstDirection: 'asc' | 'desc' = 'asc') {
35
+ if (sortField.value === field) {
36
+ sortDirection.value = sortDirection.value === 'asc' ? 'desc' : 'asc'
37
+ } else {
38
+ sortField.value = field
39
+ sortDirection.value = firstDirection
40
+ }
41
+ }
42
+
43
+ function directionFor(field: Field) {
44
+ return sortField.value === field ? sortDirection.value : null
45
+ }
46
+
47
+ const sortedMembers = computed(() => {
48
+ const factor = sortDirection.value === 'desc' ? -1 : 1
49
+ return [...members].sort(
50
+ (a, b) => factor * a[sortField.value].localeCompare(b[sortField.value]),
51
+ )
52
+ })
53
+ </script>
54
+
55
+ <template>
56
+ <List class="w-full" :columns="['minmax(0,1fr)', '7rem', '8rem', '3rem']" :row-height="56">
57
+ <ListHeader>
58
+ <ListHeaderCellSort :direction="directionFor('name')" @click="toggleSort('name')">
59
+ Member
60
+ <template #suffix="{ direction }">
61
+ <span class="block size-3.5" :class="sortIcon(direction)" />
62
+ </template>
63
+ </ListHeaderCellSort>
64
+ <ListHeaderCellSort :direction="directionFor('role')" @click="toggleSort('role')">
65
+ Role
66
+ <template #suffix="{ direction }">
67
+ <span class="block size-3.5" :class="sortIcon(direction)" />
68
+ </template>
69
+ </ListHeaderCellSort>
70
+ <ListHeaderCellSort
71
+ :direction="directionFor('since')"
72
+ class="justify-end"
73
+ @click="toggleSort('since', 'desc')"
74
+ >
75
+ Member since
76
+ <template #suffix="{ direction }">
77
+ <span class="block size-3.5" :class="sortIcon(direction)" />
78
+ </template>
79
+ </ListHeaderCellSort>
80
+ <ListHeaderCell />
81
+ </ListHeader>
82
+ <ListRows :items="sortedMembers" v-slot="{ item: member }">
83
+ <ListRow>
84
+ <ListCell>
85
+ <Avatar :label="member.name" size="xl" />
86
+ <div class="ml-3 min-w-0">
87
+ <div class="truncate text-base text-ink-gray-8">{{ member.name }}</div>
88
+ <div class="mt-0.5 truncate text-sm text-ink-gray-5">{{ member.email }}</div>
89
+ </div>
90
+ </ListCell>
91
+ <ListCell>
92
+ <span class="text-base text-ink-gray-7">{{ member.role }}</span>
93
+ </ListCell>
94
+ <ListCell class="justify-end">
95
+ <span class="text-base text-ink-gray-6">{{ member.since }}</span>
96
+ </ListCell>
97
+ <ListCell class="justify-end">
98
+ <Button variant="ghost" icon="lucide-trash-2" label="Remove member" />
99
+ </ListCell>
100
+ </ListRow>
101
+ </ListRows>
102
+ </List>
103
+ </template>
@@ -0,0 +1,105 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue'
3
+ import { Avatar, Badge, Button } from 'frappe-ui'
4
+ import { List, ListRow, ListCell } from 'frappe-ui/list'
5
+
6
+ const discussions = [
7
+ {
8
+ name: '1',
9
+ title: 'Weekly sync notes',
10
+ author: 'Rosa Diaz',
11
+ comment: 'Sounds good, let us ship it on Monday',
12
+ time: '2 h',
13
+ comments: 4,
14
+ unread: true,
15
+ },
16
+ {
17
+ name: '2',
18
+ title: 'Redesigning the onboarding flow',
19
+ author: 'Jake Peralta',
20
+ comment: 'I added the new mockups to the page',
21
+ time: '5 h',
22
+ comments: 12,
23
+ unread: false,
24
+ },
25
+ {
26
+ name: '3',
27
+ title: 'Q3 hiring plan',
28
+ author: 'Amy Santiago',
29
+ comment: 'Two backend roles and one designer',
30
+ time: '1 d',
31
+ comments: 7,
32
+ unread: true,
33
+ },
34
+ {
35
+ name: '4',
36
+ title: 'Incident review: search downtime',
37
+ author: 'Terry Jeffords',
38
+ comment: 'Root cause was the index rebuild',
39
+ time: '2 d',
40
+ comments: 9,
41
+ unread: false,
42
+ },
43
+ {
44
+ name: '5',
45
+ title: 'Docs sprint retrospective',
46
+ author: 'Raymond Holt',
47
+ comment: 'Velocity was acceptable.',
48
+ time: '4 d',
49
+ comments: 3,
50
+ unread: false,
51
+ },
52
+ ]
53
+
54
+ const selectable = ref(false)
55
+ const selection = ref<string[]>([])
56
+
57
+ function toggleSelectMode() {
58
+ selectable.value = !selectable.value
59
+ selection.value = []
60
+ }
61
+ </script>
62
+
63
+ <template>
64
+ <div class="w-full">
65
+ <div class="mb-2 flex h-7 items-center justify-end gap-3">
66
+ <span v-if="selection.length" class="text-sm text-ink-gray-5">
67
+ {{ selection.length }} selected
68
+ </span>
69
+ <Button @click="toggleSelectMode">
70
+ {{ selectable ? 'Done' : 'Select' }}
71
+ </Button>
72
+ </div>
73
+ <List :selectable="selectable" v-model:selection="selection" :row-height="60">
74
+ <ListRow
75
+ v-for="discussion in discussions"
76
+ :key="discussion.name"
77
+ :value="discussion.name"
78
+ @click="() => {}"
79
+ >
80
+ <ListCell>
81
+ <Avatar :label="discussion.author" size="2xl" />
82
+ </ListCell>
83
+ <ListCell>
84
+ <div class="min-w-0">
85
+ <div
86
+ class="truncate text-base text-ink-gray-8"
87
+ :class="discussion.unread && 'font-semibold'"
88
+ >
89
+ {{ discussion.title }}
90
+ </div>
91
+ <div class="mt-1 truncate text-base text-ink-gray-5">
92
+ {{ discussion.author }}: {{ discussion.comment }}
93
+ </div>
94
+ </div>
95
+ </ListCell>
96
+ <ListCell class="justify-end">
97
+ <div class="flex flex-col items-end gap-1">
98
+ <span class="text-sm text-ink-gray-5">{{ discussion.time }}</span>
99
+ <Badge>{{ discussion.comments }}</Badge>
100
+ </div>
101
+ </ListCell>
102
+ </ListRow>
103
+ </List>
104
+ </div>
105
+ </template>
@@ -0,0 +1,31 @@
1
+ <script setup lang="ts">
2
+ import { List, ListRow, ListCell, ListRows } from 'frappe-ui/list'
3
+
4
+ const items = Array.from({ length: 1000 }, (_, i) => ({
5
+ id: String(i + 1),
6
+ title: `Task ${i + 1}`,
7
+ status: i % 3 === 0 ? 'Done' : i % 3 === 1 ? 'In progress' : 'Backlog',
8
+ }))
9
+ </script>
10
+
11
+ <template>
12
+ <!-- The scroll container is app-owned: ListRows finds the nearest
13
+ scrollable ancestor and windows against it. -->
14
+ <div class="h-72 w-full overflow-y-auto rounded border">
15
+ <List :columns="['3rem', 'minmax(0,1fr)', '6rem']" :row-height="44" class="px-2">
16
+ <ListRows :items="items" virtual v-slot="{ item }">
17
+ <ListRow>
18
+ <ListCell>
19
+ <span class="text-sm text-ink-gray-4">#{{ item.id }}</span>
20
+ </ListCell>
21
+ <ListCell>
22
+ <span class="truncate text-base text-ink-gray-8">{{ item.title }}</span>
23
+ </ListCell>
24
+ <ListCell class="justify-end">
25
+ <span class="text-sm text-ink-gray-5">{{ item.status }}</span>
26
+ </ListCell>
27
+ </ListRow>
28
+ </ListRows>
29
+ </List>
30
+ </div>
31
+ </template>