element-book 22.2.2 → 23.0.0
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/README.md +65 -5
- package/dist/data/book-entry/base-book-entry.d.ts +7 -2
- package/dist/data/book-entry/book-entry-type.d.ts +12 -2
- package/dist/data/book-entry/book-entry-type.js +11 -6
- package/dist/data/book-entry/book-entry.d.ts +14 -4
- package/dist/data/book-entry/book-entry.js +7 -2
- package/dist/data/book-entry/book-page/book-page-controls.d.ts +62 -10
- package/dist/data/book-entry/book-page/book-page-controls.js +38 -16
- package/dist/data/book-entry/book-page/book-page.d.ts +29 -8
- package/dist/data/book-entry/book-page/book-page.js +1 -0
- package/dist/data/book-entry/book-page/controls-wrapper.d.ts +24 -4
- package/dist/data/book-entry/book-page/controls-wrapper.js +18 -3
- package/dist/data/book-entry/book-page/define-book-page.d.ts +44 -12
- package/dist/data/book-entry/book-page/define-book-page.js +19 -12
- package/dist/data/book-entry/book-root.d.ts +8 -3
- package/dist/data/book-entry/url-breadcrumbs.d.ts +17 -1
- package/dist/data/book-entry/url-breadcrumbs.js +16 -0
- package/dist/data/book-entry/verify-book-entry.d.ts +3 -6
- package/dist/data/book-entry/verify-book-entry.js +7 -7
- package/dist/data/book-tree/book-tree-node.d.ts +26 -7
- package/dist/data/book-tree/book-tree-node.js +5 -0
- package/dist/data/book-tree/book-tree.d.ts +7 -7
- package/dist/data/book-tree/book-tree.js +16 -15
- package/dist/data/book-tree/search-nodes.d.ts +1 -1
- package/dist/data/book-tree/search-nodes.js +4 -4
- package/dist/data/book-tree/tree-cache.d.ts +2 -2
- package/dist/index.d.ts +18 -10
- package/dist/index.js +18 -10
- package/dist/routing/book-router.d.ts +1 -1
- package/dist/routing/book-router.js +3 -3
- package/dist/routing/book-routing.d.ts +25 -0
- package/dist/routing/book-routing.js +15 -0
- package/dist/ui/color-theme/color-theme.d.ts +33 -13
- package/dist/ui/color-theme/color-theme.js +14 -5
- package/dist/ui/color-theme/create-color-theme.d.ts +23 -3
- package/dist/ui/color-theme/create-color-theme.js +15 -0
- package/dist/ui/elements/book-breadcrumbs.element.d.ts +3 -3
- package/dist/ui/elements/book-breadcrumbs.element.js +4 -4
- package/dist/ui/elements/book-nav/book-nav-filter.d.ts +1 -1
- package/dist/ui/elements/book-nav/book-nav-filter.js +6 -10
- package/dist/ui/elements/book-nav/book-nav.element.d.ts +3 -3
- package/dist/ui/elements/book-nav/book-nav.element.js +13 -13
- package/dist/ui/elements/common/book-error.element.d.ts +1 -1
- package/dist/ui/elements/common/book-error.element.js +4 -6
- package/dist/ui/elements/common/book-route-link.element.d.ts +3 -3
- package/dist/ui/elements/common/book-route-link.element.js +3 -3
- package/dist/ui/elements/define-book-element.d.ts +1 -1
- package/dist/ui/elements/element-book-app/element-book-app-slots.d.ts +13 -0
- package/dist/ui/elements/element-book-app/element-book-app-slots.js +13 -0
- package/dist/ui/elements/element-book-app/element-book-app.element.d.ts +22 -11
- package/dist/ui/elements/element-book-app/element-book-app.element.js +42 -36
- package/dist/ui/elements/element-book-app/element-book-config.d.ts +26 -16
- package/dist/ui/elements/element-book-app/get-current-nodes.d.ts +2 -2
- package/dist/ui/elements/element-book-app/get-current-nodes.js +3 -8
- package/dist/ui/elements/element-book-app/global-values.d.ts +5 -0
- package/dist/ui/elements/entry-display/book-breadcrumbs-bar.element.d.ts +3 -3
- package/dist/ui/elements/entry-display/book-breadcrumbs-bar.element.js +8 -8
- package/dist/ui/elements/entry-display/book-entry-description.element.d.ts +1 -1
- package/dist/ui/elements/entry-display/book-entry-description.element.js +3 -3
- package/dist/ui/elements/entry-display/book-page/book-page-controls.element.d.ts +6 -6
- package/dist/ui/elements/entry-display/book-page/book-page-controls.element.js +14 -14
- package/dist/ui/elements/entry-display/book-page/book-page-wrapper.element.d.ts +6 -6
- package/dist/ui/elements/entry-display/book-page/book-page-wrapper.element.js +13 -11
- package/dist/ui/elements/entry-display/element-example/book-element-example-controls.element.d.ts +5 -5
- package/dist/ui/elements/entry-display/element-example/book-element-example-controls.element.js +5 -5
- package/dist/ui/elements/entry-display/element-example/book-element-example-viewer.element.d.ts +5 -5
- package/dist/ui/elements/entry-display/element-example/book-element-example-viewer.element.js +13 -9
- package/dist/ui/elements/entry-display/element-example/book-element-example-wrapper.element.d.ts +6 -6
- package/dist/ui/elements/entry-display/element-example/book-element-example-wrapper.element.js +5 -5
- package/dist/ui/elements/entry-display/entry-display/book-entry-display.element.d.ts +9 -9
- package/dist/ui/elements/entry-display/entry-display/book-entry-display.element.js +6 -6
- package/dist/ui/elements/entry-display/entry-display/create-node-templates.d.ts +5 -5
- package/dist/ui/elements/entry-display/entry-display/create-node-templates.js +16 -16
- package/dist/ui/events/change-route.event.d.ts +1 -1
- package/dist/util/fuzzy-search.js +3 -2
- package/dist/util/type.d.ts +7 -0
- package/package.json +31 -29
package/README.md
CHANGED
|
@@ -2,21 +2,81 @@
|
|
|
2
2
|
|
|
3
3
|
An [`element-vir`](https://npmjs.com/package/element-vir) drop-in element for building, testing, and demonstrating a collection of elements (or, in other words, a design system).
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npm i element-book
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
## Terminology
|
|
12
12
|
|
|
13
13
|
- **Page**: a group of pages and / or element examples. Pages can be infinitely nested.
|
|
14
14
|
- **Element Example**: an individual element example with independent state, styles, title, etc.
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
## Usage
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
1. Define element-book pages with [`defineBookPage`](https://electrovir.github.io/element-vir/element-book/functions/defineBookPage.html):
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
<!-- example-link: ./src/readme-examples/define-page.example.ts -->
|
|
21
|
+
|
|
22
|
+
```TypeScript
|
|
23
|
+
import {defineBookPage} from '../data/book-entry/book-page/define-book-page.js';
|
|
24
|
+
|
|
25
|
+
export const myPage = defineBookPage({
|
|
26
|
+
/** Use `undefined` if your page is at the top level. */
|
|
27
|
+
parent: undefined,
|
|
28
|
+
title: 'My Page',
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
2. Inside of a page definition, define an element example:
|
|
33
|
+
|
|
34
|
+
<!-- example-link: ./src/readme-examples/define-example.example.ts -->
|
|
35
|
+
|
|
36
|
+
```TypeScript
|
|
37
|
+
import {html} from 'element-vir';
|
|
38
|
+
import {defineBookPage} from '../data/book-entry/book-page/define-book-page.js';
|
|
39
|
+
|
|
40
|
+
export const myPage = defineBookPage({
|
|
41
|
+
/** Use `undefined` if your page is at the top level. */
|
|
42
|
+
parent: undefined,
|
|
43
|
+
title: 'My Page',
|
|
44
|
+
defineExamples({defineExample}) {
|
|
45
|
+
defineExample({
|
|
46
|
+
title: 'My Example',
|
|
47
|
+
render() {
|
|
48
|
+
return html`
|
|
49
|
+
<p>Render your element here.</p>
|
|
50
|
+
`;
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
3. Instantiate an instance of the [element book app](https://electrovir.github.io/element-vir/element-book/variables/ElementBookApp.html) into your app and pass in all your pages:
|
|
58
|
+
|
|
59
|
+
<!-- example-link: ./src/readme-examples/use-app.example.ts -->
|
|
60
|
+
|
|
61
|
+
```TypeScript
|
|
62
|
+
import {defineElementNoInputs, html} from 'element-vir';
|
|
63
|
+
import {ElementBookApp} from '../ui/elements/element-book-app/element-book-app.element.js';
|
|
64
|
+
import {myPage} from './define-page.example.js';
|
|
65
|
+
|
|
66
|
+
export const MyApp = defineElementNoInputs({
|
|
67
|
+
tagName: 'my-app',
|
|
68
|
+
render() {
|
|
69
|
+
return html`
|
|
70
|
+
<${ElementBookApp.assign({
|
|
71
|
+
pages: [
|
|
72
|
+
myPage,
|
|
73
|
+
],
|
|
74
|
+
})}></${ElementBookApp}>
|
|
75
|
+
`;
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Why not Storybook?
|
|
21
81
|
|
|
22
82
|
Because Storybook is un-composable, impossible to debug, and full of behind-the-scenes \*magic\* that you can't backtrack without already understanding the inner workings of Storybook itself. With `element-book`, it's all just imports that you can directly follow with the TypeScript compiler.
|
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BookEntryType } from './book-entry-type.js';
|
|
2
|
+
/**
|
|
3
|
+
* Base properties for all book entry types.
|
|
4
|
+
*
|
|
5
|
+
* @category Internal
|
|
6
|
+
*/
|
|
2
7
|
export type BaseBookEntry = {
|
|
3
8
|
/**
|
|
4
9
|
* Title for the entry. This is used to create breadcrumbs and URL paths. Each title must be
|
|
5
10
|
* unique within a given entry's parent.
|
|
6
11
|
*/
|
|
7
12
|
title: string;
|
|
8
|
-
entryType:
|
|
13
|
+
entryType: BookEntryType;
|
|
9
14
|
/**
|
|
10
15
|
* The parent page. A value of undefined here indicates that the entry should be at the top
|
|
11
16
|
* level of the element book.
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* All possible types for element-book entries.
|
|
3
|
+
*
|
|
4
|
+
* @category Internal
|
|
5
|
+
*/
|
|
6
|
+
export declare enum BookEntryType {
|
|
2
7
|
/** A single element example. */
|
|
3
8
|
ElementExample = "element-example",
|
|
4
9
|
/** An individual book page with element examples and/or sub-pages. */
|
|
@@ -6,4 +11,9 @@ export declare enum BookEntryTypeEnum {
|
|
|
6
11
|
/** Tree root. Not for external use. */
|
|
7
12
|
Root = "root"
|
|
8
13
|
}
|
|
9
|
-
|
|
14
|
+
/**
|
|
15
|
+
* A union of all possible element-book entry types.
|
|
16
|
+
*
|
|
17
|
+
* @category Internal
|
|
18
|
+
*/
|
|
19
|
+
export type AnyBookEntryType = BookEntryType.ElementExample | BookEntryType.Page | BookEntryType.Root;
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* All possible types for element-book entries.
|
|
3
|
+
*
|
|
4
|
+
* @category Internal
|
|
5
|
+
*/
|
|
6
|
+
export var BookEntryType;
|
|
7
|
+
(function (BookEntryType) {
|
|
3
8
|
/** A single element example. */
|
|
4
|
-
|
|
9
|
+
BookEntryType["ElementExample"] = "element-example";
|
|
5
10
|
/** An individual book page with element examples and/or sub-pages. */
|
|
6
|
-
|
|
11
|
+
BookEntryType["Page"] = "page";
|
|
7
12
|
/** Tree root. Not for external use. */
|
|
8
|
-
|
|
9
|
-
})(
|
|
13
|
+
BookEntryType["Root"] = "root";
|
|
14
|
+
})(BookEntryType || (BookEntryType = {}));
|
|
@@ -1,7 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { BookElementExample, BookPage } from './book-page/book-page';
|
|
3
|
-
import { BookRoot } from './book-root';
|
|
1
|
+
import { BookEntryType } from './book-entry-type.js';
|
|
2
|
+
import { BookElementExample, BookPage } from './book-page/book-page.js';
|
|
3
|
+
import { BookRoot } from './book-root.js';
|
|
4
|
+
/**
|
|
5
|
+
* All possible book entries.
|
|
6
|
+
*
|
|
7
|
+
* @category Internal
|
|
8
|
+
*/
|
|
4
9
|
export type BookEntry = BookPage | BookRoot | BookElementExample;
|
|
5
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Check if the input is a book entry of the given type.
|
|
12
|
+
*
|
|
13
|
+
* @internal
|
|
14
|
+
*/
|
|
15
|
+
export declare function isBookEntry<const SpecificType extends BookEntryType>(entry: unknown, entryType: SpecificType): entry is Extract<BookEntry, {
|
|
6
16
|
entryType: SpecificType;
|
|
7
17
|
}>;
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { check } from '@augment-vir/assert';
|
|
2
|
+
/**
|
|
3
|
+
* Check if the input is a book entry of the given type.
|
|
4
|
+
*
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
2
7
|
export function isBookEntry(entry, entryType) {
|
|
3
|
-
return
|
|
8
|
+
return check.hasKey(entry, 'entryType') && entry.entryType === entryType;
|
|
4
9
|
}
|
|
@@ -1,24 +1,62 @@
|
|
|
1
|
-
|
|
1
|
+
import type { EmptyObject } from 'type-fest';
|
|
2
|
+
/**
|
|
3
|
+
* Adds a control to an element-book page.
|
|
4
|
+
*
|
|
5
|
+
* @category Internal
|
|
6
|
+
*/
|
|
7
|
+
export type BookPageControl<ControlType extends BookPageControlType = BookPageControlType> = {
|
|
2
8
|
controlType: ControlType;
|
|
3
9
|
initValue: BookPageControlValueType[ControlType];
|
|
4
10
|
/** The name and label for the control. */
|
|
5
11
|
controlName: string;
|
|
6
|
-
} & (ControlType extends
|
|
12
|
+
} & (ControlType extends BookPageControlType.Dropdown ? {
|
|
7
13
|
options: string[];
|
|
8
|
-
} :
|
|
9
|
-
|
|
10
|
-
|
|
14
|
+
} : EmptyObject);
|
|
15
|
+
/**
|
|
16
|
+
* Initialization options for an element-book page control.
|
|
17
|
+
*
|
|
18
|
+
* @category Internal
|
|
19
|
+
*/
|
|
20
|
+
export type BookPageControlInit<ControlType extends BookPageControlType> = Omit<BookPageControl<ControlType>, 'controlName'>;
|
|
21
|
+
/**
|
|
22
|
+
* Checks and type guards that the input page control init is of the given type.
|
|
23
|
+
*
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
export declare function isControlInitType<const SpecificControlType extends BookPageControlType>(controlInit: BookPageControlInit<any>, specificType: SpecificControlType): controlInit is BookPageControlInit<SpecificControlType>;
|
|
11
27
|
/**
|
|
12
28
|
* Define a page control. This doesn't do anything fancy (in fact it only returns the input) but it
|
|
13
29
|
* helps immensely with type inference.
|
|
30
|
+
*
|
|
31
|
+
* @category Main
|
|
32
|
+
*/
|
|
33
|
+
export declare function definePageControl<const ControlType extends BookPageControlType>(controlInit: BookPageControlInit<ControlType>): BookPageControlInit<ControlType>;
|
|
34
|
+
/**
|
|
35
|
+
* Maps an object of user-defined controls to their initial values.
|
|
36
|
+
*
|
|
37
|
+
* @category Internal
|
|
14
38
|
*/
|
|
15
|
-
export declare function definePageControl<const ControlType extends BookPageControlTypeEnum>(controlInit: BookPageControlInit<ControlType>): BookPageControlInit<ControlType>;
|
|
16
39
|
export type ControlsToValues<ControlsInit extends BookPageControlsInitBase> = {
|
|
17
40
|
[ControlName in keyof ControlsInit]: ControlsInit[ControlName]['initValue'];
|
|
18
41
|
};
|
|
19
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Base type for a arbitrary, user-defined object of page controls.
|
|
44
|
+
*
|
|
45
|
+
* @category Internal
|
|
46
|
+
*/
|
|
47
|
+
export type BookPageControlsInitBase = Record<string, BookPageControlInit<BookPageControlType>>;
|
|
48
|
+
/**
|
|
49
|
+
* Base type for a arbitrary, user-defined object of page control values.
|
|
50
|
+
*
|
|
51
|
+
* @category Internal
|
|
52
|
+
*/
|
|
20
53
|
export type BookPageControlsValues = ControlsToValues<BookPageControlsInitBase>;
|
|
21
|
-
|
|
54
|
+
/**
|
|
55
|
+
* All the supported page control types. One of these must be chosen when defining a page control.
|
|
56
|
+
*
|
|
57
|
+
* @category Main
|
|
58
|
+
*/
|
|
59
|
+
export declare enum BookPageControlType {
|
|
22
60
|
Checkbox = "checkbox",
|
|
23
61
|
Color = "color",
|
|
24
62
|
Dropdown = "dropdown",
|
|
@@ -27,7 +65,12 @@ export declare enum BookPageControlTypeEnum {
|
|
|
27
65
|
Number = "number",
|
|
28
66
|
Text = "text"
|
|
29
67
|
}
|
|
30
|
-
|
|
68
|
+
/**
|
|
69
|
+
* Specifies the default value for each page control type, as well as its type.
|
|
70
|
+
*
|
|
71
|
+
* @category Internal
|
|
72
|
+
*/
|
|
73
|
+
export declare const controlValueTypes: {
|
|
31
74
|
checkbox: boolean;
|
|
32
75
|
color: string;
|
|
33
76
|
dropdown: string;
|
|
@@ -35,6 +78,15 @@ declare const controlValueTypes: {
|
|
|
35
78
|
number: number;
|
|
36
79
|
text: string;
|
|
37
80
|
};
|
|
81
|
+
/**
|
|
82
|
+
* Each page control type mapped to the type of their value.
|
|
83
|
+
*
|
|
84
|
+
* @category Internal
|
|
85
|
+
*/
|
|
38
86
|
export type BookPageControlValueType = typeof controlValueTypes;
|
|
87
|
+
/**
|
|
88
|
+
* Checks that the given control init object is valid.
|
|
89
|
+
*
|
|
90
|
+
* @internal
|
|
91
|
+
*/
|
|
39
92
|
export declare function checkControls(controlsInit: BookPageControlsInitBase | undefined, pageName: string): Error[];
|
|
40
|
-
export {};
|
|
@@ -1,32 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks and type guards that the input page control init is of the given type.
|
|
3
|
+
*
|
|
4
|
+
* @internal
|
|
5
|
+
*/
|
|
1
6
|
export function isControlInitType(controlInit, specificType) {
|
|
2
7
|
return controlInit.controlType === specificType;
|
|
3
8
|
}
|
|
4
9
|
/**
|
|
5
10
|
* Define a page control. This doesn't do anything fancy (in fact it only returns the input) but it
|
|
6
11
|
* helps immensely with type inference.
|
|
12
|
+
*
|
|
13
|
+
* @category Main
|
|
7
14
|
*/
|
|
8
15
|
export function definePageControl(controlInit) {
|
|
9
16
|
return controlInit;
|
|
10
17
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
18
|
+
/**
|
|
19
|
+
* All the supported page control types. One of these must be chosen when defining a page control.
|
|
20
|
+
*
|
|
21
|
+
* @category Main
|
|
22
|
+
*/
|
|
23
|
+
export var BookPageControlType;
|
|
24
|
+
(function (BookPageControlType) {
|
|
25
|
+
BookPageControlType["Checkbox"] = "checkbox";
|
|
26
|
+
BookPageControlType["Color"] = "color";
|
|
27
|
+
BookPageControlType["Dropdown"] = "dropdown";
|
|
16
28
|
/** Hidden controls allow any values but they aren't displayed to the user for editing. */
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
})(
|
|
29
|
+
BookPageControlType["Hidden"] = "hidden";
|
|
30
|
+
BookPageControlType["Number"] = "number";
|
|
31
|
+
BookPageControlType["Text"] = "text";
|
|
32
|
+
})(BookPageControlType || (BookPageControlType = {}));
|
|
21
33
|
const anySymbol = Symbol('any-type');
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
[
|
|
34
|
+
/**
|
|
35
|
+
* Specifies the default value for each page control type, as well as its type.
|
|
36
|
+
*
|
|
37
|
+
* @category Internal
|
|
38
|
+
*/
|
|
39
|
+
export const controlValueTypes = {
|
|
40
|
+
[BookPageControlType.Checkbox]: false,
|
|
41
|
+
[BookPageControlType.Color]: '',
|
|
42
|
+
[BookPageControlType.Dropdown]: '',
|
|
43
|
+
[BookPageControlType.Hidden]: anySymbol,
|
|
44
|
+
[BookPageControlType.Number]: 0,
|
|
45
|
+
[BookPageControlType.Text]: '',
|
|
29
46
|
};
|
|
47
|
+
/**
|
|
48
|
+
* Checks that the given control init object is valid.
|
|
49
|
+
*
|
|
50
|
+
* @internal
|
|
51
|
+
*/
|
|
30
52
|
export function checkControls(controlsInit, pageName) {
|
|
31
53
|
if (!controlsInit) {
|
|
32
54
|
return [];
|
|
@@ -1,22 +1,41 @@
|
|
|
1
1
|
import { Overwrite, SetOptionalAndNullable } from '@augment-vir/common';
|
|
2
2
|
import { CSSResult, HtmlInterpolation, PropertyInitMapBase, RenderParams, TypedEvent } from 'element-vir';
|
|
3
|
-
import { GlobalValues } from '../../../ui/elements/element-book-app/global-values';
|
|
4
|
-
import { BaseBookEntry } from '../base-book-entry';
|
|
5
|
-
import {
|
|
6
|
-
import { BookPageControlsInitBase, ControlsToValues } from './book-page-controls';
|
|
3
|
+
import { GlobalValues } from '../../../ui/elements/element-book-app/global-values.js';
|
|
4
|
+
import { BaseBookEntry } from '../base-book-entry.js';
|
|
5
|
+
import { BookEntryType } from '../book-entry-type.js';
|
|
6
|
+
import { BookPageControlsInitBase, ControlsToValues } from './book-page-controls.js';
|
|
7
|
+
/**
|
|
8
|
+
* An individual element-book page.
|
|
9
|
+
*
|
|
10
|
+
* @category Type
|
|
11
|
+
*/
|
|
7
12
|
export type BookPage<GlobalValuesType extends GlobalValues = {}, ParentPage extends BookPage | undefined = any, ControlsInit extends BookPageControlsInitBase = BookPageControlsInitBase> = Overwrite<BaseBookEntry, {
|
|
13
|
+
/**
|
|
14
|
+
* The parent page of this page. If this page is meant to be at the top-level, set this to
|
|
15
|
+
* `undefined`.
|
|
16
|
+
*/
|
|
8
17
|
parent: ParentPage;
|
|
9
|
-
entryType:
|
|
18
|
+
entryType: BookEntryType.Page;
|
|
10
19
|
}> & {
|
|
11
20
|
controls: ControlsInit;
|
|
12
21
|
elementExamples: Record<string, BookElementExample>;
|
|
13
22
|
};
|
|
23
|
+
/**
|
|
24
|
+
* All parameters required for rendering an element-book page.
|
|
25
|
+
*
|
|
26
|
+
* @category Internal
|
|
27
|
+
*/
|
|
14
28
|
export type BookPageExampleRenderParams<GlobalValuesType extends GlobalValues, ControlsInit extends BookPageControlsInitBase, StateInit extends PropertyInitMapBase> = Pick<RenderParams<any, any, StateInit, any, any, any, any>, 'state' | 'updateState'> & {
|
|
15
29
|
controls: ControlsToValues<ControlsInit> & GlobalValuesType;
|
|
16
30
|
};
|
|
31
|
+
/**
|
|
32
|
+
* An individual element example for an element-book page.
|
|
33
|
+
*
|
|
34
|
+
* @category Internal
|
|
35
|
+
*/
|
|
17
36
|
export type BookElementExample<GlobalValuesType extends GlobalValues = {}, ControlsInit extends BookPageControlsInitBase = {}, StateInit extends PropertyInitMapBase = {}> = Overwrite<BaseBookEntry, {
|
|
18
37
|
parent: BookPage | undefined;
|
|
19
|
-
entryType:
|
|
38
|
+
entryType: BookEntryType.ElementExample;
|
|
20
39
|
} & {
|
|
21
40
|
/** Initialize the state for this example. */
|
|
22
41
|
stateInitStatic?: StateInit | undefined;
|
|
@@ -28,10 +47,12 @@ export type BookElementExample<GlobalValuesType extends GlobalValues = {}, Contr
|
|
|
28
47
|
*/
|
|
29
48
|
styles?: CSSResult | undefined;
|
|
30
49
|
/** Render the example. */
|
|
31
|
-
|
|
50
|
+
render: (renderParams: BookPageExampleRenderParams<GlobalValuesType, ControlsInit, StateInit>) => HtmlInterpolation;
|
|
32
51
|
}>;
|
|
33
52
|
/**
|
|
34
53
|
* The properties that are necessary to initialize an element example. Missing properties will be
|
|
35
|
-
*
|
|
54
|
+
* filled in by the parent.
|
|
55
|
+
*
|
|
56
|
+
* @category Internal
|
|
36
57
|
*/
|
|
37
58
|
export type BookElementExampleInit<GlobalValuesType extends GlobalValues, Controls extends BookPageControlsInitBase, StateInit extends PropertyInitMapBase> = SetOptionalAndNullable<Omit<BookElementExample<GlobalValuesType, Controls, StateInit>, 'entryType' | 'parent' | 'errors'>, 'descriptionParagraphs'>;
|
|
@@ -1,12 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { BookTreeNode } from '../../book-tree/book-tree-node';
|
|
3
|
-
import { BookPageControlsValues } from './book-page-controls';
|
|
1
|
+
import { PartialWithUndefined } from '@augment-vir/common';
|
|
2
|
+
import { BookTreeNode } from '../../book-tree/book-tree-node.js';
|
|
3
|
+
import { BookPageControlsValues } from './book-page-controls.js';
|
|
4
|
+
/**
|
|
5
|
+
* Nested page controls.
|
|
6
|
+
*
|
|
7
|
+
* @category Internal
|
|
8
|
+
*/
|
|
4
9
|
export type ControlsWrapper = {
|
|
5
10
|
children: {
|
|
6
11
|
[Breadcrumb: string]: ControlsWrapper;
|
|
7
12
|
};
|
|
8
13
|
controls: BookPageControlsValues;
|
|
9
14
|
};
|
|
15
|
+
/**
|
|
16
|
+
* Find the controls at the given breadcrumbs.
|
|
17
|
+
*
|
|
18
|
+
* @category Internal
|
|
19
|
+
*/
|
|
10
20
|
export declare function traverseControls(controlsWrapper: ControlsWrapper, fullUrlBreadcrumbs: ReadonlyArray<string>): BookPageControlsValues;
|
|
21
|
+
/**
|
|
22
|
+
* Add new controls at the given breadcrumbs.
|
|
23
|
+
*
|
|
24
|
+
* @category Internal
|
|
25
|
+
*/
|
|
11
26
|
export declare function createNewControls(controlsWrapper: Readonly<ControlsWrapper>, breadcrumbsForNewValue: ReadonlyArray<string>, newValues: BookPageControlsValues): ControlsWrapper;
|
|
12
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Add new controls from the given tree node.
|
|
29
|
+
*
|
|
30
|
+
* @category Internal
|
|
31
|
+
*/
|
|
32
|
+
export declare function updateTreeControls(node: BookTreeNode, existingControls: PartialWithUndefined<ControlsWrapper> | undefined): ControlsWrapper;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { mapObjectValues } from '@augment-vir/common';
|
|
2
|
-
import { isBookTreeNode } from '../../book-tree/book-tree';
|
|
3
|
-
import {
|
|
2
|
+
import { isBookTreeNode } from '../../book-tree/book-tree.js';
|
|
3
|
+
import { BookEntryType } from '../book-entry-type.js';
|
|
4
|
+
/**
|
|
5
|
+
* Find the controls at the given breadcrumbs.
|
|
6
|
+
*
|
|
7
|
+
* @category Internal
|
|
8
|
+
*/
|
|
4
9
|
export function traverseControls(controlsWrapper, fullUrlBreadcrumbs) {
|
|
5
10
|
return traverseAndInsertNewControls(controlsWrapper, [
|
|
6
11
|
/** Empty string represents the breadcrumb for the root node */
|
|
@@ -24,6 +29,11 @@ function traverseAndInsertNewControls(controlsWrapper, urlBreadcrumbs, newValues
|
|
|
24
29
|
};
|
|
25
30
|
return allControls;
|
|
26
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Add new controls at the given breadcrumbs.
|
|
34
|
+
*
|
|
35
|
+
* @category Internal
|
|
36
|
+
*/
|
|
27
37
|
export function createNewControls(controlsWrapper, breadcrumbsForNewValue, newValues) {
|
|
28
38
|
const newControls = { ...controlsWrapper };
|
|
29
39
|
traverseAndInsertNewControls(newControls, [
|
|
@@ -33,9 +43,14 @@ export function createNewControls(controlsWrapper, breadcrumbsForNewValue, newVa
|
|
|
33
43
|
], newValues);
|
|
34
44
|
return newControls;
|
|
35
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Add new controls from the given tree node.
|
|
48
|
+
*
|
|
49
|
+
* @category Internal
|
|
50
|
+
*/
|
|
36
51
|
export function updateTreeControls(node, existingControls) {
|
|
37
52
|
const controls = existingControls?.controls ||
|
|
38
|
-
(isBookTreeNode(node,
|
|
53
|
+
(isBookTreeNode(node, BookEntryType.Page)
|
|
39
54
|
? mapObjectValues(node.entry.controls, (name, setup) => {
|
|
40
55
|
return setup.initValue;
|
|
41
56
|
})
|
|
@@ -1,26 +1,58 @@
|
|
|
1
1
|
import { SetOptionalAndNullable } from '@augment-vir/common';
|
|
2
2
|
import { PropertyInitMapBase } from 'element-vir';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { BookPageControlsInitBase } from './book-page-controls';
|
|
3
|
+
import type { EmptyObject } from 'type-fest';
|
|
4
|
+
import { GlobalValues } from '../../../ui/elements/element-book-app/global-values.js';
|
|
5
|
+
import { InfiniteRecursionLimiter } from '../../../util/type.js';
|
|
6
|
+
import { BookPageControlsInitBase } from './book-page-controls.js';
|
|
7
|
+
import { BookElementExampleInit, BookPage } from './book-page.js';
|
|
8
|
+
/**
|
|
9
|
+
* The callback type for a book page definition's `defineExample` callback.
|
|
10
|
+
*
|
|
11
|
+
* @category Internal
|
|
12
|
+
*/
|
|
7
13
|
export type DefineExampleCallback<GlobalValuesType extends GlobalValues = {}, ControlsInit extends BookPageControlsInitBase = BookPageControlsInitBase> = <StateInit extends PropertyInitMapBase>(exampleInit: BookElementExampleInit<GlobalValuesType, ControlsInit, StateInit>) => void;
|
|
14
|
+
/**
|
|
15
|
+
* Used for `defineExamples` in a book page's init.
|
|
16
|
+
*
|
|
17
|
+
* @category Internal
|
|
18
|
+
*/
|
|
8
19
|
export type ElementExamplesDefiner<GlobalValuesType extends GlobalValues = {}, ControlsInit extends BookPageControlsInitBase = BookPageControlsInitBase> = (params: {
|
|
9
20
|
defineExample: DefineExampleCallback<GlobalValuesType, ControlsInit>;
|
|
10
21
|
}) => void;
|
|
11
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Collapses all element-book control inits into a single flag object.
|
|
24
|
+
*
|
|
25
|
+
* @category Internal
|
|
26
|
+
*/
|
|
27
|
+
export type CollapseControlsInit<ParentPage extends BookPage | undefined, CurrentControlsInit extends BookPageControlsInitBase,
|
|
12
28
|
/** Prevent infinite recursion TypeScript errors. */
|
|
13
|
-
RecursionDepth = InfiniteRecursionLimiter> = CurrentControlsInit & (RecursionDepth extends [any, ...infer RemainingDepth] ? ParentPage extends BookPage<infer GlobalValuesType, infer GrandParentPage, infer ParentControls> ? CollapseControlsInit<GrandParentPage, ParentControls, RemainingDepth> :
|
|
14
|
-
|
|
29
|
+
RecursionDepth = InfiniteRecursionLimiter> = CurrentControlsInit & (RecursionDepth extends [any, ...infer RemainingDepth] ? ParentPage extends BookPage<infer GlobalValuesType, infer GrandParentPage, infer ParentControls> ? CollapseControlsInit<GrandParentPage, ParentControls, RemainingDepth> : EmptyObject : EmptyObject);
|
|
30
|
+
/**
|
|
31
|
+
* Collapses all element-book global values into a single flag object.
|
|
32
|
+
*
|
|
33
|
+
* @category Internal
|
|
34
|
+
*/
|
|
35
|
+
export type CollapseGlobalValuesType<ParentPage extends BookPage | undefined, GlobalValuesType extends GlobalValues,
|
|
15
36
|
/** Prevent infinite recursion TypeScript errors. */
|
|
16
|
-
RecursionDepth = InfiniteRecursionLimiter> = GlobalValuesType & (RecursionDepth extends [any, ...infer RemainingDepth] ? ParentPage extends BookPage<infer GlobalValuesType, infer GrandParentPage, infer ParentControls> ? CollapseGlobalValuesType<GrandParentPage, GlobalValuesType, RemainingDepth> :
|
|
37
|
+
RecursionDepth = InfiniteRecursionLimiter> = GlobalValuesType & (RecursionDepth extends [any, ...infer RemainingDepth] ? ParentPage extends BookPage<infer GlobalValuesType, infer GrandParentPage, infer ParentControls> ? CollapseGlobalValuesType<GrandParentPage, GlobalValuesType, RemainingDepth> : EmptyObject : EmptyObject);
|
|
38
|
+
/**
|
|
39
|
+
* The parameters for initializing a new element-book page.
|
|
40
|
+
*
|
|
41
|
+
* @category Type
|
|
42
|
+
*/
|
|
17
43
|
export type BookPageInit<GlobalValuesType extends GlobalValues, ParentPage extends BookPage | undefined, CurrentControlsInit extends BookPageControlsInitBase> = SetOptionalAndNullable<Omit<BookPage<any, ParentPage, CurrentControlsInit>, 'entryType' | 'elementExamples' | 'errors'>, 'controls' | 'descriptionParagraphs'> & {
|
|
18
|
-
|
|
44
|
+
defineExamples?: ElementExamplesDefiner<CollapseGlobalValuesType<ParentPage, GlobalValuesType>, CollapseControlsInit<ParentPage, CurrentControlsInit>> | undefined;
|
|
19
45
|
};
|
|
20
46
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
47
|
+
* A variant of {@link defineBookPage} that allows you specify what the expected global element-book
|
|
48
|
+
* values are for the page that you are defining.
|
|
49
|
+
*
|
|
50
|
+
* @category Main
|
|
23
51
|
*/
|
|
24
52
|
export declare function defineBookPageWithGlobals<const GlobalValuesType extends GlobalValues = {}>(): <const ParentPage extends BookPage | undefined = undefined, const ControlsInit extends BookPageControlsInitBase = {}>(pageInit: BookPageInit<GlobalValuesType, ParentPage, ControlsInit>) => BookPage<GlobalValuesType, ParentPage, ControlsInit>;
|
|
53
|
+
/**
|
|
54
|
+
* Define an element-book page. This is how you create new entries for your element-book instance.
|
|
55
|
+
*
|
|
56
|
+
* @category Main
|
|
57
|
+
*/
|
|
25
58
|
export declare function defineBookPage<const GlobalValuesType extends GlobalValues = {}, const ParentPage extends BookPage | undefined = undefined, const ControlsInit extends BookPageControlsInitBase = {}>(pageInit: BookPageInit<GlobalValuesType, ParentPage, ControlsInit>): BookPage<GlobalValuesType, ParentPage, ControlsInit>;
|
|
26
|
-
export {};
|
|
@@ -1,41 +1,48 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-empty-object-type */
|
|
2
|
+
import { check } from '@augment-vir/assert';
|
|
3
|
+
import { BookEntryType } from '../book-entry-type.js';
|
|
4
|
+
import { titleToUrlBreadcrumb } from '../url-breadcrumbs.js';
|
|
4
5
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
6
|
+
* A variant of {@link defineBookPage} that allows you specify what the expected global element-book
|
|
7
|
+
* values are for the page that you are defining.
|
|
8
|
+
*
|
|
9
|
+
* @category Main
|
|
7
10
|
*/
|
|
8
11
|
export function defineBookPageWithGlobals() {
|
|
9
12
|
return (pageInit) => {
|
|
10
13
|
return defineBookPage(pageInit);
|
|
11
14
|
};
|
|
12
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Define an element-book page. This is how you create new entries for your element-book instance.
|
|
18
|
+
*
|
|
19
|
+
* @category Main
|
|
20
|
+
*/
|
|
13
21
|
export function defineBookPage(pageInit) {
|
|
14
22
|
const page = {
|
|
15
23
|
...pageInit,
|
|
16
|
-
entryType:
|
|
24
|
+
entryType: BookEntryType.Page,
|
|
17
25
|
elementExamples: {},
|
|
18
26
|
descriptionParagraphs: pageInit.descriptionParagraphs ?? [],
|
|
19
27
|
controls: pageInit.controls ?? {},
|
|
20
28
|
errors: [],
|
|
21
29
|
};
|
|
22
30
|
const alreadyTakenElementExampleNames = new Set();
|
|
23
|
-
if (pageInit.
|
|
24
|
-
pageInit.
|
|
31
|
+
if (pageInit.defineExamples) {
|
|
32
|
+
pageInit.defineExamples({
|
|
25
33
|
defineExample(elementExampleInit) {
|
|
26
34
|
const newExample = {
|
|
27
35
|
...elementExampleInit,
|
|
28
|
-
entryType:
|
|
36
|
+
entryType: BookEntryType.ElementExample,
|
|
29
37
|
parent: page,
|
|
30
38
|
descriptionParagraphs: elementExampleInit.descriptionParagraphs ?? [],
|
|
31
39
|
errors: [
|
|
32
40
|
alreadyTakenElementExampleNames.has(elementExampleInit.title) &&
|
|
33
41
|
new Error(`Example title '${elementExampleInit.title}' in page '${pageInit.title}' is already taken.`),
|
|
34
|
-
].filter(isTruthy),
|
|
42
|
+
].filter(check.isTruthy),
|
|
35
43
|
};
|
|
36
44
|
alreadyTakenElementExampleNames.add(elementExampleInit.title);
|
|
37
|
-
page.elementExamples[titleToUrlBreadcrumb(newExample.title)] =
|
|
38
|
-
newExample;
|
|
45
|
+
page.elementExamples[titleToUrlBreadcrumb(newExample.title)] = newExample;
|
|
39
46
|
},
|
|
40
47
|
});
|
|
41
48
|
}
|