@salesforcedevs/docs-components 1.27.18 → 1.27.20

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.20",
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": "60eb447eed07d2493cf56436f267fab0d95e48fb"
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}
@@ -16,6 +18,7 @@
16
18
  language={language}
17
19
  show-footer={enableFooter}
18
20
  empty-state-message={emptyStateMessage}
21
+ origin={origin}
19
22
  >
20
23
  <doc-phase
21
24
  slot="doc-phase"
@@ -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;
@@ -48,6 +50,9 @@ export default class AmfReference extends LightningElement {
48
50
  @api languages!: OptionWithLink[];
49
51
  @api language!: string;
50
52
  @api hideFooter = false;
53
+
54
+ /** Optional origin URL for the footer MFE (e.g. wp-json endpoint). Passed through to dx-footer-mfe. */
55
+ @api origin: string | null = null;
51
56
  @track navigation = [] as NavigationItem[];
52
57
  @track versions: Array<ReferenceVersion> = [];
53
58
  @track showVersionBanner = false;
@@ -1482,6 +1487,11 @@ export default class AmfReference extends LightningElement {
1482
1487
  return undefined;
1483
1488
  }
1484
1489
 
1490
+ /** Article name from breadcrumbs, used as share title (e.g. for social share). */
1491
+ get shareTitle(): string {
1492
+ return this.getArticleName() ?? "";
1493
+ }
1494
+
1485
1495
  handleSelectedItem(): void {
1486
1496
  // update topic view
1487
1497
  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}
@@ -58,7 +66,10 @@
58
66
  </div>
59
67
  </div>
60
68
  <div lwc:if={showFooter} class="footer-container">
61
- <dx-footer variant="no-signup"></dx-footer>
69
+ <dx-footer
70
+ variant="no-signup"
71
+ mfe-config-origin={effectiveFooterOrigin}
72
+ ></dx-footer>
62
73
  </div>
63
74
  </div>
64
75
  </div>
@@ -47,6 +47,18 @@ 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
+
59
+ /** Optional origin URL for the footer MFE (e.g. wp-json endpoint). Passed through to dx-footer. */
60
+ @api origin: string | null = null;
61
+
50
62
  @api
51
63
  get breadcrumbs() {
52
64
  return this._breadcrumbs;
@@ -145,10 +157,22 @@ export default class ContentLayout extends LightningElement {
145
157
  );
146
158
  }
147
159
 
160
+ /** Social share icons are only shown when twitter-via is set. */
161
+ get showSocialShare(): boolean {
162
+ return this.showBreadcrumbs && !!this.shareTwitterVia;
163
+ }
164
+
148
165
  get showReadingTime(): boolean {
149
166
  return this.readingTime != null && this.readingTime > 1;
150
167
  }
151
168
 
169
+ /** When origin is provided, pass it to the footer; otherwise use dx-footer's default. */
170
+ get effectiveFooterOrigin(): string {
171
+ return (
172
+ this.origin ?? `${window.location.origin}/developer/en-us/wp-json`
173
+ );
174
+ }
175
+
152
176
  connectedCallback(): void {
153
177
  const hasParentHighlightListener = closest(
154
178
  "doc-xml-content",
@@ -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
 
@@ -13,6 +13,7 @@
13
13
  bail-label={sidebarFooterContent.bailLabel}
14
14
  show-footer={enableFooter}
15
15
  reading-time={computedReadingTime}
16
+ origin={origin}
16
17
  >
17
18
  <doc-phase
18
19
  slot="version-banner"
@@ -33,11 +34,17 @@
33
34
  hide-badge={previewVersion}
34
35
  ></doc-version-picker>
35
36
  </div>
36
- <doc-breadcrumbs
37
- lwc:if={showBreadcrumbs}
38
- breadcrumbs={breadcrumbs}
39
- pixel-per-character={breadcrumbPixelPerCharacter}
40
- ></doc-breadcrumbs>
37
+ <div class="breadcrumb-row" lwc:if={showBreadcrumbs}>
38
+ <doc-breadcrumbs
39
+ breadcrumbs={breadcrumbs}
40
+ pixel-per-character={breadcrumbPixelPerCharacter}
41
+ ></doc-breadcrumbs>
42
+ <doc-social-share
43
+ lwc:if={showSocialShare}
44
+ title={shareTitle}
45
+ twitter-via={twitterVia}
46
+ ></doc-social-share>
47
+ </div>
41
48
  <doc-content
42
49
  docs-data={docContent}
43
50
  page-reference={pageReference}
@@ -42,6 +42,11 @@ 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;
47
+
48
+ /** Optional origin URL for the footer MFE (e.g. wp-json endpoint). Passed through to dx-footer-mfe. */
49
+ @api origin: string | null = null;
45
50
 
46
51
  @api
47
52
  get allLanguages(): Array<Language> {
@@ -679,6 +684,16 @@ export default class DocXmlContent extends LightningElementWithState<{
679
684
  return this.breadcrumbs.map((crumb) => crumb.label).join("/");
680
685
  }
681
686
 
687
+ /** Article name from breadcrumbs, used as share title (e.g. for social share). */
688
+ get shareTitle(): string {
689
+ return this.getArticleName() ?? "";
690
+ }
691
+
692
+ /** Social share icons are only shown when twitter-via is set. */
693
+ get showSocialShare(): boolean {
694
+ return !!this.twitterVia;
695
+ }
696
+
682
697
  private buildBreadcrumbs(): void {
683
698
  const { contentDocumentId } = this.pageReference;
684
699
  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);