v1.18.3

DOM réactif.
Sans compilation.

Un petit système de création de modèles conforme aux normes Web qui apporte réactivité, état et composants à Vanilla JavaScript. Aucun bundler. Pas de JSX. Pas de magie.

7,6 Kogzip CDN
0dépôts tiers
100%normes du Web
javascript
import { html, state, effect } from '@beforesemicolon/markup'

const [count, updateCount] = state(0)

const doubleCount = () => count() * 2

effect(() => {
    console.log(count())
})

const countUp = () => updateCount((prev) => prev + 1)
const countDown = () => updateCount((prev) => prev - 1)

const App = html`
    <h1>Conunter</h1>
    <p><strong>Current count</strong>: ${count}</p>
    <p><strong>Double count</strong>: ${doubleCount}</p>
    <button type="button" onclick="${countDown}">-</button>
    <button type="button" onclick="${countUp}">+</button>
`

App.render(document.getElementById('app'))

Repensez votre façon de créer.

Utilisez Markup seul pour les modèles réactifs, ou ajoutez des packages compagnons ciblés lorsque votre application a besoin d'éléments personnalisés, de routage ou de localisation.

Web Components

@beforesemicolon/web-component

Une couche réactive sur l'API native Web Components. Conservez le modèle de modèle de Markup tout en ajoutant des props, des états, des cycles de vie et des styles étendus.

Lire la documentation

Router

@beforesemicolon/router

Routage déclaratif sous forme de balises de composants Web. Composez des pages, des mises en page imbriquées, des itinéraires de requêtes et des vues à chargement différé sans adopter de routeur de structure.

Lire la documentation

Intl

@beforesemicolon/intl

Localisation pour les interfaces axées sur les composants. Ajoutez des étendues de paramètres régionaux, des messages traduits et des assistants de formatage qui s'intègrent naturellement dans l'interface utilisateur pilotée par Markup.

Lire la documentation

La plateforme est le cadre.

Les normes Web, les API Web et le JavaScript moderne sont tout ce dont vous avez besoin. Markup ajoute simplement de la réactivité.

Réactif

Les littéraux et les fonctions de modèle créent un DOM réactif avec un état, des cycles de vie et des effets secondaires.

Minuscule - moins de 8 Ko gzip

La version du navigateur CDN transfère environ 7,6 Ko de gzip. Expédiez des applications d’entreprise sans un mégaoctet de framework.

Normes Web

Trois API simples qui étendent la plateforme que vous connaissez déjà. Aucune abstraction propriétaire.

Branchez et jouez

Déposez une balise de script et c'est parti. Aucune étape de build, pas de JSX, pas de fichiers de configuration.

Web Components

Boostez le Web Components natif avec réactivité. Ignorer la manipulation manuelle DOM.

Mises à jour chirurgicales

Le rendu basé sur les données signifie que le DOM se met à jour uniquement là et quand cela est réellement nécessaire.

Cela ressemble à HTML. C'est comme de la magie.

État réactif, composition des composants et cycle de vie, le tout à partir des primitives JavaScript que vous connaissez déjà.

EXEMPLE 01
Tâches + localStorage
javascript
import { html, state, effect, repeat } from '@beforesemicolon/markup'

const [todos, setTodos] = state(
    JSON.parse(localStorage.getItem('todos') ?? '[]')
)

effect(() => {
    localStorage.setItem('todos', JSON.stringify(todos()))
})

const addTodo = () => {
    const text = window.prompt('What needs doing?')?.trim()

    if (text) setTodos((prev) => [...prev, { text, done: false }])
}

const toggle = (i) =>
    setTodos(todos().map((t, idx) => (idx === i ? { ...t, done: !t.done } : t)))

html`
    <button type="button" onclick="${addTodo}">Add</button>
    <ul>
        ${repeat(
            todos,
            (todo, i) => html`
                <li
                    class="${todo.done ? 'done' : ''}"
                    onclick="${() => toggle(i)}"
                >
                    ${todo.text}
                </li>
            `
        )}
    </ul>
`.render(document.querySelector('#app'))
EXEMPLE 02
Composant bouton utilisant WebComponent
javascript
import { WebComponent, html } from '@beforesemicolon/web-component'
import stylesheet from './button.css' with { type: 'css' }

class Button extends WebComponent {
    static observedAttributes = ['disabled', 'type']

    type = 'button'
    disabled = false

    stylesheet = stylesheet

    handleClick = (evt) => {
        evt.stopPropagation()
        this.dispatch('click')
    }

    render = () => {
        return html`
            <button ${this.props} class="btn" onclick="${this.handleClick}">
                <slot></slot>
            </button>
        `
    }
}

customElements.define('bfs-button', Button)
EXEMPLE 03
Suspense (asynchrone)
javascript
import { html, suspense } from '@beforesemicolon/markup'

const loadUser = async () => {
    const res = await fetch('/api/me')
    return res.json()
}

const renderUser = async () => {
    const user = await loadUser()
    return html`
        <article>
            <h2>${user.name}</h2>
            <p>${user.bio}</p>
        </article>
    `
}

html`
    <h1>Profile</h1>

    ${suspense(
        renderUser,
        html`<p>Loading profile...</p>`, // fallback
        (err) => html`<p>Failed: ${err.message}</p>` // catch
    )}
`.render(document.querySelector('#app'))
EXEMPLE 04
Routage des pages
html
<!-- in <head>:
<script src="https://unpkg.com/@beforesemicolon/router/dist/client.js"></script>
-->

<nav>
    <page-link path="/">Home</page-link>
    <page-link path="/about">About</page-link>
    <page-link path="/users">Users</page-link>
</nav>

<page-route path="/">
    <h1>Welcome home</h1>
</page-route>

<page-route path="/about" src="./pages/about.js"></page-route>

<page-route path="/users" exact="false">
    <page-route src="./pages/users.js"></page-route>
    <page-route path="/:userId" src="./pages/user.js"></page-route>
</page-route>

<page-route path="/404"> 404 - Page not found! </page-route>

<page-redirect path="/404" title="404 - Page not found!"></page-redirect>
EXEMPLE 05
Cycles de vie des modèles
javascript
import { html, state } from '@beforesemicolon/markup'

const [seconds, setSeconds] = state(0)

html` <p>Elapsed: ${seconds}s</p> `
    .onMount(() => {
        // runs once when attached to the DOM
        const id = setInterval(() => setSeconds(seconds() + 1), 1000)
        return () => clearInterval(id)
    })
    .onUpdate(() => {
        // runs every time a tracked value changes
        console.log('tick', seconds())
    })
    .render(document.querySelector('#app'))

Installez en quelques secondes.

Choisissez votre arme. Markup fonctionne partout où JavaScript s'exécute.

<script src="https://unpkg.com/@beforesemicolon/markup/dist/client.js"></script>
npm install @beforesemicolon/markup
yarn add @beforesemicolon/markup
pnpm add @beforesemicolon/markup

Construire le Web, à votre façon.

Rejoignez les développeurs qui livrent plus rapidement avec un framework qui respecte la plateforme et votre temps.