RecastTemplate API
RecastTemplate is the key abstraction in Recast that provides a powerful and flexible way to create HTML templates through a proxy interface.
Key Features
Proxy Interface
Method chaining
Attribute access via proxy
Built-in manipulation methods
Extensible API through custom methods
Immutability
Each operation creates a new instance
Safe template reuse
Predictable behavior
No side effects
Template Literals Syntax
Native template string syntax
Children interpolation
Automatic escaping
HTML content support
Type Safety
Full TypeScript support
Attribute validation
Typed methods
Type inference
Basic Usage
1import { div, a } from "@reface/recast/elements";
2
3// Create template
4const base = div({ class: "container" });
5
6// Add attributes (creates new template)
7const withId = base({ id: "main" });
8
9// Add content (creates new template)
10const withContent = base`Hello world`;
11
12// Chain operations (each creates new template)
13const link = a({ href: "/" }).setData("key", "value").addClass("active")`Home`;
Advantages
Composition
1// Base template2const baseButton = button({ class: "btn" });34// Variants (each is a new template)5const primaryButton = baseButton({ class: "primary" });6const secondaryButton = baseButton({ class: "secondary" });7const largeButton = baseButton({ class: "large" });Reusability
1// One template - multiple instances2const card = div({ class: "card" });34const cards = [5 ​card`Content 1`,6 ​card`Content 2`,7 ​card({ id: "special" })`Content 3`,8];Security
1const userInput = '<script>alert("XSS")</script>';23// Automatic escaping4div`${userInput}`;56// Explicit trusted HTML7div`${html`<b>Safe HTML</b>`}`;Extensibility
1const Button = createElementFactory({2 ​type: "element",3 ​methods: {4 ​ ​// Custom methods5 ​ ​primary: ({ raw }) => ({6 ​ ​ ​class: "btn-primary",7 ​ ​}),8 ​ ​loading: ({ raw }, isLoading: boolean) => ({9 ​ ​ ​disabled: isLoading,10 ​ ​ ​"data-loading": String(isLoading),11 ​ ​}),12 ​},13});
Core Imports
1// HTML elements
2import {
3 ​div,
4 ​span,
5 ​p,
6 ​a,
7 ​button,
8 ​input,
9 ​form,
10 ​img /* etc */,
11} from "@reface/recast/elements";
12
13// Core functionality
14import {
15 ​html, // For trusted HTML content
16 ​component, // For creating components
17 ​element, // For creating custom elements
18 ​styled, // For styled templates
19} from "@reface/recast";
API Overview
Template Creation and Manipulation
Basic Operations
1// Create template
2const template = div({ class: "container" });
3
4// Add attributes (creates new template)
5template({ id: "main" });
6
7// Add content (creates new template)
8template`Hello world`;
9
10// Chain operations (each creates new template)
11template({ class: "active" })`Content`;
Content Management
Children Types
1type RecastTemplateChildren =
2 ​| RecastTemplate // Other templates
3 ​| TextContent // Strings, numbers
4 ​| HtmlContent; // Trusted HTML
5
6// Examples
7div`
8 ​${"Plain text"} // TextContent
9 ​${42} // TextContent (converted)
10 ​${button`Click me`} // RecastTemplate
11 ​${html`<b>Bold</b>`} // HtmlContent
12`;
Content Safety
1// Automatic escaping
2const unsafe = '<script>alert("XSS")</script>';
3div`${unsafe}`; // Safely escaped
4
5// Trusted HTML content
6const safe = "<b>Bold</b>";
7div`${html`${safe}`}`; // Rendered as HTML
Attribute Handling
Class Attributes
1div({
2 ​class: "button primary", // String
3 ​class: ["button", "primary"], // Array
4 ​class: {
5 ​ ​// Object with flags
6 ​ ​button: true,
7 ​ ​primary: true,
8 ​ ​disabled: false,
9 ​},
10 ​// Combined
11 ​class: ["button", { primary: true }, condition && "active"],
12});
Style Attributes
1div({
2 ​style: "color: red", // String
3 ​style: ["color: red", "width: 100%"], // Array
4 ​style: {
5 ​ ​// Object (camelCase)
6 ​ ​color: "red",
7 ​ ​backgroundColor: "blue",
8 ​ ​fontSize: "16px",
9 ​},
10});
Data Attributes
1div({
2 ​"data-id": "123",
3 ​"data-type": "button",
4 ​"data-config": JSON.stringify({ key: "value" }),
5});
TypeScript Integration
1// Custom attributes interface
2interface ButtonProps {
3 ​variant: "primary" | "secondary";
4 ​size?: "small" | "large";
5 ​disabled?: boolean;
6}
7
8// Typed template
9const button = createElement<ButtonProps>("button");
10
11// Type checking
12button({ variant: "primary" }); // ✓ OK
13button({ variant: "invalid" }); // ✗ Error
14button({ unknown: true }); // ✗ Error
15
16// With HTML attributes
17interface CardProps extends HTMLAttributes {
18 ​variant?: "outlined" | "filled";
19}
20
21const Card = createElement<CardProps>("div");