423 lines
22 KiB
HTML
423 lines
22 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<meta name="description" content="PettyUI showcase — 45 headless Web Components, zero dependencies, built on browser standards." />
|
|
<title>PettyUI — Component Showcase</title>
|
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
<link href="https://fonts.googleapis.com/css2?family=Instrument+Sans:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap" rel="stylesheet" />
|
|
<script type="module">
|
|
import "pettyui/button"; import "pettyui/link"; import "pettyui/separator";
|
|
import "pettyui/badge"; import "pettyui/skeleton"; import "pettyui/avatar";
|
|
import "pettyui/card"; import "pettyui/text-field"; import "pettyui/checkbox";
|
|
import "pettyui/switch"; import "pettyui/radio-group"; import "pettyui/toggle";
|
|
import "pettyui/toggle-group"; import "pettyui/number-field"; import "pettyui/slider";
|
|
import "pettyui/tags-input"; import "pettyui/select"; import "pettyui/tabs";
|
|
import "pettyui/accordion"; import "pettyui/collapsible"; import "pettyui/breadcrumbs";
|
|
import "pettyui/pagination"; import "pettyui/dialog"; import "pettyui/alert-dialog";
|
|
import "pettyui/popover"; import "pettyui/tooltip"; import "pettyui/dropdown-menu";
|
|
import "pettyui/alert"; import "pettyui/progress"; import "pettyui/meter";
|
|
import "pettyui/toast"; import { toast } from "pettyui/toast";
|
|
import "pettyui/typewriter"; import "pettyui/counter";
|
|
import "pettyui/stagger"; import "pettyui/reveal";
|
|
import "pettyui/loading-indicator"; import "pettyui/animations";
|
|
document.querySelector("#demo-toast-btn")?.addEventListener("click", () => {
|
|
toast.success("Component loaded", { description: "PettyUI runs with zero deps" });
|
|
});
|
|
document.querySelector("#demo-toast-err")?.addEventListener("click", () => {
|
|
toast.error("Something broke", { description: "Just kidding" });
|
|
});
|
|
</script>
|
|
<link rel="stylesheet" href="./style.css" />
|
|
</head>
|
|
<body>
|
|
<a href="#main" class="skip-link">Skip to content</a>
|
|
<main class="page" id="main">
|
|
|
|
<section class="hero">
|
|
<h1><petty-typewriter speed="60">PettyUI</petty-typewriter></h1>
|
|
<p class="hero-sub"><petty-typewriter speed="25" delay="600">45 headless Web Components. Zero dependencies. Browser-native APIs. The smallest UI library that does everything.</petty-typewriter></p>
|
|
<div class="hero-stats">
|
|
<span class="hero-stat"><petty-counter to="45" duration="1500" delay="1200"></petty-counter> components</span>
|
|
<span class="hero-stat-dot" aria-hidden="true"></span>
|
|
<span class="hero-stat"><petty-counter to="0" duration="500" delay="1400"></petty-counter> dependencies</span>
|
|
<span class="hero-stat-dot" aria-hidden="true"></span>
|
|
<span class="hero-stat">~<petty-counter to="500" duration="1200" delay="1600" suffix="B"></petty-counter> runtime</span>
|
|
</div>
|
|
</section>
|
|
|
|
<section class="value-props">
|
|
<h2 class="sr-only">Why PettyUI</h2>
|
|
<dl class="value-list">
|
|
<div class="value-item">
|
|
<dt>Browser-Native</dt>
|
|
<dd>Popover API, native Dialog, Navigation API, Invoker Commands. No polyfills.</dd>
|
|
</div>
|
|
<div class="value-item">
|
|
<dt>Zero Runtime</dt>
|
|
<dd>500-byte signals. No virtual DOM, no framework. Just Custom Elements.</dd>
|
|
</div>
|
|
<div class="value-item">
|
|
<dt>AI-Native</dt>
|
|
<dd>Zod schemas for every prop. MCP tools for agent integration.</dd>
|
|
</div>
|
|
</dl>
|
|
</section>
|
|
|
|
<div class="section-separator"></div>
|
|
|
|
<section class="section">
|
|
<petty-reveal animation="fade-up" once><h2 class="section-title">Inputs & Forms</h2></petty-reveal>
|
|
<petty-reveal animation="fade-up" once delay="100"><p class="section-desc">Form primitives with built-in ARIA, keyboard navigation, and event handling.</p></petty-reveal>
|
|
<div class="grid">
|
|
|
|
<article class="demo-card">
|
|
<h3>Button</h3>
|
|
<div class="demo-row">
|
|
<petty-button><button type="button">Default</button></petty-button>
|
|
<petty-button><button type="button" class="primary">Primary</button></petty-button>
|
|
<petty-button disabled><button type="button">Disabled</button></petty-button>
|
|
<petty-button loading><button type="button">Loading</button></petty-button>
|
|
</div>
|
|
<p class="tag-name"><petty-button></p>
|
|
</article>
|
|
|
|
<article class="demo-card">
|
|
<h3>Text Field</h3>
|
|
<petty-text-field name="email">
|
|
<label data-part="label">Email address</label>
|
|
<input data-part="control" type="email" placeholder="you@example.com" aria-label="Email address" />
|
|
<span data-part="description">We will never share your email.</span>
|
|
<span data-part="error"></span>
|
|
</petty-text-field>
|
|
<p class="tag-name"><petty-text-field></p>
|
|
</article>
|
|
|
|
<article class="demo-card">
|
|
<h3>Checkbox & Switch</h3>
|
|
<div class="demo-area">
|
|
<petty-checkbox>
|
|
<input data-part="control" type="checkbox" aria-label="Accept terms" />
|
|
<label data-part="label">Accept terms</label>
|
|
</petty-checkbox>
|
|
<petty-checkbox checked>
|
|
<input data-part="control" type="checkbox" aria-label="Subscribe to updates" />
|
|
<label data-part="label">Subscribe to updates</label>
|
|
</petty-checkbox>
|
|
<petty-separator></petty-separator>
|
|
<petty-switch>
|
|
<button type="button" data-part="control" role="switch" aria-checked="false" aria-label="Dark mode"><span data-part="thumb"></span></button>
|
|
<span data-part="label">Dark mode</span>
|
|
</petty-switch>
|
|
</div>
|
|
<p class="tag-name"><petty-checkbox> <petty-switch></p>
|
|
</article>
|
|
|
|
<article class="demo-card">
|
|
<h3>Radio Group</h3>
|
|
<petty-radio-group default-value="md" orientation="vertical">
|
|
<petty-radio-item value="sm">Small</petty-radio-item>
|
|
<petty-radio-item value="md">Medium</petty-radio-item>
|
|
<petty-radio-item value="lg">Large</petty-radio-item>
|
|
</petty-radio-group>
|
|
<p class="tag-name"><petty-radio-group></p>
|
|
</article>
|
|
|
|
<article class="demo-card">
|
|
<h3>Toggle & Toggle Group</h3>
|
|
<div class="demo-area">
|
|
<div class="demo-row">
|
|
<petty-toggle><button type="button" data-part="control">Mute</button></petty-toggle>
|
|
<petty-toggle pressed><button type="button" data-part="control">Pin</button></petty-toggle>
|
|
</div>
|
|
<petty-toggle-group type="single" default-value="left">
|
|
<petty-toggle-group-item value="left">Left</petty-toggle-group-item>
|
|
<petty-toggle-group-item value="center">Center</petty-toggle-group-item>
|
|
<petty-toggle-group-item value="right">Right</petty-toggle-group-item>
|
|
</petty-toggle-group>
|
|
</div>
|
|
<p class="tag-name"><petty-toggle> <petty-toggle-group></p>
|
|
</article>
|
|
|
|
<article class="demo-card">
|
|
<h3>Number Field & Slider</h3>
|
|
<petty-number-field min="0" max="99" step="1" value="3">
|
|
<label data-part="label">Qty</label>
|
|
<button type="button" data-part="decrement">−</button>
|
|
<input data-part="control" type="number" aria-label="Quantity" />
|
|
<button type="button" data-part="increment">+</button>
|
|
</petty-number-field>
|
|
<petty-slider min="0" max="100" value="65">
|
|
<label data-part="label">Volume</label>
|
|
<input data-part="control" type="range" aria-label="Volume" />
|
|
<output data-part="output">65</output>
|
|
</petty-slider>
|
|
<p class="tag-name"><petty-number-field> <petty-slider></p>
|
|
</article>
|
|
|
|
<article class="demo-card">
|
|
<h3>Select</h3>
|
|
<petty-select default-value="ts" placeholder="Pick a language">
|
|
<button type="button" data-part="trigger" popovertarget="lang-sel">Pick a language</button>
|
|
<div id="lang-sel" popover data-part="listbox" role="listbox">
|
|
<petty-select-option value="ts">TypeScript</petty-select-option>
|
|
<petty-select-option value="rs">Rust</petty-select-option>
|
|
<petty-select-option value="go">Go</petty-select-option>
|
|
<petty-select-option value="py">Python</petty-select-option>
|
|
</div>
|
|
</petty-select>
|
|
<p class="tag-name"><petty-select></p>
|
|
</article>
|
|
|
|
<article class="demo-card">
|
|
<h3>Tags Input</h3>
|
|
<petty-tags-input value="pettyui,web-components,headless">
|
|
<span data-part="tags"></span>
|
|
<input data-part="input" placeholder="Add tag..." aria-label="Add tag" />
|
|
<input data-part="hidden" type="hidden" aria-label="Selected tags" />
|
|
</petty-tags-input>
|
|
<p class="tag-name"><petty-tags-input></p>
|
|
</article>
|
|
|
|
</div>
|
|
</section>
|
|
|
|
<section class="section section-glow">
|
|
<petty-reveal animation="fade-up" once><h2 class="section-title">Navigation</h2></petty-reveal>
|
|
<petty-reveal animation="fade-up" once delay="100"><p class="section-desc">Tab bars, accordions, breadcrumbs, and pagination — all keyboard-accessible.</p></petty-reveal>
|
|
<div class="grid">
|
|
|
|
<article class="demo-card wide">
|
|
<h3>Tabs</h3>
|
|
<petty-tabs default-value="overview">
|
|
<div role="tablist">
|
|
<petty-tab value="overview">Overview</petty-tab>
|
|
<petty-tab value="features">Features</petty-tab>
|
|
<petty-tab value="api">API</petty-tab>
|
|
</div>
|
|
<petty-tab-panel value="overview">PettyUI is a headless component library built on vanilla Web Components. No framework required.</petty-tab-panel>
|
|
<petty-tab-panel value="features">Zero dependencies, Popover API, native dialog, Invoker Commands, Navigation API, View Transitions.</petty-tab-panel>
|
|
<petty-tab-panel value="api">Every component is a Custom Element. Import and use anywhere: React, Vue, Svelte, or plain HTML.</petty-tab-panel>
|
|
</petty-tabs>
|
|
<p class="tag-name"><petty-tabs></p>
|
|
</article>
|
|
|
|
<article class="demo-card">
|
|
<h3>Accordion</h3>
|
|
<petty-accordion type="single">
|
|
<petty-accordion-item value="install">
|
|
<details><summary>Installation</summary><p data-part="content">npm install pettyui — zero peer dependencies.</p></details>
|
|
</petty-accordion-item>
|
|
<petty-accordion-item value="usage">
|
|
<details><summary>Usage</summary><p data-part="content">Import the component, write HTML. That is it.</p></details>
|
|
</petty-accordion-item>
|
|
<petty-accordion-item value="styling">
|
|
<details><summary>Styling</summary><p data-part="content">No Shadow DOM. Style with plain CSS, Tailwind, or anything.</p></details>
|
|
</petty-accordion-item>
|
|
</petty-accordion>
|
|
<p class="tag-name"><petty-accordion></p>
|
|
</article>
|
|
|
|
<article class="demo-card">
|
|
<h3>Breadcrumbs & Pagination</h3>
|
|
<petty-breadcrumbs>
|
|
<ol>
|
|
<petty-breadcrumb-item><a href="/home">Home</a></petty-breadcrumb-item>
|
|
<petty-breadcrumb-item><a href="/components">Components</a></petty-breadcrumb-item>
|
|
<petty-breadcrumb-item current>Button</petty-breadcrumb-item>
|
|
</ol>
|
|
</petty-breadcrumbs>
|
|
<petty-separator></petty-separator>
|
|
<petty-pagination total="50" page-size="10" current-page="2">
|
|
<nav aria-label="Pagination">
|
|
<petty-pagination-item type="prev">←</petty-pagination-item>
|
|
<petty-pagination-item value="1">1</petty-pagination-item>
|
|
<petty-pagination-item value="2">2</petty-pagination-item>
|
|
<petty-pagination-item value="3">3</petty-pagination-item>
|
|
<petty-pagination-item value="4">4</petty-pagination-item>
|
|
<petty-pagination-item value="5">5</petty-pagination-item>
|
|
<petty-pagination-item type="next">→</petty-pagination-item>
|
|
</nav>
|
|
</petty-pagination>
|
|
<p class="tag-name"><petty-breadcrumbs> <petty-pagination></p>
|
|
</article>
|
|
|
|
</div>
|
|
</section>
|
|
|
|
<section class="section">
|
|
<petty-reveal animation="fade-up" once><h2 class="section-title">Overlays</h2></petty-reveal>
|
|
<petty-reveal animation="fade-up" once delay="100"><p class="section-desc">Dialogs, popovers, tooltips, and drawers — powered by native browser APIs.</p></petty-reveal>
|
|
<div class="grid">
|
|
|
|
<article class="demo-card">
|
|
<h3>Dialog & Alert Dialog</h3>
|
|
<div class="demo-row">
|
|
<petty-button><button type="button" onclick="document.getElementById('demo-dlg').showModal()">Open Dialog</button></petty-button>
|
|
<petty-button><button type="button" onclick="document.getElementById('demo-alert-dlg').showModal()">Confirm Delete</button></petty-button>
|
|
</div>
|
|
<p class="tag-name"><petty-dialog> <petty-alert-dialog></p>
|
|
</article>
|
|
|
|
<article class="demo-card">
|
|
<h3>Popover & Tooltip</h3>
|
|
<div class="demo-row">
|
|
<petty-popover>
|
|
<button type="button" class="btn-outline" popovertarget="demo-pop">Show Popover</button>
|
|
<div id="demo-pop" popover data-part="content">This uses the native Popover API. Click outside to dismiss.</div>
|
|
</petty-popover>
|
|
<petty-tooltip>
|
|
<span data-part="trigger" tabindex="0" class="hint-text">Hover me</span>
|
|
<div popover="manual" data-part="content" role="tooltip">Native tooltip via Popover API</div>
|
|
</petty-tooltip>
|
|
</div>
|
|
<p class="tag-name"><petty-popover> <petty-tooltip></p>
|
|
</article>
|
|
|
|
<article class="demo-card">
|
|
<h3>Dropdown Menu</h3>
|
|
<petty-dropdown-menu>
|
|
<button type="button" data-part="trigger" class="btn-outline" popovertarget="demo-menu">Actions ▾</button>
|
|
<div id="demo-menu" popover data-part="content" role="menu">
|
|
<petty-menu-item>Edit</petty-menu-item>
|
|
<petty-menu-item>Duplicate</petty-menu-item>
|
|
<petty-menu-item>Archive</petty-menu-item>
|
|
<petty-menu-item disabled>Delete</petty-menu-item>
|
|
</div>
|
|
</petty-dropdown-menu>
|
|
<p class="tag-name"><petty-dropdown-menu></p>
|
|
</article>
|
|
|
|
</div>
|
|
</section>
|
|
|
|
<section class="section section-glow">
|
|
<petty-reveal animation="fade-up" once><h2 class="section-title">Feedback & Display</h2></petty-reveal>
|
|
<petty-reveal animation="fade-up" once delay="100"><p class="section-desc">Status indicators, progress bars, alerts, badges, and notifications.</p></petty-reveal>
|
|
<div class="grid">
|
|
|
|
<article class="demo-card">
|
|
<h3>Alert</h3>
|
|
<div class="demo-area">
|
|
<petty-alert variant="success"><span class="alert-icon" aria-hidden="true">✓</span><div data-part="content"><div data-part="title">Deployed successfully</div><div data-part="description">Your changes are live and visible to all users.</div></div></petty-alert>
|
|
<petty-alert variant="error"><span class="alert-icon" aria-hidden="true">✗</span><div data-part="content"><div data-part="title">Build failed</div><div data-part="description">Check the CI logs for error details.</div></div></petty-alert>
|
|
<petty-alert variant="warning"><span class="alert-icon" aria-hidden="true">⚠</span><div data-part="content"><div data-part="title">Rate limit approaching</div><div data-part="description">You have used 90% of your API quota this month.</div></div></petty-alert>
|
|
</div>
|
|
<p class="tag-name"><petty-alert></p>
|
|
</article>
|
|
|
|
<article class="demo-card">
|
|
<h3>Progress & Meter</h3>
|
|
<div class="demo-area">
|
|
<div class="progress-field">
|
|
<div class="progress-header"><span>Upload progress</span><span>72%</span></div>
|
|
<petty-progress value="72" max="100"><div data-part="track"><div data-part="fill"></div></div></petty-progress>
|
|
</div>
|
|
<div class="progress-field">
|
|
<div class="progress-header"><span>CPU usage</span><span class="meter-low">35%</span></div>
|
|
<petty-meter value="35" min="0" max="100" low="25" high="75" optimum="50"><div data-part="track"><div data-part="fill"></div></div></petty-meter>
|
|
</div>
|
|
<div class="progress-field">
|
|
<div class="progress-header"><span>Memory</span><span class="meter-high">85%</span></div>
|
|
<petty-meter value="85" min="0" max="100" low="25" high="75" optimum="50"><div data-part="track"><div data-part="fill"></div></div></petty-meter>
|
|
</div>
|
|
</div>
|
|
<div class="progress-field">
|
|
<div class="progress-header"><span>Loading indicator</span></div>
|
|
<div class="demo-row-spacious loading-demo">
|
|
<petty-loading-indicator size="20" aria-label="Loading tiny"></petty-loading-indicator>
|
|
<petty-loading-indicator size="28" aria-label="Loading small"></petty-loading-indicator>
|
|
<petty-loading-indicator size="36" aria-label="Loading medium"></petty-loading-indicator>
|
|
<petty-loading-indicator aria-label="Loading default"></petty-loading-indicator>
|
|
</div>
|
|
</div>
|
|
<p class="tag-name"><petty-progress> <petty-meter> <petty-loading-indicator></p>
|
|
</article>
|
|
|
|
<article class="demo-card">
|
|
<h3>Badge & Avatar</h3>
|
|
<div class="demo-area">
|
|
<div class="demo-row-loose">
|
|
<petty-badge>Default</petty-badge>
|
|
<petty-badge variant="success">Active</petty-badge>
|
|
<petty-badge variant="error">Offline</petty-badge>
|
|
<petty-badge variant="warning">Pending</petty-badge>
|
|
</div>
|
|
<div class="demo-row-loose">
|
|
<petty-avatar><span data-part="fallback">MB</span></petty-avatar>
|
|
<petty-avatar><span data-part="fallback">JD</span></petty-avatar>
|
|
<petty-avatar><span data-part="fallback">AK</span></petty-avatar>
|
|
</div>
|
|
</div>
|
|
<p class="tag-name"><petty-badge> <petty-avatar></p>
|
|
</article>
|
|
|
|
<article class="demo-card">
|
|
<h3>Toast</h3>
|
|
<div class="demo-row">
|
|
<petty-button><button type="button" id="demo-toast-btn" class="primary">Success Toast</button></petty-button>
|
|
<petty-button><button type="button" id="demo-toast-err">Error Toast</button></petty-button>
|
|
</div>
|
|
<p class="tag-name"><petty-toast-region></p>
|
|
</article>
|
|
|
|
<article class="demo-card">
|
|
<h3>Skeleton & Card</h3>
|
|
<petty-card>
|
|
<petty-card-header><h4>Loading content</h4></petty-card-header>
|
|
<petty-card-content>
|
|
<petty-skeleton class="skel-80"></petty-skeleton>
|
|
<petty-skeleton class="skel-60"></petty-skeleton>
|
|
<petty-skeleton class="skel-70"></petty-skeleton>
|
|
</petty-card-content>
|
|
<petty-card-footer>
|
|
<petty-skeleton class="skel-btn"></petty-skeleton>
|
|
</petty-card-footer>
|
|
</petty-card>
|
|
<p class="tag-name"><petty-card> <petty-skeleton></p>
|
|
</article>
|
|
|
|
<article class="demo-card">
|
|
<h3>Link & Separator</h3>
|
|
<petty-link><a href="/docs">Internal documentation link</a></petty-link>
|
|
<petty-link external><a href="https://developer.mozilla.org" target="_blank" rel="noopener">MDN Web Docs ↗</a></petty-link>
|
|
<petty-separator></petty-separator>
|
|
<span class="muted-sm">Separator shown above</span>
|
|
<p class="tag-name"><petty-link> <petty-separator></p>
|
|
</article>
|
|
|
|
</div>
|
|
</section>
|
|
|
|
<section class="footer-section">
|
|
<petty-separator></petty-separator>
|
|
<p class="footer-text">PettyUI v2 — 45 Web Components, 0 dependencies, built on browser standards.</p>
|
|
</section>
|
|
|
|
<footer class="st3-sig"><span>//ST3</span></footer>
|
|
|
|
</main>
|
|
|
|
<petty-dialog>
|
|
<dialog id="demo-dlg">
|
|
<h2>Welcome to PettyUI</h2>
|
|
<p>This dialog uses the native dialog element. Focus trap, backdrop, and Escape key work out of the box.</p>
|
|
<petty-button><button type="button" onclick="document.getElementById('demo-dlg').close()">Got it</button></petty-button>
|
|
</dialog>
|
|
</petty-dialog>
|
|
<petty-alert-dialog>
|
|
<dialog id="demo-alert-dlg" role="alertdialog">
|
|
<h2>Delete project?</h2>
|
|
<p>This action cannot be undone. All data will be permanently removed.</p>
|
|
<div class="demo-row">
|
|
<petty-button><button type="button" onclick="document.getElementById('demo-alert-dlg').close()">Cancel</button></petty-button>
|
|
<petty-button><button type="button" class="primary" onclick="document.getElementById('demo-alert-dlg').close()">Delete</button></petty-button>
|
|
</div>
|
|
</dialog>
|
|
</petty-alert-dialog>
|
|
<petty-toast-region></petty-toast-region>
|
|
</body>
|
|
</html>
|