@knpkv/rly 0.14.0 → 0.15.0

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.
Files changed (45) hide show
  1. package/README.md +51 -3
  2. package/dist/{Dialog-B9Ub_gMT.js → Dialog-CU66FqWD.js} +325 -257
  3. package/dist/Dialog-CU66FqWD.js.map +1 -0
  4. package/dist/{PortalProvider-CN_81Fy3.js → PortalProvider-op07u8na.js} +20 -18
  5. package/dist/PortalProvider-op07u8na.js.map +1 -0
  6. package/dist/components.css +1 -1
  7. package/dist/dts/foundations/Icon.d.ts +1 -1
  8. package/dist/dts/foundations/Icon.d.ts.map +1 -1
  9. package/dist/dts/internal/composedFocus.d.ts +11 -0
  10. package/dist/dts/internal/composedFocus.d.ts.map +1 -0
  11. package/dist/dts/internal/relaySummon.d.ts +50 -0
  12. package/dist/dts/internal/relaySummon.d.ts.map +1 -0
  13. package/dist/dts/patterns/RelayComposer.d.ts +65 -0
  14. package/dist/dts/patterns/RelayComposer.d.ts.map +1 -0
  15. package/dist/dts/patterns/RelayDock.d.ts.map +1 -1
  16. package/dist/dts/patterns/RelayLauncher.d.ts +32 -1
  17. package/dist/dts/patterns/RelayLauncher.d.ts.map +1 -1
  18. package/dist/dts/patterns/RelayPanel.d.ts +91 -0
  19. package/dist/dts/patterns/RelayPanel.d.ts.map +1 -0
  20. package/dist/dts/patterns/index.d.ts +6 -2
  21. package/dist/dts/patterns/index.d.ts.map +1 -1
  22. package/dist/dts/tokens/fonts.d.ts +13 -0
  23. package/dist/dts/tokens/fonts.d.ts.map +1 -0
  24. package/dist/dts/tokens/index.d.ts +2 -0
  25. package/dist/dts/tokens/index.d.ts.map +1 -1
  26. package/dist/fonts.css +7 -2
  27. package/dist/foundations/index.js +1 -1
  28. package/dist/index.js +6 -6
  29. package/dist/patterns/index.js +2 -2
  30. package/dist/{patterns-ChmGSFqO.js → patterns-CDBnXTUD.js} +1705 -1280
  31. package/dist/patterns-CDBnXTUD.js.map +1 -0
  32. package/dist/primitives/index.js +3 -3
  33. package/dist/{primitives-Bd6WhE78.js → primitives-DgQybTyq.js} +254 -322
  34. package/dist/primitives-DgQybTyq.js.map +1 -0
  35. package/dist/tokens/index.js +2 -2
  36. package/dist/{tokens-B075JP3Z.js → tokens-Cf0jXIRg.js} +14 -8
  37. package/dist/tokens-Cf0jXIRg.js.map +1 -0
  38. package/package.json +1 -1
  39. package/registry/components.json +206 -1
  40. package/registry/search.json +45 -0
  41. package/dist/Dialog-B9Ub_gMT.js.map +0 -1
  42. package/dist/PortalProvider-CN_81Fy3.js.map +0 -1
  43. package/dist/patterns-ChmGSFqO.js.map +0 -1
  44. package/dist/primitives-Bd6WhE78.js.map +0 -1
  45. package/dist/tokens-B075JP3Z.js.map +0 -1
package/README.md CHANGED
@@ -31,7 +31,10 @@ Import the global layers once at the application boundary:
31
31
  @import "@knpkv/rly/styles.css";
