@fluid-topics/ft-reader-toc 0.3.9 → 0.3.12

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.
@@ -1,21 +1,51 @@
1
- import { TemplateResult } from "lit";
2
- import { ElementDefinitionsMap } from "@fluid-topics/ft-wc-utils";
1
+ import { PropertyValues, TemplateResult } from "lit";
2
+ import { ElementDefinitionsMap, ParametrizedLabels } from "@fluid-topics/ft-wc-utils";
3
3
  import { FtReaderComponent } from "@fluid-topics/ft-reader-context/build/registration";
4
+ import { FtIconVariants } from "@fluid-topics/ft-icon";
4
5
  export interface FtReaderTocProperties {
6
+ expanded?: boolean;
7
+ iconVariant?: FtIconVariants;
8
+ collapseIcon?: string;
9
+ expandIcon?: string;
10
+ autoCollapse?: boolean;
5
11
  }
12
+ export interface FtReaderTocLabels extends ParametrizedLabels {
13
+ expand?: string;
14
+ collapse?: string;
15
+ }
16
+ export declare const DEFAULT_LABELS: FtReaderTocLabels;
6
17
  export declare const FtReaderTocCssVariables: {
7
- colorPrimary: import("@fluid-topics/ft-wc-utils").FtCssVariable;
8
- colorOnPrimary: import("@fluid-topics/ft-wc-utils").FtCssVariable;
9
18
  tabulationSize: import("@fluid-topics/ft-wc-utils").FtCssVariable;
19
+ verticalSpacing: import("@fluid-topics/ft-wc-utils").FtCssVariable;
20
+ textColor: import("@fluid-topics/ft-wc-utils").FtCssVariable;
21
+ highlightedTextColor: import("@fluid-topics/ft-wc-utils").FtCssVariable;
22
+ highlightedFontWeight: import("@fluid-topics/ft-wc-utils").FtCssVariable;
23
+ highlightedBackgroundColor: import("@fluid-topics/ft-wc-utils").FtCssVariable;
24
+ iconFontSize: import("@fluid-topics/ft-wc-utils").FtCssVariable;
10
25
  };
11
26
  export declare class FtReaderToc extends FtReaderComponent implements FtReaderTocProperties {
12
27
  static elementDefinitions: ElementDefinitionsMap;
13
28
  static styles: import("lit").CSSResult;
29
+ expanded: boolean;
30
+ iconVariant: FtIconVariants;
31
+ collapseIcon: string;
32
+ expandIcon: string;
33
+ autoCollapse: boolean;
34
+ labels: FtReaderTocLabels;
35
+ private labelResolver;
14
36
  private toc?;
15
37
  private splitToc?;
16
38
  private currentPage?;
17
39
  private visibleTopics?;
40
+ private automaticallyExpandedNodes;
41
+ private manuallyExpandedNodes;
42
+ private manuallyCollapsedNodes;
43
+ private viewportSize;
44
+ protected update(changedProperties: PropertyValues): void;
18
45
  protected render(): TemplateResult<1>;
19
46
  private renderNode;
47
+ private buildAutomaticallyExpandedNodes;
48
+ private manuallyToggle;
49
+ private onViewportSizeChange;
20
50
  }
21
51
  //# sourceMappingURL=ft-reader-toc.d.ts.map
@@ -6,20 +6,64 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  };
7
7
  import { css, html, nothing } from "lit";
8
8
  import { repeat } from "lit/directives/repeat.js";
9
- import { designSystemVariables, FtCssVariableFactory, redux } from "@fluid-topics/ft-wc-utils";
9
+ import { classMap } from "lit/directives/class-map.js";
10
+ import { styleMap } from "lit/directives/style-map.js";
11
+ import { property, state } from "lit/decorators.js";
12
+ import { deepEqual, designSystemVariables, FtCssVariableFactory, jsonProperty, ParametrizedLabelResolver, redux, setVariable } from "@fluid-topics/ft-wc-utils";
10
13
  import { FtReaderComponent, } from "@fluid-topics/ft-reader-context/build/registration";
11
- import { FtTypography } from "@fluid-topics/ft-typography";
14
+ import { FtTypography, FtTypographyCssVariables } from "@fluid-topics/ft-typography";
12
15
  import { FtReaderInternalLink } from "@fluid-topics/ft-reader-internal-link";
