Skip to content

Commit

Permalink
feat(NavMenu): add disabled options
Browse files Browse the repository at this point in the history
  • Loading branch information
maxime-gendron committed Oct 7, 2021
1 parent 65863cc commit b9ef8de
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ exports[`NavMenuButton Matches Snapshot (defaultOpen) 1`] = `
background-color: #DBDEE1;
}
.c6[disabled] {
color: #B7BBC2;
pointer-events: none;
}
.c0 {
position: relative;
}
Expand Down Expand Up @@ -163,6 +168,7 @@ exports[`NavMenuButton Matches Snapshot (defaultOpen) 1`] = `
class="c6"
data-testid="listitem-optionA"
href="/testa"
tabindex="0"
>
<span
class="c7"
Expand All @@ -176,6 +182,7 @@ exports[`NavMenuButton Matches Snapshot (defaultOpen) 1`] = `
class="c6"
data-testid="listitem-optionB"
href="/testb"
tabindex="0"
>
<span
class="c7"
Expand All @@ -189,6 +196,7 @@ exports[`NavMenuButton Matches Snapshot (defaultOpen) 1`] = `
class="c6"
data-testid="listitem-optionC"
href="/testc"
tabindex="0"
>
<span
class="c7"
Expand All @@ -202,6 +210,7 @@ exports[`NavMenuButton Matches Snapshot (defaultOpen) 1`] = `
class="c6"
data-testid="listitem-optionD"
href="/testd"
tabindex="0"
>
<span
class="c7"
Expand Down Expand Up @@ -319,6 +328,11 @@ exports[`NavMenuButton Matches Snapshot 1`] = `
background-color: #DBDEE1;
}
.c6[disabled] {
color: #B7BBC2;
pointer-events: none;
}
.c0 {
position: relative;
}
Expand Down Expand Up @@ -378,6 +392,7 @@ exports[`NavMenuButton Matches Snapshot 1`] = `
class="c6"
data-testid="listitem-optionA"
href="/testa"
tabindex="0"
>
<span
class="c7"
Expand All @@ -391,6 +406,7 @@ exports[`NavMenuButton Matches Snapshot 1`] = `
class="c6"
data-testid="listitem-optionB"
href="/testb"
tabindex="0"
>
<span
class="c7"
Expand All @@ -404,6 +420,7 @@ exports[`NavMenuButton Matches Snapshot 1`] = `
class="c6"
data-testid="listitem-optionC"
href="/testc"
tabindex="0"
>
<span
class="c7"
Expand All @@ -417,6 +434,7 @@ exports[`NavMenuButton Matches Snapshot 1`] = `
class="c6"
data-testid="listitem-optionD"
href="/testd"
tabindex="0"
>
<span
class="c7"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ const StyledNavMenu = styled(NavMenu)`
width: initial;
`;

function getFirstFocusableElement(array: NavMenuOption[]): NavMenuOption {
const focusableElements = array.filter((element) => !element.disabled);
return focusableElements[0];
}

