@duskmoon-dev/el-breadcrumbs 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,141 @@
1
+ # @duskmoon-dev/el-breadcrumbs
2
+
3
+ A breadcrumb navigation component built with Web Components.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ bun add @duskmoon-dev/el-breadcrumbs
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Auto-Register
14
+
15
+ ```typescript
16
+ import '@duskmoon-dev/el-breadcrumbs/register';
17
+ ```
18
+
19
+ ```html
20
+ <el-dm-breadcrumbs></el-dm-breadcrumbs>
21
+ ```
22
+
23
+ ### Manual Registration
24
+
25
+ ```typescript
26
+ import { ElDmBreadcrumbs, register } from '@duskmoon-dev/el-breadcrumbs';
27
+
28
+ // Register with default tag name
29
+ register();
30
+
31
+ // Or register with custom tag name
32
+ customElements.define('my-breadcrumbs', ElDmBreadcrumbs);
33
+ ```
34
+
35
+ ### Setting Items via JavaScript
36
+
37
+ ```javascript
38
+ const breadcrumbs = document.querySelector('el-dm-breadcrumbs');
39
+ breadcrumbs.items = [
40
+ { label: 'Home', href: '/' },
41
+ { label: 'Products', href: '/products' },
42
+ { label: 'Category', href: '/products/category' },
43
+ { label: 'Current Page' }, // No href = current page
44
+ ];
45
+ ```
46
+
47
+ ## Attributes
48
+
49
+ | Attribute | Type | Default | Description |
50
+ |-----------|------|---------|-------------|
51
+ | `separator` | `string` | `'/'` | Separator character |
52
+
53
+ ## Slots
54
+
55
+ | Slot | Description |
56
+ |------|-------------|
57
+ | `separator` | Custom separator element |
58
+
59
+ ## CSS Parts
60
+
61
+ | Part | Description |
62
+ |------|-------------|
63
+ | `nav` | The nav element |
64
+ | `list` | The ordered list |
65
+ | `item` | Each breadcrumb item |
66
+ | `link` | The link elements |
67
+ | `current` | The current (last) item |
68
+ | `separator` | The separator elements |
69
+
70
+ ## Events
71
+
72
+ | Event | Detail | Description |
73
+ |-------|--------|-------------|
74
+ | `navigate` | `{ item, index }` | Fired when a breadcrumb is clicked |
75
+
76
+ ## Examples
77
+
78
+ ### Basic
79
+
80
+ ```html
81
+ <el-dm-breadcrumbs id="crumbs"></el-dm-breadcrumbs>
82
+ <script>
83
+ document.querySelector('#crumbs').items = [
84
+ { label: 'Home', href: '/' },
85
+ { label: 'Library', href: '/library' },
86
+ { label: 'Data' },
87
+ ];
88
+ </script>
89
+ ```
90
+
91
+ ### Custom Separator
92
+
93
+ ```html
94
+ <el-dm-breadcrumbs separator=">"></el-dm-breadcrumbs>
95
+ <el-dm-breadcrumbs separator="→"></el-dm-breadcrumbs>
96
+ <el-dm-breadcrumbs separator="|"></el-dm-breadcrumbs>
97
+ ```
98
+
99
+ ### Custom Separator Element
100
+
101
+ ```html
102
+ <el-dm-breadcrumbs>
103
+ <span slot="separator">›</span>
104
+ </el-dm-breadcrumbs>
105
+ ```
106
+
107
+ ### Handling Navigation
108
+
109
+ ```javascript
110
+ const breadcrumbs = document.querySelector('el-dm-breadcrumbs');
111
+ breadcrumbs.addEventListener('navigate', (e) => {
112
+ e.preventDefault();
113
+ console.log('Navigate to:', e.detail.item.href);
114
+ // Handle navigation (e.g., with router)
115
+ });
116
+ ```
117
+
118
+ ### Dynamic Updates
119
+
120
+ ```javascript
121
+ // Update breadcrumbs based on route
122
+ function updateBreadcrumbs(path) {
123
+ const parts = path.split('/').filter(Boolean);
124
+ const items = [{ label: 'Home', href: '/' }];
125
+
126
+ let href = '';
127
+ parts.forEach((part, index) => {
128
+ href += `/${part}`;
129
+ items.push({
130
+ label: part.charAt(0).toUpperCase() + part.slice(1),
131
+ href: index === parts.length - 1 ? undefined : href,
132
+ });
133
+ });
134
+
135
+ document.querySelector('el-dm-breadcrumbs').items = items;
136
+ }
137
+ ```
138
+
139
+ ## License
140
+
141
+ MIT
package/dist/cjs/index.js CHANGED
@@ -35,8 +35,10 @@ __export(exports_src, {
35
35
  module.exports = __toCommonJS(exports_src);
36
36
 
37
37
  // src/el-dm-breadcrumbs.ts
38
- var import_el_core = require("@duskmoon-dev/el-core");
39
- var styles = import_el_core.css`
38
+ var import_el_base = require("@duskmoon-dev/el-base");
39
+ var import_navigation = require("@duskmoon-dev/core/components/navigation");
40
+ var coreStyles = import_navigation.css.replace(/@layer\s+components\s*\{/, "").replace(/\}\s*$/, "");
41
+ var styles = import_el_base.css`
40
42
  :host {
41
43
  display: block;
42
44
  }
@@ -45,57 +47,46 @@ var styles = import_el_core.css`
45
47
  display: none !important;
46
48
  }
47
49
 
50
+ /* Import core navigation styles */
51
+ ${coreStyles}
52
+
48
53
  .breadcrumbs-nav {
49
54
  font-family: inherit;
50
55
  }
51
56
 
52
- .breadcrumbs-list {
53
- display: flex;
54
- flex-wrap: wrap;
55
- align-items: center;
56
- gap: 0.5rem;
57
- list-style: none;
58
- margin: 0;
57
+ /* Override core .breadcrumbs padding since we manage our own layout */
58
+ .breadcrumbs {
59
59
  padding: 0;
60
60
  }
61
61
 
62
- .breadcrumbs-item {
63
- display: flex;
64
- align-items: center;
65
- gap: 0.5rem;
66
- }
67
-
68
- .breadcrumbs-link {
62
+ /* Override core .breadcrumb-link with our custom colors */
63
+ .breadcrumb-link {
69
64
  color: var(--color-primary);
70
- text-decoration: none;
71
- font-size: 0.875rem;
72
- line-height: 1.25rem;
73
- transition: color 150ms ease;
74
- cursor: pointer;
75
65
  }
76
66
 
77
- .breadcrumbs-link:hover {
67
+ .breadcrumb-link:hover {
78
68
  color: var(--color-primary-dark, var(--color-primary));
79
- text-decoration: underline;
80
69
  }
81
70
 
82
- .breadcrumbs-link:focus {
71
+ .breadcrumb-link:focus {
83
72
  outline: 2px solid var(--color-primary);
84
73
  outline-offset: 2px;
85
74
  border-radius: 2px;
86
75
  }
87
76
 
88
- .breadcrumbs-current {
77
+ .breadcrumb-item-active {
89
78
  color: var(--color-on-surface);
90
79
  font-size: 0.875rem;
91
80
  line-height: 1.25rem;
92
- font-weight: 500;
93
81
  }
94
82
 
95
- .breadcrumbs-separator {
96
- color: var(--color-on-surface-variant, var(--color-outline));
97
- font-size: 0.875rem;
98
- user-select: none;
83
+ /* Hide core's separator ::before — we render separator text explicitly */
84
+ .breadcrumb-separator::before {
85
+ display: none;
86
+ }
87
+
88
+ .breadcrumb-separator {
89
+ opacity: 1;
99
90
  }
100
91
 
101
92
  /* Hide slotted separator template */
@@ -104,7 +95,7 @@ var styles = import_el_core.css`
104
95
  }
105
96
  `;
106
97
 
107
- class ElDmBreadcrumbs extends import_el_core.BaseElement {
98
+ class ElDmBreadcrumbs extends import_el_base.BaseElement {
108
99
  static properties = {
109
100
  items: { type: Array, reflect: false },
110
101
  separator: { type: String, reflect: true, default: "/" }
@@ -144,9 +135,9 @@ class ElDmBreadcrumbs extends import_el_core.BaseElement {
144
135
  const escapedLabel = this._escapeHtml(item.label);
145
136
  if (isLast) {
146
137
  return `
147
- <li class="breadcrumbs-item" part="item">
138
+ <li class="breadcrumb-item" part="item">
148
139
  <span
149
- class="breadcrumbs-current"
140
+ class="breadcrumb-item-active"
150
141
  part="current"
151
142
  aria-current="page"
152
143
  >${escapedLabel}</span>
@@ -154,20 +145,20 @@ class ElDmBreadcrumbs extends import_el_core.BaseElement {
154
145
  `;
155
146
  }
156
147
  return `
157
- <li class="breadcrumbs-item" part="item">
148
+ <li class="breadcrumb-item" part="item">
158
149
  <a
159
- class="breadcrumbs-link"
150
+ class="breadcrumb-link"
160
151
  part="link"
161
152
  href="${item.href || "#"}"
162
153
  data-index="${index}"
163
154
  >${escapedLabel}</a>
164
- <span class="breadcrumbs-separator" part="separator" aria-hidden="true">${separatorHtml}</span>
155
+ <span class="breadcrumb-separator" part="separator" aria-hidden="true">${separatorHtml}</span>
165
156
  </li>
166
157
  `;
167
158
  }).join("");
168
159
  return `
169
160
  <nav class="breadcrumbs-nav" part="nav" aria-label="Breadcrumb">
170
- <ol class="breadcrumbs-list" part="list">
161
+ <ol class="breadcrumbs" part="list">
171
162
  ${itemsHtml}
172
163
  </ol>
173
164
  <slot name="separator"></slot>
@@ -176,7 +167,7 @@ class ElDmBreadcrumbs extends import_el_core.BaseElement {
176
167
  }
177
168
  update() {
178
169
  super.update();
179
- const links = this.shadowRoot?.querySelectorAll(".breadcrumbs-link");
170
+ const links = this.shadowRoot?.querySelectorAll(".breadcrumb-link");
180
171
  links?.forEach((link) => {
181
172
  const index = parseInt(link.getAttribute("data-index") || "0", 10);
182
173
  const item = this.items[index];
@@ -194,5 +185,5 @@ function register() {
194
185
  }
195
186
  }
196
187
 
197
- //# debugId=16C0709E0DAF4F8164756E2164756E21
188
+ //# debugId=DB27F479BECF9AF464756E2164756E21
198
189
  //# sourceMappingURL=index.js.map
@@ -2,10 +2,10 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/el-dm-breadcrumbs.ts", "../../src/index.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * DuskMoon Breadcrumbs Element\n *\n * A hierarchical navigation breadcrumbs component for displaying the user's\n * current location within a site structure.\n *\n * @element el-dm-breadcrumbs\n *\n * @attr {string} items - JSON array of breadcrumb items [{label, href}]\n * @attr {string} separator - Separator character between items (default '/')\n *\n * @slot separator - Custom separator element to use between items\n *\n * @csspart nav - The navigation container\n * @csspart list - The ordered list element\n * @csspart item - Individual breadcrumb item container\n * @csspart link - Breadcrumb link element\n * @csspart current - Current page text (last item)\n * @csspart separator - Separator element between items\n *\n * @fires navigate - Fired when a breadcrumb link is clicked. Detail: { item, index }\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-core';\n\n/**\n * Represents a single breadcrumb item\n */\nexport interface BreadcrumbItem {\n /** Display label for the breadcrumb */\n label: string;\n /** URL for the breadcrumb link (optional for last item) */\n href?: string;\n}\n\n/**\n * Event detail for the navigate event\n */\nexport interface NavigateEventDetail {\n /** The breadcrumb item that was clicked */\n item: BreadcrumbItem;\n /** The index of the clicked item */\n index: number;\n}\n\nconst styles = css`\n :host {\n display: block;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n .breadcrumbs-nav {\n font-family: inherit;\n }\n\n .breadcrumbs-list {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0.5rem;\n list-style: none;\n margin: 0;\n padding: 0;\n }\n\n .breadcrumbs-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n }\n\n .breadcrumbs-link {\n color: var(--color-primary);\n text-decoration: none;\n font-size: 0.875rem;\n line-height: 1.25rem;\n transition: color 150ms ease;\n cursor: pointer;\n }\n\n .breadcrumbs-link:hover {\n color: var(--color-primary-dark, var(--color-primary));\n text-decoration: underline;\n }\n\n .breadcrumbs-link:focus {\n outline: 2px solid var(--color-primary);\n outline-offset: 2px;\n border-radius: 2px;\n }\n\n .breadcrumbs-current {\n color: var(--color-on-surface);\n font-size: 0.875rem;\n line-height: 1.25rem;\n font-weight: 500;\n }\n\n .breadcrumbs-separator {\n color: var(--color-on-surface-variant, var(--color-outline));\n font-size: 0.875rem;\n user-select: none;\n }\n\n /* Hide slotted separator template */\n ::slotted([slot='separator']) {\n display: none;\n }\n`;\n\nexport class ElDmBreadcrumbs extends BaseElement {\n static properties = {\n items: { type: Array, reflect: false },\n separator: { type: String, reflect: true, default: '/' },\n };\n\n /** Array of breadcrumb items */\n declare items: BreadcrumbItem[];\n\n /** Separator character between items */\n declare separator: string;\n\n constructor() {\n super();\n this.attachStyles(styles);\n this.items = [];\n }\n\n /**\n * Handle click on a breadcrumb link\n */\n private _handleClick(event: Event, item: BreadcrumbItem, index: number): void {\n event.preventDefault();\n\n // emit returns true if event was not cancelled\n const notCancelled = this.emit<NavigateEventDetail>('navigate', {\n item,\n index,\n });\n\n // If event was not prevented, navigate to the href\n if (notCancelled && item.href) {\n window.location.href = item.href;\n }\n }\n\n /**\n * Get the separator HTML - either from slot or default\n */\n private _getSeparatorHtml(): string {\n const slottedSeparator = this.querySelector('[slot=\"separator\"]');\n if (slottedSeparator) {\n return slottedSeparator.outerHTML.replace('slot=\"separator\"', '');\n }\n return this.separator || '/';\n }\n\n /**\n * Escape HTML special characters to prevent XSS\n */\n private _escapeHtml(text: string): string {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n }\n\n render(): string {\n const itemsArray = Array.isArray(this.items) ? this.items : [];\n const separatorHtml = this._getSeparatorHtml();\n\n const itemsHtml = itemsArray\n .map((item, index) => {\n const isLast = index === itemsArray.length - 1;\n const escapedLabel = this._escapeHtml(item.label);\n\n if (isLast) {\n // Last item is current page - not clickable\n return `\n <li class=\"breadcrumbs-item\" part=\"item\">\n <span\n class=\"breadcrumbs-current\"\n part=\"current\"\n aria-current=\"page\"\n >${escapedLabel}</span>\n </li>\n `;\n }\n\n // Regular breadcrumb link\n return `\n <li class=\"breadcrumbs-item\" part=\"item\">\n <a\n class=\"breadcrumbs-link\"\n part=\"link\"\n href=\"${item.href || '#'}\"\n data-index=\"${index}\"\n >${escapedLabel}</a>\n <span class=\"breadcrumbs-separator\" part=\"separator\" aria-hidden=\"true\">${separatorHtml}</span>\n </li>\n `;\n })\n .join('');\n\n return `\n <nav class=\"breadcrumbs-nav\" part=\"nav\" aria-label=\"Breadcrumb\">\n <ol class=\"breadcrumbs-list\" part=\"list\">\n ${itemsHtml}\n </ol>\n <slot name=\"separator\"></slot>\n </nav>\n `;\n }\n\n update(): void {\n super.update();\n\n // Attach click handlers to all breadcrumb links\n const links = this.shadowRoot?.querySelectorAll('.breadcrumbs-link');\n links?.forEach((link) => {\n const index = parseInt(link.getAttribute('data-index') || '0', 10);\n const item = this.items[index];\n if (item) {\n link.addEventListener('click', (e) => this._handleClick(e, item, index));\n }\n });\n }\n}\n",
5
+ "/**\n * DuskMoon Breadcrumbs Element\n *\n * A hierarchical navigation breadcrumbs component for displaying the user's\n * current location within a site structure.\n *\n * @element el-dm-breadcrumbs\n *\n * @attr {string} items - JSON array of breadcrumb items [{label, href}]\n * @attr {string} separator - Separator character between items (default '/')\n *\n * @slot separator - Custom separator element to use between items\n *\n * @csspart nav - The navigation container\n * @csspart list - The ordered list element\n * @csspart item - Individual breadcrumb item container\n * @csspart link - Breadcrumb link element\n * @csspart current - Current page text (last item)\n * @csspart separator - Separator element between items\n *\n * @fires navigate - Fired when a breadcrumb link is clicked. Detail: { item, index }\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-base';\nimport { css as navigationCSS } from '@duskmoon-dev/core/components/navigation';\n\n/**\n * Represents a single breadcrumb item\n */\nexport interface BreadcrumbItem {\n /** Display label for the breadcrumb */\n label: string;\n /** URL for the breadcrumb link (optional for last item) */\n href?: string;\n}\n\n/**\n * Event detail for the navigate event\n */\nexport interface NavigateEventDetail {\n /** The breadcrumb item that was clicked */\n item: BreadcrumbItem;\n /** The index of the clicked item */\n index: number;\n}\n\n// Strip @layer wrapper for Shadow DOM compatibility\nconst coreStyles = navigationCSS.replace(/@layer\\s+components\\s*\\{/, '').replace(/\\}\\s*$/, '');\n\nconst styles = css`\n :host {\n display: block;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n /* Import core navigation styles */\n ${coreStyles}\n\n .breadcrumbs-nav {\n font-family: inherit;\n }\n\n /* Override core .breadcrumbs padding since we manage our own layout */\n .breadcrumbs {\n padding: 0;\n }\n\n /* Override core .breadcrumb-link with our custom colors */\n .breadcrumb-link {\n color: var(--color-primary);\n }\n\n .breadcrumb-link:hover {\n color: var(--color-primary-dark, var(--color-primary));\n }\n\n .breadcrumb-link:focus {\n outline: 2px solid var(--color-primary);\n outline-offset: 2px;\n border-radius: 2px;\n }\n\n .breadcrumb-item-active {\n color: var(--color-on-surface);\n font-size: 0.875rem;\n line-height: 1.25rem;\n }\n\n /* Hide core's separator ::before — we render separator text explicitly */\n .breadcrumb-separator::before {\n display: none;\n }\n\n .breadcrumb-separator {\n opacity: 1;\n }\n\n /* Hide slotted separator template */\n ::slotted([slot='separator']) {\n display: none;\n }\n`;\n\nexport class ElDmBreadcrumbs extends BaseElement {\n static properties = {\n items: { type: Array, reflect: false },\n separator: { type: String, reflect: true, default: '/' },\n };\n\n /** Array of breadcrumb items */\n declare items: BreadcrumbItem[];\n\n /** Separator character between items */\n declare separator: string;\n\n constructor() {\n super();\n this.attachStyles(styles);\n this.items = [];\n }\n\n /**\n * Handle click on a breadcrumb link\n */\n private _handleClick(event: Event, item: BreadcrumbItem, index: number): void {\n event.preventDefault();\n\n // emit returns true if event was not cancelled\n const notCancelled = this.emit<NavigateEventDetail>('navigate', {\n item,\n index,\n });\n\n // If event was not prevented, navigate to the href\n if (notCancelled && item.href) {\n window.location.href = item.href;\n }\n }\n\n /**\n * Get the separator HTML - either from slot or default\n */\n private _getSeparatorHtml(): string {\n const slottedSeparator = this.querySelector('[slot=\"separator\"]');\n if (slottedSeparator) {\n return slottedSeparator.outerHTML.replace('slot=\"separator\"', '');\n }\n return this.separator || '/';\n }\n\n /**\n * Escape HTML special characters to prevent XSS\n */\n private _escapeHtml(text: string): string {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n }\n\n render(): string {\n const itemsArray = Array.isArray(this.items) ? this.items : [];\n const separatorHtml = this._getSeparatorHtml();\n\n const itemsHtml = itemsArray\n .map((item, index) => {\n const isLast = index === itemsArray.length - 1;\n const escapedLabel = this._escapeHtml(item.label);\n\n if (isLast) {\n // Last item is current page - not clickable\n return `\n <li class=\"breadcrumb-item\" part=\"item\">\n <span\n class=\"breadcrumb-item-active\"\n part=\"current\"\n aria-current=\"page\"\n >${escapedLabel}</span>\n </li>\n `;\n }\n\n // Regular breadcrumb link\n return `\n <li class=\"breadcrumb-item\" part=\"item\">\n <a\n class=\"breadcrumb-link\"\n part=\"link\"\n href=\"${item.href || '#'}\"\n data-index=\"${index}\"\n >${escapedLabel}</a>\n <span class=\"breadcrumb-separator\" part=\"separator\" aria-hidden=\"true\">${separatorHtml}</span>\n </li>\n `;\n })\n .join('');\n\n return `\n <nav class=\"breadcrumbs-nav\" part=\"nav\" aria-label=\"Breadcrumb\">\n <ol class=\"breadcrumbs\" part=\"list\">\n ${itemsHtml}\n </ol>\n <slot name=\"separator\"></slot>\n </nav>\n `;\n }\n\n update(): void {\n super.update();\n\n // Attach click handlers to all breadcrumb links\n const links = this.shadowRoot?.querySelectorAll('.breadcrumb-link');\n links?.forEach((link) => {\n const index = parseInt(link.getAttribute('data-index') || '0', 10);\n const item = this.items[index];\n if (item) {\n link.addEventListener('click', (e) => this._handleClick(e, item, index));\n }\n });\n }\n}\n",
6
6
  "/**\n * @duskmoon-dev/el-breadcrumbs\n *\n * DuskMoon Breadcrumbs custom element\n */\n\nimport { ElDmBreadcrumbs } from './el-dm-breadcrumbs.js';\n\nexport { ElDmBreadcrumbs };\nexport type { BreadcrumbItem, NavigateEventDetail } from './el-dm-breadcrumbs.js';\n\n/**\n * Register the el-dm-breadcrumbs custom element\n *\n * @example\n * ```ts\n * import { register } from '@duskmoon-dev/el-breadcrumbs';\n * register();\n * ```\n */\nexport function register(): void {\n if (!customElements.get('el-dm-breadcrumbs')) {\n customElements.define('el-dm-breadcrumbs', ElDmBreadcrumbs);\n }\n}\n"
7
7
  ],
8
- "mappings": "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",
9
- "debugId": "16C0709E0DAF4F8164756E2164756E21",
8
+ "mappings": "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",
9
+ "debugId": "DB27F479BECF9AF464756E2164756E21",
10
10
  "names": []
11
11
  }
@@ -35,8 +35,10 @@ __export(exports_src, {
35
35
  module.exports = __toCommonJS(exports_src);
36
36
 
37
37
  // src/el-dm-breadcrumbs.ts
38
- var import_el_core = require("@duskmoon-dev/el-core");
39
- var styles = import_el_core.css`
38
+ var import_el_base = require("@duskmoon-dev/el-base");
39
+ var import_navigation = require("@duskmoon-dev/core/components/navigation");
40
+ var coreStyles = import_navigation.css.replace(/@layer\s+components\s*\{/, "").replace(/\}\s*$/, "");
41
+ var styles = import_el_base.css`
40
42
  :host {
41
43
  display: block;
42
44
  }
@@ -45,57 +47,46 @@ var styles = import_el_core.css`
45
47
  display: none !important;
46
48
  }
47
49
 
50
+ /* Import core navigation styles */
51
+ ${coreStyles}
52
+
48
53
  .breadcrumbs-nav {
49
54
  font-family: inherit;
50
55
  }
51
56
 
52
- .breadcrumbs-list {
53
- display: flex;
54
- flex-wrap: wrap;
55
- align-items: center;
56
- gap: 0.5rem;
57
- list-style: none;
58
- margin: 0;
57
+ /* Override core .breadcrumbs padding since we manage our own layout */
58
+ .breadcrumbs {
59
59
  padding: 0;
60
60
  }
61
61
 
62
- .breadcrumbs-item {
63
- display: flex;
64
- align-items: center;
65
- gap: 0.5rem;
66
- }
67
-
68
- .breadcrumbs-link {
62
+ /* Override core .breadcrumb-link with our custom colors */
63
+ .breadcrumb-link {
69
64
  color: var(--color-primary);
70
- text-decoration: none;
71
- font-size: 0.875rem;
72
- line-height: 1.25rem;
73
- transition: color 150ms ease;
74
- cursor: pointer;
75
65
  }
76
66
 
77
- .breadcrumbs-link:hover {
67
+ .breadcrumb-link:hover {
78
68
  color: var(--color-primary-dark, var(--color-primary));
79
- text-decoration: underline;
80
69
  }
81
70
 
82
- .breadcrumbs-link:focus {
71
+ .breadcrumb-link:focus {
83
72
  outline: 2px solid var(--color-primary);
84
73
  outline-offset: 2px;
85
74
  border-radius: 2px;
86
75
  }
87
76
 
88
- .breadcrumbs-current {
77
+ .breadcrumb-item-active {
89
78
  color: var(--color-on-surface);
90
79
  font-size: 0.875rem;
91
80
  line-height: 1.25rem;
92
- font-weight: 500;
93
81
  }
94
82
 
95
- .breadcrumbs-separator {
96
- color: var(--color-on-surface-variant, var(--color-outline));
97
- font-size: 0.875rem;
98
- user-select: none;
83
+ /* Hide core's separator ::before — we render separator text explicitly */
84
+ .breadcrumb-separator::before {
85
+ display: none;
86
+ }
87
+
88
+ .breadcrumb-separator {
89
+ opacity: 1;
99
90
  }
100
91
 
101
92
  /* Hide slotted separator template */
@@ -104,7 +95,7 @@ var styles = import_el_core.css`
104
95
  }
105
96
  `;
106
97
 
107
- class ElDmBreadcrumbs extends import_el_core.BaseElement {
98
+ class ElDmBreadcrumbs extends import_el_base.BaseElement {
108
99
  static properties = {
109
100
  items: { type: Array, reflect: false },
110
101
  separator: { type: String, reflect: true, default: "/" }
@@ -144,9 +135,9 @@ class ElDmBreadcrumbs extends import_el_core.BaseElement {
144
135
  const escapedLabel = this._escapeHtml(item.label);
145
136
  if (isLast) {
146
137
  return `
147
- <li class="breadcrumbs-item" part="item">
138
+ <li class="breadcrumb-item" part="item">
148
139
  <span
149
- class="breadcrumbs-current"
140
+ class="breadcrumb-item-active"
150
141
  part="current"
151
142
  aria-current="page"
152
143
  >${escapedLabel}</span>
@@ -154,20 +145,20 @@ class ElDmBreadcrumbs extends import_el_core.BaseElement {
154
145
  `;
155
146
  }
156
147
  return `
157
- <li class="breadcrumbs-item" part="item">
148
+ <li class="breadcrumb-item" part="item">
158
149
  <a
159
- class="breadcrumbs-link"
150
+ class="breadcrumb-link"
160
151
  part="link"
161
152
  href="${item.href || "#"}"
162
153
  data-index="${index}"
163
154
  >${escapedLabel}</a>
164
- <span class="breadcrumbs-separator" part="separator" aria-hidden="true">${separatorHtml}</span>
155
+ <span class="breadcrumb-separator" part="separator" aria-hidden="true">${separatorHtml}</span>
165
156
  </li>
166
157
  `;
167
158
  }).join("");
168
159
  return `
169
160
  <nav class="breadcrumbs-nav" part="nav" aria-label="Breadcrumb">
170
- <ol class="breadcrumbs-list" part="list">
161
+ <ol class="breadcrumbs" part="list">
171
162
  ${itemsHtml}
172
163
  </ol>
173
164
  <slot name="separator"></slot>
@@ -176,7 +167,7 @@ class ElDmBreadcrumbs extends import_el_core.BaseElement {
176
167
  }
177
168
  update() {
178
169
  super.update();
179
- const links = this.shadowRoot?.querySelectorAll(".breadcrumbs-link");
170
+ const links = this.shadowRoot?.querySelectorAll(".breadcrumb-link");
180
171
  links?.forEach((link) => {
181
172
  const index = parseInt(link.getAttribute("data-index") || "0", 10);
182
173
  const item = this.items[index];
@@ -197,5 +188,5 @@ function register() {
197
188
  // src/register.ts
198
189
  register();
199
190
 
200
- //# debugId=AA0E432E4F1405F164756E2164756E21
191
+ //# debugId=27B6D4A52BE6D82264756E2164756E21
201
192
  //# sourceMappingURL=register.js.map
@@ -2,11 +2,11 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/el-dm-breadcrumbs.ts", "../../src/index.ts", "../../src/register.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * DuskMoon Breadcrumbs Element\n *\n * A hierarchical navigation breadcrumbs component for displaying the user's\n * current location within a site structure.\n *\n * @element el-dm-breadcrumbs\n *\n * @attr {string} items - JSON array of breadcrumb items [{label, href}]\n * @attr {string} separator - Separator character between items (default '/')\n *\n * @slot separator - Custom separator element to use between items\n *\n * @csspart nav - The navigation container\n * @csspart list - The ordered list element\n * @csspart item - Individual breadcrumb item container\n * @csspart link - Breadcrumb link element\n * @csspart current - Current page text (last item)\n * @csspart separator - Separator element between items\n *\n * @fires navigate - Fired when a breadcrumb link is clicked. Detail: { item, index }\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-core';\n\n/**\n * Represents a single breadcrumb item\n */\nexport interface BreadcrumbItem {\n /** Display label for the breadcrumb */\n label: string;\n /** URL for the breadcrumb link (optional for last item) */\n href?: string;\n}\n\n/**\n * Event detail for the navigate event\n */\nexport interface NavigateEventDetail {\n /** The breadcrumb item that was clicked */\n item: BreadcrumbItem;\n /** The index of the clicked item */\n index: number;\n}\n\nconst styles = css`\n :host {\n display: block;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n .breadcrumbs-nav {\n font-family: inherit;\n }\n\n .breadcrumbs-list {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0.5rem;\n list-style: none;\n margin: 0;\n padding: 0;\n }\n\n .breadcrumbs-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n }\n\n .breadcrumbs-link {\n color: var(--color-primary);\n text-decoration: none;\n font-size: 0.875rem;\n line-height: 1.25rem;\n transition: color 150ms ease;\n cursor: pointer;\n }\n\n .breadcrumbs-link:hover {\n color: var(--color-primary-dark, var(--color-primary));\n text-decoration: underline;\n }\n\n .breadcrumbs-link:focus {\n outline: 2px solid var(--color-primary);\n outline-offset: 2px;\n border-radius: 2px;\n }\n\n .breadcrumbs-current {\n color: var(--color-on-surface);\n font-size: 0.875rem;\n line-height: 1.25rem;\n font-weight: 500;\n }\n\n .breadcrumbs-separator {\n color: var(--color-on-surface-variant, var(--color-outline));\n font-size: 0.875rem;\n user-select: none;\n }\n\n /* Hide slotted separator template */\n ::slotted([slot='separator']) {\n display: none;\n }\n`;\n\nexport class ElDmBreadcrumbs extends BaseElement {\n static properties = {\n items: { type: Array, reflect: false },\n separator: { type: String, reflect: true, default: '/' },\n };\n\n /** Array of breadcrumb items */\n declare items: BreadcrumbItem[];\n\n /** Separator character between items */\n declare separator: string;\n\n constructor() {\n super();\n this.attachStyles(styles);\n this.items = [];\n }\n\n /**\n * Handle click on a breadcrumb link\n */\n private _handleClick(event: Event, item: BreadcrumbItem, index: number): void {\n event.preventDefault();\n\n // emit returns true if event was not cancelled\n const notCancelled = this.emit<NavigateEventDetail>('navigate', {\n item,\n index,\n });\n\n // If event was not prevented, navigate to the href\n if (notCancelled && item.href) {\n window.location.href = item.href;\n }\n }\n\n /**\n * Get the separator HTML - either from slot or default\n */\n private _getSeparatorHtml(): string {\n const slottedSeparator = this.querySelector('[slot=\"separator\"]');\n if (slottedSeparator) {\n return slottedSeparator.outerHTML.replace('slot=\"separator\"', '');\n }\n return this.separator || '/';\n }\n\n /**\n * Escape HTML special characters to prevent XSS\n */\n private _escapeHtml(text: string): string {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n }\n\n render(): string {\n const itemsArray = Array.isArray(this.items) ? this.items : [];\n const separatorHtml = this._getSeparatorHtml();\n\n const itemsHtml = itemsArray\n .map((item, index) => {\n const isLast = index === itemsArray.length - 1;\n const escapedLabel = this._escapeHtml(item.label);\n\n if (isLast) {\n // Last item is current page - not clickable\n return `\n <li class=\"breadcrumbs-item\" part=\"item\">\n <span\n class=\"breadcrumbs-current\"\n part=\"current\"\n aria-current=\"page\"\n >${escapedLabel}</span>\n </li>\n `;\n }\n\n // Regular breadcrumb link\n return `\n <li class=\"breadcrumbs-item\" part=\"item\">\n <a\n class=\"breadcrumbs-link\"\n part=\"link\"\n href=\"${item.href || '#'}\"\n data-index=\"${index}\"\n >${escapedLabel}</a>\n <span class=\"breadcrumbs-separator\" part=\"separator\" aria-hidden=\"true\">${separatorHtml}</span>\n </li>\n `;\n })\n .join('');\n\n return `\n <nav class=\"breadcrumbs-nav\" part=\"nav\" aria-label=\"Breadcrumb\">\n <ol class=\"breadcrumbs-list\" part=\"list\">\n ${itemsHtml}\n </ol>\n <slot name=\"separator\"></slot>\n </nav>\n `;\n }\n\n update(): void {\n super.update();\n\n // Attach click handlers to all breadcrumb links\n const links = this.shadowRoot?.querySelectorAll('.breadcrumbs-link');\n links?.forEach((link) => {\n const index = parseInt(link.getAttribute('data-index') || '0', 10);\n const item = this.items[index];\n if (item) {\n link.addEventListener('click', (e) => this._handleClick(e, item, index));\n }\n });\n }\n}\n",
5
+ "/**\n * DuskMoon Breadcrumbs Element\n *\n * A hierarchical navigation breadcrumbs component for displaying the user's\n * current location within a site structure.\n *\n * @element el-dm-breadcrumbs\n *\n * @attr {string} items - JSON array of breadcrumb items [{label, href}]\n * @attr {string} separator - Separator character between items (default '/')\n *\n * @slot separator - Custom separator element to use between items\n *\n * @csspart nav - The navigation container\n * @csspart list - The ordered list element\n * @csspart item - Individual breadcrumb item container\n * @csspart link - Breadcrumb link element\n * @csspart current - Current page text (last item)\n * @csspart separator - Separator element between items\n *\n * @fires navigate - Fired when a breadcrumb link is clicked. Detail: { item, index }\n */\n\nimport { BaseElement, css } from '@duskmoon-dev/el-base';\nimport { css as navigationCSS } from '@duskmoon-dev/core/components/navigation';\n\n/**\n * Represents a single breadcrumb item\n */\nexport interface BreadcrumbItem {\n /** Display label for the breadcrumb */\n label: string;\n /** URL for the breadcrumb link (optional for last item) */\n href?: string;\n}\n\n/**\n * Event detail for the navigate event\n */\nexport interface NavigateEventDetail {\n /** The breadcrumb item that was clicked */\n item: BreadcrumbItem;\n /** The index of the clicked item */\n index: number;\n}\n\n// Strip @layer wrapper for Shadow DOM compatibility\nconst coreStyles = navigationCSS.replace(/@layer\\s+components\\s*\\{/, '').replace(/\\}\\s*$/, '');\n\nconst styles = css`\n :host {\n display: block;\n }\n\n :host([hidden]) {\n display: none !important;\n }\n\n /* Import core navigation styles */\n ${coreStyles}\n\n .breadcrumbs-nav {\n font-family: inherit;\n }\n\n /* Override core .breadcrumbs padding since we manage our own layout */\n .breadcrumbs {\n padding: 0;\n }\n\n /* Override core .breadcrumb-link with our custom colors */\n .breadcrumb-link {\n color: var(--color-primary);\n }\n\n .breadcrumb-link:hover {\n color: var(--color-primary-dark, var(--color-primary));\n }\n\n .breadcrumb-link:focus {\n outline: 2px solid var(--color-primary);\n outline-offset: 2px;\n border-radius: 2px;\n }\n\n .breadcrumb-item-active {\n color: var(--color-on-surface);\n font-size: 0.875rem;\n line-height: 1.25rem;\n }\n\n /* Hide core's separator ::before — we render separator text explicitly */\n .breadcrumb-separator::before {\n display: none;\n }\n\n .breadcrumb-separator {\n opacity: 1;\n }\n\n /* Hide slotted separator template */\n ::slotted([slot='separator']) {\n display: none;\n }\n`;\n\nexport class ElDmBreadcrumbs extends BaseElement {\n static properties = {\n items: { type: Array, reflect: false },\n separator: { type: String, reflect: true, default: '/' },\n };\n\n /** Array of breadcrumb items */\n declare items: BreadcrumbItem[];\n\n /** Separator character between items */\n declare separator: string;\n\n constructor() {\n super();\n this.attachStyles(styles);\n this.items = [];\n }\n\n /**\n * Handle click on a breadcrumb link\n */\n private _handleClick(event: Event, item: BreadcrumbItem, index: number): void {\n event.preventDefault();\n\n // emit returns true if event was not cancelled\n const notCancelled = this.emit<NavigateEventDetail>('navigate', {\n item,\n index,\n });\n\n // If event was not prevented, navigate to the href\n if (notCancelled && item.href) {\n window.location.href = item.href;\n }\n }\n\n /**\n * Get the separator HTML - either from slot or default\n */\n private _getSeparatorHtml(): string {\n const slottedSeparator = this.querySelector('[slot=\"separator\"]');\n if (slottedSeparator) {\n return slottedSeparator.outerHTML.replace('slot=\"separator\"', '');\n }\n return this.separator || '/';\n }\n\n /**\n * Escape HTML special characters to prevent XSS\n */\n private _escapeHtml(text: string): string {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n }\n\n render(): string {\n const itemsArray = Array.isArray(this.items) ? this.items : [];\n const separatorHtml = this._getSeparatorHtml();\n\n const itemsHtml = itemsArray\n .map((item, index) => {\n const isLast = index === itemsArray.length - 1;\n const escapedLabel = this._escapeHtml(item.label);\n\n if (isLast) {\n // Last item is current page - not clickable\n return `\n <li class=\"breadcrumb-item\" part=\"item\">\n <span\n class=\"breadcrumb-item-active\"\n part=\"current\"\n aria-current=\"page\"\n >${escapedLabel}</span>\n </li>\n `;\n }\n\n // Regular breadcrumb link\n return `\n <li class=\"breadcrumb-item\" part=\"item\">\n <a\n class=\"breadcrumb-link\"\n part=\"link\"\n href=\"${item.href || '#'}\"\n data-index=\"${index}\"\n >${escapedLabel}</a>\n <span class=\"breadcrumb-separator\" part=\"separator\" aria-hidden=\"true\">${separatorHtml}</span>\n </li>\n `;\n })\n .join('');\n\n return `\n <nav class=\"breadcrumbs-nav\" part=\"nav\" aria-label=\"Breadcrumb\">\n <ol class=\"breadcrumbs\" part=\"list\">\n ${itemsHtml}\n </ol>\n <slot name=\"separator\"></slot>\n </nav>\n `;\n }\n\n update(): void {\n super.update();\n\n // Attach click handlers to all breadcrumb links\n const links = this.shadowRoot?.querySelectorAll('.breadcrumb-link');\n links?.forEach((link) => {\n const index = parseInt(link.getAttribute('data-index') || '0', 10);\n const item = this.items[index];\n if (item) {\n link.addEventListener('click', (e) => this._handleClick(e, item, index));\n }\n });\n }\n}\n",
6
6
  "/**\n * @duskmoon-dev/el-breadcrumbs\n *\n * DuskMoon Breadcrumbs custom element\n */\n\nimport { ElDmBreadcrumbs } from './el-dm-breadcrumbs.js';\n\nexport { ElDmBreadcrumbs };\nexport type { BreadcrumbItem, NavigateEventDetail } from './el-dm-breadcrumbs.js';\n\n/**\n * Register the el-dm-breadcrumbs custom element\n *\n * @example\n * ```ts\n * import { register } from '@duskmoon-dev/el-breadcrumbs';\n * register();\n * ```\n */\nexport function register(): void {\n if (!customElements.get('el-dm-breadcrumbs')) {\n customElements.define('el-dm-breadcrumbs', ElDmBreadcrumbs);\n }\n}\n",
7
7
  "/**\n * Auto-register el-dm-breadcrumbs custom element\n *\n * @example\n * ```ts\n * import '@duskmoon-dev/el-breadcrumbs/register';\n *\n * // Now you can use <el-dm-breadcrumbs> in HTML\n * ```\n */\nimport { register } from './index.js';\n\nregister();\n"
8
8
  ],
9
- "mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuBiC,IAAjC;AAsBA,IAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoER,MAAM,wBAAwB,2BAAY;AAAA,SACxC,aAAa;AAAA,IAClB,OAAO,EAAE,MAAM,OAAO,SAAS,MAAM;AAAA,IACrC,WAAW,EAAE,MAAM,QAAQ,SAAS,MAAM,SAAS,IAAI;AAAA,EACzD;AAAA,EAQA,WAAW,GAAG;AAAA,IACZ,MAAM;AAAA,IACN,KAAK,aAAa,MAAM;AAAA,IACxB,KAAK,QAAQ,CAAC;AAAA;AAAA,EAMR,YAAY,CAAC,OAAc,MAAsB,OAAqB;AAAA,IAC5E,MAAM,eAAe;AAAA,IAGrB,MAAM,eAAe,KAAK,KAA0B,YAAY;AAAA,MAC9D;AAAA,MACA;AAAA,IACF,CAAC;AAAA,IAGD,IAAI,gBAAgB,KAAK,MAAM;AAAA,MAC7B,OAAO,SAAS,OAAO,KAAK;AAAA,IAC9B;AAAA;AAAA,EAMM,iBAAiB,GAAW;AAAA,IAClC,MAAM,mBAAmB,KAAK,cAAc,oBAAoB;AAAA,IAChE,IAAI,kBAAkB;AAAA,MACpB,OAAO,iBAAiB,UAAU,QAAQ,oBAAoB,EAAE;AAAA,IAClE;AAAA,IACA,OAAO,KAAK,aAAa;AAAA;AAAA,EAMnB,WAAW,CAAC,MAAsB;AAAA,IACxC,MAAM,MAAM,SAAS,cAAc,KAAK;AAAA,IACxC,IAAI,cAAc;AAAA,IAClB,OAAO,IAAI;AAAA;AAAA,EAGb,MAAM,GAAW;AAAA,IACf,MAAM,aAAa,MAAM,QAAQ,KAAK,KAAK,IAAI,KAAK,QAAQ,CAAC;AAAA,IAC7D,MAAM,gBAAgB,KAAK,kBAAkB;AAAA,IAE7C,MAAM,YAAY,WACf,IAAI,CAAC,MAAM,UAAU;AAAA,MACpB,MAAM,SAAS,UAAU,WAAW,SAAS;AAAA,MAC7C,MAAM,eAAe,KAAK,YAAY,KAAK,KAAK;AAAA,MAEhD,IAAI,QAAQ;AAAA,QAEV,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAMA;AAAA;AAAA;AAAA,MAGT;AAAA,MAGA,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,sBAKO,KAAK,QAAQ;AAAA,4BACP;AAAA,eACb;AAAA,sFACuE;AAAA;AAAA;AAAA,KAG/E,EACA,KAAK,EAAE;AAAA,IAEV,OAAO;AAAA;AAAA;AAAA,YAGC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOV,MAAM,GAAS;AAAA,IACb,MAAM,OAAO;AAAA,IAGb,MAAM,QAAQ,KAAK,YAAY,iBAAiB,mBAAmB;AAAA,IACnE,OAAO,QAAQ,CAAC,SAAS;AAAA,MACvB,MAAM,QAAQ,SAAS,KAAK,aAAa,YAAY,KAAK,KAAK,EAAE;AAAA,MACjE,MAAM,OAAO,KAAK,MAAM;AAAA,MACxB,IAAI,MAAM;AAAA,QACR,KAAK,iBAAiB,SAAS,CAAC,MAAM,KAAK,aAAa,GAAG,MAAM,KAAK,CAAC;AAAA,MACzE;AAAA,KACD;AAAA;AAEL;;;ACjNO,SAAS,QAAQ,GAAS;AAAA,EAC/B,IAAI,CAAC,eAAe,IAAI,mBAAmB,GAAG;AAAA,IAC5C,eAAe,OAAO,qBAAqB,eAAe;AAAA,EAC5D;AAAA;;;ACXF,SAAS;",
10
- "debugId": "AA0E432E4F1405F164756E2164756E21",
9
+ "mappings": "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",
10
+ "debugId": "27B6D4A52BE6D82264756E2164756E21",
11
11
  "names": []
12
12
  }