Ui kit

Installation

Option 1: All-in-one CSS

Use it if you don't have Tailwind CSS installed and don't want to.

The quickest way to get started is to use the ready-to-use CDN link. It includes all components.


<link rel="stylesheet" href="https://ui.micka.dev/cdn/cdn.min.css" />

Self-hosting

If you prefer to host the CSS yourself, you can download the CSS file and include it from the appropriate path.

Option 2: With Tailwind

Recommended if you already have Tailwind CSS installed, produce the smallest CSS file.

Just download the Tailwind-based CSS file and import it in your app stylesheet.


@import "tailwindcss";
@import "./framework.css";

Components

Accordion

A vertically stacked set of interactive headings that each reveal a section of content.


Product Information

Our flagship product combines cutting-edge technology with sleek design. Built with premium materials, it offers unparalleled performance and reliability.

Shipping Details

We offer worldwide shipping through trusted courier partners. Standard delivery takes 3-5 business days, while express shipping ensures delivery within 1-2 business days.

All orders are carefully packaged and fully insured. Track your shipment in real-time through our dedicated tracking portal.

Return Policy

We stand behind our products with a comprehensive 30-day return policy. If you're not completely satisfied, simply return the item in its original condition.

<details class="accordion" name="yourAccordion1Name" open>
    <summary class="accordion__summary">Product Information</summary>
    <div class="accordion__content">
        <p class="p">
            Our flagship product combines cutting-edge technology with
            sleek design. Built with premium materials, it offers
            unparalleled performance and reliability.
        </p>
    </div>
</details>
<details class="accordion" name="yourAccordion1Name">
    <summary class="accordion__summary">Shipping Details</summary>
    <div class="accordion__content">
        <p class="p">
            We offer worldwide shipping through trusted courier
            partners. Standard delivery takes 3-5 business days, while
            express shipping ensures delivery within 1-2 business days.
        </p>
        <p class="p">
            All orders are carefully packaged and fully insured. Track
            your shipment in real-time through our dedicated tracking
            portal.
        </p>
    </div>
</details>
<details class="accordion" name="yourAccordion1Name">
    <summary class="accordion__summary">Return Policy</summary>
    <div class="accordion__content">
        <p class="p">
            We stand behind our products with a comprehensive 30-day
            return policy. If you're not completely satisfied, simply
            return the item in its original condition.
        </p>
    </div>
</details>

Aspect ratio

Displays content within a desired ratio.


Aspect ratio example

Aspect ratio gif example

<img
    class="aspect-ratio aspect-ratio--16-9 aspect-ratio--rounded"
    src="/home/aspect-ratio_example.webp"
    loading="lazy"
    alt="Aspect ratio example"
/>

<br /><br />

<img
    class="aspect-ratio aspect-ratio--4-3 aspect-ratio--rounded"
    src="/home/gif_example.gif"
    loading="lazy"
    alt="Aspect ratio gif example"
/>

<br /><br />

<video
    class="aspect-ratio aspect-ratio--1-1 aspect-ratio--rounded"
    id="myVideo1"
    controls
    preload="none"
    aria-label="Aspect ratio video example"
>
    <source src="/home/video_example.webm" type="video/webm" />
    <source src="/home/video_example.mp4" type="video/mp4" />
    Sorry, your browser does not support embedded videos, but does
    don't worry, you can <a href="/video_examaple.mp4">download it</a>
    and watch it with your favorite video player!
</video>

Avatar

An image element with a loading skelton and a fallback for representing the user.


Avatar of John Doe JD

JD

Avatar of John Doe

Avatar of John Doe
Avatar of John Doe
Avatar of John Doe

Avatar of John Doe
Avatar of John Doe
Avatar of John Doe
Avatar of John Doe
Avatar of John Doe
<div class="avatar">
    <img
        class="avatar__img"
        src="/home/avatar_example.webp"
        loading="lazy"
        alt="Avatar of John Doe"
        onerror="this.parentElement.classList.add('avatar--empty')"
    />
    <span class="avatar__fallback">JD</span>
</div>

<br />

<div class="avatar avatar--empty">
    <span class="avatar__fallback">JD</span>
</div>

<br />

<div class="avatar avatar--rounded-lg avatar--grayscale">
    <img
        class="avatar__img"
        src="/home/avatar_example.webp"
        loading="lazy"
        alt="Avatar of John Doe"
    />
</div>

<br />

<div class="avatar-group" role="group" aria-label="Stacked avatars">
    <div class="avatar">
        <img
            class="avatar__img"
            src="/home/avatar_example.webp"
            loading="lazy"
            alt="Avatar of John Doe"
        />
    </div>
    <div class="avatar">
        <img
            class="avatar__img"
            src="/home/avatar_example.webp"
            loading="lazy"
            alt="Avatar of John Doe"
        />
    </div>
    <div class="avatar">
        <img
            class="avatar__img"
            src="/home/avatar_example.webp"
            loading="lazy"
            alt="Avatar of John Doe"
        />
    </div>
</div>

<br />

<div
    class="avatar-group avatar-group--space-2"
    role="group"
    aria-label="Avatars with different sizes"
>
    <div class="avatar avatar--xs">
        <img
            class="avatar__img"
            src="/home/avatar_example.webp"
            loading="lazy"
            alt="Avatar of John Doe"
        />
    </div>
    <div class="avatar avatar--sm">
        <img
            class="avatar__img"
            src="/home/avatar_example.webp"
            loading="lazy"
            alt="Avatar of John Doe"
        />
    </div>
    <div class="avatar avatar--md">
        <img
            class="avatar__img"
            src="/home/avatar_example.webp"
            loading="lazy"
            alt="Avatar of John Doe"
        />
    </div>
    <div class="avatar avatar--lg">
        <img
            class="avatar__img"
            src="/home/avatar_example.webp"
            loading="lazy"
            alt="Avatar of John Doe"
        />
    </div>
    <div class="avatar avatar--xl">
        <img
            class="avatar__img"
            src="/home/avatar_example.webp"
            loading="lazy"
            alt="Avatar of John Doe"
        />
    </div>
