diff --git a/docs/docs/components/breadcrumb.md b/docs/docs/components/breadcrumb.md index f6d0dfb3b..d137ffd78 100644 --- a/docs/docs/components/breadcrumb.md +++ b/docs/docs/components/breadcrumb.md @@ -98,7 +98,29 @@ Use the `suffix` slot to add content after any breadcrumb item. ### With Dropdowns -Dropdown menus can be placed in a prefix or suffix slot to provide additional options. +Dropdown menus can be placed in the default slot to provide additional options. + +```html {.example} + + Homepage + + + + + + + Web Design + Web Development + Marketing + + + + Our Services + Digital Media + +``` + +Alternatively, you can place dropdown menus in a prefix or suffix slot. ```html {.example} diff --git a/src/components/breadcrumb-item/breadcrumb-item.test.ts b/src/components/breadcrumb-item/breadcrumb-item.test.ts index 5a380e5a7..0e9e0f43e 100644 --- a/src/components/breadcrumb-item/breadcrumb-item.test.ts +++ b/src/components/breadcrumb-item/breadcrumb-item.test.ts @@ -145,4 +145,28 @@ describe('', () => { expect(childNodes.length).to.eq(1); }); }); + + describe('when rendering a wa-dropdown in the default slot', () => { + it('should not render a link or button tag, but a div wrapper', async () => { + el = await fixture(html` + + + + + + + Web Design + Web Development + Marketing + + + + `); + + await expect(el).to.be.accessible(); + expect(el.shadowRoot!.querySelector('a')).to.be.null; + expect(el.shadowRoot!.querySelector('button')).to.be.null; + expect(el.shadowRoot!.querySelector('div.breadcrumb-item__label--drop-down')).not.to.be.null; + }); + }); }); diff --git a/src/components/breadcrumb-item/breadcrumb-item.ts b/src/components/breadcrumb-item/breadcrumb-item.ts index a562c5ef1..c68d41956 100644 --- a/src/components/breadcrumb-item/breadcrumb-item.ts +++ b/src/components/breadcrumb-item/breadcrumb-item.ts @@ -1,6 +1,7 @@ -import { customElement, property } from 'lit/decorators.js'; +import { customElement, property, query, state } from 'lit/decorators.js'; import { html } from 'lit'; import { ifDefined } from 'lit/directives/if-defined.js'; +import { watch } from '../../internal/watch.js'; import componentStyles from '../../styles/component.styles.js'; import styles from './breadcrumb-item.styles.js'; import WebAwesomeElement from '../../internal/webawesome-element.js'; @@ -28,6 +29,10 @@ import type { CSSResultGroup } from 'lit'; export default class WaBreadcrumbItem extends WebAwesomeElement { static styles: CSSResultGroup = [componentStyles, styles]; + @query('slot:not([name])') defaultSlot: HTMLSlotElement; + + @state() private renderType: 'button' | 'link' | 'dropdown' = 'button'; + /** * Optional URL to direct the user to when the breadcrumb item is activated. When set, a link will be rendered * internally. When unset, a button will be rendered instead. @@ -40,16 +45,41 @@ export default class WaBreadcrumbItem extends WebAwesomeElement { /** The `rel` attribute to use on the link. Only used when `href` is set. */ @property() rel = 'noreferrer noopener'; - render() { - const isLink = this.href ? true : false; + private setRenderType() { + const hasDropdown = + this.defaultSlot.assignedElements({ flatten: true }).filter(i => i.tagName.toLowerCase() === 'sl-dropdown') + .length > 0; + if (this.href) { + this.renderType = 'link'; + return; + } + + if (hasDropdown) { + this.renderType = 'dropdown'; + return; + } + + this.renderType = 'button'; + } + + @watch('href', { waitUntilFirstUpdate: true }) + hrefChanged() { + this.setRenderType(); + } + + handleSlotChange() { + this.setRenderType(); + } + + render() { return html`