@spaethtech/svelte-ui 0.21.1-dev.122.60c38bb → 0.21.1-dev.125.4911439
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/CLAUDE.md +19 -4
- package/docs/native-first-overlays.md +54 -0
- package/package.json +1 -1
package/CLAUDE.md
CHANGED
|
@@ -148,12 +148,27 @@ for just the library artifact.
|
|
|
148
148
|
**IMPORTANT**: Drive the running demo site when working on UI components — verify behavior in a real
|
|
149
149
|
browser, don't rely on `svelte-check` alone.
|
|
150
150
|
|
|
151
|
-
|
|
151
|
+
**The dev stack is ALWAYS running — you never cold-build the demo.** A Docker container
|
|
152
|
+
(`svelte-ui-demo-1`, `node:24`, cmd `npm run dev:linked`) runs the Vite dev server **continuously
|
|
153
|
+
with HMR**, bind-mounting this repo (`/home/rspaeth/svelte-ui -> /svelte-ui`), so every edit you save
|
|
154
|
+
here hot-reloads into the live site within seconds. So "verify in a browser" needs **no build and no
|
|
155
|
+
memory** on your part — the compile already happened and stays warm. (This sandbox is small — ~1.9 GB
|
|
156
|
+
RAM, 1 vCPU — so a *second*, cold `npm run dev`/`vite build` in here can OOM; that's why you use the
|
|
157
|
+
already-running container, not a fresh build. `npm run package` is light and is fine to run.)
|
|
158
|
+
|
|
159
|
+
Reach it without `localhost` publishing: the container exposes `5173` on the Docker network (not a
|
|
160
|
+
host port). Get its IP with `docker inspect svelte-ui-demo-1 --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'`
|
|
161
|
+
(e.g. `http://172.18.0.2:5173/<route>`), or go through Caddy at `https://svelte-ui.spaethtech.dev`
|
|
162
|
+
(`svelte-ui-caddy-1` proxies to it; `php-svelte.spaethtech.dev` → the host `:5173`). `curl` the route
|
|
163
|
+
first to confirm it serves, then point a browser at it.
|
|
152
164
|
|
|
153
165
|
Use the **`/playwright-cli`** workflow for browser-driven testing (navigation, snapshots/screenshots,
|
|
154
|
-
console inspection, interaction). Point it at the
|
|
155
|
-
|
|
156
|
-
|
|
166
|
+
console inspection, interaction). Point it at the **container IP** `:5173` and the relevant demo route
|
|
167
|
+
(e.g. `/tabstrip`). The old Chrome DevTools MCP (`.mcp.json` + `chrome-devtools-mcp`) has been removed
|
|
168
|
+
in favor of this. **Browser-binary gotcha:** the Playwright in `node_modules` and the cached browser
|
|
169
|
+
revision can mismatch (e.g. it wants `headless_shell-1181` but the cache has `chromium-1229`); pass
|
|
170
|
+
`executablePath` to the installed `~/.cache/ms-playwright/chromium-*/chrome-linux64/chrome` instead of
|
|
171
|
+
re-downloading.
|
|
157
172
|
|
|
158
173
|
### Demo pages (`src/routes/<component>/`)
|
|
159
174
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Native-first overlays — design note (Popup2 / Menu2 / Dialog2)
|
|
2
|
+
|
|
3
|
+
Status: **parked for a decision** (2026-10-24). The field-shaped native-first `*2` variants
|
|
4
|
+
(`Select2`, `Disclosure2`/`Accordion2`, `DatePicker2`) shipped; the **overlays** need a call on a
|
|
5
|
+
cross-browser tradeoff before they're worth building, because unlike the others they can't be made
|
|
6
|
+
both pixel-perfect *and* robustly no-JS today.
|
|
7
|
+
|
|
8
|
+
## Why the overlays are different
|
|
9
|
+
|
|
10
|
+
The shipped `*2` components lean on native elements that are **Baseline** and fully
|
|
11
|
+
self-positioning: `<select>`, `<details>`, `<input type=date>`. They need no placement logic — the
|
|
12
|
+
browser lays them out. `Popup`/`Menu`/`Dialog` are **anchored, top-layer overlays**: their whole job
|
|
13
|
+
is to appear *next to a trigger*, flipping/ shifting against the viewport. Today's `Popup` does both
|
|
14
|
+
halves in **JavaScript** — the Popover API for the top layer, and our `anchored` action for placement.
|
|
15
|
+
|
|
16
|
+
A no-JS rebuild would need:
|
|
17
|
+
|
|
18
|
+
1. **Toggle + top layer, no JS** — the **`popover` attribute** + a `popovertarget` button. This is
|
|
19
|
+
Baseline (2024): a `<button popovertarget="x">` opens/closes `<div popover id="x">` with
|
|
20
|
+
light-dismiss and top-layer, zero script. ✅ Solid.
|
|
21
|
+
2. **Placement next to the trigger, no JS** — **CSS anchor positioning** (`anchor-name` /
|
|
22
|
+
`position-anchor` / `position-area` / `position-try`). This is where it breaks down: Chromium has
|
|
23
|
+
it, Safari shipped it recently, **Firefox is still partial/flagged**. Without it, a `popover` opens
|
|
24
|
+
but lands in its default (centered) position — not under the button.
|
|
25
|
+
|
|
26
|
+
So a no-JS `Menu2` would toggle correctly everywhere but be **mispositioned in browsers lacking anchor
|
|
27
|
+
positioning** — the opposite of the "pixel-perfect" goal.
|
|
28
|
+
|
|
29
|
+
## Options
|
|
30
|
+
|
|
31
|
+
- **A — Progressive enhancement (recommended).** Ship `Menu2`/`Popup2` with `popover` +
|
|
32
|
+
`popovertarget` for the no-JS toggle, CSS anchor positioning for placement where supported, and a
|
|
33
|
+
sane `position-area` fallback. When JS is present (hydrated), optionally enhance with the existing
|
|
34
|
+
`anchored` engine for perfect placement everywhere. Honest caveat: no-JS placement is
|
|
35
|
+
Chromium/Safari-first until Firefox catches up. Best if php-svelte's target browsers are
|
|
36
|
+
Chromium/Safari.
|
|
37
|
+
- **B — Wait.** Hold the overlays until CSS anchor positioning is Baseline across the board, then the
|
|
38
|
+
no-JS story is clean everywhere. The field-shaped `*2` components already cover the common SSR form
|
|
39
|
+
needs (selects, disclosures, dates); menus/dialogs on a no-JS page are rarer.
|
|
40
|
+
- **C — Dialog-only now.** `Dialog2` as a `<dialog popover>` / `popover` panel is *centered* by
|
|
41
|
+
nature (a modal doesn't anchor to a trigger), so it dodges the anchor-positioning gap. A no-JS
|
|
42
|
+
"open this dialog" via `popovertarget` works cross-browser today; the modal **backdrop + focus
|
|
43
|
+
trap** still want `showModal()` (JS) for full fidelity, but a `popover` dialog is a reasonable no-JS
|
|
44
|
+
approximation. Menu/Popup stay parked.
|
|
45
|
+
|
|
46
|
+
## Recommendation
|
|
47
|
+
|
|
48
|
+
Decide between **A** (build now, Chromium/Safari-first no-JS placement, documented) and **C** (do
|
|
49
|
+
`Dialog2` now since it sidesteps anchoring, park `Menu2`/`Popup2` for **B**). Either way, `Menu2`
|
|
50
|
+
should be built on a `Popup2` primitive the same way `Menu` is built on `Popup`, and both reuse the
|
|
51
|
+
existing surface/panel classes so the open overlay stays pixel-identical to today's.
|
|
52
|
+
|
|
53
|
+
The key input needed: **which browsers must php-svelte support with JS disabled?** If it's
|
|
54
|
+
Chromium/Safari, go **A**. If Firefox-no-JS matters, go **B**/**C**.
|