@typed/ui 1.0.0-beta.0 → 1.0.0-beta.10
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/LICENSE +21 -0
- package/README.md +78 -26
- package/dist/Alert.d.ts +72 -0
- package/dist/Alert.d.ts.map +1 -0
- package/dist/Alert.js +40 -0
- package/dist/Button.d.ts +100 -0
- package/dist/Button.d.ts.map +1 -0
- package/dist/Button.js +42 -0
- package/dist/Carousel.d.ts +346 -0
- package/dist/Carousel.d.ts.map +1 -0
- package/dist/Carousel.js +264 -0
- package/dist/Checkbox.d.ts +168 -0
- package/dist/Checkbox.d.ts.map +1 -0
- package/dist/Checkbox.js +146 -0
- package/dist/Collection.d.ts +254 -0
- package/dist/Collection.d.ts.map +1 -0
- package/dist/Collection.js +218 -0
- package/dist/Combobox.d.ts +367 -0
- package/dist/Combobox.d.ts.map +1 -0
- package/dist/Combobox.js +300 -0
- package/dist/Composite.d.ts +823 -0
- package/dist/Composite.d.ts.map +1 -0
- package/dist/Composite.js +615 -0
- package/dist/Dialog.d.ts +544 -0
- package/dist/Dialog.d.ts.map +1 -0
- package/dist/Dialog.js +357 -0
- package/dist/Disclosure.d.ts +219 -0
- package/dist/Disclosure.d.ts.map +1 -0
- package/dist/Disclosure.js +128 -0
- package/dist/Dom/Events.d.ts +122 -0
- package/dist/Dom/Events.d.ts.map +1 -0
- package/dist/Dom/Events.js +192 -0
- package/dist/Dom/Props.d.ts +161 -0
- package/dist/Dom/Props.d.ts.map +1 -0
- package/dist/Dom/Props.js +110 -0
- package/dist/Dom/Refs.d.ts +58 -0
- package/dist/Dom/Refs.d.ts.map +1 -0
- package/dist/Dom/Refs.js +61 -0
- package/dist/Dom/Render.d.ts +59 -0
- package/dist/Dom/Render.d.ts.map +1 -0
- package/dist/Dom/Render.js +71 -0
- package/dist/Dom/Types.d.ts +570 -0
- package/dist/Dom/Types.d.ts.map +1 -0
- package/dist/Dom/Types.js +1 -0
- package/dist/Dom/index.d.ts +20 -0
- package/dist/Dom/index.d.ts.map +1 -0
- package/dist/Dom/index.js +8 -0
- package/dist/Dom.d.ts +14 -0
- package/dist/Dom.d.ts.map +1 -0
- package/dist/Dom.js +13 -0
- package/dist/Focusable.d.ts +85 -0
- package/dist/Focusable.d.ts.map +1 -0
- package/dist/Focusable.js +35 -0
- package/dist/Form.d.ts +1727 -0
- package/dist/Form.d.ts.map +1 -0
- package/dist/Form.js +1142 -0
- package/dist/Grid.d.ts +388 -0
- package/dist/Grid.d.ts.map +1 -0
- package/dist/Grid.js +284 -0
- package/dist/Group.d.ts +128 -0
- package/dist/Group.d.ts.map +1 -0
- package/dist/Group.js +71 -0
- package/dist/Heading.d.ts +87 -0
- package/dist/Heading.d.ts.map +1 -0
- package/dist/Heading.js +58 -0
- package/dist/Hovercard.d.ts +297 -0
- package/dist/Hovercard.d.ts.map +1 -0
- package/dist/Hovercard.js +188 -0
- package/dist/HttpRouter.d.ts +129 -6
- package/dist/HttpRouter.d.ts.map +1 -1
- package/dist/HttpRouter.js +199 -56
- package/dist/Link.d.ts +63 -28
- package/dist/Link.d.ts.map +1 -1
- package/dist/Link.js +84 -37
- package/dist/Listbox.d.ts +305 -0
- package/dist/Listbox.d.ts.map +1 -0
- package/dist/Listbox.js +245 -0
- package/dist/Menu.d.ts +663 -0
- package/dist/Menu.d.ts.map +1 -0
- package/dist/Menu.js +569 -0
- package/dist/Menubar.d.ts +249 -0
- package/dist/Menubar.d.ts.map +1 -0
- package/dist/Menubar.js +207 -0
- package/dist/Meter.d.ts +157 -0
- package/dist/Meter.d.ts.map +1 -0
- package/dist/Meter.js +87 -0
- package/dist/NativeDetails.d.ts +41 -0
- package/dist/NativeDetails.d.ts.map +1 -0
- package/dist/NativeDetails.js +40 -0
- package/dist/NativeDialog.d.ts +66 -0
- package/dist/NativeDialog.d.ts.map +1 -0
- package/dist/NativeDialog.js +88 -0
- package/dist/NativePopover.d.ts +43 -0
- package/dist/NativePopover.d.ts.map +1 -0
- package/dist/NativePopover.js +84 -0
- package/dist/Popover.d.ts +240 -0
- package/dist/Popover.d.ts.map +1 -0
- package/dist/Popover.js +140 -0
- package/dist/RadioGroup.d.ts +330 -0
- package/dist/RadioGroup.d.ts.map +1 -0
- package/dist/RadioGroup.js +241 -0
- package/dist/Role.d.ts +64 -0
- package/dist/Role.d.ts.map +1 -0
- package/dist/Role.js +27 -0
- package/dist/Select.d.ts +418 -0
- package/dist/Select.d.ts.map +1 -0
- package/dist/Select.js +357 -0
- package/dist/Separator.d.ts +58 -0
- package/dist/Separator.d.ts.map +1 -0
- package/dist/Separator.js +32 -0
- package/dist/Slider.d.ts +141 -0
- package/dist/Slider.d.ts.map +1 -0
- package/dist/Slider.js +101 -0
- package/dist/SpinButton.d.ts +141 -0
- package/dist/SpinButton.d.ts.map +1 -0
- package/dist/SpinButton.js +101 -0
- package/dist/Storybook.d.ts +76 -0
- package/dist/Storybook.d.ts.map +1 -0
- package/dist/Storybook.js +102 -0
- package/dist/Switch.d.ts +148 -0
- package/dist/Switch.d.ts.map +1 -0
- package/dist/Switch.js +110 -0
- package/dist/Tab.d.ts +26 -0
- package/dist/Tab.d.ts.map +1 -0
- package/dist/Tab.js +25 -0
- package/dist/Tabs.d.ts +411 -0
- package/dist/Tabs.d.ts.map +1 -0
- package/dist/Tabs.js +262 -0
- package/dist/Toolbar.d.ts +248 -0
- package/dist/Toolbar.d.ts.map +1 -0
- package/dist/Toolbar.js +187 -0
- package/dist/Tooltip.d.ts +296 -0
- package/dist/Tooltip.d.ts.map +1 -0
- package/dist/Tooltip.js +172 -0
- package/dist/Tree.d.ts +405 -0
- package/dist/Tree.d.ts.map +1 -0
- package/dist/Tree.js +333 -0
- package/dist/TreeGrid.d.ts +426 -0
- package/dist/TreeGrid.d.ts.map +1 -0
- package/dist/TreeGrid.js +308 -0
- package/dist/VisuallyHidden.d.ts +68 -0
- package/dist/VisuallyHidden.d.ts.map +1 -0
- package/dist/VisuallyHidden.js +44 -0
- package/dist/WindowSplitter.d.ts +336 -0
- package/dist/WindowSplitter.d.ts.map +1 -0
- package/dist/WindowSplitter.js +305 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +48 -0
- package/package.json +47 -14
- package/src/HttpRouter.test.ts +0 -294
- package/src/HttpRouter.ts +0 -168
- package/src/Link.test.ts +0 -85
- package/src/Link.ts +0 -107
- package/src/index.ts +0 -2
- package/tsconfig.json +0 -6
package/src/Link.test.ts
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert";
|
|
2
|
-
import { describe, it } from "vitest";
|
|
3
|
-
import { Effect } from "effect";
|
|
4
|
-
import * as Layer from "effect/Layer";
|
|
5
|
-
import { Fx } from "@typed/fx";
|
|
6
|
-
import { CurrentPath } from "@typed/navigation";
|
|
7
|
-
import { ServerRouter } from "@typed/router/Router";
|
|
8
|
-
import { DomRenderTemplate, render } from "@typed/template";
|
|
9
|
-
import { Link } from "./Link.js";
|
|
10
|
-
import { Window } from "happy-dom";
|
|
11
|
-
|
|
12
|
-
describe("typed/ui/Link", () => {
|
|
13
|
-
it("renders <a> with href and content", () =>
|
|
14
|
-
Effect.gen(function* () {
|
|
15
|
-
const [window, layer] = createHappyDomLayer();
|
|
16
|
-
|
|
17
|
-
const [root] = yield* render(
|
|
18
|
-
Link({ href: "/about", content: "Go to about" }),
|
|
19
|
-
window.document.body,
|
|
20
|
-
).pipe(Fx.provide(layer), Fx.take(1), Fx.collectAll);
|
|
21
|
-
|
|
22
|
-
assert(root instanceof window.HTMLElement);
|
|
23
|
-
const anchor = root as HTMLAnchorElement;
|
|
24
|
-
assert(anchor.tagName === "A");
|
|
25
|
-
assert(anchor.getAttribute("href") === "/about");
|
|
26
|
-
assert(anchor.textContent === "Go to about");
|
|
27
|
-
}).pipe(Effect.scoped, Effect.runPromise));
|
|
28
|
-
|
|
29
|
-
it("intercepts same-origin click and navigates", () => {
|
|
30
|
-
const [window, layer] = createHappyDomLayer({ url: "http://localhost/" });
|
|
31
|
-
return Effect.gen(function* () {
|
|
32
|
-
const [root] = yield* render(
|
|
33
|
-
Link({ href: "/about", content: "Go" }),
|
|
34
|
-
window.document.body,
|
|
35
|
-
).pipe(Fx.take(1), Fx.collectAll);
|
|
36
|
-
|
|
37
|
-
assert(root instanceof window.HTMLElement);
|
|
38
|
-
const anchor = root as HTMLAnchorElement;
|
|
39
|
-
assert(anchor.tagName === "A");
|
|
40
|
-
|
|
41
|
-
const pathBefore = yield* CurrentPath;
|
|
42
|
-
anchor.click();
|
|
43
|
-
yield* Effect.sleep(50);
|
|
44
|
-
const pathAfter = yield* CurrentPath;
|
|
45
|
-
|
|
46
|
-
assert(pathBefore === "/" || pathBefore === "");
|
|
47
|
-
assert(pathAfter === "/about");
|
|
48
|
-
}).pipe(Effect.provide(layer), Effect.scoped, Effect.runPromise);
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
it("does not intercept when modifier key is pressed", () => {
|
|
52
|
-
const [window, layer] = createHappyDomLayer();
|
|
53
|
-
return Effect.gen(function* () {
|
|
54
|
-
const [root] = yield* render(
|
|
55
|
-
Link({ href: "/other", content: "Go" }),
|
|
56
|
-
window.document.body,
|
|
57
|
-
).pipe(Fx.take(1), Fx.collectAll);
|
|
58
|
-
|
|
59
|
-
assert(root instanceof window.HTMLElement);
|
|
60
|
-
const anchor = root as HTMLAnchorElement;
|
|
61
|
-
assert(anchor.tagName === "A");
|
|
62
|
-
|
|
63
|
-
const ev = new window.MouseEvent("click", {
|
|
64
|
-
bubbles: true,
|
|
65
|
-
cancelable: true,
|
|
66
|
-
ctrlKey: true,
|
|
67
|
-
});
|
|
68
|
-
anchor.dispatchEvent(ev);
|
|
69
|
-
yield* Effect.sleep(50);
|
|
70
|
-
const pathAfter = yield* CurrentPath;
|
|
71
|
-
|
|
72
|
-
assert(pathAfter === "/" || pathAfter === "");
|
|
73
|
-
}).pipe(Effect.provide(layer), Effect.scoped, Effect.runPromise);
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
function createHappyDomLayer(...params: ConstructorParameters<typeof Window>) {
|
|
78
|
-
const window = new Window(...params) as unknown as globalThis.Window & typeof globalThis;
|
|
79
|
-
const domLayer = DomRenderTemplate.using(window.document);
|
|
80
|
-
const opts = params[0] as { url?: string } | undefined;
|
|
81
|
-
const url = opts?.url ?? "http://localhost/";
|
|
82
|
-
const routerLayer = ServerRouter({ url });
|
|
83
|
-
const layer = domLayer.pipe(Layer.merge(routerLayer));
|
|
84
|
-
return [window, layer] as const;
|
|
85
|
-
}
|
package/src/Link.ts
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import * as Effect from "effect/Effect";
|
|
2
|
-
import type { Scope } from "effect/Scope";
|
|
3
|
-
import type { Stream } from "effect/Stream";
|
|
4
|
-
import { type Fx, gen } from "@typed/fx/Fx";
|
|
5
|
-
import { RefSubject } from "@typed/fx/RefSubject";
|
|
6
|
-
import { getUrl, type NavigationError, Navigation } from "@typed/navigation";
|
|
7
|
-
import {
|
|
8
|
-
EventHandler,
|
|
9
|
-
type Renderable,
|
|
10
|
-
type RenderEvent,
|
|
11
|
-
type RenderTemplate,
|
|
12
|
-
html,
|
|
13
|
-
} from "@typed/template";
|
|
14
|
-
|
|
15
|
-
type EventHandlerProperty = `on${string}`;
|
|
16
|
-
|
|
17
|
-
type AnchorEventHandlers = {
|
|
18
|
-
readonly [K in keyof HTMLAnchorElement as K extends EventHandlerProperty ? K : never]?:
|
|
19
|
-
| Effect.Effect<unknown, any, any>
|
|
20
|
-
| EventHandler.EventHandler<Event, any, any>;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
type AnchorRef = {
|
|
24
|
-
readonly ref?: (
|
|
25
|
-
element: HTMLAnchorElement,
|
|
26
|
-
) => void | Effect.Effect<unknown, any, any> | Stream<unknown, any, any> | Fx<unknown, any, any>;
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
type IfEquals<X, Y, Output> =
|
|
30
|
-
(<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? Output : never;
|
|
31
|
-
|
|
32
|
-
type WritableKeys<T> = {
|
|
33
|
-
[P in keyof T]-?: IfEquals<{ [Q in P]: T[P] }, { -readonly [Q in P]: T[P] }, P>;
|
|
34
|
-
}[keyof T];
|
|
35
|
-
|
|
36
|
-
type AnchorProperties = {
|
|
37
|
-
readonly [K in WritableKeys<HTMLAnchorElement> as K extends EventHandlerProperty | "ref"
|
|
38
|
-
? never
|
|
39
|
-
: K]?: Renderable<HTMLAnchorElement[K], any, any>;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export interface LinkOptions extends AnchorEventHandlers, AnchorRef, AnchorProperties {
|
|
43
|
-
readonly href: Renderable<string, any, any>;
|
|
44
|
-
readonly content: Renderable<
|
|
45
|
-
string | number | boolean | null | undefined | void | RenderEvent,
|
|
46
|
-
any,
|
|
47
|
-
any
|
|
48
|
-
>;
|
|
49
|
-
readonly replace?: boolean; // false
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function makeLinkClickHandler(
|
|
53
|
-
replace$: RefSubject.RefSubject<boolean>,
|
|
54
|
-
): EventHandler.EventHandler<
|
|
55
|
-
MouseEvent & { readonly currentTarget: HTMLAnchorElement },
|
|
56
|
-
NavigationError,
|
|
57
|
-
Navigation
|
|
58
|
-
> {
|
|
59
|
-
return EventHandler.make((ev: MouseEvent & { readonly currentTarget: HTMLAnchorElement }) =>
|
|
60
|
-
Effect.gen(function* () {
|
|
61
|
-
const href = ev.currentTarget.href;
|
|
62
|
-
if (ev.ctrlKey || ev.metaKey || ev.shiftKey) return;
|
|
63
|
-
const t = ev.currentTarget.target;
|
|
64
|
-
if (t && t !== "_self") return;
|
|
65
|
-
const nav = yield* Navigation;
|
|
66
|
-
const target = getUrl(nav.origin, href);
|
|
67
|
-
if (target.origin !== nav.origin) return;
|
|
68
|
-
ev.preventDefault();
|
|
69
|
-
const replace = yield* replace$;
|
|
70
|
-
yield* nav.navigate(href, { history: replace ? "replace" : "push" });
|
|
71
|
-
}),
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Renders an `<a href="...">` that intercepts same-origin, same-document clicks
|
|
77
|
-
* and navigates via `Navigation.navigate` instead of full page load. Requires
|
|
78
|
-
* `Navigation` and `RenderTemplate` in the Effect context (e.g. `BrowserRouter`).
|
|
79
|
-
*/
|
|
80
|
-
export function Link<const Opts extends LinkOptions>(
|
|
81
|
-
options: Opts,
|
|
82
|
-
): Fx<
|
|
83
|
-
RenderEvent,
|
|
84
|
-
Renderable.ErrorFromObject<Opts>,
|
|
85
|
-
Renderable.ServicesFromObject<Opts> | Scope | RenderTemplate
|
|
86
|
-
> {
|
|
87
|
-
return gen(function* () {
|
|
88
|
-
const { replace = false, onclick, content: children, ...rest } = options;
|
|
89
|
-
const replace$ = yield* RefSubject.make(replace);
|
|
90
|
-
const navigationHandler = makeLinkClickHandler(replace$);
|
|
91
|
-
const userHandler = onclick ? EventHandler.fromEffectOrEventHandler(onclick) : undefined;
|
|
92
|
-
const clickHandler = userHandler
|
|
93
|
-
? EventHandler.make(
|
|
94
|
-
Effect.fn(function* (ev: MouseEvent & { readonly currentTarget: HTMLAnchorElement }) {
|
|
95
|
-
yield* userHandler.handler(ev);
|
|
96
|
-
if (ev.defaultPrevented) return;
|
|
97
|
-
yield* navigationHandler.handler(ev);
|
|
98
|
-
}),
|
|
99
|
-
{ ...userHandler.options, preventDefault: true },
|
|
100
|
-
)
|
|
101
|
-
: navigationHandler;
|
|
102
|
-
|
|
103
|
-
const props: Record<string, unknown> = { ...rest, onclick: clickHandler };
|
|
104
|
-
|
|
105
|
-
return html`<a ...${props}>${children}</a>`;
|
|
106
|
-
});
|
|
107
|
-
}
|
package/src/index.ts
DELETED