create-hozu 0.3.0 → 0.4.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/package.json +1 -1
- package/skill/reference.md +30 -2
package/package.json
CHANGED
package/skill/reference.md
CHANGED
|
@@ -21,9 +21,30 @@ export const docs = route({ path: '/docs/:path+', params: z.object({ path: z.arr
|
|
|
21
21
|
literal option values are all members, so one submit carries a title and a priority.
|
|
22
22
|
- `ui.dom.valueAsNumber` (number | null), `ui.dom.checked`, `ui.dom.key`, and similar event fields.
|
|
23
23
|
- Also: `ui.html(value)` (trusted HTML from query data only, HZ030), `ui.asset(new URL('./x.png', import.meta.url))`,
|
|
24
|
-
`ui.window({ on })` / `ui.document({ on })` for global listeners, widgets (
|
|
24
|
+
`ui.window({ on })` / `ui.document({ on })` for global listeners, widgets (see Widgets) for browser APIs and
|
|
25
25
|
third-party DOM libraries.
|
|
26
26
|
|
|
27
|
+
## Widgets (browser APIs, DOM libraries)
|
|
28
|
+
There is no `widget` export: declare with `ui.widget`, place with `ui.use`, list the declaration in the feature's
|
|
29
|
+
`declarations`, and implement it in a client module.
|
|
30
|
+
```ts
|
|
31
|
+
export const Copy = ui.widget({ tag: 'button', props: z.object({ text: z.string() }),
|
|
32
|
+
events: { copied: z.object({}) }, client: new URL('./copy.client.ts', import.meta.url), load: 'visible', wraps: true })
|
|
33
|
+
ui.use(Copy, { props: { text: block.code }, on: { copied: () => ui.send(Copied, {}) }, class: 'btn' }, ['Copy'])
|
|
34
|
+
```
|
|
35
|
+
```ts
|
|
36
|
+
// copy.client.ts: a type-only import of the declaration
|
|
37
|
+
import { implement } from '@hozu/core/widget'
|
|
38
|
+
import type { Copy } from './widgets.ts'
|
|
39
|
+
export default implement<typeof Copy>(({ el, props, emit, signal }) => {
|
|
40
|
+
el.addEventListener('click', () => navigator.clipboard.writeText(props.text).then(() => emit('copied', {})), { signal })
|
|
41
|
+
return { update(next) { props = next } }
|
|
42
|
+
})
|
|
43
|
+
```
|
|
44
|
+
`load`: `'eager' | 'visible' | 'idle'`; `wraps: true` keeps the children as server HTML. Serve with
|
|
45
|
+
`widgets: await bundleWidgets(build)` from `@hozu/bundle` (and pass it to `exportStatic`); `hozu build` bundles
|
|
46
|
+
them itself (HZ029 for a client module that does not bundle).
|
|
47
|
+
|
|
27
48
|
## Forms without JavaScript
|
|
28
49
|
A submit whose payload reads only `ui.dom.form('name')`, literals, context, params and search also works without JS
|
|
29
50
|
(otherwise HZ036 warns). The server runs the same machine and mutation, then redirects (on `navigate`, or when the
|
|
@@ -112,8 +133,12 @@ There are no rewrites: one URL has one owner.
|
|
|
112
133
|
dimensions). With `@hozu/image` installed, pass `images: await optimizeImages(build)` to `createServer` (and
|
|
113
134
|
`hozu build` does it itself): raster assets get WebP `srcset` widths and `sizes`.
|
|
114
135
|
- **Share images:** `head.render` → `image: ui.og({ title, subtitle })` renders a 1200×630 card; pass
|
|
115
|
-
`og: ogImage` (from `@hozu/image`) to `createServer`.
|
|
136
|
+
`og: ogImage` (from `@hozu/image`) to `createServer`. On a static host, use a file instead:
|
|
137
|
+
`image: ui.asset(new URL('./share.png', import.meta.url))` (made absolute with `site.url`).
|
|
116
138
|
- **Fonts:** a local `@font-face` gets a size-matched `"<Family> Fallback"` automatically.
|
|
139
|
+
- **Page transitions:** the stylesheet turns on cross-document view transitions, so links between pages cross-fade
|
|
140
|
+
instead of flashing (no JS). Turn them off with `@view-transition { navigation: none; }` in `app.css`; style them
|
|
141
|
+
with `::view-transition-*`.
|
|
117
142
|
|
|
118
143
|
## Preview (drafts)
|
|
119
144
|
`createServer({ preview: { secret } })`; `GET /_hozu/preview?secret=…&path=/posts/a` turns preview on (a signed
|
|
@@ -136,6 +161,9 @@ Cloudflare Workers or Vercel the server is `createHandler({ build, manifest, res
|
|
|
136
161
|
`@hozu/runtime-server` with `export default { fetch: handler.fetch }`, where
|
|
137
162
|
`import * as render from './dist/server/render.js'` is the page code `hozu build` generates (edge runtimes cannot
|
|
138
163
|
generate it at startup). Page cache and tag revalidation are per instance.
|
|
164
|
+
A fully static site (GitHub Pages, any file host): `exportStatic({ build, styles, resolvers, outDir })` from
|
|
165
|
+
`@hozu/adapter-static` writes every page without per-request data, plus the files they link to, and lists skipped
|
|
166
|
+
routes.
|
|
139
167
|
```ts
|
|
140
168
|
import manifest from './dist/manifest.json' with { type: 'json' }
|
|
141
169
|
import * as render from './dist/server/render.js'
|