diff --git a/mod.ts b/mod.ts index 93c6db3..2954a8e 100644 --- a/mod.ts +++ b/mod.ts @@ -9,6 +9,7 @@ export type { Extension } from './extensions.ts' export { default as jwt } from './jwt.ts' export { LocationData } from './location_data.ts' export { otp } from './otp.ts' +export { h, Renderer } from './render.ts' export { sendMail } from './send_mail.ts' export { Store } from './store.ts' diff --git a/render.ts b/render.ts new file mode 100644 index 0000000..2b11b8b --- /dev/null +++ b/render.ts @@ -0,0 +1,58 @@ +// Copyright 2023 Samuel Kopp. All rights reserved. Apache-2.0 license. +import { brightYellow, gray } from 'https://deno.land/std@0.198.0/fmt/colors.ts' +import { + defineConfig, + extract, + install, +} 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' +import { default as renderToString } from 'https://esm.sh/preact-render-to-string@6.1.0?deps=preact@10.17.1&target=es2022' +import { VNode } from 'https://esm.sh/preact@10.17.1?target=es2022' +import { Context } from './mod.ts' + +export function render(c: Context, Component: VNode) { + const htmlString = renderToString(Component) + + try { + const { html, css } = extract(htmlString) // twind throws error when trying to extract if it is not installed + + c.res.body = `${html}` + } catch (_err) { + if (c.dev) { + console.warn( + gray( + `${ + brightYellow('warning') + } - twind is not installed, thus styles might not be applied`, + ), + ) + } + + c.res.body = htmlString + } + + c.res.header('content-type', 'text/html; charset=utf-8') +} + +export class Renderer { + render + + constructor(options?: Parameters[0]) { + if (options) { + options.presets = options.presets + ? [presetAutoPrefix(), presetTailwind(), ...options.presets] + : [presetAutoPrefix(), presetTailwind()] + } + + install(defineConfig( + options ?? { + presets: [presetAutoPrefix(), presetTailwind()], + }, + )) + + this.render = render + } +} + +export { h } from 'https://esm.sh/preact@10.17.1?target=es2022' diff --git a/render.tsx b/render.tsx deleted file mode 100644 index 741a6c7..0000000 --- a/render.tsx +++ /dev/null @@ -1,23 +0,0 @@ -// 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, - ) - try { - const { html, css } = extract(html$) // twind throws error when trying to extract if it is not installed - c.res.body = `${html}` - } 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' diff --git a/test/deps.ts b/test/deps.ts index f642d71..44d2a13 100644 --- a/test/deps.ts +++ b/test/deps.ts @@ -3,10 +3,5 @@ export { 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' +export { z } from 'https://deno.land/x/zod@v3.21.4/mod.ts' diff --git a/test/render.test.tsx b/test/render.test.tsx index 219e3c2..92c071d 100644 --- a/test/render.test.tsx +++ b/test/render.test.tsx @@ -1,23 +1,12 @@ // 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' +import cheetah, { h, Renderer } from '../mod.ts' +import { assert, assertEquals, DOMParser } from './deps.ts' Deno.test('render', async () => { const app = new cheetah() - install(defineConfig({ - presets: [presetAutoPrefix(), presetTailwind()], - })) + + const { render } = new Renderer() function Styled() { return ( @@ -27,12 +16,14 @@ Deno.test('render', async () => { ) } - app.get('/a', (c) => render(c, Styled)) + app.get('/a', (c) => render(c, )) const a = await app.fetch(new Request('http://localhost/a')) + const tx = await a.text() + const document = new DOMParser().parseFromString( - await a.text(), + tx, 'text/html', )