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
@@ -1,10 +1,14 @@
1
1
  <template>
2
- <div class="flex flex-col mt-2">
2
+ <!--
3
+ Legacy adapter for `Sidebar`'s deprecated `sections` config prop. New code
4
+ composes `SidebarLabel` + `SidebarItem` directly instead of this component.
5
+ -->
6
+ <div class="mt-2 flex flex-col">
3
7
  <div
4
- v-if="props.label"
8
+ v-if="label"
5
9
  class="relative flex items-center gap-1 px-2 py-1.5"
6
- :class="props.collapsible ? 'cursor-pointer' : ''"
7
- @click="props.collapsible ? (isCollapsed = !isCollapsed) : null"
10
+ :class="collapsible ? 'cursor-pointer' : ''"
11
+ @click="collapsible ? (isSectionCollapsed = !isSectionCollapsed) : null"
8
12
  >
9
13
  <h3
10
14
  class="h-4 text-sm text-ink-gray-5 transition-all duration-300 ease-in-out"
@@ -14,34 +18,39 @@
14
18
  : 'w-auto opacity-100'
15
19
  "
16
20
  >
17
- {{ props.label }}
21
+ {{ label }}
18
22
  </h3>
19
- <div v-if="props.collapsible">
23
+ <div v-if="collapsible">
20
24
  <span
21
25
  v-if="!isSidebarCollapsed"
22
26
  class="lucide-chevron-right size-4 text-ink-gray-5 transition-all duration-300 ease-in-out"
23
- :class="{ 'rotate-90': !isCollapsed }"
27
+ :class="{ 'rotate-90': !isSectionCollapsed }"
24
28
  />
25
29
  </div>
26
30
  <div
27
31
  v-if="isSidebarCollapsed"
28
- class="absolute top-0 left-0 flex h-full w-full items-center justify-center transition-all duration-300 ease-in-out"
29
- :class="isSidebarCollapsed ? 'opacity-100' : 'opacity-0'"
32
+ aria-hidden="true"
33
+ class="absolute inset-0 flex items-center"
30
34
  >
31
35
  <hr class="w-full border-t border-ink-gray-3" />
32
36
  </div>
33
37
  </div>
38
+
34
39
  <transition
35
40
  enter-active-class="duration-300 ease-in"
36
- leave-active-class="duration-300 ease-[cubic-bezier(0, 1, 0.5, 1)]"
41
+ leave-active-class="duration-300 ease-[cubic-bezier(0,1,0.5,1)]"
37
42
  enter-to-class="max-h-[200px] overflow-hidden"
38
43
  leave-from-class="max-h-[200px] overflow-hidden"
39
44
  enter-from-class="max-h-0 overflow-hidden"
40
45
  leave-to-class="max-h-0 overflow-hidden"
41
46
  >
42
- <nav v-if="!isCollapsed" class="flex flex-col gap-0.5">
47
+ <nav v-if="!isSectionCollapsed" class="flex flex-col gap-0.5">
43
48
  <template v-for="item in visibleItems" :key="item.label">
44
- <slot name="sidebar-item" :item="item" :isCollapsed="isSidebarCollapsed">
49
+ <slot
50
+ name="sidebar-item"
51
+ :item="item"
52
+ :isCollapsed="isSidebarCollapsed"
53
+ >
45
54
  <SidebarItem
46
55
  :label="item.label"
47
56
  :accessKey="item.accessKey"
@@ -65,8 +74,14 @@ import { SidebarSectionProps, sidebarCollapsedKey } from './types'
65
74
 
66
75
  const props = defineProps<SidebarSectionProps>()
67
76
 
68
- const isSidebarCollapsed = inject(sidebarCollapsedKey, computed(() => false))
69
- const isCollapsed = ref(false)
77
+ const isSidebarCollapsed = inject(
78
+ sidebarCollapsedKey,
79
+ computed(() => false),
80
+ )
81
+ // Per-section open/closed state for `collapsible` sections — distinct from the
82
+ // whole-sidebar collapse above.
83
+ const isSectionCollapsed = ref(false)
84
+
70
85
  const visibleItems = computed(() =>
71
86
  props.items.filter((item) => toValue(item.condition) !== false),
72
87
  )
