mirror of
https://github.com/kennethnym/jrx.git
synced 2026-03-20 11:51:17 +00:00
Compare commits
6 Commits
add-exampl
...
add-readme
| Author | SHA1 | Date | |
|---|---|---|---|
| a38feebc2a | |||
| 12500a869d | |||
| 403d40ab8c | |||
| acf9f7f696 | |||
| 0a1a4fbf09 | |||
| b9e45afea0 |
10
.devcontainer/Dockerfile
Normal file
10
.devcontainer/Dockerfile
Normal file
@@ -0,0 +1,10 @@
|
||||
FROM mcr.microsoft.com/devcontainers/base:ubuntu-24.04
|
||||
|
||||
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||
&& apt-get -y install --no-install-recommends \
|
||||
curl unzip git ca-certificates \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
RUN curl -fsSL https://bun.sh/install | bash \
|
||||
&& ln -s /root/.bun/bin/bun /usr/local/bin/bun \
|
||||
&& ln -s /root/.bun/bin/bunx /usr/local/bin/bunx
|
||||
8
.devcontainer/devcontainer.json
Normal file
8
.devcontainer/devcontainer.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "jrx",
|
||||
"build": {
|
||||
"context": ".",
|
||||
"dockerfile": "Dockerfile"
|
||||
},
|
||||
"postCreateCommand": "bun install && cd example && bun install"
|
||||
}
|
||||
159
README.md
Normal file
159
README.md
Normal file
@@ -0,0 +1,159 @@
|
||||
# jrx
|
||||
|
||||
JSX factory for [json-render](https://github.com/vercel-labs/json-render). Write JSX, get Spec JSON.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
bun add jrx @json-render/core
|
||||
```
|
||||
|
||||
## Setup
|
||||
|
||||
Configure your `tsconfig.json` to use jrx as the JSX source:
|
||||
|
||||
```json
|
||||
{
|
||||
"compilerOptions": {
|
||||
"jsx": "react-jsx",
|
||||
"jsxImportSource": "jrx"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Or use a per-file pragma:
|
||||
|
||||
```tsx
|
||||
/** @jsxImportSource jrx */
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Define components
|
||||
|
||||
Create wrapper functions that map JSX tags to json-render component type names:
|
||||
|
||||
```ts
|
||||
import { jsx } from "jrx/jsx-runtime";
|
||||
import type { JrxNode } from "jrx";
|
||||
|
||||
export function Stack(props: Record<string, unknown>): JrxNode {
|
||||
return jsx("Stack", props);
|
||||
}
|
||||
|
||||
export function Text(props: Record<string, unknown>): JrxNode {
|
||||
return jsx("Text", props);
|
||||
}
|
||||
|
||||
export function Button(props: Record<string, unknown>): JrxNode {
|
||||
return jsx("Button", props);
|
||||
}
|
||||
```
|
||||
|
||||
### Render JSX to Spec JSON
|
||||
|
||||
```tsx
|
||||
import { render } from "jrx";
|
||||
import { Stack, Text, Button } from "./components";
|
||||
|
||||
const spec = render(
|
||||
<Stack>
|
||||
<Text content="Hello from jrx!" />
|
||||
<Button label="Click me" />
|
||||
</Stack>
|
||||
);
|
||||
```
|
||||
|
||||
This produces:
|
||||
|
||||
```json
|
||||
{
|
||||
"root": "stack-1",
|
||||
"elements": {
|
||||
"text-1": {
|
||||
"type": "Text",
|
||||
"props": { "content": "Hello from jrx!" }
|
||||
},
|
||||
"button-1": {
|
||||
"type": "Button",
|
||||
"props": { "label": "Click me" }
|
||||
},
|
||||
"stack-1": {
|
||||
"type": "Stack",
|
||||
"props": {},
|
||||
"children": ["text-1", "button-1"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### State, events, visibility, and watchers
|
||||
|
||||
Pass json-render bindings as JSX props:
|
||||
|
||||
```tsx
|
||||
const spec = render(
|
||||
<Stack>
|
||||
<Text content={{ $state: "/count" }} />
|
||||
<Button
|
||||
label="Increment"
|
||||
on={{
|
||||
press: {
|
||||
action: "increment",
|
||||
params: { statePath: "/count" },
|
||||
},
|
||||
}}
|
||||
/>
|
||||
<Text
|
||||
content="Hidden until toggled"
|
||||
visible={{ $state: "/showDetails", eq: true }}
|
||||
/>
|
||||
</Stack>,
|
||||
{
|
||||
state: {
|
||||
count: 0,
|
||||
showDetails: false,
|
||||
},
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
The `render()` function accepts an options object with `state` to include initial state in the Spec output.
|
||||
|
||||
### Reserved props
|
||||
|
||||
These props are extracted from JSX and mapped to Spec fields rather than passed through as component props:
|
||||
|
||||
| Prop | Spec field | Description |
|
||||
|---|---|---|
|
||||
| `key` | element key | Explicit element key (overrides auto-generation) |
|
||||
| `visible` | `visible` | Visibility condition |
|
||||
| `on` | `on` | Event bindings |
|
||||
| `repeat` | `repeat` | Repeat configuration |
|
||||
| `watch` | `watch` | State watchers |
|
||||
| `children` | `children` | Child element references |
|
||||
|
||||
## Example
|
||||
|
||||
The `example/` directory contains a Bun HTTP server that demonstrates jrx in action. It shows JSX source, live rendered UI (via `@json-render/react`), and JSON output side by side.
|
||||
|
||||
```bash
|
||||
cd example
|
||||
bun install
|
||||
bun dev
|
||||
```
|
||||
|
||||
This starts a dev server with HMR at `http://localhost:3000`.
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
bun install # install dependencies
|
||||
bun run build # build dist/
|
||||
bun test # run tests
|
||||
bun run typecheck # type check
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
Reference in New Issue
Block a user