This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Input
|
||||
|
||||
Form input component with icons, password toggle, and validation. Use `Label()` and `Tooltip()` as wrappers for label and tooltip functionality.
|
||||
Form input component with icons, password toggle, and validation.
|
||||
|
||||
## Tag
|
||||
|
||||
@@ -13,11 +13,9 @@ Form input component with icons, password toggle, and validation. Use `Label()`
|
||||
| `type` | `string` | `'text'` | Input type (text, password, email, number, date) |
|
||||
| `value` | `string \| Signal<string>` | `''` | Input value |
|
||||
| `placeholder` | `string` | `' '` | Placeholder text |
|
||||
| `icon` | `string \| VNode \| Signal` | `-` | Icon displayed inside input |
|
||||
| `disabled` | `boolean \| Signal<boolean>` | `false` | Disabled state |
|
||||
| `class` | `string` | `''` | Additional CSS classes (DaisyUI + Tailwind) |
|
||||
| `oninput` | `function` | `-` | Input event handler |
|
||||
| `validate` | `function` | `-` | Validation function returning error message |
|
||||
|
||||
## Styling
|
||||
|
||||
@@ -36,18 +34,19 @@ Input supports all **daisyUI Input classes**:
|
||||
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title text-sm uppercase opacity-50 mb-4">Live Demo</h3>
|
||||
<div id="demo-basic" class="bg-base-100 p-6 rounded-xl border border-base-300 flex items-center justify-center"></div>
|
||||
<div id="demo-basic" class="bg-base-100 p-6 rounded-xl border border-base-300"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { Input, Mount } = window;
|
||||
|
||||
const BasicDemo = () => {
|
||||
const name = $("");
|
||||
|
||||
return Input({
|
||||
placeholder: "Enter your name",
|
||||
value: name,
|
||||
oninput: (e) => name(e.target.value),
|
||||
oninput: (e) => name(e.target.value)
|
||||
});
|
||||
};
|
||||
Mount(BasicDemo, "#demo-basic");
|
||||
@@ -55,25 +54,29 @@ Mount(BasicDemo, "#demo-basic");
|
||||
|
||||
### With Icon
|
||||
|
||||
Wrap the input inside a `Div` with class `input` and add an icon as a sibling.
|
||||
|
||||
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title text-sm uppercase opacity-50 mb-4">Live Demo</h3>
|
||||
<div id="demo-icon" class="bg-base-100 p-6 rounded-xl border border-base-300 flex items-center justify-center"></div>
|
||||
<div id="demo-icon" class="bg-base-100 p-6 rounded-xl border border-base-300"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { InputLabel, Div, Icon, Mount } = window;
|
||||
|
||||
const IconDemo = () => {
|
||||
const email = $("");
|
||||
|
||||
return Label({ class: "input" }, [
|
||||
return Div({ class: "input input-bordered flex items-center gap-2" }, [
|
||||
Icon("✉️"),
|
||||
Input({
|
||||
class: "grow",
|
||||
Tag("input", {
|
||||
class: "grow",
|
||||
type: "email",
|
||||
value: email,
|
||||
oninput: (e) => email(e.target.value),
|
||||
}),
|
||||
placeholder: "Email",
|
||||
oninput: (e) => email(e.target.value)
|
||||
})
|
||||
]);
|
||||
};
|
||||
Mount(IconDemo, "#demo-icon");
|
||||
@@ -84,30 +87,31 @@ Mount(IconDemo, "#demo-icon");
|
||||
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title text-sm uppercase opacity-50 mb-4">Live Demo</h3>
|
||||
<div id="demo-password" class="bg-base-100 p-6 rounded-xl border border-base-300 flex items-center justify-center"></div>
|
||||
<div id="demo-password" class="bg-base-100 p-6 rounded-xl border border-base-300"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { Input, Div, Icon, Swap, Mount } = window;
|
||||
|
||||
const PasswordDemo = () => {
|
||||
const password = $("");
|
||||
const visible = $(false);
|
||||
|
||||
return Label({ class: "input input-bordered w-full max-w-xs" }, [
|
||||
return Div({ class: "input input-bordered flex items-center gap-2" }, [
|
||||
Icon("icon-[lucide--lock]"),
|
||||
Input({
|
||||
Tag("input", {
|
||||
type: () => (visible() ? "text" : "password"),
|
||||
value: password,
|
||||
placeholder: "Contraseña",
|
||||
placeholder: "Password",
|
||||
class: "grow",
|
||||
oninput: (e) => password(e.target.value),
|
||||
oninput: (e) => password(e.target.value)
|
||||
}),
|
||||
Swap({
|
||||
value: visible,
|
||||
class: "swap-rotate",
|
||||
on: Icon("icon-[lucide--eye]"),
|
||||
off: Icon("icon-[lucide--eye-off]"),
|
||||
}),
|
||||
off: Icon("icon-[lucide--eye-off]")
|
||||
})
|
||||
]);
|
||||
};
|
||||
Mount(PasswordDemo, "#demo-password");
|
||||
@@ -115,93 +119,86 @@ Mount(PasswordDemo, "#demo-password");
|
||||
|
||||
### With Floating Label
|
||||
|
||||
Wrap the input with `Label()` component:
|
||||
Use a wrapper `Div` with class `floating-label`.
|
||||
|
||||
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title text-sm uppercase opacity-50 mb-4">Live Demo</h3>
|
||||
<div id="demo-label" class="bg-base-100 p-6 rounded-xl border border-base-300 flex items-center justify-center"></div>
|
||||
<div id="demo-label" class="bg-base-100 p-6 rounded-xl border border-base-300"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { Input, Div, Span, Mount } = window;
|
||||
|
||||
const LabelDemo = () => {
|
||||
const email = $("");
|
||||
|
||||
return Label({ class: "floating-label" }, [
|
||||
Span("Text floating"),
|
||||
return Div({ class: "floating-label" }, [
|
||||
Span("Email"),
|
||||
Input({
|
||||
type: "email",
|
||||
label: "Email",
|
||||
value: email,
|
||||
placeholder: "Clic here",
|
||||
oninput: (e) => email(e.target.value),
|
||||
}),
|
||||
placeholder: " ",
|
||||
oninput: (e) => email(e.target.value)
|
||||
})
|
||||
]);
|
||||
};
|
||||
Mount(LabelDemo, "#demo-label");
|
||||
```
|
||||
|
||||
### With Tooltip & label
|
||||
### With Tooltip
|
||||
|
||||
Wrap the input with `Tooltip()` component:
|
||||
Wrap the input with `Tooltip` component.
|
||||
|
||||
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title text-sm uppercase opacity-50 mb-4">Live Demo</h3>
|
||||
<div id="demo-tooltip" class="bg-base-100 p-6 rounded-xl border border-base-300 flex items-center justify-center"></div>
|
||||
<div id="demo-tooltip" class="bg-base-100 p-6 rounded-xl border border-base-300"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { Input, Tooltip, Mount } = window;
|
||||
|
||||
const TooltipDemo = () => {
|
||||
const username = $("");
|
||||
|
||||
return Tooltip(
|
||||
{ tip: "Must be at least 3 characters" },
|
||||
Label({ class: "input" }, [
|
||||
Span({ class: "label" }, "User"),
|
||||
Input({
|
||||
value: username,
|
||||
label: "Username",
|
||||
placeholder: "Username",
|
||||
oninput: (e) => username(e.target.value),
|
||||
}),
|
||||
]),
|
||||
);
|
||||
return Tooltip({ tip: "Must be at least 3 characters" }, [
|
||||
Input({
|
||||
placeholder: "Username",
|
||||
value: username,
|
||||
oninput: (e) => username(e.target.value)
|
||||
})
|
||||
]);
|
||||
};
|
||||
Mount(TooltipDemo, "#demo-tooltip");
|
||||
```
|
||||
|
||||
### Error State
|
||||
|
||||
Add `input-error` class and show a validation message.
|
||||
|
||||
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title text-sm uppercase opacity-50 mb-4">Live Demo</h3>
|
||||
<div id="demo-error" class="bg-base-100 p-6 rounded-xl border border-base-300 flex items-center justify-center"></div>
|
||||
<div id="demo-error" class="bg-base-100 p-6 rounded-xl border border-base-300"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { Input, Div, Mount } = window;
|
||||
|
||||
const ErrorDemo = () => {
|
||||
const email = $("");
|
||||
|
||||
return Div({ class: "form-control w-full max-w-xs" }, [
|
||||
Label({ class: "label" }, Span({ class: "label-text" }, "Email")),
|
||||
Div({ class: "relative w-full" }, [
|
||||
Input({
|
||||
type: "email",
|
||||
value: email,
|
||||
placeholder: "mail@site.com",
|
||||
class: "input input-bordered w-full pl-10 validator",
|
||||
required: true,
|
||||
oninput: (e) => email(e.target.value)
|
||||
}),
|
||||
Span({ class: "absolute left-3 top-1/2 -translate-y-1/2 text-base-content/60" },
|
||||
Icon("icon-[lucide--mail]")
|
||||
)
|
||||
]),
|
||||
Div({ class: "validator-hint hidden" }, "Enter a valid email address")
|
||||
const isValid = () => email().includes("@");
|
||||
return Div({ class: "flex flex-col gap-2" }, [
|
||||
Tag("input", {
|
||||
type: "email",
|
||||
class: () => `input input-bordered ${email() && !isValid() ? "input-error" : ""}`,
|
||||
value: email,
|
||||
placeholder: "mail@example.com",
|
||||
oninput: (e) => email(e.target.value)
|
||||
}),
|
||||
() => email() && !isValid() ? Div({ class: "text-error text-sm" }, "Enter a valid email") : null
|
||||
]);
|
||||
};
|
||||
Mount(ErrorDemo, "#demo-error");
|
||||
@@ -212,16 +209,15 @@ Mount(ErrorDemo, "#demo-error");
|
||||
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title text-sm uppercase opacity-50 mb-4">Live Demo</h3>
|
||||
<div id="demo-disabled" class="bg-base-100 p-6 rounded-xl border border-base-300 flex items-center justify-center"></div>
|
||||
<div id="demo-disabled" class="bg-base-100 p-6 rounded-xl border border-base-300"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { Input, Mount } = window;
|
||||
|
||||
const DisabledDemo = () => {
|
||||
return Input({
|
||||
value: "john.doe",
|
||||
disabled: true,
|
||||
});
|
||||
return Input({ value: "john.doe", disabled: true });
|
||||
};
|
||||
Mount(DisabledDemo, "#demo-disabled");
|
||||
```
|
||||
@@ -231,38 +227,27 @@ Mount(DisabledDemo, "#demo-disabled");
|
||||
<div class="card bg-base-200 border border-base-300 shadow-sm my-6">
|
||||
<div class="card-body">
|
||||
<h3 class="card-title text-sm uppercase opacity-50 mb-4">Live Demo</h3>
|
||||
<div id="demo-variants" class="bg-base-100 p-6 rounded-xl border border-base-300 flex flex-col gap-4"></div>
|
||||
<div id="demo-variants" class="bg-base-100 p-6 rounded-xl border border-base-300"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
```javascript
|
||||
```js
|
||||
const { Input, Div, Mount } = window;
|
||||
|
||||
const VariantsDemo = () => {
|
||||
const text = $("");
|
||||
const number = $(0);
|
||||
|
||||
return Div({ class: "flex flex-col gap-4" }, [
|
||||
Input({
|
||||
placeholder: "Type something...",
|
||||
value: text,
|
||||
oninput: (e) => text(e.target.value),
|
||||
}),
|
||||
Input({
|
||||
type: "number",
|
||||
value: number,
|
||||
oninput: (e) => number(parseInt(e.target.value) || 0),
|
||||
}),
|
||||
Input({
|
||||
type: "date",
|
||||
value: $("2024-01-01"),
|
||||
}),
|
||||
Input({ class: "input-primary", value: "Primary" }),
|
||||
Input({ class: "input-secondary", value: "Secondary" }),
|
||||
Input({ class: "input-accent", value: "Accent" }),
|
||||
Input({ class: "input-ghost", value: "Ghost" }),
|
||||
Input({ class: "input-info", value: "Info" }),
|
||||
Input({ class: "input-success", value: "Success" }),
|
||||
Input({ class: "input-warning", value: "Warning" }),
|
||||
Input({ class: "input-error", value: "Error" }),
|
||||
Input({ placeholder: "Default", value: text, oninput: (e) => text(e.target.value) }),
|
||||
Input({ class: "input-primary", placeholder: "Primary", value: $("") }),
|
||||
Input({ class: "input-secondary", placeholder: "Secondary", value: $("") }),
|
||||
Input({ class: "input-accent", placeholder: "Accent", value: $("") }),
|
||||
Input({ class: "input-ghost", placeholder: "Ghost", value: $("") }),
|
||||
Input({ class: "input-info", placeholder: "Info", value: $("") }),
|
||||
Input({ class: "input-success", placeholder: "Success", value: $("") }),
|
||||
Input({ class: "input-warning", placeholder: "Warning", value: $("") }),
|
||||
Input({ class: "input-error", placeholder: "Error", value: $("") }),
|
||||
Input({ type: "number", placeholder: "Number", value: $(0), oninput: (e) => e.target.value }),
|
||||
Input({ type: "date", value: $("2024-01-01") })
|
||||
]);
|
||||
};
|
||||
Mount(VariantsDemo, "#demo-variants");
|
||||
|
||||
Reference in New Issue
Block a user