From cccdac299387314d28886bdea3f2f63f7d96608f Mon Sep 17 00:00:00 2001 From: Rafael Bardini Date: Fri, 2 Aug 2024 16:58:03 +0200 Subject: [PATCH] =?UTF-8?q?Release=20the=20Kraken!=20=F0=9F=90=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/publish.yml | 14 +++++++++++++ .gitignore | 1 + .vscode/extensions.json | 5 +++++ .vscode/settings.json | 6 ++++++ LICENSE | 21 +++++++++++++++++++ README.md | 39 +++++++++++++++++++++++++++++++++++ deno.json | 19 +++++++++++++++++ deno.lock | 26 +++++++++++++++++++++++ mod.ts | 11 ++++++++++ mod_test.ts | 32 ++++++++++++++++++++++++++++ 10 files changed, 174 insertions(+) create mode 100644 .github/workflows/publish.yml create mode 100644 .gitignore create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json create mode 100644 LICENSE create mode 100644 README.md create mode 100644 deno.json create mode 100644 deno.lock create mode 100644 mod.ts create mode 100644 mod_test.ts diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..e509609 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,14 @@ +name: Publish +on: + push: + branches: + - main +jobs: + publish: + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + steps: + - uses: actions/checkout@v4 + - run: npx jsr publish diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..09cf720 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "denoland.vscode-deno" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7fe6ae6 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "deno.enable": true, + "deno.lint": true, + "editor.defaultFormatter": "denoland.vscode-deno", + "editor.formatOnSave": true +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0ebbfc0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Rafael Bardini + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..c4de105 --- /dev/null +++ b/README.md @@ -0,0 +1,39 @@ +# @rbardini/html + +[![JSR](https://jsr.io/badges/@rbardini/html)](https://jsr.io/@rbardini/html) +[![JSR Score](https://jsr.io/badges/@rbardini/html/score)](https://jsr.io/@rbardini/html) + +Tiny tagged template literal for no-build JSX-like syntax, compatible with all +modern browsers and runtimes. + +```ts +import { html } from '@rbardini/html' + +const heading = ({ level = 1, children }) => + html`${children}` + +const list = ({ title, items }) => + html` + ${title && heading(title)} + + ` +``` + +Inspired by [jimniels/html](https://github.com/jimniels/html). + +## Usage + +```sh +# Deno +deno add @rbardini/html + +# npm (one of the below, depending on your package manager) +npx jsr add @rbardini/html +yarn dlx jsr add @rbardini/html +pnpm dlx jsr add @rbardini/html +bunx jsr add @rbardini/html +``` + +Or copy-paste the contents of [`mod.ts`](./mod.ts). diff --git a/deno.json b/deno.json new file mode 100644 index 0000000..796420b --- /dev/null +++ b/deno.json @@ -0,0 +1,19 @@ +{ + "name": "@rbardini/html", + "version": "1.0.0", + "exports": "./mod.ts", + "imports": { + "@std/assert": "jsr:@std/assert@1" + }, + "publish": { + "include": [ + "LICENSE", + "README.md", + "mod.ts" + ] + }, + "fmt": { + "semiColons": false, + "singleQuote": true + } +} diff --git a/deno.lock b/deno.lock new file mode 100644 index 0000000..b083dd1 --- /dev/null +++ b/deno.lock @@ -0,0 +1,26 @@ +{ + "version": "3", + "packages": { + "specifiers": { + "jsr:@std/assert@1": "jsr:@std/assert@1.0.2", + "jsr:@std/internal@^1.0.1": "jsr:@std/internal@1.0.1" + }, + "jsr": { + "@std/assert@1.0.2": { + "integrity": "ccacec332958126deaceb5c63ff8b4eaf9f5ed0eac9feccf124110435e59e49c", + "dependencies": [ + "jsr:@std/internal@^1.0.1" + ] + }, + "@std/internal@1.0.1": { + "integrity": "6f8c7544d06a11dd256c8d6ba54b11ed870aac6c5aeafff499892662c57673e6" + } + } + }, + "remote": {}, + "workspace": { + "dependencies": [ + "jsr:@std/assert@1" + ] + } +} diff --git a/mod.ts b/mod.ts new file mode 100644 index 0000000..bfcbcbc --- /dev/null +++ b/mod.ts @@ -0,0 +1,11 @@ +export function html( + strings: TemplateStringsArray, + ...values: unknown[] +): string { + return strings.reduce((acc, string, i) => { + const value = values[i] + if (Array.isArray(value)) return acc + string + value.join('') + if (value != null && !!value !== value) return acc + string + value + return acc + string + }, '') +} diff --git a/mod_test.ts b/mod_test.ts new file mode 100644 index 0000000..d38f192 --- /dev/null +++ b/mod_test.ts @@ -0,0 +1,32 @@ +import { assertEquals } from '@std/assert' +import { html } from './mod.ts' + +Deno.test(function arrayTest() { + const value = [1, 2, 3] + assertEquals(html`
${value}
`, `
${value.join('')}
`) +}) + +Deno.test(function objectTest() { + const value = { a: 1 } + assertEquals(html`
${value}
`, `
${value}
`) +}) + +Deno.test(function stringTest() { + const value = 'string' + assertEquals(html`
${value}
`, `
${value}
`) +}) + +Deno.test(function numberTest() { + const value = 0 + assertEquals(html`
${value}
`, `
${value}
`) +}) + +Deno.test(function nullTest() { + const value = null + assertEquals(html`
${value}
`, `
`) +}) + +Deno.test(function undefinedTest() { + const value = undefined + assertEquals(html`
${value}
`, `
`) +})