Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 13 additions & 3 deletions packages/breadcrumbs/spec/web-component-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<vaadin-breadcrumbs>`. |

| CSS Custom Property | Default | Description |
|---|---|---|
| `--vaadin-breadcrumbs-overflow-icon` | `var(--_vaadin-icon-ellipsis)` | The mask-image icon used inside the overflow button. |
Expand Down Expand Up @@ -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,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m9 18 6-6-6-6"/></svg>');
--_vaadin-icon-slash: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><rect x="13.7812" y="4.22583" width="1.5" height="16" rx="0.75" transform="rotate(20 13.7812 4.22583)" fill="currentColor"/></svg>');
```

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`.
Expand Down Expand Up @@ -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.
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
24 changes: 24 additions & 0 deletions packages/breadcrumbs/test/visual/base/breadcrumbs.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,28 @@ describe('breadcrumbs', () => {
await visualDiff(div, 'overflow-opened');
});
});

describe('theme', () => {
let breadcrumbs;

beforeEach(async () => {
fixtureSync(
`
<vaadin-breadcrumbs>
<vaadin-breadcrumbs-item path="/">Home</vaadin-breadcrumbs-item>
<vaadin-breadcrumbs-item path="/docs">Docs</vaadin-breadcrumbs-item>
<vaadin-breadcrumbs-item>Current</vaadin-breadcrumbs-item>
</vaadin-breadcrumbs>
`,
div,
);
breadcrumbs = div.querySelector('vaadin-breadcrumbs');
await nextRender();
});

it('slash', async () => {
breadcrumbs.setAttribute('theme', 'slash');
await visualDiff(div, 'theme-slash');
});
});
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions packages/component-base/src/styles/style-props.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ addGlobalStyles(
--_vaadin-icon-redo: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 7v6h-6"/><path d="M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3l3 2.7"/></svg>');
--_vaadin-icon-refresh: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><path d="M22 10C22 10 19.995 7.26822 18.3662 5.63824C16.7373 4.00827 14.4864 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21C16.1031 21 19.5649 18.2543 20.6482 14.5M22 10V4M22 10H16" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>');
--_vaadin-icon-resize: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill-rule="evenodd" clip-rule="evenodd" d="M18.5303 7.46967c.2929.29289.2929.76777 0 1.06066L8.53033 18.5304c-.29289.2929-.76777.2929-1.06066 0s-.29289-.7678 0-1.0607L17.4697 7.46967c.2929-.29289.7677-.29289 1.0606 0Zm0 4.50003c.2929.2929.2929.7678 0 1.0607l-5.5 5.5c-.2929.2928-.7677.2928-1.0606 0-.2929-.2929-.2929-.7678 0-1.0607l5.4999-5.5c.2929-.2929.7678-.2929 1.0607 0Zm0 4.5c.2929.2928.2929.7677 0 1.0606l-1 1.0001c-.2929.2928-.7677.2929-1.0606 0-.2929-.2929-.2929-.7678 0-1.0607l1-1c.2929-.2929.7677-.2929 1.0606 0Z" fill="currentColor"/></svg>');
--_vaadin-icon-slash: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none"><rect x="13.7812" y="4.22583" width="1.5" height="16" rx="0.75" transform="rotate(20 13.7812 4.22583)" fill="currentColor"/></svg>');
--_vaadin-icon-sort: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="8" height="12" viewBox="0 0 8 12" fill="none"><path d="M7.49854 6.99951C7.92795 6.99951 8.15791 7.50528 7.87549 7.82861L4.37646 11.8296C4.17728 12.0571 3.82272 12.0571 3.62354 11.8296L0.125488 7.82861C-0.157248 7.50531 0.0719873 6.99956 0.501465 6.99951H7.49854ZM3.62354 0.17041C3.82275 -0.0573875 4.17725 -0.0573848 4.37646 0.17041L7.87549 4.17041C8.15825 4.49373 7.92806 5.00049 7.49854 5.00049L0.501465 4.99951C0.0719873 4.99946 -0.157248 4.49371 0.125488 4.17041L3.62354 0.17041Z" fill="black"/></svg>');
--_vaadin-icon-undo: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 7v6h6"/><path d="M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13"/></svg>');
--_vaadin-icon-upload: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v12"/><path d="m17 8-5-5-5 5"/><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/></svg>');
Expand Down
Loading