@salesforcedevs/dx-components 0.5.5 → 0.8.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforcedevs/dx-components",
3
- "version": "0.5.5",
3
+ "version": "0.8.3",
4
4
  "description": "DX Lightning web components",
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -22,12 +22,12 @@
22
22
  "debounce": "^1.2.0",
23
23
  "lightning-base-components": "1.12.3-alpha",
24
24
  "lodash.get": "^4.4.2",
25
- "tippy.js": "^6.2.7"
25
+ "microtip": "0.2.2"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/classnames": "^2.2.10",
29
29
  "@types/debounce": "^1.2.0",
30
30
  "@types/lodash.get": "^4.4.6"
31
31
  },
32
- "gitHead": "b837abbfadaf24fa1c9df28a3566431ab05dd1ea"
32
+ "gitHead": "6eea544cc7d58dc43abb71a74816c23dff1191ea"
33
33
  }
@@ -28,7 +28,10 @@
28
28
  </template>
29
29
  <template if:true={showCodeSourceBtn}>
30
30
  <div class="toolbar-item">
31
- <dx-tooltip persist label="View Code Source">
31
+ <dx-tooltip
32
+ label="View Code Source"
33
+ placement="top-left"
34
+ >
32
35
  <dx-button
33
36
  href={sourceLink}
34
37
  type="button"
@@ -44,7 +47,7 @@
44
47
  <div class="divider"></div>
45
48
  </template>
46
49
  <div class="toolbar-item">
47
- <dx-tooltip label={updateThemeBtnText}>
50
+ <dx-tooltip label={updateThemeBtnText} placement="top-left">
48
51
  <dx-button
49
52
  onclick={updateTheme}
50
53
  type="button"
@@ -57,7 +60,7 @@
57
60
  </div>
58
61
  <div class="divider"></div>
59
62
  <div class="toolbar-item">
60
- <dx-tooltip persist label={copyBtnText}>
63
+ <dx-tooltip label={copyBtnText} placement="top-left">
61
64
  <dx-button
62
65
  onclick={copySource}
63
66
  type="button"
@@ -1,5 +1,6 @@
1
1
  import Dropdown from "dx/dropdown";
2
2
  import DropdownOption from "dx/dropdownOption";
3
+ import Popover from "dx/popover";
3
4
  import { getOptionsCount } from "utils/options";
4
5
  import { createRenderComponent } from "utils/tests";
5
6
  import mockNestedOptions from "./mockNestedOptions";
