Paint Something New
Palette is a front-end web component and app library which works in tendem with browser APIs to bring modern development ergonomics closer to the platform.
import { define, html, css } from "@rusticarcade/palette";
const CountingButton = define("counting-button", {
template: html`<button>${"$count"}</button>`,
styles: css`
:host {
--border-color: black;
}
button {
font-size: 1.5em;
border: 3px solid var(--border-color);
}
`,
initialState: { count: 0 },
script() {
this.listen("button", "click", () => {
this.liveState.count += 1;
});
}
});
Template with HTML
Palette's templating language is standard HTML. Internally,
Templates use standard <template> elements.
The expressive Notation system allows for binding
data to attributes or utility directives like ::each
and ::swap
// index.html
<!-- Using a normal <template> tag! -->
<template id="user-avatar">
<img :src="@avatar" :title="@username" :alt="*description" />
</template>
<div id="root"></div>
// script.ts
const $root = document.getElementById("root");
const $raw = document.getElementById("user-avatar");
const template = new Template($raw);
template.render($root, {
attr: {
avatar: "...",
username: "...",
},
data: {
description: "...",
},
});
Handle State However
Powerful State management with deep reactivity, array mutation support, and even transactions with rollbacks.
const state = new State({ count: 0 });
state.addListener((current) => {
console.log(current);
});
// Prints "1"
state.set("count", 1);
// Prints "2"
state.patch({
count: 2,
});
// Prints "3"
state.live.count = 3;
// Prints "4"
state.mutate((data) => {
return { count: data.count + 1 }
});
// Prints "5"
state.transaction((s) => {
s.set("count", 5);
});
// Does nothing, rolls back error
state.transaction((s) => {
s.set("count", 6);
throw new Error("Oop!");
});
For the Browser, Not Against
There's a lot of frameworks out there, and a lot of them are very good. However, most try to replace the DOM and browser standards, which made a lot more sense not long ago when browser APIs were much less mature and far quirkier.
Palette was designed inside and out to feel like an extension of the browser rather than an opaque layer atop it. Palette maintains a strict contract with the DOM, giving you the peace of mind to access, modify, and manage elements as you need.
const Demo = define("x-example", {
template: html`<button id="btn"></button>`,
script() {
const btn = this.requireElementById("btn");
// You wanna manually set the text value?
// Go for it!
btn.textContent = "Click me!";
}
});
Take Full Control
The define() helper is great for 90% of Components, but
if you want total control over your E-Destiny, you can directly
extend the Component class for more flexibility:
import { Component, html, css } from "@rusticarcade/palette";
class CountingButton extends Component {
static tagName = "counting-button";
static template = html`<button>${"$count"}</button>`;
static styles = css`
:host {
--border-color: black;
}
button {
font-size: 1.5em;
border: 3px solid var(--border-color);
}
`;
initialState = { count: 0 };
script() {
this.listen("button", "click", () => {
this.liveState.count += 1;
});
}
};
Component.register(CountingButton);