Latest repo

This commit is contained in:
Marc
2025-06-02 16:42:16 +00:00
parent 53ddf1a329
commit cde5fae175
27907 changed files with 3875388 additions and 1 deletions

18
node_modules/hast-util-to-jsx-runtime/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,18 @@
export type {
Components,
CreateEvaluater,
ElementAttributeNameCase,
EvaluateExpression,
EvaluateProgram,
Evaluater,
ExtraProps,
Fragment,
Jsx,
JsxDev,
Options,
Props,
Source,
Space,
StylePropertyNameCase
} from './lib/types.js'
export {toJsxRuntime} from './lib/index.js'

2
node_modules/hast-util-to-jsx-runtime/index.js generated vendored Normal file
View File

@@ -0,0 +1,2 @@
// Note: types exposed from `index.d.ts`.
export {toJsxRuntime} from './lib/index.js'

16
node_modules/hast-util-to-jsx-runtime/lib/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,16 @@
/**
* Transform a hast tree to preact, react, solid, svelte, vue, etc.,
* with an automatic JSX runtime.
*
* @param {Nodes} tree
* Tree to transform.
* @param {Options} options
* Configuration (required).
* @returns {JsxElement}
* JSX element.
*/
export function toJsxRuntime(tree: Nodes, options: Options): JsxElement;
import type { Nodes } from 'hast';
import type { Options } from 'hast-util-to-jsx-runtime';
import type { JsxElement } from './types.js';
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.js"],"names":[],"mappings":"AA8CA;;;;;;;;;;GAUG;AAEH,mCARW,KAAK,WAEL,OAAO,GAEL,UAAU,CAgEtB;2BAnHqD,MAAM;6BADd,0BAA0B;gCAMP,YAAY"}

