From 991c21aa05514707cc4318d127f6ddffea09f580 Mon Sep 17 00:00:00 2001 From: ShankarV-CodeJunkie Date: Mon, 22 May 2023 17:15:29 +0530 Subject: [PATCH 01/12] feat: add enterDelayMs-type prop to delay displaying SideNav component --- .../__snapshots__/PublicAPI-test.js.snap | 3 + .../react/src/components/UIShell/SideNav.tsx | 28 +++++-- .../src/components/UIShell/UIShell.stories.js | 75 +++++++++++++++++++ 3 files changed, 99 insertions(+), 7 deletions(-) diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap index 85332c3cf45b..5cbc5b5cb873 100644 --- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap +++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap @@ -6536,6 +6536,9 @@ Map { "defaultExpanded": Object { "type": "bool", }, + "enterDelayMs": Object { + "type": "number", + }, "expanded": Object { "type": "bool", }, diff --git a/packages/react/src/components/UIShell/SideNav.tsx b/packages/react/src/components/UIShell/SideNav.tsx index 972145108204..405e867fe9a9 100644 --- a/packages/react/src/components/UIShell/SideNav.tsx +++ b/packages/react/src/components/UIShell/SideNav.tsx @@ -22,6 +22,7 @@ import { usePrefix } from '../../internal/usePrefix'; import { keys, match } from '../../internal/keyboard'; import { useMergedRefs } from '../../internal/useMergedRefs'; import { useWindowEvent } from '../../internal/useEvent'; +import { useDelayedState } from '../../internal/useDelayedState'; // TO-DO: comment back in when footer is added for rails // import SideNavFooter from './SideNavFooter'; @@ -43,6 +44,7 @@ interface SideNavProps extends ComponentProps<'nav'> { addMouseListeners?: boolean | undefined; onOverlayClick?: MouseEventHandler | undefined; onSideNavBlur?: () => void | undefined; + enterDelayMs?: number; } function SideNavRenderFunction( @@ -65,28 +67,29 @@ function SideNavRenderFunction( addMouseListeners = true, onOverlayClick, onSideNavBlur, + enterDelayMs = 100, ...other }: SideNavProps, ref: ForwardedRef ) { const prefix = usePrefix(); const { current: controlled } = useRef(expandedProp !== undefined); - const [expandedState, setExpandedState] = useState(defaultExpanded); + const [expandedState, setExpandedState] = useDelayedState(defaultExpanded); const [expandedViaHoverState, setExpandedViaHoverState] = - useState(defaultExpanded); + useDelayedState(defaultExpanded); const expanded = controlled ? expandedProp : expandedState; const sideNavRef = useRef(null); const navRef = useMergedRefs([sideNavRef, ref]); const handleToggle: typeof onToggle = (event, value = !expanded) => { if (!controlled) { - setExpandedState(value); + setExpandedState(value, enterDelayMs); } if (onToggle) { onToggle(event, value); } if (controlled || isRail) { - setExpandedViaHoverState(value); + setExpandedViaHoverState(value, enterDelayMs); } }; @@ -101,7 +104,7 @@ function SideNavRenderFunction( // : t('carbon.sidenav.state.closed'); const className = cx(customClassName, { - [`${prefix}--side-nav`]: true, + [`${prefix}--side-nav`]: false, [`${prefix}--side-nav--expanded`]: expanded || expandedViaHoverState, [`${prefix}--side-nav--collapsed`]: !expanded && isFixedNav, [`${prefix}--side-nav--rail`]: isRail, @@ -174,8 +177,14 @@ function SideNavRenderFunction( } if (addMouseListeners && isRail) { - eventHandlers.onMouseEnter = () => handleToggle(true, true); - eventHandlers.onMouseLeave = () => handleToggle(false, false); + eventHandlers.onMouseEnter = () => { + handleToggle(true, true); + }; + eventHandlers.onMouseLeave = () => { + setExpandedState(false); + setExpandedViaHoverState(false); + handleToggle(false, false); + }; } useWindowEvent('keydown', (event: Event) => { @@ -303,6 +312,11 @@ SideNav.propTypes = { * the label you want displayed or read by screen readers. */ // translateById: PropTypes.func, + + /** + * Specify the duration in milliseconds to delay before displaying the sidenavigation + */ + enterDelayMs: PropTypes.number, }; export default SideNav; diff --git a/packages/react/src/components/UIShell/UIShell.stories.js b/packages/react/src/components/UIShell/UIShell.stories.js index 9e6a5e06e193..4fea5252cca7 100644 --- a/packages/react/src/components/UIShell/UIShell.stories.js +++ b/packages/react/src/components/UIShell/UIShell.stories.js @@ -160,6 +160,9 @@ export default { docs: { page: mdx, }, + controls: { + hideNoControlsWarning: true, + }, }, argTypes: { className: { @@ -1019,4 +1022,76 @@ export const SideNavWLargeSideNavItems = () => ( ); +const UIShellPlayground = (props) => { + const { isRail, enterDelayMs } = props; + return ( + + + + + Link + + + Link + + + Link + + + + + Link + + + Link + + + Link + + + + + Link + + + Link + + + Link + + + + Link + + + Link + + + + ); +}; +export const Playground = UIShellPlayground.bind({}); +Playground.argTypes = { + isRail: { + defaultValue: 'true', + control: { + type: 'boolean', + }, + }, + enterDelayMs: { + control: { + type: 'number', + }, + }, +}; SideNavWLargeSideNavItems.storyName = 'SideNav w/ large side nav items'; From 8160b7a8e761f25e8bdb31a7dc3dfcd59d03da7e Mon Sep 17 00:00:00 2001 From: ShankarV-CodeJunkie Date: Mon, 22 May 2023 19:21:08 +0530 Subject: [PATCH 02/12] fix: lint errors --- packages/react/src/components/UIShell/SideNav.tsx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/react/src/components/UIShell/SideNav.tsx b/packages/react/src/components/UIShell/SideNav.tsx index 405e867fe9a9..627f6220d1aa 100644 --- a/packages/react/src/components/UIShell/SideNav.tsx +++ b/packages/react/src/components/UIShell/SideNav.tsx @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. */ import React, { - useState, useRef, type ForwardedRef, type ComponentProps, @@ -250,6 +249,11 @@ SideNav.propTypes = { * If `true`, the SideNav will be open on initial render. */ defaultExpanded: PropTypes.bool, + + /** + * Specify the duration in milliseconds to delay before displaying the sidenavigation + */ + enterDelayMs: PropTypes.number, /** * If `true`, the SideNav will be expanded, otherwise it will be collapsed. @@ -312,11 +316,6 @@ SideNav.propTypes = { * the label you want displayed or read by screen readers. */ // translateById: PropTypes.func, - - /** - * Specify the duration in milliseconds to delay before displaying the sidenavigation - */ - enterDelayMs: PropTypes.number, }; export default SideNav; From d46c38c7a0aee79790a5e24222f98d772157b8bc Mon Sep 17 00:00:00 2001 From: ShankarV-CodeJunkie Date: Mon, 22 May 2023 19:26:17 +0530 Subject: [PATCH 03/12] fix: yarn format --- packages/react/src/components/UIShell/SideNav.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/src/components/UIShell/SideNav.tsx b/packages/react/src/components/UIShell/SideNav.tsx index 627f6220d1aa..0b10650ac566 100644 --- a/packages/react/src/components/UIShell/SideNav.tsx +++ b/packages/react/src/components/UIShell/SideNav.tsx @@ -249,7 +249,7 @@ SideNav.propTypes = { * If `true`, the SideNav will be open on initial render. */ defaultExpanded: PropTypes.bool, - + /** * Specify the duration in milliseconds to delay before displaying the sidenavigation */ From e1572f778f02bc565c500dda5716cac20a4ea2ca Mon Sep 17 00:00:00 2001 From: ShankarV-CodeJunkie Date: Tue, 23 May 2023 18:59:05 +0530 Subject: [PATCH 04/12] fix: fix Visual regressions test failures --- .../react/src/components/UIShell/SideNav.tsx | 17 +++++++++++++++-- .../src/components/UIShell/UIShell.stories.js | 2 +- .../components/ui-shell/side-nav/_side-nav.scss | 2 +- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/packages/react/src/components/UIShell/SideNav.tsx b/packages/react/src/components/UIShell/SideNav.tsx index 0b10650ac566..7ca8d41b0bcc 100644 --- a/packages/react/src/components/UIShell/SideNav.tsx +++ b/packages/react/src/components/UIShell/SideNav.tsx @@ -103,12 +103,14 @@ function SideNavRenderFunction( // : t('carbon.sidenav.state.closed'); const className = cx(customClassName, { - [`${prefix}--side-nav`]: false, + [`${prefix}--side-nav`]: true, [`${prefix}--side-nav--expanded`]: expanded || expandedViaHoverState, [`${prefix}--side-nav--collapsed`]: !expanded && isFixedNav, [`${prefix}--side-nav--rail`]: isRail, [`${prefix}--side-nav--ux`]: isChildOfHeader, [`${prefix}--side-nav--hidden`]: !isPersistent, + [`${prefix}--cds--side-nav--expand-on-hover`]: + expanded || expandedViaHoverState, }); const overlayClassName = cx({ @@ -145,7 +147,12 @@ function SideNavRenderFunction( const eventHandlers: Partial< Pick< ComponentProps<'nav'>, - 'onFocus' | 'onBlur' | 'onKeyDown' | 'onMouseEnter' | 'onMouseLeave' + | 'onFocus' + | 'onBlur' + | 'onKeyDown' + | 'onMouseEnter' + | 'onMouseLeave' + | 'onClick' > > = {}; @@ -184,6 +191,12 @@ function SideNavRenderFunction( setExpandedViaHoverState(false); handleToggle(false, false); }; + eventHandlers.onClick = () => { + //if delay is enabled, and user intentionally clicks it to see it expanded immediately + setExpandedState(true); + setExpandedViaHoverState(true); + handleToggle(true, true); + }; } useWindowEvent('keydown', (event: Event) => { diff --git a/packages/react/src/components/UIShell/UIShell.stories.js b/packages/react/src/components/UIShell/UIShell.stories.js index 4fea5252cca7..6b04e90dad68 100644 --- a/packages/react/src/components/UIShell/UIShell.stories.js +++ b/packages/react/src/components/UIShell/UIShell.stories.js @@ -1083,7 +1083,7 @@ const UIShellPlayground = (props) => { export const Playground = UIShellPlayground.bind({}); Playground.argTypes = { isRail: { - defaultValue: 'true', + defaultValue: true, control: { type: 'boolean', }, diff --git a/packages/styles/scss/components/ui-shell/side-nav/_side-nav.scss b/packages/styles/scss/components/ui-shell/side-nav/_side-nav.scss index f20235afeddc..f71ea676e8fc 100644 --- a/packages/styles/scss/components/ui-shell/side-nav/_side-nav.scss +++ b/packages/styles/scss/components/ui-shell/side-nav/_side-nav.scss @@ -68,7 +68,7 @@ width: 0; } - .#{$prefix}--side-nav.#{$prefix}--side-nav--rail:not( + .#{$prefix}--side-nav.#{$prefix}--side-nav--rail.#{prefix}--cds--side-nav--expand-on-hover:not( .#{$prefix}--side-nav--fixed ):hover, .#{$prefix}--side-nav--expanded { From 482d378d1d02856d32bbef36918ede087d44b07f Mon Sep 17 00:00:00 2001 From: ShankarV-CodeJunkie <56068832+Shankar-CodeJunkie@users.noreply.github.com> Date: Wed, 24 May 2023 13:37:56 +0530 Subject: [PATCH 05/12] Update packages/styles/scss/components/ui-shell/side-nav/_side-nav.scss Co-authored-by: TJ Egan --- .../styles/scss/components/ui-shell/side-nav/_side-nav.scss | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/styles/scss/components/ui-shell/side-nav/_side-nav.scss b/packages/styles/scss/components/ui-shell/side-nav/_side-nav.scss index f71ea676e8fc..46797f50922f 100644 --- a/packages/styles/scss/components/ui-shell/side-nav/_side-nav.scss +++ b/packages/styles/scss/components/ui-shell/side-nav/_side-nav.scss @@ -68,9 +68,6 @@ width: 0; } - .#{$prefix}--side-nav.#{$prefix}--side-nav--rail.#{prefix}--cds--side-nav--expand-on-hover:not( - .#{$prefix}--side-nav--fixed - ):hover, .#{$prefix}--side-nav--expanded { width: mini-units(32); } From edc9183a245f737dc91fada866d8f67fa9636d50 Mon Sep 17 00:00:00 2001 From: ShankarV-CodeJunkie <56068832+Shankar-CodeJunkie@users.noreply.github.com> Date: Wed, 24 May 2023 13:38:07 +0530 Subject: [PATCH 06/12] Update packages/react/src/components/UIShell/SideNav.tsx Co-authored-by: TJ Egan --- packages/react/src/components/UIShell/SideNav.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/react/src/components/UIShell/SideNav.tsx b/packages/react/src/components/UIShell/SideNav.tsx index 7ca8d41b0bcc..638f48a85a10 100644 --- a/packages/react/src/components/UIShell/SideNav.tsx +++ b/packages/react/src/components/UIShell/SideNav.tsx @@ -109,8 +109,6 @@ function SideNavRenderFunction( [`${prefix}--side-nav--rail`]: isRail, [`${prefix}--side-nav--ux`]: isChildOfHeader, [`${prefix}--side-nav--hidden`]: !isPersistent, - [`${prefix}--cds--side-nav--expand-on-hover`]: - expanded || expandedViaHoverState, }); const overlayClassName = cx({ From ca93f973814ec8eb334f6bace038638b1d5c1da4 Mon Sep 17 00:00:00 2001 From: ShankarV-CodeJunkie Date: Fri, 26 May 2023 13:44:06 +0530 Subject: [PATCH 07/12] chore: modify playground story for sidenavigation with proper content --- .../src/components/UIShell/UIShell.stories.js | 157 ++++++++++++------ 1 file changed, 104 insertions(+), 53 deletions(-) diff --git a/packages/react/src/components/UIShell/UIShell.stories.js b/packages/react/src/components/UIShell/UIShell.stories.js index 6b04e90dad68..3f82ec427c0f 100644 --- a/packages/react/src/components/UIShell/UIShell.stories.js +++ b/packages/react/src/components/UIShell/UIShell.stories.js @@ -1025,59 +1025,110 @@ export const SideNavWLargeSideNavItems = () => ( const UIShellPlayground = (props) => { const { isRail, enterDelayMs } = props; return ( - - - - - Link - - - Link - - - Link - - - - - Link - - - Link - - - Link - - - - - Link - - - Link - - - Link - - - - Link - - - Link - - - + ( + <> +
+ + + + [Platform] + + + Link 1 + Link 2 + Link 3 + + Sub-link 1 + Sub-link 2 + Sub-link 3 + + + + + + + + + + + + + + + + + + Link + + + Link + + + Link + + + + + Link + + + Link + + + Link + + + + + Link + + + Link + + + Link + + + + Link + + + Link + + + +
+ + + )} + /> ); }; export const Playground = UIShellPlayground.bind({}); From 0b328f01881d781a4163d8b5dcd296b8196292ed Mon Sep 17 00:00:00 2001 From: ShankarV-CodeJunkie Date: Mon, 29 May 2023 13:04:29 +0530 Subject: [PATCH 08/12] chore: removed playground story for sidenav component --- .../src/components/UIShell/UIShell.stories.js | 130 +----------------- 1 file changed, 6 insertions(+), 124 deletions(-) diff --git a/packages/react/src/components/UIShell/UIShell.stories.js b/packages/react/src/components/UIShell/UIShell.stories.js index 3f82ec427c0f..048137ed11cb 100644 --- a/packages/react/src/components/UIShell/UIShell.stories.js +++ b/packages/react/src/components/UIShell/UIShell.stories.js @@ -815,7 +815,11 @@ FixedSideNavWDivider.storyName = 'Fixed SideNav w/ Divider'; export const SideNavRail = () => ( <> - + @@ -917,6 +921,7 @@ export const SideNavRailWHeader = () => ( ( ); -const UIShellPlayground = (props) => { - const { isRail, enterDelayMs } = props; - return ( - ( - <> -
- - - - [Platform] - - - Link 1 - Link 2 - Link 3 - - Sub-link 1 - Sub-link 2 - Sub-link 3 - - - - - - - - - - - - - - - - - - Link - - - Link - - - Link - - - - - Link - - - Link - - - Link - - - - - Link - - - Link - - - Link - - - - Link - - - Link - - - -
- - - )} - /> - ); -}; -export const Playground = UIShellPlayground.bind({}); -Playground.argTypes = { - isRail: { - defaultValue: true, - control: { - type: 'boolean', - }, - }, - enterDelayMs: { - control: { - type: 'number', - }, - }, -}; SideNavWLargeSideNavItems.storyName = 'SideNav w/ large side nav items'; From f2ace9d729abc51e4d27b85ae59c7d2ce2cf3e50 Mon Sep 17 00:00:00 2001 From: ShankarV-CodeJunkie Date: Wed, 31 May 2023 17:32:56 +0530 Subject: [PATCH 09/12] chore: modify UIShell storybook to have enterDelayMs prop control --- .../src/components/UIShell/UIShell.stories.js | 49 +++++++++++++++---- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/packages/react/src/components/UIShell/UIShell.stories.js b/packages/react/src/components/UIShell/UIShell.stories.js index 048137ed11cb..00884e825f73 100644 --- a/packages/react/src/components/UIShell/UIShell.stories.js +++ b/packages/react/src/components/UIShell/UIShell.stories.js @@ -813,13 +813,9 @@ export const FixedSideNavWDivider = () => ( FixedSideNavWDivider.storyName = 'Fixed SideNav w/ Divider'; -export const SideNavRail = () => ( +export const SideNavRail = (args) => ( <> - + @@ -872,9 +868,26 @@ export const SideNavRail = () => ( ); +SideNavRail.argTypes = { + isRail: { + control: { + type: 'boolean', + }, + defaultValue: true, + }, + enterDelayMs: { + control: { + type: 'number', + }, + defaultValue: 1000, + description: + 'Specify the duration in milliseconds to delay before displaying the sidenav', + }, +}; + SideNavRail.storyName = 'SideNav Rail'; -export const SideNavRailWHeader = () => ( +export const SideNavRailWHeader = (args) => ( ( <> @@ -920,12 +933,11 @@ export const SideNavRailWHeader = () => ( + onSideNavBlur={onClickSideNavExpand} + {...args}> @@ -981,6 +993,23 @@ export const SideNavRailWHeader = () => ( /> ); +SideNavRailWHeader.argTypes = { + isRail: { + control: { + type: 'boolean', + }, + defaultValue: true, + }, + enterDelayMs: { + control: { + type: 'number', + }, + defaultValue: 1000, + description: + 'Specify the duration in milliseconds to delay before displaying the sidenav', + }, +}; + SideNavRailWHeader.storyName = 'SideNav Rail w/Header'; export const SideNavWLargeSideNavItems = () => ( From 3c3836a72f057646709fef8103fac1deb194fc2f Mon Sep 17 00:00:00 2001 From: Francine Lucca <40550942+francinelucca@users.noreply.github.com> Date: Wed, 31 May 2023 13:16:25 -0400 Subject: [PATCH 10/12] Update packages/react/src/components/UIShell/UIShell.stories.js --- .../react/src/components/UIShell/UIShell.stories.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/react/src/components/UIShell/UIShell.stories.js b/packages/react/src/components/UIShell/UIShell.stories.js index 00884e825f73..c655453782c8 100644 --- a/packages/react/src/components/UIShell/UIShell.stories.js +++ b/packages/react/src/components/UIShell/UIShell.stories.js @@ -874,14 +874,20 @@ SideNavRail.argTypes = { type: 'boolean', }, defaultValue: true, + table: { + defaultValue: { summary: true } + }, + description: 'Optional prop to display the side nav rail.' }, enterDelayMs: { control: { type: 'number', }, - defaultValue: 1000, - description: - 'Specify the duration in milliseconds to delay before displaying the sidenav', + table: { + defaultValue: { summary: 100 }, + }, + defaultValue: 100, + description: 'Specify the duration in milliseconds to delay before displaying the sidenav' }, }; From 56d4db29bd38c915fdede1d65febdb0b8e3cb95e Mon Sep 17 00:00:00 2001 From: Francine Lucca <40550942+francinelucca@users.noreply.github.com> Date: Wed, 31 May 2023 13:16:32 -0400 Subject: [PATCH 11/12] Update packages/react/src/components/UIShell/UIShell.stories.js --- .../react/src/components/UIShell/UIShell.stories.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/react/src/components/UIShell/UIShell.stories.js b/packages/react/src/components/UIShell/UIShell.stories.js index c655453782c8..87816a8badd6 100644 --- a/packages/react/src/components/UIShell/UIShell.stories.js +++ b/packages/react/src/components/UIShell/UIShell.stories.js @@ -1005,14 +1005,20 @@ SideNavRailWHeader.argTypes = { type: 'boolean', }, defaultValue: true, + table: { + defaultValue: { summary: true } + }, + description: 'Optional prop to display the side nav rail.' }, enterDelayMs: { control: { type: 'number', }, - defaultValue: 1000, - description: - 'Specify the duration in milliseconds to delay before displaying the sidenav', + table: { + defaultValue: { summary: 100 }, + }, + defaultValue: 100, + description: 'Specify the duration in milliseconds to delay before displaying the sidenav' }, }; From 154d7bdccafd5b389c80901a9b89f37e787c8ec3 Mon Sep 17 00:00:00 2001 From: Francine Lucca Date: Wed, 31 May 2023 13:23:33 -0400 Subject: [PATCH 12/12] fix: format --- .../src/components/UIShell/UIShell.stories.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/react/src/components/UIShell/UIShell.stories.js b/packages/react/src/components/UIShell/UIShell.stories.js index 87816a8badd6..ee9f73a650f3 100644 --- a/packages/react/src/components/UIShell/UIShell.stories.js +++ b/packages/react/src/components/UIShell/UIShell.stories.js @@ -875,9 +875,9 @@ SideNavRail.argTypes = { }, defaultValue: true, table: { - defaultValue: { summary: true } + defaultValue: { summary: true }, }, - description: 'Optional prop to display the side nav rail.' + description: 'Optional prop to display the side nav rail.', }, enterDelayMs: { control: { @@ -887,7 +887,8 @@ SideNavRail.argTypes = { defaultValue: { summary: 100 }, }, defaultValue: 100, - description: 'Specify the duration in milliseconds to delay before displaying the sidenav' + description: + 'Specify the duration in milliseconds to delay before displaying the sidenav', }, }; @@ -1006,9 +1007,9 @@ SideNavRailWHeader.argTypes = { }, defaultValue: true, table: { - defaultValue: { summary: true } + defaultValue: { summary: true }, }, - description: 'Optional prop to display the side nav rail.' + description: 'Optional prop to display the side nav rail.', }, enterDelayMs: { control: { @@ -1018,7 +1019,8 @@ SideNavRailWHeader.argTypes = { defaultValue: { summary: 100 }, }, defaultValue: 100, - description: 'Specify the duration in milliseconds to delay before displaying the sidenav' + description: + 'Specify the duration in milliseconds to delay before displaying the sidenav', }, };