lightview 2.3.7 → 2.4.4

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 (43) hide show
  1. package/.gemini/CODE_ANALYSIS_AND_IMPROVEMENT_PLAN.md +56 -0
  2. package/AI-GUIDANCE.md +259 -0
  3. package/README.md +35 -0
  4. package/components/data-display/diff.js +36 -4
  5. package/docs/api/hypermedia.html +75 -5
  6. package/docs/api/index.html +3 -3
  7. package/docs/api/nav.html +0 -16
  8. package/docs/articles/html-vs-json-partials.md +102 -0
  9. package/docs/articles/lightview-vs-htmx.md +610 -0
  10. package/docs/benchmarks/tagged-fragment.js +36 -0
  11. package/docs/cdom.html +6 -5
  12. package/docs/components/chart.html +157 -210
  13. package/docs/components/component-nav.html +1 -1
  14. package/docs/components/diff.html +33 -21
  15. package/docs/components/gallery.html +107 -4
  16. package/docs/components/index.css +18 -3
  17. package/docs/components/index.html +20 -9
  18. package/docs/dom-benchmark.html +644 -0
  19. package/docs/getting-started/index.html +2 -2
  20. package/docs/hypermedia/index.html +391 -0
  21. package/docs/hypermedia/nav.html +17 -0
  22. package/docs/index.html +128 -18
  23. package/index.html +59 -10
  24. package/lightview-all.js +223 -67
  25. package/lightview-cdom.js +1 -2
  26. package/lightview-x.js +144 -13
  27. package/lightview.js +85 -277
  28. package/package.json +2 -2
  29. package/src/lightview-cdom.js +1 -5
  30. package/src/lightview-x.js +158 -27
  31. package/src/lightview.js +94 -60
  32. package/1769196538097-package.json +0 -43
  33. package/build_tmp/lightview-router.js +0 -185
  34. package/build_tmp/lightview-x.js +0 -1608
  35. package/build_tmp/lightview.js +0 -932
  36. package/docs/articles/calculator-no-javascript-hackernoon.md +0 -283
  37. package/docs/articles/calculator-no-javascript.md +0 -290
  38. package/docs/articles/part1-reference.md +0 -236
  39. package/lightview.js.bak +0 -1
  40. package/test-xpath.html +0 -63
  41. package/test_error.txt +0 -0
  42. package/test_output.txt +0 -0
  43. package/test_output_full.txt +0 -0
