Skip to content

ihasq/strix

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GitHub Repo stars npm

GitHub License npm package minimized gzipped size (select exports)


import { html } from '@strix/html';

const Counter = () => {

    let count = 0;

    return () => html`
        <h1>${count}</h1>
        <button @click=${() => count++}>
            Increment
        </button>
    `;
};

export default Counter;

Strix is light-weight DOM manipulation helper.
Visit strix.sh for more infomation.

Open in StackBlitz

Directories

directory about
mod Modules
pkg Packages
kit Developnent Kits
web Publications
repl Playground REPL

Packages

package about exports
html HTML in JavaScript library html
write Client-side HTML Writer write
define Defining Web Components define
set Signal-like Hook set
layout Layout manager layout
nitro Design systems nitro
material3 Material Design 3 port m3
md Markdown-to-HTML Plugin md
react React compatibility hook React

SDK

project about
Trixel Fullstack Strix Framework
Create Project template generator
Analyzer VSCode analyzer

Modules

module about
html HTML template parser
attr Attribute template parser
event Event router

Installation

CDN

import html from 'https://strix.sh/html';
const html = await import('https://strix.sh/html');

NPM

npm create strix@latest

Deno

deno init 

Build From Source

git clone https://github.com/ihasq/strix
deno task build

Smart Attributes on strix-HTML

html`
    <!-- text -->
    <label>${text}</label>
    <!-- attribute -->
    <iframe src=${formURL}; />
    <!-- identifier (not the id attribute) -->
    <img #mainImgRef/>
    <!-- event listener -->
    <button @click=${() => console.log('clicked')}; />
    <input @@keydown=${() => console.log('cancelled')}; /> <!-- preventDefault() -->
    <!-- StrixEffectEvent - triggered when the value changes -->
    <h1 @effect=${() => console.log('changed')};>${count}</h1>
    <!-- style -->
    <h1 *color=${titleColor}></h1>
    <!-- property -->
    <input #inputWithProp type=text; value=ok; />
    <input type=checkbox; value=${true}; /> <!-- CORRECT type -->
    <input type=checkbox; value=true; /> <!-- This is NOT boolean, this is string -->
    <div someprop.deeper='more deeper'; />
    <!-- embedding component -->
    <${DefinedComponent} my-attribute=1; />
    <!-- custom attribute -->
    <div ${name}=taro></div>
    <div ${alsoWithType}=${true}></div>
    <!-- to child elements -->
    <div value&input=${inputvalue}>...</div>
    <!-- branching with psuedo class or booleanish -->
    <button *color:hover=red; *color${Date.now() % 2}=blue></button>
    <!-- nesting -->
    <div
        #hasNested
        :hover {
            *color=red;
        };
        ${window.clientHeight >= 100} {
            *color=blue;
        };
    ></div>
`;

4 Ways To Make View

const Instance = html.new`
    <div>It works!</div>
`;

const Primitive = html`
    <div>It works!</div>
`;

const Transformer = ({ color }) => html`
    <label *color=${color}>Label with colors!</label>
`

const Component = () => {

    let count = 0;

    return () => html`
        <button @click=${() => {
            count++;
            alert(count);
        }}>Fully working!</button>
    `;
};

write(document.body, html`
    <${Instance} />
    <${Primitive} />
    <${Transformer} color=red />
    <${Component} />
`);

Usage

import html from "https://strix.sh/html"

const Count = () => {

    const count = [0],
        buttonText = ['Hover me!'],
        isHovering = () => value => {
            buttonText[0] = value? 'Click me!' : 'Hover me!'
            return html`
                *background-color=red;
                *color=white;
            `;
        };

    return html`
        <p>You clicked ${count} times</p>
        <button
            @click=${() => count[0]++};
            ${isHovering}=${false};
            ${isHovering}:hover=${true};
        >
            ${buttonText}
        </button>
    `;
};

export default Count;
<body onload='
    import("https://strix.sh/write").then(write => write(this, import(this.src)))
