@panphora/bevel 0.3.0 → 0.3.2

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 CHANGED
@@ -196,7 +196,7 @@ npm run dev # build, watch and serve on :7383
196
196
  npm run preview -- modal
197
197
  ```
198
198
 
199
- `npm test` runs the original checks plus component, adapter, HTTP/SSE and snapshot regressions. The browser tests need `npx playwright install chromium` once. Run `node tests/clay-snapshot.mjs` for the documented registration against the pinned Clay snapshot fixture; full host boot and transport coverage remains separate.
199
+ `npm test` runs the original checks plus component, adapter, HTTP/SSE and snapshot regressions. The browser tests need `npm run browser:install && npx playwright install firefox webkit` once. Run `node tests/clay-snapshot.mjs` for the documented registration against the pinned Clay snapshot fixture; full host boot and transport coverage remains separate.
200
200
 
201
201
  ## License
202
202
 
package/bevel.js CHANGED
@@ -717,10 +717,10 @@
717
717
  setExpanded(root, true);
718
718
  if (!root.matches(".bevel-combobox__listbox") && (source !== "external" || !document.activeElement || document.activeElement === document.body)) {
719
719
  let interrupted = false;
720
- const interrupt = () => { interrupted = true; };
721
- document.addEventListener("keydown", interrupt, true); document.addEventListener("pointerdown", interrupt, true);
720
+ const interrupt = () => { interrupted = true; }, focusInside = event => { if (root.contains(event.target)) interrupted = true; };
721
+ document.addEventListener("keydown", interrupt, true); document.addEventListener("pointerdown", interrupt, true); document.addEventListener("focusin", focusInside, true);
722
722
  requestAnimationFrame(() => {
723
- document.removeEventListener("keydown", interrupt, true); document.removeEventListener("pointerdown", interrupt, true);
723
+ document.removeEventListener("keydown", interrupt, true); document.removeEventListener("pointerdown", interrupt, true); document.removeEventListener("focusin", focusInside, true);
724
724
  if (!interrupted) (root.querySelector("[autofocus]") || focusable(root))?.focus();
725
725
  });
726
726
  }
@@ -51,7 +51,7 @@ npm run roundtrip # playwright: change every state on the docs page, save, rel
51
51
  npm run dev # serve on :7383
52
52
  ```
53
53
 
54
- `npm test` runs the three checks. The round trip needs `npx playwright install chromium` once.
54
+ `npm test` runs the three checks. The round trip needs `npm run browser:install` once.
55
55
 
56
56
  ## License
57
57
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@panphora/bevel",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Beveled controls in an editorial page. One stylesheet, one script, no build.",
5
5
  "license": "MIT-0",
6
6
  "author": "David Miranda",
@@ -473,6 +473,7 @@
473
473
  "quickcrop:integration": "node tests/quickcrop.mjs",
474
474
  "examples:peers": "node examples/setup-peers.mjs richclay tests/fixtures/richclay && node examples/setup-peers.mjs quickcrop tests/fixtures/quickcrop && node examples/setup-peers.mjs hypercms tests/fixtures/hypercms && node examples/setup-peers.mjs clay-mutation tests/fixtures/clay-mutation",
475
475
  "predev": "npm run examples:peers",
476
+ "browser:install": "node scripts/chrome-for-testing/browser-runtime.cjs install",
476
477
  "packaged:peers": "node tests/packaged-peers.mjs",
477
478
  "upload:integration": "node tests/upload.mjs",
478
479
  "correction:c3:navigation": "node tests/correction-c3-navigation.mjs",
@@ -518,7 +519,8 @@
518
519
  "vendor:richclay": "node scripts/vendor-richclay-fixture.mjs ../richclay",
519
520
  "vendor:quickcrop": "node scripts/vendor-quickcrop-fixture.mjs ../quickcrop",
520
521
  "vendor:hypercms": "node scripts/vendor-hypercms-fixture.mjs ../hypercms ../clayjs",
521
- "prepublishOnly": "testbox run"
522
+ "prepublishOnly": "testbox run",
523
+ "build:hosted": "node scripts/build-hosted-page.mjs"
522
524
  },
