@react5/dom-jsx 0.1.4 → 0.1.6
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/README.md +48 -9
- package/dist/index.js +1 -1
- package/dist/jsx-runtime.d.ts +13 -2
- package/dist/jsx-runtime.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,26 +24,33 @@ The runtime also works with Vite. Vite discovers the package's ESM `jsx-runtime`
|
|
|
24
24
|
Function components may return DOM nodes with an attached API:
|
|
25
25
|
|
|
26
26
|
```tsx
|
|
27
|
-
type
|
|
27
|
+
type ModalApi = { open(): void; close(): void }
|
|
28
28
|
|
|
29
29
|
function Modal() {
|
|
30
30
|
const element = <dialog /> as HTMLDialogElement
|
|
31
|
-
|
|
32
|
-
return Object.assign(element, {
|
|
31
|
+
const api: ModalApi = {
|
|
33
32
|
open: () => element.showModal(),
|
|
34
33
|
close: () => element.close()
|
|
35
|
-
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return Object.assign(element, { api }) satisfies
|
|
37
|
+
HTMLDialogElement & { api: ModalApi }
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
const modal = <Modal />
|
|
39
|
-
modal.open()
|
|
41
|
+
modal.api?.open()
|
|
40
42
|
```
|
|
41
43
|
|
|
42
44
|
TypeScript represents all JSX expressions with one `JSX.Element` type, so it
|
|
43
45
|
cannot preserve the exact intersection type of an individual component in
|
|
44
|
-
TSX. The library's JSX element type therefore
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
TSX. The library's JSX element type therefore allows an optional `api`
|
|
47
|
+
property, typed loosely as `Record<string, any>`, on every JSX result.
|
|
48
|
+
Accessing any other property directly on the node (e.g. a typo'd DOM
|
|
49
|
+
property) is still checked normally. `api` is optional because plain
|
|
50
|
+
intrinsic elements don't have one, so calling through it via `<Tag />` JSX
|
|
51
|
+
syntax needs `?.`. To get the component's exact, non-optional `api`
|
|
52
|
+
type instead, call the component directly or call `jsx(Modal, null)` /
|
|
53
|
+
`jsxDEV(Modal, null)`.
|
|
47
54
|
|
|
48
55
|
## Runtime behavior
|
|
49
56
|
|
|
@@ -52,7 +59,7 @@ Intrinsic JSX tags become DOM elements. `class` sets `className`, `style` accept
|
|
|
52
59
|
The public entry points are:
|
|
53
60
|
|
|
54
61
|
```ts
|
|
55
|
-
import { createRef, jsx, jsxs, Fragment } from '@react5/dom-jsx'
|
|
62
|
+
import { createRef, createContext, useContext, jsx, jsxs, Fragment } from '@react5/dom-jsx'
|
|
56
63
|
import { jsx, jsxs, jsxDEV, Fragment } from '@react5/dom-jsx/jsx-dev-runtime'
|
|
57
64
|
```
|
|
58
65
|
|
|
@@ -77,6 +84,38 @@ inputRef.current // HTMLInputElement
|
|
|
77
84
|
|
|
78
85
|
A callback ref (`ref={(el) => ...}`) is also supported and is invoked with the element once it's created.
|
|
79
86
|
|
|
87
|
+
### Context
|
|
88
|
+
|
|
89
|
+
Pass values down to nested components without threading props through every level:
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
import { createContext, useContext } from '@react5/dom-jsx'
|
|
93
|
+
|
|
94
|
+
const ThemeContext = createContext({ color: 'black' })
|
|
95
|
+
|
|
96
|
+
function Title(props: { text: string }) {
|
|
97
|
+
const theme = useContext(ThemeContext)
|
|
98
|
+
return <h1 style={{ color: theme.color }}>{props.text}</h1>
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const page = (
|
|
102
|
+
<ThemeContext.Provider value={{ color: 'red' }}>
|
|
103
|
+
{() => <Title text="Hello" />}
|
|
104
|
+
</ThemeContext.Provider>
|
|
105
|
+
)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
JSX in this runtime is evaluated eagerly from the inside out: children are
|
|
109
|
+
created before their parent component runs. A Provider's child must
|
|
110
|
+
therefore be a render function (`{() => ...}`); the Provider calls it while
|
|
111
|
+
its value is active, so every component rendered inside sees that value.
|
|
112
|
+
Providers can be nested, and the innermost value wins.
|
|
113
|
+
|
|
114
|
+
`useContext` returns the nearest Provider's value only while rendering is in
|
|
115
|
+
progress. Call it synchronously in a component body and keep the result.
|
|
116
|
+
Called later, for example from an event handler or a `setTimeout`, it
|
|
117
|
+
returns the context's default value.
|
|
118
|
+
|
|
80
119
|
## Development
|
|
81
120
|
|
|
82
121
|
```sh
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Fragment as r,
|
|
1
|
+
import{Fragment as r,createContext as m,createRef as o,jsx as t,jsxs as e,useContext as i}from"./jsx-runtime.js";export{r as Fragment,m as createContext,o as createRef,t as jsx,e as jsxs,i as useContext};
|
package/dist/jsx-runtime.d.ts
CHANGED
|
@@ -25,13 +25,24 @@ export type ElementProps<T extends HTMLElement> = Partial<Omit<T, 'children' | '
|
|
|
25
25
|
export declare function createRef<T>(): {
|
|
26
26
|
current: T | null;
|
|
27
27
|
};
|
|
28
|
+
export type ProviderProps<T> = {
|
|
29
|
+
value: T;
|
|
30
|
+
children: () => Child;
|
|
31
|
+
};
|
|
32
|
+
export type Context<T> = {
|
|
33
|
+
Provider: (props: ProviderProps<T>) => Node;
|
|
34
|
+
};
|
|
35
|
+
export declare function createContext<T>(defaultValue: T): Context<T>;
|
|
36
|
+
export declare function useContext<T>(context: Context<T>): T;
|
|
28
37
|
export declare namespace JSX {
|
|
29
|
-
type Element = Node &
|
|
38
|
+
type Element = Node & {
|
|
39
|
+
api?: Record<string, any>;
|
|
40
|
+
};
|
|
30
41
|
type IntrinsicElements = {
|
|
31
42
|
[K in keyof HTMLElementTagNameMap]: ElementProps<HTMLElementTagNameMap[K]>;
|
|
32
43
|
};
|
|
33
44
|
}
|
|
34
|
-
export declare function jsx<R extends Node>(tag: (props:
|
|
45
|
+
export declare function jsx<P, R extends Node>(tag: (props: P) => R, props: {} extends P ? P | null : P, _key?: string | number): R;
|
|
35
46
|
export declare function jsx(tag: string, props: Props | null, _key?: string | number): Node;
|
|
36
47
|
export declare const jsxs: typeof jsx;
|
|
37
48
|
export declare function Fragment(props: Props): DocumentFragment;
|
package/dist/jsx-runtime.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function e(){return{current:null}}function t(e,t,n){return function(e,t){const n=t??{};if("function"==typeof e)return e(n);const r=document.createElement(e);for(const[i
|
|
1
|
+
function e(){return{current:null}}var t=/* @__PURE__ */new WeakMap;function n(e){const n=[],r={Provider({value:e,children:t}){if("function"!=typeof t)throw new TypeError("Context Provider expects a single function child: {() => ...}");n.push(e);try{const e=t();if(e instanceof Node)return e;const n=document.createDocumentFragment();return s(n,e),n}finally{n.pop()}}};return t.set(r,{defaultValue:e,stack:n}),r}function r(e){const n=t.get(e);if(!n)throw new TypeError("useContext expects a context created by createContext");const{defaultValue:r,stack:o}=n;return o.length>0?o[o.length-1]:r}function o(e,t,n){return function(e,t){const n=t??{};if("function"==typeof e)return e(n);const r=document.createElement(e);for(const[c,i]of Object.entries(n))if("children"!==c&&"ref"!==c)if(c.startsWith("on")&&"function"==typeof i)r.addEventListener(c.slice(2).toLowerCase(),i);else if("class"!==c){if("style"===c&&i&&"object"==typeof i)Object.assign(r.style,i);else if(null!=i)if(c.includes("-"))r.setAttribute(c,String(i));else{if(c in r){if(!1===i)continue;try{r[c]=i;continue}catch{}}r.setAttribute(c,!0===i?"":String(i))}}else r.className=String(i??"");s(r,n.children);const o=n.ref;"function"==typeof o?o(r):o&&(o.current=r);return r}(e,t)}var c=o;function i(e){const t=document.createDocumentFragment();return s(t,e.children),t}function s(e,t){if(Array.isArray(t))for(const n of t)s(e,n);else t instanceof Node?e.appendChild(t):null!=t&&!1!==t&&!0!==t&&e.appendChild(document.createTextNode(String(t)))}export{i as Fragment,n as createContext,e as createRef,o as jsx,c as jsxs,r as useContext};
|