@triptease/tt-navbar 0.0.26 → 0.0.28

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.
@@ -17,6 +17,8 @@ export declare class TtNavbar extends LitElement {
17
17
  protected allNavLinks: Array<HTMLAnchorElement>;
18
18
  private sidebarOpen;
19
19
  protected firstUpdated(): void;
20
+ connectedCallback(): void;
21
+ disconnectedCallback(): void;
20
22
  private setActiveState;
21
23
  private closeAllDetails;
22
24
  private toggleSidebar;
@@ -133,6 +133,14 @@ export class TtNavbar extends LitElement {
133
133
  firstUpdated() {
134
134
  this.setActiveState();
135
135
  }
136
+ connectedCallback() {
137
+ window.addEventListener('popstate', this.setActiveState);
138
+ super.connectedCallback();
139
+ }
140
+ disconnectedCallback() {
141
+ window.removeEventListener('popstate', this.setActiveState);
142
+ super.disconnectedCallback();
143
+ }
136
144
  render() {
137
145
  return html `
138
146
  <nav id=${this.id} class="${this.sidebarOpen ? '' : 'sidebar-closed'}">
@@ -1 +1 @@
1
- {"version":3,"file":"TtNavbar.js","sourceRoot":"","sources":["../../src/TtNavbar.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement } from 'lit';\nimport { property, queryAll, state } from 'lit/decorators.js';\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js';\nimport {\n campaigns,\n channels,\n chevronDown,\n external,\n gear,\n graph,\n home,\n logout,\n sidebarCollapsed,\n user,\n wallet\n} from '@triptease/icons';\nimport '@triptease/tt-combobox';\nimport { styles } from './styles.js';\nimport { tripteaseLogo } from './triptease-logo.js';\nimport { urlMappings } from './urlMappings.js';\nimport { Routes } from './Routes.js';\n\nconst jsonArrayConverter = (value: string | null) => {\n if (!value) return [];\n try {\n return JSON.parse(value);\n } catch {\n return [];\n }\n};\n\nexport class TtNavbar extends LitElement {\n static styles = styles;\n\n @property({ type: Function })\n navigate: ((e: MouseEvent) => void) | undefined;\n\n @property({ type: String, attribute: 'campaign-manager-url' })\n campaignManagerUrl: string = 'https://app.campaign-manager.triptease.io';\n\n @property({ type: String, attribute: 'platform-url' })\n platformUrl?: string;\n\n @property({ type: String, attribute: 'client-key' })\n clientKey?: string;\n\n @property({ type: String, attribute: 'active-route' })\n activeRoute?: keyof typeof Routes;\n\n @property({ type: Array, converter: jsonArrayConverter })\n clients: { clientKey: string; displayName: string }[] = [];\n\n @property({ type: Object })\n onClientChange: ((clientKeySelected: string) => void ) | undefined;\n\n @queryAll('details')\n protected allDetailsElements!: Array<HTMLDetailsElement>;\n\n @queryAll('a')\n protected allNavLinks!: Array<HTMLAnchorElement>;\n\n @state()\n private sidebarOpen = true;\n\n protected firstUpdated() {\n this.setActiveState();\n }\n\n /*\n * Set the active state for the current page.\n *\n * This function iterates over all nav links and compares the current URL path with the href of each link.\n * If the current URL path starts with the href of a link, the link is marked as active. If multiple links\n * share the same prefix, the longest prefix is used as it is more specific.\n *\n * Example:\n * - Current URL: /channels/123\n * - Nav links:\n * - /channels\n * - /channels/123\n * - /channels/456\n *\n * Loop 1: currentPath = /channels/123, linkPath = /channels, bestMatch = /channels\n * Loop 2: currentPath = /channels/123, linkPath = /channels/123, bestMatch = /channels/123\n * Loop 3: currentPath = /channels/123, linkPath = /channels/456, bestMatch = /channels/123\n * Result: /channels/123 is marked as active\n *\n */\n private setActiveState = () => {\n const currentPath = window.location.pathname;\n\n let bestMatch: HTMLAnchorElement | undefined;\n let bestMatchLength = 0;\n\n // Check special cases first, as everything will always match on / and return Dashboard\n if (this.activeRoute === Routes.CampaignManager) {\n const links = Object.values(this.allNavLinks);\n bestMatch = links.find(link => link.id === Routes.CampaignManager);\n }\n\n if (!bestMatch && this.clientKey) {\n const parsedPath = currentPath.replace(this.clientKey, '$CLIENT_KEY');\n const mappedUrl = urlMappings[parsedPath];\n\n if (mappedUrl) {\n const links = Object.values(this.allNavLinks);\n bestMatch = links.find(link => link.href.includes(mappedUrl));\n }\n }\n\n if (!bestMatch) {\n for (const link of this.allNavLinks) {\n link.classList.remove('current-page');\n if (link.hasAttribute('aria-current')) {\n link.attributes.removeNamedItem('aria-current');\n }\n\n const linkPath = new URL(link.href).pathname;\n\n if (currentPath.startsWith(linkPath)) {\n if (linkPath.length > bestMatchLength) {\n bestMatch = link;\n bestMatchLength = linkPath.length;\n }\n }\n }\n }\n\n if (bestMatch) {\n bestMatch.classList.add('current-page');\n bestMatch.setAttribute('aria-current', 'page');\n } else {\n console.error(`No matching nav link found for path: ${currentPath}`);\n }\n };\n\n private closeAllDetails = (element?: HTMLDetailsElement) => {\n this.allDetailsElements.forEach(detail => {\n if (element && !detail.contains(element)) {\n detail.removeAttribute('open');\n } else if (!element) {\n detail.removeAttribute('open');\n }\n });\n };\n\n private toggleSidebar = () => {\n this.closeAllDetails();\n this.sidebarOpen = !this.sidebarOpen;\n };\n\n private handleToggle = (e: ToggleEvent) => {\n const { newState } = e;\n const target = e.currentTarget as HTMLDetailsElement;\n\n if (newState === 'open') {\n if (!this.sidebarOpen) {\n this.sidebarOpen = true;\n }\n\n this.closeAllDetails(target);\n }\n };\n\n private buildUrl = (path: string): string => {\n if (!this.clientKey) throw new Error('clientKey is required');\n\n const formattedPath = path.replace('$CLIENT_KEY', this.clientKey);\n if (!this.platformUrl) return formattedPath;\n\n return new URL(formattedPath, this.platformUrl).toString();\n };\n\n private onAnchorClick = (e: MouseEvent) => {\n if (this.navigate) {\n this.navigate(e);\n this.setActiveState();\n }\n };\n\n private handleClientChange = (e: Event) => {\n const combobox = e.target as any;\n const selectedClientKey = combobox.value?.[0];\n\n if (selectedClientKey && this.onClientChange) {\n this.onClientChange(selectedClientKey);\n }\n };\n\n render() {\n return html`\n <nav id=${this.id} class=\"${this.sidebarOpen ? '' : 'sidebar-closed'}\">\n <div class=\"sidebar-header ${this.sidebarOpen ? '' : 'sidebar-closed'}\">\n <div class=\"logo\">\n ${unsafeSVG(tripteaseLogo)}\n </div>\n <button id=\"navbar-toggle-btn\" class=\"nav-item nav-toggle-button\" @click=${this.toggleSidebar}>\n ${unsafeSVG(sidebarCollapsed)}\n <span class=\"tooltip nav-toggle-tooltip\">\n ${unsafeSVG(sidebarCollapsed)}\n <span>Collapse sidebar</span>\n </span>\n </button>\n </div>\n\n <div class=\"nav-items ${this.sidebarOpen ? '' : 'sidebar-closed'}\">\n <a\n class=\"nav-item\"\n href=${this.buildUrl('/')}\n @click=${this.onAnchorClick}\n >${unsafeSVG(home)}<span>Dashboard</span></a\n >\n <a id=\"${Routes.CampaignManager}\" class=\"nav-item\" href=${this.campaignManagerUrl}\n >${unsafeSVG(campaigns)}<span>Campaigns</span></a\n >\n <a\n class=\"nav-item\"\n href=${this.buildUrl('/channels')}\n @click=${this.onAnchorClick}\n >${unsafeSVG(channels)}<span>Channels</span></a\n >\n <details id=\"market-insights\" @toggle=${this.handleToggle}>\n <summary>\n ${unsafeSVG(graph)}\n <span>Market Insights</span>\n <span class=\"icon chevron\"> ${unsafeSVG(chevronDown)}</span>\n </summary>\n <div class=\"dropdown-items\">\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/parity/$CLIENT_KEY')}\n @click=${this.onAnchorClick}\n >Parity monitoring</a\n >\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/guest-insights/$CLIENT_KEY')}\n @click=${this.onAnchorClick}\n >Guest insights</a\n >\n </div>\n </details>\n <details id=\"settings\" @toggle=${this.handleToggle}>\n <summary>\n ${unsafeSVG(gear)}\n <span>Settings</span>\n <span class=\"icon chevron\"> ${unsafeSVG(chevronDown)}</span>\n </summary>\n <div class=\"dropdown-items\">\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/$CLIENT_KEY/guest-behavioural-data')}\n @click=${this.onAnchorClick}\n >Email setup</a\n >\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/$CLIENT_KEY/crm-config')}\n @click=${this.onAnchorClick}\n >CRM connectivity</a\n >\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/settings/$CLIENT_KEY/guides')}\n @click=${this.onAnchorClick}\n >Group settings</a\n >\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/settings/$CLIENT_KEY/hotels')}\n @click=${this.onAnchorClick}\n >Property settings</a\n >\n </div>\n </details>\n <hr />\n <details id=\"account\" @toggle=${this.handleToggle}>\n <summary>\n ${unsafeSVG(user)}\n <span>Account</span>\n <span class=\"icon chevron\"> ${unsafeSVG(chevronDown)}</span>\n </summary>\n <div class=\"dropdown-items\">\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/account')}\n @click=${this.onAnchorClick}\n >User settings</a\n >\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/account/team/$CLIENT_KEY')}\n @click=${this.onAnchorClick}\n >Team and permissions</a\n >\n </div>\n </details>\n <details id=\"billing-routes\" @toggle=${this.handleToggle}>\n <summary>\n ${unsafeSVG(wallet)}\n <span>Billing</span>\n <span class=\"icon chevron\"> ${unsafeSVG(chevronDown)}</span>\n </summary>\n <div>\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/account/billing-management/$CLIENT_KEY')}\n @click=${this.onAnchorClick}\n >Booking reconciliation</a\n >\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/subscriptions/$CLIENT_KEY')}\n @click=${this.onAnchorClick}\n >Subscriptions</a\n >\n </div>\n </details>\n </div>\n <div class=\"tertiary-nav ${this.sidebarOpen ? '' : 'sidebar-closed'}\">\n <div id=\"external-links\" class=\"nav-items\">\n <a\n class=\"nav-item external-link\"\n href='https://triptease.canny.io/feature-requests'\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n Feature requests\n ${unsafeSVG(external)}\n </a>\n <a\n class='nav-item external-link'\n href='https://triptease.canny.io/changelog'\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n Product updates\n ${unsafeSVG(external)}\n </a>\n <a\n class='nav-item external-link'\n href='https://help.triptease.com/'\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n Help center\n ${unsafeSVG(external)}\n </a>\n <hr />\n </div>\n <div class='nav-items'>\n <div id=\"client-selector\">\n ${this.clients.length > 1 ? html`\n <tt-combobox\n .openUpward=${true}\n .value=${this.clientKey ? [this.clientKey] : []}\n @change=${this.handleClientChange}\n >\n ${this.clients.map((client) => html`\n <option slot=\"option\" value=${client.clientKey}>\n ${client.displayName}\n </option>\n `)}\n </tt-combobox>\n ` : html`\n <div class=\"single-client-name\">\n ${this.clients.find((m) => m.clientKey === this.clientKey)?.displayName}\n </div>\n `}\n </div>\n <a\n id=\"logout-link\"\n class=\"nav-item\"\n href=${this.buildUrl('/logout')}\n @click=${this.onAnchorClick}\n >${unsafeSVG(logout)}<span>Logout</span></a>\n </div>\n </nav>\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"TtNavbar.js","sourceRoot":"","sources":["../../src/TtNavbar.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement } from 'lit';\nimport { property, queryAll, state } from 'lit/decorators.js';\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js';\nimport {\n campaigns,\n channels,\n chevronDown,\n external,\n gear,\n graph,\n home,\n logout,\n sidebarCollapsed,\n user,\n wallet\n} from '@triptease/icons';\nimport '@triptease/tt-combobox';\nimport { styles } from './styles.js';\nimport { tripteaseLogo } from './triptease-logo.js';\nimport { urlMappings } from './urlMappings.js';\nimport { Routes } from './Routes.js';\n\nconst jsonArrayConverter = (value: string | null) => {\n if (!value) return [];\n try {\n return JSON.parse(value);\n } catch {\n return [];\n }\n};\n\nexport class TtNavbar extends LitElement {\n static styles = styles;\n\n @property({ type: Function })\n navigate: ((e: MouseEvent) => void) | undefined;\n\n @property({ type: String, attribute: 'campaign-manager-url' })\n campaignManagerUrl: string = 'https://app.campaign-manager.triptease.io';\n\n @property({ type: String, attribute: 'platform-url' })\n platformUrl?: string;\n\n @property({ type: String, attribute: 'client-key' })\n clientKey?: string;\n\n @property({ type: String, attribute: 'active-route' })\n activeRoute?: keyof typeof Routes;\n\n @property({ type: Array, converter: jsonArrayConverter })\n clients: { clientKey: string; displayName: string }[] = [];\n\n @property({ type: Object })\n onClientChange: ((clientKeySelected: string) => void ) | undefined;\n\n @queryAll('details')\n protected allDetailsElements!: Array<HTMLDetailsElement>;\n\n @queryAll('a')\n protected allNavLinks!: Array<HTMLAnchorElement>;\n\n @state()\n private sidebarOpen = true;\n\n protected firstUpdated() {\n this.setActiveState();\n }\n\n public connectedCallback() {\n\n window.addEventListener('popstate', this.setActiveState);\n super.connectedCallback();\n }\n\n public disconnectedCallback() {\n\n window.removeEventListener('popstate', this.setActiveState);\n super.disconnectedCallback();\n }\n\n /*\n * Set the active state for the current page.\n *\n * This function iterates over all nav links and compares the current URL path with the href of each link.\n * If the current URL path starts with the href of a link, the link is marked as active. If multiple links\n * share the same prefix, the longest prefix is used as it is more specific.\n *\n * Example:\n * - Current URL: /channels/123\n * - Nav links:\n * - /channels\n * - /channels/123\n * - /channels/456\n *\n * Loop 1: currentPath = /channels/123, linkPath = /channels, bestMatch = /channels\n * Loop 2: currentPath = /channels/123, linkPath = /channels/123, bestMatch = /channels/123\n * Loop 3: currentPath = /channels/123, linkPath = /channels/456, bestMatch = /channels/123\n * Result: /channels/123 is marked as active\n *\n */\n private setActiveState = () => {\n const currentPath = window.location.pathname;\n\n let bestMatch: HTMLAnchorElement | undefined;\n let bestMatchLength = 0;\n\n // Check special cases first, as everything will always match on / and return Dashboard\n if (this.activeRoute === Routes.CampaignManager) {\n const links = Object.values(this.allNavLinks);\n bestMatch = links.find(link => link.id === Routes.CampaignManager);\n }\n\n if (!bestMatch && this.clientKey) {\n const parsedPath = currentPath.replace(this.clientKey, '$CLIENT_KEY');\n const mappedUrl = urlMappings[parsedPath];\n\n if (mappedUrl) {\n const links = Object.values(this.allNavLinks);\n bestMatch = links.find(link => link.href.includes(mappedUrl));\n }\n }\n\n if (!bestMatch) {\n for (const link of this.allNavLinks) {\n link.classList.remove('current-page');\n if (link.hasAttribute('aria-current')) {\n link.attributes.removeNamedItem('aria-current');\n }\n\n const linkPath = new URL(link.href).pathname;\n\n if (currentPath.startsWith(linkPath)) {\n if (linkPath.length > bestMatchLength) {\n bestMatch = link;\n bestMatchLength = linkPath.length;\n }\n }\n }\n }\n\n if (bestMatch) {\n bestMatch.classList.add('current-page');\n bestMatch.setAttribute('aria-current', 'page');\n } else {\n console.error(`No matching nav link found for path: ${currentPath}`);\n }\n };\n\n private closeAllDetails = (element?: HTMLDetailsElement) => {\n this.allDetailsElements.forEach(detail => {\n if (element && !detail.contains(element)) {\n detail.removeAttribute('open');\n } else if (!element) {\n detail.removeAttribute('open');\n }\n });\n };\n\n private toggleSidebar = () => {\n this.closeAllDetails();\n this.sidebarOpen = !this.sidebarOpen;\n };\n\n private handleToggle = (e: ToggleEvent) => {\n const { newState } = e;\n const target = e.currentTarget as HTMLDetailsElement;\n\n if (newState === 'open') {\n if (!this.sidebarOpen) {\n this.sidebarOpen = true;\n }\n\n this.closeAllDetails(target);\n }\n };\n\n private buildUrl = (path: string): string => {\n if (!this.clientKey) throw new Error('clientKey is required');\n\n const formattedPath = path.replace('$CLIENT_KEY', this.clientKey);\n if (!this.platformUrl) return formattedPath;\n\n return new URL(formattedPath, this.platformUrl).toString();\n };\n\n private onAnchorClick = (e: MouseEvent) => {\n if (this.navigate) {\n this.navigate(e);\n this.setActiveState();\n }\n };\n\n private handleClientChange = (e: Event) => {\n const combobox = e.target as any;\n const selectedClientKey = combobox.value?.[0];\n\n if (selectedClientKey && this.onClientChange) {\n this.onClientChange(selectedClientKey);\n }\n };\n\n render() {\n return html`\n <nav id=${this.id} class=\"${this.sidebarOpen ? '' : 'sidebar-closed'}\">\n <div class=\"sidebar-header ${this.sidebarOpen ? '' : 'sidebar-closed'}\">\n <div class=\"logo\">\n ${unsafeSVG(tripteaseLogo)}\n </div>\n <button id=\"navbar-toggle-btn\" class=\"nav-item nav-toggle-button\" @click=${this.toggleSidebar}>\n ${unsafeSVG(sidebarCollapsed)}\n <span class=\"tooltip nav-toggle-tooltip\">\n ${unsafeSVG(sidebarCollapsed)}\n <span>Collapse sidebar</span>\n </span>\n </button>\n </div>\n\n <div class=\"nav-items ${this.sidebarOpen ? '' : 'sidebar-closed'}\">\n <a\n class=\"nav-item\"\n href=${this.buildUrl('/')}\n @click=${this.onAnchorClick}\n >${unsafeSVG(home)}<span>Dashboard</span></a\n >\n <a id=\"${Routes.CampaignManager}\" class=\"nav-item\" href=${this.campaignManagerUrl}\n >${unsafeSVG(campaigns)}<span>Campaigns</span></a\n >\n <a\n class=\"nav-item\"\n href=${this.buildUrl('/channels')}\n @click=${this.onAnchorClick}\n >${unsafeSVG(channels)}<span>Channels</span></a\n >\n <details id=\"market-insights\" @toggle=${this.handleToggle}>\n <summary>\n ${unsafeSVG(graph)}\n <span>Market Insights</span>\n <span class=\"icon chevron\"> ${unsafeSVG(chevronDown)}</span>\n </summary>\n <div class=\"dropdown-items\">\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/parity/$CLIENT_KEY')}\n @click=${this.onAnchorClick}\n >Parity monitoring</a\n >\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/guest-insights/$CLIENT_KEY')}\n @click=${this.onAnchorClick}\n >Guest insights</a\n >\n </div>\n </details>\n <details id=\"settings\" @toggle=${this.handleToggle}>\n <summary>\n ${unsafeSVG(gear)}\n <span>Settings</span>\n <span class=\"icon chevron\"> ${unsafeSVG(chevronDown)}</span>\n </summary>\n <div class=\"dropdown-items\">\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/$CLIENT_KEY/guest-behavioural-data')}\n @click=${this.onAnchorClick}\n >Email setup</a\n >\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/$CLIENT_KEY/crm-config')}\n @click=${this.onAnchorClick}\n >CRM connectivity</a\n >\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/settings/$CLIENT_KEY/guides')}\n @click=${this.onAnchorClick}\n >Group settings</a\n >\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/settings/$CLIENT_KEY/hotels')}\n @click=${this.onAnchorClick}\n >Property settings</a\n >\n </div>\n </details>\n <hr />\n <details id=\"account\" @toggle=${this.handleToggle}>\n <summary>\n ${unsafeSVG(user)}\n <span>Account</span>\n <span class=\"icon chevron\"> ${unsafeSVG(chevronDown)}</span>\n </summary>\n <div class=\"dropdown-items\">\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/account')}\n @click=${this.onAnchorClick}\n >User settings</a\n >\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/account/team/$CLIENT_KEY')}\n @click=${this.onAnchorClick}\n >Team and permissions</a\n >\n </div>\n </details>\n <details id=\"billing-routes\" @toggle=${this.handleToggle}>\n <summary>\n ${unsafeSVG(wallet)}\n <span>Billing</span>\n <span class=\"icon chevron\"> ${unsafeSVG(chevronDown)}</span>\n </summary>\n <div>\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/account/billing-management/$CLIENT_KEY')}\n @click=${this.onAnchorClick}\n >Booking reconciliation</a\n >\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/subscriptions/$CLIENT_KEY')}\n @click=${this.onAnchorClick}\n >Subscriptions</a\n >\n </div>\n </details>\n </div>\n <div class=\"tertiary-nav ${this.sidebarOpen ? '' : 'sidebar-closed'}\">\n <div id=\"external-links\" class=\"nav-items\">\n <a\n class=\"nav-item external-link\"\n href='https://triptease.canny.io/feature-requests'\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n Feature requests\n ${unsafeSVG(external)}\n </a>\n <a\n class='nav-item external-link'\n href='https://triptease.canny.io/changelog'\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n Product updates\n ${unsafeSVG(external)}\n </a>\n <a\n class='nav-item external-link'\n href='https://help.triptease.com/'\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n Help center\n ${unsafeSVG(external)}\n </a>\n <hr />\n </div>\n <div class='nav-items'>\n <div id=\"client-selector\">\n ${this.clients.length > 1 ? html`\n <tt-combobox\n .openUpward=${true}\n .value=${this.clientKey ? [this.clientKey] : []}\n @change=${this.handleClientChange}\n >\n ${this.clients.map((client) => html`\n <option slot=\"option\" value=${client.clientKey}>\n ${client.displayName}\n </option>\n `)}\n </tt-combobox>\n ` : html`\n <div class=\"single-client-name\">\n ${this.clients.find((m) => m.clientKey === this.clientKey)?.displayName}\n </div>\n `}\n </div>\n <a\n id=\"logout-link\"\n class=\"nav-item\"\n href=${this.buildUrl('/logout')}\n @click=${this.onAnchorClick}\n >${unsafeSVG(logout)}<span>Logout</span></a>\n </div>\n </nav>\n `;\n }\n}\n"]}
@@ -193,6 +193,13 @@ export const styles = css `
193
193
  }
194
194
  }
195
195
 
196
+ .sidebar-closed details:has(.current-page) > summary {
197
+ --nav-item-color: var(--color-primary-400);
198
+ border-radius: var(--border-radius-100);
199
+ background-color: var(--color-primary-100);
200
+ color: var(--nav-item-color);
201
+ }
202
+
196
203
  .sub-nav-item {
197
204
  width: 100%;
198
205
  display: flex;
@@ -224,8 +231,7 @@ export const styles = css `
224
231
  }
225
232
  }
