Repository files navigation

hyperlit

hyperlit lets you declare your hyperapp views in a html-like fashion, similar to JSX. Unlike JSX you don't need a build-step and babel config to do it -- it happens run-time in your browser. It's quite small – ca 0.6kb.

Here's Hyperapp's "Quickstart" example using hyperlit:

<!DOCTYPE html><htmllang="en"><head><scripttype="module">import{app}from'https://unpkg.com/hyperapp'importhtmlfrom'https://unpkg.com/hyperlit'app({init: 0,view: state=>html`<main><h1>${state}</h1><buttononclick=${state=>state-1}>-</button><buttononclick=${state=>state+1}>+</button></main>`,node: document.getElementById('app')})</script></head><body><mainid="app"></main></body></html>

In the following instructions I will just focus on how hyperlit replaces Hyperapp's h function. For actually making working apps with this, familiarity with Hyperapp is assumed.

Getting hyperlit into your project

Using npm

In projects where you do bundle your app up, install hyperlit using:

npm i hyperlit

Note that hyperapp is a peer-dependency which you'll also need to have installed.

Once installed, you can import hyperlit wherever you declare views:

importhtmlfrom'hyperlit'

Browser modules

If you prefer not to use npm, you can use client side imports directly like this:

importhtmlfrom'https://unpkg.com/hyperlit'

Usage

Hyperlit replaces hyperapp's built-in h, allowing you to write:

html`<divclass="big"><h1>Title</h1><pclass="aligned"> Content 1 <br/> Content 2</p></div>`

instead of:

h('div',{class: 'big'},[h('h1',{},text('Title')),h('p',{class: 'aligned'},[text('Content 1'),h('br',{}),text('Content 2')]),])

Injecting props

If you have non-string props you want to add to your vnodes, or values kept in variables, use the ${val} syntax to inject them:

constfoo=32constnode=html`<pclass=${{bigger: foo>30}}>...</p>`

Spreading props

If you have a bunch of props you want to assign, you don't have to write them out individually, you can just:

constprops={class: 'bigger',id: 'a-1',key: 'a-1'}constnode=html`<p${props}>...</p>`

(For compatibility with views you may have written using htm, the ...${props} syntax is also supported)

Injecting content.

constname='Joe'constgreeting=html`<span>Hello ${name}!</span>`

results in h('span', {}, [text('Hello'), text('Joe'), text('!')]).

Content can be a string or a vnode. Content can also be an array:

constnames=['Kim','Robin','Sam']constperson=name=>html`<p>${name}</p>`constlist=html`<div><p>Members:</p>${names.map(person)}</div>`

results in list being equivalent to:

h('div',{},[h('p',{},text('Members:')),h('p',{},text('Kim')),h('p',{},text('Robin')),h('p',{},text('Sam')),])

Since hyperapp filters out falsy children, you can conditionally render some content:

constshow=falsehtml`<p>Secret: ${show&&'I work for the CIA'}</p>`

Components

Let's say you have this component:

constbox=(props,content)=>html`<divclass=${{fancy: true,active: props.active}}><h1>${props.title}</h1>${content}</div>`

You could of course add it to a view in this way:

constview=html`<main>${box({active: false,title: 'My bio'},[html`<p>Lorem ipsum</p>`,html`<p>Dolor sit amet</p>`,])}</main>`

But hyperlit allows you to do it this way as well:

constview=html`<main><${box}active=${false} title="My bio"><p>Lorem ipsum</p><p>Dolor sit amet</p><//></main>`

For backwards compatibility with htm it is also possible to close components as </${box}>

Tooling

Transform to plain function calls with Babel

This library is meant to let you write html-like views that can be rendered in the browser without any build step. Still, you might eventually perfer the parsing to be taken care of by your build-toolchain in order to get faster renders. Of course you should be able to do so! Simply add babel-plugin-hyperlit to your babel config. In package.json for example, it looks like this:

"babel": {
"plugins": ["hyperlit"]
}

With that, babel will make sure to transform all your hyperlit views into plain function calls, so the browser doesn't have to do any parsing.

Syntax highlighting

If you use VS Code, install the lit-html to get highlighting and autocompletion that works well with hyperlit.

Credits

This project was inspired by Jason Miller'shtm. I made it to have a similar solution that would work well with Hyperapp.

Thanks to Jorge Bucaran for making Hyperapp and for coming up with the name of this project!

About

A JSX-like ttl for Hyperapp

Resources

Stars

68 stars

Watchers