</div>

Alert

Displays a callout for user attention.




<div class="alert" role="alert">
    <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10" /><path d="m9 12 2 2 4-4" /></svg>
    <strong class="alert__title">
        Success! Your changes have been saved
    </strong>
    <p class="alert__content">
        This is an alert with icon, title and description.
    </p>
</div>

<br />

<div class="alert" role="alert">
    <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-popcorn-icon lucide-popcorn"><path d="M18 8a2 2 0 0 0 0-4 2 2 0 0 0-4 0 2 2 0 0 0-4 0 2 2 0 0 0-4 0 2 2 0 0 0 0 4"/><path d="M10 22 9 8"/><path d="m14 22 1-14"/><path d="M20 8c.5 0 .9.4.8 1l-2.6 12c-.1.5-.7 1-1.2 1H7c-.6 0-1.1-.4-1.2-1L3.2 9c-.1-.6.3-1 .8-1Z"/></svg>
    <strong class="alert__title">
      This Alert has a title and an icon. No description.
    </strong>
</div>

<br />

<div class="alert alert--destructive" role="alert">
    <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-circle-x-icon lucide-circle-x"><circle cx="12" cy="12" r="10" /><path d="m15 9-6 6" /><path d="m9 9 6 6" /></svg>
    <strong class="alert__title">Unable to process your payment.</strong>
    <div class="alert__content">
        <p>Please verify your billing information and try again.</p>
        <ul class="list-inside list-disc text-sm">
            <li>Check your card details</li>
            <li>Ensure sufficient funds</li>
            <li>Verify billing address</li>
        </ul>
    </div>
</div>

Alert dialog

A modal dialog that interrupts the user with important content and expects a response.


Are you absolutely sure?

This action cannot be undone. This will permanently delete your account and remove your data from our servers.

<button
    class="button"
    type="button"
    onclick="document.getElementById('myAlertDialog1').showModal()"
>
    Delete my account
</button>

<dialog
    class="dialog"
    id="myAlertDialog1"
    aria-labelledby="myAlertDialog1Title"
    aria-describedby="myAlertDialog1Desc"
>
    <form class="dialog__shape" method="dialog">
        <header class="dialog__header">
            <h2 class="dialog__title" id="myAlertDialog1Title">
                Are you absolutely sure?
            </h2>
            <p class="dialog__desc" id="myAlertDialog1Desc">
                This action cannot be undone. This will permanently
                delete your account and remove your data from our
                servers.
            </p>
        </header>

        <footer class="dialog__footer">
            <button class="button" value="cancel" formnovalidate>
                Cancel
            </button>
            <button class="button button--primary" value="submit">
                Continue
            </button>
        </footer>
    </form>
</dialog>

<script type="module">
    const dialog = document.getElementById("myAlertDialog1");
    const output = document.getElementById("myAlertDialog1Output");
    const form = dialog.querySelector("form");
    // Handle close → distinguish cancel / save
    dialog.addEventListener("close", () => {
        if (dialog.returnValue === "submit") {
            output.textContent = "✅ Submitted!";
        } else {
            output.textContent = "❌ Cancelled!";
        }
        // Reset form
        dialog.returnValue = "";
        form.reset();
    });
    // Optional: reset scroll position on submit attempt
    form.addEventListener("submit", (e) => {
        form.querySelector(".dialog__content")?.scrollTo(0, 0);
    });
</script>

<output id="myAlertDialog1Output"></output>

Appearance select

A component that allows the user to switch between light, dark and auto mode.


<!-- Inline this inside <head> to avoid flash of unstyled content -->
<script>
    try {
        const storedAppearance = localStorage.getItem("appearance");
        applyAppearance(storedAppearance);

        function applyAppearance(value) {
            if (value === "dark" || value === "light") {
                document.documentElement.classList.toggle(
                    "dark",
                    value === "dark"
                );
                localStorage.setItem("appearance", value);
            } else {
                const isDeviceDark = window.matchMedia(
                    "(prefers-color-scheme: dark)"
                ).matches;
                document.documentElement.classList.toggle(
                    "dark",
                    isDeviceDark
                );
                localStorage.removeItem("appearance");
            }
            applyMetaColor();
        }

        function applyMetaColor() {
            const meta = document.querySelector(
                "meta[name=theme-color]"
            );
            if (meta == null) return;
            const appHeader = document.querySelector("body > header");
            if (appHeader == null) return;
            const newColor =
                window.getComputedStyle(appHeader).backgroundColor;
            meta.setAttribute("content", newColor);
        }

        window
            .matchMedia("(prefers-color-scheme: dark)")
            .addEventListener("change", (e) => {
                if (storedAppearance) return;
                document.documentElement.classList.toggle(
                    "dark",
                    e.matches
                );
            });

        document.addEventListener("app:appearance", (e) => {
            applyAppearance(e.detail)
        });
    } catch (err) {
        console.error(err);
    }
</script>

<!-- Usage example -->
<select
    class="select"
    id="myAppearanceSelect"
    name="appearance"
    aria-label="Appearance"
>
    <option value="" selected>🖥️ Auto</option>
    <option value="light">☀️ Light</option>
    <option value="dark">🌙 Dark</option>
</select>
<script type="module">
    const el = document.getElementById("myAppearanceSelect");
    el.value = localStorage.getItem("appearance") || "";
    el.onchange = (e) => {
        document.dispatchEvent(
            new CustomEvent("app:appearance", {
                detail: e.target.value,
            })
        );
    };
</script>

Badge

Displays a badge or a component that looks like a badge.


Badge Secondary Destructive Outline Verified
8 99 20+
<span class="badge">Badge</span>
<span class="badge badge--secondary">Secondary</span>
<span class="badge badge--destructive">Destructive</span>
<span class="badge badge--outline">Outline</span>

