@salesforcedevs/dx-components 0.10.0 → 0.10.1-alpha.100

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.
Files changed (88) hide show
  1. package/lwc.config.json +3 -3
  2. package/package.json +3 -4
  3. package/src/.DS_Store +0 -0
  4. package/src/assets/svg/docs-empty-state-small.svg +72 -0
  5. package/src/assets/svg/sidebar-loading.svg +34 -0
  6. package/src/modules/.DS_Store +0 -0
  7. package/src/modules/dx/.DS_Store +0 -0
  8. package/src/modules/dx/cardGrid/__tests__/cardMockProps.ts +78 -148
  9. package/src/modules/dx/cardGrid/cardGrid.css +0 -32
  10. package/src/modules/dx/cardGrid/cardGrid.html +5 -11
  11. package/src/modules/dx/codeBlock/__tests__/codeBlock.test.ts +47 -5
  12. package/src/modules/dx/codeBlock/codeBlock.stories.ts +2 -69
  13. package/src/modules/dx/codeBlock/codeBlock.ts +43 -22
  14. package/src/modules/dx/codeBlock/darkTheme.css +0 -1
  15. package/src/modules/dx/codeBlock/lightTheme.css +0 -1
  16. package/src/modules/dx/emptyState/__tests__/emptyState.test.ts +29 -10
  17. package/src/modules/dx/emptyState/__tests__/mockProps.ts +1 -3
  18. package/src/modules/dx/emptyState/emptyState.css +45 -13
  19. package/src/modules/dx/emptyState/emptyState.html +6 -4
  20. package/src/modules/dx/emptyState/emptyState.stories.ts +18 -38
  21. package/src/modules/dx/emptyState/emptyState.ts +11 -20
  22. package/src/modules/dx/footer/links.ts +3 -5
  23. package/src/modules/dx/header/__tests__/mockProps.ts +7 -1
  24. package/src/modules/dx/headerNav/__tests__/headerNav.test.ts +2 -4
  25. package/src/modules/dx/headerNav/headerNav.html +8 -6
  26. package/src/modules/dx/headerNav/headerNav.ts +2 -2
  27. package/src/modules/dx/headerSearch/headerSearch.html +2 -4
  28. package/src/modules/dx/headerSearch/headerSearch.ts +19 -25
  29. package/src/modules/dx/newsletterForm/newsletterForm.html +5 -3
  30. package/src/modules/dx/popover/popover.ts +11 -7
  31. package/src/modules/dx/searchResults/coveo.css +314 -111
  32. package/src/modules/dx/sidebar/__tests__/sidebar.test.ts +0 -70
  33. package/src/modules/dx/sidebar/sidebar.css +42 -23
  34. package/src/modules/dx/sidebar/sidebar.html +62 -40
  35. package/src/modules/dx/sidebar/sidebar.stories.ts +54 -4
  36. package/src/modules/dx/sidebar/sidebar.ts +126 -66
  37. package/src/modules/dx/sidebarSearch/__tests__/preloadedState.ts +3459 -0
  38. package/src/modules/dx/sidebarSearch/__tests__/sidebarSearch.test.ts +44 -0
  39. package/src/modules/dx/sidebarSearch/sidebarSearch.css +3 -0
  40. package/src/modules/dx/sidebarSearch/sidebarSearch.html +26 -0
  41. package/src/modules/dx/sidebarSearch/sidebarSearch.ts +358 -0
  42. package/src/modules/dx/sidebarSearch/utils.ts +2 -0
  43. package/src/modules/dx/sidebarSearchResult/__tests__/sidebarSearchResult.test.ts +55 -0
  44. package/src/modules/dx/sidebarSearchResult/sidebarSearchResult.css +36 -0
  45. package/src/modules/dx/sidebarSearchResult/sidebarSearchResult.html +14 -0
  46. package/src/modules/dx/sidebarSearchResult/sidebarSearchResult.ts +56 -0
  47. package/src/modules/dx/spinner/__tests__/spinner.test.ts +37 -0
  48. package/src/modules/dx/spinner/spinner.css +750 -0
  49. package/src/modules/dx/spinner/spinner.html +6 -0
  50. package/src/modules/dx/spinner/spinner.stories.ts +69 -0
  51. package/src/modules/dx/spinner/spinner.ts +20 -0
  52. package/src/modules/dx/tab/__tests__/tab.test.ts +112 -54
  53. package/src/modules/dx/tab/tab.css +91 -16
  54. package/src/modules/dx/tab/tab.html +10 -12
  55. package/src/modules/dx/tab/tab.stories.ts +57 -0
  56. package/src/modules/dx/tab/tab.ts +35 -28
  57. package/src/modules/dx/tooltip/tippy.css +1 -0
  58. package/src/modules/dx/treeTile/__tests__/treeTile.test.ts +1 -1
  59. package/src/modules/dx/treeTile/treeTile.css +3 -19
  60. package/src/modules/dx/treeTile/treeTile.html +4 -1
  61. package/src/modules/dx/treeTile/treeTile.ts +2 -2
  62. package/src/modules/helpers/sidebar/sidebar.css +21 -0
  63. package/src/modules/helpers/table/table.css +23 -7
  64. package/src/modules/utils/coveo/coveo.ts +60 -0
  65. package/src/modules/utils/highlight/highlight.ts +31 -0
  66. package/src/modules/utils/normalizers/normalizers.ts +3 -0
  67. package/src/modules/utils/recentSearches/__tests__/recentSearches.test.ts +79 -0
  68. package/src/modules/utils/recentSearches/recentSearches.ts +57 -0
  69. package/src/modules/utils/regexps/regexps.ts +5 -0
  70. package/LICENSE +0 -12
  71. package/src/modules/dx/headerNavOption/__tests__/headerNavOption.test.ts +0 -113
  72. package/src/modules/dx/headerNavOption/headerNavOption.css +0 -91
  73. package/src/modules/dx/headerNavOption/headerNavOption.html +0 -9
  74. package/src/modules/dx/headerNavOption/headerNavOption.ts +0 -31
  75. package/src/modules/dx/headerSearch/__tests__/mockProps.ts +0 -11
  76. package/src/modules/dx/tab/__tests__/mockProps.ts +0 -4
  77. package/src/modules/dx/tabPanel/__tests__/mockProps.ts +0 -4
  78. package/src/modules/dx/tabPanel/__tests__/tabPanel.test.ts +0 -46
  79. package/src/modules/dx/tabPanel/tabPanel.css +0 -9
  80. package/src/modules/dx/tabPanel/tabPanel.html +0 -13
  81. package/src/modules/dx/tabPanel/tabPanel.ts +0 -27
  82. package/src/modules/dx/tabs/__tests__/mockProps.ts +0 -3
  83. package/src/modules/dx/tabs/__tests__/tabs.test.ts +0 -47
  84. package/src/modules/dx/tabs/tabs.css +0 -7
  85. package/src/modules/dx/tabs/tabs.html +0 -21
  86. package/src/modules/dx/tabs/tabs.stories.ts +0 -74
  87. package/src/modules/dx/tabs/tabs.ts +0 -112
  88. package/src/modules/dx/tabs/uniqueId.ts +0 -6
