v1.18.3

DOM reactivo.
Sin compilación.

Un pequeño sistema de plantillas basado en estándares web que aporta reactividad, estado y componentes al básico JavaScript. Sin paquetes. Sin JSX. Sin magia.

7,6 KBCDN-gzip
0departamentos de terceros
100%estándares 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'))

Amplía tu forma de crear.

Utilice Markup por sí solo para plantillas reactivas o agregue paquetes complementarios específicos cuando su aplicación necesite elementos personalizados, enrutamiento o localización.

Web Components

@beforesemicolon/web-component

Una capa reactiva sobre la API nativa Web Components. Mantenga el modelo de plantilla de Markup mientras agrega props, estado, ciclos de vida y estilos de ámbito.

Leer la documentación

Router

@beforesemicolon/router

Enrutamiento declarativo como etiquetas de componentes web. Redacte páginas, diseños anidados, rutas de consulta y vistas cargadas de forma diferida sin adoptar un enrutador de marco.

Leer la documentación

Intl

@beforesemicolon/intl

Localización para interfaces de componentes primero. Agregue ámbitos locales, mensajes traducidos y ayudantes de formateo que se adapten naturalmente a la interfaz de usuario basada en Markup.

Leer la documentación

La plataforma es el marco.

Estándares web, API web y JavaScript moderno es todo lo que necesita. Markup solo agrega la reactividad.

reactivo

Los literales y funciones de plantilla crean DOM reactivo con estado, ciclos de vida y efectos secundarios.

Pequeño: menos de 8 KB gzip

La compilación del navegador CDN se transfiere a aproximadamente 7,6 KB gzip. Envíe aplicaciones empresariales sin un megabyte de marco.

Estándares web

Tres API simples que amplían la plataforma que ya conoces. Sin abstracciones propietarias.

Conectar y reproducir

Introduzca una etiqueta de secuencia de comandos y listo. Sin pasos de compilación, sin JSX, sin archivos de configuración.

Web Components

Supercarga el Web Components nativo con reactividad. Omita la manipulación manual DOM.

Actualizaciones quirúrgicas

La representación basada en datos significa que DOM se actualiza solo donde y cuando realmente es necesario.

Parece HTML. Se siente como magia.

Estado reactivo, composición de componentes y ciclo de vida: todo desde las primitivas JavaScript que ya conoce.

EJEMPLO 01
Tareas + 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'))
EJEMPLO 02
Componente de botón usando 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)
EJEMPLO 03
Suspenso (asíncrono)
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'))
EJEMPLO 04
Enrutamiento de página
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>
EJEMPLO 05
Ciclos de vida de plantillas
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'))

Instalar en segundos.

Elige tu arma. Markup funciona en todos los lugares donde se ejecuta JavaScript.

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

construir la web, a tu manera.

Únase a los desarrolladores que realizan envíos más rápido con un marco que respeta la plataforma y su tiempo.