16
+ import { FtIconVariants } from "@fluid-topics/ft-icon";
17
+ import { FtButton, FtButtonCssVariables } from "@fluid-topics/ft-button";
18
+ import { FtSizeCategory, FtSizeWatcher } from "@fluid-topics/ft-size-watcher";
19
+ export const DEFAULT_LABELS = {
20
+ expand: "Expand {0}",
21
+ collapse: "Collapse {0}",
22
+ };
13
23
  export const FtReaderTocCssVariables = {
14
- colorPrimary: FtCssVariableFactory.external(designSystemVariables.colorPrimary, "Design system"),
15
- colorOnPrimary: FtCssVariableFactory.external(designSystemVariables.colorOnPrimary, "Design system"),
16
- tabulationSize: FtCssVariableFactory.create("--ft-reader-toc-tabulation-size", "SIZE", "8px"),
24
+ tabulationSize: FtCssVariableFactory.create("--ft-reader-toc-tabulation-size", "SIZE", "16px"),
25
+ verticalSpacing: FtCssVariableFactory.create("--ft-reader-toc-vertical-spacing", "SIZE", "4px"),
26
+ textColor: FtCssVariableFactory.extend("--ft-reader-toc-text-color", designSystemVariables.colorOnSurface),
27
+ highlightedTextColor: FtCssVariableFactory.extend("--ft-reader-toc-highlighted-text-color", designSystemVariables.colorPrimary),
28
+ highlightedFontWeight: FtCssVariableFactory.create("--ft-reader-toc-highlighted-font-weight", "UNKNOWN", "bold"),
29
+ highlightedBackgroundColor: FtCssVariableFactory.create("--ft-reader-toc-highlighted-background-color", "COLOR", "transparent"),
30
+ iconFontSize: FtCssVariableFactory.create("--ft-reader-toc-icon-font-size", "SIZE", "16px"),
17
31
  };
