This repository has been archived by the owner on Oct 19, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 395
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(breadcrumb): add support for current page (#2054)
* feat(breadcrumb): add support for current page * chore(breadcrumb): add new prop types behind feature flag * chore(breadcrumb): update imports in storybook * Update Breadcrumb-story.js
- Loading branch information
Showing
12 changed files
with
575 additions
and
123 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
/** | ||
* 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 PropTypes from 'prop-types'; | ||
import React from 'react'; | ||
import cx from 'classnames'; | ||
import { settings } from 'carbon-components'; | ||
import Link from '../Link'; | ||
import { componentsX } from '../../internal/FeatureFlags'; | ||
|
||
const { prefix } = settings; | ||
|
||
const BreadcrumbItem = ({ | ||
'aria-current': ariaCurrent, | ||
children, | ||
className: customClassName, | ||
href, | ||
isCurrentPage, | ||
...rest | ||
}) => { | ||
const className = cx({ | ||
[`${prefix}--breadcrumb-item`]: true, | ||
// We set the current class only if `isCurrentPage` is passed in and we do | ||
// not have an `aria-current="page"` set for the breadcrumb item | ||
[`${prefix}--breadcrumb-item--current`]: | ||
componentsX && isCurrentPage && ariaCurrent !== 'page', | ||
[customClassName]: !!customClassName, | ||
}); | ||
|
||
if (typeof children === 'string' && href) { | ||
return ( | ||
<div className={className} {...rest}> | ||
<Link href={href} aria-current={ariaCurrent}> | ||
{children} | ||
</Link> | ||
</div> | ||
); | ||
} | ||
|
||
return ( | ||
<div className={className} {...rest}> | ||
{React.cloneElement(children, { | ||
'aria-current': ariaCurrent, | ||
className: `${prefix}--link`, | ||
})} | ||
</div> | ||
); | ||
}; | ||
|
||
BreadcrumbItem.propTypes = { | ||
/** | ||
* Pass in content that will be inside of the BreadcrumbItem | ||
*/ | ||
children: PropTypes.node, | ||
/** | ||
* Specify an optional className to be applied to the container node | ||
*/ | ||
className: PropTypes.string, | ||
|
||
/** | ||
* Optional string representing the link location for the BreadcrumbItem | ||
*/ | ||
href: PropTypes.string, | ||
}; | ||
|
||
if (componentsX) { | ||
BreadcrumbItem.propTypes.children = PropTypes.oneOfType([ | ||
PropTypes.element, | ||
PropTypes.string, | ||
]).isRequired; | ||
BreadcrumbItem.propTypes.isCurrentPage = PropTypes.bool; | ||
} | ||
|
||
export default BreadcrumbItem; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
/** | ||
* 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 React from 'react'; | ||
import { mount } from 'enzyme'; | ||
|
||
describe('Breadcrumb', () => { | ||
let Breadcrumb; | ||
let BreadcrumbItem; | ||
|
||
beforeEach(() => { | ||
jest.resetModules(); | ||
const BreadcrumbEntrypoint = require('../'); | ||
Breadcrumb = BreadcrumbEntrypoint.Breadcrumb; | ||
BreadcrumbItem = BreadcrumbEntrypoint.BreadcrumbItem; | ||
}); | ||
|
||
it('should render', () => { | ||
const wrapper = mount( | ||
<Breadcrumb className="parent-class"> | ||
<BreadcrumbItem | ||
className="some-class" | ||
href="www.carbondesignsystem.com"> | ||
Breadcrumb 1 | ||
</BreadcrumbItem> | ||
</Breadcrumb> | ||
); | ||
expect(wrapper).toMatchSnapshot(); | ||
}); | ||
|
||
it('should support rendering without a trailing slash', () => { | ||
const wrapper = mount( | ||
<Breadcrumb noTrailingSlash> | ||
<BreadcrumbItem href="www.carbondesignsystem.com"> | ||
Breadcrumb 1 | ||
</BreadcrumbItem> | ||
</Breadcrumb> | ||
); | ||
expect(wrapper).toMatchSnapshot(); | ||
}); | ||
|
||
it('should support rendering a custom component as a breadcrumb item', () => { | ||
const CustomComponent = jest.fn(({ children, href, ...rest }) => ( | ||
<a href={href} data-test-id="custom-component" {...rest}> | ||
{children} | ||
</a> | ||
)); | ||
|
||
mount( | ||
<Breadcrumb> | ||
<BreadcrumbItem href="#a">A</BreadcrumbItem> | ||
<BreadcrumbItem href="#b">B</BreadcrumbItem> | ||
<BreadcrumbItem> | ||
<CustomComponent href="#c">C</CustomComponent> | ||
</BreadcrumbItem> | ||
</Breadcrumb> | ||
); | ||
|
||
expect(CustomComponent).toHaveBeenCalled(); | ||
expect(CustomComponent).toHaveBeenCalledWith( | ||
expect.objectContaining({ | ||
className: 'bx--link', | ||
}), | ||
{} | ||
); | ||
}); | ||
|
||
describe('experimental', () => { | ||
let Breadcrumb; | ||
let BreadcrumbItem; | ||
|
||
beforeEach(() => { | ||
jest.resetModules(); | ||
const FeatureFlags = require('../../../internal/FeatureFlags'); | ||
FeatureFlags.componentsX = true; | ||
const BreadcrumbEntrypoint = require('../'); | ||
Breadcrumb = BreadcrumbEntrypoint.Breadcrumb; | ||
BreadcrumbItem = BreadcrumbEntrypoint.BreadcrumbItem; | ||
}); | ||
|
||
it('should render', () => { | ||
const wrapper = mount( | ||
<Breadcrumb className="parent-class"> | ||
<BreadcrumbItem | ||
className="some-class" | ||
href="www.carbondesignsystem.com"> | ||
Breadcrumb 1 | ||
</BreadcrumbItem> | ||
</Breadcrumb> | ||
); | ||
expect(wrapper).toMatchSnapshot(); | ||
}); | ||
|
||
it('should support rendering the current page', () => { | ||
const manual = mount( | ||
<Breadcrumb> | ||
<BreadcrumbItem href="#a">A</BreadcrumbItem> | ||
<BreadcrumbItem href="#b">B</BreadcrumbItem> | ||
<BreadcrumbItem href="#c" isCurrentPage> | ||
C | ||
</BreadcrumbItem> | ||
</Breadcrumb> | ||
); | ||
expect(manual).toMatchSnapshot(); | ||
|
||
const aria = mount( | ||
<Breadcrumb> | ||
<BreadcrumbItem href="#a">A</BreadcrumbItem> | ||
<BreadcrumbItem href="#b">B</BreadcrumbItem> | ||
<BreadcrumbItem href="#c" aria-current="page"> | ||
C | ||
</BreadcrumbItem> | ||
</Breadcrumb> | ||
); | ||
expect(aria).toMatchSnapshot(); | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.