787
node_modules/hast-util-to-jsx-runtime/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1,787 @@
/**
* @import {Identifier, Literal, MemberExpression} from 'estree'
* @import {Jsx, JsxDev, Options, Props} from 'hast-util-to-jsx-runtime'
* @import {Element, Nodes, Parents, Root, Text} from 'hast'
* @import {MdxFlowExpressionHast, MdxTextExpressionHast} from 'mdast-util-mdx-expression'
* @import {MdxJsxFlowElementHast, MdxJsxTextElementHast} from 'mdast-util-mdx-jsx'
* @import {MdxjsEsmHast} from 'mdast-util-mdxjs-esm'
* @import {Position} from 'unist'
* @import {Child, Create, Field, JsxElement, State, Style} from './types.js'
*/
import {stringify as commas} from 'comma-separated-tokens'
import {ok as assert} from 'devlop'
import {name as isIdentifierName} from 'estree-util-is-identifier-name'
import {whitespace} from 'hast-util-whitespace'
import {find, hastToReact, html, svg} from 'property-information'
import {stringify as spaces} from 'space-separated-tokens'
import styleToJs from 'style-to-js'
import {pointStart} from 'unist-util-position'
import {VFileMessage} from 'vfile-message'
// To do: next major: `Object.hasOwn`.
const own = {}.hasOwnProperty
/** @type {Map<string, number>} */
const emptyMap = new Map()
const cap = /[A-Z]/g
// `react-dom` triggers a warning for *any* white space in tables.
// To follow GFM, `mdast-util-to-hast` injects line endings between elements.
// Other tools might do so too, but they dont do here, so we remove all of
// that.
// See: <https://github.com/facebook/react/pull/7081>.
// See: <https://github.com/facebook/react/pull/7515>.
// See: <https://github.com/remarkjs/remark-react/issues/64>.
// See: <https://github.com/rehypejs/rehype-react/pull/29>.
// See: <https://github.com/rehypejs/rehype-react/pull/32>.
// See: <https://github.com/rehypejs/rehype-react/pull/45>.
const tableElements = new Set(['table', 'tbody', 'thead', 'tfoot', 'tr'])
const tableCellElement = new Set(['td', 'th'])
const docs = 'https://github.com/syntax-tree/hast-util-to-jsx-runtime'
/**
* Transform a hast tree to preact, react, solid, svelte, vue, etc.,
* with an automatic JSX runtime.
*
* @param {Nodes} tree
* Tree to transform.
* @param {Options} options
* Configuration (required).
* @returns {JsxElement}
* JSX element.
*/
export function toJsxRuntime(tree, options) {
if (!options || options.Fragment === undefined) {
throw new TypeError('Expected `Fragment` in options')
}
const filePath = options.filePath || undefined
/** @type {Create} */
let create
if (options.development) {
if (typeof options.jsxDEV !== 'function') {
throw new TypeError(
'Expected `jsxDEV` in options when `development: true`'
)
}
create = developmentCreate(filePath, options.jsxDEV)
} else {
if (typeof options.jsx !== 'function') {
throw new TypeError('Expected `jsx` in production options')
}
if (typeof options.jsxs !== 'function') {
throw new TypeError('Expected `jsxs` in production options')
}
create = productionCreate(filePath, options.jsx, options.jsxs)
}
/** @type {State} */
const state = {
Fragment: options.Fragment,
ancestors: [],
components: options.components || {},
create,
elementAttributeNameCase: options.elementAttributeNameCase || 'react',
evaluater: options.createEvaluater ? options.createEvaluater() : undefined,
filePath,
ignoreInvalidStyle: options.ignoreInvalidStyle || false,
passKeys: options.passKeys !== false,
passNode: options.passNode || false,
schema: options.space === 'svg' ? svg : html,
stylePropertyNameCase: options.stylePropertyNameCase || 'dom',
tableCellAlignToStyle: options.tableCellAlignToStyle !== false
}
const result = one(state, tree, undefined)
// JSX element.
if (result && typeof result !== 'string') {
return result
}
// Text node or something that turned into nothing.
return state.create(
tree,
state.Fragment,
{children: result || undefined},
undefined
)
}
/**
* Transform a node.
*
* @param {State} state
* Info passed around.
* @param {Nodes} node
* Current node.
* @param {string | undefined} key
* Key.
* @returns {Child | undefined}
* Child, optional.
*/
function one(state, node, key) {
if (node.type === 'element') {
return element(state, node, key)
}
if (node.type === 'mdxFlowExpression' || node.type === 'mdxTextExpression') {
return mdxExpression(state, node)
}
if (node.type === 'mdxJsxFlowElement' || node.type === 'mdxJsxTextElement') {
return mdxJsxElement(state, node, key)
}
if (node.type === 'mdxjsEsm') {
return mdxEsm(state, node)
}
if (node.type === 'root') {
return root(state, node, key)
}
if (node.type === 'text') {
return text(state, node)
}
}
/**
* Handle element.
*
* @param {State} state
* Info passed around.
* @param {Element} node
* Current node.
* @param {string | undefined} key
* Key.
* @returns {Child | undefined}
* Child, optional.
*/
function element(state, node, key) {
const parentSchema = state.schema
let schema = parentSchema
if (node.tagName.toLowerCase() === 'svg' && parentSchema.space === 'html') {
schema = svg
state.schema = schema
}
state.ancestors.push(node)
const type = findComponentFromName(state, node.tagName, false)
const props = createElementProps(state, node)
let children = createChildren(state, node)
if (tableElements.has(node.tagName)) {
children = children.filter(function (child) {
return typeof child === 'string' ? !whitespace(child) : true
})
}
addNode(state, props, type, node)
addChildren(props, children)
// Restore.
state.ancestors.pop()
state.schema = parentSchema
return state.create(node, type, props, key)
}
/**
* Handle MDX expression.
*
* @param {State} state
* Info passed around.
* @param {MdxFlowExpressionHast | MdxTextExpressionHast} node
* Current node.
* @returns {Child | undefined}
* Child, optional.
*/
function mdxExpression(state, node) {
if (node.data && node.data.estree && state.evaluater) {
const program = node.data.estree
const expression = program.body[0]
assert(expression.type === 'ExpressionStatement')
// Assume result is a child.
return /** @type {Child | undefined} */ (
state.evaluater.evaluateExpression(expression.expression)
)
}
crashEstree(state, node.position)
}
/**
* Handle MDX ESM.
*
* @param {State} state
* Info passed around.
* @param {MdxjsEsmHast} node
* Current node.
* @returns {Child | undefined}
* Child, optional.
*/
function mdxEsm(state, node) {
if (node.data && node.data.estree && state.evaluater) {
// Assume result is a child.
return /** @type {Child | undefined} */ (
state.evaluater.evaluateProgram(node.data.estree)
)
}
crashEstree(state, node.position)
}
/**
* Handle MDX JSX.
*
* @param {State} state
* Info passed around.
* @param {MdxJsxFlowElementHast | MdxJsxTextElementHast} node
* Current node.
* @param {string | undefined} key
* Key.
* @returns {Child | undefined}
* Child, optional.
*/
function mdxJsxElement(state, node, key) {
const parentSchema = state.schema
let schema = parentSchema
if (node.name === 'svg' && parentSchema.space === 'html') {
schema = svg
state.schema = schema
}
state.ancestors.push(node)
const type =
node.name === null
? state.Fragment
: findComponentFromName(state, node.name, true)
const props = createJsxElementProps(state, node)
const children = createChildren(state, node)
addNode(state, props, type, node)
addChildren(props, children)
// Restore.
state.ancestors.pop()
state.schema = parentSchema
return state.create(node, type, props, key)
}
/**
* Handle root.
*
* @param {State} state
* Info passed around.
* @param {Root} node
* Current node.
* @param {string | undefined} key
* Key.
* @returns {Child | undefined}
* Child, optional.
*/
function root(state, node, key) {
/** @type {Props} */
const props = {}
addChildren(props, createChildren(state, node))
return state.create(node, state.Fragment, props, key)
}
/**
* Handle text.
*
* @param {State} _
* Info passed around.
* @param {Text} node
* Current node.
* @returns {Child | undefined}
* Child, optional.
*/
function text(_, node) {
return node.value
}
/**
* Add `node` to props.
*
* @param {State} state
* Info passed around.
* @param {Props} props
* Props.
* @param {unknown} type
* Type.
* @param {Element | MdxJsxFlowElementHast | MdxJsxTextElementHast} node
* Node.
* @returns {undefined}
* Nothing.
*/
function addNode(state, props, type, node) {
// If this is swapped out for a component:
if (typeof type !== 'string' && type !== state.Fragment && state.passNode) {
props.node = node
}
}
/**
* Add children to props.
*
* @param {Props} props
* Props.
* @param {Array<Child>} children
* Children.
* @returns {undefined}
* Nothing.
*/
function addChildren(props, children) {
if (children.length > 0) {
const value = children.length > 1 ? children : children[0]
if (value) {
props.children = value
}
}
}
/**
* @param {string | undefined} _
* Path to file.
* @param {Jsx} jsx
* Dynamic.
* @param {Jsx} jsxs
* Static.
* @returns {Create}
* Create a production element.
*/
function productionCreate(_, jsx, jsxs) {
return create
/** @type {Create} */
function create(_, type, props, key) {
// Only an array when there are 2 or more children.
const isStaticChildren = Array.isArray(props.children)
const fn = isStaticChildren ? jsxs : jsx
return key ? fn(type, props, key) : fn(type, props)
}
}
/**
* @param {string | undefined} filePath
* Path to file.
* @param {JsxDev} jsxDEV
* Development.
* @returns {Create}
* Create a development element.
*/
function developmentCreate(filePath, jsxDEV) {
return create
/** @type {Create} */
function create(node, type, props, key) {
// Only an array when there are 2 or more children.
const isStaticChildren = Array.isArray(props.children)
const point = pointStart(node)
return jsxDEV(
type,
props,
key,
isStaticChildren,
{
columnNumber: point ? point.column - 1 : undefined,
fileName: filePath,
lineNumber: point ? point.line : undefined
},
undefined
)
}
}
/**
* Create props from an element.
*
* @param {State} state
* Info passed around.
* @param {Element} node
* Current element.
* @returns {Props}
* Props.
*/
function createElementProps(state, node) {
/** @type {Props} */
const props = {}
/** @type {string | undefined} */
let alignValue
/** @type {string} */
let prop
for (prop in node.properties) {
if (prop !== 'children' && own.call(node.properties, prop)) {
const result = createProperty(state, prop, node.properties[prop])
if (result) {
const [key, value] = result
if (
state.tableCellAlignToStyle &&
key === 'align' &&
typeof value === 'string' &&
tableCellElement.has(node.tagName)
) {
alignValue = value
} else {
props[key] = value
}
}
}
}
if (alignValue) {
// Assume style is an object.
const style = /** @type {Style} */ (props.style || (props.style = {}))
style[state.stylePropertyNameCase === 'css' ? 'text-align' : 'textAlign'] =
alignValue
}
return props
}
/**
* Create props from a JSX element.
*
* @param {State} state
* Info passed around.
* @param {MdxJsxFlowElementHast | MdxJsxTextElementHast} node
* Current JSX element.
* @returns {Props}
* Props.
*/
function createJsxElementProps(state, node) {
/** @type {Props} */
const props = {}
for (const attribute of node.attributes) {
if (attribute.type === 'mdxJsxExpressionAttribute') {
if (attribute.data && attribute.data.estree && state.evaluater) {
const program = attribute.data.estree
const expression = program.body[0]
assert(expression.type === 'ExpressionStatement')
const objectExpression = expression.expression
assert(objectExpression.type === 'ObjectExpression')
const property = objectExpression.properties[0]
assert(property.type === 'SpreadElement')
Object.assign(
props,
state.evaluater.evaluateExpression(property.argument)
)
} else {
crashEstree(state, node.position)
}
} else {
// For JSX, the author is responsible of passing in the correct values.
const name = attribute.name
/** @type {unknown} */
let value
if (attribute.value && typeof attribute.value === 'object') {
if (
attribute.value.data &&
attribute.value.data.estree &&
state.evaluater
) {
const program = attribute.value.data.estree
const expression = program.body[0]
assert(expression.type === 'ExpressionStatement')
value = state.evaluater.evaluateExpression(expression.expression)
} else {
crashEstree(state, node.position)
}
} else {
value = attribute.value === null ? true : attribute.value
}
// Assume a prop.
props[name] = /** @type {Props[keyof Props]} */ (value)
}
}
return props
}
/**
* Create children.
*
* @param {State} state
* Info passed around.
* @param {Parents} node
* Current element.
* @returns {Array<Child>}
* Children.
*/
function createChildren(state, node) {
/** @type {Array<Child>} */
const children = []
let index = -1
/** @type {Map<string, number>} */
// Note: test this when Solid doesnt want to merge my upcoming PR.
/* c8 ignore next */
const countsByName = state.passKeys ? new Map() : emptyMap
while (++index < node.children.length) {
const child = node.children[index]
/** @type {string | undefined} */
let key
if (state.passKeys) {
const name =
child.type === 'element'
? child.tagName
: child.type === 'mdxJsxFlowElement' ||
child.type === 'mdxJsxTextElement'
? child.name
: undefined
if (name) {
const count = countsByName.get(name) || 0
key = name + '-' + count
countsByName.set(name, count + 1)
}
}
const result = one(state, child, key)
if (result !== undefined) children.push(result)
}
return children
}
/**
* Handle a property.
*
* @param {State} state
* Info passed around.
* @param {string} prop
* Key.
* @param {Array<number | string> | boolean | number | string | null | undefined} value
* hast property value.
* @returns {Field | undefined}
* Field for runtime, optional.
*/
function createProperty(state, prop, value) {
const info = find(state.schema, prop)
// Ignore nullish and `NaN` values.
if (
value === null ||
value === undefined ||
(typeof value === 'number' && Number.isNaN(value))
) {
return
}
if (Array.isArray(value)) {
// Accept `array`.
// Most props are space-separated.
value = info.commaSeparated ? commas(value) : spaces(value)
}
// React only accepts `style` as object.
if (info.property === 'style') {
let styleObject =
typeof value === 'object' ? value : parseStyle(state, String(value))
if (state.stylePropertyNameCase === 'css') {
styleObject = transformStylesToCssCasing(styleObject)
}
return ['style', styleObject]
}
return [
state.elementAttributeNameCase === 'react' && info.space
? hastToReact[info.property] || info.property
: info.attribute,
value
]
}
/**
* Parse a CSS declaration to an object.
*
* @param {State} state
* Info passed around.
* @param {string} value
* CSS declarations.
* @returns {Style}
* Properties.
* @throws
* Throws `VFileMessage` when CSS cannot be parsed.
*/
function parseStyle(state, value) {
try {
return styleToJs(value, {reactCompat: true})
} catch (error) {
if (state.ignoreInvalidStyle) {
return {}
}
const cause = /** @type {Error} */ (error)
const message = new VFileMessage('Cannot parse `style` attribute', {
ancestors: state.ancestors,
cause,
ruleId: 'style',
source: 'hast-util-to-jsx-runtime'
})
message.file = state.filePath || undefined
message.url = docs + '#cannot-parse-style-attribute'
throw message
}
}
/**
* Create a JSX name from a string.
*
* @param {State} state
* To do.
* @param {string} name
* Name.
* @param {boolean} allowExpression
* Allow member expressions and identifiers.
* @returns {unknown}
* To do.
*/
function findComponentFromName(state, name, allowExpression) {
/** @type {Identifier | Literal | MemberExpression} */
let result
if (!allowExpression) {
result = {type: 'Literal', value: name}
} else if (name.includes('.')) {
const identifiers = name.split('.')
let index = -1
/** @type {Identifier | Literal | MemberExpression | undefined} */
let node
while (++index < identifiers.length) {
/** @type {Identifier | Literal} */
const prop = isIdentifierName(identifiers[index])
? {type: 'Identifier', name: identifiers[index]}
: {type: 'Literal', value: identifiers[index]}
node = node
? {
type: 'MemberExpression',
object: node,
property: prop,
computed: Boolean(index && prop.type === 'Literal'),
optional: false
}
: prop
}
assert(node, 'always a result')
result = node
} else {
result =
isIdentifierName(name) && !/^[a-z]/.test(name)
? {type: 'Identifier', name}
: {type: 'Literal', value: name}
}
// Only literals can be passed in `components` currently.
// No identifiers / member expressions.
if (result.type === 'Literal') {
const name = /** @type {string | number} */ (result.value)
return own.call(state.components, name) ? state.components[name] : name
}
// Assume component.
if (state.evaluater) {
return state.evaluater.evaluateExpression(result)
}
crashEstree(state)
}
/**
* @param {State} state
* @param {Position | undefined} [place]
* @returns {never}
*/
function crashEstree(state, place) {
const message = new VFileMessage(
'Cannot handle MDX estrees without `createEvaluater`',
{
ancestors: state.ancestors,
place,
ruleId: 'mdx-estree',
source: 'hast-util-to-jsx-runtime'
}
)
message.file = state.filePath || undefined
message.url = docs + '#cannot-handle-mdx-estrees-without-createevaluater'
throw message
}
/**
* Transform a DOM casing style object to a CSS casing style object.
*
* @param {Style} domCasing
* @returns {Style}
*/
function transformStylesToCssCasing(domCasing) {
/** @type {Style} */
const cssCasing = {}
/** @type {string} */
let from
for (from in domCasing) {
if (own.call(domCasing, from)) {
cssCasing[transformStyleToCssCasing(from)] = domCasing[from]
}
}
return cssCasing
}
/**
* Transform a DOM casing style field to a CSS casing style field.
*
* @param {string} from
* @returns {string}
*/
function transformStyleToCssCasing(from) {
let to = from.replace(cap, toDash)
// Handle `ms-xxx` -> `-ms-xxx`.
if (to.slice(0, 3) === 'ms-') to = '-' + to
return to
}
/**
* Make `$0` dash cased.
*
* @param {string} $0
* Capitalized ASCII leter.
* @returns {string}
* Dash and lower letter.
*/
function toDash($0) {
return '-' + $0.toLowerCase()
}

