Skip to main content

Get Started

Learn how to use xnew in less than 10 minutes.

Setup

Via CDN

Include the following script in your HTML file:

<script src="https://unpkg.com/xnew@3.0.x/dist/xnew.js"></script>

Via CDN (ESM)

Use the ES module version with an import map:

<script type="importmap">
{
"imports": {
"xnew": "https://unpkg.com/xnew@3.0.x/dist/xnew.mjs"
}
}
</script>

<script type="module">
import xnew from 'xnew';

// Your code here
</script>

Via npm

Install xnew using npm:

npm install xnew@3.0.x

Then import it in your JavaScript file:

import xnew from 'xnew';

Tutorial

Basic Usage

Calling xnew creates a unit (self). You can define a component function to implement features.

const unit = xnew(Component, ...args);

function Component(self, ...args) {
// Implement features here
}

You can also create a HTML element with xnew:

const unit = xnew({ className: '...', style: '...', ... }, 'inner html');

unit.element; // Access the created element

Example 1: Creating HTML Elements

Use xnew and xnew.nest to create HTML elements.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://unpkg.com/xnew@3.0.x/dist/xnew.js"></script>
</head>
<body>
<script>
// Create first component.
xnew(Component);

function Component(self) {
// Pattern 1: Create new HTML element.
xnew({ tag: 'p' }, 'Create new HTML elements.');

// Pattern 2: Create child component.
xnew(ChildComponent);
}

function ChildComponent(self) {
// If tag is omitted, tag: 'div' is set as default.

// Pattern 3: Create new HTML element and nest the following elements.
xnew.nest({ style: { display: 'flex' } });

// The following elements are nested.
xnew({ style: { width: '160px', height: '36px', background: '#d66' } }, '1');
xnew({ style: { width: '160px', height: '36px', background: '#6d6' } }, '2');
xnew({ style: { width: '160px', height: '36px', background: '#66d' } }, '3');
}
</script>
</body>
</html>

The above program will generate the following HTML elements:

<body>
<p>my div</p>
<div style="display: flex;">
<div style="width: 160px; height: 36px; background: #d66;">1</div>
<div style="width: 160px; height: 36px; background: #6d6;">2</div>
<div style="width: 160px; height: 36px; background: #66d;">3</div>
</div>
</body>

Example 2: Adding Events and Animations

You can implement event listeners and animations in the component function.
In the demo program below, a box is animated. Clicking on the box will toggle it start / stop.

<body>
<script>
xnew(Component);

function Component(self) {
xnew.nest({ style: { position: 'absolute', width: '200px', height: '200px', inset: 0, margin: 'auto', background: '#08F' } });

const text = xnew({ tag: 'span' });

let isRunning = false;
self.on('click', (event) => {
isRunning ? self.stop() : self.start();
});

return {
start() {
isRunning = true;
text.element.textContent = 'start';
},
update(count) {
text.element.style.transform = `rotate(${count}deg)`;
},
stop() {
isRunning = false;
text.element.textContent = 'stop';
},
};
}
</script>
</body>

Example 3: Parent-Child Relation

When xnew is called inside a component function, a parent-child relation is established.
Connected units work together. For example, stopping the parent component also stops its children.

<body>
<script>
xnew(Component);

function Component(self) {
xnew.nest({ style: { position: 'absolute', width: '200px', height: '200px', inset: 0, margin: 'auto', background: '#08F' } });

const text = xnew({ tag: 'span' });

xnew(ChildComponent);

let isRunning = false;
self.on('click', () => {
isRunning ? self.stop() : self.start();
});

return {
start() {
isRunning = true;
text.element.textContent = 'parent: start';
},
update(count) {
self.element.style.transform = `rotate(${count}deg)`;
},
stop() {
isRunning = false;
text.element.textContent = 'parent: stop';
},
};
}

function ChildComponent(self) {
xnew.nest({ style: { position: 'absolute', width: '100px', height: '100px', inset: 0, margin: 'auto', background: '#F80' } });

const text = xnew({ tag: 'span' });

let isRunning = false;
self.on('click', (event) => {
event.stopPropagation(); // Prevent propagation to the parent element
isRunning ? self.stop() : self.start();
});

return {
start() {
isRunning = true;
text.element.textContent = 'child: start';
},
update(count) {
self.element.style.transform = `rotate(${count}deg)`;
},
stop() {
isRunning = false;
text.element.textContent = 'child: stop';
},
};
}
</script>
</body>