@@ -0,0 +1,56 @@
1
+ # cDOM / JPRX Code Analysis and Improvement Recommendations
2
+
3
+ ## 1. Executive Summary
4
+ This document outlines the analysis of the current JPRX (JSON Reactive Path eXpressions) and cDOM implementation within Lightview. While the system is powerful and integral to the framework's reactivity, its core logic (`jprx/parser.js`) has grown into a monolithic module that mixes tokenization, parsing, evaluation, and runtime state management. The primary recommendation is to refactor this into distinct layers to improve maintainability, performance, and testability.
5
+
6
+ ## 2. Current State Analysis
7
+
8
+ ### 2.1 Code Structure
9
+ * **Monolithic Design**: `jprx/parser.js` is approximately 1,900 lines long. It encapsulates:
10
+ * **Tokenizer**: Regex-based lexer (`tokenize`).
11
+ * **Pratt Parser**: Top-down operator precedence parser.
12
+ * **Evaluator**: `evaluateAST` and `resolvePath` logic.
13
+ * **Runtime Types**: `BindingTarget`, `LazyValue`.
14
+ * **Global Registry**: Storage for helpers and operators.
15
+ * **Coupling**: The parser is tightly coupled with Lightview's specific reactivity model (Signals/Proxies) via direct imports and assumption of `Lightview.state` structure.
16
+
17
+ ### 2.2 Performance
18
+ * **Repeated Parsing**: Currently, there is no visible caching mechanism for parsed ASTs. Every time an expression is evaluated (unless manually memoized externally), it goes through the tokenization and parsing steps.
19
+ * **Object Creation**: The heavy use of intermediate objects during AST traversals and resolution could trigger frequent garbage collection in high-frequency updates.
20
+
21
+ ### 2.3 DX and Reliability
22
+ * **Error Reporting**: Syntax errors in JPRX expressions often result in generic failures or silent returns, making debugging difficult for the end-user.
23
+ * **Complexity**: Adding new operators or features requires modifying the central file, increasing the risk of regressions.
24
+
25
+ ## 3. Improvement Recommendations
26
+
27
+ ### Phase 1: Modularization (High Priority)
28
+ Decompose `jprx/parser.js` into focused modules under a `jprx/core/` directory:
29
+
30
+ 1. **`tokenization.js`**: Pure functions handling string-to-token conversion.
31
+ 2. **`grammar.js`**: Definition of operators, precedence levels, and AST node types.
32
+ 3. **`parser.js`**: The Pratt parser implementation that outputs a pure AST.
33
+ 4. **`runtime.js`**: The `evaluateAST` logic and `BindingTarget`/`LazyValue` classes.
34
+ 5. **`registry.js`**: Singleton or context-based registry for helpers and operators.
35
+
36
+ ### Phase 2: Performance Enhancements
37
+ 1. **LRU Cache for ASTs**: Implement a Least Recently Used cache for the `tokenize -> parse` pipeline. If an expression string `count + 1` is seen again, serve the cached AST immediately.
38
+ 2. **Fast-Path for Simple Paths**: 90% of expressions are likely simple property access (e.g., `user.name`). Implement a proper regex check to bypass the full parser for these cases and use direct traversal.
39
+ 3. **Instruction Caching**: For repeated evaluations of the same AST, consider compiling to a closure (similar to how `new Function` works, but safe and sandboxed) if performance bottlenecks appear.
40
+
41
+ ### Phase 3: Robustness and Validation
42
+ 1. **Fuzz Testing**: Implement grammar-based fuzz testing to ensure the parser does not crash on malformed inputs.
43
+ 2. **Strict Mode**: Introduce a strict mode that throws descriptive errors for undefined paths or invalid operations, rather than silently failing.
44
+ 3. **Type Safety**: If possible, add JSDoc type definitions to all internal AST nodes to aid tooling and potential future TypeScript migration.
45
+
46
+ ## 4. Code Specific Observations
47
+
48
+ * **`BindingTarget` Implementation**: The current "duck-typing" (`isBindingTarget = true`) is practical but could be cleaner using `Symbol.for('jprx.bindingTarget')` to avoid property collision.
49
+ * **Operator Registration**: The dynamic `registerOperator` is powerful but allows overwriting core behavior. Consider locking core operators (math, logic) after initialization.
50
+ * **Reactivity Integration**: The dependency on `Lightview.state` could be abstracted behind an interface (e.g., `IReactiveSource`), allowing JPRX to be used with other state management libraries if desired.
51
+
52
+ ## 5. Next Steps
53
+ 1. Create the `jprx/core` directory structure.
54
+ 2. Move `BindingTarget` and `LazyValue` to a `types.js` file.
55
+ 3. Extract the `tokenize` function and unit test it in isolation.
56
+ 4. Draft the `AST` cache mechanism.
package/AI-GUIDANCE.md ADDED
@@ -0,0 +1,259 @@
1
+ # Lightview AI Guidance
2
+
3
+ This document is the **definitive guide** for Large Language Models (LLMs) on how to effectively use the Lightview library. It covers all development workflows, particularly emphasizing correct source file usage, hypermedia patterns, and dynamic generation.
4
+
5
+ ## Table of Contents
6
+ 1. [Critical: Source Files vs Modules](#source-files)
7
+ 2. [The Four UI Syntaxes](#the-four-ui-syntaxes)
8
+ 3. [Hypermedia & Lightview X](#hypermedia-lightview-x)
9
+ 4. [JPRX & cDOM (AI-Safe Generation)](#jprx-cdom)
10
+ 5. [Component System](#component-system)
11
+ 6. [Routing & Navigation](#routing-navigation)
12
+ 7. [AI Development Strategies](#ai-development-strategies)
13
+ 8. [Deep Links & Resources](#deep-links)
14
+
15
+ ---
16
+
17
+ <a name="source-files"></a>
18
+ ## 1. Critical: Source Files vs Modules
19
+
20
+ **PAY CAREFUL ATTENTION TO FILE TYPES.**
21
+
22
+ * **Standard Scripts (`.js`)**: These files exist in the root and are suitable for direct browser inclusion via script tags or simple bundling.
23
+ * `lightview.js`: The core reactive engine (Signals, State, $, Effect).
24
+ * `lightview-x.js`: The "Extension" module (Hypermedia, src fetching, simple validation, vDOM/oDOM conversion).
25
+ * `lightview-router.js`: The Router implementation.
26
+ * `lightview-cdom.js`: The parser for JPRX and cDOM.
27
+
28
+ * **ES Modules (in subdirectories)**: Files in `jprx/`, `components/`, etc., are ES modules.
29
+ * **Do not** reference these directly in a generic HTML script tag without `type="module"`.
30
+ * **Do** import them in your application logic files (e.g., `import { ... } from './jprx/parser.js'`).
31
+
32
+ **Guidance**: When helping a user set up a new project, prefer importing from the root standard scripts for simplicity, or set up a proper `build.js` if deep module imports are needed.
33
+
34
+ **Note on Syntaxes**:
35
+ - **Tagged API**: Supported in `lightview.js`.
36
+ - **vDOM**: Supported in `lightview.js` (standard `{ tag: ... }` objects).
37
+ - **oDOM**: Requires `lightview-x.js` (converts `{ div: ... }` usage).
38
+
39
+ ---
40
+
41
+ <a name="the-four-ui-syntaxes"></a>
42
+ ## 2. The Four UI Syntaxes
43
+
44
+ Choose the syntax that matches your goal.
45
+
46
+ ### A. Tagged API (Best for Logic)
47
+ Javascript functions representing HTML tags. Best for building applications with complex logic.
48
+ ```javascript
49
+ const { div, h1, button } = Lightview.tags;
50
+ const count = signal(0);
51
+
52
+ const view = div({ class: "p-4" },
53
+ h1("Counter"),
54
+ button({ onclick: () => count.value++ }, () => `Count: ${count.value}`)
55
+ );
56
+ ```
57
+
58
+ ### B. vDOM (Best for Structured Data)
59
+ Explicit JSON structure. Use this when you need a standard, serializable format.
60
+ ```javascript
61
+ const view = {
62
+ tag: "div",
63
+ attributes: { class: "p-4" },
64
+ children: [
65
+ { tag: "h1", children: ["Counter"] },
66
+ { tag: "button", attributes: { onclick: () => count.value++ }, children: [() => `Count: ${count.value}`] }
67
+ ]
68
+ };
69
+ ```
70
+
71
+ ### C. oDOM (Best for Compact Templates)
72
+ "Object DOM" uses keys as tags. It is significantly more concise. **Preferred for configuration-based UIs.**
73
+ ```javascript
74
+ const view = {
75
+ div: {
76
+ class: "p-4",
77
+ children: [
78
+ { h1: "Counter" },
79
+ { button: { onclick: "...", children: ["Increment"] } }
80
+ ]
81
+ }
82
+ };
83
+ ```
84
+
85
+ ### D. Custom Elements (Best for Hybrid Apps)
86
+ Standard HTML tags powered by Lightview. Use these when enhancing an existing HTML page.
87
+ ```html
88
+ <lv-button onclick="alert('clicked')">Click Me</lv-button>
89
+ ```
90
+
91
+ ---
92
+
93
+ <a name="hypermedia-lightview-x"></a>
94
+ ## 3. Hypermedia & Lightview X
95
+
96
+ Lightview X adds powerful **Hypermedia** capabilities to standard HTML elements.
97
+
98
+ ### The `src` and `href` Attributes (Hypermedia)
99
+ * **`src`**: Fetches content and replaces the element or its content.
100
+ * **Support**: `.html`, `.json`, `.vdom`, `.odom`, `.cdom`, `.cdomc`
101
+ * **Usage**: `<div src="/components/user-card.vdom"></div>`
102
+ * **`href`**: Non-standard tags (like `div`) with `href` act as "Links".
103
+ * **Behavior**: Clicking them fetches the content at the URL and replaces the element's `src`.
104
+ * **Targeting**: Use `target="#dest:beforeend"` to direct the content elsewhere.
105
+ * **Usage**: `<div href="/api/next-page" target="#content:beforeend">Load More</div>`
106
+
107
+ ### Advanced Fetches (`data-method` & `data-body`)
108
+ Customize HTTP requests for `src` and `href` actions.
109
+
110
+ * **`data-method`**: Specify the HTTP verb (e.g., `POST`, `PUT`, `DELETE`). Defaults to `GET`.
111
+ * **`data-body`**: The data to send with the request.
112
+ * **CSS Selector (Default)**: Grabs the data from the DOM.
113
+ * `form`: Serialized as `FormData`.
114
+ * `input`/`select`/`textarea`: Sends the current `value`.
115
+ * `checkbox`/`radio`: Sends `value` only if checked.
116
+ * Other elements: Sends `innerText`.
117
+ * **`javascript:expr`**: Evaluates a Javascript expression (has access to `state` and `signal`).
118
+ * **`json:{...}`**: Sends a literal JSON string (sets `Content-Type: application/json`).
119
+ * **`text:...`**: Sends raw text (sets `Content-Type: text/plain`).
120
+ * **GET Requests**: If the method is `GET`, the data from `data-body` is automatically converted into **URL Query Parameters**.
121
+
122
+ **Usage**:
123
+ ```html
124
+ <!-- Post a form -->
125
+ <button href="/api/user/save" data-method="POST" data-body="#user-form">Save</button>
126
+
127
+ <!-- Fetch with query params from an input -->
128
+ <button href="/api/search" data-body="#search-input" target="#results">Search</button>
129
+ ```
130
+
131
+ * **Template Literals**: Supported in HTML, vDOM, and oDOM strings (e.g., `class="${ val > 10 ? 'red' : 'blue' }"`) via `lightview-x.js`.
132
+ * **Gating**:
133
+ 1. **`Lightview.hooks.validateUrl`**: Intercept/block URLs.
134
+ 2. **`lv-before`**: Attribute that gates events (e.g., `lv-before="click: throttle(500)"` or custom functions).
135
+
136
+ ### Logic in Attributes (`template literals`)
137
+ Lightview X allows embedded `${}` expressions in attributes for simple reactivity
138
+ ```javascript
139
+ {
140
+ div: {
141
+ class: "${ count.value > 10 ? 'text-red-500' : 'text-green-500' }",
142
+ children: ["Status"]
143
+ }
144
+ }
145
+ ```
146
+
147
+ ---
148
+
149
+ <a name="jprx-cdom"></a>
150
+ ## 4. JPRX & cDOM (Safe Dynamic UI Generation For Humans and AIs)
151
+
152
+ **cDOM (Computed DOM)** and **JPRX (JSON Reactive Expressions)** allow you to build fully reactive UIs using **only JSON**.
153
+
154
+ ### JPRX Helper Reference
155
+ JPRX supports a wide range of helpers. AI agents should use these instead of trying to write JS when builing streaming UIs at runtime.
156
+
157
+ | Category | Helpers |
158
+ | :--- | :--- |
159
+ | **Math** | `add`, `subtract`, `multiply`, `divide`, `mod`, `pow`, `abs`, `round`, `ceil`, `floor`, `sqrt`, `negate`, `toPercent` |
160
+ | **Logic** | `and`, `or`, `not`, `if`, `eq`, `neq`, `gt`, `lt`, `gte`, `lte` |
161
+ | **String** | `join`, `concat`, `upper`, `lower`, `trim`, `len`, `split`, `replace`, `capitalize`, `contains` |
162
+ | **Array** | `map`, `filter`, `reduce`, `push`, `pop`, `sort`, `reverse`, `slice`, `find` |
163
+ | **Stats** | `sum`, `avg`, `min`, `max`, `median`, `stdev`, `variance` |
164
+ | **Data** | `lookup(val, searchArr, resultArr)` (VLOOKUP-style) |
165
+ | **State** | `state(val, opts)`, `set(path, val)`, `bind(path)`, `increment`, `decrement`, `toggle` |
166
+ | **DOM** | `xpath(expr)` (Backward-looking only), `move(target, loc)` |
167
+ | **Net** | `fetchHelper(url, opts)`, `mount(url, opts)` |
168
+
169
+ ### The "Decentralized Layout" Pattern (AI Strategy)
170
+ 1. **Define**: Create a self-contained component with state.
171
+ 2. **Move**: Use `=move('#target')` in `onmount` to teleport it.
172
+ 3. **Stream**: Determine the update needed, generate the `.cdomc`, and let it patch itself.
173
+
174
+ ```javascript
175
+ /* .cdomc format */
176
+ {
177
+ div: {
178
+ id: "widget-1",
179
+ onmount: ["=state({val:0}, {name:'w1', scope:$this})", "=move('#sidebar')"],
180
+ children: [ { p: "Val: =/w1/val" } ]
181
+ }
182
+ }
183
+ ```
184
+
185
+ ---
186
+
187
+ <a name="component-system"></a>
188
+ ## 5. Component System
189
+
190
+ Built on **DaisyUI** and **Tailwind CSS**.
191
+
192
+ * **Import**: `import { Button } from './components/index.js';`
193
+ * **Init**: `LightviewX.initComponents()` (Shadow DOM).
194
+ * **Theming**: `Lightview.setTheme('dark')` or `localStorage.setItem('lightview-theme', 'dark')`.
195
+
196
+ ---
197
+
198
+ <a name="routing-navigation"></a>
199
+ ## 6. Routing & Navigation
200
+
201
+ The `LightviewRouter` uses a pipeline (chain) architecture.
202
+
203
+ ### Advanced: Middleware Chains
204
+ You can chain multiple handlers for a single route. This is powerful for authentication or data pre-loading.
205
+ ```javascript
206
+ const checkAuth = async (ctx) => {
207
+ const user = await getUser();
208
+ if (!user) {
209
+ LightviewRouter.navigate('/login');
210
+ return null; // Stop chain
211
+ }
212
+ return { ...ctx, user }; // Pass data to next handler
213
+ };
214
+
215
+ router.use(
216
+ '/admin/*',
217
+ checkAuth, // 1. Guard
218
+ '/views/admin.html' // 2. Render
219
+ );
220
+ ```
221
+
222
+ ### Route Patterns
223
+ * **Static**: `router.use('/about', 'about.html')`
224
+ * **Wildcard**: `router.use('/docs/*', handler)` -> matches `/docs/api/v1`
225
+ * **Parameters**: `router.use('/users/:id', handler)` -> `ctx.params.id`
226
+ * **Replacement**: `router.use('/blog/:slug', '/content/posts/:slug.html')` -> Maps URL params to file path automatically.
227
+
228
+ ---
229
+
230
+ <a name="ai-development-strategies"></a>
231
+ ## 7. AI Development Strategies
232
+
233
+ **Scenario A: "I need a full web application."**
234
+ * **Strategy**: Use **Tagged API** + **lightview-router.js**.
235
+ * **Output**: Generate `.js` files.
236
+
237
+ **Scenario B: "I need a dynamic dashboard widget of unknown nature at app development time."**
238
+ * **Strategy**: Use **cDOM/JPRX**.
239
+ * **Output**: Stream `.cdomc` chunks.
240
+
241
+ **Scenario C: "I need a config-driven UI."**
242
+ * **Strategy**: Use **oDOM**.
243
+ * **Output**: Generate `.json` config files.
244
+
245
+ ---
246
+
247
+ <a name="deep-links"></a>
248
+ ## 8. Deep Links & Resources
249
+
250
+ * **Documentation Home**: [/docs/index.html](file:///c:/Users/Owner/AntigravityProjects/lightview/docs/index.html)
251
+ * **Core Logic**: [/lightview.js](file:///c:/Users/Owner/AntigravityProjects/lightview/lightview.js)
252
+ * **Extension (Hypermedia)**: [/lightview-x.js](file:///c:/Users/Owner/AntigravityProjects/lightview/lightview-x.js)
253
+ * **Router**: [/lightview-router.js](file:///c:/Users/Owner/AntigravityProjects/lightview/lightview-router.js)
254
+ * **CDOM/JPRX Parser**: [/lightview-cdom.js](file:///c:/Users/Owner/AntigravityProjects/lightview/lightview-cdom.js)
255
+ * **Component Index**: [/components/index.js](file:///c:/Users/Owner/AntigravityProjects/lightview/components/index.js)
256
+ * **JPRX Helpers**: [/jprx/helpers/](file:///c:/Users/Owner/AntigravityProjects/lightview/jprx/helpers/)
257
+
258
+ ---
259
+ © 2026 AnyWhichWay LLC.
package/README.md CHANGED
@@ -4,6 +4,8 @@ A lightweight reactive UI library with signal-based reactivity and a clean API.
4
4
 
5
5
  Access the full documentation and interactive examples at [lightview.dev](https://lightview.dev).
6
6
 
7
+ LLMs should read [AI-GUIDANCE.md](AI-GUIDANCE.md) for instructions on how to use Lightview.
8
+
7
9
  ## Modular Architecture
8
10
 
9
11
  **Core Library**: ~7.75KB | **Extended (Hypermedia + Components)**: ~20KB | **Router**: ~3KB
@@ -25,6 +27,39 @@ Lightview supports multiple ways to build UIs, allowing you to pick the style th
25
27
 
26
28
  All syntaxes share the same underlying reactive engine based on **Signals** and **State**.
27
29
 
30
+ ## cDOM & JPRX: AI-Assisted Declarative UIs
31
+
32
+ Lightview includes **cDOM** (Computed DOM) powered by **JPRX** (JSON Pointer Reactive eXpressions)—a fully declarative UI layer that requires **zero custom JavaScript**. Much like **XPath** provides a powerful query language for XML, JPRX provides a reactive, formula-based language for JSON state.
33
+
34
+ ### Why This Matters for AI Collaboration
35
+
36
+ Traditional UI development requires AI agents to generate imperative JavaScript code, which introduces security risks (XSS, code injection) and unpredictable behavior. cDOM flips this model:
37
+
38
+ - **Pure Data, No Code**: UIs are defined as JSON structures with reactive expressions—no `eval()`, no `new Function()`, no executable strings.
39
+ - **Safe by Design**: AI agents can generate, modify, and compose UIs without producing potentially harmful code.
40
+ - **Auditable Output**: Every generated UI is a transparent data structure that can be validated, diffed, and sandboxed.
41
+
42
+ ### Example: A Reactive Counter (No JavaScript)
43
+
44
+ ```json
45
+ {
46
+ "state": { "count": 0 },
47
+ "div": {
48
+ "children": [
49
+ { "p": "{$count}" },
50
+ { "button": { "onclick": "{set('count', add(count, 1))}", "children": ["Increment"] } }
51
+ ]
52
+ }
53
+ }
54
+ ```
55
+
56
+ This JSON is **the entire application**. The `{...}` expressions are JPRX—a sandboxed, spreadsheet-like formula language (inspired by **XPath** and **JSON Pointers**) that resolves paths, calls registered helpers, and triggers reactivity automatically.
57
+
58
+ ### Learn More
59
+
60
+ - [cDOM Documentation](https://lightview.dev/docs/cdom)
61
+ - [JPRX Expression Reference](https://lightview.dev/docs/cdom#jprx)
62
+
28
63
  ## Quick Start
29
64
 
30
65
  ### 1. Tagged API (Concise & Expressive)
@@ -20,7 +20,7 @@ const Diff = (props = {}, ...children) => {
20
20
  const { div, shadowDOM } = tags;
21
21
 
22
22
  const {
23
- aspectRatio = 'aspect-16/9',
23
+ aspectRatio = 'aspect-video',
24
24
  useShadow,
25
25
  class: className = '',
26
26
  ...rest
@@ -67,7 +67,7 @@ Diff.Item1 = (props = {}, ...children) => {
67
67
 
68
68
  if (src) {
69
69
  return tags.div({ class: `diff-item-1 ${className}`.trim(), role: 'img', ...rest },
70
- tags.img({ src, alt })
70
+ tags.img({ src, alt, style: 'width: 100%; height: 100%; object-fit: cover; display: block;' })
71
71
  );
72
72
  }
73
73
 
@@ -85,7 +85,7 @@ Diff.Item2 = (props = {}, ...children) => {
85
85
 
86
86
  if (src) {
87
87
  return tags.div({ class: `diff-item-2 ${className}`.trim(), role: 'img', tabindex: '0', ...rest },
88
- tags.img({ src, alt })
88
+ tags.img({ src, alt, style: 'width: 100%; height: 100%; object-fit: cover; display: block;' })
89
89
  );
90
90
  }
91
91
 
@@ -99,7 +99,15 @@ Diff.Resizer = (props = {}) => {
99
99
  const { tags } = globalThis.Lightview || {};
100
100
  if (!tags) return null;
101
101
 
102
- return tags.div({ class: 'diff-resizer', ...props });
102
+ return tags.input({
103
+ type: 'range',
104
+ min: '0',
105
+ max: '100',
106
+ value: '50',
107
+ class: 'diff-resizer',
108
+ oninput: "this.parentElement.style.setProperty('--diff-offset', this.value + '%')",
109
+ ...props
110
+ });
103
111
  };
104
112
 
105
113
  const tags = globalThis.Lightview.tags;
@@ -108,4 +116,28 @@ tags['Diff.Item1'] = Diff.Item1;
108
116
  tags['Diff.Item2'] = Diff.Item2;
109
117
  tags['Diff.Resizer'] = Diff.Resizer;
110
118
 
119
+ // Register as Custom Elements using customElementWrapper
120
+ if (globalThis.LightviewX && typeof customElements !== 'undefined') {
121
+ const { customElementWrapper } = globalThis.LightviewX;
122
+
123
+ if (!customElements.get('lv-diff')) {
124
+ customElements.define('lv-diff', customElementWrapper(Diff, {
125
+ attributeMap: { aspectRatio: String }
126
+ }));
127
+ }
128
+ if (!customElements.get('lv-diff-item1')) {
129
+ customElements.define('lv-diff-item1', customElementWrapper(Diff.Item1, {
130
+ attributeMap: { src: String, alt: String }
131
+ }));
132
+ }
133
+ if (!customElements.get('lv-diff-item2')) {
134
+ customElements.define('lv-diff-item2', customElementWrapper(Diff.Item2, {
135
+ attributeMap: { src: String, alt: String }
136
+ }));
137
+ }
138
+ if (!customElements.get('lv-diff-resizer')) {
139
+ customElements.define('lv-diff-resizer', customElementWrapper(Diff.Resizer, {}));
140
+ }
141
+ }
142
+
111
143
  export default Diff;
@@ -70,7 +70,10 @@ Lightview.hooks.validateUrl = () => true;</code></pre>
70
70
 
71
71
  <h3 id="vdom-object-dom">vDOM and Object DOM</h3>
72
72
  <p>
73
- Files with <code>.vdom</code> or <code>.odom</code> extensions are parsed as JSON and converted to elements.
73
+ Files with <code>.<a id="vdom" href="/docs/api/elements#vdom">vdom</a></code>,
74
+ <code>.<a id="odom" href="/docs/api/elements#object-dom">odom</a></code> or
75
+ <code>.<a id="cdom" href="/docs/cdom">cdom</a></code> extensions are parsed as JSON and converted to
76
+ elements.
74
77
  Any <a href="#template-literals">Template Literals</a> within the JSON values are automatically resolved.
75
78
  </p>
76
79
  <pre><code>// /api/cards.vdom
@@ -80,9 +83,76 @@ Lightview.hooks.validateUrl = () => true;</code></pre>
80
83
  ]
81
84
 
82
85
  // Load vDOM
83
- div({ src: '/api/cards.vdom' })</code></pre>
86
+ div({ src: '/api/cards.vdom' })
84
87
 
85
- <h2>Cloning DOM Elements</h2>
88
+ // Load safe, reactive HTML
89
+ div({ src: '/api/ai-generated.cdom' })
90
+ </code></pre>
91
+
92
+ <h2 id="advanced-fetches">Advanced Fetches (data-method & data-body)</h2>
93
+ <p>
94
+ You can customize the HTTP request method and body for any <code>src</code> or <code>href</code> action
95
+ using <code>data-method</code> and <code>data-body</code>.
96
+ </p>
97
+
98
+ <h3>1. Request Methods</h3>
99
+ <p>Use <code>data-method</code> to specify an HTTP verb. Defaults to <code>GET</code>.</p>
100
+ <pre><code>// Send a DELETE request
101
+ button({
102
+ href: '/api/items/123',
103
+ 'data-method': 'DELETE',
104
+ target: '#status-log'
105
+ }, 'Delete Item')</code></pre>
106
+
107
+ <h3>2. Request Bodies</h3>
108
+ <p>Use <code>data-body</code> to send data. If no prefix is used, it is treated as a CSS selector.</p>
109
+
110
+ <h4>CSS Selectors (Default)</h4>
111
+ <p>Grabs data from the DOM based on the element type:</p>
112
+ <ul>
113
+ <li><strong>Forms:</strong> If the selector points to a <code>&lt;form&gt;</code>, the entire form is
114
+ serialized as <code>FormData</code>.
115
+ </li>
116
+ <li><strong>Checkboxes/Radios:</strong> Only sends the <code>value</code> if the element is
117
+ <code>checked</code>. Otherwise, no data is sent.
118
+ </li>
119
+ <li><strong>Input/Select/Textarea:</strong> Sends the current <code>value</code>.</li>
120
+ <li><strong>Other Elements:</strong> Sends the <code>innerText</code> (e.g., from a <code>&lt;div&gt;</code>
121
+ or <code>&lt;span&gt;</code>).
122
+ </li>
123
+ </ul>
124
+ <pre><code>&lt;!-- Send the value of an input (Query param search?body=...) --&gt;
125
+ &lt;button href="/api/search" data-body="#search-input" target="#results"&gt;Search&lt;/button&gt;
126
+ &lt;input id="search-input" type="text"&gt;
127
+
128
+ &lt;!-- Send an entire form as POST --&gt;
129
+ &lt;button href="/api/user/update" data-method="POST" data-body="#user-form"&gt;Save&lt;/button&gt;
130
+ &lt;form id="user-form"&gt;
131
+ &lt;input name="email" value="user@example.com"&gt;
132
+ &lt;/form&gt;</code></pre>
133
+
134
+ <h4>Prefixes</h4>
135
+ <p>You can use prefixes to control exactly how the body is constructed:</p>
136
+ <ul>
137
+ <li><code>javascript:</code> - Evaluates an expression (has access to <code>state</code> and
138
+ <code>signal</code>).
139
+ </li>
140
+ <li><code>json:</code> - Sends a literal JSON string (sets <code>Content-Type: application/json</code>).
141
+ </li>
142
+ <li><code>text:</code> - Sends raw text (sets <code>Content-Type: text/plain</code>).</li>
143
+ </ul>
144
+ <pre><code>&lt;!-- Dynamic calculation --&gt;
145
+ &lt;button href="/api/log" data-body="javascript:state.user.id"&gt;Log ID&lt;/button&gt;
146
+
147
+ &lt;!-- Literal JSON --&gt;
148
+ &lt;button href="/api/config" data-method="POST" data-body='json:{"theme": "dark"}'&gt;Set Dark Mode&lt;/button&gt;</code></pre>
149
+
150
+ <h4>GET Request Handling</h4>
151
+ <p>If the method is <code>GET</code>, the data provided via <code>data-body</code> is automatically converted
152
+ into <strong>URL Query Parameters</strong>. If multiple values are found (like in a form), all are
153
+ appended to the URL.</p>
154
+
155
+ <h2 id="cloning-dom-elements">Cloning DOM Elements</h2>
86
156
  <p>
87
157
  Use CSS selectors to clone existing elements:
88
158
  </p>
@@ -299,7 +369,7 @@ const app = div({ class: 'app' },
299
369
  })
300
370
  );</code></pre>
301
371
 
302
- <h3>Using Plain HTML (Lightview Syntax)</h3>
372
+ <h3>Using Lightview Syntax</h3>
303
373
  <pre><code>&lt;div class="app"&gt;
304
374
  &lt;nav class="sidebar"&gt;
305
375
  &lt;button href="/pages/dashboard.html" target="#content"&gt;📊 Dashboard&lt;/button&gt;
@@ -309,7 +379,7 @@ const app = div({ class: 'app' },
309
379
  &lt;main id="content" src="/pages/dashboard.html"&gt;&lt;/main&gt;
310
380
  &lt;/div&gt;</code></pre>
311
381
 
312
- <h3>Using HTMX</h3>
382
+ <h3>vs. Using HTMX</h3>
313
383
  <pre><code>&lt;div class="app"&gt;
314
384
  &lt;nav class="sidebar"&gt;
315
385
  &lt;button hx-get="/pages/dashboard.html" hx-target="#content"&gt;📊 Dashboard&lt;/button&gt;
@@ -96,12 +96,12 @@
96
96
  </td>
97
97
  </tr>
98
98
  <tr>
99
- <td><a href="./hypermedia.html#fetching-content"><code>src="..."</code></a></td>
99
+ <td><a href="/docs/hypermedia/#fetching-content"><code>src="..."</code></a></td>
100
100
  <td>Attribute to automatically fetch HTML or JSON representing HTML and inject it into the element.
101
101
  </td>
102
102
  </tr>
103
103
  <tr>
104
- <td><a href="./hypermedia.html#href-navigation"><code>href="..."</code></a></td>
104
+ <td><a href="/docs/hypermedia/#href-navigation"><code>href="..."</code></a></td>
105
105
  <td>Attribute for SPA navigation and src injection on any element. Supports targeting content
106
106
  before, at the start of, and the end of or after other elements via CSS selectors.</td>
107
107
  </tr>
@@ -165,7 +165,7 @@ const { state } = LightviewX; // Deep state (lightview-x)</code></pre>
165
165
  Add reactivity to existing HTML. Progressive enhancement made easy.
166
166
  </p>
167
167
  </a>
168
- <a href="./hypermedia.html" class="feature-card" style="text-decoration: none; color: inherit;">
168
+ <a href="/docs/hypermedia/" class="feature-card" style="text-decoration: none; color: inherit;">
169
169
  <h3 class="feature-title">Hypermedia</h3>
170
170
  <p class="feature-description">
171
171
  Fetch content with src. HTM-style patterns, built in.
package/docs/api/nav.html CHANGED
@@ -54,21 +54,5 @@
54
54
  Validators</a>
55
55
  </div>
56
56
  </div>
57
- <div class="docs-nav-item">
58
- <a href="./hypermedia.html" class="docs-nav-link">Hypermedia</a>
59
- <div class="docs-nav-subsection" style="margin-left: 1rem; border-left: 1px solid var(--site-border);">
60
- <a href="./hypermedia.html#fetching-content" class="docs-nav-link" style="font-size: 0.85em;">Fetching
61
- Content</a>
62
- <a href="./hypermedia.html#href-navigation" class="docs-nav-link" style="font-size: 0.85em;">HREF
63
- Navigation</a>
64
- <a href="./hypermedia.html#event-gating" class="docs-nav-link" style="font-size: 0.85em;">Event
65
- Gating</a>
66
- <a href="./hypermedia.html#template-literals" class="docs-nav-link" style="font-size: 0.85em;">Template
67
- Literals</a>
68
- <a href="./hypermedia.html#shadow-dom" class="docs-nav-link" style="font-size: 0.85em;">Shadow DOM</a>
69
- <a href="./hypermedia.html#htmx-style-apps" class="docs-nav-link" style="font-size: 0.85em;">HTMX-style
70
- Apps</a>
71
- </div>
72
- </div>
73
57
  </div>
74
58
  </nav>