446
node_modules/hast-util-to-jsx-runtime/lib/types.d.ts generated vendored Normal file
View File

@@ -0,0 +1,446 @@
import type {Expression, Program} from 'estree'
import type {Element, Nodes, Parents} from 'hast'
import type {
MdxJsxFlowElementHast,
MdxJsxTextElementHast
} from 'mdast-util-mdx-jsx'
import type {Schema} from 'property-information'
/**
* Child.
*/
export type Child = JsxElement | string | null | undefined
/**
* Possible components to use.
*
* Each key is a tag name typed in `JSX.IntrinsicElements`.
* Each value is either a different tag name, or a component accepting the
* corresponding props (and an optional `node` prop if `passNode` is on).
*
* You can access props at `JSX.IntrinsicElements`.
* For example, to find props for `a`, use `JSX.IntrinsicElements['a']`.
*/
// Note: this type has to be in `.ts` or `.d.ts`, otherwise TSC hardcodes
// react into the `.d.ts` file.
export type Components = {
[TagName in keyof JsxIntrinsicElements]:
| Component<JsxIntrinsicElements[TagName] & ExtraProps>
| keyof JsxIntrinsicElements
}
/**
* Function or class component.
*
* You can access props at `JsxIntrinsicElements`.
* For example, to find props for `a`, use `JsxIntrinsicElements['a']`.
*
* @typeParam ComponentProps
* Props type.
*/
type Component<ComponentProps> =
| ClassComponent<ComponentProps>
| FunctionComponent<ComponentProps>
/**
* Create an evaluator that turns ESTree ASTs from embedded MDX into values.
*/
export type CreateEvaluater = () => Evaluater
/**
* Create something in development or production.
*/
export type Create = (
node: Nodes,
type: unknown,
props: Props,
key: string | undefined
) => JsxElement
/**
* Class component: given props, returns an instance.
*
* @typeParam ComponentProps
* Props type.
* @param props
* Props.
* @returns
* Instance.
*/
type ClassComponent<ComponentProps> = new (
props: ComponentProps
) => JsxElementClass
/**
* Casing to use for attribute names.
*
* HTML casing is for example `class`, `stroke-linecap`, `xml:lang`.
* React casing is for example `className`, `strokeLinecap`, `xmlLang`.
*/
export type ElementAttributeNameCase = 'html' | 'react'
/**
* Turn an MDX expression into a value.
*/
export type EvaluateExpression = (expression: Expression) => unknown
/**
* Turn an MDX program (export/import statements) into a value.
*/
export type EvaluateProgram = (expression: Program) => unknown
/**
* Evaluator that turns ESTree ASTs from embedded MDX into values.
*/
export interface Evaluater {
/**
* Evaluate an expression.
*/
evaluateExpression: EvaluateExpression
/**
* Evaluate a program.
*/
evaluateProgram: EvaluateProgram
}
/**
* Extra fields we pass.
*/
export interface ExtraProps {
/**
* Node (hast),
* passed when `passNode` is on.
*/
node?: Element | undefined
}
/**
* Property field.
*/
export type Field = [string, Value]
/**
* Represent the children, typically a symbol.
*/
export type Fragment = unknown
/**
* Basic functional component: given props, returns an element.
*
* @typeParam ComponentProps
* Props type.
* @param props
* Props.
* @returns
* Result.
*/
type FunctionComponent<ComponentProps> = (
props: ComponentProps
) => JsxElement | string | null | undefined
/**
* Conditional type for a class.
*/
// @ts-ignore: conditionally defined;
// it used to be possible to detect that with `any extends X ? X : Y`
// but no longer.
export type JsxElementClass = JSX.ElementClass
/**
* Conditional type for a node object.
*/
// @ts-ignore: conditionally defined;
// it used to be possible to detect that with `any extends X ? X : Y`
// but no longer.
export type JsxElement = JSX.Element
/**
* Conditional type for a record of tag names to corresponding props.
*/
// @ts-ignore: conditionally defined;
// it used to be possible to detect that with `any extends X ? X : Y`
// but no longer.
export type JsxIntrinsicElements = JSX.IntrinsicElements
/**
* Create a development element.
*/
export type JsxDev = (
// `any` because runtimes often have complex framework-specific types here.
// type-coverage:ignore-next-line
type: any,
props: Props,
key: string | undefined,
isStaticChildren: boolean,
source: Source,
self: undefined
) => JsxElement
/**
* Create a production element.
*/
export type Jsx = (
// `any` because runtimes often have complex framework-specific types here.
// type-coverage:ignore-next-line
type: any,
props: Props,
key?: string | undefined
) => JsxElement
/**
* Configuration.
*/
export interface OptionsBase {
/**
* Components to use (optional).
*/
components?: Partial<Components> | null | undefined
/**
* Create an evaluator that turns ESTree ASTs into values (optional).
*/
createEvaluater?: CreateEvaluater | null | undefined
/**
* Specify casing to use for attribute names (default: `'react'`).
*/
elementAttributeNameCase?: ElementAttributeNameCase | null | undefined
/**
* File path to the original source file (optional).
*
* Passed in source info to `jsxDEV` when using the automatic runtime with
* `development: true`.
*/
filePath?: string | null | undefined
/**
* Ignore invalid CSS in `style` props (default: `false`);
* the default behavior is to throw an error.
*/
ignoreInvalidStyle?: boolean | null | undefined
/**
* Generate keys to optimize frameworks that support them (default: `true`).
*
* > 👉 **Note**: Solid currently fails if keys are passed.
*/
passKeys?: boolean | null | undefined
/**
* Pass the hast element node to components (default: `false`).
*/
passNode?: boolean | null | undefined
/**
* Whether `tree` is in the `'html'` or `'svg'` space (default: `'html'`).
*
* When an `<svg>` element is found in the HTML space, this package already
* automatically switches to and from the SVG space when entering and exiting
* it.
*/
space?: Space | null | undefined
/**
* Specify casing to use for property names in `style` objects (default:
* `'dom'`).
*/
stylePropertyNameCase?: StylePropertyNameCase | null | undefined
/**
* Turn obsolete `align` props on `td` and `th` into CSS `style` props
* (default: `true`).
*/
tableCellAlignToStyle?: boolean | null | undefined
}
/**
* Configuration (development).
*/
export interface OptionsDevelopment extends OptionsBase {
/**
* Fragment.
*/
Fragment: Fragment
/**
* Whether to use `jsxDEV` (when on) or `jsx` and `jsxs` (when off).
*/
development: true
/**
* Development JSX.
*/
jsxDEV: JsxDev
/**
* Static JSX (optional).
*/
jsxs?: Jsx | null | undefined
/**
* Dynamic JSX (optional).
*/
jsx?: Jsx | null | undefined
}
/**
* Configuration (production).
*/
export interface OptionsProduction extends OptionsBase {
/**
* Fragment.
*/
Fragment: Fragment
/**
* Whether to use `jsxDEV` (when on) or `jsx` and `jsxs` (when off) (optional).
*/
development?: false | null | undefined
/**
* Development JSX (optional).
*/
jsxDEV?: JsxDev | null | undefined
/**
* Static JSX.
*/
jsxs: Jsx
/**
* Dynamic JSX.
*/
jsx: Jsx
}
/**
* Configuration (production or development).
*/
export interface OptionsUnknown extends OptionsBase {
/**
* Fragment.
*/
Fragment: Fragment
/**
* Whether to use `jsxDEV` (when on) or `jsx` and `jsxs` (when off).
*/
development: boolean
/**
* Dynamic JSX (optional).
*/
jsx?: Jsx | null | undefined
/**
* Development JSX (optional).
*/
jsxDEV?: JsxDev | null | undefined
/**
* Static JSX (optional).
*/
jsxs?: Jsx | null | undefined
}
export type Options = OptionsDevelopment | OptionsProduction | OptionsUnknown
/**
* Properties and children.
*/
export interface Props {
[prop: string]:
| Array<Child>
| Child
| Element
| MdxJsxFlowElementHast
| MdxJsxTextElementHast
| Value
| undefined
children?: Array<Child> | Child
node?: Element | MdxJsxFlowElementHast | MdxJsxTextElementHast | undefined
}
/**
* Info about source.
*/
export interface Source {
/**
* Column where thing starts (0-indexed).
*/
columnNumber: number | undefined
/**
* Name of source file.
*/
fileName: string | undefined
/**
* Line where thing starts (1-indexed).
*/
lineNumber: number | undefined
}
/**
* Namespace.
*
* > 👉 **Note**: hast is not XML.
* > It supports SVG as embedded in HTML.
* > It does not support the features available in XML.
* > Passing SVG might break but fragments of modern SVG should be fine.
* > Use `xast` if you need to support SVG as XML.
*/
export type Space = 'html' | 'svg'
/**
* Info passed around.
*/
export interface State {
/**
* Fragment symbol.
*/
Fragment: unknown
/**
* Stack of parents.
*/
ancestors: Array<Parents>
/**
* Components to swap.
*/
components: Partial<Components>
/**
* Create something in development or production.
*/
create: Create
/**
* Casing to use for attribute names.
*/
elementAttributeNameCase: ElementAttributeNameCase
/**
* Evaluator that turns ESTree ASTs into values.
*/
evaluater: Evaluater | undefined
/**
* File path.
*/
filePath: string | undefined
/**
* Ignore invalid CSS in `style` props.
*/
ignoreInvalidStyle: boolean
/**
* Generate keys to optimize frameworks that support them.
*/
passKeys: boolean
/**
* Pass `node` to components.
*/
passNode: boolean
/**
* Current schema.
*/
schema: Schema
/**
* Casing to use for property names in `style` objects.
*/
stylePropertyNameCase: StylePropertyNameCase
/**
* Turn obsolete `align` props on `td` and `th` into CSS `style` props.
*/
tableCellAlignToStyle: boolean
}
/**
* Casing to use for property names in `style` objects.
*
* CSS casing is for example `background-color` and `-webkit-line-clamp`.
* DOM casing is for example `backgroundColor` and `WebkitLineClamp`.
*/
export type StylePropertyNameCase = 'css' | 'dom'
/**
* Style map.
*/
type Style = Record<string, string>
/**
* Primitive property value and `Style` map.
*/
type Value = Style | boolean | number | string

