ferrovue 0.2.0 → 0.4.0
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 +103 -15
- package/dist/attrs.d.ts +8 -42
- package/dist/attrs.js +148 -297
- package/dist/calls.d.ts +4 -0
- package/dist/calls.js +219 -0
- package/dist/children.d.ts +9 -0
- package/dist/children.js +273 -0
- package/dist/classes.d.ts +13 -0
- package/dist/classes.js +176 -0
- package/dist/cli.js +121 -27
- package/dist/client.d.ts +11 -2
- package/dist/client.js +45 -9
- package/dist/compiler.d.ts +4 -0
- package/dist/compiler.js +37 -90
- package/dist/component.js +19 -82
- package/dist/context.d.ts +6 -68
- package/dist/context.js +25 -38
- package/dist/diff.d.ts +1 -0
- package/dist/diff.js +68 -0
- package/dist/emitter.d.ts +0 -8
- package/dist/emitter.js +0 -12
- package/dist/expr.d.ts +0 -70
- package/dist/expr.js +30 -855
- package/dist/fallthrough.d.ts +9 -0
- package/dist/fallthrough.js +78 -0
- package/dist/fixture.d.ts +2 -1
- package/dist/fixture.js +37 -22
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/islands.d.ts +6 -0
- package/dist/islands.js +5 -0
- package/dist/lists.d.ts +0 -11
- package/dist/lists.js +4 -39
- package/dist/loops.d.ts +3 -0
- package/dist/loops.js +164 -0
- package/dist/model.d.ts +22 -130
- package/dist/model.js +37 -9
- package/dist/narrowing.d.ts +19 -0
- package/dist/narrowing.js +126 -0
- package/dist/numbers.d.ts +8 -0
- package/dist/numbers.js +73 -0
- package/dist/parens.d.ts +0 -27
- package/dist/parens.js +0 -44
- package/dist/plugin.d.ts +84 -0
- package/dist/plugin.js +26 -0
- package/dist/plugins/i18n.d.ts +23 -0
- package/dist/{i18n.js → plugins/i18n.js} +76 -19
- package/dist/plugins/index.d.ts +2 -0
- package/dist/plugins/index.js +8 -0
- package/dist/plugins/router-link.d.ts +8 -0
- package/dist/{router.js → plugins/router-link.js} +65 -57
- package/dist/plugins/router.d.ts +42 -0
- package/dist/plugins/router.js +256 -0
- package/dist/plugins/scoped.d.ts +12 -0
- package/dist/{scoped.js → plugins/scoped.js} +55 -20
- package/dist/plugins/shared-types.d.ts +2 -0
- package/dist/plugins/shared-types.js +7 -0
- package/dist/plugins/stores.d.ts +37 -0
- package/dist/plugins/stores.js +377 -0
- package/dist/plugins/teleport.d.ts +5 -0
- package/dist/plugins/teleport.js +55 -0
- package/dist/rust.d.ts +2 -5
- package/dist/rust.js +66 -161
- package/dist/script.d.ts +0 -6
- package/dist/script.js +22 -121
- package/dist/slots.d.ts +13 -0
- package/dist/slots.js +160 -0
- package/dist/strings.d.ts +13 -0
- package/dist/strings.js +208 -0
- package/dist/styles.d.ts +14 -0
- package/dist/styles.js +181 -0
- package/dist/template.d.ts +2 -40
- package/dist/template.js +40 -691
- package/dist/testing.d.ts +1 -0
- package/dist/testing.js +1 -8
- package/dist/types.d.ts +2 -0
- package/dist/typescript.d.ts +0 -13
- package/dist/typescript.js +8 -41
- package/dist/vite.d.ts +1 -0
- package/dist/vite.js +35 -14
- package/package.json +11 -2
- package/dist/i18n.d.ts +0 -27
- package/dist/router.d.ts +0 -17
- package/dist/scoped.d.ts +0 -10
- package/dist/stores.d.ts +0 -6
- package/dist/stores.js +0 -227
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ The project has two halves:
|
|
|
26
26
|
| | What it is | Published as |
|
|
27
27
|
|---|---|---|
|
|
28
28
|
| `packages/ferrovue` | The compiler and the `ferrovue` command (TypeScript, runs on Node) | npm: [`ferrovue`](https://www.npmjs.com/package/ferrovue) |
|
|
29
|
-
| `crates/ferrovue` | The runtime the generated Rust calls: escaping, slots, islands, `<RouterLink>` matching | crates.io: [`ferrovue`](https://crates.io/crates/ferrovue) ([API docs](https://docs.rs/ferrovue)) |
|
|
29
|
+
| `crates/ferrovue` | The runtime the generated Rust calls: escaping, slots, islands, `<RouterLink>` matching. The router, vue-i18n and the escaping and number primitives they share are crates of their own (`crates/ferrovue-router`, `ferrovue-i18n`, `ferrovue-core`), which `ferrovue` re-exports | crates.io: [`ferrovue`](https://crates.io/crates/ferrovue) ([API docs](https://docs.rs/ferrovue)) |
|
|
30
30
|
|
|
31
31
|
## Quick start
|
|
32
32
|
|
|
@@ -82,8 +82,11 @@ defineProps<{ name: string; unread: number; note?: string }>();
|
|
|
82
82
|
### 4. Generate and render
|
|
83
83
|
|
|
84
84
|
```sh
|
|
85
|
+
npx ferrovue init # a starter ferrovue.config.json and components/Hello.vue
|
|
85
86
|
npx ferrovue # writes src/generated/{greeting.rs, mod.rs}
|
|
86
87
|
npx ferrovue --check # in CI: exits 1 if the committed modules are stale
|
|
88
|
+
npx ferrovue --check --diff # …and shows what differs, as `diff -u` does
|
|
89
|
+
npx ferrovue --watch # regenerates when components or configs change
|
|
87
90
|
```
|
|
88
91
|
|
|
89
92
|
```rust
|
|
@@ -115,9 +118,28 @@ With `routes` configured, the generated `route_table::router()` builds the route
|
|
|
115
118
|
each request's location with `router.at(path)` and pass the result to the components that take a
|
|
116
119
|
route.
|
|
117
120
|
|
|
121
|
+
The router and vue-i18n are features of the crate, `router` and `i18n`, both on by default. An
|
|
122
|
+
application with neither routes nor translations can leave them out, and build neither
|
|
123
|
+
`ferrovue-router` nor `ferrovue-i18n`: `ferrovue = { version = "0.4", default-features = false }`.
|
|
124
|
+
|
|
118
125
|
With the `maud` feature, `ferrovue::Html` implements `maud::Render`, so `(greeting::html(&props))` can go
|
|
119
126
|
straight into a `maud::html!` page.
|
|
120
127
|
|
|
128
|
+
With the `axum` feature, `Html` is an `IntoResponse`, and with `actix-web` a `Responder`: a handler
|
|
129
|
+
responds with the component, as `text/html; charset=utf-8`. `into_html(props)` and
|
|
130
|
+
`into_island(props)` take the props by value, so a handler that builds them returns the page:
|
|
131
|
+
|
|
132
|
+
```rust
|
|
133
|
+
async fn hello(Path(name): Path<String>) -> impl IntoResponse {
|
|
134
|
+
greeting::into_html(greeting::Props::new(name, 0))
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
With the `dioxus` feature, a component goes into a Dioxus 0.7 page (`dioxus-ssr` or fullstack):
|
|
139
|
+
`{greeting::island(&props)}` in `rsx!` is the island element itself, with exactly the markup Vue
|
|
140
|
+
hydrates inside it. See `examples/dioxus` and the crate guide's
|
|
141
|
+
[Dioxus page](crates/ferrovue/docs/guide/dioxus.md).
|
|
142
|
+
|
|
121
143
|
## What a component may use
|
|
122
144
|
|
|
123
145
|
ferrovue compiles `<script setup lang="ts">` components. Props are declared by type, with
|
|
@@ -138,11 +160,12 @@ ferrovue compiles `<script setup lang="ts">` components. Props are declared by t
|
|
|
138
160
|
| `class` | strings, arrays, objects (`{ active: on }`, computed keys), `cond && "x"`, `cond ? "x" : null`, merged with a static `class` |
|
|
139
161
|
| `style` | objects (camelCase or kebab-case keys, `--custom` properties), arrays of objects, strings, merged with a static `style`, and `v-show`; later values override earlier ones as in Vue. A global `<style>` block is allowed |
|
|
140
162
|
| Scoped styles | `<style scoped>`: the id on every element, on child components' roots (a root that is itself a component, fragments, recursion and `inheritAttrs: false` as Vue renders them) and, from a component with `:slotted()` rules, on the slot content it is given, forwarded slots included; inside `<Transition>`, `<KeepAlive>`, `<Teleport>` and `v-if`; on `<RouterLink>` and what it holds, as vue-router renders them |
|
|
141
|
-
| Components | imported child components, `v-bind` of a child's own `Props`, `v-model` on a child's `defineModel`, recursion |
|
|
163
|
+
| Components | imported child components, `v-bind` of a child's own `Props`, `v-model` on a child's `defineModel`, recursion; props named in `kebab-case` or `camelCase` |
|
|
164
|
+
| Fallthrough attributes | what a parent passes a child beyond its props (static and bound attributes, `class`, `style`, `data-*`, `aria-*`, booleans, `undefined`): onto its single root, merged with the root's own class and style and replacing its other attributes where they stand, as Vue's `mergeProps` merges them; none for two roots; on through a root that is a component, or a `<RouterLink>`; with `inheritAttrs: false`, onto the elements or components that bind `v-bind="$attrs"` or a `useAttrs()` binding, before or after their own; beside scope ids. Listeners are dropped, as Vue's server drops them. See the crate's [`generated_code`](https://docs.rs/ferrovue/latest/ferrovue/guide/generated_code/index.html#fallthrough-attributes) guide |
|
|
142
165
|
| Slots | default and named slots, fallbacks, `$slots.name` tests, scoped slots (`<slot :item="x">` and `#item="{ item }"` or `v-slot="props"`), whose props a parent can hand to its own children |
|
|
143
166
|
| Forms | `v-model` on text inputs, checkboxes, radios, `<select>` and `<textarea>` (renders the initial state) |
|
|
144
167
|
| Built-ins | `<Transition>`, `<TransitionGroup>`, `<KeepAlive>`, `<Suspense>` (synchronous content), `<Teleport>` (to any target, nested, disabled: see below), `v-text`, `v-once`, `v-pre`, `v-memo`, custom directives listed in `clientDirectives` |
|
|
145
|
-
| Vue Router | `<RouterLink>` (resolved by name or imported) with a string `to` or `{ name, params, query, hash }` / `{ path, query, hash }`, `active-class`, `exact-active-class`, `aria-current-value`, `replace`; vue-router's own encoding and active-link matching, nested routes included (a parent link is active on its children's pages, exact only on its own); a history base. `useRoute()` and `$route`: `path`, `fullPath`, `hash`, `name`, `params`, and `query` (a value written once, without `=`, or repeated, exactly as vue-router parses it). `<RouterView>`, at the top and in nested route components: each takes the page it shows as a slot |
|
|
168
|
+
| Vue Router | `<RouterLink>` (resolved by name or imported) with a string `to` or `{ name, params, query, hash }` / `{ path, query, hash }`, `active-class`, `exact-active-class`, `aria-current-value`, `replace`; vue-router's own encoding and active-link matching, nested routes included (a parent link is active on its children's pages, exact only on its own); a history base. `useRoute()` and `$route`: `path`, `fullPath`, `hash`, `name`, `params`, and `query` (a value written once, without `=`, or repeated, exactly as vue-router parses it; `typeof route.query.q === "string"` narrows one to a single string). `<RouterView>`, at the top and in nested route components: each takes the page it shows as a slot |
|
|
146
169
|
| Pinia | option stores with a typed `state`, and setup stores (`defineStore(id, () => { … })`) whose returned refs are typed by `ref<T>()` or their initial literal; read through `useX()` or `storeToRefs`, in the template or in `computed`; getters that are an expression of the state, and a setup store's computeds, which may read each other |
|
|
147
170
|
| vue-i18n | `$t` and `useI18n()`'s `t` and `locale`: named and list values, plurals by vue-i18n's rule, literals, linked messages with `upper`/`lower`/`capitalize`, nested and flat keys, fallback locales, a missing key shown as itself. Messages are parsed at build time by vue-i18n's own compiler |
|
|
148
171
|
| `v-html` | only on a `TrustedHtml` prop (`import type { TrustedHtml } from "ferrovue/types"`) |
|
|
@@ -171,7 +194,18 @@ Refused at compile time, each with an error that names the construct:
|
|
|
171
194
|
- two strings that may each hold half of a surrogate pair compared, searched or joined (see
|
|
172
195
|
[Strings](#strings))
|
|
173
196
|
- `null`
|
|
197
|
+
- an attribute (`class` and `style` aside) bound to a value that may be neither a string, a number
|
|
198
|
+
nor a boolean: a list, an object, or a `route.query` value, which is an array when its key is
|
|
199
|
+
repeated. Vue's server renderer leaves the attribute out and hydration then sets it, silently;
|
|
200
|
+
join a list (`.join(",")`), or narrow a query value with `typeof route.query.q === "string"`
|
|
174
201
|
- any method call without a Rust twin
|
|
202
|
+
- a value read from `$attrs` or `useAttrs()` (`$attrs.title`), which has no type; an attribute a
|
|
203
|
+
component is passed that would reach a prop of the component (or `<RouterLink>`) its root passes it
|
|
204
|
+
on to; `$attrs` in a component that is the root of one that may be handed scope ids, where it would
|
|
205
|
+
hold them; an attribute named by a number, or bound to a `$route.query` value; a class merged by
|
|
206
|
+
`v-bind` with a string that may equal the class before it, which Vue would write once; attributes
|
|
207
|
+
passed to a component whose root is a `<Transition>` or `<KeepAlive>` around a `v-if`, which Vue's
|
|
208
|
+
server drops but its client keeps
|
|
175
209
|
|
|
176
210
|
An object prop handed to a child component is cloned. Its strings are `Cow`s, so borrowed ones
|
|
177
211
|
cost nothing to copy.
|
|
@@ -203,7 +237,8 @@ same in development and production, and do not change, nor change the generated
|
|
|
203
237
|
component's source does.
|
|
204
238
|
|
|
205
239
|
A component a parent may hand ids to has a `render_scoped(…, attrs)` beside `render`, which
|
|
206
|
-
generated parents call
|
|
240
|
+
generated parents call (for one a parent also passes attributes to, `attrs` is an `fv::Attrs`
|
|
241
|
+
holding them and the ids). A component whose outlets pass a slot scope id (`:slotted()`) takes slot
|
|
207
242
|
content that is given it: `Slot::slotted` for a slot, a third `&str` parameter for a scoped slot's
|
|
208
243
|
closure. `render`, and content from Rust, need none of it: markup written from Rust carries no ids.
|
|
209
244
|
|
|
@@ -217,7 +252,7 @@ gives the ids that other component inherits.
|
|
|
217
252
|
String methods count as JavaScript counts: in UTF-16 code units, so `"🦀".length` is 2 and
|
|
218
253
|
`"🦀 crab".slice(3)` is `"crab"`. Strings are ordered by code unit too, which puts every character
|
|
219
254
|
from U+E000 to U+FFFF after one beyond U+FFFF. Each runtime routine is held to vectors recorded from
|
|
220
|
-
JavaScript (`crates
|
|
255
|
+
JavaScript (`crates/*/tests/vectors/`).
|
|
221
256
|
|
|
222
257
|
A JavaScript string can hold half of a surrogate pair — `"🦀".slice(0, 1)`, `.charAt(1)`,
|
|
223
258
|
`.split("")` — and a Rust string cannot. ferrovue writes U+FFFD in its place, which is exactly what
|
|
@@ -286,6 +321,37 @@ let row = |out: &mut String, p: &data_list::RowSlotProps<'_>| {
|
|
|
286
321
|
data_list::render(&mut page, &props, data_list::Slots { row: Some(&row), ..Default::default() });
|
|
287
322
|
```
|
|
288
323
|
|
|
324
|
+
### Hydrating islands
|
|
325
|
+
|
|
326
|
+
`mountIslands` from `ferrovue` hydrates every `data-island` element on the page with the
|
|
327
|
+
component of that name, from the props the server wrote. With the Vite plugin, `ferrovue/islands`
|
|
328
|
+
gives it every island there is, so nothing has to be listed by hand:
|
|
329
|
+
|
|
330
|
+
```ts
|
|
331
|
+
import { hydrateState, mountIslands } from "ferrovue";
|
|
332
|
+
import islands from "ferrovue/islands"; // written by `ferrovue()` from `ferrovue/vite`
|
|
333
|
+
|
|
334
|
+
hydrateState(pinia);
|
|
335
|
+
await mountIslands(islands, { pinia, router }); // one Pinia and one router for every island
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
The islands are exactly the components that have an `island()`: those that render from their props
|
|
339
|
+
alone, as the compiler finds while it generates them. That is the only set the server can write
|
|
340
|
+
`data-island` for, so it needs no folder convention or list to keep in step, and making a component
|
|
341
|
+
an island is a matter of the server calling its `island()`. Each is keyed by its `NAME`, the file
|
|
342
|
+
name without `.vue`, which is what `data-island` carries.
|
|
343
|
+
|
|
344
|
+
Each entry is a lazy `import()`, so the bundler gives every island a chunk of its own and a page
|
|
345
|
+
fetches the code of the islands it holds and no more. `mountIslands` takes such loaders and
|
|
346
|
+
components alike, so a hand-written island can join them: `mountIslands({ ...islands, Chart })`.
|
|
347
|
+
An island whose name is not among them is left as the server rendered it, with a warning naming it
|
|
348
|
+
(`onError` to handle it otherwise), as is one whose component fails to load.
|
|
349
|
+
|
|
350
|
+
An island's `<style>` goes into its chunk too, and Vite links it only once the island's script has
|
|
351
|
+
loaded, after the server's markup is on screen. Link those stylesheets from the page up front: a
|
|
352
|
+
server reading Vite's manifest takes the `css` of the entry's `dynamicImports` as well as its own
|
|
353
|
+
(`examples/fullstack/src/assets.rs`).
|
|
354
|
+
|
|
289
355
|
### Hydrating Pinia state
|
|
290
356
|
|
|
291
357
|
```rust
|
|
@@ -293,7 +359,7 @@ ferrovue::state_script_into(&mut page, "__pinia", &stores); // a <script type=
|
|
|
293
359
|
```
|
|
294
360
|
|
|
295
361
|
```ts
|
|
296
|
-
import { hydrateState } from "ferrovue
|
|
362
|
+
import { hydrateState } from "ferrovue";
|
|
297
363
|
hydrateState(pinia); // before app.mount(): every store starts from what the server rendered
|
|
298
364
|
```
|
|
299
365
|
|
|
@@ -301,7 +367,12 @@ hydrateState(pinia); // before app.mount(): every store starts from what the ser
|
|
|
301
367
|
|
|
302
368
|
`ferrovue::hole()` is a slot whose content you write later. Render a layout with holes,
|
|
303
369
|
`split_holes` the output, and stream the pieces with each hole's content between them, in whatever
|
|
304
|
-
order the content is ready.
|
|
370
|
+
order the content is ready. With the `axum` or `actix-web` feature, `ferrovue::HtmlStream` is that
|
|
371
|
+
streamed response, from the render and a future for each hole's content:
|
|
372
|
+
|
|
373
|
+
```rust
|
|
374
|
+
let body = ferrovue::HtmlStream::new(page).hole(async move { reviews_of(&id).await });
|
|
375
|
+
```
|
|
305
376
|
|
|
306
377
|
## Performance
|
|
307
378
|
|
|
@@ -361,21 +432,37 @@ ferrovue version.
|
|
|
361
432
|
## Repository layout
|
|
362
433
|
|
|
363
434
|
```text
|
|
364
|
-
crates/ferrovue/ the Rust runtime crate
|
|
365
|
-
src/
|
|
435
|
+
crates/ferrovue/ the Rust runtime crate, which generated code calls
|
|
436
|
+
src/ a module per part (`Html`, slots, class and style, the state script,
|
|
437
|
+
strings, teleports, fallthrough attributes), each module's unit tests
|
|
438
|
+
beside it in <module>/tests.rs; lib.rs re-exports them all, and the
|
|
439
|
+
three crates below
|
|
366
440
|
tests/conformance/ components, fixtures, recorded HTML, generated Rust
|
|
367
|
-
tests/vectors/ vectors recorded from JavaScript
|
|
441
|
+
tests/vectors/ vectors recorded from JavaScript and Vue
|
|
368
442
|
tests/properties.rs property-based tests of the runtime
|
|
369
443
|
benches/ criterion benchmarks of generated renderers (see Performance)
|
|
444
|
+
crates/ferrovue-core/ escaping and JavaScript's numbers, which the other crates share
|
|
445
|
+
tests/vectors/ vectors recorded from escapeHtml, String(n), Math and toFixed
|
|
446
|
+
crates/ferrovue-router/ vue-router's matching and links (the `router` feature)
|
|
447
|
+
tests/vectors/ vectors recorded from vue-router
|
|
448
|
+
crates/ferrovue-i18n/ vue-i18n's t() (the `i18n` feature)
|
|
370
449
|
packages/ferrovue/ the compiler (npm package)
|
|
371
|
-
src/
|
|
372
|
-
src/
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
450
|
+
src/index.ts `ferrovue`: the browser API, `mountIslands`, `hydrateState` and the types
|
|
451
|
+
src/compiler.ts `ferrovue/compiler`: `generate`, `write`
|
|
452
|
+
src/component.ts, script.ts, typescript.ts
|
|
453
|
+
a `.vue` file read, <script setup>, TypeScript types
|
|
454
|
+
src/template.ts, children.ts, slots.ts, loops.ts
|
|
455
|
+
the compiled template: statements, child components, slots, v-for
|
|
456
|
+
src/expr.ts, strings.ts, numbers.ts, narrowing.ts, calls.ts, lists.ts
|
|
457
|
+
expressions: operators, strings, numbers, narrowing, calls, lists
|
|
458
|
+
src/attrs.ts, classes.ts, styles.ts, fallthrough.ts
|
|
459
|
+
attributes, class and style, attributes a parent passes on
|
|
460
|
+
src/plugin.ts the plugin interface (see CONTRIBUTING.md)
|
|
461
|
+
src/plugins/ vue-router, Pinia, vue-i18n, scoped styles, <Teleport>, shared types
|
|
376
462
|
src/rust.ts, emitter.ts the Rust source written out
|
|
377
463
|
src/cli.ts, vite.ts the `ferrovue` command and the Vite plugin
|
|
378
464
|
src/client.ts browser-side helpers: `mountIslands`, `hydrateState`
|
|
465
|
+
src/islands.ts `ferrovue/islands`, which the Vite plugin writes: every island, loaded lazily
|
|
379
466
|
src/testing.ts utilities for a project's own conformance suite
|
|
380
467
|
src/types.ts `ferrovue/types`: `TrustedHtml`, `Float`
|
|
381
468
|
test/ compiler, CLI, router, vector, island, Vite and conformance tests
|
|
@@ -384,6 +471,7 @@ packages/ferrovue/ the compiler (npm package)
|
|
|
384
471
|
fuzz/ the randomised differential tester (`pnpm fuzz`)
|
|
385
472
|
examples/greeting/ the smallest setup: one component rendered from Rust
|
|
386
473
|
examples/fullstack/ axum + Vite: islands, Pinia state, routes and streaming
|
|
474
|
+
examples/dioxus/ a Dioxus page, rendered with dioxus-ssr, with an island in it
|
|
387
475
|
scripts/release.ts the release version bump (see RELEASING.md)
|
|
388
476
|
```
|
|
389
477
|
|
package/dist/attrs.d.ts
CHANGED
|
@@ -1,51 +1,17 @@
|
|
|
1
1
|
import { type N, type Scope, type Val } from "./model.ts";
|
|
2
2
|
import { Emitter } from "./emitter.ts";
|
|
3
|
-
|
|
3
|
+
export declare function display(e: Emitter, v: Val): boolean;
|
|
4
4
|
export declare function interpolate(e: Emitter, v: Val): void;
|
|
5
|
-
/** The value half of `key="value"`, escaped. */
|
|
6
5
|
export declare function attrValue(e: Emitter, v: Val): void;
|
|
7
|
-
|
|
8
|
-
export declare function renderAttr(e: Emitter, key: string, v: Val): void;
|
|
9
|
-
/** `ssrRenderDynamicAttr(key, value)`: as `renderAttr`, but a boolean attribute is present or
|
|
10
|
-
* absent, and an empty string renders the name alone. */
|
|
6
|
+
export declare function renderAttr(s: Scope, e: Emitter, key: string, v: Val, n: N): void;
|
|
11
7
|
export declare function renderDynamicAttr(s: Scope, e: Emitter, key: string, v: Val, n: N): void;
|
|
12
|
-
/** One item of a class list once it is flattened: literal text, known now, or a Rust `&str`
|
|
13
|
-
* expression evaluated at run time — empty when the item contributes nothing. */
|
|
14
|
-
export type ClassItem = {
|
|
15
|
-
lit: string;
|
|
16
|
-
} | {
|
|
17
|
-
code: string;
|
|
18
|
-
};
|
|
19
|
-
/** `normalizeClass`'s view of a class binding, flattened: a string, an array of items, an object
|
|
20
|
-
* of `name: condition`, `cond && "name"`, `cond ? "a" : null`. Every item is trimmed and the empty
|
|
21
|
-
* ones dropped before they are joined with one space, which is what `class_into` does too, so an
|
|
22
|
-
* object's keys become items of their own. */
|
|
23
|
-
export declare function classItems(s: Scope, n: N): ClassItem[];
|
|
24
|
-
/** `ssrRenderClass(value)`: normalised, then escaped. `after` says a class was already written. */
|
|
25
|
-
export declare function renderClass(s: Scope, e: Emitter, n: N, after?: boolean): void;
|
|
26
8
|
export declare const IGNORED_PROPS: Set<string>;
|
|
27
|
-
/** `ssrGetDirectiveProps(_ctx, dir)`: a custom directive's server props, which are none for a
|
|
28
|
-
* directive the configuration declares client-only. `false` when `n` is not such a call. */
|
|
29
9
|
export declare function directiveProps(s: Scope, n: N): boolean;
|
|
30
|
-
|
|
31
|
-
|
|
10
|
+
export declare function isAttrs(n: N): boolean;
|
|
11
|
+
export declare function dollarAttrs(s: Scope, n: N): boolean;
|
|
12
|
+
export declare function mergedParts(n: N): N[];
|
|
32
13
|
export declare function renderAttrs(s: Scope, e: Emitter, n: N): void;
|
|
33
|
-
/** `mergeProps(a, _attrs, b, …)` as one object literal, without `_attrs`: it holds only scope ids,
|
|
34
|
-
* which the caller writes after the rest. Of the rest, `class` and `style` values are merged as an
|
|
35
|
-
* array, and any other key keeps the place it first had with the last value given. */
|
|
36
14
|
export declare function mergeProps(s: Scope, n: N): N;
|
|
37
|
-
|
|
38
|
-
export
|
|
39
|
-
|
|
40
|
-
entries: {
|
|
41
|
-
key: string;
|
|
42
|
-
css: string;
|
|
43
|
-
value: N;
|
|
44
|
-
}[];
|
|
45
|
-
}
|
|
46
|
-
/** The objects a style binding merges, in order: an object literal, a static `style` the compiler
|
|
47
|
-
* parsed, `v-show`'s `cond ? null : { display: "none" }`, and arrays of those. */
|
|
48
|
-
export declare function styleItems(s: Scope, n: N, when: string | null): StyleItem[];
|
|
49
|
-
/** `ssrRenderStyle(value)`: a string as it is, or the objects merged — each property where it first
|
|
50
|
-
* appears, with the last value given — and written `name:value;`, all escaped. */
|
|
51
|
-
export declare function renderStyle(s: Scope, e: Emitter, n: N): void;
|
|
15
|
+
export declare function attrEntries(s: Scope, obj: N, side: "vnode" | "own"): string[];
|
|
16
|
+
export declare function attrOf(s: Scope, key: string, n: N, side: "vnode" | "own"): string;
|
|
17
|
+
export declare function valueAttr(s: Scope, v: Val, n: N): string;
|