5 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

hyperlit

hyperlit lets you declare your hyperapp views in a html-like fashion, similar to JSX. Unlike JSX you don't need a build-step and babel config to do it -- it happens run-time in your browser. It's quite small – ca 0.6kb.

Here's Hyperapp's "Quickstart" example using hyperlit:

<!DOCTYPE html><htmllang="en"><head><scripttype="module">import{app}from'https://unpkg.com/hyperapp'importhtmlfrom'https://unpkg.com/hyperlit'app({init: 0,view: state=>html`<main><h1>${state}</h1><buttononclick=${state=>state-1}>-</button><buttononclick=${state=>state+1}>+</button></main>`,node: document.getElementById('app')})</script></head><body><mainid="app"></main></body></html>

In the following instructions I will just focus on how hyperlit replaces Hyperapp's h function. For actually making working apps with this, familiarity with Hyperapp is assumed.

Getting hyperlit into your project

Using npm

In projects where you do bundle your app up, install hyperlit using:

npm i hyperlit

Note that hyperapp is a peer-dependency which you'll also need to have installed.

Once installed, you can import hyperlit wherever you declare views:

importhtmlfrom'hyperlit'

Browser modules

If you prefer not to use npm, you can use client side imports directly like this:

importhtmlfrom'https://unpkg.com/hyperlit'

Usage

Hyperlit replaces hyperapp's built-in h, allowing you to write:

html`<divclass="big"><h1>Title</h1><pclass="aligned"> Content 1 <br/> Content 2</p></div>`

instead of:

h('div',{class: 'big'},[h('h1',{},text('Title')),h('p',{class: 'aligned'},[text('Content 1'),h('br',{}),text('Content 2')]),])

Injecting props

If you have non-string props you want to add to your vnodes, or values kept in variables, use the ${val} syntax to inject them:

constfoo=32constnode=html`<pclass=${{bigger: foo>30}}>...</p>`

Spreading props

If you have a bunch of props you want to assign, you don't have to write them out individually, you can just:

constprops={class: 'bigger',id: 'a-1',key: 'a-1'}constnode=html`<p${props}>...</p>`

(For compatibility with views you may have written using htm, the ...${props} syntax is also supported)

Injecting content.

constname='Joe'constgreeting=html`<span>Hello ${name}!</span>`

results in h('span', {}, [text('Hello'), text('Joe'), text('!')]).

Content can be a string or a vnode. Content can also be an array:

constnames=['Kim','Robin','Sam']constperson=name=>html`<p>${name}</p>`constlist=html`<div><p>Members:</p>${names.map(person)}</div>`

results in list being equivalent to:

h('div',{},[h('p',{},text('Members:')),h('p',{},text('Kim')),h('p',{},text('Robin')),h('p',{},text('Sam')),])

Since hyperapp filters out falsy children, you can conditionally render some content:

constshow=falsehtml`<p>Secret: ${show&&'I work for the CIA'}</p>`

Components

Let's say you have this component:

constbox=(props,content)=>html`<divclass=${{fancy: true,active: props.active}}><h1>${props.title}</h1>${content}</div>`

You could of course add it to a view in this way:

constview=html`<main>${box({active: false,title: 'My bio'},[html`<p>Lorem ipsum</p>`,html`<p>Dolor sit amet</p>`,])}</main>`

But hyperlit allows you to do it this way as well:

constview=html`<main><${box}active=${false} title="My bio"><p>Lorem ipsum</p><p>Dolor sit amet</p><//></main>`

For backwards compatibility with htm it is also possible to close components as </${box}>

Tooling

Transform to plain function calls with Babel

This library is meant to let you write html-like views that can be rendered in the browser without any build step. Still, you might eventually perfer the parsing to be taken care of by your build-toolchain in order to get faster renders. Of course you should be able to do so! Simply add babel-plugin-hyperlit to your babel config. In package.json for example, it looks like this:

"babel": {
"plugins": ["hyperlit"]
}

With that, babel will make sure to transform all your hyperlit views into plain function calls, so the browser doesn't have to do any parsing.

Syntax highlighting

If you use VS Code, install the lit-html to get highlighting and autocompletion that works well with hyperlit.

Credits

This project was inspired by Jason Miller'shtm. I made it to have a similar solution that would work well with Hyperapp.

Thanks to Jorge Bucaran for making Hyperapp and for coming up with the name of this project!

About

A JSX-like ttl for Hyperapp

Resources

Stars

68 stars

Watchers

5 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

hyperlit