@@ -1,5 +1,16 @@
1
1
  export { default as Sidebar } from './Sidebar.vue'
2
- export { default as SidebarHeader } from './SidebarHeader.vue'
3
2
  export { default as SidebarItem } from './SidebarItem.vue'
3
+ export { default as SidebarLabel } from './SidebarLabel.vue'
4
+ export { default as SidebarCollapseToggle } from './SidebarCollapseToggle.vue'
5
+ export { default as SidebarHeader } from './SidebarHeader.vue'
6
+ // Legacy adapter for the deprecated `sections` config prop.
4
7
  export { default as SidebarSection } from './SidebarSection.vue'
5
- export type { SidebarProps } from './types'
8
+
9
+ export type {
10
+ SidebarProps,
11
+ SidebarItemProps,
12
+ SidebarLabelProps,
13
+ SidebarHeaderProps,
14
+ SidebarSectionProps,
15
+ } from './types'
16
+ export { sidebarCollapsedKey, sidebarToggleKey } from './types'
@@ -0,0 +1,40 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue'
3
+ import {
4
+ Sidebar,
5
+ SidebarItem,
6
+ SidebarLabel,
7
+ SidebarCollapseToggle,
8
+ } from 'frappe-ui'
9
+
10
+ const collapsed = ref(true)
11
+ const active = ref('inbox')
12
+ const items = [
13
+ { id: 'inbox', label: 'Inbox', icon: 'lucide-inbox' },
14
+ { id: 'starred', label: 'Starred', icon: 'lucide-star' },
15
+ { id: 'sent', label: 'Sent', icon: 'lucide-send' },
16
+ ]
17
+ </script>
18
+
19
+ <template>
20
+ <div class="flex h-[360px] w-fit overflow-hidden rounded-md border">
21
+ <!-- v-model:collapsed is app state; SidebarCollapseToggle flips it. -->
22
+ <Sidebar v-model:collapsed="collapsed">
23
+ <div class="flex-1 overflow-y-auto px-2 pt-2">
24
+ <SidebarLabel divider>Mail</SidebarLabel>
25
+ <SidebarItem
26
+ v-for="item in items"
27
+ :key="item.id"
28
+ :icon="item.icon"
29
+ :label="item.label"
30
+ :active="active === item.id"
31
+ @click="active = item.id"
32
+ />
33
+ </div>
34
+
35
+ <div class="mt-auto px-2 pb-2">
36
+ <SidebarCollapseToggle />
37
+ </div>
38
+ </Sidebar>
39
+ </div>
40
+ </template>
@@ -0,0 +1,153 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue'
3
+ import {
4
+ Sidebar,
5
+ SidebarItem,
6
+ SidebarLabel,
7
+ ScrollArea,
8
+ Button,
9
+ Dropdown,
10
+ } from 'frappe-ui'
11
+
12
+ // A faithful Gameplan sidebar: an app switcher up top, then a scrolling list of
13
+ // spaces with lucide icons, unread counts, private locks, and a hover-reveal
14
+ // options menu. Only <Sidebar>/<SidebarItem>/<SidebarLabel> come from the
15
+ // family — the header, the ScrollArea, and the spaces markup are the app's own.
16
+ const active = ref('product')
17
+ const sort = ref('Recent activity')
18
+
19
+ const spaces = [
20
+ { id: 'product', title: 'Product', icon: 'lucide-rocket', unread: 0, private: false },
21
+ { id: 'design', title: 'Design', icon: 'lucide-palette', unread: 3, private: false },
22
+ { id: 'engineering', title: 'Engineering', icon: 'lucide-code', unread: 12, private: false },
23
+ { id: 'marketing', title: 'Marketing', icon: 'lucide-megaphone', unread: 0, private: false },
24
+ { id: 'sales', title: 'Sales', icon: 'lucide-trending-up', unread: 1, private: false },
25
+ { id: 'support', title: 'Customer Support', icon: 'lucide-headphones', unread: 0, private: false },
26
+ { id: 'people', title: 'People & Culture', icon: 'lucide-users', unread: 0, private: false },
27
+ { id: 'finance', title: 'Finance', icon: 'lucide-wallet', unread: 0, private: true },
28
+ { id: 'leadership', title: 'Leadership', icon: 'lucide-crown', unread: 2, private: true },
29
+ { id: 'design-system', title: 'Design System', icon: 'lucide-component', unread: 0, private: false },
30
+ { id: 'research', title: 'User Research', icon: 'lucide-microscope', unread: 5, private: false },
31
+ { id: 'ops', title: 'Operations', icon: 'lucide-settings-2', unread: 0, private: false },
32
+ { id: 'events', title: 'Events', icon: 'lucide-party-popper', unread: 0, private: false },
33
+ { id: 'data', title: 'Data & Analytics', icon: 'lucide-database', unread: 8, private: false },
34
+ { id: 'brand', title: 'Brand', icon: 'lucide-sparkles', unread: 0, private: false },
35
+ { id: 'partnerships', title: 'Partnerships', icon: 'lucide-handshake', unread: 0, private: false },
36
+ { id: 'security', title: 'Security', icon: 'lucide-shield', unread: 0, private: true },
37
+ { id: 'onboarding', title: 'Onboarding', icon: 'lucide-graduation-cap', unread: 0, private: false },
38
+ { id: 'random', title: 'Random', icon: 'lucide-shuffle', unread: 0, private: false },
39
+ ]
40
+
41
+ const sortOptions = [
42
+ {
43
+ group: 'Sort by',
44
+ options: ['Recent activity', 'Alphabetical'].map((label) => ({
45
+ label,
46
+ icon: sort.value === label ? 'lucide-check' : null,
47
+ onClick: () => (sort.value = label),
48
+ })),
49
+ },
50
+ ]
51
+ </script>
52
+
53
+ <template>
54
+ <div class="flex h-[560px] w-fit overflow-hidden rounded-md border">
55
+ <Sidebar disable-collapse width="14rem">
56
+ <!-- App switcher — the app owns the header. -->
57
+ <div class="flex shrink-0 items-center p-2">
58
+ <button
59
+ class="flex h-8 w-full items-center gap-2 rounded px-1 transition hover:bg-surface-gray-2"
60
+ >
61
+ <div
62
+ class="grid size-6 shrink-0 place-items-center rounded bg-surface-gray-7 text-xs font-medium text-ink-white"
63
+ >
64
+ F
65
+ </div>
66
+ <span class="flex-1 truncate text-left text-base text-ink-gray-8">Frappe</span>
67
+ <span class="lucide-chevrons-up-down size-4 shrink-0 text-ink-gray-5" />
68
+ </button>
69
+ </div>
70
+
71
+ <!--
72
+ The app owns the scroll region. frappe-ui's ScrollArea keeps the thin,
73
+ auto-hiding overlay scrollbar; padding the viewport (px-2) gives the
74
+ active row's shadow room so overflow-hidden doesn't clip it.
75
+ -->
76
+ <ScrollArea class="min-h-0 flex-1" viewport-class="px-2 pt-0.5 pb-10">
77
+ <div class="flex h-7 items-center justify-between">
78
+ <SidebarLabel>Spaces</SidebarLabel>
79
+ <div class="flex items-center">
80
+ <Dropdown :options="sortOptions" align="end">
81
+ <template #trigger="{ open }">
82
+ <Button
83
+ variant="ghost"
84
+ size="sm"
85
+ icon="lucide-arrow-up-down text-ink-gray-5"
86
+ label="Sort spaces"
87
+ tooltip="Sort spaces"
88
+ :active="open"
89
+ />
90
+ </template>
91
+ </Dropdown>
92
+ <Button
93
+ variant="ghost"
94
+ size="sm"
95
+ icon="lucide-plus text-ink-gray-5"
96
+ label="New space"
97
+ />
98
+ </div>
99
+ </div>
100
+
101
+ <nav class="mt-0.5 space-y-0.5">
102
+ <SidebarItem
103
+ v-for="space in spaces"
104
+ :key="space.id"
105
+ :icon="space.icon"
106
+ :active="active === space.id"
107
+ @click="active = space.id"
108
+ >
109
+ <span class="flex-1 inline-flex items-center gap-1 truncate text-sm">
110
+ <span
111
+ v-if="space.private"
112
+ class="lucide-lock size-3 shrink-0 text-ink-gray-5"
113
+ />
114
+ {{ space.title }}
115
+ </span>
116
+
117
+ <template #suffix>
118
+ <!--
119
+ Count and options menu share one cell: the count fades out on row
120
+ hover/focus while the "…" menu fades in. The group is
121
+ SidebarItem's root (`group/sidebar-item`).
122
+ -->
123
+ <div class="relative mr-1 flex size-7 shrink-0 items-center justify-end">
124
+ <span
125
+ v-if="space.unread > 0"
126
+ class="absolute right-1 text-xs text-ink-gray-5 transition-opacity group-hover/sidebar-item:opacity-0 group-focus-within/sidebar-item:opacity-0"
127
+ >
128
+ {{ space.unread }}
129
+ </span>
130
+ <Dropdown
131
+ :options="[{ label: 'Mark all as read' }, { label: 'Leave space' }]"
132
+ align="start"
133
+ side="right"
134
+ >
135
+ <template #default="{ open }">
136
+ <Button
137
+ :variant="open ? 'subtle' : 'ghost'"
138
+ size="xs"
139
+ icon="lucide-more-horizontal text-ink-gray-5"
140
+ :label="`${space.title} options`"
141
+ class="absolute right-0 -mr-0.5 opacity-0 group-hover/sidebar-item:opacity-100 group-focus-within/sidebar-item:opacity-100"
142
+ :class="open ? 'opacity-100' : ''"
143
+ />
144
+ </template>
145
+ </Dropdown>
146
+ </div>
147
+ </template>
148
+ </SidebarItem>
149
+ </nav>
150
+ </ScrollArea>
151
+ </Sidebar>
152
+ </div>
153
+ </template>
@@ -0,0 +1,36 @@
1
+ <script setup lang="ts">
2
+ // The deprecated config-object API, kept working for one release on top of the
3
+ // new sub-components. Prefer the composition API (see Default) for new code.
4
+ import { Sidebar } from 'frappe-ui'
5
+
6
+ const header = {
7
+ title: 'Frappe CRM',
8
+ subtitle: 'crm.frappe.io',
9
+ menuItems: [{ label: 'Settings' }, { label: 'Log out' }],
10
+ }
11
+
12
+ const sections = [
13
+ {
14
+ label: '',
15
+ items: [
16
+ { label: 'Leads', to: '/leads', icon: 'lucide-user-plus' },
17
+ { label: 'Deals', to: '/deals', icon: 'lucide-handshake' },
18
+ { label: 'Contacts', to: '/contacts', icon: 'lucide-contact' },
19
+ ],
20
+ },
21
+ {
22
+ label: 'Views',
23
+ collapsible: true,
24
+ items: [
25
+ { label: 'My Open Deals', to: '/my-open-deals', icon: 'lucide-flame' },
26
+ { label: 'Unassigned', to: '/unassigned', icon: 'lucide-circle-dashed' },
27
+ ],
28
+ },
29
+ ]
30
+ </script>
31
+
32
+ <template>
33
+ <div class="flex h-[420px] w-fit overflow-hidden rounded-md border">
34
+ <Sidebar :header="header" :sections="sections" disable-collapse />
35
+ </div>
36
+ </template>
@@ -1,39 +1,124 @@
1
- import type { ComputedRef, InjectionKey, MaybeRefOrGetter } from 'vue'
1
+ import type {
2
+ Component,
3
+ ComputedRef,
4
+ InjectionKey,
5
+ MaybeRefOrGetter,
6
+ } from 'vue'
2
7
  import { RouteLocationRaw } from 'vue-router'
