UNPKG

vite-plugin-vanjs

Version:

A mini meta-framework for VanJS powered by Vite

224 lines (202 loc) 5.84 kB
/// <reference path="global.d.ts" /> import type { Element as VElement, TagFunc as IsoTagFunc, } from "mini-van-plate/van-plate"; import van from "vanjs-core"; import type { ChildDom, Primitive, Props, PropsWithKnownKeys, PropValueOrDerived, State, } from "vanjs-core"; // type VanElement = VElement | Exclude<Primitive, boolean | undefined>; type DOMElement = globalThis.Element; type PrimitiveChild = Primitive | State<Primitive | undefined | null>; type VanElement = | SVGElement | HTMLElement | DOMElement | Node | VElement | PrimitiveChild; export type VanNode = | VanElement | VanNode[] | (() => VanNode) | null | undefined; type ComponentProps1<T> = & Props & PropsWithKnownKeys<T>; type ComponentProps<K extends keyof HTMLElementTagNameMap> = & Props & PropsWithKnownKeys<HTMLElementTagNameMap[K]>; export type VanComponent< K extends keyof HTMLElementTagNameMap = "div", O extends (Record<string, PropValueOrDerived> | undefined) = undefined, > = { ( props?: O extends object ? ComponentProps<K> & Partial<O> : ComponentProps<K>, ...children: ChildDom[] ): HTMLElementTagNameMap[K]; }; // router.mjs /** * A virtual component that renders the current route * in your VanJS application. It must be used in your main component. * * @example * import { Router } from '@vanjs/router'; * * export const App = () => { * return Router(); // or <Router /> for JSX * } */ // export const Router: JSX.Component<HTMLElement> & VanComponent<HTMLElement>; // export function Router(props?: ComponentProps<HTMLElement>): HTMLElement; // export function Router( // props?: JSX.IntrinsicElements["main"] & { children: null }, // ): HTMLElement; export const Router: & VanComponent<"main"> & JSX.Component<"main">; // a.mjs /** * A virtual component that creates an anchor element * that navigates to the specified href when clicked. * * @example * import { A } from '@vanjs/router'; * import van from 'vanjs-core'; * * export const Navigation = () => { * const { nav } = van.tags * return nav( * A({ href="/" }, "Home"), // or <A href="/">Home</A> with JSX * A({ href="/about" }, "About"), // or <A href="/about">About</A> with JSX * // ...other children * ); * } */ export const A: & VanComponent<"a"> & JSX.Component<"a">; // helpers.mjs /** * Navigates to the specified href in the client and sets the router state. * Keep in mind that the router handles the search params and hash. * * @param href the URL to navigate to * @param options when true, will replace the current history entry */ export const navigate: ( href: string, options?: { replace?: boolean }, ) => void; /** * A client only helper function that reloads the current page. */ export const reload: () => void; /** * A helper function that redirects the user to the specified href. * When called in the server, it will return a function that will redirect the user * to the specified href when called. * @param {string | undefined} href the URL to redirect to */ export const redirect: (href?: string) => void | (() => void); // routes.mjs export type RouteEntry = { path: string; component: Promise<ComponentModule>; preload?: (params?: Record<string, string>) => void; load?: (params?: Record<string, string>) => void; }; export type RouteProps = { path: string; component: | (() => HTMLElementTagNameMap[unknown] | HTMLElementTagNameMap[unknown][]) | VanComponent | (() => ComponentModule); preload?: (params?: Record<string, string>) => void; load?: (params?: Record<string, string>) => void; }; export const routes: RouteEntry[]; /** * Registers a new route in the router state. * @param route the route to register * * @example * import { Route, lazy } from '@vanjs/router'; * import Home from './pages/Home'; * import NotFound from './pages/NotFound'; * * Route({ path: '/', component: Home }); * Route({ path: '/about', component: lazy(() => import("./pages/About.ts")) }); * Route({ path: '*', component: NotFound }); */ export const Route: (route: RouteProps) => void; // state.mjs export type RouterState = { pathname: string; searchParams: URLSearchParams; params: Record<string, string>; }; /** * A reactive object that holds the current router state. * This state is maintained by both server and client. */ export const routerState: { pathname: van.state<RouterState.pathname>; searchParams: van.state<RouterState.searchParams>; params?: van.state<RouterState.params>; }; /** * Sets the router state to the specified href. * @param href the URL to navigate to * @param search the search string * @param params the route params object */ export const setRouterState: ( href: string, search?: string, params?: Record<string, string>, ) => void; /** * Merge the children of an Element or an array of elements with an optional array of children * into the childen of a single HTMLFragmentElement element. * @param source * @param {...VanNode[]} children */ export const unwrap: ( source: | VanNode | IsoTagFunc | VanNode[] | IsoTagFunc[] | (() => IsoTagFunc | IsoTagFunc[] | VanNode | VanNode[]), ...children: VanNode[] ) => VanNode; export type ComponentModule = { component: VanComponent | JSX.Element; route: Pick<RouteEntry, "load" | "preload">; }; export type DynamicModule = { Page: VanComponent | JSX.Element; default?: VanComponent | JSX.Element; route?: Pick<RouteEntry, "load" | "preload">; }; export type LazyComponent = Promise<DynamicModule>; /** * Registers a lazy component. * @param importFn */ export const lazy: (importFn: () => LazyComponent) => () => ComponentModule; /** * Fixes the URL of a route. * @param url */ export const fixRouteUrl: (url: string) => string;