mirror of
https://github.com/hunvreus/basecoat.git
synced 2026-11-11 04:38:18 +00:00
297 lines
15 KiB
Plaintext
297 lines
15 KiB
Plaintext
# Select
|
|
|
|
<Preview>
|
|
<div id="select-demo" class="select" data-placeholder="Select a fruit">
|
|
<button type="button" class="w-[180px]" id="select-demo-trigger" aria-haspopup="listbox" aria-expanded="false" aria-controls="select-demo-listbox">
|
|
<span class="truncate">Select a fruit</span>
|
|
<svg 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-chevron-down text-muted-foreground opacity-50 shrink-0"><path d="m6 9 6 6 6-6" /></svg>
|
|
</button>
|
|
<div id="select-demo-popover" data-popover aria-hidden="true">
|
|
<div role="listbox" id="select-demo-listbox" aria-orientation="vertical" aria-labelledby="select-demo-trigger">
|
|
<div role="group" aria-labelledby="select-demo-fruits">
|
|
<span role="heading" id="select-demo-fruits">Fruits</span>
|
|
<div role="option" data-value="apple">Apple</div>
|
|
<div role="option" data-value="banana">Banana</div>
|
|
<div role="option" data-value="blueberry">Blueberry</div>
|
|
<div role="option" data-value="grapes">Grapes</div>
|
|
<div role="option" data-value="pineapple">Pineapple</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<input type="hidden" name="select-demo-value" value="" />
|
|
</div>
|
|
</Preview>
|
|
|
|
## Usage
|
|
|
|
<Callout title="Template macros available" icon="code" action={{ label: "More", href: "/templates#select" }}>
|
|
This component ships a `select()` macro for Jinja and Nunjucks.
|
|
</Callout>
|
|
|
|
<Steps>
|
|
<Step title="Include CSS">
|
|
|
|
Import Tailwind and one full Basecoat style bundle.
|
|
|
|
```css
|
|
@import "tailwindcss";
|
|
@import "basecoat-css/vega.css";
|
|
```
|
|
|
|
Or import only the base CSS, Select component CSS, and one style pack.
|
|
|
|
```css
|
|
@import "tailwindcss";
|
|
@import "basecoat-css/base.css";
|
|
@import "basecoat-css/components/select.css";
|
|
@import "basecoat-css/styles/vega.css";
|
|
```
|
|
|
|
Using CDN or bundler imports? See the [Installation page](/installation).
|
|
|
|
</Step>
|
|
<Step title="Include JavaScript">
|
|
|
|
Copy or serve the full Basecoat JavaScript bundle.
|
|
|
|
```html
|
|
<script src="/assets/js/all.min.js" defer></script>
|
|
```
|
|
|
|
Or copy or serve the Basecoat runtime and Select script.
|
|
|
|
```html
|
|
<script src="/assets/js/basecoat.min.js" defer></script>
|
|
<script src="/assets/js/select.min.js" defer></script>
|
|
```
|
|
|
|
Using CDN or bundler imports? See the [Installation page](/installation).
|
|
|
|
</Step>
|
|
<Step title="Add your select HTML">
|
|
|
|
```html
|
|
<div id="select-theme" class="select" data-placeholder="Theme">
|
|
<button type="button" class="w-[180px]" id="select-theme-trigger" aria-haspopup="listbox" aria-expanded="false" aria-controls="select-theme-listbox">
|
|
<span class="truncate">Theme</span>
|
|
<svg 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-chevron-down text-muted-foreground opacity-50 shrink-0"><path d="m6 9 6 6 6-6" /></svg>
|
|
</button>
|
|
<div id="select-theme-popover" data-popover aria-hidden="true">
|
|
<div role="listbox" id="select-theme-listbox" aria-orientation="vertical" aria-labelledby="select-theme-trigger">
|
|
<div role="option" data-value="light">Light</div>
|
|
<div role="option" data-value="dark">Dark</div>
|
|
<div role="option" data-value="system">System</div>
|
|
</div>
|
|
</div>
|
|
<input type="hidden" name="theme" value="" />
|
|
</div>
|
|
```
|
|
|
|
</Step>
|
|
</Steps>
|
|
|
|
### HTML structure
|
|
|
|
<dl>
|
|
<dt><code><div class="select"></code></dt>
|
|
<dd>
|
|
Select root. Add <code>data-placeholder</code> to show placeholder text when no value is selected. Supports <code>data-close-on-select="true"</code> for multiple select and <code>data-format="object"</code> for serialized object values.
|
|
<dl>
|
|
<dt><code><button type="button"></code></dt>
|
|
<dd>Trigger button. Use <code>aria-haspopup="listbox"</code>, <code>aria-expanded</code>, and <code>aria-controls</code>.</dd>
|
|
<dt><code><div data-popover aria-hidden="true"></code></dt>
|
|
<dd>
|
|
Popover content. Supports <code>data-side</code> and <code>data-align</code> through the shared Popover rules.
|
|
<dl>
|
|
<dt><code><div role="listbox"></code></dt>
|
|
<dd>
|
|
Options container. Add <code>aria-multiselectable="true"</code> for multiple selection.
|
|
<dl>
|
|
<dt><code><div role="option" data-value="..." data-label="..."></code></dt>
|
|
<dd>Selectable option. <code>data-value</code> is submitted. <code>data-label</code> is optional and controls the selected display label and <code>data-format="object"</code> label; when omitted, Basecoat uses trimmed text content.</dd>
|
|
<dt><code><hr role="separator"></code> <span class="badge" data-variant="secondary">Optional</span></dt>
|
|
<dd>Separator between groups or options.</dd>
|
|
<dt><code><div role="group"></code> <span class="badge" data-variant="secondary">Optional</span></dt>
|
|
<dd>Option group. Use <code>aria-labelledby</code> to connect it to its heading.</dd>
|
|
<dt><code><span role="heading"></code> <span class="badge" data-variant="secondary">Optional</span></dt>
|
|
<dd>Group heading.</dd>
|
|
</dl>
|
|
</dd>
|
|
</dl>
|
|
</dd>
|
|
<dt><code><input type="hidden"></code></dt>
|
|
<dd>Submitted value. Empty value means no selection when the root has <code>data-placeholder</code>. Single select stores a string; multiple select stores a JSON array. With <code>data-format="object"</code>, values are serialized as <code>{ value, label }</code> objects.</dd>
|
|
</dl>
|
|
</dd>
|
|
</dl>
|
|
|
|
### JavaScript API
|
|
|
|
| API | Type | Description |
|
|
| --- | --- | --- |
|
|
| `change` | Event | Dispatched on selection changes with `event.detail.value` and `event.detail.selected`. |
|
|
| `select.refresh()` | Method | Rescans options after children change inside the existing `role="listbox"` element. |
|
|
|
|
## Examples
|
|
|
|
### Groups
|
|
|
|
<Preview>
|
|
<div id="select-groups" class="select" data-placeholder="Select a fruit">
|
|
<button type="button" class="w-[180px]" id="select-groups-trigger" aria-haspopup="listbox" aria-expanded="false" aria-controls="select-groups-listbox">
|
|
<span class="truncate">Select a fruit</span>
|
|
<svg 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-chevron-down text-muted-foreground opacity-50 shrink-0"><path d="m6 9 6 6 6-6" /></svg>
|
|
</button>
|
|
<div id="select-groups-popover" data-popover aria-hidden="true">
|
|
<div role="listbox" id="select-groups-listbox" aria-orientation="vertical" aria-labelledby="select-groups-trigger">
|
|
<div role="group" aria-labelledby="select-groups-fruits">
|
|
<span role="heading" id="select-groups-fruits">Fruits</span>
|
|
<div role="option" data-value="apple">Apple</div>
|
|
<div role="option" data-value="banana">Banana</div>
|
|
<div role="option" data-value="blueberry">Blueberry</div>
|
|
</div>
|
|
<hr role="separator" />
|
|
<div role="group" aria-labelledby="select-groups-vegetables">
|
|
<span role="heading" id="select-groups-vegetables">Vegetables</span>
|
|
<div role="option" data-value="carrot">Carrot</div>
|
|
<div role="option" data-value="broccoli">Broccoli</div>
|
|
<div role="option" data-value="spinach">Spinach</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<input type="hidden" name="select-groups-value" value="" />
|
|
</div>
|
|
</Preview>
|
|
|
|
### Scrollable
|
|
|
|
A select with many items that scrolls.
|
|
|
|
<Preview>
|
|
<div id="select-scrollable" class="select" data-placeholder="Select a timezone">
|
|
<button type="button" class="w-[280px]" id="select-scrollable-trigger" aria-haspopup="listbox" aria-expanded="false" aria-controls="select-scrollable-listbox">
|
|
<span class="truncate">Select a timezone</span>
|
|
<svg 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-chevron-down text-muted-foreground opacity-50 shrink-0"><path d="m6 9 6 6 6-6" /></svg>
|
|
</button>
|
|
<div id="select-scrollable-popover" data-popover aria-hidden="true">
|
|
<div role="listbox" id="select-scrollable-listbox" class="scrollbar-sm max-h-70 overflow-y-auto" aria-orientation="vertical" aria-labelledby="select-scrollable-trigger">
|
|
<div role="group" aria-labelledby="select-scrollable-north-america">
|
|
<span role="heading" id="select-scrollable-north-america">North America</span>
|
|
<div role="option" data-value="est">Eastern Standard Time (EST)</div>
|
|
<div role="option" data-value="cst">Central Standard Time (CST)</div>
|
|
<div role="option" data-value="mst">Mountain Standard Time (MST)</div>
|
|
<div role="option" data-value="pst">Pacific Standard Time (PST)</div>
|
|
<div role="option" data-value="akst">Alaska Standard Time (AKST)</div>
|
|
<div role="option" data-value="hst">Hawaii Standard Time (HST)</div>
|
|
</div>
|
|
<div role="group" aria-labelledby="select-scrollable-europe-africa">
|
|
<span role="heading" id="select-scrollable-europe-africa">Europe & Africa</span>
|
|
<div role="option" data-value="gmt">Greenwich Mean Time (GMT)</div>
|
|
<div role="option" data-value="cet">Central European Time (CET)</div>
|
|
<div role="option" data-value="eet">Eastern European Time (EET)</div>
|
|
<div role="option" data-value="west">Western European Summer Time (WEST)</div>
|
|
<div role="option" data-value="cat">Central Africa Time (CAT)</div>
|
|
<div role="option" data-value="eat">East Africa Time (EAT)</div>
|
|
</div>
|
|
<div role="group" aria-labelledby="select-scrollable-asia">
|
|
<span role="heading" id="select-scrollable-asia">Asia</span>
|
|
<div role="option" data-value="msk">Moscow Time (MSK)</div>
|
|
<div role="option" data-value="ist">India Standard Time (IST)</div>
|
|
<div role="option" data-value="cst_china">China Standard Time (CST)</div>
|
|
<div role="option" data-value="jst">Japan Standard Time (JST)</div>
|
|
<div role="option" data-value="kst">Korea Standard Time (KST)</div>
|
|
<div role="option" data-value="ist_indonesia">Indonesia Central Standard Time (WITA)</div>
|
|
</div>
|
|
<div role="group" aria-labelledby="select-scrollable-australia-pacific">
|
|
<span role="heading" id="select-scrollable-australia-pacific">Australia & Pacific</span>
|
|
<div role="option" data-value="awst">Australian Western Standard Time (AWST)</div>
|
|
<div role="option" data-value="acst">Australian Central Standard Time (ACST)</div>
|
|
<div role="option" data-value="aest">Australian Eastern Standard Time (AEST)</div>
|
|
<div role="option" data-value="nzst">New Zealand Standard Time (NZST)</div>
|
|
<div role="option" data-value="fjt">Fiji Time (FJT)</div>
|
|
</div>
|
|
<div role="group" aria-labelledby="select-scrollable-south-america">
|
|
<span role="heading" id="select-scrollable-south-america">South America</span>
|
|
<div role="option" data-value="art">Argentina Time (ART)</div>
|
|
<div role="option" data-value="bot">Bolivia Time (BOT)</div>
|
|
<div role="option" data-value="brt">Brasilia Time (BRT)</div>
|
|
<div role="option" data-value="clt">Chile Standard Time (CLT)</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<input type="hidden" name="select-scrollable-value" value="" />
|
|
</div>
|
|
</Preview>
|
|
|
|
### Disabled
|
|
|
|
<Preview>
|
|
<div id="select-disabled" class="select" data-placeholder="Select a fruit">
|
|
<button type="button" class="w-[180px]" id="select-disabled-trigger" aria-haspopup="listbox" aria-expanded="false" aria-controls="select-disabled-listbox" disabled>
|
|
<span class="truncate">Select a fruit</span>
|
|
<svg 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-chevron-down text-muted-foreground opacity-50 shrink-0"><path d="m6 9 6 6 6-6" /></svg>
|
|
</button>
|
|
<div id="select-disabled-popover" data-popover aria-hidden="true">
|
|
<div role="listbox" id="select-disabled-listbox" aria-orientation="vertical" aria-labelledby="select-disabled-trigger">
|
|
<div role="option" data-value="apple">Apple</div>
|
|
<div role="option" data-value="banana">Banana</div>
|
|
<div role="option" data-value="blueberry">Blueberry</div>
|
|
<div role="option" data-value="grapes" aria-disabled="true">Grapes</div>
|
|
<div role="option" data-value="pineapple">Pineapple</div>
|
|
</div>
|
|
</div>
|
|
<input type="hidden" name="select-disabled-value" value="" />
|
|
</div>
|
|
</Preview>
|
|
|
|
### Invalid
|
|
|
|
<Preview>
|
|
<div class="field" data-invalid="true">
|
|
<label for="select-invalid-trigger">Fruit</label>
|
|
<div id="select-invalid" class="select" data-placeholder="Select a fruit">
|
|
<button type="button" class="w-[180px]" id="select-invalid-trigger" aria-haspopup="listbox" aria-expanded="false" aria-controls="select-invalid-listbox" aria-invalid="true">
|
|
<span class="truncate">Select a fruit</span>
|
|
<svg 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-chevron-down text-muted-foreground opacity-50 shrink-0"><path d="m6 9 6 6 6-6" /></svg>
|
|
</button>
|
|
<div id="select-invalid-popover" data-popover aria-hidden="true">
|
|
<div role="listbox" id="select-invalid-listbox" aria-orientation="vertical" aria-labelledby="select-invalid-trigger">
|
|
<div role="option" data-value="apple">Apple</div>
|
|
<div role="option" data-value="banana">Banana</div>
|
|
<div role="option" data-value="blueberry">Blueberry</div>
|
|
<div role="option" data-value="grapes">Grapes</div>
|
|
<div role="option" data-value="pineapple">Pineapple</div>
|
|
</div>
|
|
</div>
|
|
<input type="hidden" name="fruit" value="" />
|
|
</div>
|
|
<p role="alert">Please select a valid fruit.</p>
|
|
</div>
|
|
</Preview>
|
|
|
|
### RTL
|
|
|
|
<Preview>
|
|
<div dir="rtl">
|
|
<div id="select-rtl" class="select" data-placeholder="اختر فاكهة">
|
|
<button type="button" class="w-[180px]" id="select-rtl-trigger" aria-haspopup="listbox" aria-expanded="false" aria-controls="select-rtl-listbox">
|
|
<span class="truncate">اختر فاكهة</span>
|
|
<svg 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-chevron-down text-muted-foreground opacity-50 shrink-0"><path d="m6 9 6 6 6-6" /></svg>
|
|
</button>
|
|
<div id="select-rtl-popover" data-popover aria-hidden="true">
|
|
<div role="listbox" id="select-rtl-listbox" aria-orientation="vertical" aria-labelledby="select-rtl-trigger">
|
|
<div role="group" aria-labelledby="select-rtl-fruits">
|
|
<span role="heading" id="select-rtl-fruits">الفواكه</span>
|
|
<div role="option" data-value="apple">تفاح</div>
|
|
<div role="option" data-value="banana">موز</div>
|
|
<div role="option" data-value="blueberry">توت أزرق</div>
|
|
<div role="option" data-value="grapes">عنب</div>
|
|
<div role="option" data-value="pineapple">أناناس</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<input type="hidden" name="select-rtl-value" value="" />
|
|
</div>
|
|
</div>
|
|
</Preview>
|