3
8
 
9
+ /**
10
+ * Read-only collapsed state, provided by `Sidebar` and consumed by
11
+ * `SidebarItem` / `SidebarLabel` / `SidebarHeader` to shrink to icon-only.
12
+ */
4
13
  export const sidebarCollapsedKey: InjectionKey<ComputedRef<boolean>> =
5
14
  Symbol('sidebarCollapsed')
6
15
 
7
- export type SidebarHeaderProps = {
8
- title: string
9
- subtitle?: string
10
- logo?: any // Icon component or image string
11
- menuItems?: {
12
- label: string
13
- icon: any // Icon component
14
- onClick?: () => void
15
- }[]
16
+ /**
17
+ * Toggles the sidebar's collapsed state, provided by `Sidebar` and consumed by
18
+ * `SidebarCollapseToggle`. Kept separate from {@link sidebarCollapsedKey} so
19
+ * existing read-only consumers need no change.
20
+ */
21
+ export const sidebarToggleKey: InjectionKey<() => void> =
22
+ Symbol('sidebarToggle')
23
+
24
+ export type SidebarProps = {
25
+ /**
26
+ * @deprecated Config-object header. Prefer composing your own header in the
27
+ * default slot. Kept for one release for backward compatibility.
28
+ */
29
+ header?: SidebarHeaderProps
30
+
31
+ /**
32
+ * @deprecated Config-object sections. Prefer composing `SidebarLabel` +
33
+ * `SidebarItem` in the default slot. Kept for one release.
34
+ */
35
+ sections?: SidebarSectionProps[]
36
+
37
+ /** Disables collapsing entirely (fixed width, no built-in toggle). */
38
+ disableCollapse?: boolean
39
+
40
+ /** Expanded width as a CSS length. Applied inline so apps can override it. */
41
+ width?: string
42
+
43
+ /** Collapsed width as a CSS length. */
44
+ collapsedWidth?: string
16
45
  }
17
46
 
18
- export type SidebarItemProps = {
19
- label: string
47
+ export interface SidebarItemProps {
48
+ /** Row label. Used as the accessible name and the default slot fallback. */
49
+ label?: string
50
+
51
+ /** `accesskey` attribute for a keyboard shortcut. */
20
52
  accessKey?: string
21
- icon?: any // Icon component
53
+
54
+ /**
55
+ * Leading icon: a CSS class (e.g. `lucide-box`), plain text, or a component.
56
+ * Ignored when the `#prefix` slot is used.
57
+ */
58
+ icon?: string | Component
59
+
60
+ /** Trailing text. Ignored when the `#suffix` slot is used. */
22
61
  suffix?: string
62
+
63
+ /**
64
+ * Navigation target. When set the row's main area renders as a router link;
65
+ * otherwise it renders as a button. A click still invokes `onClick`.
66
+ */
23
67
  to?: RouteLocationRaw
68
+
69
+ /**
70
+ * Marks the row active (`data-state="active"`). When omitted, active state is
71
+ * inferred by matching `to` against the current route.
72
+ */
73
+ active?: boolean
74
+
75
+ /** @deprecated Use `active`. Alias kept for the config-object path. */
24
76
  isActive?: boolean
25
- onClick?: () => void
77
+
78
+ /**
79
+ * Click handler. Bound from `@click` in composition and from `item.onClick`
80
+ * in the config-object path — both resolve to this prop.
81
+ */
82
+ onClick?: (event: MouseEvent) => void
83
+
84
+ /** @deprecated Config-object visibility flag; filtered by the legacy adapter. */
26
85
  condition?: MaybeRefOrGetter<boolean>
27
86
  }
28
87
 
88
+ export interface SidebarLabelProps {
89
+ /**
90
+ * When true, collapses to a horizontal divider while the sidebar is collapsed
91
+ * (matches the previous `SidebarSection` label behavior).
92
+ */
93
+ divider?: boolean
94
+ }
95
+
96
+ export type SidebarHeaderProps = {
97
+ title: string
98
+ subtitle?: string
99
+ logo?: string | Component
100
+ /**
101
+ * Whether to render the leading logo/avatar box. Defaults to `true`. Set to
102
+ * `false` when workspace identity is already shown elsewhere (e.g. a left
103
+ * rail) to avoid a duplicate avatar; the title then sits flush-left. Best
104
+ * paired with a non-collapsing sidebar, since a collapsed header with no logo
105
+ * has nothing to show.
106
+ */
107
+ showLogo?: boolean
108
+ menuItems?: {
109
+ label: string
110
+ icon?: string | Component
111
+ onClick?: () => void
112
+ }[]
113
+ }
114
+
115
+ /**
116
+ * @deprecated Legacy config-object section shape. Rendered by the internal
117
+ * `SidebarSection` adapter for `Sidebar`'s `sections` prop. New code composes
118
+ * `SidebarLabel` + `SidebarItem` directly.
119
+ */
29
120
  export type SidebarSectionProps = {
30
121
  label?: string
31
122
  items: SidebarItemProps[]
32
123
  collapsible?: boolean
33
124
  }
34
-
35
- export type SidebarProps = {
36
- header?: SidebarHeaderProps
37
- sections?: SidebarSectionProps[]
38
- disableCollapse?: boolean
39
- }
@@ -0,0 +1,21 @@
1
+ import Skeleton from './Skeleton.vue'
2
+
3
+ describe('Skeleton', () => {
4
+ it('renders an animated placeholder', () => {
5
+ cy.mount(Skeleton)
6
+
7
+ cy.get('.fui-skeleton')
8
+ .should('exist')
9
+ .and('have.class', 'animate-pulse')
10
+ .and('have.attr', 'aria-hidden', 'true')
11
+ })
12
+
13
+ it('is sized by the classes passed to it', () => {
14
+ cy.mount(Skeleton, { attrs: { class: 'h-5 w-48' } })
15
+
16
+ cy.get('.fui-skeleton').should(($el) => {
17
+ expect($el[0].clientHeight).to.equal(20)
18
+ expect($el[0].clientWidth).to.equal(192)
19
+ })
20
+ })
21
+ })
@@ -0,0 +1,21 @@
1
+ # Skeleton
2
+
3
+ A placeholder block that communicates loading content. Render it in place of content while data loads, then swap it for the real element once ready.
4
+
5
+ ## Text
6
+
7
+ <ComponentPreview name="Skeleton-Text" />
8
+
9
+ ## List
10
+
11
+ <ComponentPreview name="Skeleton-List" />
12
+
13
+ ## Card
14
+
15
+ <ComponentPreview name="Skeleton-Card" />
16
+
17
+ ## API Reference
18
+
19
+ `Skeleton` takes no props. Control its size and shape with utility classes (or
20
+ inline styles) on the element itself — for example `class="h-5 w-48"` for a text
21
+ line or `class="size-10 rounded-full"` for an avatar.
@@ -0,0 +1,6 @@
1
+ <template>
2
+ <div
3
+ class="fui-skeleton animate-pulse bg-surface-gray-3"
4
+ aria-hidden="true"
5
+ />
6
+ </template>
@@ -0,0 +1 @@
1
+ export { default as Skeleton } from './Skeleton.vue'
@@ -0,0 +1,12 @@
1
+ <script setup lang="ts">
2
+ import { Skeleton } from 'frappe-ui'
3
+ </script>
4
+
5
+ <template>
6
+ <div class="w-64 space-y-4">
7
+ <Skeleton class="h-40 w-full rounded-lg" />
8
+ <Skeleton class="h-5 w-3/5" />
9
+ <Skeleton class="h-4 w-full" />
10
+ <Skeleton class="h-4 w-4/5" />
11
+ </div>
12
+ </template>
@@ -0,0 +1,15 @@
1
+ <script setup lang="ts">
2
+ import { Skeleton } from 'frappe-ui'
3
+ </script>
4
+
5
+ <template>
6
+ <div class="w-64 space-y-3">
7
+ <div v-for="i in 4" :key="i" class="flex items-center gap-3">
8
+ <Skeleton class="size-10 rounded-full" />
9
+ <div class="flex-1 space-y-2">
10
+ <Skeleton class="h-4 w-40" />
11
+ <Skeleton class="h-4 w-24" />
12
+ </div>
13
+ </div>
14
+ </div>
15
+ </template>
@@ -0,0 +1,11 @@
1
+ <script setup lang="ts">
2
+ import { Skeleton } from 'frappe-ui'
3
+ </script>
4
+
5
+ <template>
6
+ <div class="space-y-3">
7
+ <Skeleton class="h-5 w-48" />
8
+ <Skeleton class="h-5 w-72" />
9
+ <Skeleton class="h-5 w-60" />
10
+ </div>
11
+ </template>
@@ -21,7 +21,7 @@
21
21
  },
22
22
  {
23
23
  name: 'min',
24
- description: 'Minimum allowed slider value.',
24
+ description: 'Minimum allowed slider value. Negative values enable bidirectional fill from zero.',
25
25
  required: false,
26
26
  type: 'number',
27
27
  default: '0'
@@ -102,4 +102,33 @@ describe('Slider', () => {
102
102
  cy.get('#sl-err').should('have.attr', 'data-state', 'invalid')
103
103
  })
104
104
  })
