Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

TypeSafe HTML templates using TypeScript. No need to learn a template library.

NotificationsYou must be signed in to change notification settings

nicojs/typed-html

Repository files navigation

Build Status

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:

// example.tsxconstitem='item';consticon='icon-add';constul=<ul><li>{item}</li></ul>;typeoful;// stringconstbutton=<buttononclick="handleClick"><iclass={icon}></i></button>;typeofbutton;// stringconsole.log(ul);console.log(button);

Prints:

<ul><li>item</li></ul><buttononclick="handleClick"><iclass="icon-add"></i></button>

Getting started

Install:

npm install --save typed-html

Configure your TypeScript compiler for JSX:

{"compilerOptions": {"jsx":"react","jsxFactory":"elements.createElement"    }}

Although we're configuring the compiler to useReact, this is not what is being used.Instead, we redirect all jsx element to typed-html'selements.createElement.

Now create a *.tsx file. For example:example.tsx with the following content:

// example.tsximport*aselementsfrom'typed-html';constw='world';consthelloWorld=<p>Hello<strong>{w}</strong></p>;typeofhelloWorld;// => Just a string of course

However, the following piece of code willNOT compile:

<foo></foo>;// => Error: Property 'foo' does not exist on type 'JSX.IntrinsicElements'.<afoo="bar"></a>;// => 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.

// Direct ES import:import*aselementsfrom'./node_modules/typed-html/dist/elements.js';// OR, when using a bundler like rollup or webpackimport*aselementsfrom'typed-html';

Supported scenarios

All template scenarios are supported with plain TypeScript.

Control flow

Conditional template with?

<div>Random>0.5:{Math.random()>.5 ?<strong>yes</strong>:'no'}</div>

Repeat a template withArray.map

constitems=['item','item2'];<ul>{items.map(i=><li>{i}</li>)}</ul>;

Helper templates

Want a helper template? Just call a function

functionlistItem(n:number){return<li>{n}</li>;}<ul>{[1,2].map(listItem)}</ul>

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.

import{Attributes,CustomElementHandler}from"typed-html"functionButton(attributes:Attributes|undefined,contents:string[]){return<div><buttontype="button"class="original-class"{...attributes}>{contents}</button></div>;}// OrconstButton:CustomElementHandler=(attributes,contents)=><div><buttontype="button"class="original-class"{...attributes}>{contents}</button></div>;}console.log(<Buttonstyle="color:#f00">ButtonText</Button>);

Prints:

<div><buttontype="button"class="original-class"style="color:#f00">Button Text</button></div>

React-style children

It's possible to write React-style components as well. Consider the example below.

import{Attributes,CustomElementHandler}from"typed-html"functionButton({ children, ...attributes}:Attributes){return<div><buttontype="button"class="original-class"{...attributes}>{children}</button></div>;}console.log(<Buttonstyle="color:#f00">ButtonText</Button>);

Prints:

<div><buttontype="button"class="original-class"style="color:#f00">Button Text</button></div>

Sanitization

Security isNOT a feature. This library doesNOT sanitize.

constscript='<script>alert("hacked!")</script>';constbody=<body>{script}</body>;

Will result in:

<body><script>alert('hacked!');</script></body>

If you need sanitization, you can use something likesanitize-html.

Supported HTML

All HTML elements and attributes are supported, except for thesvg.

Missing an element or attribute? Please create an issue or a PR to add it. It's easy to add.

Void elements

Void elements (elements without closing tags) are supported, however you should close them in TypeScript.

constimg=<imghref="/foo/bar.png">;// => Error! JSX element 'img' has no corresponding closing tag.

In the example above, closing the image tag is required for valid TSX code:

constimg=<imghref="/foo/bar.png"></img>;// => '<img href="/foo/bar.png">'

Seethis code for a list of supported void elements.

Attribute types

All HTML attributes support a string value, however some attributes also support anumber,Date orboolean(or absent value) type:

<metervalue={1}min={0}max={5}low={1}high={4}optimum={3}></meter>;// => <meter value="1" min="0" max="5" low="1" high="4" optimum="3"></meter><olstart={3}></ol>;<progressvalue={3}max={4}></progress>;<tdcolspan={3}rowspan={3}></td>;<thcolspan={3}rowspan={3}></th>;constdate=newDate('1914-12-20T08:00');<timedatetime={date}></time>;// => <time datetime="1914-12-20T08:00:00.000Z"></time><insdatetime={date}>updated</ins>;<deldatetime={date}>old</del>;// => <form> <input type="checkbox" checked> </form><formnovalidate={false}><inputtype="checkbox"checkeddisabled={false}></input></form>

Custom elements

You can add custom elements by adding them to theintrinsic elements yourself:

// MyCustomElements.d.tsdeclarenamespaceJSX{interfaceCustomElement{customAttribute?:string;}interfaceIntrinsicElements{myCustomElement:CustomElement;}}

Now you can use it:

// UseCustomElement.tsimport*aselementsfrom'typed-html';constmyElement=<myCustomElementcustomAttribute="customValue"></myCustomElement>console.log(myElement);

This prints:

<my-custom-elementcustom-attribute="customValue"></my-custom-element>

Custom attributes

Custom attribute names are already supported out-of-the-box for attributes with a dash (-) in the name. For example:

<buttondata-menu-item="3"></button>

Transformation

As a browser is case insensitive when it comes to element and attribute names, it is common practice to usekebab case for this. However<custom-element></custom-element> is not allowed in TypeScript. Thereforetyped-html will transform<customElement></customElement> to<custom-element></custom-element>.

This transformation also works for custom attributes you define on a custom element yourself. For example:

<customElementaCustomAttr="value"></customElement>

Becomes

<custom-elementa-custom-attr="value"></custom-element>

How this all works

The way this works is by using TypeScript's jsx support, but not for jsx/react interoperability. Instead, it defines thenormal html tags asIntrinsicElements in the JSX namespace.

At runtime, theelements.createElement function is called for every html tag. It simply converts the given element to a string with minimal overhead.

This:

<olstart={2}>{[1,2].map(i=><li>{i}</li>)}</ol>

Compiles to:

elements.createElement("ol",{start:2},[1,2].map(function(li){returnelements.createElement("li",null,li);}));

Which translates to:

<olstart="2"><li>1</li><li>2</li></ol>

About

TypeSafe HTML templates using TypeScript. No need to learn a template library.

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp