@arbor-education/design-system.components 0.25.9 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gather/instructions/project-overview.md +1 -1
- package/CHANGELOG.md +14 -0
- package/CONTRIBUTING.md +7 -5
- package/component-library.md +97 -3
- package/dist/components/emptyState/EmptyState.d.ts +22 -0
- package/dist/components/emptyState/EmptyState.d.ts.map +1 -0
- package/dist/components/emptyState/EmptyState.js +11 -0
- package/dist/components/emptyState/EmptyState.js.map +1 -0
- package/dist/components/emptyState/EmptyState.stories.d.ts +117 -0
- package/dist/components/emptyState/EmptyState.stories.d.ts.map +1 -0
- package/dist/components/emptyState/EmptyState.stories.js +332 -0
- package/dist/components/emptyState/EmptyState.stories.js.map +1 -0
- package/dist/components/emptyState/EmptyState.test.d.ts +2 -0
- package/dist/components/emptyState/EmptyState.test.d.ts.map +1 -0
- package/dist/components/emptyState/EmptyState.test.js +80 -0
- package/dist/components/emptyState/EmptyState.test.js.map +1 -0
- package/dist/components/favourite/FavouriteButton.d.ts +18 -0
- package/dist/components/favourite/FavouriteButton.d.ts.map +1 -0
- package/dist/components/favourite/FavouriteButton.js +16 -0
- package/dist/components/favourite/FavouriteButton.js.map +1 -0
- package/dist/components/favourite/FavouriteButton.test.d.ts +2 -0
- package/dist/components/favourite/FavouriteButton.test.d.ts.map +1 -0
- package/dist/components/favourite/FavouriteButton.test.js +37 -0
- package/dist/components/favourite/FavouriteButton.test.js.map +1 -0
- package/dist/components/filterBar/FilterBar.d.ts +1 -1
- package/dist/components/filterBar/FilterBar.stories.d.ts +1 -1
- package/dist/components/icon/Icon.d.ts +1 -1
- package/dist/components/icon/Icon.d.ts.map +1 -1
- package/dist/components/icon/Icon.js +1 -1
- package/dist/components/icon/Icon.js.map +1 -1
- package/dist/components/pill/Pill.d.ts +3 -2
- package/dist/components/pill/Pill.d.ts.map +1 -1
- package/dist/components/pill/Pill.js +15 -9
- package/dist/components/pill/Pill.js.map +1 -1
- package/dist/components/pill/Pill.stories.d.ts +21 -3
- package/dist/components/pill/Pill.stories.d.ts.map +1 -1
- package/dist/components/pill/Pill.stories.js +275 -40
- package/dist/components/pill/Pill.stories.js.map +1 -1
- package/dist/components/pill/Pill.test.js +64 -3
- package/dist/components/pill/Pill.test.js.map +1 -1
- package/dist/components/sideNavigation/SideNavigation.d.ts +34 -0
- package/dist/components/sideNavigation/SideNavigation.d.ts.map +1 -0
- package/dist/components/sideNavigation/SideNavigation.js +30 -0
- package/dist/components/sideNavigation/SideNavigation.js.map +1 -0
- package/dist/components/sideNavigation/SideNavigation.stories.d.ts +72 -0
- package/dist/components/sideNavigation/SideNavigation.stories.d.ts.map +1 -0
- package/dist/components/sideNavigation/SideNavigation.stories.js +298 -0
- package/dist/components/sideNavigation/SideNavigation.stories.js.map +1 -0
- package/dist/components/sideNavigation/SideNavigation.test.d.ts +2 -0
- package/dist/components/sideNavigation/SideNavigation.test.d.ts.map +1 -0
- package/dist/components/sideNavigation/SideNavigation.test.js +74 -0
- package/dist/components/sideNavigation/SideNavigation.test.js.map +1 -0
- package/dist/components/sideNavigation/SideNavigationContext.d.ts +10 -0
- package/dist/components/sideNavigation/SideNavigationContext.d.ts.map +1 -0
- package/dist/components/sideNavigation/SideNavigationContext.js +15 -0
- package/dist/components/sideNavigation/SideNavigationContext.js.map +1 -0
- package/dist/components/{sidebarNav/SidebarNavGroup.d.ts → sideNavigation/SideNavigationGroup.d.ts} +3 -3
- package/dist/components/sideNavigation/SideNavigationGroup.d.ts.map +1 -0
- package/dist/components/sideNavigation/SideNavigationGroup.js +16 -0
- package/dist/components/sideNavigation/SideNavigationGroup.js.map +1 -0
- package/dist/components/sideNavigation/SideNavigationGroup.test.d.ts +2 -0
- package/dist/components/sideNavigation/SideNavigationGroup.test.d.ts.map +1 -0
- package/dist/components/sideNavigation/SideNavigationGroup.test.js +58 -0
- package/dist/components/sideNavigation/SideNavigationGroup.test.js.map +1 -0
- package/dist/components/{sidebarNav/SidebarNavItem.d.ts → sideNavigation/SideNavigationItem.d.ts} +11 -12
- package/dist/components/sideNavigation/SideNavigationItem.d.ts.map +1 -0
- package/dist/components/sideNavigation/SideNavigationItem.js +28 -0
- package/dist/components/sideNavigation/SideNavigationItem.js.map +1 -0
- package/dist/components/sideNavigation/SideNavigationItem.test.d.ts +2 -0
- package/dist/components/sideNavigation/SideNavigationItem.test.d.ts.map +1 -0
- package/dist/components/sideNavigation/SideNavigationItem.test.js +65 -0
- package/dist/components/sideNavigation/SideNavigationItem.test.js.map +1 -0
- package/dist/components/sideNavigation/SideNavigationItemFavourite.d.ts +8 -0
- package/dist/components/sideNavigation/SideNavigationItemFavourite.d.ts.map +1 -0
- package/dist/components/{sidebarNav/SidebarNavItemFavourite.js → sideNavigation/SideNavigationItemFavourite.js} +5 -5
- package/dist/components/sideNavigation/SideNavigationItemFavourite.js.map +1 -0
- package/dist/components/sideNavigation/SideNavigationItemFavourite.test.d.ts +2 -0
- package/dist/components/sideNavigation/SideNavigationItemFavourite.test.d.ts.map +1 -0
- package/dist/components/sideNavigation/SideNavigationItemFavourite.test.js +31 -0
- package/dist/components/sideNavigation/SideNavigationItemFavourite.test.js.map +1 -0
- package/dist/components/sideNavigation/SideNavigationTitle.d.ts +4 -0
- package/dist/components/sideNavigation/SideNavigationTitle.d.ts.map +1 -0
- package/dist/components/sideNavigation/SideNavigationTitle.js +7 -0
- package/dist/components/sideNavigation/SideNavigationTitle.js.map +1 -0
- package/dist/components/sideNavigation/SideNavigationTitle.test.d.ts +2 -0
- package/dist/components/sideNavigation/SideNavigationTitle.test.d.ts.map +1 -0
- package/dist/components/sideNavigation/SideNavigationTitle.test.js +22 -0
- package/dist/components/sideNavigation/SideNavigationTitle.test.js.map +1 -0
- package/dist/components/sideNavigation/SideNavigationTooltip.d.ts +7 -0
- package/dist/components/sideNavigation/SideNavigationTooltip.d.ts.map +1 -0
- package/dist/components/{sidebarNav/SidebarNavTooltip.js → sideNavigation/SideNavigationTooltip.js} +2 -2
- package/dist/components/sideNavigation/SideNavigationTooltip.js.map +1 -0
- package/dist/components/sideNavigation/SideNavigationTooltip.test.d.ts +2 -0
- package/dist/components/sideNavigation/SideNavigationTooltip.test.d.ts.map +1 -0
- package/dist/components/sideNavigation/SideNavigationTooltip.test.js +26 -0
- package/dist/components/sideNavigation/SideNavigationTooltip.test.js.map +1 -0
- package/dist/components/sideNavigation/resolvePanelItemProps.d.ts +4 -0
- package/dist/components/sideNavigation/resolvePanelItemProps.d.ts.map +1 -0
- package/dist/components/{sidebarNav → sideNavigation}/resolvePanelItemProps.js +5 -4
- package/dist/components/sideNavigation/resolvePanelItemProps.js.map +1 -0
- package/dist/components/sideNavigation/resolvePanelItemProps.test.d.ts.map +1 -0
- package/dist/components/{sidebarNav → sideNavigation}/resolvePanelItemProps.test.js +18 -4
- package/dist/components/sideNavigation/resolvePanelItemProps.test.js.map +1 -0
- package/dist/components/sideNavigation/types.d.ts +47 -0
- package/dist/components/sideNavigation/types.d.ts.map +1 -0
- package/dist/components/sideNavigation/types.js +2 -0
- package/dist/components/sideNavigation/types.js.map +1 -0
- package/dist/components/sidebar/Sidebar.d.ts +13 -0
- package/dist/components/sidebar/Sidebar.d.ts.map +1 -0
- package/dist/components/sidebar/Sidebar.js +9 -0
- package/dist/components/sidebar/Sidebar.js.map +1 -0
- package/dist/components/sidebar/Sidebar.stories.d.ts +48 -0
- package/dist/components/sidebar/Sidebar.stories.d.ts.map +1 -0
- package/dist/components/sidebar/Sidebar.stories.js +444 -0
- package/dist/components/sidebar/Sidebar.stories.js.map +1 -0
- package/dist/components/sidebar/Sidebar.test.d.ts +2 -0
- package/dist/components/sidebar/Sidebar.test.d.ts.map +1 -0
- package/dist/components/sidebar/Sidebar.test.js +81 -0
- package/dist/components/sidebar/Sidebar.test.js.map +1 -0
- package/dist/components/sidebar/SidebarItem.d.ts +7 -0
- package/dist/components/sidebar/SidebarItem.d.ts.map +1 -0
- package/dist/components/sidebar/SidebarItem.js +11 -0
- package/dist/components/sidebar/SidebarItem.js.map +1 -0
- package/dist/components/singleUser/SingleUser.d.ts +1 -1
- package/dist/components/tabs/TabsItem.stories.d.ts +2 -2
- package/dist/components/toast/Toast.d.ts +11 -2
- package/dist/components/toast/Toast.d.ts.map +1 -1
- package/dist/components/toast/Toast.js +5 -3
- package/dist/components/toast/Toast.js.map +1 -1
- package/dist/components/toast/Toast.stories.d.ts +15 -3
- package/dist/components/toast/Toast.stories.d.ts.map +1 -1
- package/dist/components/toast/Toast.stories.js +43 -41
- package/dist/components/toast/Toast.stories.js.map +1 -1
- package/dist/components/toast/Toast.test.js +19 -4
- package/dist/components/toast/Toast.test.js.map +1 -1
- package/dist/components/toast/ToastAction.d.ts +7 -0
- package/dist/components/toast/ToastAction.d.ts.map +1 -0
- package/dist/components/toast/ToastAction.js +9 -0
- package/dist/components/toast/ToastAction.js.map +1 -0
- package/dist/components/tooltip/TooltipWrapper.d.ts +1 -0
- package/dist/components/tooltip/TooltipWrapper.d.ts.map +1 -1
- package/dist/components/tooltip/TooltipWrapper.js +2 -2
- package/dist/components/tooltip/TooltipWrapper.js.map +1 -1
- package/dist/components/widget/Widget.d.ts +18 -0
- package/dist/components/widget/Widget.d.ts.map +1 -0
- package/dist/components/widget/Widget.js +51 -0
- package/dist/components/widget/Widget.js.map +1 -0
- package/dist/components/widget/Widget.stories.d.ts +128 -0
- package/dist/components/widget/Widget.stories.d.ts.map +1 -0
- package/dist/components/widget/Widget.stories.js +417 -0
- package/dist/components/widget/Widget.stories.js.map +1 -0
- package/dist/components/widget/Widget.test.d.ts +2 -0
- package/dist/components/widget/Widget.test.d.ts.map +1 -0
- package/dist/components/widget/Widget.test.js +110 -0
- package/dist/components/widget/Widget.test.js.map +1 -0
- package/dist/components/widget/WidgetBody.d.ts +6 -0
- package/dist/components/widget/WidgetBody.d.ts.map +1 -0
- package/dist/components/widget/WidgetBody.js +20 -0
- package/dist/components/widget/WidgetBody.js.map +1 -0
- package/dist/components/widget/WidgetContext.d.ts +20 -0
- package/dist/components/widget/WidgetContext.d.ts.map +1 -0
- package/dist/components/widget/WidgetContext.js +10 -0
- package/dist/components/widget/WidgetContext.js.map +1 -0
- package/dist/components/widget/WidgetHeader.d.ts +8 -0
- package/dist/components/widget/WidgetHeader.d.ts.map +1 -0
- package/dist/components/widget/WidgetHeader.js +56 -0
- package/dist/components/widget/WidgetHeader.js.map +1 -0
- package/dist/components/widget/types.d.ts +43 -0
- package/dist/components/widget/types.d.ts.map +1 -0
- package/dist/components/widget/types.js +2 -0
- package/dist/components/widget/types.js.map +1 -0
- package/dist/components/widgetCalendar/WidgetCalendar.d.ts +35 -0
- package/dist/components/widgetCalendar/WidgetCalendar.d.ts.map +1 -0
- package/dist/components/widgetCalendar/WidgetCalendar.js +22 -0
- package/dist/components/widgetCalendar/WidgetCalendar.js.map +1 -0
- package/dist/components/widgetCalendar/WidgetCalendar.stories.d.ts +60 -0
- package/dist/components/widgetCalendar/WidgetCalendar.stories.d.ts.map +1 -0
- package/dist/components/widgetCalendar/WidgetCalendar.stories.js +140 -0
- package/dist/components/widgetCalendar/WidgetCalendar.stories.js.map +1 -0
- package/dist/components/widgetCalendar/WidgetCalendar.test.d.ts +2 -0
- package/dist/components/widgetCalendar/WidgetCalendar.test.d.ts.map +1 -0
- package/dist/components/widgetCalendar/WidgetCalendar.test.js +88 -0
- package/dist/components/widgetCalendar/WidgetCalendar.test.js.map +1 -0
- package/dist/components/widgetCalendar/WidgetCalendarItem.d.ts +17 -0
- package/dist/components/widgetCalendar/WidgetCalendarItem.d.ts.map +1 -0
- package/dist/components/widgetCalendar/WidgetCalendarItem.js +25 -0
- package/dist/components/widgetCalendar/WidgetCalendarItem.js.map +1 -0
- package/dist/components/widgetFavourites/WidgetFavourites.d.ts +12 -0
- package/dist/components/widgetFavourites/WidgetFavourites.d.ts.map +1 -0
- package/dist/components/widgetFavourites/WidgetFavourites.js +23 -0
- package/dist/components/widgetFavourites/WidgetFavourites.js.map +1 -0
- package/dist/components/widgetFavourites/WidgetFavourites.stories.d.ts +84 -0
- package/dist/components/widgetFavourites/WidgetFavourites.stories.d.ts.map +1 -0
- package/dist/components/widgetFavourites/WidgetFavourites.stories.js +210 -0
- package/dist/components/widgetFavourites/WidgetFavourites.stories.js.map +1 -0
- package/dist/components/widgetFavourites/WidgetFavourites.test.d.ts +2 -0
- package/dist/components/widgetFavourites/WidgetFavourites.test.d.ts.map +1 -0
- package/dist/components/widgetFavourites/WidgetFavourites.test.js +67 -0
- package/dist/components/widgetFavourites/WidgetFavourites.test.js.map +1 -0
- package/dist/components/widgetFavourites/WidgetFavouritesItem.d.ts +3 -0
- package/dist/components/widgetFavourites/WidgetFavouritesItem.d.ts.map +1 -0
- package/dist/components/widgetFavourites/WidgetFavouritesItem.js +10 -0
- package/dist/components/widgetFavourites/WidgetFavouritesItem.js.map +1 -0
- package/dist/components/widgetFavourites/types.d.ts +25 -0
- package/dist/components/widgetFavourites/types.d.ts.map +1 -0
- package/dist/components/widgetFavourites/types.js +2 -0
- package/dist/components/widgetFavourites/types.js.map +1 -0
- package/dist/components/widgetNotifications/WidgetNotifications.d.ts +33 -0
- package/dist/components/widgetNotifications/WidgetNotifications.d.ts.map +1 -0
- package/dist/components/widgetNotifications/WidgetNotifications.js +18 -0
- package/dist/components/widgetNotifications/WidgetNotifications.js.map +1 -0
- package/dist/components/widgetNotifications/WidgetNotifications.stories.d.ts +60 -0
- package/dist/components/widgetNotifications/WidgetNotifications.stories.d.ts.map +1 -0
- package/dist/components/widgetNotifications/WidgetNotifications.stories.js +269 -0
- package/dist/components/widgetNotifications/WidgetNotifications.stories.js.map +1 -0
- package/dist/components/widgetNotifications/WidgetNotifications.test.d.ts +2 -0
- package/dist/components/widgetNotifications/WidgetNotifications.test.d.ts.map +1 -0
- package/dist/components/widgetNotifications/WidgetNotifications.test.js +79 -0
- package/dist/components/widgetNotifications/WidgetNotifications.test.js.map +1 -0
- package/dist/components/widgetNotifications/WidgetNotificationsItem.d.ts +14 -0
- package/dist/components/widgetNotifications/WidgetNotificationsItem.d.ts.map +1 -0
- package/dist/components/widgetNotifications/WidgetNotificationsItem.js +14 -0
- package/dist/components/widgetNotifications/WidgetNotificationsItem.js.map +1 -0
- package/dist/index.css +756 -78
- package/dist/index.css.map +1 -1
- package/dist/index.d.ts +15 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -8
- package/dist/index.js.map +1 -1
- package/dist/utils/favourites/favouriteConstants.d.ts +12 -0
- package/dist/utils/favourites/favouriteConstants.d.ts.map +1 -0
- package/dist/utils/favourites/favouriteConstants.js +16 -0
- package/dist/utils/favourites/favouriteConstants.js.map +1 -0
- package/dist/utils/favourites/favouriteConstants.test.d.ts +2 -0
- package/dist/utils/favourites/favouriteConstants.test.d.ts.map +1 -0
- package/dist/utils/favourites/favouriteConstants.test.js +12 -0
- package/dist/utils/favourites/favouriteConstants.test.js.map +1 -0
- package/dist/utils/hooks/useControllableBoolean.d.ts.map +1 -0
- package/dist/utils/hooks/useControllableBoolean.js.map +1 -0
- package/dist/utils/hooks/useControllableBoolean.test.d.ts +2 -0
- package/dist/utils/hooks/useControllableBoolean.test.d.ts.map +1 -0
- package/dist/utils/hooks/useControllableBoolean.test.js +34 -0
- package/dist/utils/hooks/useControllableBoolean.test.js.map +1 -0
- package/package.json +1 -1
- package/src/components/emptyState/EmptyState.stories.tsx +487 -0
- package/src/components/emptyState/EmptyState.test.tsx +140 -0
- package/src/components/emptyState/EmptyState.tsx +84 -0
- package/src/components/emptyState/emptyState.scss +63 -0
- package/src/components/favourite/FavouriteButton.test.tsx +83 -0
- package/src/components/favourite/FavouriteButton.tsx +70 -0
- package/src/components/favourite/favouriteButton.scss +37 -0
- package/src/components/icon/Icon.tsx +2 -2
- package/src/components/link/link.scss +26 -0
- package/src/components/pill/Pill.stories.tsx +432 -41
- package/src/components/pill/Pill.test.tsx +74 -3
- package/src/components/pill/Pill.tsx +26 -11
- package/src/components/sideNavigation/SideNavigation.stories.tsx +578 -0
- package/src/components/sideNavigation/SideNavigation.test.tsx +109 -0
- package/src/components/sideNavigation/SideNavigation.tsx +98 -0
- package/src/components/sideNavigation/SideNavigationContext.tsx +25 -0
- package/src/components/sideNavigation/SideNavigationGroup.test.tsx +103 -0
- package/src/components/{sidebarNav/SidebarNavGroup.tsx → sideNavigation/SideNavigationGroup.tsx} +8 -8
- package/src/components/sideNavigation/SideNavigationItem.test.tsx +137 -0
- package/src/components/sideNavigation/SideNavigationItem.tsx +125 -0
- package/src/components/sideNavigation/SideNavigationItemFavourite.test.tsx +54 -0
- package/src/components/{sidebarNav/SidebarNavItemFavourite.tsx → sideNavigation/SideNavigationItemFavourite.tsx} +7 -7
- package/src/components/sideNavigation/SideNavigationTitle.test.tsx +23 -0
- package/src/components/sideNavigation/SideNavigationTitle.tsx +13 -0
- package/src/components/sideNavigation/SideNavigationTooltip.test.tsx +44 -0
- package/src/components/{sidebarNav/SidebarNavTooltip.tsx → sideNavigation/SideNavigationTooltip.tsx} +2 -2
- package/src/components/{sidebarNav → sideNavigation}/resolvePanelItemProps.test.ts +20 -4
- package/src/components/{sidebarNav → sideNavigation}/resolvePanelItemProps.ts +8 -7
- package/src/components/{sidebarNav/sidebarNav.scss → sideNavigation/sideNavigation.scss} +37 -136
- package/src/components/sideNavigation/types.ts +56 -0
- package/src/components/sidebar/Sidebar.stories.tsx +670 -0
- package/src/components/sidebar/Sidebar.test.tsx +155 -0
- package/src/components/sidebar/Sidebar.tsx +27 -0
- package/src/components/sidebar/SidebarItem.tsx +64 -0
- package/src/components/sidebar/sidebar.scss +65 -0
- package/src/components/toast/Toast.stories.tsx +75 -67
- package/src/components/toast/Toast.test.tsx +40 -10
- package/src/components/toast/Toast.tsx +19 -5
- package/src/components/toast/ToastAction.tsx +17 -0
- package/src/components/toast/toast.scss +37 -0
- package/src/components/tooltip/TooltipWrapper.tsx +3 -1
- package/src/components/widget/Widget.stories.tsx +600 -0
- package/src/components/widget/Widget.test.tsx +263 -0
- package/src/components/widget/Widget.tsx +102 -0
- package/src/components/widget/WidgetBody.tsx +66 -0
- package/src/components/widget/WidgetContext.tsx +31 -0
- package/src/components/widget/WidgetHeader.tsx +155 -0
- package/src/components/widget/types.ts +47 -0
- package/src/components/widget/widget.scss +218 -0
- package/src/components/widgetCalendar/WidgetCalendar.stories.tsx +241 -0
- package/src/components/widgetCalendar/WidgetCalendar.test.tsx +137 -0
- package/src/components/widgetCalendar/WidgetCalendar.tsx +105 -0
- package/src/components/widgetCalendar/WidgetCalendarItem.tsx +105 -0
- package/src/components/widgetCalendar/widgetCalendar.scss +124 -0
- package/src/components/widgetFavourites/WidgetFavourites.stories.tsx +341 -0
- package/src/components/widgetFavourites/WidgetFavourites.test.tsx +127 -0
- package/src/components/widgetFavourites/WidgetFavourites.tsx +83 -0
- package/src/components/widgetFavourites/WidgetFavouritesItem.tsx +37 -0
- package/src/components/widgetFavourites/types.ts +26 -0
- package/src/components/widgetFavourites/widgetFavourites.scss +84 -0
- package/src/components/widgetNotifications/WidgetNotifications.stories.tsx +417 -0
- package/src/components/widgetNotifications/WidgetNotifications.test.tsx +152 -0
- package/src/components/widgetNotifications/WidgetNotifications.tsx +112 -0
- package/src/components/widgetNotifications/WidgetNotificationsItem.tsx +88 -0
- package/src/components/widgetNotifications/widgetNotifications.scss +186 -0
- package/src/docs/Contributing.mdx +1 -1
- package/src/index.scss +9 -1
- package/src/index.ts +22 -18
- package/src/tokens.scss +12 -2
- package/src/utils/favourites/favouriteConstants.test.ts +19 -0
- package/src/utils/favourites/favouriteConstants.ts +21 -0
- package/src/utils/hooks/useControllableBoolean.test.ts +48 -0
- package/dist/components/sidebarNav/SidebarNav.d.ts +0 -46
- package/dist/components/sidebarNav/SidebarNav.d.ts.map +0 -1
- package/dist/components/sidebarNav/SidebarNav.js +0 -102
- package/dist/components/sidebarNav/SidebarNav.js.map +0 -1
- package/dist/components/sidebarNav/SidebarNav.stories.d.ts +0 -61
- package/dist/components/sidebarNav/SidebarNav.stories.d.ts.map +0 -1
- package/dist/components/sidebarNav/SidebarNav.stories.js +0 -253
- package/dist/components/sidebarNav/SidebarNav.stories.js.map +0 -1
- package/dist/components/sidebarNav/SidebarNav.test.d.ts +0 -2
- package/dist/components/sidebarNav/SidebarNav.test.d.ts.map +0 -1
- package/dist/components/sidebarNav/SidebarNav.test.js +0 -240
- package/dist/components/sidebarNav/SidebarNav.test.js.map +0 -1
- package/dist/components/sidebarNav/SidebarNavContext.d.ts +0 -13
- package/dist/components/sidebarNav/SidebarNavContext.d.ts.map +0 -1
- package/dist/components/sidebarNav/SidebarNavContext.js +0 -15
- package/dist/components/sidebarNav/SidebarNavContext.js.map +0 -1
- package/dist/components/sidebarNav/SidebarNavGroup.d.ts.map +0 -1
- package/dist/components/sidebarNav/SidebarNavGroup.js +0 -16
- package/dist/components/sidebarNav/SidebarNavGroup.js.map +0 -1
- package/dist/components/sidebarNav/SidebarNavItem.d.ts.map +0 -1
- package/dist/components/sidebarNav/SidebarNavItem.js +0 -44
- package/dist/components/sidebarNav/SidebarNavItem.js.map +0 -1
- package/dist/components/sidebarNav/SidebarNavItemFavourite.d.ts +0 -8
- package/dist/components/sidebarNav/SidebarNavItemFavourite.d.ts.map +0 -1
- package/dist/components/sidebarNav/SidebarNavItemFavourite.js.map +0 -1
- package/dist/components/sidebarNav/SidebarNavPanel.d.ts +0 -4
- package/dist/components/sidebarNav/SidebarNavPanel.d.ts.map +0 -1
- package/dist/components/sidebarNav/SidebarNavPanel.js +0 -9
- package/dist/components/sidebarNav/SidebarNavPanel.js.map +0 -1
- package/dist/components/sidebarNav/SidebarNavPanelNav.d.ts +0 -10
- package/dist/components/sidebarNav/SidebarNavPanelNav.d.ts.map +0 -1
- package/dist/components/sidebarNav/SidebarNavPanelNav.js +0 -21
- package/dist/components/sidebarNav/SidebarNavPanelNav.js.map +0 -1
- package/dist/components/sidebarNav/SidebarNavRail.d.ts +0 -6
- package/dist/components/sidebarNav/SidebarNavRail.d.ts.map +0 -1
- package/dist/components/sidebarNav/SidebarNavRail.js +0 -7
- package/dist/components/sidebarNav/SidebarNavRail.js.map +0 -1
- package/dist/components/sidebarNav/SidebarNavRailItem.d.ts +0 -10
- package/dist/components/sidebarNav/SidebarNavRailItem.d.ts.map +0 -1
- package/dist/components/sidebarNav/SidebarNavRailItem.js +0 -25
- package/dist/components/sidebarNav/SidebarNavRailItem.js.map +0 -1
- package/dist/components/sidebarNav/SidebarNavRailList.d.ts +0 -4
- package/dist/components/sidebarNav/SidebarNavRailList.d.ts.map +0 -1
- package/dist/components/sidebarNav/SidebarNavRailList.js +0 -7
- package/dist/components/sidebarNav/SidebarNavRailList.js.map +0 -1
- package/dist/components/sidebarNav/SidebarNavRailSlot.d.ts +0 -6
- package/dist/components/sidebarNav/SidebarNavRailSlot.d.ts.map +0 -1
- package/dist/components/sidebarNav/SidebarNavRailSlot.js +0 -7
- package/dist/components/sidebarNav/SidebarNavRailSlot.js.map +0 -1
- package/dist/components/sidebarNav/SidebarNavSeparator.d.ts +0 -6
- package/dist/components/sidebarNav/SidebarNavSeparator.d.ts.map +0 -1
- package/dist/components/sidebarNav/SidebarNavSeparator.js +0 -8
- package/dist/components/sidebarNav/SidebarNavSeparator.js.map +0 -1
- package/dist/components/sidebarNav/SidebarNavTitle.d.ts +0 -4
- package/dist/components/sidebarNav/SidebarNavTitle.d.ts.map +0 -1
- package/dist/components/sidebarNav/SidebarNavTitle.js +0 -7
- package/dist/components/sidebarNav/SidebarNavTitle.js.map +0 -1
- package/dist/components/sidebarNav/SidebarNavTooltip.d.ts +0 -7
- package/dist/components/sidebarNav/SidebarNavTooltip.d.ts.map +0 -1
- package/dist/components/sidebarNav/SidebarNavTooltip.js.map +0 -1
- package/dist/components/sidebarNav/SidebarNavTrigger.d.ts +0 -8
- package/dist/components/sidebarNav/SidebarNavTrigger.d.ts.map +0 -1
- package/dist/components/sidebarNav/SidebarNavTrigger.js +0 -15
- package/dist/components/sidebarNav/SidebarNavTrigger.js.map +0 -1
- package/dist/components/sidebarNav/index.d.ts +0 -4
- package/dist/components/sidebarNav/index.d.ts.map +0 -1
- package/dist/components/sidebarNav/index.js +0 -3
- package/dist/components/sidebarNav/index.js.map +0 -1
- package/dist/components/sidebarNav/resolvePanelItemProps.d.ts +0 -4
- package/dist/components/sidebarNav/resolvePanelItemProps.d.ts.map +0 -1
- package/dist/components/sidebarNav/resolvePanelItemProps.js.map +0 -1
- package/dist/components/sidebarNav/resolvePanelItemProps.test.d.ts.map +0 -1
- package/dist/components/sidebarNav/resolvePanelItemProps.test.js.map +0 -1
- package/dist/components/sidebarNav/types.d.ts +0 -100
- package/dist/components/sidebarNav/types.d.ts.map +0 -1
- package/dist/components/sidebarNav/types.js +0 -4
- package/dist/components/sidebarNav/types.js.map +0 -1
- package/dist/components/sidebarNav/useControllableBoolean.d.ts.map +0 -1
- package/dist/components/sidebarNav/useControllableBoolean.js.map +0 -1
- package/src/components/sidebarNav/SidebarNav.stories.tsx +0 -484
- package/src/components/sidebarNav/SidebarNav.test.tsx +0 -611
- package/src/components/sidebarNav/SidebarNav.tsx +0 -230
- package/src/components/sidebarNav/SidebarNavContext.tsx +0 -28
- package/src/components/sidebarNav/SidebarNavItem.tsx +0 -162
- package/src/components/sidebarNav/SidebarNavPanel.tsx +0 -20
- package/src/components/sidebarNav/SidebarNavPanelNav.tsx +0 -55
- package/src/components/sidebarNav/SidebarNavRail.tsx +0 -20
- package/src/components/sidebarNav/SidebarNavRailItem.tsx +0 -83
- package/src/components/sidebarNav/SidebarNavRailList.tsx +0 -11
- package/src/components/sidebarNav/SidebarNavRailSlot.tsx +0 -15
- package/src/components/sidebarNav/SidebarNavSeparator.tsx +0 -19
- package/src/components/sidebarNav/SidebarNavTitle.tsx +0 -13
- package/src/components/sidebarNav/SidebarNavTrigger.tsx +0 -52
- package/src/components/sidebarNav/index.ts +0 -6
- package/src/components/sidebarNav/types.ts +0 -126
- /package/dist/components/{sidebarNav → sideNavigation}/resolvePanelItemProps.test.d.ts +0 -0
- /package/dist/{components/sidebarNav → utils/hooks}/useControllableBoolean.d.ts +0 -0
- /package/dist/{components/sidebarNav → utils/hooks}/useControllableBoolean.js +0 -0
- /package/src/{components/sidebarNav → utils/hooks}/useControllableBoolean.ts +0 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import '@testing-library/jest-dom/vitest';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import userEvent from '@testing-library/user-event';
|
|
4
|
+
import { Icon } from 'Components/icon/Icon';
|
|
5
|
+
import { Separator } from 'Components/separator/Separator';
|
|
6
|
+
import { describe, expect, test, vi } from 'vitest';
|
|
7
|
+
import { Sidebar } from './Sidebar.js';
|
|
8
|
+
import { SidebarItem } from './SidebarItem.js';
|
|
9
|
+
|
|
10
|
+
describe('Sidebar', () => {
|
|
11
|
+
test('renders a nav element with default aria-label', () => {
|
|
12
|
+
render(<Sidebar />);
|
|
13
|
+
expect(screen.getByRole('navigation', { name: 'Sidebar' })).toBeInTheDocument();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('renders a nav element with a custom ariaLabel', () => {
|
|
17
|
+
render(<Sidebar ariaLabel="App navigation" />);
|
|
18
|
+
expect(screen.getByRole('navigation', { name: 'App navigation' })).toBeInTheDocument();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('applies data-testid to the nav', () => {
|
|
22
|
+
render(<Sidebar />);
|
|
23
|
+
expect(screen.getByTestId('sidebar')).toBeInTheDocument();
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
describe('SidebarItem', () => {
|
|
28
|
+
test('renders an anchor when href is provided', () => {
|
|
29
|
+
render(
|
|
30
|
+
<Sidebar>
|
|
31
|
+
<SidebarItem href="/home" aria-label="Home">
|
|
32
|
+
<Icon name="menu" size={24} />
|
|
33
|
+
</SidebarItem>
|
|
34
|
+
</Sidebar>,
|
|
35
|
+
);
|
|
36
|
+
const link = screen.getByRole('link', { name: 'Home' });
|
|
37
|
+
expect(link).toBeInTheDocument();
|
|
38
|
+
expect(link).toHaveAttribute('href', '/home');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('renders a button when no href is provided', () => {
|
|
42
|
+
render(
|
|
43
|
+
<Sidebar>
|
|
44
|
+
<SidebarItem aria-label="Menu" onClick={vi.fn()}>
|
|
45
|
+
<Icon name="menu" size={24} />
|
|
46
|
+
</SidebarItem>
|
|
47
|
+
</Sidebar>,
|
|
48
|
+
);
|
|
49
|
+
const button = screen.getByRole('button', { name: 'Menu' });
|
|
50
|
+
expect(button).toBeInTheDocument();
|
|
51
|
+
expect(button.tagName).toBe('BUTTON');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('applies selected class and aria-current when current is true on a link', () => {
|
|
55
|
+
render(
|
|
56
|
+
<Sidebar>
|
|
57
|
+
<SidebarItem href="/home" aria-label="Home" selected>
|
|
58
|
+
<Icon name="menu" size={24} />
|
|
59
|
+
</SidebarItem>
|
|
60
|
+
</Sidebar>,
|
|
61
|
+
);
|
|
62
|
+
const link = screen.getByRole('link', { name: 'Home' });
|
|
63
|
+
expect(link).toHaveClass('ds-sidebar__item--selected');
|
|
64
|
+
expect(link).toHaveAttribute('aria-current', 'true');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test('applies selected class on a button when selected is true', () => {
|
|
68
|
+
render(
|
|
69
|
+
<Sidebar>
|
|
70
|
+
<SidebarItem aria-label="Menu" selected onClick={vi.fn()}>
|
|
71
|
+
<Icon name="menu" size={24} />
|
|
72
|
+
</SidebarItem>
|
|
73
|
+
</Sidebar>,
|
|
74
|
+
);
|
|
75
|
+
const button = screen.getByRole('button', { name: 'Menu' });
|
|
76
|
+
expect(button).toHaveClass('ds-sidebar__item--selected');
|
|
77
|
+
expect(button).toHaveAttribute('aria-current', 'true');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('does not apply selected class or aria-current when current is false', () => {
|
|
81
|
+
render(
|
|
82
|
+
<Sidebar>
|
|
83
|
+
<SidebarItem href="/home" aria-label="Home">
|
|
84
|
+
<Icon name="menu" size={24} />
|
|
85
|
+
</SidebarItem>
|
|
86
|
+
</Sidebar>,
|
|
87
|
+
);
|
|
88
|
+
const link = screen.getByRole('link', { name: 'Home' });
|
|
89
|
+
expect(link).not.toHaveClass('ds-sidebar__item--selected');
|
|
90
|
+
expect(link).toHaveAttribute('aria-current', 'false');
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test('calls onClick when the button is clicked', async () => {
|
|
94
|
+
const onClick = vi.fn();
|
|
95
|
+
render(
|
|
96
|
+
<Sidebar>
|
|
97
|
+
<SidebarItem aria-label="Menu" onClick={onClick}>
|
|
98
|
+
<Icon name="menu" size={24} />
|
|
99
|
+
</SidebarItem>
|
|
100
|
+
</Sidebar>,
|
|
101
|
+
);
|
|
102
|
+
await userEvent.click(screen.getByRole('button', { name: 'Menu' }));
|
|
103
|
+
expect(onClick).toHaveBeenCalledOnce();
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test('passes through extra HTML attributes to the button', () => {
|
|
107
|
+
render(
|
|
108
|
+
<Sidebar>
|
|
109
|
+
<SidebarItem
|
|
110
|
+
aria-label="Toggle nav"
|
|
111
|
+
aria-expanded={false}
|
|
112
|
+
aria-controls="nav-panel"
|
|
113
|
+
onClick={vi.fn()}
|
|
114
|
+
>
|
|
115
|
+
<Icon name="menu" size={24} />
|
|
116
|
+
</SidebarItem>
|
|
117
|
+
</Sidebar>,
|
|
118
|
+
);
|
|
119
|
+
const button = screen.getByRole('button', { name: 'Toggle nav' });
|
|
120
|
+
expect(button).toHaveAttribute('aria-expanded', 'false');
|
|
121
|
+
expect(button).toHaveAttribute('aria-controls', 'nav-panel');
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test('applies data-testid to the rendered element', () => {
|
|
125
|
+
render(
|
|
126
|
+
<Sidebar>
|
|
127
|
+
<SidebarItem href="/home" aria-label="Home" data-testid="home-item">
|
|
128
|
+
<Icon name="menu" size={24} />
|
|
129
|
+
</SidebarItem>
|
|
130
|
+
</Sidebar>,
|
|
131
|
+
);
|
|
132
|
+
expect(screen.getByTestId('home-item')).toBeInTheDocument();
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
describe('Sidebar + SidebarItem + Separator composition', () => {
|
|
137
|
+
test('renders items and a separator together', () => {
|
|
138
|
+
render(
|
|
139
|
+
<Sidebar ariaLabel="App navigation">
|
|
140
|
+
<SidebarItem href="/home" aria-label="Home">
|
|
141
|
+
<Icon name="menu" size={24} />
|
|
142
|
+
</SidebarItem>
|
|
143
|
+
<Separator orientation="horizontal" decorative />
|
|
144
|
+
<SidebarItem href="/calendar" aria-label="Calendar">
|
|
145
|
+
<Icon name="date" size={24} />
|
|
146
|
+
</SidebarItem>
|
|
147
|
+
</Sidebar>,
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
expect(screen.getByRole('navigation', { name: 'App navigation' })).toBeInTheDocument();
|
|
151
|
+
expect(screen.getByRole('link', { name: 'Home' })).toBeInTheDocument();
|
|
152
|
+
expect(screen.getByRole('link', { name: 'Calendar' })).toBeInTheDocument();
|
|
153
|
+
expect(document.querySelector('.ds-separator')).toBeInTheDocument();
|
|
154
|
+
});
|
|
155
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import classNames from 'classnames';
|
|
2
|
+
import { SidebarItem, type SidebarItemProps } from './SidebarItem.js';
|
|
3
|
+
|
|
4
|
+
export type SidebarProps = {
|
|
5
|
+
ariaLabel?: string;
|
|
6
|
+
} & React.HTMLAttributes<HTMLDivElement>;
|
|
7
|
+
|
|
8
|
+
export const Sidebar = (props: SidebarProps) => {
|
|
9
|
+
const { ariaLabel = 'Sidebar', className, children, ...rest } = props;
|
|
10
|
+
return (
|
|
11
|
+
<nav
|
|
12
|
+
aria-label={ariaLabel}
|
|
13
|
+
className={classNames('ds-sidebar', className)}
|
|
14
|
+
data-testid="sidebar"
|
|
15
|
+
{...rest}
|
|
16
|
+
>
|
|
17
|
+
{children}
|
|
18
|
+
</nav>
|
|
19
|
+
);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
Sidebar.Item = SidebarItem;
|
|
23
|
+
|
|
24
|
+
export namespace Sidebar {
|
|
25
|
+
export type Props = SidebarProps;
|
|
26
|
+
export type ItemProps = SidebarItemProps;
|
|
27
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import classNames from 'classnames';
|
|
2
|
+
import { Tooltip } from 'Components/tooltip/Tooltip.js';
|
|
3
|
+
|
|
4
|
+
export type SidebarItemProps = {
|
|
5
|
+
'href'?: string;
|
|
6
|
+
'selected'?: boolean;
|
|
7
|
+
'data-testid'?: string;
|
|
8
|
+
} & React.HTMLAttributes<HTMLElement>;
|
|
9
|
+
|
|
10
|
+
export const SidebarItem = (props: SidebarItemProps) => {
|
|
11
|
+
const {
|
|
12
|
+
href,
|
|
13
|
+
onClick,
|
|
14
|
+
selected,
|
|
15
|
+
'aria-label': ariaLabel,
|
|
16
|
+
'data-testid': dataTestId,
|
|
17
|
+
className,
|
|
18
|
+
children,
|
|
19
|
+
...rest
|
|
20
|
+
} = props;
|
|
21
|
+
|
|
22
|
+
const itemClassName = classNames(
|
|
23
|
+
'ds-sidebar__item',
|
|
24
|
+
{ 'ds-sidebar__item--selected': Boolean(selected) },
|
|
25
|
+
className,
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<Tooltip>
|
|
30
|
+
<Tooltip.Trigger>
|
|
31
|
+
{href
|
|
32
|
+
? (
|
|
33
|
+
<a
|
|
34
|
+
href={href}
|
|
35
|
+
className={itemClassName}
|
|
36
|
+
aria-current={selected ? 'true' : 'false'}
|
|
37
|
+
aria-label={ariaLabel}
|
|
38
|
+
onClick={onClick}
|
|
39
|
+
data-testid={dataTestId}
|
|
40
|
+
{...rest}
|
|
41
|
+
>
|
|
42
|
+
{children}
|
|
43
|
+
</a>
|
|
44
|
+
)
|
|
45
|
+
: (
|
|
46
|
+
<button
|
|
47
|
+
type="button"
|
|
48
|
+
className={itemClassName}
|
|
49
|
+
aria-current={selected ? 'true' : 'false'}
|
|
50
|
+
aria-label={ariaLabel}
|
|
51
|
+
onClick={onClick}
|
|
52
|
+
data-testid={dataTestId}
|
|
53
|
+
{...rest}
|
|
54
|
+
>
|
|
55
|
+
{children}
|
|
56
|
+
</button>
|
|
57
|
+
)}
|
|
58
|
+
</Tooltip.Trigger>
|
|
59
|
+
<Tooltip.Content side="right">
|
|
60
|
+
{ariaLabel}
|
|
61
|
+
</Tooltip.Content>
|
|
62
|
+
</Tooltip>
|
|
63
|
+
);
|
|
64
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
.ds-sidebar {
|
|
2
|
+
margin: 0;
|
|
3
|
+
width: var(--sidebar-nav-rail-width);
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
align-items: center;
|
|
7
|
+
padding: var(--spacing-small);
|
|
8
|
+
gap: var(--spacing-large);
|
|
9
|
+
box-sizing: border-box;
|
|
10
|
+
border-right: var(--border-weight) solid var(--page-base-color-border);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.ds-sidebar__item {
|
|
14
|
+
position: relative;
|
|
15
|
+
display: inline-flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
justify-content: center;
|
|
18
|
+
width: var(--sidebar-nav-rail-item-size);
|
|
19
|
+
height: var(--sidebar-nav-rail-item-size);
|
|
20
|
+
background: transparent;
|
|
21
|
+
border: 0;
|
|
22
|
+
padding: 0;
|
|
23
|
+
border-radius: var(--border-radius-round);
|
|
24
|
+
color: var(--sidebar-nav-rail-item-color-icon);
|
|
25
|
+
cursor: pointer;
|
|
26
|
+
text-decoration: none;
|
|
27
|
+
|
|
28
|
+
&:hover,
|
|
29
|
+
&:active,
|
|
30
|
+
&[data-state='delayed-open'],
|
|
31
|
+
&[data-state='instant-open'],
|
|
32
|
+
&[data-state='open'] {
|
|
33
|
+
color: var(--sidebar-nav-rail-item-color-icon-hover);
|
|
34
|
+
background: var(--sidebar-nav-rail-item-color-background-hover);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
&:focus {
|
|
38
|
+
outline: none;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
&:focus-visible {
|
|
42
|
+
outline: none;
|
|
43
|
+
box-shadow: 0 0 0 var(--focus-border) var(--focus-color-focus);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.ds-sidebar__item--selected {
|
|
48
|
+
color: var(--sidebar-nav-rail-item-color-icon-selected);
|
|
49
|
+
background: var(--sidebar-nav-rail-item-color-background-selected);
|
|
50
|
+
|
|
51
|
+
&:hover,
|
|
52
|
+
&:active,
|
|
53
|
+
&[data-state='delayed-open'],
|
|
54
|
+
&[data-state='instant-open'],
|
|
55
|
+
&[data-state='open'] {
|
|
56
|
+
color: var(--sidebar-nav-rail-item-color-icon-selected);
|
|
57
|
+
background: var(--sidebar-nav-rail-item-color-background-selected);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.ds-sidebar__item .ds-badge {
|
|
62
|
+
position: absolute;
|
|
63
|
+
top: var(--spacing-xsmall);
|
|
64
|
+
right: var(--spacing-xsmall);
|
|
65
|
+
}
|
|
@@ -10,8 +10,9 @@ import {
|
|
|
10
10
|
Subtitle,
|
|
11
11
|
Title,
|
|
12
12
|
} from '@storybook/addon-docs/blocks';
|
|
13
|
-
import { Toast
|
|
13
|
+
import { Toast } from './Toast.js';
|
|
14
14
|
import { Button } from 'Components/button/Button';
|
|
15
|
+
import { getFavouriteRemovedToastMessage } from 'Utils/favourites/favouriteConstants';
|
|
15
16
|
|
|
16
17
|
// ---------------------------------------------------------------------------
|
|
17
18
|
// Docs page content
|
|
@@ -52,7 +53,7 @@ const USAGE_GUIDANCE = [
|
|
|
52
53
|
'- **Acceptable: 2 lines.** A little more context is fine — "Assessment period saved. Pupils can now submit work."',
|
|
53
54
|
'- **Never: 3+ lines.** If you need that much copy, use a Banner instead.',
|
|
54
55
|
'- Use sentence case. No trailing punctuation on single sentences (optional on two-sentence messages).',
|
|
55
|
-
'-
|
|
56
|
+
'- Pass action controls via `toastActions` — use `Toast.Action` for safe-to-ignore undo patterns',
|
|
56
57
|
].join('\n');
|
|
57
58
|
|
|
58
59
|
const DEVELOPER_NOTES = [
|
|
@@ -93,9 +94,7 @@ const DEVELOPER_NOTES = [
|
|
|
93
94
|
' return (',
|
|
94
95
|
' <>',
|
|
95
96
|
' <Button onClick={handleSave}>Save</Button>',
|
|
96
|
-
' <Toast open={open} onOpenChange={setOpen} variant="success"
|
|
97
|
-
' Assessment period saved',
|
|
98
|
-
' </Toast>',
|
|
97
|
+
' <Toast open={open} onOpenChange={setOpen} variant="success" toastContent="Assessment period saved" />',
|
|
99
98
|
' </>',
|
|
100
99
|
' );',
|
|
101
100
|
'}',
|
|
@@ -114,7 +113,7 @@ const DEVELOPER_NOTES = [
|
|
|
114
113
|
'',
|
|
115
114
|
'- Radix renders `role="status"` (for `type="background"`, the default) or `role="alert"`',
|
|
116
115
|
' (for `type="foreground"`). Do NOT add `aria-live` yourself — Radix handles this.',
|
|
117
|
-
'- `
|
|
116
|
+
'- `toastContent` is rendered as `Toast.Title` — it is always required for screen reader announcement.',
|
|
118
117
|
'- `type="foreground"` causes the toast to be announced immediately, interrupting the user.',
|
|
119
118
|
' Use only for genuinely urgent messages. Default `type="background"` announces at the next pause.',
|
|
120
119
|
'',
|
|
@@ -139,6 +138,8 @@ const DEVELOPER_NOTES = [
|
|
|
139
138
|
'',
|
|
140
139
|
'type ToastProps = RadixToast.ToastProps & {',
|
|
141
140
|
' variant?: ToastVariant; // default: "information"',
|
|
141
|
+
' toastContent: ReactNode;',
|
|
142
|
+
' toastActions?: ReactNode;',
|
|
142
143
|
'};',
|
|
143
144
|
'```',
|
|
144
145
|
].join('\n');
|
|
@@ -184,6 +185,10 @@ const meta = {
|
|
|
184
185
|
title: 'Components/Toast',
|
|
185
186
|
component: Toast,
|
|
186
187
|
tags: ['autodocs'],
|
|
188
|
+
args: {
|
|
189
|
+
variant: 'information',
|
|
190
|
+
toastContent: 'Attendance report generated',
|
|
191
|
+
},
|
|
187
192
|
parameters: {
|
|
188
193
|
layout: 'centered',
|
|
189
194
|
docs: {
|
|
@@ -200,7 +205,7 @@ const meta = {
|
|
|
200
205
|
defaultValue: { summary: "'information'" },
|
|
201
206
|
},
|
|
202
207
|
},
|
|
203
|
-
|
|
208
|
+
toastContent: {
|
|
204
209
|
control: 'text',
|
|
205
210
|
description: [
|
|
206
211
|
'The toast message. Rendered as `Toast.Title` — always required for screen reader announcement.',
|
|
@@ -288,7 +293,7 @@ const ToastStoryWrapper = ({ children }: { children: React.ReactNode }) => (
|
|
|
288
293
|
</Toast.Provider>
|
|
289
294
|
);
|
|
290
295
|
|
|
291
|
-
const DefaultTemplate = (args:
|
|
296
|
+
const DefaultTemplate = (args: Toast.Props) => {
|
|
292
297
|
const [open, setOpen] = useState(false);
|
|
293
298
|
return (
|
|
294
299
|
<ToastStoryWrapper>
|
|
@@ -312,18 +317,10 @@ const AllVariantsTemplate = () => {
|
|
|
312
317
|
<Button onClick={() => setWarningOpen(true)}>Warning</Button>
|
|
313
318
|
<Button onClick={() => setDangerOpen(true)}>Danger</Button>
|
|
314
319
|
</div>
|
|
315
|
-
<Toast variant="information" open={infoOpen} onOpenChange={setInfoOpen}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
<Toast variant="
|
|
319
|
-
Assessment period saved
|
|
320
|
-
</Toast>
|
|
321
|
-
<Toast variant="warning" open={warningOpen} onOpenChange={setWarningOpen}>
|
|
322
|
-
Session expires in 5 minutes
|
|
323
|
-
</Toast>
|
|
324
|
-
<Toast variant="danger" open={dangerOpen} onOpenChange={setDangerOpen}>
|
|
325
|
-
Failed to save changes — please try again
|
|
326
|
-
</Toast>
|
|
320
|
+
<Toast variant="information" open={infoOpen} onOpenChange={setInfoOpen} toastContent="Attendance report generated" />
|
|
321
|
+
<Toast variant="success" open={successOpen} onOpenChange={setSuccessOpen} toastContent="Assessment period saved" />
|
|
322
|
+
<Toast variant="warning" open={warningOpen} onOpenChange={setWarningOpen} toastContent="Session expires in 5 minutes" />
|
|
323
|
+
<Toast variant="danger" open={dangerOpen} onOpenChange={setDangerOpen} toastContent="Failed to save changes — please try again" />
|
|
327
324
|
</ToastStoryWrapper>
|
|
328
325
|
);
|
|
329
326
|
};
|
|
@@ -355,15 +352,9 @@ const ContentGuidelinesTemplate = () => {
|
|
|
355
352
|
</span>
|
|
356
353
|
</div>
|
|
357
354
|
</div>
|
|
358
|
-
<Toast variant="success" open={idealOpen} onOpenChange={setIdealOpen}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
<Toast variant="success" open={acceptableOpen} onOpenChange={setAcceptableOpen}>
|
|
362
|
-
Assessment period saved. Pupils can now submit work for grading.
|
|
363
|
-
</Toast>
|
|
364
|
-
<Toast variant="information" open={tooLongOpen} onOpenChange={setTooLongOpen}>
|
|
365
|
-
Assessment period saved. Pupils can now submit work for grading. Remember to notify your department heads and check the term dates align with your reporting schedule before the deadline.
|
|
366
|
-
</Toast>
|
|
355
|
+
<Toast variant="success" open={idealOpen} onOpenChange={setIdealOpen} toastContent="Assessment period saved" />
|
|
356
|
+
<Toast variant="success" open={acceptableOpen} onOpenChange={setAcceptableOpen} toastContent="Assessment period saved. Pupils can now submit work for grading." />
|
|
357
|
+
<Toast variant="information" open={tooLongOpen} onOpenChange={setTooLongOpen} toastContent="Assessment period saved. Pupils can now submit work for grading. Remember to notify your department heads and check the term dates align with your reporting schedule before the deadline." />
|
|
367
358
|
</ToastStoryWrapper>
|
|
368
359
|
);
|
|
369
360
|
};
|
|
@@ -378,12 +369,35 @@ const WithCustomDurationTemplate = () => {
|
|
|
378
369
|
<Button onClick={() => setShortOpen(true)}>Short (2 s)</Button>
|
|
379
370
|
<Button onClick={() => setLongOpen(true)}>Long (10 s)</Button>
|
|
380
371
|
</div>
|
|
381
|
-
<Toast variant="information" open={shortOpen} onOpenChange={setShortOpen} duration={2000}
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
372
|
+
<Toast variant="information" open={shortOpen} onOpenChange={setShortOpen} duration={2000} toastContent="Dismissed in 2 seconds" />
|
|
373
|
+
<Toast variant="information" open={longOpen} onOpenChange={setLongOpen} duration={10000} toastContent="Dismissed in 10 seconds — use for important but non-urgent messages" />
|
|
374
|
+
</ToastStoryWrapper>
|
|
375
|
+
);
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
const WithActionTemplate = () => {
|
|
379
|
+
const [open, setOpen] = useState(false);
|
|
380
|
+
|
|
381
|
+
const handleUndo = () => {
|
|
382
|
+
setOpen(false);
|
|
383
|
+
};
|
|
384
|
+
|
|
385
|
+
return (
|
|
386
|
+
<ToastStoryWrapper>
|
|
387
|
+
<Button onClick={() => setOpen(true)}>Remove favourite</Button>
|
|
388
|
+
<Toast
|
|
389
|
+
open={open}
|
|
390
|
+
onOpenChange={setOpen}
|
|
391
|
+
type="foreground"
|
|
392
|
+
duration={10000}
|
|
393
|
+
variant="information"
|
|
394
|
+
toastContent={getFavouriteRemovedToastMessage('Daily Attendance')}
|
|
395
|
+
toastActions={(
|
|
396
|
+
<Toast.Action altText="Undo removal" onClick={handleUndo} asChild>
|
|
397
|
+
<Button variant="text-link" type="button" hasHorizontalPadding={false}>Undo</Button>
|
|
398
|
+
</Toast.Action>
|
|
399
|
+
)}
|
|
400
|
+
/>
|
|
387
401
|
</ToastStoryWrapper>
|
|
388
402
|
);
|
|
389
403
|
};
|
|
@@ -396,7 +410,7 @@ export const Default: Story = withDescription(
|
|
|
396
410
|
{
|
|
397
411
|
args: {
|
|
398
412
|
variant: 'information',
|
|
399
|
-
|
|
413
|
+
toastContent: 'Attendance report generated',
|
|
400
414
|
},
|
|
401
415
|
render: args => <DefaultTemplate {...args} />,
|
|
402
416
|
parameters: {
|
|
@@ -414,9 +428,7 @@ function ToastDemo() {
|
|
|
414
428
|
return (
|
|
415
429
|
<Toast.Provider>
|
|
416
430
|
<Button onClick={() => setOpen(true)}>Show toast</Button>
|
|
417
|
-
<Toast variant="information" open={open} onOpenChange={setOpen}
|
|
418
|
-
Attendance report generated
|
|
419
|
-
</Toast>
|
|
431
|
+
<Toast variant="information" open={open} onOpenChange={setOpen} toastContent="Attendance report generated" />
|
|
420
432
|
<Toast.Viewport />
|
|
421
433
|
</Toast.Provider>
|
|
422
434
|
);
|
|
@@ -430,7 +442,7 @@ export default ToastDemo;
|
|
|
430
442
|
[
|
|
431
443
|
'The default `information` toast. Click the button to trigger it — it auto-dismisses after 5 seconds',
|
|
432
444
|
'or can be closed manually with the X button.',
|
|
433
|
-
'Tweak the **variant** and **
|
|
445
|
+
'Tweak the **variant** and **toastContent** controls to preview other variants.',
|
|
434
446
|
].join(' '),
|
|
435
447
|
);
|
|
436
448
|
|
|
@@ -459,18 +471,10 @@ function AllVariantsDemo() {
|
|
|
459
471
|
<Button onClick={() => setWarningOpen(true)}>Warning</Button>
|
|
460
472
|
<Button onClick={() => setDangerOpen(true)}>Danger</Button>
|
|
461
473
|
|
|
462
|
-
<Toast variant="information" open={infoOpen} onOpenChange={setInfoOpen}
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
<Toast variant="
|
|
466
|
-
Assessment period saved
|
|
467
|
-
</Toast>
|
|
468
|
-
<Toast variant="warning" open={warningOpen} onOpenChange={setWarningOpen}>
|
|
469
|
-
Session expires in 5 minutes
|
|
470
|
-
</Toast>
|
|
471
|
-
<Toast variant="danger" open={dangerOpen} onOpenChange={setDangerOpen}>
|
|
472
|
-
Failed to save changes — please try again
|
|
473
|
-
</Toast>
|
|
474
|
+
<Toast variant="information" open={infoOpen} onOpenChange={setInfoOpen} toastContent="Attendance report generated" />
|
|
475
|
+
<Toast variant="success" open={successOpen} onOpenChange={setSuccessOpen} toastContent="Assessment period saved" />
|
|
476
|
+
<Toast variant="warning" open={warningOpen} onOpenChange={setWarningOpen} toastContent="Session expires in 5 minutes" />
|
|
477
|
+
<Toast variant="danger" open={dangerOpen} onOpenChange={setDangerOpen} toastContent="Failed to save changes — please try again" />
|
|
474
478
|
<Toast.Viewport />
|
|
475
479
|
</Toast.Provider>
|
|
476
480
|
);
|
|
@@ -501,21 +505,13 @@ export const ContentGuidelines: Story = withDescription(
|
|
|
501
505
|
language: 'tsx',
|
|
502
506
|
code: `
|
|
503
507
|
// ✅ Ideal — 1 line, past tense, no trailing punctuation
|
|
504
|
-
<Toast variant="success" open={open} onOpenChange={setOpen}
|
|
505
|
-
Assessment period saved
|
|
506
|
-
</Toast>
|
|
508
|
+
<Toast variant="success" open={open} onOpenChange={setOpen} toastContent="Assessment period saved" />
|
|
507
509
|
|
|
508
510
|
// ✅ Acceptable — 2 lines with brief context
|
|
509
|
-
<Toast variant="success" open={open} onOpenChange={setOpen}
|
|
510
|
-
Assessment period saved. Pupils can now submit work for grading.
|
|
511
|
-
</Toast>
|
|
511
|
+
<Toast variant="success" open={open} onOpenChange={setOpen} toastContent="Assessment period saved. Pupils can now submit work for grading." />
|
|
512
512
|
|
|
513
513
|
// ❌ Too long — switch to a Banner instead
|
|
514
|
-
<Toast variant="information" open={open} onOpenChange={setOpen}
|
|
515
|
-
Assessment period saved. Pupils can now submit work for grading.
|
|
516
|
-
Remember to notify your department heads and check the term dates
|
|
517
|
-
align with your reporting schedule before the deadline.
|
|
518
|
-
</Toast>
|
|
514
|
+
<Toast variant="information" open={open} onOpenChange={setOpen} toastContent="Assessment period saved. Pupils can now submit work for grading. Remember to notify your department heads and check the term dates align with your reporting schedule before the deadline." />
|
|
519
515
|
`.trim(),
|
|
520
516
|
},
|
|
521
517
|
},
|
|
@@ -549,12 +545,10 @@ function CustomDurationDemo() {
|
|
|
549
545
|
<Button onClick={() => setOpen(true)}>Show toast</Button>
|
|
550
546
|
|
|
551
547
|
{/* Per-toast duration overrides the provider default (5000ms) */}
|
|
552
|
-
<Toast variant="information" open={open} onOpenChange={setOpen} duration={10000}
|
|
553
|
-
This stays visible for 10 seconds
|
|
554
|
-
</Toast>
|
|
548
|
+
<Toast variant="information" open={open} onOpenChange={setOpen} duration={10000} toastContent="This stays visible for 10 seconds" />
|
|
555
549
|
|
|
556
550
|
{/* Pass Infinity to keep the toast open until manually dismissed */}
|
|
557
|
-
{/* <Toast duration={Infinity}
|
|
551
|
+
{/* <Toast duration={Infinity} toastContent="Persistent until closed" /> */}
|
|
558
552
|
|
|
559
553
|
<Toast.Viewport />
|
|
560
554
|
</Toast.Provider>
|
|
@@ -573,3 +567,17 @@ export default CustomDurationDemo;
|
|
|
573
567
|
'Pass `duration={Infinity}` to keep the toast open until the user explicitly dismisses it.',
|
|
574
568
|
].join(' '),
|
|
575
569
|
);
|
|
570
|
+
|
|
571
|
+
export const WithAction: Story = withDescription(
|
|
572
|
+
{
|
|
573
|
+
render: WithActionTemplate,
|
|
574
|
+
parameters: {
|
|
575
|
+
controls: { disable: true },
|
|
576
|
+
},
|
|
577
|
+
},
|
|
578
|
+
[
|
|
579
|
+
'Use `toastActions` with `Toast.Action` for safe-to-ignore undo patterns — mirroring the Radix toast undo example.',
|
|
580
|
+
'Set `type="foreground"` and a longer `duration` so keyboard users have time to act.',
|
|
581
|
+
'Pass `altText` for screen reader users who need an alternative way to trigger the action.',
|
|
582
|
+
].join(' '),
|
|
583
|
+
);
|
|
@@ -8,9 +8,7 @@ describe('Toast', () => {
|
|
|
8
8
|
const renderToast = (props = {}) => {
|
|
9
9
|
return render(
|
|
10
10
|
<Toast.Provider>
|
|
11
|
-
<Toast open={true} {...props}
|
|
12
|
-
Test message
|
|
13
|
-
</Toast>
|
|
11
|
+
<Toast open={true} toastContent="Test message" {...props} />
|
|
14
12
|
<Toast.Viewport />
|
|
15
13
|
</Toast.Provider>,
|
|
16
14
|
);
|
|
@@ -74,20 +72,54 @@ describe('Toast', () => {
|
|
|
74
72
|
|
|
75
73
|
render(
|
|
76
74
|
<Toast.Provider>
|
|
77
|
-
<Toast open={true} onOpenChange={onOpenChange}
|
|
78
|
-
Test message
|
|
79
|
-
</Toast>
|
|
75
|
+
<Toast open={true} toastContent="Test message" onOpenChange={onOpenChange} />
|
|
80
76
|
<Toast.Viewport />
|
|
81
77
|
</Toast.Provider>,
|
|
82
78
|
);
|
|
83
79
|
|
|
84
|
-
const closeButton = screen.getByRole('button');
|
|
80
|
+
const closeButton = screen.getByRole('button', { name: 'Close' });
|
|
85
81
|
await user.click(closeButton);
|
|
86
82
|
|
|
87
83
|
expect(onOpenChange).toHaveBeenCalled();
|
|
88
84
|
});
|
|
89
85
|
});
|
|
90
86
|
|
|
87
|
+
describe('Toast.Action', () => {
|
|
88
|
+
it('renders action inline with title and calls handler when clicked', async () => {
|
|
89
|
+
const user = userEvent.setup();
|
|
90
|
+
const onAction = vi.fn();
|
|
91
|
+
|
|
92
|
+
const { container } = render(
|
|
93
|
+
<Toast.Provider>
|
|
94
|
+
<Toast
|
|
95
|
+
open={true}
|
|
96
|
+
type="foreground"
|
|
97
|
+
duration={10000}
|
|
98
|
+
toastContent="Item removed"
|
|
99
|
+
toastActions={(
|
|
100
|
+
<Toast.Action altText="Undo removal" onClick={onAction}>
|
|
101
|
+
Undo
|
|
102
|
+
</Toast.Action>
|
|
103
|
+
)}
|
|
104
|
+
/>
|
|
105
|
+
<Toast.Viewport />
|
|
106
|
+
</Toast.Provider>,
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
expect(screen.getByText('Item removed')).toBeInTheDocument();
|
|
110
|
+
expect(container.querySelector('.ds-toast__message-row')).toBeInTheDocument();
|
|
111
|
+
expect(container.querySelector('.ds-toast__title')?.parentElement).toHaveClass('ds-toast__message-row');
|
|
112
|
+
|
|
113
|
+
await user.click(screen.getByRole('button', { name: 'Undo' }));
|
|
114
|
+
|
|
115
|
+
expect(onAction).toHaveBeenCalled();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('exposes Action component', () => {
|
|
119
|
+
expect(Toast.Action).toBeDefined();
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
|
|
91
123
|
describe('Provider and Viewport', () => {
|
|
92
124
|
it('exposes Provider component', () => {
|
|
93
125
|
expect(Toast.Provider).toBeDefined();
|
|
@@ -112,9 +144,7 @@ describe('Toast', () => {
|
|
|
112
144
|
renderToast();
|
|
113
145
|
const { container } = render(
|
|
114
146
|
<Toast.Provider>
|
|
115
|
-
<Toast open={true} variant="success"
|
|
116
|
-
Success message
|
|
117
|
-
</Toast>
|
|
147
|
+
<Toast open={true} variant="success" toastContent="Success message" />
|
|
118
148
|
<Toast.Viewport />
|
|
119
149
|
</Toast.Provider>,
|
|
120
150
|
);
|