<span class="badge">
    Verified
    <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check-icon lucide-check"><path d="M20 6 9 17l-5-5" /></svg>
</span>

<br />

<span class="badge badge--pill">8</span>
<span class="badge badge--pill badge--destructive">99</span>
<span class="badge badge--pill badge--outline">20+</span>

Busy

Render a busy state containing a spinner indicator.





<div class="busy" inert aria-busy="true">
    <span class="busy__indicator"></span>

    <form>
        <input class="input" name="busy1" type="text" placeholder="Email" />
        <br>
        <button class="button button--primary" type="submit">
            <span>Submit</span>
        </button>
    </form>
</div>

<br /><br />

<div class="busy" inert aria-busy="true">
    <button class="button" type="button">
        <span class="busy__indicator"></span>
        <span>Click me!</span>
    </button>
</div>

Button

Displays a button or a component that looks like a button.









<button class="button" type="button">Default</button>

<br /><br />

<button class="button button--primary" type="button">Primary</button>
<button class="button button--secondary" type="button">Secondary</button>
<button class="button button--outline" type="button">Outline</button>
<button class="button button--ghost" type="button">Ghost</button>
<button class="button button--destructive" type="button">Destructive</button>

<br />

<button class="button" type="button" disabled>Disabled</button>

<br /><br />

<button class="button button--icon" type="button" aria-label="Settings">
    <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-settings-icon lucide-settings"><path d="M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915"/><circle cx="12" cy="12" r="3"/></svg>
</button>

<button class="button button--outline" type="button">
    <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check-icon lucide-check"><path d="M20 6 9 17l-5-5" /></svg>
    Icon before
</button>

<br /><br />

<label class="button button--outline">
    <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-upload-icon lucide-upload"><path d="M12 3v12"/><path d="m17 8-5-5-5 5"/><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/></svg>
    <span>Upload</span>
    <input type="file">
</label>

<label class="button button--outline">
    <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-upload-icon lucide-upload"><path d="M12 3v12"/><path d="m17 8-5-5-5 5"/><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/></svg>
    <span>Upload</span>
    <input type="file" disabled>
</label>

Button group

A container that groups related buttons together with consistent styling.




<div
    class="button-group button-group--sm"
    role="group"
    aria-label="Buttons group example in small size"
>
    <button class="button" type="button">Small</button>
    <button class="button" type="button">Button</button>
    <button class="button" type="button">Group</button>
    <button class="button button--icon" type="button" aria-label="Add">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus-icon lucide-plus"><path d="M5 12h14"/><path d="M12 5v14"/></svg>
    </button>
</div>

<br />

<div
    class="button-group"
    role="group"
    aria-label="Buttons group example in medium size"
>
    <button class="button" type="button">Default</button>
    <button class="button" type="button">Button</button>
    <button class="button" type="button">Group</button>
    <button class="button button--icon" type="button" aria-label="Add">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus-icon lucide-plus"><path d="M5 12h14"/><path d="M12 5v14"/></svg>
    </button>
</div>

<br />

<div
    class="button-group button-group--lg"
    role="group"
    aria-label="Buttons group example in large size"
>
    <button class="button" type="button">Large</button>
    <button class="button" type="button">Button</button>
    <button class="button" type="button">Group</button>
    <button class="button button--icon" type="button" aria-label="Add">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus-icon lucide-plus"><path d="M5 12h14"/><path d="M12 5v14"/></svg>
    </button>
</div>

Calendar ❔

A date field component that allows users to enter and edit date.


Not planned.

Card

Displays a card with header, content, and footer.


<article class="card">
    <header class="card__header">
        <h3 class="card__title">Card</h3>
        <p class="card__desc">Card content</p>
    </header>
    <div class="card__content">
        <p>Card content</p>
    </div>
    <footer class="card__footer">
        <a href="#" aria-label="card action">Card action</a>
    </footer>
</article>

Not planned.

Chart 🚧

Beautiful charts. Built using Recharts. Copy and paste into your apps.


Work in progress...

Checkbox

Displays a checkbox or a component that looks like a checkbox.


<label class="label">
    <input class="checkbox" name="checkbox1" type="checkbox" />
    <span>Remember me</span>
</label>

Checkbox group 🚧 JS

Provides shared state to a series of checkboxes.


I want to receive
<script type="module" src="https://ui.micka.dev/cdn/elements/checkbox-group.element.js"></script>

<fieldset class="fieldset">
    <legend class="fieldset__legend">I want to receive</legend>

    <label class="label">
        <input
            class="checkbox checkbox--master"
            type="checkbox"
            id="checkboxGroupMaster1"
        />
        <strong>All</strong>
    </label>
    <x-checkbox-group class="checkbox-group" for="checkboxGroupMaster1">
        <label class="label label--normal">
            <input
                class="checkbox"
                type="checkbox"
                name="checkboxGroup1Name1"
                checked
            />
            The weekly newsletter
        </label>
        <label class="label label--normal">
            <input
                class="checkbox"
                type="checkbox"
                name="checkboxGroup1Name2"
            />
            Offers from the company
        </label>

        <label class="label">
            <input
                class="checkbox checkbox--master"
                type="checkbox"
                id="checkboxGroupMaster2"
            />
            <strong>Partner Communications</strong>
        </label>
        <x-checkbox-group class="checkbox-group" for="checkboxGroupMaster2">
            <label class="label label--normal">
                <input
                    class="checkbox"
                    type="checkbox"
                    name="checkboxGroup2Name1"
                    checked
                />
                Partner newsletters
            </label>

            <label class="label label--normal">
                <input
                    class="checkbox"
                    type="checkbox"
                    name="checkboxGroup2Name2"
                />
                Offers from associated companies
            </label>

            <label class="label label--normal">
                <input
                    class="checkbox"
                    type="checkbox"
                    name="checkboxGroup2Name3"
                />
                Third-party promotions
            </label>

            <label class="label label--normal">
                <input
                    class="checkbox"
                    type="checkbox"
                    name="checkboxGroup2Name4"
                    disabled
                />
                Premium partner offers (unavailable)
            </label>
        </x-checkbox-group>

        <label class="label label--normal">
            <input
                class="checkbox"
                type="checkbox"
                name="checkboxGroup1Name4"
                disabled
            />
            Special offers (unavailable)
        </label>
        <label class="label label--normal">
            <input
                class="checkbox"
                type="checkbox"
                name="checkboxGroup1Name5"
            />
            Product updates
        </label>
    </x-checkbox-group>
