@triptease/tt-navbar 0.0.22 → 0.0.24
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.
- package/dist/src/TtNavbar.d.ts +1 -0
- package/dist/src/TtNavbar.js +9 -2
- package/dist/src/TtNavbar.js.map +1 -1
- package/dist/stories/{index.stories.d.ts → tt-navbar.stories.d.ts} +4 -0
- package/dist/stories/{index.stories.js → tt-navbar.stories.js} +11 -5
- package/dist/stories/tt-navbar.stories.js.map +1 -0
- package/dist/test/tt-navbar.test.js +34 -10
- package/dist/test/tt-navbar.test.js.map +1 -1
- package/dist/web/Routes.js +1 -1
- package/dist/web/TtNavbar.js +10 -3
- package/dist/web/TtNavbar.js.map +2 -2
- package/dist/web/index.js +10 -3
- package/dist/web/index.js.map +2 -2
- package/dist/web/styles.js +1 -1
- package/dist/web/triptease-logo.js +1 -1
- package/dist/web/tt-navbar.js +10 -3
- package/dist/web/tt-navbar.js.map +2 -2
- package/dist/web/urlMappings.js +1 -1
- package/package.json +1 -1
- package/src/TtNavbar.ts +11 -2
- package/stories/{index.stories.ts → tt-navbar.stories.ts} +13 -4
- package/test/tt-navbar.test.ts +59 -31
- package/dist/stories/index.stories.js.map +0 -1
package/dist/web/urlMappings.js
CHANGED
package/package.json
CHANGED
package/src/TtNavbar.ts
CHANGED
|
@@ -178,6 +178,15 @@ export class TtNavbar extends LitElement {
|
|
|
178
178
|
}
|
|
179
179
|
};
|
|
180
180
|
|
|
181
|
+
private handleClientChange = (e: Event) => {
|
|
182
|
+
const combobox = e.target as any;
|
|
183
|
+
const selectedClientKey = combobox.value?.[0];
|
|
184
|
+
|
|
185
|
+
if (selectedClientKey && this.onClientChange) {
|
|
186
|
+
this.onClientChange(selectedClientKey);
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
|
|
181
190
|
render() {
|
|
182
191
|
return html`
|
|
183
192
|
<nav id=${this.id} class="${this.sidebarOpen ? '' : 'sidebar-closed'}">
|
|
@@ -344,8 +353,8 @@ export class TtNavbar extends LitElement {
|
|
|
344
353
|
${this.clients.length > 1 ? html`
|
|
345
354
|
<tt-combobox
|
|
346
355
|
.openUpward=${true}
|
|
347
|
-
.value=${this.clientKey}
|
|
348
|
-
|
|
356
|
+
.value=${this.clientKey ? [this.clientKey] : []}
|
|
357
|
+
@change=${this.handleClientChange}
|
|
349
358
|
>
|
|
350
359
|
${this.clients.map((client) => html`
|
|
351
360
|
<option slot="option" value=${client.clientKey}>
|
|
@@ -7,7 +7,8 @@ const meta = {
|
|
|
7
7
|
argTypes: {
|
|
8
8
|
clientKey: { control: 'text' },
|
|
9
9
|
clients: { control: 'object' },
|
|
10
|
-
campaignManagerUrl: { control: 'text' }
|
|
10
|
+
campaignManagerUrl: { control: 'text' },
|
|
11
|
+
onClientChange: { action: 'clientChanged' }
|
|
11
12
|
}
|
|
12
13
|
};
|
|
13
14
|
|
|
@@ -29,30 +30,38 @@ interface ArgTypes {
|
|
|
29
30
|
clientKey?: string;
|
|
30
31
|
clients?: Client[];
|
|
31
32
|
campaignManagerUrl?: string;
|
|
33
|
+
onClientChange: (clientKey: string) => void;
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
const Template: Story<ArgTypes> = ({
|
|
35
37
|
clientKey = 'zxd47KQGAP',
|
|
36
38
|
clients = [],
|
|
37
|
-
campaignManagerUrl = 'https://app.campaign-manager.triptease.io'
|
|
39
|
+
campaignManagerUrl = 'https://app.campaign-manager.triptease.io',
|
|
40
|
+
onClientChange
|
|
38
41
|
}: ArgTypes) => html`
|
|
39
42
|
<div>
|
|
40
43
|
<tt-navbar
|
|
41
44
|
client-key=${clientKey}
|
|
42
45
|
campaign-manager-url=${campaignManagerUrl}
|
|
43
|
-
|
|
46
|
+
clients=${JSON.stringify(clients)}
|
|
47
|
+
.onClientChange=${onClientChange}
|
|
44
48
|
>
|
|
45
49
|
</tt-navbar>
|
|
46
50
|
</div>
|
|
47
51
|
`;
|
|
48
52
|
|
|
53
|
+
const clientChangeHandler = (clientKey: string) => {
|
|
54
|
+
console.log('Client changed to:', clientKey);
|
|
55
|
+
}
|
|
56
|
+
|
|
49
57
|
export const MultipleClients = Template.bind({});
|
|
50
58
|
MultipleClients.args = {
|
|
51
59
|
clientKey: 'zxd47KQGAP',
|
|
52
60
|
clients: [
|
|
53
61
|
{ clientKey: 'zxd47KQGAP', displayName: 'Demo Client' },
|
|
54
62
|
{ clientKey: 'a1b2c3d4e5', displayName: 'Another Client' }
|
|
55
|
-
]
|
|
63
|
+
],
|
|
64
|
+
onClientChange: clientChangeHandler
|
|
56
65
|
};
|
|
57
66
|
|
|
58
67
|
export const SingleClient = Template.bind({});
|
package/test/tt-navbar.test.ts
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import '../src/tt-navbar.js';
|
|
2
|
-
import {
|
|
3
|
-
elementUpdated,
|
|
4
|
-
expect,
|
|
5
|
-
fixture,
|
|
6
|
-
nextFrame,
|
|
7
|
-
waitUntil,
|
|
8
|
-
} from '@open-wc/testing';
|
|
2
|
+
import { elementUpdated, expect, fixture, nextFrame, waitUntil } from '@open-wc/testing';
|
|
9
3
|
import { TtNavbar } from '../src/index.js';
|
|
10
4
|
import { Routes } from '../src/Routes.js';
|
|
11
5
|
|
|
@@ -20,10 +14,20 @@ const getLinkByHref = (links: NodeListOf<HTMLAnchorElement>, href: string) => {
|
|
|
20
14
|
return undefined;
|
|
21
15
|
};
|
|
22
16
|
|
|
17
|
+
const selectComboboxOption = async (combobox: Element, value: string) => {
|
|
18
|
+
const input = combobox.shadowRoot!.querySelector('[role="combobox"]') as HTMLInputElement;
|
|
19
|
+
input.click();
|
|
20
|
+
|
|
21
|
+
await elementUpdated(combobox);
|
|
22
|
+
|
|
23
|
+
const option = combobox.shadowRoot!.querySelector(`[role="option"][data-value="${value}"]`) as HTMLLIElement;
|
|
24
|
+
option.click();
|
|
25
|
+
};
|
|
26
|
+
|
|
23
27
|
const isVisuallyHidden = (element: Element) => {
|
|
24
28
|
const style = getComputedStyle(element);
|
|
25
29
|
|
|
26
|
-
|
|
30
|
+
return Boolean(
|
|
27
31
|
style.position === 'absolute' &&
|
|
28
32
|
style.width === '1px' &&
|
|
29
33
|
style.height === '1px' &&
|
|
@@ -33,9 +37,8 @@ const isVisuallyHidden = (element: Element) => {
|
|
|
33
37
|
style.overflow === 'hidden' &&
|
|
34
38
|
style.clip === 'rect(0px, 0px, 0px, 0px)' &&
|
|
35
39
|
style.clipPath === 'inset(50%)' &&
|
|
36
|
-
style.whiteSpace === 'nowrap'
|
|
37
|
-
|
|
38
|
-
return result;
|
|
40
|
+
style.whiteSpace === 'nowrap'
|
|
41
|
+
);
|
|
39
42
|
};
|
|
40
43
|
|
|
41
44
|
const CLIENT_KEY = 'zxd47KQGAP';
|
|
@@ -50,7 +53,7 @@ describe('TtNavbar', () => {
|
|
|
50
53
|
});
|
|
51
54
|
it('should render with the default links', async () => {
|
|
52
55
|
const navbar = await fixture<TtNavbar>(
|
|
53
|
-
`<tt-navbar client-key=${CLIENT_KEY}></tt-navbar
|
|
56
|
+
`<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`
|
|
54
57
|
);
|
|
55
58
|
const links = navbar.shadowRoot?.querySelectorAll('a');
|
|
56
59
|
|
|
@@ -77,7 +80,7 @@ describe('TtNavbar', () => {
|
|
|
77
80
|
it('should render platform URLs against the base URL when it is defined', async () => {
|
|
78
81
|
const platformUrl = 'https://app.triptease.io';
|
|
79
82
|
const navbar = await fixture<TtNavbar>(
|
|
80
|
-
`<tt-navbar client-key=${CLIENT_KEY} platform-url="${platformUrl}"></tt-navbar
|
|
83
|
+
`<tt-navbar client-key=${CLIENT_KEY} platform-url="${platformUrl}"></tt-navbar>`
|
|
81
84
|
);
|
|
82
85
|
const links = navbar.shadowRoot?.querySelectorAll('a');
|
|
83
86
|
|
|
@@ -98,7 +101,7 @@ describe('TtNavbar', () => {
|
|
|
98
101
|
};
|
|
99
102
|
|
|
100
103
|
const navbar = await fixture<TtNavbar>(
|
|
101
|
-
`<tt-navbar client-key=${CLIENT_KEY}></tt-navbar
|
|
104
|
+
`<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`
|
|
102
105
|
);
|
|
103
106
|
navbar.navigate = onNavigate;
|
|
104
107
|
await navbar.updateComplete;
|
|
@@ -108,17 +111,17 @@ describe('TtNavbar', () => {
|
|
|
108
111
|
|
|
109
112
|
await waitUntil(
|
|
110
113
|
() => expect(navigateEventCount).to.equal(13),
|
|
111
|
-
'navigate event did not fire'
|
|
114
|
+
'navigate event did not fire'
|
|
112
115
|
);
|
|
113
116
|
});
|
|
114
117
|
|
|
115
118
|
it('should render a combobox when multiple clients are provided', async () => {
|
|
116
119
|
const navbar = await fixture<TtNavbar>(
|
|
117
|
-
`<tt-navbar client-key=${CLIENT_KEY}></tt-navbar
|
|
120
|
+
`<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`
|
|
118
121
|
);
|
|
119
122
|
navbar.clients = [
|
|
120
123
|
{ clientKey: CLIENT_KEY, displayName: 'Client One' },
|
|
121
|
-
{ clientKey: 'abc123', displayName: 'Client Two' }
|
|
124
|
+
{ clientKey: 'abc123', displayName: 'Client Two' }
|
|
122
125
|
];
|
|
123
126
|
await navbar.updateComplete;
|
|
124
127
|
|
|
@@ -127,14 +130,15 @@ describe('TtNavbar', () => {
|
|
|
127
130
|
|
|
128
131
|
expect(combobox).to.exist;
|
|
129
132
|
expect(singleClientName).to.not.exist;
|
|
133
|
+
expect(combobox?.value).to.deep.equal([CLIENT_KEY]);
|
|
130
134
|
});
|
|
131
135
|
|
|
132
136
|
it('should render the client name when only one client is provided', async () => {
|
|
133
137
|
const navbar = await fixture<TtNavbar>(
|
|
134
|
-
`<tt-navbar client-key=${CLIENT_KEY}></tt-navbar
|
|
138
|
+
`<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`
|
|
135
139
|
);
|
|
136
140
|
navbar.clients = [
|
|
137
|
-
{ clientKey: CLIENT_KEY, displayName: 'Single Client' }
|
|
141
|
+
{ clientKey: CLIENT_KEY, displayName: 'Single Client' }
|
|
138
142
|
];
|
|
139
143
|
await navbar.updateComplete;
|
|
140
144
|
|
|
@@ -148,7 +152,7 @@ describe('TtNavbar', () => {
|
|
|
148
152
|
|
|
149
153
|
it('should render the logout link', async () => {
|
|
150
154
|
const navbar = await fixture<TtNavbar>(
|
|
151
|
-
`<tt-navbar client-key=${CLIENT_KEY}></tt-navbar
|
|
155
|
+
`<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`
|
|
152
156
|
);
|
|
153
157
|
|
|
154
158
|
const links = navbar.shadowRoot?.querySelectorAll('a');
|
|
@@ -159,7 +163,7 @@ describe('TtNavbar', () => {
|
|
|
159
163
|
|
|
160
164
|
it('should close other details when one is being opened', async () => {
|
|
161
165
|
const navbar = await fixture<TtNavbar>(
|
|
162
|
-
`<tt-navbar client-key=${CLIENT_KEY}></tt-navbar
|
|
166
|
+
`<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`
|
|
163
167
|
);
|
|
164
168
|
|
|
165
169
|
const allDetails = navbar.shadowRoot!.querySelectorAll('summary');
|
|
@@ -185,11 +189,11 @@ describe('TtNavbar', () => {
|
|
|
185
189
|
|
|
186
190
|
it('should collapse the navbar when toggle clicked', async () => {
|
|
187
191
|
const navbar = await fixture<TtNavbar>(
|
|
188
|
-
`<tt-navbar client-key=${CLIENT_KEY}></tt-navbar
|
|
192
|
+
`<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`
|
|
189
193
|
);
|
|
190
194
|
|
|
191
195
|
const navbarToggleBtn = navbar.shadowRoot!.querySelector(
|
|
192
|
-
'#navbar-toggle-btn'
|
|
196
|
+
'#navbar-toggle-btn'
|
|
193
197
|
) as HTMLButtonElement;
|
|
194
198
|
|
|
195
199
|
navbarToggleBtn.click();
|
|
@@ -219,7 +223,7 @@ describe('TtNavbar', () => {
|
|
|
219
223
|
for (const element of [
|
|
220
224
|
...rootLinksHiddenElements,
|
|
221
225
|
...summaryHiddenElements,
|
|
222
|
-
logoutLink
|
|
226
|
+
logoutLink!
|
|
223
227
|
]) {
|
|
224
228
|
expect(isVisuallyHidden(element)).to.be.true;
|
|
225
229
|
}
|
|
@@ -229,16 +233,16 @@ describe('TtNavbar', () => {
|
|
|
229
233
|
'market-insights',
|
|
230
234
|
'settings',
|
|
231
235
|
'account',
|
|
232
|
-
'billing-routes'
|
|
236
|
+
'billing-routes'
|
|
233
237
|
];
|
|
234
238
|
collapsibleIds.forEach(id => {
|
|
235
239
|
it(`should open the nav bar when the ${id} collapsible is clicked`, async () => {
|
|
236
240
|
const navbar = await fixture<TtNavbar>(
|
|
237
|
-
`<tt-navbar client-key=${CLIENT_KEY}></tt-navbar
|
|
241
|
+
`<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`
|
|
238
242
|
);
|
|
239
243
|
|
|
240
244
|
const navbarToggleBtn = navbar.shadowRoot!.querySelector(
|
|
241
|
-
'#navbar-toggle-btn'
|
|
245
|
+
'#navbar-toggle-btn'
|
|
242
246
|
) as HTMLButtonElement;
|
|
243
247
|
|
|
244
248
|
navbarToggleBtn.click();
|
|
@@ -255,7 +259,7 @@ describe('TtNavbar', () => {
|
|
|
255
259
|
element!.click();
|
|
256
260
|
|
|
257
261
|
await waitUntil(() => logo?.checkVisibility(), 'navbar should be open', {
|
|
258
|
-
timeout: 500
|
|
262
|
+
timeout: 500
|
|
259
263
|
});
|
|
260
264
|
});
|
|
261
265
|
});
|
|
@@ -268,7 +272,7 @@ describe('TtNavbar', () => {
|
|
|
268
272
|
[`/parity/${CLIENT_KEY}/foo`, 'Parity'],
|
|
269
273
|
[`/meta/${CLIENT_KEY}/performance`, 'Channels'],
|
|
270
274
|
[`/chat/insights/${CLIENT_KEY}`, 'Channels'],
|
|
271
|
-
[`/${CLIENT_KEY}/email`, 'Channels']
|
|
275
|
+
[`/${CLIENT_KEY}/email`, 'Channels']
|
|
272
276
|
];
|
|
273
277
|
|
|
274
278
|
URLs.forEach(([route, text]) => {
|
|
@@ -277,7 +281,7 @@ describe('TtNavbar', () => {
|
|
|
277
281
|
history.pushState({}, '', route); // 👈 mock URL
|
|
278
282
|
|
|
279
283
|
const navbar = await fixture<TtNavbar>(
|
|
280
|
-
`<tt-navbar client-key=${CLIENT_KEY}></tt-navbar
|
|
284
|
+
`<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`
|
|
281
285
|
);
|
|
282
286
|
|
|
283
287
|
const anchor = navbar.shadowRoot!.querySelector('a[aria-current="page"]');
|
|
@@ -292,10 +296,34 @@ describe('TtNavbar', () => {
|
|
|
292
296
|
const campaignManagerUrl = 'http://localhost:8000';
|
|
293
297
|
|
|
294
298
|
const navbar = await fixture<TtNavbar>(
|
|
295
|
-
`<tt-navbar client-key=${CLIENT_KEY} platform-url=${platformUrl} campaign-manager-url=${campaignManagerUrl} active-route="${Routes.CampaignManager}"></tt-navbar
|
|
299
|
+
`<tt-navbar client-key=${CLIENT_KEY} platform-url=${platformUrl} campaign-manager-url=${campaignManagerUrl} active-route="${Routes.CampaignManager}"></tt-navbar>`
|
|
296
300
|
);
|
|
297
301
|
const anchor = navbar.shadowRoot!.querySelector('a[aria-current="page"]');
|
|
298
302
|
expect(anchor).to.exist;
|
|
299
303
|
expect(anchor!.textContent).to.include('Campaigns');
|
|
300
304
|
});
|
|
305
|
+
|
|
306
|
+
it('should fire an event when the client is changed', async () => {
|
|
307
|
+
let selectedClientKey: string | undefined;
|
|
308
|
+
const onClientChange = (clientKey: string) => {
|
|
309
|
+
selectedClientKey = clientKey;
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
const navbar = await fixture<TtNavbar>(
|
|
313
|
+
`<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`
|
|
314
|
+
);
|
|
315
|
+
navbar.clients = [
|
|
316
|
+
{ clientKey: CLIENT_KEY, displayName: 'Client One' },
|
|
317
|
+
{ clientKey: 'abc123', displayName: 'Client Two' }
|
|
318
|
+
];
|
|
319
|
+
navbar.onClientChange = onClientChange;
|
|
320
|
+
await navbar.updateComplete;
|
|
321
|
+
|
|
322
|
+
const combobox = navbar.shadowRoot?.querySelector('tt-combobox');
|
|
323
|
+
expect(combobox).to.exist;
|
|
324
|
+
|
|
325
|
+
await selectComboboxOption(combobox!, 'abc123');
|
|
326
|
+
|
|
327
|
+
expect(selectedClientKey).to.equal('abc123');
|
|
328
|
+
});
|
|
301
329
|
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.stories.js","sourceRoot":"","sources":["../../stories/index.stories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAkB,MAAM,KAAK,CAAC;AAC3C,OAAO,qBAAqB,CAAC;AAE7B,MAAM,IAAI,GAAG;IACX,KAAK,EAAE,UAAU;IACjB,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE;QACR,SAAS,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;QAC9B,OAAO,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE;QAC9B,kBAAkB,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;KACxC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC;AAoBpB,MAAM,QAAQ,GAAoB,CAAC,EACE,SAAS,GAAG,YAAY,EACxB,OAAO,GAAG,EAAE,EACZ,kBAAkB,GAAG,2CAA2C,EACvD,EAAE,EAAE,CAAC,IAAI,CAAA;;;mBAGpC,SAAS;6BACC,kBAAkB;iBAC9B,OAAO;;;;CAIvB,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACjD,eAAe,CAAC,IAAI,GAAG;IACrB,SAAS,EAAE,YAAY;IACvB,OAAO,EAAE;QACP,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE;QACvD,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE;KAC3D;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC9C,YAAY,CAAC,IAAI,GAAG;IAClB,SAAS,EAAE,YAAY;IACvB,OAAO,EAAE;QACP,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE;KACxD;CACF,CAAC","sourcesContent":["import { html, TemplateResult } from 'lit';\nimport '../src/tt-navbar.js';\n\nconst meta = {\n title: 'TtNavbar',\n component: 'tt-navbar',\n argTypes: {\n clientKey: { control: 'text' },\n clients: { control: 'object' },\n campaignManagerUrl: { control: 'text' }\n }\n};\n\nexport default meta;\n\ninterface Story<T> {\n (args: T): TemplateResult;\n\n args?: Partial<T>;\n argTypes?: Record<string, unknown>;\n}\n\ninterface Client {\n clientKey: string;\n displayName: string;\n}\n\ninterface ArgTypes {\n clientKey?: string;\n clients?: Client[];\n campaignManagerUrl?: string;\n}\n\nconst Template: Story<ArgTypes> = ({\n clientKey = 'zxd47KQGAP',\n clients = [],\n campaignManagerUrl = 'https://app.campaign-manager.triptease.io'\n }: ArgTypes) => html`\n <div>\n <tt-navbar\n client-key=${clientKey}\n campaign-manager-url=${campaignManagerUrl}\n .clients=${clients}\n >\n </tt-navbar>\n </div>\n`;\n\nexport const MultipleClients = Template.bind({});\nMultipleClients.args = {\n clientKey: 'zxd47KQGAP',\n clients: [\n { clientKey: 'zxd47KQGAP', displayName: 'Demo Client' },\n { clientKey: 'a1b2c3d4e5', displayName: 'Another Client' }\n ]\n};\n\nexport const SingleClient = Template.bind({});\nSingleClient.args = {\n clientKey: 'zxd47KQGAP',\n clients: [\n { clientKey: 'zxd47KQGAP', displayName: 'Demo Client' }\n ]\n};\n"]}
|