poseui 0.0.1
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 +109 -0
- package/dist/index.d.ts +824 -0
- package/dist/index.js +518 -0
- package/package.json +40 -0
package/README.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Pose
|
|
2
|
+
|
|
3
|
+
> ⚠️ Prototype — API is unstable
|
|
4
|
+
|
|
5
|
+
Type-safe HTML templating engine with a fluent Tailwind v4 builder API. Inspired by [gpui](https://www.gpui.rs/).
|
|
6
|
+
|
|
7
|
+
Uses [UnoCSS](https://unocss.dev) + [presetWind4](https://unocss.dev/presets/wind4) for CSS generation and [Standard Schema](https://standardschema.dev) for prop validation.
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import pose from "poseui";
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
|
|
13
|
+
const button = pose
|
|
14
|
+
.as("button")
|
|
15
|
+
.input(
|
|
16
|
+
z.object({
|
|
17
|
+
variant: z.enum(["primary", "secondary"]).default("primary"),
|
|
18
|
+
disabled: z.boolean().default(false),
|
|
19
|
+
}),
|
|
20
|
+
)
|
|
21
|
+
.px(4)
|
|
22
|
+
.py(2)
|
|
23
|
+
.rounded()
|
|
24
|
+
.font_semibold()
|
|
25
|
+
.transition()
|
|
26
|
+
.when("variant", {
|
|
27
|
+
primary: (b) => b.bg("indigo-600").text_color("white"),
|
|
28
|
+
secondary: (b) => b.bg("slate-200").text_color("slate-900"),
|
|
29
|
+
})
|
|
30
|
+
.when(
|
|
31
|
+
({ disabled }) => disabled,
|
|
32
|
+
(b) => b.opacity(50).cursor_not_allowed(),
|
|
33
|
+
)
|
|
34
|
+
.child(({ variant }) => (variant === "primary" ? "Submit" : "Cancel"));
|
|
35
|
+
|
|
36
|
+
// just HTML — sync
|
|
37
|
+
button({ variant: "primary" });
|
|
38
|
+
// <button class="px-4 py-2 rounded font-semibold transition bg-indigo-600 text-white">Submit</button>
|
|
39
|
+
|
|
40
|
+
// HTML + generated CSS — async, runs UnoCSS
|
|
41
|
+
const { html, css } = await button.render({ variant: "primary" });
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Install
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
bun add poseui
|
|
48
|
+
# optional
|
|
49
|
+
bun add zod # or valibot, arktype, any Standard Schema lib
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Core concepts
|
|
53
|
+
|
|
54
|
+
**`pose.as(tag)`** — start a builder for any HTML tag.
|
|
55
|
+
|
|
56
|
+
**`.input(schema)`** — bind a [Standard Schema](https://standardschema.dev) object schema. Infers `TProps` from the output type, so `.default()` transforms work. Validates on every render, throws `PoseValidationError` on failure.
|
|
57
|
+
|
|
58
|
+
**Style methods** — mirror Tailwind v4 utilities. Every method that takes a value also accepts `(props: TProps) => value` for one-off dynamic styles. See the source for the full list.
|
|
59
|
+
|
|
60
|
+
**`.when(pred, apply)`** — apply styles when a predicate returns true:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
.when(({ disabled }) => disabled, (b) => b.opacity(50).cursor_not_allowed())
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**`.when(key, cases)`** — switch on a prop key and apply styles per matching case. Case keys are typed to the prop's actual union values — typos are compile errors:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
.when("size", {
|
|
70
|
+
sm: (b) => b.px(2).py(1).text_sm(),
|
|
71
|
+
md: (b) => b.px(4).py(2).text_base(),
|
|
72
|
+
lg: (b) => b.px(6).py(3).text_lg(),
|
|
73
|
+
})
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Cases are `Partial` — unmatched values emit no classes. Multiple `.when()` calls stack independently.
|
|
77
|
+
|
|
78
|
+
**`.cls(value)`** — escape hatch for anything not in the builder. Accepts a raw class string or `(props) => string`.
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
pose
|
|
82
|
+
.as("div")
|
|
83
|
+
.cls("hover:opacity-75")
|
|
84
|
+
.cls(({ active }) => (active ? "ring-2 ring-blue-500" : ""));
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**`.child(value | fn)`** — append children. Accepts a string, number, another `PozElement`, an array of those, or `(props: TProps) => any of the above`. Chainable.
|
|
88
|
+
|
|
89
|
+
**`element(props)`** — render to an HTML string synchronously. If the bound schema has async validation, returns `Promise<string>`.
|
|
90
|
+
|
|
91
|
+
**`element.render(props)`** — render to `{ html, css }`. Runs UnoCSS against the rendered HTML to generate only the CSS rules that are actually used.
|
|
92
|
+
|
|
93
|
+
## Validation errors
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import { PoseValidationError } from "poseui";
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
button({ variant: "primary" });
|
|
100
|
+
} catch (err) {
|
|
101
|
+
if (err instanceof PoseValidationError) {
|
|
102
|
+
console.log(err.issues); // StandardSchemaV1.Issue[]
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## License
|
|
108
|
+
|
|
109
|
+
MIT
|