import type { Meta, StoryObj } from '@storybook/react-vite'
import { useState } from 'react'
import { EditableText } from './EditableText'
const meta = {
title: 'Inputs/EditableText',
component: EditableText,
args: {
value: 'Team charter',
placeholder: 'Add a title',
label: 'Title',
onCommit: () => true as boolean,
className: 'text-body-1 font-medium',
},
argTypes: { onCommit: { control: false } },
decorators: [(Story) =>
{Story()}
],
} satisfies Meta
export default meta
type Story = StoryObj
/** Click the text: it becomes a field. Enter commits, Escape cancels, blur commits. */
export const Title: Story = {
parameters: { controls: { disable: true } },
render: (args) => {
const [value, setValue] = useState(args.value)
return (
{
setValue(next)
return true
}}
/>
)
},
}
/** Shift+Enter is a new line; Enter still commits. */
export const Multiline: Story = {
args: {
value: 'A longer piece of text.\nIt keeps its lines.',
placeholder: 'Add a description',
label: 'Description',
multiline: true,
className: 'text-body-2',
},
}
/** Empty shows the placeholder, muted — still clickable. */
export const Empty: Story = {
args: { value: '' },
// axe color-contrast is off here until PLAN.md stage 0.10 is ruled:
// the placeholder is muted text, 3.94:1 on --bg-base in signal (AA 4.5:1).
parameters: { a11y: { config: { rules: [{ id: 'color-contrast', enabled: false }] } } },
}
/** For a reader who cannot write: the value alone, no edit affordance. */
export const ReadOnly: Story = { args: { readOnly: true } }
/**
* A commit that resolves `false` keeps the field open with the text in it —
* an edit is never silently lost. Try committing anything here.
*/
export const RefusedCommit: Story = {
args: { onCommit: () => false },
}