import type { Meta, StoryObj } from '@storybook/react-vite' import { useRef, useState } from 'react' import { FieldLine } from './Field' import { InlineText, type InlineTextHandle } from './InlineText' /** * A page's title and the line under it, edited where they stand. Click into * either and type: no box, nothing moves. Enter saves and goes on down the * page; Escape or clicking away saves too. */ const meta = { title: 'Primitives/InlineText', component: InlineText, parameters: { layout: 'padded' }, decorators: [ (Story) => (
), ], } satisfies Meta export default meta type Story = StoryObj const LINE = 'A line of plain text under the title, saying in a sentence what this is about.' const LONG = 'A line of plain text under the title that goes on for longer than a line should, so it wraps the way the text around it does and the reader sees all of it, without anything cut off at the edge or hidden behind a control.' /** A title, the line under it, and the text below: Enter in the title goes to the line, Enter in the line goes to the text. */ function Page({ title = 'Item one', line = LINE, refuse = false, readOnly = false }: { title?: string; line?: string; refuse?: boolean; readOnly?: boolean }) { const lineRef = useRef(null) const textRef = useRef(null) const [saved, setSaved] = useState({ title, line }) const [refused, setRefused] = useState(false) return (
(setSaved((s) => ({ ...s, title: next })), true)} onEnter={() => lineRef.current?.focus('start')} /> text !== null && setRefused(false)} onCommit={(next) => { if (refuse) { setRefused(true) return false } setSaved((s) => ({ ...s, line: next })) return true }} onEnter={() => textRef.current?.focus()} /> {refused && Not saved: the change was refused. Your text is still here.}

The text of the page starts here. Nothing above it moves while you write in the title or the line under it.

) } export const Default: Story = { render: () => } /** Nothing written yet: what each is for, muted, in its place. */ export const Empty: Story = { render: () => } /** A long line wraps like the text around it. */ export const Long: Story = { render: () => } /** The save is refused: the text stays where you wrote it, and the app says why under it. */ export const Refused: Story = { render: () => } /** Someone who cannot change it: the same text, in the same place. */ export const ReadOnly: Story = { render: () => }