@typed/ui 1.0.0-beta.1 → 1.0.0-beta.11

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 (155) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +54 -10
  3. package/dist/Alert.d.ts +72 -0
  4. package/dist/Alert.d.ts.map +1 -0
  5. package/dist/Alert.js +40 -0
  6. package/dist/Button.d.ts +100 -0
  7. package/dist/Button.d.ts.map +1 -0
  8. package/dist/Button.js +42 -0
  9. package/dist/Carousel.d.ts +346 -0
  10. package/dist/Carousel.d.ts.map +1 -0
  11. package/dist/Carousel.js +264 -0
  12. package/dist/Checkbox.d.ts +168 -0
  13. package/dist/Checkbox.d.ts.map +1 -0
  14. package/dist/Checkbox.js +146 -0
  15. package/dist/Collection.d.ts +254 -0
  16. package/dist/Collection.d.ts.map +1 -0
  17. package/dist/Collection.js +218 -0
  18. package/dist/Combobox.d.ts +367 -0
  19. package/dist/Combobox.d.ts.map +1 -0
  20. package/dist/Combobox.js +300 -0
  21. package/dist/Composite.d.ts +823 -0
  22. package/dist/Composite.d.ts.map +1 -0
  23. package/dist/Composite.js +615 -0
  24. package/dist/Dialog.d.ts +544 -0
  25. package/dist/Dialog.d.ts.map +1 -0
  26. package/dist/Dialog.js +357 -0
  27. package/dist/Disclosure.d.ts +219 -0
  28. package/dist/Disclosure.d.ts.map +1 -0
  29. package/dist/Disclosure.js +128 -0
  30. package/dist/Dom/Events.d.ts +122 -0
  31. package/dist/Dom/Events.d.ts.map +1 -0
  32. package/dist/Dom/Events.js +192 -0
  33. package/dist/Dom/Props.d.ts +161 -0
  34. package/dist/Dom/Props.d.ts.map +1 -0
  35. package/dist/Dom/Props.js +110 -0
  36. package/dist/Dom/Refs.d.ts +58 -0
  37. package/dist/Dom/Refs.d.ts.map +1 -0
  38. package/dist/Dom/Refs.js +61 -0
  39. package/dist/Dom/Render.d.ts +59 -0
  40. package/dist/Dom/Render.d.ts.map +1 -0
  41. package/dist/Dom/Render.js +71 -0
  42. package/dist/Dom/Types.d.ts +570 -0
  43. package/dist/Dom/Types.d.ts.map +1 -0
  44. package/dist/Dom/Types.js +1 -0
  45. package/dist/Dom/index.d.ts +20 -0
  46. package/dist/Dom/index.d.ts.map +1 -0
  47. package/dist/Dom/index.js +8 -0
  48. package/dist/Dom.d.ts +14 -0
  49. package/dist/Dom.d.ts.map +1 -0
  50. package/dist/Dom.js +13 -0
  51. package/dist/Focusable.d.ts +85 -0
  52. package/dist/Focusable.d.ts.map +1 -0
  53. package/dist/Focusable.js +35 -0
  54. package/dist/Form.d.ts +1727 -0
  55. package/dist/Form.d.ts.map +1 -0
  56. package/dist/Form.js +1142 -0
  57. package/dist/Grid.d.ts +388 -0
  58. package/dist/Grid.d.ts.map +1 -0
  59. package/dist/Grid.js +284 -0
  60. package/dist/Group.d.ts +128 -0
  61. package/dist/Group.d.ts.map +1 -0
  62. package/dist/Group.js +71 -0
  63. package/dist/Heading.d.ts +87 -0
  64. package/dist/Heading.d.ts.map +1 -0
  65. package/dist/Heading.js +58 -0
  66. package/dist/Hovercard.d.ts +297 -0
  67. package/dist/Hovercard.d.ts.map +1 -0
  68. package/dist/Hovercard.js +188 -0
  69. package/dist/HttpRouter.d.ts +129 -6
  70. package/dist/HttpRouter.d.ts.map +1 -1
  71. package/dist/HttpRouter.js +198 -55
  72. package/dist/Link.d.ts +63 -28
  73. package/dist/Link.d.ts.map +1 -1
  74. package/dist/Link.js +84 -37
  75. package/dist/Listbox.d.ts +305 -0
  76. package/dist/Listbox.d.ts.map +1 -0
  77. package/dist/Listbox.js +245 -0
  78. package/dist/Menu.d.ts +663 -0
  79. package/dist/Menu.d.ts.map +1 -0
  80. package/dist/Menu.js +569 -0
  81. package/dist/Menubar.d.ts +249 -0
  82. package/dist/Menubar.d.ts.map +1 -0
  83. package/dist/Menubar.js +207 -0
  84. package/dist/Meter.d.ts +157 -0
  85. package/dist/Meter.d.ts.map +1 -0
  86. package/dist/Meter.js +87 -0
  87. package/dist/NativeDetails.d.ts +41 -0
  88. package/dist/NativeDetails.d.ts.map +1 -0
  89. package/dist/NativeDetails.js +40 -0
  90. package/dist/NativeDialog.d.ts +66 -0
  91. package/dist/NativeDialog.d.ts.map +1 -0
  92. package/dist/NativeDialog.js +88 -0
  93. package/dist/NativePopover.d.ts +43 -0
  94. package/dist/NativePopover.d.ts.map +1 -0
  95. package/dist/NativePopover.js +84 -0
  96. package/dist/Popover.d.ts +240 -0
  97. package/dist/Popover.d.ts.map +1 -0
  98. package/dist/Popover.js +140 -0
  99. package/dist/RadioGroup.d.ts +330 -0
  100. package/dist/RadioGroup.d.ts.map +1 -0
  101. package/dist/RadioGroup.js +241 -0
  102. package/dist/Role.d.ts +64 -0
  103. package/dist/Role.d.ts.map +1 -0
  104. package/dist/Role.js +27 -0
  105. package/dist/Select.d.ts +418 -0
  106. package/dist/Select.d.ts.map +1 -0
  107. package/dist/Select.js +357 -0
  108. package/dist/Separator.d.ts +58 -0
  109. package/dist/Separator.d.ts.map +1 -0
  110. package/dist/Separator.js +32 -0
  111. package/dist/Slider.d.ts +141 -0
  112. package/dist/Slider.d.ts.map +1 -0
  113. package/dist/Slider.js +101 -0
  114. package/dist/SpinButton.d.ts +141 -0
  115. package/dist/SpinButton.d.ts.map +1 -0
  116. package/dist/SpinButton.js +101 -0
  117. package/dist/Storybook.d.ts +76 -0
  118. package/dist/Storybook.d.ts.map +1 -0
  119. package/dist/Storybook.js +102 -0
  120. package/dist/Switch.d.ts +148 -0
  121. package/dist/Switch.d.ts.map +1 -0
  122. package/dist/Switch.js +110 -0
  123. package/dist/Tab.d.ts +26 -0
  124. package/dist/Tab.d.ts.map +1 -0
  125. package/dist/Tab.js +25 -0
  126. package/dist/Tabs.d.ts +411 -0
  127. package/dist/Tabs.d.ts.map +1 -0
  128. package/dist/Tabs.js +262 -0
  129. package/dist/Toolbar.d.ts +248 -0
  130. package/dist/Toolbar.d.ts.map +1 -0
  131. package/dist/Toolbar.js +187 -0
  132. package/dist/Tooltip.d.ts +296 -0
  133. package/dist/Tooltip.d.ts.map +1 -0
  134. package/dist/Tooltip.js +172 -0
  135. package/dist/Tree.d.ts +405 -0
  136. package/dist/Tree.d.ts.map +1 -0
  137. package/dist/Tree.js +333 -0
  138. package/dist/TreeGrid.d.ts +426 -0
  139. package/dist/TreeGrid.d.ts.map +1 -0
  140. package/dist/TreeGrid.js +308 -0
  141. package/dist/VisuallyHidden.d.ts +68 -0
  142. package/dist/VisuallyHidden.d.ts.map +1 -0
  143. package/dist/VisuallyHidden.js +44 -0
  144. package/dist/WindowSplitter.d.ts +336 -0
  145. package/dist/WindowSplitter.d.ts.map +1 -0
  146. package/dist/WindowSplitter.js +305 -0
  147. package/dist/index.d.ts +48 -0
  148. package/dist/index.d.ts.map +1 -1
  149. package/dist/index.js +48 -0
  150. package/package.json +48 -20
  151. package/src/HttpRouter.test.ts +0 -294
  152. package/src/HttpRouter.ts +0 -168
  153. package/src/Link.test.ts +0 -84
  154. package/src/Link.ts +0 -107
  155. package/src/index.ts +0 -2
