@fluid-topics/ft-reader-toc 0.3.8 → 0.3.11

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