interface MenuButtonProps {
/**
* Sets nav's description
Expand Down Expand Up @@ -131,7 +136,9 @@ export function NavMenuButton({

useEffect(() => {
if (options.length > 0) {
setFocusedValue(isOpen ? options[0].value : '');
const firstFocusableElement = getFirstFocusableElement(options);

setFocusedValue(isOpen ? firstFocusableElement.value : '');
}
document.addEventListener('mouseup', handleClickOutside);

Expand Down
24 changes: 24 additions & 0 deletions packages/react/src/components/nav-menu/nav-menu.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,21 @@ const optionsWithHtmlLinks: NavMenuOption[] = [
},
];

const optionsDisabled: NavMenuOption[] = [
{
label: 'Option A',
value: 'optionA',
href: '/testA',
disabled: true,
},
{
label: 'Option B',
value: 'optionB',
href: '/testB',
disabled: true,
},
];

describe('NavMenu', () => {
test('Calls onChange callback when an option is clicked', () => {
const callback = jest.fn();
Expand All @@ -73,6 +88,15 @@ describe('NavMenu', () => {
expect(callback).toHaveBeenCalledTimes(1);
});

test('Does not call onChange callback when a disabled option is clicked', () => {
const callback = jest.fn();
const wrapper = mountWithProviders(<NavMenu options={optionsDisabled} onChange={callback} />);

getByTestId(wrapper, 'listitem-optionA').simulate('click');

expect(callback).toHaveBeenCalledTimes(0);
});

test('Calls onChange callback when enter key is pressed on option', () => {
const callback = jest.fn();
const wrapper = shallow(<NavMenu options={options} onChange={callback} />);
Expand Down
18 changes: 18 additions & 0 deletions packages/react/src/components/nav-menu/nav-menu.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ exports[`NavMenu Is hidden 1`] = `
background-color: #DBDEE1;
}
.c1[disabled] {
color: #B7BBC2;
pointer-events: none;
}
<ul
class="c0"
data-testid="menu-list"
Expand All @@ -57,6 +62,7 @@ exports[`NavMenu Is hidden 1`] = `
class="c1"
data-testid="listitem-optionA"
href="/testA"
tabindex="0"
>
<span
class="c2"
Expand All @@ -70,6 +76,7 @@ exports[`NavMenu Is hidden 1`] = `
class="c1"
data-testid="listitem-optionB"
href="/testB"
tabindex="0"
>
<span
class="c2"
Expand All @@ -83,6 +90,7 @@ exports[`NavMenu Is hidden 1`] = `
class="c1"
data-testid="listitem-optionC"
href="/testC"
tabindex="0"
>
<span
class="c2"
Expand All @@ -96,6 +104,7 @@ exports[`NavMenu Is hidden 1`] = `
class="c1"
data-testid="listitem-optionD"
href="/testD"
tabindex="0"
>
<span
class="c2"
Expand Down Expand Up @@ -154,6 +163,11 @@ exports[`NavMenu Matches the snapshot 1`] = `
background-color: #DBDEE1;
}
.c1[disabled] {
color: #B7BBC2;
pointer-events: none;
}
<ul
class="c0"
data-testid="menu-list"
Expand All @@ -163,6 +177,7 @@ exports[`NavMenu Matches the snapshot 1`] = `
class="c1"
data-testid="listitem-optionA"
href="/testA"
tabindex="0"
>
<span
class="c2"
Expand All @@ -176,6 +191,7 @@ exports[`NavMenu Matches the snapshot 1`] = `
class="c1"
data-testid="listitem-optionB"
href="/testB"
tabindex="0"
>
<span
class="c2"
Expand All @@ -189,6 +205,7 @@ exports[`NavMenu Matches the snapshot 1`] = `
class="c1"
data-testid="listitem-optionC"
href="/testC"
tabindex="0"
>
<span
class="c2"
Expand All @@ -202,6 +219,7 @@ exports[`NavMenu Matches the snapshot 1`] = `
class="c1"
data-testid="listitem-optionD"
href="/testD"
tabindex="0"
>
<span
class="c2"
Expand Down
24 changes: 17 additions & 7 deletions packages/react/src/components/nav-menu/nav-menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ const List = styled.ul`
width: 100%;
`;

interface LinkProps {
$device: DeviceContextProps;
}

const Label = styled.span`
overflow: hidden;
text-overflow: ellipsis;
Expand All @@ -50,6 +46,11 @@ const EndIcon = styled(Icon).attrs({ size: iconSize })`
min-width: ${iconSize}px;
`;

interface LinkProps {
$device: DeviceContextProps;
disabled?: boolean;
}

const linkStyles = css<LinkProps>`
align-items: center;
color: ${({ theme }) => theme.greys.black};
Expand All @@ -73,6 +74,11 @@ const linkStyles = css<LinkProps>`
color: ${({ theme }) => theme.greys.black};
}
}
&[disabled] {
color: ${({ theme }) => theme.greys['mid-grey']};
pointer-events: none;
}
`;

export const ReactRouterNavLink = styled(NavLink)<LinkProps & NavLinkProps>`
Expand All @@ -84,6 +90,7 @@ export const HtmlLink = styled.a<LinkProps>`
`;

export interface NavMenuOption {
disabled?: boolean;
endIcon?: IconName;
exact?: boolean;
href: string;
Expand Down Expand Up @@ -190,8 +197,9 @@ export const NavMenu = forwardRef(({
data-testid={testId}
ref={option.ref}
$device={device}
href={option.href}
onClick={handleOnClick}
href={option.disabled ? undefined : option.href}
disabled={option.disabled}
onClick={option.disabled ? undefined : handleOnClick}
onKeyDown={(event) => handleKeyDown(event, option)}
>
{label}
Expand All @@ -202,8 +210,10 @@ export const NavMenu = forwardRef(({
exact={option.exact}
innerRef={option.ref}
$device={device}
tabIndex={option.disabled ? -1 : 0}
to={option.href}
onClick={handleOnClick}
disabled={option.disabled}
onClick={option.disabled ? undefined : handleOnClick}
onKeyDown={(event) => handleKeyDown(event, option)}
>
{label}
Expand Down
26 changes: 26 additions & 0 deletions packages/storybook/stories/nav-menu-button.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,26 @@ const optionsWithHtmlLinks: NavMenuOption[] = [
},
];

const optionsDisabled: NavMenuOption[] = [
{
label: 'Option A',
value: 'optionA',
href: '/testa',
disabled: true,
},
{
label: 'Option B',
value: 'optionB',
href: '/testb',
},
{
label: 'Option C',
value: 'optionC',
href: '/testc',
disabled: true,
},
];

export const Desktop: Story = () => (
<ApplicationMenu>
<NavMenuButton options={options}>Menu</NavMenuButton>
Expand Down Expand Up @@ -141,3 +161,9 @@ export const WithHtmlLinks: Story = () => (
<NavMenuButton options={optionsWithHtmlLinks}>Menu</NavMenuButton>
</ApplicationMenu>
);

export const WithDisabledOptions: Story = () => (
<ApplicationMenu>
<NavMenuButton options={optionsDisabled}>Menu</NavMenuButton>
</ApplicationMenu>
);

0 comments on commit b9ef8de

Please sign in to comment.