Skip to content

Commit

Permalink
Add support for passing props as HTML attributes
Browse files Browse the repository at this point in the history
Previously, all properties were passed using React casing.
This does not work, particularly for complex cases such as SVG and XML,
in any other JSX runtime.
Instead, all other JSX runtimes converge on allowing HTML casing.

This adds an option for that.
  • Loading branch information
wooorm committed Feb 2, 2023
1 parent cc05806 commit c9889fc
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 2 deletions.
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/**
* @typedef {import('./lib/components.js').Components} Components
* @typedef {import('./lib/index.js').ElementAttributeNameCase} ElementAttributeNameCase
* @typedef {import('./lib/index.js').Fragment} Fragment
* @typedef {import('./lib/index.js').Jsx} Jsx
* @typedef {import('./lib/index.js').JsxDev} JsxDev
Expand Down
15 changes: 14 additions & 1 deletion lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@
* @typedef {'html' | 'svg'} Space
* Namespace.
*
* @typedef {'react' | 'html'} ElementAttributeNameCase
* Specify casing to use for attribute names.
*
* React casing is for example `className`, `strokeLinecap`, `xmlLang`.
* HTML casing is for example `class`, `stroke-linecap`, `xml:lang`.
*
* @typedef Source
* Info about source.
* @property {string | undefined} fileName
Expand Down Expand Up @@ -91,6 +97,8 @@
* Components to swap.
* @property {boolean} passNode
* Pass `node` to components.
* @property {ElementAttributeNameCase} elementAttributeNameCase
* Casing to use for attribute names.
* @property {Schema} schema
* Current schema.
* @property {unknown} Fragment
Expand All @@ -112,6 +120,8 @@
* `development: true`.
* @property {boolean | null | undefined} [passNode=false]
* Pass the hast element node to components.
* @property {ElementAttributeNameCase | null | undefined} [elementAttributeNameCase='react']
* Specify casing to use for attribute names.
* @property {Space | null | undefined} [space='html']
* Whether `tree` is in the `'html'` or `'svg'` space.
*
Expand Down Expand Up @@ -244,6 +254,7 @@ export function toJsxRuntime(tree, options) {
Fragment: options.Fragment,
schema: options.space === 'svg' ? svg : html,
passNode: options.passNode || false,
elementAttributeNameCase: options.elementAttributeNameCase || 'react',
components: options.components || {},
filePath,
create
Expand Down Expand Up @@ -479,7 +490,9 @@ function createProperty(state, node, prop, value) {
}

return [
info.space ? hastToReact[info.property] || info.property : info.attribute,
state.elementAttributeNameCase === 'react' && info.space
? hastToReact[info.property] || info.property
: info.attribute,
value
]
}
Expand Down
24 changes: 23 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ with an automatic JSX runtime.
* [`toJsxRuntime(tree, options)`](#tojsxruntimetree-options)
* [`Options`](#options)
* [`Components`](#components-1)
* [`ElementAttributeNameCase`](#elementattributenamecase-1)
* [`Fragment`](#fragment-1)
* [`Jsx`](#jsx-1)
* [`JsxDev`](#jsxdev-1)
Expand Down Expand Up @@ -163,6 +164,11 @@ File path to the original source file (`string`, optional).
Passed in source info to `jsxDEV` when using the automatic runtime with
`development: true`.

###### `elementAttributeNameCase`

Specify casing to use for attribute names
([`ElementAttributeNameCase`][elementattributenamecase], default: `'react'`).

###### `passNode`

Pass the hast element node to components (`boolean`, default: `false`).
Expand Down Expand Up @@ -213,6 +219,19 @@ type Component<ComponentProps> =
| (new (props: ComponentProps) => JSX.ElementClass)
```
### `ElementAttributeNameCase`
Specify casing to use for attribute names (TypeScript type).
React casing is for example `className`, `strokeLinecap`, `xmlLang`.
HTML casing is for example `class`, `stroke-linecap`, `xml:lang`.
###### Type
```ts
type ElementAttributeNameCase = 'react' | 'html'
```
### `Fragment`
Represent the children, typically a symbol (TypeScript type).
Expand Down Expand Up @@ -281,7 +300,7 @@ type Props = {
| number
| boolean
| undefined
children: Array<JSX.Element | string | null | undefined>
children: Array<JSX.Element | string | null | undefined> | undefined
node?: Element | undefined
}
```
Expand Down Expand Up @@ -397,6 +416,7 @@ followed by browsers such as Chrome, Firefox, and Safari.

This package is fully typed with [TypeScript][].
It exports the additional types [`Components`][components],
[`ElementAttributeNameCase`][elementattributenamecase],
[`Fragment`][fragment], [`Jsx`][jsx], [`JsxDev`][jsxdev], [`Options`][options],
[`Props`][props], [`Source`][source], and [`Space`][Space].

Expand Down Expand Up @@ -513,3 +533,5 @@ abide by its terms.
[space]: #space-1

[components]: #components-1

[elementattributenamecase]: #elementattributenamecase-1

0 comments on commit c9889fc

Please sign in to comment.