Commit 77e35f47 authored by Jonathan Giroux's avatar Jonathan Giroux
Browse files

feat: can customize BreadcrumbItem's inner link

parent 02fbc161
...@@ -19,6 +19,10 @@ const propTypes = { ...@@ -19,6 +19,10 @@ const propTypes = {
* `href` attribute for the inner `a` element * `href` attribute for the inner `a` element
*/ */
href: PropTypes.string, href: PropTypes.string,
/**
* You can use a custom element type for this component's inner link.
*/
linkAs: PropTypes.elementType,
/** /**
* `title` attribute for the inner `a` element * `title` attribute for the inner `a` element
*/ */
...@@ -37,7 +41,18 @@ const defaultProps = { ...@@ -37,7 +41,18 @@ const defaultProps = {
const BreadcrumbItem = React.forwardRef( const BreadcrumbItem = React.forwardRef(
// Need to define the default "as" during prop destructuring to be compatible with styled-components github.com/react-bootstrap/react-bootstrap/issues/3595 // Need to define the default "as" during prop destructuring to be compatible with styled-components github.com/react-bootstrap/react-bootstrap/issues/3595
({ bsPrefix, active, className, as: Component = 'li', ...props }, ref) => { (
{
bsPrefix,
active,
children,
className,
as: Component = 'li',
linkAs: LinkComponent = SafeAnchor,
...props
},
ref,
) => {
const prefix = useBootstrapPrefix(bsPrefix, 'breadcrumb-item'); const prefix = useBootstrapPrefix(bsPrefix, 'breadcrumb-item');
const { href, title, target, ...elementProps } = props; const { href, title, target, ...elementProps } = props;
...@@ -49,11 +64,7 @@ const BreadcrumbItem = React.forwardRef( ...@@ -49,11 +64,7 @@ const BreadcrumbItem = React.forwardRef(
className={classNames(prefix, className, { active })} className={classNames(prefix, className, { active })}
aria-current={active ? 'page' : undefined} aria-current={active ? 'page' : undefined}
> >
{active ? ( {active ? children : <LinkComponent {...elementProps} {...linkProps} />}
<span {...elementProps} className={classNames({ active })} />
) : (
<SafeAnchor {...elementProps} {...linkProps} />
)}
</Component> </Component>
); );
}, },
......
...@@ -3,6 +3,7 @@ import sinon from 'sinon'; ...@@ -3,6 +3,7 @@ import sinon from 'sinon';
import { mount } from 'enzyme'; import { mount } from 'enzyme';
import Breadcrumb from '../src/Breadcrumb'; import Breadcrumb from '../src/Breadcrumb';
import Button from '../src/Button';
describe('<Breadcrumb.Item>', () => { describe('<Breadcrumb.Item>', () => {
it('Should render `a` as inner element when is not active', () => { it('Should render `a` as inner element when is not active', () => {
...@@ -11,21 +12,26 @@ describe('<Breadcrumb.Item>', () => { ...@@ -11,21 +12,26 @@ describe('<Breadcrumb.Item>', () => {
.should.have.length(0); .should.have.length(0);
}); });
it('Should render `span.active` with `active` attribute set.', () => { it('Should render `li` with no children as inner element when active.', () => {
mount(<Breadcrumb.Item active>Active Crumb</Breadcrumb.Item>) let li = mount(<Breadcrumb.Item active>Active Crumb</Breadcrumb.Item>).find(
.find('span.active') 'li',
.should.have.length(1); );
li.should.have.length(1);
li.children()
.html()
.should.eql('Active Crumb');
}); });
it('Should render `span.active` when active and has href', () => { it('Should render `li` with no children as inner element when active and has href', () => {
const instance = mount( let li = mount(
<Breadcrumb.Item href="#" active> <Breadcrumb.Item href="#" active>
Active Crumb Active Crumb
</Breadcrumb.Item>, </Breadcrumb.Item>,
); ).find('li');
instance.find('span.active').should.have.length(1); li.should.have.length(1);
instance.find('span[href="#"]').should.have.length(0); li.children()
instance.find('a').should.have.length(0); .html()
.should.eql('Active Crumb');
}); });
it('Should add custom classes onto `li` wrapper element', () => { it('Should add custom classes onto `li` wrapper element', () => {
...@@ -123,4 +129,18 @@ describe('<Breadcrumb.Item>', () => { ...@@ -123,4 +129,18 @@ describe('<Breadcrumb.Item>', () => {
it('Should have li as default component', () => { it('Should have li as default component', () => {
mount(<Breadcrumb.Item />).assertSingle('li'); mount(<Breadcrumb.Item />).assertSingle('li');
}); });
it('Should be able to customize inner link element', () => {
const instance = mount(<Breadcrumb.Item linkAs={Button} />);
instance.find('a').should.have.length(0);
instance.find('button').should.have.length(1);
});
it('Should spread property on customized inner link element', () => {
const instance = mount(<Breadcrumb.Item linkAs={Button} type="submit" />);
instance
.find('button')
.prop('type')
.should.eq('submit');
});
}); });
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment