UNPKG

@zeix/ui-element

Version:

UIElement - a HTML-first library for reactive Web Components

620 lines (590 loc) 27.3 kB
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Examples – UIElement Docs</title> <meta name="description" content="Common use cases and demos" /> <link rel="stylesheet" href="./assets/main.css" /> <script type="module" src="./assets/main.js"></script> </head> <body class=""> <context-router> <header class="content-grid"> <h1 class="content"> UIElement Docs <small>Version 0.13.3</small> </h1> <section-menu> <nav> <h2 class="visually-hidden">Main Menu</h2> <ol> <li> <a href="index.html"> <span class="icon">📖</span> <strong>Introduction</strong> <small>Overview and key benefits of UIElement</small> </a> </li> <li> <a href="getting-started.html"> <span class="icon">🚀</span> <strong>Getting Started</strong> <small>Installation, setup, and first steps</small> </a> </li> <li> <a href="components.html"> <span class="icon">🏗️</span> <strong>Components</strong> <small>Anatomy, lifecycle, signals, effects</small> </a> </li> <li> <a href="styling.html"> <span class="icon">🎨</span> <strong>Styling</strong> <small>Scoped styles, CSS custom properties</small> </a> </li> <li> <a href="data-flow.html"> <span class="icon">🔄</span> <strong>Data Flow</strong> <small>Passing state, events, context</small> </a> </li> <li> <a href="examples.html"> <span class="icon">🍽️</span> <strong>Examples</strong> <small>Common use cases and demos</small> </a> </li> <li> <a href="blog.html"> <span class="icon">📜</span> <strong>Blog</strong> <small>Latest articles and updates</small> </a> </li> <li> <a href="api.html"> <span class="icon">📚</span> <strong>API Reference</strong> <small>Functions, types, and constants</small> </a> </li> <li> <a href="about.html"> <span class="icon">🤝</span> <strong>About</strong> <small>License, versioning, getting involved</small> </a> </li> </ol> </nav> </section-menu> <card-callout class="content danger" hidden> <p class="error" role="alert" aria-live="polite"></p> </card-callout> </header> <main class="content-grid"><section-hero> <h1 id="examples-recipes"> <a name="examples-recipes" class="anchor" href="#examples-recipes"> <span class="permalink">🔗</span> </a> 🍽️ Examples &amp; Recipes </h1> <div> <p class="lead">Discover practical examples and patterns for building reactive, modular components with UIElement. Each example focuses on showcasing a specific feature or best practice, guiding you through real-world use cases.</p> <module-toc> <nav> <h2>In this Page</h2> <ol> <li><a href="#counter">Counter</a></li> <li><a href="#carousel">Carousel</a></li> <li><a href="#combobox">Combobox</a></li> <li><a href="#todo-app">Todo App</a></li> <li><a href="#lazy-loading">Lazy Loading</a></li> </ol> </nav> </module-toc> </div> </section-hero> <section> <h2 id="counter"> <a name="counter" class="anchor" href="#counter"> <span class="permalink">🔗</span> </a> Counter </h2> <module-demo> <div class="preview"> <basic-counter> <button type="button">💐 <span>5</span></button> </basic-counter> </div> <details> <summary>Source Code</summary> <module-lazy src="./examples/basic-counter.html"> <card-callout> <p class="loading" role="status">Loading...</p> <p class="error" role="alert" aria-live="polite"></p> </card-callout> </module-lazy> </details> </module-demo> </section> <section> <h2 id="carousel"> <a name="carousel" class="anchor" href="#carousel"> <span class="permalink">🔗</span> </a> Carousel </h2> <module-demo> <div class="preview"> <module-carousel> <h2 class="visually-hidden">Slides</h2> <div class="slides"> <div id="slide1" role="tabpanel" aria-current="true" style="background: var(--color-blue-20);"> <h3 id="slide-1"> <a name="slide-1" class="anchor" href="#slide-1"> <span class="permalink">🔗</span> </a> Slide 1 </h3> <hello-world> <label>Your name<br> <input type="text"> </label> <p>Hello, <span>World</span>!</p> </hello-world> </div> <div id="slide2" role="tabpanel" aria-current="false" style="background: var(--color-purple-20);"> <h3 id="slide-2"> <a name="slide-2" class="anchor" href="#slide-2"> <span class="permalink">🔗</span> </a> Slide 2 </h3> </div> <div id="slide3" role="tabpanel" aria-current="false" style="background: var(--color-pink-20);"> <h3 id="slide-3"> <a name="slide-3" class="anchor" href="#slide-3"> <span class="permalink">🔗</span> </a> Slide 3 </h3> </div> <div id="slide4" role="tabpanel" aria-current="false" style="background: var(--color-orange-20);"> <h3 id="slide-4"> <a name="slide-4" class="anchor" href="#slide-4"> <span class="permalink">🔗</span> </a> Slide 4 </h3> </div> <div id="slide5" role="tabpanel" aria-current="false" style="background: var(--color-green-20);"> <h3 id="slide-5"> <a name="slide-5" class="anchor" href="#slide-5"> <span class="permalink">🔗</span> </a> Slide 5 </h3> </div> </div> <nav aria-label="Carousel Navigation"> <button type="button" class="prev" aria-label="Previous"></button> <button type="button" class="next" aria-label="Next"></button> <div role="tablist"> <button role="tab" aria-selected="true" aria-controls="slide1" aria-label="Slide1" data-index="0" tabindex="0" ></button> <button role="tab" aria-current="false" aria-controls="slide2" aria-label="Slide 2" data-index="1" tabindex="-1" ></button> <button role="tab" aria-current="false" aria-controls="slide3" aria-label="Slide 3" data-index="2" tabindex="-1" ></button> <button role="tab" aria-current="false" aria-controls="slide4" aria-label="Slide 4" data-index="3" tabindex="-1" ></button> <button role="tab" aria-current="false" aria-controls="slide5" aria-label="Slide 5" data-index="4" tabindex="-1" ></button> </div> </nav> </module-carousel> </div> <details> <summary>Source Code</summary> <module-lazy src="./examples/module-carousel.html"> <card-callout> <p class="loading" role="status">Loading...</p> <p class="error" role="alert" aria-live="polite"></p> </card-callout> </module-lazy> </details> </module-demo> </section> <section> <h2 id="combobox"> <a name="combobox" class="anchor" href="#combobox"> <span class="permalink">🔗</span> </a> Combobox </h2> <module-demo> <div class="preview"> <form-combobox value=""> <label for="city-input">Choose a city</label> <div class="input"> <input id="city-input" type="text" role="combobox" aria-expanded="false" aria-controls="city-popup" aria-autocomplete="list" autocomplete="off" required /> <ol id="city-popup" role="listbox" hidden> <li role="option" tabindex="-1">Amsterdam</li> <li role="option" tabindex="-1">Berlin</li> <li role="option" tabindex="-1">Copenhagen</li> <li role="option" tabindex="-1">Dublin</li> <li role="option" tabindex="-1">Edinburgh</li> <li role="option" tabindex="-1">Frankfurt</li> <li role="option" tabindex="-1">Geneva</li> <li role="option" tabindex="-1">Helsinki</li> <li role="option" tabindex="-1">Istanbul</li> <li role="option" tabindex="-1">Jakarta</li> <li role="option" tabindex="-1">Kairo</li> <li role="option" tabindex="-1">London</li> <li role="option" tabindex="-1">Madrid</li> <li role="option" tabindex="-1">New York</li> <li role="option" tabindex="-1">Oslo</li> <li role="option" tabindex="-1">Paris</li> <li role="option" tabindex="-1">Qingdao</li> <li role="option" tabindex="-1">Rome</li> <li role="option" tabindex="-1">Stockholm</li> <li role="option" tabindex="-1">Tokyo</li> <li role="option" tabindex="-1">Ulan Bator</li> <li role="option" tabindex="-1">Vienna</li> <li role="option" tabindex="-1">Warsaw</li> <li role="option" tabindex="-1">Xi'an</li> <li role="option" tabindex="-1">Yokohama</li> <li role="option" tabindex="-1">Zurich</li> </ol> <button type="button" class="clear" aria-label="Clear input" hidden></button> </div> <p class="error" aria-live="assertive" id="city-error"></p> <p class="description" aria-live="polite" id="city-description">Tell us where you live so we can set your timezone for our calendar and notification features.</p> </form-combobox> </div> <details> <summary>Source Code</summary> <module-lazy src="./examples/form-combobox.html"> <card-callout> <p class="loading" role="status">Loading...</p> <p class="error" role="alert" aria-live="polite"></p> </card-callout> </module-lazy> </details> </module-demo> </section> <section> <h2 id="todo-app"> <a name="todo-app" class="anchor" href="#todo-app"> <span class="permalink">🔗</span> </a> Todo App </h2> <module-demo> <div class="preview"> <module-todo> <form action="#"> <form-textbox> <label for="add-todo">What needs to be done?</label> <div class="input"> <input id="add-todo" type="text" value="" /> </div> </form-textbox> <basic-button class="submit"> <button type="submit" class="constructive" disabled> Add Todo </button> </basic-button> </form> <ol filter="all"></ol> <template> <li> <form-checkbox class="todo"> <label> <input type="checkbox" class="visually-hidden" /> <span class="label"><slot></slot></span> </label> </form-checkbox> <basic-button class="delete"> <button type="button" class="destructive small">Delete</button> </basic-button> </li> </template> <footer> <div class="todo-count"> <p class="all-done">Well done, all done!</p> <p class="remaining"> <span class="count"></span> <span class="singular">task</span> <span class="plural">tasks</span> remaining </p> </div> <form-radiogroup value="all" class="split-button"> <fieldset> <legend class="visually-hidden">Filter</legend> <label class="selected"> <input type="radio" class="visually-hidden" name="filter" value="all" checked /> <span>All</span> </label> <label> <input type="radio" class="visually-hidden" name="filter" value="active" /> <span>Active</span> </label> <label> <input type="radio" class="visually-hidden" name="filter" value="completed" /> <span>Completed</span> </label> </fieldset> </form-radiogroup> <basic-button class="clear-completed"> <button type="button" class="destructive"> <span class="label">Clear Completed</span> <span class="badge"></span> </button> </basic-button> </footer> </module-todo> </div> <details> <summary>ModuleTodo Source Code</summary> <module-lazy src="./examples/module-todo.html"> <card-callout> <p class="loading" role="status">Loading...</p> <p class="error" role="alert" aria-live="polite"></p> </card-callout> </module-lazy> </details> <details> <summary>InputTextbox Source Code</summary> <module-lazy src="./examples/form-textbox.html"> <card-callout> <p class="loading" role="status">Loading...</p> <p class="error" role="alert" aria-live="polite"></p> </card-callout> </module-lazy> </details> <details> <summary>InputButton Source Code</summary> <module-lazy src="./examples/basic-button.html"> <card-callout> <p class="loading" role="status">Loading...</p> <p class="error" role="alert" aria-live="polite"></p> </card-callout> </module-lazy> </details> <details> <summary>InputCheckbox Source Code</summary> <module-lazy src="./examples/form-checkbox.html"> <card-callout> <p class="loading" role="status">Loading...</p> <p class="error" role="alert" aria-live="polite"></p> </card-callout> </module-lazy> </details> <details> <summary>InputRadiogroup Source Code</summary> <module-lazy src="./examples/form-radiogroup.html"> <card-callout> <p class="loading" role="status">Loading...</p> <p class="error" role="alert" aria-live="polite"></p> </card-callout> </module-lazy> </details> </module-demo> </section> <section> <h2 id="lazy-loading"> <a name="lazy-loading" class="anchor" href="#lazy-loading"> <span class="permalink">🔗</span> </a> Lazy Loading </h2> <p>This example shows how to handle asynchronous data loading and error states.</p> <p><strong>Features:</strong></p> <ul> <li>Lazy loading with intersection observer</li> <li>Loading states and error handling</li> <li>Content replacement patterns</li> </ul> <module-codeblock collapsed language="js" copy-success="Copied!" copy-error="Error trying to copy to clipboard!"> <p class="meta"> <span class="language">js</span> </p> <pre class="shiki monokai" style="background-color:#272822;color:#F8F8F2" tabindex="0"><code><span class="line"><span style="color:#A6E22E">component</span><span style="color:#F8F8F2">(</span></span> <span class="line"><span style="color:#E6DB74"> 'module-lazy'</span><span style="color:#F8F8F2">,</span></span> <span class="line"><span style="color:#F8F8F2"> {</span></span> <span class="line"><span style="color:#F8F8F2"> src: </span><span style="color:#A6E22E">asString</span><span style="color:#F8F8F2">(),</span></span> <span class="line"><span style="color:#F8F8F2"> loaded: </span><span style="color:#A6E22E">asBoolean</span><span style="color:#F8F8F2">(),</span></span> <span class="line"><span style="color:#F8F8F2"> loading: </span><span style="color:#A6E22E">asBoolean</span><span style="color:#F8F8F2">(),</span></span> <span class="line"><span style="color:#F8F8F2"> error: </span><span style="color:#A6E22E">asString</span><span style="color:#F8F8F2">(),</span></span> <span class="line"><span style="color:#F8F8F2"> },</span></span> <span class="line"><span style="color:#F8F8F2"> (</span><span style="color:#FD971F;font-style:italic">el</span><span style="color:#F8F8F2">, { </span><span style="color:#FD971F;font-style:italic">first</span><span style="color:#F8F8F2"> }) </span><span style="color:#66D9EF;font-style:italic">=></span><span style="color:#F8F8F2"> {</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> let</span><span style="color:#F8F8F2"> observer</span></span> <span class="line"></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#A6E22E"> loadContent</span><span style="color:#F92672"> =</span><span style="color:#F92672"> async</span><span style="color:#F8F8F2"> () </span><span style="color:#66D9EF;font-style:italic">=></span><span style="color:#F8F8F2"> {</span></span> <span class="line"><span style="color:#F92672"> if</span><span style="color:#F8F8F2"> (el.loaded </span><span style="color:#F92672">||</span><span style="color:#F8F8F2"> el.loading </span><span style="color:#F92672">||</span><span style="color:#F92672"> !</span><span style="color:#F8F8F2">el.src) </span><span style="color:#F92672">return</span></span> <span class="line"></span> <span class="line"><span style="color:#F8F8F2"> el.loading </span><span style="color:#F92672">=</span><span style="color:#AE81FF"> true</span></span> <span class="line"><span style="color:#F8F8F2"> el.error </span><span style="color:#F92672">=</span><span style="color:#E6DB74"> ''</span></span> <span class="line"></span> <span class="line"><span style="color:#F92672"> try</span><span style="color:#F8F8F2"> {</span></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#F8F8F2"> response </span><span style="color:#F92672">=</span><span style="color:#F92672"> await</span><span style="color:#A6E22E"> fetch</span><span style="color:#F8F8F2">(el.src)</span></span> <span class="line"><span style="color:#F92672"> if</span><span style="color:#F8F8F2"> (</span><span style="color:#F92672">!</span><span style="color:#F8F8F2">response.ok) </span><span style="color:#F92672">throw</span><span style="color:#F92672"> new</span><span style="color:#A6E22E"> Error</span><span style="color:#F8F8F2">(</span><span style="color:#E6DB74">`HTTP </span><span style="color:#F92672">${</span><span style="color:#F8F8F2">response.status</span><span style="color:#F92672">}</span><span style="color:#E6DB74">`</span><span style="color:#F8F8F2">)</span></span> <span class="line"></span> <span class="line"><span style="color:#66D9EF;font-style:italic"> const</span><span style="color:#F8F8F2"> content </span><span style="color:#F92672">=</span><span style="color:#F92672"> await</span><span style="color:#F8F8F2"> response.</span><span style="color:#A6E22E">text</span><span style="color:#F8F8F2">()</span></span> <span class="line"><span style="color:#F8F8F2"> el.</span><span style="color:#A6E22E">querySelector</span><span style="color:#F8F8F2">(</span><span style="color:#E6DB74">'.content'</span><span style="color:#F8F8F2">).innerHTML </span><span style="color:#F92672">=</span><span style="color:#F8F8F2"> content</span></span> <span class="line"><span style="color:#F8F8F2"> el.loaded </span><span style="color:#F92672">=</span><span style="color:#AE81FF"> true</span></span> <span class="line"><span style="color:#F8F8F2"> } </span><span style="color:#F92672">catch</span><span style="color:#F8F8F2"> (err) {</span></span> <span class="line"><span style="color:#F8F8F2"> el.error </span><span style="color:#F92672">=</span><span style="color:#F8F8F2"> err.message</span></span> <span class="line"><span style="color:#F8F8F2"> } </span><span style="color:#F92672">finally</span><span style="color:#F8F8F2"> {</span></span> <span class="line"><span style="color:#F8F8F2"> el.loading </span><span style="color:#F92672">=</span><span style="color:#AE81FF"> false</span></span> <span class="line"><span style="color:#F8F8F2"> }</span></span> <span class="line"><span style="color:#F8F8F2"> }</span></span> <span class="line"></span> <span class="line"><span style="color:#F92672"> return</span><span style="color:#F8F8F2"> [</span></span> <span class="line"><span style="color:#88846F"> // Loading state</span></span> <span class="line"><span style="color:#A6E22E"> first</span><span style="color:#F8F8F2">(</span></span> <span class="line"><span style="color:#E6DB74"> '.loading'</span><span style="color:#F8F8F2">,</span></span> <span class="line"><span style="color:#A6E22E"> setStyle</span><span style="color:#F8F8F2">(</span><span style="color:#E6DB74">'display'</span><span style="color:#F8F8F2">, () </span><span style="color:#66D9EF;font-style:italic">=></span><span style="color:#F8F8F2"> (el.loading </span><span style="color:#F92672">?</span><span style="color:#E6DB74"> 'block'</span><span style="color:#F92672"> :</span><span style="color:#E6DB74"> 'none'</span><span style="color:#F8F8F2">)),</span></span> <span class="line"><span style="color:#F8F8F2"> ),</span></span> <span class="line"></span> <span class="line"><span style="color:#88846F"> // Error state</span></span> <span class="line"><span style="color:#A6E22E"> first</span><span style="color:#F8F8F2">(</span></span> <span class="line"><span style="color:#E6DB74"> '.error'</span><span style="color:#F8F8F2">,</span></span> <span class="line"><span style="color:#A6E22E"> setText</span><span style="color:#F8F8F2">(</span><span style="color:#E6DB74">'error'</span><span style="color:#F8F8F2">),</span></span> <span class="line"><span style="color:#A6E22E"> setStyle</span><span style="color:#F8F8F2">(</span><span style="color:#E6DB74">'display'</span><span style="color:#F8F8F2">, () </span><span style="color:#66D9EF;font-style:italic">=></span><span style="color:#F8F8F2"> (el.error </span><span style="color:#F92672">?</span><span style="color:#E6DB74"> 'block'</span><span style="color:#F92672"> :</span><span style="color:#E6DB74"> 'none'</span><span style="color:#F8F8F2">)),</span></span> <span class="line"><span style="color:#F8F8F2"> ),</span></span> <span class="line"></span> <span class="line"><span style="color:#88846F"> // Content container</span></span> <span class="line"><span style="color:#A6E22E"> first</span><span style="color:#F8F8F2">(</span></span> <span class="line"><span style="color:#E6DB74"> '.content'</span><span style="color:#F8F8F2">,</span></span> <span class="line"><span style="color:#A6E22E"> setStyle</span><span style="color:#F8F8F2">(</span><span style="color:#E6DB74">'display'</span><span style="color:#F8F8F2">, () </span><span style="color:#66D9EF;font-style:italic">=></span><span style="color:#F8F8F2"> (el.loaded </span><span style="color:#F92672">?</span><span style="color:#E6DB74"> 'block'</span><span style="color:#F92672"> :</span><span style="color:#E6DB74"> 'none'</span><span style="color:#F8F8F2">)),</span></span> <span class="line"><span style="color:#F8F8F2"> ),</span></span> <span class="line"></span> <span class="line"><span style="color:#88846F"> // Setup intersection observer</span></span> <span class="line"><span style="color:#F8F8F2"> () </span><span style="color:#66D9EF;font-style:italic">=></span><span style="color:#F8F8F2"> {</span></span> <span class="line"><span style="color:#F8F8F2"> observer </span><span style="color:#F92672">=</span><span style="color:#F92672"> new</span><span style="color:#A6E22E"> IntersectionObserver</span><span style="color:#F8F8F2">(</span><span style="color:#FD971F;font-style:italic">entries</span><span style="color:#66D9EF;font-style:italic"> =></span><span style="color:#F8F8F2"> {</span></span> <span class="line"><span style="color:#F92672"> if</span><span style="color:#F8F8F2"> (entries[</span><span style="color:#AE81FF">0</span><span style="color:#F8F8F2">].isIntersecting) {</span></span> <span class="line"><span style="color:#A6E22E"> loadContent</span><span style="color:#F8F8F2">()</span></span> <span class="line"><span style="color:#F8F8F2"> observer.</span><span style="color:#A6E22E">disconnect</span><span style="color:#F8F8F2">()</span></span> <span class="line"><span style="color:#F8F8F2"> }</span></span> <span class="line"><span style="color:#F8F8F2"> })</span></span> <span class="line"></span> <span class="line"><span style="color:#F8F8F2"> observer.</span><span style="color:#A6E22E">observe</span><span style="color:#F8F8F2">(el)</span></span> <span class="line"></span> <span class="line"><span style="color:#F92672"> return</span><span style="color:#F8F8F2"> () </span><span style="color:#66D9EF;font-style:italic">=></span><span style="color:#F8F8F2"> observer?.</span><span style="color:#A6E22E">disconnect</span><span style="color:#F8F8F2">()</span></span> <span class="line"><span style="color:#F8F8F2"> },</span></span> <span class="line"><span style="color:#F8F8F2"> ]</span></span> <span class="line"><span style="color:#F8F8F2"> },</span></span> <span class="line"><span style="color:#F8F8F2">)</span></span> <span class="line"></span></code></pre> <basic-button class="copy"> <button type="button" class="secondary small"> <span class="label">Copy</span> </button> </basic-button> <button type="button" class="overlay">Expand</button> </module-codeblock> <module-codeblock language="html" copy-success="Copied!" copy-error="Error trying to copy to clipboard!"> <p class="meta"> <span class="language">html</span> </p> <pre class="shiki monokai" style="background-color:#272822;color:#F8F8F2" tabindex="0"><code><span class="line"><span style="color:#F8F8F2">&#x3C;</span><span style="color:#F92672">module-lazy</span><span style="color:#A6E22E"> src</span><span style="color:#F8F8F2">=</span><span style="color:#E6DB74">"/api/user-profile"</span><span style="color:#F8F8F2">></span></span> <span class="line"><span style="color:#F8F8F2"> &#x3C;</span><span style="color:#F92672">div</span><span style="color:#A6E22E"> class</span><span style="color:#F8F8F2">=</span><span style="color:#E6DB74">"loading"</span><span style="color:#F8F8F2">>Loading user profile...&#x3C;/</span><span style="color:#F92672">div</span><span style="color:#F8F8F2">></span></span> <span class="line"><span style="color:#F8F8F2"> &#x3C;</span><span style="color:#F92672">div</span><span style="color:#A6E22E"> class</span><span style="color:#F8F8F2">=</span><span style="color:#E6DB74">"error"</span><span style="color:#F8F8F2">>&#x3C;/</span><span style="color:#F92672">div</span><span style="color:#F8F8F2">></span></span> <span class="line"><span style="color:#F8F8F2"> &#x3C;</span><span style="color:#F92672">div</span><span style="color:#A6E22E"> class</span><span style="color:#F8F8F2">=</span><span style="color:#E6DB74">"content"</span><span style="color:#F8F8F2">>&#x3C;/</span><span style="color:#F92672">div</span><span style="color:#F8F8F2">></span></span> <span class="line"><span style="color:#F8F8F2">&#x3C;/</span><span style="color:#F92672">module-lazy</span><span style="color:#F8F8F2">></span></span> <span class="line"></span></code></pre> <basic-button class="copy"> <button type="button" class="secondary small"> <span class="label">Copy</span> </button> </basic-button> </module-codeblock> </section> </main> <footer class="content-grid"> <div class="content"> <h2 class="visually-hidden">Footer</h2> <p>© 2024 – 2025 Zeix AG</p> </div> </footer> </context-router> </body> </html>