@ydant/base 0.1.0 → 0.1.2
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 +54 -41
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -25,8 +25,8 @@ pnpm add @ydant/base
|
|
|
25
25
|
## Usage
|
|
26
26
|
|
|
27
27
|
```typescript
|
|
28
|
-
import { mount } from "@ydant/core";
|
|
29
|
-
import { createBasePlugin, div, p, text, classes
|
|
28
|
+
import { mount, type Component } from "@ydant/core";
|
|
29
|
+
import { createBasePlugin, div, p, text, classes } from "@ydant/base";
|
|
30
30
|
|
|
31
31
|
const Greeting: Component = () =>
|
|
32
32
|
div(function* () {
|
|
@@ -53,30 +53,34 @@ The base plugin extends `RenderContext` and `PluginAPI`:
|
|
|
53
53
|
// RenderContext extensions
|
|
54
54
|
interface RenderContextExtensions {
|
|
55
55
|
isCurrentElementReused: boolean;
|
|
56
|
-
pendingKey: string | number | null;
|
|
57
56
|
keyedNodes: Map<string | number, KeyedNode>;
|
|
58
57
|
mountCallbacks: Array<() => void | (() => void)>;
|
|
59
58
|
unmountCallbacks: Array<() => void>;
|
|
60
59
|
}
|
|
61
60
|
|
|
62
|
-
// PluginAPI extensions
|
|
61
|
+
// PluginAPI extensions
|
|
63
62
|
interface PluginAPIExtensions {
|
|
64
63
|
// DOM operations
|
|
65
|
-
readonly
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
setCurrentElement(element: Element | null): void;
|
|
64
|
+
readonly parent: Node;
|
|
65
|
+
readonly currentElement: globalThis.Element | null;
|
|
66
|
+
setCurrentElement(element: globalThis.Element | null): void;
|
|
69
67
|
setParent(parent: Node): void;
|
|
68
|
+
appendChild(node: Node): void;
|
|
70
69
|
|
|
71
70
|
// Lifecycle
|
|
72
71
|
onMount(callback: () => void | (() => void)): void;
|
|
73
72
|
onUnmount(callback: () => void): void;
|
|
74
73
|
addUnmountCallbacks(...callbacks: Array<() => void>): void;
|
|
75
74
|
executeMount(): void;
|
|
75
|
+
getUnmountCallbacks(): Array<() => void>;
|
|
76
|
+
|
|
77
|
+
// Children processing
|
|
78
|
+
processChildren(builder: Builder, options?: { parent?: Node; inheritContext?: boolean }): void;
|
|
79
|
+
createChildAPI(parent: Node): PluginAPI;
|
|
76
80
|
|
|
77
81
|
// Keyed elements
|
|
78
|
-
readonly
|
|
79
|
-
|
|
82
|
+
readonly isCurrentElementReused: boolean;
|
|
83
|
+
setCurrentElementReused(reused: boolean): void;
|
|
80
84
|
getKeyedNode(key: string | number): KeyedNode | undefined;
|
|
81
85
|
setKeyedNode(key: string | number, node: KeyedNode): void;
|
|
82
86
|
deleteKeyedNode(key: string | number): void;
|
|
@@ -89,18 +93,25 @@ HTML elements: `div`, `span`, `p`, `button`, `input`, `h1`-`h3`, `ul`, `li`, `a`
|
|
|
89
93
|
|
|
90
94
|
SVG elements: `svg`, `circle`, `ellipse`, `line`, `path`, `polygon`, `polyline`, `rect`, `g`, `defs`, `use`, `clipPath`, `mask`, `linearGradient`, `radialGradient`, `stop`, `svgText`, `tspan`
|
|
91
95
|
|
|
96
|
+
Custom elements can be created with factory helpers:
|
|
97
|
+
|
|
98
|
+
| Function | Description |
|
|
99
|
+
| ------------------------ | ----------------------------------------- |
|
|
100
|
+
| `createHTMLElement(tag)` | Create an element factory for an HTML tag |
|
|
101
|
+
| `createSVGElement(tag)` | Create an element factory for an SVG tag |
|
|
102
|
+
|
|
92
103
|
### Primitives
|
|
93
104
|
|
|
94
|
-
| Function | Description
|
|
95
|
-
| --------------------- |
|
|
96
|
-
| `text(content)` | Create a text node
|
|
97
|
-
| `attr(key, value)` | Set an HTML attribute
|
|
98
|
-
| `classes(...names)` | Set class attribute
|
|
99
|
-
| `on(event, handler)` | Add event listener
|
|
100
|
-
| `style(styles)` | Set inline styles
|
|
101
|
-
| `key
|
|
102
|
-
| `onMount(callback)` | Lifecycle hook for mount
|
|
103
|
-
| `onUnmount(callback)` | Lifecycle hook for unmount
|
|
105
|
+
| Function | Description |
|
|
106
|
+
| --------------------- | ------------------------------------- |
|
|
107
|
+
| `text(content)` | Create a text node |
|
|
108
|
+
| `attr(key, value)` | Set an HTML attribute |
|
|
109
|
+
| `classes(...names)` | Set class attribute |
|
|
110
|
+
| `on(event, handler)` | Add event listener |
|
|
111
|
+
| `style(styles)` | Set inline styles |
|
|
112
|
+
| `keyed(key, factory)` | Wrap a factory with a key for diffing |
|
|
113
|
+
| `onMount(callback)` | Lifecycle hook for mount |
|
|
114
|
+
| `onUnmount(callback)` | Lifecycle hook for unmount |
|
|
104
115
|
|
|
105
116
|
#### `on()` Type Overloads
|
|
106
117
|
|
|
@@ -128,19 +139,19 @@ yield *
|
|
|
128
139
|
|
|
129
140
|
### Types
|
|
130
141
|
|
|
131
|
-
| Type | Description
|
|
132
|
-
| --------------- |
|
|
133
|
-
| `Slot` | `{ node: HTMLElement, refresh: (
|
|
134
|
-
| `SlotRef` |
|
|
135
|
-
| `
|
|
136
|
-
| `
|
|
137
|
-
| `
|
|
138
|
-
| `
|
|
139
|
-
| `
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
142
|
-
|
|
143
|
-
|
|
142
|
+
| Type | Description |
|
|
143
|
+
| --------------- | -------------------------------------------------------------- |
|
|
144
|
+
| `Slot` | `{ readonly node: HTMLElement, refresh: (children) => void }` |
|
|
145
|
+
| `SlotRef` | Reference holder for a `Slot`, created by `createSlotRef()` |
|
|
146
|
+
| `ElementRender` | `Generator<Element, Slot, ChildNext>` - Element factory return |
|
|
147
|
+
| `Element` | Tagged type for HTML/SVG elements |
|
|
148
|
+
| `Attribute` | Tagged type for attributes |
|
|
149
|
+
| `Listener` | Tagged type for event listeners |
|
|
150
|
+
| `Text` | Tagged type for text nodes |
|
|
151
|
+
| `Lifecycle` | Tagged type for lifecycle hooks |
|
|
152
|
+
| `Decoration` | Union type `Attribute \| Listener` |
|
|
153
|
+
|
|
154
|
+
> `Render`, `Component` types are defined in `@ydant/core`.
|
|
144
155
|
|
|
145
156
|
### createSlotRef
|
|
146
157
|
|
|
@@ -148,34 +159,36 @@ yield *
|
|
|
148
159
|
function createSlotRef(): SlotRef;
|
|
149
160
|
|
|
150
161
|
interface SlotRef {
|
|
151
|
-
current: Slot | null;
|
|
162
|
+
readonly current: Slot | null;
|
|
163
|
+
bind(slot: Slot): void;
|
|
164
|
+
refresh(children: Builder): void;
|
|
165
|
+
readonly node: HTMLElement | null;
|
|
152
166
|
}
|
|
153
167
|
```
|
|
154
168
|
|
|
155
|
-
Creates a
|
|
169
|
+
Creates a reference holder for a `Slot`. Use `bind()` to associate a Slot, then `refresh()` and `node` to interact with it:
|
|
156
170
|
|
|
157
171
|
```typescript
|
|
158
172
|
const ref = createSlotRef();
|
|
159
173
|
|
|
160
174
|
yield *
|
|
161
175
|
div(function* () {
|
|
162
|
-
ref.
|
|
176
|
+
ref.bind(yield* div(() => [text("Content")]));
|
|
163
177
|
});
|
|
164
178
|
|
|
165
179
|
// Later: update via ref
|
|
166
|
-
ref.
|
|
180
|
+
ref.refresh(() => [text("Updated!")]);
|
|
167
181
|
```
|
|
168
182
|
|
|
169
|
-
###
|
|
183
|
+
### keyed() and Element Reuse
|
|
170
184
|
|
|
171
|
-
|
|
185
|
+
`keyed()` wraps an element factory or component, attaching a key for list diffing. The same key will reuse the existing DOM element:
|
|
172
186
|
|
|
173
187
|
```typescript
|
|
174
188
|
yield *
|
|
175
189
|
ul(function* () {
|
|
176
190
|
for (const item of items) {
|
|
177
|
-
yield*
|
|
178
|
-
yield* li(() => [text(item.name)]);
|
|
191
|
+
yield* keyed(item.id, li)(() => [text(item.name)]);
|
|
179
192
|
}
|
|
180
193
|
});
|
|
181
194
|
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ydant/base",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Base DSL primitives and plugin for Ydant",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dom",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
}
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"@ydant/core": "0.1.
|
|
43
|
+
"@ydant/core": "0.1.1"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|
|
46
46
|
"build": "vite build",
|