Note: the kc-prompt-input element handles the full attach UX automatically — this story shows how to wire the Solid primitives manually if you need full control.
);
},
};
const SUGGESTION_GROUPS = [
{ label: 'Get started', items: ['Summarize this document', 'What are the key takeaways?', 'Create an outline'] },
{ label: 'Go deeper', items: ['Compare with similar approaches', 'What are the tradeoffs?', 'Find contradictions'] },
];
const FULL_MODELS: ModelOption[] = [
{ id: 'claude-4-opus', name: 'Claude 4 Opus', provider: 'Anthropic' },
{ id: 'claude-4-sonnet', name: 'Claude 4 Sonnet', provider: 'Anthropic' },
{ id: 'gemini-2', name: 'Gemini 2.5 Pro', provider: 'Google' },
];
export const StoppableStreaming: Story = {
name: 'Stoppable / Stop Button (kc-prompt-input)',
render: () => {
const [loading, setLoading] = createSignal(false);
let timer: ReturnType | undefined;
const handleSubmit = () => {
setLoading(true);
// Simulate a 3-second stream. In production: store the AbortController from
// your fetch() call and call controller.abort() from onStop instead.
timer = setTimeout(() => setLoading(false), 3000);
};
const handleStop = () => {
clearTimeout(timer);
setLoading(false);
};
return (
The Solid primitive equivalent of stoppable on kc-prompt-input:
when loading is true, the send button is replaced by a Stop button (square icon).
Clicking Stop fires kc-stop — your handler calls controller.abort()
then clears the loading flag. Press Submit to start the simulated 3-second stream.
{}}
>
}
>
Element usage: <kc-prompt-input stoppable loading> then listen for
{' '}kc-stop to call controller.abort().
);
},
};
export const FullExample: Story = {
name: 'Full Example',
render: () => {
const [value, setValue] = createSignal('');
const [modelId, setModelId] = createSignal('claude-4-opus');
const [streaming, setStreaming] = createSignal(false);
let abortRef: ReturnType | undefined;
const handleSubmit = () => {
if (!value().trim()) return;
setStreaming(true);
setValue('');
// Simulate a streaming reply that finishes after 3 s.
// In production: store the AbortController from your fetch() call here,
// then call controller.abort() from the Stop button handler instead.
abortRef = setTimeout(() => setStreaming(false), 3000);
};
const handleStop = () => {
clearTimeout(abortRef);
setStreaming(false);
};
return (
Production-ready composer: model switcher, grouped suggestions, streaming state with Stop,
and a send button that enables once you type. Submit → 3-second simulated stream → idle.