@fest-lib/lure 0.1.48 โ 0.1.49
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 +59 -266
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,305 +1,98 @@
|
|
|
1
|
-
<h1 align="center">๐ LUR
|
|
2
|
-
<p align="center"><img src="./assets/logo/logo-0.png" width="128" alt="LUR
|
|
3
|
-
|
|
4
|
-
---
|
|
1
|
+
<h1 align="center">๐ LUR.E</h1>
|
|
2
|
+
<p align="center"><img src="./assets/logo/logo-0.png" width="128" alt="LUR.E"></p>
|
|
5
3
|
|
|
6
4
|
<p align="center">
|
|
7
|
-
<a href="https://
|
|
8
|
-
<a href="
|
|
9
|
-
<a href="https://github.com/fest-live/lur.e
|
|
10
|
-
<a href="https://github.com/fest-live/lur.e/issues"><img src="https://img.shields.io/github/issues/fest-live/lur.e?style=flat-square" alt="Issues"/></a>
|
|
5
|
+
<a href="https://www.npmjs.com/package/@fest-lib/lure"><img src="https://img.shields.io/npm/v/@fest-lib/lure?style=flat-square" alt="npm"></a>
|
|
6
|
+
<a href="LICENSE"><img src="https://img.shields.io/npm/l/@fest-lib/lure?style=flat-square" alt="MIT"></a>
|
|
7
|
+
<a href="https://github.com/fest-live/lur.e"><img src="https://img.shields.io/github/stars/fest-live/lur.e?style=flat-square" alt="stars"></a>
|
|
11
8
|
</p>
|
|
12
9
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
`@fest-lib/lure` (LUR.E) is the fest-lib reactive DOM layer. It binds `@fest-lib/object` refs to real nodes (`E`, `H`, `M`, `Q`, `T`, `C`, `S`), form/input observers, overlay placement, and drag helpers. Web components and CSS-in-JS (`S`) are first-class.
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## โจ Features
|
|
20
|
-
|
|
21
|
-
- **Efficient Memory Management**
|
|
22
|
-
- **Advanced Cache & Reaction System**
|
|
23
|
-
- **Low-Level DOM Manipulation**
|
|
24
|
-
- **Full CSS Compatibility**
|
|
25
|
-
- **Web Components Support**
|
|
26
|
-
- **Experimental Typed OM**
|
|
27
|
-
- **Attribute Mutation Observer**
|
|
28
|
-
- **Reactive Input Handling**
|
|
29
|
-
|
|
30
|
-
---
|
|
10
|
+
`@fest-lib/lure` โ level 2 reactive DOM. Binds `@fest-lib/object` refs to real nodes (`E`, `H`, `M`, `Q`, `T`, `C`, `S`), forms, overlays, and drag. Web components and CSS-in-JS (`S`) are first-class.
|
|
31
11
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
npm install @fest-lib/object
|
|
37
|
-
npm install @fest-lib/dom
|
|
38
|
-
npm install @fest-lib/uniform
|
|
39
|
-
npm install @fest-lib/lure
|
|
12
|
+
```text
|
|
13
|
+
core ยท dom ยท object ยท uniform
|
|
14
|
+
โโโ fest/lure โ you are here
|
|
15
|
+
โโโ icon ยท image ยท veela ยท fl-ui
|
|
40
16
|
```
|
|
41
17
|
|
|
42
|
-
|
|
43
|
-
- Other previously is dependencies.
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
## ๐ API Overview
|
|
48
|
-
|
|
49
|
-
The core API provides a concise and powerful way to work with the DOM:
|
|
18
|
+
## Install
|
|
50
19
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
- `M(Array|Set, generateCb)`
|
|
54
|
-
- Map arrays or sets to DOM elements.
|
|
55
|
-
- `H(DOMCode)` or `` H`DOMCode` ``
|
|
56
|
-
- Create static DOM HTML from code.
|
|
57
|
-
- `T(String|StringRef)` or `` T`Code` ``
|
|
58
|
-
- Create a TextNode object (with reactive support).
|
|
59
|
-
- `C(ref, whatToMake)`
|
|
60
|
-
- Create changeable DOM element (include for texts).
|
|
61
|
-
- `S(CSSCode)` or `` S`CSSCode` ``
|
|
62
|
-
- Create controllable CSS code for elements
|
|
63
|
-
- `Q(selector, root)`
|
|
64
|
-
- Make dynamically query selected wrapper
|
|
65
|
-
- Alternative of JQuery features, which is static
|
|
66
|
-
|
|
67
|
-
---
|
|
68
|
-
|
|
69
|
-
## API Specification
|
|
70
|
-
|
|
71
|
-
This is a consolidated, human-friendly overview of the public API exported from `src/index.ts`. For the full, generated reference, see the markdown files under `./docs/`.
|
|
72
|
-
|
|
73
|
-
### Imports
|
|
74
|
-
|
|
75
|
-
```ts
|
|
76
|
-
import {
|
|
77
|
-
// Core
|
|
78
|
-
bindBeh, bindCtrl, bindHandler, bindWith, bindForms,
|
|
79
|
-
$observeInput, $observeAttribute,
|
|
80
|
-
// Refs
|
|
81
|
-
makeRef, attrRef, valueRef, valueAsNumberRef, localStorageRef,
|
|
82
|
-
sizeRef, checkedRef, scrollRef, visibleRef, matchMediaRef, hashTargetRef, orientRef, makeWeakRef,
|
|
83
|
-
// Node
|
|
84
|
-
E, M, Q, createElement, H,
|
|
85
|
-
// Extensions (selected)
|
|
86
|
-
bindDraggable, grabForDrag, agWrapEvent,
|
|
87
|
-
} from "@fest-lib/lure";
|
|
20
|
+
```bash
|
|
21
|
+
npm install @fest-lib/core @fest-lib/dom @fest-lib/object @fest-lib/uniform @fest-lib/lure
|
|
88
22
|
```
|
|
89
23
|
|
|
90
|
-
|
|
24
|
+
Peers: `core`, `dom`, `object`, `uniform` (`>=0.1.0`). ESM, `sideEffects: true`.
|
|
91
25
|
|
|
92
26
|
```ts
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
attributes: { id: "app" },
|
|
96
|
-
classList: new Set(["box"]),
|
|
97
|
-
style: { padding: "8px" },
|
|
98
|
-
}, [
|
|
99
|
-
"Hello",
|
|
100
|
-
]);
|
|
27
|
+
import { E, H, M, Q, T } from "@fest-lib/lure";
|
|
28
|
+
import { observe, iterated } from "@fest-lib/object";
|
|
101
29
|
|
|
30
|
+
const el = E("div", {
|
|
31
|
+
attributes: { id: "app" },
|
|
32
|
+
classList: new Set(["box"]),
|
|
33
|
+
style: { padding: "8px" },
|
|
34
|
+
on: { click: () => console.log("hi") }
|
|
35
|
+
}, ["Hello"]);
|
|
102
36
|
document.body.append(el as Node);
|
|
103
37
|
```
|
|
104
38
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
- `bindBeh(element, store, behavior)`: Invoke `behavior` on store changes.
|
|
108
|
-
- `bindCtrl(element, ctrlCb)`: Wire common input/change/click listeners.
|
|
109
|
-
- `bindHandler(element, value, prop, handler, set?, withObserver?)`: Generic bridge for refs โ DOM.
|
|
110
|
-
- `bindWith(el, prop, value, handler, set?, withObserver?)`: Apply once and affected.
|
|
111
|
-
- `bindForms(fields?, wrapper?, state?)`: Two-way bind inputs within a container to a reactive `state`.
|
|
112
|
-
- `$observeInput(element, ref?, prop = "value")`: Sync input property to ref.
|
|
113
|
-
- `$observeAttribute(el, ref?, prop)`: Sync attribute to ref.
|
|
114
|
-
|
|
115
|
-
### Refs
|
|
39
|
+
## Factory map
|
|
116
40
|
|
|
117
|
-
|
|
41
|
+
| API | Role |
|
|
42
|
+
| --- | --- |
|
|
43
|
+
| `E(tag \| node, props, children)` | create / wrap + bind |
|
|
44
|
+
| `H\`html\`` / `H("<div>")` | parse HTML or tagged template |
|
|
45
|
+
| `M(list, mapFn)` | reactive list โ nodes |
|
|
46
|
+
| `Q(selector, root?)` | live query wrapper |
|
|
47
|
+
| `T(string \| ref)` | text node |
|
|
48
|
+
| `C(ref, factory)` | swap node when ref changes |
|
|
49
|
+
| `S\`css\`` | controllable stylesheet |
|
|
118
50
|
|
|
119
|
-
|
|
120
|
-
- `attrRef(host, name)`, `valueRef(host, name)`, `valueAsNumberRef(host, name)`
|
|
121
|
-
- `localStorageRef(key)`, `sizeRef(host, prop?)`, `checkedRef(host)`, `scrollRef(host, prop?)`, `visibleRef(host)`
|
|
122
|
-
- `matchMediaRef(query)`, `hashTargetRef()`, `orientRef(host)`
|
|
123
|
-
- `makeWeakRef(initial?, behavior?)`
|
|
124
|
-
|
|
125
|
-
### Node API
|
|
126
|
-
|
|
127
|
-
#### `E`: Element factory with bindings
|
|
51
|
+
`H` prefixes: `attr:*` attribute ยท `prop:*` property ยท `on:*` / `@*` event ยท `ref` / `ref:*` assign.
|
|
128
52
|
|
|
129
53
|
```ts
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
on: { click: (e) => console.log("clicked", e) },
|
|
134
|
-
}, ["OK"]);
|
|
54
|
+
const items = iterated(["A", "B"]);
|
|
55
|
+
const list = H`<ul>${M(items, (x) => H`<li>${x}</li>`)}</ul>`;
|
|
56
|
+
items.push("C"); // DOM updates
|
|
135
57
|
```
|
|
136
58
|
|
|
137
|
-
|
|
59
|
+
## Triggers & overlays
|
|
138
60
|
|
|
139
|
-
|
|
140
|
-
// Use with JSX if configured (jsxFactory: createElement)
|
|
141
|
-
const v = createElement("div", { className: "c" }, ["hello"]);
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
#### `Q`: Query wrapper
|
|
61
|
+
Use these instead of ad-hoc listeners:
|
|
145
62
|
|
|
146
63
|
```ts
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
`M(observable, mapper)` maps a reactive array/set into DOM. Returns a reactive fragment-like node.
|
|
154
|
-
|
|
155
|
-
```ts
|
|
156
|
-
import { observe } from "@fest-lib/object";
|
|
157
|
-
|
|
158
|
-
const rxItems = iterated(["A", "B", "C"]);
|
|
159
|
-
const list = H`<ul>${M(rxItems, (x) => H`<li>${x}</li>`)}</ul>`;
|
|
160
|
-
|
|
161
|
-
// later
|
|
162
|
-
rxItems.push("D"); // DOM updates
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
### `H` and HTML Templates
|
|
166
|
-
|
|
167
|
-
`H` supports both raw HTML strings and tagged template strings.
|
|
168
|
-
|
|
169
|
-
- Raw string starting/ending with `<`/`>` โ parsed into `Node`/`DocumentFragment`.
|
|
170
|
-
- Plain string โ `Text` node.
|
|
171
|
-
- Function โ invoked and processed recursively.
|
|
172
|
-
- Tagged template โ interpolates values into content/attributes/events/props.
|
|
173
|
-
|
|
174
|
-
Attribute/prop/event/ref prefixes inside tagged templates:
|
|
175
|
-
|
|
176
|
-
- `attr:*` โ HTML attribute
|
|
177
|
-
- `prop:*` โ DOM property
|
|
178
|
-
- `on:*` or `@*` โ event listener
|
|
179
|
-
- `ref` or `ref:*` โ assigns element to ref(s)
|
|
180
|
-
|
|
181
|
-
Examples:
|
|
182
|
-
|
|
183
|
-
```ts
|
|
184
|
-
// Raw string โ Node
|
|
185
|
-
const el = H("<div class=box>hello</div>");
|
|
186
|
-
|
|
187
|
-
// Tagged template โ content interpolation
|
|
188
|
-
const name = "World";
|
|
189
|
-
const title = H`<h1 class="title">Hello, ${name}!</h1>`;
|
|
190
|
-
|
|
191
|
-
// Dynamic tag: supports tag#id.class1.class2
|
|
192
|
-
const tag = "button.primary";
|
|
193
|
-
const btn = H`<${tag}>Click</${tag}>`;
|
|
194
|
-
|
|
195
|
-
// Attributes/props/events/refs
|
|
196
|
-
const ref = { value: null as HTMLElement | null };
|
|
197
|
-
const click = (e: Event) => console.log("clicked", e);
|
|
198
|
-
const button = H`<button attr:title=${"Click"} prop:disabled=${false} on:click=${click} ref=${ref}>OK</button>`;
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
Static vs Reactive lists in `H` content:
|
|
202
|
-
|
|
203
|
-
```ts
|
|
204
|
-
// Static (non-reactive) mapping in template content
|
|
205
|
-
const items = ["A", "B", "C"];
|
|
206
|
-
const listStatic = H`<ul>${items.map(x => H`<li>${x}</li>`)}</ul>`;
|
|
207
|
-
|
|
208
|
-
// Reactive list: use M(...)
|
|
209
|
-
import { observe } from "@fest-lib/object";
|
|
210
|
-
const rxItems = iterated(["A", "B", "C"]);
|
|
211
|
-
const listReactive = H`<ul>${M(rxItems, (x) => H`<li>${x}</li>`)}</ul>`;
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
Multiple top-level nodes produce a `DocumentFragment`:
|
|
215
|
-
|
|
216
|
-
```ts
|
|
217
|
-
const frag = H`<div>one</div><div>two</div>`; // DocumentFragment
|
|
64
|
+
import {
|
|
65
|
+
withTriggerModifiers,
|
|
66
|
+
bindOutsideDismiss,
|
|
67
|
+
resolvePlacement,
|
|
68
|
+
registerTransientOverlay
|
|
69
|
+
} from "@fest-lib/lure";
|
|
218
70
|
```
|
|
219
71
|
|
|
220
|
-
|
|
72
|
+
- **TriggerCore** โ `once` / `debounce` / `prevent` / `stop` / `capture` / `passive` via `withTriggerModifiers` and `E({ on })` tuples.
|
|
73
|
+
- **bindOutsideDismiss** โ composed path, panel roots, Escape, idempotent cleanup.
|
|
74
|
+
- **resolvePlacement** / `placeOverlay` โ CSS-anchor with JS fallback.
|
|
75
|
+
- **registerTransientOverlay** โ same-kind overlays close LIFO.
|
|
221
76
|
|
|
222
|
-
|
|
77
|
+
Forms: `formLink` / `bindForms` / `FormBinding` (`bindFormControl`, `formRef`). Mount lifecycle is opt-in (`bindWhileConnected`).
|
|
223
78
|
|
|
224
79
|
```ts
|
|
225
|
-
import { bindDraggable
|
|
226
|
-
|
|
227
|
-
const target = H`<div class="draggable" />` as HTMLElement;
|
|
80
|
+
import { bindDraggable } from "@fest-lib/lure";
|
|
228
81
|
bindDraggable(target, () => console.log("drag end"));
|
|
229
82
|
```
|
|
230
83
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
**Flexible handling of refs and DOM elements:**
|
|
84
|
+
## Also in the package
|
|
234
85
|
|
|
235
|
-
|
|
236
|
-
- HTML DOM elements also can be placed as content of other DOM elements
|
|
237
|
-
- `ref(...)` are reactive and will be updated when the referenced content changes
|
|
86
|
+
OPFS / file helpers (`pickFile`, `saveFile`, markdown asset bind), clipboard, history, scrollbar, voice input, theme / color engines. Subpath: `@fest-lib/lure/markdown-assets`. JSX: `jsxFactory` โ `createElement` (`@fest-lib/lure/src/lure/node/jsx-runtime`).
|
|
238
87
|
|
|
239
|
-
|
|
240
|
-
import { ref } from "@fest-lib/object";
|
|
241
|
-
import { H } from "@fest-lib/lure";
|
|
242
|
-
|
|
243
|
-
// referenced content is also a DOM element (`Text` node)
|
|
244
|
-
const txt = ref("Hello");
|
|
245
|
-
const hookOf = (el: HTMLElement) => { console.log(el); };
|
|
246
|
-
const span = H`<span ref=${hookOf}>${txt}</span>`; // span is a DOM element (`HTMLSpanElement`)
|
|
247
|
-
const button = H`<button>${span}</button>`;
|
|
248
|
-
|
|
249
|
-
// Regular DOM elements
|
|
250
|
-
const regular = document.createElement("span");
|
|
251
|
-
regular.textContent = "Hello";
|
|
252
|
-
const another = H`<button>${regular}</button>`;
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
### Documentation
|
|
256
|
-
|
|
257
|
-
- Full markdown API reference is generated into `./docs/` by:
|
|
258
|
-
|
|
259
|
-
```bash
|
|
260
|
-
npm run docs:md
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
- HTML documentation can be generated by:
|
|
88
|
+
## Workspace
|
|
264
89
|
|
|
265
90
|
```bash
|
|
266
|
-
|
|
91
|
+
cd modules/projects/lur.e
|
|
92
|
+
npm test # linker, interaction, placement, overlay-host, trigger-core, form-binding
|
|
93
|
+
npm run demo
|
|
94
|
+
npm run build
|
|
95
|
+
npm run publish
|
|
267
96
|
```
|
|
268
97
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
## ๐ง Roadmap & Plans
|
|
272
|
-
|
|
273
|
-
- Investigate advanced MutationObserver and IntersectionObserver features for DOM tree changes.
|
|
274
|
-
- Explore integration with [Web Animations API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Animations_API).
|
|
275
|
-
- Research and implement animation-specific features, including scroll-driven animations and animation worklets.
|
|
276
|
-
- Consider adding support for ResizeObserver.
|
|
277
|
-
|
|
278
|
-
---
|
|
279
|
-
|
|
280
|
-
## ๐ License
|
|
281
|
-
|
|
282
|
-
This project is licensed under the [MIT License](./LICENSE).
|
|
283
|
-
|
|
284
|
-
---
|
|
285
|
-
|
|
286
|
-
## ๐ค Contributing
|
|
287
|
-
|
|
288
|
-
Contributions, issues, and feature requests are welcome!
|
|
289
|
-
Feel free to check [issues page](https://github.com/fest-live/lur.e/issues).
|
|
290
|
-
|
|
291
|
-
---
|
|
292
|
-
|
|
293
|
-
<p align="center"><b>Made with โค๏ธ by fest-live</b></p>
|
|
294
|
-
|
|
295
|
-
---
|
|
296
|
-
|
|
297
|
-
## About naming conflicts
|
|
298
|
-
|
|
299
|
-
- Originally, project was named as **BLU.E**.
|
|
300
|
-
- However, I won't have 'B' as first letter.
|
|
301
|
-
- Also, **LUR.E** also should been named as **BLUR**.
|
|
302
|
-
- However, I would to save 'E' letter at end.
|
|
303
|
-
- And also, I don't want 'B' as first letter.
|
|
304
|
-
- So, I decided to use **LUR.E** naming.
|
|
305
|
-
- However, that naming still controversial.
|
|
98
|
+
Typedoc: `npm run docs:md`. License: [MIT](LICENSE).
|