@@ -1,10 +1,15 @@
1
1
  import CodeBlock from "../codeBlock";
2
2
  import { createRenderComponent } from "utils/tests";
3
3
  import mockProps from "./mockProps";
4
+ import { track as gtmTrack } from "dx/instrumentation";
4
5
  //import Prism from "utils/prismjs";
5
6
 
6
7
  const TAG = "dx-code-block";
7
8
  const render = createRenderComponent(TAG, CodeBlock);
9
+
10
+ jest.mock("dx/instrumentation");
11
+
12
+ const GTM_EVENT_NAME = "custEv_codeBlock";
8
13
  /*
9
14
  const mockPrismHighlight = jest.fn();
10
15
  jest.mock("utils/prismjs", () =>
@@ -20,6 +25,10 @@ describe(TAG, () => {
20
25
  const oldNavigator = window.navigator;
21
26
  const oldError = console.error;
22
27
 
28
+ afterEach(() => {
29
+ jest.clearAllMocks();
30
+ });
31
+
23
32
  afterAll(() => {
24
33
  Object.assign(window.navigator, oldNavigator);
25
34
  Object.assign(console.error, oldError);
@@ -46,9 +55,8 @@ describe(TAG, () => {
46
55
  title: "Java Example",
47
56
  language: "java"
48
57
  });
49
- const dxThemeLight = element.shadowRoot.querySelector(
50
- ".dx-theme-light"
51
- );
58
+ const dxThemeLight =
59
+ element.shadowRoot.querySelector(".dx-theme-light");
52
60
  expect(dxThemeLight).not.toContain(null);
53
61
 
54
62
  expect(element.shadowRoot.querySelector(".source-btn")).toBe(null);
@@ -67,8 +75,15 @@ describe(TAG, () => {
67
75
  const divTheme = element.shadowRoot.querySelector(".dx-theme-light");
68
76
  expect(divTheme).not.toBeNull();
69
77
 
78
+ const updateThemeBtn = element.shadowRoot.querySelector(
79
+ "dx-button.update-theme-btn"
80
+ );
81
+
70
82
  //update light -> dark
71
- element.shadowRoot.querySelector("dx-button.update-theme-btn").click();
83
+ updateThemeBtn.click();
84
+
85
+ //gtm event
86
+ expect(gtmTrack).toBeCalled();
72
87
 
73
88
  return Promise.resolve()
74
89
  .then(() => {
@@ -77,10 +92,28 @@ describe(TAG, () => {
77
92
  element.shadowRoot
78
93
  .querySelector("dx-button.update-theme-btn")
79
94
  .click();
95
+
96
+ //expect gtm event for dark mode
97
+ expect(gtmTrack).toBeCalledWith(
98
+ updateThemeBtn,
99
+ GTM_EVENT_NAME,
100
+ {
101
+ codeBlockAction: "darkmode"
102
+ }
103
+ );
80
104
  })
81
105
  .then(() => {
82
106
  //expect -> light
83
107
  expect(divTheme.classList).toContain("dx-theme-light");
108
+
109
+ //expect gtm event for dark mode
110
+ expect(gtmTrack).toBeCalledWith(
111
+ updateThemeBtn,
112
+ GTM_EVENT_NAME,
113
+ {
114
+ codeBlockAction: "lightmode"
115
+ }
116
+ );
84
117
  });
85
118
  });
86
119
 
@@ -140,6 +173,13 @@ describe(TAG, () => {
140
173
  expect(sourceBtn).not.toBe(null);
141
174
  sourceBtn.click();
142
175
 
176
+ //gtm event
177
+ expect(gtmTrack).toBeCalled();
178
+
179
+ expect(gtmTrack).toBeCalledWith(sourceBtn, GTM_EVENT_NAME, {
180
+ codeBlockAction: "copy"
181
+ });
182
+
143
183
  expect(window.navigator.clipboard.writeText).toBeCalledTimes(1);
144
184
  expect(window.navigator.clipboard.writeText).toBeCalledWith(
145
185
  element.shadowRoot.querySelector(".code-block-content").textContent
@@ -195,6 +235,8 @@ describe(TAG, () => {
195
235
 
196
236
  const divTheme = element.shadowRoot.querySelector(".dx-theme-light");
197
237
  expect(divTheme).not.toBeNull();
198
- expect(window.localStorage.getItem("dx-codeblock-theme")).toBe("dark");
238
+ expect(window.localStorage.getItem("dx-codeblock-theme")).toBe(
239
+ element.defaultTheme
240
+ );
199
241
  });
200
242
  });
@@ -16,7 +16,7 @@ const styles = `
16
16
  }
17
17
  </style>`;
18
18
 
19
- export const DarkTheme = (args: any) => `${styles}
19
+ export const Base = (args: any) => `${styles}
20
20
 
21
21
  <span class="dx-text-heading-7 dx-code-block-heading">XML Example - Dark Theme</span>
22
22
  <dx-code-block
@@ -98,74 +98,7 @@ export const DarkTheme = (args: any) => `${styles}
98
98
  language="php"
99
99
  default-theme="dark"
100
100
  ></dx-code-block>`;
101
- DarkTheme.args = mockProps;
102
-
103
- export const LightTheme = (args: any) => `${styles}
104
-
105
- <span class="dx-text-heading-7 dx-code-block-heading">XML Example - Light Theme</span>
106
- <dx-code-block
107
- title="XML example"
108
- code-block="${args.xml}"
109
- language="xml
110
- ></dx-code-block>
111
-
112
- <span class="dx-text-heading-7 dx-code-block-heading">Visualforce Example - Light Theme</span>
113
- <dx-code-block
114
- title="Visualforce example"
115
- code-block="${args.visualforce}"
116
- language="visualforce"
117
- ></dx-code-block>
118
-
119
- <span class="dx-text-heading-7 dx-code-block-heading">Java Example - Light Theme</span>
120
- <dx-code-block
121
- title="Java example"
122
- code-block="${args.java}"
123
- language="java"
124
- ></dx-code-block>
125
-
126
- <span class="dx-text-heading-7 dx-code-block-heading">Light Theme</span>
127
- <dx-code-block
128
- title="HTML Example"
129
- code-block="${args.html}"
130
- source-link="http://www.salesforce.com"
131
- language="html"
132
- ></dx-code-block>
133
-
134
- <span class="dx-text-heading-7 dx-code-block-heading">TypeScript Example - Light Theme</span>
135
- <dx-code-block
136
- title="TypeScript example"
137
- code-block="${args.TypeScript}"
138
- language="TypeScript"
139
- ></dx-code-block>
140
-
141
- <span class="dx-text-heading-7 dx-code-block-heading">Light Theme</span>
142
- <dx-code-block
143
- title="CSS example"
144
- code-block="${args.css}"
145
- language="css"
146
- ></dx-code-block>
147
-
148
- <span class="dx-text-heading-7 dx-code-block-heading">Apex Example - Light Theme</span>
149
- <dx-code-block
150
- title="Apex example"
151
- code-block="${args.apex}"
152
- language="apex"
153
- ></dx-code-block>
154
-
155
- <span class="dx-text-heading-7 dx-code-block-heading">No Language Example - Light Theme</span>
156
- <dx-code-block
157
- title="No Language"
158
- code-block="${args.apex}"
159
- ></dx-code-block>
160
-
161
- <span class="dx-text-heading-7 dx-code-block-heading">Light Theme</span>
162
- <dx-code-block
163
- title="PHP Example"
164
- code-block="${args.php}"
165
- language="php"
166
- ></dx-code-block>`;
167
-
168
- LightTheme.args = mockProps;
101
+ Base.args = mockProps;
169
102
 
170
103
  export const PreTag = (args: any) => `${styles}
171
104
  <span class="dx-text-heading-7 dx-code-block-heading">Dark Theme</span>
@@ -1,25 +1,28 @@
1
- import { LightningElement, api, wire, track } from "lwc";
1
+ import { LightningElement, api, track } from "lwc";
2
2
  import { CodeBlockTheme, CodeBlockLanguage } from "typings/custom";
3
3
  import cx from "classnames";
4
- import Prism from "utils/prismjs";
5
- import {
6
- getLocalStorageData,
7
- setLocalStorageData
8
- } from "@sfdocs-internal/wires";
4
+ // import Prism from "utils/prismjs";
5
+ // import {
6
+ // getLocalStorageData,
7
+ // setLocalStorageData
8
+ // } from "@sfdocs-internal/wires";
9
+ import { track as gtmTrack } from "dx/instrumentation";
9
10
 
10
11
  // Used por remove enclosing <pre> tag's (if occurs)
11
12
  const preTagRegexp: RegExp = /^<pre.*?>(.*)<\/pre>$/is;
12
13
 
13
14
  const LIGHT = "light";
14
15
  const DARK = "dark";
15
- const themes: CodeBlockTheme[] = [LIGHT, DARK];
16
- const LOCAL_STORAGE_KEY = "dx-codeblock-theme";
16
+ // const themes: CodeBlockTheme[] = [LIGHT, DARK];
17
+ // const LOCAL_STORAGE_KEY = "dx-codeblock-theme";
17
18
 
18
19
  export default class CodeBlock extends LightningElement {
19
20
  @api defaultTheme: CodeBlockTheme = LIGHT;
20
21
  @api title: string = "title";
21
22
  @api sourceLink: string = "";
22
23
  @api language: string = "";
24
+ // if it is true, it renders code as is coming instead of wrapping it into html/xml comments tags.
25
+ @api isEncoded = false;
23
26
 
24
27
  private markupLangs = ["visualforce", "html", "xml"];
25
28
  private _codeBlockRendered: boolean = false;
@@ -65,14 +68,17 @@ export default class CodeBlock extends LightningElement {
65
68
 
66
69
  @track private theme: CodeBlockTheme | null = null;
67
70
 
68
- @wire(getLocalStorageData, { key: "dx-codeblock-theme" })
69
- updateThemeForCodeblock(value: any) {
70
- if (themes.includes(value)) {
71
- this.theme = value;
72
- } else {
73
- setLocalStorageData(LOCAL_STORAGE_KEY, this.theme);
74
- }
75
- }
71
+ // @wire(getLocalStorageData, { key: "dx-codeblock-theme" })
72
+ // updateThemeForCodeblock(value: any) {
73
+ // if (themes.includes(value)) {
74
+ // this.theme = value;
75
+ // } else {
76
+ // setLocalStorageData(
77
+ // LOCAL_STORAGE_KEY,
78
+ // this.theme || this.defaultTheme
79
+ // );
80
+ // }
81
+ // }
76
82
 
77
83
  get updateThemeBtnText(): string {
78
84
  return `Switch to ${this.theme === DARK ? "Light" : "Dark"} mode`;
@@ -89,7 +95,10 @@ export default class CodeBlock extends LightningElement {
89
95
  formatCodeBlock() {
90
96
  const divEl = this.template.querySelector("div.code-block-content");
91
97
  const templateEl = document.createElement("template");
92
- if (this.markupLangs.includes(this.selectedLanguage.id || "")) {
98
+ if (
99
+ !this.isEncoded &&
100
+ this.markupLangs.includes(this.selectedLanguage.id || "")
101
+ ) {
93
102
  // eslint-disable-next-line
94
103
  templateEl.innerHTML = `<pre class='codeblock'><!-- ${this.codeBlock.replace(
95
104
  /<!--(.*?)-->/gs,
@@ -97,7 +106,11 @@ export default class CodeBlock extends LightningElement {
97
106
  )} --></pre>`;
98
107
  } else {
99
108
  // eslint-disable-next-line
100
- templateEl.innerHTML = `<pre class='codeblock'>${this.codeBlock}</pre>`;
109
+ const innerHtml = this.isEncoded
110
+ ? this.codeBlock
111
+ : this.codeBlock.replace(/</g, "&lt").replace(/>/g, "&gt");
112
+
113
+ templateEl.innerHTML = `<pre class='codeblock'>${innerHtml}</pre>`;
101
114
  }
102
115
  const codeBlockEls = templateEl.content.querySelectorAll("pre");
103
116
  codeBlockEls.forEach((codeBlockEl) => {
@@ -120,7 +133,7 @@ export default class CodeBlock extends LightningElement {
120
133
  // eslint-disable-next-line
121
134
  codeBlockEl.innerHTML = "";
122
135
  codeBlockEl.appendChild(codeEl);
123
- Prism.highlightAllUnder(codeBlockEl);
136
+ // Prism.highlightAllUnder(codeBlockEl);
124
137
  });
125
138
 
126
139
  if (divEl) {
@@ -154,7 +167,11 @@ export default class CodeBlock extends LightningElement {
154
167
  * Note: There is a known issue in storybook@6.1.13 where some apis are not available if you access Storybook through IP address.
155
168
  * https://github.com/storybookjs/storybook/issues/13529
156
169
  */
