Skip to content
These are temporary community docs. The official docs are in progress.Help improve them
Markless
Esc
↑↓navigate↵open⌘Jpreview
On this page

Markup and expressions

How text, attributes, and expressions in .tsrx markup turn into updates that the compiler plans ahead.

Last page, {count} sat inside a button. What else fits inside the braces?

Most expressions do. The compiler reads each pair of braces at build time and notes which state it reads. When that state changes, Markless updates that one text or attribute.

An attribute can do one more thing. Its value decides if the attribute exists at all.

Click Count three times.

When does the button get disabled?

Click Count three times. Watch the button's HTML under the page.

The pageTry it
Counter
0

The page's HTML right now

<section class="panel"> <button>Count 0</button> <output>0</output> </section>
Your code: Counter.tsrx
import { state } from '@markless/core'; export default function Counter() @{ let count = state(0); <section class={count > 0 ? 'panel active' : 'panel'}> <button disabled={count >= 3} onClick={() => count++}>Count {count}</button> (false: left out) <output>{count * 2}</output> </section>}
What Markless did
Updates planned before the app ran4class, disabled, 2 texts
count >= 3false
disabled on the buttonleft out
  1. ranRan Counter once, to build the page. count >= 3 is false, so disabled is left out.

Simplified. The HTML view shows the elements this component made. Yellow marks only the text or attribute that changed on the last click.

Notice that disabled appears only when count >= 3 turns true.

Text and attributes

import { state } from '@markless/core';

export default function Counter() @{
	let count = state(0);

	<section class={count > 0 ? 'panel active' : 'panel'}>
		<button disabled={count >= 3} onClick={() => count++}>Count {count}</button>
		<output>{count * 2}</output>
	</section>
}

For this file, the compiler plans four updates: class, disabled, the button text, and the <output> text. Nothing else changes when count changes.

  • false, null, and undefined leave the attribute out. true writes it empty, as in disabled="".
  • aria-* and data-* attributes write true as the text "true".
  • A < that cannot start a tag is text. I <3 this shows as written.
  • {...attrs} copies attributes once. Later changes to attrs do not reach the page, and the compiler warns with MARKLESS_SPREAD_STATIC_SNAPSHOT.

Component tags

<Badge /> renders the component Badge. A tag with a dot, such as <checkbox.root>, must come from an import. If it does not, the build fails with MARKLESS_COMPONENT_TAG_UNRESOLVED.

Coming from another framework?

The braces work like JSX braces. Markless writes class, as HTML does. A class value is a string, not an object.

Next: How do you show a part of the page only some of the time? Control flow →

Was this page helpful?