::: layout landing-hero title=”” title2=”” primaryLabel=”” secondaryLabel=”npm i @beforesemicolon/markup”
=== copy
=== stat
##
=== stat
=== stat
=== code filename=counter.js lang=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'))
:::
::: layout landing-ecosystem
=== header
##
=== product title=”” package=@beforesemicolon/web-component color=orange icon=webComponents href=https://web-component.beforesemicolon.com/
=== product title=Router package=@beforesemicolon/router color=cyan icon=router href=https://router.beforesemicolon.com/
=== product title=Intl package=@beforesemicolon/intl color=primary icon=reactive href=https://intl.beforesemicolon.com/
:::
::: layout landing-features
=== header
##
=== feature icon=reactive
###
=== feature icon=tiny
###
=== feature icon=standards
###
=== feature icon=plug
###
=== feature icon=webComponents
###
=== feature icon=surgical
###
:::
::: layout landing-showcase
=== header
##
=== example label=”” color=orange filename=todos.js lang=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'))
=== example label=”” color=cyan filename=button-component.js lang=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)
=== example label=”” color=orange filename=profile.js lang=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'))
=== example label=”” color=cyan filename=app.html lang=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>
=== example label=”” color=orange filename=timer.js lang=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'))
:::
::: layout landing-install
=== header
##
=== tab key=cdn label=CDN command=”<script src="https://unpkg.com/@beforesemicolon/markup/dist/client.js"></script>”
=== tab key=npm label=npm command=”npm install @beforesemicolon/markup”
=== tab key=yarn label=yarn command=”yarn add @beforesemicolon/markup”
=== tab key=pnpm label=pnpm command=”pnpm add @beforesemicolon/markup”
:::
::: layout landing-cta title=”” title2=””
=== copy
:::