226
233
 
227
- .current-page,
228
- .sidebar-closed details:has(.current-page) > summary {
234
+ .current-page {
229
235
  --nav-item-color: var(--color-primary-400);
230
236
  border-radius: var(--border-radius-100);
231
237
  background-color: var(--color-primary-100);
@@ -1 +1 @@
1
- {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../src/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,MAAM,iBAAiB,GAAG,GAAG,CAAA;;;;;;;;;;;CAW5B,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAoCf,iBAAiB;;;;UAIjB,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA6DjB,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwP1B,CAAC","sourcesContent":["import { css } from 'lit';\n\nconst visuallyHiddenCss = css`\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n border: 0;\n overflow: hidden;\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n white-space: nowrap;\n`;\n\nexport const styles = css`\n :host {\n --nav-bar-width: 260px;\n\n display: block;\n height: 100vh;\n }\n\n * {\n box-sizing: border-box;\n }\n\n nav {\n max-width: var(--nav-bar-width);\n width: var(--nav-bar-width);\n min-height: 100vh;\n height: max-content;\n display: flex;\n align-items: start;\n gap: var(--space-scale-3-5);\n flex-direction: column;\n background-color: var(--color-surface-inverted-100);\n color: var(--color-text-inverted-400);\n padding-top: var(--space-scale-2);\n padding-bottom: var(--space-scale-2);\n z-index: 1;\n\n .nav-items {\n display: flex;\n flex-direction: column;\n padding: 0 var(--space-scale-1);\n width: 100%;\n }\n\n .nav-items.sidebar-closed {\n a span {\n ${visuallyHiddenCss}\n }\n\n details summary span {\n ${visuallyHiddenCss}\n }\n }\n\n .sidebar-header {\n width: 100%;\n display: grid;\n grid-template-columns: 1fr auto;\n align-items: center;\n justify-content: center;\n padding: 0 var(--space-scale-2);\n\n button {\n background-color: transparent;\n color: var(--color-text-inverted-400);\n border: none;\n }\n }\n\n .sidebar-header.sidebar-closed {\n padding: 0 var(--space-scale-1);\n .logo {\n display: none;\n visibility: hidden;\n }\n }\n\n hr {\n width: 100%;\n height: 1px;\n background-color: var(--color-surface-inverted-200);\n border: none;\n }\n\n .tertiary-nav {\n display: flex;\n flex-direction: column;\n margin-top: auto;\n gap: var(--space-scale-2);\n width: 100%;\n\n .external-link {\n font-size: var(--font-size-100);\n line-height: var(--font-line-height-100);\n\n .icon {\n width: var(--space-scale-2);\n height: var(--space-scale-2);\n }\n }\n }\n\n .tertiary-nav.sidebar-closed {\n .external-link,\n hr,\n #client-selector {\n display: none;\n visibility: hidden;\n }\n\n a span {\n ${visuallyHiddenCss}\n }\n }\n\n .icon {\n display: flex;\n align-items: center;\n width: var(--space-scale-3);\n height: var(--space-scale-3);\n color: var(--nav-item-color);\n }\n\n .nav-item {\n display: flex;\n font-size: var(--font-size-100);\n line-height: var(--font-line-height-100);\n gap: var(--space-scale-1-5);\n border-radius: var(--border-radius-100);\n color: var(--nav-item-color);\n align-items: center;\n padding: var(--space-scale-1);\n width: 100%;\n text-decoration: none;\n }\n }\n\n nav.sidebar-closed {\n width: fit-content;\n }\n\n details {\n border-radius: var(--border-radius-100);\n\n summary {\n font-size: var(--font-size-100);\n line-height: var(--font-line-height-100);\n position: relative;\n display: flex;\n align-items: baseline;\n\n &::marker {\n content: '';\n }\n }\n\n .chevron {\n margin-left: auto;\n margin-right: var(--space-scale-1);\n width: var(--space-scale-2);\n }\n\n &[open] .chevron {\n transform: rotate(180deg);\n }\n\n .dropdown-items {\n display: flex;\n flex-direction: column;\n }\n }\n\n details > summary {\n display: flex;\n gap: var(--space-scale-1-5);\n padding: var(--space-scale-1);\n border-radius: var(--border-radius-100);\n color: var(--nav-item-color);\n align-items: center;\n\n a {\n color: var(--nav-item-color);\n }\n\n &:hover,\n &:focus-visible {\n background-color: var(--color-surface-inverted-200);\n border-radius: var(--border-radius-100);\n text-decoration: none;\n }\n }\n\n .sub-nav-item {\n width: 100%;\n display: flex;\n padding-left: 44px;\n padding-top: 10px;\n padding-bottom: 10px;\n color: var(--color-text-inverted-400);\n font-size: var(--font-size-100);\n line-height: var(--font-line-height-100);\n text-decoration: none;\n\n button {\n color: var(--color-text-inverted-400);\n padding: 0;\n }\n }\n\n .sub-nav-item:hover,\n .sub-nav-item:focus-visible,\n .nav-item:hover,\n .nav-item:focus-visible {\n background-color: var(--color-surface-inverted-200);\n border-radius: var(--border-radius-100);\n text-decoration: none;\n color: var(--color-text-inverted-400);\n\n .icon {\n color: var(--color-text-inverted-400);\n }\n }\n\n .current-page,\n .sidebar-closed details:has(.current-page) > summary {\n --nav-item-color: var(--color-primary-400);\n border-radius: var(--border-radius-100);\n background-color: var(--color-primary-100);\n color: var(--nav-item-color);\n }\n\n .link-page {\n display: flex;\n position: absolute;\n overflow: auto;\n flex-direction: column;\n gap: var(--space-scale-4);\n padding: var(--space-scale-5);\n left: var(--nav-bar-width);\n background-color: var(--color-surface-200);\n width: calc(100% - var(--nav-bar-width));\n height: 100%;\n transition-property: left, visibility;\n transition-duration: 700ms, 400ms;\n transition-timing-function: ease-out, ease-in;\n\n &.hidden {\n left: -100%;\n visibility: hidden;\n }\n }\n\n .link-page > .section {\n display: flex;\n flex-direction: column;\n gap: var(--space-scale-2);\n }\n\n .section > .links-container {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: var(--space-scale-3);\n overflow-y: auto;\n height: 100%;\n }\n\n .visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n border: 0;\n overflow: hidden;\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n white-space: nowrap;\n }\n\n .tooltip {\n position: absolute;\n display: flex;\n white-space: nowrap;\n align-items: center;\n gap: var(--space-scale-1);\n color: black;\n background-color: var(--color-surface-600);\n padding: var(--space-scale-1);\n z-index: 1000;\n border-radius: var(--border-radius-50);\n font-weight: var(--font-weight-medium);\n }\n\n .auth-container {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n }\n\n .error-container {\n padding: 4rem 1rem 1rem;\n max-width: 1280px;\n margin-left: auto;\n margin-right: auto;\n }\n\n .error-stack {\n width: 100%;\n padding: 1rem;\n overflow-x: auto;\n }\n\n .fullscreen-iframe {\n width: 100%;\n height: 100vh;\n border: 0;\n }\n\n .nav-toggle-button {\n position: relative;\n }\n\n .nav-toggle-tooltip {\n left: 100%;\n top: 100%;\n visibility: hidden;\n opacity: 0;\n }\n\n .nav-toggle-button:hover .nav-toggle-tooltip {\n visibility: visible;\n opacity: 1;\n }\n\n #client-selector {\n display: flex;\n align-items: center;\n }\n\n #client-selector tt-combobox {\n --tt-combobox-color: var(--color-text-inverted-400);\n --tt-combobox-dropdown-color: var(--color-text-inverted-400);\n --tt-combobox-list-background-color: var(--color-surface-inverted-100);\n --tt-combobox-option-background-color-hover: var(--color-surface-inverted-200);\n --tt-combobox-placeholder-color: var(--color-text-inverted-300);\n --tt-combobox-background-color: var(--color-surface-inverted-100);\n --tt-combobox-hover-background-color: var(--color-surface-inverted-200);\n --tt-combobox-list-max-width: 80ch;\n --tt-combobox-min-width: 244px;\n --tt-combobox-max-width: 244px;\n }\n\n .single-client-name {\n height: 39px;\n padding: var(--space-scale-1); /* match tt-combobox height */\n font-size: var(--font-size-100);\n color: var(--color-text-inverted-400);\n }\n`;\n"]}
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../src/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,MAAM,iBAAiB,GAAG,GAAG,CAAA;;;;;;;;;;;CAW5B,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAoCf,iBAAiB;;;;UAIjB,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA6DjB,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8P1B,CAAC","sourcesContent":["import { css } from 'lit';\n\nconst visuallyHiddenCss = css`\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n border: 0;\n overflow: hidden;\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n white-space: nowrap;\n`;\n\nexport const styles = css`\n :host {\n --nav-bar-width: 260px;\n\n display: block;\n height: 100vh;\n }\n\n * {\n box-sizing: border-box;\n }\n\n nav {\n max-width: var(--nav-bar-width);\n width: var(--nav-bar-width);\n min-height: 100vh;\n height: max-content;\n display: flex;\n align-items: start;\n gap: var(--space-scale-3-5);\n flex-direction: column;\n background-color: var(--color-surface-inverted-100);\n color: var(--color-text-inverted-400);\n padding-top: var(--space-scale-2);\n padding-bottom: var(--space-scale-2);\n z-index: 1;\n\n .nav-items {\n display: flex;\n flex-direction: column;\n padding: 0 var(--space-scale-1);\n width: 100%;\n }\n\n .nav-items.sidebar-closed {\n a span {\n ${visuallyHiddenCss}\n }\n\n details summary span {\n ${visuallyHiddenCss}\n }\n }\n\n .sidebar-header {\n width: 100%;\n display: grid;\n grid-template-columns: 1fr auto;\n align-items: center;\n justify-content: center;\n padding: 0 var(--space-scale-2);\n\n button {\n background-color: transparent;\n color: var(--color-text-inverted-400);\n border: none;\n }\n }\n\n .sidebar-header.sidebar-closed {\n padding: 0 var(--space-scale-1);\n .logo {\n display: none;\n visibility: hidden;\n }\n }\n\n hr {\n width: 100%;\n height: 1px;\n background-color: var(--color-surface-inverted-200);\n border: none;\n }\n\n .tertiary-nav {\n display: flex;\n flex-direction: column;\n margin-top: auto;\n gap: var(--space-scale-2);\n width: 100%;\n\n .external-link {\n font-size: var(--font-size-100);\n line-height: var(--font-line-height-100);\n\n .icon {\n width: var(--space-scale-2);\n height: var(--space-scale-2);\n }\n }\n }\n\n .tertiary-nav.sidebar-closed {\n .external-link,\n hr,\n #client-selector {\n display: none;\n visibility: hidden;\n }\n\n a span {\n ${visuallyHiddenCss}\n }\n }\n\n .icon {\n display: flex;\n align-items: center;\n width: var(--space-scale-3);\n height: var(--space-scale-3);\n color: var(--nav-item-color);\n }\n\n .nav-item {\n display: flex;\n font-size: var(--font-size-100);\n line-height: var(--font-line-height-100);\n gap: var(--space-scale-1-5);\n border-radius: var(--border-radius-100);\n color: var(--nav-item-color);\n align-items: center;\n padding: var(--space-scale-1);\n width: 100%;\n text-decoration: none;\n }\n }\n\n nav.sidebar-closed {\n width: fit-content;\n }\n\n details {\n border-radius: var(--border-radius-100);\n\n summary {\n font-size: var(--font-size-100);\n line-height: var(--font-line-height-100);\n position: relative;\n display: flex;\n align-items: baseline;\n\n &::marker {\n content: '';\n }\n }\n\n .chevron {\n margin-left: auto;\n margin-right: var(--space-scale-1);\n width: var(--space-scale-2);\n }\n\n &[open] .chevron {\n transform: rotate(180deg);\n }\n\n .dropdown-items {\n display: flex;\n flex-direction: column;\n }\n }\n\n details > summary {\n display: flex;\n gap: var(--space-scale-1-5);\n padding: var(--space-scale-1);\n border-radius: var(--border-radius-100);\n color: var(--nav-item-color);\n align-items: center;\n\n a {\n color: var(--nav-item-color);\n }\n\n &:hover,\n &:focus-visible {\n background-color: var(--color-surface-inverted-200);\n border-radius: var(--border-radius-100);\n text-decoration: none;\n }\n }\n\n .sidebar-closed details:has(.current-page) > summary {\n --nav-item-color: var(--color-primary-400);\n border-radius: var(--border-radius-100);\n background-color: var(--color-primary-100);\n color: var(--nav-item-color);\n }\n\n .sub-nav-item {\n width: 100%;\n display: flex;\n padding-left: 44px;\n padding-top: 10px;\n padding-bottom: 10px;\n color: var(--color-text-inverted-400);\n font-size: var(--font-size-100);\n line-height: var(--font-line-height-100);\n text-decoration: none;\n\n button {\n color: var(--color-text-inverted-400);\n padding: 0;\n }\n }\n\n .sub-nav-item:hover,\n .sub-nav-item:focus-visible,\n .nav-item:hover,\n .nav-item:focus-visible {\n background-color: var(--color-surface-inverted-200);\n border-radius: var(--border-radius-100);\n text-decoration: none;\n color: var(--color-text-inverted-400);\n\n .icon {\n color: var(--color-text-inverted-400);\n }\n }\n\n .current-page {\n --nav-item-color: var(--color-primary-400);\n border-radius: var(--border-radius-100);\n background-color: var(--color-primary-100);\n color: var(--nav-item-color);\n }\n\n .link-page {\n display: flex;\n position: absolute;\n overflow: auto;\n flex-direction: column;\n gap: var(--space-scale-4);\n padding: var(--space-scale-5);\n left: var(--nav-bar-width);\n background-color: var(--color-surface-200);\n width: calc(100% - var(--nav-bar-width));\n height: 100%;\n transition-property: left, visibility;\n transition-duration: 700ms, 400ms;\n transition-timing-function: ease-out, ease-in;\n\n &.hidden {\n left: -100%;\n visibility: hidden;\n }\n }\n\n .link-page > .section {\n display: flex;\n flex-direction: column;\n gap: var(--space-scale-2);\n }\n\n .section > .links-container {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: var(--space-scale-3);\n overflow-y: auto;\n height: 100%;\n }\n\n .visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n border: 0;\n overflow: hidden;\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n white-space: nowrap;\n }\n\n .tooltip {\n position: absolute;\n display: flex;\n white-space: nowrap;\n align-items: center;\n gap: var(--space-scale-1);\n color: black;\n background-color: var(--color-surface-600);\n padding: var(--space-scale-1);\n z-index: 1000;\n border-radius: var(--border-radius-50);\n font-weight: var(--font-weight-medium);\n }\n\n .auth-container {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 100vh;\n }\n\n .error-container {\n padding: 4rem 1rem 1rem;\n max-width: 1280px;\n margin-left: auto;\n margin-right: auto;\n }\n\n .error-stack {\n width: 100%;\n padding: 1rem;\n overflow-x: auto;\n }\n\n .fullscreen-iframe {\n width: 100%;\n height: 100vh;\n border: 0;\n }\n\n .nav-toggle-button {\n position: relative;\n }\n\n .nav-toggle-tooltip {\n left: 100%;\n top: 100%;\n visibility: hidden;\n opacity: 0;\n }\n\n .nav-toggle-button:hover .nav-toggle-tooltip {\n visibility: visible;\n opacity: 1;\n }\n\n #client-selector {\n display: flex;\n align-items: center;\n }\n\n #client-selector tt-combobox {\n --tt-combobox-color: var(--color-text-inverted-400);\n --tt-combobox-dropdown-color: var(--color-text-inverted-400);\n --tt-combobox-list-background-color: var(--color-surface-inverted-100);\n --tt-combobox-option-background-color-hover: var(--color-surface-inverted-200);\n --tt-combobox-placeholder-color: var(--color-text-inverted-300);\n --tt-combobox-background-color: var(--color-surface-inverted-100);\n --tt-combobox-hover-background-color: var(--color-surface-inverted-200);\n --tt-combobox-list-max-width: 80ch;\n --tt-combobox-min-width: 244px;\n --tt-combobox-max-width: 244px;\n }\n\n .single-client-name {\n height: 39px;\n padding: var(--space-scale-1); /* match tt-combobox height */\n font-size: var(--font-size-100);\n color: var(--color-text-inverted-400);\n }\n`;\n"]}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @triptease/tt-navbar v0.0.26
2
+ * @triptease/tt-navbar v0.0.28
3
3
  */
4
4
 
5
5
  // src/Routes.ts
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @triptease/tt-navbar v0.0.26
2
+ * @triptease/tt-navbar v0.0.28
3
3
  */
4
4
  var __defProp = Object.defineProperty;
5
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -1806,6 +1806,13 @@ var styles2 = i`
1806
1806
  }
1807
1807
  }
1808
1808
 
1809
+ .sidebar-closed details:has(.current-page) > summary {
1810
+ --nav-item-color: var(--color-primary-400);
1811
+ border-radius: var(--border-radius-100);
1812
+ background-color: var(--color-primary-100);
1813
+ color: var(--nav-item-color);
1814
+ }
1815
+
1809
1816
  .sub-nav-item {
1810
1817
  width: 100%;
1811
1818
  display: flex;
@@ -1837,8 +1844,7 @@ var styles2 = i`
1837
1844
  }
1838
1845
  }
1839
1846
 
1840
- .current-page,
1841
- .sidebar-closed details:has(.current-page) > summary {
1847
+ .current-page {
1842
1848
  --nav-item-color: var(--color-primary-400);
1843
1849
  border-radius: var(--border-radius-100);
1844
1850
  background-color: var(--color-primary-100);
@@ -2121,6 +2127,14 @@ var TtNavbar = class extends i4 {
2121
2127
  firstUpdated() {
2122
2128
  this.setActiveState();
2123
2129
  }
2130
+ connectedCallback() {
2131
+ window.addEventListener("popstate", this.setActiveState);
2132
+ super.connectedCallback();
2133
+ }
2134
+ disconnectedCallback() {
2135
+ window.removeEventListener("popstate", this.setActiveState);
2136
+ super.disconnectedCallback();
2137
+ }
2124
2138
  render() {
2125
2139
  return x`
2126
2140
  <nav id=${this.id} class="${this.sidebarOpen ? "" : "sidebar-closed"}">