'></body>
const Todo = () => {

    const todoArray = [];

    const TodoRow = ({ todoContent, swapRow, deleteRow }) => {

        let todoData = todoContent;
        let isEditable = false;
        let isDone = false;

        return () => html`
            <li
                contenteditable=${isEditable? 'plaintext-only' : undefined}
                @input=${async ({ target }) => todoData = (await target).data}
                @blur=${() => isEditable = false}
                *text-decoration=${isDone? 'line-through' : 'none'}
                *font-style=${isDone? 'italic' : 'normal'}
            >
                ${todoData}
            </li>
            <button @click=${() => isEditable = true}>edit</button>
            <button @click=${() => isDone = true}>done</button>
            <button @click=${() => deleteRow()}>delete</button>
            <button @click=${() => swapRow(1)}>swap above</button>
            <button @click=${() => swapRow(-1)}>swap below</button>
        `
    }

    return () => html`
        <ul>${todoArray}</ul>
        <input @@keydown.Enter=${({ target }) => {
            const newRow = html.new`
                <div
                    *width=100%
                    @dragover=${({ target }) => {
                    }}
                ></div>
                <${TodoRow}
                    draggable=${true}
                    todoContent=${target.value}
                    swapRow=${(direction) => {
                        const i = todoArray.indexOf(newRow);
                        [todoArray[i], todoArray[i + direction]] = [todoArray[i + direction],todoArray[i]];
                    }}
                    deleteRow=${() => delete todoArray[todoArray.indexOf(newRow)]}
                />
            `;
            todoArray.push(newRow);
            target.value = "";
        }} />
    `
}
const ReverseStr = ($) => {
    const { ptr } = $.std;

    const revText = ptr(''),
        textValuePtr = ptr('', true);

    return () => html`
        <input
            type=text;
            value=${textValuePtr};
            @keydown=${async () => revText(value.split('').reverse().join(''))}
        />
        <h2>${revText}</h2>
    `;
};
const C2DApp = html`
    <canvas @load=${({ target: canvas }) => {
        const ctx = canvas.getContext('2d');
        // ...
    }};></canvas>
`;
import nitro from 'https://esm.sh/strix-nitro';
// Nitro Design - The Design System By Strix

const StyleImport = () => {
    return () => html`
        <button ${nitro}>I am themed by Nitro Design!</button>
    `;
};
const sampleAttrModule = () => attr`
    *background-color=${attr.value === 'system' ? '#000' : attr.value === 'dark' ? '#fff' : '#000'}
    *color=red;
    ${anotherAttrModule}=${true}
    :hover {
        *color=blue;
        @click=${() => alert('I am hovered')}
    };
    button {
        @@click=${() => alert('prevented by parent!')}
    };
    &div[${someAttrModule}=${true}] {
        &span {
            amIDeeperChild=${true}
        };
    };
    ::selection {
        *background-color=black; 
    };
`; // psuedo elements are style attributes only

const WithAttributeModule = () => () => html`
    <div ${sampleAttrModule}=system;>
        <button></button>
    </div>
`;
import { center } from 'strix-layout';

const HowToCenterADiv = () => () => html`
    <div ${center}>Now I am a centered div!</div>
`;
import { react } from 'strix-react';

import * as React from 'react@latest';
import { Button } from '@shadcn/ui/components/ui/button';

react.use(React);

const ReactEmbedded = () => () => html`
    <${Button} ${react}>I am the Button from @shadcn/ui in Strix!</${Button}>
`;
const withJsxImportSource = () => {
    let count = 0;
    return () => (
        <div>{count}</div>
        <button @click={() => count++}></button>
    );
}
const primitive = html`<div>Hi</div>`;

const samePrimitive = primitive;
alert(primitive === samePrimitive); // true

const regeneratedPrimitive = primitive.new();
alert(primitive === regeneratedPrimitive); // false

const anotherPrimitive = html`<div>Hi</div>`;
alert(primitive === anotherPrimitive); // false
html`<input type=text; @input=${({ target: { value } }) => alert(value)} />`
html`<input type=text; @input.target.value=${value => alert(value)} />`
const animation = async ({ frame }) => {
    let rgbValue = 0;
    for(let i = 0; i < 60; i++) {
        rgbValue++
        await frame(html`*background-color=#${rgbValue.toString(16).padStart(6, "0")};`);
    }
}

const deltaTime = async ({ delta }) => {
    let rgbValue = 0;
    for(let i = 0; i < 60; i++) {
        rgbValue++
        await delta(html`*background-color=#${rgbValue.toString(16).padStart(6, "0")};`);
    }
}

html`<div @click=${animation}>woooaaah</div>`
const Bidirectional = () => {

    const count = [0, ({ value }) => console.log(value)];

    return () => html`
        <input type=text strix.bind=${count} />
    `
}

License

Strix is MIT Licensed.