</fieldset>

Collapsible ❔

An interactive component which expands/collapses a panel.


Not planned.

Combobox 🚧 JS

Autocomplete input and command palette with a list of suggestions.


Work in progress...

Command ❔ JS

Fast, composable, unstyled command menu for React.


Not planned.

Context menu ❔ JS

Displays a menu to the user — such as a set of actions or functions — triggered by a button.


Not planned.

Copy text JS

Copy text to clipboard.


This is some text to copy.

<script type="module" src="https://ui.micka.dev/cdn/elements/copy-text.element.js"></script>

<p id="myTextToCopy">This is some text to copy.</p>

<x-copy-text for="myTextToCopy">
    <button
        class="button button--icon tooltip tooltip--start"
        style="--tooltip-content: 'Copy to clipboard'"
        aria-label="Copy to clipboard"
    ></button>
</x-copy-text>

Data table ❔ JS

Powerful table and datagrids built using TanStack Table.


Not planned.

Date picker ❔ JS

A date picker component with range and presets.


Not planned.

Dialog

A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.


Edit profile

Make changes to your profile here. Click save when you're done.

<button
    class="button"
    type="button"
    onclick="document.getElementById('myDialog1').showModal()"
>
    Show dialog
</button>

<dialog
    class="dialog"
    id="myDialog1"
    aria-labelledby="myDialog1Title"
    aria-describedby="myDialog1Desc"
>
    <form class="dialog__shape" method="dialog">
        <header class="dialog__header">
            <h2 class="dialog__title" id="myDialog1Title">Edit profile</h2>
            <p class="dialog__desc" id="myDialog1Desc">
                Make changes to your profile here. Click save when
                you're done.
            </p>
        </header>

        <fieldset class="dialog__content fieldset">
            <div class="field">
                <label class="field__label" for="myDialog1Name">Name</label>
                <input
                    class="input"
                    id="myDialog1Name"
                    name="name"
                    autocomplete="name"
                    minlength="3"
                    required
                    aria-invalid="false"
                    aria-errormessage="myDialog1NameError"
                />
            </div>
            <div class="field">
                <label class="field__label" for="myDialog1Username">Username</label>
                <input
                    class="input"
                    id="myDialog1Username"
                    name="username"
                    autocomplete="username"
                    required
                    aria-invalid="false"
                    aria-errormessage="myDialog1UsernameError"
                />
            </div>
        </fieldset>

        <footer class="dialog__footer">
            <button class="button" formnovalidate>
                Cancel
            </button>
            <button class="button button--primary" value="submit">
                Save changes
            </button>
        </footer>

        <button
            class="dialog__cancel"
            aria-label="Cancel"
            formnovalidate
        >
            <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-x-icon lucide-x"><path d="M18 6 6 18" /><path d="m6 6 12 12" /></svg>
        </button>
    </form>
</dialog>

<script type="module">
    const dialog = document.getElementById("myDialog1");
    const output = document.getElementById("myDialog1Output");
    const form = dialog.querySelector("form");
    // Optional: Close on click outside
    dialog.addEventListener("click", (e) => {
        if (e.target === dialog) dialog.close();
    })
    // Handle close → distinguish cancel / save
    dialog.addEventListener("close", () => {
        if (dialog.returnValue === "submit") {
            output.textContent =
                "✅ " + JSON.stringify(Object.fromEntries(new FormData(form).entries()));
        } else {
            output.textContent = "❌ Cancelled!";
        }
        // Reset form
        dialog.returnValue = "";
        form.reset();
    });
    // Optional: reset scroll position on submit attempt
    form.addEventListener("submit", (e) => {
        dialog.querySelector(".dialog__content")?.scrollTo(0, 0);
    });
</script>

<output id="myDialog1Output"></output>

Diff JS

A diff component that allows the user to compare two items.


Diff example first image Diff example second image
<script type="module" src="https://ui.micka.dev/cdn/elements/slider.element.js"></script>

<x-slider class="diff diff--rounded" style="aspect-ratio: 16/9">
    <input class="diff__range" type="range" min="0" max="100" value="50" />
    <div class="diff__line">
        <div class="diff__line__thumb" aria-label="Diff thumb">
            <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-grip-vertical-icon lucide-grip-vertical"><circle cx="9" cy="12" r="1"/><circle cx="9" cy="5" r="1"/><circle cx="9" cy="19" r="1"/><circle cx="15" cy="12" r="1"/><circle cx="15" cy="5" r="1"/><circle cx="15" cy="19" r="1"/></svg>
        </div>
    </div>
    <img
        class="diff__content"
        src="/home/aspect-ratio_example.webp"
        loading="lazy"
        alt="Diff example first image"
    />
    <img
        class="diff__content"
        style="filter: blur(1.5rem);"
        src="/home/aspect-ratio_example.webp"
        loading="lazy"
        alt="Diff example second image"
    />
</x-slider>

Drawer ❔

A drawer component that slides in from the bottom.


Not planned.

Not planned.

Empty ❔

Use the Empty component to display a empty state.


Not planned.

Field 🚧

Combine labels, controls, and help text to compose accessible form fields and grouped inputs.


Payment Method

All transactions are secure and encrypted

Name on card is required
Enter your 16-digit card number

Billing address

The billing address associated with your payment method

<form>
    <fieldset class="fieldset">
        <legend class="fieldset__legend">Payment Method</legend>
        <p class="fieldset__desc">
            All transactions are secure and encrypted
        </p>

        <div class="field-group">
            <div class="field">
                <label class="field__label" for="myField1Label">Name on card</label>
                <input
                    class="input"
                    id="myField1Label"
                    name="nameOnCard"
                    type="text"
                    placeholder="Evil Rabbit"
                    required
                />
                <div class="field__error" aria-live="polite">
                    <span>Name on card is required</span>
                </div>
            </div>

            <div class="field">
                <label class="field__label" for="myField2Label">Card number</label>
                <input
                    class="input"
                    id="myField2Label"
                    name="cardNumber"
                    type="text"
                    placeholder="1234 5678 9012 3456"
                    required
                />
                <div class="field__desc">
                    Enter your 16-digit card number
                </div>
            </div>

            <div class="field-group field-group__horizontal" role="group">
                <div class="field">
                    <label class="field__label" for="expiryMonth">Month</label>
                    <select class="select" name="expiryMonth" id="expiryMonth" required>
                        <option value="" selected disabled>MM</option>
                        <option value="1">January</option>
                        <option value="2">February</option>
                        <option value="3">March</option>
                        <option value="4">April</option>
                        <option value="5">May</option>
                        <option value="6">June</option>
                        <option value="7">July</option>
                        <option value="8">August</option>
                        <option value="9">September</option>
                        <option value="10">October</option>
                        <option value="11">November</option>
                        <option value="12">December</option>
                    </select>
                </div>

                <div class="field">
                    <label class="field__label" for="expiryYear">Year</label>
                    <select class="select" name="myField4" id="expiryYear" required>
                        <option value="" selected disabled>YYYY</option>
                        <option value="2022">2024</option>
                        <option value="2023">2025</option>
                        <option value="2022">2026</option>
                        <option value="2021">2027</option>
                        <option value="2020">2028</option>
                        <option value="2019">2029</option>
                    </select>
                </div>

                <div class="field">
                    <label class="field__label" for="cvv">CVV</label>
                    <input
                        class="input"
                        id="cvv"
                        name="cvv"
                        type="text"
                        placeholder="123"
                        required
                    />
                </div>
            </div>

            <hr />

            <fieldset class="fieldset">
                <legend class="fieldset__legend">Billing address</legend>
                <p class="fieldset__desc">
                    The billing address associated with your payment method
                </p>

                <div class="field-group">
                    <div class="field field--horizontal">
                        <input id="mySameAsShipping1" class="checkbox" name="sameAsShipping" type="checkbox" />
                        <label for="mySameAsShipping1" class="field__label field__label--normal">
                            Same as shipping address
                        </label>
                    </div>
                    <div class="field">
                        <label for="myComments1" class="field__label">
                            Comments
                        </label>
                        <textarea
                            class="textarea"
                            id="myComments1"
                            name="myComments1"
                            placeholder="Add any additional comments"
                        ></textarea>
                    </div>
                </div>
            </fieldset>
        </div>
    </fieldset>
</form>

Hover card 🚧 JS

For sighted users to preview content available behind a link.


@nextjs
<script type="module" src="https://ui.micka.dev/cdn/elements/floating.element.js"></script>

<a class="link" href="https://nextjs.org" aria-describedby="myHoverCard1">
    @nextjs
</a>

<x-hover-card
    id="myHoverCard1"
    class="hover-card hover-card--bottom hover-card--center"
    aria-hidden="true"
>
    <!-- Your content -->
    <div style="display: flex; gap: 1rem; justify-content: space-between; max-width: 320px">
        <div class="avatar">
            <img
                class="avatar__img"
                alt="Avatar of John Doe"
                src="/home/avatar_example.webp"
            />
        </div>
        <div style="display: flex; flex-direction: column; gap: 0.25rem">
            <h4 style="font-size: var(--text-sm); font-weight: var(--font-weight-semibold)">
                @nextjs
            </h4>
            <br />
            <p style="font-size: var(--text-sm)">
                The React Framework – created and maintained by
                @vercel.
            </p>
            <div class="muted">Joined December 2021</div>
        </div>
    </div>
    <!-- / Your content -->
</x-hover-card>

Input 🚧

Displays a form input field or a component that looks like an input field.


<input
    class="input"
    name="email"
    type="email"
    placeholder="Email"
    autocomplete="email"
    aria-label="Email"
/>

Input group 🚧

Display additional information or actions to an input or textarea.


Work in progress...

Input OTP ❔

Accessible one-time password component with copy paste functionality.


Not planned.

Item ❔

A versatile component that you can use to display any content.


Not planned.

Kbd

Used to display textual user input from keyboard.




+K


Use Ctrl + B Cmd + K to open the command palette


<div class="kbd-group" role="group" aria-label="Keyboard shortcuts example">
    <kbd class="kbd">⌘</kbd>
    <kbd class="kbd">⇧</kbd>
    <kbd class="kbd">⌥</kbd>
    <kbd class="kbd">⌃</kbd>
</div>

<br /><br />

<div class="kbd-group" role="group" aria-label="Search command shortcut">
    <kbd class="kbd">⌘</kbd>+<kbd class="kbd">K</kbd>
</div>

<br /><br />

<p class="muted">
    Use
    <span
        class="kbd-group"
        role="group"
        aria-label="Open command palette shortcut"
    >
        <kbd class="kbd">Ctrl + B</kbd>
        <kbd class="kbd">Cmd + K</kbd>
    </span>
    to open the command palette
</p>

<br />

<button class="button">
    <span>Accept</span><kbd class="kbd">⌘</kbd>
</button>
<button class="button">
    <span>Cancel</span><kbd class="kbd">⌘</kbd>
</button>

Label 🚧

Renders an accessible label associated with controls.


<label class="label label--required">
    <input class="checkbox" name="label1" type="checkbox" required />
    <span>Accept terms and conditions</span>
</label>

<a class="link" href="#">Link</a>

