@salesforcedevs/arch-components 1.20.17-alpha5 → 1.20.17-alpha6
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 +1 -1
- package/src/{modules/common → common}/context/context.ts +21 -21
- package/src/common/effectAdapter/__tests__/effectAdapter.test.ts +12 -0
- package/src/common/effectAdapter/effectAdapter.html +1 -0
- package/src/common/effectAdapter/effectAdapter.ts +18 -0
- package/src/common/reflectedElement/__tests__/modules/test/select/select.html +3 -0
- package/src/common/reflectedElement/__tests__/modules/test/select/select.ts +7 -0
- package/src/common/reflectedElement/__tests__/modules/test/selectTransform/selectTransform.html +3 -0
- package/src/common/reflectedElement/__tests__/modules/test/selectTransform/selectTransform.ts +18 -0
- package/src/common/reflectedElement/__tests__/reflectedElement.test.ts +75 -0
- package/src/common/reflectedElement/reflectedElement.ts +50 -0
- package/src/common/slot/__tests__/slot.test.ts +96 -0
- package/src/common/slot/slot.ts +20 -0
- package/src/sa/coverage/coverage.css +35 -0
- package/src/sa/coverage/coverage.html +15 -0
- package/src/sa/coverage/coverage.ts +404 -0
- package/src/sa/coverage/types.d.ts +22 -0
- package/src/sa/expandableSection/expandableSection.css +24 -0
- package/src/sa/expandableSection/expandableSection.html +20 -0
- package/src/sa/expandableSection/expandableSection.stories.ts +37 -0
- package/src/sa/expandableSection/expandableSection.ts +24 -0
- package/src/sa/explorer/explorer.css +303 -0
- package/src/sa/explorer/explorer.html +403 -0
- package/src/sa/explorer/explorer.ts +664 -0
- package/src/sa/explorer/types.d.ts +60 -0
- package/src/sa/gallery/gallery.css +358 -0
- package/src/sa/gallery/gallery.html +65 -0
- package/src/sa/gallery/gallery.ts +300 -0
- package/src/sa/gallery/types.d.ts +35 -0
- package/src/sa/socialShare/socialShare.css +49 -0
- package/src/sa/socialShare/socialShare.html +56 -0
- package/src/sa/socialShare/socialShare.ts +29 -0
- /package/src/{modules/common → common}/context/context.html +0 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import { LightningElement, api, track } from 'lwc';
|
|
2
|
+
import { Card } from 'tm/card';
|
|
3
|
+
import { FilterOption } from './types';
|
|
4
|
+
import { sendInteractionEvent, InteractionEventTypes } from 'shared/helpers';
|
|
5
|
+
import { debounce } from 'shared/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 await 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 (item.hasOwnProperty(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
|
+
// Set imgSrc to thumbnail if it exists, otherwise use image
|
|
35
|
+
if (item.thumbnail) {
|
|
36
|
+
card.imgSrc = `/1/asset/immutable/s/${imageHash}${item.thumbnail}`;
|
|
37
|
+
} else if (item.image) {
|
|
38
|
+
card.imgSrc = item.image;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return card;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
export default class gallery extends LightningElement {
|
|
46
|
+
|
|
47
|
+
// get the inputs from the config
|
|
48
|
+
_content: string | null = null;
|
|
49
|
+
_filterData;
|
|
50
|
+
_filterProperty;
|
|
51
|
+
_filterLabel;
|
|
52
|
+
_searchTitle;
|
|
53
|
+
_imageHash: string | null = null;
|
|
54
|
+
@api containerId: string;
|
|
55
|
+
|
|
56
|
+
// second filter drop down is optional and pulled from the json data set
|
|
57
|
+
_showMetaFilter = false;
|
|
58
|
+
_metaFilterProperty;
|
|
59
|
+
_metaFilterLabel;
|
|
60
|
+
|
|
61
|
+
// get the inputs from the form
|
|
62
|
+
_selectFilter: string = '';
|
|
63
|
+
_keywordFilter: string = '';
|
|
64
|
+
_selectMetaFilter: string = '';
|
|
65
|
+
|
|
66
|
+
// set up the outputs
|
|
67
|
+
allCards: Card[] = [];
|
|
68
|
+
filteredCards: Card[] = [];
|
|
69
|
+
shareUrl = window.location.href;
|
|
70
|
+
|
|
71
|
+
// prep the filters options
|
|
72
|
+
filterOptions: FilterOption[] = [];
|
|
73
|
+
metaFilterOptions: FilterOption[] = [];
|
|
74
|
+
|
|
75
|
+
// populate the filter drop down
|
|
76
|
+
connectedCallback() {
|
|
77
|
+
// Check if we're on the data model gallery page
|
|
78
|
+
if (this.containerId === 'data-model-gallery' && window.location.hash === '#data-model-gallery') {
|
|
79
|
+
window.location.href = 'https://developer.salesforce.com/docs/platform/data-models/guide/get-started.html';
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
get socialTitle(){
|
|
83
|
+
//Search title is plurar, removing last letter to make the title singular (should be a letter S)
|
|
84
|
+
return `${this._searchTitle.substring(0, this._searchTitle.length - 1)} Gallery`;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// fetch the filter data from a url
|
|
88
|
+
async fetchFilterData() {
|
|
89
|
+
try {
|
|
90
|
+
const response = await fetch(this._filterData);
|
|
91
|
+
const data = await response.json();
|
|
92
|
+
this.filterOptions = data as FilterOption[];
|
|
93
|
+
} catch (error) {
|
|
94
|
+
console.error("An error occurred getting the filter list:", error.message);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// handle the filter selection change
|
|
99
|
+
filterChange(evt: { detail: string }) {
|
|
100
|
+
this._selectFilter = evt.detail;
|
|
101
|
+
this.applyFilters();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
private sendInteractionEvent = debounce((event,target)=>{
|
|
105
|
+
sendInteractionEvent("Gallery Search",InteractionEventTypes.INPUT_CHANGE,event,target);
|
|
106
|
+
},1000);
|
|
107
|
+
|
|
108
|
+
// handle typing in the search box
|
|
109
|
+
keywordFilterChange(evt: InputEvent) {
|
|
110
|
+
const target = (evt.currentTarget as HTMLInputElement);
|
|
111
|
+
this.sendInteractionEvent(evt,target);
|
|
112
|
+
this._keywordFilter = (evt.currentTarget as HTMLInputElement).value;
|
|
113
|
+
this.applyFilters();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// handle the filter selection change
|
|
117
|
+
metaFilterChange(evt: { detail: string }) {
|
|
118
|
+
this._selectMetaFilter = evt.detail;
|
|
119
|
+
this.applyFilters();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// update the gallery based on filtering
|
|
123
|
+
async applyFilters() {
|
|
124
|
+
this.filteredCards = this.allCards.filter((card) => {
|
|
125
|
+
let isFilterMatch = (this._selectFilter === '' || card[this._filterProperty]?.toLowerCase().includes(this._selectFilter.toLocaleLowerCase()));
|
|
126
|
+
let isMetaMatch = ((this._showMetaFilter) ? ((this._selectMetaFilter === '' || card[this._metaFilterProperty]?.toLowerCase().includes(this._selectMetaFilter.toLocaleLowerCase()))) : true);
|
|
127
|
+
let isKeywordMatch = (this._keywordFilter === ''
|
|
128
|
+
|| (card.pretitle && card.pretitle.toLowerCase().includes(this._keywordFilter.toLowerCase()))
|
|
129
|
+
|| (card.title && card.title.toLowerCase().includes(this._keywordFilter.toLowerCase()))
|
|
130
|
+
|| (card.description && card.description.toLowerCase().includes(this._keywordFilter.toLowerCase()))
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
if (isFilterMatch && isMetaMatch && isKeywordMatch)
|
|
134
|
+
return card;
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// Update page state so that we track filters in URL params
|
|
138
|
+
const params = new URLSearchParams();
|
|
139
|
+
|
|
140
|
+
if (this._selectFilter !== '')
|
|
141
|
+
params.set(this._filterLabel, this._selectFilter);
|
|
142
|
+
if (this._showMetaFilter && this._selectMetaFilter !== '')
|
|
143
|
+
params.set(this._metaFilterLabel, this._selectMetaFilter);
|
|
144
|
+
if (this._keywordFilter !== '')
|
|
145
|
+
params.set('keywords', this._keywordFilter);
|
|
146
|
+
|
|
147
|
+
const paramsString = params.toString();
|
|
148
|
+
let updatedUrl = window.location.pathname;
|
|
149
|
+
|
|
150
|
+
// Update the hash to the containerId if it's been filtered or from the URL on load
|
|
151
|
+
const hash = this.containerId ? `#${this.containerId}` : window.location.hash.split('?')[0];
|
|
152
|
+
|
|
153
|
+
if (hash)
|
|
154
|
+
updatedUrl += hash;
|
|
155
|
+
if (paramsString)
|
|
156
|
+
updatedUrl += `?${paramsString}`;
|
|
157
|
+
|
|
158
|
+
history.replaceState(history.state, document.title, updatedUrl);
|
|
159
|
+
this.shareUrl = `${window.location.protocol}//${window.location.hostname}${updatedUrl}`;
|
|
160
|
+
|
|
161
|
+
// Scrolls to container element to keep new data in focus.
|
|
162
|
+
if (hash) {
|
|
163
|
+
const targetElement = document.querySelector(`#${this.containerId}`);
|
|
164
|
+
// Scroll to the target element if it exists
|
|
165
|
+
if (targetElement) {
|
|
166
|
+
targetElement.scrollIntoView({ behavior: "smooth" });
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
checkURLParams() {
|
|
172
|
+
// Load filters from URL params
|
|
173
|
+
let requireFilterUpdate = false;
|
|
174
|
+
const url = new URL(window.location.href.replace('#', ''));
|
|
175
|
+
const params = url.searchParams;
|
|
176
|
+
for (const [key, value] of params.entries()) {
|
|
177
|
+
switch (key) {
|
|
178
|
+
case this._filterLabel:
|
|
179
|
+
this._selectFilter = value;
|
|
180
|
+
requireFilterUpdate = true;
|
|
181
|
+
break;
|
|
182
|
+
case this._metaFilterLabel:
|
|
183
|
+
this._selectMetaFilter = value;
|
|
184
|
+
requireFilterUpdate = true;
|
|
185
|
+
break;
|
|
186
|
+
case 'keywords':
|
|
187
|
+
this._keywordFilter = value;
|
|
188
|
+
requireFilterUpdate = true;
|
|
189
|
+
break;
|
|
190
|
+
default:
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
return requireFilterUpdate;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
handleResetFiltersClick() {
|
|
199
|
+
this._selectFilter = '';
|
|
200
|
+
(this._showMetaFilter) ? this._selectMetaFilter = '' : true;
|
|
201
|
+
this._keywordFilter = '';
|
|
202
|
+
this.applyFilters();
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
private updateCards() {
|
|
206
|
+
if (this._content && this._imageHash) {
|
|
207
|
+
try {
|
|
208
|
+
getGridCards(this._content, this._imageHash).then((res) => {
|
|
209
|
+
this.allCards = this.filteredCards = res;
|
|
210
|
+
if (this._showMetaFilter) {
|
|
211
|
+
let typesArr = [...new Set(this.allCards.map(item => item.type))];
|
|
212
|
+
typesArr.sort((a, b) => a.localeCompare(b));
|
|
213
|
+
this.metaFilterOptions = typesArr.map(type => ({ label: type, value: type })) as FilterOption[];
|
|
214
|
+
}
|
|
215
|
+
if (this.checkURLParams())
|
|
216
|
+
this.applyFilters();
|
|
217
|
+
});
|
|
218
|
+
} catch (error) {
|
|
219
|
+
console.error("An error occurred getting the cards:", error.message);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// bind the config to the variables
|
|
225
|
+
@api
|
|
226
|
+
set searchtitle(value) {
|
|
227
|
+
if (this._searchTitle !== value) {
|
|
228
|
+
this._searchTitle = value;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
get searchtitle() {
|
|
232
|
+
return this._searchTitle;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
@api
|
|
236
|
+
set imageHash(value) {
|
|
237
|
+
this._imageHash = value;
|
|
238
|
+
this.updateCards();
|
|
239
|
+
}
|
|
240
|
+
get imageHash() {
|
|
241
|
+
return this._imageHash;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
@api
|
|
245
|
+
set content(value) {
|
|
246
|
+
this._content = value;
|
|
247
|
+
this.updateCards();
|
|
248
|
+
}
|
|
249
|
+
get content() {
|
|
250
|
+
return this._content;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
@api
|
|
254
|
+
set filter(value) {
|
|
255
|
+
if (this._filterData !== value) {
|
|
256
|
+
this._filterData = value;
|
|
257
|
+
if (!this._filterData.endsWith('.json')) {
|
|
258
|
+
this.filterOptions = JSON.parse(this._filterData) as FilterOption[];
|
|
259
|
+
} else {
|
|
260
|
+
this.fetchFilterData();
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
get filter() {
|
|
265
|
+
return this._filterData;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
@api
|
|
269
|
+
set property(value) {
|
|
270
|
+
if (this._filterProperty !== value) {
|
|
271
|
+
this._filterProperty = value;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
get property() {
|
|
275
|
+
return this._filterProperty;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
@api
|
|
279
|
+
set label(value) {
|
|
280
|
+
if (this._filterLabel !== value) {
|
|
281
|
+
this._filterLabel = value;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
get label() {
|
|
285
|
+
return this._filterLabel;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// below is for getting and setting the optional second filter
|
|
289
|
+
@api
|
|
290
|
+
set metafilters(value) {
|
|
291
|
+
if (this._metaFilterProperty !== value) {
|
|
292
|
+
this._showMetaFilter = true;
|
|
293
|
+
this._metaFilterProperty = value;
|
|
294
|
+
this._metaFilterLabel = value.charAt(0).toUpperCase() + value.slice(1);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
get metafilters() {
|
|
298
|
+
return this._metaFilterProperty;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
@@ -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,49 @@
|
|
|
1
|
+
@import 'tds/reset';
|
|
2
|
+
|
|
3
|
+
:host {
|
|
4
|
+
display: flex;
|
|
5
|
+
align-items: center;
|
|
6
|
+
justify-content: space-between;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.actions {
|
|
10
|
+
align-items: center;
|
|
11
|
+
display: grid;
|
|
12
|
+
grid-auto-flow: column;
|
|
13
|
+
grid-column-gap: var(--tds-spacing-2);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@media screen and (max-width: 800px) {
|
|
17
|
+
.actions {
|
|
18
|
+
width: 120px;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.actions a {
|
|
23
|
+
margin-right: 1rem;
|
|
24
|
+
}
|
|
25
|
+
.actions a:last-of-type {
|
|
26
|
+
margin-right: 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.actions svg {
|
|
30
|
+
height: 1rem;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.actions svg.fill {
|
|
34
|
+
fill: var(--tds-color-meteorite);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.actions svg.fill:hover {
|
|
38
|
+
fill: var(--tds-color-brand);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.actions svg.stroke {
|
|
42
|
+
stroke: var(--tds-color-meteorite);
|
|
43
|
+
fill: var(--tds-color-meteorite);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.actions svg.stroke:hover {
|
|
47
|
+
stroke: var(--tds-color-brand);
|
|
48
|
+
fill: var(--tds-color-brand);
|
|
49
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="actions">
|
|
3
|
+
<a
|
|
4
|
+
onclick={handleClick}
|
|
5
|
+
href={shareTwitter}
|
|
6
|
+
target="_blank"
|
|
7
|
+
rel="noopener"
|
|
8
|
+
id="Share-on-Twitter"
|
|
9
|
+
name="Share on Twitter"
|
|
10
|
+
aria-label="Share on Twitter (opens new tab)"
|
|
11
|
+
class="fill"
|
|
12
|
+
><svg
|
|
13
|
+
viewBox="0 0 18 14"
|
|
14
|
+
class="fill"
|
|
15
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
16
|
+
>
|
|
17
|
+
<path
|
|
18
|
+
d="M17.308 2.325a7.333 7.333 0 01-2.041.52 3.396 3.396 0 001.565-1.836 7.374 7.374 0 01-2.258.808c-.33-.33-.73-.595-1.176-.775a3.767 3.767 0 00-1.412-.274 3.75 3.75 0 00-2.518.995A3.218 3.218 0 008.43 4.108c.002.254.033.507.094.755A10.658 10.658 0 014.46 3.847a9.912 9.912 0 01-3.256-2.471 3.128 3.128 0 00-.39 2.419c.205.823.738 1.544 1.494 2.017A3.678 3.678 0 01.72 5.39a.124.124 0 000 .053c.005.767.294 1.509.82 2.101.525.592 1.254 1 2.065 1.153-.326.071-.66.1-.995.087a4.39 4.39 0 01-.671 0 3.36 3.36 0 001.265 1.638c.594.412 1.31.645 2.052.666a7.475 7.475 0 01-4.413 1.423 8.92 8.92 0 01-.844-.08 10.571 10.571 0 005.445 1.49c6.526 0 10.096-5.057 10.096-9.446v-.434a6.933 6.933 0 001.767-1.717z"
|
|
19
|
+
></path></svg>
|
|
20
|
+
</a>
|
|
21
|
+
<a
|
|
22
|
+
onclick={handleClick}
|
|
23
|
+
href={shareLinkedIn}
|
|
24
|
+
target="_blank"
|
|
25
|
+
rel="noopener"
|
|
26
|
+
id="Share-on-LinkedIn"
|
|
27
|
+
name="Share on LinkedIn"
|
|
28
|
+
aria-label="Share on LinkedIn (opens new tab)"
|
|
29
|
+
><svg
|
|
30
|
+
viewBox="0 0 16 17"
|
|
31
|
+
class="fill"
|
|
32
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
33
|
+
>
|
|
34
|
+
<path
|
|
35
|
+
d="M15.923 10.187v6.428H12.51v-5.998c0-1.506-.493-2.535-1.729-2.535-.943 0-1.504.693-1.75 1.364-.09.24-.114.573-.114.908v6.261H5.503s.046-10.158 0-11.21h3.414v1.588l-.023.037h.023v-.037c.453-.762 1.263-1.852 3.076-1.852 2.246 0 3.93 1.602 3.93 5.046zM1.932 0C.764 0 0 .837 0 1.937c0 1.076.742 1.938 1.887 1.938h.022c1.19 0 1.931-.862 1.931-1.938C3.818.837 3.1 0 1.932 0zM.202 16.615h3.413V5.405H.203v11.21z"
|
|
36
|
+
></path></svg>
|
|
37
|
+
</a>
|
|
38
|
+
<a
|
|
39
|
+
onclick={handleClick}
|
|
40
|
+
href={shareFacebook}
|
|
41
|
+
target="_blank"
|
|
42
|
+
rel="noopener"
|
|
43
|
+
id="Share-on-Facebook"
|
|
44
|
+
name="Share on Facebook"
|
|
45
|
+
aria-label="Share on Facebook (opens new tab)"
|
|
46
|
+
><svg
|
|
47
|
+
viewBox="0 0 9 18"
|
|
48
|
+
class="stroke"
|
|
49
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
50
|
+
>
|
|
51
|
+
<path
|
|
52
|
+
d="M6.115 0c-2.173 0-3.66 1.5-3.66 4.23v2.363H0v3.195h2.455V18h2.926V9.788h2.45l.37-3.195H5.38V4.545c0-.922.236-1.545 1.42-1.545h1.507V.128A18.2 18.2 0 006.115 0z"
|
|
53
|
+
></path></svg>
|
|
54
|
+
</a>
|
|
55
|
+
</div>
|
|
56
|
+
</template>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { LightningElement, api } from 'lwc';
|
|
2
|
+
import { sendInteractionEvent, InteractionEventTypes } from 'shared/helpers';
|
|
3
|
+
|
|
4
|
+
export default class extends LightningElement {
|
|
5
|
+
@api title: string | null = '';
|
|
6
|
+
@api url: string = window.location.href;
|
|
7
|
+
|
|
8
|
+
private get shareTwitter() {
|
|
9
|
+
return `https://twitter.com/intent/tweet/?text=${encodeURIComponent(
|
|
10
|
+
this.title
|
|
11
|
+
)}&url=${encodeURIComponent(this.url)}&via=SalesforceArchs`;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
private get shareLinkedIn() {
|
|
15
|
+
return `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURI(
|
|
16
|
+
this.url
|
|
17
|
+
)}`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
private get shareFacebook() {
|
|
21
|
+
return `https://www.facebook.com/sharer/sharer.php?u=${encodeURI(
|
|
22
|
+
this.url
|
|
23
|
+
)}`;
|
|
24
|
+
}
|
|
25
|
+
handleClick(e){
|
|
26
|
+
sendInteractionEvent('Social Share Click', InteractionEventTypes.CLICK, e, e.currentTarget);
|
|
27
|
+
|
|
28
|
+
}
|
|
29
|
+
}
|
|
File without changes
|