105
+
106
+ describe('bidirectional fill', () => {
107
+ // Targets the range element: the only absolutely-positioned element inside the control.
108
+ const range = () => cy.get('[data-slot="control"] .absolute')
109
+
110
+ it('fills from zero-crossing to a positive value', () => {
111
+ cy.mount(Slider, { props: { modelValue: [50], min: -100, max: 100 } })
112
+ range()
113
+ .should('have.attr', 'style')
114
+ .and('include', 'left: 50%')
115
+ .and('include', 'right: 25%')
116
+ })
117
+
118
+ it('fills from a negative value to the zero-crossing', () => {
119
+ cy.mount(Slider, { props: { modelValue: [-50], min: -100, max: 100 } })
120
+ range()
121
+ .should('have.attr', 'style')
122
+ .and('include', 'left: 25%')
123
+ .and('include', 'right: 50%')
124
+ })
125
+
126
+ it('renders zero-width fill when value is at zero', () => {
127
+ cy.mount(Slider, { props: { modelValue: [0], min: -100, max: 100 } })
128
+ range()
129
+ .should('have.attr', 'style')
130
+ .and('include', 'left: 50%')
131
+ .and('include', 'right: 50%')
132
+ })
133
+ })
105
134
  })
@@ -2,6 +2,10 @@
2
2
 
3
3
  A slider input for selecting a single value or a range of values within a minimum and maximum.
4
4
 
5
+ ## Playground
6
+
7
+ <ClientOnly><SliderBuilder /></ClientOnly>
8
+
5
9
  <ComponentPreview name="Slider-Default" layout="stacked" />
6
10
 
7
11
  ## Sizes
@@ -14,6 +18,12 @@ Use a two-element `modelValue` to render two thumbs.
14
18
 
15
19
  <ComponentPreview name="Slider-Range" />
16
20
 
21
+ ## Negative Values
22
+
23
+ When `min` is negative the slider fills bidirectionally from the zero-crossing, so positive and negative values are visually distinct.
24
+
25
+ <ComponentPreview name="Slider-NegativeValues" />
26
+
17
27
  ## Labeling
18
28
 
19
29
  <ComponentPreview name="Slider-Labeling" />