Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/nicojs/typed-html
TypeSafe HTML templates using TypeScript. No need to learn a template library.
https://github.com/nicojs/typed-html
html template-engine typescript
Last synced: 12 days ago
JSON representation
TypeSafe HTML templates using TypeScript. No need to learn a template library.
- Host: GitHub
- URL: https://github.com/nicojs/typed-html
- Owner: nicojs
- Created: 2017-04-18T15:43:42.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2024-02-17T13:14:31.000Z (9 months ago)
- Last Synced: 2024-04-14T06:39:32.153Z (7 months ago)
- Topics: html, template-engine, typescript
- Language: TypeScript
- Homepage:
- Size: 921 KB
- Stars: 322
- Watchers: 7
- Forks: 41
- Open Issues: 22
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
README
[![Build Status](https://travis-ci.org/nicojs/typed-html.svg?branch=master)](https://travis-ci.org/nicojs/typed-html)
# Typed HTML
HTML templates have never been this easy. Type safe using plain TypeScript with a minimal runtime footprint.
No need to learn a template language, if you know TypeScript, you're set.This:
```typescript
// example.tsx
const item = 'item';
const icon = 'icon-add';
const ul =
- {item}
typeof ul; // string
const button =
;
typeof button; // string
console.log(ul);
console.log(button);
```
Prints:
```html
- item
```
## Getting started
Install:
```bash
npm install --save typed-html
```
Configure your TypeScript compiler for JSX:
```json
{
"compilerOptions": {
"jsx": "react",
"jsxFactory": "elements.createElement"
}
}
```
Although we're configuring the compiler to use [React](https://facebook.github.io/react), this is not what is being used.
Instead, we redirect all jsx element to typed-html's `elements.createElement`.
Now create a \*.ts**x** file. For example: `example.tsx` with the following content:
```typescript
// example.tsx
import * as elements from 'typed-html';
const w = 'world';
const helloWorld =
Hello {w}
;typeof helloWorld; // => Just a string of course
```
However, the following piece of code will **NOT** compile:
```typescript
; // => Error: Property 'foo' does not exist on type 'JSX.IntrinsicElements'.
; // => Error: Property 'foo' does not exist on type 'HtmlAnchorTag'
```
## Supported environments
Typed HTML supports both NodeJS and (since 2.0) the browser.
For use in the browser, either load typed-html as a module, or use a bundler like webpack or rollup to bundle the package for you.
```ts
// Direct ES import:
import * as elements from './node_modules/typed-html/dist/elements.js';
// OR, when using a bundler like rollup or webpack
import * as elements from 'typed-html';
```
## Supported scenarios
All template scenarios are supported with plain TypeScript.
### Control flow
Conditional template with `?`
```typescript
```
Repeat a template with `Array.map`
```typescript
const items = ['item', 'item2'];
- {i} )}
{items.map(i =>
```
### Helper templates
Want a helper template? Just call a function
```typescript
function listItem(n: number) {
return
}
{[1, 2].map(listItem)}
```
#### Using a helper template like an element
Want a helper component? Create a function that implements CustomElementHandler and you can call it like an HTML element.
```typescript
import {Attributes, CustomElementHandler} from "typed-html"
function Button(attributes: Attributes | undefined, contents: string[]) {
return
}
// Or
const Button: CustomElementHandler = (attributes, contents) =>
}
console.log(Button Text);
```
Prints:
```html
Button Text
```
#### React-style children
It's possible to write React-style components as well. Consider the example below.
```typescript
import {Attributes, CustomElementHandler} from "typed-html"
function Button({ children, ...attributes }: Attributes) {
return
}
console.log(Button Text);
```
Prints:
```html
Button Text
```
## Sanitization
Security is *NOT* a feature. This library does *NOT* sanitize.
```ts
const script = 'alert("hacked!")';
const body = {script};
```
Will result in:
```html
alert('hacked!');
```
If you need sanitization, you can use something like [sanitize-html](https://www.npmjs.com/package/sanitize-html).
## Supported HTML
All HTML elements and attributes are supported, except for the [svg](https://www.w3.org/TR/SVG/).
* Supported html elements: https://dev.w3.org/html5/html-author/#the-elements
* Supported html events: http://htmlcss.wikia.com/wiki/HTML5_Event_Attributes
Missing an element or attribute? Please create an issue or a PR to add it. It's easy to add.
### Void elements
[Void elements](https://www.w3.org/TR/html51/syntax.html#void-elements) (elements without closing tags) are supported, however you should close them in TypeScript.
```typescript
const img = ; // => Error! JSX element 'img' has no corresponding closing tag.
```
In the example above, closing the image tag is required for valid TSX code:
```typescript
const img = ; // => ''
```
See [this code](https://github.com/nicojs/typed-html/blob/master/src/elements.tsx#L68) for a list of supported void elements.
### Attribute types
All HTML attributes support a string value, however some attributes also support a [`number`](https://www.w3.org/TR/html51/infrastructure.html#numbers), [`Date`](https://www.w3.org/TR/html51/infrastructure.html#dates-and-times) or [`boolean`](https://www.w3.org/TR/html51/infrastructure.html#sec-boolean-attributes)(or absent value) type:
```typescript
;
// =>
;
;
;
const date = new Date('1914-12-20T08:00');
;
// =>
updated;
old;
// =>
```
## Custom elements
You can add custom elements by adding them to the [intrinsic elements](https://www.typescriptlang.org/docs/handbook/jsx.html#intrinsic-elements) yourself:
```typescript
// MyCustomElements.d.ts
declare namespace JSX {
interface CustomElement {
customAttribute?: string;
}
interface IntrinsicElements {
myCustomElement: CustomElement;
}
}
```
Now you can use it:
```typescript
// UseCustomElement.ts
import * as elements from 'typed-html';
const myElement =
console.log(myElement);
```
This prints:
```html
```
### Custom attributes
Custom attribute names are already supported out-of-the-box for attributes with a dash (`-`) in the name. For example:
```typescript
```
### Transformation
As a browser is case insensitive when it comes to element and attribute names, it is common practice to use [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles) for this. However `` is not allowed in TypeScript. Therefore `typed-html` will transform `` to ``.
This transformation also works for custom attributes you define on a custom element yourself. For example:
```typescript
```
Becomes
```html
```
## How this all works
The way this works is by using TypeScript's jsx support, but not for jsx/react interoperability. Instead, it defines the *normal* html tags as `IntrinsicElements` in the JSX namespace.
At runtime, the `elements.createElement` function is called for every html tag. It simply converts the given element to a string with minimal overhead.
This:
```typescript
- {[1, 2].map(i =>
- {i} )}
```
Compiles to:
```javascript
elements.createElement("ol", { start: 2 }, [1, 2].map(function (li) {
return elements.createElement("li", null, li);
}));
```
Which translates to:
```html
- 1
- 2
```