<br /><br />

<a class="link" href="#" target="_blank" rel="noopener noreferrer">
    <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-globe-icon lucide-globe"><circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/></svg>
    Visit Website
</a>

<br />

<a
    class="link"
    href="mailto:hello@example.com?subject=Hello&body=How%20are%20you?"
>
    <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-mail-icon lucide-mail"><path d="m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7"/><rect x="2" y="4" width="20" height="16" rx="2"/></svg>
    hello@example.com
</a>

<br />

<a class="link" href="tel:+1234567890">
    <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-phone-icon lucide-phone"><path d="M13.832 16.568a1 1 0 0 0 1.213-.303l.355-.465A2 2 0 0 1 17 15h3a2 2 0 0 1 2 2v3a2 2 0 0 1-2 2A18 18 0 0 1 2 4a2 2 0 0 1 2-2h3a2 2 0 0 1 2 2v3a2 2 0 0 1-.8 1.6l-.468.351a1 1 0 0 0-.292 1.233 14 14 0 0 0 6.392 6.384"/></svg>
    +1 (234) 567-890
</a>

<br />

<a
    class="link"
    href="https://maps.app.goo.gl/Pjt8Km7YAW6vR6L99"
    data-href-apple="maps://maps.apple.com/place?place-id=IDBCCCA2A9059133"
    target="_blank"
    rel="noopener noreferrer"
    onclick="if (/iPhone|iPad|Mac/.test(navigator.userAgent))this.href=this.dataset.hrefApple;this.onclick=null"
>
    <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-map-pin-icon lucide-map-pin"><path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"/><circle cx="12" cy="10" r="3"/></svg>
    Av. Gustave Eiffel, 75007 Paris
</a>

Not planned.

Not planned.

Pagination ❔

Pagination with page navigation, next and previous links.


Not planned.

Popover 🚧 JS

Displays rich content in a portal, triggered by a button. Use Floating UI under the hood.


My content
<button class="button" type="button" popovertarget="myPopover1">
    Open popover
</button>

<x-popover
    id="myPopover1"
    class="popover popover--bottom popover--center"
>
    <dialog
        class="popover__dialog"
        onclick="if (event.target === this) this.close()"
    >
        <form class="popover__dialog__shape" method="dialog">
            <!-- Your content -->
            My content
            <!-- ? Your content -->
        </form>
    </dialog>
</x-popover>

Progress

Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.


<progress
    class="progress"
    value="50"
    max="100"
    aria-label="Content loading…"
></progress>

Radio group

A set of checkable buttons—known as radio buttons—where no more than one of the buttons can be checked at a time.


Notify me about...

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do

<fieldset class="fieldset">
    <legend class="fieldset__legend fieldset__legend--label">
        Notify me about...
    </legend>
    <p class="fieldset__desc">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
    </p>

    <div class="radio-group">
        <label class="label label--normal">
            <input
                class="radio"
                type="radio"
                name="radioGroup2"
                value="1"
                checked
            />
            All new messages
        </label>
        <label class="label label--normal">
            <input
                class="radio"
                type="radio"
                name="radioGroup2"
                value="2"
                disabled
            />
            Direct messages and mentions
        </label>
        <label class="label label--normal">
            <input
                class="radio"
                type="radio"
                name="radioGroup2"
                value="3"
            />
            Nothing
        </label>
    </div>
</fieldset>

Resizable ❔

Accessible resizable panel groups and layouts with keyboard support.


Not planned.

Scroll area ❔

Augments native scroll functionality for custom, cross-browser styling.


Not planned.

Select

Displays a list of options for the user to pick from—triggered by a button.


<select class="select" id="mySelect" aria-label="Choose a dinosaur">
    <option value="" selected disabled>Select a dinosaur</option>
    <hr />
    <optgroup label="Theropods">
        <option value="tyrannosaurus">Tyrannosaurus</option>
        <option value="velociraptor">Velociraptor</option>
        <option value="deinonychus">Deinonychus</option>
    </optgroup>
    <hr />
    <optgroup label="Sauropods">
        <option value="diplodocus">Diplodocus</option>
        <option value="saltasaurus">Saltasaurus</option>
        <option value="apatosaurus">Apatosaurus</option>
    </optgroup>
</select>

Separator ❔

Visually or semantically separates content.


Not planned.

Sheet ❔

Extends the Dialog component to display content that complements the main content of the screen.


Not planned.

Not planned.

Skeleton ❔

Use to show a placeholder while content is loading.


Not planned.

Slider JS

An input where the user selects a value from within a given range.








<script type="module" src="https://ui.micka.dev/cdn/elements/slider.element.js"></script>

<x-slider class="slider">
    <input
        class="slider__range"
        name="mySlider1"
        type="range"
        min="0"
        max="100"
        aria-label="Volume"
    />
</x-slider>

<br /><br />

<x-slider class="slider">
    <input
        class="slider__range"
        name="mySlider2"
        type="range"
        min="0"
        max="3"
        value="3"
    />
    <div class="slider__datalist" aria-hidden="true">
        <div></div>
        <div></div>
        <div></div>
        <div></div>
    </div>
</x-slider>

<br /><br />

<x-slider class="slider">
    <input
        class="slider__range"
        name="mySlider3"
        type="range"
        min="0"
        max="2"
        value="0"
    />
    <div class="slider__datalist" aria-hidden="true">
        <div>Small</div>
        <div>Medium</div>
        <div>Large</div>
    </div>
</x-slider>

<br /><br />

