Experimental JavaScript framework for building supercharged web components
 
 
 
Go to file
intrnl e3ab5ebc5e
docs: fix syntax
2023-10-25 10:53:53 +07:00
.vscode chore: fmt 2023-09-26 07:48:50 +07:00
packages chore: fmt 2023-09-26 07:48:50 +07:00
playground chore: format playground dist folder 2023-09-26 07:49:53 +07:00
.editorconfig dont trim snap files 2021-12-21 17:56:52 +07:00
.eslintignore chore: eslint ignore bundles 2022-06-06 10:04:43 +07:00
.eslintrc.json chore: fmt 2023-03-07 08:35:08 +07:00
.gitignore chore: add wireit as build runner 2022-08-18 21:44:13 +07:00
.prettierignore chore: format playground dist folder 2023-09-26 07:49:53 +07:00
.prettierrc chore: switch to prettier from dprint 2023-09-26 07:44:12 +07:00
LICENSE add proper license and attribution 2021-12-27 11:32:15 +07:00
README.md docs: fix syntax 2023-10-25 10:53:53 +07:00
jsconfig.json chore: fmt 2023-03-07 08:35:08 +07:00
package.json chore: switch to prettier from dprint 2023-09-26 07:44:12 +07:00
pnpm-lock.yaml chore: switch to prettier from dprint 2023-09-26 07:44:12 +07:00
pnpm-workspace.yaml chore: switch to pnpm 2023-09-26 07:42:54 +07:00

README.md

Velvet

Velvet, an experimental JavaScript framework for building supercharged web components.

Summary

A template like this...

<script>
	let count = 0;

	function increment() {
		count += 1;
	}
</script>

<button @click={increment}>Clicked {count} times</button>

...is transformed into a web component with efficient DOM mutations...

import { append, clone, define, html, on, signal, text, traverse } from '@intrnl/velvet/internal';

let template0 = html('<button>Clicked <!> times</button>');

function setup($$root, $$host) {
	let count = signal(0);

	function increment() {
		count.value += 1;
	}

	let fragment0 = clone(template0);

	let marker0 = traverse(fragment0, [0, 1]);
	let child0 = traverse(fragment0, [0]);

	text(marker0, () => count.value);
	on(child0, 'click', increment);

	append($$root, fragment0);
}

export default define('x-app', setup, {}, []);

Overview

Hello, world!

Velvet components are self-contained fragments of HTML-like templating along with related scripting and styling code for it, written in a .velvet file.

<h1>Hello, world!</h1>

These components are generated into a valid web component, and are named based off their file names by default, so Greeting.velvet becomes x-greeting, and you can use it as you would with regular HTML elements.

<x-greeting name="world"></x-greeting>
let greet = document.createElement('x-greeting');
greet.name = 'world';

Expressions

Our current component looks a little empty, so let's give it some flair by first defining a <script> element to define our name variable in.

<script>
	let name = 'world';
</script>

<h1>Hello, world!</h1>

We can then refer to the name variable within the template:

<h1>Hello, {name}!</h1>

These curly braces here acts as a window to running JS expressions right within the template, so we can do other things like calling a format function like so:

<script>
	const today = new Date();
	const formatter = new Intl.DateTimeFormat('en-US', { weekday: 'long' });
</script>

<p>Today is {formatter.format(today)}</p>

These curly braces can also be used to control element attributes

<script>
	let name = 'Katherine Johnson';
	let src = 'https://i.imgur.com/MK3eW3As.jpg';
</script>

<h3>Amazing scientists</h3>

<img src="{src}" alt="{name}" />

Styling

Velvet components can have a <style> tag, where all the styling are scoped to the component. They can't affect other elements that are elsewhere in your app.

<p>This is a paragraph.</p>

<style>
	p {
		color: purple;
		font-size: 2em;
	}
</style>