hyperlit lets you declare your hyperapp views in a html-like fashion, similar to JSX. Unlike JSX you don't need a build-step and babel config to do it -- it happens run-time in your browser. It's quite small – ca 0.6kb.

Here's Hyperapp's "Quickstart" example using hyperlit:

<!DOCTYPE html><htmllang="en"><head><scripttype="module">import{app}from'https://unpkg.com/hyperapp'importhtmlfrom'https://unpkg.com/hyperlit'app({init: 0,view: state=>html`<main><h1>${state}</h1><buttononclick=${state=>state-1}>-</button><buttononclick=${state=>state+1}>+</button></main>`,node: document.getElementById('app')})</script></head><body><mainid="app"></main></body></html>

In the following instructions I will just focus on how hyperlit replaces Hyperapp's h function. For actually making working apps with this, familiarity with Hyperapp is assumed.

Getting hyperlit into your project

Using npm

In projects where you do bundle your app up, install hyperlit using:

npm i hyperlit

Note that hyperapp is a peer-dependency which you'll also need to have installed.

Once installed, you can import hyperlit wherever you declare views:

importhtmlfrom'hyperlit'

Browser modules

If you prefer not to use npm, you can use client side imports directly like this:

importhtmlfrom'https://unpkg.com/hyperlit'

Usage

Hyperlit replaces hyperapp's built-in h, allowing you to write:

html`<divclass="big"><h1>Title</h1><pclass="aligned"> Content 1 <br/> Content 2</p></div>`

instead of:

h('div',{class: 'big'},[h('h1',{},text('Title')),h('p',{class: 'aligned'},[text('Content 1'),h('br',{}),text('Content 2')]),])

Injecting props

If you have non-string props you want to add to your vnodes, or values kept in variables, use the ${val} syntax to inject them:

constfoo=32constnode=html`<pclass=${{bigger: foo>30}}>...</p>`

Spreading props

If you have a bunch of props you want to assign, you don't have to write them out individually, you can just:

constprops={class: 'bigger',id: 'a-1',key: 'a-1'}constnode=html`<p${props}>...</p>`

(For compatibility with views you may have written using htm, the ...${props} syntax is also supported)

Injecting content.

constname='Joe'constgreeting=html`<span>Hello ${name}!</span>`

results in h('span', {}, [text('Hello'), text('Joe'), text('!')]).

Content can be a string or a vnode. Content can also be an array:

constnames=['Kim','Robin','Sam']constperson=name=>html`<p>${name}</p>`constlist=html`<div><p>Members:</p>${names.map(person)}</div>`

results in list being equivalent to:

h('div',{},[h('p',{},text('Members:')),h('p',{},text('Kim')),h('p',{},text('Robin')),h('p',{},text('Sam')),])

Since hyperapp filters out falsy children, you can conditionally render some content:

constshow=falsehtml`<p>Secret: ${show&&'I work for the CIA'}</p>`

Components

Let's say you have this component:

constbox=(props,content)=>html`<divclass=${{fancy: true,active: props.active}}><h1>${props.title}</h1>${content}</div>`

You could of course add it to a view in this way:

constview=html`<main>${box({active: false,title: 'My bio'},[html`<p>Lorem ipsum</p>`,html`<p>Dolor sit amet</p>`,])}</main>`

But hyperlit allows you to do it this way as well:

constview=html`<main><${box}active=${false} title="My bio"><p>Lorem ipsum</p><p>Dolor sit amet</p><//></main>`

For backwards compatibility with htm it is also possible to close components as </${box}>

Tooling

Transform to plain function calls with Babel

This library is meant to let you write html-like views that can be rendered in the browser without any build step. Still, you might eventually perfer the parsing to be taken care of by your build-toolchain in order to get faster renders. Of course you should be able to do so! Simply add babel-plugin-hyperlit to your babel config. In package.json for example, it looks like this:

"babel": {
"plugins": ["hyperlit"]
}

With that, babel will make sure to transform all your hyperlit views into plain function calls, so the browser doesn't have to do any parsing.

Syntax highlighting

If you use VS Code, install the lit-html to get highlighting and autocompletion that works well with hyperlit.

Credits

This project was inspired by Jason Miller'shtm. I made it to have a similar solution that would work well with Hyperapp.

Thanks to Jorge Bucaran for making Hyperapp and for coming up with the name of this project!

About

A JSX-like ttl for Hyperapp

Resources

Stars

68 stars

Watchers

5 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

hyperlit

