@salesforcedevs/dx-components 1.38.0 → 1.39.0-alpha1
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 +47 -47
- package/src/modules/dx/footer/footer.ts +3 -1
- package/src/modules/dx/icon/icon.ts +4 -1
- package/src/modules/dx/instrumentation/instrumentation.ts +86 -40
- package/src/modules/dx/searchResults/resultsTemplate.js +5 -2
- package/src/modules/dx/searchResults/searchResults.ts +2 -0
- package/src/modules/dx/sidebarSearch/sidebarSearch.ts +4 -1
- package/LICENSE +0 -12
package/package.json
CHANGED
|
@@ -1,48 +1,48 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
2
|
+
"name": "@salesforcedevs/dx-components",
|
|
3
|
+
"version": "1.39.0-alpha1",
|
|
4
|
+
"description": "DX Lightning web components",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": "22.x"
|
|
8
|
+
},
|
|
9
|
+
"publishConfig": {
|
|
10
|
+
"access": "public"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@coveo/headless": "3.22.2",
|
|
14
|
+
"@floating-ui/dom": "1.5.1",
|
|
15
|
+
"@optimizely/optimizely-sdk": "5.3.0",
|
|
16
|
+
"@shikijs/colorized-brackets": "^3.12.2",
|
|
17
|
+
"@types/throttle-debounce": "5.0.2",
|
|
18
|
+
"@vimeo/player": "2.22.0",
|
|
19
|
+
"classnames": "2.5.1",
|
|
20
|
+
"composed-offset-position": "0.0.4",
|
|
21
|
+
"coveo-search-ui": "2.10113.0",
|
|
22
|
+
"debounce": "1.2.1",
|
|
23
|
+
"js-cookie": "3.0.5",
|
|
24
|
+
"lodash.defaults": "4.2.0",
|
|
25
|
+
"lodash.get": "4.4.2",
|
|
26
|
+
"lodash.kebabcase": "4.1.1",
|
|
27
|
+
"memoize-one": "6.0.0",
|
|
28
|
+
"microtip": "0.2.2",
|
|
29
|
+
"shiki": "^3.12.2",
|
|
30
|
+
"throttle-debounce": "5.0.0",
|
|
31
|
+
"uuid": "9.0.1"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/classnames": "2.3.1",
|
|
35
|
+
"@types/debounce": "1.2.4",
|
|
36
|
+
"@types/js-cookie": "3.0.6",
|
|
37
|
+
"@types/lodash.defaults": "4.2.9",
|
|
38
|
+
"@types/lodash.get": "4.4.9",
|
|
39
|
+
"@types/lodash.kebabcase": "4.1.9",
|
|
40
|
+
"@types/luxon": "3.4.2",
|
|
41
|
+
"@types/uuid": "8.3.4",
|
|
42
|
+
"@types/vimeo__player": "2.18.3",
|
|
43
|
+
"eventsourcemock": "2.0.0",
|
|
44
|
+
"luxon": "3.4.4",
|
|
45
|
+
"msw": "^2.12.4"
|
|
46
|
+
},
|
|
47
|
+
"stableVersion": "1.39.0"
|
|
48
|
+
}
|
|
@@ -103,7 +103,9 @@ class Footer extends LightningElement {
|
|
|
103
103
|
// This encapsulates the old non-MFE footer functionality that should be removed once the footer MFE supports rendering in non-full-width contexts.
|
|
104
104
|
// It's encapsulated like this solely for ease of deletion later.
|
|
105
105
|
function augmentWithNonMFEFooterFunctionality(FooterClass: typeof Footer) {
|
|
106
|
-
|
|
106
|
+
// Prefix with the deploy asset base path (e.g. "/PR-123"); empty in local dev.
|
|
107
|
+
const assetBasePath = (globalThis as any)?.LWR?.env?.assetBasePath || "";
|
|
108
|
+
const baseSocialIconUrl = `${assetBasePath}/assets/icons/brand-sprite/svg/symbols.svg`;
|
|
107
109
|
|
|
108
110
|
return class NonMFEFooter extends FooterClass {
|
|
109
111
|
private didRequestFooterConfig = false;
|
|
@@ -40,7 +40,10 @@ export default class Icon extends LightningElement {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
private get assetUrl() {
|
|
43
|
-
|
|
43
|
+
// Prefix with the deploy asset base path (e.g. "/PR-123") so icons resolve
|
|
44
|
+
// when the site is served under a sub-path. Empty in local dev, so no-op there.
|
|
45
|
+
const assetBasePath = (globalThis as any)?.LWR?.env?.assetBasePath || "";
|
|
46
|
+
return `${assetBasePath}/assets/icons/${this.sprite}-sprite/svg/symbols.svg`;
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
private get href() {
|
|
@@ -38,6 +38,47 @@ function archTrack(
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
interface NamespaceConfig {
|
|
42
|
+
eventName: string;
|
|
43
|
+
queue: string;
|
|
44
|
+
indicator: string;
|
|
45
|
+
replay: (
|
|
46
|
+
element: EventTarget,
|
|
47
|
+
event: string,
|
|
48
|
+
payload: Record<string, unknown>
|
|
49
|
+
) => void;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// The two tracking-event namespaces dx-instrumentation can bridge. Keyed by the
|
|
53
|
+
// values accepted by the `namespaces` attribute.
|
|
54
|
+
const NAMESPACE_CONFIGS: Record<"developer" | "architect", NamespaceConfig> = {
|
|
55
|
+
developer: {
|
|
56
|
+
eventName: DX_TRACKING_EVENT_NAME,
|
|
57
|
+
queue: DX_LISTENER_QUEUE,
|
|
58
|
+
indicator: DX_LISTENER_INDICATOR,
|
|
59
|
+
replay: dxTrack
|
|
60
|
+
},
|
|
61
|
+
architect: {
|
|
62
|
+
eventName: ARCH_TRACKING_EVENT_NAME,
|
|
63
|
+
queue: ARCH_LISTENER_QUEUE,
|
|
64
|
+
indicator: ARCH_LISTENER_INDICATOR,
|
|
65
|
+
replay: archTrack
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// Maps the `namespaces` attribute to the configs it activates.
|
|
70
|
+
function resolveNamespaceConfigs(namespaces: string): NamespaceConfig[] {
|
|
71
|
+
switch (namespaces) {
|
|
72
|
+
case "developer":
|
|
73
|
+
return [NAMESPACE_CONFIGS.developer];
|
|
74
|
+
case "architect":
|
|
75
|
+
return [NAMESPACE_CONFIGS.architect];
|
|
76
|
+
case "both":
|
|
77
|
+
default:
|
|
78
|
+
return [NAMESPACE_CONFIGS.developer, NAMESPACE_CONFIGS.architect];
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
41
82
|
const googleTagManager = {
|
|
42
83
|
track: function (e: Event) {
|
|
43
84
|
if ((window as any).dataLayer === undefined) {
|
|
@@ -54,13 +95,14 @@ interface TrackEventListener {
|
|
|
54
95
|
}
|
|
55
96
|
|
|
56
97
|
/**
|
|
57
|
-
* Attaches a listener for
|
|
58
|
-
*
|
|
59
|
-
* event to every tracker function. A single component can therefore
|
|
60
|
-
* event namespaces into the dataLayer.
|
|
98
|
+
* Attaches a listener for each of the given tracking event names (e.g.
|
|
99
|
+
* `developerwebsite_track` and/or `architectssite_track`), forwarding every
|
|
100
|
+
* caught event to every tracker function. A single component can therefore
|
|
101
|
+
* bridge one or both event namespaces into the dataLayer.
|
|
61
102
|
*/
|
|
62
103
|
export function instrumentationTrackEventListener(
|
|
63
|
-
trackerFns: { track: (e: Event) => void }[] = []
|
|
104
|
+
trackerFns: { track: (e: Event) => void }[] = [],
|
|
105
|
+
eventNames: string[] = [DX_TRACKING_EVENT_NAME, ARCH_TRACKING_EVENT_NAME]
|
|
64
106
|
): TrackEventListener {
|
|
65
107
|
if (trackerFns.length === 0) {
|
|
66
108
|
throw new Error("No tracker functions passed");
|
|
@@ -73,16 +115,15 @@ export function instrumentationTrackEventListener(
|
|
|
73
115
|
};
|
|
74
116
|
|
|
75
117
|
const attachEventListener = () => {
|
|
76
|
-
|
|
77
|
-
|
|
118
|
+
eventNames.forEach((eventName) => {
|
|
119
|
+
document.addEventListener(eventName, handleTrackEvent);
|
|
120
|
+
});
|
|
78
121
|
};
|
|
79
122
|
|
|
80
123
|
const removeEventListener = () => {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
handleTrackEvent
|
|
85
|
-
);
|
|
124
|
+
eventNames.forEach((eventName) => {
|
|
125
|
+
document.removeEventListener(eventName, handleTrackEvent);
|
|
126
|
+
});
|
|
86
127
|
};
|
|
87
128
|
|
|
88
129
|
return {
|
|
@@ -93,49 +134,54 @@ export function instrumentationTrackEventListener(
|
|
|
93
134
|
|
|
94
135
|
/**
|
|
95
136
|
* Unified instrumentation bridge. Mount a single <dx-instrumentation> to forward
|
|
96
|
-
*
|
|
97
|
-
* dataLayer
|
|
98
|
-
*
|
|
137
|
+
* developer-website and/or architect-website tracking events into the GTM
|
|
138
|
+
* dataLayer. Renders nothing.
|
|
139
|
+
*
|
|
140
|
+
* By default (`namespaces="both"`) it bridges both the developer
|
|
141
|
+
* (`developerwebsite_track`) and architect (`architectssite_track`) namespaces,
|
|
142
|
+
* replacing the need to mount <dw-instrumentation> and <arch-instrumentation>
|
|
143
|
+
* separately. Set `namespaces="developer"` (or `"architect"`) to bridge only one
|
|
144
|
+
* — e.g. on a site whose header analytics already reach the dataLayer through
|
|
145
|
+
* another path, so draining the architect queue here would double-count.
|
|
99
146
|
*/
|
|
100
147
|
export default class Instrumentation extends LightningElement {
|
|
101
148
|
@api useGoogleTagManager = false;
|
|
102
149
|
|
|
150
|
+
// "both" (default) | "developer" | "architect"
|
|
151
|
+
@api namespaces = "both";
|
|
152
|
+
|
|
103
153
|
private tracker: TrackEventListener | null = null;
|
|
104
154
|
|
|
105
155
|
private setupTracker() {
|
|
156
|
+
const configs = resolveNamespaceConfigs(this.namespaces);
|
|
106
157
|
const trackerFunctions = this.useGoogleTagManager
|
|
107
158
|
? [googleTagManager]
|
|
108
159
|
: [];
|
|
109
|
-
this.tracker = instrumentationTrackEventListener(
|
|
160
|
+
this.tracker = instrumentationTrackEventListener(
|
|
161
|
+
trackerFunctions,
|
|
162
|
+
configs.map((c) => c.eventName)
|
|
163
|
+
);
|
|
110
164
|
this.tracker.add();
|
|
111
|
-
// Mark
|
|
112
|
-
//
|
|
113
|
-
(
|
|
114
|
-
|
|
165
|
+
// Mark each active namespace initialized so track() calls from that
|
|
166
|
+
// stack dispatch live events instead of queueing.
|
|
167
|
+
configs.forEach((c) => {
|
|
168
|
+
(window as any)[c.indicator] = true;
|
|
169
|
+
});
|
|
115
170
|
}
|
|
116
171
|
|
|
117
172
|
private dispatchQueuedEvents() {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
event
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
173
|
+
resolveNamespaceConfigs(this.namespaces).forEach((config) => {
|
|
174
|
+
const queue = (window as any)[config.queue];
|
|
175
|
+
if (Array.isArray(queue)) {
|
|
176
|
+
while (queue.length > 0) {
|
|
177
|
+
const event = queue.pop() as {
|
|
178
|
+
event: string;
|
|
179
|
+
payload: Record<string, unknown>;
|
|
180
|
+
};
|
|
181
|
+
config.replay(this, event.event, event.payload);
|
|
182
|
+
}
|
|
126
183
|
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const archQueue = (window as any)[ARCH_LISTENER_QUEUE];
|
|
130
|
-
if (Array.isArray(archQueue)) {
|
|
131
|
-
while (archQueue.length > 0) {
|
|
132
|
-
const event = archQueue.pop() as {
|
|
133
|
-
event: string;
|
|
134
|
-
payload: Record<string, unknown>;
|
|
135
|
-
};
|
|
136
|
-
archTrack(this, event.event, event.payload);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
184
|
+
});
|
|
139
185
|
}
|
|
140
186
|
|
|
141
187
|
renderedCallback() {
|
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
const html = String.raw;
|
|
7
7
|
|
|
8
|
+
// Prefix hardcoded asset URLs with the deploy asset base path (e.g. "/PR-123"); empty in local dev.
|
|
9
|
+
const assetBasePath = (globalThis && globalThis.LWR && globalThis.LWR.env && globalThis.LWR.env.assetBasePath) || "";
|
|
10
|
+
|
|
8
11
|
export default html`
|
|
9
12
|
<div class="coveo-show-if-no-results">
|
|
10
13
|
<div class="no-results">
|
|
@@ -70,7 +73,7 @@ export default html`
|
|
|
70
73
|
>
|
|
71
74
|
<%- title %>
|
|
72
75
|
<% if (!raw.uri.includes('developer.salesforce.com') && !raw.uri.includes('developer-website-s.herokuapp.com')) { %>
|
|
73
|
-
<svg xmlns="http://www.w3.org/2000/svg" style="display: inline; vertical-align: baseline;" fill="var(--dx-g-blue-vibrant-20)" width="20" height="20" part="svg" aria-hidden="true"><use xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#new_window"></use></svg>
|
|
76
|
+
<svg xmlns="http://www.w3.org/2000/svg" style="display: inline; vertical-align: baseline;" fill="var(--dx-g-blue-vibrant-20)" width="20" height="20" part="svg" aria-hidden="true"><use xlink:href="${assetBasePath}/assets/icons/utility-sprite/svg/symbols.svg#new_window"></use></svg>
|
|
74
77
|
<% } %>
|
|
75
78
|
</a>
|
|
76
79
|
<span class="CoveoFieldValue" data-field="@sflastmodifieddate" data-helper="postedDate" data-html-value="true"></span>
|
|
@@ -121,7 +124,7 @@ export default html`
|
|
|
121
124
|
<%- uri %>
|
|
122
125
|
<% } %>
|
|
123
126
|
<% if (!raw.uri.includes('developer.salesforce.com') && !raw.uri.includes('developer-website-s.herokuapp.com')) { %>
|
|
124
|
-
<svg xmlns="http://www.w3.org/2000/svg" style="display: inline; vertical-align: baseline;" fill="var(--dx-g-blue-vibrant-20)" width="20" height="20" part="svg" aria-hidden="true"><use xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#new_window"></use></svg>
|
|
127
|
+
<svg xmlns="http://www.w3.org/2000/svg" style="display: inline; vertical-align: baseline;" fill="var(--dx-g-blue-vibrant-20)" width="20" height="20" part="svg" aria-hidden="true"><use xlink:href="${assetBasePath}/assets/icons/utility-sprite/svg/symbols.svg#new_window"></use></svg>
|
|
125
128
|
<% } %>
|
|
126
129
|
</a>
|
|
127
130
|
<span class="CoveoFieldValue" data-field="@sflastmodifieddate" data-helper="postedDate" data-html-value="true"></span>
|
|
@@ -54,6 +54,8 @@ const buildTemplateHelperBadge = (value: keyof typeof CONTENT_TYPE_LABELS) => {
|
|
|
54
54
|
const style = getContentTypeColorVariables(value);
|
|
55
55
|
const label = CONTENT_TYPE_LABELS[value];
|
|
56
56
|
const { iconSprite, iconSymbol } = CONTENT_TYPE_ICONS[value];
|
|
57
|
+
// Prefix with the deploy asset base path (e.g. "/PR-123"); empty in local dev.
|
|
58
|
+
const assetBasePath = (globalThis as any)?.LWR?.env?.assetBasePath || "";
|
|
57
59
|
return `
|
|
58
60
|
<div style="${style}" class="dx-badge">
|
|
59
61
|
<svg
|
|
@@ -317,9 +317,12 @@ export default class SidebarSearch extends LightningElement {
|
|
|
317
317
|
|
|
318
318
|
// discussion about this normalization here: https://salesforce-internal.slack.com/archives/C020S6784JX/p1639506238376600
|
|
319
319
|
|
|
320
|
+
// Deploy base path (e.g. "/PR-123"); empty in local dev. window.location.pathname
|
|
321
|
+
// is served under this prefix, so route hrefs and comparisons must include it.
|
|
322
|
+
const basePath = (globalThis as any)?.LWR?.env?.basePath || "";
|
|
320
323
|
let pathname, queryParam;
|
|
321
324
|
if (sfhtml_url__c) {
|
|
322
|
-
pathname =
|
|
325
|
+
pathname = `${basePath}/docs/${sfhtml_url__c}`;
|
|
323
326
|
} else {
|
|
324
327
|
const isNestedGuide = clickUri.includes("/guide/");
|
|
325
328
|
const url = new URL(clickUri);
|
package/LICENSE
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
Copyright (c) 2020, Salesforce.com, Inc.
|
|
2
|
-
All rights reserved.
|
|
3
|
-
|
|
4
|
-
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
5
|
-
|
|
6
|
-
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
7
|
-
|
|
8
|
-
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
9
|
-
|
|
10
|
-
* Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
11
|
-
|
|
12
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|