You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: trim deeply-technical implementation detail from pitch pages
The "For X teams/shops" pages are persuasive intros aimed at framework
users who haven't adopted Rozie yet. Mid-pitch detours into compiler
implementation (verbatim emit dumps, per-target lowering catalogs,
modifier-grammar caveats) break the pacing — the reader has been told
"Rozie handles this for you", then handed twenty lines of the handler.
- `for-react-teams.md` — drop the `useControllableState` emit dump; the
pitch is the consumer code, not the compiler's controllable-state
glue. Strip "the compiler walks the auto-tracked signal reads inside
$onMount, $watch, and <listeners> blocks" from the exhaustive-deps
paragraph — landing the result without the internals.
- `for-angular-shops.md` — drop the verbatim `rozie-out SearchInput
angular` reassurance block (the contrast is already made by the
upstream "what Angular shops typically write" handwritten block);
link to the example page instead. Lighten the "Not in v1" caveats
list (modifier valueTransform, $watch ordering, TS floor) into a
one-paragraph "Documented edges" pointer to /parity + /compatibility.
- `for-lit-teams.md` — replace the inline `@property/repeat/html`
bridge emit example with the consumer-side fill; replace the
long-form "Note the canonical Lit shape: @CustomElement decorator,
SignalWatcher(LitElement) from @lit-labs/preact-signals, @Property
decorators, rozieSpread directive…" paragraph with a one-sentence
"canonical LitElement subclass" summary plus a link out. Compress
the "Documented edges" three-bullet caveats block into a single
pointer paragraph.
- `for-vanilla-js-shops.md` — soften the per-target-lowering catalog
in "compiler invariants" (drop `this._ref__rozieRoot` on Lit,
`getCurrentInstance()?.vnode.el` on Vue, per-target reactive-primitive
listing) — the reader doesn't need the implementation-name receipt to
trust the claim. Strip the CI test-path internals
(`packages/core/tests/engine-examples.compile.test.ts — 14 × 6 = 84`)
in favor of a plain claim.
Verified: docs build clean. Net -70 lines.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/guide/for-lit-teams.md
+17-59Lines changed: 17 additions & 59 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,58 +22,20 @@ Lit's `<slot>` element projects light-DOM children into shadow DOM by name. It d
22
22
23
23
Community workarounds: serialize params as JSON into `data-*` attributes, hand-roll a "fillSlot" property API, or expose imperative methods the consumer queries. Each is a bespoke surface in every Lit component.
24
24
25
-
Rozie's compiler emits the canonical version of one of these (the typed property-fill bridge) on your behalf:
Same authoring shape as a Vue scoped slot. Same emitted compose surface as a hand-rolled Lit fill-API. Zero boilerplate either side.
35
+
Same authoring shape as a Vue scoped slot. Same emitted compose surface as
36
+
a hand-rolled Lit fill-API. Zero boilerplate either side. Plain-HTML
37
+
consumers fill the slot via the corresponding `.row=${(scope) => html`…`}`
38
+
property splice — fully typed off the producer's `.d.ts`.
77
39
78
40
### Consumer CSS doesn't reach into shadow DOM
79
41
@@ -127,19 +89,15 @@ Rozie's compile-time dispatch handles dynamic slot names on every target includi
127
89
128
90
## What you write vs. what Lit sees
129
91
130
-
The canonical `examples/SearchInput.rozie` compiles to a working Lit Web Component. Below is the source + the verbatim Lit emit produced by `@rozie/core` on every docs build.
131
-
132
-
### The Rozie source
92
+
The canonical `examples/SearchInput.rozie` compiles to a working Lit Web Component:
133
93
134
94
```rozie-src SearchInput
135
95
```
136
96
137
-
### What the Rozie compiler emits for the `lit` target
138
-
139
-
```rozie-out SearchInput lit
140
-
```
141
-
142
-
Note the canonical Lit shape: `@customElement('rozie-search-input')` decorator, `SignalWatcher(LitElement)` from `@lit-labs/preact-signals` for reactivity, `@property` decorators on each declared prop (with `reflect: true` where appropriate), `render()` returning a lit-html template, paired `disconnectedCallback()` cleanup. The `rozieSpread` and `rozieListeners` directives are tiny runtime helpers (~30 LOC each) that handle attribute fallthrough and listener fallthrough at lit-html part level — the same machinery your hand-written components would replicate.
97
+
The compiled output is a canonical `LitElement` subclass — `@customElement`
98
+
decorator, `@property`-declared reactive properties, `render()` returning a
99
+
lit-html template, paired `disconnectedCallback()` cleanup. See the
100
+
[SearchInput example page](/examples/search-input) for the full Lit emit.
143
101
144
102
The compiled file is a valid, ready-to-`customElements.define`, fully-typed Lit component. You import it like any Web Component:
145
103
@@ -214,11 +172,11 @@ Three audiences in particular:
214
172
215
173
## Documented edges
216
174
217
-
The Lit target has a few v1 edges, documented in the [Cross-Framework Parity](/parity) page:
218
-
219
-
-**Scoped-slot params transport via a property-fill bridge** (vs. native template slots on the other targets). Same authoring shape via the `<template #name="{ … }">` syntax; the bridge is invisible to authors. The bridge uses `data-rozie-s-<hash>` scoping for consumer-CSS reach (documented above).
220
-
-**`$onMount` /`$onUnmount` on always-rendered components**: see [the parity note](/parity#lit-solid-—-lifecycle-hooks-colocated-with-an-always-rendered-component) — `connectedCallback` / `disconnectedCallback` semantics differ from React `useEffect`-style mount/unmount in edge cases (a component that's removed from the DOM and re-attached fires both, where React's mount-once contract holds across StrictMode but breaks across portal-detach-and-reattach).
221
-
-**Engine DOM mutation** needs `$reconcileAfterDomMutation()` — documented escape hatch.
175
+
A few small Lit-target edges (scoped-slot params travel via a property-fill
176
+
bridge rather than native template slots; `$onMount` / `$onUnmount` timing
177
+
on always-rendered components differs slightly from React; engine DOM
178
+
mutation needs the`$reconcileAfterDomMutation()` escape hatch) are
Copy file name to clipboardExpand all lines: docs/guide/for-react-teams.md
+3-17Lines changed: 3 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -132,11 +132,11 @@ CSS Modules hashes class names at build time. That means any code that reference
132
132
133
133
### Statically-computed `useEffect` dep arrays
134
134
135
-
`eslint-plugin-react-hooks/exhaustive-deps` is the lint rule everyone respects and quietly hates. With Rozie, you don't write the dep array — the compiler walks the auto-tracked signal reads inside `$onMount`, `$watch`, and `<listeners>` blocks and emits the correct array. Every reference example passes `exhaustive-deps` cleanly on output.
135
+
`eslint-plugin-react-hooks/exhaustive-deps` is the lint rule everyone respects and quietly hates. With Rozie, you don't write the dep array — the compiler emits the correct one from the lifecycle hook's body. Output passes `exhaustive-deps` cleanly.
136
136
137
137
### StrictMode double-fire safety
138
138
139
-
`$onMount` returning a cleanup function lowers to one `useEffect` with a cleanup return — the canonical React 18 StrictMode-safe pattern. All reference examples + engine-wrapper demos validated under `<React.StrictMode>`.
139
+
`$onMount` returning a cleanup function lowers to one `useEffect` with a cleanup return — the canonical React 18 StrictMode-safe pattern.
140
140
141
141
### Static error on prop mutation
142
142
@@ -150,21 +150,7 @@ The single most common React-component bug class (mutating a prop instead of cal
150
150
151
151
### Two-way binding that doesn't require a state-management library
152
152
153
-
The React `useControllableState` pattern lives in every component library that does headlessly-controllable components (Radix, Headless UI, React Aria, etc.) — each implementation is a hand-rolled bit of glue. Rozie compiles `model: true` to the canonical hybrid:
The React `useControllableState` pattern lives in every component library that does headlessly-controllable components (Radix, Headless UI, React Aria) — each one re-implements the same glue. Declare `model: true` on a `<props>` member and Rozie emits the canonical controllable-state pair for you. Consumer code stays vanilla React:
0 commit comments