@caperjs/solid 0.7.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/README.md +191 -0
- package/jsx.d.ts +39 -0
- package/lib/AnimatedShow.d.ts +25 -0
- package/lib/AnimatedShow.d.ts.map +1 -0
- package/lib/AnimatedShow.test.d.ts +2 -0
- package/lib/AnimatedShow.test.d.ts.map +1 -0
- package/lib/Composable.d.ts +39 -0
- package/lib/Composable.d.ts.map +1 -0
- package/lib/Composable.test.d.ts +2 -0
- package/lib/Composable.test.d.ts.map +1 -0
- package/lib/animated.d.ts +16 -0
- package/lib/animated.d.ts.map +1 -0
- package/lib/animated.test.d.ts +2 -0
- package/lib/animated.test.d.ts.map +1 -0
- package/lib/asComponent.d.ts +19 -0
- package/lib/asComponent.d.ts.map +1 -0
- package/lib/asComponent.test.d.ts +2 -0
- package/lib/asComponent.test.d.ts.map +1 -0
- package/lib/caper-plugin-solid.mjs +337 -0
- package/lib/caper-plugin-solid.mjs.map +1 -0
- package/lib/catalog.d.ts +17 -0
- package/lib/catalog.d.ts.map +1 -0
- package/lib/index.d.ts +9 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/renderer.d.ts +4 -0
- package/lib/renderer.d.ts.map +1 -0
- package/lib/renderer.test.d.ts +2 -0
- package/lib/renderer.test.d.ts.map +1 -0
- package/lib/useTick.d.ts +4 -0
- package/lib/useTick.d.ts.map +1 -0
- package/lib/useTick.test.d.ts +2 -0
- package/lib/useTick.test.d.ts.map +1 -0
- package/lib/version.d.ts +2 -0
- package/lib/version.d.ts.map +1 -0
- package/package.json +66 -0
- package/src/AnimatedShow.test.tsx +146 -0
- package/src/AnimatedShow.tsx +87 -0
- package/src/Composable.test.ts +214 -0
- package/src/Composable.ts +84 -0
- package/src/animated.test.ts +94 -0
- package/src/animated.ts +39 -0
- package/src/asComponent.test.ts +168 -0
- package/src/asComponent.ts +37 -0
- package/src/catalog.ts +28 -0
- package/src/index.ts +11 -0
- package/src/renderer.test.ts +272 -0
- package/src/renderer.ts +155 -0
- package/src/useTick.test.ts +28 -0
- package/src/useTick.ts +10 -0
- package/src/version.ts +1 -0
- package/vite.d.mts +10 -0
- package/vite.mjs +25 -0
package/README.md
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# @caperjs/solid
|
|
2
|
+
|
|
3
|
+
A declarative [SolidJS](https://www.solidjs.com/) view layer for Caper. Any
|
|
4
|
+
`Container` subclass may declare its members by returning JSX from a `compose()`
|
|
5
|
+
method; Solid's universal renderer mounts that tree into the container **once**,
|
|
6
|
+
and signals do every update after that — fine-grained, no VDOM, no re-render.
|
|
7
|
+
It is purely additive: imperative Caper (`this.add.*`, `added()`, `update()`)
|
|
8
|
+
keeps working exactly as before.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
pnpm add @caperjs/solid solid-js
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## tsconfig contract
|
|
17
|
+
|
|
18
|
+
Three settings, and all three are required:
|
|
19
|
+
|
|
20
|
+
```jsonc
|
|
21
|
+
{
|
|
22
|
+
"compilerOptions": {
|
|
23
|
+
// Leave the JSX alone — vite-plugin-solid does the real compilation.
|
|
24
|
+
"jsx": "preserve",
|
|
25
|
+
// Names the *type* lookup root for JSX. Nothing called `CaperJSX.h` ever
|
|
26
|
+
// runs; it exists because a transitive `@types/react` shadows any global
|
|
27
|
+
// `JSX` namespace, and `jsxImportSource` only applies in `react-jsx` mode.
|
|
28
|
+
"jsxFactory": "CaperJSX.h",
|
|
29
|
+
// Ships that `CaperJSX` namespace: the intrinsic elements and their props.
|
|
30
|
+
"types": ["@caperjs/core/client", "@caperjs/solid/jsx"]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`caper doctor` checks all three whenever the app depends on `@caperjs/solid`,
|
|
36
|
+
and prints the exact keys that are missing. It walks the `extends` chain, so
|
|
37
|
+
these three can live in a shared base config instead of the app's own file.
|
|
38
|
+
|
|
39
|
+
## Compose
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import { ComposableContainer, type Composes } from '@caperjs/solid';
|
|
43
|
+
import { createSignal } from 'solid-js';
|
|
44
|
+
|
|
45
|
+
export class HealthBar extends ComposableContainer implements Composes {
|
|
46
|
+
private health = createSignal(100);
|
|
47
|
+
|
|
48
|
+
/** Imperative API — an ordinary method that happens to write a signal. */
|
|
49
|
+
public damage(amount: number) {
|
|
50
|
+
this.health[1]((hp) => Math.max(0, hp - amount));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public compose() {
|
|
54
|
+
const hp = this.health[0];
|
|
55
|
+
return (
|
|
56
|
+
<container>
|
|
57
|
+
<graphics draw={BAR_BG} />
|
|
58
|
+
<graphics draw={BAR_FILL} scale={{ x: hp() / 100, y: 1 }} />
|
|
59
|
+
<text text={`${hp()} HP`} anchor={0.5} x={WIDTH / 2} y={HEIGHT / 2} />
|
|
60
|
+
</container>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`compose()` runs the first time the container hits the stage, and the Solid root
|
|
67
|
+
is disposed in `destroy()`. Re-adding does not remount. The rule of thumb:
|
|
68
|
+
**`compose()` declares what exists, signals say when state changed, `update()`
|
|
69
|
+
moves things every frame.**
|
|
70
|
+
|
|
71
|
+
Intrinsic elements are `container`, `sprite`, `text`, `graphics` and
|
|
72
|
+
`flexContainer`. For anything else, `asComponent(Ctor, defaults?)` lifts an
|
|
73
|
+
existing display class into JSX — it constructs the instance once and applies
|
|
74
|
+
props reactively:
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
const Orbiter$ = asComponent(Orbiter);
|
|
78
|
+
<Orbiter$ x={40} y={80} ref={(el: Orbiter) => (this.orbiter = el)} />;
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`useTick(fn)` runs `fn` every frame for the lifetime of the owning component —
|
|
82
|
+
`update()` for function components.
|
|
83
|
+
|
|
84
|
+
## Animation
|
|
85
|
+
|
|
86
|
+
`animated(source, opts?)` returns a **gliding** accessor: it reads like any other
|
|
87
|
+
signal, but eases toward its source instead of snapping to it. The binding stays
|
|
88
|
+
declarative — nothing in the view knows an animation is running.
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
const width = animated(() => hp() / 100); // opts: { duration, ease }
|
|
92
|
+
<graphics draw={BAR_FILL} scale={{ x: width(), y: 1 }} />;
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`<AnimatedShow>` is `<Show>` that holds its children on stage until the exit
|
|
96
|
+
animation finishes, so popups and panels can leave gracefully:
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
<AnimatedShow when={open} exit={{ pixi: { alpha: 0, y: 20 }, duration: 0.3 }}>
|
|
100
|
+
<container>…</container>
|
|
101
|
+
</AnimatedShow>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`enter` / `exit` are plain GSAP vars; target properties live in a `pixi: {...}`
|
|
105
|
+
block, which is GSAP's PixiPlugin — caper's `GSAPPlugin` registers it at app
|
|
106
|
+
bootstrap, so inside a running app there is nothing to wire up. Both APIs must be
|
|
107
|
+
called inside a reactive owner (a component body or a `compose()`).
|
|
108
|
+
|
|
109
|
+
One-shot effects (shake, pulse) stay imperative through a ref: every Caper
|
|
110
|
+
container carries the `Animated` mixin already.
|
|
111
|
+
|
|
112
|
+
## Authoring rules
|
|
113
|
+
|
|
114
|
+
Six rules. The first is the mental model; the rest are the edges that bite.
|
|
115
|
+
|
|
116
|
+
1. **Signals for event-rate state, `update()` for per-frame bulk motion.**
|
|
117
|
+
`text={purse()}` on a value that changes when the player does something is
|
|
118
|
+
free. Hundreds of per-frame bindings are fine too, but moving a crowd of
|
|
119
|
+
objects every frame still belongs in an imperative `update()` — or in
|
|
120
|
+
`useTick(fn)` + a `ref` when the code lives in a function component. Per-frame
|
|
121
|
+
signals are the seasoning, not the meal.
|
|
122
|
+
|
|
123
|
+
2. **`draw` functions must be stable references.** Solid batches an element's
|
|
124
|
+
dynamic props into one `!==`-guarded effect, so an inline
|
|
125
|
+
`draw={dot(3, color)}` allocates a fresh closure on every change of *any* prop
|
|
126
|
+
in that batch and forces a full `clear()` + redraw. Hoist the factory result
|
|
127
|
+
to a module constant (or a `createMemo`) and pass the same function every
|
|
128
|
+
time.
|
|
129
|
+
|
|
130
|
+
3. **Never imperatively remove or reparent a child JSX created.** Solid owns
|
|
131
|
+
those nodes and will try to move or dispose them later. Imperative work
|
|
132
|
+
alongside a composed tree is fine — `initialize()`, `this.add.*`, `update()`
|
|
133
|
+
all keep working, and `compose()` appends rather than taking over — it just
|
|
134
|
+
must not reach into the declarative half.
|
|
135
|
+
|
|
136
|
+
4. **Each `compose()` is its own reactive root.** Signals cross roots fine, so
|
|
137
|
+
instance fields are the bridge between a class's imperative API and its view.
|
|
138
|
+
Solid **context** does not cross the class boundary — pass props or read an
|
|
139
|
+
instance field instead.
|
|
140
|
+
|
|
141
|
+
5. **`text` elements default to `eventMode: 'none'`.** A hit-testable but
|
|
142
|
+
non-interactive label sitting over a button would otherwise swallow the tap.
|
|
143
|
+
Attaching an `on*` prop flips the element to `'static'` automatically, and an
|
|
144
|
+
explicit `eventMode` prop overrides the default.
|
|
145
|
+
|
|
146
|
+
6. **One-shot effects stay imperative.** Shake, pulse and friends are a `ref`
|
|
147
|
+
away: a Caper container mounted from JSX still carries the `Animated` mixin,
|
|
148
|
+
so `bar.shake()` works unchanged. Reserve `animated()` / `<AnimatedShow>` for
|
|
149
|
+
motion that is a function of state.
|
|
150
|
+
|
|
151
|
+
## Testing your components
|
|
152
|
+
|
|
153
|
+
Vitest resolves `solid-js` to its **server** build by default, where signals set
|
|
154
|
+
once and never update again. Force the reactive build in your app's
|
|
155
|
+
`vitest.config.ts` (this package's own config does the same):
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
export default defineConfig({
|
|
159
|
+
// Externalized deps are resolved by node, so the conditions only take effect
|
|
160
|
+
// once solid is inlined — both halves are needed.
|
|
161
|
+
resolve: { conditions: ['development', 'browser'] },
|
|
162
|
+
test: { server: { deps: { inline: [/solid-js/] } } },
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Build wiring
|
|
167
|
+
|
|
168
|
+
One flag in the app's vite config:
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
import { caper } from '@caperjs/core/vite';
|
|
172
|
+
|
|
173
|
+
export default defineConfig({
|
|
174
|
+
plugins: [caper({ solid: true })],
|
|
175
|
+
});
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
The preset resolves `@caperjs/solid/vite` from the **app's** `node_modules`, so
|
|
179
|
+
the app needs `@caperjs/solid` and `solid-js` installed; `vite-plugin-solid`
|
|
180
|
+
comes with this package and never has to be installed by hand. Pass an object to
|
|
181
|
+
narrow what gets compiled as JSX: `caper({ solid: { include: ['src/ui/**/*.tsx'] } })`
|
|
182
|
+
(default `['**/*.tsx']`).
|
|
183
|
+
|
|
184
|
+
Outside the preset — a bare vite config, or a vitest config that has to compile
|
|
185
|
+
JSX — use the plugin directly:
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
import { caperSolid } from '@caperjs/solid/vite';
|
|
189
|
+
|
|
190
|
+
export default defineConfig({ plugins: [caperSolid()] });
|
|
191
|
+
```
|
package/jsx.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSX types for `@caperjs/solid`. Add "@caperjs/solid/jsx" to the "types" array
|
|
3
|
+
* of your tsconfig, alongside `"jsx": "preserve"` and
|
|
4
|
+
* `"jsxFactory": "CaperJSX.h"`.
|
|
5
|
+
*
|
|
6
|
+
* The namespace hangs off `CaperJSX` rather than the global `JSX` namespace
|
|
7
|
+
* because `@types/react` is routinely in an app's program (pulled in
|
|
8
|
+
* transitively) and its `declare global { namespace JSX }` shadows any global
|
|
9
|
+
* one we add. `jsxFactory` names the type-lookup root instead; under
|
|
10
|
+
* `jsx: "preserve"` it is *only* a type lookup — vite-plugin-solid still does
|
|
11
|
+
* the real compilation, so nothing named `CaperJSX.h` is ever called.
|
|
12
|
+
* (`jsxImportSource` would be the modern answer, but it only applies in
|
|
13
|
+
* `react-jsx` mode.)
|
|
14
|
+
*
|
|
15
|
+
* Element props are deliberately loose for v1; a later release types each
|
|
16
|
+
* intrinsic against its Pixi class.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
declare namespace CaperJSX {
|
|
20
|
+
function h(type: any, props?: any, ...children: any[]): any;
|
|
21
|
+
|
|
22
|
+
/** The v1 prop bag for every intrinsic element: anything the class accepts. */
|
|
23
|
+
type ElementProps = Record<string, any> & { children?: any };
|
|
24
|
+
|
|
25
|
+
namespace JSX {
|
|
26
|
+
interface IntrinsicElements {
|
|
27
|
+
container: ElementProps;
|
|
28
|
+
sprite: ElementProps;
|
|
29
|
+
text: ElementProps;
|
|
30
|
+
graphics: ElementProps;
|
|
31
|
+
flexContainer: ElementProps;
|
|
32
|
+
}
|
|
33
|
+
type Element = any;
|
|
34
|
+
type ElementType = any;
|
|
35
|
+
interface ElementChildrenAttribute {
|
|
36
|
+
children: {};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conditional UI with enter / exit animations.
|
|
3
|
+
*
|
|
4
|
+
* ```tsx
|
|
5
|
+
* <AnimatedShow when={open}>
|
|
6
|
+
* <container>…</container>
|
|
7
|
+
* </AnimatedShow>
|
|
8
|
+
* ```
|
|
9
|
+
*
|
|
10
|
+
* Custom `enter` / `exit` are plain GSAP vars — put target properties in a
|
|
11
|
+
* `pixi: {...}` block (`{ pixi: { y: 20, alpha: 0 }, duration: 0.3 }`).
|
|
12
|
+
* There is no `fallback` — the whole point is that the node outlives the flag.
|
|
13
|
+
*
|
|
14
|
+
* Requires GSAP's PixiPlugin, which caper's `GSAPPlugin` registers during app
|
|
15
|
+
* bootstrap. This package deliberately does not register it itself; outside a
|
|
16
|
+
* booted `Application` (tests, standalone use) call
|
|
17
|
+
* `gsap.registerPlugin(PixiPlugin)` yourself first.
|
|
18
|
+
*/
|
|
19
|
+
export declare function AnimatedShow(props: {
|
|
20
|
+
when: boolean | (() => boolean);
|
|
21
|
+
children: any;
|
|
22
|
+
enter?: gsap.TweenVars;
|
|
23
|
+
exit?: gsap.TweenVars;
|
|
24
|
+
}): any;
|
|
25
|
+
//# sourceMappingURL=AnimatedShow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnimatedShow.d.ts","sourceRoot":"","sources":["../src/AnimatedShow.tsx"],"names":[],"mappings":"AAcA;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,IAAI,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,CAAC;IAChC,QAAQ,EAAE,GAAG,CAAC;IACd,KAAK,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC;IACvB,IAAI,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC;CACvB,OAiDA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AnimatedShow.test.d.ts","sourceRoot":"","sources":["../src/AnimatedShow.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Container, Constructor, Scene } from '@caperjs/core';
|
|
2
|
+
/**
|
|
3
|
+
* What `compose()` hands back. `unknown` for now so this file stays JSX-free;
|
|
4
|
+
* it becomes the real element type when `jsx.d.ts` lands.
|
|
5
|
+
*/
|
|
6
|
+
export type Composed = unknown;
|
|
7
|
+
/**
|
|
8
|
+
* The optional contract a `Composable` subclass opts into. Declared separately
|
|
9
|
+
* from the mixin (rather than merged onto it) so the mixin never claims a
|
|
10
|
+
* `compose` member of its own — the runtime just checks for one.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* class HealthBar extends ComposableContainer implements Composes {
|
|
15
|
+
* compose() {
|
|
16
|
+
* return <text text="100 HP" />;
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export interface Composes {
|
|
22
|
+
compose(): Composed;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Give a display class the `compose()` contract.
|
|
26
|
+
*
|
|
27
|
+
* The mixin adds no public members, so the returned constructor keeps `Base`'s
|
|
28
|
+
* own type — `compose()` is declared by the subclass via {@link Composes}.
|
|
29
|
+
*
|
|
30
|
+
* @param Base - The display class to make composable.
|
|
31
|
+
*/
|
|
32
|
+
export declare function Composable<TBase extends Constructor<any>>(Base: TBase): TBase;
|
|
33
|
+
/** A caper {@link Container} that can declare its members with JSX. */
|
|
34
|
+
export declare const ComposableContainer: typeof Container;
|
|
35
|
+
export type ComposableContainer = InstanceType<typeof ComposableContainer>;
|
|
36
|
+
/** A caper {@link Scene} that can declare its members with JSX. */
|
|
37
|
+
export declare const ComposableScene: typeof Scene;
|
|
38
|
+
export type ComposableScene = InstanceType<typeof ComposableScene>;
|
|
39
|
+
//# sourceMappingURL=Composable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Composable.d.ts","sourceRoot":"","sources":["../src/Composable.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAM9D;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,CAAC;AAE/B;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,QAAQ;IACvB,OAAO,IAAI,QAAQ,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,SAAS,WAAW,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,KAAK,GAAG,KAAK,CAiC7E;AAED,uEAAuE;AACvE,eAAO,MAAM,mBAAmB,kBAAwB,CAAC;AACzD,MAAM,MAAM,mBAAmB,GAAG,YAAY,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAE3E,mEAAmE;AACnE,eAAO,MAAM,eAAe,cAAoB,CAAC;AACjD,MAAM,MAAM,eAAe,GAAG,YAAY,CAAC,OAAO,eAAe,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Composable.test.d.ts","sourceRoot":"","sources":["../src/Composable.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Follow `source` smoothly.
|
|
3
|
+
*
|
|
4
|
+
* Must be called inside a reactive owner (a component body or a `compose()`),
|
|
5
|
+
* because it registers an `onCleanup` to kill its animation.
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* const barWidth = animated(() => hp() / 100);
|
|
9
|
+
* <graphics scale={{ x: barWidth(), y: 1 }} />
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export declare function animated(source: () => number, opts?: {
|
|
13
|
+
duration?: number;
|
|
14
|
+
ease?: string;
|
|
15
|
+
}): () => number;
|
|
16
|
+
//# sourceMappingURL=animated.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animated.d.ts","sourceRoot":"","sources":["../src/animated.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,MAAM,CAoBxG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"animated.test.d.ts","sourceRoot":"","sources":["../src/animated.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { PixiNode } from './renderer';
|
|
2
|
+
/**
|
|
3
|
+
* Lift an existing imperative display class into a JSX component.
|
|
4
|
+
*
|
|
5
|
+
* The instance is constructed once (untracked, so constructor reads don't
|
|
6
|
+
* subscribe to anything) and every prop is then applied through the renderer's
|
|
7
|
+
* own `spread`, which gives them the same reactivity as an intrinsic element —
|
|
8
|
+
* including `ref`.
|
|
9
|
+
*
|
|
10
|
+
* ```tsx
|
|
11
|
+
* const Orbiter$ = asComponent(Orbiter);
|
|
12
|
+
* <Orbiter$ x={40} y={80} />
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* @param Ctor - The display class to lift. Called as `new Ctor(defaults)`.
|
|
16
|
+
* @param defaults - Config handed to the constructor on every mount.
|
|
17
|
+
*/
|
|
18
|
+
export declare function asComponent<TNode extends PixiNode, TConfig>(Ctor: new (config?: TConfig) => TNode, defaults?: TConfig): (props: Record<string, any>) => TNode;
|
|
19
|
+
//# sourceMappingURL=asComponent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asComponent.d.ts","sourceRoot":"","sources":["../src/asComponent.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAG3C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,KAAK,SAAS,QAAQ,EAAE,OAAO,EACzD,IAAI,EAAE,KAAK,MAAM,CAAC,EAAE,OAAO,KAAK,KAAK,EACrC,QAAQ,CAAC,EAAE,OAAO,GACjB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,KAAK,CASvC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"asComponent.test.d.ts","sourceRoot":"","sources":["../src/asComponent.test.ts"],"names":[],"mappings":""}
|