157
- async copySource() {
170
+ async copySource(event: any) {
171
+ gtmTrack(event.target, "custEv_codeBlock", {
172
+ codeBlockAction: "copy"
173
+ });
174
+
158
175
  try {
159
176
  const snippetContainer: HTMLElement | null = this.template.querySelector(
160
177
  ".code-block-content"
@@ -173,9 +190,13 @@ export default class CodeBlock extends LightningElement {
173
190
  }
174
191
  }
175
192
 
176
- updateTheme() {
193
+ updateTheme(event: any) {
177
194
  this.theme = this.theme === DARK ? LIGHT : DARK;
178
- setLocalStorageData(LOCAL_STORAGE_KEY, this.theme);
195
+ // setLocalStorageData(LOCAL_STORAGE_KEY, this.theme);
196
+
197
+ gtmTrack(event.target, "custEv_codeBlock", {
198
+ codeBlockAction: this.theme === DARK ? "darkmode" : "lightmode"
199
+ });
179
200
  }
180
201
 
181
202
  renderedCallback() {
@@ -19,7 +19,6 @@
19
19
  }
20
20
 
21
21
  .dx-theme-dark .token.operator {
22
- background-color: var(--dx-g-blue-vibrant-20);
23
22
  color: var(--dx-g-pink-vibrant-65);
24
23
  }
25
24
 
@@ -16,7 +16,6 @@
16
16
 
17
17
  .dx-theme-light .token.operator {
18
18
  color: var(--dx-g-green-vibrant-50);
19
- background-color: #fff;
20
19
  }
21
20
 
22
21
  .dx-theme-light .token.property {
@@ -8,15 +8,12 @@ const render = createRenderComponent(TAG, EmptyState);
8
8
  describe(TAG, () => {
9
9
  it("renders", () => {
10
10
  const element = render(mockProps);
11
- const container: HTMLElement = element.shadowRoot.querySelector(
12
- ".container"
13
- );
14
- const renderedTitle: HTMLElement = element.shadowRoot.querySelector(
15
- "h3"
16
- );
17
- const renderedSubTitle: HTMLElement = element.shadowRoot.querySelector(
18
- "p"
19
- );
11
+ const container: HTMLElement =
12
+ element.shadowRoot.querySelector(".container");
13
+ const renderedTitle: HTMLElement =
14
+ element.shadowRoot.querySelector("h3");
15
+ const renderedSubTitle: HTMLElement =
16
+ element.shadowRoot.querySelector("p");
20
17
  const image: HTMLImageElement = element.shadowRoot.querySelector("img");
21
18
 
22
19
  expect(renderedTitle).not.toBeNull();
@@ -26,8 +23,30 @@ describe(TAG, () => {
26
23
 
27
24
  expect(renderedSubTitle.textContent).toEqual(mockProps.subtitle);
28
25
  expect(renderedTitle.textContent).toEqual(mockProps.title);
29
- expect(image.src).toEqual(`http://localhost${mockProps.imgSrc}`);
30
26
 
31
27
  return expect(element).toBeAccessible();
32
28
  });
29
+
30
+ it("renders as the large variant by default", () => {
31
+ const element = render(mockProps);
32
+ const container: HTMLElement =
33
+ element.shadowRoot.querySelector(".container");
34
+ const image: HTMLImageElement = element.shadowRoot.querySelector("img");
35
+ expect(container.classList).toContain("size-large");
36
+ expect(container.classList).toHaveLength(2);
37
+ expect(image.src).not.toContain("-small.svg");
38
+ });
39
+
40
+ it("renders as the small variant when specified", () => {
41
+ const element = render({
42
+ ...mockProps,
43
+ size: "small"
44
+ });
45
+ const container: HTMLElement =
46
+ element.shadowRoot.querySelector(".container");
47
+ const image: HTMLImageElement = element.shadowRoot.querySelector("img");
48
+ expect(container.classList).toContain("size-small");
49
+ expect(container.classList).toHaveLength(2);
50
+ expect(image.src).toContain("-small.svg");
51
+ });
33
52
  });
@@ -1,6 +1,4 @@
1
1
  export default {
2
2
  title: "No matches",
3
- subtitle: "Try searching for different words",
4
- imgSrc: "/assets/svg/lake-mountain.svg",
5
- imgAlt: "test"
3
+ subtitle: "Try searching for different words"
6
4
  };
@@ -1,31 +1,63 @@
1
1
  @import "helpers/reset";
2
2
  @import "helpers/text";
3
3
 
4
+ :host {
5
+ --dx-c-empty-state-background: var(--dx-g-gray-95);
6
+ --dx-c-empty-state-image-width: 600px;
7
+
8
+ width: 100%;
9
+ }
10
+
4
11
  .container {
5
- text-align: center;
6
- display: block;
12
+ position: relative;
13
+ background: var(--dx-c-empty-state-background);
14
+ border-radius: var(--dx-g-spacing-md);
15
+ padding: var(--dx-g-spacing-2xl) 0;
16
+ display: flex;
17
+ align-items: center;
18
+ justify-content: center;
19
+ overflow: hidden;
7
20
  }
8
21
 
9
22
  img {
10
- margin: auto;
23
+ width: var(--dx-c-empty-state-image-width);
24
+ min-width: var(--dx-c-empty-state-image-width);
25
+ }
26
+
27
+ .size-small img {
28
+ width: calc(100% - 40px);
29
+ min-width: calc(100% - 40px);
30
+ }
31
+
32
+ .text {
33
+ position: absolute;
34
+ top: 35%;
35
+ min-height: 15%;
36
+ left: 0;
11
37
  width: 100%;
12
- margin-bottom: var(--dx-g-spacing-xl);
38
+ display: flex;
39
+ justify-content: center;
40
+ align-items: center;
41
+ flex-direction: column;
42
+ text-align: center;
43
+ padding: 0 var(--dx-g-spacing-xl);
13
44
  }
14
45
 
15
- .subtitle {
16
- font-size: var(--dx-g-text-xs);
46
+ .size-small .text {
47
+ top: 40%;
17
48
  }
18
49
 
19
50
  .title {
20
- font-size: var(--dx-g-text-lg);
21
- padding-bottom: var(--dx-g-spacing-sm);
51
+ font-size: var(--dx-g-text-2xl);
22
52
  }
23
53
 
24
- .title.dx-text-heading-3 {
25
- font-size: var(--dx-g-text-2xl);
54
+ .size-small .title {
55
+ font-size: var(--dx-g-text-base);
56
+ white-space: nowrap;
26
57
  }
27
58
 
28
- .subtitle.dx-text-label-1 {
29
- font-size: var(--dx-g-text-md);
30
- text-transform: none;
59
+ .subtitle {
60
+ padding-top: var(--dx-g-spacing-sm);
61
+ color: var(--dx-g-text-heading-color);
62
+ font-weight: bold;
31
63
  }
@@ -1,7 +1,9 @@
1
1
  <template>
2
- <div class="container" part="container">
3
- <img src={imgSrc} alt={imgAlt} />
4
- <h3 class={titleClass} part="title">{title}</h3>
5
- <p class={subtitleClass} part="subtitle">{subtitle}</p>
2
+ <div class={containerClassName} part="container">
3
+ <img src={imageAssetPath} alt="Mountains" />
4
+ <div class="text">
5
+ <h3 class="title dx-text-heading-3">{title}</h3>
6
+ <p class="subtitle dx-text-body-2" if:true={subtitle}>{subtitle}</p>
7
+ </div>
6
8
  </div>
7
9
  </template>
@@ -8,58 +8,38 @@ export default {
8
8
  const createStyles = () => html`
9
9
  <style>
10
10
  body {
11
- padding: 12px 0 0 0 !important;
11
+ padding: 12px !important;
12
12
  }
13
13
  .title {
14
14
  font-weight: bold;
15
15
  margin: 24px;
16
16
  }
17
- </style>
18
- `;
19
-
20
- const title = (value: string) => html`<p class="title">${value}</p>`;
21
-
22
- const customTextStyles = () => html`
23
- <style>
24
- .custom-text-styles::part(container) {
25
- position: relative;
26
- }
27
-
28
- .custom-text-styles::part(title),
29
- .custom-text-styles::part(subtitle) {
30
- --y-pos: -100%;
31
- position: absolute;
32
- top: 50%;
33
- left: 50%;
34
- transform: translateX(-50%) translateY(var(--y-pos));
17
+ #styled {
18
+ --dx-c-empty-state-background: var(--sds-g-gray-2);
19
+ --dx-c-empty-state-image-width: 400px;
20
+ width: 300px;
21
+ display: block;
35
22
  }
36
-
37
- .custom-text-styles::part(subtitle) {
38
- --y-pos: 100%;
23
+ .small-container {
24
+ width: 250px;
39
25
  }
40
26
  </style>
41
27
  `;
42
28
 
29
+ const title = (value: string) => html`<p class="title">${value}</p>`;
30
+
43
31
  export const Base = () => html`
44
32
  ${createStyles()} ${title("Default")}
45
- <dx-empty-state
46
- title="No matches"
47
- subtitle="Try searching for different words"
48
- img-src="/assets/svg/lake-mountain.svg"
49
- img-alt="test"
50
- ></dx-empty-state>
51
-
52
- ${title(
53
- "Large title/subtitle. Center text w/ external styles via part selector."
54
- )}
55
- ${customTextStyles()}
56
33
  <dx-empty-state
57
34
  title="Beep boop. That did not compute."
58
35
  subtitle="No results"
59
- img-src="/assets/svg/docs-empty-state.svg"
60
- img-alt="test"
61
- subtitle-size="large"
62
- title-size="large"
63
- class="custom-text-styles"
64
36
  ></dx-empty-state>
37
+
38
+ ${title("No subtitle and customized with style hooks")}
39
+ <dx-empty-state id="styled" title="No Results"></dx-empty-state>
40
+
41
+ ${title("Small variant")}
42
+ <div class="small-container">
43
+ <dx-empty-state title="No Results" size="small"></dx-empty-state>
44
+ </div>
65
45
  `;
@@ -1,29 +1,20 @@
1
1
  import { LightningElement, api } from "lwc";
2
- import cx from "classnames";
2
+ import { EmptyStateSize } from "typings/custom";
3
3
 
4
4
  export default class EmptyState extends LightningElement {
5
5
  @api title: string = "";
6
- @api subtitle: string = "";
7
- @api imgSrc: string = "";
8
- @api imgAlt: string = "";
9
- @api titleSize?: "large" | "small" = "small";
10
- @api subtitleSize?: "large" | "small" = "small";
6
+ @api subtitle?: string | null = null;
7
+ @api size?: EmptyStateSize = "large";
11
8
 
12
- private get titleClass() {
13
- return cx(
14
- "title",
15
- this.titleSize === "small"
16
- ? "dx-text-heading-alt-1"
17
- : "dx-text-heading-3"
18
- );
9
+ get containerClassName() {
10
+ return `container ${
11
+ !this.size || this.size === "large" ? "size-large" : "size-small"
12
+ }`;
19
13
  }
20
14
 
21
- private get subtitleClass() {
22
- return cx(
23
- "subtitle",
24
- this.subtitleSize === "small"
25
- ? "dx-text-heading-alt-1"
26
- : "dx-text-label-1"
27
- );
15
+ get imageAssetPath() {
16
+ return `/assets/svg/docs-empty-state${
17
+ this.size === "small" ? "-small" : ""
18
+ }.svg`;
28
19
  }
29
20
  }
@@ -45,7 +45,7 @@ export const generalLinksRaw = [
45
45
  label: "Community",
46
46
  options: [
47
47
  {
48
- href: "https://trailblazers.salesforce.com/",
48
+ href: "https://trailhead.salesforce.com/trailblazer-community/feed",
49
49
  label: "Trailblazer Community"
50
50
  },
51
51
  {
@@ -90,13 +90,11 @@ export const intellectualHref =
90
90
  export const termsLinks = [
91
91
  { href: privacyHref, label: "Privacy Statement" },
92
92
  {
93
- href:
94
- "https://trailblazer.me/resource/documents/documents/pdf/TermsOfUse_en_US.pdf",
93
+ href: "https://trailblazer.me/resource/documents/documents/pdf/TermsOfUse_en_US.pdf",
95
94
  label: "Terms of Use"
96
95
  },
97
96
  {
98
- href:
99
- "https://www.salesforce.com/company/privacy/full_privacy/#nav_info",
97
+ href: "https://www.salesforce.com/company/privacy/full_privacy/#nav_info",
100
98
  label: "Use of Cookies"
101
99
  },
102
100
  { href: "https://trust.salesforce.com/en/", label: "Trust" }
@@ -13,7 +13,13 @@ import {
13
13
  mockNavAnalytics
14
14
  } from "./mockNavs";
15
15
  import mockNavDevelopers from "./mockNavDevelopers";
16
- import { coveoConfig } from "../../headerSearch/__tests__/mockProps";
16
+
17
+ export const coveoConfig = {
18
+ coveoOrganizationId: "coveosalesforcetestakshatha",
19
+ coveoPublicAccessToken: "xx114e9d50-bc6b-40f1-b25b-fa5a06c7e168",
20
+ coveoSearchPipeline: "salesforcedevdoc",
21
+ coveoSearchHub: "salesforcedevdoc2"
22
+ };
17
23
 
18
24
  const versions = JSON.stringify([
19
25
  {
@@ -11,9 +11,7 @@ describe(TAG, () => {
11
11
  const element = render({ navItems });
12
12
 
13
13
  const items = element.shadowRoot.querySelectorAll(".nav-list-item");
14
- const dropdownItems = element.shadowRoot.querySelectorAll(
15
- "dx-header-nav-option"
16
- );
14
+ const dropdownItems = element.shadowRoot.querySelectorAll("dx-tab");
17
15
 
18
16
  // items with more options render something different on mobile and desktop whose display is toggled by `display: none;`
19
17
  const expectedItemLength =
@@ -34,7 +32,7 @@ describe(TAG, () => {
34
32
  const mockOpenNav = jest.fn();
35
33
  element.addEventListener("requestopennavmenu", mockOpenNav);
36
34
  const navOption: HTMLElement = element.shadowRoot.querySelector(
37
- "dx-header-nav-option.nav-list-item-nav-menu"
35
+ "dx-tab.nav-list-item-nav-menu"
38
36
  );
39
37
  expect(navOption).not.toBeNull();
40
38
  navOption.click();