web-toolkit-x 0.0.1 → 0.70.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/AUTHORS +3 -0
- package/LICENSE +1 -1
- package/NOTICE +7 -0
- package/README.md +162 -6
- package/dist/release/index.d.ts +650 -0
- package/dist/release/index.d.ts.map +1 -0
- package/dist/release/index.js +2831 -0
- package/dist/release/index.js.map +1 -0
- package/dist/release/toolkit-0.70.0.js +2834 -0
- package/dist/release/toolkit-0.70.0.js.map +1 -0
- package/package.json +71 -18
- package/src/core/bragi.ts +122 -0
- package/src/core/browser.ts +538 -0
- package/src/core/child-nodes.ts +77 -0
- package/src/core/comment.ts +24 -0
- package/src/core/component.ts +190 -0
- package/src/core/created-roots.ts +38 -0
- package/src/core/custom-element.ts +191 -0
- package/src/core/description.ts +241 -0
- package/src/core/diff.ts +590 -0
- package/src/core/dispatcher.ts +221 -0
- package/src/core/dom.ts +124 -0
- package/src/core/draft.ts +609 -0
- package/src/core/lifecycle.ts +301 -0
- package/src/core/nodes.ts +13 -0
- package/src/core/patch.ts +412 -0
- package/src/core/plugins.ts +231 -0
- package/src/core/reconciler.ts +185 -0
- package/src/core/renderer.ts +75 -0
- package/src/core/runtime.ts +36 -0
- package/src/core/sandbox.ts +128 -0
- package/src/core/service.ts +39 -0
- package/src/core/template.ts +472 -0
- package/src/core/text.ts +24 -0
- package/src/core/toolkit.ts +220 -0
- package/src/core/utils.ts +148 -0
- package/src/core/virtual-dom.ts +118 -0
- package/src/core/virtual-element.ts +72 -0
- package/src/core/virtual-node.ts +87 -0
- package/src/core/web-component.ts +285 -0
- package/src/globals.d.ts +10 -0
- package/src/index.ts +62 -0
- package/src/plugins/logger.ts +38 -0
- package/src/release.ts +3 -0
- package/index.js +0 -1
package/AUTHORS
ADDED
package/LICENSE
CHANGED
|
@@ -187,7 +187,7 @@
|
|
|
187
187
|
same "printed page" as the copyright notice for easier
|
|
188
188
|
identification within third-party archives.
|
|
189
189
|
|
|
190
|
-
Copyright
|
|
190
|
+
Copyright 2017-2020 Opera Software AS
|
|
191
191
|
|
|
192
192
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
193
193
|
you may not use this file except in compliance with the License.
|
package/NOTICE
ADDED
package/README.md
CHANGED
|
@@ -1,13 +1,169 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Web Toolkit X
|
|
2
2
|
|
|
3
|
-
Web
|
|
3
|
+
Web Toolkit X is a lightweight library for building Web user interfaces as a composition of small, self-contained apps. You describe what the UI should look like for a given state, and Toolkit keeps the page in sync with it.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
It originates from the Opera Web UI Toolkit.
|
|
6
|
+
|
|
7
|
+
## In a nutshell
|
|
8
|
+
|
|
9
|
+
- **Self-contained pieces** - each part of the UI owns its state, styles and behaviour, isolated from the rest of the page, so it can be built, tested and reused on its own.
|
|
10
|
+
- **Just JavaScript** - the UI is described with plain data and functions, with no template language to learn and no build step required.
|
|
11
|
+
- **Predictable state** - the state changes only in explicit, named steps, and the UI always reflects the current state.
|
|
12
|
+
- **Built on the platform** - it relies on what the browser already provides, like Web Components and ES modules, rather than working around it.
|
|
13
|
+
- **Mistakes caught early** - types and a debug mode point out errors in the UI while it is being written.
|
|
14
|
+
- **Extensible** - plugins add behaviour across all the apps, like logging, shared styles or helper methods, without changing them.
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import toolkit, {
|
|
20
|
+
WebComponent,
|
|
21
|
+
type CommandsAPI,
|
|
22
|
+
type Template,
|
|
23
|
+
} from 'web-toolkit-x'
|
|
24
|
+
|
|
25
|
+
type Props = { start: number }
|
|
26
|
+
type State = { count: number }
|
|
27
|
+
|
|
28
|
+
const CounterCommands = {
|
|
29
|
+
increment() {
|
|
30
|
+
this.count += 1
|
|
31
|
+
},
|
|
32
|
+
} satisfies CommandsAPI<State>
|
|
33
|
+
|
|
34
|
+
class Counter extends WebComponent<Props, State, typeof CounterCommands> {
|
|
35
|
+
static elementName = 'my-counter'
|
|
36
|
+
|
|
37
|
+
static styles = ['styles/counter.css']
|
|
38
|
+
|
|
39
|
+
static commands = CounterCommands
|
|
40
|
+
|
|
41
|
+
getInitialState(props: Props): State {
|
|
42
|
+
return { count: props.start }
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
render(): Template {
|
|
46
|
+
return [
|
|
47
|
+
'button',
|
|
48
|
+
{ onClick: () => this.commands.increment() },
|
|
49
|
+
`Clicked ${this.props.count} times`,
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
await toolkit.render(Counter, document.body, { start: 0 })
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The types are optional, the same component works in plain JavaScript without them.
|
|
58
|
+
|
|
59
|
+
Toolkit is also available as a single script, exposing the `toolkit` global:
|
|
60
|
+
|
|
61
|
+
```html
|
|
62
|
+
<script src="toolkit-0.70.0.js"></script>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Configuration
|
|
66
|
+
|
|
67
|
+
Toolkit renders without the debug mode and plugins by default. Both can be configured at any time, also after rendering. Options not provided keep their current values. Changed plugins are uninstalled from the created roots and the new ones installed:
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
toolkit.configure({ debug: true, plugins: [plugin] })
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Components
|
|
74
|
+
|
|
75
|
+
Web Components render the content of an app, managing its state. Nested Web Components are rendered in their own custom elements.
|
|
76
|
+
Their state is created from the props in `getInitialState()` and updated with commands, or by the parent with `getUpdatedState()`.
|
|
77
|
+
|
|
78
|
+
Components render fragments of a Web Component from props, and pure components are just functions:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
const Square = (props: { color: string; size: number }): Template => [
|
|
82
|
+
'section',
|
|
83
|
+
{
|
|
84
|
+
class: 'square',
|
|
85
|
+
style: {
|
|
86
|
+
backgroundColor: props.color,
|
|
87
|
+
height: [props.size, 'px'],
|
|
88
|
+
width: [props.size, 'px'],
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Both can define the `onCreated()`, `onAttached()`, `onPropsReceived()`, `onUpdated()`, `onDestroyed()` and `onDetached()` lifecycle methods.
|
|
95
|
+
|
|
96
|
+
Read more about [Bragi templates](BRAGI.md), the [Commands API](COMMANDS.md) and see a few [examples](EXAMPLES.md).
|
|
97
|
+
|
|
98
|
+
## TypeScript
|
|
99
|
+
|
|
100
|
+
Components are typed with their props, and their `render()` methods return a `Template`. Templates are type-checked, so misspelled props and attributes, unknown style properties or listeners of wrong event types are reported:
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import { Component, type Template } from 'web-toolkit-x'
|
|
104
|
+
|
|
105
|
+
class Title extends Component<{ text: string }> {
|
|
106
|
+
render(): Template {
|
|
107
|
+
return ['h1', { class: 'title' }, this.props.text]
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Child templates passed to a component are available as `this.children`:
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
class Card extends Component<{ title: string }> {
|
|
116
|
+
render(): Template {
|
|
117
|
+
return ['section', ['h2', this.props.title], ...this.children]
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Web Components take the types of props, state and the Commands API: `WebComponent<Props, State, Commands>`. The Commands API is typed with the state it changes, using `satisfies CommandsAPI<State>`, as in the usage example above.
|
|
123
|
+
|
|
124
|
+
## Build
|
|
125
|
+
|
|
126
|
+
```sh
|
|
127
|
+
npm run build
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
It creates in `dist/release`:
|
|
131
|
+
|
|
132
|
+
- `index.js` - an ES module with type declarations in `index.d.ts`,
|
|
133
|
+
- `toolkit-<version>.js` - a single script exposing the `toolkit` global,
|
|
134
|
+
|
|
135
|
+
both with source maps, and a declaration map leading editors to the TypeScript sources.
|
|
136
|
+
|
|
137
|
+
`npm run dev` creates the same files in `dist/dev` and builds them again on every change.
|
|
138
|
+
|
|
139
|
+
## Demo
|
|
140
|
+
|
|
141
|
+
```sh
|
|
142
|
+
npm run demo
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
It builds Toolkit and runs the demo with the ES module build.
|
|
146
|
+
|
|
147
|
+
## Development
|
|
148
|
+
|
|
149
|
+
Toolkit requires Node 24, as defined in `.nvmrc`:
|
|
6
150
|
|
|
7
151
|
```sh
|
|
8
|
-
|
|
152
|
+
nvm use
|
|
153
|
+
npm install
|
|
154
|
+
npx playwright install chromium # once, for running the tests
|
|
9
155
|
```
|
|
10
156
|
|
|
11
|
-
|
|
157
|
+
| Command | Description |
|
|
158
|
+
| ------------------- | ------------------------------------------------------------------- |
|
|
159
|
+
| `npm test` | runs the tests in Chromium with Vitest |
|
|
160
|
+
| `npm run build` | builds Toolkit into `dist/release` |
|
|
161
|
+
| `npm run dev` | builds Toolkit into `dist/dev` on every change |
|
|
162
|
+
| `npm run typecheck` | checks the types with TypeScript |
|
|
163
|
+
| `npm run lint` | lints the code with ESLint |
|
|
164
|
+
| `npm run verify` | runs the build, the type check, the linter and the formatting check |
|
|
165
|
+
| `npm run format` | formats the code with Prettier |
|
|
166
|
+
| `npm run coverage` | runs the tests with the coverage report |
|
|
167
|
+
| `npm run bench` | runs the benchmarks |
|
|
12
168
|
|
|
13
|
-
|
|
169
|
+
Git hooks format and lint the committed files, and run the checks and tests before pushing.
|