wj-elements 0.5.1 → 0.5.2
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/dist/packages/wje-breadcrumb/breadcrumb.element.d.ts +145 -1
- package/dist/packages/wje-breadcrumbs/breadcrumbs.element.d.ts +15 -1
- package/dist/packages/wje-toolbar-action/toolbar-action.element.d.ts +6 -0
- package/dist/wje-breadcrumb.js +336 -37
- package/dist/wje-breadcrumb.js.map +1 -1
- package/dist/wje-breadcrumbs.js +41 -3
- package/dist/wje-breadcrumbs.js.map +1 -1
- package/dist/wje-toolbar-action.js +22 -1
- package/dist/wje-toolbar-action.js.map +1 -1
- package/package.json +1 -1
|
@@ -77,6 +77,11 @@ export default class Breadcrumb extends WJElement {
|
|
|
77
77
|
*/
|
|
78
78
|
get collapsedVariant(): string;
|
|
79
79
|
_collapsedVariant: string;
|
|
80
|
+
/**
|
|
81
|
+
* Get collapsed variant token.
|
|
82
|
+
* @returns {string}
|
|
83
|
+
*/
|
|
84
|
+
get collapsedVariantName(): string;
|
|
80
85
|
/**
|
|
81
86
|
* Handles attribute changes for the custom element and updates its behavior or appearance accordingly.
|
|
82
87
|
* @param {string} name The name of the attribute that was changed.
|
|
@@ -124,10 +129,15 @@ export default class Breadcrumb extends WJElement {
|
|
|
124
129
|
/**
|
|
125
130
|
* Renders the collapsed indicator based on the current collapsed variant.
|
|
126
131
|
* If the collapsed variant is 'DROPDOWN', it invokes the collapseDropdown method.
|
|
127
|
-
*
|
|
132
|
+
* Mobile breakpoint variants render compact breadcrumb summaries, otherwise the default button is used.
|
|
128
133
|
* @returns {any} The rendered collapsed indicator, either as a dropdown or a button.
|
|
129
134
|
*/
|
|
130
135
|
drawCollapsedIndicator(): any;
|
|
136
|
+
/**
|
|
137
|
+
* Returns whether the current collapsed variant is a compact mobile layout.
|
|
138
|
+
* @returns {boolean}
|
|
139
|
+
*/
|
|
140
|
+
isMobileCollapsedVariant(): boolean;
|
|
131
141
|
/**
|
|
132
142
|
* Creates and returns a dropdown UI component for collapsed breadcrumbs.
|
|
133
143
|
* This method generates a dropdown element with a button trigger and a menu populated with items corresponding
|
|
@@ -137,6 +147,134 @@ export default class Breadcrumb extends WJElement {
|
|
|
137
147
|
* @returns {HTMLElement} A configured dropdown element containing a button as trigger and a menu with breadcrumb items.
|
|
138
148
|
*/
|
|
139
149
|
collapseDropdown(): HTMLElement;
|
|
150
|
+
/**
|
|
151
|
+
* Creates a dropdown containing breadcrumb menu items.
|
|
152
|
+
* @param {object} options Configuration for the dropdown shell.
|
|
153
|
+
* @param {Array<HTMLElement>} options.breadcrumbs Breadcrumb elements to mirror in the menu.
|
|
154
|
+
* @param {HTMLElement} options.trigger Element assigned to the dropdown trigger slot.
|
|
155
|
+
* @param {string} options.placement Floating UI placement token for the popup.
|
|
156
|
+
* @returns {HTMLElement}
|
|
157
|
+
*/
|
|
158
|
+
createBreadcrumbDropdown({ breadcrumbs, trigger, placement }: {
|
|
159
|
+
breadcrumbs: Array<HTMLElement>;
|
|
160
|
+
trigger: HTMLElement;
|
|
161
|
+
placement: string;
|
|
162
|
+
}): HTMLElement;
|
|
163
|
+
/**
|
|
164
|
+
* Creates the menu used by collapsed dropdown variants.
|
|
165
|
+
* @param {Array<HTMLElement>} breadcrumbs Breadcrumb items represented by menu items.
|
|
166
|
+
* @returns {HTMLElement}
|
|
167
|
+
*/
|
|
168
|
+
createCollapsedBreadcrumbMenu(breadcrumbs: Array<HTMLElement>): HTMLElement;
|
|
169
|
+
/**
|
|
170
|
+
* Returns breadcrumbs that should be exposed in a collapsed menu.
|
|
171
|
+
* @param {boolean} isBreakpointMenuIndicator Whether this trigger controls the full breakpoint menu.
|
|
172
|
+
* @returns {Array<HTMLElement>}
|
|
173
|
+
*/
|
|
174
|
+
getCollapsedMenuBreadcrumbs(isBreakpointMenuIndicator: boolean): Array<HTMLElement>;
|
|
175
|
+
/**
|
|
176
|
+
* Renders one of the compact mobile breakpoint variants.
|
|
177
|
+
* @param {string} variant Normalized uppercase variant token.
|
|
178
|
+
* @returns {HTMLElement}
|
|
179
|
+
*/
|
|
180
|
+
collapseMobileVariant(variant: string): HTMLElement;
|
|
181
|
+
/**
|
|
182
|
+
* Renders only the current breadcrumb title.
|
|
183
|
+
* @returns {HTMLElement}
|
|
184
|
+
*/
|
|
185
|
+
collapseMobileText(): HTMLElement;
|
|
186
|
+
/**
|
|
187
|
+
* Renders a parent back action above the current title.
|
|
188
|
+
* @returns {HTMLElement}
|
|
189
|
+
*/
|
|
190
|
+
collapseMobileBack(): HTMLElement;
|
|
191
|
+
/**
|
|
192
|
+
* Renders parent context above the current title.
|
|
193
|
+
* @returns {HTMLElement}
|
|
194
|
+
*/
|
|
195
|
+
collapseMobileParentTitle(): HTMLElement;
|
|
196
|
+
/**
|
|
197
|
+
* Renders a menu trigger with the current title.
|
|
198
|
+
* @returns {HTMLElement}
|
|
199
|
+
*/
|
|
200
|
+
collapseMobileMenuTitle(): HTMLElement;
|
|
201
|
+
/**
|
|
202
|
+
* Renders the future sheet variant using the dropdown fallback for now.
|
|
203
|
+
* @returns {HTMLElement}
|
|
204
|
+
*/
|
|
205
|
+
collapseMobileSheet(): HTMLElement;
|
|
206
|
+
/**
|
|
207
|
+
* Creates a dropdown fallback for mobile menu-like variants.
|
|
208
|
+
* @param {HTMLElement} trigger Element that opens the fallback dropdown.
|
|
209
|
+
* @returns {HTMLElement}
|
|
210
|
+
*/
|
|
211
|
+
createMobileDropdown(trigger: HTMLElement): HTMLElement;
|
|
212
|
+
/**
|
|
213
|
+
* Creates a compact mobile dropdown trigger.
|
|
214
|
+
* @param {object} options Visual settings for the compact trigger.
|
|
215
|
+
* @param {string} options.icon Icon shown next to the title.
|
|
216
|
+
* @param {string} options.iconPosition Whether the icon renders at the start or end.
|
|
217
|
+
* @param {string} options.label Current breadcrumb label shown beside the icon.
|
|
218
|
+
* @param {string} options.ariaLabel Accessible name for the dropdown trigger.
|
|
219
|
+
* @param {string} options.className Variant-specific class applied to the trigger.
|
|
220
|
+
* @returns {HTMLElement}
|
|
221
|
+
*/
|
|
222
|
+
createMobileDropdownTrigger({ icon, iconPosition, label, ariaLabel, className }: {
|
|
223
|
+
icon: string;
|
|
224
|
+
iconPosition: string;
|
|
225
|
+
label: string;
|
|
226
|
+
ariaLabel: string;
|
|
227
|
+
className: string;
|
|
228
|
+
}): HTMLElement;
|
|
229
|
+
/**
|
|
230
|
+
* Creates a wrapper for compact mobile breadcrumb variants.
|
|
231
|
+
* @param {string} className Variant class.
|
|
232
|
+
* @returns {HTMLElement}
|
|
233
|
+
*/
|
|
234
|
+
createMobileContainer(className: string): HTMLElement;
|
|
235
|
+
/**
|
|
236
|
+
* Creates a text or button control for a breadcrumb.
|
|
237
|
+
* @param {HTMLElement|null} breadcrumb Source breadcrumb.
|
|
238
|
+
* @param {string} className Class applied to the created control.
|
|
239
|
+
* @param {object} options Behavior and accessibility settings for the control.
|
|
240
|
+
* @param {boolean} options.actionable Whether clicks should forward to the source breadcrumb.
|
|
241
|
+
* @param {boolean} options.ariaCurrent Whether the control marks the current page.
|
|
242
|
+
* @param {string} options.ariaLabel Accessible name for action controls.
|
|
243
|
+
* @param {string} options.icon Optional icon shown before the label.
|
|
244
|
+
* @returns {HTMLElement}
|
|
245
|
+
*/
|
|
246
|
+
createMobileBreadcrumbControl(breadcrumb: HTMLElement | null, className: string, { actionable, ariaCurrent, ariaLabel, icon }?: {
|
|
247
|
+
actionable: boolean;
|
|
248
|
+
ariaCurrent: boolean;
|
|
249
|
+
ariaLabel: string;
|
|
250
|
+
icon: string;
|
|
251
|
+
}): HTMLElement;
|
|
252
|
+
/**
|
|
253
|
+
* Returns the full trail of sibling breadcrumbs.
|
|
254
|
+
* @returns {Array<HTMLElement>}
|
|
255
|
+
*/
|
|
256
|
+
getTrailBreadcrumbs(): Array<HTMLElement>;
|
|
257
|
+
/**
|
|
258
|
+
* Returns the current breadcrumb item.
|
|
259
|
+
* @returns {HTMLElement|null}
|
|
260
|
+
*/
|
|
261
|
+
getCurrentBreadcrumb(): HTMLElement | null;
|
|
262
|
+
/**
|
|
263
|
+
* Returns the parent breadcrumb item.
|
|
264
|
+
* @returns {HTMLElement|null}
|
|
265
|
+
*/
|
|
266
|
+
getParentBreadcrumb(): HTMLElement | null;
|
|
267
|
+
/**
|
|
268
|
+
* Returns whether a breadcrumb has a known action to forward.
|
|
269
|
+
* @param {HTMLElement|null} breadcrumb Breadcrumb to inspect.
|
|
270
|
+
* @returns {boolean}
|
|
271
|
+
*/
|
|
272
|
+
isBreadcrumbActionable(breadcrumb: HTMLElement | null): boolean;
|
|
273
|
+
/**
|
|
274
|
+
* Forwards a compact control or menu item click to the original breadcrumb.
|
|
275
|
+
* @param {HTMLElement|null} breadcrumb Source breadcrumb.
|
|
276
|
+
*/
|
|
277
|
+
forwardBreadcrumbClick(breadcrumb: HTMLElement | null): void;
|
|
140
278
|
/**
|
|
141
279
|
* Creates the dropdown trigger for collapsed breadcrumbs.
|
|
142
280
|
* @param {boolean} isBreakpointMenuIndicator Whether this trigger controls the full breakpoint menu.
|
|
@@ -155,6 +293,12 @@ export default class Breadcrumb extends WJElement {
|
|
|
155
293
|
* @param {HTMLElement} breadcrumb Source breadcrumb.
|
|
156
294
|
*/
|
|
157
295
|
populateCollapsedMenuItem(menuItem: HTMLElement, breadcrumb: HTMLElement): void;
|
|
296
|
+
/**
|
|
297
|
+
* Resolves a readable label for a breadcrumb item.
|
|
298
|
+
* @param {HTMLElement|null} breadcrumb Source breadcrumb.
|
|
299
|
+
* @returns {string}
|
|
300
|
+
*/
|
|
301
|
+
getBreadcrumbLabel(breadcrumb: HTMLElement | null): string;
|
|
158
302
|
/**
|
|
159
303
|
* Resolves a readable label for icon-only collapsed menu items.
|
|
160
304
|
* @param {HTMLElement} breadcrumb Source breadcrumb.
|
|
@@ -11,7 +11,7 @@ import { default as WJElement } from '../wje-element/element.js';
|
|
|
11
11
|
* @attribute {number} max-items - The maximum number of visible breadcrumbs before collapsing.
|
|
12
12
|
* @attribute {number} items-before-collapse - The number of breadcrumbs to show before the collapsed indicator.
|
|
13
13
|
* @attribute {number} items-after-collapse - The number of breadcrumbs to show after the collapsed indicator.
|
|
14
|
-
* @attribute {string} collapsed-variant - The UI used for collapsed breadcrumbs. Use "dropdown" to render a menu.
|
|
14
|
+
* @attribute {string} collapsed-variant - The UI used for collapsed breadcrumbs. Use "dropdown" to render a menu, or "text", "back", "parent-title", "menu-title", and "sheet" for compact breakpoint menu layouts.
|
|
15
15
|
* @attribute {string} breakpoint - The viewport breakpoint where collapsing starts.
|
|
16
16
|
* @attribute {string} breakpoint-collapse - The collapse behavior used below the breakpoint. Use "menu" to put the whole trail into one menu.
|
|
17
17
|
* @attribute {string} breakpoint-collapse-icon - Icon used by the default breakpoint menu trigger.
|
|
@@ -90,6 +90,11 @@ export default class Breadcrumbs extends WJElement {
|
|
|
90
90
|
* @returns {string}
|
|
91
91
|
*/
|
|
92
92
|
get collapsedVariant(): string;
|
|
93
|
+
/**
|
|
94
|
+
* Gets the collapsed indicator variant as a normalized token.
|
|
95
|
+
* @returns {string}
|
|
96
|
+
*/
|
|
97
|
+
get normalizedCollapsedVariant(): string;
|
|
93
98
|
/**
|
|
94
99
|
* Sets the collapse breakpoint token or value.
|
|
95
100
|
* @param {string} value Breakpoint token or CSS size.
|
|
@@ -157,6 +162,10 @@ export default class Breadcrumbs extends WJElement {
|
|
|
157
162
|
* @param {string|null} newValue Next value.
|
|
158
163
|
*/
|
|
159
164
|
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
|
|
165
|
+
/**
|
|
166
|
+
* Syncs host navigation semantics while preserving user-provided names.
|
|
167
|
+
*/
|
|
168
|
+
syncAria(): void;
|
|
160
169
|
/**
|
|
161
170
|
* Draw method for the Breadcrumbs element.
|
|
162
171
|
* @returns {object} fragment - The document fragment
|
|
@@ -275,6 +284,11 @@ export default class Breadcrumbs extends WJElement {
|
|
|
275
284
|
* @returns {boolean}
|
|
276
285
|
*/
|
|
277
286
|
isBreakpointMenuCollapseActive(): boolean;
|
|
287
|
+
/**
|
|
288
|
+
* Returns whether the active collapsed variant is one of the mobile compact layouts.
|
|
289
|
+
* @returns {boolean}
|
|
290
|
+
*/
|
|
291
|
+
usesMobileCollapsedVariant(): boolean;
|
|
278
292
|
/**
|
|
279
293
|
* Clears attributes/classes managed by the collapse algorithm.
|
|
280
294
|
* @param {Array<Element>} breadcrumbs Breadcrumb items.
|
|
@@ -161,6 +161,12 @@ export default class ToolbarAction extends WJElement {
|
|
|
161
161
|
* @returns {HTMLElement}
|
|
162
162
|
*/
|
|
163
163
|
createMenuItem(action: HTMLElement): HTMLElement;
|
|
164
|
+
/**
|
|
165
|
+
* Resolves readable text for a toolbar action copied into an overflow menu.
|
|
166
|
+
* @param {HTMLElement} action The original action element.
|
|
167
|
+
* @returns {string}
|
|
168
|
+
*/
|
|
169
|
+
getActionLabel(action: HTMLElement): string;
|
|
164
170
|
/**
|
|
165
171
|
* Creates a divider separating existing dropdown actions from responsive overflow actions.
|
|
166
172
|
* @returns {HTMLElement}
|
package/dist/wje-breadcrumb.js
CHANGED
|
@@ -11,7 +11,8 @@ import "./wje-menu.js";
|
|
|
11
11
|
import "./wje-menu-item.js";
|
|
12
12
|
import "./wje-popup.js";
|
|
13
13
|
import "./wje-tooltip.js";
|
|
14
|
-
const styles = "/*\n[ WJ Breadcrumb ]\n*/\n\n:host {\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n line-height: var(--wje-breadcrumb-line-height, 1.5);\n\n .native-breadcrumb {\n display: flex;\n align-items: center;\n width: 100%;\n outline: none;\n background: inherit;\n margin: var(--wje-breadcrumb-margin, var(--wje-breadcrumb-native-margin, 0));\n padding: var(--wje-breadcrumb-padding, var(--wje-breadcrumb-native-padding, 0.25rem 0.75rem));\n color: var(--wje-breadcrumb-a);\n text-decoration: none;\n font-size: var(--wje-breadcrumb-font-size);\n line-height: var(--wje-breadcrumb-native-line-height, var(--wje-breadcrumb-line-height, 1.5));\n &.hidden {\n display: none;\n }\n &.active {\n font-weight: var(--wje-breadcrumb-active-font-weight);\n font-size: var(--wje-breadcrumb-active-font-size);\n }\n &.disabled {\n cursor: default;\n opacity: 0.6;\n }\n &:hover {\n color: var(--wje-breadcrumb-a-hover);\n }\n }\n\n button {\n margin-inline: 0.75rem;\n border: 0 solid transparent;\n border-radius: 3px;\n background-color: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n }\n\n .separator {\n display: inline-flex;\n align-items: center;\n }\n}\n\n:host(.collapsed) {\n display: none;\n}\n\n::slotted([slot='start']) {\n margin-inline: 0 0.5rem;\n}\n\n::slotted([slot='end']) {\n margin-inline: 0.5rem 0;\n}\n";
|
|
14
|
+
const styles = "/*\n[ WJ Breadcrumb ]\n*/\n\n:host {\n display: flex;\n flex: 0 0 auto;\n align-items: center;\n line-height: var(--wje-breadcrumb-line-height, 1.5);\n\n .native-breadcrumb {\n display: flex;\n align-items: center;\n width: 100%;\n outline: none;\n background: inherit;\n margin: var(--wje-breadcrumb-margin, var(--wje-breadcrumb-native-margin, 0));\n padding: var(--wje-breadcrumb-padding, var(--wje-breadcrumb-native-padding, 0.25rem 0.75rem));\n color: var(--wje-breadcrumb-a);\n text-decoration: none;\n font-size: var(--wje-breadcrumb-font-size);\n line-height: var(--wje-breadcrumb-native-line-height, var(--wje-breadcrumb-line-height, 1.5));\n &.hidden {\n display: none;\n }\n &.active {\n font-weight: var(--wje-breadcrumb-active-font-weight);\n font-size: var(--wje-breadcrumb-active-font-size);\n }\n &.disabled {\n cursor: default;\n opacity: 0.6;\n }\n &:hover {\n color: var(--wje-breadcrumb-a-hover);\n }\n }\n\n button {\n margin-inline: 0.75rem;\n border: 0 solid transparent;\n border-radius: 3px;\n background-color: transparent;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n }\n\n .separator {\n display: inline-flex;\n align-items: center;\n }\n}\n\n:host(.collapsed) {\n display: none;\n}\n\n:host([mobile-collapsed-indicator]) {\n flex: 1 1 auto;\n min-width: 0;\n max-width: 100%;\n overflow: hidden;\n}\n\n.breadcrumb-mobile {\n display: flex;\n align-items: center;\n min-width: 0;\n max-width: 100%;\n color: var(--wje-breadcrumb-a);\n font-size: var(--wje-breadcrumb-font-size);\n line-height: var(--wje-breadcrumb-line-height, 1.5);\n}\n\n.breadcrumb-mobile--text,\n.breadcrumb-mobile--back,\n.breadcrumb-mobile--parent-title {\n width: 100%;\n}\n\n.breadcrumb-mobile--back,\n.breadcrumb-mobile--parent-title {\n flex-direction: column;\n align-items: flex-start;\n gap: 0.125rem;\n}\n\n.breadcrumb-mobile-dropdown,\n.breadcrumb-mobile__menu {\n min-width: 0;\n max-width: 100%;\n}\n\n.breadcrumb-mobile__menu {\n --wje-button-margin-inline: 0;\n --wje-padding-top: 0;\n --wje-padding-bottom: 0;\n --wje-padding-start: 0;\n --wje-padding-end: 0;\n gap: 0.35rem;\n color: var(--wje-breadcrumb-a);\n}\n\n.breadcrumb-mobile__back,\n.breadcrumb-mobile__parent,\n.breadcrumb-mobile__title {\n min-width: 0;\n max-width: 100%;\n overflow: hidden;\n color: inherit;\n font: inherit;\n line-height: inherit;\n text-align: start;\n text-decoration: none;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.breadcrumb-mobile__back,\n.breadcrumb-mobile__parent {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0;\n border: 0;\n background: transparent;\n color: var(--wje-breadcrumb-a);\n cursor: default;\n font-size: var(--wje-breadcrumb-mobile-parent-font-size, 0.8125rem);\n opacity: 0.72;\n}\n\nbutton.breadcrumb-mobile__back,\nbutton.breadcrumb-mobile__parent,\nbutton.breadcrumb-mobile__title {\n margin-inline: 0;\n cursor: pointer;\n}\n\nbutton.breadcrumb-mobile__back:hover,\nbutton.breadcrumb-mobile__parent:hover,\nbutton.breadcrumb-mobile__title:hover,\n.breadcrumb-mobile__menu:hover {\n color: var(--wje-breadcrumb-a-hover);\n}\n\n.breadcrumb-mobile__title {\n display: block;\n font-weight: var(--wje-breadcrumb-active-font-weight, 600);\n font-size: var(--wje-breadcrumb-active-font-size, inherit);\n}\n\n.breadcrumb-mobile__label {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.breadcrumb-mobile__icon {\n flex: 0 0 auto;\n}\n\n::slotted([slot='start']) {\n margin-inline: 0 0.5rem;\n}\n\n::slotted([slot='end']) {\n margin-inline: 0.5rem 0;\n}\n";
|
|
15
|
+
const MOBILE_COLLAPSED_VARIANTS = /* @__PURE__ */ new Set(["TEXT", "BACK", "PARENT-TITLE", "MENU-TITLE", "SHEET"]);
|
|
15
16
|
class Breadcrumb extends WJElement {
|
|
16
17
|
/**
|
|
17
18
|
* Breadcrumb constructor method.
|
|
@@ -86,9 +87,15 @@ class Breadcrumb extends WJElement {
|
|
|
86
87
|
* @returns {string} The collapsed variant value in uppercase.
|
|
87
88
|
*/
|
|
88
89
|
get collapsedVariant() {
|
|
90
|
+
return this.collapsedVariantName.toUpperCase();
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Get collapsed variant token.
|
|
94
|
+
* @returns {string}
|
|
95
|
+
*/
|
|
96
|
+
get collapsedVariantName() {
|
|
89
97
|
var _a, _b;
|
|
90
|
-
|
|
91
|
-
return variant.toUpperCase();
|
|
98
|
+
return String(((_a = this.parentElement) == null ? void 0 : _a.collapsedVariant) || ((_b = this.parentElement) == null ? void 0 : _b.variant) || this._collapsedVariant || "button").trim();
|
|
92
99
|
}
|
|
93
100
|
/**
|
|
94
101
|
* Get CSS stylesheet for the Breadcrumb element.
|
|
@@ -284,17 +291,25 @@ class Breadcrumb extends WJElement {
|
|
|
284
291
|
/**
|
|
285
292
|
* Renders the collapsed indicator based on the current collapsed variant.
|
|
286
293
|
* If the collapsed variant is 'DROPDOWN', it invokes the collapseDropdown method.
|
|
287
|
-
*
|
|
294
|
+
* Mobile breakpoint variants render compact breadcrumb summaries, otherwise the default button is used.
|
|
288
295
|
* @returns {any} The rendered collapsed indicator, either as a dropdown or a button.
|
|
289
296
|
*/
|
|
290
297
|
drawCollapsedIndicator() {
|
|
291
|
-
|
|
292
|
-
if (
|
|
293
|
-
|
|
294
|
-
}
|
|
295
|
-
|
|
298
|
+
const variant = this.collapsedVariant;
|
|
299
|
+
if (variant === "DROPDOWN") {
|
|
300
|
+
return this.collapseDropdown();
|
|
301
|
+
}
|
|
302
|
+
if (this.isMobileCollapsedVariant() && this.isBreakpointMenuIndicator()) {
|
|
303
|
+
return this.collapseMobileVariant(variant);
|
|
296
304
|
}
|
|
297
|
-
return
|
|
305
|
+
return this.collapseButton();
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Returns whether the current collapsed variant is a compact mobile layout.
|
|
309
|
+
* @returns {boolean}
|
|
310
|
+
*/
|
|
311
|
+
isMobileCollapsedVariant() {
|
|
312
|
+
return MOBILE_COLLAPSED_VARIANTS.has(this.collapsedVariant);
|
|
298
313
|
}
|
|
299
314
|
/**
|
|
300
315
|
* Creates and returns a dropdown UI component for collapsed breadcrumbs.
|
|
@@ -306,11 +321,37 @@ class Breadcrumb extends WJElement {
|
|
|
306
321
|
*/
|
|
307
322
|
collapseDropdown() {
|
|
308
323
|
const isBreakpointMenuIndicator = this.isBreakpointMenuIndicator();
|
|
309
|
-
|
|
310
|
-
dropdown.setAttribute("placement", isBreakpointMenuIndicator ? "bottom-start" : "bottom");
|
|
311
|
-
dropdown.setAttribute("offset", "10");
|
|
324
|
+
const breadcrumbs = this.getCollapsedMenuBreadcrumbs(isBreakpointMenuIndicator);
|
|
312
325
|
const trigger = this.createCollapsedDropdownTrigger(isBreakpointMenuIndicator);
|
|
313
|
-
|
|
326
|
+
return this.createBreadcrumbDropdown({
|
|
327
|
+
breadcrumbs,
|
|
328
|
+
trigger,
|
|
329
|
+
placement: isBreakpointMenuIndicator ? "bottom-start" : "bottom"
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Creates a dropdown containing breadcrumb menu items.
|
|
334
|
+
* @param {object} options Configuration for the dropdown shell.
|
|
335
|
+
* @param {Array<HTMLElement>} options.breadcrumbs Breadcrumb elements to mirror in the menu.
|
|
336
|
+
* @param {HTMLElement} options.trigger Element assigned to the dropdown trigger slot.
|
|
337
|
+
* @param {string} options.placement Floating UI placement token for the popup.
|
|
338
|
+
* @returns {HTMLElement}
|
|
339
|
+
*/
|
|
340
|
+
createBreadcrumbDropdown({ breadcrumbs, trigger, placement = "bottom" }) {
|
|
341
|
+
const dropdown = document.createElement("wje-dropdown");
|
|
342
|
+
dropdown.setAttribute("placement", placement);
|
|
343
|
+
dropdown.setAttribute("offset", "10");
|
|
344
|
+
const menu = this.createCollapsedBreadcrumbMenu(breadcrumbs);
|
|
345
|
+
dropdown.append(trigger, menu);
|
|
346
|
+
return dropdown;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Creates the menu used by collapsed dropdown variants.
|
|
350
|
+
* @param {Array<HTMLElement>} breadcrumbs Breadcrumb items represented by menu items.
|
|
351
|
+
* @returns {HTMLElement}
|
|
352
|
+
*/
|
|
353
|
+
createCollapsedBreadcrumbMenu(breadcrumbs) {
|
|
354
|
+
const menu = document.createElement("wje-menu");
|
|
314
355
|
menu.setAttribute("variant", "context");
|
|
315
356
|
menu.style.setProperty("--wje-menu-item-justify-content", "flex-start");
|
|
316
357
|
menu.addEventListener("click", (e) => {
|
|
@@ -318,37 +359,286 @@ class Breadcrumb extends WJElement {
|
|
|
318
359
|
e.stopPropagation();
|
|
319
360
|
(_a = e.stopImmediatePropagation) == null ? void 0 : _a.call(e);
|
|
320
361
|
});
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
this.populateCollapsedMenuItem(menuItem,
|
|
324
|
-
menuItem.__breadcrumb =
|
|
362
|
+
breadcrumbs.forEach((breadcrumb) => {
|
|
363
|
+
const menuItem = document.createElement("wje-menu-item");
|
|
364
|
+
this.populateCollapsedMenuItem(menuItem, breadcrumb);
|
|
365
|
+
menuItem.__breadcrumb = breadcrumb;
|
|
325
366
|
menuItem.addEventListener("wje-menu-item:click", (e) => {
|
|
326
|
-
var _a, _b
|
|
367
|
+
var _a, _b;
|
|
327
368
|
(_a = e.preventDefault) == null ? void 0 : _a.call(e);
|
|
328
369
|
e.stopPropagation();
|
|
329
370
|
(_b = e.stopImmediatePropagation) == null ? void 0 : _b.call(e);
|
|
330
|
-
|
|
331
|
-
if (!breadcrumb) return;
|
|
332
|
-
const native = breadcrumb.native || ((_c = breadcrumb.context) == null ? void 0 : _c.querySelector("a.native-breadcrumb"));
|
|
333
|
-
if (native && typeof native.click === "function") {
|
|
334
|
-
native.click();
|
|
335
|
-
} else if (typeof breadcrumb.click === "function") {
|
|
336
|
-
breadcrumb.click();
|
|
337
|
-
} else {
|
|
338
|
-
breadcrumb.dispatchEvent(
|
|
339
|
-
new MouseEvent("click", {
|
|
340
|
-
bubbles: true,
|
|
341
|
-
composed: true,
|
|
342
|
-
cancelable: true
|
|
343
|
-
})
|
|
344
|
-
);
|
|
345
|
-
}
|
|
371
|
+
this.forwardBreadcrumbClick(e.currentTarget.__breadcrumb);
|
|
346
372
|
});
|
|
347
373
|
menu.append(menuItem);
|
|
348
374
|
});
|
|
349
|
-
|
|
375
|
+
return menu;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Returns breadcrumbs that should be exposed in a collapsed menu.
|
|
379
|
+
* @param {boolean} isBreakpointMenuIndicator Whether this trigger controls the full breakpoint menu.
|
|
380
|
+
* @returns {Array<HTMLElement>}
|
|
381
|
+
*/
|
|
382
|
+
getCollapsedMenuBreadcrumbs(isBreakpointMenuIndicator) {
|
|
383
|
+
var _a, _b;
|
|
384
|
+
const breadcrumbs = this.getBreadcrumbs();
|
|
385
|
+
if (isBreakpointMenuIndicator) {
|
|
386
|
+
return ((_a = breadcrumbs == null ? void 0 : breadcrumbs.getBreadcrumbs) == null ? void 0 : _a.call(breadcrumbs)) || [];
|
|
387
|
+
}
|
|
388
|
+
return ((_b = breadcrumbs == null ? void 0 : breadcrumbs.getBreadcrumbsCollapsed) == null ? void 0 : _b.call(breadcrumbs)) || [];
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Renders one of the compact mobile breakpoint variants.
|
|
392
|
+
* @param {string} variant Normalized uppercase variant token.
|
|
393
|
+
* @returns {HTMLElement}
|
|
394
|
+
*/
|
|
395
|
+
collapseMobileVariant(variant) {
|
|
396
|
+
if (variant === "TEXT") return this.collapseMobileText();
|
|
397
|
+
if (variant === "BACK") return this.collapseMobileBack();
|
|
398
|
+
if (variant === "PARENT-TITLE") return this.collapseMobileParentTitle();
|
|
399
|
+
if (variant === "MENU-TITLE") return this.collapseMobileMenuTitle();
|
|
400
|
+
if (variant === "SHEET") return this.collapseMobileSheet();
|
|
401
|
+
return this.collapseButton();
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Renders only the current breadcrumb title.
|
|
405
|
+
* @returns {HTMLElement}
|
|
406
|
+
*/
|
|
407
|
+
collapseMobileText() {
|
|
408
|
+
const current = this.getCurrentBreadcrumb();
|
|
409
|
+
const container = this.createMobileContainer("breadcrumb-mobile--text");
|
|
410
|
+
const title = this.createMobileBreadcrumbControl(current, "breadcrumb-mobile__title", {
|
|
411
|
+
ariaCurrent: true,
|
|
412
|
+
actionable: this.isBreadcrumbActionable(current)
|
|
413
|
+
});
|
|
414
|
+
container.append(title);
|
|
415
|
+
return container;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Renders a parent back action above the current title.
|
|
419
|
+
* @returns {HTMLElement}
|
|
420
|
+
*/
|
|
421
|
+
collapseMobileBack() {
|
|
422
|
+
const current = this.getCurrentBreadcrumb();
|
|
423
|
+
const parent = this.getParentBreadcrumb();
|
|
424
|
+
const container = this.createMobileContainer("breadcrumb-mobile--back");
|
|
425
|
+
if (parent) {
|
|
426
|
+
const back = this.createMobileBreadcrumbControl(parent, "breadcrumb-mobile__back", {
|
|
427
|
+
ariaLabel: "Go to parent",
|
|
428
|
+
icon: "arrow-left",
|
|
429
|
+
actionable: this.isBreadcrumbActionable(parent)
|
|
430
|
+
});
|
|
431
|
+
container.append(back);
|
|
432
|
+
}
|
|
433
|
+
const title = this.createMobileBreadcrumbControl(current, "breadcrumb-mobile__title", {
|
|
434
|
+
ariaCurrent: true,
|
|
435
|
+
actionable: false
|
|
436
|
+
});
|
|
437
|
+
container.append(title);
|
|
438
|
+
return container;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Renders parent context above the current title.
|
|
442
|
+
* @returns {HTMLElement}
|
|
443
|
+
*/
|
|
444
|
+
collapseMobileParentTitle() {
|
|
445
|
+
const current = this.getCurrentBreadcrumb();
|
|
446
|
+
const parent = this.getParentBreadcrumb();
|
|
447
|
+
const container = this.createMobileContainer("breadcrumb-mobile--parent-title");
|
|
448
|
+
if (parent) {
|
|
449
|
+
const parentControl = this.createMobileBreadcrumbControl(parent, "breadcrumb-mobile__parent", {
|
|
450
|
+
actionable: this.isBreadcrumbActionable(parent)
|
|
451
|
+
});
|
|
452
|
+
container.append(parentControl);
|
|
453
|
+
}
|
|
454
|
+
const title = this.createMobileBreadcrumbControl(current, "breadcrumb-mobile__title", {
|
|
455
|
+
ariaCurrent: true,
|
|
456
|
+
actionable: false
|
|
457
|
+
});
|
|
458
|
+
container.append(title);
|
|
459
|
+
return container;
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Renders a menu trigger with the current title.
|
|
463
|
+
* @returns {HTMLElement}
|
|
464
|
+
*/
|
|
465
|
+
collapseMobileMenuTitle() {
|
|
466
|
+
const trigger = this.createMobileDropdownTrigger({
|
|
467
|
+
icon: "dots",
|
|
468
|
+
label: this.getBreadcrumbLabel(this.getCurrentBreadcrumb()),
|
|
469
|
+
ariaLabel: "Show breadcrumb menu",
|
|
470
|
+
className: "breadcrumb-mobile--menu-title"
|
|
471
|
+
});
|
|
472
|
+
return this.createMobileDropdown(trigger);
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Renders the future sheet variant using the dropdown fallback for now.
|
|
476
|
+
* @returns {HTMLElement}
|
|
477
|
+
*/
|
|
478
|
+
collapseMobileSheet() {
|
|
479
|
+
const trigger = this.createMobileDropdownTrigger({
|
|
480
|
+
icon: "chevron-down",
|
|
481
|
+
iconPosition: "end",
|
|
482
|
+
label: this.getBreadcrumbLabel(this.getCurrentBreadcrumb()),
|
|
483
|
+
ariaLabel: "Show breadcrumb path",
|
|
484
|
+
className: "breadcrumb-mobile--sheet"
|
|
485
|
+
});
|
|
486
|
+
return this.createMobileDropdown(trigger);
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Creates a dropdown fallback for mobile menu-like variants.
|
|
490
|
+
* @param {HTMLElement} trigger Element that opens the fallback dropdown.
|
|
491
|
+
* @returns {HTMLElement}
|
|
492
|
+
*/
|
|
493
|
+
createMobileDropdown(trigger) {
|
|
494
|
+
const dropdown = this.createBreadcrumbDropdown({
|
|
495
|
+
breadcrumbs: this.getTrailBreadcrumbs(),
|
|
496
|
+
trigger,
|
|
497
|
+
placement: "bottom-start"
|
|
498
|
+
});
|
|
499
|
+
dropdown.classList.add("breadcrumb-mobile-dropdown");
|
|
350
500
|
return dropdown;
|
|
351
501
|
}
|
|
502
|
+
/**
|
|
503
|
+
* Creates a compact mobile dropdown trigger.
|
|
504
|
+
* @param {object} options Visual settings for the compact trigger.
|
|
505
|
+
* @param {string} options.icon Icon shown next to the title.
|
|
506
|
+
* @param {string} options.iconPosition Whether the icon renders at the start or end.
|
|
507
|
+
* @param {string} options.label Current breadcrumb label shown beside the icon.
|
|
508
|
+
* @param {string} options.ariaLabel Accessible name for the dropdown trigger.
|
|
509
|
+
* @param {string} options.className Variant-specific class applied to the trigger.
|
|
510
|
+
* @returns {HTMLElement}
|
|
511
|
+
*/
|
|
512
|
+
createMobileDropdownTrigger({ icon, iconPosition = "start", label, ariaLabel, className }) {
|
|
513
|
+
const trigger = document.createElement("wje-button");
|
|
514
|
+
trigger.setAttribute("slot", "trigger");
|
|
515
|
+
trigger.setAttribute("fill", "link");
|
|
516
|
+
trigger.setAttribute("aria-label", ariaLabel);
|
|
517
|
+
trigger.classList.add("breadcrumb-mobile", "breadcrumb-mobile__menu", className);
|
|
518
|
+
const iconElement = document.createElement("wje-icon");
|
|
519
|
+
iconElement.setAttribute("name", icon);
|
|
520
|
+
iconElement.setAttribute("slot", iconPosition === "end" ? "end" : "start");
|
|
521
|
+
iconElement.classList.add("breadcrumb-mobile__icon");
|
|
522
|
+
const title = document.createElement("span");
|
|
523
|
+
title.classList.add("breadcrumb-mobile__title");
|
|
524
|
+
title.setAttribute("aria-current", "page");
|
|
525
|
+
title.textContent = label;
|
|
526
|
+
if (label) title.setAttribute("title", label);
|
|
527
|
+
if (iconPosition === "end") {
|
|
528
|
+
trigger.append(title, iconElement);
|
|
529
|
+
} else {
|
|
530
|
+
trigger.append(iconElement, title);
|
|
531
|
+
}
|
|
532
|
+
return trigger;
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Creates a wrapper for compact mobile breadcrumb variants.
|
|
536
|
+
* @param {string} className Variant class.
|
|
537
|
+
* @returns {HTMLElement}
|
|
538
|
+
*/
|
|
539
|
+
createMobileContainer(className) {
|
|
540
|
+
const container = document.createElement("div");
|
|
541
|
+
container.classList.add("breadcrumb-mobile", className);
|
|
542
|
+
return container;
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Creates a text or button control for a breadcrumb.
|
|
546
|
+
* @param {HTMLElement|null} breadcrumb Source breadcrumb.
|
|
547
|
+
* @param {string} className Class applied to the created control.
|
|
548
|
+
* @param {object} options Behavior and accessibility settings for the control.
|
|
549
|
+
* @param {boolean} options.actionable Whether clicks should forward to the source breadcrumb.
|
|
550
|
+
* @param {boolean} options.ariaCurrent Whether the control marks the current page.
|
|
551
|
+
* @param {string} options.ariaLabel Accessible name for action controls.
|
|
552
|
+
* @param {string} options.icon Optional icon shown before the label.
|
|
553
|
+
* @returns {HTMLElement}
|
|
554
|
+
*/
|
|
555
|
+
createMobileBreadcrumbControl(breadcrumb, className, { actionable = false, ariaCurrent = false, ariaLabel, icon } = {}) {
|
|
556
|
+
const label = this.getBreadcrumbLabel(breadcrumb);
|
|
557
|
+
const control = document.createElement(actionable ? "button" : "span");
|
|
558
|
+
control.classList.add(className);
|
|
559
|
+
if (actionable) {
|
|
560
|
+
control.setAttribute("type", "button");
|
|
561
|
+
control.addEventListener("click", (e) => {
|
|
562
|
+
var _a;
|
|
563
|
+
e.preventDefault();
|
|
564
|
+
e.stopPropagation();
|
|
565
|
+
(_a = e.stopImmediatePropagation) == null ? void 0 : _a.call(e);
|
|
566
|
+
this.forwardBreadcrumbClick(breadcrumb);
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
if (ariaCurrent) control.setAttribute("aria-current", "page");
|
|
570
|
+
if (ariaLabel && actionable) control.setAttribute("aria-label", ariaLabel);
|
|
571
|
+
if (label) control.setAttribute("title", label);
|
|
572
|
+
if (icon) {
|
|
573
|
+
const iconElement = document.createElement("wje-icon");
|
|
574
|
+
iconElement.setAttribute("name", icon);
|
|
575
|
+
iconElement.classList.add("breadcrumb-mobile__icon");
|
|
576
|
+
control.append(iconElement);
|
|
577
|
+
}
|
|
578
|
+
const text = document.createElement("span");
|
|
579
|
+
text.classList.add("breadcrumb-mobile__label");
|
|
580
|
+
text.textContent = label;
|
|
581
|
+
control.append(text);
|
|
582
|
+
return control;
|
|
583
|
+
}
|
|
584
|
+
/**
|
|
585
|
+
* Returns the full trail of sibling breadcrumbs.
|
|
586
|
+
* @returns {Array<HTMLElement>}
|
|
587
|
+
*/
|
|
588
|
+
getTrailBreadcrumbs() {
|
|
589
|
+
var _a, _b;
|
|
590
|
+
return ((_b = (_a = this.getBreadcrumbs()) == null ? void 0 : _a.getBreadcrumbs) == null ? void 0 : _b.call(_a)) || [];
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* Returns the current breadcrumb item.
|
|
594
|
+
* @returns {HTMLElement|null}
|
|
595
|
+
*/
|
|
596
|
+
getCurrentBreadcrumb() {
|
|
597
|
+
const breadcrumbs = this.getTrailBreadcrumbs();
|
|
598
|
+
return breadcrumbs[breadcrumbs.length - 1] || null;
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Returns the parent breadcrumb item.
|
|
602
|
+
* @returns {HTMLElement|null}
|
|
603
|
+
*/
|
|
604
|
+
getParentBreadcrumb() {
|
|
605
|
+
const breadcrumbs = this.getTrailBreadcrumbs();
|
|
606
|
+
return breadcrumbs.length > 1 ? breadcrumbs[breadcrumbs.length - 2] : null;
|
|
607
|
+
}
|
|
608
|
+
/**
|
|
609
|
+
* Returns whether a breadcrumb has a known action to forward.
|
|
610
|
+
* @param {HTMLElement|null} breadcrumb Breadcrumb to inspect.
|
|
611
|
+
* @returns {boolean}
|
|
612
|
+
*/
|
|
613
|
+
isBreadcrumbActionable(breadcrumb) {
|
|
614
|
+
var _a, _b, _c, _d;
|
|
615
|
+
if (!breadcrumb || breadcrumb.disabled || ((_a = breadcrumb.hasAttribute) == null ? void 0 : _a.call(breadcrumb, "disabled"))) return false;
|
|
616
|
+
return Boolean(
|
|
617
|
+
((_b = breadcrumb.hasAttribute) == null ? void 0 : _b.call(breadcrumb, "href")) || ((_c = breadcrumb.hasAttribute) == null ? void 0 : _c.call(breadcrumb, "onclick")) || breadcrumb.__wjeBreadcrumbManaged || ((_d = breadcrumb.hasAttribute) == null ? void 0 : _d.call(breadcrumb, "data-wje-breadcrumbs-item"))
|
|
618
|
+
);
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* Forwards a compact control or menu item click to the original breadcrumb.
|
|
622
|
+
* @param {HTMLElement|null} breadcrumb Source breadcrumb.
|
|
623
|
+
*/
|
|
624
|
+
forwardBreadcrumbClick(breadcrumb) {
|
|
625
|
+
var _a;
|
|
626
|
+
if (!breadcrumb) return;
|
|
627
|
+
const native = breadcrumb.native || ((_a = breadcrumb.context) == null ? void 0 : _a.querySelector("a.native-breadcrumb"));
|
|
628
|
+
if (native && typeof native.click === "function") {
|
|
629
|
+
native.click();
|
|
630
|
+
} else if (typeof breadcrumb.click === "function") {
|
|
631
|
+
breadcrumb.click();
|
|
632
|
+
} else {
|
|
633
|
+
breadcrumb.dispatchEvent(
|
|
634
|
+
new MouseEvent("click", {
|
|
635
|
+
bubbles: true,
|
|
636
|
+
composed: true,
|
|
637
|
+
cancelable: true
|
|
638
|
+
})
|
|
639
|
+
);
|
|
640
|
+
}
|
|
641
|
+
}
|
|
352
642
|
/**
|
|
353
643
|
* Creates the dropdown trigger for collapsed breadcrumbs.
|
|
354
644
|
* @param {boolean} isBreakpointMenuIndicator Whether this trigger controls the full breakpoint menu.
|
|
@@ -393,11 +683,20 @@ class Breadcrumb extends WJElement {
|
|
|
393
683
|
const nodes = Array.from(breadcrumb.childNodes).map((node) => node.cloneNode(true));
|
|
394
684
|
menuItem.replaceChildren(...nodes);
|
|
395
685
|
if (menuItem.textContent.trim()) return;
|
|
396
|
-
const label = this.
|
|
686
|
+
const label = this.getBreadcrumbLabel(breadcrumb);
|
|
397
687
|
if (label) {
|
|
398
688
|
menuItem.append(document.createTextNode(label));
|
|
399
689
|
}
|
|
400
690
|
}
|
|
691
|
+
/**
|
|
692
|
+
* Resolves a readable label for a breadcrumb item.
|
|
693
|
+
* @param {HTMLElement|null} breadcrumb Source breadcrumb.
|
|
694
|
+
* @returns {string}
|
|
695
|
+
*/
|
|
696
|
+
getBreadcrumbLabel(breadcrumb) {
|
|
697
|
+
if (!breadcrumb) return "";
|
|
698
|
+
return this.getCollapsedMenuItemLabel(breadcrumb);
|
|
699
|
+
}
|
|
401
700
|
/**
|
|
402
701
|
* Resolves a readable label for icon-only collapsed menu items.
|
|
403
702
|
* @param {HTMLElement} breadcrumb Source breadcrumb.
|