le-kit 0.1.18 → 0.2.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.
Files changed (173) hide show
  1. package/dist/cjs/index-pT2cVC5w.js.map +1 -1
  2. package/dist/cjs/le-button_13.cjs.entry.js +24 -28
  3. package/dist/cjs/le-card.cjs.entry.js +1 -1
  4. package/dist/cjs/le-combobox.cjs.entry.js +1 -1
  5. package/dist/cjs/le-header-placeholder.cjs.entry.js +1 -1
  6. package/dist/cjs/le-icon.cjs.entry.js +108 -0
  7. package/dist/cjs/le-kit.cjs.js +1 -1
  8. package/dist/cjs/le-multiselect.cjs.entry.js +3 -3
  9. package/dist/cjs/le-navigation.cjs.entry.js +499 -0
  10. package/dist/cjs/le-number-input.cjs.entry.js +1 -1
  11. package/dist/cjs/le-round-progress.cjs.entry.js +1 -1
  12. package/dist/cjs/le-segmented-control.cjs.entry.js +1 -1
  13. package/dist/cjs/le-stack.cjs.entry.js +1 -1
  14. package/dist/cjs/le-tab-bar.cjs.entry.js +1 -1
  15. package/dist/cjs/le-tab-panel.cjs.entry.js +2 -2
  16. package/dist/cjs/le-tab.cjs.entry.js +1 -1
  17. package/dist/cjs/le-tabs.cjs.entry.js +2 -2
  18. package/dist/cjs/le-tag.cjs.entry.js +1 -1
  19. package/dist/cjs/le-turntable.cjs.entry.js +1 -1
  20. package/dist/cjs/loader.cjs.js +1 -1
  21. package/dist/collection/assets/icons/chevron-down.svg +3 -0
  22. package/dist/collection/collection-manifest.json +2 -0
  23. package/dist/collection/components/le-button/le-button.css +24 -24
  24. package/dist/collection/components/le-button/le-button.js +2 -2
  25. package/dist/collection/components/le-button/le-button.js.map +1 -1
  26. package/dist/collection/components/le-card/le-card.js +1 -1
  27. package/dist/collection/components/le-checkbox/le-checkbox.js +1 -1
  28. package/dist/collection/components/le-collapse/le-collapse.css +3 -3
  29. package/dist/collection/components/le-collapse/le-collapse.js +11 -15
  30. package/dist/collection/components/le-collapse/le-collapse.js.map +1 -1
  31. package/dist/collection/components/le-combobox/le-combobox.js +1 -1
  32. package/dist/collection/components/le-current-heading/le-current-heading.js +1 -1
  33. package/dist/collection/components/le-dropdown-base/le-dropdown-base.js +1 -1
  34. package/dist/collection/components/le-header/le-header.js +2 -2
  35. package/dist/collection/components/le-header-placeholder/le-header-placeholder.js +1 -1
  36. package/dist/collection/components/le-icon/le-icon.css +13 -0
  37. package/dist/collection/components/le-icon/le-icon.js +168 -0
  38. package/dist/collection/components/le-icon/le-icon.js.map +1 -0
  39. package/dist/collection/components/le-multiselect/le-multiselect.js +3 -3
  40. package/dist/collection/components/le-navigation/le-navigation.css +323 -0
  41. package/dist/collection/components/le-navigation/le-navigation.js +742 -0
  42. package/dist/collection/components/le-navigation/le-navigation.js.map +1 -0
  43. package/dist/collection/components/le-number-input/le-number-input.js +1 -1
  44. package/dist/collection/components/le-popover/le-popover.js +3 -3
  45. package/dist/collection/components/le-popup/le-popup.js +7 -7
  46. package/dist/collection/components/le-round-progress/le-round-progress.js +1 -1
  47. package/dist/collection/components/le-scroll-progress/le-scroll-progress.js +1 -1
  48. package/dist/collection/components/le-segmented-control/le-segmented-control.js +1 -1
  49. package/dist/collection/components/le-select/le-select.js +2 -2
  50. package/dist/collection/components/le-slot/le-slot.js +1 -1
  51. package/dist/collection/components/le-stack/le-stack.js +1 -1
  52. package/dist/collection/components/le-string-input/le-string-input.js +2 -2
  53. package/dist/collection/components/le-tab/le-tab.js +1 -1
  54. package/dist/collection/components/le-tab-bar/le-tab-bar.js +1 -1
  55. package/dist/collection/components/le-tab-panel/le-tab-panel.js +2 -2
  56. package/dist/collection/components/le-tabs/le-tabs.js +2 -2
  57. package/dist/collection/components/le-tag/le-tag.js +1 -1
  58. package/dist/collection/components/le-turntable/le-turntable.js +1 -1
  59. package/dist/collection/dist/components/assets/custom-elements.json +2149 -1404
  60. package/dist/collection/dist/components/assets/icons/chevron-down.json +13 -0
  61. package/dist/collection/dist/components/assets/icons/chevron-down.svg +3 -0
  62. package/dist/collection/types/options.js.map +1 -1
  63. package/dist/components/assets/custom-elements.json +2149 -1404
  64. package/dist/components/assets/icons/chevron-down.json +13 -0
  65. package/dist/components/assets/icons/chevron-down.svg +3 -0
  66. package/dist/components/index.js.map +1 -1
  67. package/dist/components/le-button2.js +8 -8
  68. package/dist/components/le-button2.js.map +1 -1
  69. package/dist/components/le-card.js +1 -1
  70. package/dist/components/le-collapse.js +1 -137
  71. package/dist/components/le-collapse.js.map +1 -1
  72. package/dist/components/le-collapse2.js +138 -0
  73. package/dist/components/le-collapse2.js.map +1 -0
  74. package/dist/components/le-combobox.js +1 -1
  75. package/dist/components/le-current-heading.js +1 -1
  76. package/dist/components/le-dropdown-base2.js +1 -1
  77. package/dist/components/le-header-placeholder.js +1 -1
  78. package/dist/components/le-header.js +2 -2
  79. package/dist/components/le-icon.d.ts +11 -0
  80. package/dist/components/le-icon.js +9 -0
  81. package/dist/components/le-icon.js.map +1 -0
  82. package/dist/components/le-icon2.js +133 -0
  83. package/dist/components/le-icon2.js.map +1 -0
  84. package/dist/components/le-multiselect.js +3 -3
  85. package/dist/components/le-navigation.d.ts +11 -0
  86. package/dist/components/le-navigation.js +598 -0
  87. package/dist/components/le-navigation.js.map +1 -0
  88. package/dist/components/le-number-input.js +1 -1
  89. package/dist/components/le-popover2.js +3 -3
  90. package/dist/components/le-round-progress.js +1 -1
  91. package/dist/components/le-scroll-progress.js +1 -1
  92. package/dist/components/le-segmented-control.js +1 -1
  93. package/dist/components/le-stack.js +1 -1
  94. package/dist/components/le-tab-bar.js +1 -1
  95. package/dist/components/le-tab-panel.js +2 -2
  96. package/dist/components/le-tab2.js +1 -1
  97. package/dist/components/le-tabs.js +2 -2
  98. package/dist/components/le-tag2.js +1 -1
  99. package/dist/components/le-turntable.js +1 -1
  100. package/dist/docs.json +515 -27
  101. package/dist/esm/index-CNv6tzAt.js.map +1 -1
  102. package/dist/esm/le-button_13.entry.js +24 -28
  103. package/dist/esm/le-card.entry.js +1 -1
  104. package/dist/esm/le-combobox.entry.js +1 -1
  105. package/dist/esm/le-header-placeholder.entry.js +1 -1
  106. package/dist/esm/le-icon.entry.js +106 -0
  107. package/dist/esm/le-icon.entry.js.map +1 -0
  108. package/dist/esm/le-kit.js +1 -1
  109. package/dist/esm/le-multiselect.entry.js +3 -3
  110. package/dist/esm/le-navigation.entry.js +497 -0
  111. package/dist/esm/le-navigation.entry.js.map +1 -0
  112. package/dist/esm/le-number-input.entry.js +1 -1
  113. package/dist/esm/le-round-progress.entry.js +1 -1
  114. package/dist/esm/le-segmented-control.entry.js +1 -1
  115. package/dist/esm/le-stack.entry.js +1 -1
  116. package/dist/esm/le-tab-bar.entry.js +1 -1
  117. package/dist/esm/le-tab-panel.entry.js +2 -2
  118. package/dist/esm/le-tab.entry.js +1 -1
  119. package/dist/esm/le-tabs.entry.js +2 -2
  120. package/dist/esm/le-tag.entry.js +1 -1
  121. package/dist/esm/le-turntable.entry.js +1 -1
  122. package/dist/esm/loader.js +1 -1
  123. package/dist/le-kit/dist/components/assets/custom-elements.json +2149 -1404
  124. package/dist/le-kit/dist/components/assets/icons/chevron-down.json +13 -0
  125. package/dist/le-kit/dist/components/assets/icons/chevron-down.svg +3 -0
  126. package/dist/le-kit/le-kit.esm.js +1 -1
  127. package/dist/le-kit/{p-b3531106.entry.js → p-0ac4397c.entry.js} +2 -2
  128. package/dist/le-kit/{p-31c3649c.entry.js → p-25a29e69.entry.js} +2 -2
  129. package/dist/le-kit/p-2ec60692.entry.js +2 -0
  130. package/dist/le-kit/{p-269fb44f.entry.js → p-511fbb63.entry.js} +2 -2
  131. package/dist/le-kit/{p-8afe6862.entry.js → p-58120921.entry.js} +2 -2
  132. package/dist/le-kit/{p-c83a1255.entry.js → p-5ceb06d8.entry.js} +2 -2
  133. package/dist/le-kit/p-8c5a8f1e.entry.js +2 -0
  134. package/dist/le-kit/p-8c5a8f1e.entry.js.map +1 -0
  135. package/dist/le-kit/{p-deef1f4d.entry.js → p-9a3bdbe1.entry.js} +2 -2
  136. package/dist/le-kit/p-CNv6tzAt.js.map +1 -1
  137. package/dist/le-kit/{p-e4618b36.entry.js → p-a0d2c580.entry.js} +2 -2
  138. package/dist/le-kit/{p-629c5e13.entry.js → p-a8963634.entry.js} +2 -2
  139. package/dist/le-kit/p-b1dc7e06.entry.js +2 -0
  140. package/dist/le-kit/p-b1dc7e06.entry.js.map +1 -0
  141. package/dist/le-kit/p-bb160082.entry.js +2 -0
  142. package/dist/le-kit/p-bb160082.entry.js.map +1 -0
  143. package/dist/le-kit/{p-7d316315.entry.js → p-de5638c9.entry.js} +2 -2
  144. package/dist/le-kit/{p-d2a5d431.entry.js → p-df9389f0.entry.js} +2 -2
  145. package/dist/le-kit/{p-684adc9f.entry.js → p-e24d3e33.entry.js} +2 -2
  146. package/dist/le-kit/{p-95cf203e.entry.js → p-ec20e438.entry.js} +2 -2
  147. package/dist/le-kit/{p-9ba2bfb3.entry.js → p-f4f2c3e7.entry.js} +2 -2
  148. package/dist/types/components/le-collapse/le-collapse.d.ts +5 -3
  149. package/dist/types/components/le-icon/le-icon.d.ts +28 -0
  150. package/dist/types/components/le-navigation/le-navigation.d.ts +112 -0
  151. package/dist/types/components.d.ts +194 -10
  152. package/dist/types/types/options.d.ts +5 -0
  153. package/package.json +1 -1
  154. package/dist/collection/dist/components/assets/.gitkeep +0 -1
  155. package/dist/components/assets/.gitkeep +0 -1
  156. package/dist/le-kit/dist/components/assets/.gitkeep +0 -1
  157. package/dist/le-kit/p-3829f572.entry.js +0 -2
  158. package/dist/le-kit/p-3829f572.entry.js.map +0 -1
  159. package/dist/le-kit/p-e07d4b78.entry.js +0 -2
  160. /package/dist/le-kit/{p-b3531106.entry.js.map → p-0ac4397c.entry.js.map} +0 -0
  161. /package/dist/le-kit/{p-31c3649c.entry.js.map → p-25a29e69.entry.js.map} +0 -0
  162. /package/dist/le-kit/{p-e07d4b78.entry.js.map → p-2ec60692.entry.js.map} +0 -0
  163. /package/dist/le-kit/{p-269fb44f.entry.js.map → p-511fbb63.entry.js.map} +0 -0
  164. /package/dist/le-kit/{p-8afe6862.entry.js.map → p-58120921.entry.js.map} +0 -0
  165. /package/dist/le-kit/{p-c83a1255.entry.js.map → p-5ceb06d8.entry.js.map} +0 -0
  166. /package/dist/le-kit/{p-deef1f4d.entry.js.map → p-9a3bdbe1.entry.js.map} +0 -0
  167. /package/dist/le-kit/{p-e4618b36.entry.js.map → p-a0d2c580.entry.js.map} +0 -0
  168. /package/dist/le-kit/{p-629c5e13.entry.js.map → p-a8963634.entry.js.map} +0 -0
  169. /package/dist/le-kit/{p-7d316315.entry.js.map → p-de5638c9.entry.js.map} +0 -0
  170. /package/dist/le-kit/{p-d2a5d431.entry.js.map → p-df9389f0.entry.js.map} +0 -0
  171. /package/dist/le-kit/{p-684adc9f.entry.js.map → p-e24d3e33.entry.js.map} +0 -0
  172. /package/dist/le-kit/{p-95cf203e.entry.js.map → p-ec20e438.entry.js.map} +0 -0
  173. /package/dist/le-kit/{p-9ba2bfb3.entry.js.map → p-f4f2c3e7.entry.js.map} +0 -0
