@salesforcedevs/docs-components 1.27.18 → 1.27.19

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforcedevs/docs-components",
3
- "version": "1.27.18",
3
+ "version": "1.27.19",
4
4
  "description": "Docs Lightning web components for DSC",
5
5
  "license": "MIT",
6
6
  "main": "index.js",
@@ -25,5 +25,5 @@
25
25
  "@types/lodash.orderby": "4.6.9",
26
26
  "@types/lodash.uniqby": "4.7.9"
27
27
  },
28
- "gitHead": "39f762aa6e34b9a3607c0f3ce4c1ad445c79c3bc"
28
+ "gitHead": "e8a07ec5b69da0c6e7f65c2da19e6d6a64573047"
29
29
  }
@@ -3,6 +3,8 @@
3
3
  lwc:if={isVersionFetched}
4
4
  class="content-type content-type-reference"
5
5
  breadcrumbs={breadcrumbs}
6
+ share-title={shareTitle}
7
+ share-twitter-via={twitterVia}
6
8
  sidebar-header={sidebarHeader}
7
9
  sidebar-value={selectedSidebarValue}
8
10
  sidebar-content={navigation}
@@ -41,6 +41,8 @@ type NavigationItem = {
41
41
 
42
42
  export default class AmfReference extends LightningElement {
43
43
  @api breadcrumbs: string | null = null;
44
+ /** Optional Twitter "via" handle (e.g. SalesforceDevs) for social share; passed to doc-content-layout. */
45
+ @api twitterVia: string | null = null;
44
46
  @api sidebarHeader!: string;
45
47
  @api tocTitle?: string;
46
48
  @api tocOptions?: string;
@@ -1482,6 +1484,11 @@ export default class AmfReference extends LightningElement {
1482
1484
  return undefined;
1483
1485
  }
1484
1486
 
1487
+ /** Article name from breadcrumbs, used as share title (e.g. for social share). */
1488
+ get shareTitle(): string {
1489
+ return this.getArticleName() ?? "";
1490
+ }
1491
+
1485
1492
  handleSelectedItem(): void {
1486
1493
  // update topic view
1487
1494
  const { referenceId, amfId, type } = this.selectedTopic!;
@@ -25,10 +25,11 @@
25
25
  </div>
26
26
  <div class="content-body-container">
27
27
  <div class="content-body">
28
- <doc-breadcrumbs
29
- lwc:if={showBreadcrumbs}
30
- breadcrumbs={breadcrumbs}
31
- ></doc-breadcrumbs>
28
+ <div class="breadcrumb-row" lwc:if={showBreadcrumbs}>
29
+ <doc-breadcrumbs
30
+ breadcrumbs={breadcrumbs}
31
+ ></doc-breadcrumbs>
32
+ </div>
32
33
  <div class="read" lwc:if={showReadingTime}>
33
34
  <svg
34
35
  xmlns="http://www.w3.org/2000/svg"
@@ -44,6 +45,13 @@
44
45
  </svg>
45
46
  {readingTime} minute read
46
47
  </div>
48
+ <div class="share-below-read" lwc:if={showSocialShare}>
49
+ <doc-social-share
50
+ title={shareTitle}
51
+ url={shareUrl}
52
+ twitter-via={shareTwitterVia}
53
+ ></doc-social-share>
54
+ </div>
47
55
  <slot onslotchange={onSlotChange}></slot>
48
56
  <doc-sprig-survey
49
57
  lwc:if={shouldDisplayFeedback}
@@ -47,6 +47,15 @@ export default class ContentLayout extends LightningElement {
47
47
 
48
48
  @api readingTime?: number;
49
49
 
50
+ /** Optional document title for social share (e.g. article name from breadcrumbs). When set, share icons are shown on the breadcrumb row. */
51
+ @api shareTitle: string | null = null;
52
+
53
+ /** Optional URL for social share; defaults to current page URL when not set. */
54
+ @api shareUrl: string | null = null;
55
+
56
+ /** Optional Twitter "via" handle (e.g. SalesforceDevs) passed through to doc-social-share. */
57
+ @api shareTwitterVia: string | null = null;
58
+
50
59
  @api
51
60
  get breadcrumbs() {
52
61
  return this._breadcrumbs;
@@ -145,6 +154,11 @@ export default class ContentLayout extends LightningElement {
145
154
  );
146
155
  }
147
156
 
157
+ /** Social share icons are only shown when twitter-via is set. */
158
+ get showSocialShare(): boolean {
159
+ return this.showBreadcrumbs && !!this.shareTwitterVia;
160
+ }
161
+
148
162
  get showReadingTime(): boolean {
149
163
  return this.readingTime != null && this.readingTime > 1;
150
164
  }
@@ -0,0 +1,43 @@
1
+ :host {
2
+ display: inline-flex;
3
+ align-items: center;
4
+ }
5
+
6
+ .actions {
7
+ align-items: center;
8
+ display: grid;
9
+ grid-auto-flow: column;
10
+ grid-column-gap: var(--dx-g-spacing-sm, 12px);
11
+ }
12
+
13
+ .actions a {
14
+ margin-right: var(--dx-g-spacing-sm, 12px);
15
+ color: var(--dx-g-gray-30, #3e3e3c);
16
+ }
17
+
18
+ .actions a:last-of-type {
19
+ margin-right: 0;
20
+ }
21
+
22
+ .actions svg {
23
+ height: 1rem;
24
+ width: 1rem;
25
+ }
26
+
27
+ .actions svg.fill {
28
+ fill: currentcolor;
29
+ }
30
+
31
+ .actions svg.fill:hover {
32
+ fill: var(--dx-g-blue-vibrant-50, #0176d3);
33
+ }
34
+
35
+ .actions svg.stroke {
36
+ stroke: currentcolor;
37
+ fill: currentcolor;
38
+ }
39
+
40
+ .actions svg.stroke:hover {
41
+ stroke: var(--dx-g-blue-vibrant-50, #0176d3);
42
+ fill: var(--dx-g-blue-vibrant-50, #0176d3);
43
+ }
@@ -0,0 +1,62 @@
1
+ <template>
2
+ <div class="actions">
3
+ <a
4
+ class="fill"
5
+ href={shareTwitter}
6
+ target="_blank"
7
+ rel="noopener noreferrer"
8
+ id="Share-on-Twitter"
9
+ name="Share on Twitter"
10
+ aria-label="Share on Twitter (opens new tab)"
11
+ onclick={handleClick}
12
+ >
13
+ <svg
14
+ viewBox="0 0 18 14"
15
+ class="fill"
16
+ xmlns="http://www.w3.org/2000/svg"
17
+ >
18
+ <path
19
+ 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"
20
+ ></path>
21
+ </svg>
22
+ </a>
23
+ <a
24
+ href={shareLinkedIn}
25
+ target="_blank"
26
+ rel="noopener noreferrer"
27
+ id="Share-on-LinkedIn"
28
+ name="Share on LinkedIn"
29
+ aria-label="Share on LinkedIn (opens new tab)"
30
+ onclick={handleClick}
31
+ >
32
+ <svg
33
+ viewBox="0 0 16 17"
34
+ class="fill"
35
+ xmlns="http://www.w3.org/2000/svg"
36
+ >
37
+ <path
38
+ 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"
39
+ ></path>
40
+ </svg>
41
+ </a>
42
+ <a
43
+ href={shareFacebook}
44
+ target="_blank"
45
+ rel="noopener noreferrer"
46
+ id="Share-on-Facebook"
47
+ name="Share on Facebook"
48
+ aria-label="Share on Facebook (opens new tab)"
49
+ onclick={handleClick}
50
+ >
51
+ <svg
52
+ viewBox="0 0 9 18"
53
+ class="stroke"
54
+ xmlns="http://www.w3.org/2000/svg"
55
+ >
56
+ <path
57
+ 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"
58
+ ></path>
59
+ </svg>
60
+ </a>
61
+ </div>
62
+ </template>
@@ -0,0 +1,73 @@
1
+ import { LightningElement, api } from "lwc";
2
+ import { track } from "dxUtils/analytics";
3
+
4
+ /**
5
+ * Social share links for Twitter, LinkedIn, and Facebook.
6
+ * Renders share URLs that open in a new tab; intended to sit on the same row as breadcrumbs.
7
+ */
8
+ export default class SocialShare extends LightningElement {
9
+ /** Page/document title used for Twitter share text. */
10
+ @api title: string = "";
11
+
12
+ /** URL to share; defaults to current page URL when not set. */
13
+ @api url: string = "";
14
+
15
+ /** Optional Twitter "via" handle (e.g. SalesforceArchs, SalesforceDevs). */
16
+ @api twitterVia: string = "";
17
+
18
+ private get shareUrl(): string {
19
+ return (
20
+ this.url ||
21
+ (typeof window !== "undefined" ? window.location.href : "")
22
+ );
23
+ }
24
+
25
+ get shareTwitter(): string {
26
+ const text = encodeURIComponent(this.title || document?.title || "");
27
+ const urlParam = encodeURIComponent(this.shareUrl);
28
+ const via = this.twitterVia
29
+ ? `&via=${encodeURIComponent(this.twitterVia)}`
30
+ : "";
31
+ return `https://twitter.com/intent/tweet/?text=${text}&url=${urlParam}${via}`;
32
+ }
33
+
34
+ get shareLinkedIn(): string {
35
+ return `https://www.linkedin.com/sharing/share-offsite/?url=${encodeURI(
36
+ this.shareUrl
37
+ )}`;
38
+ }
39
+
40
+ get shareFacebook(): string {
41
+ return `https://www.facebook.com/sharer/sharer.php?u=${encodeURI(
42
+ this.shareUrl
43
+ )}`;
44
+ }
45
+
46
+ handleClick(event: Event): void {
47
+ const anchor = event.currentTarget as HTMLAnchorElement;
48
+ const platform =
49
+ anchor?.id === "Share-on-Twitter"
50
+ ? "Twitter"
51
+ : anchor?.id === "Share-on-LinkedIn"
52
+ ? "LinkedIn"
53
+ : anchor?.id === "Share-on-Facebook"
54
+ ? "Facebook"
55
+ : "Unknown";
56
+
57
+ track(this.template.host, "custEv_socialShare", {
58
+ share_platform: platform,
59
+ share_url: this.shareUrl,
60
+ share_title:
61
+ this.title ||
62
+ (typeof document !== "undefined" ? document.title : "")
63
+ });
64
+
65
+ this.dispatchEvent(
66
+ new CustomEvent("socialshareclick", {
67
+ bubbles: true,
68
+ composed: true,
69
+ detail: { platform }
70
+ })
71
+ );
72
+ }
73
+ }
@@ -8,6 +8,24 @@ doc-content-layout {
8
8
  --dx-c-sidebar-height: calc(100vh - var(--dx-g-global-header-height));
9
9
  }
10
10
 
11
+ .breadcrumb-row {
12
+ display: flex;
13
+ align-items: center;
14
+ justify-content: space-between;
15
+ gap: var(--dx-g-spacing-md);
16
+ margin-bottom: var(--dx-g-spacing-md);
17
+ }
18
+
19
+ .breadcrumb-row doc-breadcrumbs {
20
+ flex: 1;
21
+ min-width: 0;
22
+ margin-bottom: 0;
23
+ }
24
+
25
+ .breadcrumb-row doc-social-share {
26
+ flex-shrink: 0;
27
+ }
28
+
11
29
  doc-breadcrumbs {
12
30
  --dx-c-popover-z-index: 5;
13
31
 
@@ -33,11 +33,17 @@
33
33
  hide-badge={previewVersion}
34
34
  ></doc-version-picker>
35
35
  </div>
36
- <doc-breadcrumbs
37
- lwc:if={showBreadcrumbs}
38
- breadcrumbs={breadcrumbs}
39
- pixel-per-character={breadcrumbPixelPerCharacter}
40
- ></doc-breadcrumbs>
36
+ <div class="breadcrumb-row" lwc:if={showBreadcrumbs}>
37
+ <doc-breadcrumbs
38
+ breadcrumbs={breadcrumbs}
39
+ pixel-per-character={breadcrumbPixelPerCharacter}
40
+ ></doc-breadcrumbs>
41
+ <doc-social-share
42
+ lwc:if={showSocialShare}
43
+ title={shareTitle}
44
+ twitter-via={twitterVia}
45
+ ></doc-social-share>
46
+ </div>
41
47
  <doc-content
42
48
  docs-data={docContent}
43
49
  page-reference={pageReference}
@@ -42,6 +42,8 @@ export default class DocXmlContent extends LightningElementWithState<{
42
42
  @api apiDomain = "https://developer.salesforce.com";
43
43
  @api hideFooter = false;
44
44
  @api displayReadingTime = false;
45
+ /** Optional Twitter "via" handle (e.g. SalesforceDevs) for social share. */
46
+ @api twitterVia: string | null = null;
45
47
 
46
48
  @api
47
49
  get allLanguages(): Array<Language> {
@@ -679,6 +681,16 @@ export default class DocXmlContent extends LightningElementWithState<{
679
681
  return this.breadcrumbs.map((crumb) => crumb.label).join("/");
680
682
  }
681
683
 
684
+ /** Article name from breadcrumbs, used as share title (e.g. for social share). */
685
+ get shareTitle(): string {
686
+ return this.getArticleName() ?? "";
687
+ }
688
+
689
+ /** Social share icons are only shown when twitter-via is set. */
690
+ get showSocialShare(): boolean {
691
+ return !!this.twitterVia;
692
+ }
693
+
682
694
  private buildBreadcrumbs(): void {
683
695
  const { contentDocumentId } = this.pageReference;
684
696
  if (!contentDocumentId) {
@@ -17,6 +17,20 @@
17
17
  display: block;
18
18
  }
19
19
 
20
+ .breadcrumb-row {
21
+ display: flex;
22
+ align-items: center;
23
+ justify-content: space-between;
24
+ gap: var(--dx-g-spacing-md);
25
+ margin-bottom: var(--dx-g-spacing-2xl);
26
+ }
27
+
28
+ .breadcrumb-row doc-breadcrumbs {
29
+ flex: 1;
30
+ min-width: 0;
31
+ margin-bottom: 0;
32
+ }
33
+
20
34
  doc-breadcrumbs {
21
35
  --dx-c-popover-z-index: 5;
22
36
 
@@ -37,6 +51,11 @@ doc-breadcrumbs {
37
51
  flex-shrink: 0;
38
52
  }
39
53
 
54
+ .share-below-read {
55
+ margin-top: var(--dx-g-spacing-sm, 12px);
56
+ margin-bottom: var(--dx-g-spacing-lg, 16px);
57
+ }
58
+
40
59
  dx-sidebar,
41
60
  dx-sidebar-old {
42
61
  --dx-c-sidebar-vertical-padding: var(--dx-g-spacing-md);