Skip to content

Commit

Permalink
Add tons of examples to verify frameworks work
Browse files Browse the repository at this point in the history
  • Loading branch information
wooorm committed Feb 3, 2023
1 parent 7dac6c4 commit a7bf98b
Show file tree
Hide file tree
Showing 15 changed files with 519 additions and 15 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@
coverage/
node_modules/
yarn.lock
example/hast-util-to-jsx-runtime.min.js
!lib/components.d.ts
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
coverage/
example/hast-util-to-jsx-runtime.min.js
*.html
*.md
200 changes: 200 additions & 0 deletions example/create-tree.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
/**
* Generate a hast tree for checking.
*
* > 👉 **Note**: this file is actual ESM that runs in browsers.
*/

/* eslint-env browser */

// @ts-expect-error: hush.
import * as hastscript from 'https://esm.sh/hastscript@7?dev'

/** @type {typeof import('hastscript').h} */
const h = hastscript.h
/** @type {typeof import('hastscript').s} */
const s = hastscript.s

export function createTree() {
return h('div', [
h('p', [
'note: to show that state is kept, this is rerendered every second, it’s now ',
h('b', new Date().toLocaleString()),
'!'
]),
h('hr'),
h('h2', 'Event handlers'),
h('p', [
'You should be able to click on this and print something to the console.'
]),
h('button', {onClick: 'console.log("it worked!")'}, 'Print to console'),
h('hr'),
h('h2', 'Inputs with control'),
h('p', ['You should be able to change this text input:']),
h('div', [
h('input#text-a', {type: 'text', value: 'Some text?'}),
h('label', {htmlFor: 'text-a'}, 'Text input')
]),
h('hr'),
h('p', ['You should be able to change this range input:']),
h('div', [
h('input#range-a', {type: 'range', value: 5, min: 0, max: 10}),
h('label', {htmlFor: 'range-a'}, 'Range input')
]),
h('hr'),
h('p', ['You should be able to change this radio group:']),
h('div', [
h('input#radio-a', {
type: 'radio',
name: 'radios',
value: 'a',
checked: true
}),
h('label', {htmlFor: 'radio-a'}, 'Alpha'),
h('input#radio-b', {type: 'radio', name: 'radios', value: 'b'}),
h('label', {htmlFor: 'radio-b'}, 'Bravo'),
h('input#radio-c', {type: 'radio', name: 'radios', value: 'c'}),
h('label', {htmlFor: 'radio-c'}, 'Charlie')
]),
h('hr'),
h('h2', 'Style attribute'),
h(
'p',
{style: {color: '#0366d6'}},
'is this blue? Then style objects work'
),
h('p', {style: 'color: #0366d6'}, 'is this blue? Then style strings work'),
h(
'p',
{style: '-webkit-transform: rotate(0.01turn)'},
'is this tilted in webkit? Then vendor prefixes in style strings work'
),
h(
'p',
{style: {'-webkit-transform': 'rotate(0.01turn)'}},
'is this tilted in webkit? Then prefixes in style objects work'
),
h(
'p',
{style: {WebkitTransform: 'rotate(0.01turn)'}},
'is this tilted in webkit? Then camelcased in style objects work'
),
h(
'p',
{
style:
'display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2'
},
'This should be capped at 2 lines in webkit! Lorem ipsum dolor sit amet consectetur adipisicing elit. Temporibus natus similique eum. Dolorem est at aliquam, explicabo similique repudiandae veritatis? Eum aliquam hic eaque tenetur, enim ex odio voluptatum repellendus!'
),
h(
'p',
{style: '--fg: #0366d6; color: var(--fg)'},
'Is this blue? Then CSS variables work.'
),
h('h2', 'SVG: camel- and dash-cased attributes'),
h('p', [
'You should see two bright blue circles, the second skewed. ',
'This checks that the ',
h('code', 'gradientUnits'),
' attribute (camel case), ',
h('code', 'gradientTransform'),
' attribute (camel case), and ',
h('code', 'stop-color'),
' attribute (dash case), all work. ',
'It also checks that the ',
h('code', 'radialGradient'),
' element (camel case) works.'
]),
// Example based on <https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/gradientTransform>
s('svg', {viewBox: '0 0 420 200', xmlns: 'http://www.w3.org/2000/svg'}, [
s(
'radialGradient#gradient-a',
{gradientUnits: 'userSpaceOnUse', cx: 100, cy: 100, r: 100},
[
s('stop', {offset: '50%', stopColor: '#0366d6'}),
s('stop', {offset: '50.1%', stopColor: 'transparent'})
]
),
s(
'radialGradient#gradient-b',
{
gradientUnits: 'userSpaceOnUse',
cx: 100,
cy: 100,
r: 100,
gradientTransform: 'skewX(25) translate(-50, 0)'
},
[
s('stop', {offset: '50%', stopColor: '#0366d6'}),
s('stop', {offset: '50.1%', stopColor: 'transparent'})
]
),
s('rect', {
x: 0,
y: 0,
width: 200,
height: 200,
fill: 'url(#gradient-a)'
}),
s('rect', {
x: 0,
y: 0,
width: 200,
height: 200,
fill: 'url(#gradient-b)',
style: {transform: 'translateX(220px)'}
})
]),
h('h2', 'xlink:href'),
h('p', [
'You should see one big circle broken down over four squares. ',
'The top right square is different, it instead contains one small circle. ',
'This checks that the ',
h('code', 'clipPathUnits'),
' attribute (camel case), ',
h('code', 'clip-path'),
' attribute (dash case), and',
h('code', 'clipPath'),
' element (camel case), all work. ',
'Importantly, it also checks for ',
h('code', 'xlink:href'),
'!'
]),
// Example from <https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/clipPathUnits>
s('svg', {viewBox: '0 0 100 100'}, [
s('clipPath#clip-a', {clipPathUnits: 'userSpaceOnUse'}, [
s('circle', {cx: 50, cy: 50, r: 35})
]),
s('clipPath#clip-b', {clipPathUnits: 'objectBoundingBox'}, [
s('circle', {cx: 0.5, cy: 0.5, r: 0.35})
]),
s('rect#rect-a', {x: 0, y: 0, width: 45, height: 45}),
s('rect#rect-b', {x: 0, y: 55, width: 45, height: 45}),
s('rect#rect-c', {x: 55, y: 55, width: 45, height: 45}),
s('rect#rect-d', {x: 55, y: 0, width: 45, height: 45}),
s('use', {
clipPath: 'url(#clip-a)',
xLinkHref: '#rect-a',
fill: '#0366d6'
}),
s('use', {
clipPath: 'url(#clip-a)',
xLinkHref: '#rect-b',
fill: '#0366d6'
}),
s('use', {
clipPath: 'url(#clip-a)',
xLinkHref: '#rect-c',
fill: '#0366d6'
}),
s('use', {
clipPath: 'url(#clip-b)',
xLinkHref: '#rect-d',
fill: '#0366d6'
})
]),
h('h2', 'xml:lang'),
h('style', ':lang(fr) { color: #0366d6; }'),
h('p', {xmlLang: 'fr'}, "C'est bleu ? Ensuite ça marche")
])
}
48 changes: 48 additions & 0 deletions example/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* Style the examples.
*/