2
node_modules/hast-util-to-jsx-runtime/lib/types.js generated vendored Normal file
View File

@@ -0,0 +1,2 @@
// TypeScript only.
export {}

22
node_modules/hast-util-to-jsx-runtime/license generated vendored Normal file
View File

@@ -0,0 +1,22 @@
(The MIT License)
Copyright (c) Titus Wormer <tituswormer@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

138
node_modules/hast-util-to-jsx-runtime/package.json generated vendored Normal file
View File

@@ -0,0 +1,138 @@
{
"author": "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
"bugs": "https://github.com/syntax-tree/hast-util-to-jsx-runtime/issues",
"contributors": [
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)"
],
"dependencies": {
"@types/estree": "^1.0.0",
"@types/hast": "^3.0.0",
"@types/unist": "^3.0.0",
"comma-separated-tokens": "^2.0.0",
"devlop": "^1.0.0",
"estree-util-is-identifier-name": "^3.0.0",
"hast-util-whitespace": "^3.0.0",
"mdast-util-mdx-expression": "^2.0.0",
"mdast-util-mdx-jsx": "^3.0.0",
"mdast-util-mdxjs-esm": "^2.0.0",
"property-information": "^7.0.0",
"space-separated-tokens": "^2.0.0",
"style-to-js": "^1.0.0",
"unist-util-position": "^5.0.0",
"vfile-message": "^4.0.0"
},
"description": "hast utility to transform to preact, react, solid, svelte, vue, etc",
"devDependencies": {
"@types/node": "^22.0.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"c8": "^10.0.0",
"esbuild": "^0.25.0",
"estree-util-visit": "^2.0.0",
"hastscript": "^9.0.0",
"prettier": "^3.0.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"remark-cli": "^12.0.0",
"remark-preset-wooorm": "^11.0.0",
"sval": "^0.6.0",
"type-coverage": "^2.0.0",
"typescript": "^5.0.0",
"xo": "^0.60.0"
},
"exports": "./index.js",
"files": [
"lib/",
"index.d.ts",
"index.js"
],
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/unified"
},
"keywords": [
"hast-util",
"hast",
"html",
"preact",
"react",
"solid",
"svelte",
"unist",
"utility",
"util",
"vue"
],
"license": "MIT",
"name": "hast-util-to-jsx-runtime",
"prettier": {
"bracketSpacing": false,
"semi": false,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "none",
"useTabs": false
},
"remarkConfig": {
"plugins": [
"remark-preset-wooorm"
]
},
"repository": "syntax-tree/hast-util-to-jsx-runtime",
"scripts": {
"build": "tsc --build --clean && tsc --build && type-coverage",
"format": "remark --frail --output --quiet -- . && prettier --log-level warn --write -- . && xo --fix",
"generate": "esbuild --bundle --format=esm --minify --outfile=example/hast-util-to-jsx-runtime.min.js --target=es2020 .",
"prepack": "npm run build && npm run format",
"test-api": "node --conditions development test/index.js",
"test-coverage": "c8 --100 --reporter lcov -- npm run test-api",
"test": "npm run generate && npm run build && npm run format && npm run test-coverage"
},
"sideEffects": false,
"typeCoverage": {
"atLeast": 100,
"detail": true,
"ignoreCatch": true,
"ignoreFiles": [
"example/**/*.js"
],
"strict": true
},
"type": "module",
"version": "2.3.6",
"xo": {
"overrides": [
{
"files": [
"**/*.d.ts"
],
"rules": {
"@typescript-eslint/array-type": [
"error",
{
"default": "generic"
}
],
"@typescript-eslint/ban-ts-comment": 0,
"@typescript-eslint/ban-types": [
"error",
{
"extendDefaults": true
}
],
"@typescript-eslint/consistent-type-definitions": [
"error",
"interface"
]
}
}
],
"prettier": true,
"rules": {
"logical-assignment-operators": "off",
"unicorn/prefer-at": "off",
"unicorn/prefer-string-replace-all": "off",
"unicorn/prevent-abbreviations": "off"
}
}
}

