Skip to content

Commit d2a2684

Browse files
committed
feat: add separator prop to DBBreadcrumb component with support for chevron and slash styles
1 parent 7027bea commit d2a2684

File tree

7 files changed

+110
-56
lines changed

7 files changed

+110
-56
lines changed

packages/components/src/components/breadcrumb/breadcrumb.lite.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import type { DBBreadcrumbProps, DBBreadcrumbState } from './model';
1010
useMetadata({});
1111

1212
useDefaultProps<DBBreadcrumbProps>({
13-
size: 'small'
13+
size: 'small',
14+
separator: 'chevron'
1415
});
1516

1617
export default function DBBreadcrumb(props: DBBreadcrumbProps) {
@@ -24,6 +25,7 @@ export default function DBBreadcrumb(props: DBBreadcrumbProps) {
2425
id={props.id}
2526
class={cls('db-breadcrumb', props.className)}
2627
data-size={props.size}
28+
data-separator={props.separator}
2729
aria-label="breadcrumb">
2830
<ol class="db-breadcrumb-list" role="list">
2931
{props.children}

packages/components/src/components/breadcrumb/breadcrumb.scss

Lines changed: 65 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -21,69 +21,82 @@
2121
display: flex;
2222
align-items: center;
2323
gap: variables.$db-spacing-fixed-3xs; // 2px between separator and item (small)
24+
}
2425

25-
// Separator icon (chevron-right) before each item except the first
26-
&:not(:first-child)::before {
27-
content: "\203A"; // Unicode chevron right (›)
28-
display: flex;
29-
align-items: center;
30-
justify-content: center;
31-
inline-size: variables.$db-sizing-sm; // 24px (small)
32-
block-size: variables.$db-sizing-sm;
33-
font-size: variables.$db-sizing-md; // 20px
34-
color: colors.$db-adaptive-on-bg-basic-emphasis-100-default;
35-
font-weight: 400;
26+
// Link and text styling (small)
27+
a,
28+
span {
29+
display: flex;
30+
align-items: center;
31+
padding: variables.$db-spacing-fixed-3xs variables.$db-spacing-fixed-2xs; // 2px 4px (small)
32+
border-radius: variables.$db-border-radius-xs; // 4px
33+
background-color: colors.$db-adaptive-bg-basic-transparent-full-default;
34+
color: colors.$db-adaptive-on-bg-basic-emphasis-100-default;
35+
font-size: variables.$db-sizing-sm; // 14px (body-sm)
36+
line-height: variables.$db-sizing-md; // 20px
37+
font-family: var(--db-font-family-sans);
38+
font-weight: 400;
39+
text-decoration: none;
40+
white-space: nowrap;
41+
transition: background-color 0.2s ease;
42+
43+
&:hover,
44+
&:focus {
45+
background-color: colors.$db-adaptive-bg-basic-transparent-semi-default;
46+
text-decoration: underline;
47+
}
48+
49+
&:active {
50+
background-color: colors.$db-adaptive-bg-basic-transparent-full-pressed;
3651
}
3752

38-
// Link and text styling (small)
53+
@media screen and (prefers-reduced-motion: reduce) {
54+
transition: none;
55+
}
56+
}
57+
58+
// Current page (last item with aria-current="page")
59+
li[aria-current="page"] {
3960
a,
4061
span {
41-
display: flex;
42-
align-items: center;
43-
padding: variables.$db-spacing-fixed-3xs
44-
variables.$db-spacing-fixed-2xs; // 2px 4px (small)
45-
46-
border-radius: variables.$db-border-radius-xs; // 4px
47-
background-color: colors.$db-adaptive-bg-basic-transparent-full-default;
48-
color: colors.$db-adaptive-on-bg-basic-emphasis-100-default;
49-
font-size: variables.$db-sizing-sm; // 14px (body-sm)
50-
line-height: variables.$db-sizing-md; // 20px
51-
font-family: var(--db-font-family-sans);
52-
font-weight: 400;
53-
text-decoration: none;
54-
white-space: nowrap;
55-
transition: background-color 0.2s ease;
62+
font-weight: 700; // Bold for current item
63+
cursor: default;
64+
pointer-events: none;
5665

5766
&:hover,
5867
&:focus {
59-
background-color: colors.$db-adaptive-bg-basic-transparent-semi-default;
60-
text-decoration: underline;
61-
}
62-
63-
&:active {
64-
background-color: colors.$db-adaptive-bg-basic-transparent-full-pressed;
65-
}
66-
67-
@media screen and (prefers-reduced-motion: reduce) {
68-
transition: none;
68+
background-color: colors.$db-adaptive-bg-basic-transparent-full-default;
69+
text-decoration: none;
6970
}
7071
}
72+
}
7173

72-
// Current page (last item with aria-current="page")
73-
&[aria-current="page"] {
74-
a,
75-
span {
76-
font-weight: 700; // Bold for current item
77-
cursor: default;
78-
pointer-events: none;
79-
80-
&:hover,
81-
&:focus {
82-
background-color: colors.$db-adaptive-bg-basic-transparent-full-default;
83-
text-decoration: none;
84-
}
85-
}
86-
}
74+
// Default chevron: apply when the breadcrumb does NOT request a slash
75+
&:not([data-separator="slash"])
76+
.db-breadcrumb-list
77+
li:not(:first-child)::before {
78+
content: ""; // chevron right glyph (U+203A)
79+
display: flex;
80+
align-items: center;
81+
justify-content: center;
82+
inline-size: variables.$db-sizing-sm; // 24px (small)
83+
block-size: variables.$db-sizing-sm;
84+
font-size: variables.$db-sizing-md; // 20px
85+
color: colors.$db-adaptive-on-bg-basic-emphasis-100-default;
86+
font-weight: 400;
87+
}
88+
89+
// Slash separator override when component has data-separator="slash"
90+
&[data-separator="slash"] .db-breadcrumb-list li:not(:first-child)::before {
91+
content: "/"; // ASCII slash (0x2F)
92+
font-weight: 400;
93+
color: colors.$db-adaptive-on-bg-basic-emphasis-100-default;
94+
95+
/* reduce the inline size so the slash doesn't create extra empty box */
96+
inline-size: auto;
97+
block-size: auto;
98+
font-size: variables.$db-sizing-sm; // match small text sizing by default
99+
margin: 0 variables.$db-spacing-fixed-2xs; // small horizontal spacing
87100
}
88101

89102
// Medium size variant
@@ -114,7 +127,6 @@
114127
// Keep the medium padding but ensure comfortable tap/click area
115128
padding: variables.$db-spacing-fixed-2xs
116129
variables.$db-spacing-fixed-xs; // 4px 8px (medium)
117-
118130
font-size: variables.$db-sizing-md; // 16px (body-md)
119131
line-height: variables.$db-sizing-lg; // 24px
120132
}

packages/components/src/components/breadcrumb/model.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,19 @@ import { GlobalProps, GlobalState } from '../../shared/model';
22

33
export const BreadcrumbSizeList = ['small', 'medium'] as const;
44
export type BreadcrumbSize = (typeof BreadcrumbSizeList)[number];
5+
export const BreadcrumbSeparatorList = ['chevron', 'slash'] as const;
6+
export type BreadcrumbSeparator = (typeof BreadcrumbSeparatorList)[number];
57

68
export interface DBBreadcrumbDefaultProps {
79
/**
810
* The size of the breadcrumb items
911
*/
1012
size?: BreadcrumbSize;
13+
14+
/**
15+
* The separator between breadcrumb items: 'chevron' or 'slash'
16+
*/
17+
separator?: BreadcrumbSeparator;
1118
}
1219

1320
export interface DBBreadcrumbProps

showcases/angular-showcase/src/app/components/breadcrumb/breadcrumb.component.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
(exampleProps?.className ? ' ' + exampleProps.className : '')
1818
"
1919
[attr.data-size]="exampleProps?.size ?? 'small'"
20+
[attr.data-separator]="exampleProps?.separator"
2021
aria-label="breadcrumb"
2122
>
2223
<ol class="db-breadcrumb-list" role="list">

showcases/react-showcase/src/components/breadcrumb/index.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@ type BreadcrumbExampleProps = {
1313
children?: BreadcrumbItem[];
1414
size?: 'small' | 'medium';
1515
className?: string;
16+
separator?: 'chevron' | 'slash';
1617
};
1718

1819
const getBreadcrumb = ({
1920
children,
2021
size,
21-
className
22+
className,
23+
separator
2224
}: BreadcrumbExampleProps) => (
23-
<DBBreadcrumb size={size} className={className}>
25+
<DBBreadcrumb size={size} className={className} separator={separator}>
2426
{children && Array.isArray(children)
2527
? children.map((item, index) =>
2628
item.href ? (

showcases/shared/breadcrumb.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,34 @@
2727
}
2828
}
2929
]
30+
},
31+
{
32+
"name": "Separator",
33+
"examples": [
34+
{
35+
"name": "Chevron",
36+
"className": "w-full",
37+
"props": {
38+
"separator": "chevron",
39+
"children": [
40+
{ "href": "#", "text": "Home" },
41+
{ "href": "#", "text": "Category" },
42+
{ "text": "Current Page", "ariaCurrent": "page" }
43+
]
44+
}
45+
},
46+
{
47+
"name": "Slash",
48+
"className": "w-full",
49+
"props": {
50+
"separator": "slash",
51+
"children": [
52+
{ "href": "#", "text": "Home" },
53+
{ "href": "#", "text": "Category" },
54+
{ "text": "Current Page", "ariaCurrent": "page" }
55+
]
56+
}
57+
}
58+
]
3059
}
3160
]

showcases/vue-showcase/src/components/breadcrumb/breadcrumb.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const DBBreadcrumb = "nav";
1717
:is="DBBreadcrumb"
1818
:class="['db-breadcrumb', exampleProps?.className]"
1919
:data-size="exampleProps?.size"
20+
:data-separator="exampleProps?.separator"
2021
aria-label="breadcrumb"
2122
>
2223
<ol class="db-breadcrumb-list" role="list">

0 commit comments

Comments
 (0)