hyperlit lets you declare your hyperapp views in a html-like fashion, similar to JSX. Unlike JSX you don't need a build-step and babel config to do it -- it happens run-time in your browser. It's quite small – ca 0.6kb.

Here's Hyperapp's "Quickstart" example using hyperlit:

<!DOCTYPE html><htmllang="en"><head><scripttype="module">import{app}from'https://unpkg.com/hyperapp'importhtmlfrom'https://unpkg.com/hyperlit'app({init: 0,view: state=>html`<main><h1>${state}</h1><buttononclick=${state=>state-1}>-</button><buttononclick=${state=>state+1}>+</button></main>`,node: document.getElementById('app')})</script></head><body><mainid="app"></main></body></html>

In the following instructions I will just focus on how hyperlit replaces Hyperapp's h function. For actually making working apps with this, familiarity with Hyperapp is assumed.

Getting hyperlit into your project

Using npm

In projects where you do bundle your app up, install hyperlit using:

npm i hyperlit

Note that hyperapp is a peer-dependency which you'll also need to have installed.

Once installed, you can import hyperlit wherever you declare views:

importhtmlfrom'hyperlit'

Browser modules

If you prefer not to use npm, you can use client side imports directly like this:

importhtmlfrom'https://unpkg.com/hyperlit'

Usage

Hyperlit replaces hyperapp's built-in h, allowing you to write:

html`<divclass="big"><h1>Title</h1><pclass="aligned"> Content 1 <br/> Content 2</p></div>`

instead of:

h('div',{class: 'big'},[h('h1',{},text('Title')),h('p',{class: 'aligned'},[text('Content 1'),h('br',{}),text('Content 2')]),])

Injecting props

If you have non-string props you want to add to your vnodes, or values kept in variables, use the ${val} syntax to inject them:

constfoo=32constnode=html`<pclass=${{bigger: foo>30}}>...</p>`

Spreading props

If you have a bunch of props you want to assign, you don't have to write them out individually, you can just:

constprops={class: 'bigger',id: 'a-1',key: 'a-1'}constnode=html`<p${props}>...</p>`

(For compatibility with views you may have written using htm, the ...${props} syntax is also supported)

Injecting content.

constname='Joe'constgreeting=html`<span>Hello ${name}!</span>`

results in h('span', {}, [text('Hello'), text('Joe'), text('!')]).

Content can be a string or a vnode. Content can also be an array:

constnames=['Kim','Robin','Sam']constperson=name=>html`<p>${name}</p>`constlist=html`<div><p>Members:</p>${names.map(person)}</div>`

results in list being equivalent to:

h('div',{},[h('p',{},text('Members:')),h('p',{},text('Kim')),h('p',{},text('Robin')),h('p',{},text('Sam')),])

Since hyperapp filters out falsy children, you can conditionally render some content:

constshow=falsehtml`<p>Secret: ${show&&'I work for the CIA'}</p>`

Components

Let's say you have this component:

constbox=(props,content)=>html`<divclass=${{fancy: true,active: props.active}}><h1>${props.title}</h1>${content}</div>`

You could of course add it to a view in this way:

constview=html`<main>${box({active: false,title: 'My bio'},[html`<p>Lorem ipsum</p>`,html`<p>Dolor sit amet</p>`,])}</main>`

But hyperlit allows you to do it this way as well:

constview=html`<main><${box}active=${false} title="My bio"><p>Lorem ipsum</p><p>Dolor sit amet</p><//></main>`

For backwards compatibility with htm it is also possible to close components as </${box}>

Tooling

Transform to plain function calls with Babel

This library is meant to let you write html-like views that can be rendered in the browser without any build step. Still, you might eventually perfer the parsing to be taken care of by your build-toolchain in order to get faster renders. Of course you should be able to do so! Simply add babel-plugin-hyperlit to your babel config. In package.json for example, it looks like this:

"babel": {
"plugins": ["hyperlit"]
}

With that, babel will make sure to transform all your hyperlit views into plain function calls, so the browser doesn't have to do any parsing.

Syntax highlighting

If you use VS Code, install the lit-html to get highlighting and autocompletion that works well with hyperlit.

Credits

This project was inspired by Jason Miller'shtm. I made it to have a similar solution that would work well with Hyperapp.

Thanks to Jorge Bucaran for making Hyperapp and for coming up with the name of this project!

About

A JSX-like ttl for Hyperapp

Resources

Stars

68 stars

Watchers

5 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

hyperlit

