react-pebble 0.1.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/lib/compiler.cjs +3 -0
- package/dist/lib/compiler.cjs.map +1 -0
- package/dist/lib/compiler.js +54 -0
- package/dist/lib/compiler.js.map +1 -0
- package/dist/lib/components.cjs +2 -0
- package/dist/lib/components.cjs.map +1 -0
- package/dist/lib/components.js +80 -0
- package/dist/lib/components.js.map +1 -0
- package/dist/lib/hooks.cjs +2 -0
- package/dist/lib/hooks.cjs.map +1 -0
- package/dist/lib/hooks.js +99 -0
- package/dist/lib/hooks.js.map +1 -0
- package/dist/lib/index.cjs +2 -0
- package/dist/lib/index.cjs.map +1 -0
- package/dist/lib/index.js +585 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/platform.cjs +2 -0
- package/dist/lib/platform.cjs.map +1 -0
- package/dist/lib/platform.js +52 -0
- package/dist/lib/platform.js.map +1 -0
- package/dist/lib/plugin.cjs +60 -0
- package/dist/lib/plugin.cjs.map +1 -0
- package/dist/lib/plugin.js +102 -0
- package/dist/lib/plugin.js.map +1 -0
- package/dist/lib/src/compiler/index.d.ts +40 -0
- package/dist/lib/src/components/index.d.ts +129 -0
- package/dist/lib/src/hooks/index.d.ts +75 -0
- package/dist/lib/src/index.d.ts +36 -0
- package/dist/lib/src/pebble-dom-shim.d.ts +45 -0
- package/dist/lib/src/pebble-dom.d.ts +59 -0
- package/dist/lib/src/pebble-output.d.ts +44 -0
- package/dist/lib/src/pebble-reconciler.d.ts +16 -0
- package/dist/lib/src/pebble-render.d.ts +31 -0
- package/dist/lib/src/platform.d.ts +30 -0
- package/dist/lib/src/plugin/index.d.ts +20 -0
- package/package.json +90 -0
- package/scripts/compile-to-piu.ts +1794 -0
- package/scripts/deploy.sh +46 -0
- package/src/compiler/index.ts +114 -0
- package/src/components/index.tsx +280 -0
- package/src/hooks/index.ts +311 -0
- package/src/index.ts +126 -0
- package/src/pebble-dom-shim.ts +266 -0
- package/src/pebble-dom.ts +190 -0
- package/src/pebble-output.ts +310 -0
- package/src/pebble-reconciler.ts +54 -0
- package/src/pebble-render.ts +311 -0
- package/src/platform.ts +50 -0
- package/src/plugin/index.ts +274 -0
- package/src/types/moddable.d.ts +156 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pebble-dom.ts — Virtual DOM layer for React Pebble
|
|
3
|
+
*
|
|
4
|
+
* Modeled after Ink's dom.ts but stripped of Yoga layout.
|
|
5
|
+
* Pebble uses absolute positioning (x, y, w, h) rather than flexbox,
|
|
6
|
+
* so nodes are just plain JS objects with type, props, and children.
|
|
7
|
+
*
|
|
8
|
+
* Each node type maps to a Pebble drawing primitive:
|
|
9
|
+
* pbl-root → Container root (the Window)
|
|
10
|
+
* pbl-rect → fillRect / drawRect
|
|
11
|
+
* pbl-circle → fillCircle / drawCircle
|
|
12
|
+
* pbl-text → drawText
|
|
13
|
+
* pbl-line → drawLine
|
|
14
|
+
* pbl-image → drawImage (bitmap)
|
|
15
|
+
* pbl-group → Logical grouping with offset (no draw call)
|
|
16
|
+
* #text → Raw text content (only valid inside pbl-text)
|
|
17
|
+
*/
|
|
18
|
+
export type ElementType = 'pbl-root' | 'pbl-rect' | 'pbl-circle' | 'pbl-text' | 'pbl-line' | 'pbl-image' | 'pbl-group' | 'pbl-statusbar' | 'pbl-actionbar';
|
|
19
|
+
export declare const ELEMENT_TYPES: ReadonlySet<ElementType>;
|
|
20
|
+
/**
|
|
21
|
+
* Loose prop bag — element-specific shapes are documented on each component
|
|
22
|
+
* wrapper, but the reconciler treats them uniformly.
|
|
23
|
+
*/
|
|
24
|
+
export type NodeProps = Record<string, unknown> & {
|
|
25
|
+
_hidden?: boolean;
|
|
26
|
+
};
|
|
27
|
+
export interface DOMElement {
|
|
28
|
+
id: number;
|
|
29
|
+
type: ElementType;
|
|
30
|
+
props: NodeProps;
|
|
31
|
+
children: Array<DOMElement | TextNode>;
|
|
32
|
+
parent: DOMElement | null;
|
|
33
|
+
/** Called by the reconciler after each commit; wired up by `render()`. */
|
|
34
|
+
onRender: (() => void) | null;
|
|
35
|
+
/** Optional layout pass; we currently don't use this. */
|
|
36
|
+
onComputeLayout: (() => void) | null;
|
|
37
|
+
/** Internal dirty flag (currently informational only). */
|
|
38
|
+
_dirty: boolean;
|
|
39
|
+
}
|
|
40
|
+
export interface TextNode {
|
|
41
|
+
id: number;
|
|
42
|
+
type: '#text';
|
|
43
|
+
value: string;
|
|
44
|
+
parent: DOMElement | null;
|
|
45
|
+
/** Saved value while the node is hidden by Suspense. */
|
|
46
|
+
_hiddenValue?: string;
|
|
47
|
+
}
|
|
48
|
+
export type AnyNode = DOMElement | TextNode;
|
|
49
|
+
export declare function createNode(type: ElementType): DOMElement;
|
|
50
|
+
export declare function createTextNode(text: string): TextNode;
|
|
51
|
+
export declare function appendChildNode(parent: DOMElement, child: AnyNode): void;
|
|
52
|
+
export declare function insertBeforeNode(parent: DOMElement, child: AnyNode, beforeChild: AnyNode): void;
|
|
53
|
+
export declare function removeChildNode(parent: DOMElement, child: AnyNode): void;
|
|
54
|
+
export declare function setAttribute(node: DOMElement, key: string, value: unknown): void;
|
|
55
|
+
export declare function setTextNodeValue(node: TextNode, text: string): void;
|
|
56
|
+
export declare function getTextContent(node: AnyNode): string;
|
|
57
|
+
export type Visitor = (node: AnyNode, depth: number) => void;
|
|
58
|
+
export declare function walkTree(root: AnyNode, visitor: Visitor, depth?: number): void;
|
|
59
|
+
export declare function findRoot(node: AnyNode): DOMElement;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { default as Poco, PocoColor, PocoFont } from 'commodetto/Poco';
|
|
2
|
+
import { DOMElement } from './pebble-dom.js';
|
|
3
|
+
export interface RGB {
|
|
4
|
+
r: number;
|
|
5
|
+
g: number;
|
|
6
|
+
b: number;
|
|
7
|
+
}
|
|
8
|
+
export declare const COLOR_PALETTE: Readonly<Record<string, RGB>>;
|
|
9
|
+
export interface FontSpec {
|
|
10
|
+
family: string;
|
|
11
|
+
size: number;
|
|
12
|
+
}
|
|
13
|
+
export declare const FONT_PALETTE: Readonly<Record<string, FontSpec>>;
|
|
14
|
+
export interface RenderOptions {
|
|
15
|
+
backgroundColor?: string;
|
|
16
|
+
/**
|
|
17
|
+
* Incremental update region. If provided, `poco.begin(x, y, w, h)` is used
|
|
18
|
+
* to clip drawing to just that region. Otherwise the full frame is redrawn.
|
|
19
|
+
*/
|
|
20
|
+
dirty?: {
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
w: number;
|
|
24
|
+
h: number;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export declare class PocoRenderer {
|
|
28
|
+
readonly poco: Poco;
|
|
29
|
+
private readonly colorCache;
|
|
30
|
+
private readonly fontCache;
|
|
31
|
+
constructor(poco: Poco);
|
|
32
|
+
/**
|
|
33
|
+
* Render the full tree into a fresh frame.
|
|
34
|
+
*/
|
|
35
|
+
render(rootNode: DOMElement, options?: RenderOptions): void;
|
|
36
|
+
/** Resolve a color name (or pass-through int) to a PocoColor. */
|
|
37
|
+
getColor(name: string | undefined): PocoColor;
|
|
38
|
+
/** Resolve a font name to a PocoFont (cached). */
|
|
39
|
+
getFont(name: string | undefined): PocoFont;
|
|
40
|
+
private renderChildren;
|
|
41
|
+
private renderNode;
|
|
42
|
+
}
|
|
43
|
+
export declare function resolveColorName(color: string | undefined): string;
|
|
44
|
+
export declare function resolveFontName(font: string | undefined): string;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ComponentChild } from 'preact';
|
|
2
|
+
import { DOMElement } from './pebble-dom.js';
|
|
3
|
+
import { ShimElement } from './pebble-dom-shim.js';
|
|
4
|
+
export interface PebbleContainer {
|
|
5
|
+
shimRoot: ShimElement;
|
|
6
|
+
pblRoot: DOMElement;
|
|
7
|
+
}
|
|
8
|
+
export declare function createContainer(): PebbleContainer;
|
|
9
|
+
export declare function updateContainer(vnode: ComponentChild, container: PebbleContainer): void;
|
|
10
|
+
export declare function unmountContainer(container: PebbleContainer): void;
|
|
11
|
+
declare const _default: {
|
|
12
|
+
createContainer: typeof createContainer;
|
|
13
|
+
updateContainer: typeof updateContainer;
|
|
14
|
+
unmountContainer: typeof unmountContainer;
|
|
15
|
+
};
|
|
16
|
+
export default _default;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ComponentChild } from 'preact';
|
|
2
|
+
import { default as Poco } from 'commodetto/Poco';
|
|
3
|
+
import { DOMElement } from './pebble-dom.js';
|
|
4
|
+
export interface PebblePlatformInfo {
|
|
5
|
+
isReal: boolean;
|
|
6
|
+
platform: 'alloy' | 'mock';
|
|
7
|
+
screenWidth: number;
|
|
8
|
+
screenHeight: number;
|
|
9
|
+
}
|
|
10
|
+
export interface DrawCall {
|
|
11
|
+
op: string;
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
}
|
|
14
|
+
export interface RenderOptions {
|
|
15
|
+
backgroundColor?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface PebbleApp {
|
|
18
|
+
update(newElement: ComponentChild): void;
|
|
19
|
+
unmount(): void;
|
|
20
|
+
readonly platform: PebblePlatformInfo;
|
|
21
|
+
readonly drawLog: readonly DrawCall[];
|
|
22
|
+
readonly _root: DOMElement;
|
|
23
|
+
}
|
|
24
|
+
export interface RenderOptionsExt extends RenderOptions {
|
|
25
|
+
/**
|
|
26
|
+
* Pre-imported Poco constructor. Alloy entry files must import Poco at
|
|
27
|
+
* the top and pass it here so the Moddable bundler resolves it correctly.
|
|
28
|
+
*/
|
|
29
|
+
poco?: typeof Poco;
|
|
30
|
+
}
|
|
31
|
+
export declare function render(element: ComponentChild, options?: RenderOptionsExt): PebbleApp;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* src/platform.ts — Screen dimensions and platform constants.
|
|
3
|
+
*
|
|
4
|
+
* The compiler sets these before rendering so components can use
|
|
5
|
+
* SCREEN.width / SCREEN.height instead of hardcoding pixel values.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* import { SCREEN } from 'react-pebble';
|
|
9
|
+
* <Rect x={0} y={0} w={SCREEN.width} h={SCREEN.height} fill="black" />
|
|
10
|
+
*/
|
|
11
|
+
export interface PebblePlatform {
|
|
12
|
+
name: string;
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
isRound: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare const PLATFORMS: Record<string, PebblePlatform>;
|
|
18
|
+
/**
|
|
19
|
+
* Current screen dimensions. Set by the compiler before rendering.
|
|
20
|
+
* Components import this and use SCREEN.width / SCREEN.height for
|
|
21
|
+
* responsive layouts.
|
|
22
|
+
*/
|
|
23
|
+
export declare const SCREEN: {
|
|
24
|
+
width: number;
|
|
25
|
+
height: number;
|
|
26
|
+
isRound: boolean;
|
|
27
|
+
platform: string;
|
|
28
|
+
};
|
|
29
|
+
/** @internal — called by the compiler to set the platform. */
|
|
30
|
+
export declare function _setPlatform(platform: string): void;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
export interface PebblePiuOptions {
|
|
3
|
+
/** Path to the entry .tsx file (relative to project root) */
|
|
4
|
+
entry: string;
|
|
5
|
+
/** Milliseconds to wait for async effects before snapshotting */
|
|
6
|
+
settleMs?: number;
|
|
7
|
+
/** Target platform — sets screen dimensions (default: 'emery') */
|
|
8
|
+
platform?: string;
|
|
9
|
+
/** Directory for the generated Pebble project (default: '.pebble-build') */
|
|
10
|
+
buildDir?: string;
|
|
11
|
+
/** Auto-run pebble build + install after compilation */
|
|
12
|
+
deploy?: boolean;
|
|
13
|
+
/** Emulator platform for deploy (default: same as platform) */
|
|
14
|
+
emulator?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Vite plugin that compiles react-pebble JSX to piu and scaffolds a
|
|
18
|
+
* Pebble project for deployment.
|
|
19
|
+
*/
|
|
20
|
+
export declare function pebblePiu(options: PebblePiuOptions): Plugin;
|
package/package.json
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-pebble",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Write Pebble watchfaces and apps in JSX — compiles to piu for Pebble Alloy at build time",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/lib/index.cjs",
|
|
7
|
+
"module": "dist/lib/index.js",
|
|
8
|
+
"types": "dist/lib/src/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/lib/src/index.d.ts",
|
|
12
|
+
"import": "./dist/lib/index.js",
|
|
13
|
+
"require": "./dist/lib/index.cjs"
|
|
14
|
+
},
|
|
15
|
+
"./hooks": {
|
|
16
|
+
"types": "./dist/lib/src/hooks/index.d.ts",
|
|
17
|
+
"import": "./dist/lib/hooks.js",
|
|
18
|
+
"require": "./dist/lib/hooks.cjs"
|
|
19
|
+
},
|
|
20
|
+
"./components": {
|
|
21
|
+
"types": "./dist/lib/src/components/index.d.ts",
|
|
22
|
+
"import": "./dist/lib/components.js",
|
|
23
|
+
"require": "./dist/lib/components.cjs"
|
|
24
|
+
},
|
|
25
|
+
"./plugin": {
|
|
26
|
+
"types": "./dist/lib/src/plugin/index.d.ts",
|
|
27
|
+
"import": "./dist/lib/plugin.js"
|
|
28
|
+
},
|
|
29
|
+
"./compiler": {
|
|
30
|
+
"types": "./dist/lib/src/compiler/index.d.ts",
|
|
31
|
+
"import": "./dist/lib/compiler.js"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"files": [
|
|
35
|
+
"dist/lib",
|
|
36
|
+
"src",
|
|
37
|
+
"scripts"
|
|
38
|
+
],
|
|
39
|
+
"scripts": {
|
|
40
|
+
"typecheck": "tsc --noEmit",
|
|
41
|
+
"test": "npm run typecheck && npx tsx test/snapshot-test.ts",
|
|
42
|
+
"test:snapshots": "npx tsx test/snapshot-test.ts",
|
|
43
|
+
"test:update": "npx tsx test/snapshot-test.ts --update",
|
|
44
|
+
"build": "npm run build:lib",
|
|
45
|
+
"build:lib": "vite build --config vite.config.lib.js",
|
|
46
|
+
"prepublishOnly": "npm run test && npm run build"
|
|
47
|
+
},
|
|
48
|
+
"keywords": [
|
|
49
|
+
"pebble",
|
|
50
|
+
"smartwatch",
|
|
51
|
+
"watchface",
|
|
52
|
+
"piu",
|
|
53
|
+
"moddable",
|
|
54
|
+
"alloy",
|
|
55
|
+
"jsx",
|
|
56
|
+
"preact",
|
|
57
|
+
"compiler",
|
|
58
|
+
"vite-plugin"
|
|
59
|
+
],
|
|
60
|
+
"license": "MIT",
|
|
61
|
+
"repository": {
|
|
62
|
+
"type": "git",
|
|
63
|
+
"url": "https://github.com/eddiemoore/react-pebble"
|
|
64
|
+
},
|
|
65
|
+
"homepage": "https://github.com/eddiemoore/react-pebble#readme",
|
|
66
|
+
"bugs": {
|
|
67
|
+
"url": "https://github.com/eddiemoore/react-pebble/issues"
|
|
68
|
+
},
|
|
69
|
+
"engines": {
|
|
70
|
+
"node": ">=18"
|
|
71
|
+
},
|
|
72
|
+
"peerDependencies": {
|
|
73
|
+
"vite": ">=5.0.0"
|
|
74
|
+
},
|
|
75
|
+
"peerDependenciesMeta": {
|
|
76
|
+
"vite": {
|
|
77
|
+
"optional": true
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
"devDependencies": {
|
|
81
|
+
"@types/node": "^25.5.2",
|
|
82
|
+
"tsx": "^4.21.0",
|
|
83
|
+
"typescript": "^6.0.2",
|
|
84
|
+
"vite": "^8.0.7",
|
|
85
|
+
"vite-plugin-dts": "^4.5.4"
|
|
86
|
+
},
|
|
87
|
+
"dependencies": {
|
|
88
|
+
"preact": "^10.29.1"
|
|
89
|
+
}
|
|
90
|
+
}
|