package/dist/Link.d.ts CHANGED
@@ -1,36 +1,71 @@
1
- import * as Effect from "effect/Effect";
2
1
  import type { Scope } from "effect/Scope";
3
- import type { Stream } from "effect/Stream";
4
- import { type Fx } from "@typed/fx/Fx";
5
- import { EventHandler, type Renderable, type RenderEvent, type RenderTemplate } from "@typed/template";
6
- type EventHandlerProperty = `on${string}`;
7
- type AnchorEventHandlers = {
8
- readonly [K in keyof HTMLAnchorElement as K extends EventHandlerProperty ? K : never]?: Effect.Effect<unknown, any, any> | EventHandler.EventHandler<Event, any, any>;
9
- };
10
- type AnchorRef = {
11
- readonly ref?: (element: HTMLAnchorElement) => void | Effect.Effect<unknown, any, any> | Stream<unknown, any, any> | Fx<unknown, any, any>;
12
- };
13
- type IfEquals<X, Y, Output> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? Output : never;
14
- type WritableKeys<T> = {
15
- [P in keyof T]-?: IfEquals<{
16
- [Q in P]: T[P];
17
- }, {
18
- -readonly [Q in P]: T[P];
19
- }, P>;
20
- }[keyof T];
21
- type AnchorProperties = {
22
- readonly [K in WritableKeys<HTMLAnchorElement> as K extends EventHandlerProperty | "ref" ? never : K]?: Renderable<HTMLAnchorElement[K], any, any>;
23
- };
24
- export interface LinkOptions extends AnchorEventHandlers, AnchorRef, AnchorProperties {
2
+ import * as Fx from "@typed/fx/Fx";
3
+ import { type NavigationError, Navigation } from "@typed/navigation";
4
+ import { type Renderable, type RenderEvent, type RenderTemplate } from "@typed/template";
5
+ import * as Dom from "./Dom.js";
6
+ import type { HostResult } from "./Dom/Types.js";
7
+ /**
8
+ * Native anchor options plus Typed navigation behavior.
9
+ *
10
+ * @remarks
11
+ * `href` and content remain renderable, while `replace` selects history policy.
12
+ * Ordinary anchor options—including target, download, rel, and user click
13
+ * handlers—stay available through the DOM host model.
14
+ * @since 1.0.0
15
+ * @category Component options
16
+ */
17
+ export type LinkOptions = Dom.HostOptions<HTMLAnchorElement> & {
25
18
  readonly href: Renderable<string, any, any>;
26
19
  readonly content: Renderable<string | number | boolean | null | undefined | void | RenderEvent, any, any>;
27
20
  readonly replace?: boolean;
28
- }
21
+ };
22
+ type LinkError<Options extends object> = Renderable.ErrorFromObject<Options> | NavigationError;
23
+ type LinkServices<Options extends object> = Renderable.ServicesFromObject<Options> | Navigation | Scope | RenderTemplate;
29
24
  /**
30
- * Renders an `<a href="...">` that intercepts same-origin, same-document clicks
31
- * and navigates via `Navigation.navigate` instead of full page load. Requires
32
- * `Navigation` and `RenderTemplate` in the Effect context (e.g. `BrowserRouter`).
25
+ * Renders a native anchor with safe, eligible same-origin SPA navigation.
26
+ *
27
+ * Modified clicks, downloads, external URLs, non-HTTP(S) destinations, and
28
+ * non-self targets retain browser behavior. Unsafe executable schemes are
29
+ * rendered as `about:blank` and their clicks are canceled. A user click handler
30
+ * runs first through DOM host event chaining; `preventDefault()` prevents the
31
+ * internal navigation decision.
32
+ *
33
+ * @remarks
34
+ * `Link` keeps the anchor as the integration boundary: native opening, copying,
35
+ * status previews, modifier keys, downloads, and external navigation continue
36
+ * to work. Only an unmodified primary click to same-origin HTTP(S) is handed to
37
+ * Typed's Effect-native `Navigation` service.
38
+ *
39
+ * Calling `Link` starts no work. Running the returned Fx subscribes to dynamic
40
+ * href/content and installs a real, non-passive DOM click listener in its
41
+ * Effect Scope. Scope finalization removes only those resources. Navigation
42
+ * failures and required services remain visible in the Fx type. A custom host
43
+ * must preserve the sanitized href, chained click handler, content, and native
44
+ * anchor behavior.
45
+ *
46
+ * @example
47
+ * ```ts
48
+ * import { html } from "@typed/template";
49
+ * import { Link } from "@typed/ui/Link";
50
+ *
51
+ * export const AccountLinks = html`<nav aria-label="Account">
52
+ * ${Link({ href: "/account/profile", content: "Edit profile" })}
53
+ * ${Link({
54
+ * href: "/account/security",
55
+ * content: "Security settings",
56
+ * replace: false,
57
+ * })}
58
+ * ${Link({
59
+ * href: "https://www.w3.org/WAI/",
60
+ * content: "Accessibility resources (opens in a new tab)",
61
+ * props: { target: "_blank", rel: "noopener" },
62
+ * })}
63
+ * </nav>`;
64
+ * ```
65
+ * @since 1.0.0
66
+ * @category Native controls
33
67
  */