hyperlit lets you declare your hyperapp views in a html-like fashion, similar to JSX. Unlike JSX you don't need a build-step and babel config to do it -- it happens run-time in your browser. It's quite small – ca 0.6kb.

Here's Hyperapp's "Quickstart" example using hyperlit:

<!DOCTYPE html><htmllang="en"><head><scripttype="module">import{app}from'https://unpkg.com/hyperapp'importhtmlfrom'https://unpkg.com/hyperlit'app({init: 0,view: state=>html`<main><h1>${state}</h1><buttononclick=${state=>state-1}>-</button><buttononclick=${state=>state+1}>+</button></main>`,node: document.getElementById('app')})</script></head><body><mainid="app"></main></body></html>

In the following instructions I will just focus on how hyperlit replaces Hyperapp's h function. For actually making working apps with this, familiarity with Hyperapp is assumed.

Getting hyperlit into your project

Using npm

In projects where you do bundle your app up, install hyperlit using:

npm i hyperlit

Note that hyperapp is a peer-dependency which you'll also need to have installed.

Once installed, you can import hyperlit wherever you declare views:

importhtmlfrom'hyperlit'

Browser modules

If you prefer not to use npm, you can use client side imports directly like this:

importhtmlfrom'https://unpkg.com/hyperlit'

Usage

Hyperlit replaces hyperapp's built-in h, allowing you to write:

html`<divclass="big"><h1>Title</h1><pclass="aligned"> Content 1 <br/> Content 2</p></div>`

instead of:

h('div',{class: 'big'},[h('h1',{},text('Title')),h('p',{class: 'aligned'},[text('Content 1'),h('br',{}),text('Content 2')]),])

Injecting props

If you have non-string props you want to add to your vnodes, or values kept in variables, use the ${val} syntax to inject them:

constfoo=32constnode=html`<pclass=${{bigger: foo>30}}>...</p>`

Spreading props

If you have a bunch of props you want to assign, you don't have to write them out individually, you can just:

constprops={class: 'bigger',id: 'a-1',key: 'a-1'}constnode=html`<p${props}>...</p>`

(For compatibility with views you may have written using htm, the ...${props} syntax is also supported)

Injecting content.

constname='Joe'constgreeting=html`<span>Hello ${name}!</span>`

results in h('span', {}, [text('Hello'), text('Joe'), text('!')]).

Content can be a string or a vnode. Content can also be an array:

constnames=['Kim','Robin','Sam']constperson=name=>html`<p>${name}</p>`constlist=html`<div><p>Members:</p>${names.map(person)}</div>`

results in list being equivalent to:

h('div',{},[h('p',{},text('Members:')),h('p',{},text('Kim')),h('p',{},text('Robin')),h('p',{},text('Sam')),])

Since hyperapp filters out falsy children, you can conditionally render some content:

constshow=falsehtml`<p>Secret: ${show&&'I work for the CIA'}</p>`

Components

Let's say you have this component:

constbox=(props,content)=>html`<divclass=${{fancy: true,active: props.active}}><h1>${props.title}</h1>${content}</div>`

You could of course add it to a view in this way:

constview=html`<main>${box({active: false,title: 'My bio'},[html`<p>Lorem ipsum</p>`,html`<p>Dolor sit amet</p>`,])}</main>`

But hyperlit allows you to do it this way as well:

constview=html`<main><${box}active=${false} title="My bio"><p>Lorem ipsum</p><p>Dolor sit amet</p><//></main>`

For backwards compatibility with htm it is also possible to close components as </${box}>

Tooling

Transform to plain function calls with Babel

This library is meant to let you write html-like views that can be rendered in the browser without any build step. Still, you might eventually perfer the parsing to be taken care of by your build-toolchain in order to get faster renders. Of course you should be able to do so! Simply add babel-plugin-hyperlit to your babel config. In package.json for example, it looks like this:

"babel": {
"plugins": ["hyperlit"]
}

With that, babel will make sure to transform all your hyperlit views into plain function calls, so the browser doesn't have to do any parsing.

Syntax highlighting

If you use VS Code, install the lit-html to get highlighting and autocompletion that works well with hyperlit.

Credits

This project was inspired by Jason Miller'shtm. I made it to have a similar solution that would work well with Hyperapp.

Thanks to Jorge Bucaran for making Hyperapp and for coming up with the name of this project!

About

A JSX-like ttl for Hyperapp

Resources

Stars

68 stars

Watchers

5 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

hyperlit