32
32
  ```
33
33
 
34
- The stylesheet contains self-hosted Geist and Geist Mono variable fonts,
34
+ The stylesheet contains self-hosted Geist and Geist Mono variable fonts (with
35
+ `font-display: optional`: preload each file in `RLY_FONT_FACES` from your own
36
+ origin with `crossorigin`, and Geist renders from first paint; a late face keeps
37
+ the metric-matched fallback for that page view rather than swapping),
35
38
  semantic `light-dark()` color pairs, typography, spacing, shape, motion, a
36
39
  scoped reset, and base styles. Set `data-theme="light|dark|system"` on the rly
37
40
  root; system is the default. Forced colors and reduced motion are handled
@@ -466,10 +469,55 @@ the platform) only when the host binds that key and prevents the browser's own C
466
469
  or `null` where it binds none, such as a live terminal that keeps its chords.
467
470
  The hint hides at 40rem and below, and the button is 32px tall, 44px for a coarse pointer.
468
471
 
472
+ `RelayComposer` is Relay's message box: it grows with its text up to 12 lines or 40%
473
+ of the viewport, Enter adds a line and Ctrl/⌘+Enter sends (said beside Send), and an
474
+ IME composition never sends. Context refs are removable chips. One `preset` slot holds
475
+ the run preset. Stop appears only when the host passes `onStop`. While `busyReason` is
476
+ set, Send stays focusable and announces why it is unavailable. `useRelayDraft(objectKey, { newRequestId })`
477
+ keeps the draft per object (the JSON ObjectRef) for the page, so closing, reopening or
478
+ resizing Relay keeps it and one object's draft never sends as another's; pass
479
+ `storage: () => sessionStorage` to survive a reload (never localStorage). Its
480
+ `submission()` reuses one request id until the text changes, so a retry after an
481
+ uncertain outcome is deduplicated; call `accepted(requestId)` once the server accepts
482
+ that request, which clears the draft unless the user has typed since.
483
+
484
+ `RelayPanel` is Relay's frame: header (mark, title, exact scope with the revision in
485
+ mono, an optional pin, options, close), tabs whose counts are part of their names, a
486
+ freshness line, a body, and a footer for the composer. Only the body scrolls, so the
487
+ composer never leaves the screen. `overlay` floats over the right of the page with
488
+ no backdrop and no focus trap; render it right after the launcher so Tab order
489
+ follows. `pinned` is a sticky column for the host's grid, and `fullscreen` is a modal
490
+ dialog with the page inert. Escape and the close button call `onClose` and return
491
+ focus to the launcher; closing hides Relay in every presentation, and whether it was
492
+ pinned stays the host's remembered preference. `useRelayPresentation({ pinned,
493
+ minHostWidth })` picks the presentation: full screen at 640 CSS px and narrower,
494
+ pinned only when the user pinned it at 1440 and up with the host's minimum beside the
495
+ 440px column, otherwise the overlay. Hosts set `--rly-relay-panel-offset` to their
496
+ sticky header's height and `--app-bottom-inset` to any bar docked at the bottom.
497
+ Full screen portals through `PortalProvider`, so render Relay inside one, and set
498
+ `interactive-widget=resizes-content` in the viewport meta so the full-screen footer
499
+ stays above a phone's on-screen keyboard.
500
+
501
+ `useRelaySummon` binds that shortcut. From the page it opens Relay and focuses the composer (or, if
502
+ Relay is already open, moves focus to the composer); from inside Relay it takes focus back to where it
503
+ came from, and Relay stays open. Full screen, it closes Relay. Escape closes Relay when focus is inside
504
+ it or Relay is full screen, and returns focus. Only the exact chord is handled and prevented, so Ctrl+K,
505
+ `?`, g-sequences and Alt keys reach the host. On a non-Latin layout the physical J key works; a Latin
506
+ layout uses the J the user sees. Escape is left to an IME composition and to a dialog, listbox or menu
507
+ open inside or opened from Relay, including inside shadow roots. When the element Relay came from is
508
+ gone, focus returns to the `launcher`; after a close, focus returns once Relay has actually closed.
509
+ Attach the returned `regionRef` to Relay's region and `composerRef` to the composer, which is focused
510
+ as soon as it mounts. The hook follows Relay into another document (an iframe portal). Pass the same
511
+ `shortcut` the launcher advertises, or `null` while the host's own surface owns the key; Escape inside
512
+ Relay works either way.
513
+
469
514
  ```tsx
470
- import { RelayLauncher, useRelayShortcut } from "@knpkv/rly/patterns"
515
+ import { RelayLauncher, useRelayShortcut, useRelaySummon } from "@knpkv/rly/patterns"
516
+
517
+ ;const shortcut = useRelayShortcut()
518
+ const { composerRef, regionRef } = useRelaySummon({ fullscreen: false, launcher, onOpenChange: setOpen, open, shortcut })
471
519
 
472
- ;<RelayLauncher expanded={open} onClick={() => setOpen((value) => !value)} shortcut={useRelayShortcut()} />
520
+ <RelayLauncher expanded={open} onClick={() => setOpen((value) => !value)} ref={launcher} shortcut={shortcut} />
473
521
  ```
474
522
 
475
523
  `RelayDock` is the shared product frame for one adapter-owned Relay thread. It