@@ -12,6 +13,13 @@ describe(TAG, () => {
12
13
  describe("render", () => {
13
14
  it("renders all options when open", () => {
14
15
  const component = render({ ...mockProps, open: true });
16
+
17
+ const menuDiv: HTMLElement = component.shadowRoot.querySelector(
18
+ ".menu_list"
19
+ );
20
+ expect(menuDiv).not.toBeNull();
21
+ expect(menuDiv.getAttribute("role")).toBe("menu");
22
+
15
23
  const options = component.shadowRoot.querySelectorAll(
16
24
  "dx-dropdown-option"
17
25
  );
@@ -55,6 +63,24 @@ describe(TAG, () => {
55
63
  expect(id).toEqual(mockProps.value);
56
64
  return expect(component).toBeAccessible();
57
65
  });
66
+
67
+ it("renders with menu-offset-small and menu-hidden", () => {
68
+ const component = render({ offset: "small", options: [] });
69
+ const popover: Popover = component.shadowRoot.querySelector(
70
+ "dx-popover"
71
+ );
72
+ expect(popover).not.toBeNull();
73
+
74
+ expect(popover.classList).toContain("menu-offset-small");
75
+ expect(popover.classList).toContain("menu-hidden");
76
+
77
+ const options = component.shadowRoot.querySelectorAll(
78
+ "dx-dropdown-option"
79
+ );
80
+ expect(options).toHaveLength(0);
81
+
82
+ return expect(component).toBeAccessible();
83
+ });
58
84
  });
59
85
 
60
86
  describe("interactions", () => {
@@ -98,34 +124,49 @@ describe(TAG, () => {
98
124
  option.dispatchEvent(new CustomEvent("select", { detail: id }));
99
125
 
100
126
  expect(mockClose).toHaveBeenCalledTimes(1);
101
- expect(component.open).toEqual(false);
102
127
  return expect(component).toBeAccessible();
103
128
  });
104
129
 
105
- it("handles open event from popover", () => {
106
- const component = render(mockProps);
107
- expect(component.open).toBeFalsy();
130
+ it("handles keydown event with ArrowDown key", () => {
131
+ const [firstOption] = mockProps.options;
132
+ const component = render({ ...mockProps, value: null, open: true });
133
+ expect(component.focusedValue).toBeNull();
108
134
 
109
- const popover: HTMLElement = component.shadowRoot.querySelector(
110
- "dx-popover"
135
+ component.dispatchEvent(
136
+ new KeyboardEvent("keydown", { key: "ArrowDown" })
111
137
  );
112
- expect(popover).not.toBeNull();
113
- popover.dispatchEvent(new CustomEvent("open"));
138
+ expect(component.focusedValue).toBe(firstOption.id);
139
+ });
140
+
141
+ it("ignores other click keys", () => {
142
+ const component = render({ ...mockProps, open: true });
114
143
 
115
- expect(component.open).toBe(true);
144
+ component.dispatchEvent(
145
+ new KeyboardEvent("keydown", { key: "ArrowDown" })
146
+ );
147
+ expect(component.focusedValue).toBe(mockProps.value);
148
+
149
+ component.dispatchEvent(
150
+ new KeyboardEvent("keydown", { key: "ArrowLeft" })
151
+ );
152
+
153
+ expect(component.focusedValue).toBe(mockProps.value);
116
154
  });
117
155
 
118
156
  it("handles close event from popover", () => {
119
157
  const component = render({ ...mockProps, open: true });
120
- expect(component.open).toBe(true);
158
+
159
+ component.dispatchEvent(
160
+ new KeyboardEvent("keydown", { key: "ArrowDown" })
161
+ );
162
+ expect(component.focusedValue).toBe(mockProps.value);
121
163
 
122
164
  const popover: HTMLElement = component.shadowRoot.querySelector(
123
165
  "dx-popover"
124
166
  );
125
167
  expect(popover).not.toBeNull();
126
168
  popover.dispatchEvent(new CustomEvent("close"));
127
-
128
- expect(component.open).toBe(false);
169
+ expect(component.focusedValue).toBeNull();
129
170
  });
130
171
  });
131
172
  });
@@ -4,7 +4,6 @@
4
4
  class={className}
5
5
  full-width={fullWidth}
6
6
  offset={offset}
7
- onopen={onOpen}
8
7
  onclose={onClose}
9
8
  open-on-hover={openOnHover}
10
9
  open={open}
@@ -23,6 +23,7 @@ export default class Dropdown extends LightningElement {
23
23
  @api ariaLabel: string | null = null;
24
24
  @api tempId: string | null = null;
25
25
  @api offset?: "small" | "medium";
26
+ @api open: boolean | null = null;
26
27
  @api pagePadding?: number = 16; // padding between dropdown and the edge of the page
27
28
  @api placement?: PopperPlacement = "bottom-start";
28
29
  @api small?: boolean = false;
@@ -44,12 +45,8 @@ export default class Dropdown extends LightningElement {
44
45
  }
45
46
 
46
47
  @api
47
- get open() {
48
- return this._open;
49
- }
50
-
51
- set open(value) {
52
- this._open = value;
48
+ get focusedValue() {
49
+ return this._focusedValue;
53
50
  }
54
51
 
55
52
  @track
@@ -57,8 +54,7 @@ export default class Dropdown extends LightningElement {
57
54
 
58
55
  // PRIVATE VARS
59
56
 
60
- private focusedValue: string | null = null;
61
- private _open = false;
57
+ private _focusedValue: string | null = null;
62
58
  private popoverEl: HTMLElement | null = null;
63
59
 
64
60
  constructor() {
@@ -98,18 +94,16 @@ export default class Dropdown extends LightningElement {
98
94
  // CLASS FNS
99
95
 
100
96
  private onKeyDown = (e: KeyboardEvent) => {
101
- if (this.open) {
102
- switch (e.key) {
103
- case "ArrowDown":
104
- e.preventDefault();
105
- this.incrementOptionFocus(1);
106
- break;
107
- case "ArrowUp":
108
- e.preventDefault();
109
- this.incrementOptionFocus(-1);
110
- break;
111
- default:
112
- }
97
+ switch (e.key) {
98
+ case "ArrowDown":
99
+ e.preventDefault();
100
+ this.incrementOptionFocus(1);
101
+ break;
102
+ case "ArrowUp":
103
+ e.preventDefault();
104
+ this.incrementOptionFocus(-1);
105
+ break;
106
+ default:
113
107
  }
114
108
  };
115
109
 
@@ -125,7 +119,7 @@ export default class Dropdown extends LightningElement {
125
119
  private onOptionFocus(e: PointerEvent) {
126
120
  if (e.target) {
127
121
  // @ts-ignore
128
- this.focusedValue = e.target.option.id;
122
+ this._focusedValue = e.target.option.id;
129
123
  }
130
124
  }
131
125
 
@@ -137,13 +131,13 @@ export default class Dropdown extends LightningElement {
137
131
  }
138
132
 
139
133
  private incrementOptionFocus(indexChange: number) {
140
- if (!this.focusedValue) {
134
+ if (!this._focusedValue) {
141
135
  this.focusDefaultOption();
142
136
  return;
143
137
  }
144
138
 
145
139
  const focusedOptionIndex = this.findOptionElementIndex(
146
- this.focusedValue
140
+ this._focusedValue
147
141
  );
148
142
 
149
143
  let nextIndex = focusedOptionIndex + indexChange;
@@ -160,13 +154,8 @@ export default class Dropdown extends LightningElement {
160
154
  }
161
155
  }
162
156
 
163
- private onOpen(): void {
164
- this._open = true;
165
- }
166
-
167
157
  private onClose(): void {
168
- this.focusedValue = null;
169
- this._open = false;
158
+ this._focusedValue = null;
170
159
  }
171
160
 
172
161
  private focusDefaultOption() {
@@ -179,7 +168,7 @@ export default class Dropdown extends LightningElement {
179
168
  ];
180
169
  if (optionToFocus) {
181
170
  optionToFocus.focus();
182
- this.focusedValue = optionToFocus.option.id;
171
+ this._focusedValue = optionToFocus.option.id;
183
172
  }
184
173
  }
185
174
 
@@ -8,10 +8,16 @@ import {
8
8
  mockPropsEmployees,
9
9
  mockPropsNoNavigation
10
10
  } from "./mockProps";
11
+ import { track } from "dx/instrumentation";
11
12
 
12
13
  const TAG = "dx-header";
13
14
  const render = createRenderComponent(TAG, Header);
14
15
 
16
+ jest.mock("dx/instrumentation");
17
+
18
+ const GTM_EVENT_NAME = "custEv_signUpClick";
19
+ const SIGN_UP_LABEL = "Sign Up";
20
+
15
21
  describe("dx-header", () => {
16
22
  it("renders", () => {
17
23
  const subtitle = "testsubtitle";
@@ -195,4 +201,19 @@ describe("dx-header", () => {
195
201
  expect(headerSearch).toBeNull();
196
202
  return expect(element).toBeAccessible();
197
203
  });
204
+
205
+ it("signup button track is beign called", () => {
206
+ const element = render(mockPropsDevelopers);
207
+
208
+ const button: HTMLElement = element.shadowRoot.querySelector(
209
+ "dx-button"
210
+ );
211
+
212
+ button.click();
213
+
214
+ expect(track).toBeCalledTimes(1);
215
+ expect(track).toBeCalledWith(button, GTM_EVENT_NAME, {
216
+ clickText: SIGN_UP_LABEL
217
+ });
218
+ });
198
219
  });
@@ -27,6 +27,7 @@
27
27
  aria-label="Sign Up For Salesforce Developer Edition"
28
28
  size="small"
29
29
  href={signupLink}
30
+ onclick={handleSignUpClick}
30
31
  >
31
32
  Sign Up
32
33
  </dx-button>
@@ -24,7 +24,7 @@ const COVEO_CONFIG = {
24
24
  reducers: searchAppReducers
25
25
  };
26
26
 
27
- const REDIRECT_URL = "https://beta.developer.salesforce.com";
27
+ const REDIRECT_URL = "https://developer.salesforce.com";
28
28
 
29
29
  const TAG = "dx-header-search";
30
30
  const render = createRenderComponent(TAG, HeaderSearch);
@@ -80,7 +80,7 @@ export default class HeaderSearch extends LightningElement {
80
80
  private instantiateSearchbox() {
81
81
  const options: StandaloneSearchBoxOptions = {
82
82
  numberOfSuggestions: 3,
83
- redirectionUrl: "https://beta.developer.salesforce.com"
83
+ redirectionUrl: "https://developer.salesforce.com"
84
84
  };
85
85
 
86
86
  const engine = new HeadlessEngine({
@@ -4,6 +4,5 @@ export default {
4
4
  pagePadding: 20,
5
5
  placement: "top-start",
6
6
  small: true,
7
- openOnHover: true,
8
7
  width: "300px"
9
8
  };
@@ -37,6 +37,7 @@ export default class Popover extends LightningElement {
37
37
  return this._open;
38
38
  }
39
39
  set open(value: boolean | null) {
40
+ this.controlled = typeof value === "boolean";
40
41
  if (value !== this._open) {
41
42
  if (value) {
42
43
  this.openPopover();
@@ -101,6 +102,7 @@ export default class Popover extends LightningElement {
101
102
 
102
103
  // PRIVATE VARS
103
104
 
105
+ private controlled: boolean = false;
104
106
  private _open: boolean = false;
105
107
  private _rendered: boolean = isPrerender();
106
108
  private _role: string | null = null;
@@ -152,19 +154,26 @@ export default class Popover extends LightningElement {
152
154
 
153
155
  private addControlListeners() {
154
156
  if (this.control) {
155
- this.control.addEventListener("click", this.onControlClick);
156
157
  this.control.addEventListener("keydown", this.onControlKeydown);
157
- this.control.addEventListener(
158
- "mouseenter",
159
- this.onControlMouseEnter
160
- );
158
+
159
+ if (!this.openOnHover) {
160
+ this.control.addEventListener("click", this.onControlClick);
161
+ }
162
+
163
+ if (this.openOnHover) {
164
+ this.control.addEventListener(
165
+ "mouseenter",
166
+ this.onControlMouseEnter
167
+ );
168
+ }
161
169
  }
162
170
  }
163
171
 
164
172
  private removeControlListeners() {
165
173
  if (this.control) {
166
- this.control.removeEventListener("click", this.onControlClick);
167
174
  this.control.removeEventListener("keydown", this.onControlKeydown);
175
+
176
+ this.control.removeEventListener("click", this.onControlClick);
168
177
  this.control.removeEventListener(
169
178
  "mouseenter",
170
179
  this.onControlMouseEnter
@@ -186,11 +195,7 @@ export default class Popover extends LightningElement {
186
195
  // @ts-ignore something weird happening here with debounce types
187
196
  debounce(this._interactOutsideListener(e), 100);
188
197
 
189
- private onControlMouseEnter = () => {
190
- if (this.openOnHover) {
191
- this.openPopover();
192
- }
193
- };
198
+ private onControlMouseEnter = () => this.openPopover();
194
199
 
195
200
  private onControlKeydown = (e: KeyboardEvent) => {
196
201
  switch (e.key) {
@@ -207,13 +212,13 @@ export default class Popover extends LightningElement {
207
212
  };
208
213
 
209
214
  private onControlClick = () => {
210
- if (this.open && !this.openOnHover) {
211
- this.closePopover();
215
+ if (this.controlled) {
216
+ this.dispatchRequestCloseEvent("click-control");
212
217
  return;
213
218
  }
214
219
 
215
220
  if (this.open) {
216
- this.dispatchRequestCloseEvent("click-control");
221
+ this.closePopover();
217
222
  return;
218
223
  }
219
224
 
@@ -1,5 +1,6 @@
1
1
  import Button from "dx/button";
2
2
  import Input from "dx/input";
3
+ import { track } from "dx/instrumentation";
3
4
  import Sidebar from "dx/sidebar";
4
5
  import Tree from "dx/tree";
5
6
  import { TreeNode } from "typings/custom";
@@ -7,14 +8,21 @@ import { createMediaMock } from "utils/jest";
7
8
  import { createRenderComponent } from "utils/tests";
8
9
  import { SAMPLE_TREES } from "./mockProps";
9
10
 
11
+ jest.mock("dx/instrumentation");
12
+
10
13
  const TAG = "dx-sidebar";
11
14
  const renderComponent = createRenderComponent(TAG, Sidebar);
12
15
 
13
16
  const COLLAPSED_CLASS = "collapsed";
14
-
15
17
  const EXPECTED_QUERY = "(max-width: 768px)";
18
+ const GTM_EVENT_NAME = "custEv_leftNavLinkClick";
19
+ const TOGGLE_BUTTON_LABEL = "Toggle Sidebar";
16
20
 
17
21
  describe(TAG, () => {
22
+ afterEach(() => {
23
+ jest.clearAllMocks();
24
+ });
25
+
18
26
  describe("desktop", () => {
19
27
  describe("component render", () => {
20
28
  it("should render as expanded with all the elements that sidebar includes", () => {
@@ -160,6 +168,12 @@ describe(TAG, () => {
160
168
  );
161
169
  toggleButton.click();
162
170
 
171
+ expect(track).toBeCalledTimes(1);
172
+ expect(track).toBeCalledWith(toggleButton, GTM_EVENT_NAME, {
173
+ sidebarNavAction: "collapse",
174
+ clickText: TOGGLE_BUTTON_LABEL
175
+ });
176
+
163
177
  return Promise.resolve()
164
178
  .then(() => {
165
179
  expect(container.classList).toContain(COLLAPSED_CLASS);
@@ -185,6 +199,16 @@ describe(TAG, () => {
185
199
  expect(trees).toBeNull();
186
200
 
187
201
  toggleButton.click();
202
+
203
+ expect(track).toBeCalledTimes(2);
204
+ expect(track).toHaveBeenLastCalledWith(
205
+ toggleButton,
206
+ GTM_EVENT_NAME,
207
+ {
208
+ sidebarNavAction: "expand",
209
+ clickText: TOGGLE_BUTTON_LABEL
210
+ }
211
+ );
188
212
  })
189
213
  .then(() => {
190
214
  expect(container.classList).not.toContain(
@@ -337,6 +361,12 @@ describe(TAG, () => {
337
361
  );
338
362
  toggleDiv.click();
339
363
 
364
+ expect(track).toBeCalledTimes(1);
365
+ expect(track).toBeCalledWith(toggleDiv, GTM_EVENT_NAME, {
366
+ sidebarNavAction: "expand",
367
+ clickText: TOGGLE_BUTTON_LABEL
368
+ });
369
+
340
370
  return Promise.resolve()
341
371
  .then(() => {
342
372
  expect(container.classList).not.toContain(
@@ -382,6 +412,16 @@ describe(TAG, () => {
382
412
  expect(toggleButtonDesktop).toBeNull();
383
413
 
384
414
  toggleDiv.click();
415
+
416
+ expect(track).toBeCalledTimes(2);
417
+ expect(track).toHaveBeenLastCalledWith(
418
+ toggleDiv,
419
+ GTM_EVENT_NAME,
420
+ {
421
+ sidebarNavAction: "collapse",
422
+ clickText: TOGGLE_BUTTON_LABEL
423
+ }
424
+ );
385
425
  })
386
426
  .then(() => {
387
427
  expect(container.classList).toContain(COLLAPSED_CLASS);
@@ -1,11 +1,13 @@
1
+ import cx from "classnames";
2
+ import { track } from "dx/instrumentation";
1
3
  import { LightningElement, api } from "lwc";
2
4
 
3
- import { TreeNode } from "typings/custom";
4
- import cx from "classnames";
5
+ import { TreeNode, SidebarGtmAction } from "typings/custom";
5
6
  import { toJson } from "utils/normalizers";
6
7
 
7
8
  const WAIT_TIME = 500;
8
9
  const MOBILE_SIZE_MATCH = "768px";
10
+ const TOGGLE_BUTTON_LABEL = "Toggle Sidebar";
9
11
 
10
12
  export default class Sidebar extends LightningElement {
11
13
  @api header: string = "";
@@ -89,9 +91,16 @@ export default class Sidebar extends LightningElement {
89
91
  this._value = event.detail.name;
90
92
  }
91
93
 
92
- private onToggleClick() {
94
+ private onToggleClick(event: Event) {
93
95
  this.expanded = !this.expanded;
94
96
  this._toggleHovered = false;
97
+ const sidebarNavAction: SidebarGtmAction = this.expanded
98
+ ? "expand"
99
+ : "collapse";
100
+ track(event.currentTarget!, "custEv_leftNavLinkClick", {
101
+ sidebarNavAction,
102
+ clickText: TOGGLE_BUTTON_LABEL
103
+ });
95
104
  }
96
105
 
97
106
  private onToggleMouseEnter() {
@@ -1,66 +1,23 @@
1
1
  import Tooltip from "dx/tooltip";
2
2
  import { createRenderComponent } from "utils/tests";
3
- import createTooltip from "tippy.js";
4
-
5
- const mockSetProps = jest.fn();
6
- jest.mock("tippy.js", () =>
7
- jest.fn().mockImplementation(() => {
8
- return {
9
- setProps: mockSetProps
10
- };
11
- })
12
- );
13
3
 
14
4
  const TAG = "dx-tooltip";
15
5
  const render = createRenderComponent(TAG, Tooltip);
16
6
 
17
7
  describe(TAG, () => {
18
- afterEach(() => {
19
- jest.clearAllMocks();
20
- });
21
-
22
8
  it("calls tippy constructor with correct parameters", () => {
23
- const element = render({ label: "First Label", persist: true });
9
+ const element = render({ label: "First Label", placement: "top" });
24
10
 
25
- const slotContainer = element.shadowRoot.querySelector(
26
- "div.slot-container"
11
+ const slotContainer: HTMLElement = element.shadowRoot.querySelector(
12
+ "div"
27
13
  );
28
14
 
29
15
  expect(slotContainer).not.toBeNull();
30
-
31
- expect(createTooltip).toBeCalledTimes(1);
32
- expect(createTooltip).toBeCalledWith(slotContainer, {
33
- content: "First Label",
34
- placement: "top",
35
- hideOnClick: false,
36
- appendTo: slotContainer
37
- });
38
- expect(mockSetProps).not.toBeCalled();
39
-
40
- return expect(element).toBeAccessible();
41
- });
42
-
43
- it("doesn't call tippy if label is not provided", () => {
44
- const element = render();
45
-
46
- const slotContainer = element.shadowRoot.querySelector(
47
- "div.slot-container"
16
+ expect(slotContainer.getAttribute("data-microtip-position")).toEqual(
17
+ "top"
48
18
  );
49
- expect(slotContainer).not.toBeNull();
50
-
51
- expect(createTooltip).not.toBeCalled();
52
- expect(mockSetProps).not.toBeCalled();
53
- });
54
-
55
- it("changes label after creation", () => {
56
- const element = render({ label: "First Label" });
57
-
58
- expect(createTooltip).toBeCalledTimes(1);
59
- element.label = "New label";
19
+ expect(slotContainer.getAttribute("aria-label")).toEqual("First Label");
60
20
 
61
- expect(createTooltip).toBeCalledTimes(1);
62
- expect(mockSetProps).toBeCalledTimes(1);
63
- expect(mockSetProps).toBeCalledWith({ content: "New label" });
64
21
  return expect(element).toBeAccessible();
65
22
  });
66
23
  });
@@ -0,0 +1,269 @@
1
+ /* Code generated by scripts/postinstall.js DO NOT EDIT*/
2
+
3
+
4
+ /* -------------------------------------------------------------------
5
+ Microtip
6
+
7
+ Modern, lightweight css-only tooltips
8
+ Just 1kb minified and gzipped
9
+
10
+ @author Ghosh
11
+ @package Microtip
12
+
13
+ ----------------------------------------------------------------------
14
+ 1. Base Styles
15
+ 2. Direction Modifiers
16
+ 3. Position Modifiers
17
+ --------------------------------------------------------------------*/
18
+
19
+
20
+ /* ------------------------------------------------
21
+ [1] Base Styles
22
+ -------------------------------------------------*/
23
+
24
+ [aria-label][role~="tooltip"] {
25
+ position: relative;
26
+ }
27
+
28
+ [aria-label][role~="tooltip"]::before,
29
+ [aria-label][role~="tooltip"]::after {
30
+ transform: translate3d(0, 0, 0);
31
+ -webkit-backface-visibility: hidden;
32
+ backface-visibility: hidden;
33
+ will-change: transform;
34
+ opacity: 0;
35
+ pointer-events: none;
36
+ transition: all var(--microtip-transition-duration, .18s) var(--microtip-transition-easing, ease-in-out) var(--microtip-transition-delay, 0s);
37
+ position: absolute;
38
+ box-sizing: border-box;
39
+ z-index: 10;
40
+ transform-origin: top;
41
+ }
42
+
43
+ [aria-label][role~="tooltip"]::before {
44
+ background-size: 100% auto !important;
45
+ content: "";
46
+ }
47
+
48
+ [aria-label][role~="tooltip"]::after {
49
+ background: rgba(17, 17, 17, .9);
50
+ border-radius: 4px;
51
+ color: #ffffff;
52
+ content: attr(aria-label);
53
+ font-size: var(--microtip-font-size, 13px);
54
+ font-weight: var(--microtip-font-weight, normal);
55
+ text-transform: var(--microtip-text-transform, none);
56
+ padding: .5em 1em;
57
+ white-space: nowrap;
58
+ box-sizing: content-box;
59
+ }
60
+
61
+ [aria-label][role~="tooltip"]:hover::before,
62
+ [aria-label][role~="tooltip"]:hover::after,
63
+ [aria-label][role~="tooltip"]:focus::before,
64
+ [aria-label][role~="tooltip"]:focus::after {
65
+ opacity: 1;
66
+ pointer-events: auto;
67
+ }
68
+
69
+
70
+
71
+ /* ------------------------------------------------
72
+ [2] Position Modifiers
73
+ -------------------------------------------------*/
74
+
75
+ [role~="tooltip"][data-microtip-position|="top"]::before {
76
+ background: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%280%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat;
77
+ height: 6px;
78
+ width: 18px;
79
+ margin-bottom: 5px;
80
+ }
81
+
82
+ [role~="tooltip"][data-microtip-position|="top"]::after {
83
+ margin-bottom: 11px;
84
+ }
85
+
86
+ [role~="tooltip"][data-microtip-position|="top"]::before {
87
+ transform: translate3d(-50%, 0, 0);
88
+ bottom: 100%;
89
+ left: 50%;
90
+ }
91
+
92
+ [role~="tooltip"][data-microtip-position|="top"]:hover::before {
93
+ transform: translate3d(-50%, -5px, 0);
94
+ }
95
+
96
+ [role~="tooltip"][data-microtip-position|="top"]::after {
97
+ transform: translate3d(-50%, 0, 0);
98
+ bottom: 100%;
99
+ left: 50%;
100
+ }
101
+
102
+ [role~="tooltip"][data-microtip-position="top"]:hover::after {
103
+ transform: translate3d(-50%, -5px, 0);
104
+ }
105
+
106
+ /* ------------------------------------------------
107
+ [2.1] Top Left
108
+ -------------------------------------------------*/
109
+ [role~="tooltip"][data-microtip-position="top-left"]::after {
110
+ transform: translate3d(calc(-100% + 16px), 0, 0);
111
+ bottom: 100%;
112
+ }
113
+
114
+ [role~="tooltip"][data-microtip-position="top-left"]:hover::after {
115
+ transform: translate3d(calc(-100% + 16px), -5px, 0);
116
+ }
117
+
118
+
119
+ /* ------------------------------------------------
120
+ [2.2] Top Right
121
+ -------------------------------------------------*/
122
+ [role~="tooltip"][data-microtip-position="top-right"]::after {
123
+ transform: translate3d(calc(0% + -16px), 0, 0);
124
+ bottom: 100%;
125
+ }
126
+
127
+ [role~="tooltip"][data-microtip-position="top-right"]:hover::after {
128
+ transform: translate3d(calc(0% + -16px), -5px, 0);
129
+ }
130
+
131
+
132
+ /* ------------------------------------------------
133
+ [2.3] Bottom
134
+ -------------------------------------------------*/
135
+ [role~="tooltip"][data-microtip-position|="bottom"]::before {
136
+ background: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%28180%2018%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat;
137
+ height: 6px;
138
+ width: 18px;
139
+ margin-top: 5px;
140
+ margin-bottom: 0;
141
+ }
142
+
143
+ [role~="tooltip"][data-microtip-position|="bottom"]::after {
144
+ margin-top: 11px;
145
+ }
146
+
147
+ [role~="tooltip"][data-microtip-position|="bottom"]::before {
148
+ transform: translate3d(-50%, -10px, 0);
149
+ bottom: auto;
150
+ left: 50%;
151
+ top: 100%;
152
+ }
153
+
154
+ [role~="tooltip"][data-microtip-position|="bottom"]:hover::before {
155
+ transform: translate3d(-50%, 0, 0);
156
+ }
157
+
158
+ [role~="tooltip"][data-microtip-position|="bottom"]::after {
159
+ transform: translate3d(-50%, -10px, 0);
160
+ top: 100%;
161
+ left: 50%;
162
+ }
163
+
164
+ [role~="tooltip"][data-microtip-position="bottom"]:hover::after {
165
+ transform: translate3d(-50%, 0, 0);
166
+ }
167
+
168
+
169
+ /* ------------------------------------------------
170
+ [2.4] Bottom Left
171
+ -------------------------------------------------*/
172
+ [role~="tooltip"][data-microtip-position="bottom-left"]::after {
173
+ transform: translate3d(calc(-100% + 16px), -10px, 0);
174
+ top: 100%;
175
+ }
176
+
177
+ [role~="tooltip"][data-microtip-position="bottom-left"]:hover::after {
178
+ transform: translate3d(calc(-100% + 16px), 0, 0);
179
+ }
180
+
181
+
182
+ /* ------------------------------------------------
183
+ [2.5] Bottom Right
184
+ -------------------------------------------------*/
185
+ [role~="tooltip"][data-microtip-position="bottom-right"]::after {
186
+ transform: translate3d(calc(0% + -16px), -10px, 0);
187
+ top: 100%;
188
+ }
189
+
190
+ [role~="tooltip"][data-microtip-position="bottom-right"]:hover::after {
191
+ transform: translate3d(calc(0% + -16px), 0, 0);
192
+ }
193
+
194
+
195
+ /* ------------------------------------------------
196
+ [2.6] Left
197
+ -------------------------------------------------*/
198
+ [role~="tooltip"][data-microtip-position="left"]::before,
199
+ [role~="tooltip"][data-microtip-position="left"]::after {
200
+ bottom: auto;
201
+ left: auto;
202
+ right: 100%;
203
+ top: 50%;
204
+ transform: translate3d(10px, -50%, 0);
205
+ }
206
+
207
+ [role~="tooltip"][data-microtip-position="left"]::before {
208
+ background: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%28-90%2018%2018%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat;
209
+ height: 18px;
210
+ width: 6px;
211
+ margin-right: 5px;
212
+ margin-bottom: 0;
213
+ }
214
+
215
+ [role~="tooltip"][data-microtip-position="left"]::after {
216
+ margin-right: 11px;
217
+ }
218
+
219
+ [role~="tooltip"][data-microtip-position="left"]:hover::before,
220
+ [role~="tooltip"][data-microtip-position="left"]:hover::after {
221
+ transform: translate3d(0, -50%, 0);
222
+ }
223
+
224
+
225
+ /* ------------------------------------------------
226
+ [2.7] Right
227
+ -------------------------------------------------*/
228
+ [role~="tooltip"][data-microtip-position="right"]::before,
229
+ [role~="tooltip"][data-microtip-position="right"]::after {
230
+ bottom: auto;
231
+ left: 100%;
232
+ top: 50%;
233
+ transform: translate3d(-10px, -50%, 0);
234
+ }
235
+
236
+ [role~="tooltip"][data-microtip-position="right"]::before {
237
+ background: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%2817,%2017,%2017,%200.9%29%22%20transform%3D%22rotate%2890%206%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E") no-repeat;
238
+ height: 18px;
239
+ width: 6px;
240
+ margin-bottom: 0;
241
+ margin-left: 5px;
242
+ }
243
+
244
+ [role~="tooltip"][data-microtip-position="right"]::after {
245
+ margin-left: 11px;
246
+ }
247
+
248
+ [role~="tooltip"][data-microtip-position="right"]:hover::before,
249
+ [role~="tooltip"][data-microtip-position="right"]:hover::after {
250
+ transform: translate3d(0, -50%, 0);
251
+ }
252
+
253
+ /* ------------------------------------------------
254
+ [3] Size
255
+ -------------------------------------------------*/
256
+ [role~="tooltip"][data-microtip-size="small"]::after {
257
+ white-space: initial;
258
+ width: 80px;
259
+ }
260
+
261
+ [role~="tooltip"][data-microtip-size="medium"]::after {
262
+ white-space: initial;
263
+ width: 150px;
264
+ }
265
+
266
+ [role~="tooltip"][data-microtip-size="large"]::after {
267
+ white-space: initial;
268
+ width: 260px;
269
+ }
@@ -1,4 +1,4 @@
1
- @import "./tippy.css";
1
+ @import "./microtip.css";
2
2
 
3
3
  :host {
4
4
  display: inline-block;
@@ -8,17 +8,29 @@
8
8
  display: inherit;
9
9
  }
10
10
 
11
- .tippy-box {
12
- display: flex;
13
- justify-content: center;
14
- align-items: center;
15
- height: var(--dx-g-spacing-xl);
11
+ [role~="tooltip"][data-microtip-position|="bottom"]::before {
12
+ background: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%28116,%20116,%20116,%201%29%22%20transform%3D%22rotate%28180%2018%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E")
13
+ no-repeat;
14
+ }
15
+
16
+ [role~="tooltip"][data-microtip-position|="top"]::before {
17
+ background: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2236px%22%20height%3D%2212px%22%3E%3Cpath%20fill%3D%22rgba%28116,%20116,%20116,%201%29%22%20transform%3D%22rotate%280%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E")
18
+ no-repeat;
19
+ }
20
+
21
+ [role~="tooltip"][data-microtip-position|="left"]::before {
22
+ background: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%28116,%20116,%20116,%201%29%22%20transform%3D%22rotate%28-90%2018%2018%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E")
23
+ no-repeat;
24
+ }
25
+
26
+ [role~="tooltip"][data-microtip-position|="right"]::before {
27
+ background: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2212px%22%20height%3D%2236px%22%3E%3Cpath%20fill%3D%22rgba%28116,%20116,%20116,%201%29%22%20transform%3D%22rotate%2890%206%206%29%22%20d%3D%22M2.658,0.000%20C-13.615,0.000%2050.938,0.000%2034.662,0.000%20C28.662,0.000%2023.035,12.002%2018.660,12.002%20C14.285,12.002%208.594,0.000%202.658,0.000%20Z%22/%3E%3C/svg%3E")
28
+ no-repeat;
29
+ }
30
+
31
+ [aria-label][role~="tooltip"]::after {
16
32
  background-color: var(--dx-g-gray-50);
17
33
  font-family: var(--dx-g-font-sans);
18
34
  font-size: var(--dx-g-text-xs);
19
35
  color: white;
20
36
  }
21
-
22
- .tippy-arrow {
23
- color: var(--dx-g-gray-50);
24
- }
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="slot-container">
2
+ <div data-microtip-position={placement} role="tooltip" aria-label={label}>
3
3
  <slot></slot>
4
4
  </div>
5
5
  </template>
@@ -5,29 +5,18 @@ export default {
5
5
  component: "dx-tooltip",
6
6
  argTypes: {
7
7
  placement: {
8
- defaultValue: "top-end",
8
+ defaultValue: "top",
9
9
  control: {
10
10
  type: "select",
11
11
  options: [
12
- "auto",
13
- "auto-end",
14
- "auto-start",
15
-
12
+ "top",
13
+ "top-left",
14
+ "top-right",
16
15
  "bottom",
17
- "bottom-end",
18
- "bottom-start",
19
-
16
+ "bottom-left",
17
+ "bottom-right",
20
18
  "left",
21
- "left-end",
22
- "left-start",
23
-
24
- "right",
25
- "right-end",
26
- "right-start",
27
-
28
- "top",
29
- "top-end",
30
- "top-start"
19
+ "right"
31
20
  ]
32
21
  }
33
22
  },
@@ -55,11 +44,3 @@ export const Default = (args: any) => html `${createStyles()}
55
44
  <button>Hover</button>
56
45
  </dx-tooltip>
57
46
  </div>`;
58
-
59
- // prettier-ignore
60
- export const PersistOnClick = (args: any) => html `${createStyles()}
61
- <div class="story-container">
62
- <dx-tooltip label="${args.label}" persist=${true} placement="${args.placement}">
63
- <button>Hover and click</button>
64
- </dx-tooltip>
65
- </div>`;
@@ -1,42 +1,6 @@
1
1
  import { LightningElement, api } from "lwc";
2
- import tippy from "tippy.js";
3
- import { Placement } from "@popperjs/core";
4
- export default class Tooltip extends LightningElement {
5
- @api placement?: Placement = "top";
6
- @api persist: Boolean = false;
7
-
8
- @api
9
- set label(value: string) {
10
- const isChanged: boolean = this._label !== value;
11
- this._label = value;
12
- if (this.tooltip && isChanged) {
13
- this.tooltip.setProps({ content: this._label });
14
- }
15
- }
16
-
17
- get label(): string {
18
- return this._label;
19
- }
20
2
 
21
- private _label: string = "";
22
- private tooltip: any = null;
23
- private container: HTMLElement | null = null;
24
-
25
- renderedCallback() {
26
- if (!this.container) {
27
- this.container = this.template.querySelector(".slot-container");
28
- this.addTooltip();
29
- }
30
- }
31
-
32
- private addTooltip() {
33
- if (this.container && this.label) {
34
- this.tooltip = tippy(this.container, {
35
- content: this.label,
36
- appendTo: this.container,
37
- placement: this.placement,
38
- hideOnClick: !this.persist
39
- });
40
- }
41
- }
3
+ export default class Tooltip extends LightningElement {
4
+ @api placement?: String = "top";
5
+ @api label: string = "";
42
6
  }
@@ -3,6 +3,7 @@ import {
3
3
  NODE_WITH_CHILDREN,
4
4
  SINGLE_NODE_WITH_LINK
5
5
  } from "./mockProps";
6
+ import { track } from "dx/instrumentation";
6
7
  import TreeItem from "dx/treeItem";
7
8
  import TreeTile from "dx/treeTile";
8
9
  import { createRenderComponent } from "utils/tests";
@@ -10,6 +11,10 @@ import { createRenderComponent } from "utils/tests";
10
11
  const TAG = "dx-tree-item";
11
12
  const renderComponent = createRenderComponent(TAG, TreeItem);
12
13
 
14
+ jest.mock("dx/instrumentation");
15
+
16
+ const GTM_EVENT_NAME = "custEv_leftNavLinkClick";
17
+
13
18
  const assertTile = (tile: TreeTile, properties: { [key: string]: any }) =>
14
19
  Object.keys(properties).forEach((key) =>
15
20
  expect(tile).toHaveProperty(key, properties[key])
@@ -167,7 +172,7 @@ describe(TAG, () => {
167
172
  const mockTileSelected = jest.fn();
168
173
 
169
174
  afterEach(() => {
170
- jest.resetAllMocks();
175
+ jest.clearAllMocks();
171
176
  });
172
177
 
173
178
  it("should render the children when the dx-tree-tile emits iconclick", () => {
@@ -189,6 +194,12 @@ describe(TAG, () => {
189
194
  expect(tile).toHaveProperty("isExpanded", false);
190
195
  tile.dispatchEvent(new CustomEvent("iconclick"));
191
196
 
197
+ expect(track).toBeCalledTimes(1);
198
+ expect(track).toBeCalledWith(tile, GTM_EVENT_NAME, {
199
+ clickText: NODE_WITH_CHILDREN.label,
200
+ sidebarNavAction: "expand"
201
+ });
202
+
192
203
  return Promise.resolve().then(() => {
193
204
  const children: Array<TreeItem> = component.shadowRoot.querySelectorAll(
194
205
  "dx-tree-item"
@@ -233,6 +244,12 @@ describe(TAG, () => {
233
244
 
234
245
  tile.dispatchEvent(new CustomEvent("iconclick"));
235
246
 
247
+ expect(track).toBeCalledTimes(1);
248
+ expect(track).toBeCalledWith(tile, GTM_EVENT_NAME, {
249
+ clickText: NODE_WITH_CHILDREN.label,
250
+ sidebarNavAction: "collapse"
251
+ });
252
+
236
253
  return Promise.resolve().then(() => {
237
254
  expect(tile).toHaveProperty("isExpanded", false);
238
255
 
@@ -269,6 +286,12 @@ describe(TAG, () => {
269
286
  expect(button).not.toBeNull();
270
287
  button.click();
271
288
 
289
+ expect(track).toBeCalledTimes(1);
290
+ expect(track).toBeCalledWith(button, GTM_EVENT_NAME, {
291
+ clickText: NODE_WITH_CHILDREN.label,
292
+ sidebarNavAction: "click"
293
+ });
294
+
272
295
  return Promise.resolve().then(() => {
273
296
  expect(mockExpandCollapse).toBeCalledTimes(1);
274
297
  const [expandCall] = mockExpandCollapse.mock.calls[0];
@@ -366,5 +389,24 @@ describe(TAG, () => {
366
389
  expect(trees).toHaveLength(NODE_WITH_CHILDREN.children!.length);
367
390
  });
368
391
  });
392
+
393
+ it("should call track from dx/instrumentation when link is clicked", () => {
394
+ const component = renderComponent({
395
+ treeNode: SINGLE_NODE_WITH_LINK
396
+ });
397
+
398
+ const link: HTMLAnchorElement = component.shadowRoot.querySelector(
399
+ "a"
400
+ );
401
+ expect(link).not.toBeNull();
402
+
403
+ link.click();
404
+
405
+ expect(track).toBeCalledTimes(1);
406
+ expect(track).toBeCalledWith(link, GTM_EVENT_NAME, {
407
+ clickText: SINGLE_NODE_WITH_LINK.label,
408
+ sidebarNavAction: "click"
409
+ });
410
+ });
369
411
  });
370
412
  });
@@ -9,7 +9,7 @@
9
9
  oniconclick={onIconClick}
10
10
  ></dx-tree-tile>
11
11
  </button>
12
- <a if:true={href} href={href} target={target}>
12
+ <a if:true={href} href={href} target={target} onclick={onLinkClick}>
13
13
  <dx-tree-tile
14
14
  is-root={isRoot}
15
15
  tree-node={treeNode}
@@ -1,5 +1,7 @@
1
1
  import { LightningElement, api } from "lwc";
2
2
  import { InternalTreeNode } from "typings/custom";
3
+ import { track } from "dx/instrumentation";
4
+ import { SidebarGtmAction } from "typings/custom";
3
5
 
4
6
  const DEFAULT_TARGET = "_self";
5
7
 
@@ -55,18 +57,24 @@ export default class TreeItem extends LightningElement {
55
57
  }
56
58
  }
57
59
 
58
- private onIconClick(): void {
60
+ private onIconClick(event: CustomEvent): void {
59
61
  this.doExpand();
62
+ this.sendGtm(event, this.isExpanded ? "expand" : "collapse");
60
63
  }
61
64
 
62
- private onButtonClick(): void {
65
+ private onButtonClick(event: Event): void {
63
66
  if (this.hasChildren) {
64
67
  this.doExpand();
65
68
  }
66
69
 
70
+ this.sendGtm(event, "click");
67
71
  this.fireEvent("tileselected", { name: this._treeNode.name });
68
72
  }
69
73
 
74
+ private onLinkClick(event: Event): void {
75
+ this.sendGtm(event, "click");
76
+ }
77
+
70
78
  private doExpand(): void {
71
79
  this.isExpanded = !this.isExpanded;
72
80
  this.fireEvent("expandcollapse");
@@ -88,4 +96,11 @@ export default class TreeItem extends LightningElement {
88
96
  private setExpanded(value: boolean): void {
89
97
  this.isExpanded = value;
90
98
  }
99
+
100
+ private sendGtm(event: Event, sidebarNavAction: SidebarGtmAction) {
101
+ track(event.currentTarget!, "custEv_leftNavLinkClick", {
102
+ clickText: this._treeNode.label,
103
+ sidebarNavAction
104
+ });
105
+ }
91
106
  }
@@ -2,6 +2,7 @@ import { LightningElement, api } from "lwc";
2
2
  import cx from "classnames";
3
3
  import { Brand, Option } from "typings/custom";
4
4
  import { toJson } from "utils/normalizers";
5
+ import { track } from "dx/instrumentation";
5
6
 
6
7
  const VALID_BRANDS = [
7
8
  "analytics",
@@ -17,6 +18,7 @@ const VALID_BRANDS = [
17
18
  "service",
18
19
  "success"
19
20
  ];
21
+ const SIGN_UP_LABEL = "Sign Up";
20
22
 
21
23
  export abstract class HeaderBase extends LightningElement {
22
24
  @api bailHref?: string | null = null;
@@ -178,6 +180,12 @@ export abstract class HeaderBase extends LightningElement {
178
180
  }
179
181
  };
180
182
 
183
+ private handleSignUpClick(e: PointerEvent) {
184
+ track(e.currentTarget!, "custEv_signUpClick", {
185
+ clickText: SIGN_UP_LABEL
186
+ });
187
+ }
188
+
181
189
  protected additionalClasses(): string {
182
190
  return "";
183
191
  }
@@ -1 +0,0 @@
1
- /* Code generated by scripts/postinstall.js DO NOT EDIT */.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}