hyperlit lets you declare your hyperapp views in a html-like fashion, similar to JSX. Unlike JSX you don't need a build-step and babel config to do it -- it happens run-time in your browser. It's quite small – ca 0.6kb.

Here's Hyperapp's "Quickstart" example using hyperlit:

<!DOCTYPE html><htmllang="en"><head><scripttype="module">import{app}from'https://unpkg.com/hyperapp'importhtmlfrom'https://unpkg.com/hyperlit'app({init: 0,view: state=>html`<main><h1>${state}</h1><buttononclick=${state=>state-1}>-</button><buttononclick=${state=>state+1}>+</button></main>`,node: document.getElementById('app')})</script></head><body><mainid="app"></main></body></html>

In the following instructions I will just focus on how hyperlit replaces Hyperapp's h function. For actually making working apps with this, familiarity with Hyperapp is assumed.

Getting hyperlit into your project

Using npm

In projects where you do bundle your app up, install hyperlit using:

npm i hyperlit

Note that hyperapp is a peer-dependency which you'll also need to have installed.

Once installed, you can import hyperlit wherever you declare views:

importhtmlfrom'hyperlit'

Browser modules

If you prefer not to use npm, you can use client side imports directly like this:

importhtmlfrom'https://unpkg.com/hyperlit'

Usage

Hyperlit replaces hyperapp's built-in h, allowing you to write:

html`<divclass="big"><h1>Title</h1><pclass="aligned"> Content 1 <br/> Content 2</p></div>`

instead of:

h('div',{class: 'big'},[h('h1',{},text('Title')),h('p',{class: 'aligned'},[text('Content 1'),h('br',{}),text('Content 2')]),])

Injecting props

If you have non-string props you want to add to your vnodes, or values kept in variables, use the ${val} syntax to inject them:

constfoo=32constnode=html`<pclass=${{bigger: foo>30}}>...</p>`

Spreading props

If you have a bunch of props you want to assign, you don't have to write them out individually, you can just:

constprops={class: 'bigger',id: 'a-1',key: 'a-1'}constnode=html`<p${props}>...</p>`

(For compatibility with views you may have written using htm, the ...${props} syntax is also supported)

Injecting content.

constname='Joe'constgreeting=html`<span>Hello ${name}!</span>`

results in h('span', {}, [text('Hello'), text('Joe'), text('!')]).

Content can be a string or a vnode. Content can also be an array:

constnames=['Kim','Robin','Sam']constperson=name=>html`<p>${name}</p>`constlist=html`<div><p>Members:</p>${names.map(person)}</div>`

results in list being equivalent to:

h('div',{},[h('p',{},text('Members:')),h('p',{},text('Kim')),h('p',{},text('Robin')),h('p',{},text('Sam')),])

Since hyperapp filters out falsy children, you can conditionally render some content:

constshow=falsehtml`<p>Secret: ${show&&'I work for the CIA'}</p>`

Components

Let's say you have this component:

constbox=(props,content)=>html`<divclass=${{fancy: true,active: props.active}}><h1>${props.title}</h1>${content}</div>`

You could of course add it to a view in this way:

constview=html`<main>${box({active: false,title: 'My bio'},[html`<p>Lorem ipsum</p>`,html`<p>Dolor sit amet</p>`,])}</main>`

But hyperlit allows you to do it this way as well:

constview=html`<main><${box}active=${false} title="My bio"><p>Lorem ipsum</p><p>Dolor sit amet</p><//></main>`

For backwards compatibility with htm it is also possible to close components as </${box}>

Tooling

Transform to plain function calls with Babel

This library is meant to let you write html-like views that can be rendered in the browser without any build step. Still, you might eventually perfer the parsing to be taken care of by your build-toolchain in order to get faster renders. Of course you should be able to do so! Simply add babel-plugin-hyperlit to your babel config. In package.json for example, it looks like this:

"babel": {
"plugins": ["hyperlit"]
}

With that, babel will make sure to transform all your hyperlit views into plain function calls, so the browser doesn't have to do any parsing.

Syntax highlighting

If you use VS Code, install the lit-html to get highlighting and autocompletion that works well with hyperlit.

Credits

This project was inspired by Jason Miller'shtm. I made it to have a similar solution that would work well with Hyperapp.

Thanks to Jorge Bucaran for making Hyperapp and for coming up with the name of this project!

About

A JSX-like ttl for Hyperapp

Resources

Stars

68 stars

Watchers

5 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

hyperlit

