@salesforcedevs/docs-components 1.34.4-final-alpha → 1.34.4-final-alpha1

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.34.4-final-alpha",
3
+ "version": "1.34.4-final-alpha1",
4
4
  "description": "Docs Lightning web components for DSC",
5
5
  "license": "MIT",
6
6
  "main": "index.js",
@@ -10,6 +10,15 @@ import { throttle } from "throttle-debounce";
10
10
  import { pollUntil } from "dxUtils/async";
11
11
  import { toJson } from "dxUtils/normalizers";
12
12
  import { oldVersionDocInfo } from "docUtils/utils";
13
+ import {
14
+ applyVersionToHref,
15
+ collectSubtreeCanonicalHrefs,
16
+ normalizePath,
17
+ getTopicVersionKey,
18
+ persistTopicVersion,
19
+ toCanonicalHref
20
+ } from "dxUtils/topicVersion";
21
+ import type { VersionedNode } from "dxUtils/topicVersion";
13
22
  import type { DocPhaseInfo, OptionWithLink } from "typings/custom";
14
23
 
15
24
  declare global {
@@ -47,6 +56,8 @@ type ReferenceVersion = {
47
56
  type ReferenceConfig = {
48
57
  refList: ReferenceItem[];
49
58
  versions?: ReferenceVersion[];
59
+ /** Sidebar topic name. Sidebar stores the selected version under this key. */
60
+ versionTopicKey?: string;
50
61
  };
51
62
 
52
63
  const SCROLL_THROTTLE_DELAY = 50;
@@ -129,6 +140,29 @@ export default class RedocReference extends LightningElement {
129
140
  */
130
141
  @api headerHref: string | null = null;
131
142
 
143
+ /**
144
+ * Versioned topic that owns this spec, including its children.
145
+ * Href matches this page, so an older version still has its version
146
+ * in the path.
147
+ */
148
+ @api
149
+ set parentTopicFamily(value: string | { topics?: VersionedNode[] } | null) {
150
+ try {
151
+ const parsed = toJson(value) as { topics?: VersionedNode[] } | null;
152
+ this._parentTopicFamilyNode = parsed?.topics?.[0] ?? null;
153
+ } catch (error) {
154
+ this._parentTopicFamilyNode = null;
155
+ }
156
+ }
157
+
158
+ get parentTopicFamily(): { topics?: VersionedNode[] } | null {
159
+ return this._parentTopicFamilyNode
160
+ ? { topics: [this._parentTopicFamilyNode] }
161
+ : null;
162
+ }
163
+
164
+ private _parentTopicFamilyNode: VersionedNode | null = null;
165
+
132
166
  @api
133
167
  get contentType(): string {
134
168
  return this._contentType;
@@ -233,13 +267,64 @@ export default class RedocReference extends LightningElement {
233
267
  private onBackClick = (event: Event): void => {
234
268
  event.preventDefault();
235
269
 
236
- const target = this.getTranslatedBackTarget() ?? this.headerHref;
270
+ const target = this.getVersionedBackTarget() ?? this.headerHref;
237
271
 
238
272
  if (target) {
239
273
  window.location.assign(target);
240
274
  }
241
275
  };
242
276
 
277
+ /**
278
+ * When the back target is in this spec's topic, return it on the
279
+ * selected version. With no back target, do the same for the header
280
+ * link when that link is the versioned parent.
281
+ */
282
+ private getVersionedBackTarget(): string | null {
283
+ const stored = this.getTranslatedBackTarget();
284
+ const selectedVersion = this.selectedVersion;
285
+ const target = stored ?? this.headerHref;
286
+ if (!target || !selectedVersion) {
287
+ return stored;
288
+ }
289
+
290
+ let targetUrl: URL;
291
+ try {
292
+ targetUrl = new URL(target, window.location.origin);
293
+ } catch {
294
+ return target;
295
+ }
296
+
297
+ // Family hrefs match this page's version. Compare them without
298
+ // the version segment. Rewrite only the pathname so the target's
299
+ // query and hash survive.
300
+ const familyHrefs = this._parentTopicFamilyNode
301
+ ? collectSubtreeCanonicalHrefs(this._parentTopicFamilyNode).map(
302
+ (href) => toCanonicalHref(href, this.versions)
303
+ )
304
+ : [];
305
+
306
+ const canonicalTarget = toCanonicalHref(
307
+ targetUrl.pathname,
308
+ this.versions
309
+ );
310
+ const inFamily = familyHrefs.some(
311
+ (href) => normalizePath(href) === normalizePath(canonicalTarget)
312
+ );
313
+ if (!inFamily) {
314
+ return target;
315
+ }
316
+
317
+ const versioned = applyVersionToHref(
318
+ canonicalTarget,
319
+ selectedVersion,
320
+ this.versions
321
+ );
322
+ if (!versioned) {
323
+ return target;
324
+ }
325
+ return `${versioned}${targetUrl.search}${targetUrl.hash}`;
326
+ }
327
+
243
328
  private getTranslatedBackTarget(): string | null {
244
329
  const stored = this.getBackTargetFromSession();
245
330
  if (stored) {
@@ -362,6 +447,13 @@ export default class RedocReference extends LightningElement {
362
447
  // Track the back target, preserving it across locale switches
363
448
  this.trackBackTarget();
364
449
 
450
+ // Remember the selected version for the sidebar. Changing version
451
+ // reloads this page.
452
+ const topicKey = this.getParentTopicVersionKey();
453
+ if (topicKey && this.selectedVersion) {
454
+ persistTopicVersion(topicKey, this.selectedVersion.id);
455
+ }
456
+
365
457
  window.addEventListener("scroll", this.handleScrollAndResize);
366
458
  window.addEventListener("resize", this.handleScrollAndResize);
367
459
  }
@@ -670,6 +762,18 @@ export default class RedocReference extends LightningElement {
670
762
  return wrapper;
671
763
  }
672
764
 
765
+ /**
766
+ * Key the sidebar uses for this topic's selected version.
767
+ * Missing `versionTopicKey` returns null so nothing is written.
768
+ */
769
+ private getParentTopicVersionKey(): string | null {
770
+ const versionTopicKey = this._referenceConfig?.versionTopicKey;
771
+ if (!versionTopicKey) {
772
+ return null;
773
+ }
774
+ return getTopicVersionKey({ name: versionTopicKey }) || null;
775
+ }
776
+
673
777
  /** Stashes the current view (URL hash) before the version link navigates. */
674
778
  private onVersionChange = (): void => {
675
779
  sessionStorage.setItem(