PettyUI/packages/showcase/src/sections/inputs-basic.tsx
Mats Bosson 8761d317ae All 44 component demos
Layout & Display, Inputs Basic, Inputs Selection, Inputs Advanced,
Navigation, Overlays, Feedback & Status, and Data sections with
live interactive demos for every PettyUI component.
2026-03-30 03:36:22 +07:00

117 lines
5.6 KiB
TypeScript

import { Button } from "pettyui/button";
import { TextField } from "pettyui/text-field";
import { NumberField } from "pettyui/number-field";
import { Checkbox } from "pettyui/checkbox";
import { Switch } from "pettyui/switch";
import { Toggle } from "pettyui/toggle";
import { ComponentDemo } from "../component-demo";
/** Button demo with primary, secondary, ghost, disabled variants. */
const ButtonDemo = () => (
<div class="flex items-center gap-3">
<Button class="px-4 py-2 text-sm font-medium rounded bg-indigo-600 text-white hover:bg-indigo-700">Primary</Button>
<Button class="px-4 py-2 text-sm font-medium rounded border border-gray-300 hover:bg-gray-50">Secondary</Button>
<Button class="px-4 py-2 text-sm font-medium rounded text-indigo-600 hover:bg-indigo-50">Ghost</Button>
<Button disabled class="px-4 py-2 text-sm font-medium rounded bg-gray-100 text-gray-400 cursor-not-allowed">Disabled</Button>
</div>
);
/** TextField demo with label, description, and error state. */
const TextFieldDemo = () => (
<div class="flex gap-6">
<TextField class="flex flex-col gap-1">
<TextField.Label class="text-sm font-medium text-gray-700">Name</TextField.Label>
<TextField.Input placeholder="Enter your name" class="border border-gray-300 rounded px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500" />
<TextField.Description class="text-xs text-gray-400">Your full name</TextField.Description>
</TextField>
<TextField validationState="invalid" class="flex flex-col gap-1">
<TextField.Label class="text-sm font-medium text-red-600">Email</TextField.Label>
<TextField.Input value="not-an-email" class="border border-red-300 rounded px-3 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-red-500" />
<TextField.ErrorMessage class="text-xs text-red-500">Invalid email address</TextField.ErrorMessage>
</TextField>
</div>
);
/** NumberField demo with increment and decrement buttons. */
const NumberFieldDemo = () => (
<NumberField defaultValue={5} min={0} max={100} class="flex flex-col gap-1">
<NumberField.Label class="text-sm font-medium text-gray-700">Quantity</NumberField.Label>
<div class="flex items-center gap-1">
<NumberField.DecrementTrigger class="w-8 h-8 flex items-center justify-center border border-gray-300 rounded hover:bg-gray-50 text-sm">-</NumberField.DecrementTrigger>
<NumberField.Input class="w-16 text-center border border-gray-300 rounded px-2 py-1 text-sm focus:outline-none focus:ring-2 focus:ring-indigo-500" />
<NumberField.IncrementTrigger class="w-8 h-8 flex items-center justify-center border border-gray-300 rounded hover:bg-gray-50 text-sm">+</NumberField.IncrementTrigger>
</div>
</NumberField>
);
/** Checkbox demo with checked and unchecked states. */
const CheckboxDemo = () => (
<div class="flex flex-col gap-3">
<Checkbox class="flex items-center gap-2 cursor-pointer">
{(state) => (
<>
<div class={`w-4 h-4 border rounded flex items-center justify-center text-xs ${state.checked() ? "bg-indigo-600 border-indigo-600 text-white" : "border-gray-300"}`}>
{state.checked() ? "✓" : ""}
</div>
<span class="text-sm text-gray-700">Accept terms and conditions</span>
</>
)}
</Checkbox>
<Checkbox defaultChecked class="flex items-center gap-2 cursor-pointer">
{(state) => (
<>
<div class={`w-4 h-4 border rounded flex items-center justify-center text-xs ${state.checked() ? "bg-indigo-600 border-indigo-600 text-white" : "border-gray-300"}`}>
{state.checked() ? "✓" : ""}
</div>
<span class="text-sm text-gray-700">Subscribe to newsletter</span>
</>
)}
</Checkbox>
</div>
);
/** Switch demo with on/off toggle. */
const SwitchDemo = () => (
<Switch class="flex items-center gap-3 cursor-pointer">
{(state) => (
<>
<div class={`w-10 h-6 rounded-full relative transition-colors ${state.checked() ? "bg-indigo-600" : "bg-gray-300"}`}>
<div class={`absolute top-0.5 w-5 h-5 rounded-full bg-white shadow transition-transform ${state.checked() ? "translate-x-4" : "translate-x-0.5"}`} />
</div>
<span class="text-sm text-gray-700">{state.checked() ? "On" : "Off"}</span>
</>
)}
</Switch>
);
/** Toggle demo with pressed/unpressed states. */
const ToggleDemo = () => (
<Toggle class="px-3 py-1.5 text-sm border rounded transition-colors data-[pressed]:bg-indigo-100 data-[pressed]:text-indigo-700 data-[pressed]:border-indigo-300 border-gray-300 hover:bg-gray-50">
Bold
</Toggle>
);
/** Inputs Basic section with fundamental input components. */
export const InputsBasicSection = () => (
<>
<ComponentDemo name="Button" description="Clickable element that triggers an action">
<ButtonDemo />
</ComponentDemo>
<ComponentDemo name="TextField" description="Text input field with label, description, and error message support">
<TextFieldDemo />
</ComponentDemo>
<ComponentDemo name="NumberField" description="Numeric input with increment/decrement buttons and keyboard support">
<NumberFieldDemo />
</ComponentDemo>
<ComponentDemo name="Checkbox" description="Toggle control for boolean input, supports indeterminate state">
<CheckboxDemo />
</ComponentDemo>
<ComponentDemo name="Switch" description="Toggle control for on/off states, visually distinct from checkbox">
<SwitchDemo />
</ComponentDemo>
<ComponentDemo name="Toggle" description="Two-state button that can be toggled on or off">
<ToggleDemo />
</ComponentDemo>
</>
);