@salesforcedevs/dx-components 0.53.10 → 0.53.11-alpha

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 (45) hide show
  1. package/lwc.config.json +15 -17
  2. package/package.json +3 -6
  3. package/src/modules/base-elements/headerBase/headerBase.ts +1 -1
  4. package/src/modules/dx/cardCallout/cardCallout.ts +4 -4
  5. package/src/modules/dx/cardNews/cardNews.ts +1 -1
  6. package/src/modules/dx/codeBlock/codeBlock.ts +1 -1
  7. package/src/modules/dx/dropdownOption/dropdownOption.ts +1 -1
  8. package/src/modules/dx/footer/footer.ts +1 -1
  9. package/src/modules/dx/footerOption/footerOption.ts +1 -1
  10. package/src/modules/dx/groupText/groupText.ts +1 -1
  11. package/src/modules/dx/headerMobileNavMenuOption/headerMobileNavMenuOption.ts +1 -1
  12. package/src/modules/dx/pagination/pagination.ts +1 -1
  13. package/src/modules/dx/sidebar/sidebar.ts +1 -1
  14. package/src/modules/dx/sidebarOld/sidebarOld.ts +1 -1
  15. package/src/modules/dx/tab/tab.ts +1 -1
  16. package/src/modules/dx/treeItem/treeItem.ts +1 -1
  17. package/src/modules/utils/analytics/analytics.ts +24 -0
  18. package/LICENSE +0 -12
  19. package/src/modules/dx/cardBlogPostProvider/cardBlogPostProvider.css +0 -3
  20. package/src/modules/dx/cardBlogPostProvider/cardBlogPostProvider.html +0 -16
  21. package/src/modules/dx/cardBlogPostProvider/cardBlogPostProvider.ts +0 -29
  22. package/src/modules/dx/cardPodcastEpisodeProvider/cardPodcastEpisodeProvider.css +0 -3
  23. package/src/modules/dx/cardPodcastEpisodeProvider/cardPodcastEpisodeProvider.html +0 -12
  24. package/src/modules/dx/cardPodcastEpisodeProvider/cardPodcastEpisodeProvider.ts +0 -29
  25. package/src/modules/dx/contentArchive/contentArchive.css +0 -242
  26. package/src/modules/dx/contentArchive/contentArchive.html +0 -337
  27. package/src/modules/dx/contentArchive/contentArchive.ts +0 -461
  28. package/src/modules/dx/contentArchive/contentArchive.types.ts +0 -6
  29. package/src/modules/dx/instrumentation/instrumentation.html +0 -1
  30. package/src/modules/dx/instrumentation/instrumentation.ts +0 -116
  31. package/src/modules/dx/newsletterForm/newsletterForm.css +0 -73
  32. package/src/modules/dx/newsletterForm/newsletterForm.html +0 -73
  33. package/src/modules/dx/newsletterForm/newsletterForm.ts +0 -238
  34. package/src/modules/dx/podcastSubscription/podcastSubscription.css +0 -91
  35. package/src/modules/dx/podcastSubscription/podcastSubscription.html +0 -24
  36. package/src/modules/dx/podcastSubscription/podcastSubscription.ts +0 -52
  37. package/src/modules/dx/searchResults/coveo.css +0 -18989
  38. package/src/modules/dx/searchResults/searchResults.css +0 -387
  39. package/src/modules/dx/searchResults/searchResults.html +0 -104
  40. package/src/modules/dx/searchResults/searchResults.ts +0 -186
  41. package/src/modules/dx/slackCta/slackCta.css +0 -47
  42. package/src/modules/dx/slackCta/slackCta.html +0 -17
  43. package/src/modules/dx/slackCta/slackCta.ts +0 -12
  44. package/src/modules/utils/contentArchive/altData.js +0 -3
  45. package/src/modules/utils/contentArchive/contentArchive.ts +0 -163
