1.4 KBRaw
| 1 | use 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. |
| 11 | const 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] |
| 31 | pub async fn input(#[default] mut attrs: Attributes) -> Result { |
| 32 | view! { <input class=(class!(INPUT, attrs.remove("class"))) (attrs)> } |
| 33 | } |