added optional web component UI control
All checks were successful
CI / React UI Build (push) Successful in 12s
CI / Native Windows Build And Tests (push) Successful in 2m20s
CI / Windows Release Package (push) Successful in 2m56s

This commit is contained in:
Aiden
2026-05-30 22:57:59 +10:00
parent a6d2ee385e
commit 27690c3afa
26 changed files with 804 additions and 76 deletions

View File

@@ -102,6 +102,7 @@ Optional fields:
- `fonts`: packaged font assets for live text parameters.
- `temporal`: history-buffer requirements.
- `feedback`: optional previous-frame shader-local feedback surface.
- `ui`: optional custom control UI module for this shader.
Parameter objects may also include an optional `description` string. The control UI displays it as one-line helper text with the full text available on hover, so use it for short operational guidance rather than long documentation.
@@ -121,6 +122,78 @@ Shader-visible identifiers must be valid Slang-style identifiers:
Use letters, numbers, and underscores only, and start with a letter or underscore. For example, `logoTexture` is valid; `logo-texture` is not valid as a shader-visible texture ID.
## Custom Control UI
Shaders may optionally declare a custom browser control panel implemented as a standard Web Component. This only changes the bundled React control surface; it does not change shader validation, parameter storage, render cadence, or video I/O behavior.
Manifest example:
```json
{
"ui": {
"type": "webComponent",
"entry": "ui/controls.js",
"tag": "my-shader-controls"
}
}
```
The `entry` file is loaded as a JavaScript module from:
```text
/shader-assets/{shaderId}/ui/controls.js
```
Rules:
- `type` must be `webComponent`.
- `entry` must be a safe relative `.js` or `.mjs` path inside the shader package. Use the package `ui/` directory for UI assets.
- `tag` must be a valid custom element name with a hyphen, for example `my-shader-controls`.
- The `entry` file must exist when the manifest is loaded.
- Custom UI controls must update declared manifest parameters. They cannot create hidden runtime parameters or bypass host validation.
- The React UI still provides a **Default controls** fallback for each layer.
Custom element API:
```js
class MyShaderControls extends HTMLElement {
set layer(value) {}
set parameters(value) {}
set values(value) {}
connectedCallback() {}
}
customElements.define("my-shader-controls", MyShaderControls);
```
The host sets these properties whenever layer state changes:
- `layer`: full layer object from `/api/state`.
- `parameters`: array of manifest parameter definitions with current `value`.
- `values`: object keyed by parameter id.
- `setParameter(id, value)`: updates a declared layer parameter through the same route used by the default controls.
- `requestReset()`: resets the layer parameters through the normal reset route.
A custom element may either call the functions directly:
```js
this.setParameter("strength", 0.75);
this.requestReset();
```
or dispatch events:
```js
this.dispatchEvent(new CustomEvent("shader-parameter-change", {
detail: { parameterId: "strength", value: 0.75 }
}));
this.dispatchEvent(new CustomEvent("shader-reset-parameters"));
```
When the host updates the element's properties, it also dispatches `shader-layer-update` with `{ layer, parameters, values }` in `event.detail`.
## Render Passes
Most shaders should omit `passes`. The runtime then creates one implicit pass:
@@ -852,5 +925,6 @@ Before committing a new shader package:
- Font files referenced by `fonts` exist.
- Enum defaults are present in their `options`.
- Text `fontParameter` selectors reference valid font assets through their enum options.
- Custom UI entries, when present, load from a safe package-relative JavaScript module and register the declared web component tag.
- Temporal shaders handle short or empty history gracefully.
- The app can reload and compile the shader without errors.