Rewrote all the docs - more noob friendly now.
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
+66
-62
@@ -1,37 +1,28 @@
|
||||
# Select
|
||||
|
||||
A styled `<select>` dropdown. Supports a pre-selected value, optional label, and optional description text. HTMX attributes can be added.
|
||||
A styled dropdown that lets the user pick one option from a list. Use it for things like country selection, category filters, or anything where the user chooses from a fixed set of values.
|
||||
|
||||
---
|
||||
|
||||
## HTML structure
|
||||
## Quick example
|
||||
|
||||
```
|
||||
div.flex.flex-col.gap-1.5
|
||||
label[for={id}].text-sm.font-medium ← omitted when label is empty
|
||||
{label}
|
||||
select[id, name, class, $$HxAttrs$$]
|
||||
option[value, $$Selected$$] ← one per option; selected="selected" when matched
|
||||
{display}
|
||||
p.text-sm.text-muted-foreground ← omitted when description is empty
|
||||
{description}
|
||||
```csharp
|
||||
new Select(
|
||||
id: "country",
|
||||
name: "country",
|
||||
label: "Country",
|
||||
options: new[]
|
||||
{
|
||||
("us", "United States"),
|
||||
("gb", "United Kingdom"),
|
||||
("ca", "Canada"),
|
||||
},
|
||||
selectedValue: "us")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## CSS mechanics
|
||||
|
||||
| Class | Effect |
|
||||
|---|---|
|
||||
| `flex h-10 w-full rounded-md border border-input bg-background` | Full-width 40px select field |
|
||||
| `px-3 py-2 text-sm` | Inner padding and text size |
|
||||
| `focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring` | Keyboard focus ring |
|
||||
| `disabled:cursor-not-allowed disabled:opacity-50` | Disabled state |
|
||||
| `bg-background` | Ensures the dropdown matches the page background in dark mode |
|
||||
|
||||
---
|
||||
|
||||
## Constructor signature
|
||||
## All the options
|
||||
|
||||
```csharp
|
||||
public Select(
|
||||
@@ -45,59 +36,72 @@ public Select(
|
||||
string hxAttrs = "")
|
||||
```
|
||||
|
||||
| Parameter | Description |
|
||||
| Parameter | What it does |
|
||||
|---|---|
|
||||
| `id` | Element id and label `for` target |
|
||||
| `options` | List of `(Value, Display)` tuples |
|
||||
| `selectedValue` | Pre-selected option value; `null` = no pre-selection (first option shown) |
|
||||
| `name` | Form field name |
|
||||
| `label` | Optional visible label |
|
||||
| `description` | Optional helper text below the field |
|
||||
| `extraClasses` | Additional Tailwind classes on the `<select>` element |
|
||||
| `hxAttrs` | Verbatim HTMX / data attributes |
|
||||
| `id` | The element id. Also used by the `<label for="...">`. |
|
||||
| `options` | The list of choices. Each is a `(Value, Display)` tuple. |
|
||||
| `selectedValue` | The `Value` of the option to pre-select. Leave `null` to show the first option. |
|
||||
| `name` | Form field name — required if you want the value submitted. |
|
||||
| `label` | Visible text label above the dropdown. |
|
||||
| `description` | Small hint text below the field. |
|
||||
| `extraClasses` | Additional Tailwind classes on the `<select>` element. |
|
||||
| `hxAttrs` | Extra HTML attributes appended verbatim — use for HTMX and `data-*`. |
|
||||
|
||||
---
|
||||
|
||||
## Usage examples
|
||||
## Real-world examples
|
||||
|
||||
### Country selector
|
||||
### Category filter that reloads the list on change
|
||||
|
||||
```csharp
|
||||
new Select(
|
||||
id: "country",
|
||||
name: "country",
|
||||
label: "Country",
|
||||
id: "category",
|
||||
name: "category",
|
||||
label: "Filter by category",
|
||||
options: categories.Select(c => (c.Slug, c.Name)),
|
||||
selectedValue: currentCategory,
|
||||
hxAttrs: """hx-get="/products" hx-target="#product-list" hx-trigger="change"""")
|
||||
```
|
||||
|
||||
### Dynamic options from the database (with current value pre-selected)
|
||||
|
||||
```csharp
|
||||
var options = roles.Select(r => (r.Id.ToString(), r.Name));
|
||||
|
||||
new Select(
|
||||
id: "role",
|
||||
name: "roleId",
|
||||
label: "Role",
|
||||
options: options,
|
||||
selectedValue: user.RoleId.ToString())
|
||||
```
|
||||
|
||||
Reading on the server:
|
||||
|
||||
```csharp
|
||||
public record Command([property: FromForm] string RoleId);
|
||||
```
|
||||
|
||||
### Simple yes/no choice
|
||||
|
||||
```csharp
|
||||
new Select(
|
||||
id: "active",
|
||||
name: "isActive",
|
||||
label: "Status",
|
||||
options: new[]
|
||||
{
|
||||
("us", "United States"),
|
||||
("gb", "United Kingdom"),
|
||||
("ca", "Canada"),
|
||||
("au", "Australia"),
|
||||
("true", "Active"),
|
||||
("false", "Inactive"),
|
||||
},
|
||||
selectedValue: "us")
|
||||
selectedValue: user.IsActive ? "true" : "false")
|
||||
```
|
||||
|
||||
### Dynamic options from data
|
||||
---
|
||||
|
||||
```csharp
|
||||
var options = categories.Select(c => (c.Slug, c.Name));
|
||||
## How it works
|
||||
|
||||
new Select(
|
||||
id: "category",
|
||||
name: "category",
|
||||
label: "Category",
|
||||
options: options,
|
||||
selectedValue: existingCategory)
|
||||
```
|
||||
|
||||
### HTMX on-change reload
|
||||
|
||||
```csharp
|
||||
new Select(
|
||||
id: "region",
|
||||
name: "region",
|
||||
label: "Region",
|
||||
options: regions,
|
||||
Select renders a standard `<select>` element — no custom dropdown JavaScript. The browser's native dropdown is used, which is the most accessible and reliable approach. The selected option is matched by `Value` and has `selected="selected"` set on render.
|
||||
hxAttrs: """hx-get="/cities" hx-target="#city-select" hx-trigger="change" hx-include="[name='region']"""")
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user