Skip to content
This repository has been archived by the owner on Jun 27, 2024. It is now read-only.

Commit

Permalink
feat: add styling for jsx using twind (#182)
Browse files Browse the repository at this point in the history
* feat: enable styling for jsx using twind

* test: add testing for tw-in-jsx

* feat: versioning (#180)

* feat: add versioning

* fix outstanding issues

* refactor: small editorial changes to versioning (#181)

* chore: `deno task check`

* refactor: move functionality to `render.tsx`

chore: removed `tw.ts` and let user handle twind install

---------

Co-authored-by: Samuel Kopp <62482066+boywithkeyboard@users.noreply.github.com>
  • Loading branch information
ivy and boywithkeyboard committed Aug 19, 2023
1 parent 20e5b98 commit b6f347c
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 32 deletions.
10 changes: 9 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
{
"deno.enable": true,
"deno.unstable": true
"deno.unstable": true,
"editor.defaultFormatter": "denoland.vscode-deno",
"[typescript]": {
"editor.defaultFormatter": "denoland.vscode-deno"
},
"[typescriptreact]": {
"editor.defaultFormatter": "denoland.vscode-deno"
},
"editor.formatOnSave": true
}
23 changes: 23 additions & 0 deletions render.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright 2023 Samuel Kopp. All rights reserved. Apache-2.0 license.
/** @jsx h */
import { default as renderToString } from 'https://esm.sh/preact-render-to-string@6.1.0?deps=preact@10.16.0'
import { h, VNode } from 'https://esm.sh/preact@10.17.0'
import { extract } from 'https://esm.sh/@twind/core@1.1.3'

import { Context } from './mod.ts'

export function render(c: Context, Component: (() => h.JSX.Element) | VNode) {
const html$ = renderToString(
Component instanceof Function ? <Component /> : Component,
)
try {
const { html, css } = extract(html$) // twind throws error when trying to extract if it is not installed
c.res.body = `<style>${css}</style><body>${html}</body>`
} catch (e) {
console.warn('twind is not installed, styles might not be applied')
c.res.body = html$
}
c.res.header('content-type', 'text/html; charset=utf-8')
}

export { h } from 'https://esm.sh/preact@10.17.0'
13 changes: 11 additions & 2 deletions test/deps.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
export { assertEquals } from 'https://deno.land/std@0.198.0/assert/assert_equals.ts'
export { assertInstanceOf } from 'https://deno.land/std@0.198.0/assert/assert_instance_of.ts'
export {
assert,
assertEquals,
assertInstanceOf,
} from 'https://deno.land/std@0.198.0/assert/mod.ts'
export { z } from 'https://deno.land/x/zod@v3.21.4/mod.ts'
export { defineConfig } from 'https://esm.sh/@twind/core@1.1.3'
import presetAutoPrefix from 'https://esm.sh/@twind/preset-autoprefix@1.0.7'
import presetTailwind from 'https://esm.sh/@twind/preset-tailwind@1.1.4'
export { presetAutoPrefix, presetTailwind }
export { DOMParser } from 'https://deno.land/x/deno_dom@v0.1.38/deno-dom-wasm.ts'
export { install } from 'https://esm.sh/@twind/core@1.1.3'
49 changes: 49 additions & 0 deletions test/render.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2023 Samuel Kopp. All rights reserved. Apache-2.0 license.
/** @jsx h */

import { h, render } from '../render.tsx'
import cheetah from '../mod.ts'
import {
assert,
assertEquals,
defineConfig,
DOMParser,
install,
presetAutoPrefix,
presetTailwind,
} from './deps.ts'

Deno.test('render', async () => {
const app = new cheetah()
install(defineConfig({
presets: [presetAutoPrefix(), presetTailwind()],
}))

function Styled() {
return (
<h3 class='text-sm italic' id='styled'>
styled <code class='font-mono'>h3</code> component
</h3>
)
}

app.get('/a', (c) => render(c, Styled))

const a = await app.fetch(new Request('http://localhost/a'))

const document = new DOMParser().parseFromString(
await a.text(),
'text/html',
)

assert(document)
assert([...document.getElementsByTagName('style')].length)
assertEquals(
document.getElementById('styled')?.innerText,
'styled h3 component',
)
assertEquals(
a.headers.get('content-type'),
'text/html; charset=utf-8',
)
})
1 change: 1 addition & 0 deletions x/jsx.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/** @jsx h */
import { default as renderToString } from 'https://esm.sh/preact-render-to-string@6.1.0?deps=preact@10.16.0'
import { h, VNode } from 'https://esm.sh/preact@10.17.0'

import { Context } from '../mod.ts'

export function jsx(c: Context, Component: (() => h.JSX.Element) | VNode) {
Expand Down
60 changes: 31 additions & 29 deletions x/x.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,34 +20,36 @@ Deno.test('x', async (t) => {
assertEquals(await verify(token, cryptoKey) !== undefined, true)
})

await t.step('jsx', async () => {
const app = new cheetah()

function Custom() {
return <h1>hello world</h1>
}

app.get('/a', (c) => jsx(c, Custom))
app.get('/b', (c) => jsx(c, <Custom />))

const a = await app.fetch(new Request('http://localhost/a'))
const b = await app.fetch(new Request('http://localhost/b'))

assertEquals(
await a.text(),
'<h1>hello world</h1>',
)
assertEquals(
a.headers.get('content-type'),
'text/html; charset=utf-8',
)
assertEquals(
await b.text(),
'<h1>hello world</h1>',
)
assertEquals(
b.headers.get('content-type'),
'text/html; charset=utf-8',
)
await t.step('jsx', async (t) => {
await t.step('plain', async () => {
const app = new cheetah()

function Custom() {
return <h1>hello world</h1>
}

app.get('/a', (c) => jsx(c, Custom))
app.get('/b', (c) => jsx(c, <Custom />))

const a = await app.fetch(new Request('http://localhost/a'))
const b = await app.fetch(new Request('http://localhost/b'))

assertEquals(
await a.text(),
'<h1>hello world</h1>',
)
assertEquals(
a.headers.get('content-type'),
'text/html; charset=utf-8',
)
assertEquals(
await b.text(),
'<h1>hello world</h1>',
)
assertEquals(
b.headers.get('content-type'),
'text/html; charset=utf-8',
)
})
})
})

0 comments on commit b6f347c

Please sign in to comment.