34
- export declare function Link<const Opts extends LinkOptions>(options: Opts): Fx<RenderEvent, Renderable.ErrorFromObject<Opts>, Renderable.ServicesFromObject<Opts> | Scope | RenderTemplate>;
68
+ export declare function Link<const Options extends object>(options: Options, ..._: Options extends LinkOptions ? [] : ["Link options must satisfy LinkOptions"]): Fx.Fx<RenderEvent, LinkError<Options>, LinkServices<Options>>;
69
+ export declare function Link<const Options extends object, const Host extends HostResult>(options: Options, host: Dom.HostOverride<Dom.HostProps<HTMLAnchorElement>, Renderable.Any, Host>, ..._: Options extends LinkOptions ? [] : ["Link options must satisfy LinkOptions"]): Fx.Fx<RenderEvent, LinkError<Options> | Fx.Error<Host>, LinkServices<Options> | Fx.Services<Host>>;
35
70
  export {};
36
71
  //# sourceMappingURL=Link.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../src/Link.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,EAAO,MAAM,cAAc,CAAC;AAG5C,OAAO,EACL,YAAY,EACZ,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;AAEzB,KAAK,oBAAoB,GAAG,KAAK,MAAM,EAAE,CAAC;AAE1C,KAAK,mBAAmB,GAAG;IACzB,QAAQ,EAAE,CAAC,IAAI,MAAM,iBAAiB,IAAI,CAAC,SAAS,oBAAoB,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,EAClF,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,GAChC,YAAY,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC;CAC/C,CAAC;AAEF,KAAK,SAAS,GAAG;IACf,QAAQ,CAAC,GAAG,CAAC,EAAE,CACb,OAAO,EAAE,iBAAiB,KACvB,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;CAClG,CAAC;AAEF,KAAK,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,IACxB,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,GAAG,KAAK,CAAC;AAEvF,KAAK,YAAY,CAAC,CAAC,IAAI;KACpB,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;SAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;KAAE,EAAE;QAAE,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;KAAE,EAAE,CAAC,CAAC;CAChF,CAAC,MAAM,CAAC,CAAC,CAAC;AAEX,KAAK,gBAAgB,GAAG;IACtB,QAAQ,EAAE,CAAC,IAAI,YAAY,CAAC,iBAAiB,CAAC,IAAI,CAAC,SAAS,oBAAoB,GAAG,KAAK,GACpF,KAAK,GACL,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC;CACpD,CAAC;AAEF,MAAM,WAAW,WAAY,SAAQ,mBAAmB,EAAE,SAAS,EAAE,gBAAgB;IACnF,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAC5C,QAAQ,CAAC,OAAO,EAAE,UAAU,CAC1B,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,GAAG,WAAW,EACjE,GAAG,EACH,GAAG,CACJ,CAAC;IACF,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAyBD;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,KAAK,CAAC,IAAI,SAAS,WAAW,EACjD,OAAO,EAAE,IAAI,GACZ,EAAE,CACH,WAAW,EACX,UAAU,CAAC,eAAe,CAAC,IAAI,CAAC,EAChC,UAAU,CAAC,kBAAkB,CAAC,IAAI,CAAC,GAAG,KAAK,GAAG,cAAc,CAC7D,CAqBA"}
