mirror of
https://github.com/remorses/gpuix.git
synced 2026-10-29 03:04:52 +08:00
Installing the published packages and writing an app was not possible by
following the README. Three things blocked it.
**1. `key` failed on every GPUIX element**
error TS2322: Type '{ key: string; ... }' is not assignable to type 'Props'.
Property 'key' does not exist on type 'Props'.
Any list built with `.map()` broke on the first `tsc` run. `key` was expected
to arrive through `JSX.IntrinsicAttributes`, but TypeScript 5 ignores that
member for intrinsic elements. React's DOM types work only because
`DetailedHTMLProps` already carries `key`.
`key` now sits on `Props`, next to `ref`, and on `VirtualListShared`, the one
element prop type that does not extend `Props`. Verified with a probe over all
12 intrinsic elements plus `motion.div`, `VirtualList`, Select, Combobox and
Tooltip.
`jsx-dev-runtime.d.ts` also re-exported `jsx` and `jsxs` from
`react/jsx-dev-runtime`, which exports only `jsxDEV`. The declarations now
match `jsx-dev-runtime.js`.
Nothing caught this because Bun never typechecks and the build tsconfig
excludes `src/__tests__`. CI now runs `bun run typecheck` in `example-app`,
whose `app.tsx` maps a keyed list inside a `<virtual-list>`.
**2. A hello world installed 254 MB**
`@gpuix/native` packed all six platform binaries into the main tarball through
a `*.node` glob, on top of the six per-platform packages that
`optionalDependencies` already resolves.
node_modules 254M
|- @gpuix/native 185M <- all six, never loaded
|- @gpuix/native-darwin-arm64 23M <- the one that loads
|- @gpuix/react 544K
The glob is gone. `index.js` still resolves the platform package at runtime.
**3. The README never said how to install**
It opened with the architecture and the mutation protocol. There was no
`bun add` anywhere, and no mention of `jsxImportSource`, which is required:
without it TypeScript uses DOM types and `<virtual-list>`, `<markdown>`,
`<code>` and `style.hover` all fail.
A **Quickstart** now sits between the hero and Examples: install, tsconfig,
entry file, `bun --hot`, `bun build --compile`. Nothing was removed. The
Building section says up front that it is for working on GPUIX itself.
**example-app/**
A todo app to copy, in one file, using the Waku palette from `chat.tsx`.
| Script | What it does |
|---|---|
| `bun run dev` | `bun --hot app.tsx` |
| `bun run build` | standalone binary in `dist/todo` |
| `bun run web:build` | browser renderer, needs nightly Rust |
| `bun run web:dev` | browser bundle served with COOP/COEP |
| `bun run screenshot` | drives the app through the automation client |
| `bun run typecheck` | `tsc --noEmit` |
It shows `<virtual-list>`, a native `<input>`, `motion.div`, tinted `<svg>`,
native `hover` and `active`, and `testId` hooks. `scripts/screenshots.ts`
regenerates `docs/images/todo-app.png` from it.
Verified on all four paths: `bun --hot`, the 77 MB binary, the browser build at
`localhost:4188`, and a clean `typecheck`.
Two things worth remembering, both now in comments:
- the browser build embeds only IBM Plex Sans and Lilex, so `Helvetica` falls
back to a monospace and the family has to differ per target
- `maxWidth` on a `<virtual-list>` row does nothing; the list lays each row out
at list width, so the column cap goes one level in
`bun.lock` carries a few entries from unrelated in-flight work in `examples/`.
They are inert and prune on the next install.
Session: ses_fc1c928b0ffeeHIfdRpxtE0QaV
32 lines
1.2 KiB
HTML
32 lines
1.2 KiB
HTML
<!-- Browser page for the GPUIX todo app. GPUI creates the canvas itself. -->
|
|
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1" />
|
|
<title>GPUIX Todo</title>
|
|
<style>
|
|
* { box-sizing: border-box; }
|
|
html, body { margin: 0; width: 100%; height: 100%; overflow: hidden; background: #1a1a1a; }
|
|
canvas { display: block; width: 100%; height: 100%; touch-action: none; }
|
|
/* The app draws every glyph itself, so the page must not behave like a
|
|
document: a long press would select the body and pop the iOS callout. */
|
|
html, body, canvas {
|
|
-webkit-user-select: none;
|
|
user-select: none;
|
|
-webkit-touch-callout: none;
|
|
-webkit-tap-highlight-color: transparent;
|
|
}
|
|
/* GPUI's hidden IME textarea still needs a real selection for
|
|
composition, backspace context, and clipboard. */
|
|
[data-gpui-input] {
|
|
-webkit-user-select: text !important;
|
|
user-select: text !important;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<script type="module" src="/app.js"></script>
|
|
</body>
|
|
</html>
|