@@ -0,0 +1,598 @@
1
+ import { proxyCustomElement, HTMLElement, createEvent, h, Host, transformTag } from '@stencil/core/internal/client';
2
+ import { g as generateId, h as classnames } from './utils.js';
3
+ import { d as defineCustomElement$2, a as defineCustomElement$3, b as defineCustomElement$4, c as defineCustomElement$5, e as defineCustomElement$9, f as defineCustomElement$b, g as defineCustomElement$c } from './le-button2.js';
4
+ import { d as defineCustomElement$a } from './le-collapse2.js';
5
+ import { d as defineCustomElement$8 } from './le-dropdown-base2.js';
6
+ import { d as defineCustomElement$7 } from './le-icon2.js';
7
+ import { d as defineCustomElement$6 } from './le-popover2.js';
8
+
9
+ const leNavigationCss = () => `:host{display:block;--le-nav-radius:var(--le-radius-md);--le-nav-gap:var(--le-spacing-2);--le-nav-item-padding-x:var(--le-spacing-1);--le-nav-item-padding-y:var(--le-spacing-2);--le-nav-item-gap:var(--le-spacing-2);--le-nav-color:var(--le-color-text-primary);--le-nav-muted:var(--le-color-text-secondary);--le-nav-hover-bg:var(--le-color-gray-100);--le-nav-selected-bg:var(--le-color-primary);--le-nav-selected-color:var(--le-color-primary-contrast)}.nav-vertical{display:flex;flex-direction:column;gap:var(--le-nav-gap)}.nav-search{width:100%}.nav-search-input{--le-input-radius:var(--le-radius-md)}.nav-empty{padding:var(--le-spacing-2);color:var(--le-nav-muted);font-size:var(--le-font-size-sm)}.nav-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--le-spacing-1)}.nav-row{display:flex;align-items:stretch;gap:var(--le-spacing-1);border-radius:var(--le-nav-radius)}.nav-row:hover{background:var(--le-nav-hover-bg)}.nav-toggle,.nav-toggle-spacer{box-sizing:border-box;width:var(--le-spacing-4);min-width:var(--le-spacing-4);display:inline-flex;align-items:center;justify-content:center;border:1px solid transparent;border-radius:var(--le-nav-radius);color:inherit}.nav-toggle{background:transparent;cursor:pointer;opacity:0.4}.nav-toggle:hover:not(:disabled){opacity:1}.nav-toggle:focus-visible{outline:2px solid var(--le-color-focus);outline-offset:2px;opacity:1}.nav-chevron{display:inline-block;transition:transform var(--le-transition-fast)}.nav-chevron svg{display:block;width:var(--le-spacing-4);height:var(--le-spacing-4)}.nav-node>div>button>.nav-chevron{transform:rotate(-90deg)}.nav-node.open>div>button>.nav-chevron{transform:rotate(0deg)}.nav-item{flex:1;display:inline-flex;align-items:center;gap:var(--le-nav-item-gap);padding:var(--le-nav-item-padding-y) var(--le-nav-item-padding-x) var(--le-nav-item-padding-y) 0;border-radius:var(--le-nav-radius);border:1px solid transparent;background:transparent;text-decoration:none;color:var(--le-nav-color);font-family:var(--le-font-family-base);font-size:var(--le-font-size-md);line-height:var(--le-line-height-tight);cursor:pointer}.nav-item:focus-visible{outline:2px solid var(--le-color-focus);outline-offset:2px}.nav-node.selected>.nav-row{background:var(--le-nav-selected-bg);color:var(--le-nav-selected-color)}.nav-node.selected>.nav-row>.nav-item{color:inherit}.nav-node.disabled>.nav-row>.nav-item{opacity:0.5;cursor:not-allowed}.nav-text{display:flex;flex-direction:column;min-width:0}.nav-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.nav-description{color:color-mix(in srgb, var(--le-nav-muted) 90%, transparent);font-size:var(--le-font-size-sm);line-height:var(--le-line-height-tight)}.nav-icon{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0}.nav-icon-end{margin-left:auto}.nav-children{margin-top:var(--le-spacing-1)}.nav-horizontal{display:flex;align-items:center;gap:var(--le-spacing-2)}.nav-horizontal-shell{position:relative}.nav-horizontal-measure{position:absolute;left:-10000px;top:-10000px;visibility:hidden;pointer-events:none;display:flex;align-items:center;gap:var(--le-spacing-2);flex-wrap:wrap}.nav-horizontal.wrap{flex-wrap:wrap}.nav-horizontal.nowrap{flex-wrap:nowrap;overflow:hidden}.h-item{display:flex;align-items:center}.h-link{display:inline-flex;align-items:center;gap:var(--le-spacing-2);padding:var(--le-spacing-2) var(--le-spacing-3);border-radius:var(--le-nav-radius);border:1px solid transparent;background:transparent;text-decoration:none;color:var(--le-nav-color);font-family:var(--le-font-family-base);font-size:var(--le-font-size-md);cursor:pointer}.h-link:hover{background:var(--le-nav-hover-bg)}.h-link:focus-visible{outline:2px solid var(--le-color-focus);outline-offset:2px}.h-link.disabled,.h-trigger.disabled{opacity:0.5;pointer-events:none}.h-link.selected,.h-trigger.selected{background:var(--le-nav-selected-bg);color:var(--le-nav-selected-color)}.h-label{white-space:nowrap}.h-trigger{display:inline-flex;align-items:center;gap:var(--le-spacing-1);border-radius:var(--le-nav-radius)}.h-submenu-toggle{width:var(--le-spacing-3);height:var(--le-spacing-3);display:inline-flex;align-items:center;justify-content:center;border:1px solid transparent;border-radius:var(--le-nav-radius);background:transparent;color:currentColor;cursor:pointer}.h-submenu-toggle:hover{background:var(--le-nav-hover-bg)}.more-trigger-wrap{display:flex;align-items:center}.more-trigger-wrap.is-measure{position:absolute;visibility:hidden;pointer-events:none}.more-trigger-wrap.is-visible{position:static;visibility:visible}.overflow-trigger{display:inline-flex;align-items:center;justify-content:center;gap:var(--le-spacing-2);padding:var(--le-spacing-2) var(--le-spacing-3);border-radius:var(--le-nav-radius);border:1px solid transparent;background:transparent;color:var(--le-nav-color);cursor:pointer;font-family:var(--le-font-family-base);font-size:var(--le-font-size-md)}.overflow-trigger:hover{background:var(--le-nav-hover-bg)}.overflow-trigger:focus-visible{outline:2px solid var(--le-color-focus);outline-offset:2px}le-popover::part(content){padding:var(--le-spacing-1)}`;
10
+
11
+ const LeNavigation$1 = /*@__PURE__*/ proxyCustomElement(class LeNavigation extends HTMLElement {
12
+ constructor(registerHost) {
13
+ super();
14
+ if (registerHost !== false) {
15
+ this.__registerHost();
16
+ }
17
+ this.__attachShadow();
18
+ this.leNavItemSelect = createEvent(this, "leNavItemSelect", 7);
19
+ this.leNavItemToggle = createEvent(this, "leNavItemToggle", 7);
20
+ }
21
+ get el() { return this; }
22
+ /**
23
+ * Navigation items.
24
+ * Can be passed as an array or JSON string (same pattern as le-select).
25
+ */
26
+ items = [];
27
+ /**
28
+ * Layout orientation.
29
+ */
30
+ orientation = 'vertical';
31
+ /**
32
+ * Horizontal wrapping behavior.
33
+ * If false, overflow behavior depends on `overflowMode`.
34
+ */
35
+ wrap = true;
36
+ /**
37
+ * Overflow behavior for horizontal, non-wrapping menus.
38
+ * - more: moves overflow items into a "More" popover
39
+ * - hamburger: turns the whole nav into a hamburger popover
40
+ */
41
+ overflowMode = 'more';
42
+ /**
43
+ * Enables a search input for the vertical navigation.
44
+ */
45
+ searchable = false;
46
+ /**
47
+ * Placeholder text for the search input.
48
+ */
49
+ searchPlaceholder = 'Search...';
50
+ /**
51
+ * Text shown when no items match the filter.
52
+ */
53
+ emptyText = 'No results found';
54
+ /**
55
+ * Whether submenu popovers should include a filter input.
56
+ */
57
+ submenuSearchable = false;
58
+ /**
59
+ * Fired when a navigation item is activated.
60
+ *
61
+ * This event is cancelable. Call `event.preventDefault()` to prevent
62
+ * default browser navigation and implement custom routing.
63
+ */
64
+ leNavItemSelect;
65
+ /**
66
+ * Fired when a tree branch is toggled.
67
+ */
68
+ leNavItemToggle;
69
+ searchQuery = '';
70
+ openState = {};
71
+ overflowIds = [];
72
+ hamburgerActive = false;
73
+ submenuQueries = {};
74
+ navContainerEl;
75
+ measureEl;
76
+ measureMoreEl;
77
+ topItemEls = new Map();
78
+ popoverRefs = new Map();
79
+ resizeObserver;
80
+ instanceId = generateId('le-nav');
81
+ handleLayoutInputsChange() {
82
+ this.scheduleOverflowRecalc();
83
+ }
84
+ componentDidLoad() {
85
+ this.setupResizeObserver();
86
+ this.scheduleOverflowRecalc();
87
+ }
88
+ disconnectedCallback() {
89
+ this.resizeObserver?.disconnect();
90
+ this.resizeObserver = undefined;
91
+ }
92
+ componentDidRender() {
93
+ // In case refs change after render.
94
+ this.scheduleOverflowRecalc();
95
+ }
96
+ setupResizeObserver() {
97
+ this.resizeObserver?.disconnect();
98
+ if (typeof ResizeObserver === 'undefined')
99
+ return;
100
+ this.resizeObserver = new ResizeObserver(() => this.computeOverflow());
101
+ this.observeContainer(this.navContainerEl);
102
+ }
103
+ observeContainer(el) {
104
+ if (!this.resizeObserver)
105
+ return;
106
+ this.resizeObserver.disconnect();
107
+ if (el)
108
+ this.resizeObserver.observe(el);
109
+ }
110
+ scheduleOverflowRecalc() {
111
+ // Avoid work for vertical layout.
112
+ if (this.orientation !== 'horizontal')
113
+ return;
114
+ // Ensure it runs after layout.
115
+ requestAnimationFrame(() => this.computeOverflow());
116
+ }
117
+ get parsedItems() {
118
+ if (typeof this.items === 'string') {
119
+ try {
120
+ return JSON.parse(this.items);
121
+ }
122
+ catch {
123
+ return [];
124
+ }
125
+ }
126
+ return this.items;
127
+ }
128
+ getItemId(item, path) {
129
+ return item.id ?? `${this.instanceId}:${path}`;
130
+ }
131
+ getChildItems(item) {
132
+ return Array.isArray(item.children) ? item.children : [];
133
+ }
134
+ isOpen(item, id) {
135
+ const fromState = this.openState[id];
136
+ if (typeof fromState === 'boolean')
137
+ return fromState;
138
+ return !!item.open;
139
+ }
140
+ setOpen(id, open) {
141
+ if (this.openState[id] === open)
142
+ return;
143
+ this.openState = {
144
+ ...this.openState,
145
+ [id]: open,
146
+ };
147
+ }
148
+ matchesQuery(option, query) {
149
+ if (!query)
150
+ return true;
151
+ const q = query.toLowerCase();
152
+ return (option.label.toLowerCase().includes(q) ||
153
+ (option.description?.toLowerCase().includes(q) ?? false));
154
+ }
155
+ filterTree(items, query, pathPrefix, autoOpen) {
156
+ if (!query)
157
+ return items;
158
+ const result = [];
159
+ items.forEach((item, index) => {
160
+ const path = pathPrefix ? `${pathPrefix}.${index}` : String(index);
161
+ const id = this.getItemId(item, path);
162
+ const children = this.getChildItems(item);
163
+ const filteredChildren = this.filterTree(children, query, path, autoOpen);
164
+ const selfMatch = this.matchesQuery(item, query);
165
+ const childMatch = filteredChildren.length > 0;
166
+ if (selfMatch || childMatch) {
167
+ if (childMatch) {
168
+ autoOpen.add(id);
169
+ }
170
+ if (childMatch && filteredChildren !== children) {
171
+ result.push({
172
+ ...item,
173
+ children: filteredChildren,
174
+ });
175
+ }
176
+ else {
177
+ result.push(item);
178
+ }
179
+ }
180
+ });
181
+ return result;
182
+ }
183
+ handleItemSelect = (e, item, id) => {
184
+ if (item.disabled) {
185
+ e.preventDefault();
186
+ e.stopPropagation();
187
+ return;
188
+ }
189
+ const emitted = this.leNavItemSelect.emit({
190
+ item,
191
+ id,
192
+ href: item.href,
193
+ originalEvent: e,
194
+ });
195
+ if (emitted.defaultPrevented) {
196
+ e.preventDefault();
197
+ }
198
+ };
199
+ handleToggle = (e, item, id) => {
200
+ e.preventDefault();
201
+ e.stopPropagation();
202
+ if (item.disabled)
203
+ return;
204
+ const next = !this.isOpen(item, id);
205
+ this.setOpen(id, next);
206
+ this.leNavItemToggle.emit({
207
+ item,
208
+ id,
209
+ open: next,
210
+ originalEvent: e,
211
+ });
212
+ };
213
+ handleSearchInput = (e) => {
214
+ const target = e.target;
215
+ this.searchQuery = target.value;
216
+ };
217
+ handleSubmenuSearchInput = (submenuId, e) => {
218
+ const target = e.target;
219
+ const value = target.value;
220
+ if (this.submenuQueries[submenuId] === value)
221
+ return;
222
+ this.submenuQueries = {
223
+ ...this.submenuQueries,
224
+ [submenuId]: value,
225
+ };
226
+ // Position may change as items filter.
227
+ requestAnimationFrame(() => this.popoverRefs.get(submenuId)?.updatePosition());
228
+ };
229
+ getTopLevelIds(items) {
230
+ return items.map((item, index) => this.getItemId(item, String(index)));
231
+ }
232
+ computeOverflow() {
233
+ // Only applies to horizontal, non-wrapping navs.
234
+ if (this.orientation !== 'horizontal' || this.wrap) {
235
+ if (this.overflowIds.length)
236
+ this.overflowIds = [];
237
+ if (this.hamburgerActive)
238
+ this.hamburgerActive = false;
239
+ return;
240
+ }
241
+ const container = this.navContainerEl;
242
+ if (!container)
243
+ return;
244
+ const topIds = this.getTopLevelIds(this.parsedItems);
245
+ const widths = topIds.map(id => this.topItemEls.get(id)?.getBoundingClientRect().width ?? 0);
246
+ const totalWidth = widths.reduce((a, b) => a + b, 0);
247
+ const availableWidth = container.getBoundingClientRect().width;
248
+ if (this.overflowMode === 'hamburger') {
249
+ const shouldHamburger = totalWidth > availableWidth;
250
+ if (shouldHamburger !== this.hamburgerActive) {
251
+ this.hamburgerActive = shouldHamburger;
252
+ }
253
+ if (this.overflowIds.length)
254
+ this.overflowIds = [];
255
+ return;
256
+ }
257
+ // overflowMode === 'more'
258
+ this.computeOverflowMoreByWrap(availableWidth);
259
+ }
260
+ computeOverflowMoreByWrap(availableWidth) {
261
+ const container = this.navContainerEl;
262
+ const measure = this.measureEl;
263
+ const measureMore = this.measureMoreEl;
264
+ const items = this.parsedItems;
265
+ if (!container || !measure)
266
+ return;
267
+ // Ensure measurement container matches visible container width.
268
+ measure.style.width = `${availableWidth}px`;
269
+ const allIds = this.getTopLevelIds(items);
270
+ const itemEls = allIds
271
+ .map(id => measure.querySelector(`[data-nav-id="${CSS.escape(id)}"]`))
272
+ .filter((el) => !!el);
273
+ // Reset measurement visibility.
274
+ itemEls.forEach(el => {
275
+ el.style.display = '';
276
+ });
277
+ if (measureMore) {
278
+ measureMore.style.display = 'none';
279
+ }
280
+ if (itemEls.length === 0) {
281
+ if (this.overflowIds.length)
282
+ this.overflowIds = [];
283
+ return;
284
+ }
285
+ const firstRowTop = Math.min(...itemEls.map(el => el.offsetTop));
286
+ const overflowSet = new Set();
287
+ // Pass 1: detect which items fall onto rows > 1 (without "More" in flow).
288
+ itemEls.forEach(el => {
289
+ const id = el.getAttribute('data-nav-id');
290
+ if (!id)
291
+ return;
292
+ if (el.offsetTop > firstRowTop)
293
+ overflowSet.add(id);
294
+ });
295
+ if (overflowSet.size === 0) {
296
+ if (this.overflowIds.length)
297
+ this.overflowIds = [];
298
+ return;
299
+ }
300
+ // Pass 2: show "More" and iteratively move items into overflow until "More" fits on row 1.
301
+ if (measureMore) {
302
+ measureMore.style.display = '';
303
+ }
304
+ // Hide currently overflowing items.
305
+ itemEls.forEach(el => {
306
+ const id = el.getAttribute('data-nav-id');
307
+ if (!id)
308
+ return;
309
+ if (overflowSet.has(id))
310
+ el.style.display = 'none';
311
+ });
312
+ const getVisibleItemEls = () => itemEls.filter(el => el.style.display !== 'none');
313
+ while (measureMore) {
314
+ const visible = getVisibleItemEls();
315
+ const rowTop = visible.length ? Math.min(...visible.map(el => el.offsetTop)) : 0;
316
+ if (measureMore.offsetTop <= rowTop)
317
+ break;
318
+ if (visible.length === 0)
319
+ break;
320
+ // Remove one last visible item and retry.
321
+ const last = visible[visible.length - 1];
322
+ const lastId = last.getAttribute('data-nav-id');
323
+ if (!lastId)
324
+ break;
325
+ last.style.display = 'none';
326
+ overflowSet.add(lastId);
327
+ }
328
+ const overflowIds = allIds.filter(id => overflowSet.has(id));
329
+ const same = overflowIds.length === this.overflowIds.length &&
330
+ overflowIds.every((v, i) => v === this.overflowIds[i]);
331
+ if (!same) {
332
+ this.overflowIds = overflowIds;
333
+ }
334
+ }
335
+ renderHorizontalMeasureItem(item, index) {
336
+ const id = this.getItemId(item, String(index));
337
+ const children = this.getChildItems(item);
338
+ const hasChildren = children.length > 0;
339
+ const setRef = (el) => {
340
+ if (el)
341
+ this.topItemEls.set(id, el);
342
+ };
343
+ if (!hasChildren) {
344
+ return (h("div", { class: "h-item", ref: setRef, "data-nav-id": id }, h("span", { class: "h-link" }, item.iconStart && (h("span", { class: "nav-icon", "aria-hidden": "true" }, item.iconStart)), h("span", { class: "h-label" }, item.label), item.iconEnd && (h("span", { class: "nav-icon nav-icon-end", "aria-hidden": "true" }, item.iconEnd)))));
345
+ }
346
+ return (h("div", { class: "h-item", ref: setRef, "data-nav-id": id }, h("span", { class: "h-trigger" }, h("span", { class: "h-link" }, item.iconStart && (h("span", { class: "nav-icon", "aria-hidden": "true" }, item.iconStart)), h("span", { class: "h-label" }, item.label)), h("span", { class: "h-submenu-toggle", "aria-hidden": "true" }, h("span", { class: "nav-chevron" }, "\u25BC")))));
347
+ }
348
+ renderVerticalList(items, { depth, pathPrefix, autoOpenIds, searchable, searchQuery, searchPlaceholder, emptyText, submenuId, }) {
349
+ const query = searchQuery ?? '';
350
+ const openFromSearch = autoOpenIds ?? new Set();
351
+ const filtered = query ? this.filterTree(items, query, pathPrefix, openFromSearch) : items;
352
+ return (h("div", { class: classnames('nav-vertical', { 'is-submenu': !!submenuId }) }, searchable && (h("div", { class: "nav-search" }, h("le-string-input", { mode: "default", class: "nav-search-input", placeholder: searchPlaceholder ?? 'Search...', value: query, onInput: (e) => submenuId ? this.handleSubmenuSearchInput(submenuId, e) : this.handleSearchInput(e) }))), filtered.length === 0 ? (h("div", { class: "nav-empty" }, emptyText ?? this.emptyText)) : (h("ul", { class: "nav-list", role: "tree" }, filtered.map((item, index) => {
353
+ const path = pathPrefix ? `${pathPrefix}.${index}` : String(index);
354
+ const id = this.getItemId(item, path);
355
+ const children = this.getChildItems(item);
356
+ const hasChildren = children.length > 0;
357
+ const open = hasChildren && (this.isOpen(item, id) || openFromSearch.has(id));
358
+ const paddingLeft = `calc(var(--le-nav-item-padding-x) + ${depth} * var(--le-spacing-4))`;
359
+ const TagType = item.href && !item.disabled ? 'a' : 'button';
360
+ const attrs = TagType === 'a'
361
+ ? { href: item.href, role: 'treeitem' }
362
+ : { type: 'button', role: 'treeitem' };
363
+ return (h("li", { class: classnames('nav-node', {
364
+ 'disabled': item.disabled,
365
+ 'selected': item.selected,
366
+ open,
367
+ 'has-children': hasChildren,
368
+ }), key: id, role: "none" }, h("div", { class: "nav-row", style: { paddingLeft } }, hasChildren ? (h("button", { type: "button", class: "nav-toggle", "aria-label": open ? 'Collapse' : 'Expand', "aria-expanded": open ? 'true' : 'false', onClick: (e) => this.handleToggle(e, item, id), disabled: item.disabled }, h("le-icon", { name: "chevron-down", class: "nav-chevron", "aria-hidden": "true" }))) : (h("span", { class: "nav-toggle-spacer", "aria-hidden": "true" })), h(TagType, { class: "nav-item", ...attrs, "aria-disabled": item.disabled ? 'true' : undefined, onClick: (e) => {
369
+ // For buttons, also toggle if this is a purely structural node.
370
+ this.handleItemSelect(e, item, id);
371
+ if (!item.href && hasChildren && !item.disabled) {
372
+ this.handleToggle(e, item, id);
373
+ }
374
+ } }, item.iconStart && (h("span", { class: "nav-icon", "aria-hidden": "true" }, item.iconStart)), h("span", { class: "nav-text" }, h("span", { class: "nav-label" }, item.label), item.description && (h("span", { class: "nav-description" }, item.description))), item.iconEnd && (h("span", { class: "nav-icon nav-icon-end", "aria-hidden": "true" }, item.iconEnd)))), hasChildren && (h("le-collapse", { class: "nav-children", closed: !open, noFading: true, role: "group" }, this.renderVerticalList(children, {
375
+ depth: depth + 1,
376
+ pathPrefix: path,
377
+ autoOpenIds: openFromSearch,
378
+ })))));
379
+ })))));
380
+ }
381
+ renderHorizontalItem(item, index) {
382
+ const id = this.getItemId(item, String(index));
383
+ const children = this.getChildItems(item);
384
+ const hasChildren = children.length > 0;
385
+ if (!hasChildren) {
386
+ const TagType = item.href && !item.disabled ? 'a' : 'button';
387
+ const attrs = TagType === 'a'
388
+ ? { href: item.href, role: 'menuitem' }
389
+ : { type: 'button', role: 'menuitem' };
390
+ return (h("div", { class: "h-item" }, h(TagType, { class: classnames('h-link', {
391
+ disabled: item.disabled,
392
+ selected: item.selected,
393
+ }), ...attrs, "aria-disabled": item.disabled ? 'true' : undefined, onClick: (e) => this.handleItemSelect(e, item, id) }, item.iconStart && (h("span", { class: "nav-icon", "aria-hidden": "true" }, item.iconStart)), h("span", { class: "h-label" }, item.label), item.iconEnd && (h("span", { class: "nav-icon nav-icon-end", "aria-hidden": "true" }, item.iconEnd)))));
394
+ }
395
+ const submenuId = id;
396
+ return (h("div", { class: "h-item" }, h("le-popover", { ref: el => {
397
+ if (el)
398
+ this.popoverRefs.set(submenuId, el);
399
+ }, mode: "default", showClose: false, closeOnClickOutside: true, closeOnEscape: true, position: "bottom", align: "start", minWidth: "240px" }, h("div", { slot: "trigger", class: classnames('h-trigger', {
400
+ disabled: item.disabled,
401
+ selected: item.selected,
402
+ }), role: "menuitem", "aria-disabled": item.disabled ? 'true' : undefined, onClick: (e) => {
403
+ // Don’t let le-popover auto-toggle from its internal wrapper.
404
+ e.stopPropagation();
405
+ if (item.disabled)
406
+ return;
407
+ if (item.href) {
408
+ this.handleItemSelect(e, item, id);
409
+ }
410
+ else {
411
+ this.popoverRefs.get(submenuId)?.toggle();
412
+ }
413
+ } }, item.href ? (h("a", { class: "h-link", href: item.href, onClick: (e) => {
414
+ e.stopPropagation();
415
+ this.handleItemSelect(e, item, id);
416
+ } }, item.iconStart && (h("span", { class: "nav-icon", "aria-hidden": "true" }, item.iconStart)), h("span", { class: "h-label" }, item.label))) : (h("button", { type: "button", class: "h-link", onClick: (e) => {
417
+ e.stopPropagation();
418
+ if (item.disabled)
419
+ return;
420
+ this.popoverRefs.get(submenuId)?.toggle();
421
+ } }, item.iconStart && (h("span", { class: "nav-icon", "aria-hidden": "true" }, item.iconStart)), h("span", { class: "h-label" }, item.label))), h("button", { type: "button", class: "h-submenu-toggle", "aria-label": "Open submenu", onClick: (e) => {
422
+ e.preventDefault();
423
+ e.stopPropagation();
424
+ if (item.disabled)
425
+ return;
426
+ this.popoverRefs.get(submenuId)?.toggle();
427
+ } }, h("span", { class: "nav-chevron", "aria-hidden": "true" }, h("le-icon", { name: "chevron-down" })))), h("div", { class: "popover-menu" }, this.renderVerticalList(children, {
428
+ depth: 0,
429
+ pathPrefix: String(index),
430
+ searchable: this.submenuSearchable,
431
+ searchQuery: this.submenuQueries[submenuId] ?? '',
432
+ searchPlaceholder: this.searchPlaceholder,
433
+ emptyText: this.emptyText,
434
+ submenuId,
435
+ })))));
436
+ }
437
+ renderHorizontal() {
438
+ const items = this.parsedItems;
439
+ const overflowSet = new Set(this.overflowIds);
440
+ const overflowItems = [];
441
+ items.forEach((item, index) => {
442
+ const id = this.getItemId(item, String(index));
443
+ if (!this.wrap && this.overflowMode === 'more' && overflowSet.has(id)) {
444
+ overflowItems.push(item);
445
+ }
446
+ });
447
+ // Hamburger mode: show a single trigger if anything overflows.
448
+ if (!this.wrap && this.overflowMode === 'hamburger' && this.hamburgerActive) {
449
+ return (h("div", { class: "nav-horizontal-shell" }, h("div", { class: "nav-horizontal-measure", "aria-hidden": "true", ref: el => {
450
+ this.measureEl = el;
451
+ } }, items.map((item, index) => this.renderHorizontalMeasureItem(item, index)), h("div", { class: "h-item", ref: el => {
452
+ this.measureMoreEl = el;
453
+ } }, h("button", { type: "button", class: "overflow-trigger" }, "More"))), h("div", { class: "nav-horizontal", ref: el => {
454
+ this.navContainerEl = el;
455
+ this.setupResizeObserver();
456
+ this.observeContainer(this.navContainerEl);
457
+ } }, h("le-popover", { mode: "default", showClose: false, closeOnClickOutside: true, closeOnEscape: true, position: "bottom", align: "end", minWidth: "260px" }, h("button", { slot: "trigger", type: "button", class: "overflow-trigger", "aria-label": "Open menu" }, "\u2630"), h("div", { class: "popover-menu" }, this.renderVerticalList(items, { depth: 0, pathPrefix: '' }))))));
458
+ }
459
+ const showMore = !this.wrap && this.overflowMode === 'more' && overflowItems.length > 0;
460
+ return (h("div", { class: "nav-horizontal-shell", role: "menubar" }, h("div", { class: "nav-horizontal-measure", "aria-hidden": "true", ref: el => {
461
+ this.measureEl = el;
462
+ } }, items.map((item, index) => this.renderHorizontalMeasureItem(item, index)), h("div", { class: "h-item", ref: el => {
463
+ this.measureMoreEl = el;
464
+ } }, h("button", { type: "button", class: "overflow-trigger" }, "More"))), h("div", { class: classnames('nav-horizontal', {
465
+ wrap: this.wrap,
466
+ nowrap: !this.wrap,
467
+ }), ref: el => {
468
+ this.navContainerEl = el;
469
+ this.setupResizeObserver();
470
+ this.observeContainer(this.navContainerEl);
471
+ } }, items.map((item, index) => {
472
+ const id = this.getItemId(item, String(index));
473
+ const isOverflow = !this.wrap && this.overflowMode === 'more' && overflowSet.has(id);
474
+ if (isOverflow)
475
+ return null;
476
+ return this.renderHorizontalItem(item, index);
477
+ }), h("div", { class: classnames('more-trigger-wrap', {
478
+ 'is-visible': showMore,
479
+ 'is-measure': !showMore,
480
+ }) }, h("le-popover", { mode: "default", position: "bottom", align: "end", minWidth: "260px", showClose: false }, h("button", { slot: "trigger", type: "button", class: "overflow-trigger", "aria-label": "More" }, "More"), h("div", { class: "popover-menu" }, this.renderVerticalList(overflowItems, { depth: 0, pathPrefix: '' })))))));
481
+ }
482
+ render() {
483
+ const items = this.parsedItems;
484
+ if (this.orientation === 'horizontal') {
485
+ return (h(Host, null, h("le-component", { component: "le-navigation" }, this.renderHorizontal())));
486
+ }
487
+ return (h(Host, null, h("le-component", { component: "le-navigation" }, this.renderVerticalList(items, {
488
+ depth: 0,
489
+ pathPrefix: '',
490
+ searchable: this.searchable,
491
+ searchQuery: this.searchQuery,
492
+ searchPlaceholder: this.searchPlaceholder,
493
+ emptyText: this.emptyText,
494
+ }))));
495
+ }
496
+ static get watchers() { return {
497
+ "items": ["handleLayoutInputsChange"],
498
+ "orientation": ["handleLayoutInputsChange"],
499
+ "wrap": ["handleLayoutInputsChange"],
500
+ "overflowMode": ["handleLayoutInputsChange"]
501
+ }; }
502
+ static get style() { return leNavigationCss(); }
503
+ }, [769, "le-navigation", {
504
+ "items": [1],
505
+ "orientation": [513],
506
+ "wrap": [516],
507
+ "overflowMode": [513, "overflow-mode"],
508
+ "searchable": [4],
509
+ "searchPlaceholder": [1, "search-placeholder"],
510
+ "emptyText": [1, "empty-text"],
511
+ "submenuSearchable": [4, "submenu-searchable"],
512
+ "searchQuery": [32],
513
+ "openState": [32],
514
+ "overflowIds": [32],
515
+ "hamburgerActive": [32],
516
+ "submenuQueries": [32]
517
+ }, undefined, {
518
+ "items": ["handleLayoutInputsChange"],
519
+ "orientation": ["handleLayoutInputsChange"],
520
+ "wrap": ["handleLayoutInputsChange"],
521
+ "overflowMode": ["handleLayoutInputsChange"]
522
+ }]);
523
+ function defineCustomElement$1() {
524
+ if (typeof customElements === "undefined") {
525
+ return;
526
+ }
527
+ const components = ["le-navigation", "le-button", "le-checkbox", "le-collapse", "le-component", "le-dropdown-base", "le-icon", "le-popover", "le-popup", "le-select", "le-slot", "le-string-input"];
528
+ components.forEach(tagName => { switch (tagName) {
529
+ case "le-navigation":
530
+ if (!customElements.get(transformTag(tagName))) {
531
+ customElements.define(transformTag(tagName), LeNavigation$1);
532
+ }
533
+ break;
534
+ case "le-button":
535
+ if (!customElements.get(transformTag(tagName))) {
536
+ defineCustomElement$c();
537
+ }
538
+ break;
539
+ case "le-checkbox":
540
+ if (!customElements.get(transformTag(tagName))) {
541
+ defineCustomElement$b();
542
+ }
543
+ break;
544
+ case "le-collapse":
545
+ if (!customElements.get(transformTag(tagName))) {
546
+ defineCustomElement$a();
547
+ }
548
+ break;
549
+ case "le-component":
550
+ if (!customElements.get(transformTag(tagName))) {
551
+ defineCustomElement$9();
552
+ }
553
+ break;
554
+ case "le-dropdown-base":
555
+ if (!customElements.get(transformTag(tagName))) {
556
+ defineCustomElement$8();
557
+ }
558
+ break;
559
+ case "le-icon":
560
+ if (!customElements.get(transformTag(tagName))) {
561
+ defineCustomElement$7();
562
+ }
563
+ break;
564
+ case "le-popover":
565
+ if (!customElements.get(transformTag(tagName))) {
566
+ defineCustomElement$6();
567
+ }
568
+ break;
569
+ case "le-popup":
570
+ if (!customElements.get(transformTag(tagName))) {
571
+ defineCustomElement$5();
572
+ }
573
+ break;
574
+ case "le-select":
575
+ if (!customElements.get(transformTag(tagName))) {
576
+ defineCustomElement$4();
577
+ }
578
+ break;
579
+ case "le-slot":
580
+ if (!customElements.get(transformTag(tagName))) {
581
+ defineCustomElement$3();
582
+ }
583
+ break;
584
+ case "le-string-input":
585
+ if (!customElements.get(transformTag(tagName))) {
586
+ defineCustomElement$2();
587
+ }
588
+ break;
589
+ } });
590
+ }
591
+
592
+ const LeNavigation = LeNavigation$1;
593
+ const defineCustomElement = defineCustomElement$1;
594
+
595
+ export { LeNavigation, defineCustomElement };
596
+ //# sourceMappingURL=le-navigation.js.map
597
+
598
+ //# sourceMappingURL=le-navigation.js.map