1
+ {"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../src/Link.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,KAAK,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,KAAK,eAAe,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,WAAW,EAChB,KAAK,cAAc,EAEpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD;;;;;;;;;GASG;AACH,MAAM,MAAM,WAAW,GAAG,GAAG,CAAC,WAAW,CAAC,iBAAiB,CAAC,GAAG;IAC7D,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAC5C,QAAQ,CAAC,OAAO,EAAE,UAAU,CAC1B,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,GAAG,WAAW,EACjE,GAAG,EACH,GAAG,CACJ,CAAC;IACF,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF,KAAK,SAAS,CAAC,OAAO,SAAS,MAAM,IAAI,UAAU,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,eAAe,CAAC;AAE/F,KAAK,YAAY,CAAC,OAAO,SAAS,MAAM,IACpC,UAAU,CAAC,kBAAkB,CAAC,OAAO,CAAC,GACtC,UAAU,GACV,KAAK,GACL,cAAc,CAAC;AAsDnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,IAAI,CAAC,KAAK,CAAC,OAAO,SAAS,MAAM,EAC/C,OAAO,EAAE,OAAO,EAChB,GAAG,CAAC,EAAE,OAAO,SAAS,WAAW,GAAG,EAAE,GAAG,CAAC,uCAAuC,CAAC,GACjF,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC;AACjE,wBAAgB,IAAI,CAAC,KAAK,CAAC,OAAO,SAAS,MAAM,EAAE,KAAK,CAAC,IAAI,SAAS,UAAU,EAC9E,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,iBAAiB,CAAC,EAAE,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,EAC9E,GAAG,CAAC,EAAE,OAAO,SAAS,WAAW,GAAG,EAAE,GAAG,CAAC,uCAAuC,CAAC,GACjF,EAAE,CAAC,EAAE,CACN,WAAW,EACX,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EACnC,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAC1C,CAAC"}
package/dist/Link.js CHANGED
@@ -1,45 +1,92 @@
1
+ /**
2
+ * Native anchors with selective same-origin Navigation interception.
3
+ * Modified clicks, external links, downloads, and non-self targets retain native behavior.
4
+ *
5
+ * Read the [Link guide](/explore/ui-link) for a complete example.
6
+ *
7
+ * [APG interaction reference](https://www.w3.org/WAI/ARIA/apg/patterns/link/).
8
+ * @since 1.0.0
9
+ * @category Overview
10
+ * @packageDocumentation
11
+ */
1
12
  import * as Effect from "effect/Effect";
