@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.
Files changed (2) hide show
  1. package/README.md +54 -41
  2. 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, type Component } from "@ydant/base";
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 (in addition to core's parent, currentElement, processChildren, createChildAPI)
61
+ // PluginAPI extensions
63
62
  interface PluginAPIExtensions {
64
63
  // DOM operations
65
- readonly isCurrentElementReused: boolean;
66
- setCurrentElementReused(reused: boolean): void;
67
- appendChild(node: Node): void;
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 pendingKey: string | number | null;
79
- setPendingKey(key: string | number | null): void;
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(value)` | Set key for list diffing |
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: (fn) => void }` |
134
- | `SlotRef` | Mutable reference holder for a `Slot`, created by `createSlotRef()` |
135
- | `Render` | `Generator<Child, ChildReturn, ChildNext>` - Rendering generator |
136
- | `Component` | `() => Render` - Root component type |
137
- | `ElementRender` | `Generator<Element, Slot, ChildNext>` - Element factory return |
138
- | `Element` | Tagged type for HTML/SVG elements |
139
- | `Attribute` | Tagged type for attributes |
140
- | `Listener` | Tagged type for event listeners |
141
- | `Text` | Tagged type for text nodes |
142
- | `Lifecycle` | Tagged type for lifecycle hooks |
143
- | `Key` | Tagged type for list keys |
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 mutable reference to a `Slot`. Useful for capturing a Slot reference within array syntax where `yield*` is not available:
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.current = yield* div(() => [text("Content")]);
176
+ ref.bind(yield* div(() => [text("Content")]));
163
177
  });
164
178
 
165
179
  // Later: update via ref
166
- ref.current?.refresh(() => [text("Updated!")]);
180
+ ref.refresh(() => [text("Updated!")]);
167
181
  ```
168
182
 
169
- ### Key and Element Reuse
183
+ ### keyed() and Element Reuse
170
184
 
171
- When using `key()` for list items, the same key will reuse the existing DOM element:
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* key(item.id);
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.0",
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.0"
43
+ "@ydant/core": "0.1.1"
44
44
  },
45
45
  "scripts": {
46
46
  "build": "vite build",