@limetech/lime-elements 38.33.5 → 38.33.7

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.
Files changed (30) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/cjs/limel-badge.cjs.entry.js +1 -1
  3. package/dist/cjs/limel-badge.cjs.entry.js.map +1 -1
  4. package/dist/cjs/limel-breadcrumbs_8.cjs.entry.js +147 -21
  5. package/dist/cjs/limel-breadcrumbs_8.cjs.entry.js.map +1 -1
  6. package/dist/cjs/limel-tab-bar.cjs.entry.js +1 -1
  7. package/dist/cjs/limel-tab-bar.cjs.entry.js.map +1 -1
  8. package/dist/collection/components/badge/badge.css +1 -0
  9. package/dist/collection/components/menu/menu.js +147 -21
  10. package/dist/collection/components/menu/menu.js.map +1 -1
  11. package/dist/collection/components/tab-bar/tab-bar.css +5 -3
  12. package/dist/collection/test-assets/icons/home.svg +6 -0
  13. package/dist/esm/limel-badge.entry.js +1 -1
  14. package/dist/esm/limel-badge.entry.js.map +1 -1
  15. package/dist/esm/limel-breadcrumbs_8.entry.js +147 -21
  16. package/dist/esm/limel-breadcrumbs_8.entry.js.map +1 -1
  17. package/dist/esm/limel-tab-bar.entry.js +1 -1
  18. package/dist/esm/limel-tab-bar.entry.js.map +1 -1
  19. package/dist/lime-elements/lime-elements.esm.js +1 -1
  20. package/dist/lime-elements/{p-eb121716.entry.js → p-033a0aa9.entry.js} +4 -4
  21. package/dist/lime-elements/p-033a0aa9.entry.js.map +1 -0
  22. package/dist/lime-elements/p-18256ad9.entry.js +2 -0
  23. package/dist/lime-elements/p-18256ad9.entry.js.map +1 -0
  24. package/dist/lime-elements/{p-d80e776d.entry.js → p-407a0e61.entry.js} +2 -2
  25. package/dist/lime-elements/{p-d80e776d.entry.js.map → p-407a0e61.entry.js.map} +1 -1
  26. package/dist/types/components/menu/menu.d.ts +39 -24
  27. package/package.json +1 -1
  28. package/dist/lime-elements/p-18a3c28a.entry.js +0 -2
  29. package/dist/lime-elements/p-18a3c28a.entry.js.map +0 -1
  30. package/dist/lime-elements/p-eb121716.entry.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,3 +1,20 @@
