Skip to content

Commit

Permalink
refactor(react): update HeaderNavigation to functional component (#9911)
Browse files Browse the repository at this point in the history
* refactor(react): update HeaderNavigation to functional component

* chore: remove ref from refactor

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
joshblack and kodiakhq[bot] authored Oct 30, 2021
1 parent 51ccb35 commit 96f45ee
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 5 deletions.
8 changes: 4 additions & 4 deletions docs/migration/11.x-carbon-components-react.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
## Table of Contents

- [Components](#components)
- [SideNavMenu](#sidenavmenu)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->
<!-- prettier-ignore-end -->
Expand All @@ -32,8 +31,9 @@ For a full overview of changes to components, checkout our

## Components

| Component | Changes |
| :------------ | :-------------------------------------------------------------- |
| `SideNavMenu` | Updated from a class to functional component. No other changes. |
| Component | Changes |
| :----------------- | :-------------------------------------------------------------- |
| `HeaderNavigation` | Updated from a class to functional component. No other changes. |
| `SideNavMenu` | Updated from a class to functional component. No other changes. |

## FAQ
6 changes: 5 additions & 1 deletion packages/react/src/components/UIShell/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
*/

import * as FeatureFlags from '@carbon/feature-flags';
import HeaderNavigationClassic from './HeaderNavigation';
import { HeaderNavigation as HeaderNavigationNext } from './next';
import SideNavMenuClassic from './SideNavMenu';
import { SideNavMenu as SideNavMenuNext } from './next/SideNavMenu';

Expand All @@ -19,7 +21,9 @@ export HeaderMenu from './HeaderMenu';
export HeaderMenuButton from './HeaderMenuButton';
export HeaderMenuItem from './HeaderMenuItem';
export HeaderName from './HeaderName';
export HeaderNavigation from './HeaderNavigation';
export const HeaderNavigation = FeatureFlags.enabled('enable-v11-release')
? HeaderNavigationNext
: HeaderNavigationClassic;
export HeaderPanel from './HeaderPanel';
export HeaderSideNavItems from './HeaderSideNavItems';
export Switcher from './Switcher';
Expand Down
56 changes: 56 additions & 0 deletions packages/react/src/components/UIShell/next/HeaderNavigation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* Copyright IBM Corp. 2016, 2018
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import cx from 'classnames';
import React from 'react';
import PropTypes from 'prop-types';
import { AriaLabelPropType } from '../../../prop-types/AriaPropTypes';
import { usePrefix } from '../../../internal/usePrefix';

function HeaderNavigation(props) {
const {
'aria-label': ariaLabel,
'aria-labelledby': ariaLabelledBy,
children,
className: customClassName,
...rest
} = props;
const prefix = usePrefix();
const className = cx(`${prefix}--header__nav`, customClassName);
// Assign both label strategies in this option, only one should be defined
// so when we spread that should be the one that is applied to the node
const accessibilityLabel = {
'aria-label': ariaLabel,
'aria-labelledby': ariaLabelledBy,
};

return (
<nav {...rest} {...accessibilityLabel} className={className}>
<ul className={`${prefix}--header__menu-bar`}>{children}</ul>
</nav>
);
}

HeaderNavigation.propTypes = {
/**
* Required props for accessibility label on the underlying menu
*/
...AriaLabelPropType,

/**
* Provide valid children of HeaderNavigation, for example `HeaderMenuItem`
* or `HeaderMenu`
*/
children: PropTypes.node,

/**
* Optionally provide a custom class to apply to the underlying <nav> node
*/
className: PropTypes.string,
};

export { HeaderNavigation };
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* Copyright IBM Corp. 2016, 2018
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import { cleanup, render, screen } from '@testing-library/react';
import React from 'react';
import { HeaderNavigation } from '../HeaderNavigation';

describe('HeaderNavigation', () => {
it('should render children that are passed to the component', () => {
render(
<HeaderNavigation aria-label="navigation">
<li data-testid="child" />
</HeaderNavigation>
);
expect(screen.getByTestId('child')).toBeVisible();
});

it('should add an accessibility label to the <nav>', () => {
render(
<HeaderNavigation aria-label="navigation">
<li data-testid="child" />
</HeaderNavigation>
);

expect(screen.getByLabelText('navigation')).toBeVisible();

cleanup();
render(
<>
<span id="label">navigation</span>
<HeaderNavigation aria-labelledby="label">
<li data-testid="child" />
</HeaderNavigation>
</>
);

expect(screen.getByLabelText('navigation')).toBeVisible();
});

it('should support a custom className', () => {
const { container } = render(
<HeaderNavigation aria-label="navigation" className="test">
<li data-testid="child" />
</HeaderNavigation>
);

expect(container.firstChild).toHaveClass('test');
});

it('should pass additional props to the outermost element', () => {
const { container } = render(
<HeaderNavigation aria-label="navigation" data-testid="test">
<li data-testid="child" />
</HeaderNavigation>
);

expect(container.firstChild).toHaveAttribute('data-testid', 'test');
});
});
1 change: 1 addition & 0 deletions packages/react/src/components/UIShell/next/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
* LICENSE file in the root directory of this source tree.
*/

export { HeaderNavigation } from './HeaderNavigation';
export { SideNavMenu } from './SideNavMenu';

0 comments on commit 96f45ee

Please sign in to comment.