├── LICENSE
├── README.md
├── _examples
└── server.tsx
├── deno.jsonc
├── handlers.ts
├── import-map.json
├── init.ts
├── jsx.d.ts
├── mod.ts
├── setup.ts
└── styles.ts
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018-2022 the oak authors
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # nat
2 |
3 | A server side rendering framework for Deno CLI and Deploy.
4 |
5 | Incorporating [acorn](https://deno.land/x/acorn/),
6 | [nano-jsx](https://nanojsx.io/), and [twind](https://twind.dev/), it provides
7 | the tooling to provide a server centric framework for providing dynamic websites
8 | served from the edge.
9 |
10 | ## Getting started
11 |
12 | nat as a setup script which makes it easy to scaffold out a project and is the
13 | easiest way to get started. You will need the Deno CLI [installed]() locally and
14 | will want to run the following command within the current directory you want to
15 | setup:
16 |
17 | ```
18 | > deno run https://deno.land/x/nat/setup.ts
19 | ```
20 |
21 | The script will prompt you for read and write permissions to the current
22 | directory as well as ask for your confirmation to write out the initial setup
23 | files for the project.
24 |
25 | Once the project is setup, edit the `main.tsx` and use `deno task start` to run
26 | your server locally.
27 |
28 | You can also deploy the project to [Deno Deploy](https://dash.deno.com/new).
29 |
30 | ## Concepts
31 |
32 | The framework includes the acorn
33 | [Router](https://doc.deno.land/https://deno.land/x/acorn/mod.ts/~/Router). An
34 | instance of the router is returned from the
35 | [init()](https://doc.deno.land/https://deno.land/x/nat/mod.ts/~/init) function.
36 | The acorn router is based of web standard [URLPattern]() API which allows
37 | matching URLs and parsing out values to variables. Those variables are available
38 | in the handler's
39 | [context `.params` property](https://doc.deno.land/https://deno.land/x/acorn/mod.ts/~/Context#params).
40 |
41 | The framework comes with [nano-jsx](https://nanojsx.io/) built in, which makes
42 | it easy to server-side render JSX/TSX as a response.
43 |
44 | The framework also comes with [twind](https://twind.dev/) integrated which is
45 | well suited to server side rendering of tailwind's functional CSS styles in a
46 | super efficient way.
47 |
48 | ---
49 |
50 | Copyright 2022 the oak authors. All rights reserved. MIT License.
51 |
--------------------------------------------------------------------------------
/_examples/server.tsx:
--------------------------------------------------------------------------------
1 | /** @jsx h */
2 | /** @jsxFrag Fragment */
3 | import { createStyle, Fragment, h, init, render } from "../mod.ts";
4 |
5 | const router = init();
6 | const style = createStyle({
7 | title: "text-xl",
8 | });
9 |
10 | const App = ({ name }: { name: string }) => (
11 | <>
12 |
Hello {name}!
13 | >
14 | );
15 |
16 | router.get("/", render());
17 |
18 | router.listen();
19 |
--------------------------------------------------------------------------------
/deno.jsonc:
--------------------------------------------------------------------------------
1 | {
2 | "importMap": "./import-map.json",
3 | "tasks": {
4 | "example": "deno run --check --allow-net --allow-hrtime _examples/server.tsx"
5 | }
6 | }
--------------------------------------------------------------------------------
/handlers.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2022 the oak authors. All rights reserved. MIT License.
2 |
3 | /**
4 | * Handlers,
5 | * @module
6 | */
7 |
8 | import { Helmet } from "nano-jsx/helmet";
9 | import { renderSSR } from "nano-jsx/ssr";
10 | import { contentType } from "std/media_types";
11 | import { getStyleTag, virtualSheet } from "twind/sheets";
12 |
13 | export const sheet = virtualSheet();
14 |
15 | /** A handler function which renders JSX and send it to the client.
16 | *
17 | * ### Example
18 | *
19 | * ```ts
20 | * import { h, init, render } from "https://deno.land/x/nat/mod.ts";
21 | * import { App } from "./App.tsx";
22 | *
23 | * const router = init();
24 | * router.get("/", render());
25 | * router.listen();
26 | * ```
27 | */
28 | export function render(jsx: unknown) {
29 | return function handler() {
30 | sheet.reset();
31 | const page = renderSSR(jsx);
32 | const styles = getStyleTag(sheet);
33 | const {
34 | body,
35 | head,
36 | footer,
37 | attributes: { body: bodyAttributes, html: htmlAttributes },
38 | } = Helmet.SSR(page);
39 | return new Response(
40 | `
41 |
42 |
43 | ${styles}
44 | ${head.join("\n")}
45 |
46 |
47 | ${body}
48 | ${footer.join("\n")}
49 |
50 | `,
51 | {
52 | headers: {
53 | "content-type": contentType("text/html")!,
54 | },
55 | },
56 | );
57 | };
58 | }
59 |
--------------------------------------------------------------------------------
/import-map.json:
--------------------------------------------------------------------------------
1 | {
2 | "imports": {
3 | "acorn": "https://deno.land/x/acorn@0.0.10/mod.ts",
4 | "nano-jsx/core": "https://deno.land/x/nano_jsx@v0.0.30/core.ts",
5 | "nano-jsx/fragment": "https://deno.land/x/nano_jsx@v0.0.30/fragment.ts",
6 | "nano-jsx/helmet": "https://deno.land/x/nano_jsx@v0.0.30/components/helmet.ts",
7 | "nano-jsx/ssr": "https://deno.land/x/nano_jsx@v0.0.30/ssr.ts",
8 | "oak_commons/types": "https://deno.land/x/oak_commons@0.3.1/types.d.ts",
9 | "std/media_types": "https://deno.land/std@0.142.0/media_types/mod.ts",
10 | "twind": "https://esm.sh/twind@0.16.17?pin=v82",
11 | "twind/css": "https://esm.sh/twind@0.16.17/css?pin=v82",
12 | "twind/sheets": "https://esm.sh/twind@0.16.17/sheets?pin=v82"
13 | }
14 | }
--------------------------------------------------------------------------------
/init.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2022 the oak authors. All rights reserved. MIT License.
2 |
3 | /** Contains initialization and setup functionality.
4 | *
5 | * @module
6 | */
7 |
8 | import { Router } from "acorn";
9 | import { type Configuration as TwindConfig, setup } from "twind";
10 | import { type KeyRing } from "oak_commons/types";
11 |
12 | import { sheet } from "./handlers.ts";
13 |
14 | export interface StartOptions extends TwindConfig {
15 | /** A key ring which will be used for signing and validating cookies. */
16 | keys?: KeyRing;
17 | /** When providing internal responses, like on unhandled errors, prefer JSON
18 | * responses to HTML responses. When set to `false` HTML will be preferred
19 | * when responding, but content type negotiation will still be respected.
20 | * Defaults to `true`. */
21 | preferJson?: boolean;
22 | /** When `true` skip setting up default logging on the router. */
23 | quiet?: boolean;
24 | }
25 |
26 | /** Initialize the environment optionally using the provided options, returning
27 | * an instance of {@linkcode Router}.
28 | *
29 | * ### Example
30 | *
31 | * ```ts
32 | * import { init, render } from "https://deno.land/x/nat/mod.ts";
33 | * import { App } from "./App.tsx";
34 | *
35 | * const router = init();
36 | * router.get("/", render());
37 | *
38 | * router.listen();
39 | * ```
40 | */
41 | export function init(options: StartOptions = {}): Router {
42 | options.sheet = sheet;
43 | setup(options);
44 | const router = new Router(options);
45 | if (!options.quiet) {
46 | router.addEventListener(
47 | "listen",
48 | ({ secure, hostname, port }) =>
49 | console.log(
50 | `%cListening: %c${
51 | secure ? "https://" : "http://"
52 | }${hostname}:${port}`,
53 | "color:green;font-weight:bold;",
54 | "color:yellow",
55 | ),
56 | );
57 | router.addEventListener(
58 | "handled",
59 | (
60 | {
61 | response: { status },
62 | route,
63 | request: { url, method },
64 | measure: { duration },
65 | },
66 | ) => {
67 | const responseColor = status < 400
68 | ? "color:green"
69 | : status < 500
70 | ? "color:yellow"
71 | : "color:red";
72 | let path = route?.route;
73 | if (!path) {
74 | try {
75 | path = new URL(url).pathname;
76 | } catch {
77 | // just swallow errors here
78 | }
79 | }
80 | console.log(
81 | `%c${method} ${path} - [${status}] ${duration.toFixed(2)}ms`,
82 | responseColor,
83 | );
84 | },
85 | );
86 | }
87 | return router;
88 | }
89 |
--------------------------------------------------------------------------------
/jsx.d.ts:
--------------------------------------------------------------------------------
1 | // Copyright 2022 the oak authors. All rights reserved. MIT License.
2 |
3 | // deno-lint-ignore-file no-explicit-any ban-types no-empty-interface
4 |
5 | /**
6 | * Provides a scaffold of JSX types intended to be neutral to a specific JSX
7 | * implementation. Largely borrowed from [preact](https://preactjs.com/) type
8 | * definitions.
9 | *
10 | * @module
11 | */
12 |
13 | ///
14 | ///
15 | ///
16 | ///
17 | ///
18 | ///
19 |
20 | type Key = string | number | any;
21 |
22 | type Component = any;
23 |
24 | interface ComponentClass {
25 | new (props: P): Component;
26 | }
27 |
28 | type RefObject = { current: T | null };
29 | type RefCallback = (instance: T | null) => void;
30 | type Ref = RefObject | RefCallback;
31 |
32 | type RenderableProps =
33 | & P
34 | & Readonly }>;
35 |
36 | interface FunctionComponent {
37 | (props: RenderableProps
, context?: any): VNode | null;
38 | displayName?: string;
39 | defaultProps?: Partial;
40 | }
41 |
42 | type ComponentType
= ComponentClass
| FunctionComponent
;
43 |
44 | type ComponentChild = any;
45 |
46 | type ComponentChildren = ComponentChild[] | ComponentChild;
47 |
48 | interface VNode
{
49 | type: ComponentType
| string;
50 | props: P & { children: ComponentChildren };
51 | key: Key;
52 | ref?: Ref | null;
53 | }
54 |
55 | interface BaseDOMAttributes {
56 | children?: any;
57 | dangerouslySetInnerHTML?: {
58 | __html: string;
59 | };
60 | }
61 |
62 | interface Attributes {
63 | key?: Key;
64 | jsx?: boolean;
65 | }
66 |
67 | interface ClassAttributes extends Attributes {
68 | ref?: Ref;
69 | }
70 |
71 | type Defaultize =
72 | // Distribute over unions
73 | Props extends any // Make any properties included in Default optional
74 | ?
75 | & Partial>>
76 | & // Include the remaining properties from Props
77 | Pick>
78 | : never;
79 |
80 | declare namespace JSX {
81 | export type LibraryManagedAttributes = Component extends {
82 | defaultProps: infer Defaults;
83 | } ? Defaultize
84 | : Props;
85 |
86 | export interface IntrinsicAttributes {
87 | key?: any;
88 | }
89 |
90 | export interface Element extends VNode {}
91 |
92 | export interface ElementClass extends Component {}
93 |
94 | export interface ElementAttributesProperty {
95 | props: any;
96 | }
97 |
98 | export interface ElementChildrenAttribute {
99 | children: any;
100 | }
101 |
102 | export type DOMCSSProperties = {
103 | [
104 | key in keyof Omit<
105 | CSSStyleDeclaration,
106 | | "item"
107 | | "setProperty"
108 | | "removeProperty"
109 | | "getPropertyValue"
110 | | "getPropertyPriority"
111 | >
112 | ]?: string | number | null | undefined;
113 | };
114 | export type AllCSSProperties = {
115 | [key: string]: string | number | null | undefined;
116 | };
117 | export interface CSSProperties extends AllCSSProperties, DOMCSSProperties {
118 | cssText?: string | null;
119 | }
120 |
121 | export interface SVGAttributes
122 | extends HTMLAttributes {
123 | accentHeight?: number | string;
124 | accumulate?: "none" | "sum";
125 | additive?: "replace" | "sum";
126 | alignmentBaseline?:
127 | | "auto"
128 | | "baseline"
129 | | "before-edge"
130 | | "text-before-edge"
131 | | "middle"
132 | | "central"
133 | | "after-edge"
134 | | "text-after-edge"
135 | | "ideographic"
136 | | "alphabetic"
137 | | "hanging"
138 | | "mathematical"
139 | | "inherit";
140 | allowReorder?: "no" | "yes";
141 | alphabetic?: number | string;
142 | amplitude?: number | string;
143 | arabicForm?: "initial" | "medial" | "terminal" | "isolated";
144 | ascent?: number | string;
145 | attributeName?: string;
146 | attributeType?: string;
147 | autoReverse?: number | string;
148 | azimuth?: number | string;
149 | baseFrequency?: number | string;
150 | baselineShift?: number | string;
151 | baseProfile?: number | string;
152 | bbox?: number | string;
153 | begin?: number | string;
154 | bias?: number | string;
155 | by?: number | string;
156 | calcMode?: number | string;
157 | capHeight?: number | string;
158 | clip?: number | string;
159 | clipPath?: string;
160 | clipPathUnits?: number | string;
161 | clipRule?: number | string;
162 | colorInterpolation?: number | string;
163 | colorInterpolationFilters?: "auto" | "sRGB" | "linearRGB" | "inherit";
164 | colorProfile?: number | string;
165 | colorRendering?: number | string;
166 | contentScriptType?: number | string;
167 | contentStyleType?: number | string;
168 | cursor?: number | string;
169 | cx?: number | string;
170 | cy?: number | string;
171 | d?: string;
172 | decelerate?: number | string;
173 | descent?: number | string;
174 | diffuseConstant?: number | string;
175 | direction?: number | string;
176 | display?: number | string;
177 | divisor?: number | string;
178 | dominantBaseline?: number | string;
179 | dur?: number | string;
180 | dx?: number | string;
181 | dy?: number | string;
182 | edgeMode?: number | string;
183 | elevation?: number | string;
184 | enableBackground?: number | string;
185 | end?: number | string;
186 | exponent?: number | string;
187 | externalResourcesRequired?: number | string;
188 | fill?: string;
189 | fillOpacity?: number | string;
190 | fillRule?: "nonzero" | "evenodd" | "inherit";
191 | filter?: string;
192 | filterRes?: number | string;
193 | filterUnits?: number | string;
194 | floodColor?: number | string;
195 | floodOpacity?: number | string;
196 | focusable?: number | string;
197 | fontFamily?: string;
198 | fontSize?: number | string;
199 | fontSizeAdjust?: number | string;
200 | fontStretch?: number | string;
201 | fontStyle?: number | string;
202 | fontVariant?: number | string;
203 | fontWeight?: number | string;
204 | format?: number | string;
205 | from?: number | string;
206 | fx?: number | string;
207 | fy?: number | string;
208 | g1?: number | string;
209 | g2?: number | string;
210 | glyphName?: number | string;
211 | glyphOrientationHorizontal?: number | string;
212 | glyphOrientationVertical?: number | string;
213 | glyphRef?: number | string;
214 | gradientTransform?: string;
215 | gradientUnits?: string;
216 | hanging?: number | string;
217 | horizAdvX?: number | string;
218 | horizOriginX?: number | string;
219 | ideographic?: number | string;
220 | imageRendering?: number | string;
221 | in2?: number | string;
222 | in?: string;
223 | intercept?: number | string;
224 | k1?: number | string;
225 | k2?: number | string;
226 | k3?: number | string;
227 | k4?: number | string;
228 | k?: number | string;
229 | kernelMatrix?: number | string;
230 | kernelUnitLength?: number | string;
231 | kerning?: number | string;
232 | keyPoints?: number | string;
233 | keySplines?: number | string;
234 | keyTimes?: number | string;
235 | lengthAdjust?: number | string;
236 | letterSpacing?: number | string;
237 | lightingColor?: number | string;
238 | limitingConeAngle?: number | string;
239 | local?: number | string;
240 | markerEnd?: string;
241 | markerHeight?: number | string;
242 | markerMid?: string;
243 | markerStart?: string;
244 | markerUnits?: number | string;
245 | markerWidth?: number | string;
246 | mask?: string;
247 | maskContentUnits?: number | string;
248 | maskUnits?: number | string;
249 | mathematical?: number | string;
250 | mode?: number | string;
251 | numOctaves?: number | string;
252 | offset?: number | string;
253 | opacity?: number | string;
254 | operator?: number | string;
255 | order?: number | string;
256 | orient?: number | string;
257 | orientation?: number | string;
258 | origin?: number | string;
259 | overflow?: number | string;
260 | overlinePosition?: number | string;
261 | overlineThickness?: number | string;
262 | paintOrder?: number | string;
263 | panose1?: number | string;
264 | pathLength?: number | string;
265 | patternContentUnits?: string;
266 | patternTransform?: number | string;
267 | patternUnits?: string;
268 | pointerEvents?: number | string;
269 | points?: string;
270 | pointsAtX?: number | string;
271 | pointsAtY?: number | string;
272 | pointsAtZ?: number | string;
273 | preserveAlpha?: number | string;
274 | preserveAspectRatio?: string;
275 | primitiveUnits?: number | string;
276 | r?: number | string;
277 | radius?: number | string;
278 | refX?: number | string;
279 | refY?: number | string;
280 | renderingIntent?: number | string;
281 | repeatCount?: number | string;
282 | repeatDur?: number | string;
283 | requiredExtensions?: number | string;
284 | requiredFeatures?: number | string;
285 | restart?: number | string;
286 | result?: string;
287 | rotate?: number | string;
288 | rx?: number | string;
289 | ry?: number | string;
290 | scale?: number | string;
291 | seed?: number | string;
292 | shapeRendering?: number | string;
293 | slope?: number | string;
294 | spacing?: number | string;
295 | specularConstant?: number | string;
296 | specularExponent?: number | string;
297 | speed?: number | string;
298 | spreadMethod?: string;
299 | startOffset?: number | string;
300 | stdDeviation?: number | string;
301 | stemh?: number | string;
302 | stemv?: number | string;
303 | stitchTiles?: number | string;
304 | stopColor?: string;
305 | stopOpacity?: number | string;
306 | strikethroughPosition?: number | string;
307 | strikethroughThickness?: number | string;
308 | string?: number | string;
309 | stroke?: string;
310 | strokeDasharray?: string | number;
311 | strokeDashoffset?: string | number;
312 | strokeLinecap?: "butt" | "round" | "square" | "inherit";
313 | strokeLinejoin?: "miter" | "round" | "bevel" | "inherit";
314 | strokeMiterlimit?: string | number;
315 | strokeOpacity?: number | string;
316 | strokeWidth?: number | string;
317 | surfaceScale?: number | string;
318 | systemLanguage?: number | string;
319 | tableValues?: number | string;
320 | targetX?: number | string;
321 | targetY?: number | string;
322 | textAnchor?: string;
323 | textDecoration?: number | string;
324 | textLength?: number | string;
325 | textRendering?: number | string;
326 | to?: number | string;
327 | transform?: string;
328 | u1?: number | string;
329 | u2?: number | string;
330 | underlinePosition?: number | string;
331 | underlineThickness?: number | string;
332 | unicode?: number | string;
333 | unicodeBidi?: number | string;
334 | unicodeRange?: number | string;
335 | unitsPerEm?: number | string;
336 | vAlphabetic?: number | string;
337 | values?: string;
338 | vectorEffect?: number | string;
339 | version?: string;
340 | vertAdvY?: number | string;
341 | vertOriginX?: number | string;
342 | vertOriginY?: number | string;
343 | vHanging?: number | string;
344 | vIdeographic?: number | string;
345 | viewBox?: string;
346 | viewTarget?: number | string;
347 | visibility?: number | string;
348 | vMathematical?: number | string;
349 | widths?: number | string;
350 | wordSpacing?: number | string;
351 | writingMode?: number | string;
352 | x1?: number | string;
353 | x2?: number | string;
354 | x?: number | string;
355 | xChannelSelector?: string;
356 | xHeight?: number | string;
357 | xlinkActuate?: string;
358 | xlinkArcrole?: string;
359 | xlinkHref?: string;
360 | xlinkRole?: string;
361 | xlinkShow?: string;
362 | xlinkTitle?: string;
363 | xlinkType?: string;
364 | xmlBase?: string;
365 | xmlLang?: string;
366 | xmlns?: string;
367 | xmlnsXlink?: string;
368 | xmlSpace?: string;
369 | y1?: number | string;
370 | y2?: number | string;
371 | y?: number | string;
372 | yChannelSelector?: string;
373 | z?: number | string;
374 | zoomAndPan?: string;
375 | }
376 |
377 | export interface PathAttributes {
378 | d: string;
379 | }
380 |
381 | export type TargetedEvent<
382 | Target extends EventTarget = EventTarget,
383 | TypedEvent extends Event = Event,
384 | > = Omit & {
385 | readonly currentTarget: Target;
386 | };
387 |
388 | export type TargetedAnimationEvent<
389 | Target extends EventTarget,
390 | > = TargetedEvent;
391 | export type TargetedClipboardEvent<
392 | Target extends EventTarget,
393 | > = TargetedEvent;
394 | export type TargetedCompositionEvent<
395 | Target extends EventTarget,
396 | > = TargetedEvent;
397 | export type TargetedDragEvent = TargetedEvent<
398 | Target,
399 | DragEvent
400 | >;
401 | export type TargetedFocusEvent = TargetedEvent<
402 | Target,
403 | FocusEvent
404 | >;
405 | export type TargetedKeyboardEvent = TargetedEvent<
406 | Target,
407 | KeyboardEvent
408 | >;
409 | export type TargetedMouseEvent = TargetedEvent<
410 | Target,
411 | MouseEvent
412 | >;
413 | export type TargetedPointerEvent = TargetedEvent<
414 | Target,
415 | PointerEvent
416 | >;
417 | export type TargetedTouchEvent = TargetedEvent<
418 | Target,
419 | TouchEvent
420 | >;
421 | export type TargetedTransitionEvent<
422 | Target extends EventTarget,
423 | > = TargetedEvent;
424 | export type TargetedUIEvent = TargetedEvent<
425 | Target,
426 | UIEvent
427 | >;
428 | export type TargetedWheelEvent = TargetedEvent<
429 | Target,
430 | WheelEvent
431 | >;
432 |
433 | export interface EventHandler {
434 | /**
435 | * The `this` keyword always points to the DOM element the event handler
436 | * was invoked on. See: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Event_handlers#Event_handlers_parameters_this_binding_and_the_return_value
437 | */
438 | (this: never, event: E): void;
439 | }
440 |
441 | export type AnimationEventHandler = EventHandler<
442 | TargetedAnimationEvent
443 | >;
444 | export type ClipboardEventHandler = EventHandler<
445 | TargetedClipboardEvent
446 | >;
447 | export type CompositionEventHandler<
448 | Target extends EventTarget,
449 | > = EventHandler>;
450 | export type DragEventHandler = EventHandler<
451 | TargetedDragEvent
452 | >;
453 | export type FocusEventHandler = EventHandler<
454 | TargetedFocusEvent
455 | >;
456 | export type GenericEventHandler = EventHandler<
457 | TargetedEvent
458 | >;
459 | export type KeyboardEventHandler = EventHandler<
460 | TargetedKeyboardEvent
461 | >;
462 | export type MouseEventHandler = EventHandler<
463 | TargetedMouseEvent
464 | >;
465 | export type PointerEventHandler = EventHandler<
466 | TargetedPointerEvent
467 | >;
468 | export type TouchEventHandler = EventHandler<
469 | TargetedTouchEvent
470 | >;
471 | export type TransitionEventHandler = EventHandler<
472 | TargetedTransitionEvent
473 | >;
474 | export type UIEventHandler = EventHandler<
475 | TargetedUIEvent
476 | >;
477 | export type WheelEventHandler = EventHandler<
478 | TargetedWheelEvent
479 | >;
480 |
481 | export interface DOMAttributes
482 | extends BaseDOMAttributes {
483 | // Image Events
484 | onLoad?: GenericEventHandler;
485 | onLoadCapture?: GenericEventHandler;
486 | onError?: GenericEventHandler;
487 | onErrorCapture?: GenericEventHandler;
488 |
489 | // Clipboard Events
490 | onCopy?: ClipboardEventHandler;
491 | onCopyCapture?: ClipboardEventHandler;
492 | onCut?: ClipboardEventHandler;
493 | onCutCapture?: ClipboardEventHandler;
494 | onPaste?: ClipboardEventHandler;
495 | onPasteCapture?: ClipboardEventHandler;
496 |
497 | // Composition Events
498 | onCompositionEnd?: CompositionEventHandler;
499 | onCompositionEndCapture?: CompositionEventHandler;
500 | onCompositionStart?: CompositionEventHandler;
501 | onCompositionStartCapture?: CompositionEventHandler;
502 | onCompositionUpdate?: CompositionEventHandler;
503 | onCompositionUpdateCapture?: CompositionEventHandler;
504 |
505 | // Details Events
506 | onToggle?: GenericEventHandler;
507 |
508 | // Focus Events
509 | onFocus?: FocusEventHandler;
510 | onFocusCapture?: FocusEventHandler;
511 | onfocusin?: FocusEventHandler;
512 | onfocusinCapture?: FocusEventHandler;
513 | onfocusout?: FocusEventHandler;
514 | onfocusoutCapture?: FocusEventHandler;
515 | onBlur?: FocusEventHandler;
516 | onBlurCapture?: FocusEventHandler;
517 |
518 | // Form Events
519 | onChange?: GenericEventHandler;
520 | onChangeCapture?: GenericEventHandler;
521 | onInput?: GenericEventHandler;
522 | onInputCapture?: GenericEventHandler;
523 | onBeforeInput?: GenericEventHandler;
524 | onBeforeInputCapture?: GenericEventHandler;
525 | onSearch?: GenericEventHandler;
526 | onSearchCapture?: GenericEventHandler;
527 | onSubmit?: GenericEventHandler;
528 | onSubmitCapture?: GenericEventHandler;
529 | onInvalid?: GenericEventHandler;
530 | onInvalidCapture?: GenericEventHandler;
531 | onReset?: GenericEventHandler;
532 | onResetCapture?: GenericEventHandler;
533 | onFormData?: GenericEventHandler;
534 | onFormDataCapture?: GenericEventHandler;
535 |
536 | // Keyboard Events
537 | onKeyDown?: KeyboardEventHandler;
538 | onKeyDownCapture?: KeyboardEventHandler;
539 | onKeyPress?: KeyboardEventHandler;
540 | onKeyPressCapture?: KeyboardEventHandler;
541 | onKeyUp?: KeyboardEventHandler;
542 | onKeyUpCapture?: KeyboardEventHandler;
543 |
544 | // Media Events
545 | onAbort?: GenericEventHandler;
546 | onAbortCapture?: GenericEventHandler;
547 | onCanPlay?: GenericEventHandler;
548 | onCanPlayCapture?: GenericEventHandler;
549 | onCanPlayThrough?: GenericEventHandler;
550 | onCanPlayThroughCapture?: GenericEventHandler;
551 | onDurationChange?: GenericEventHandler;
552 | onDurationChangeCapture?: GenericEventHandler;
553 | onEmptied?: GenericEventHandler;
554 | onEmptiedCapture?: GenericEventHandler;
555 | onEncrypted?: GenericEventHandler;
556 | onEncryptedCapture?: GenericEventHandler;
557 | onEnded?: GenericEventHandler;
558 | onEndedCapture?: GenericEventHandler;
559 | onLoadedData?: GenericEventHandler;
560 | onLoadedDataCapture?: GenericEventHandler;
561 | onLoadedMetadata?: GenericEventHandler;
562 | onLoadedMetadataCapture?: GenericEventHandler;
563 | onLoadStart?: GenericEventHandler;
564 | onLoadStartCapture?: GenericEventHandler;
565 | onPause?: GenericEventHandler;
566 | onPauseCapture?: GenericEventHandler;
567 | onPlay?: GenericEventHandler;
568 | onPlayCapture?: GenericEventHandler;
569 | onPlaying?: GenericEventHandler;
570 | onPlayingCapture?: GenericEventHandler;
571 | onProgress?: GenericEventHandler;
572 | onProgressCapture?: GenericEventHandler;
573 | onRateChange?: GenericEventHandler;
574 | onRateChangeCapture?: GenericEventHandler;
575 | onSeeked?: GenericEventHandler;
576 | onSeekedCapture?: GenericEventHandler;
577 | onSeeking?: GenericEventHandler;
578 | onSeekingCapture?: GenericEventHandler;
579 | onStalled?: GenericEventHandler;
580 | onStalledCapture?: GenericEventHandler;
581 | onSuspend?: GenericEventHandler;
582 | onSuspendCapture?: GenericEventHandler;
583 | onTimeUpdate?: GenericEventHandler;
584 | onTimeUpdateCapture?: GenericEventHandler;
585 | onVolumeChange?: GenericEventHandler;
586 | onVolumeChangeCapture?: GenericEventHandler;
587 | onWaiting?: GenericEventHandler;
588 | onWaitingCapture?: GenericEventHandler;
589 |
590 | // MouseEvents
591 | onClick?: MouseEventHandler;
592 | onClickCapture?: MouseEventHandler;
593 | onContextMenu?: MouseEventHandler;
594 | onContextMenuCapture?: MouseEventHandler;
595 | onDblClick?: MouseEventHandler;
596 | onDblClickCapture?: MouseEventHandler;
597 | onDrag?: DragEventHandler;
598 | onDragCapture?: DragEventHandler;
599 | onDragEnd?: DragEventHandler;
600 | onDragEndCapture?: DragEventHandler;
601 | onDragEnter?: DragEventHandler;
602 | onDragEnterCapture?: DragEventHandler;
603 | onDragExit?: DragEventHandler;
604 | onDragExitCapture?: DragEventHandler;
605 | onDragLeave?: DragEventHandler;
606 | onDragLeaveCapture?: DragEventHandler;
607 | onDragOver?: DragEventHandler;
608 | onDragOverCapture?: DragEventHandler;
609 | onDragStart?: DragEventHandler;
610 | onDragStartCapture?: DragEventHandler;
611 | onDrop?: DragEventHandler;
612 | onDropCapture?: DragEventHandler;
613 | onMouseDown?: MouseEventHandler;
614 | onMouseDownCapture?: MouseEventHandler;
615 | onMouseEnter?: MouseEventHandler;
616 | onMouseEnterCapture?: MouseEventHandler;
617 | onMouseLeave?: MouseEventHandler;
618 | onMouseLeaveCapture?: MouseEventHandler;
619 | onMouseMove?: MouseEventHandler;
620 | onMouseMoveCapture?: MouseEventHandler;
621 | onMouseOut?: MouseEventHandler;
622 | onMouseOutCapture?: MouseEventHandler;
623 | onMouseOver?: MouseEventHandler;
624 | onMouseOverCapture?: MouseEventHandler;
625 | onMouseUp?: MouseEventHandler;
626 | onMouseUpCapture?: MouseEventHandler;
627 |
628 | // Selection Events
629 | onSelect?: GenericEventHandler;
630 | onSelectCapture?: GenericEventHandler;
631 |
632 | // Touch Events
633 | onTouchCancel?: TouchEventHandler;
634 | onTouchCancelCapture?: TouchEventHandler;
635 | onTouchEnd?: TouchEventHandler;
636 | onTouchEndCapture?: TouchEventHandler;
637 | onTouchMove?: TouchEventHandler;
638 | onTouchMoveCapture?: TouchEventHandler;
639 | onTouchStart?: TouchEventHandler;
640 | onTouchStartCapture?: TouchEventHandler;
641 |
642 | // Pointer Events
643 | onPointerOver?: PointerEventHandler;
644 | onPointerOverCapture?: PointerEventHandler;
645 | onPointerEnter?: PointerEventHandler;
646 | onPointerEnterCapture?: PointerEventHandler;
647 | onPointerDown?: PointerEventHandler;
648 | onPointerDownCapture?: PointerEventHandler;
649 | onPointerMove?: PointerEventHandler;
650 | onPointerMoveCapture?: PointerEventHandler;
651 | onPointerUp?: PointerEventHandler;
652 | onPointerUpCapture?: PointerEventHandler;
653 | onPointerCancel?: PointerEventHandler;
654 | onPointerCancelCapture?: PointerEventHandler;
655 | onPointerOut?: PointerEventHandler;
656 | onPointerOutCapture?: PointerEventHandler;
657 | onPointerLeave?: PointerEventHandler;
658 | onPointerLeaveCapture?: PointerEventHandler;
659 | onGotPointerCapture?: PointerEventHandler;
660 | onGotPointerCaptureCapture?: PointerEventHandler;
661 | onLostPointerCapture?: PointerEventHandler;
662 | onLostPointerCaptureCapture?: PointerEventHandler;
663 |
664 | // UI Events
665 | onScroll?: UIEventHandler;
666 | onScrollCapture?: UIEventHandler;
667 |
668 | // Wheel Events
669 | onWheel?: WheelEventHandler;
670 | onWheelCapture?: WheelEventHandler;
671 |
672 | // Animation Events
673 | onAnimationStart?: AnimationEventHandler;
674 | onAnimationStartCapture?: AnimationEventHandler;
675 | onAnimationEnd?: AnimationEventHandler;
676 | onAnimationEndCapture?: AnimationEventHandler;
677 | onAnimationIteration?: AnimationEventHandler;
678 | onAnimationIterationCapture?: AnimationEventHandler;
679 |
680 | // Transition Events
681 | onTransitionEnd?: TransitionEventHandler;
682 | onTransitionEndCapture?: TransitionEventHandler;
683 | }
684 |
685 | export interface HTMLAttributes
686 | extends ClassAttributes, DOMAttributes {
687 | // Standard HTML Attributes
688 | accept?: string;
689 | acceptCharset?: string;
690 | accessKey?: string;
691 | action?: string;
692 | allow?: string;
693 | allowFullScreen?: boolean;
694 | allowTransparency?: boolean;
695 | alt?: string;
696 | as?: string;
697 | async?: boolean;
698 | autocomplete?: string;
699 | autoComplete?: string;
700 | autocorrect?: string;
701 | autoCorrect?: string;
702 | autofocus?: boolean;
703 | autoFocus?: boolean;
704 | autoPlay?: boolean;
705 | capture?: boolean | string;
706 | cellPadding?: number | string;
707 | cellSpacing?: number | string;
708 | charSet?: string;
709 | challenge?: string;
710 | checked?: boolean;
711 | cite?: string;
712 | class?: string;
713 | className?: string;
714 | cols?: number;
715 | colSpan?: number;
716 | content?: string;
717 | contentEditable?: boolean;
718 | contextMenu?: string;
719 | controls?: boolean;
720 | controlsList?: string;
721 | coords?: string;
722 | crossOrigin?: string;
723 | data?: string;
724 | dateTime?: string;
725 | default?: boolean;
726 | defaultChecked?: boolean;
727 | defaultValue?: string;
728 | defer?: boolean;
729 | dir?: "auto" | "rtl" | "ltr";
730 | disabled?: boolean;
731 | disableRemotePlayback?: boolean;
732 | download?: any;
733 | decoding?: "sync" | "async" | "auto";
734 | draggable?: boolean;
735 | encType?: string;
736 | enterkeyhint?:
737 | | "enter"
738 | | "done"
739 | | "go"
740 | | "next"
741 | | "previous"
742 | | "search"
743 | | "send";
744 | form?: string;
745 | formAction?: string;
746 | formEncType?: string;
747 | formMethod?: string;
748 | formNoValidate?: boolean;
749 | formTarget?: string;
750 | frameBorder?: number | string;
751 | headers?: string;
752 | height?: number | string;
753 | hidden?: boolean;
754 | high?: number;
755 | href?: string;
756 | hrefLang?: string;
757 | for?: string;
758 | htmlFor?: string;
759 | httpEquiv?: string;
760 | icon?: string;
761 | id?: string;
762 | inputMode?: string;
763 | integrity?: string;
764 | is?: string;
765 | keyParams?: string;
766 | keyType?: string;
767 | kind?: string;
768 | label?: string;
769 | lang?: string;
770 | list?: string;
771 | loading?: "eager" | "lazy";
772 | loop?: boolean;
773 | low?: number;
774 | manifest?: string;
775 | marginHeight?: number;
776 | marginWidth?: number;
777 | max?: number | string;
778 | maxLength?: number;
779 | media?: string;
780 | mediaGroup?: string;
781 | method?: string;
782 | min?: number | string;
783 | minLength?: number;
784 | multiple?: boolean;
785 | muted?: boolean;
786 | name?: string;
787 | nomodule?: boolean;
788 | nonce?: string;
789 | noValidate?: boolean;
790 | open?: boolean;
791 | optimum?: number;
792 | pattern?: string;
793 | ping?: string;
794 | placeholder?: string;
795 | playsInline?: boolean;
796 | poster?: string;
797 | preload?: string;
798 | radioGroup?: string;
799 | readonly?: boolean;
800 | readOnly?: boolean;
801 | referrerpolicy?:
802 | | "no-referrer"
803 | | "no-referrer-when-downgrade"
804 | | "origin"
805 | | "origin-when-cross-origin"
806 | | "same-origin"
807 | | "strict-origin"
808 | | "strict-origin-when-cross-origin"
809 | | "unsafe-url";
810 | rel?: string;
811 | required?: boolean;
812 | reversed?: boolean;
813 | role?: string;
814 | rows?: number;
815 | rowSpan?: number;
816 | sandbox?: string;
817 | scope?: string;
818 | scoped?: boolean;
819 | scrolling?: string;
820 | seamless?: boolean;
821 | selected?: boolean;
822 | shape?: string;
823 | size?: number;
824 | sizes?: string;
825 | slot?: string;
826 | span?: number;
827 | spellcheck?: boolean;
828 | spellCheck?: boolean;
829 | src?: string;
830 | srcset?: string;
831 | srcDoc?: string;
832 | srcLang?: string;
833 | srcSet?: string;
834 | start?: number;
835 | step?: number | string;
836 | style?: string | CSSProperties;
837 | summary?: string;
838 | tabIndex?: number;
839 | target?: string;
840 | title?: string;
841 | type?: string;
842 | useMap?: string;
843 | value?: string | string[] | number;
844 | volume?: string | number;
845 | width?: number | string;
846 | wmode?: string;
847 | wrap?: string;
848 |
849 | // Non-standard Attributes
850 | autocapitalize?:
851 | | "off"
852 | | "none"
853 | | "on"
854 | | "sentences"
855 | | "words"
856 | | "characters";
857 | autoCapitalize?:
858 | | "off"
859 | | "none"
860 | | "on"
861 | | "sentences"
862 | | "words"
863 | | "characters";
864 | disablePictureInPicture?: boolean;
865 | results?: number;
866 | translate?: "yes" | "no";
867 |
868 | // RDFa Attributes
869 | about?: string;
870 | datatype?: string;
871 | inlist?: any;
872 | prefix?: string;
873 | property?: string;
874 | resource?: string;
875 | typeof?: string;
876 | vocab?: string;
877 |
878 | // Microdata Attributes
879 | itemProp?: string;
880 | itemScope?: boolean;
881 | itemType?: string;
882 | itemID?: string;
883 | itemRef?: string;
884 | }
885 |
886 | export type DetailedHTMLProps<
887 | HA extends HTMLAttributes,
888 | RefType extends EventTarget = EventTarget,
889 | > = HA;
890 |
891 | export interface HTMLMarqueeElement extends HTMLElement {
892 | behavior?: "scroll" | "slide" | "alternate";
893 | bgColor?: string;
894 | direction?: "left" | "right" | "up" | "down";
895 | height?: number | string;
896 | hspace?: number | string;
897 | loop?: number | string;
898 | scrollAmount?: number | string;
899 | scrollDelay?: number | string;
900 | trueSpeed?: boolean;
901 | vspace?: number | string;
902 | width?: number | string;
903 | }
904 |
905 | export interface IntrinsicElements {
906 | // HTML
907 | a: HTMLAttributes;
908 | abbr: HTMLAttributes;
909 | address: HTMLAttributes;
910 | area: HTMLAttributes;
911 | article: HTMLAttributes;
912 | aside: HTMLAttributes;
913 | audio: HTMLAttributes;
914 | b: HTMLAttributes;
915 | base: HTMLAttributes;
916 | bdi: HTMLAttributes;
917 | bdo: HTMLAttributes;
918 | big: HTMLAttributes;
919 | blockquote: HTMLAttributes;
920 | body: HTMLAttributes;
921 | br: HTMLAttributes;
922 | button: HTMLAttributes;
923 | canvas: HTMLAttributes;
924 | caption: HTMLAttributes;
925 | cite: HTMLAttributes