1
+ ## [38.33.7](https://github.com/Lundalogik/lime-elements/compare/v38.33.6...v38.33.7) (2025-12-12)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+
7
+ * **menu:** improve keyboard navigation ([eecb117](https://github.com/Lundalogik/lime-elements/commit/eecb11780af9be340b365f1b2f62f77b3133a57b))
8
+
9
+ ## [38.33.6](https://github.com/Lundalogik/lime-elements/compare/v38.33.5...v38.33.6) (2025-12-11)
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+
15
+ * **tab-bar:** allow consumers to override tab's badge background color ([01c8747](https://github.com/Lundalogik/lime-elements/commit/01c8747522d9c323b92db0c254f0e5b38d54a328))
16
+ * **tab-bar:** better icon color in dark mode ([728138f](https://github.com/Lundalogik/lime-elements/commit/728138fdb68d1b8d584ebe9e0f651157cf498675))
17
+
1
18
  ## [38.33.5](https://github.com/Lundalogik/lime-elements/compare/v38.33.4...v38.33.5) (2025-12-11)
2
19
 
3
20
 
@@ -6,7 +6,7 @@ const index = require('./index-174a078a.js');
6
6
  const format = require('./format-c8759d02.js');
7
7
  require('./_commonjsHelpers-a5111d61.js');
8
8
 
9
- const badgeCss = "@charset \"UTF-8\";:host([hidden]){display:none}:host(limel-badge){--limel-min-badge-size:1rem;display:inline-flex;justify-content:center;align-items:center;flex-shrink:0;min-height:var(--limel-min-badge-size);min-width:var(--limel-min-badge-size)}span{cursor:default;box-sizing:border-box;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;text-align:center;font-size:0.6875rem;line-height:var(--limel-min-badge-size);color:var(--badge-text-color, rgb(var(--contrast-1200)));border-radius:var(--limel-min-badge-size);max-height:var(--limel-min-badge-size);min-width:0.5rem;min-height:0.5rem;background-color:var(--badge-background-color, rgb(var(--contrast-500)))}span:not(:empty){min-width:var(--limel-min-badge-size);max-width:var(--badge-max-width, 2.75rem);padding:0 0.28125rem}:host(.has-large-label) span{cursor:help}";
9
+ const badgeCss = "@charset \"UTF-8\";:host([hidden]){display:none}:host(limel-badge){--limel-min-badge-size:1rem;display:inline-flex;justify-content:center;align-items:center;flex-shrink:0;min-height:var(--limel-min-badge-size);min-width:var(--limel-min-badge-size);border-radius:var(--limel-min-badge-size)}span{cursor:default;box-sizing:border-box;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;text-align:center;font-size:0.6875rem;line-height:var(--limel-min-badge-size);color:var(--badge-text-color, rgb(var(--contrast-1200)));border-radius:var(--limel-min-badge-size);max-height:var(--limel-min-badge-size);min-width:0.5rem;min-height:0.5rem;background-color:var(--badge-background-color, rgb(var(--contrast-500)))}span:not(:empty){min-width:var(--limel-min-badge-size);max-width:var(--badge-max-width, 2.75rem);padding:0 0.28125rem}:host(.has-large-label) span{cursor:help}";
10
10
 
11
11
  const Badge = class {
12
12
  constructor(hostRef) {
@@ -1 +1 @@
1
- {"file":"limel-badge.entry.cjs.js","mappings":";;;;;;;;AAAA,MAAM,QAAQ,GAAG,i0BAAi0B;;MCgBr0B,KAAK;;;;;EAUP,MAAM;IACT,QACIA,QAACC,UAAI,IACD,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,KAAK,GAAG,EAAE,EAC5C,KAAK,EAAE;QACH,iBAAiB,EAAE,IAAI,CAAC,YAAY,EAAE;OACzC,IAEDD,sBAAO,IAAI,CAAC,WAAW,EAAE,CAAQ,CAC9B,EACT;GACL;EAEO,WAAW;IACf,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE;MAChC,OAAOE,iBAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;KACjC;IAED,OAAO,IAAI,CAAC,KAAK,CAAC;GACrB;EAEO,YAAY;IAChB,MAAM,iBAAiB,GAAG,GAAG,CAAC;IAC9B,MAAM,gBAAgB,GAAG,CAAC,CAAC;IAC3B,IACI,CAAC,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ;MAC3B,IAAI,CAAC,KAAK,GAAG,iBAAiB;OACjC,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ;QAC3B,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,gBAAgB,CAAC,EAC3C;MACE,OAAO,IAAI,CAAC;KACf;GACJ;;;;;;","names":["h","Host","abbreviate"],"sources":["./src/components/badge/badge.scss?tag=limel-badge&encapsulation=shadow","./src/components/badge/badge.tsx"],"sourcesContent":["@use '../../style/functions';\n@use '../../style/mixins';\n\n/**\n * @prop --badge-background-color: badge background color\n * @prop --badge-text-color: badge text color\n * @prop --badge-max-width: maximum width of the badge, before its text gets truncated\n */\n\n:host([hidden]) {\n display: none;\n}\n\n:host(limel-badge) {\n --limel-min-badge-size: 1rem;\n display: inline-flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 0;\n min-height: var(--limel-min-badge-size);\n min-width: var(--limel-min-badge-size);\n}\n\nspan {\n cursor: default;\n box-sizing: border-box;\n\n @include mixins.truncate-text;\n text-align: center;\n font-size: functions.pxToRem(11);\n line-height: var(--limel-min-badge-size);\n\n color: var(--badge-text-color, rgb(var(--contrast-1200)));\n\n border-radius: var(--limel-min-badge-size);\n max-height: var(--limel-min-badge-size);\n min-width: 0.5rem;\n min-height: 0.5rem;\n\n background-color: var(--badge-background-color, rgb(var(--contrast-500)));\n\n &:not(:empty) {\n min-width: var(\n --limel-min-badge-size\n ); // ensures that a badge with only one character rendered as perfect circle\n max-width: var(--badge-max-width, 2.75rem);\n padding: 0 functions.pxToRem(4.5);\n }\n}\n\n:host(.has-large-label) {\n span {\n cursor: help;\n }\n}\n","import { Component, Prop, h, Host } from '@stencil/core';\nimport { abbreviate } from './format';\n\n/**\n * The Badge component can be used to display a notification badge,\n * optionally with a number or a text label.\n *\n * @exampleComponent limel-example-badge\n * @exampleComponent limel-example-badge-number\n * @exampleComponent limel-example-badge-string\n */\n@Component({\n tag: 'limel-badge',\n styleUrl: 'badge.scss',\n shadow: true,\n})\nexport class Badge {\n /**\n * Label to display in the badge.\n * Numeric labels larger than 999 will be rounded and abbreviated.\n * String labels get truncated if their length is longer than\n * six characters.\n */\n @Prop({ reflect: true })\n public label?: number | string;\n\n public render() {\n return (\n <Host\n title={this.labelIsLarge() ? this.label : ''}\n class={{\n 'has-large-label': this.labelIsLarge(),\n }}\n >\n <span>{this.renderLabel()}</span>\n </Host>\n );\n }\n\n private renderLabel() {\n if (typeof this.label === 'number') {\n return abbreviate(this.label);\n }\n\n return this.label;\n }\n\n private labelIsLarge() {\n const largeNumericLabel = 999;\n const largeStringLabel = 6;\n if (\n (typeof this.label === 'number' &&\n this.label > largeNumericLabel) ||\n (typeof this.label === 'string' &&\n this.label.length > largeStringLabel)\n ) {\n return true;\n }\n }\n}\n"],"version":3}
1
+ {"file":"limel-badge.entry.cjs.js","mappings":";;;;;;;;AAAA,MAAM,QAAQ,GAAG,22BAA22B;;MCgB/2B,KAAK;;;;;EAUP,MAAM;IACT,QACIA,QAACC,UAAI,IACD,KAAK,EAAE,IAAI,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,KAAK,GAAG,EAAE,EAC5C,KAAK,EAAE;QACH,iBAAiB,EAAE,IAAI,CAAC,YAAY,EAAE;OACzC,IAEDD,sBAAO,IAAI,CAAC,WAAW,EAAE,CAAQ,CAC9B,EACT;GACL;EAEO,WAAW;IACf,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE;MAChC,OAAOE,iBAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;KACjC;IAED,OAAO,IAAI,CAAC,KAAK,CAAC;GACrB;EAEO,YAAY;IAChB,MAAM,iBAAiB,GAAG,GAAG,CAAC;IAC9B,MAAM,gBAAgB,GAAG,CAAC,CAAC;IAC3B,IACI,CAAC,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ;MAC3B,IAAI,CAAC,KAAK,GAAG,iBAAiB;OACjC,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ;QAC3B,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,gBAAgB,CAAC,EAC3C;MACE,OAAO,IAAI,CAAC;KACf;GACJ;;;;;;","names":["h","Host","abbreviate"],"sources":["./src/components/badge/badge.scss?tag=limel-badge&encapsulation=shadow","./src/components/badge/badge.tsx"],"sourcesContent":["@use '../../style/functions';\n@use '../../style/mixins';\n\n/**\n * @prop --badge-background-color: badge background color\n * @prop --badge-text-color: badge text color\n * @prop --badge-max-width: maximum width of the badge, before its text gets truncated\n */\n\n:host([hidden]) {\n display: none;\n}\n\n:host(limel-badge) {\n --limel-min-badge-size: 1rem;\n display: inline-flex;\n justify-content: center;\n align-items: center;\n flex-shrink: 0;\n min-height: var(--limel-min-badge-size);\n min-width: var(--limel-min-badge-size);\n border-radius: var(--limel-min-badge-size);\n}\n\nspan {\n cursor: default;\n box-sizing: border-box;\n\n @include mixins.truncate-text;\n text-align: center;\n font-size: functions.pxToRem(11);\n line-height: var(--limel-min-badge-size);\n\n color: var(--badge-text-color, rgb(var(--contrast-1200)));\n\n border-radius: var(--limel-min-badge-size);\n max-height: var(--limel-min-badge-size);\n min-width: 0.5rem;\n min-height: 0.5rem;\n\n background-color: var(--badge-background-color, rgb(var(--contrast-500)));\n\n &:not(:empty) {\n min-width: var(\n --limel-min-badge-size\n ); // ensures that a badge with only one character rendered as perfect circle\n max-width: var(--badge-max-width, 2.75rem);\n padding: 0 functions.pxToRem(4.5);\n }\n}\n\n:host(.has-large-label) {\n span {\n cursor: help;\n }\n}\n","import { Component, Prop, h, Host } from '@stencil/core';\nimport { abbreviate } from './format';\n\n/**\n * The Badge component can be used to display a notification badge,\n * optionally with a number or a text label.\n *\n * @exampleComponent limel-example-badge\n * @exampleComponent limel-example-badge-number\n * @exampleComponent limel-example-badge-string\n */\n@Component({\n tag: 'limel-badge',\n styleUrl: 'badge.scss',\n shadow: true,\n})\nexport class Badge {\n /**\n * Label to display in the badge.\n * Numeric labels larger than 999 will be rounded and abbreviated.\n * String labels get truncated if their length is longer than\n * six characters.\n */\n @Prop({ reflect: true })\n public label?: number | string;\n\n public render() {\n return (\n <Host\n title={this.labelIsLarge() ? this.label : ''}\n class={{\n 'has-large-label': this.labelIsLarge(),\n }}\n >\n <span>{this.renderLabel()}</span>\n </Host>\n );\n }\n\n private renderLabel() {\n if (typeof this.label === 'number') {\n return abbreviate(this.label);\n }\n\n return this.label;\n }\n\n private labelIsLarge() {\n const largeNumericLabel = 999;\n const largeStringLabel = 6;\n if (\n (typeof this.label === 'number' &&\n this.label > largeNumericLabel) ||\n (typeof this.label === 'string' &&\n this.label.length > largeStringLabel)\n ) {\n return true;\n }\n }\n}\n"],"version":3}
@@ -2514,10 +2514,10 @@ const Menu = class {
2514
2514
  if (breadcrumbsItems.length === 0) {
2515
2515
  return;
2516
2516
  }
2517
- return (index.h("limel-breadcrumbs", { style: {
2517
+ return (index.h("limel-breadcrumbs", { ref: this.setBreadcrumbsElement, style: {
2518
2518
  'border-bottom': 'solid 1px rgb(var(--contrast-500))',
2519
2519
  'flex-shrink': '0',
2520
- }, onSelect: this.handleBreadcrumbsSelect, items: breadcrumbsItems }));
2520
+ }, onSelect: this.handleBreadcrumbsSelect, onKeyDown: this.handleBreadcrumbsKeyDown, items: breadcrumbsItems }));
2521
2521
  };
2522
2522
  this.handleBreadcrumbsSelect = (event) => {
2523
2523
  if (!event.detail.menuItem) {
@@ -2582,8 +2582,8 @@ const Menu = class {
2582
2582
  this.loadingSubItems = false;
2583
2583
  };
2584
2584
  // Key handler for the input search field
2585
- // Will change focus to the first/last item in the dropdown
2586
- // list to enable selection with the keyboard
2585
+ // Will change focus to breadcrumbs (if present) or the first/last item
2586
+ // in the dropdown list to enable selection with the keyboard
2587
2587
  this.handleInputKeyDown = (event) => {
2588
2588
  const isForwardTab = event.key === keycodes.TAB &&
2589
2589
  !event.altKey &&
@@ -2594,26 +2594,58 @@ const Menu = class {
2594
2594
  if (!isForwardTab && !isUp && !isDown) {
2595
2595
  return;
2596
2596
  }
2597
- if (!this.list) {
2598
- return;
2599
- }
2600
2597
  event.stopPropagation();
2601
2598
  event.preventDefault();
2602
2599
  if (isForwardTab || isDown) {
2603
- const listItems = this.list.shadowRoot.querySelectorAll('.mdc-deprecated-list-item');
2604
- const listElement = listItems[0];
2605
- listElement === null || listElement === void 0 ? void 0 : listElement.focus();
2600
+ if (this.focusBreadcrumbs()) {
2601
+ return;
2602
+ }
2603
+ this.focusFirstListItem();
2606
2604
  return;
2607
2605
  }
2608
2606
  if (isUp) {
2609
- const listItems = this.list.shadowRoot.querySelectorAll('.mdc-deprecated-list-item');
2610
- const listElement = [...listItems].at(-1);
2611
- listElement === null || listElement === void 0 ? void 0 : listElement.focus();
2607
+ // Focus the last list item (wrapping behavior)
2608
+ this.focusLastListItem();
2612
2609
  }
2613
2610
  };
2614
- // Key handler for the menu list
2611
+ // Key handler for the menu list (capture phase)
2612
+ // Handles Up arrow on first item and Down arrow on last item
2613
+ // Must run in capture phase to intercept before MDC Menu wraps focus
2614
+ // Only intercepts when there's a search input or breadcrumbs to navigate to
2615
+ this.handleListKeyDownCapture = (event) => {
2616
+ const isUp = event.key === keycodes.ARROW_UP;
2617
+ const isDown = event.key === keycodes.ARROW_DOWN;
2618
+ if (!isUp && !isDown) {
2619
+ return;
2620
+ }
2621
+ // Up on first item: go to breadcrumbs or search input (if they exist)
2622
+ if (isUp && this.isFirstListItemFocused()) {
2623
+ // Try to focus breadcrumbs first
2624
+ if (this.focusBreadcrumbs()) {
2625
+ event.stopPropagation();
2626
+ event.preventDefault();
2627
+ return;
2628
+ }
2629
+ // Then try search input
2630
+ if (this.searchInput) {
2631
+ event.stopPropagation();
2632
+ event.preventDefault();
2633
+ this.searchInput.focus();
2634
+ }
2635
+ // If neither exists, let MDC Menu handle wrap-around
2636
+ return;
2637
+ }
2638
+ // Down on last item: go to search input (if it exists)
2639
+ if (isDown && this.isLastListItemFocused() && this.searchInput) {
2640
+ event.stopPropagation();
2641
+ event.preventDefault();
2642
+ this.searchInput.focus();
2643
+ }
2644
+ // If no search input, let MDC Menu handle wrap-around
2645
+ };
2646
+ // Key handler for the menu list (bubble phase)
2615
2647
  // Will change focus to the search field if using shift+tab
2616
- // And can go forward/back with righ/left arrow keys
2648
+ // And can go forward/back with right/left arrow keys
2617
2649
  this.handleMenuKeyDown = (event) => {
2618
2650
  var _a;
2619
2651
  const isBackwardTab = event.key === keycodes.TAB &&
@@ -2629,8 +2661,9 @@ const Menu = class {
2629
2661
  event.stopPropagation();
2630
2662
  event.preventDefault();
2631
2663
  (_a = this.searchInput) === null || _a === void 0 ? void 0 : _a.focus();
2664
+ return;
2632
2665
  }
2633
- else if (!this.gridLayout) {
2666
+ if (!this.gridLayout && (isLeft || isRight)) {
2634
2667
  const currentItem = this.getCurrentItem();
2635
2668
  event.stopPropagation();
2636
2669
  event.preventDefault();
@@ -2642,17 +2675,43 @@ const Menu = class {
2642
2675
  }
2643
2676
  }
2644
2677
  };
2678
+ // Key handler for breadcrumbs
2679
+ // Up arrow: focus search input
2680
+ // Down arrow: focus first list item
2681
+ this.handleBreadcrumbsKeyDown = (event) => {
2682
+ var _a;
2683
+ const isUp = event.key === keycodes.ARROW_UP;
2684
+ const isDown = event.key === keycodes.ARROW_DOWN;
2685
+ if (!isUp && !isDown) {
2686
+ return;
2687
+ }
2688
+ event.stopPropagation();
2689
+ event.preventDefault();
2690
+ if (isUp) {
2691
+ (_a = this.searchInput) === null || _a === void 0 ? void 0 : _a.focus();
2692
+ return;
2693
+ }
2694
+ if (isDown) {
2695
+ this.focusFirstListItem();
2696
+ }
2697
+ };
2645
2698
  this.clearSearch = () => {
2646
2699
  this.searchValue = '';
2647
2700
  this.searchResults = null;
2648
2701
  this.loadingSubItems = false;
2649
2702
  };
2650
2703
  this.getCurrentItem = () => {
2651
- var _a, _b, _c;
2652
- const activeItem = (_b = (_a = this.list) === null || _a === void 0 ? void 0 : _a.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('[role="menuitem"][tabindex="0"]');
2653
- const attrIndex = (_c = activeItem === null || activeItem === void 0 ? void 0 : activeItem.attributes) === null || _c === void 0 ? void 0 : _c.getNamedItem('data-index');
2654
- const dataIndex = Number.parseInt((attrIndex === null || attrIndex === void 0 ? void 0 : attrIndex.value) || '0', 10);
2655
- return this.visibleItems[dataIndex];
2704
+ var _a, _b, _c, _d, _e, _f;
2705
+ let menuElement = (_c = (_b = (_a = this.list) === null || _a === void 0 ? void 0 : _a.shadowRoot) === null || _b === void 0 ? void 0 : _b.activeElement) !== null && _c !== void 0 ? _c : null;
2706
+ if (menuElement && menuElement.getAttribute('role') !== 'menuitem') {
2707
+ menuElement = menuElement.closest('[role="menuitem"]');
2708
+ }
2709
+ if (!menuElement) {
2710
+ menuElement = (_e = (_d = this.list) === null || _d === void 0 ? void 0 : _d.shadowRoot) === null || _e === void 0 ? void 0 : _e.querySelector('[role="menuitem"][tabindex="0"]');
2711
+ }
2712
+ const dataIndex = Number.parseInt((_f = menuElement === null || menuElement === void 0 ? void 0 : menuElement.dataset.index) !== null && _f !== void 0 ? _f : '0', 10);
2713
+ const item = this.visibleItems[dataIndex];
2714
+ return (item !== null && item !== void 0 ? item : this.visibleItems[0]);
2656
2715
  };
2657
2716
  this.goForward = (currentItem) => {
2658
2717
  this.handleSelect(currentItem, false);
@@ -2745,7 +2804,13 @@ const Menu = class {
2745
2804
  this.handleSelect(event.detail);
2746
2805
  };
2747
2806
  this.setListElement = (element) => {
2807
+ if (this.list) {
2808
+ this.list.removeEventListener('keydown', this.handleListKeyDownCapture, true);
2809
+ }
2748
2810
  this.list = element;
2811
+ if (this.list) {
2812
+ this.list.addEventListener('keydown', this.handleListKeyDownCapture, true);
2813
+ }
2749
2814
  };
2750
2815
  this.setFocus = () => {
2751
2816
  setTimeout(() => {
@@ -2771,6 +2836,67 @@ const Menu = class {
2771
2836
  this.setSearchElement = (element) => {
2772
2837
  this.searchInput = element;
2773
2838
  };
2839
+ this.setBreadcrumbsElement = (element) => {
2840
+ this.breadcrumbs = element;
2841
+ };
2842
+ /**
2843
+ * Focuses the first focusable element inside breadcrumbs.
2844
+ * Returns true if breadcrumbs exist and were focused,
2845
+ * false otherwise.
2846
+ */
2847
+ this.focusBreadcrumbs = () => {
2848
+ var _a;
2849
+ if (!this.breadcrumbs) {
2850
+ return false;
2851
+ }
2852
+ const focusableElement = (_a = this.breadcrumbs.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('button, a');
2853
+ if (focusableElement) {
2854
+ focusableElement.focus();
2855
+ return true;
2856
+ }
2857
+ return false;
2858
+ };
2859
+ this.focusFirstListItem = () => {
2860
+ const listItems = this.getListItems();
2861
+ const firstItem = listItems === null || listItems === void 0 ? void 0 : listItems[0];
2862
+ firstItem === null || firstItem === void 0 ? void 0 : firstItem.focus();
2863
+ };
2864
+ this.focusLastListItem = () => {
2865
+ const listItems = this.getListItems();
2866
+ const lastItem = listItems === null || listItems === void 0 ? void 0 : listItems.at(-1);
2867
+ lastItem === null || lastItem === void 0 ? void 0 : lastItem.focus();
2868
+ };
2869
+ this.isFirstListItemFocused = () => {
2870
+ var _a;
2871
+ const listItems = this.getListItems();
2872
+ if (!listItems) {
2873
+ return false;
2874
+ }
2875
+ const firstItem = listItems[0];
2876
+ const activeElement = (_a = this.list.shadowRoot) === null || _a === void 0 ? void 0 : _a.activeElement;
2877
+ return firstItem === activeElement;
2878
+ };
2879
+ this.isLastListItemFocused = () => {
2880
+ var _a;
2881
+ const listItems = this.getListItems();
2882
+ if (!listItems) {
2883
+ return false;
2884
+ }
2885
+ const lastItem = listItems.at(-1);
2886
+ const activeElement = (_a = this.list.shadowRoot) === null || _a === void 0 ? void 0 : _a.activeElement;
2887
+ return lastItem === activeElement;
2888
+ };
2889
+ this.getListItems = () => {
2890
+ var _a;
2891
+ if (!this.list) {
2892
+ return null;
2893
+ }
2894
+ const items = (_a = this.list.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelectorAll('.mdc-deprecated-list-item');
2895
+ if (!(items === null || items === void 0 ? void 0 : items.length)) {
2896
+ return null;
2897
+ }
2898
+ return [...items];
2899
+ };
2774
2900
  this.focusMenuItem = () => {
2775
2901
  var _a;
2776
2902
  if (!this.list) {