886
node_modules/hast-util-to-jsx-runtime/readme.md generated vendored Normal file
View File

@@ -0,0 +1,886 @@
# hast-util-to-jsx-runtime
[![Build][badge-build-image]][badge-build-url]
[![Coverage][badge-coverage-image]][badge-coverage-url]
[![Downloads][badge-downloads-image]][badge-downloads-url]
[![Size][badge-size-image]][badge-size-url]
hast utility to transform a tree to
preact, react, solid, svelte, vue, etcetera,
with an automatic JSX runtime.
## Contents
* [What is this?](#what-is-this)
* [When should I use this?](#when-should-i-use-this)
* [Install](#install)
* [Use](#use)
* [API](#api)
* [`toJsxRuntime(tree, options)`](#tojsxruntimetree-options)
* [`Components`](#components)
* [`CreateEvaluater`](#createevaluater)
* [`ElementAttributeNameCase`](#elementattributenamecase)
* [`EvaluateExpression`](#evaluateexpression)
* [`EvaluateProgram`](#evaluateprogram)
* [`Evaluater`](#evaluater)
* [`ExtraProps`](#extraprops)
* [`Fragment`](#fragment)
* [`Jsx`](#jsx)
* [`JsxDev`](#jsxdev)
* [`Options`](#options)
* [`Props`](#props)
* [`Source`](#source)
* [`Space`](#space)
* [`StylePropertyNameCase`](#stylepropertynamecase)
* [Errors](#errors)
* [Examples](#examples)
* [Example: Preact](#example-preact)
* [Example: Solid](#example-solid)
* [Example: Svelte](#example-svelte)
* [Example: Vue](#example-vue)
* [Syntax](#syntax)
* [Compatibility](#compatibility)
* [Security](#security)
* [Related](#related)
* [Contribute](#contribute)
* [License](#license)
## What is this?
This package is a utility that takes a [hast][github-hast] tree and an
[automatic JSX runtime][reactjs-jsx-runtime] and turns the tree into anything
you wish.
## When should I use this?
You can use this package when you have a hast syntax tree and want to use it
with whatever framework.
This package uses an automatic JSX runtime,
which is a sort of lingua franca for frameworks to support JSX.
Notably,
automatic runtimes have support for passing extra information in development,
and have guaranteed support for fragments.
## Install
This package is [ESM only][github-gist-esm].
In Node.js (version 16+),
install with [npm][npmjs-install]:
```sh
npm install hast-util-to-jsx-runtime
```
In Deno with [`esm.sh`][esmsh]:
```js
import {toJsxRuntime} from 'https://esm.sh/hast-util-to-jsx-runtime@2'
```
In browsers with [`esm.sh`][esmsh]:
```html
<script type="module">
import {toJsxRuntime} from 'https://esm.sh/hast-util-to-jsx-runtime@2?bundle'
</script>
```
## Use
```js
import {h} from 'hastscript'
import {toJsxRuntime} from 'hast-util-to-jsx-runtime'
import {Fragment, jsxs, jsx} from 'react/jsx-runtime'
import {renderToStaticMarkup} from 'react-dom/server'
const tree = h('h1', 'Hello, world!')
const doc = renderToStaticMarkup(toJsxRuntime(tree, {Fragment, jsxs, jsx}))
console.log(doc)
```
Yields:
```html
<h1>Hello, world!</h1>
```
> **Note**:
> to add better type support,
> register a global JSX namespace:
>
> ```ts
> import type {JSX as Jsx} from 'react/jsx-runtime'
>
> declare global {
> namespace JSX {
> type ElementClass = Jsx.ElementClass
> type Element = Jsx.Element
> type IntrinsicElements = Jsx.IntrinsicElements
> }
> }
> ```
## API
This package exports the identifier [`toJsxRuntime`][api-to-jsx-runtime].
It exports the [TypeScript][] types
[`Components`][api-components],
[`CreateEvaluater`][api-create-evaluater],
[`ElementAttributeNameCase`][api-element-attribute-name-case],
[`EvaluateExpression`][api-evaluate-expression],
[`EvaluateProgram`][api-evaluate-program],
[`Evaluater`][api-evaluater],
[`ExtraProps`][api-extra-props],
[`Fragment`][api-fragment],
[`Jsx`][api-jsx],
[`JsxDev`][api-jsx-dev],
[`Options`][api-options],
[`Props`][api-props],
[`Source`][api-source],
[`Space`][api-Space],
and
[`StylePropertyNameCase`][api-style-property-name-case].
There is no default export.
### `toJsxRuntime(tree, options)`
Transform a hast tree to
preact, react, solid, svelte, vue, etcetera,
with an automatic JSX runtime.
##### Parameters
* `tree`
([`Node`][github-hast-nodes])
— tree to transform
* `options`
([`Options`][api-options], required)
— configuration
##### Returns
Result from your configured JSX runtime
(`JSX.Element` if defined,
otherwise `unknown` which you can cast yourself).
### `Components`
Possible components to use (TypeScript type).
Each key is a tag name typed in `JSX.IntrinsicElements`,
if defined.
Each value is either a different tag name
or a component accepting the corresponding props
(and an optional `node` prop if `passNode` is on).
You can access props at `JSX.IntrinsicElements`.
For example,
to find props for `a`,
use `JSX.IntrinsicElements['a']`.
###### Type
```ts
import type {Element} from 'hast'
type ExtraProps = {node?: Element | undefined}
type Components = {
[TagName in keyof JSX.IntrinsicElements]:
| Component<JSX.IntrinsicElements[TagName] & ExtraProps>
| keyof JSX.IntrinsicElements
}
type Component<ComponentProps> =
// Class component:
| (new (props: ComponentProps) => JSX.ElementClass)
// Function component:
| ((props: ComponentProps) => JSX.Element | string | null | undefined)
```
### `CreateEvaluater`
Create an evaluator that turns ESTree ASTs from embedded MDX into values
(TypeScript type).
###### Parameters
There are no parameters.
###### Returns
Evaluater ([`Evaluater`][api-evaluater]).
### `ElementAttributeNameCase`
Casing to use for attribute names (TypeScript type).
HTML casing is for example
`class`, `stroke-linecap`, `xml:lang`.
React casing is for example
`className`, `strokeLinecap`, `xmlLang`.
###### Type
```ts
type ElementAttributeNameCase = 'html' | 'react'
```
### `EvaluateExpression`
Turn an MDX expression into a value (TypeScript type).
###### Parameters
* `expression` (`Expression` from `@types/estree`)
— estree expression
###### Returns
Result of expression (`unknown`).
### `EvaluateProgram`
Turn an MDX program (export/import statements) into a value (TypeScript type).
###### Parameters
* `program` (`Program` from `@types/estree`)
— estree program
###### Returns
Result of program (`unknown`);
should likely be `undefined` as ESM changes the scope but doesnt yield
something.
### `Evaluater`
Evaluator that turns ESTree ASTs from embedded MDX into values (TypeScript
type).
###### Fields
* `evaluateExpression` ([`EvaluateExpression`][api-evaluate-expression])
— evaluate an expression
* `evaluateProgram` ([`EvaluateProgram`][api-evaluate-program])
— evaluate a program
### `ExtraProps`
Extra fields we pass (TypeScript type).
###### Type
```ts
type ExtraProps = {node?: Element | undefined}
```
### `Fragment`
Represent the children,
typically a symbol (TypeScript type).
###### Type
```ts
type Fragment = unknown
```
### `Jsx`
Create a production element (TypeScript type).
###### Parameters
* `type` (`unknown`)
— element type:
`Fragment` symbol,
tag name (`string`),
component
* `props` ([`Props`][api-props])
— element props,
`children`,
and maybe `node`
* `key` (`string` or `undefined`)
— dynamicly generated key to use
###### Returns
Element from your framework
(`JSX.Element` if defined,
otherwise `unknown` which you can cast yourself).
### `JsxDev`
Create a development element (TypeScript type).
###### Parameters
* `type` (`unknown`)
— element type:
`Fragment` symbol,
tag name (`string`),
component
* `props` ([`Props`][api-props])
— element props,
`children`,
and maybe `node`
* `key` (`string` or `undefined`)
— dynamicly generated key to use
* `isStaticChildren` (`boolean`)
— whether two or more children are passed (in an array),
which is whether `jsxs` or `jsx` would be used
* `source` ([`Source`][api-source])
— info about source
* `self` (`undefined`)
— nothing (this is used by frameworks that have components,
we dont)
###### Returns
Element from your framework
(`JSX.Element` if defined,
otherwise `unknown` which you can cast yourself).
### `Options`
Configuration (TypeScript type).
###### Fields
* `Fragment` ([`Fragment`][api-fragment], required)
— fragment
* `jsxDEV` ([`JsxDev`][api-jsx-dev], required in development)
— development JSX
* `jsxs` ([`Jsx`][api-jsx], required in production)
— static JSX
* `jsx` ([`Jsx`][api-jsx], required in production)
— dynamic JSX
* `components` ([`Partial<Components>`][api-components], optional)
— components to use
* `createEvaluater` ([`CreateEvaluater`][api-create-evaluater], optional)
— create an evaluator that turns ESTree ASTs into values
* `development` (`boolean`, default: `false`)
— whether to use `jsxDEV` when on or `jsx` and `jsxs` when off
* `elementAttributeNameCase`
([`ElementAttributeNameCase`][api-element-attribute-name-case],
default: `'react'`)
— specify casing to use for attribute names
* `filePath` (`string`, optional)
— file path to the original source file,
passed in source info to `jsxDEV` when using the automatic runtime with
`development: true`
* `passNode` (`boolean`, default: `false`)
— pass the hast element node to components
* `space` ([`Space`][api-space], default: `'html'`)
— whether `tree` is in the `'html'` or `'svg'` space, when an `<svg>`
element is found in the HTML space,
this package already automatically switches to and from the SVG space when
entering and exiting it
* `stylePropertyNameCase`
([`StylePropertyNameCase`][api-style-property-name-case],
default: `'dom'`)
— specify casing to use for property names in `style` objects
* `tableCellAlignToStyle`
(`boolean`, default: `true`)
— turn obsolete `align` props on `td` and `th` into CSS `style` props
### `Props`
Properties and children (TypeScript type).
###### Type
```ts
import type {Element} from 'hast'
type Props = {
[prop: string]:
| Array<JSX.Element | string | null | undefined> // For `children`.
| Record<string, string> // For `style`.
| Element // For `node`.
| boolean
| number
| string
| undefined
children: Array<JSX.Element | string | null | undefined> | undefined
node?: Element | undefined
}
```
### `Source`
Info about source (TypeScript type).
###### Fields
* `columnNumber` (`number` or `undefined`)
— column where thing starts (0-indexed)
* `fileName` (`string` or `undefined`)
— name of source file
* `lineNumber` (`number` or `undefined`)
— line where thing starts (1-indexed)
### `Space`
Namespace (TypeScript type).
> 👉 **Note**:
> hast is not XML;
> it supports SVG as embedded in HTML;
> it does not support the features available in XML;
> passing SVG might break but fragments of modern SVG should be fine;
> use `xast` if you need to support SVG as XML.
###### Type
```ts
type Space = 'html' | 'svg'
```
### `StylePropertyNameCase`
Casing to use for property names in `style` objects (TypeScript type).
CSS casing is for example `background-color` and `-webkit-line-clamp`.
DOM casing is for example `backgroundColor` and `WebkitLineClamp`.
###### Type
```ts
type StylePropertyNameCase = 'css' | 'dom'
```
## Errors
The following errors are thrown:
###### ``Expected `Fragment` in options``
This error is thrown when either `options` is not passed at all or
when `options.Fragment` is `undefined`.
The automatic JSX runtime needs a symbol for a fragment to work.
To solve the error,
make sure you are passing the correct fragment symbol from your framework.
###### `` Expected `jsxDEV` in options when `development: true` ``
This error is thrown when `options.development` is turned on (`true`),
but when `options.jsxDEV` is not a function.
The automatic JSX runtime,
in development,
needs this function.
To solve the error,
make sure you are importing the correct runtime functions
(for example, `'react/jsx-dev-runtime'`),
and pass `jsxDEV`.
###### ``Expected `jsx` in production options``
###### ``Expected `jsxs` in production options``
These errors are thrown when `options.development` is *not* turned on
(`false` or not defined),
and when `options.jsx` or `options.jsxs` are not functions.
The automatic JSX runtime,
in production,
needs these functions.
To solve the error,
make sure you are importing the correct runtime functions
(for example, `'react/jsx-runtime'`),
and pass `jsx` and `jsxs`.
###### `` Cannot handle MDX estrees without `createEvaluater` ``
This error is thrown when MDX nodes are passed that represent JavaScript
programs or expressions.
Supporting JavaScript can be unsafe and requires a different project.
To support JavaScript,
pass a `createEvaluater` function in `options`.
###### ``Cannot parse `style` attribute``
This error is thrown when a `style` attribute is found on an element,
which cannot be parsed as CSS.
Most frameworks dont accept `style` as a string,
so we need to parse it as CSS,
and pass it as an object.
But when broken CSS is used,
such as `style="color:red; /*"`,
we crash.
To solve the error,
make sure authors write valid CSS.
Alternatively,
pass `options.ignoreInvalidStyle: true` to swallow these errors.
## Examples
### Example: Preact
> 👉 **Note**:
> you must set `elementAttributeNameCase: 'html'` for preact.
In Node.js,
do:
```js
import {h} from 'hastscript'
import {toJsxRuntime} from 'hast-util-to-jsx-runtime'
import {Fragment, jsx, jsxs} from 'preact/jsx-runtime'
import {render} from 'preact-render-to-string'
const result = render(
toJsxRuntime(h('h1', 'hi!'), {
Fragment,
jsx,
jsxs,
elementAttributeNameCase: 'html'
})
)
console.log(result)
```
Yields:
```html
<h1>hi!</h1>
```
In a browser,
do:
```js
import {h} from 'https://esm.sh/hastscript@9'
import {toJsxRuntime} from 'https://esm.sh/hast-util-to-jsx-runtime@2'
import {Fragment, jsx, jsxs} from 'https://esm.sh/preact@10/jsx-runtime'
import {render} from 'https://esm.sh/preact@10'
render(
toJsxRuntime(h('h1', 'hi!'), {
Fragment,
jsx,
jsxs,
elementAttributeNameCase: 'html'
}),
document.getElementById('root')
)
```
To add better type support,
register a global JSX namespace:
```ts
import type {JSX as Jsx} from 'preact/jsx-runtime'
declare global {
namespace JSX {
type ElementClass = Jsx.ElementClass
type Element = Jsx.Element
type IntrinsicElements = Jsx.IntrinsicElements
}
}
```
### Example: Solid
> 👉 **Note**:
> you must set `elementAttributeNameCase: 'html'` and
> `stylePropertyNameCase: 'css'` for Solid.
In Node.js,
do:
```js
import {h} from 'hastscript'
import {toJsxRuntime} from 'hast-util-to-jsx-runtime'
import {Fragment, jsx, jsxs} from 'solid-jsx/jsx-runtime'
console.log(
toJsxRuntime(h('h1', 'hi!'), {
Fragment,
jsx,
jsxs,
elementAttributeNameCase: 'html',
stylePropertyNameCase: 'css'
}).t
)
```
Yields:
```html
<h1 >hi!</h1>
```
In a browser,
do:
```js
import {h} from 'https://esm.sh/hastscript@9'
import {toJsxRuntime} from 'https://esm.sh/hast-util-to-jsx-runtime@2'
import {Fragment, jsx, jsxs} from 'https://esm.sh/solid-js@1/h/jsx-runtime'
import {render} from 'https://esm.sh/solid-js@1/web'
render(Component, document.getElementById('root'))
function Component() {
return toJsxRuntime(h('h1', 'hi!'), {
Fragment,
jsx,
jsxs,
elementAttributeNameCase: 'html',
stylePropertyNameCase: 'css'
})
}
```
To add better type support,
register a global JSX namespace:
```ts
import type {JSX as Jsx} from 'solid-js/jsx-runtime'
declare global {
namespace JSX {
type ElementClass = Jsx.ElementClass
type Element = Jsx.Element
type IntrinsicElements = Jsx.IntrinsicElements
}
}
```
### Example: Svelte
<!-- To do: improve svelte when it fixes a bunch of bugs. -->
I have no clue how to render a Svelte component in Node,
but you can get that component with:
```js
import {h} from 'hastscript'
import {toJsxRuntime} from 'hast-util-to-jsx-runtime'
import {Fragment, jsx, jsxs} from 'svelte-jsx'
const svelteComponent = toJsxRuntime(h('h1', 'hi!'), {Fragment, jsx, jsxs})
console.log(svelteComponent)
```
Yields:
```text
[class Component extends SvelteComponent]
```
Types for Svelte are broken.
Raise it with Svelte.
### Example: Vue
> 👉 **Note**:
> you must set `elementAttributeNameCase: 'html'` for Vue.
In Node.js,
do:
```js
import serverRenderer from '@vue/server-renderer'
import {h} from 'hastscript'
import {toJsxRuntime} from 'hast-util-to-jsx-runtime'
import {Fragment, jsx, jsxs} from 'vue/jsx-runtime' // Available since `vue@3.3`.
console.log(
await serverRenderer.renderToString(
toJsxRuntime(h('h1', 'hi!'), {
Fragment,
jsx,
jsxs,
elementAttributeNameCase: 'html'
})
)
)
```
Yields:
```html
<h1>hi!</h1>
```
In a browser,
do:
```js
import {h} from 'https://esm.sh/hastscript@9'
import {toJsxRuntime} from 'https://esm.sh/hast-util-to-jsx-runtime@2'
import {createApp} from 'https://esm.sh/vue@3'
import {Fragment, jsx, jsxs} from 'https://esm.sh/vue@3/jsx-runtime'
createApp(Component).mount('#root')
function Component() {
return toJsxRuntime(h('h1', 'hi!'), {
Fragment,
jsx,
jsxs,
elementAttributeNameCase: 'html'
})
}
```
To add better type support,
register a global JSX namespace:
```ts
import type {JSX as Jsx} from 'vue/jsx-runtime'
declare global {
namespace JSX {
type ElementClass = Jsx.ElementClass
type Element = Jsx.Element
type IntrinsicElements = Jsx.IntrinsicElements
}
}
```
## Syntax
HTML is parsed according to WHATWG HTML (the living standard),
which is also followed by browsers such as Chrome,
Firefox,
and Safari.
## Compatibility
Projects maintained by the unified collective are compatible with maintained
versions of Node.js.
When we cut a new major release,
we drop support for unmaintained versions of Node.
This means we try to keep the current release line,
`hast-util-to-jsx-runtime@2`,
compatible with Node.js 16.
## Security
Be careful with user input in your hast tree.
Use [`hast-util-santize`][github-hast-util-sanitize] to make hast trees safe.
## Related
* [`hastscript`](https://github.com/syntax-tree/hastscript)
— build hast trees
* [`hast-util-to-html`](https://github.com/syntax-tree/hast-util-to-html)
— serialize hast as HTML
* [`hast-util-sanitize`][github-hast-util-sanitize]
— sanitize hast
## Contribute
See [`contributing.md`][health-contributing]
in
[`syntax-tree/.github`][health]
for ways to get started.
See [`support.md`][health-support] for ways to get help.
This project has a [code of conduct][health-coc].
By interacting with this repository,
organization,
or community you agree to abide by its terms.
## License
[MIT][file-license] © [Titus Wormer][wooorm]
<!-- Definitions -->
[api-components]: #components
[api-create-evaluater]: #createevaluater
[api-element-attribute-name-case]: #elementattributenamecase
[api-evaluate-expression]: #evaluateexpression
[api-evaluate-program]: #evaluateprogram
[api-evaluater]: #evaluater
[api-extra-props]: #extraprops
[api-fragment]: #fragment
[api-jsx]: #jsx
[api-jsx-dev]: #jsxdev
[api-options]: #options
[api-props]: #props
[api-source]: #source
[api-space]: #space
[api-style-property-name-case]: #stylepropertynamecase
[api-to-jsx-runtime]: #tojsxruntimetree-options
[badge-build-image]: https://github.com/syntax-tree/hast-util-to-jsx-runtime/workflows/main/badge.svg
[badge-build-url]: https://github.com/syntax-tree/hast-util-to-jsx-runtime/actions
[badge-coverage-image]: https://img.shields.io/codecov/c/github/syntax-tree/hast-util-to-jsx-runtime.svg
[badge-coverage-url]: https://codecov.io/github/syntax-tree/hast-util-to-jsx-runtime
[badge-downloads-image]: https://img.shields.io/npm/dm/hast-util-to-jsx-runtime.svg
[badge-downloads-url]: https://www.npmjs.com/package/hast-util-to-jsx-runtime
[badge-size-image]: https://img.shields.io/bundlejs/size/hast-util-to-jsx-runtime
[badge-size-url]: https://bundlejs.com/?q=hast-util-to-jsx-runtime
[esmsh]: https://esm.sh
[file-license]: license
[github-gist-esm]: https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c
[github-hast]: https://github.com/syntax-tree/hast
[github-hast-nodes]: https://github.com/syntax-tree/hast#nodes
[github-hast-util-sanitize]: https://github.com/syntax-tree/hast-util-sanitize
[health]: https://github.com/syntax-tree/.github
[health-coc]: https://github.com/syntax-tree/.github/blob/main/code-of-conduct.md
[health-contributing]: https://github.com/syntax-tree/.github/blob/main/contributing.md
[health-support]: https://github.com/syntax-tree/.github/blob/main/support.md
[npmjs-install]: https://docs.npmjs.com/cli/install
[reactjs-jsx-runtime]: https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html
[typescript]: https://www.typescriptlang.org
[wooorm]: https://wooorm.com