hyperlit lets you declare your hyperapp views in a html-like fashion, similar to JSX. Unlike JSX you don't need a build-step and babel config to do it -- it happens run-time in your browser. It's quite small – ca 0.6kb.

Here's Hyperapp's "Quickstart" example using hyperlit:

<!DOCTYPE html><htmllang="en"><head><scripttype="module">import{app}from'https://unpkg.com/hyperapp'importhtmlfrom'https://unpkg.com/hyperlit'app({init: 0,view: state=>html`<main><h1>${state}</h1><buttononclick=${state=>state-1}>-</button><buttononclick=${state=>state+1}>+</button></main>`,node: document.getElementById('app')})</script></head><body><mainid="app"></main></body></html>

In the following instructions I will just focus on how hyperlit replaces Hyperapp's h function. For actually making working apps with this, familiarity with Hyperapp is assumed.

Getting hyperlit into your project

Using npm

In projects where you do bundle your app up, install hyperlit using:

npm i hyperlit

Note that hyperapp is a peer-dependency which you'll also need to have installed.

Once installed, you can import hyperlit wherever you declare views:

importhtmlfrom'hyperlit'

Browser modules

If you prefer not to use npm, you can use client side imports directly like this:

importhtmlfrom'https://unpkg.com/hyperlit'

Usage

Hyperlit replaces hyperapp's built-in h, allowing you to write:

html`<divclass="big"><h1>Title</h1><pclass="aligned"> Content 1 <br/> Content 2</p></div>`

instead of:

h('div',{class: 'big'},[h('h1',{},text('Title')),h('p',{class: 'aligned'},[text('Content 1'),h('br',{}),text('Content 2')]),])

Injecting props

If you have non-string props you want to add to your vnodes, or values kept in variables, use the ${val} syntax to inject them:

constfoo=32constnode=html`<pclass=${{bigger: foo>30}}>...</p>`

Spreading props

If you have a bunch of props you want to assign, you don't have to write them out individually, you can just:

constprops={class: 'bigger',id: 'a-1',key: 'a-1'}constnode=html`<p${props}>...</p>`

(For compatibility with views you may have written using htm, the ...${props} syntax is also supported)

Injecting content.

constname='Joe'constgreeting=html`<span>Hello ${name}!</span>`

results in h('span', {}, [text('Hello'), text('Joe'), text('!')]).

Content can be a string or a vnode. Content can also be an array:

constnames=['Kim','Robin','Sam']constperson=name=>html`<p>${name}</p>`constlist=html`<div><p>Members:</p>${names.map(person)}</div>`

results in list being equivalent to:

h('div',{},[h('p',{},text('Members:')),h('p',{},text('Kim')),h('p',{},text('Robin')),h('p',{},text('Sam')),])

Since hyperapp filters out falsy children, you can conditionally render some content:

constshow=falsehtml`<p>Secret: ${show&&'I work for the CIA'}</p>`

Components

Let's say you have this component:

constbox=(props,content)=>html`<divclass=${{fancy: true,active: props.active}}><h1>${props.title}</h1>${content}</div>`

You could of course add it to a view in this way:

constview=html`<main>${box({active: false,title: 'My bio'},[html`<p>Lorem ipsum</p>`,html`<p>Dolor sit amet</p>`,])}</main>`

But hyperlit allows you to do it this way as well:

constview=html`<main><${box}active=${false} title="My bio"><p>Lorem ipsum</p><p>Dolor sit amet</p><//></main>`

For backwards compatibility with htm it is also possible to close components as </${box}>

Tooling

Transform to plain function calls with Babel

This library is meant to let you write html-like views that can be rendered in the browser without any build step. Still, you might eventually perfer the parsing to be taken care of by your build-toolchain in order to get faster renders. Of course you should be able to do so! Simply add babel-plugin-hyperlit to your babel config. In package.json for example, it looks like this:

"babel": {
"plugins": ["hyperlit"]
}

With that, babel will make sure to transform all your hyperlit views into plain function calls, so the browser doesn't have to do any parsing.

Syntax highlighting

If you use VS Code, install the lit-html to get highlighting and autocompletion that works well with hyperlit.

Credits

This project was inspired by Jason Miller'shtm. I made it to have a similar solution that would work well with Hyperapp.

Thanks to Jorge Bucaran for making Hyperapp and for coming up with the name of this project!

About

A JSX-like ttl for Hyperapp

Resources

Stars

68 stars

Watchers

5 watching

Forks

Releases

Packages

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

hyperlit

