/* * (c) Copyright 2026 Palantir Technologies Inc. All rights reserved. */ import type { Meta, StoryObj } from "@storybook/react-vite"; import { storybookLayoutDecorator } from "@storybook-common"; import { type ChangeEvent, useCallback, useState } from "react"; import { Flex } from "@blueprintjs/labs"; import { Intent, Size } from "../../common"; import { Button } from "../button/buttons"; import { Tag } from "../tag/tag"; import { InputGroup } from "./inputGroup"; const meta: Meta = { title: "Core/Form/Inputs/InputGroup", component: InputGroup, decorators: [storybookLayoutDecorator], tags: ["autodocs"], args: { intent: "none", size: "medium", placeholder: "Enter text...", disabled: false, readOnly: false, fill: false, round: false, }, argTypes: { intent: { control: "select", options: Object.values(Intent), }, size: { control: "select", options: Object.values(Size), }, placeholder: { control: "text", }, disabled: { control: "boolean", }, readOnly: { control: "boolean", }, fill: { control: "boolean", }, round: { control: "boolean", }, leftIcon: { control: "text", }, onChange: { action: "changed" }, // deprecated props large: { table: { disable: true } }, small: { table: { disable: true } }, }, } satisfies Meta; export default meta; type Story = StoryObj; /** * A basic input group with default styling. */ export const Default: Story = {}; /** * Use the `intent` prop to apply a semantic color that conveys the purpose or status of the input. */ export const IntentExample: Story = { name: "Intent", argTypes: { intent: { table: { disable: true } }, }, render: args => ( {Object.values(Intent).map(intent => ( ))} ), }; /** * Use the `size` prop to adjust the input dimensions. */ export const SizeExample: Story = { name: "Size", argTypes: { size: { table: { disable: true } }, }, render: args => ( {Object.values(Size).map(size => ( ))} ), }; /** * InputGroup supports `disabled` and `readOnly` states. */ export const StateExample: Story = { name: "State", argTypes: { disabled: { table: { disable: true } }, readOnly: { table: { disable: true } }, }, render: args => ( ), }; /** * Use `leftIcon`, `leftElement`, and `rightElement` to add content around the input. */ export const IconExample: Story = { name: "Icons", argTypes: { leftIcon: { table: { disable: true } }, }, render: args => ( } placeholder="Password..." type="password" /> ), }; /** * Use `leftElement`, and `rightElement` to add content around the input. */ export const LeftRightElementsExample: Story = { name: "Left & Right Elements", argTypes: { leftElement: { table: { disable: true } }, rightElement: { table: { disable: true } }, }, render: args => ( Left} placeholder="Search..." /> Left} rightElement={Right} placeholder="Search..." /> Right} placeholder="With right element..." /> ), }; /** * Use the `round` prop to render the input with rounded caps. */ export const RoundExample: Story = { name: "Round", argTypes: { round: { table: { disable: true } }, }, render: args => ( ), }; /** * Use the `fill` prop to make the input expand to the full width of its container. */ export const FillExample: Story = { name: "Fill", argTypes: { fill: { table: { disable: true } }, }, decorators: [ Story => (
), ], render: args => ( ), }; /** * An input in the focused state, showing the focus ring. Use controls to change the intent. */ export const FocusedExample: Story = { name: "Focused", play: async ({ canvas, userEvent }) => { const input = canvas.getByPlaceholderText("Click to focus..."); await userEvent.click(input); }, render: args => , }; /** * Interactive playground with all props togglable via Storybook controls. */ export const Playground: Story = { render: function Render(args) { const [value, setValue] = useState(""); const handleChange = useCallback( (e: ChangeEvent) => { setValue(e.target.value); args.onChange?.(e); }, [args], ); const handleClear = useCallback(() => setValue(""), []); return ( 0 ? (