523
525
  "devDependencies": {
524
526
  "@floating-ui/core": "1.8.0",
@@ -526,7 +528,7 @@
526
528
  "@fontsource-variable/newsreader": "5.3.0",
527
529
  "@fontsource/ibm-plex-mono": "5.3.0",
528
530
  "@fontsource/ibm-plex-sans": "5.3.0",
529
- "playwright": "1.62.1",
531
+ "playwright": "1.64.1",
530
532
  "@base-ui/react": "1.8.0",
531
533
  "@pierre/trees": "1.0.0-beta.6",
532
534
  "react": "19.2.8",
package/react/README.md CHANGED
@@ -64,6 +64,8 @@ Field and Form retain native name, form, reset, validity and submission behavior
64
64
 
65
65
  `AppShell.SidebarToggle` is labelled Collapse sidebar or Expand sidebar unless you pass `label`. In classic markup, `data-bevel-label-collapse` and `data-bevel-label-expand` on the `[data-bevel-shell-collapse]` button replace those two labels.
66
66
 
67
+ Base UI defaults `closeOnClick` to `false` on `Menu.RadioItem`, `Menu.CheckboxItem` and `Menu.LinkItem`, while `Menu.Item` defaults to `true`. When picking a radio item, client-routed link, download link or new-tab link should dismiss the popup instead of leaving `aria-expanded="true"` on the trigger, pass `closeOnClick` at the call site rather than changing Bevel's `Menu` wrapper, and assert in tests that the menu closed.
68
+
67
69
  ## Dialogs
68
70
 
69
71
  ```tsx
@@ -118,6 +120,8 @@ FilterBuilder edits a draft and validates before Apply. Its shared filter model
118
120
 
119
121
  Sortable uses stable string IDs and supports pointer movement and arrows/Home/End. SplitPanes uses a percentage ratio, measured pixel minimums, a keyboard separator and mobile stacking. Escape or pointer cancellation discards the preview. KanbanBoard receives ordered column card IDs and immutable card records. Its inspector, editor, checklist, archive controls and explicit Move operation use application callbacks. Filtered boards disable ambiguous dragging while preserving explicit moves. Supply `today` as an ISO date when due styling is needed. New cards, checklist items, filter rules and accepted uploads receive random UUIDs that remain independent of React tree IDs after reload.
120
122
 
123
+ In native HTML5 drag and drop (including `FileTree` and `useFileTreeOutsideDrop`), Chrome intersects the source's `effectAllowed` with the target's `dropEffect` and silently cancels the drop with `dragend.dropEffect === "none"` when they do not overlap, even after `dragover` calls `preventDefault()`. Set `dropEffect = transfer.types.includes('Files') ? 'copy' : 'move'` on the drop target instead of hardcoding one value, and verify drop wiring with real pointer input in a browser because synthetic jsdom `DataTransfer` tests skip effect negotiation.
124
+
121
125
  ## Forms, drafts and feedback
122
126
 
123
127
  `FormErrorSummary` accepts ordered `{ id, message }` errors. `nativeFormErrors(form)` collects invalid controls with stable IDs from that form. Increment `focusToken` for each failed submission to focus the summary, or pass `focus="first-field"`. Rendering existing server errors alone does not move focus. Error links retain the control's existing descriptions.
@@ -130,6 +134,10 @@ SaveStatus receives explicit clean/dirty/saving/saved/error state. A new eventKe
130
134
 
131
135
  Tooltip follows [Base UI's visual hint contract](https://base-ui.com/react/components/tooltip). Give its trigger a matching accessible name. Put essential descriptions in inline text or Popover; Tooltip.Popup does not add a tooltip role or an automatic accessible description.
132
136
 
137
+ `<Field.Error>{problem}</Field.Error>` renders nothing unless `match` is passed, because Base UI otherwise gates it on native browser validity failures and ignores custom validation state. Always render custom field errors as `<Field.Error match role="alert">{problem}</Field.Error>` so the message mounts and wires `aria-describedby`, and test validation by asserting the error is present for bad input rather than absent for good input.
138
+
139
+ A `Toast` with `priority: 'high'` sets `aria-hidden="true"` on its popup until focused, so `getByRole` queries for `dialog` or `alertdialog` find nothing even while the toast is visible on screen (`priority: 'high'` also leaves auto-dismiss unchanged, gated on timeout greater than zero). Assert high-priority toast messages through the separate `role="alert"` live region rendered by the provider.
140
+
133
141
  ## Optional integrations and recipes
134
142
 
135
143
  These entries are excluded from the root barrel and basic component graphs. They accept consumer supplied peers and do not fetch or install them.