@ptcwebops/ptcw-design 6.4.11-beta → 6.4.12-beta

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.
@@ -0,0 +1,433 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ const index = require('./index-63ddc79c.js');
6
+
7
+ const ptcSubnavV2Css = "h1,h2,h3,h4,h5,h6,p,ul,li,ptc-subnav,ptc-tab-list,ptc-link,ptc-square-card,.hyphenate-text,ptc-footer{word-break:break-word;hyphens:manual;-webkit-hyphens:manual;-moz-hyphens:manual;-ms-hyphens:manual}@supports (hyphenate-limit-chars: 12 3 3){h1,h2,h3,h4,h5,h6,p,ul,li,ptc-subnav,ptc-tab-list,ptc-link,ptc-square-card,.hyphenate-text,ptc-footer{hyphens:auto;-webkit-hyphenate-limit-before:3;-webkit-hyphenate-limit-after:3;hyphenate-limit-chars:12 3 3;hyphenate-limit-lines:2;hyphenate-limit-last:always;hyphenate-limit-zone:6%;-webkit-hyphens:auto;-webkit-hyphenate-limit-before:3;-webkit-hyphenate-limit-after:3;-webkit-hyphenate-limit-chars:12 3 3;-webkit-hyphenate-limit-lines:2;-moz-hyphens:auto;-moz-hyphenate-limit-chars:12 3 3;-moz-hyphenate-limit-lines:2;-ms-hyphens:auto;-ms-hyphenate-limit-chars:12 3 3;-ms-hyphenate-limit-lines:2}}:host{display:block;font-family:var(--ptc-font-latin);position:sticky;top:0;z-index:105;background-color:var(--color-standard-gray);box-shadow:var(--ptc-shadow-small)}:host .subnav-container{display:flex;flex-direction:row;justify-content:space-between;align-items:center;padding:0 24px;margin:0 auto;max-width:1200px;gap:24px}@media only screen and (min-width: 768px){:host .subnav-container{flex-wrap:wrap;gap:48px}}@media only screen and (min-width: 1200px){:host .subnav-container{padding-left:0;padding-right:0;max-width:1136px}}@media only screen and (min-width: 1440px){:host .subnav-container{padding-left:0;padding-right:0;max-width:1200px}}:host .subnav-menu-left{display:flex;align-items:center;flex:1}@media only screen and (min-width: 768px){:host .subnav-menu-left{justify-content:flex-start}}:host .subnav-menu-left ul.desktop-menu{list-style:none;padding:0;margin:0;display:flex;align-items:center;justify-content:center;gap:4px;flex-wrap:wrap;margin-bottom:-2px}@media only screen and (min-width: 768px){:host .subnav-menu-left ul.desktop-menu{justify-content:flex-start;gap:32px}}:host .subnav-menu-left ul.desktop-menu li{display:inline-block}:host .subnav-menu-left ul.desktop-menu li a{color:var(--color-gray-07);text-decoration:none;padding:8px 12px;font-size:var(--ptc-font-size-xx-small);font-weight:var(--ptc-font-weight-bold);line-height:var(--ptc-line-height-densest);display:block;position:relative;border-bottom:3px solid transparent}@media only screen and (min-width: 768px){:host .subnav-menu-left ul.desktop-menu li a{padding:20px 0 17px 0}}:host .subnav-menu-left ul.desktop-menu li a:hover{color:var(--color-gray-10)}:host .subnav-menu-left ul.desktop-menu li a.active{color:var(--color-gray-10);border-bottom:3px solid var(--color-green-07)}:host .subnav-menu-left ul.desktop-menu li a:focus-visible{border-radius:var(--ptc-border-radius-standard);outline:5px solid var(--keyboard-nav-outline)}:host .subnav-menu-left .overflow-menu-container{position:relative;display:none}@media only screen and (min-width: 768px){:host .subnav-menu-left .overflow-menu-container{display:inline-block}}:host .subnav-menu-left .overflow-menu-container .overflow-button{background:none;border:none;padding:20px 0 17px 0;font-size:var(--ptc-font-size-xx-small);font-weight:var(--ptc-font-weight-bold);color:var(--color-gray-07);cursor:pointer;display:flex;align-items:center;justify-content:center;min-width:32px;border-bottom:3px solid transparent;transition:all 0.2s ease}:host .subnav-menu-left .overflow-menu-container .overflow-button:hover{color:var(--color-gray-10)}:host .subnav-menu-left .overflow-menu-container .overflow-button:focus-visible{border-radius:var(--ptc-border-radius-standard);outline:5px solid var(--keyboard-nav-outline)}:host .subnav-menu-left .overflow-menu-container .overflow-button .overflow-dots{border-radius:2px;border:1px solid var(--color-gray-07);line-height:1;width:18px;height:18px;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all 0.2s ease}:host .subnav-menu-left .overflow-menu-container .overflow-button .overflow-dots:hover{background-color:var(--color-gray-04);border-color:var(--color-gray-04)}:host .subnav-menu-left .overflow-menu-container .overflow-button .overflow-dots:hover svg circle{fill:var(--color-gray-10)}:host .subnav-menu-left .overflow-menu-container .overflow-button .overflow-dots:focus-visible{border-radius:var(--ptc-border-radius-standard);outline:5px solid var(--keyboard-nav-outline)}:host .subnav-menu-left .overflow-menu-container .overflow-button[aria-expanded],:host .subnav-menu-left .overflow-menu-container .overflow-button.selected-active{border-bottom:3px solid var(--color-green-07)}:host .subnav-menu-left .overflow-menu-container .overflow-button[aria-expanded] .overflow-dots,:host .subnav-menu-left .overflow-menu-container .overflow-button.selected-active .overflow-dots{background-color:var(--color-green-07);border-color:var(--color-green-07)}:host .subnav-menu-left .overflow-menu-container .overflow-button[aria-expanded] .overflow-dots svg circle,:host .subnav-menu-left .overflow-menu-container .overflow-button.selected-active .overflow-dots svg circle{fill:var(--color-white)}:host .subnav-menu-left .overflow-menu-container .overflow-dropdown{position:absolute;top:100%;right:0;background:var(--color-white);border-radius:var(--ptc-border-radius-standard);box-shadow:var(--ptc-shadow-x-large);min-width:200px;z-index:1001;padding:14px 0;margin-top:-4px;max-width:312px;width:-moz-max-content;width:max-content}:host .subnav-menu-left .overflow-menu-container .overflow-dropdown a{display:block;padding:12px 32px 12px 24px;color:var(--color-gray-07);text-decoration:none;font-size:var(--ptc-font-size-xx-small);font-weight:var(--ptc-font-weight-bold);line-height:var(--ptc-line-height-densest);transition:all 0.2s ease;position:relative;border:none}:host .subnav-menu-left .overflow-menu-container .overflow-dropdown a:hover{background-color:var(--color-gray-02);color:var(--color-gray-10)}:host .subnav-menu-left .overflow-menu-container .overflow-dropdown a.active{color:var(--color-gray-10);border-bottom:none}:host .subnav-menu-left .overflow-menu-container .overflow-dropdown a.active::before{content:\"\";display:block;width:2px;height:calc(100% - 0px);background-color:var(--color-green-07);position:absolute;left:16px;top:0}:host .subnav-menu-left .overflow-menu-container .overflow-dropdown a:focus-visible{border-radius:var(--ptc-border-radius-standard);outline:5px solid var(--keyboard-nav-outline)}:host .mobile-dropdown-container{position:relative;display:block}@media only screen and (min-width: 768px){:host .mobile-dropdown-container{display:none !important}}@media (min-width: 768px){:host .mobile-dropdown-container{display:none !important}}:host .mobile-dropdown-container .mobile-dropdown-button{display:flex;padding:20px 0 17px 0;justify-content:center;align-items:center;gap:10px;align-self:stretch;border:none;cursor:pointer;transition:all 0.2s ease;background-color:transparent;border-bottom:3px solid var(--color-green-07)}:host .mobile-dropdown-container .mobile-dropdown-button .mobile-selected-item{color:var(--color-gray-07);font-size:var(--ptc-font-size-xx-small);font-style:normal;font-weight:var(--ptc-font-weight-bold);line-height:var(--ptc-line-height-densest);display:-webkit-box;line-clamp:1;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis;max-width:100%}:host .mobile-dropdown-container .mobile-dropdown-button:hover{border-color:var(--color-gray-04);color:var(--color-gray-10)}:host .mobile-dropdown-container .mobile-dropdown-button:focus-visible{border-radius:var(--ptc-border-radius-standard);outline:5px solid var(--keyboard-nav-outline)}:host .mobile-dropdown-container .mobile-dropdown-button[aria-expanded]{border-color:var(--color-green-07);color:var(--color-gray-10)}:host .mobile-dropdown-container .mobile-dropdown-button .mobile-selected-item{flex:1;text-align:left}:host .mobile-dropdown-container .mobile-dropdown-button .mobile-arrow{display:flex;align-items:center;justify-content:center;transition:transform 0.2s ease}:host .mobile-dropdown-container .mobile-dropdown-button .mobile-arrow svg{transition:transform 0.2s ease}:host .mobile-dropdown-container .mobile-dropdown-button .mobile-arrow.rotated svg{transform:rotate(180deg)}:host .mobile-dropdown-container .mobile-dropdown{position:absolute;top:calc(100% - 4px);left:auto;right:auto;background:var(--color-white);border:1px solid var(--color-gray-02);border-radius:var(--ptc-border-radius-standard);box-shadow:var(--ptc-shadow-medium);z-index:1001;margin-top:4px;overflow-y:auto;min-width:280px;width:-moz-fit-content;width:fit-content;list-style:none;padding:0;margin:4px 0 0 0}:host .mobile-dropdown-container .mobile-dropdown li{display:block;border-bottom:1px solid var(--color-gray-01)}:host .mobile-dropdown-container .mobile-dropdown li:last-child{border-bottom:none}:host .mobile-dropdown-container .mobile-dropdown li .mobile-dropdown-item{width:100%;background:none;border:none;padding:12px 16px;color:var(--color-gray-07);text-decoration:none;font-size:var(--ptc-font-size-xx-small);font-weight:var(--ptc-font-weight-bold);line-height:var(--ptc-line-height-densest);text-align:left;cursor:pointer;transition:all 0.2s ease;word-break:break-word;display:block}:host .mobile-dropdown-container .mobile-dropdown li .mobile-dropdown-item:hover{background-color:var(--color-gray-01);color:var(--color-gray-10)}:host .mobile-dropdown-container .mobile-dropdown li .mobile-dropdown-item.active{background-color:var(--color-gray-01);color:var(--color-gray-10);border-left:3px solid var(--color-green-07)}:host .mobile-dropdown-container .mobile-dropdown li .mobile-dropdown-item:focus-visible{border-radius:var(--ptc-border-radius-standard);outline:5px solid var(--keyboard-nav-outline)}:host .subnav-menu-right{max-width:300px;padding:12px 0}@media only screen and (min-width: 768px){:host .subnav-menu-right{margin-left:48px;width:auto}}:host .subnav-menu-right ptc-button{max-width:300px}";
8
+
9
+ const PtcSubnavV2 = class {
10
+ constructor(hostRef) {
11
+ index.registerInstance(this, hostRef);
12
+ this.handleClickOutside = (event) => {
13
+ const target = event.target;
14
+ if (!this.el.contains(target)) {
15
+ this.showOverflowMenu = false;
16
+ }
17
+ };
18
+ this.handleKeyDown = (event) => {
19
+ // Handle Escape key to close dropdowns
20
+ if (event.key === "Escape" && this.showOverflowMenu) {
21
+ this.showOverflowMenu = false;
22
+ // Return focus to the button that opened the menu
23
+ if (this.overflowButton) {
24
+ this.overflowButton.focus();
25
+ }
26
+ }
27
+ };
28
+ this.handleScroll = () => {
29
+ // Throttle scroll events for better performance
30
+ if (this.scrollThrottleTimeout) {
31
+ return;
32
+ }
33
+ this.scrollThrottleTimeout = window.setTimeout(() => {
34
+ // Don't update active state if user just manually navigated
35
+ if (this.isManualNavigation) {
36
+ this.scrollThrottleTimeout = null;
37
+ return;
38
+ }
39
+ // Fallback scroll handler to ensure active state is updated
40
+ const navItems = this.getNavItems();
41
+ const subnavHeight = this.el.offsetHeight;
42
+ const scrollPosition = window.scrollY + subnavHeight + 100; // Offset for better detection
43
+ // Find the section that should be active based on scroll position
44
+ let activeSection = navItems[0].id; // Default to first section
45
+ for (let i = navItems.length - 1; i >= 0; i--) {
46
+ const section = document.getElementById(navItems[i].id);
47
+ if (section && section.offsetTop <= scrollPosition) {
48
+ activeSection = navItems[i].id;
49
+ break;
50
+ }
51
+ }
52
+ // Only update if different from current active
53
+ if (activeSection !== this.currentActive) {
54
+ this.currentActive = activeSection;
55
+ // Update mobile selected item if in mobile mode
56
+ if (this.isMobile) {
57
+ const activeItem = navItems.find((item) => item.id === activeSection);
58
+ if (activeItem) {
59
+ this.selectedMobileItem = activeItem;
60
+ }
61
+ }
62
+ }
63
+ this.scrollThrottleTimeout = null;
64
+ }, 16); // ~60fps throttling
65
+ };
66
+ this.handleResize = () => {
67
+ if (this.navContainer) {
68
+ // Add a small delay to ensure DOM has been updated
69
+ setTimeout(() => {
70
+ this.calculateVisibleItems();
71
+ }, 10);
72
+ }
73
+ };
74
+ this.setupIntersectionObserver = () => {
75
+ // Get all sections that correspond to our navigation items
76
+ const navItems = this.getNavItems();
77
+ // Create intersection observer
78
+ this.intersectionObserver = new IntersectionObserver((entries) => {
79
+ // Clear any existing timeout
80
+ if (this.scrollTimeout) {
81
+ clearTimeout(this.scrollTimeout);
82
+ }
83
+ // Debounce the intersection changes
84
+ this.scrollTimeout = window.setTimeout(() => {
85
+ // Don't update active state if user just manually navigated
86
+ if (this.isManualNavigation) {
87
+ return;
88
+ }
89
+ // Find all intersecting sections
90
+ const intersectingSections = entries.filter((entry) => entry.isIntersecting);
91
+ if (intersectingSections.length > 0) {
92
+ // Sort by intersection ratio (how much of the section is visible)
93
+ // and then by position (top to bottom)
94
+ intersectingSections.sort((a, b) => {
95
+ // First sort by intersection ratio (higher = more visible)
96
+ if (b.intersectionRatio !== a.intersectionRatio) {
97
+ return (b.intersectionRatio - a.intersectionRatio);
98
+ }
99
+ // If intersection ratios are equal, sort by position
100
+ return (a.boundingClientRect.top -
101
+ b.boundingClientRect.top);
102
+ });
103
+ // Get the most visible section
104
+ const mostVisibleSection = intersectingSections[0];
105
+ const sectionId = mostVisibleSection.target.id;
106
+ if (sectionId && sectionId !== this.currentActive) {
107
+ this.currentActive = sectionId;
108
+ // Update mobile selected item if in mobile mode
109
+ if (this.isMobile) {
110
+ const activeItem = navItems.find((item) => item.id === sectionId);
111
+ if (activeItem) {
112
+ this.selectedMobileItem = activeItem;
113
+ }
114
+ }
115
+ }
116
+ }
117
+ }, 100); // Increased debounce time for better performance
118
+ }, {
119
+ root: null,
120
+ rootMargin: "-20% 0px -60% 0px",
121
+ threshold: [0, 0.1, 0.25, 0.5, 0.75, 1.0], // Multiple thresholds for better detection
122
+ });
123
+ // Observe all sections
124
+ navItems.forEach((item) => {
125
+ const section = document.getElementById(item.id);
126
+ if (section) {
127
+ this.intersectionObserver.observe(section);
128
+ }
129
+ });
130
+ };
131
+ this.extractNavItemsFromSlots = () => {
132
+ // Look for slot content with nav-items in the light DOM
133
+ const slotElement = this.el.querySelector('[slot="nav-items"]');
134
+ if (slotElement) {
135
+ const links = slotElement.querySelectorAll("a");
136
+ const items = Array.from(links)
137
+ .map((link) => {
138
+ var _a, _b;
139
+ return ({
140
+ id: ((_a = link.getAttribute("href")) === null || _a === void 0 ? void 0 : _a.substring(1)) || "",
141
+ label: ((_b = link.textContent) === null || _b === void 0 ? void 0 : _b.trim()) || "",
142
+ title: link.getAttribute("title") || "",
143
+ trackerId: link.getAttribute("tracker-id") || "",
144
+ });
145
+ })
146
+ .filter((item) => item.id && item.label);
147
+ if (items.length > 0) {
148
+ return items;
149
+ }
150
+ }
151
+ return null;
152
+ };
153
+ this.getNavItems = () => {
154
+ // Extract navigation items from slots (SEO-friendly approach)
155
+ const slotItems = this.extractNavItemsFromSlots();
156
+ if (slotItems) {
157
+ return slotItems;
158
+ }
159
+ // If navItems prop is provided, parse and use it (fallback)
160
+ if (this.navItems && this.navItems.trim()) {
161
+ try {
162
+ const parsedItems = JSON.parse(this.navItems);
163
+ // Validate that it's an array with proper structure
164
+ if (Array.isArray(parsedItems) && parsedItems.length > 0) {
165
+ // Ensure each item has required properties
166
+ const validItems = parsedItems.filter((item) => item &&
167
+ typeof item.id === "string" &&
168
+ typeof item.label === "string");
169
+ if (validItems.length > 0) {
170
+ return validItems;
171
+ }
172
+ }
173
+ }
174
+ catch (error) {
175
+ console.warn("Invalid navItems JSON provided to ptc-subnav-v2:", error);
176
+ }
177
+ }
178
+ // Return empty array if no navigation items found
179
+ console.warn("No navigation items found in slots or props for ptc-subnav-v2");
180
+ return [];
181
+ };
182
+ this.calculateMobileDropdownItems = () => {
183
+ const navItems = this.getNavItems();
184
+ // Handle case where no navigation items are found
185
+ if (navItems.length === 0) {
186
+ this.mobileDropdownItems = [];
187
+ return;
188
+ }
189
+ const currentItem = this.selectedMobileItem || {
190
+ id: this.currentActive,
191
+ };
192
+ // Filter out the currently selected item from all nav items
193
+ this.mobileDropdownItems = navItems.filter((item) => item.id !== currentItem.id);
194
+ };
195
+ this.hasActiveOverflowItem = () => {
196
+ return this.overflowItems.some((item) => item.id === this.currentActive);
197
+ };
198
+ this.calculateVisibleItems = () => {
199
+ const navItems = this.getNavItems();
200
+ // Handle case where no navigation items are found
201
+ if (navItems.length === 0) {
202
+ this.visibleItems = [];
203
+ this.overflowItems = [];
204
+ this.selectedMobileItem = null;
205
+ return;
206
+ }
207
+ // Check if we're in mobile mode (below 767px)
208
+ const wasMobile = this.isMobile;
209
+ this.isMobile = window.innerWidth <= 767;
210
+ // Force re-render if mobile state changed
211
+ if (wasMobile !== this.isMobile) {
212
+ this.showOverflowMenu = false; // Close any open menus when switching modes
213
+ }
214
+ if (this.isMobile) {
215
+ // On mobile, show only the current active item
216
+ const activeItem = navItems.find((item) => item.id === this.currentActive) ||
217
+ navItems[0];
218
+ this.selectedMobileItem = activeItem;
219
+ this.visibleItems = [activeItem];
220
+ this.overflowItems = navItems.filter((item) => item.id !== activeItem.id);
221
+ }
222
+ else {
223
+ // Desktop behavior - calculate based on available width
224
+ const containerWidth = this.navContainer
225
+ ? this.navContainer.offsetWidth
226
+ : 0;
227
+ const buttonWidth = this.overflowButton
228
+ ? this.overflowButton.offsetWidth + 32
229
+ : 0; // 32px for gap
230
+ const availableWidth = containerWidth - buttonWidth - 48; // 48px for right margin
231
+ // Fallback if container width is not available yet
232
+ if (containerWidth === 0) {
233
+ this.visibleItems = navItems;
234
+ this.overflowItems = [];
235
+ return;
236
+ }
237
+ let visibleCount = 0;
238
+ let totalWidth = 0;
239
+ // Create temporary elements to measure width
240
+ const tempContainer = document.createElement("div");
241
+ tempContainer.style.position = "absolute";
242
+ tempContainer.style.visibility = "hidden";
243
+ tempContainer.style.whiteSpace = "nowrap";
244
+ tempContainer.style.fontSize = "14px";
245
+ tempContainer.style.fontWeight = "700";
246
+ tempContainer.style.padding = "20px 0 17px 0";
247
+ document.body.appendChild(tempContainer);
248
+ for (let i = 0; i < navItems.length; i++) {
249
+ const item = navItems[i];
250
+ tempContainer.textContent = item.label;
251
+ const itemWidth = tempContainer.offsetWidth + 32; // 32px for gap
252
+ if (totalWidth + itemWidth <= availableWidth) {
253
+ totalWidth += itemWidth;
254
+ visibleCount++;
255
+ }
256
+ else {
257
+ break;
258
+ }
259
+ }
260
+ document.body.removeChild(tempContainer);
261
+ this.visibleItems = navItems.slice(0, visibleCount);
262
+ this.overflowItems = navItems.slice(visibleCount);
263
+ }
264
+ // Don't automatically show overflow menu - it should be closed by default
265
+ // this.showOverflowMenu = this.overflowItems.length > 0;
266
+ };
267
+ this.toggleOverflowMenu = () => {
268
+ this.showOverflowMenu = !this.showOverflowMenu;
269
+ };
270
+ this.handleNavClick = (event, section) => {
271
+ event.preventDefault();
272
+ this.currentActive = section;
273
+ // Update mobile selected item if in mobile mode
274
+ if (this.isMobile) {
275
+ const navItems = this.getNavItems();
276
+ const activeItem = navItems.find((item) => item.id === section);
277
+ if (activeItem) {
278
+ this.selectedMobileItem = activeItem;
279
+ this.calculateMobileDropdownItems();
280
+ }
281
+ }
282
+ // Set manual navigation flag to prevent intersection observer from overriding
283
+ this.isManualNavigation = true;
284
+ // Clear any existing manual navigation timeout
285
+ if (this.manualNavigationTimeout) {
286
+ clearTimeout(this.manualNavigationTimeout);
287
+ }
288
+ // Reset manual navigation flag after scroll animation completes
289
+ this.manualNavigationTimeout = window.setTimeout(() => {
290
+ this.isManualNavigation = false;
291
+ }, 1500); // Give enough time for smooth scroll to complete
292
+ // Emit custom event for parent components
293
+ const customEvent = new CustomEvent("sectionChange", {
294
+ detail: { section },
295
+ bubbles: true,
296
+ composed: true,
297
+ });
298
+ this.el.dispatchEvent(customEvent);
299
+ // Smooth scroll to section if it exists
300
+ const targetElement = document.querySelector(`#${section}`);
301
+ if (targetElement) {
302
+ targetElement.scrollIntoView({
303
+ behavior: "smooth",
304
+ block: "start",
305
+ });
306
+ }
307
+ };
308
+ this.activeSection = "overview";
309
+ this.navItems = "";
310
+ this.currentActive = "overview";
311
+ this.visibleItems = [];
312
+ this.overflowItems = [];
313
+ this.showOverflowMenu = false;
314
+ this.containerWidth = 0;
315
+ this.isMobile = false;
316
+ this.selectedMobileItem = null;
317
+ this.isManualNavigation = false;
318
+ this.mobileDropdownItems = [];
319
+ }
320
+ componentWillLoad() {
321
+ this.currentActive = this.activeSection;
322
+ // Initialize selected mobile item with the current active section
323
+ const navItems = this.getNavItems();
324
+ if (navItems.length > 0) {
325
+ this.selectedMobileItem =
326
+ navItems.find((item) => item.id === this.activeSection) ||
327
+ navItems[0];
328
+ }
329
+ else {
330
+ this.selectedMobileItem = null;
331
+ }
332
+ this.calculateMobileDropdownItems();
333
+ }
334
+ componentDidLoad() {
335
+ // Bind the functions once
336
+ this.boundHandleResize = this.handleResize.bind(this);
337
+ this.boundHandleClickOutside = this.handleClickOutside.bind(this);
338
+ this.boundHandleScroll = this.handleScroll.bind(this);
339
+ this.boundHandleKeyDown = this.handleKeyDown.bind(this);
340
+ // Recalculate navigation items in case slots are used
341
+ this.calculateMobileDropdownItems();
342
+ this.handleResize();
343
+ window.addEventListener("resize", this.boundHandleResize);
344
+ document.addEventListener("click", this.boundHandleClickOutside);
345
+ document.addEventListener("keydown", this.boundHandleKeyDown);
346
+ // Setup intersection observer for scroll-based active state
347
+ this.setupIntersectionObserver();
348
+ // Add scroll listener as fallback
349
+ window.addEventListener("scroll", this.boundHandleScroll, {
350
+ passive: true,
351
+ });
352
+ }
353
+ disconnectedCallback() {
354
+ window.removeEventListener("resize", this.boundHandleResize);
355
+ document.removeEventListener("click", this.boundHandleClickOutside);
356
+ document.removeEventListener("keydown", this.boundHandleKeyDown);
357
+ window.removeEventListener("scroll", this.boundHandleScroll);
358
+ // Clean up intersection observer
359
+ if (this.intersectionObserver) {
360
+ this.intersectionObserver.disconnect();
361
+ }
362
+ // Clean up scroll timeout
363
+ if (this.scrollTimeout) {
364
+ clearTimeout(this.scrollTimeout);
365
+ }
366
+ // Clean up scroll throttle timeout
367
+ if (this.scrollThrottleTimeout) {
368
+ clearTimeout(this.scrollThrottleTimeout);
369
+ }
370
+ // Clean up manual navigation timeout
371
+ if (this.manualNavigationTimeout) {
372
+ clearTimeout(this.manualNavigationTimeout);
373
+ }
374
+ }
375
+ render() {
376
+ var _a, _b;
377
+ const navItems = this.getNavItems();
378
+ // If no navigation items, don't render the navigation
379
+ if (navItems.length === 0) {
380
+ return (index.h(index.Host, null, index.h("div", { class: "subnav-container" }, index.h("div", { class: "subnav-menu-right" }, index.h("slot", { name: "subnav-menu-right" })))));
381
+ }
382
+ return (index.h(index.Host, null, index.h("div", { class: "subnav-container" }, index.h("nav", { class: "subnav-menu-left", role: "navigation", "aria-label": "Sub navigation", ref: (el) => (this.navContainer = el) }, this.isMobile ? (
383
+ // Mobile layout - dropdown with arrows
384
+ index.h("div", { class: "mobile-dropdown-container" }, index.h("button", { class: "mobile-dropdown-button", onClick: this.toggleOverflowMenu, onKeyDown: (e) => {
385
+ if (e.key === "Enter" ||
386
+ e.key === " ") {
387
+ e.preventDefault();
388
+ this.toggleOverflowMenu();
389
+ }
390
+ }, "aria-expanded": this.showOverflowMenu, "aria-haspopup": "true", "aria-label": `${((_a = this.selectedMobileItem) === null || _a === void 0 ? void 0 : _a.label) || "Select Section"} - Choose navigation section`, "tracker-id": "mobile-dropdown-button", ref: (el) => (this.overflowButton = el) }, index.h("span", { class: "mobile-selected-item" }, ((_b = this.selectedMobileItem) === null || _b === void 0 ? void 0 : _b.label) ||
391
+ "Select Section"), index.h("span", { class: `mobile-arrow ${this.showOverflowMenu ? "rotated" : ""}`, "aria-hidden": "true" }, index.h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "12", height: "8", viewBox: "0 0 12 8", fill: "none", "aria-hidden": "true" }, index.h("path", { d: "M1 1.5L5.94975 6.44975L10.8995 1.5", stroke: "#00890B", "stroke-width": "2", "stroke-linecap": "round" })))), this.showOverflowMenu && (index.h("ul", { class: "mobile-dropdown", role: "menu", "aria-label": "Navigation sections" }, this.mobileDropdownItems.map((item) => (index.h("li", { key: item.id }, index.h("a", { href: `#${item.id}`, class: `mobile-dropdown-item mf-listen ${this
392
+ .currentActive ===
393
+ item.id
394
+ ? "active"
395
+ : ""}`, role: "menuitem", "aria-current": this
396
+ .currentActive ===
397
+ item.id
398
+ ? "page"
399
+ : undefined, "tracker-id": item.trackerId ||
400
+ `mobile-nav-${item.id}`, title: item.title || "", onClick: (e) => {
401
+ this.handleNavClick(e, item.id);
402
+ this.showOverflowMenu = false;
403
+ } }, item.label)))))))) : (
404
+ // Desktop layout - original behavior
405
+ index.h("ul", { class: "desktop-menu" }, this.visibleItems.map((item) => (index.h("li", { key: item.id, class: "mf-listen", "tracker-id": item.trackerId || `nav-${item.id}` }, index.h("a", { href: `#${item.id}`, class: this.currentActive === item.id
406
+ ? "active"
407
+ : "", title: item.title || "", onClick: (e) => this.handleNavClick(e, item.id), "aria-current": this.currentActive === item.id
408
+ ? "page"
409
+ : undefined }, item.label)))), this.overflowItems.length > 0 && (index.h("li", { class: "overflow-menu-container mf-listen", "tracker-id": "overflow-menu" }, index.h("button", { class: `overflow-button ${this.hasActiveOverflowItem() ? "selected-active" : ""}`, onClick: this.toggleOverflowMenu, onKeyDown: (e) => {
410
+ if (e.key === "Enter" ||
411
+ e.key === " ") {
412
+ e.preventDefault();
413
+ this.toggleOverflowMenu();
414
+ }
415
+ }, "aria-expanded": this.showOverflowMenu, "aria-haspopup": "true", "aria-label": "Show more navigation items", "tracker-id": "overflow-button", ref: (el) => (this.overflowButton = el) }, index.h("span", { class: "overflow-dots", "aria-hidden": "true" }, index.h("svg", { xmlns: "http://www.w3.org/2000/svg", width: "10", height: "10", viewBox: "0 0 10 10", fill: "none", "aria-hidden": "true" }, index.h("circle", { cx: "1.25", cy: "5", r: "1.25", fill: "#617480" }), index.h("circle", { cx: "5", cy: "5", r: "1.25", fill: "#617480" }), index.h("circle", { cx: "8.75", cy: "5", r: "1.25", fill: "#617480" })))), this.showOverflowMenu && (index.h("div", { class: "overflow-dropdown", role: "menu", "aria-label": "Additional navigation sections" }, this.overflowItems.map((item) => (index.h("a", { key: item.id, href: `#${item.id}`, class: `mf-listen ${this
416
+ .currentActive ===
417
+ item.id
418
+ ? "active"
419
+ : ""}`, title: item.title || "", "tracker-id": item.trackerId ||
420
+ `overflow-link-${item.id}`, role: "menuitem", onClick: (e) => {
421
+ this.handleNavClick(e, item.id);
422
+ this.showOverflowMenu = false;
423
+ }, "aria-current": this
424
+ .currentActive ===
425
+ item.id
426
+ ? "page"
427
+ : undefined }, item.label)))))))))), index.h("div", { class: "subnav-menu-right" }, index.h("slot", { name: "subnav-menu-right" })))));
428
+ }
429
+ get el() { return index.getElement(this); }
430
+ };
431
+ PtcSubnavV2.style = ptcSubnavV2Css;
432
+
433
+ exports.ptc_subnav_v2 = PtcSubnavV2;