:root {
color-scheme: light dark;
background-color: hsl(0, 0%, 90%);
}

* {
line-height: calc(1em + 1ex);
box-sizing: border-box;
}

a {
color: #0367d8;
}

body {
font-family: system-ui;
margin: 3em auto;
max-width: 30em;
}

input {
font: inherit;
}

code {
font-family: 'San Francisco Mono', 'Monaco', 'Consolas', 'Lucida Console',
'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
font-feature-settings: normal;
font-size: smaller;
background-color: rgba(0, 0, 0, 0.04);
border-radius: 3px;
padding: 0.2em 0.4em;
}

@media (prefers-color-scheme: dark) {
:root {
background-color: hsl(214, 13%, 10%);
color: hsl(214, 13%, 90%);
}

code {
background-color: rgba(0, 0, 0, 0.4);
}
}
13 changes: 13 additions & 0 deletions example/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang=en>
<meta charset=utf8>
<title>hast-util-to-jsx-runtime</title>
<link rel=stylesheet href=index.css />
<h1><code>hast-util-to-jsx-runtime</code></h1>
<p>See the following examples to check how different frameworks work:
<ol>
<li><a href=react.html>React</a>
<li><a href=preact.html>preact</a>
<li><a href=solid.html>Solid</a>
<li><a href=svelte.html>Svelte</a>
<li><a href=vue.html>Vue</a>
25 changes: 25 additions & 0 deletions example/preact.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!doctype html>
<html lang=en>
<meta charset=utf8>
<title>preact + hast-util-to-jsx-runtime</title>
<link rel=stylesheet href=index.css />
<h1><code>preact</code> + <code>hast-util-to-jsx-runtime</code></h1>
<p style="color:green">Note! This example is dynamic!</p>
<div id=root></div>
<script type=module>
/* eslint-env browser */
import {Fragment, jsx, jsxs} from 'https://esm.sh/preact@10/jsx-runtime?dev'
import {render} from 'https://esm.sh/preact@10?dev'
import {toJsxRuntime} from './hast-util-to-jsx-runtime.min.js'
import {createTree} from './create-tree.js'