@@ -1,461 +0,0 @@
1
- import { LightningElement } from "lwc";
2
- import cx from "classnames";
3
- import { getArchivePosts, getArchiveFilterList } from "utils/contentArchive";
4
- import { sortSplittedPostsByMonth } from "utils/dates";
5
- import { Filters } from "./contentArchive.types";
6
- import { QueryCoordinator } from "utils/queryCoordinator";
7
-
8
- const MOBILE_MATCH = "767px";
9
-
10
- const QUERY_SITE_FILTER = "c__filter";
11
- const PODCASTS = { id: 2, name: "Podcasts" };
12
- const BLOGS = { id: 1, name: "Blogs" };
13
- export default class ContentArchive extends LightningElement {
14
- private _contentTypeList = [
15
- { ...BLOGS, checked: false },
16
- { ...PODCASTS, checked: false }
17
- ];
18
- private totalResults: number | null = null;
19
- private currentPage: number = 1;
20
- private totalPages: number = 1;
21
- private loading: boolean = true;
22
- private filtersLoading: boolean = true;
23
- private modalOpen: boolean = false;
24
- private cardType: string = "expanded";
25
-
26
- private postsByDate: {} = {};
27
- private dateList: any[] = [];
28
- private authorList: any[] = [];
29
- private categoryList: any[] = [];
30
-
31
- private isMobile: boolean = false;
32
- private mobileMatchMedia!: MediaQueryList;
33
-
34
- private selectedFilterMenuData: Filters = {
35
- site: [],
36
- dates: [],
37
- authors: [],
38
- categories: []
39
- };
40
- private posts: any[] = [];
41
-
42
- get currentPageLength() {
43
- if (this.loading) {
44
- return "Loading Results...";
45
- }
46
-
47
- let currentFirstResultNumber = 0;
48
- const currentLastResultNumber = this.currentPage * this.posts.length;
49
-
50
- if (this.currentPage > 1) {
51
- currentFirstResultNumber =
52
- currentLastResultNumber - this.posts.length;
53
- } else if (this.currentPage === 1 && !this.isEmptyState) {
54
- currentFirstResultNumber = 1;
55
- }
56
-
57
- return `Showing ${currentFirstResultNumber} - ${currentLastResultNumber} of ${this.totalResults}`;
58
- }
59
-
60
- get showPagination() {
61
- return this.totalPages > 1;
62
- }
63
-
64
- get resultsHeading() {
65
- let pageInfo = "";
66
-
67
- if (this.currentPage !== 1) {
68
- pageInfo = `- Page ${this.currentPage}`;
69
- }
70
- return this.totalResults ? `Archive Results ${pageInfo}` : "No results";
71
- }
72
-
73
- get isEmptyState() {
74
- return this.totalResults === 0 && !this.loading;
75
- }
76
-
77
- get spinnerSize() {
78
- return this.isMobile ? "medium" : "large";
79
- }
80
-
81
- get isMinimalCard() {
82
- return this.cardType === "minimal";
83
- }
84
-
85
- get minimalCardClass() {
86
- return cx("min-card-btn", this.cardType === "minimal" && "btn-active");
87
- }
88
-
89
- get expandedCardClass() {
90
- return cx("exp-card-btn", this.cardType === "expanded" && "btn-active");
91
- }
92
-
93
- get postsByMonth() {
94
- const posts = this.splitPostsByMonth(this.posts);
95
-
96
- return Object.keys(posts).map((key) => [key, [...posts[key]]]);
97
- }
98
-
99
- get contentTypeList() {
100
- return this._contentTypeList;
101
- }
102
-
103
- get hideBlogFilters() {
104
- return (
105
- this.selectedFilterMenuData.site.length === 1 &&
106
- this.selectedFilterMenuData.site[0].id === 2
107
- );
108
- }
109
-
110
- get contentTypeTitle() {
111
- return `Content Type ${
112
- this.selectedFilterMenuData.site.length > 0
113
- ? `(${this.selectedFilterMenuData.site.length})`
114
- : ""
115
- }`;
116
- }
117
- get dateTitle() {
118
- return `Date ${
119
- this.selectedFilterMenuData.dates.length > 0
120
- ? `(${this.selectedFilterMenuData.dates.length})`
121
- : ""
122
- }`;
123
- }
124
- get authorTitle() {
125
- return `Blog Author ${
126
- this.selectedFilterMenuData.authors.length > 0
127
- ? `(${this.selectedFilterMenuData.authors.length})`
128
- : ""
129
- }`;
130
- }
131
- get categoryTitle() {
132
- return `Topic ${
133
- this.selectedFilterMenuData.categories.length > 0
134
- ? `(${this.selectedFilterMenuData.categories.length})`
135
- : ""
136
- }`;
137
- }
138
-
139
- private filterSelectedDates(
140
- currentDateList: Array<{ name: string }>,
141
- selectedDate: string,
142
- toRemove: boolean = false
143
- ) {
144
- return currentDateList.filter((currentDateItem: { name: string }) => {
145
- const year = currentDateItem.name.slice(-4);
146
-
147
- if (toRemove) {
148
- return selectedDate.slice(-4) !== currentDateItem.name;
149
- }
150
-
151
- return year !== selectedDate;
152
- });
153
- }
154
-
155
- private handleUpdateSiteFilter(e: CustomEvent) {
156
- const { value, name, checked } = e.detail;
157
-
158
- let selectedFilters: string[] | null = [];
159
- this._contentTypeList.forEach((option) => {
160
- if (option.name === value.name) {
161
- option.checked = checked;
162
- }
163
- if (option.checked) {
164
- selectedFilters?.push(option.name);
165
- }
166
- });
167
-
168
- if (selectedFilters?.length === 0) {
169
- selectedFilters = null;
170
- }
171
- QueryCoordinator.setUrlParamValue(QUERY_SITE_FILTER, selectedFilters);
172
-
173
- this.updateSelectedFilters(value, name, checked);
174
- }
175
-
176
- private handleFiltersEvent(e: CustomEvent) {
177
- const { value, name, checked } = e.detail;
178
- this.updateSelectedFilters(value, name, checked);
179
- }
180
-
181
- private updateSelectedFilters(
182
- value: any,
183
- name: keyof Filters,
184
- checked: any
185
- ) {
186
- let copy = {
187
- ...this.selectedFilterMenuData
188
- };
189
-
190
- if (!checked) {
191
- copy[name] = copy[name].filter(
192
- (selectedFilterItem: { name: string }) => {
193
- return selectedFilterItem.name !== value.name;
194
- }
195
- );
196
- } else if (!copy[name].includes(value)) {
197
- const regex = /^(\d{4})$/g;
198
-
199
- if (regex.test(value.name) && copy[name].length > 0) {
200
- copy[name] = this.filterSelectedDates(copy[name], value.name);
201
- } else if (regex.test(value.name.slice(-4))) {
202
- copy[name] = this.filterSelectedDates(
203
- copy[name],
204
- value.name,
205
- true
206
- );
207
- }
208
-
209
- copy[name].push(value);
210
- }
211
-
212
- // Remove filters when only podcast is selected
213
- if (
214
- name === "site" &&
215
- copy[name].length === 1 &&
216
- !copy[name].some((item: { id: number }) => item.id === 1)
217
- ) {
218
- copy = {
219
- site: [...copy.site],
220
- categories: [...copy.categories],
221
- dates: [...copy.dates],
222
- authors: []
223
- };
224
- }
225
-
226
- // Checkmark the blog type if value is a blog author
227
- if (name === "authors" && checked) {
228
- copy = {
229
- site: [{ id: 1, name: "Blogs" }],
230
- categories: [...copy.categories],
231
- dates: [...copy.dates],
232
- authors: [...copy.authors]
233
- };
234
- }
235
-
236
- this.selectedFilterMenuData = copy;
237
- this.currentPage = 1;
238
- this.updateCheckedStatus();
239
- this.fetchPostsByCardType();
240
- }
241
-
242
- private updateCheckedStatus() {
243
- const filterMenuElements =
244
- this.template.querySelectorAll("dx-filter-menu");
245
-
246
- filterMenuElements.forEach((filterMenuElement: any) =>
247
- filterMenuElement.updateCheckedStatus(this.selectedFilterMenuData)
248
- );
249
- }
250
-
251
- private removeFilterItem(e: any) {
252
- const { name, value } = e.target;
253
-
254
- this.handleUpdateSiteFilter(
255
- new CustomEvent("updateselectedfilters", {
256
- detail: {
257
- name,
258
- value,
259
- checked: false
260
- }
261
- })
262
- );
263
- }
264
-
265
- private toggleModal() {
266
- this.modalOpen = !this.modalOpen;
267
- }
268
-
269
- // split posts by month for the minimal view date header
270
- private splitPostsByMonth(posts: any[]) {
271
- const postsByMonth: { [key: string]: Array<{}> } = {};
272
-
273
- posts.forEach((post) => {
274
- const date = new Date(post.date);
275
- const month = new Intl.DateTimeFormat("en-US", {
276
- month: "long"
277
- }).format(date);
278
- const year = date.getFullYear();
279
-
280
- if (!postsByMonth[`${month} ${year}`]) {
281
- postsByMonth[`${month} ${year}`] = [];
282
- }
283
-
284
- postsByMonth[`${month} ${year}`].push({ ...post });
285
- });
286
-
287
- return sortSplittedPostsByMonth(postsByMonth);
288
- }
289
-
290
- private handleCardTypeChange(e: any) {
291
- const selectedCardType = e.target.value;
292
- if (this.cardType !== selectedCardType) {
293
- this.cardType = selectedCardType;
294
-
295
- this.fetchPostsByCardType();
296
- }
297
- }
298
-
299
- private handleFilterClear() {
300
- this.selectedFilterMenuData = {
301
- site: [],
302
- dates: [],
303
- authors: [],
304
- categories: []
305
- };
306
-
307
- this.updateCheckedStatus();
308
- this.fetchPostsByCardType();
309
- QueryCoordinator.setUrlParamValue(QUERY_SITE_FILTER, null);
310
- }
311
-
312
- private goToPage(e: CustomEvent) {
313
- const page = e.detail;
314
- this.currentPage = page;
315
- this.totalResults = 0;
316
- this.totalPages = 0;
317
-
318
- this.fetchPostsByCardType();
319
- }
320
-
321
- private fetchPostsByCardType() {
322
- if (this.cardType === "minimal") {
323
- this.fetchPosts(20);
324
- } else {
325
- this.fetchPosts(10);
326
- }
327
- }
328
-
329
- private async fetchArchiveFilterList() {
330
- this.filtersLoading = true;
331
-
332
- if (this.dateList.length === 0) {
333
- const filterListdata = await getArchiveFilterList();
334
- this.dateList = this.splitOptionsByDate(filterListdata.dates);
335
-
336
- this.authorList = filterListdata.authors;
337
- this.categoryList = filterListdata.categories;
338
- }
339
-
340
- this.filtersLoading = false;
341
- }
342
-
343
- private async fetchPosts(numberOfPosts: number) {
344
- this.loading = true;
345
-
346
- const postData = await getArchivePosts(
347
- numberOfPosts,
348
- this.currentPage,
349
- this.cardType,
350
- this.selectedFilterMenuData
351
- );
352
-
353
- // get the list of filters for the filter menu
354
- this.fetchArchiveFilterList();
355
-
356
- this.posts = postData.posts;
357
- this.totalResults = postData.totalResults;
358
- this.totalPages = postData.totalPages;
359
- this.loading = false;
360
- }
361
-
362
- private paddedMonth(date: Date) {
363
- return `${(date.getMonth() + 1).toString().padStart(2, "0")}`;
364
- }
365
-
366
- // split filter options by year/month for nested checkboxes
367
- private splitOptionsByDate(dateOptions: any) {
368
- return dateOptions.reduce((acc: any, curr: any) => {
369
- const date = new Date(curr.replace(/-/g, "/"));
370
- const month = new Intl.DateTimeFormat("en-US", {
371
- month: "long"
372
- }).format(date);
373
- const year = String(date.getFullYear());
374
-
375
- const foundYear = acc.find((post: any) => post.name === year);
376
- const foundMonth = foundYear?.months.find(
377
- (m: any) => m.id === month
378
- );
379
-
380
- if (!foundYear) {
381
- acc.push({
382
- id: year,
383
- name: year,
384
- isYear: true,
385
- months: [
386
- {
387
- id: month,
388
- name: `${month} ${year}`,
389
- shortName: `${year},${date.getMonth() + 1}`,
390
- isYear: false,
391
- numberOfPosts: 1
392
- }
393
- ],
394
- totalNumberOfPosts: 1
395
- });
396
-
397
- return acc;
398
- }
399
-
400
- if (!foundMonth) {
401
- foundYear.months.push({
402
- id: month,
403
- name: `${month} ${year}`,
404
- shortName: `${year},${date.getMonth() + 1}`,
405
- isYear: false,
406
- numberOfPosts: 1
407
- });
408
- foundYear.totalNumberOfPosts += 1;
409
-
410
- return acc;
411
- }
412
-
413
- foundMonth.numberOfPosts += 1;
414
- foundYear.totalNumberOfPosts += 1;
415
-
416
- return acc;
417
- }, []);
418
- }
419
-
420
- private onMobileChange = (e: MediaQueryListEvent | MediaQueryList) => {
421
- this.isMobile = e.matches;
422
-
423
- requestAnimationFrame(() => this.updateCheckedStatus());
424
- };
425
-
426
- connectedCallback(): void {
427
- this.mobileMatchMedia = window.matchMedia(
428
- `(max-width: ${MOBILE_MATCH})`
429
- );
430
- this.onMobileChange(this.mobileMatchMedia);
431
- this.mobileMatchMedia.addEventListener("change", this.onMobileChange);
432
-
433
- const presetFilters: string[] =
434
- QueryCoordinator.getUrlParamValue(QUERY_SITE_FILTER);
435
- if (
436
- presetFilters?.some((filterString) => filterString === BLOGS.name)
437
- ) {
438
- this.presetSiteFilter(BLOGS);
439
- }
440
- if (
441
- presetFilters?.some(
442
- (filterString) => filterString === PODCASTS.name
443
- )
444
- ) {
445
- this.presetSiteFilter(PODCASTS);
446
- }
447
-
448
- if (this.posts.length === 0) {
449
- this.fetchPostsByCardType();
450
- }
451
- }
452
-
453
- presetSiteFilter(filter: any) {
454
- this._contentTypeList.forEach((option) => {
455
- if (option.name === filter.name) {
456
- option.checked = true;
457
- }
458
- });
459
- this.updateSelectedFilters(filter, "site", true);
460
- }
461
- }
@@ -1,6 +0,0 @@
1
- export interface Filters {
2
- site: any[];
3
- dates: any[];
4
- authors: any[];
5
- categories: any[];
6
- }
@@ -1 +0,0 @@
1
- <template></template>
@@ -1,116 +0,0 @@
1
- import { LightningElement, api } from "lwc";
2
-
3
- const TRACKING_EVENT_NAME = "developerwebsite_track";
4
- const LISTENER_QUEUE = "__DX_INSTRUMENTATION_QUEUE__";
5
- const LISTENER_INDICATOR = "__DX_INSTRUMENTATION_IS_INITIALIZED__";
6
-
7
- export function track(
8
- element: EventTarget,
9
- event: string,
10
- payload: Record<string, unknown>
11
- ): void {
12
- const detail = { event, payload };
13
- // if window.LISTENER_INDICATOR is undefined, `dx-instrumentation` has not
14
- // been mounted, and the listener hasn't been attached.
15
- if ((window as any)[LISTENER_INDICATOR] === undefined) {
16
- (window as any)[LISTENER_QUEUE] = (window as any)[LISTENER_QUEUE] || [];
17
- (window as any)[LISTENER_QUEUE].push(detail);
18
- } else {
19
- const e = new CustomEvent(TRACKING_EVENT_NAME, {
20
- bubbles: true,
21
- composed: true,
22
- detail
23
- });
24
- element.dispatchEvent(e);
25
- }
26
- }
27
-
28
- const googleTagManager = {
29
- track: function (e: Event) {
30
- if ((window as any).dataLayer === undefined) {
31
- (window as any).dataLayer = [];
32
- }
33
- const { event, payload } = (e as CustomEvent).detail;
34
- (window as any).dataLayer.push({ ...payload, event });
35
- }
36
- };
37
-
38
- interface TrackEventListener {
39
- add: () => void;
40
- remove: () => void;
41
- }
42
-
43
- export function developerwebTrackEventListener(
44
- trackerFns: { track: (e: Event) => void }[] = []
45
- ): TrackEventListener {
46
- if (trackerFns.length === 0) {
47
- throw new Error("No tracker functions passed");
48
- }
49
-
50
- const trackdeveloperwebEvent = (e: Event) => {
51
- trackerFns.forEach((tracker) => {
52
- tracker.track(e);
53
- });
54
- };
55
-
56
- const attachEventListener = () => {
57
- document.addEventListener(TRACKING_EVENT_NAME, trackdeveloperwebEvent);
58
- };
59
-
60
- const removeEventListener = () => {
61
- document.removeEventListener(
62
- TRACKING_EVENT_NAME,
63
- trackdeveloperwebEvent
64
- );
65
- };
66
-
67
- return {
68
- add: attachEventListener,
69
- remove: removeEventListener
70
- };
71
- }
72
-
73
- export default class Instrumentation extends LightningElement {
74
- @api useGoogleTagManager = false;
75
-
76
- private tracker: TrackEventListener | null = null;
77
-
78
- private setupTracker() {
79
- const trackerFunctions = this.useGoogleTagManager
80
- ? [googleTagManager]
81
- : [];
82
- this.tracker = developerwebTrackEventListener(trackerFunctions);
83
- this.tracker.add();
84
- (window as any)[LISTENER_INDICATOR] = true;
85
- }
86
-
87
- private dispatchQueuedEvents() {
88
- while ((window as any)[LISTENER_QUEUE].length > 0) {
89
- const event = (window as any)[LISTENER_QUEUE].pop() as {
90
- event: string;
91
- payload: Record<string, unknown>;
92
- };
93
- track(this, event.event, event.payload);
94
- }
95
- }
96
-
97
- renderedCallback() {
98
- if (this.tracker === null) {
99
- this.setupTracker();
100
-
101
- if (
102
- (window as any)[LISTENER_QUEUE] !== undefined &&
103
- (window as any)[LISTENER_QUEUE].length > 0
104
- ) {
105
- this.dispatchQueuedEvents();
106
- }
107
- }
108
- }
109
-
110
- disconnectedCallback() {
111
- if (this.tracker !== null) {
112
- this.tracker.remove();
113
- this.tracker = null;
114
- }
115
- }
116
- }
@@ -1,73 +0,0 @@
1
- @import "helpers/text";
2
- @import "helpers/button";
3
-
4
- :host {
5
- --dx-g-text-base: 20px;
6
- --dx-c-checkbox-text-line-height: 20px;
7
- --dx-c-checkbox-align-label: flex-start;
8
- --dx-c-checkbox-font-size: 14px;
9
- --dx-c-checkbox-text-transform: none;
10
- }
11
-
12
- h4 {
13
- font-size: 20px;
14
- margin: 0 0 28px 0;
15
- text-align: center;
16
- }
17
-
18
- dx-input,
19
- dx-select {
20
- display: block;
21
- margin-top: 12px;
22
- height: 77px;
23
- }
24
-
25
- dx-input {
26
- --dx-c-input-width: 100%;
27
- }
28
-
29
- dx-checkbox:not(:first-child) {
30
- margin-top: 12px;
31
- }
32
-
33
- dx-checkbox:last-of-type {
34
- margin-bottom: 16px;
35
- }
36
-
37
- .form-submit {
38
- background-color: var(--dx-g-blue-vibrant-50);
39
- border: 2px solid var(--dx-g-blue-vibrant-50);
40
- border-radius: 4px;
41
- font-family: var(--dx-g-font-display);
42
- font-size: 14px;
43
- color: white;
44
- height: 44px;
45
- width: 100%;
46
- margin-top: 20px;
47
- }
48
-
49
- .form-submit:hover {
50
- background-color: var(--dx-g-blue-vibrant-40);
51
- border-color: var(--dx-g-blue-vibrant-40);
52
- cursor: pointer;
53
- }
54
-
55
- .legal-text {
56
- font-size: 14px;
57
- margin: 0 0 16px 0;
58
- }
59
-
60
- @media screen and (max-width: 360px) {
61
- :host {
62
- --dx-g-text-base: 16px;
63
- --dx-c-checkbox-display: inline-block;
64
- }
65
-
66
- h4 {
67
- font-size: 16px;
68
- }
69
-
70
- .form-submit {
71
- margin-top: 0;
72
- }
73
- }