<form>
    <div class="field">
        <label class="field__label" for="mySlider4">Volume</label>
        <x-slider class="slider">
            <input
                class="slider__range"
                id="mySlider4"
                name="mySlider4"
                type="range"
                min="0"
                max="100"
                step="10"
                aria-label="Volume"
            />
        </x-slider>
        <div role="group" aria-label="Slider controls">
            <button
                class="button"
                type="button"
                onclick="document.getElementById('mySlider4').stepDown()"
                aria-label="Decrement"
            >
                <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-minus-icon lucide-minus"><path d="M5 12h14"/></svg>
            </button>
            <button
                class="button"
                type="button"
                onclick="document.getElementById('mySlider4').stepUp()"
                aria-label="Increment"
            >
                <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus-icon lucide-plus"><path d="M5 12h14"/><path d="M12 5v14"/></svg>
            </button>
            <button class="button" type="reset" aria-label="Reset">
                <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-ccw-icon lucide-rotate-ccw"><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/></svg>
            </button>
        </div>
    </div>
</form>

Sonner ❔

An opinionated toast component.


Not planned.

Snippet

A code snippet rendered with PrismJS.


// program to display fibonacci sequence using recursion
function fibonacci(num) {
    if (num < 2) {
        return num;
    }
    else {
        return fibonacci(num - 1) + fibonacci(num - 2);
    }
}

for(let i = 0; i < 5; i++) {
    console.log(fibonacci(i));
}
<script type="module" src="https://ui.micka.dev/cdn/elements/snippet.element.js"></script>

<x-snippet class="snippet snippet--typescript">
    <pre id="mySnippet1">// program to display fibonacci sequence using recursion
function fibonacci(num) {
    if (num &lt; 2) {
        return num;
    }
    else {
        return fibonacci(num - 1) + fibonacci(num - 2);
    }
}

for(let i = 0; i &lt; 5; i++) {
    console.log(fibonacci(i));
}</pre>
    <x-copy-text for="mySnippet1">
        <button
            class="button button--icon tooltip tooltip--end"
            style="--tooltip-content: 'Copy to clipboard'"
            aria-label="Copy to clipboard"
        ></button>
    </x-copy-text>
</x-snippet>

Spinner 🚧

An indicator that can be used to show a loading state.


<div class="spinner" aria-live="polite" aria-label="Loading">
    <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-loader-icon lucide-loader"><path d="M12 2v4"/><path d="m16.2 7.8 2.9-2.9"/><path d="M18 12h4"/><path d="m16.2 16.2 2.9 2.9"/><path d="M12 18v4"/><path d="m4.9 19.1 2.9-2.9"/><path d="M2 12h4"/><path d="m4.9 4.9 2.9 2.9"/></svg>
</div>

Switch

A control that allows the user to toggle between checked and not checked.


<label class="label">
    <input class="switch" name="switch1" type="checkbox" role="switch" />
    Airplane mode
</label>

Table 🚧

An opinionated toast component.


Work in progress...

Tabs 🚧

A set of layered sections of content—known as tab panels—that are displayed one at a time.


This is the Overview panel.

Details panel content.

Resources panel content.

<script type="module" src="https://ui.micka.dev/cdn/elements/tabs.element.js"></script>

<x-tabs class="tabs">
    <div
        class="tabs__list"
        role="tablist"
        aria-orientation="horizontal"
        aria-label="Example Tabs"
    >
        <button id="myTabs1Tab1" role="tab" aria-controls="myTabs1Panel1">
            Overview
        </button>
        <button
            id="myTabs1Tab2"
            role="tab"
            aria-controls="myTabs1Panel2"
            aria-selected="true"
        >
            Details
        </button>
        <button id="myTabs1Tab3" role="tab" aria-controls="myTabs1Panel3">
            Resources
        </button>
    </div>

    <div
        class="tabs__panel"
        id="myTabs1Panel1"
        role="tabpanel"
        aria-labelledby="myTabs1Tab1"
    >
        <p>This is the Overview panel.</p>
    </div>
    <div
        class="tabs__panel"
        id="myTabs1Panel2"
        role="tabpanel"
        aria-labelledby="myTabs1Tab2"
    >
        <p>Details panel content.</p>
    </div>
    <div
        class="tabs__panel"
        id="myTabs1Panel3"
        role="tabpanel"
        aria-labelledby="myTabs1Tab3"
    >
        <p>Resources panel content.</p>
    </div>
</x-tabs>

Textarea

Displays a form textarea or a component that looks like a textarea.


<div class="field">
    <label class="field__label" for="myTextarea1">My message</label>
    <textarea
        class="textarea"
        id="myTextarea1"
        name="message1"
        placeholder="Type your message here"
    ></textarea>
</div>

Toggle

A two-state button that can be either on or off.


<label class="button button--outline button--icon">
    <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-italic-icon lucide-italic"><line x1="19" x2="10" y1="4" y2="4"/><line x1="14" x2="5" y1="20" y2="20"/><line x1="15" x2="9" y1="4" y2="20"/></svg>
    <input name="toggle1" type="checkbox" role="switch" />
    <span>Toggle italic</span>
</label>

<label class="button button--ghost">
    <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-italic-icon lucide-italic"><line x1="19" x2="10" y1="4" y2="4"/><line x1="14" x2="5" y1="20" y2="20"/><line x1="15" x2="9" y1="4" y2="20"/></svg>
    <input name="toggle2" type="checkbox" role="switch" />
    <span>Italic</span>
</label>

Toggle group

A set of two-state buttons that can be toggled on or off.




<div
    class="button-group button-group--space-2"
    role="group"
    aria-label="Toggle group with spaces example"
