@triptease/tt-navbar 0.0.21 → 0.0.22

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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @triptease/tt-navbar v0.0.21
2
+ * @triptease/tt-navbar v0.0.22
3
3
  */
4
4
 
5
5
  // src/urlMappings.ts
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Webcomponent tt-navbar following open-wc recommendations",
4
4
  "license": "MIT",
5
5
  "author": "tt-navbar",
6
- "version": "0.0.21",
6
+ "version": "0.0.22",
7
7
  "type": "module",
8
8
  "main": "dist/src/index.js",
9
9
  "module": "dist/src/index.js",
@@ -28,6 +28,7 @@
28
28
  },
29
29
  "dependencies": {
30
30
  "@triptease/icons": "^1.1.1",
31
+ "@triptease/tt-combobox": "^5.2.1",
31
32
  "lit": "^3.1.4"
32
33
  },
33
34
  "devDependencies": {
package/src/TtNavbar.ts CHANGED
@@ -5,20 +5,30 @@ import {
5
5
  campaigns,
6
6
  channels,
7
7
  chevronDown,
8
+ external,
8
9
  gear,
9
10
  graph,
10
11
  home,
11
12
  logout,
12
- user,
13
- wallet,
14
- external,
15
13
  sidebarCollapsed,
14
+ user,
15
+ wallet
16
16
  } from '@triptease/icons';
17
+ import '@triptease/tt-combobox';
17
18
  import { styles } from './styles.js';
18
19
  import { tripteaseLogo } from './triptease-logo.js';
19
20
  import { urlMappings } from './urlMappings.js';
20
21
  import { Routes } from './Routes.js';
21
22
 
23
+ const jsonArrayConverter = (value: string | null) => {
24
+ if (!value) return [];
25
+ try {
26
+ return JSON.parse(value);
27
+ } catch {
28
+ return [];
29
+ }
30
+ };
31
+
22
32
  export class TtNavbar extends LitElement {
23
33
  static styles = styles;
24
34
 
@@ -37,6 +47,12 @@ export class TtNavbar extends LitElement {
37
47
  @property({ type: String, attribute: 'active-route' })
38
48
  activeRoute?: keyof typeof Routes;
39
49
 
50
+ @property({ type: Array, converter: jsonArrayConverter })
51
+ clients: { clientKey: string; displayName: string }[] = [];
52
+
53
+ @property({ type: Object })
54
+ onClientChange: ((clientKeySelected: string) => void ) | undefined;
55
+
40
56
  @queryAll('details')
41
57
  protected allDetailsElements!: Array<HTMLDetailsElement>;
42
58
 
@@ -324,7 +340,25 @@ export class TtNavbar extends LitElement {
324
340
  <hr />
325
341
  </div>
326
342
  <div class='nav-items'>
327
- <slot id="client-selector" name="clientSelector"></slot>
343
+ <div id="client-selector">
344
+ ${this.clients.length > 1 ? html`
345
+ <tt-combobox
346
+ .openUpward=${true}
347
+ .value=${this.clientKey}
348
+ .onChange=${this.onClientChange}
349
+ >
350
+ ${this.clients.map((client) => html`
351
+ <option slot="option" value=${client.clientKey}>
352
+ ${client.displayName}
353
+ </option>
354
+ `)}
355
+ </tt-combobox>
356
+ ` : html`
357
+ <div class="single-client-name">
358
+ ${this.clients.find((m) => m.clientKey === this.clientKey)?.displayName}
359
+ </div>
360
+ `}
361
+ </div>
328
362
  <a
329
363
  id="logout-link"
330
364
  class="nav-item"
@@ -332,7 +366,6 @@ export class TtNavbar extends LitElement {
332
366
  @click=${this.onAnchorClick}
333
367
  >${unsafeSVG(logout)}<span>Logout</span></a>
334
368
  </div>
335
- <div>
336
369
  </nav>
337
370
  `;
338
371
  }
package/src/styles.ts CHANGED
@@ -107,8 +107,8 @@ export const styles = css`
107
107
 
108
108
  .tertiary-nav.sidebar-closed {
109
109
  .external-link,
110
- slot,
111
- hr {
110
+ hr,
111
+ #client-selector {
112
112
  display: none;
113
113
  visibility: hidden;
114
114
  }
@@ -336,4 +336,29 @@ export const styles = css`
336
336
  visibility: visible;
337
337
  opacity: 1;
338
338
  }
339
+
340
+ #client-selector {
341
+ display: flex;
342
+ align-items: center;
343
+ }
344
+
345
+ #client-selector tt-combobox {
346
+ --tt-combobox-color: var(--color-text-inverted-400);
347
+ --tt-combobox-dropdown-color: var(--color-text-inverted-400);
348
+ --tt-combobox-list-background-color: var(--color-surface-inverted-100);
349
+ --tt-combobox-option-background-color-hover: var(--color-surface-inverted-200);
350
+ --tt-combobox-placeholder-color: var(--color-text-inverted-300);
351
+ --tt-combobox-background-color: var(--color-surface-inverted-100);
352
+ --tt-combobox-hover-background-color: var(--color-surface-inverted-200);
353
+ --tt-combobox-list-max-width: 80ch;
354
+ --tt-combobox-min-width: 244px;
355
+ --tt-combobox-max-width: 244px;
356
+ }
357
+
358
+ .single-client-name {
359
+ height: 39px;
360
+ padding: var(--space-scale-1); /* match tt-combobox height */
361
+ font-size: var(--font-size-100);
362
+ color: var(--color-text-inverted-400);
363
+ }
339
364
  `;
@@ -1,22 +1,64 @@
1
- import { html } from 'lit';
1
+ import { html, TemplateResult } from 'lit';
2
2
  import '../src/tt-navbar.js';
3
3
 
4
- export default {
4
+ const meta = {
5
5
  title: 'TtNavbar',
6
6
  component: 'tt-navbar',
7
+ argTypes: {
8
+ clientKey: { control: 'text' },
9
+ clients: { control: 'object' },
10
+ campaignManagerUrl: { control: 'text' }
11
+ }
7
12
  };
8
13
 
9
- const Template = () => html`
14
+ export default meta;
15
+
16
+ interface Story<T> {
17
+ (args: T): TemplateResult;
18
+
19
+ args?: Partial<T>;
20
+ argTypes?: Record<string, unknown>;
21
+ }
22
+
23
+ interface Client {
24
+ clientKey: string;
25
+ displayName: string;
26
+ }
27
+
28
+ interface ArgTypes {
29
+ clientKey?: string;
30
+ clients?: Client[];
31
+ campaignManagerUrl?: string;
32
+ }
33
+
34
+ const Template: Story<ArgTypes> = ({
35
+ clientKey = 'zxd47KQGAP',
36
+ clients = [],
37
+ campaignManagerUrl = 'https://app.campaign-manager.triptease.io'
38
+ }: ArgTypes) => html`
10
39
  <div>
11
40
  <tt-navbar
12
- client-key="zxd47KQGAP"
13
- campaign-manager-url="https://app.campaign-manager.triptease.io"
41
+ client-key=${clientKey}
42
+ campaign-manager-url=${campaignManagerUrl}
43
+ .clients=${clients}
14
44
  >
15
- <div slot="clientSelector">
16
- <p>My Cool Client Selector</p>
17
- </div>
18
45
  </tt-navbar>
19
46
  </div>
20
47
  `;
21
48
 
22
- export const Regular = Template.bind({});
49
+ export const MultipleClients = Template.bind({});
50
+ MultipleClients.args = {
51
+ clientKey: 'zxd47KQGAP',
52
+ clients: [
53
+ { clientKey: 'zxd47KQGAP', displayName: 'Demo Client' },
54
+ { clientKey: 'a1b2c3d4e5', displayName: 'Another Client' }
55
+ ]
56
+ };
57
+
58
+ export const SingleClient = Template.bind({});
59
+ SingleClient.args = {
60
+ clientKey: 'zxd47KQGAP',
61
+ clients: [
62
+ { clientKey: 'zxd47KQGAP', displayName: 'Demo Client' }
63
+ ]
64
+ };
@@ -112,14 +112,38 @@ describe('TtNavbar', () => {
112
112
  );
113
113
  });
114
114
 
115
- it('should render the given client selector', async () => {
115
+ it('should render a combobox when multiple clients are provided', async () => {
116
116
  const navbar = await fixture<TtNavbar>(
117
- `<tt-navbar client-key=${CLIENT_KEY}><div slot="clientSelector"><div id="myCoolClientSelector"></div></div></tt-navbar>`,
117
+ `<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`,
118
+ );
119
+ navbar.clients = [
120
+ { clientKey: CLIENT_KEY, displayName: 'Client One' },
121
+ { clientKey: 'abc123', displayName: 'Client Two' },
122
+ ];
123
+ await navbar.updateComplete;
124
+
125
+ const combobox = navbar.shadowRoot?.querySelector('tt-combobox');
126
+ const singleClientName = navbar.shadowRoot?.querySelector('.single-client-name');
127
+
128
+ expect(combobox).to.exist;
129
+ expect(singleClientName).to.not.exist;
130
+ });
131
+
132
+ it('should render the client name when only one client is provided', async () => {
133
+ const navbar = await fixture<TtNavbar>(
134
+ `<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`,
118
135
  );
136
+ navbar.clients = [
137
+ { clientKey: CLIENT_KEY, displayName: 'Single Client' },
138
+ ];
139
+ await navbar.updateComplete;
119
140
 
120
- const clientSelector = navbar.querySelector('#myCoolClientSelector');
141
+ const singleClientName = navbar.shadowRoot?.querySelector('.single-client-name');
142
+ const combobox = navbar.shadowRoot?.querySelector('tt-combobox');
121
143
 
122
- expect(clientSelector).to.exist;
144
+ expect(singleClientName).to.exist;
145
+ expect(singleClientName?.textContent?.trim()).to.equal('Single Client');
146
+ expect(combobox).to.not.exist;
123
147
  });
124
148
 
125
149
  it('should render the logout link', async () => {