18
32
  export class FtReaderToc extends FtReaderComponent {
33
+ constructor() {
34
+ super(...arguments);
35
+ this.expanded = false;
36
+ this.iconVariant = FtIconVariants.fluid_topics;
37
+ this.collapseIcon = "MINUS";
38
+ this.expandIcon = "PLUS";
39
+ this.autoCollapse = false;
40
+ this.labels = {};
41
+ this.labelResolver = new ParametrizedLabelResolver(DEFAULT_LABELS, {});
42
+ this.automaticallyExpandedNodes = new Set();
43
+ this.manuallyExpandedNodes = new Set();
44
+ this.manuallyCollapsedNodes = new Set();
45
+ this.viewportSize = FtSizeCategory.M;
46
+ }
47
+ update(changedProperties) {
48
+ var _a, _b;
49
+ super.update(changedProperties);
50
+ if (changedProperties.has("labels")) {
51
+ this.labelResolver = new ParametrizedLabelResolver(DEFAULT_LABELS, this.labels);
52
+ }
53
+ if (!this.expanded && ["splitToc", "visibleTopics", "currentPage", "toc"].some(p => changedProperties.has(p))) {
54
+ this.automaticallyExpandedNodes = this.buildAutomaticallyExpandedNodes(this.splitToc ? [(_a = this.currentPage) === null || _a === void 0 ? void 0 : _a.rootTocId] : (_b = this.visibleTopics) !== null && _b !== void 0 ? _b : []);
55
+ }
56
+ }
19
57
  render() {
20
58
  var _a;
59
+ const classes = {
60
+ "ft-reader-toc": true,
61
+ "ft-reader-toc-mobile": this.viewportSize === FtSizeCategory.S,
62
+ "ft-reader-toc-desktop": this.viewportSize !== FtSizeCategory.S
63
+ };
21
64
  return html `
22
- <div class="ft-reader-toc">
65
+ <div class=${classMap(classes)}>
66
+ <ft-size-watcher @change=${this.onViewportSizeChange}></ft-size-watcher>
23
67
  ${repeat((_a = this.toc) !== null && _a !== void 0 ? _a : [], node => node.tocId, node => this.renderNode(node))}
24
68
  </div>
25
69
  `;
@@ -28,36 +72,134 @@ export class FtReaderToc extends FtReaderComponent {
28
72
  var _a, _b;
29
73
  const shouldSplit = this.splitToc && node.page != null && !node.page.onItsOwn;
30
74
  const isHighlighted = this.splitToc ? ((_a = this.currentPage) === null || _a === void 0 ? void 0 : _a.rootTocId) === node.tocId : (_b = this.visibleTopics) === null || _b === void 0 ? void 0 : _b.includes(node.tocId);
75
+ const isExpanded = this.expanded || this.manuallyExpandedNodes.has(node.tocId) || (this.automaticallyExpandedNodes.has(node.tocId) && !this.manuallyCollapsedNodes.has(node.tocId));
76
+ const canDisplayChildren = !shouldSplit && node.children.length > 0;
77
+ const displayToggle = canDisplayChildren && !this.expanded;
78
+ const styles = {
79
+ "padding-left": `calc( ${FtReaderTocCssVariables.tabulationSize} * ${node.depth - 1} + 4px)` // +4px for padding before button
80
+ };
31
81
  return html `
32
- <div class="ft-reader-toc--node">
33
- <ft-reader-internal-link
34
- class="${isHighlighted ? "ft-reader-toc--node-visible" : ""}"
35
- tocId=${node.tocId}>
36
- <ft-typography variant="body2">${node.title}</ft-typography>
37
- </ft-reader-internal-link>
38
- <div class="ft-reader-toc--node-children">
39
- ${shouldSplit ? nothing : repeat(node.children, (child) => child.tocId, child => this.renderNode(child))}
82
+ <div class="ft-reader-toc--node ${isHighlighted ? "ft-reader-toc--node-highlighted" : ""}">
83
+ <div class="ft-reader-toc--link-container" data-depth="${node.depth}" style=${styleMap(styles)}>
84
+ <div class="ft-reader-toc--toggle-container">
85
+ ${displayToggle
86
+ ? html `
87
+ <ft-button round hideTooltip
88
+ ?dense=${this.viewportSize !== FtSizeCategory.S}
89
+ label="${this.labelResolver.resolve(isExpanded ? "collapse" : "expand", node.title)}"
90
+ iconVariant="${this.iconVariant}"
91
+ icon="${(isExpanded ? this.collapseIcon : this.expandIcon)}"
92
+ @click=${() => this.manuallyToggle(node.tocId, isExpanded)}
93
+ data-expand-node="${node.tocId}"
94
+ >
95
+ </ft-button>
96
+ `
97
+ : nothing}
98
+ </div>
99
+ <ft-reader-internal-link
100
+ tocId="${node.tocId}"
101
+ removeStyle>
102
+ <ft-typography variant="body2">${node.title}</ft-typography>
103
+ </ft-reader-internal-link>
40
104
  </div>
105
+ ${canDisplayChildren
106
+ ? html `
107
+ <div class="ft-reader-toc--node-children">
108
+ ${isExpanded
109
+ ? repeat(node.children, (child) => child.tocId, child => this.renderNode(child))
110
+ : nothing}
111
+ </div>
112
+ `
113
+ : nothing}
41
114
  </div>
42
115
  `;
43
116
  }
117
+ buildAutomaticallyExpandedNodes(tocIds) {
118
+ var _a, _b;
119
+ let topicsToExpand = new Set(this.autoCollapse ? [] : this.automaticallyExpandedNodes);
120
+ for (let tocId of tocIds) {
121
+ while (tocId && !topicsToExpand.has(tocId)) {
122
+ topicsToExpand.add(tocId);
123
+ this.manuallyCollapsedNodes.delete(tocId);
124
+ tocId = (_b = (_a = this.service) === null || _a === void 0 ? void 0 : _a.getTocNodeOrThrow(tocId)) === null || _b === void 0 ? void 0 : _b.parentTocId;
125
+ }
126
+ }
127
+ return topicsToExpand;
128
+ }
129
+ manuallyToggle(tocId, isExpanded) {
130
+ if (isExpanded) {
131
+ this.manuallyCollapsedNodes.add(tocId);
132
+ this.manuallyExpandedNodes.delete(tocId);
133
+ }
134
+ else {
135
+ this.manuallyExpandedNodes.add(tocId);
136
+ this.manuallyCollapsedNodes.delete(tocId);
137
+ }
138
+ this.requestUpdate();
139
+ }
140
+ onViewportSizeChange(event) {
141
+ this.viewportSize = event.detail.category;
142
+ }
44
143
  }
45
144
  // Uncomment to use scoped web components
46
145
  FtReaderToc.elementDefinitions = {
146
+ "ft-button": FtButton,
147
+ "ft-reader-internal-link": FtReaderInternalLink,
148
+ "ft-size-watcher": FtSizeWatcher,
47
149
  "ft-typography": FtTypography,
48
- "ft-reader-internal-link": FtReaderInternalLink
49
150
  };
50
151
  // language=CSS
51
152
  FtReaderToc.styles = css `
52
- .ft-reader-toc--node-visible {
53
- background-color: ${FtReaderTocCssVariables.colorPrimary};
54
- color: ${FtReaderTocCssVariables.colorOnPrimary};
153
+ .ft-reader-toc {
154
+ color: ${FtReaderTocCssVariables.textColor};
155
+ }
156
+
157
+ .ft-reader-toc--node-highlighted > .ft-reader-toc--link-container {
158
+ background-color: ${FtReaderTocCssVariables.highlightedBackgroundColor};
159
+ color: ${FtReaderTocCssVariables.highlightedTextColor};
160
+ ${setVariable(FtTypographyCssVariables.fontWeight, FtReaderTocCssVariables.highlightedFontWeight)}
55
161
  }
56
162
 
57
- .ft-reader-toc--node-children {
58
- padding-left: ${FtReaderTocCssVariables.tabulationSize};
163
+ .ft-reader-toc--link-container {
164
+ display: flex;
165
+ gap: 4px;
166
+ padding: ${FtReaderTocCssVariables.verticalSpacing} 4px; /* left padding is override on inline style */
167
+ align-items: center;
168
+ }
169
+
170
+ .ft-reader-toc-mobile .ft-reader-toc--toggle-container {
171
+ flex-shrink: 0;
172
+ width: calc(${FtReaderTocCssVariables.iconFontSize} + 12px); /*--ft-button-internal-horizontal-padding: 8px; in ft-button NOT dense*/
173
+ }
174
+
175
+ .ft-reader-toc-desktop .ft-reader-toc--toggle-container {
176
+ flex-shrink: 0;
177
+ width: calc(${FtReaderTocCssVariables.iconFontSize} + 4px); /*--ft-button-internal-horizontal-padding: 4px; in ft-button dense*/
178
+ }
179
+
180
+ ft-button {
181
+ ${setVariable(FtButtonCssVariables.iconSize, FtReaderTocCssVariables.iconFontSize)};
182
+ ${setVariable(FtButtonCssVariables.backgroundColor, "transparent")};
59
183
  }
60
184
  `;
185
+ __decorate([
186
+ property({ type: Boolean })
187
+ ], FtReaderToc.prototype, "expanded", void 0);
188
+ __decorate([
189
+ property()
190
+ ], FtReaderToc.prototype, "iconVariant", void 0);
191
+ __decorate([
192
+ property()
193
+ ], FtReaderToc.prototype, "collapseIcon", void 0);
194
+ __decorate([
195
+ property()
196
+ ], FtReaderToc.prototype, "expandIcon", void 0);
197
+ __decorate([
198
+ property({ type: Boolean })
199
+ ], FtReaderToc.prototype, "autoCollapse", void 0);
200
+ __decorate([
201
+ jsonProperty({})
202
+ ], FtReaderToc.prototype, "labels", void 0);
61
203
  __decorate([
62
204
  redux()
63
205
  ], FtReaderToc.prototype, "toc", void 0);
@@ -70,4 +212,16 @@ __decorate([
70
212
  __decorate([
71
213
  redux()
72
214
  ], FtReaderToc.prototype, "visibleTopics", void 0);
215
+ __decorate([
216
+ state({ hasChanged: (value, oldValue) => !deepEqual(value, oldValue) })
217
+ ], FtReaderToc.prototype, "automaticallyExpandedNodes", void 0);
218
+ __decorate([
219
+ state({ hasChanged: (value, oldValue) => !deepEqual(value, oldValue) })
220
+ ], FtReaderToc.prototype, "manuallyExpandedNodes", void 0);
221
+ __decorate([
222
+ state({ hasChanged: (value, oldValue) => !deepEqual(value, oldValue) })
223
+ ], FtReaderToc.prototype, "manuallyCollapsedNodes", void 0);
224
+ __decorate([
225
+ state()
226
+ ], FtReaderToc.prototype, "viewportSize", void 0);
73
227
  //# sourceMappingURL=ft-reader-toc.js.map