@velumo/controls 0.1.0-beta.0
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/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +20 -0
- package/src/index.ts +112 -0
- package/tsconfig.json +10 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { JsonValue, Layer } from "@velumo/core";
|
|
2
|
+
import type { VelumoPlugin, LayerRenderer } from "@velumo/runtime";
|
|
3
|
+
export declare const CONTROL_BUTTON_LAYER_TYPE = "control.button";
|
|
4
|
+
export interface ControlAction {
|
|
5
|
+
readonly type: string;
|
|
6
|
+
readonly payload?: JsonValue;
|
|
7
|
+
}
|
|
8
|
+
export interface ControlButtonProps {
|
|
9
|
+
readonly label: string;
|
|
10
|
+
readonly action: ControlAction;
|
|
11
|
+
readonly variant?: "primary" | "ghost";
|
|
12
|
+
}
|
|
13
|
+
export declare function controlButton(props: ControlButtonProps, options?: {
|
|
14
|
+
id?: string;
|
|
15
|
+
}): Layer;
|
|
16
|
+
export interface ControlElement {
|
|
17
|
+
readonly ownerDocument: ControlDocument;
|
|
18
|
+
textContent: string;
|
|
19
|
+
setAttribute(name: string, value: string): void;
|
|
20
|
+
getAttribute?(name: string): string | null;
|
|
21
|
+
append(...children: Array<ControlElement | string>): void;
|
|
22
|
+
addEventListener?(type: "click", handler: () => void): void;
|
|
23
|
+
}
|
|
24
|
+
export interface ControlDocument {
|
|
25
|
+
createElement(tagName: string): ControlElement;
|
|
26
|
+
}
|
|
27
|
+
export interface ControlLayerContext {
|
|
28
|
+
readonly layer: Layer;
|
|
29
|
+
createElement(tagName: string): ControlElement;
|
|
30
|
+
dispatch?(action: ControlAction): void;
|
|
31
|
+
}
|
|
32
|
+
export type ControlLayerRenderer = LayerRenderer<ControlLayerContext, ControlElement>;
|
|
33
|
+
export declare function createControlsPlugin(): VelumoPlugin<ControlLayerContext, ControlElement, unknown>;
|
|
34
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEnE,eAAO,MAAM,yBAAyB,mBAAmB,CAAC;AAQ1D,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC;CAC9B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;CACxC;AAID,wBAAgB,aAAa,CAC3B,KAAK,EAAE,kBAAkB,EACzB,OAAO,GAAE;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5B,KAAK,CAeP;AAMD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,aAAa,EAAE,eAAe,CAAC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAChD,YAAY,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC3C,MAAM,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,cAAc,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC;IAC1D,gBAAgB,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;CAC7D;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAAC;CAChD;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAAC;IAG/C,QAAQ,CAAC,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;CACxC;AAED,MAAM,MAAM,oBAAoB,GAAG,aAAa,CAC9C,mBAAmB,EACnB,cAAc,CACf,CAAC;AAEF,wBAAgB,oBAAoB,IAAI,YAAY,CAClD,mBAAmB,EACnB,cAAc,EACd,OAAO,CACR,CAiCA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export const CONTROL_BUTTON_LAYER_TYPE = "control.button";
|
|
2
|
+
const DATA_CONTROL = "data-velumo-control";
|
|
3
|
+
const DATA_CONTROL_VARIANT = "data-velumo-control-variant";
|
|
4
|
+
const PLUGIN_ID = "velumo/controls";
|
|
5
|
+
// Authoring builder — returns a plain JSON-safe Layer (the shape the manifest
|
|
6
|
+
// expects). Omits absent optional fields so the round-trip is exact.
|
|
7
|
+
export function controlButton(props, options = {}) {
|
|
8
|
+
return {
|
|
9
|
+
type: CONTROL_BUTTON_LAYER_TYPE,
|
|
10
|
+
props: {
|
|
11
|
+
label: props.label,
|
|
12
|
+
action: {
|
|
13
|
+
type: props.action.type,
|
|
14
|
+
...(props.action.payload === undefined
|
|
15
|
+
? {}
|
|
16
|
+
: { payload: props.action.payload }),
|
|
17
|
+
},
|
|
18
|
+
...(props.variant === undefined ? {} : { variant: props.variant }),
|
|
19
|
+
},
|
|
20
|
+
...(options.id === undefined ? {} : { id: options.id }),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export function createControlsPlugin() {
|
|
24
|
+
return {
|
|
25
|
+
id: PLUGIN_ID,
|
|
26
|
+
setup({ registry }) {
|
|
27
|
+
const renderer = (context) => {
|
|
28
|
+
const props = (context.layer.props ??
|
|
29
|
+
{});
|
|
30
|
+
const button = context.createElement("button");
|
|
31
|
+
button.setAttribute("type", "button");
|
|
32
|
+
button.setAttribute(DATA_CONTROL, "button");
|
|
33
|
+
if (props.variant !== undefined) {
|
|
34
|
+
button.setAttribute(DATA_CONTROL_VARIANT, props.variant);
|
|
35
|
+
}
|
|
36
|
+
button.textContent = props.label ?? "";
|
|
37
|
+
const action = props.action;
|
|
38
|
+
button.addEventListener?.("click", () => {
|
|
39
|
+
if (action !== undefined) {
|
|
40
|
+
// Conditional-spread the payload so an absent payload stays absent
|
|
41
|
+
// across the dispatch seam (no explicit `payload: undefined` key),
|
|
42
|
+
// matching the builder's JSON-safe shape (gate-3).
|
|
43
|
+
context.dispatch?.({
|
|
44
|
+
type: action.type,
|
|
45
|
+
...(action.payload === undefined
|
|
46
|
+
? {}
|
|
47
|
+
: { payload: action.payload }),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
return button;
|
|
52
|
+
};
|
|
53
|
+
registry.registerLayerRenderer(CONTROL_BUTTON_LAYER_TYPE, renderer);
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,yBAAyB,GAAG,gBAAgB,CAAC;AAC1D,MAAM,YAAY,GAAG,qBAAqB,CAAC;AAC3C,MAAM,oBAAoB,GAAG,6BAA6B,CAAC;AAC3D,MAAM,SAAS,GAAG,iBAAiB,CAAC;AAgBpC,8EAA8E;AAC9E,qEAAqE;AACrE,MAAM,UAAU,aAAa,CAC3B,KAAyB,EACzB,UAA2B,EAAE;IAE7B,OAAO;QACL,IAAI,EAAE,yBAAyB;QAC/B,KAAK,EAAE;YACL,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,MAAM,EAAE;gBACN,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,IAAI;gBACvB,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS;oBACpC,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;aACvC;YACD,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;SACnE;QACD,GAAG,CAAC,OAAO,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC;KAC/C,CAAC;AACb,CAAC;AAgCD,MAAM,UAAU,oBAAoB;IAKlC,OAAO;QACL,EAAE,EAAE,SAAS;QACb,KAAK,CAAC,EAAE,QAAQ,EAAE;YAChB,MAAM,QAAQ,GAAyB,CAAC,OAAO,EAAE,EAAE;gBACjD,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK;oBAChC,EAAE,CAAgC,CAAC;gBACrC,MAAM,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;gBAC/C,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;gBACtC,MAAM,CAAC,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;gBAC5C,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;oBAChC,MAAM,CAAC,YAAY,CAAC,oBAAoB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;gBAC3D,CAAC;gBACD,MAAM,CAAC,WAAW,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;gBACvC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;gBAC5B,MAAM,CAAC,gBAAgB,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;oBACtC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;wBACzB,mEAAmE;wBACnE,mEAAmE;wBACnE,mDAAmD;wBACnD,OAAO,CAAC,QAAQ,EAAE,CAAC;4BACjB,IAAI,EAAE,MAAM,CAAC,IAAI;4BACjB,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS;gCAC9B,CAAC,CAAC,EAAE;gCACJ,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;yBACjC,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC,CAAC,CAAC;gBACH,OAAO,MAAM,CAAC;YAChB,CAAC,CAAC;YACF,QAAQ,CAAC,qBAAqB,CAAC,yBAAyB,EAAE,QAAQ,CAAC,CAAC;QACtE,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"fileNames":["../../../node_modules/typescript/lib/lib.es5.d.ts","../../../node_modules/typescript/lib/lib.es2015.d.ts","../../../node_modules/typescript/lib/lib.es2016.d.ts","../../../node_modules/typescript/lib/lib.es2017.d.ts","../../../node_modules/typescript/lib/lib.es2018.d.ts","../../../node_modules/typescript/lib/lib.es2019.d.ts","../../../node_modules/typescript/lib/lib.es2020.d.ts","../../../node_modules/typescript/lib/lib.es2021.d.ts","../../../node_modules/typescript/lib/lib.es2022.d.ts","../../../node_modules/typescript/lib/lib.dom.d.ts","../../../node_modules/typescript/lib/lib.dom.iterable.d.ts","../../../node_modules/typescript/lib/lib.dom.asynciterable.d.ts","../../../node_modules/typescript/lib/lib.webworker.importscripts.d.ts","../../../node_modules/typescript/lib/lib.scripthost.d.ts","../../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../../node_modules/typescript/lib/lib.es2016.intl.d.ts","../../../node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../../node_modules/typescript/lib/lib.es2017.date.d.ts","../../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../../node_modules/typescript/lib/lib.es2021.promise.d.ts","../../../node_modules/typescript/lib/lib.es2021.string.d.ts","../../../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../../node_modules/typescript/lib/lib.es2021.intl.d.ts","../../../node_modules/typescript/lib/lib.es2022.array.d.ts","../../../node_modules/typescript/lib/lib.es2022.error.d.ts","../../../node_modules/typescript/lib/lib.es2022.intl.d.ts","../../../node_modules/typescript/lib/lib.es2022.object.d.ts","../../../node_modules/typescript/lib/lib.es2022.string.d.ts","../../../node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../../node_modules/typescript/lib/lib.decorators.d.ts","../../../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../../node_modules/typescript/lib/lib.es2022.full.d.ts","../../core/dist/types.d.ts","../../core/dist/builders.d.ts","../../core/dist/manifest-schema.d.ts","../../core/dist/layout-validation.d.ts","../../core/dist/capabilities.d.ts","../../core/dist/validation.d.ts","../../core/dist/index.d.ts","../../runtime/dist/controller.d.ts","../../runtime/dist/hash.d.ts","../../runtime/dist/notes.d.ts","../../runtime/dist/registry.d.ts","../../runtime/dist/timeline.d.ts","../../runtime/dist/action-dispatcher.d.ts","../../runtime/dist/cue-dispatcher.d.ts","../../runtime/dist/camera.d.ts","../../runtime/dist/spatial.d.ts","../../runtime/dist/scene-player.d.ts","../../runtime/dist/theme-bundle.d.ts","../../runtime/dist/index.d.ts","../src/index.ts"],"fileIdsList":[[70,82],[64],[64,65,66,67,68,69],[70,71,74],[75],[70],[70,74,75,76],[71],[71,72,73,74,75,76,77,78,79,80,81],[70,71],[70,79],[70,75],[70,74]],"fileInfos":[{"version":"bcd24271a113971ba9eb71ff8cb01bc6b0f872a85c23fdbe5d93065b375933cd","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f88bedbeb09c6f5a6645cb24c7c55f1aa22d19ae96c8e6959cbd8b85a707bc6","impliedFormat":1},{"version":"7fe93b39b810eadd916be8db880dd7f0f7012a5cc6ffb62de8f62a2117fa6f1f","impliedFormat":1},{"version":"bb0074cc08b84a2374af33d8bf044b80851ccc9e719a5e202eacf40db2c31600","impliedFormat":1},{"version":"1a7daebe4f45fb03d9ec53d60008fbf9ac45a697fdc89e4ce218bc94b94f94d6","impliedFormat":1},{"version":"f94b133a3cb14a288803be545ac2683e0d0ff6661bcd37e31aaaec54fc382aed","impliedFormat":1},{"version":"f59d0650799f8782fd74cf73c19223730c6d1b9198671b1c5b3a38e1188b5953","impliedFormat":1},{"version":"8a15b4607d9a499e2dbeed9ec0d3c0d7372c850b2d5f1fb259e8f6d41d468a84","impliedFormat":1},{"version":"26e0fe14baee4e127f4365d1ae0b276f400562e45e19e35fd2d4c296684715e6","impliedFormat":1},{"version":"d6b1eba8496bdd0eed6fc8a685768fe01b2da4a0388b5fe7df558290bffcf32f","affectsGlobalScope":true,"impliedFormat":1},{"version":"7f57fc4404ff020bc45b9c620aff2b40f700b95fe31164024c453a5e3c163c54","impliedFormat":1},{"version":"7f57fc4404ff020bc45b9c620aff2b40f700b95fe31164024c453a5e3c163c54","impliedFormat":1},{"version":"2a2de5b9459b3fc44decd9ce6100b72f1b002ef523126c1d3d8b2a4a63d74d78","affectsGlobalScope":true,"impliedFormat":1},{"version":"f13f4b465c99041e912db5c44129a94588e1aafee35a50eab51044833f50b4ee","affectsGlobalScope":true,"impliedFormat":1},{"version":"eadcffda2aa84802c73938e589b9e58248d74c59cb7fcbca6474e3435ac15504","affectsGlobalScope":true,"impliedFormat":1},{"version":"105ba8ff7ba746404fe1a2e189d1d3d2e0eb29a08c18dded791af02f29fb4711","affectsGlobalScope":true,"impliedFormat":1},{"version":"00343ca5b2e3d48fa5df1db6e32ea2a59afab09590274a6cccb1dbae82e60c7c","affectsGlobalScope":true,"impliedFormat":1},{"version":"ebd9f816d4002697cb2864bea1f0b70a103124e18a8cd9645eeccc09bdf80ab4","affectsGlobalScope":true,"impliedFormat":1},{"version":"2c1afac30a01772cd2a9a298a7ce7706b5892e447bb46bdbeef720f7b5da77ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"7b0225f483e4fa685625ebe43dd584bb7973bbd84e66a6ba7bbe175ee1048b4f","affectsGlobalScope":true,"impliedFormat":1},{"version":"c0a4b8ac6ce74679c1da2b3795296f5896e31c38e888469a8e0f99dc3305de60","affectsGlobalScope":true,"impliedFormat":1},{"version":"3084a7b5f569088e0146533a00830e206565de65cae2239509168b11434cd84f","affectsGlobalScope":true,"impliedFormat":1},{"version":"c5079c53f0f141a0698faa903e76cb41cd664e3efb01cc17a5c46ec2eb0bef42","affectsGlobalScope":true,"impliedFormat":1},{"version":"32cafbc484dea6b0ab62cf8473182bbcb23020d70845b406f80b7526f38ae862","affectsGlobalScope":true,"impliedFormat":1},{"version":"fca4cdcb6d6c5ef18a869003d02c9f0fd95df8cfaf6eb431cd3376bc034cad36","affectsGlobalScope":true,"impliedFormat":1},{"version":"b93ec88115de9a9dc1b602291b85baf825c85666bf25985cc5f698073892b467","affectsGlobalScope":true,"impliedFormat":1},{"version":"f5c06dcc3fe849fcb297c247865a161f995cc29de7aa823afdd75aaaddc1419b","affectsGlobalScope":true,"impliedFormat":1},{"version":"b77e16112127a4b169ef0b8c3a4d730edf459c5f25fe52d5e436a6919206c4d7","affectsGlobalScope":true,"impliedFormat":1},{"version":"fbffd9337146eff822c7c00acbb78b01ea7ea23987f6c961eba689349e744f8c","affectsGlobalScope":true,"impliedFormat":1},{"version":"a995c0e49b721312f74fdfb89e4ba29bd9824c770bbb4021d74d2bf560e4c6bd","affectsGlobalScope":true,"impliedFormat":1},{"version":"c7b3542146734342e440a84b213384bfa188835537ddbda50d30766f0593aff9","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce6180fa19b1cccd07ee7f7dbb9a367ac19c0ed160573e4686425060b6df7f57","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f02e2476bccb9dbe21280d6090f0df17d2f66b74711489415a8aa4df73c9675","affectsGlobalScope":true,"impliedFormat":1},{"version":"45e3ab34c1c013c8ab2dc1ba4c80c780744b13b5676800ae2e3be27ae862c40c","affectsGlobalScope":true,"impliedFormat":1},{"version":"805c86f6cca8d7702a62a844856dbaa2a3fd2abef0536e65d48732441dde5b5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"e42e397f1a5a77994f0185fd1466520691456c772d06bf843e5084ceb879a0ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"f4c2b41f90c95b1c532ecc874bd3c111865793b23aebcc1c3cbbabcd5d76ffb0","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab26191cfad5b66afa11b8bf935ef1cd88fabfcb28d30b2dfa6fad877d050332","affectsGlobalScope":true,"impliedFormat":1},{"version":"2088bc26531e38fb05eedac2951480db5309f6be3fa4a08d2221abb0f5b4200d","affectsGlobalScope":true,"impliedFormat":1},{"version":"cb9d366c425fea79716a8fb3af0d78e6b22ebbab3bd64d25063b42dc9f531c1e","affectsGlobalScope":true,"impliedFormat":1},{"version":"500934a8089c26d57ebdb688fc9757389bb6207a3c8f0674d68efa900d2abb34","affectsGlobalScope":true,"impliedFormat":1},{"version":"689da16f46e647cef0d64b0def88910e818a5877ca5379ede156ca3afb780ac3","affectsGlobalScope":true,"impliedFormat":1},{"version":"bc21cc8b6fee4f4c2440d08035b7ea3c06b3511314c8bab6bef7a92de58a2593","affectsGlobalScope":true,"impliedFormat":1},{"version":"7ca53d13d2957003abb47922a71866ba7cb2068f8d154877c596d63c359fed25","affectsGlobalScope":true,"impliedFormat":1},{"version":"54725f8c4df3d900cb4dac84b64689ce29548da0b4e9b7c2de61d41c79293611","affectsGlobalScope":true,"impliedFormat":1},{"version":"e5594bc3076ac29e6c1ebda77939bc4c8833de72f654b6e376862c0473199323","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f3eb332c2d73e729f3364fcc0c2b375e72a121e8157d25a82d67a138c83a95c","affectsGlobalScope":true,"impliedFormat":1},{"version":"6f4427f9642ce8d500970e4e69d1397f64072ab73b97e476b4002a646ac743b1","affectsGlobalScope":true,"impliedFormat":1},{"version":"48915f327cd1dea4d7bd358d9dc7732f58f9e1626a29cc0c05c8c692419d9bb7","affectsGlobalScope":true,"impliedFormat":1},{"version":"b7bf9377723203b5a6a4b920164df22d56a43f593269ba6ae1fdc97774b68855","affectsGlobalScope":true,"impliedFormat":1},{"version":"db9709688f82c9e5f65a119c64d835f906efe5f559d08b11642d56eb85b79357","affectsGlobalScope":true,"impliedFormat":1},{"version":"4b25b8c874acd1a4cf8444c3617e037d444d19080ac9f634b405583fd10ce1f7","affectsGlobalScope":true,"impliedFormat":1},{"version":"37be57d7c90cf1f8112ee2636a068d8fd181289f82b744160ec56a7dc158a9f5","affectsGlobalScope":true,"impliedFormat":1},{"version":"a917a49ac94cd26b754ab84e113369a75d1a47a710661d7cd25e961cc797065f","affectsGlobalScope":true,"impliedFormat":1},{"version":"6d3261badeb7843d157ef3e6f5d1427d0eeb0af0cf9df84a62cfd29fd47ac86e","affectsGlobalScope":true,"impliedFormat":1},{"version":"195daca651dde22f2167ac0d0a05e215308119a3100f5e6268e8317d05a92526","affectsGlobalScope":true,"impliedFormat":1},{"version":"8b11e4285cd2bb164a4dc09248bdec69e9842517db4ca47c1ba913011e44ff2f","affectsGlobalScope":true,"impliedFormat":1},{"version":"0508571a52475e245b02bc50fa1394065a0a3d05277fbf5120c3784b85651799","affectsGlobalScope":true,"impliedFormat":1},{"version":"8f9af488f510c3015af3cc8c267a9e9d96c4dd38a1fdff0e11dc5a544711415b","affectsGlobalScope":true,"impliedFormat":1},{"version":"fc611fea8d30ea72c6bbfb599c9b4d393ce22e2f5bfef2172534781e7d138104","affectsGlobalScope":true,"impliedFormat":1},{"version":"1ce14b81c5cc821994aa8ec1d42b220dd41b27fcc06373bce3958af7421b77d4","affectsGlobalScope":true,"impliedFormat":1},{"version":"b3a048b3e9302ef9a34ef4ebb9aecfb28b66abb3bce577206a79fee559c230da","affectsGlobalScope":true,"impliedFormat":1},{"version":"01a30f9e8582b369075c0808df71121e6855cb06fd8d3d39511d9ebb66405205","impliedFormat":1},{"version":"8877805003603477c63696f8af86eb14be659de3027a597617e7a95ca9250a92","impliedFormat":99},{"version":"a2c4bcfeeaf83801774f8c21daf4c18b15fd9da4469e222a6708a58d235bb286","impliedFormat":99},{"version":"163a1497b249fb8ac3eac7710af6df75222a21b20434ec35d4489c85f18a397b","impliedFormat":99},{"version":"b1d091ebe44dc4eb7ba1535c76bcbf15df97a0cde19fda1bbd34e1503df10e95","impliedFormat":99},{"version":"baeb0570658dce9269d3a5dabb44a1e6e11d8712f45750ca80885fd0e2dab38e","impliedFormat":99},{"version":"def8ed8b7980dbad419047252c19812799dbf761e797d624a9a030fb318a27ee","impliedFormat":99},{"version":"09451d1bdb65b1b10cafbccc4c762f9181609881ba078e4aabfbb7c6d4effe17","impliedFormat":99},{"version":"4c26794e2a073e20bf40b3482be4f25fa4d6b83c8d4cdb7e3744d8401eef6c38","impliedFormat":99},{"version":"92692f5dcdd41d6cebb9785ebe83f6631e448d468c7e77f56c2fe6f8f32869ba","impliedFormat":99},{"version":"1093522585079cf706e859f4323d23832ef5b62b04805190bcba06614fc8bdcb","impliedFormat":99},{"version":"165426a72c724ac8b6c5068f64aeeedc976a31cddaf7bdb30689ca0e0e885885","impliedFormat":99},{"version":"9c6738ae625093663883e4694a79bd8d9c8ff79f0d0bb60b8d6e4ab39393b77d","impliedFormat":99},{"version":"f864cf8286ef0798ae6eb2808965e2038c10ffb940b196a3a6e6364fe534115f","impliedFormat":99},{"version":"d6628b767083fceffd23177e8c53e1348d372e5755c2880f8f2e958d7a6dbafc","impliedFormat":99},{"version":"efbeb4d5e4df969ce57b6fe98d6cabe2097cae2e0695b6ef85c77f7a8045e9a3","impliedFormat":99},{"version":"4bbc05996c36885d4da5e1d3b140fd16ee7121a4184843447a3bb47b240e3386","impliedFormat":99},{"version":"0eaeeda7b43eb04e6503115b59ea0fc0dcede7d39dc6651a1ae8ba94e5974b46","impliedFormat":99},{"version":"8cad53853f3c0a8f7391721d625259ba815e33c26139f59e08751fa38c326f6d","impliedFormat":99},{"version":"7af78eb71c547cc0353d89ca54074af736128b01e231ab5662e1300adc0e17fd","impliedFormat":99},{"version":"7c15a437198c4f5171582a9a4e0409eca74aab4dab40bbd8b96f040c0635764a","signature":"5083c064f7f8f9e23e7349885a326911ff8eeb756a901a69cb3f3419168109cf","impliedFormat":99}],"root":[83],"options":{"composite":true,"declaration":true,"declarationMap":true,"module":199,"outDir":"./","rootDir":"../src","skipLibCheck":true,"sourceMap":true,"strict":true,"target":9,"tsBuildInfoFile":"./tsconfig.tsbuildinfo"},"referencedMap":[[83,1],[65,2],[68,2],[70,3],[67,2],[69,2],[76,4],[78,5],[71,6],[77,7],[72,8],[82,9],[73,10],[74,6],[80,11],[79,12],[81,13],[75,6]],"latestChangedDtsFile":"./index.d.ts","version":"6.0.3"}
|
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@velumo/controls",
|
|
3
|
+
"version": "0.1.0-beta.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"default": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"@velumo/core": "0.0.0",
|
|
15
|
+
"@velumo/runtime": "0.0.0"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc -b"
|
|
19
|
+
}
|
|
20
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { JsonValue, Layer } from "@velumo/core";
|
|
2
|
+
import type { VelumoPlugin, LayerRenderer } from "@velumo/runtime";
|
|
3
|
+
|
|
4
|
+
export const CONTROL_BUTTON_LAYER_TYPE = "control.button";
|
|
5
|
+
const DATA_CONTROL = "data-velumo-control";
|
|
6
|
+
const DATA_CONTROL_VARIANT = "data-velumo-control-variant";
|
|
7
|
+
const PLUGIN_ID = "velumo/controls";
|
|
8
|
+
|
|
9
|
+
// An action reference — pure data, dispatched by a registered handler. Payload
|
|
10
|
+
// is JsonValue (parity with core's CueAction), never a function or on* key, so
|
|
11
|
+
// the manifest stays JSON-safe.
|
|
12
|
+
export interface ControlAction {
|
|
13
|
+
readonly type: string;
|
|
14
|
+
readonly payload?: JsonValue;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface ControlButtonProps {
|
|
18
|
+
readonly label: string;
|
|
19
|
+
readonly action: ControlAction;
|
|
20
|
+
readonly variant?: "primary" | "ghost";
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Authoring builder — returns a plain JSON-safe Layer (the shape the manifest
|
|
24
|
+
// expects). Omits absent optional fields so the round-trip is exact.
|
|
25
|
+
export function controlButton(
|
|
26
|
+
props: ControlButtonProps,
|
|
27
|
+
options: { id?: string } = {},
|
|
28
|
+
): Layer {
|
|
29
|
+
return {
|
|
30
|
+
type: CONTROL_BUTTON_LAYER_TYPE,
|
|
31
|
+
props: {
|
|
32
|
+
label: props.label,
|
|
33
|
+
action: {
|
|
34
|
+
type: props.action.type,
|
|
35
|
+
...(props.action.payload === undefined
|
|
36
|
+
? {}
|
|
37
|
+
: { payload: props.action.payload }),
|
|
38
|
+
},
|
|
39
|
+
...(props.variant === undefined ? {} : { variant: props.variant }),
|
|
40
|
+
},
|
|
41
|
+
...(options.id === undefined ? {} : { id: options.id }),
|
|
42
|
+
} as Layer;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// DOM-like element/document surface, mirroring @velumo/effects so the
|
|
46
|
+
// renderer can append the result directly. Unlike EffectElement it declares an
|
|
47
|
+
// optional addEventListener — a real browser <button> supplies it; a minimal
|
|
48
|
+
// host may omit it (the click simply never wires, which is inert).
|
|
49
|
+
export interface ControlElement {
|
|
50
|
+
readonly ownerDocument: ControlDocument;
|
|
51
|
+
textContent: string;
|
|
52
|
+
setAttribute(name: string, value: string): void;
|
|
53
|
+
getAttribute?(name: string): string | null;
|
|
54
|
+
append(...children: Array<ControlElement | string>): void;
|
|
55
|
+
addEventListener?(type: "click", handler: () => void): void;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface ControlDocument {
|
|
59
|
+
createElement(tagName: string): ControlElement;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface ControlLayerContext {
|
|
63
|
+
readonly layer: Layer;
|
|
64
|
+
createElement(tagName: string): ControlElement;
|
|
65
|
+
// Optional so the control renders inert on a minimal host; the DOM renderer
|
|
66
|
+
// always binds it.
|
|
67
|
+
dispatch?(action: ControlAction): void;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export type ControlLayerRenderer = LayerRenderer<
|
|
71
|
+
ControlLayerContext,
|
|
72
|
+
ControlElement
|
|
73
|
+
>;
|
|
74
|
+
|
|
75
|
+
export function createControlsPlugin(): VelumoPlugin<
|
|
76
|
+
ControlLayerContext,
|
|
77
|
+
ControlElement,
|
|
78
|
+
unknown
|
|
79
|
+
> {
|
|
80
|
+
return {
|
|
81
|
+
id: PLUGIN_ID,
|
|
82
|
+
setup({ registry }) {
|
|
83
|
+
const renderer: ControlLayerRenderer = (context) => {
|
|
84
|
+
const props = (context.layer.props ??
|
|
85
|
+
{}) as Partial<ControlButtonProps>;
|
|
86
|
+
const button = context.createElement("button");
|
|
87
|
+
button.setAttribute("type", "button");
|
|
88
|
+
button.setAttribute(DATA_CONTROL, "button");
|
|
89
|
+
if (props.variant !== undefined) {
|
|
90
|
+
button.setAttribute(DATA_CONTROL_VARIANT, props.variant);
|
|
91
|
+
}
|
|
92
|
+
button.textContent = props.label ?? "";
|
|
93
|
+
const action = props.action;
|
|
94
|
+
button.addEventListener?.("click", () => {
|
|
95
|
+
if (action !== undefined) {
|
|
96
|
+
// Conditional-spread the payload so an absent payload stays absent
|
|
97
|
+
// across the dispatch seam (no explicit `payload: undefined` key),
|
|
98
|
+
// matching the builder's JSON-safe shape (gate-3).
|
|
99
|
+
context.dispatch?.({
|
|
100
|
+
type: action.type,
|
|
101
|
+
...(action.payload === undefined
|
|
102
|
+
? {}
|
|
103
|
+
: { payload: action.payload }),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return button;
|
|
108
|
+
};
|
|
109
|
+
registry.registerLayerRenderer(CONTROL_BUTTON_LAYER_TYPE, renderer);
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
package/tsconfig.json
ADDED