@spaethtech/svelte-ui 0.21.1-dev.128.59d3487 → 0.21.1-dev.130.6593aa4
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
CHANGED
|
@@ -162,9 +162,21 @@ host port). Get its IP with `docker inspect svelte-ui-demo-1 --format '{{range .
|
|
|
162
162
|
(`svelte-ui-caddy-1` proxies to it; `php-svelte.spaethtech.dev` → the host `:5173`). `curl` the route
|
|
163
163
|
first to confirm it serves, then point a browser at it.
|
|
164
164
|
|
|
165
|
+
**For INTERACTION / HYDRATION testing, use the Caddy route `https://svelte-ui.spaethtech.dev/<route>`
|
|
166
|
+
(Playwright `ignoreHTTPSErrors: true`), NOT the container IP.** Hitting the container IP `:5173`
|
|
167
|
+
directly serves the SSR HTML but **intermittently fails to hydrate**: vite's HMR client tries
|
|
168
|
+
`ws://<ip>:443` (refused) and the route's dynamic client module then fails to fetch, so the page stays
|
|
169
|
+
SSR-only and **all client interactivity is dead** — clicks/keyboard/`bind:`/`oninput` do nothing, and a
|
|
170
|
+
Svelte `.fill()` won't propagate to bound state. This looks exactly like a component bug but isn't; it
|
|
171
|
+
bit this project's DatePicker2-reset and Tree-lazy verifications. The Caddy origin terminates TLS on
|
|
172
|
+
`:443`, so HMR + module imports load and the page hydrates reliably. Container IP is fine for
|
|
173
|
+
**SSR-only / visual** checks (screenshots of rendered markup); use Caddy whenever you click, type, or
|
|
174
|
+
assert post-hydration state. Confirm hydration first (e.g. toggle a known control and see state flip)
|
|
175
|
+
before trusting an interaction result — don't report "verified" from a page that never hydrated.
|
|
176
|
+
|
|
165
177
|
Use the **`/playwright-cli`** workflow for browser-driven testing (navigation, snapshots/screenshots,
|
|
166
|
-
console inspection, interaction). Point it at the **
|
|
167
|
-
(e.g. `/tabstrip`). The old Chrome DevTools MCP (`.mcp.json` + `chrome-devtools-mcp`) has been removed
|
|
178
|
+
console inspection, interaction). Point it at the **Caddy route** for interaction (container IP only for
|
|
179
|
+
SSR/visual) and the relevant demo route (e.g. `/tabstrip`). The old Chrome DevTools MCP (`.mcp.json` + `chrome-devtools-mcp`) has been removed
|
|
168
180
|
in favor of this. **Browser-binary gotcha:** the Playwright in `node_modules` and the cached browser
|
|
169
181
|
revision can mismatch (e.g. it wants `headless_shell-1181` but the cache has `chromium-1229`); pass
|
|
170
182
|
`executablePath` to the installed `~/.cache/ms-playwright/chromium-*/chrome-linux64/chrome` instead of
|
|
@@ -23,7 +23,10 @@
|
|
|
23
23
|
children,
|
|
24
24
|
...rest
|
|
25
25
|
}: {
|
|
26
|
-
items
|
|
26
|
+
/** The menu items — a static list, OR a function of the triggering event so one wrapper can build
|
|
27
|
+
* the menu from whatever was right-clicked (read `event.target`, a row's `data-key`, …) without
|
|
28
|
+
* the consumer tracking target state during the bubble. Return `[]` to suppress the menu. */
|
|
29
|
+
items: MenuItem[] | ((event: MouseEvent) => MenuItem[]);
|
|
27
30
|
size?: Responsive<Size>;
|
|
28
31
|
variant?: Variant;
|
|
29
32
|
disabled?: boolean;
|
|
@@ -35,10 +38,14 @@
|
|
|
35
38
|
let anchorEl = $state<HTMLElement>();
|
|
36
39
|
let x = $state(0);
|
|
37
40
|
let y = $state(0);
|
|
41
|
+
// The items shown for the current open — a snapshot (for the function form, computed from the event).
|
|
42
|
+
let resolvedItems = $state<MenuItem[]>([]);
|
|
38
43
|
|
|
39
44
|
function onContextMenu(e: MouseEvent) {
|
|
40
45
|
if (disabled) return;
|
|
41
46
|
e.preventDefault();
|
|
47
|
+
resolvedItems = typeof items === "function" ? items(e) : items;
|
|
48
|
+
if (!resolvedItems?.length) return; // nothing to show → don't open (and let no empty menu flash)
|
|
42
49
|
x = e.clientX;
|
|
43
50
|
y = e.clientY;
|
|
44
51
|
open = true;
|
|
@@ -57,4 +64,4 @@
|
|
|
57
64
|
style="position: fixed; left: {x}px; top: {y}px; width: 0; height: 0; pointer-events: none;"
|
|
58
65
|
></span>
|
|
59
66
|
|
|
60
|
-
<Menu anchor={anchorEl} bind:open {
|
|
67
|
+
<Menu anchor={anchorEl} bind:open items={resolvedItems} {size} {variant} side="bottom" align="start" />
|
|
@@ -5,7 +5,10 @@ import type { Variant } from "../../types/variants.js";
|
|
|
5
5
|
import type { Size } from "../../types/sizes.js";
|
|
6
6
|
import type { Responsive } from "../../types/responsive.js";
|
|
7
7
|
type $$ComponentProps = {
|
|
8
|
-
items
|
|
8
|
+
/** The menu items — a static list, OR a function of the triggering event so one wrapper can build
|
|
9
|
+
* the menu from whatever was right-clicked (read `event.target`, a row's `data-key`, …) without
|
|
10
|
+
* the consumer tracking target state during the bubble. Return `[]` to suppress the menu. */
|
|
11
|
+
items: MenuItem[] | ((event: MouseEvent) => MenuItem[]);
|
|
9
12
|
size?: Responsive<Size>;
|
|
10
13
|
variant?: Variant;
|
|
11
14
|
disabled?: boolean;
|
package/docs/components.md
CHANGED
|
@@ -840,8 +840,11 @@ Vertical event sequence — marker + connecting line + title/time/description.
|
|
|
840
840
|
Right-click menu over any content; opens `Menu` at the pointer.
|
|
841
841
|
|
|
842
842
|
- **Location**: `src/lib/components/ContextMenu/ContextMenu.svelte`
|
|
843
|
-
- **Props**: `items` (`MenuItem[]`
|
|
844
|
-
`children` (the right-clickable content)
|
|
843
|
+
- **Props**: `items` (`MenuItem[]` **or** `(event: MouseEvent) => MenuItem[]`), `size`, `variant`,
|
|
844
|
+
`disabled` (leaves the native menu), `class`, `children` (the right-clickable content)
|
|
845
|
+
- **Dynamic items**: pass a function to build the menu from whatever was right-clicked — read
|
|
846
|
+
`event.target` (e.g. a row's `data-key`) and return that target's items; return `[]` to suppress the
|
|
847
|
+
menu. Lets one wrapper serve many targets (e.g. a `Tree`/file list) without tracking target state.
|
|
845
848
|
- **Composition**: `Menu` anchored to a 0-size point at the pointer; flips/shifts at edges
|
|
846
849
|
|
|
847
850
|
### Tree
|