Componentes (SFC)

Single-file components defined with <define-component> (inline with name, or external with src). Each instance has its own local state; _ is local and window._ is the global.

Besides Menut’s own examples. Menut is part of Weblin catalog.

Do you want to add a component? See CONTRIBUTING.md for the procedure and conventions, or read the auto-generated reference of the library.

Forms & inputs

x-stepper

<x-stepper min="0" max="10" value="3">

x-rating

<x-rating value="2.5" step="0.5">

x-color-picker

<x-color-picker><div class="swatch" value="#f00" style="background:#f00"></div>…</x-color-picker>

dual-range

<dual-range min="0" max="100" low="25" high="75">


x-pagination

<x-pagination total="10" page="1">

scroll-select

<scroll-select><div class="item" value="a">…</div></scroll-select>

València
Mallorca
Barcelona
Menorca
Alacant

tag-input

<tag-input name="tags" value="apple, mango">

searchable-select

<searchable-select><span role="option" value="1">…</span></searchable-select>

Apple Pear Orange Banana

drop-uploader

<drop-uploader>

highlighted-input

<highlighted-input words="lang:,repo:,user:,AND,OR,NOT">

input-enhanced

<input-enhanced label="Email" hint="..." type="email" required>

Drop-in wrapper: label, hint, error are rendered as field chrome; all other attributes pass straight to the inner <input>. All events are forwarded.

drag-list

<drag-list name="selected"><div class="item" slot="source">…</div><div class="item" slot="target">…</div></drag-list>

Apple
Pear
Orange
Kiwi

Drag between panes, double-click to move, or use the arrows. Form-associated: the right pane is submitted with the form.

order-list

<order-list><div>…</div></order-list>

First
Second
Third
Fourth

One
Two
Three

Vertical and horizontal (horizontal). Drag to reorder.

step-form

<step-form><div class="step">…</div></step-form>

Step 1

Step 2

Step 3

Done.

field-when

<field-when conditions="source=other">…</field-when>

Shows the field only when «Type» = «Other».

form-enhance

<form-enhance><form>…</form></form-enhance>

fullscreen-select

<fullscreen-select name="x"><option>…</option></fullscreen-select>

Basado en <base-select> (Chrome 137+).

date-picker

<date-picker value="2026-08-11" lang="en"></date-picker>

Styled wrapper around the native <input type="date"> with a formatted readout.

date-range-picker

<date-range-picker min="2026-08-01" max="2026-08-31" start="2026-08-10" end="2026-08-20"></date-range-picker>

Dual-handle slider mapped to dates; thumbs show formatted start/end labels.

mini-calendar

<mini-calendar value="2026-08-14" month="2026-08" lang="en"></mini-calendar>

Month grid (Sunday first). Prev/next navigation, today highlight and day selection.

<mini-calendar value="2026-08-14" month="2026-08" lang="es"></mini-calendar>

Month grid (Monday first for Spanish locale).

<mini-calendar value="2026-08-14" week lang="en"></mini-calendar>

Week view: shows only the 7 days of the current week containing value.

address-input

<address-input name="shipping"></address-input>


        

Auto-fills city & state from postal code via zippopotam.us. Detects country from IP. All sub-fields are real <input>/<select> that participate in native form submission. Dispatches address-change with structured {country, postal_code, city, state, street, number}.

Progress & data

x-progress

<x-progress value="72" danger>

progress-circle

<progress-circle style="--value:60,25,15">

45,25 60,25,15

stat-counter

<stat-counter number="1234" duration="2">

x-viewport

<x-viewport>

Resize the window to see the size attribute change. Current:

Sets --vv-width and the size attribute (xs/sm/md/lg/xl) on the host from the visual viewport.

data-grid

<data-grid value="[{…}]" editable key-field="id"></data-grid>

Inline editable table with add/duplicate/delete per row. Emits change.

x-export

<x-export data="[{…}]" format="csv"></x-export>

spark-line

<spark-line values="12,19,3,5,2,3" stroke="#6366f1"></spark-line>

trend

x-countdown

<x-countdown until="2026-12-31T23:59:59" format="d:h:m:s"></x-countdown>

x-inspector

