Unverified Commit 6cea3bf3 authored by Brady Pascoe's avatar Brady Pascoe Committed by GitHub
Browse files

Merge pull request #5043 from KoltesDigital/master2

feat: can customize BreadcrumbItem's inner link
parents 08ddde5d 7d8146fe
......@@ -19,6 +19,10 @@ const propTypes = {
* `href` attribute for the inner `a` element
*/
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
*/
......@@ -36,8 +40,19 @@ const defaultProps = {
};
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
({ bsPrefix, active, className, as: Component = 'li', ...props }, ref) => {
(
{
bsPrefix,
active,
children,
className,
// Need to define the default "as" during prop destructuring to be compatible with styled-components github.com/react-bootstrap/react-bootstrap/issues/3595
as: Component = 'li',
linkAs: LinkComponent = SafeAnchor,
...props
},
ref,
) => {
const prefix = useBootstrapPrefix(bsPrefix, 'breadcrumb-item');
const { href, title, target, ...elementProps } = props;
......@@ -49,11 +64,7 @@ const BreadcrumbItem = React.forwardRef(
className={classNames(prefix, className, { active })}
aria-current={active ? 'page' : undefined}
>
{active ? (
<span {...elementProps} className={classNames({ active })} />
) : (
<SafeAnchor {...elementProps} {...linkProps} />
)}
{active ? children : <LinkComponent {...elementProps} {...linkProps} />}
</Component>
);
},
......
......@@ -3,6 +3,7 @@ import sinon from 'sinon';
import { mount } from 'enzyme';
import Breadcrumb from '../src/Breadcrumb';
import Button from '../src/Button';
describe('<Breadcrumb.Item>', () => {
it('Should render `a` as inner element when is not active', () => {
......@@ -11,21 +12,26 @@ describe('<Breadcrumb.Item>', () => {
.should.have.length(0);
});
it('Should render `span.active` with `active` attribute set.', () => {
mount(<Breadcrumb.Item active>Active Crumb</Breadcrumb.Item>)
.find('span.active')
.should.have.length(1);
it('Should render `li` with no children as inner element when active.', () => {
let li = mount(<Breadcrumb.Item active>Active Crumb</Breadcrumb.Item>).find(
'li',
);
li.should.have.length(1);
li.children()
.html()
.should.eql('Active Crumb');
});
it('Should render `span.active` when active and has href', () => {
const instance = mount(
it('Should render `li` with no children as inner element when active and has href', () => {
let li = mount(
<Breadcrumb.Item href="#" active>
Active Crumb
</Breadcrumb.Item>,
);
instance.find('span.active').should.have.length(1);
instance.find('span[href="#"]').should.have.length(0);
instance.find('a').should.have.length(0);
).find('li');
li.should.have.length(1);
li.children()
.html()
.should.eql('Active Crumb');
});
it('Should add custom classes onto `li` wrapper element', () => {
......@@ -123,4 +129,18 @@ describe('<Breadcrumb.Item>', () => {
it('Should have li as default component', () => {
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');
});
});
......@@ -5,6 +5,7 @@ import { BsPrefixComponent } from './helpers';
export interface BreadcrumbItemProps {
active?: boolean;
href?: string;
linkAs?: React.ElementType;
target?: string;
title?: React.ReactNode;
}
......
Markdown is supported
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