diff --git a/packages/breadcrumbs/spec/web-component-spec.md b/packages/breadcrumbs/spec/web-component-spec.md index 29c6f3a631a..79e8f0c3822 100644 --- a/packages/breadcrumbs/spec/web-component-spec.md +++ b/packages/breadcrumbs/spec/web-component-spec.md @@ -83,6 +83,10 @@ The overflow overlay's outer panel and inner wrapper are re-exported on the brea |---|---| | `has-overflow` | Set when one or more items are collapsed into the overflow overlay. | +| Theme | Description | +|---|---| +| `slash` | Renders a slash (`/`) instead of the default chevron between items. Set via `theme="slash"` on ``. | + | CSS Custom Property | Default | Description | |---|---|---| | `--vaadin-breadcrumbs-overflow-icon` | `var(--_vaadin-icon-ellipsis)` | The mask-image icon used inside the overflow button. | @@ -197,14 +201,16 @@ Internal behavior: ### `packages/component-base/src/styles/style-props.js` — Modification needed -Add a `--_vaadin-icon-chevron-right` icon definition alongside the existing `--_vaadin-icon-chevron-down`: +Add two icon definitions to the shared icon set: + +- `--_vaadin-icon-chevron-right` — the default separator icon. The breadcrumb separator defaults to a right-pointing chevron, which did not exist in the shared icon set. +- `--_vaadin-icon-slash` — the icon bound to `--vaadin-breadcrumbs-separator` by the `theme="slash"` variant (see "Theme" table on the container). ```css --_vaadin-icon-chevron-right: url('data:image/svg+xml;utf8,'); +--_vaadin-icon-slash: url('data:image/svg+xml;utf8,'); ``` -The breadcrumb separator defaults to a right-pointing chevron. This icon does not exist in the shared icon set. - ### `packages/component-base/src/i18n-mixin.js` — Used as-is Provides the `i18n` property with a `moreItems` key for localizing the overflow button's `aria-label`. @@ -322,3 +328,7 @@ When an item's text wraps onto multiple lines (very narrow viewport, long curren **Q: Why does each item carry a padding-based click target paired with a negative `margin-inline`?** The inline padding gives the link a hit area noticeably larger than the visible text, matching the WCAG 2.5.8 minimum target size and aligning with how trail items render an offset focus outline. The negative `margin-inline` exactly cancels the inline padding for layout, so the visual width and the trail's gaps look the same as a no-padding rendering — the trail still reads as text first, while clicks within the larger hit area still register. Overlay items skip the negative-margin compensator because they need the visual padding (their hover/focus background fills the row). + +**Q: Why does base styles ship a `theme="slash"` separator variant rather than leaving it to each theme?** + +The slash is the second common breadcrumb separator convention after the chevron, and the mask-image recipe makes the variant trivial — `theme="slash"` rebinds `--vaadin-breadcrumbs-separator` to the bundled `--_vaadin-icon-slash` token. Shipping it in base means applications written without a Vaadin theme still get the variant for free, and Lumo / Aura themes do not have to re-implement the same selector. diff --git a/packages/breadcrumbs/src/styles/vaadin-breadcrumbs-base-styles.js b/packages/breadcrumbs/src/styles/vaadin-breadcrumbs-base-styles.js index 92a9fb9c0aa..20a4de68c9b 100644 --- a/packages/breadcrumbs/src/styles/vaadin-breadcrumbs-base-styles.js +++ b/packages/breadcrumbs/src/styles/vaadin-breadcrumbs-base-styles.js @@ -85,6 +85,10 @@ export const breadcrumbsStyles = css` transform: scaleX(-1); } + :host([theme~='slash']) { + --vaadin-breadcrumbs-separator: var(--_vaadin-icon-slash); + } + @media (forced-colors: active) { [part='overflow-button']::before, [part='overflow']::after { diff --git a/packages/breadcrumbs/test/visual/base/breadcrumbs.test.js b/packages/breadcrumbs/test/visual/base/breadcrumbs.test.js index 27a9341750a..720fc4d03f9 100644 --- a/packages/breadcrumbs/test/visual/base/breadcrumbs.test.js +++ b/packages/breadcrumbs/test/visual/base/breadcrumbs.test.js @@ -119,4 +119,28 @@ describe('breadcrumbs', () => { await visualDiff(div, 'overflow-opened'); }); }); + + describe('theme', () => { + let breadcrumbs; + + beforeEach(async () => { + fixtureSync( + ` + + Home + Docs + Current + + `, + div, + ); + breadcrumbs = div.querySelector('vaadin-breadcrumbs'); + await nextRender(); + }); + + it('slash', async () => { + breadcrumbs.setAttribute('theme', 'slash'); + await visualDiff(div, 'theme-slash'); + }); + }); }); diff --git a/packages/breadcrumbs/test/visual/base/screenshots/breadcrumbs/baseline/theme-slash.png b/packages/breadcrumbs/test/visual/base/screenshots/breadcrumbs/baseline/theme-slash.png new file mode 100644 index 00000000000..73a9a161e66 Binary files /dev/null and b/packages/breadcrumbs/test/visual/base/screenshots/breadcrumbs/baseline/theme-slash.png differ diff --git a/packages/component-base/src/styles/style-props.js b/packages/component-base/src/styles/style-props.js index ba25dfdf8d0..93a6664e8d8 100644 --- a/packages/component-base/src/styles/style-props.js +++ b/packages/component-base/src/styles/style-props.js @@ -104,6 +104,7 @@ addGlobalStyles( --_vaadin-icon-redo: url('data:image/svg+xml;utf8,'); --_vaadin-icon-refresh: url('data:image/svg+xml;utf8,'); --_vaadin-icon-resize: url('data:image/svg+xml;utf8,'); + --_vaadin-icon-slash: url('data:image/svg+xml;utf8,'); --_vaadin-icon-sort: url('data:image/svg+xml;utf8,'); --_vaadin-icon-undo: url('data:image/svg+xml;utf8,'); --_vaadin-icon-upload: url('data:image/svg+xml;utf8,');