Alumna Shadcn
Icon <div class="input-group">
<span class="input-addon" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="11" cy="11" r="7"></circle>
<path d="m20 20-3-3"></path>
</svg>
</span>
<input class="input" type="search" placeholder="Search...">
</div> Text <div class="input-group">
<span class="input-addon"> lt;/span>
<input class="input" type="text" placeholder="0.00">
<span class="input-addon" data-align="end">USD</span>
</div>
<div class="input-group">
<span class="input-addon">https://</span>
<input class="input" type="text" placeholder="example.com">
<span class="input-addon" data-align="end">.com</span>
</div>
<div class="input-group">
<input class="input" type="text" placeholder="username">
<span class="input-addon" data-align="end">@acme.test</span>
</div>
<div class="input-group">
<input class="input" type="url" value="https://alumna.dev" readonly>
<span class="input-addon" data-align="end">
<button class="button button-ghost button-sm" type="button">Copy</button>
</span>
</div>
<div class="input-group">
<input class="input" type="search" placeholder="Type to search...">
<button class="button button-secondary button-sm" type="button">Search</button>
</div> Textarea data-align="block-start" is a header, block-end a footer. Both turn the group into a column.
52% used Send
Ask, search or chat…
Cancel Post
<div class="input-group">
<textarea class="textarea" placeholder="Ask, search or chat…"></textarea>
<span class="input-addon" data-align="block-end">
<span>52% used</span>
<button class="button button-sm" type="button">Send</button>
</span>
</div>
<div class="input-group">
<textarea class="textarea" id="prompt"></textarea>
<span class="input-addon" data-align="block-start">
<label class="label" for="prompt">Ask, search or chat…</label>
</span>
</div>
<div class="input-group">
<textarea class="textarea" placeholder="Share your thoughts…"></textarea>
<span class="input-addon" data-align="block-end">
<button class="button button-ghost button-sm" type="button">Cancel</button>
<button class="button button-sm" type="button">Post</button>
</span>
</div> Spinner <div class="input-group">
<input class="input" placeholder="Searching…" disabled>
<span class="input-addon" data-align="end">
<svg class="spinner" viewBox="0 0 24 24" fill="none" aria-hidden="true">
<circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="2" opacity="0.25"></circle>
<path d="M21 12a9 9 0 0 1-9 9" stroke="currentColor" stroke-width="2" stroke-linecap="round"></path>
</svg>
</span>
</div> Same addon with src/components/ui/Spinner.svelte (Spinner ):
<script>
import Spinner from './ui/Spinner.svelte';
</script>
<div class="input-group">
<input class="input" placeholder="Searching…" disabled>
<span class="input-addon" data-align="end">
<Spinner decorative />
</span>
</div> Label <div class="input-group">
<span class="input-addon"><label class="label" for="handle">@</label></span>
<input class="input" id="handle" placeholder="alumna">
</div> <script>
import { tip_enter, tip_leave } from './ui/Place.svelte';
let tip;
</script>
<div class="input-group">
<input class="input" placeholder="Enter a URL">
<span class="input-addon" data-align="end">
<button class="button button-ghost button-sm button-icon" type="button" aria-label="About this field"
onmouseenter={(event) => tip_enter(event, tip)}
onmouseleave={(event) => tip_leave(event, tip)}
>?</button>
</span>
</div>
<div bind:this={tip} popover="manual" class="tooltip">Must start with https://</div> Dropdown <script>
import { on_menu_toggle, menu_keydown, choose_item } from './ui/Place.svelte';
let scheme = $state('https://');
</script>
<div class="input-group">
<span class="input-addon">
<button class="button button-ghost button-sm" type="button" popovertarget="scheme" aria-haspopup="menu" aria-expanded="false">{scheme}</button>
</span>
<input class="input" placeholder="example.com">
</div>
<div id="scheme" popover class="menu" role="menu" tabindex="-1" ontoggle={on_menu_toggle} onkeydown={menu_keydown}>
<button class="menu-item" type="button" role="menuitem" onclick={(event) => { scheme = 'https://'; choose_item(event); }}>https://</button>
<button class="menu-item" type="button" role="menuitem" onclick={(event) => { scheme = 'http://'; choose_item(event); }}>http://</button>
</div> Kbd <div class="input-group">
<span class="input-addon" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<circle cx="11" cy="11" r="7"></circle>
<path d="m20 20-3-3"></path>
</svg>
</span>
<input class="input" type="search" placeholder="Search…">
<span class="input-addon" data-align="end">
<kbd class="kbd">⌘</kbd>
<kbd class="kbd">K</kbd>
</span>
</div> Prefix and suffix sit in .button-group-text around the
input group. Shared radii come from .button-group.
<div class="button-group" style="width: 100%">
<span class="button-group-text"><label class="label" for="url">https://</label></span>
<div class="input-group">
<input class="input" id="url" placeholder="example">
<span class="input-addon" data-align="end" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M10 13a5 5 0 0 0 7.07 0l1.41-1.41a5 5 0 0 0-7.07-7.07L10 5.93"></path>
<path d="M14 11a5 5 0 0 0-7.07 0L5.52 12.41a5 5 0 0 0 7.07 7.07L14 18.07"></path>
</svg>
</span>
</div>
<span class="button-group-text">.com</span>
</div> In card <div class="card" style="max-width: 24rem">
<div class="card-header">
<div class="card-title">Contact</div>
<div class="card-description">Input groups inside a card.</div>
</div>
<div class="card-content">
<div class="field-group">
<div class="field">
<label class="label" for="email">Email</label>
<div class="input-group">
<input class="input" id="email" type="email" placeholder="you@example.com">
<span class="input-addon" data-align="end" aria-hidden="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="3" y="5" width="18" height="14" rx="2"></rect>
<path d="m3 7 9 6 9-6"></path>
</svg>
</span>
</div>
</div>
<div class="field">
<label class="label" for="site">Website</label>
<div class="input-group">
<span class="input-addon">https://</span>
<input class="input" id="site" placeholder="example.com">
</div>
</div>
</div>
</div>
<div class="card-footer" style="justify-content: flex-end; gap: 0.5rem">
<button class="button button-outline" type="button">Cancel</button>
<button class="button" type="button">Submit</button>
</div>
</div> Invalid and disabled aria-invalid="true" on a control tints the group. data-disabled on the group fades it (keep the control disabled too). A spinner next to a disabled input
does not need the fade.
<div class="input-group">
<input class="input" type="email" placeholder="hello@" aria-invalid="true">
<span class="input-addon" data-align="end">.com</span>
</div>
<div class="input-group" data-disabled>
<span class="input-addon">lt;/span>
<input class="input" placeholder="0.00" disabled>
</div>