import type { Meta, StoryObj } from 'storybook-solidjs-vite'; import { fn } from 'storybook/test'; import { createSignal } from 'solid-js'; import { PromptInput, PromptInputTextarea, PromptInputActions } from './prompt-input'; import { Button } from '../ui/button'; import { componentDescription } from '../stories/docs/element-controls'; const meta = { title: 'Solid (Advanced)/Elements/PromptInput', component: PromptInput, tags: ['autodocs'], parameters: { layout: 'padded', docs: { controls: { exclude: ['use:eventListener'] }, description: componentDescription([ 'A composer shell that hosts an auto-resizing `PromptInputTextarea` and a `PromptInputActions` toolbar, with controlled or uncontrolled value, loading, and disabled states.', '**When to use:** as the message input at the bottom of any chat surface, wherever the user types and submits a prompt.', '**How to use:** control text via `value` + `onValueChange` (or leave uncontrolled), wire `onSubmit` (also fired on Enter without Shift), and place your send/stop controls inside `PromptInputActions`. Toggle `isLoading` / `disabled` for in-flight and read-only states.', '**Placement:** pinned at the bottom of the chat column, below the message transcript.', ]), }, }, argTypes: { value: { control: 'text', description: 'Controlled text value of the textarea.', }, isLoading: { control: 'boolean', description: 'Marks a response as in-flight (e.g. to show a Stop action).', table: { defaultValue: { summary: 'false' } }, }, disabled: { control: 'boolean', description: 'Disables the textarea and dims the composer.', table: { defaultValue: { summary: 'false' } }, }, maxHeight: { control: 'number', description: 'Max auto-resize height in px (or a CSS length string) before the textarea scrolls.', table: { defaultValue: { summary: '240' } }, }, onValueChange: { action: 'valueChange', description: 'Fired with the new text whenever the textarea value changes.', table: { category: 'Events' }, }, onSubmit: { action: 'submit', description: 'Fired on Enter (without Shift), and wherever you call it from an action.', table: { category: 'Events' }, }, children: { control: false, description: 'Composer contents — usually a textarea plus an actions row.', }, class: { control: 'text', description: 'Extra classes for the composer shell.', }, }, args: { value: '', isLoading: false, disabled: false, maxHeight: 240, onValueChange: fn(), onSubmit: fn(), }, render: (args) => (
), } satisfies Meta; export default meta; type Story = StoryObj; const IMPORT = `import { PromptInput, PromptInputTextarea, PromptInputActions, Button } from '@kitn.ai/chat';`; const src = (code: string) => ({ parameters: { docs: { source: { code: `${IMPORT}\n\n${code}`, language: 'tsx' } } }, }); /** Interactive playground — toggle loading/disabled and edit the value via controls. */ export const Playground: Story = { ...src(` `), }; /** Empty composer with a Send button disabled until there is text. */ export const Default: Story = { render: () => { const [value, setValue] = createSignal(''); return (
); }, ...src(` `), }; /** Pre-filled with a prompt. */ export const WithContent: Story = { render: () => { const [value, setValue] = createSignal('Tell me about SolidJS reactive primitives'); return (
); }, ...src(` `), }; /** Read-only composer — `disabled` dims it and blocks input. */ export const Disabled: Story = { render: () => (
{}}>
), ...src(` `), }; /** In-flight — `isLoading` typically pairs with a Stop action. */ export const Loading: Story = { render: () => (
{}}>
), ...src(` `), }; /** A split actions row — a leading icon control and a trailing Send (showcase). */ export const WithMultipleActions: Story = { render: () => { const [value, setValue] = createSignal(''); return (
); }, ...src(` `), };