>
    <label class="button button--outline button--sm">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-star-icon lucide-star"><path d="M11.525 2.295a.53.53 0 0 1 .95 0l2.31 4.679a2.123 2.123 0 0 0 1.595 1.16l5.166.756a.53.53 0 0 1 .294.904l-3.736 3.638a2.123 2.123 0 0 0-.611 1.878l.882 5.14a.53.53 0 0 1-.771.56l-4.618-2.428a2.122 2.122 0 0 0-1.973 0L6.396 21.01a.53.53 0 0 1-.77-.56l.881-5.139a2.122 2.122 0 0 0-.611-1.879L2.16 9.795a.53.53 0 0 1 .294-.906l5.165-.755a2.122 2.122 0 0 0 1.597-1.16z"/></svg>
        <input
            name="toggleGroup1"
            type="checkbox"
            onchange="this.previousElementSibling.querySelector('path').setAttribute('fill', this.checked ? 'currentColor' : 'none')"
        />
        <span>Star</span>
    </label>

    <label class="button button--outline button--sm">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-heart-icon lucide-heart"><path d="M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5"/></svg>
        <input
            name="toggleGroup2"
            type="checkbox"
            onchange="this.previousElementSibling.querySelector('path').setAttribute('fill', this.checked ? 'currentColor' : 'none')"
        />
        <span>Heart</span>
    </label>

    <label class="button button--outline button--sm">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-bookmark-icon lucide-bookmark"><path d="m19 21-7-4-7 4V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v16z"/></svg>
        <input
            name="toggleGroup3"
            type="checkbox"
            onchange="this.previousElementSibling.querySelector('path').setAttribute('fill', this.checked ? 'currentColor' : 'none')"
        />
        <span>Bookmark</span>
    </label>
</div>

<br/>

<div
    class="button-group"
    role="group"
    aria-label="Toggle group example"
>
    <label class="button button--outline button--icon">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-bold-icon lucide-bold"><path d="M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8"/></svg>
        <span>Toggle bold</span>
        <input name="toggleGroup4" type="checkbox" />
    </label>

    <label class="button button--outline button--icon">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-italic-icon lucide-italic"><line x1="19" x2="10" y1="4" y2="4"/><line x1="14" x2="5" y1="20" y2="20"/><line x1="15" x2="9" y1="4" y2="20"/></svg>
        <span>Toggle italic</span>
        <input name="toggleGroup5" type="checkbox" />
    </label>

    <label class="button button--outline button--icon">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-underline-icon lucide-underline"><path d="M6 4v6a6 6 0 0 0 12 0V4"/><line x1="4" x2="20" y1="20" y2="20"/></svg>
        <span>Toggle underline</span>
        <input name="toggleGroup6" type="checkbox" />
    </label>
</div>

<br/>

<div
    class="button-group"
    role="group"
    aria-label="Text formatting controls"
>
    <label class="button button--ghost button--icon">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-bold-icon lucide-bold"><path d="M6 12h9a4 4 0 0 1 0 8H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h7a4 4 0 0 1 0 8"/></svg>
        <input name="toggleGroup7" type="checkbox" />
        <span>Toggle bold</span>
    </label>

    <label class="button button--ghost button--icon">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-italic-icon lucide-italic"><line x1="19" x2="10" y1="4" y2="4"/><line x1="14" x2="5" y1="20" y2="20"/><line x1="15" x2="9" y1="4" y2="20"/></svg>
        <input name="toggleGroup8" type="checkbox" />
        <span>Toggle italic</span>
    </label>

    <label class="button button--ghost button--icon">
        <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-underline-icon lucide-underline"><path d="M6 4v6a6 6 0 0 0 12 0V4"/><line x1="4" x2="20" y1="20" y2="20"/></svg>
        <input name="toggleGroup9" type="checkbox" />
        <span>Toggle strikethrough</span>
    </label>
</div>

Tooltip

A popup that displays information related to an element when the element receives keyboard focus or the mouse hovers over it.




<button
    class="button tooltip tooltip--top tooltip--center"
    style="--tooltip-content: 'Add to library'"
    type="button"
>
    Top center
</button>

<button
    class="button tooltip tooltip--top tooltip--start"
    style="--tooltip-content: 'Add to library'"
    type="button"
>
    Top start
</button>

<button
    class="button tooltip tooltip--bottom tooltip--end"
    style="--tooltip-content: 'Add to library'"
    type="button"
>
    Bottom end
</button>

<br /><br />

<button
    class="button tooltip tooltip--right tooltip--center"
    style="--tooltip-content: 'Add to library'"
    type="button"
>
    Right start
</button>

<button
    class="button tooltip tooltip--right tooltip--start"
    style="--tooltip-content: 'Add to library'"
    type="button"
>
    Right start
</button>

<button
    class="button tooltip tooltip--left tooltip--end"
    style="--tooltip-content: 'Add to library'"
    type="button"
>
    Left end
</button>

Typography

Styles for headings, paragraphs, lists...etc


Heading 1

Heading 2

Heading 3

Heading 4

Paragraph


"After all," he said, "everyone enjoys a good joke, so it's only fair that they should pay for the privilege." "After all," he said, "everyone enjoys a good joke, so it's only fair that they should pay for the privilege." "After all," he said, "everyone enjoys a good joke, so it's only fair that they should pay for the privilege."

  • Unordered list
  • Unordered list
  • Unordered list
King's Treasury People's happiness
Empty Overflowing
Modest Satisfied
Full Ecstatic


Enter your email address.

<div class="typography">
    <h1>Heading 1</h1>
    <h2>Heading 2</h2>
    <h3>Heading 3</h3>
    <h4>Heading 4</h4>
    <p>Paragraph</p>
    <br />
    <blockquote>
        "After all," he said, "everyone enjoys a good joke, so it's only
        fair that they should pay for the privilege." "After all," he
        said, "everyone enjoys a good joke, so it's only fair that they
        should pay for the privilege." "After all," he said, "everyone
        enjoys a good joke, so it's only fair that they should pay for
        the privilege."
    </blockquote>
    <br />
    <ul>
        <li>Unordered list</li>
        <li>Unordered list</li>
        <li>Unordered list</li>
    </ul>

    <table>
        <thead>
            <tr>
                <th>King's Treasury</th>
                <th>People's happiness</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>Empty</td>
                <td>Overflowing</td>
            </tr>
            <tr>
                <td>Modest</td>
                <td>Satisfied</td>
            </tr>
            <tr>
                <td>Full</td>
                <td>Ecstatic</td>
            </tr>
        </tbody>
    </table>
</div>

<br /><br />

<p class="muted">Enter your email address.</p>