@salesforcedevs/docs-components 0.57.1-flex-ref1 → 0.61.1

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/LICENSE ADDED
@@ -0,0 +1,12 @@
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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforcedevs/docs-components",
3
- "version": "0.57.1-flex-ref1",
3
+ "version": "0.61.1",
4
4
  "description": "Docs Lightning web components for DSC",
5
5
  "license": "MIT",
6
6
  "main": "index.js",
@@ -24,5 +24,5 @@
24
24
  "@types/lodash.orderby": "^4.6.7",
25
25
  "@types/lodash.uniqby": "^4.7.7"
26
26
  },
27
- "gitHead": "4629fdd9ca18a13480044ad43515b91945d16aad"
27
+ "gitHead": "6e9bf005600ca7a99a22b99cf5d5e0618590d9ce"
28
28
  }
@@ -4,12 +4,13 @@
4
4
  :host {
5
5
  display: flex;
6
6
  align-items: center;
7
+ justify-content: center;
7
8
  width: fit-content;
8
9
  }
9
10
 
10
11
  :host(.breadcrumb_long) {
11
12
  /* ensure 30 character min-width */
12
- min-width: 245px;
13
+ min-width: 200px;
13
14
  }
14
15
 
15
16
  :host(.breadcrumb_back-arrow) {
@@ -4,6 +4,8 @@
4
4
  :host {
5
5
  --dx-c-breadcrumbs-title-color: var(--dx-g-blue-vibrant-20);
6
6
  --dx-c-breadcrumbs-breadcrumb-color: var(--dx-g-blue-vibrant-20);
7
+
8
+ font-family: var(--dx-g-font-sans);
7
9
  }
8
10
 
9
11
  nav {
@@ -36,7 +36,7 @@
36
36
  analytics-event={analyticsEventName}
37
37
  analytics-base-payload={analyticsBasePayload}
38
38
  href={breadcrumb.href}
39
- key={breadcrumb.label}
39
+ key={breadcrumb.id}
40
40
  label={breadcrumb.label}
41
41
  ></doc-breadcrumb-item>
42
42
  <span class="breadcrumb-item_slash" key={breadcrumb.label}>
@@ -8,10 +8,12 @@ type BreadcrumbConfig = {
8
8
  };
9
9
 
10
10
  const GAP = 8;
11
+
12
+ // Unit in pixels based on Salesforce Sans font-family.
11
13
  const CONSTANTS = {
12
- pixelPerCharacter: 7.2,
13
- pixelPerCrumbSpace: GAP * 2 + 4.6,
14
- minWidthPerCrumb: 245,
14
+ pixelPerCharacter: 7.7,
15
+ pixelPerCrumbSpace: GAP * 2 + 8.6,
16
+ minWidthPerCrumb: 200,
15
17
  dropdownWidth: 32
16
18
  };
17
19
 
@@ -29,15 +31,26 @@ export default class Breadcrumbs extends LightningElement {
29
31
  get breadcrumbs(): Breadcrumb[] {
30
32
  return this._breadcrumbs;
31
33
  }
34
+
32
35
  set breadcrumbs(value) {
33
- this._breadcrumbs = toJson(value) || [];
36
+ this.normalizeAndAssignBreadcrumbs(value);
34
37
  this.calculateBreadcrumbsConfigs();
35
38
  if (this.observer) {
36
39
  this.updateDropdownOptionAmount();
37
40
  }
38
41
  }
39
42
 
43
+ @api
44
+ get pixelPerCharacter(): number {
45
+ return this._pixelPerCharacter;
46
+ }
47
+
48
+ set pixelPerCharacter(value: number | string) {
49
+ this._pixelPerCharacter = +value;
50
+ }
51
+
40
52
  private _breadcrumbs: Breadcrumb[] = [];
53
+ private _pixelPerCharacter = CONSTANTS.pixelPerCharacter;
41
54
  private navWidth = 0;
42
55
  private observer: ResizeObserver | null = null;
43
56
  private breadcrumbConfigs: BreadcrumbConfig[] = [];
@@ -72,7 +85,7 @@ export default class Breadcrumbs extends LightningElement {
72
85
  private get dropdownOptions(): OptionWithLink[] {
73
86
  return this.breadcrumbs!.slice(1, this.dropdownOptionAmount! + 1).map(
74
87
  (link) => ({
75
- id: link.href!,
88
+ id: link.id!,
76
89
  label: link.label,
77
90
  link: { href: link.href! }
78
91
  })
@@ -118,6 +131,17 @@ export default class Breadcrumbs extends LightningElement {
118
131
  this.observer?.disconnect();
119
132
  }
120
133
 
134
+ private normalizeAndAssignBreadcrumbs(breadcrumbs?: Breadcrumb[] | string) {
135
+ if (!breadcrumbs) {
136
+ return;
137
+ }
138
+
139
+ this._breadcrumbs = toJson(breadcrumbs).map((crumb: Breadcrumb) => ({
140
+ ...crumb,
141
+ id: crumb.id || crumb.href
142
+ }));
143
+ }
144
+
121
145
  private updateDropdownOptionAmount(): void {
122
146
  this.dropdownOptionAmount = this.breadcrumbConfigs.find(
123
147
  ({ minWidth }) => minWidth <= this.navWidth
@@ -150,7 +174,8 @@ export default class Breadcrumbs extends LightningElement {
150
174
  (previousValue, element) =>
151
175
  previousValue +
152
176
  Math.min(
153
- element.label.length * CONSTANTS.pixelPerCharacter,
177
+ element.label.length *
178
+ (this.pixelPerCharacter || CONSTANTS.pixelPerCharacter),
154
179
  CONSTANTS.minWidthPerCrumb
155
180
  ),
156
181
  (breadcrumbs.length - 1) * CONSTANTS.pixelPerCrumbSpace + offset
@@ -4,12 +4,19 @@
4
4
  display: block;
5
5
  }
6
6
 
7
+ doc-breadcrumbs {
8
+ --dx-c-popover-z-index: 5;
9
+
10
+ display: block;
11
+ margin-bottom: var(--dx-g-spacing-2xl);
12
+ }
13
+
7
14
  dx-sidebar,
8
15
  dx-sidebar-old {
9
16
  --dx-c-sidebar-height: 100%;
10
17
  --dx-c-sidebar-vertical-padding: var(--dx-c-content-vertical-spacing);
11
18
 
12
- z-index: 5;
19
+ z-index: 6;
13
20
  }
14
21
 
15
22
  dx-toc {
@@ -56,11 +63,6 @@ dx-toc {
56
63
  max-width: 275px;
57
64
  }
58
65
 
59
- dx-breadcrumbs {
60
- display: block;
61
- margin-bottom: var(--dx-g-spacing-2xl);
62
- }
63
-
64
66
  @media screen and (max-width: 1024px) {
65
67
  .right-nav-bar {
66
68
  display: none;
@@ -68,10 +70,6 @@ dx-breadcrumbs {
68
70
  }
69
71
 
70
72
  @media screen and (max-width: 800px) {
71
- dx-breadcrumbs {
72
- display: none;
73
- }
74
-
75
73
  .content-body {
76
74
  margin-top: var(--dx-c-content-vertical-spacing);
77
75
  }
@@ -28,17 +28,10 @@
28
28
  <slot name="doc-phase"></slot>
29
29
  <div class="content-body-container">
30
30
  <div class="content-body">
31
- <dx-breadcrumbs
31
+ <doc-breadcrumbs
32
32
  if:true={breadcrumbs}
33
33
  breadcrumbs={breadcrumbs}
34
- truncate
35
- hide-current-location
36
- ></dx-breadcrumbs>
37
- <dx-breadcrumbs
38
- if:false={breadcrumbs}
39
- pathname={pathname}
40
- hide-current-location
41
- ></dx-breadcrumbs>
34
+ ></doc-breadcrumbs>
42
35
  <slot onslotchange={onSlotChange}></slot>
43
36
  </div>
44
37
  <div class="right-nav-bar is-sticky">
@@ -24,6 +24,7 @@ export type TreeNode = {
24
24
  name: string;
25
25
  children?: Array<TreeNode>;
26
26
  isExpanded?: boolean;
27
+ parent?: TreeNode;
27
28
  };
28
29
 
29
30
  type DropdownOption = {
@@ -109,3 +110,5 @@ export type ContentApiOptions = {
109
110
  version: string;
110
111
  language: string;
111
112
  };
113
+
114
+ export type TocMap = { [key: string]: TreeNode };
@@ -8,7 +8,8 @@ import {
8
8
  DocumentData,
9
9
  DocLanguage,
10
10
  DocVersion,
11
- TreeNode
11
+ TreeNode,
12
+ TocMap
12
13
  } from "./types";
13
14
  import { Language } from "typings/custom";
14
15
  import { getLanguageDisplayTextById } from "dxUtils/language";
@@ -100,26 +101,26 @@ export class FetchContent {
100
101
 
101
102
  private normalizeNavItem(
102
103
  navItem: ApiNavItem,
103
- tocMap: { [key: string]: TreeNode }
104
+ tocMap: TocMap,
105
+ parentNavItem?: TreeNode
104
106
  ): TreeNode {
105
107
  const name = this.calculateNavItemName(navItem, tocMap);
106
108
  const node: TreeNode = {
107
109
  label: navItem.text,
108
- name
110
+ name,
111
+ parent: parentNavItem
109
112
  };
113
+
110
114
  if (name) {
111
115
  tocMap[name] = node;
112
116
  }
113
117
  node.children = navItem.children?.map((child) =>
114
- this.normalizeNavItem(child, tocMap)
118
+ this.normalizeNavItem(child, tocMap, node)
115
119
  );
116
120
  return node;
117
121
  }
118
122
 
119
- private calculateNavItemName(
120
- navItem: ApiNavItem,
121
- tocMap: { [key: string]: TreeNode }
122
- ): string {
123
+ private calculateNavItemName(navItem: ApiNavItem, tocMap: TocMap): string {
123
124
  let href = navItem.a_attr?.href || "";
124
125
  if (href.includes("#")) {
125
126
  const [pathUrl] = href.split("#");
@@ -144,11 +145,13 @@ export class FetchContent {
144
145
  }
145
146
 
146
147
  private normalizeLanguage(language: ApiDocLanguage): DocLanguage {
147
-
148
148
  return (
149
149
  language && {
150
- label: getLanguageDisplayTextById(this.languages, language.locale) ||
151
- language.label,
150
+ label:
151
+ getLanguageDisplayTextById(
152
+ this.languages,
153
+ language.locale
154
+ ) || language.label,
152
155
  id: language.locale,
153
156
  code: language.code,
154
157
  url: language.url
@@ -3,6 +3,11 @@
3
3
  --button-primary-color-hover: var(--dx-g-blue-vibrant-40);
4
4
  }
5
5
 
6
+ doc-breadcrumbs {
7
+ display: block;
8
+ margin-bottom: var(--dx-g-spacing-2xl);
9
+ }
10
+
6
11
  dx-dropdown {
7
12
  --dx-c-dropdown-option-font-size: var(--dx-g-text-sm);
8
13
  }
@@ -25,6 +25,11 @@
25
25
  </dx-button>
26
26
  </dx-dropdown>
27
27
  </div>
28
+ <doc-breadcrumbs
29
+ if:true={breadcrumbs}
30
+ breadcrumbs={breadcrumbs}
31
+ pixel-per-character={breadcrumbPixelPerCharacter}
32
+ ></doc-breadcrumbs>
28
33
  <doc-content
29
34
  docs-data={docContent}
30
35
  page-reference={pageReference}
@@ -8,15 +8,26 @@ import {
8
8
  TreeNode,
9
9
  Header,
10
10
  HistoryState,
11
- PageReference
11
+ PageReference,
12
+ TocMap
12
13
  } from "./types";
13
14
  import { SearchSyncer } from "docUtils/SearchSyncer";
14
15
  import { LightningElementWithState } from "docBaseElements/lightningElementWithState";
15
- import { Language } from "typings/custom";
16
+ import { Breadcrumb, Language } from "typings/custom";
16
17
 
17
18
  // TODO: Imitating from actual implementation as doc-content use it like this. We should refactor it later.
18
19
  const handleContentError = (error): void => console.log(error);
19
20
 
21
+ const FIRST_CRUMB = {
22
+ href: "/docs",
23
+ label: "Documentation"
24
+ };
25
+
26
+ const PIXEL_PER_CHARACTER_MAP: { [key: string]: number } = {
27
+ default: 7.7,
28
+ "ja-jp": 12.5
29
+ };
30
+
20
31
  export default class DocXmlContent extends LightningElementWithState<{
21
32
  isFetchingDocument: boolean;
22
33
  isFetchingContent: boolean;
@@ -53,7 +64,7 @@ export default class DocXmlContent extends LightningElementWithState<{
53
64
  private language: DocLanguage = null;
54
65
  private loaded = false;
55
66
  private pdfUrl = "";
56
- private tocMap = null;
67
+ private tocMap: TocMap = {};
57
68
  private sidebarContent: Array<TreeNode> = null;
58
69
  private version: DocVersion = null;
59
70
  private docTitle = "";
@@ -102,6 +113,7 @@ export default class DocXmlContent extends LightningElementWithState<{
102
113
  private _allLanguages: Array<Language> = [];
103
114
 
104
115
  @track private pageReference: PageReference = {};
116
+ @track breadcrumbs: Array<Breadcrumb> = [];
105
117
 
106
118
  constructor() {
107
119
  super();
@@ -267,6 +279,13 @@ export default class DocXmlContent extends LightningElementWithState<{
267
279
  }));
268
280
  }
269
281
 
282
+ private get breadcrumbPixelPerCharacter() {
283
+ return (
284
+ PIXEL_PER_CHARACTER_MAP[this.language.id] ||
285
+ PIXEL_PER_CHARACTER_MAP.default
286
+ );
287
+ }
288
+
270
289
  private handlePopState = (): void =>
271
290
  this.updatePageReference(this.getReferenceFromUrl());
272
291
 
@@ -280,15 +299,15 @@ export default class DocXmlContent extends LightningElementWithState<{
280
299
 
281
300
  if (name) {
282
301
  const hashIndex = name.indexOf("#");
283
- this.pageReference.hash =
284
- hashIndex > -1 ? name.slice(hashIndex) : "";
285
-
286
- const contentId = hashIndex > -1 ? name.slice(0, hashIndex) : name;
287
- if (this.pageReference.contentDocumentId !== contentId) {
288
- this.pageReference.contentDocumentId = contentId;
289
- this.fetchContent().catch(handleContentError);
290
- }
291
-
302
+ const hash = hashIndex > -1 ? name.slice(hashIndex) : "";
303
+
304
+ const contentDocumentId =
305
+ hashIndex > -1 ? name.slice(0, hashIndex) : name;
306
+ this.updatePageReference({
307
+ ...this.pageReference,
308
+ contentDocumentId,
309
+ hash
310
+ });
292
311
  this.updateUrl();
293
312
  }
294
313
  }
@@ -321,15 +340,17 @@ export default class DocXmlContent extends LightningElementWithState<{
321
340
  return;
322
341
  }
323
342
 
324
- const isSameDocId = this.pageReference.docId !== newPageReference.docId;
343
+ const isSameDocId = this.pageReference.docId === newPageReference.docId;
325
344
  this.pageReference = newPageReference;
326
345
 
327
- if (isSameDocId) {
346
+ if (!isSameDocId) {
328
347
  this.fetchDocument();
329
348
  return;
330
349
  }
331
350
 
332
- this.fetchContent().catch(handleContentError);
351
+ this.fetchContent()
352
+ .then(() => this.buildBreadcrumbs())
353
+ .catch(handleContentError);
333
354
  }
334
355
 
335
356
  getReferenceFromUrl(): PageReference {
@@ -386,6 +407,8 @@ export default class DocXmlContent extends LightningElementWithState<{
386
407
 
387
408
  this.updateHeader();
388
409
 
410
+ this.buildBreadcrumbs();
411
+
389
412
  if (this.pageReference.deliverable !== data.deliverable) {
390
413
  this.pageReference.deliverable = data.deliverable;
391
414
  this.updateUrl(HistoryState.REPLACE_STATE);
@@ -558,6 +581,32 @@ export default class DocXmlContent extends LightningElementWithState<{
558
581
  );
559
582
  }
560
583
 
584
+ private buildBreadcrumbs(): void {
585
+ const { contentDocumentId } = this.pageReference;
586
+ if (!contentDocumentId) {
587
+ return;
588
+ }
589
+
590
+ const currentNode = this.tocMap[contentDocumentId];
591
+ this.breadcrumbs = this.nodeToBreadcrumb(currentNode);
592
+ }
593
+
594
+ private nodeToBreadcrumb(node?: TreeNode): Breadcrumb[] {
595
+ if (!node) {
596
+ return [FIRST_CRUMB];
597
+ }
598
+ return [
599
+ ...this.nodeToBreadcrumb(node.parent),
600
+ {
601
+ href: this.pageReferenceToString({
602
+ ...this.pageReference,
603
+ contentDocumentId: node.name
604
+ }),
605
+ label: node.label
606
+ }
607
+ ];
608
+ }
609
+
561
610
  addMetatags(): void {
562
611
  const div = document.createElement("div");
563
612
  div.innerHTML = this.docContent;