@salesforcedevs/arch-components 1.20.17-alpha9 → 1.25.1-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.
- package/lwc.config.json +42 -3
- package/package.json +34 -45
- package/src/assets/css/arch-variables.css +512 -0
- package/src/modules/arch/badge/badge.css +22 -0
- package/src/modules/arch/badge/badge.html +5 -0
- package/src/modules/arch/badge/badge.ts +9 -0
- package/src/modules/arch/button/button.css +1 -0
- package/src/modules/arch/button/button.html +20 -0
- package/src/modules/arch/button/button.ts +67 -0
- package/src/modules/arch/buttonLink/buttonLink.css +1 -0
- package/src/modules/arch/buttonLink/buttonLink.html +19 -0
- package/src/modules/arch/buttonLink/buttonLink.stories.js +34 -0
- package/src/modules/arch/buttonLink/buttonLink.ts +8 -0
- package/src/modules/arch/buttonStyles/buttonStyles.css +220 -0
- package/src/modules/arch/card/card.css +128 -0
- package/src/modules/arch/card/card.html +85 -0
- package/src/modules/arch/card/card.ts +277 -0
- package/src/modules/arch/cardBase/cardBase.css +11 -0
- package/src/modules/arch/cardBase/cardBase.html +2 -0
- package/src/modules/arch/cardGridA/cardGridA.css +11 -0
- package/src/modules/arch/cardGridA/cardGridA.html +21 -0
- package/src/modules/arch/cardGridA/cardGridA.stories.js +118 -0
- package/src/modules/arch/cardGridA/cardGridA.ts +24 -0
- package/src/modules/arch/cardGridC/cardGridC.css +24 -0
- package/src/modules/arch/cardGridC/cardGridC.html +22 -0
- package/src/modules/arch/cardGridC/cardGridC.stories.js +51 -0
- package/src/modules/arch/cardGridC/cardGridC.ts +11 -0
- package/src/modules/arch/cardGridD/cardGridD.css +17 -0
- package/src/modules/arch/cardGridD/cardGridD.html +20 -0
- package/src/modules/arch/cardGridD/cardGridD.stories.js +43 -0
- package/src/modules/arch/cardGridD/cardGridD.ts +7 -0
- package/src/modules/arch/cardNew/cardNew.css +31 -0
- package/src/modules/arch/cardNew/cardNew.html +32 -0
- package/src/modules/arch/cardNew/cardNew.ts +66 -0
- package/src/modules/arch/children/children.html +2 -0
- package/src/modules/arch/children/children.ts +31 -0
- package/src/modules/arch/color/color.ts +59 -0
- package/src/modules/arch/content/__fixtures__/index.ts +884 -0
- package/src/modules/arch/content/content.css +643 -0
- package/src/modules/arch/content/content.html +65 -0
- package/src/modules/arch/content/content.stories.js +21 -0
- package/src/modules/arch/content/content.ts +169 -0
- package/src/modules/arch/contentIcon/contentIcon.css +48 -0
- package/src/modules/arch/contentIcon/contentIcon.html +15 -0
- package/src/modules/arch/contentIcon/contentIcon.stories.js +130 -0
- package/src/modules/arch/contentIcon/contentIcon.ts +68 -0
- package/src/{common → modules/arch}/context/context.ts +21 -19
- package/src/modules/arch/contextAdapter/constants.ts +1 -0
- package/src/modules/arch/contextAdapter/contextAdapter.ts +54 -0
- package/src/modules/arch/debounce/debounce.ts +32 -0
- package/src/modules/arch/dialog/dialog.ts +154 -0
- package/src/modules/arch/dialogStyles/dialogStyles.css +90 -0
- package/src/modules/arch/effectAdapter/effectAdapter.html +1 -0
- package/src/modules/arch/effectAdapter/effectAdapter.ts +28 -0
- package/src/modules/arch/explorer/explorer.css +301 -0
- package/src/modules/arch/explorer/explorer.html +418 -0
- package/src/modules/arch/explorer/explorer.ts +718 -0
- package/src/modules/arch/explorer/types.d.ts +60 -0
- package/src/modules/arch/fetch/fetch.ts +55 -0
- package/src/modules/arch/footerMfe/footerMfe.html +3 -0
- package/src/modules/arch/footerMfe/footerMfe.ts +19 -0
- package/src/modules/arch/gallery/gallery.css +365 -0
- package/src/modules/arch/gallery/gallery.html +71 -0
- package/src/modules/arch/gallery/gallery.ts +366 -0
- package/src/modules/arch/gallery/types.d.ts +35 -0
- package/src/modules/arch/heading/heading.css +1 -0
- package/src/modules/arch/heading/heading.html +9 -0
- package/src/modules/arch/heading/heading.ts +36 -0
- package/src/modules/arch/helpers/helpers.ts +141 -0
- package/src/modules/arch/heroA/heroA.css +116 -0
- package/src/modules/arch/heroA/heroA.html +28 -0
- package/src/modules/arch/heroA/heroA.stories.js +60 -0
- package/src/modules/arch/heroA/heroA.ts +53 -0
- package/src/modules/arch/heroB/heroB.css +79 -0
- package/src/modules/arch/heroB/heroB.html +27 -0
- package/src/modules/arch/heroB/heroB.stories.js +55 -0
- package/src/modules/arch/heroB/heroB.ts +26 -0
- package/src/modules/arch/i18n/i18n.ts +78 -0
- package/src/modules/arch/icon/icon.css +28 -0
- package/src/modules/arch/icon/icon.html +17 -0
- package/src/modules/arch/icon/icon.stories.js +26 -0
- package/src/modules/arch/icon/icon.ts +92 -0
- package/src/modules/arch/instrumentation/instrumentation.css +1 -0
- package/src/modules/arch/instrumentation/instrumentation.html +1 -0
- package/src/modules/arch/instrumentation/instrumentation.ts +113 -0
- package/src/modules/arch/labels/helpers.ts +25 -0
- package/src/modules/arch/labels/pointHelpers.ts +47 -0
- package/src/modules/arch/labels/timeHelpers.ts +182 -0
- package/src/modules/arch/labels/types.d.ts +5 -0
- package/src/modules/arch/logger/logger.ts +33 -0
- package/src/modules/arch/menu/menu.ts +260 -0
- package/src/modules/arch/overflow/overflow.ts +71 -0
- package/src/modules/arch/page/page.css +3 -0
- package/src/modules/arch/page/page.html +3 -0
- package/src/modules/arch/page/page.stories.js +19 -0
- package/src/modules/arch/page/page.ts +3 -0
- package/src/modules/arch/pageHeaderA/pageHeaderA.css +82 -0
- package/src/modules/arch/pageHeaderA/pageHeaderA.html +24 -0
- package/src/modules/arch/pageHeaderA/pageHeaderA.stories.js +25 -0
- package/src/modules/arch/pageHeaderA/pageHeaderA.ts +51 -0
- package/src/modules/arch/pill/pill.css +70 -0
- package/src/modules/arch/pill/pill.html +17 -0
- package/src/modules/arch/pill/pill.ts +34 -0
- package/src/modules/arch/polling-request.ts +97 -0
- package/src/modules/arch/reflectedElement/reflectedElement.html +2 -0
- package/src/{common → modules/arch}/reflectedElement/reflectedElement.ts +5 -3
- package/src/modules/arch/reset/reset.css +39 -0
- package/src/modules/arch/searchList/searchList.css +120 -0
- package/src/modules/arch/searchList/searchList.html +42 -0
- package/src/modules/arch/searchList/searchList.ts +53 -0
- package/src/modules/arch/sectionA/sectionA.css +64 -0
- package/src/modules/arch/sectionA/sectionA.html +21 -0
- package/src/modules/arch/sectionA/sectionA.stories.js +25 -0
- package/src/modules/arch/sectionA/sectionA.ts +27 -0
- package/src/modules/arch/select/select.css +40 -0
- package/src/modules/arch/select/select.html +24 -0
- package/src/modules/arch/select/select.ts +64 -0
- package/src/modules/arch/socialShare/socialShare.css +50 -0
- package/src/modules/arch/socialShare/socialShare.html +56 -0
- package/src/modules/arch/socialShare/socialShare.ts +29 -0
- package/src/modules/arch/spinner/spinner.css +195 -0
- package/src/modules/arch/spinner/spinner.html +9 -0
- package/src/modules/arch/spinner/spinner.ts +15 -0
- package/src/modules/arch/styles/styles.css +24 -0
- package/src/modules/arch/summary/summary.css +134 -0
- package/src/modules/arch/summary/summary.html +71 -0
- package/src/modules/arch/summary/summary.stories.js +163 -0
- package/src/modules/arch/summary/summary.ts +96 -0
- package/src/modules/arch/tab/tab.css +3 -0
- package/src/modules/arch/tab/tab.html +5 -0
- package/src/modules/arch/tab/tab.ts +46 -0
- package/src/modules/arch/tabset/tabset.css +112 -0
- package/src/modules/arch/tabset/tabset.html +62 -0
- package/src/modules/arch/tabset/tabset.ts +244 -0
- package/src/modules/arch/testutils.ts +118 -0
- package/src/modules/arch/threeCardGrid/threeCardGrid.css +6 -0
- package/src/modules/arch/threeCardGrid/threeCardGrid.html +5 -0
- package/src/modules/arch/threeCardGrid/threeCardGrid.ts +3 -0
- package/src/modules/arch/track/track.ts +23 -0
- package/src/modules/arch/trailhead.ts +120 -0
- package/src/modules/arch/types.d.ts +1 -0
- package/src/modules/arch/useEffectAttr.ts +16 -0
- package/src/modules/arch/utils/utils.ts +20 -0
- package/src/modules/arch/withState.ts +21 -0
- package/src/modules/arch/xsfMfeEvents/xsfMfeEvents.html +1 -0
- package/src/modules/arch/xsfMfeEvents/xsfMfeEvents.ts +47 -0
- package/src/common/effectAdapter/__tests__/effectAdapter.test.ts +0 -12
- package/src/common/effectAdapter/effectAdapter.ts +0 -18
- package/src/common/reflectedElement/__tests__/modules/test/select/select.html +0 -3
- package/src/common/reflectedElement/__tests__/modules/test/select/select.ts +0 -7
- package/src/common/reflectedElement/__tests__/modules/test/selectTransform/selectTransform.html +0 -3
- package/src/common/reflectedElement/__tests__/modules/test/selectTransform/selectTransform.ts +0 -18
- package/src/common/reflectedElement/__tests__/reflectedElement.test.ts +0 -75
- package/src/common/slot/__tests__/slot.test.ts +0 -96
- package/src/common/slot/slot.ts +0 -20
- /package/src/{common → modules/arch}/context/context.html +0 -0
- /package/src/{common/effectAdapter/effectAdapter.html → modules/arch/contextAdapter/contextAdapter.html} +0 -0
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
import { LightningElement, api } from "lwc";
|
|
2
|
+
import { Card } from "arch/card";
|
|
3
|
+
import { FilterOption } from "./types";
|
|
4
|
+
import { sendInteractionEvent, InteractionEventTypes } from "arch/helpers";
|
|
5
|
+
import { debounce } from "arch/debounce";
|
|
6
|
+
|
|
7
|
+
// function to get the cards array from the json payload
|
|
8
|
+
async function getGridCards(data, imageHash) {
|
|
9
|
+
const parsedData = JSON.parse(data);
|
|
10
|
+
// Sort the data based on the `sort` value
|
|
11
|
+
parsedData.sort((a, b) => a.sort - b.sort);
|
|
12
|
+
// load the gallery cards
|
|
13
|
+
return parsedData.map((item) => {
|
|
14
|
+
const card: Card = {
|
|
15
|
+
assistiveText: "Click here to go to this resource",
|
|
16
|
+
//ctaTitle: "Read More",
|
|
17
|
+
ctaTarget: null,
|
|
18
|
+
pretitleHref: null,
|
|
19
|
+
pretitleHrefText: null
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// Dynamically set all other properties based on the data object
|
|
23
|
+
for (const prop in item) {
|
|
24
|
+
if (Object.prototype.hasOwnProperty.call(item, prop)) {
|
|
25
|
+
switch (prop) {
|
|
26
|
+
case "url":
|
|
27
|
+
card.ctaHref = item[prop];
|
|
28
|
+
break;
|
|
29
|
+
default:
|
|
30
|
+
card[prop] = item[prop];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Set imgSrc to thumbnail if it exists, otherwise use image
|
|
36
|
+
if (item.thumbnail) {
|
|
37
|
+
// Use thumbnail as-is if it's a full URL (starts with http), otherwise prepend asset path
|
|
38
|
+
if (item.thumbnail.startsWith("http")) {
|
|
39
|
+
card.imgSrc = item.thumbnail;
|
|
40
|
+
} else {
|
|
41
|
+
card.imgSrc = `/1/asset/immutable/s/${imageHash}${item.thumbnail}`;
|
|
42
|
+
}
|
|
43
|
+
} else if (item.image) {
|
|
44
|
+
card.imgSrc = item.image;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return card;
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
export default class gallery extends LightningElement {
|
|
51
|
+
// get the inputs from the config
|
|
52
|
+
_content: string | null = null;
|
|
53
|
+
_filterData;
|
|
54
|
+
_filterProperty;
|
|
55
|
+
_filterLabel;
|
|
56
|
+
_searchTitle;
|
|
57
|
+
_imageHash: string | null = null;
|
|
58
|
+
@api containerId: string;
|
|
59
|
+
|
|
60
|
+
// second filter drop down is optional and pulled from the json data set
|
|
61
|
+
_showMetaFilter = false;
|
|
62
|
+
_metaFilterProperty;
|
|
63
|
+
_metaFilterLabel;
|
|
64
|
+
|
|
65
|
+
// get the inputs from the form
|
|
66
|
+
_selectFilter: string = "";
|
|
67
|
+
_keywordFilter: string = "";
|
|
68
|
+
_selectMetaFilter: string = "";
|
|
69
|
+
|
|
70
|
+
// set up the outputs
|
|
71
|
+
allCards: Card[] = [];
|
|
72
|
+
filteredCards: Card[] = [];
|
|
73
|
+
shareUrl = window.location.href;
|
|
74
|
+
|
|
75
|
+
// prep the filters options
|
|
76
|
+
filterOptions: FilterOption[] = [];
|
|
77
|
+
metaFilterOptions: FilterOption[] = [];
|
|
78
|
+
|
|
79
|
+
// populate the filter drop down
|
|
80
|
+
connectedCallback() {
|
|
81
|
+
// Check if we're on the data model gallery page
|
|
82
|
+
if (
|
|
83
|
+
this.containerId === "data-model-gallery" &&
|
|
84
|
+
window.location.hash === "#data-model-gallery"
|
|
85
|
+
) {
|
|
86
|
+
window.location.href =
|
|
87
|
+
"https://developer.salesforce.com/docs/platform/data-models/guide/get-started.html";
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
get socialTitle() {
|
|
91
|
+
//Search title is plurar, removing last letter to make the title singular (should be a letter S)
|
|
92
|
+
return `${this._searchTitle.substring(
|
|
93
|
+
0,
|
|
94
|
+
this._searchTitle.length - 1
|
|
95
|
+
)} Gallery`;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// fetch the filter data from a url
|
|
99
|
+
async fetchFilterData() {
|
|
100
|
+
try {
|
|
101
|
+
const response = await fetch(this._filterData);
|
|
102
|
+
const data = await response.json();
|
|
103
|
+
this.filterOptions = data as FilterOption[];
|
|
104
|
+
} catch (error) {
|
|
105
|
+
console.error(
|
|
106
|
+
"An error occurred getting the filter list:",
|
|
107
|
+
error.message
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// handle the filter selection change
|
|
113
|
+
filterChange(evt: { detail: string }) {
|
|
114
|
+
this._selectFilter = evt.detail;
|
|
115
|
+
this.applyFilters();
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
private sendInteractionEvent = debounce((event, target) => {
|
|
119
|
+
sendInteractionEvent(
|
|
120
|
+
"Gallery Search",
|
|
121
|
+
InteractionEventTypes.INPUT_CHANGE,
|
|
122
|
+
event,
|
|
123
|
+
target
|
|
124
|
+
);
|
|
125
|
+
}, 1000);
|
|
126
|
+
|
|
127
|
+
// handle typing in the search box
|
|
128
|
+
keywordFilterChange(evt: InputEvent) {
|
|
129
|
+
const target = evt.currentTarget as HTMLInputElement;
|
|
130
|
+
this.sendInteractionEvent(evt, target);
|
|
131
|
+
this._keywordFilter = (evt.currentTarget as HTMLInputElement).value;
|
|
132
|
+
this.applyFilters();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// handle the filter selection change
|
|
136
|
+
metaFilterChange(evt: { detail: string }) {
|
|
137
|
+
this._selectMetaFilter = evt.detail;
|
|
138
|
+
this.applyFilters();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// update the gallery based on filtering
|
|
142
|
+
async applyFilters() {
|
|
143
|
+
this.filteredCards = this.allCards.filter((card) => {
|
|
144
|
+
const isFilterMatch =
|
|
145
|
+
this._selectFilter === "" ||
|
|
146
|
+
card[this._filterProperty]
|
|
147
|
+
?.toLowerCase()
|
|
148
|
+
.includes(this._selectFilter.toLocaleLowerCase());
|
|
149
|
+
const isMetaMatch = this._showMetaFilter
|
|
150
|
+
? this._selectMetaFilter === "" ||
|
|
151
|
+
card[this._metaFilterProperty]
|
|
152
|
+
?.toLowerCase()
|
|
153
|
+
.includes(this._selectMetaFilter.toLocaleLowerCase())
|
|
154
|
+
: true;
|
|
155
|
+
const isKeywordMatch =
|
|
156
|
+
this._keywordFilter === "" ||
|
|
157
|
+
(card.pretitle &&
|
|
158
|
+
card.pretitle
|
|
159
|
+
.toLowerCase()
|
|
160
|
+
.includes(this._keywordFilter.toLowerCase())) ||
|
|
161
|
+
(card.title &&
|
|
162
|
+
card.title
|
|
163
|
+
.toLowerCase()
|
|
164
|
+
.includes(this._keywordFilter.toLowerCase())) ||
|
|
165
|
+
(card.description &&
|
|
166
|
+
card.description
|
|
167
|
+
.toLowerCase()
|
|
168
|
+
.includes(this._keywordFilter.toLowerCase()));
|
|
169
|
+
|
|
170
|
+
if (isFilterMatch && isMetaMatch && isKeywordMatch) {
|
|
171
|
+
return true;
|
|
172
|
+
}
|
|
173
|
+
return false;
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// Update page state so that we track filters in URL params
|
|
177
|
+
const params = new URLSearchParams();
|
|
178
|
+
|
|
179
|
+
if (this._selectFilter !== "") {
|
|
180
|
+
params.set(this._filterLabel, this._selectFilter);
|
|
181
|
+
}
|
|
182
|
+
if (this._showMetaFilter && this._selectMetaFilter !== "") {
|
|
183
|
+
params.set(this._metaFilterLabel, this._selectMetaFilter);
|
|
184
|
+
}
|
|
185
|
+
if (this._keywordFilter !== "") {
|
|
186
|
+
params.set("keywords", this._keywordFilter);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const paramsString = params.toString();
|
|
190
|
+
let updatedUrl = window.location.pathname;
|
|
191
|
+
|
|
192
|
+
// Update the hash to the containerId if it's been filtered or from the URL on load
|
|
193
|
+
const urlHash = this.containerId
|
|
194
|
+
? `#${this.containerId}`
|
|
195
|
+
: window.location.hash.split("?")[0];
|
|
196
|
+
|
|
197
|
+
if (urlHash) {
|
|
198
|
+
updatedUrl += urlHash;
|
|
199
|
+
}
|
|
200
|
+
if (paramsString) {
|
|
201
|
+
updatedUrl += `?${paramsString}`;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
window.history.replaceState(
|
|
205
|
+
window.history.state,
|
|
206
|
+
document.title,
|
|
207
|
+
updatedUrl
|
|
208
|
+
);
|
|
209
|
+
this.shareUrl = `${window.location.protocol}//${window.location.hostname}${updatedUrl}`;
|
|
210
|
+
|
|
211
|
+
// Scrolls to container element to keep new data in focus.
|
|
212
|
+
if (urlHash) {
|
|
213
|
+
const targetElement = document.querySelector(
|
|
214
|
+
`#${this.containerId}`
|
|
215
|
+
);
|
|
216
|
+
// Scroll to the target element if it exists
|
|
217
|
+
if (targetElement) {
|
|
218
|
+
targetElement.scrollIntoView({ behavior: "smooth" });
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
checkURLParams() {
|
|
224
|
+
// Load filters from URL params
|
|
225
|
+
let requireFilterUpdate = false;
|
|
226
|
+
const url = new URL(window.location.href.replace("#", ""));
|
|
227
|
+
const params = url.searchParams;
|
|
228
|
+
for (const [key, value] of params.entries()) {
|
|
229
|
+
switch (key) {
|
|
230
|
+
case this._filterLabel:
|
|
231
|
+
this._selectFilter = value;
|
|
232
|
+
requireFilterUpdate = true;
|
|
233
|
+
break;
|
|
234
|
+
case this._metaFilterLabel:
|
|
235
|
+
this._selectMetaFilter = value;
|
|
236
|
+
requireFilterUpdate = true;
|
|
237
|
+
break;
|
|
238
|
+
case "keywords":
|
|
239
|
+
this._keywordFilter = value;
|
|
240
|
+
requireFilterUpdate = true;
|
|
241
|
+
break;
|
|
242
|
+
default:
|
|
243
|
+
break;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return requireFilterUpdate;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
handleResetFiltersClick() {
|
|
251
|
+
this._selectFilter = "";
|
|
252
|
+
if (this._showMetaFilter) {
|
|
253
|
+
this._selectMetaFilter = "";
|
|
254
|
+
}
|
|
255
|
+
this._keywordFilter = "";
|
|
256
|
+
this.applyFilters();
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
private updateCards() {
|
|
260
|
+
if (this._content && this._imageHash) {
|
|
261
|
+
try {
|
|
262
|
+
getGridCards(this._content, this._imageHash).then((res) => {
|
|
263
|
+
this.allCards = this.filteredCards = res;
|
|
264
|
+
if (this._showMetaFilter) {
|
|
265
|
+
const typesArr = [
|
|
266
|
+
...new Set(this.allCards.map((item) => item.type))
|
|
267
|
+
];
|
|
268
|
+
typesArr.sort((a, b) => a.localeCompare(b));
|
|
269
|
+
this.metaFilterOptions = typesArr.map((type) => ({
|
|
270
|
+
label: type,
|
|
271
|
+
value: type
|
|
272
|
+
})) as FilterOption[];
|
|
273
|
+
}
|
|
274
|
+
if (this.checkURLParams()) {
|
|
275
|
+
this.applyFilters();
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
} catch (error) {
|
|
279
|
+
console.error(
|
|
280
|
+
"An error occurred getting the cards:",
|
|
281
|
+
error.message
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// bind the config to the variables
|
|
288
|
+
@api
|
|
289
|
+
set searchtitle(value) {
|
|
290
|
+
if (this._searchTitle !== value) {
|
|
291
|
+
this._searchTitle = value;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
get searchtitle() {
|
|
295
|
+
return this._searchTitle;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
@api
|
|
299
|
+
set imageHash(value) {
|
|
300
|
+
this._imageHash = value;
|
|
301
|
+
this.updateCards();
|
|
302
|
+
}
|
|
303
|
+
get imageHash() {
|
|
304
|
+
return this._imageHash;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
@api
|
|
308
|
+
set content(value) {
|
|
309
|
+
this._content = value;
|
|
310
|
+
this.updateCards();
|
|
311
|
+
}
|
|
312
|
+
get content() {
|
|
313
|
+
return this._content;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
@api
|
|
317
|
+
set filter(value) {
|
|
318
|
+
if (this._filterData !== value) {
|
|
319
|
+
this._filterData = value;
|
|
320
|
+
if (!this._filterData.endsWith(".json")) {
|
|
321
|
+
this.filterOptions = JSON.parse(
|
|
322
|
+
this._filterData
|
|
323
|
+
) as FilterOption[];
|
|
324
|
+
} else {
|
|
325
|
+
this.fetchFilterData();
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
get filter() {
|
|
330
|
+
return this._filterData;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
@api
|
|
334
|
+
set property(value) {
|
|
335
|
+
if (this._filterProperty !== value) {
|
|
336
|
+
this._filterProperty = value;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
get property() {
|
|
340
|
+
return this._filterProperty;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
@api
|
|
344
|
+
set label(value) {
|
|
345
|
+
if (this._filterLabel !== value) {
|
|
346
|
+
this._filterLabel = value;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
get label() {
|
|
350
|
+
return this._filterLabel;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// below is for getting and setting the optional second filter
|
|
354
|
+
@api
|
|
355
|
+
set metafilters(value) {
|
|
356
|
+
if (this._metaFilterProperty !== value) {
|
|
357
|
+
this._showMetaFilter = true;
|
|
358
|
+
this._metaFilterProperty = value;
|
|
359
|
+
this._metaFilterLabel =
|
|
360
|
+
value.charAt(0).toUpperCase() + value.slice(1);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
get metafilters() {
|
|
364
|
+
return this._metaFilterProperty;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export type GalleryCard = {
|
|
2
|
+
id?: string;
|
|
3
|
+
pretitle: string | null;
|
|
4
|
+
title: string;
|
|
5
|
+
description: string;
|
|
6
|
+
image: string | null;
|
|
7
|
+
status?: string | null;
|
|
8
|
+
sort: number | null;
|
|
9
|
+
updated?: Date | null;
|
|
10
|
+
productAreas: string[];
|
|
11
|
+
url: string | null;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type CardAttribute = string | null;
|
|
15
|
+
export type Card = {
|
|
16
|
+
assistiveText: CardAttribute;
|
|
17
|
+
ctaHref: CardAttribute;
|
|
18
|
+
ctaTarget: CardAttribute;
|
|
19
|
+
ctaTitle: CardAttribute;
|
|
20
|
+
description: CardAttribute;
|
|
21
|
+
imgSrc: CardAttribute;
|
|
22
|
+
pretitle: CardAttribute;
|
|
23
|
+
pretitleHref: CardAttribute;
|
|
24
|
+
pretitleHrefText: CardAttribute;
|
|
25
|
+
title: CardAttribute;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type GalleryCards = {
|
|
29
|
+
items: Card[];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type FilterOption = {
|
|
33
|
+
label: string;
|
|
34
|
+
value: string;
|
|
35
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import 'arch/reset';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<h1 class="heading" if:true={isLevel1}><slot></slot></h1>
|
|
3
|
+
<h2 class="heading" if:true={isLevel2}><slot></slot></h2>
|
|
4
|
+
<h3 class="heading" if:true={isLevel3}><slot></slot></h3>
|
|
5
|
+
<h4 class="heading" if:true={isLevel4}><slot></slot></h4>
|
|
6
|
+
<h5 class="heading" if:true={isLevel5}><slot></slot></h5>
|
|
7
|
+
<h6 class="heading" if:true={isLevel6}><slot></slot></h6>
|
|
8
|
+
<template if:false={isHeading}><slot></slot></template>
|
|
9
|
+
</template>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { api, LightningElement } from 'lwc';
|
|
2
|
+
|
|
3
|
+
export default class extends LightningElement {
|
|
4
|
+
// In the future, this could accept a value of "auto" which
|
|
5
|
+
// could traverse the DOM tree and figure out the appropriate level
|
|
6
|
+
@api level: '1' | '2' | '3' | '4' | '5' | '6' | null = null;
|
|
7
|
+
|
|
8
|
+
private get isHeading() {
|
|
9
|
+
// If "level" is null, we render a <slot> and with no heading
|
|
10
|
+
return this.level !== null;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
private get isLevel1() {
|
|
14
|
+
return this.level === '1';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
private get isLevel2() {
|
|
18
|
+
return this.level === '2';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
private get isLevel3() {
|
|
22
|
+
return this.level === '3';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
private get isLevel4() {
|
|
26
|
+
return this.level === '4';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
private get isLevel5() {
|
|
30
|
+
return this.level === '5';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private get isLevel6() {
|
|
34
|
+
return this.level === '6';
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
export function attrToBool(attr: any) {
|
|
2
|
+
if (typeof attr === "boolean") {
|
|
3
|
+
return attr;
|
|
4
|
+
}
|
|
5
|
+
if (typeof attr === "string") {
|
|
6
|
+
return attr === "true" || attr === "";
|
|
7
|
+
}
|
|
8
|
+
return !!attr;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function hash(value: string) {
|
|
12
|
+
let hashValue = 0;
|
|
13
|
+
for (let i = 0; i < value.length; i++) {
|
|
14
|
+
const char = value.charCodeAt(i);
|
|
15
|
+
hashValue = (hashValue << 5) - hashValue + char;
|
|
16
|
+
hashValue |= 0;
|
|
17
|
+
}
|
|
18
|
+
return hashValue;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function createImageUrl(image: string, hashParam: string) {
|
|
22
|
+
if (image.startsWith("/assets")) {
|
|
23
|
+
const segments = image.split("/");
|
|
24
|
+
return `/1/asset/immutable/s/${hashParam}/$assetsDir/images/${
|
|
25
|
+
segments[segments.length - 1]
|
|
26
|
+
}`;
|
|
27
|
+
}
|
|
28
|
+
return image;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const InteractionEventTypes = Object.freeze({
|
|
32
|
+
CLICK: "CLICK",
|
|
33
|
+
PAGE_VIEW: "PAGE_VIEW",
|
|
34
|
+
INPUT_CHANGE: "INPUT_CHANGE",
|
|
35
|
+
FILE_DOWNLOAD: "FILE_DOWNLOAD",
|
|
36
|
+
IMAGE_DOWNLOAD: "IMAGE_DOWNLOAD", //used with CDN
|
|
37
|
+
IMAGE_CLICK: "IMAGE_CLICK",
|
|
38
|
+
DROPDOWN_CHANGE: "DROPDOWN_CHANGE"
|
|
39
|
+
});
|
|
40
|
+
const channelActions = Object.freeze({
|
|
41
|
+
DOWNLOAD: "DOWNLOAD",
|
|
42
|
+
VIEW: "VIEW"
|
|
43
|
+
});
|
|
44
|
+
const channelActionsStatus = Object.freeze({
|
|
45
|
+
SUCCESS: "SUCCESS",
|
|
46
|
+
FAILURE: "FAILURE"
|
|
47
|
+
});
|
|
48
|
+
export function sendInteractionEvent(name, type, event, target?) {
|
|
49
|
+
const element = target || event.currentTarget;
|
|
50
|
+
let text: string = "";
|
|
51
|
+
let eventValue: string = "";
|
|
52
|
+
let channelAction: string = "";
|
|
53
|
+
const channelActionStatus: string = channelActionsStatus.SUCCESS;
|
|
54
|
+
const pageUrl = new URL(document.location.href);
|
|
55
|
+
const searchTitle = pageUrl.searchParams.get("keywords") || "";
|
|
56
|
+
if (
|
|
57
|
+
type === InteractionEventTypes.IMAGE_CLICK ||
|
|
58
|
+
type === InteractionEventTypes.FILE_DOWNLOAD
|
|
59
|
+
) {
|
|
60
|
+
eventValue = element.href || element.src;
|
|
61
|
+
const url = new URL(
|
|
62
|
+
eventValue,
|
|
63
|
+
window.location.protocol + "//" + window.location.host
|
|
64
|
+
);
|
|
65
|
+
text = url.pathname.substr(url.pathname.lastIndexOf("/") + 1);
|
|
66
|
+
channelAction = channelActions.DOWNLOAD;
|
|
67
|
+
}
|
|
68
|
+
if (type === InteractionEventTypes.CLICK) {
|
|
69
|
+
eventValue = element.href || "";
|
|
70
|
+
|
|
71
|
+
let textNode = element;
|
|
72
|
+
if (element.firstChild.localName === "slot") {
|
|
73
|
+
textNode = element.firstChild
|
|
74
|
+
.assignedNodes()
|
|
75
|
+
.find((child) => child.textContent !== "");
|
|
76
|
+
}
|
|
77
|
+
text = element.ariaLabel || textNode.textContent || textNode.innerText;
|
|
78
|
+
|
|
79
|
+
if (eventValue.includes("/view/")) {
|
|
80
|
+
type = InteractionEventTypes.IMAGE_CLICK;
|
|
81
|
+
const imgSrc = target.getElementsByTagName("img")[0].src;
|
|
82
|
+
channelAction = channelActions.VIEW;
|
|
83
|
+
|
|
84
|
+
if (imgSrc) {
|
|
85
|
+
const url = new URL(
|
|
86
|
+
imgSrc,
|
|
87
|
+
window.location.protocol + "//" + window.location.host
|
|
88
|
+
);
|
|
89
|
+
text = url.pathname.substr(url.pathname.lastIndexOf("/") + 1);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (eventValue.includes("/cms/delivery/media")) {
|
|
93
|
+
type = InteractionEventTypes.IMAGE_DOWNLOAD;
|
|
94
|
+
channelAction = channelActions.DOWNLOAD;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (type === InteractionEventTypes.DROPDOWN_CHANGE) {
|
|
98
|
+
text = element.id;
|
|
99
|
+
eventValue = element.value;
|
|
100
|
+
}
|
|
101
|
+
if (type === InteractionEventTypes.INPUT_CHANGE) {
|
|
102
|
+
text = element.ariaLabel;
|
|
103
|
+
eventValue = element.value;
|
|
104
|
+
}
|
|
105
|
+
let env = "DEV";
|
|
106
|
+
if (window.location.host === "architect.salesforce.com") {
|
|
107
|
+
env = "PRD";
|
|
108
|
+
}
|
|
109
|
+
if (window.location.host.includes("site-staging")) {
|
|
110
|
+
env = "STG";
|
|
111
|
+
}
|
|
112
|
+
text = text.replace(/^\s+|\s+$/g, "");
|
|
113
|
+
const pathNameArray = window.location.pathname.split("/");
|
|
114
|
+
const interaction = {
|
|
115
|
+
name: name,
|
|
116
|
+
eventType: "websiteInteractionEvent",
|
|
117
|
+
topLevelLocation: pathNameArray[1] || "/",
|
|
118
|
+
secondLevelLocation: pathNameArray[2],
|
|
119
|
+
page: pathNameArray[3],
|
|
120
|
+
params: window.location.search || window.location.hash,
|
|
121
|
+
interactionType: type,
|
|
122
|
+
interactionElement: element
|
|
123
|
+
? `${element.localName}/${element.name}/${text}`
|
|
124
|
+
: "",
|
|
125
|
+
eventValue: eventValue,
|
|
126
|
+
env: env,
|
|
127
|
+
gaClientId: localStorage.getItem("ga_client_id"),
|
|
128
|
+
elementId: element.id,
|
|
129
|
+
elementLabel: text,
|
|
130
|
+
channelAction: channelAction,
|
|
131
|
+
channelActionStatus: channelActionStatus,
|
|
132
|
+
testSend: env === "PRD" ? "false" : "true",
|
|
133
|
+
pageId: pathNameArray[pathNameArray.length - 1],
|
|
134
|
+
pageTitle: document.title,
|
|
135
|
+
searchTitle: pathNameArray[1] === "search" ? searchTitle : "",
|
|
136
|
+
domainName: window.location.hostname
|
|
137
|
+
};
|
|
138
|
+
(window as any).SalesforceInteractions?.sendEvent({
|
|
139
|
+
interaction: interaction
|
|
140
|
+
});
|
|
141
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
@import "arch/reset";
|
|
2
|
+
|
|
3
|
+
a {
|
|
4
|
+
text-decoration: none;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
img {
|
|
8
|
+
display: block;
|
|
9
|
+
max-width: 100%;
|
|
10
|
+
max-height: 475px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.hero {
|
|
14
|
+
padding: 0 var(--arch-spacing-6);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.hero-white {
|
|
18
|
+
background-color: var(--arch-color-white);
|
|
19
|
+
color: var(--arch-color-black);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.hero-dark {
|
|
23
|
+
background-color: var(--arch-color-theme-dark);
|
|
24
|
+
color: var(--arch-color-white);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.hero-blue {
|
|
28
|
+
background-color: var(--arch-color-blue-ninety-five);
|
|
29
|
+
color: var(--arch-color-black);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.hero-light {
|
|
33
|
+
background-color: var(--arch-color-theme-light);
|
|
34
|
+
color: var(--arch-color-black);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.hero-bright {
|
|
38
|
+
background-color: var(--arch-color-theme-bright);
|
|
39
|
+
color: var(--arch-color-black);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.content {
|
|
43
|
+
align-items: center;
|
|
44
|
+
display: flex;
|
|
45
|
+
justify-content: space-between;
|
|
46
|
+
margin: auto;
|
|
47
|
+
max-width: 1280px;
|
|
48
|
+
min-height: 500px;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.content-start {
|
|
52
|
+
display: flex;
|
|
53
|
+
flex-direction: column;
|
|
54
|
+
align-items: start;
|
|
55
|
+
padding-top: var(--arch-spacing-12);
|
|
56
|
+
padding-bottom: var(--arch-spacing-12);
|
|
57
|
+
padding-right: var(--arch-spacing-6);
|
|
58
|
+
width: 40%;
|
|
59
|
+
min-width: 400px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.content-end-center {
|
|
63
|
+
margin-top: var(--arch-spacing-8);
|
|
64
|
+
margin-bottom: var(--arch-spacing-8);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.content-end-bottom {
|
|
68
|
+
align-self: flex-end;
|
|
69
|
+
margin-top: var(--arch-spacing-8);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.title {
|
|
73
|
+
font-family: Neutraface, sans-serif;
|
|
74
|
+
font-size: var(--arch-font-size-6xl);
|
|
75
|
+
line-height: 1;
|
|
76
|
+
white-space: pre-line;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.subtitle {
|
|
80
|
+
line-height: 1.5;
|
|
81
|
+
margin: var(--arch-spacing-2) 0;
|
|
82
|
+
font-size: var(--arch-font-size-xl);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.cta {
|
|
86
|
+
margin-top: var(--arch-spacing-2);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@media screen and (max-width: 1100px) {
|
|
90
|
+
.content {
|
|
91
|
+
flex-direction: column;
|
|
92
|
+
padding-top: var(--arch-spacing-8);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.content-start {
|
|
96
|
+
align-items: center;
|
|
97
|
+
margin: auto;
|
|
98
|
+
max-width: 400px;
|
|
99
|
+
min-width: auto;
|
|
100
|
+
padding: var(--arch-spacing-2) 0 var(--arch-spacing-3);
|
|
101
|
+
text-align: center;
|
|
102
|
+
width: 100%;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.content-end {
|
|
106
|
+
margin-left: auto;
|
|
107
|
+
margin-right: auto;
|
|
108
|
+
max-width: 450px;
|
|
109
|
+
max-height: 450px;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.title {
|
|
113
|
+
white-space: normal;
|
|
114
|
+
font-size: var(--arch-font-size-5xl);
|
|
115
|
+
}
|
|
116
|
+
}
|