<x-inspector value='{"a":1,"b":[true,false]}'></x-inspector>

liquid-fill

<liquid-fill value="64">Storage · 12.8 GB of 20 GB</liquid-fill>

3.6 GB of 20 GB 12.8 GB of 20 GB Getting full · 4.3 GB free Almost out · 0.8 GB free

Liquid fill progress bar with animated SVG waves. Auto-colors: ≤50% → accent, 51–80% → warn, >80% → err. Override with color attribute. Animations respect prefers-reduced-motion.

Text effects

gradient-text

<gradient-text style="--gradient-from:#6366f1;--gradient-to:#ec4899">

Gradient Text

hero-text

<hero-text style="--hero-hue:320">…<small>Sub</small></hero-text>

CSS TEXT

text-morph

<text-morph>word1 word2 word3</text-morph>

HTML CSS JS HTML-first

text-rotator

<text-rotator words="hello,world,foo">

overlap-text

<overlap-text>Front</overlap-text> · <overlap-text back>

Front Back Alter

rolling-number

<rolling-number value="1234" duration="600"></rolling-number>

Mechanical counter effect. Change value to animate the digits.

dot-display

<dot-display style="--width:128;--height:16" text="MENUT">

Buttons & feedback

rainbow-button

<rainbow-button>Click</rainbow-button> · <rainbow-button outline>

Click Outline

hold-button

<hold-button>Hold to confirm</hold-button>

Hold to confirm

toast-console

<toast-console>

theme-switch

<theme-switch> · <theme-switch full>

Smart dual-state toggle: only light and dark. Clicking the option matching the system re-enables auto-following; clicking the opposite locks the override. Without full it is a round fab; with full the two options show inline.

Layout & nav

x-tree-view

<x-tree-view><ul>…</ul></x-tree-view>

  • src
    • menut.js
    • menut.min.js
    • nested
      • menut.js
      • menut.min.js
  • examples
    • components.html

x-timeline

<x-timeline><div class="item"><time>…</time><strong>…</strong></div></x-timeline>

First releaseMenut is born.
SFC componentsCustom elements.
CatalogComponents converted from Weblin.

x-splitter

<x-splitter><div slot="start">…</div><div slot="end">…</div></x-splitter>

Left
Drag the divider.
Right
Content panel.

shadow-container

<shadow-container>…</shadow-container>

Item 1 — sample content to scroll.

Item 2 — more content.

Item 3 — more content.

Item 4 — more content.

Item 5 — more content.

<shadow-container horizontal>…</shadow-container>

Item 1 — sample content to scroll.

Item 2 — more content.

Item 3 — more content.

Item 4 — more content.

Item 5 — more content.

foot-note

<foot-note num="1">Text</foot-note>

The most cited paper in historyLowry, O. H., et al. J. Biol. Chem. 193, 265–275 (1951). describes a biochemical assay.

x-code-block

<x-code-block lang="js">…</x-code-block>

window._ = { counter: 0 }; _.mount();

show-when

<show-when has-param="debug">…</show-when>

has-lang="es" — visible if browser language includes es has-lang="ca" — visible if browser language includes ca has-network="online" — visible when online has-network="offline" — visible when offline has-media="(prefers-color-scheme: dark)" — visible in dark mode has-media="(min-width: 768px)" — visible on wide screens has-support="display: grid" — visible if CSS supports display: grid has-param="demo" — visible if URL has ?demo has-param="lang=ca" — visible if URL has ?lang=ca has-hash="demo" — visible if hash is #demo has-lang="es" has-network="online" match-any — OR: visible if Spanish or online has-lang="es" has-network="online" — AND: visible only if Spanish and online

fullscreen-menu

<fullscreen-menu><a href="#">…</a></fullscreen-menu>
Shows a top-right button with access to the defined menu options.

live-reload

<live-reload watch-css>

Invisible: watches this page’s CSS/HTML changes and reloads automatically.

scroll-to-top

<scroll-to-top offset="200"></scroll-to-top>

The FAB is fixed to the viewport and floats globally once you scroll past offset pixels.

hover-scroll

<hover-scroll style="height:8rem">Long content…</hover-scroll>

Hover this box to reveal the scrollbar.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.

Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

lazy-load