hyperlit lets you declare your hyperapp views in a html-like fashion, similar to JSX. Unlike JSX you don't need a build-step and babel config to do it -- it happens run-time in your browser. It's quite small – ca 0.6kb.

Here's Hyperapp's "Quickstart" example using hyperlit:

<!DOCTYPE html><htmllang="en"><head><scripttype="module">import{app}from'https://unpkg.com/hyperapp'importhtmlfrom'https://unpkg.com/hyperlit'app({init: 0,view: state=>html`<main><h1>${state}</h1><buttononclick=${state=>state-1}>-</button><buttononclick=${state=>state+1}>+</button></main>`,node: document.getElementById('app')})</script></head><body><mainid="app"></main></body></html>

In the following instructions I will just focus on how hyperlit replaces Hyperapp's h function. For actually making working apps with this, familiarity with Hyperapp is assumed.

Getting hyperlit into your project

Using npm

In projects where you do bundle your app up, install hyperlit using:

npm i hyperlit

Note that hyperapp is a peer-dependency which you'll also need to have installed.

Once installed, you can import hyperlit wherever you declare views:

importhtmlfrom'hyperlit'

Browser modules

If you prefer not to use npm, you can use client side imports directly like this:

importhtmlfrom'https://unpkg.com/hyperlit'

Usage

Hyperlit replaces hyperapp's built-in h, allowing you to write:

html`<divclass="big"><h1>Title</h1><pclass="aligned"> Content 1 <br/> Content 2</p></div>`

instead of:

h('div',{class: 'big'},[h('h1',{},text('Title')),h('p',{class: 'aligned'},[text('Content 1'),h('br',{}),text('Content 2')]),])

Injecting props

If you have non-string props you want to add to your vnodes, or values kept in variables, use the ${val} syntax to inject them:

constfoo=32constnode=html`<pclass=${{bigger: foo>30}}>...</p>`

Spreading props

If you have a bunch of props you want to assign, you don't have to write them out individually, you can just:

constprops={class: 'bigger',id: 'a-1',key: 'a-1'}constnode=html`<p${props}>...</p>`

(For compatibility with views you may have written using htm, the ...${props} syntax is also supported)

Injecting content.

constname='Joe'constgreeting=html`<span>Hello ${name}!</span>`

results in h('span', {}, [text('Hello'), text('Joe'), text('!')]).

Content can be a string or a vnode. Content can also be an array:

constnames=['Kim','Robin','Sam']constperson=name=>html`<p>${name}</p>`constlist=html`<div><p>Members:</p>${names.map(person)}</div>`

results in list being equivalent to:

h('div',{},[h('p',{},text('Members:')),h('p',{},text('Kim')),h('p',{},text('Robin')),h('p',{},text('Sam')),])

Since hyperapp filters out falsy children, you can conditionally render some content:

constshow=falsehtml`<p>Secret: ${show&&'I work for the CIA'}</p>`

Components

Let's say you have this component:

constbox=(props,content)=>html`<divclass=${{fancy: true,active: props.active}}><h1>${props.title}</h1>${content}</div>`

You could of course add it to a view in this way:

constview=html`<main>${box({active: false,title: 'My bio'},[html`<p>Lorem ipsum</p>`,html`<p>Dolor sit amet</p>`,])}</main>`

But hyperlit allows you to do it this way as well:

constview=html`<main><${box}active=${false} title="My bio"><p>Lorem ipsum</p><p>Dolor sit amet</p><//></main>`

For backwards compatibility with htm it is also possible to close components as </${box}>

Tooling

Transform to plain function calls with Babel

This library is meant to let you write html-like views that can be rendered in the browser without any build step. Still, you might eventually perfer the parsing to be taken care of by your build-toolchain in order to get faster renders. Of course you should be able to do so! Simply add babel-plugin-hyperlit to your babel config. In package.json for example, it looks like this:

"babel": {
"plugins": ["hyperlit"]
}

With that, babel will make sure to transform all your hyperlit views into plain function calls, so the browser doesn't have to do any parsing.

Syntax highlighting

If you use VS Code, install the lit-html to get highlighting and autocompletion that works well with hyperlit.

Credits

This project was inspired by Jason Miller'shtm. I made it to have a similar solution that would work well with Hyperapp.

Thanks to Jorge Bucaran for making Hyperapp and for coming up with the name of this project!

About

A JSX-like ttl for Hyperapp

Resources

Stars

68 stars

Watchers

5 watching

Forks

Releases

Packages

Used by

Contributors

Languages