2
- import { gen } from "@typed/fx/Fx";
3
- import { RefSubject } from "@typed/fx/RefSubject";
4
- import { getUrl, Navigation } from "@typed/navigation";
13
+ import * as Stream from "effect/Stream";
14
+ import * as Fx from "@typed/fx/Fx";
15
+ import { Navigation } from "@typed/navigation";
5
16
  import { EventHandler, html, } from "@typed/template";
6
- function makeLinkClickHandler(replace$) {
7
- return EventHandler.make((ev) => Effect.gen(function* () {
8
- const href = ev.currentTarget.href;
9
- if (ev.ctrlKey || ev.metaKey || ev.shiftKey)
17
+ import * as Dom from "./Dom.js";
18
+ function makeLinkClickHandler(replace) {
19
+ // Classification and native cancellation must run during event dispatch;
20
+ // only the resulting router navigation is lazy.
21
+ return EventHandler.make((event) => {
22
+ const anchor = Dom.currentTarget(event);
23
+ const href = anchor.href;
24
+ if (event.defaultPrevented ||
25
+ event.button !== 0 ||
26
+ event.metaKey ||
27
+ event.altKey ||
28
+ event.ctrlKey ||
29
+ event.shiftKey)
30
+ return;
31
+ const target = anchor.target;
32
+ if (target && target !== "_self")
10
33
  return;
11
- const t = ev.currentTarget.target;
12
- if (t && t !== "_self")
34
+ if (anchor.hasAttribute("download"))
13
35
  return;
14
- const nav = yield* Navigation;
15
- const target = getUrl(nav.origin, href);
16
- if (target.origin !== nav.origin)
36
+ if (!isSafeLinkHref(href)) {
37
+ event.preventDefault();
17
38
  return;
18
- ev.preventDefault();
19
- const replace = yield* replace$;
20
- yield* nav.navigate(href, { history: replace ? "replace" : "push" });
21
- }));
39
+ }
40
+ const destination = new URL(href);
41
+ if (destination.protocol !== "http:" && destination.protocol !== "https:")
42
+ return;
43
+ if (destination.origin !== anchor.ownerDocument.defaultView?.location.origin)
44
+ return;
45
+ event.preventDefault();
46
+ return Effect.flatMap(Navigation, (navigation) => navigation.navigate(href, { history: replace ? "replace" : "push" }));
47
+ }, { passive: false });
22
48
  }
23
- /**
24
- * Renders an `<a href="...">` that intercepts same-origin, same-document clicks
25
- * and navigates via `Navigation.navigate` instead of full page load. Requires
26
- * `Navigation` and `RenderTemplate` in the Effect context (e.g. `BrowserRouter`).
27
- */
28
- export function Link(options) {
29
- return gen(function* () {
30
- const { replace = false, onclick, content: children, ...rest } = options;
31
- const replace$ = yield* RefSubject.make(replace);
32
- const navigationHandler = makeLinkClickHandler(replace$);
33
- const userHandler = onclick ? EventHandler.fromEffectOrEventHandler(onclick) : undefined;
34
- const clickHandler = userHandler
35
- ? EventHandler.make(Effect.fn(function* (ev) {
36
- yield* userHandler.handler(ev);
37
- if (ev.defaultPrevented)
38
- return;
39
- yield* navigationHandler.handler(ev);
40
- }), { ...userHandler.options, preventDefault: true })
41
- : navigationHandler;
42
- const props = { ...rest, onclick: clickHandler };
43
- return html `<a ...${props}>${children}</a>`;
49
+ function internalProps(options) {
50
+ return () => ({
51
+ href: sanitizeLinkHref(options.href),
52
+ onclick: makeLinkClickHandler(options.replace ?? false),
44
53
  });
45
54
  }
55
+ // Keep the implementation erased: constraining it to LinkOptions widens the
56
+ // Renderable `any` slots and loses the exact error/service inference above.
57
+ export function Link(options, host, ..._) {
58
+ const render = Dom.renderHost();
59
+ return render(options, host, internalProps(options), options.content, (props, content) => html `<a ...${props}>${content}</a>`);
60
+ }
61
+ function sanitizeLinkHref(href) {
62
+ if (Fx.isFx(href))
63
+ return Fx.map(href, neutralizeExecutableHref);
64
+ if (Stream.isStream(href)) {
65
+ return Stream.map(href, neutralizeExecutableHref);
66
+ }
67
+ if (Effect.isEffect(href))
68
+ return Effect.map(href, neutralizeExecutableHref);
69
+ if (Array.isArray(href)) {
70
+ return href.map((value) => sanitizeLinkHref(value));
71
+ }
72
+ return (typeof href === "string" ? neutralizeExecutableHref(href) : href);
73
+ }
74
+ function neutralizeExecutableHref(href) {
75
+ return isSafeLinkHref(href) ? href : "about:blank";
76
+ }
77
+ function isSafeLinkHref(href) {
78
+ try {
79
+ switch (new URL(href, "http://localhost").protocol) {
80
+ case "http:":
81
+ case "https:":
82
+ case "mailto:":
83
+ case "tel:":
84
+ return true;
85
+ default:
86
+ return false;
87
+ }
88
+ }
89
+ catch {
90
+ return false;
91
+ }
92
+ }
@@ -0,0 +1,305 @@
1
+ /**
2
+ * Listbox separates active and selected values, registers options in a Collection, and combines
3
+ * vertical keyboard movement with buffered typeahead. It supports roving focus by default and uses
4
+ * real focus, keydown, and click events.
5
+ *
6
+ * @remarks
7
+ * The module keeps policy, state transitions, and DOM rendering separable so applications can use
8
+ * the state and pure operations without mounting UI, or supply custom hosts without replacing native
9
+ * events and browser-owned focus.
10
+ *
11
+ * Learn the interaction in the [Listbox guide](/explore/ui-listbox).
12
+ *
13
+ * @since 1.0.0
14
+ * @category modules
15
+ * @packageDocumentation
16
+ */
17
+ import * as Effect from "effect/Effect";
18
+ import type * as Scope from "effect/Scope";
19
+ import * as Schema from "effect/Schema";
20
+ import type { Fx } from "@typed/fx/Fx";
21
+ import { RefSubject } from "@typed/fx";
22
+ import { EventHandler, type Renderable, type RenderEvent, type RenderTemplate } from "@typed/template";
23
+ import * as Collection from "./Collection.js";
24
+ import * as Composite from "./Composite.js";
25
+ import * as Dom from "./Dom.js";
26
+ import type { HostResult } from "./Dom/Types.js";
27
+ /**
28
+ * The committed single value and the option currently owning keyboard focus.
29
+ * Normal option focus and movement update both values; the DOM ID and saved value may differ.
30
+ *
31
+ * @since 1.0.0
32
+ * @category Selection and focus
33
+ */
34
+ export interface State extends Omit<Composite.State, "orientation"> {
35
+ /**
36
+ * Axis used to interpret Arrow-key movement.
37
+ * @since 1.0.0
38
+ * @category Keyboard navigation
39
+ */
40
+ readonly orientation: "vertical";
41
+ /**
42
+ * Current semantic value selected or edited by the widget.
43
+ * @since 1.0.0
44
+ * @category Current value
45
+ */
46
+ readonly value: string | null;
47
+ }
48
+ /**
49
+ * Initial Listbox values. value and activeId default to null, loop defaults to true, and roving
50
+ * focus is used.
51
+ *
52
+ * @since 1.0.0
53
+ * @category Selection and focus
54
+ */
55
+ export interface InitialState {
56
+ /**
57
+ * Current semantic value selected or edited by the widget.
58
+ * @since 1.0.0
59
+ * @category Current value
60
+ */
61
+ readonly value?: string | null;
62
+ /**
63
+ * Id currently active for keyboard navigation; null means no active item.
64
+ * @since 1.0.0
65
+ * @category Keyboard focus
66
+ */
67
+ readonly activeId?: string | null;
68
+ /**
69
+ * Whether movement wraps between the first and last enabled items.
70
+ * @since 1.0.0
71
+ * @category Keyboard navigation
72
+ */
73
+ readonly loop?: boolean;
74
+ }
75
+ /**
76
+ * Effect Schema used by makeState to encode, decode, and hydrate Listbox state.
77
+ *
78
+ * @remarks
79
+ * @example
80
+ * ```ts
81
+ * import * as Schema from "effect/Schema";
82
+ * import * as Listbox from "@typed/ui/Listbox";
83
+ *
84
+ * const decodeState = Schema.decodeUnknownEffect(Listbox.StateSchema);
85
+ * ```
86
+ * @since 1.0.0
87
+ * @category Selection and focus
88
+ */
89
+ export declare const StateSchema: Schema.Struct<{
90
+ readonly value: Schema.NullOr<Schema.String>;
91
+ readonly activeId: Schema.NullOr<Schema.String>;
92
+ readonly orientation: Schema.Literals<readonly ["vertical"]>;
93
+ readonly loop: Schema.Boolean;
94
+ readonly rtl: Schema.Boolean;
95
+ readonly virtualFocus: Schema.Boolean;
96
+ }>;
97
+ /**
98
+ * Creates hydrated Listbox state. value and activeId default to null, loop defaults to true, and
99
+ * roving focus is used.
100
+ *
101
+ * @remarks
102
+ * The returned Effect creates the RefSubject when run. That state is renderer-independent;
103
+ * collection registrations belong to the separate Scope that runs register or ref, not to state
104
+ * creation.
105
+ *
106
+ * @example
107
+ * ```ts
108
+ * import * as Effect from "effect/Effect";
109
+ * import * as Listbox from "@typed/ui/Listbox";
110
+ *
111
+ * const program = Effect.scoped(
112
+ * Effect.gen(function* () {
113
+ * const state = yield* Listbox.makeState({});
114
+ * const collection = yield* Listbox.makeCollection();
115
+ * return { state: yield* state, collection: yield* collection };
116
+ * }),
117
+ * );
118
+ * ```
119
+ * @since 1.0.0
120
+ * @category Selection and focus
121
+ */
122
+ export declare function makeState(initial?: InitialState): Effect.Effect<RefSubject.HydratedRefSubject<{
123
+ readonly value: string | null;
124
+ readonly activeId: string | null;
125
+ readonly orientation: "vertical";
126
+ readonly loop: boolean;
127
+ readonly rtl: boolean;
128
+ readonly virtualFocus: boolean;
129
+ }, Schema.SchemaError, never, never>, never, Scope.Scope>;
130
+ /**
131
+ * Creates a scoped Collection for Listbox items.
132
+ *
133
+ * @remarks
134
+ * The returned Effect allocates the RefSubject in the caller's Scope. Each later registration is
135
+ * owned by the Scope that runs register, independently of this construction Effect.
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * import * as Effect from "effect/Effect";
140
+ * import * as Listbox from "@typed/ui/Listbox";
141
+ *
142
+ * const program = Effect.scoped(
143
+ * Effect.gen(function* () {
144
+ * const collection = yield* Listbox.makeCollection();
145
+ * return yield* collection;
146
+ * }),
147
+ * );
148
+ * ```
149
+ * @since 1.0.0
150
+ * @category Option registration
151
+ */
152
+ export declare const makeCollection: (initial?: Collection.State<string, Element>) => Effect.Effect<RefSubject.RefSubject<Collection.State<string, Element>, never, never>, never, Scope.Scope>;
153
+ /**
154
+ * Sets both activeId and selected value in one update.
155
+ *
156
+ * @remarks
157
+ * The operation exposes Listbox's transition directly so callers can compose it in Effect programs
158
+ * and native event handlers.
159
+ *
160
+ * @since 1.0.0
161
+ * @category Selection and focus
162
+ */
163
+ export declare function select<E, R>(state: RefSubject.RefSubject<State, E, R>, id: string, value: string): Effect.Effect<State, E, R>;
164
+ /**
165
+ * Moves through the registered options, synchronizes value when the target has one, then focuses
166
+ * and scrolls the active option.
167
+ *
168
+ * @remarks
169
+ * The operation exposes Listbox's transition directly so callers can compose it in Effect programs
170
+ * and native event handlers.
171
+ *
172
+ * @since 1.0.0
173
+ * @category Selection and focus
174
+ */
175
+ export declare function move(state: RefSubject.HydratedRefSubject<State, Schema.SchemaError>, collection: RefSubject.RefSubject<Collection.State<string>>, direction: Composite.Move): Effect.Effect<State, Schema.SchemaError>;
176
+ /**
177
+ * Inputs accepted by Listbox.Root in addition to the shared DOM host options.
178
+ *
179
+ * @since 1.0.0
180
+ * @category Listbox surface
181
+ */
182
+ export interface RootOptions extends Dom.HostOptions<HTMLDivElement> {
183
+ /**
184
+ * Renderer-independent RefSubject state consumed by this component or operation.
185
+ * @since 1.0.0
186
+ * @category State connection
187
+ */
188
+ readonly state: RefSubject.HydratedRefSubject<State, Schema.SchemaError>;
189
+ /**
190
+ * Item registry used for collection-driven keyboard behavior and mounted ordering.
191
+ * @since 1.0.0
192
+ * @category Item registration
193
+ */
194
+ readonly collection?: RefSubject.RefSubject<Collection.State<string>>;
195
+ /**
196
+ * Renderable child content for the component host.
197
+ * @since 1.0.0
198
+ * @category Rendered content
199
+ */
200
+ readonly content: Renderable.Any;
201
+ /**
202
+ * Accessible label rendered through aria-label.
203
+ * @since 1.0.0
204
+ * @category Accessible naming
205
+ */
206
+ readonly label?: Renderable.Any<string | null | undefined>;
207
+ }
208
+ declare function rootProps<const Options extends RootOptions>(options: Options): ({ property }: Dom.InternalPropsHelpers<Options>) => {
209
+ readonly role: "listbox";
210
+ readonly "aria-label": Exclude<Dom.Property<Options, "label">, Dom.Nullish> | undefined;
211
+ readonly "aria-activedescendant": RefSubject.Computed<string | undefined, Schema.SchemaError, never>;
212
+ readonly tabindex: RefSubject.Computed<-1 | 0, Schema.SchemaError, never>;
213
+ readonly onfocus: Effect.Effect<void, Schema.SchemaError, never> | undefined;
214
+ readonly onkeydown: EventHandler.EventHandler<KeyboardEvent, Schema.SchemaError, never> | undefined;
215
+ readonly ref: RefSubject.HydratedRefSubject<State, Schema.SchemaError, never, never>;
216
+ };
217
+ type RootProps<Options extends RootOptions> = ReturnType<ReturnType<typeof rootProps<Options>>>;
218
+ /**
219
+ * Renders the listbox root, initializes selection on focus, and handles vertical movement and
220
+ * typeahead in DOM order.
221
+ *
222
+ * @remarks
223
+ * The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
224
+ * collection registrations only when rendered. The rendering Scope removes those resources;
225
+ * unrelated nodes and attributes remain caller-owned.
226
+ *
227
+ * @since 1.0.0
228
+ * @category Listbox surface
229
+ */
230
+ export declare function Root<const Options extends RootOptions, const Host extends HostResult = never>(options: Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, RootProps<Options>>, Options["content"], Host>): Fx<RenderEvent, Renderable.Error<Options | Host>, Renderable.Services<Options | Host> | Scope.Scope | RenderTemplate>;
231
+ /**
232
+ * Inputs accepted by Listbox.Option in addition to the shared DOM host options.
233
+ *
234
+ * @since 1.0.0
235
+ * @category Selectable options
236
+ */
237
+ export interface OptionOptions extends Dom.HostOptions<HTMLDivElement> {
238
+ /**
239
+ * Renderer-independent RefSubject state consumed by this component or operation.
240
+ * @since 1.0.0
241
+ * @category State connection
242
+ */
243
+ readonly state: RefSubject.HydratedRefSubject<State, Schema.SchemaError>;
244
+ /**
245
+ * Item registry used for collection-driven keyboard behavior and mounted ordering.
246
+ * @since 1.0.0
247
+ * @category Item registration
248
+ */
249
+ readonly collection?: RefSubject.RefSubject<Collection.State<string>>;
250
+ /**
251
+ * Stable id used for collection identity and ARIA relationships.
252
+ * @since 1.0.0
253
+ * @category Identity and relationships
254
+ */
255
+ readonly id: string;
256
+ /**
257
+ * Current semantic value selected or edited by the widget.
258
+ * @since 1.0.0
259
+ * @category Current value
260
+ */
261
+ readonly value: string;
262
+ /**
263
+ * Renderable child content for the component host.
264
+ * @since 1.0.0
265
+ * @category Rendered content
266
+ */
267
+ readonly content: Renderable.Any;
268
+ /**
269
+ * Search text used by typeahead independently of rendered markup.
270
+ * @since 1.0.0
271
+ * @category Text matching
272
+ */
273
+ readonly textValue?: string;
274
+ /**
275
+ * Flag used by collection movement and widget handlers to skip activation by default.
276
+ * @since 1.0.0
277
+ * @category Availability
278
+ */
279
+ readonly disabled?: boolean;
280
+ }
281
+ declare function optionProps<const Options extends OptionOptions>(options: Options): () => {
282
+ readonly id: string;
283
+ readonly role: "option";
284
+ readonly "aria-selected": RefSubject.Computed<boolean, Schema.SchemaError, never>;
285
+ readonly "aria-disabled": boolean;
286
+ readonly tabindex: RefSubject.Computed<-1 | 0, Schema.SchemaError, never>;
287
+ readonly onclick: Effect.Effect<void, never, never> | Effect.Effect<State, Schema.SchemaError, never>;
288
+ readonly onfocus: Effect.Effect<void, never, never> | Effect.Effect<State, Schema.SchemaError, never>;
289
+ readonly ref: ((element: Element & HTMLDivElement & RefSubject.HydrationElement) => Effect.Effect<void, any, any>) | undefined;
290
+ };
291
+ type OptionProps<Options extends OptionOptions> = ReturnType<ReturnType<typeof optionProps<Options>>>;
292
+ /**
293
+ * Renders and optionally registers an option; focus or click selects it unless disabled.
294
+ *
295
+ * @remarks
296
+ * The returned Fx installs DOM refs, native listeners, state subscriptions, and optional
297
+ * collection registrations only when rendered. The rendering Scope removes those resources;
298
+ * unrelated nodes and attributes remain caller-owned.
299
+ *
300
+ * @since 1.0.0
301
+ * @category Selectable options
302
+ */
303
+ export declare function Option<const Options extends OptionOptions, const Host extends HostResult = never>(options: Options, host?: Dom.HostOverride<Dom.RenderHostProps<Options, OptionProps<Options>>, Options["content"], Host>): Fx<RenderEvent, Renderable.Error<Options | Host>, Renderable.Services<Options | Host> | Scope.Scope | RenderTemplate>;
304
+ export {};
305
+ //# sourceMappingURL=Listbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Listbox.d.ts","sourceRoot":"","sources":["../src/Listbox.ts"],"names":[],"mappings":"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"}