From ffcca45638d7b1b221065d934ed5f34ea32c4666 Mon Sep 17 00:00:00 2001 From: Snorre Kim Date: Mon, 22 Jul 2024 17:26:22 +0200 Subject: [PATCH] added accordion option --- .../dnb-design-system-portal/gatsby-config.js | 3 +- .../src/docs/uilib/components.mdx | 1 + .../src/docs/uilib/extensions.mdx | 1 + .../src/docs/uilib/extensions/forms/Form.mdx | 1 + .../extensions/forms/Form/Appearance.mdx | 1 - .../uilib/extensions/forms/Form/ButtonRow.mdx | 1 - .../extensions/forms/Form/FieldProps.mdx | 1 - .../uilib/extensions/forms/Form/Handler.mdx | 1 - .../extensions/forms/Form/MainHeading.mdx | 1 - .../uilib/extensions/forms/Form/Section.mdx | 1 - .../forms/Form/Section/EditContainer.mdx | 1 - .../forms/Form/Section/ViewContainer.mdx | 1 - .../extensions/forms/Form/SubHeading.mdx | 1 - .../extensions/forms/Form/SubmitButton.mdx | 1 - .../extensions/forms/Form/SubmitIndicator.mdx | 1 - .../extensions/forms/Form/Visibility.mdx | 1 - .../uilib/extensions/forms/Form/getData.mdx | 1 - .../uilib/extensions/forms/Form/setData.mdx | 1 - .../uilib/extensions/forms/Form/useData.mdx | 1 - .../uilib/extensions/forms/Form/useError.mdx | 1 - .../src/shared/menu/SidebarMenu.module.scss | 54 +++----- .../src/shared/menu/SidebarMenu.tsx | 118 +++++++++++++----- .../src/shared/menu/SidebarMenuContext.tsx | 4 - 23 files changed, 114 insertions(+), 84 deletions(-) diff --git a/packages/dnb-design-system-portal/gatsby-config.js b/packages/dnb-design-system-portal/gatsby-config.js index 26a8f1f8795..0fe8c83b71b 100644 --- a/packages/dnb-design-system-portal/gatsby-config.js +++ b/packages/dnb-design-system-portal/gatsby-config.js @@ -125,7 +125,8 @@ const plugins = [ elements: [ { selector: '#portal-sidebar-menu', - ensureInView: '#portal-sidebar-menu ul li.is-active', + ensureInView: + '#portal-sidebar-menu ul li.is-active > .dnb-sidebar-menu__item', }, ], }, diff --git a/packages/dnb-design-system-portal/src/docs/uilib/components.mdx b/packages/dnb-design-system-portal/src/docs/uilib/components.mdx index 0e049e10f84..d742b5013f7 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/components.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/components.mdx @@ -2,6 +2,7 @@ title: 'Components' icon: 'components' order: 7 +expanded: true --- import ListComponents from 'dnb-design-system-portal/src/shared/parts/ListComponents' diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions.mdx index fcb86ed1c6b..331d7ea48c7 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions.mdx @@ -4,6 +4,7 @@ icon: 'extensions' order: 8 redirect_from: - /uilib/patterns +expanded: true --- import ListExtensions from 'dnb-design-system-portal/src/shared/parts/ListExtensions' diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form.mdx index 285e16ad3cf..400640874ef 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form.mdx @@ -15,6 +15,7 @@ breadcrumb: href: /uilib/extensions/forms/ - text: Form href: /uilib/extensions/forms/Form/ +expanded: false --- import Info from 'Docs/uilib/extensions/forms/Form/info' diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Appearance.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Appearance.mdx index 637189c2878..795933ace2b 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Appearance.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Appearance.mdx @@ -1,7 +1,6 @@ --- title: 'Appearance' description: '`Form.Appearance` is a provider for theming form fields.' -hideInMenu: true showTabs: true tabs: - title: Info diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/ButtonRow.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/ButtonRow.mdx index 03346bd9851..38db0b174f5 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/ButtonRow.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/ButtonRow.mdx @@ -1,7 +1,6 @@ --- title: 'ButtonRow' description: '`Form.ButtonRow` is a wrapper for horizontally separated buttons.' -hideInMenu: true showTabs: true tabs: - title: Info diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/FieldProps.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/FieldProps.mdx index 8960a7d0460..6513f4c641f 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/FieldProps.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/FieldProps.mdx @@ -1,7 +1,6 @@ --- title: 'FieldProps' description: '`Form.FieldProps` is a provider for forwarding fields properties, such as `required` or `disabled` to all nested field components.' -hideInMenu: true showTabs: true tabs: - title: Info diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Handler.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Handler.mdx index 44ad908ebfe..5e322095c31 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Handler.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Handler.mdx @@ -1,7 +1,6 @@ --- title: 'Handler' description: '`Form.Handler` provides both the DataContext.Provider and a HTML form element.' -hideInMenu: true showTabs: true tabs: - title: Info diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/MainHeading.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/MainHeading.mdx index 6385805c1eb..451a742fa81 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/MainHeading.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/MainHeading.mdx @@ -1,7 +1,6 @@ --- title: 'MainHeading' description: '`Form.MainHeading` is a standardized main heading for sections, ensuring default layout, spacing etc.' -hideInMenu: true showTabs: true tabs: - title: Info diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Section.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Section.mdx index d244f8a3956..9c73024cbe4 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Section.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Section.mdx @@ -1,7 +1,6 @@ --- title: 'Section' description: '`Form.Section` lets you compose blocks of fields and values to be reused in different contexts.' -hideInMenu: true showTabs: true tabs: - title: Info diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Section/EditContainer.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Section/EditContainer.mdx index 213701428ad..edb1e1d1109 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Section/EditContainer.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Section/EditContainer.mdx @@ -3,7 +3,6 @@ title: 'EditContainer' description: '`Form.Section.EditContainer` enables users to toggle (with animation) the content of each item between the view and edit container.' order: 9 showTabs: true -hideInMenu: true tabs: - title: Info key: '/info' diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Section/ViewContainer.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Section/ViewContainer.mdx index fdd85eca847..44fa693851f 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Section/ViewContainer.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Section/ViewContainer.mdx @@ -3,7 +3,6 @@ title: 'ViewContainer' description: '`Form.Section.ViewContainer` enables users to toggle (with animation) the content of each item between the view and edit container.' order: 8 showTabs: true -hideInMenu: true tabs: - title: Info key: '/info' diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/SubHeading.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/SubHeading.mdx index 90e1492b1d0..cb51ade954f 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/SubHeading.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/SubHeading.mdx @@ -1,7 +1,6 @@ --- title: 'SubHeading' description: '`Form.SubHeading` is a standardized sub heading for sections, ensuring default layout, spacing etc.' -hideInMenu: true showTabs: true tabs: - title: Info diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/SubmitButton.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/SubmitButton.mdx index 807077f367a..c1c7f2b733a 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/SubmitButton.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/SubmitButton.mdx @@ -1,7 +1,6 @@ --- title: 'SubmitButton' description: '`Form.SubmitButton` connects to the `Form.Handler` to submit the active state of the internal DataContext, triggering `onSubmit`.' -hideInMenu: true showTabs: true tabs: - title: Info diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/SubmitIndicator.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/SubmitIndicator.mdx index 0a481b7a064..b8edbef1a22 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/SubmitIndicator.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/SubmitIndicator.mdx @@ -1,7 +1,6 @@ --- title: 'SubmitIndicator' description: '`Form.SubmitIndicator` lets you show an indicator while async form operations are performed.' -hideInMenu: true showTabs: true tabs: - title: Info diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Visibility.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Visibility.mdx index 6aba829721b..9ff6fa1d38b 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Visibility.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/Visibility.mdx @@ -1,7 +1,6 @@ --- title: 'Visibility' description: '`Form.Visibility` makes it possible to hide components and elements on the screen based on the dynamic state of data.' -hideInMenu: true showTabs: true tabs: - title: Info diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/getData.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/getData.mdx index 966b383d3f5..665f0fd6d50 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/getData.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/getData.mdx @@ -1,7 +1,6 @@ --- title: 'getData' description: '`Form.getData` lets you access your form data outside of the form context.' -hideInMenu: true showTabs: true tabs: - title: Info diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/setData.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/setData.mdx index 53690b0dc72..7adfacc2954 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/setData.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/setData.mdx @@ -1,7 +1,6 @@ --- title: 'setData' description: '`Form.setData` lets you set or modify your form data outside of the form context.' -hideInMenu: true showTabs: true tabs: - title: Info diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/useData.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/useData.mdx index 6c5379aa2c8..0259b12ec97 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/useData.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/useData.mdx @@ -1,7 +1,6 @@ --- title: 'useData' description: '`Form.useData` lets you access or modify your form data outside of the form context within your application.' -hideInMenu: true showTabs: true tabs: - title: Info diff --git a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/useError.mdx b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/useError.mdx index 5b6d2c906dd..b1231ba6f10 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/useError.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/extensions/forms/Form/useError.mdx @@ -1,7 +1,6 @@ --- title: 'useError' description: '`Form.useError` lets you monitor your form errors outside of the form itself.' -hideInMenu: true showTabs: true tabs: - title: Info diff --git a/packages/dnb-design-system-portal/src/shared/menu/SidebarMenu.module.scss b/packages/dnb-design-system-portal/src/shared/menu/SidebarMenu.module.scss index d28a1f65471..59dff8d2fb9 100644 --- a/packages/dnb-design-system-portal/src/shared/menu/SidebarMenu.module.scss +++ b/packages/dnb-design-system-portal/src/shared/menu/SidebarMenu.module.scss @@ -66,6 +66,7 @@ min-height: 40px; display: flex; + flex-grow: 1; flex-direction: row; justify-content: space-between; align-items: center; @@ -91,7 +92,7 @@ &.is-inside-active-path { background-color: transparent; } - > .dnb-anchor { + > .dnb-sidebar-menu__item .dnb-anchor { background-color: transparent; margin-left: var(--level-icon-adjust); margin-bottom: 1rem; @@ -105,7 +106,7 @@ } &.l-2 { - > .dnb-anchor { + > .dnb-sidebar-menu__item .dnb-anchor { padding-left: calc(var(--level-offset) + var(--level) * 2); min-height: 56px; @@ -123,7 +124,7 @@ } &.l-3 { - > .dnb-anchor { + > .dnb-sidebar-menu__item .dnb-anchor { padding-left: calc(var(--level-offset) + var(--level) * 3); } @@ -134,17 +135,17 @@ } } - &.l-4 > .dnb-anchor { + &.l-4 > .dnb-sidebar-menu__item .dnb-anchor { padding-left: calc(var(--level-offset) + var(--level) * 4); } - &.l-5 > .dnb-anchor { + &.l-5 > .dnb-sidebar-menu__item .dnb-anchor { padding-left: calc(var(--level-offset) + var(--level) * 5); } - &.l-6 > .dnb-anchor { + &.l-6 > .dnb-sidebar-menu__item .dnb-anchor { padding-left: calc(var(--level-offset) + var(--level) * 6); } - .dnb-anchor:hover { + .dnb-sidebar-menu__item .dnb-anchor:hover { --anchor-background: var(--dnb-sidebar-menu-hover-bg); color: var(--color-black); > span:first-child { @@ -191,33 +192,6 @@ } } - .main-menu-toggle { - margin-left: var(--level-offset); - - .dnb-icon:nth-of-type(1) { - color: var(--color-sea-green); - margin-right: 0.5rem; - - &.dnb-icon--small { - margin-left: 0.5rem; - } - } - - &.dnb-button__text { - color: var(--color-sea-green); - } - &.dnb-button:hover { - color: var(--color-black); - .dnb-button__text, - .dnb-icon { - color: inherit; - } - } - - margin-top: 1rem; - margin-bottom: 2rem; - } - .dnb-sidebar-menu__theme-badge { position: absolute; display: flex; @@ -253,7 +227,17 @@ } } } - + .dnb-sidebar-menu__item { + display: flex; + justify-content: space-between; + } + .dnb-sidebar-menu__expand-button { + align-self: center; + &:hover { + background-color: white; + outline: 1px solid currentcolor; + } + } #portal-sidebar-menu { /* Good for a mobile menu instead diff --git a/packages/dnb-design-system-portal/src/shared/menu/SidebarMenu.tsx b/packages/dnb-design-system-portal/src/shared/menu/SidebarMenu.tsx index 65295993478..a624b6bb780 100644 --- a/packages/dnb-design-system-portal/src/shared/menu/SidebarMenu.tsx +++ b/packages/dnb-design-system-portal/src/shared/menu/SidebarMenu.tsx @@ -3,13 +3,13 @@ * */ -import React, { useContext, useEffect, useRef } from 'react' +import React, { useContext, useEffect, useRef, useState } from 'react' import classnames from 'classnames' import Anchor from '../tags/Anchor' import { useStaticQuery, graphql } from 'gatsby' import { SidebarMenuContext } from './SidebarMenuContext' import { createSkeletonClass } from '@dnb/eufemia/src/components/skeleton/SkeletonHelper' -import { Icon, Badge } from '@dnb/eufemia/src/components' +import { Icon, Badge, Button } from '@dnb/eufemia/src/components' import type { ThemeNames } from '@dnb/eufemia/src/shared/Theme' import { Context, useTheme } from '@dnb/eufemia/src/shared' import graphics from './SidebarGraphics' @@ -65,6 +65,7 @@ export default function SidebarLayout({ key } theme + expanded } } } @@ -87,7 +88,7 @@ export default function SidebarLayout({ setTimeout(() => { scrollToActiveItem() applyPageFocus('sidebar') - }, 300) // after animation is done + }, 10) // after animation is done } else if (isClosing) { setTimeout(() => { applyPageFocus('content') @@ -120,6 +121,7 @@ export default function SidebarLayout({ isInsideActivePath, isInsideActiveCategory, subheadings, + currentPathName, }, nr, ) => { @@ -133,6 +135,7 @@ export default function SidebarLayout({ isInsideActiveCategory, path, subheadings, + currentPathName, title: menuTitle || title, } @@ -244,6 +247,8 @@ type ListItemProps = { hideInMenu?: boolean isInsideActivePath?: boolean isInsideActiveCategory?: boolean + currentPathName?: string + expanded?: boolean } function ListItem({ @@ -260,11 +265,22 @@ function ListItem({ title, subheadings, hideInMenu, + currentPathName, + expanded = null, }: ListItemProps) { const { name: currentTheme } = useTheme() const { closeMenu } = useContext(SidebarMenuContext) const { skeleton } = useContext(Context) const ref = useRef(null) + const refIsInsideActivePathPrev = useRef(isInsideActivePath) + const refCurrentPathNamePrev = useRef(currentPathName) + const hasSubheadings = + subheadings && subheadings.some((x) => x.hideInMenu !== true) + + const isAccordion = expanded !== null && hasSubheadings + const [isExpanded, setIsExpanded] = useState( + isAccordion ? expanded : true, + ) if (hideInMenu) { return null @@ -283,6 +299,27 @@ function ListItem({ const params = {} + if (!isExpanded) { + if ( + (isInsideActivePath && + (!refIsInsideActivePathPrev.current || + currentPathName !== refCurrentPathNamePrev.current)) || + (isActive && currentPathName !== refCurrentPathNamePrev.current) + ) { + setIsExpanded(true) + } + } else if ( + isAccordion && + !expanded && + !isInsideActivePath && + !isActive && + currentPathName !== refCurrentPathNamePrev.current + ) { + setIsExpanded(false) + } + refIsInsideActivePathPrev.current = isInsideActivePath + refCurrentPathNamePrev.current = currentPathName + if (isActive) { params['aria-current'] = true } @@ -308,34 +345,57 @@ function ListItem({ } as React.CSSProperties /* Casting to allow css variable in JSX inline styling */ } > - - - {icon && graphics[icon] && ( - +
+ { + closeMenu() + if (!isExpanded) { + setIsExpanded(true) + } + }} + className={classnames( + 'dnb-anchor', + 'dnb-anchor--no-underline', + 'dnb-anchor--no-radius', + 'dnb-anchor--no-hover', + icon && graphics[icon] ? 'has-icon' : null, )} - - {title} + {...params} + > + + {icon && graphics[icon] && ( + + )} + + {title} + - - {theme === currentTheme && } - {status && ( - + {theme === currentTheme && } + {status && ( + + )} + + + {isAccordion && ( +
+ {hasSubheadings && isExpanded && (
    {subheadings.map((item) => ( @@ -371,6 +431,7 @@ type NavItem = { showTabs?: boolean tabs?: NavItemTabs[] subheadings?: NavItem[] + currentPathName?: string } const prepareNav = ({ @@ -530,6 +591,7 @@ function groupNavItems(navItems: NavItem[], location: Location) { isActive, isInsideActiveCategory, isInsideActivePath, + currentPathName, } // Initialize parentItem in hashmap diff --git a/packages/dnb-design-system-portal/src/shared/menu/SidebarMenuContext.tsx b/packages/dnb-design-system-portal/src/shared/menu/SidebarMenuContext.tsx index f3549bb87a6..192bffbab54 100644 --- a/packages/dnb-design-system-portal/src/shared/menu/SidebarMenuContext.tsx +++ b/packages/dnb-design-system-portal/src/shared/menu/SidebarMenuContext.tsx @@ -65,10 +65,6 @@ export class SidebarMenuProvider extends React.PureComponent { this.setState({ isClosing: true, }) - } else if (typeof window !== 'undefined') { - window.scrollTo({ - top: 0, - }) } }