Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/herp-inc/snabbdom-jsx
Yet another JSX pragma for Snabbdom
https://github.com/herp-inc/snabbdom-jsx
jsx snabbdom
Last synced: about 1 month ago
JSON representation
Yet another JSX pragma for Snabbdom
- Host: GitHub
- URL: https://github.com/herp-inc/snabbdom-jsx
- Owner: herp-inc
- Created: 2021-07-23T14:20:58.000Z (over 3 years ago)
- Default Branch: master
- Last Pushed: 2024-05-28T08:17:18.000Z (7 months ago)
- Last Synced: 2024-05-29T19:15:56.888Z (7 months ago)
- Topics: jsx, snabbdom
- Language: TypeScript
- Homepage: https://www.npmjs.com/package/@herp-inc/snabbdom-jsx
- Size: 842 KB
- Stars: 2
- Watchers: 2
- Forks: 1
- Open Issues: 10
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# @herp-inc/snabbdom-jsx [![npm](https://img.shields.io/npm/v/@herp-inc/snabbdom-jsx)](https://www.npmjs.com/package/@herp-inc/snabbdom-jsx)
Yet another [JSX](https://facebook.github.io/jsx/) pragma for [Snabbdom](https://www.npmjs.com/package/snabbdom)
## Features
- Straightforward and intuitive syntax
- `` rather than ``
- Typechecked attributes on intrinsic elements
- Only for HTML elements for now
- Typechecked children
- `className` and `id` will be the part of the [`sel`](https://github.com/snabbdom/snabbdom#sel--string)
- [Type-safe custom modules via module augmentation](#custom-modules)
- Support for [React 17 style automatic runtime](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html)## Example
```tsx
const vnode = (
);
```## Installation
Note that the following packages are peer dependencies of this library, which need to be installed separately.
| Package | Version |
| ---------------------------------------------------- | ------- |
| [`csstype`](https://www.npmjs.com/package/csstype) | `3` |
| [`snabbdom`](https://www.npmjs.com/package/snabbdom) | `3` |### With [npm](https://www.npmjs.com/)
```sh
$ npm install @herp-inc/snabbdom-jsx
```### With [yarn](https://yarnpkg.com/)
```sh
$ yarn add @herp-inc/snabbdom-jsx
```## Usage
Note that fragments are still experimental. Make sure you are using Snabbdom v3.2+ and opt it in to enable the feature.
```ts
const patch = init(modules, undefined, {
experimental: {
fragments: true,
},
});
```### With [TypeScript](https://www.typescriptlang.org/)
Add the following options to your `tsconfig.json`:
```json
{
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "@herp-inc/snabbdom-jsx"
}
}
```### With [Babel](https://babeljs.io/)
Add [`@babel/plugin-transform-react-jsx`](https://www.npmjs.com/package/@babel/plugin-transform-react-jsx) to your `devDependencies`.
Add the following options to your Babel configuration:
```json
{
"plugins": [
[
"@babel/plugin-transform-react-jsx",
{
"importSource": "@herp-inc/snabbdom-jsx",
"runtime": "automatic"
}
]
]
}
```## Attributes mapping
By default, an attribute will be passed to [the props module](https://github.com/snabbdom/snabbdom#the-props-module).
```tsx
// { props: { type: 'text' } }
```However, certain attributes will be treated differently.
### `className` and `id`
`className` and `id` attributes will be concatenated to the [`sel`](https://github.com/snabbdom/snabbdom#sel--string) with `.` and `#` respectively, and won't be passed to any modules. For example, the expression `
` will yield a virtual node with `{ sel: 'div#foo.bar.baz' }`### `aria-*`
An attribute starting with `aria-` will be passed to [the attributes module](https://github.com/snabbdom/snabbdom#the-attributes-module).
```tsx
// { attrs: { 'aria-label': 'Send' } }
```### `data-*`
An attribute starting with `data-` will be passed to [the dataset module](https://github.com/snabbdom/snabbdom#the-dataset-module). Note that the `data-` prefix will be removed and dashes will be converted to camel case.
```tsx
// { dataset: { fooBar: 'baz' } }
```### `is`
The `is` attribute can be used when you want to instantiate your customized built-in elements.
```tsx
// { is: 'custom-element' }
```### `on*`
An attribute starting with `on` will passed to [the event listeners module](https://github.com/snabbdom/snabbdom#the-eventlisteners-module).
```tsx
{
console.log(e);
}}
/>
// { on: { click: f } }
```### `list`, `role`, and `popoverTarget`
The `list`, the `role`, and the `popoverTarget` attributes will be passed to [the attributes module](https://github.com/snabbdom/snabbdom#the-attributes-module).
Note that the attribute names will be lowercased.```tsx
// { attrs: { role: 'button' } }// { attrs: { list: 'options' } }
// { attrs: { popovertarget: 'popover' } }
```### `$hook`
The `$hook` attribute is treated as [hooks](https://github.com/snabbdom/snabbdom#hooks).
```tsx
// { hook: { insert: f } }
```For the sake of backward compatibility, `hook` (without the dollar sign) also behaves the same. However it is deprecated and will be removed in the future.
### `$key`
The `$key` attribute is treated as [a key](https://github.com/snabbdom/snabbdom#key--string--number).
```tsx
// { key: 'foo' }
```For the sake of backward compatibility, `key` (without the dollar sign) also behaves the same. However it is deprecated and will be removed in the future.
### SVG elements
Attributes of `` and its descendant elements are passed to [the attributes module](https://github.com/snabbdom/snabbdom#the-attributes-module).
### Built-in modules
In Snabbdom, different functionalities are delegated to separate modules. Values can be passed to them via attributes starting with `$`.
#### `$attrs` ([the attributes module](https://github.com/snabbdom/snabbdom#the-attributes-module))
```tsx
// { attrs: { class: 'foo' } }
```#### `$class` ([the class module](https://github.com/snabbdom/snabbdom#the-class-module))
```tsx
// { class: { foo: true } }
```#### `$dataset` ([the dataset module](https://github.com/snabbdom/snabbdom#the-dataset-module))
```tsx
// { dataset: { foo: 'bar' } }
```#### `$on` ([the event listeners module](https://github.com/snabbdom/snabbdom#the-eventlisteners-module))
```tsx
{
console.log(e);
},
}}
/>
// { on: { click: f } }
```#### `$props` ([the props module](https://github.com/snabbdom/snabbdom#the-props-module))
```tsx
// { props: { className: 'foo' } }
```#### `$style` ([the style module](https://github.com/snabbdom/snabbdom#the-style-module))
```tsx
// { style: { opacity: '0', delayed: { opacity: '1' }, remove: { opacity: '0' } } }
```#### Aliases
For the sake of backward compatibility, the following aliases are also defined. However they are deprecated and will be removed in the future.
| Attribute | Alias(es) |
| ---------- | ----------------- |
| `$attrs` | `attrs` |
| `$class` | `class` |
| `$dataset` | `data`, `dataset` |
| `$on` | `on` |
| `$props` | `props` |
| `$style` | `style` |### Custom modules
Just like built-in modules, you can pass an arbitrary value to your custom modules via an attribute starting with `$`. For example, the expression `
` will yield `{ custom: { foo: 'bar' } }`.#### Note for TypeScript users
Unlike built-in modules, we have no assumptions on what kind of values should be passed to custom modules. You have to augment `jsx.CustomModules` interface so that it will typecheck.
```ts
declare module '@herp-inc/snabbdom-jsx/jsx-runtime' {
namespace jsx {
interface CustomModules {
// Add your custom modules here
custom: {
foo: string;
};
}
}
}
```## Components
A JSX component can be defined with a function with the signature of `(props: Props) => Snabbdom.VNodeChildElement`.
```tsx
import type Snabbdom from '@herp-inc/snabbdom-jsx';type Props = {
children: Snabbdom.Node;
name: string;
};const Component: Snabbdom.Component = ({ children, name }) => (
Hello, {name}!{children}
);const vnode = ;
```## Caveats
- `boolean`, `null`, and `undefined` values are not be filtered out of the tree but rendered as comment nodes (for the sake of correct diffing)
- `snabbdom-pragma`-style `MODULE-PROPERTY` notation is not supported.## Acknowledgements
The code base is based on these libraries:
- [`snabbdom`](https://www.npmjs.com/package/snabbdom)
- [`snabbdom-pragma`](https://www.npmjs.com/package/snabbdom-pragma)
- [`@types/react`](https://www.npmjs.com/package/@types/react)