rerender()

function rerender() {
render(
toJsxRuntime(createTree(), {Fragment, jsx, jsxs, elementAttributeNameCase: 'html'}),
document.getElementById('root')
)
setTimeout(rerender, 1000)
}
</script>
29 changes: 29 additions & 0 deletions example/react.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!doctype html>
<html lang=en>
<meta charset=utf8>
<title>React + hast-util-to-jsx-runtime</title>
<link rel=stylesheet href=index.css />
<h1><code>React</code> + <code>hast-util-to-jsx-runtime</code></h1>
<p style="color:green">Note! This example is dynamic!</p>
<div id=root></div>
<script type=module>
/* eslint-env browser */
import {Fragment, jsx, jsxs} from 'https://esm.sh/react@18/jsx-runtime?dev'
import React from 'https://esm.sh/react@18?dev'
import ReactDom from 'https://esm.sh/react-dom@18/client?dev'
import {toJsxRuntime} from './hast-util-to-jsx-runtime.min.js'
import {createTree} from './create-tree.js'

const root = ReactDom.createRoot(document.getElementById('root'))

rerender()

function rerender() {
root.render(React.createElement(Component))
setTimeout(rerender, 1000)
}

function Component() {
return toJsxRuntime(createTree(), {Fragment, jsx, jsxs})
}
</script>
19 changes: 19 additions & 0 deletions example/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# `hast-util-to-jsx-runtime`: web examples

This folder contains examples that run in web browsers that check whether
this utility works with different frameworks.

To use them, first set up the Git repo with:

```sh
npm install
npm test
```

Then, start a simple server in this examples folder:

```sh
python3 -m http.server
```

Open `http://localhost:8000` in a browser to see the results.
21 changes: 21 additions & 0 deletions example/solid.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!doctype html>
<html lang=en>
<meta charset=utf8>
<title>Solid + hast-util-to-jsx-runtime</title>
<link rel=stylesheet href=index.css />
<h1><code>Solid</code> + <code>hast-util-to-jsx-runtime</code></h1>
<p style="color:red">Note! This example is static! (to do: figure out a way to rerender Solid without changing everything?)</p>
<div id=root></div>
<script type=module>
/* eslint-env browser */
import {Fragment, jsx, jsxs} from 'https://esm.sh/solid-js@1/h/jsx-runtime'
import {render} from 'https://esm.sh/solid-js@1/web?dev'
import {toJsxRuntime} from './hast-util-to-jsx-runtime.min.js'
import {createTree} from './create-tree.js'

render(Component, document.getElementById('root'))

function Component() {
return toJsxRuntime(createTree(), {Fragment, jsx, jsxs, passKeys: false, elementAttributeNameCase: 'html', stylePropertyNameCase: 'css'})
}
</script>
19 changes: 19 additions & 0 deletions example/svelte.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!doctype html>
<html lang=en>
<meta charset=utf8>
<title>Svelte + hast-util-to-jsx-runtime</title>
<link rel=stylesheet href=index.css />
<h1><code>Svelte</code> + <code>hast-util-to-jsx-runtime</code></h1>
<p style="color:red">Note! This example is static! (to do: figure out a way to rerender Svelte)</p>
<p style="color:red">Note! Svelte seems completely broken: no support for style, SVG, etc.</p>
<div id=root></div>
<script type=module>
/* eslint-env browser */
import {Fragment, jsx, jsxs} from 'https://esm.sh/svelte-jsx@2/jsx-runtime'
import {toJsxRuntime} from './hast-util-to-jsx-runtime.min.js'
import {createTree} from './create-tree.js'

const Component = toJsxRuntime(createTree(), {Fragment, jsx, jsxs})

new Component({target: document.getElementById('root')})
</script>
Loading

0 comments on commit a7bf98b

Please sign in to comment.