@nimblebrain/synapse 0.12.1 → 0.12.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/dist/ui/index.js CHANGED
@@ -331,6 +331,18 @@ var RULES3 = `
331
331
  .nb-drawer-iconbtn { min-width: 44px; min-height: 44px; }
332
332
  }
333
333
  `;
334
+ function inClosedDetails(el) {
335
+ const details = el.closest("details:not([open])");
336
+ if (!details) return false;
337
+ const summary = details.querySelector("summary");
338
+ return !summary || !summary.contains(el);
339
+ }
340
+ var CANDIDATES = "a[href], button, input, select, textarea, summary, [tabindex]";
341
+ function tabbables(panel) {
342
+ return Array.from(panel.querySelectorAll(CANDIDATES)).filter(
343
+ (el) => el.tabIndex >= 0 && !el.matches(":disabled") && !el.closest("[hidden]") && !inClosedDetails(el) && el.type !== "hidden"
344
+ );
345
+ }
334
346
  var DrawerContext = createContext(null);
335
347
  function DrawerRoot({
336
348
  open,
@@ -359,12 +371,33 @@ function DrawerRoot({
359
371
  }, [open, onEscape, onClose]);
360
372
  useEffect(() => {
361
373
  if (!open) return;
374
+ const panel = panelRef.current;
362
375
  const previouslyFocused = document.activeElement;
363
- panelRef.current?.focus();
376
+ panel?.focus();
364
377
  const { body } = document;
365
378
  const prevOverflow = body.style.overflow;
366
379
  body.style.overflow = "hidden";
380
+ const onKeyDown = (e) => {
381
+ if (e.key !== "Tab" || !panel) return;
382
+ const focusables = tabbables(panel);
383
+ if (focusables.length === 0) {
384
+ e.preventDefault();
385
+ return;
386
+ }
387
+ const first = focusables[0];
388
+ const last = focusables[focusables.length - 1];
389
+ const active = document.activeElement;
390
+ if (e.shiftKey && (active === first || active === panel)) {
391
+ e.preventDefault();
392
+ last.focus();
393
+ } else if (!e.shiftKey && active === last) {
394
+ e.preventDefault();
395
+ first.focus();
396
+ }
397
+ };
398
+ panel?.addEventListener("keydown", onKeyDown);
367
399
  return () => {
400
+ panel?.removeEventListener("keydown", onKeyDown);
368
401
  body.style.overflow = prevOverflow;
369
402
  previouslyFocused?.focus?.();
370
403
  };