@jpgilldev / steid

1.4 KBRaw
1use topcoat::{
2 Result,
3 view::{Attributes, class, component, view},
4};
5
6/// The classes for the [`input`] control.
7///
8/// The height, text size, radius, shadow, and focus ring match the `Md`
9/// button, so an input and a button sit flush in a row. File inputs restyle
10/// the browser's upload button into quiet, borderless text.
11const INPUT: &str = "h-9 w-full min-w-0 rounded-lg border border-border bg-background px-3 \
12 text-sm shadow-xs transition-colors outline-none \
13 placeholder:text-muted-foreground \
14 file:mr-3 file:h-full file:border-0 file:bg-transparent file:text-sm file:font-medium \
15 focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 \
16 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50";
17
18/// A text input component.
19///
20/// The `attrs` (such as `type`, `name`, `placeholder`, `disabled`, or event
21/// handlers) are forwarded to the underlying `<input>`; a `class` among them
22/// is appended to the computed classes. The input fills its container, so
23/// size it through the container or with a width class.
24///
25/// ```ignore
26/// view! {
27/// input(attrs: attributes! { type="email" placeholder="you@example.com" })
28/// }
29/// ```
30#[component]
31pub async fn input(#[default] mut attrs: Attributes) -> Result {
32 view! { <input class=(class!(INPUT, attrs.remove("class"))) (attrs)> }
33}