Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changeset/vite-plugin-weft-css.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
'@e-cline/weft_vite_plugin': patch
---

`weft_css` styles: the plugin extracts each style file's stylesheet (running it in a module runner
of its own), strips the definitions from every bundle, and serves each sheet as a CSS module.
`weft()` puts the sheets in `virtual:weft/assets` for `weft_server`; `weftCss()` is the plugin for
an app without a server, whose modules import their sheets. In development an edit to a style
changes the stylesheet in place, with no reload. The test harness applies the head's stylesheets,
loads the others a task later (`holdStylesheets`, `releaseStylesheets`), reports what shows without
its CSS (`unstyled`), and names elements by `data-id` when they have no id.
12 changes: 12 additions & 0 deletions .changeset/weft-css.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
'@e-cline/weft_css': patch
---

A new package: styles declared in ReScript, extracted to CSS at build time. `Css.class`, `Css.var`,
`Css.keyframes` and `Css.global`, at a module's top level, take a typed record of properties (with
nested blocks, `selectors` and `media`); `ppx_weft` names each from its module and binding, and
`weft_vite_plugin` extracts each file's styles into a stylesheet of its own, leaving only the names
in the JavaScript. Classes are in the cascade layer `weft.components`, globals and variables in
`weft.base`. `Css.vars` sets variables in a `style` prop, for what changes at run time; `Css.cx`
joins class names. `Sheets.load` and `Sheets.isLoaded` load a stylesheet once per document, sharing
their state with the page's inline runtime.
7 changes: 7 additions & 0 deletions .changeset/weft-dom-stylesheets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@e-cline/weft_dom': patch
---

`Html.render ~stylesheetsOf`: a streamed segment's swap waits for the stylesheets its markup needs.
A segment inside one still waiting runs once that one is in. A new `dataId` prop writes `data-id`,
for tests to find an element by.
11 changes: 11 additions & 0 deletions .changeset/weft-server-stylesheets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
'@e-cline/weft_server': patch
---

Stylesheets: given the app's (`Page.assets`' `sheets` and `entrypointSheets`, from
`virtual:weft/assets`), `Render.toStream ~styles` sends each row the stylesheets its class names
need (`C` rows, before the row), and the decoder waits for them before a row's content shows
(`Decoder.make ~loadSheet`). A first page links the shell's stylesheets at the end of its head, held
until the shell is ready, preloads the ones the rest of the page needs, and each streamed segment
waits for its own before it's swapped in. Navigations and refetches keep the old content until the
new one's stylesheets have loaded.
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:

e2e:
# The browser tests (examples/weft_notes/e2e and examples/weft_shop/e2e), against the built apps
# in Chromium, on one Node version. Everything a browser isn't needed for is tested in the job
# in Chromium (and weft_shop's styles test in Firefox and WebKit too), on one Node version. Everything a browser isn't needed for is tested in the job
# above.
name: Browser tests
runs-on: ubuntu-latest
Expand All @@ -76,9 +76,9 @@ jobs:
- run: vp pack
working-directory: tools/weft_vite_plugin
- run: vp run build
- name: Install Chromium for Playwright
- name: Install Chromium, Firefox and WebKit for Playwright
run:
pnpm --filter @e-cline/weft_notes_example exec playwright install
--with-deps chromium
--with-deps chromium firefox webkit
- run: vp run --filter @e-cline/weft_notes_example e2e
- run: vp run --filter @e-cline/weft_shop_example e2e
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ WARNING: None of this is intended for real production use.
Weft is the UI framework in here: `weft` (components, hooks and a fiber reconciler), `weft_dom` (the
DOM renderer) and `weft_signals` (hooks for reading `signals`), plus the `weft_app` example. Server
components for it are under way: `weft_server` and `weft_vite_plugin`, with the `weft_notes`,
`weft_split` and `weft_shop` examples.
`weft_split` and `weft_shop` examples. So is CSS: `weft_css` ([its plan](docs/weft_css_plan.md)).

## Packages

Expand All @@ -24,6 +24,7 @@ components for it are under way: `weft_server` and `weft_vite_plugin`, with the
| [`@e-cline/weft`](packages/weft) | A React-like component library: `@weft.component` components and hooks, rendered by a fiber reconciler through a pluggable host renderer. |
| [`@e-cline/weft_dom`](packages/weft_dom) | The DOM renderer for `weft`: render components into a browser page. |
| [`@e-cline/weft_signals`](packages/weft_signals) | Hooks for reading `signals` atoms and computeds from `weft` components. |
| [`@e-cline/weft_css`](packages/weft_css) | Styles written in ReScript beside their components, extracted into CSS at build time, and each page sent only the CSS of what it renders. |
| [`@e-cline/weft_server`](packages/weft_server) | Server components for Weft: render on the server into a streamed payload, decode it on the client, with entrypoints loaded on demand. |
| [`@e-cline/weft_vite_plugin`](tools/weft_vite_plugin) | The Vite plugin for Weft's server components: server and client environments, an entrypoint per chunk, the boundary enforced, dev and build. |

Expand Down
Loading
Loading