<lazy-load><template>…</template></lazy-load>

Content inside the <template> is rendered only when the component enters the viewport. Emits lazy-load:visible for infinite scroll scenarios.

preload-links

<preload-links on="hover" intercept><a href="https://example.com">…</a></preload-links>

Preloads linked pages on hover/focus/pointerdown. If intercept is set, clicks serve from cache instantly.

3D & images

border-snap

<border-snap src="photo.jpg" radius="50px" max="400px">

Conditional border-radius: circular when container is wider than max, rectangular when not. Resize to see it adapt.

x-tilt

<x-tilt depth="100" scale="1">…</x-tilt>

Title

3D-tilted content.

layered-tilt

<layered-tilt max="15" scale="1.05"><div layer="40">…</div></layered-tilt>

Front
Back

image-compare

<image-compare><img src="…"><img src="…"></image-compare>

before after

x-map

<x-map lat="39.349222" lng="-0.32394" zoom="13" marker>

Loads Leaflet from CDN asynchronally (needs network).

sound-click / sound-hover

<sound-click src="…">

x-signature

<x-signature pen-color="#0f172a" background="#ffffff"></x-signature>

x-cropper

<x-cropper src="photo.jpg" aspect-ratio="1"></x-cropper>

Content & actions

x-code-highlight

<x-code-highlight lang="javascript">…</x-code-highlight>

Wraps MicroLighter by Dave Rupert. Uses CSS Custom Highlights API — no span injection.

window._ = { counter: 0, increment() { _.counter++ } }; _.mount();

ws-connect

<ws-connect url="wss://echo.rapidtoolset.com/ws" :on.message="…">

WebSocket client with auto-reconnect (3s). The :on.message handler receives the raw MessageEvent — use event.data for the payload (string, JSON, or HTML).


        

sticky-sidebar

<sticky-sidebar style="width:280px">…</sticky-sidebar>

Block 1 above the sidebar — scroll to see it stick.

Block 2 above the sidebar.

Fixed (sticky) sidebar.
Row A
Row B
Row C
Row D

Scroll the page: the sidebar stays fixed while the rows scroll.

server-action

<server-action action="append" target="#sa-list"><li>…</li></server-action>

  • Initial row

Push-based engine: the component runs its action when it appears. These buttons inject sample instances; confirm/ask POST to the demo endpoints components/confirm.php / components/ask.php. The result shows below.

html-load

<html-load src="../components/frag.html" target="#hl-zone" swap="beforeend">

With every attribute for polling (removes the attribute to stop):

json-editor

<json-editor value='{"title":"Menut","version":1}'>

date-time

<date-time format="H:i:s"> · <date-time format="…" date="…" relative>

(seconds — updates every 1s)

(minutes — updates every 1min)

(date — updates hourly)

(relative es — units follow the format)

(relative en — default)

PHP-style format (date() syntax). Auto-updates by the smallest unit: s → 1s, i → 1min, otherwise 1h. relative shows a localized «Hace …» (Intl) choosing the unit from the format; lang sets the locale (default en).

x-markdown

<x-markdown># Hello…</x-markdown> · <x-markdown src="article.md"></x-markdown>

## Menut A **micro** framework for HTML-first components. - Reactive - No build step - Native APIs first

Renders Markdown to HTML using marked.js loaded from CDN. No sanitization is applied.

lorem-ipsum

<lorem-ipsum size="words:30"> · <lorem-ipsum size="paragraphs:2">

virtual-list

<virtual-list style="height:12rem;overflow:auto"><div>item 1</div>…</virtual-list>

sse-connect

<sse-connect src="../components/sse-stream.php" append></sse-connect>

  • Initial row

Opens an SSE connection and appends each message as HTML after the component. Here the server pushes <server-action> fragments that append rows to the list.

cookie-consent

<cookie-consent categories="essential,analytics,marketing">…</cookie-consent>

Bottom bar with Accept All / Reject All at the same level, and a Customize link for granular toggles. Scripts with data-consent="category" load only after consent. Demo bar appears at the page bottom — click "Cookie preferences" link to re-open.

Cookie preferences

We use cookies to analyze traffic and improve your experience. You can accept, reject, or customize your preferences.