# Prompt

Import: `import { Prompt } from '@neo4j-ndl/react/ai'`

## Props

### Prompt

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `bottomContent` | `ReactNode` |  |  | Content to display below the textarea, on the leading side |
| `bottomTrailingContent` | `ReactNode` |  |  | Content to display below the textarea, on the trailing side next to the submit button |
| `disclaimer` | `ReactNode` |  | `All information should be verified.` | Disclaimer to display below the component |
| `headerContent` | `ReactNode` |  |  | Content to display above the input card, e.g. a status message while a prompt is running |
| `isDisabled` | `boolean` |  | `false` | Whether the textarea is disabled |
| `isRunningPrompt` | `boolean` |  | `false` | Whether the submit button is "running". Shows a stop icon when true. |
| `isSubmitDisabled` | `boolean` |  | `false` | Whether the submit button is disabled |
| `maxRows` | `number` |  | `5` | Maximum number of rows the textarea can expand to |
| `onCancelPrompt` | `((e: MouseEvent<HTMLButtonElement, MouseEvent>) => void)` |  |  | Callback function called when the cancel button is clicked |
| `onChange` | `((e: ChangeEvent<HTMLTextAreaElement, Element>) => void)` |  |  | Callback function called when the prompt text changes |
| `onSubmitPrompt` | `((e: KeyboardEvent<HTMLTextAreaElement> \| MouseEvent<HTMLButtonElement, MouseEvent>) => void)` |  |  | Callback function called when the submit button is clicked |
| `ref` | `Ref<HTMLDivElement>` |  |  | A ref to apply to the root element. |
| `textareaProps` | `HtmlAttributes<"textarea">` |  |  | Props for the textarea element |
| `topContent` | `ReactNode` |  |  | Content to display above the textarea |
| `value` | `string \| number \| readonly string[]` |  |  | The prompt text |

### Prompt.ContextTag

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `children` | `string` |  |  |  |
| `onClose` | `() => void` | ✅ |  |  |

### Prompt.Select

| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| `onChange` | `(option: { label: ReactNode; value: string; }) => void` | ✅ |  |  |
| `options` | `{ label: ReactNode; value: string; }[]` |  | `[]` |  |
| `value` | `{ label: ReactNode; value: string; }` | ✅ |  |  |

## Examples

### Default

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { CleanIconButton } from '@neo4j-ndl/react';
import { Prompt } from '@neo4j-ndl/react/ai';
import { PlusIconOutline } from '@neo4j-ndl/react/icons';
import { useState } from 'react';

const Component = () => {
  const [prompt, setPrompt] = useState('');
  const [isRunningPrompt, setIsRunningPrompt] = useState(false);

  const handleSubmitPrompt = () => {
    setIsRunningPrompt(true);
    alert(`You submitted the following prompt: ${prompt}`);
    setPrompt('');
  };

  return (
    <Prompt
      isRunningPrompt={isRunningPrompt}
      value={prompt}
      onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) =>
        setPrompt(e.target.value)
      }
      onSubmitPrompt={handleSubmitPrompt}
      onCancelPrompt={() => setIsRunningPrompt(false)}
      bottomContent={
        <CleanIconButton description="Add files" size="small">
          <PlusIconOutline />
        </CleanIconButton>
      }
    />
  );
};

export default Component;
```

### Advanced

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { CleanIconButton } from '@neo4j-ndl/react';
import { FileTag, ImageTag, Prompt } from '@neo4j-ndl/react/ai';
import { DocumentIconOutline, PlusIconOutline } from '@neo4j-ndl/react/icons';
import { useState } from 'react';

const Component = () => {
  const [isRunningPrompt, setIsRunningPrompt] = useState(false);
  const options: Array<{ label: React.ReactNode; value: string }> = [
    { label: 'Neo4j AI', value: 'neo4j' },
    { label: 'Special Agent', value: 'special-agent' },
    { label: 'Another Agent', value: 'another-agent' },
  ];
  const [selectedOption, setSelectedOption] = useState(options[0]);
  const [prompt, setPrompt] = useState('');

  const handleSubmitPrompt = () => {
    setIsRunningPrompt(true);
    alert(`You submitted the following prompt: ${prompt}`);
    setPrompt('');
  };

  return (
    <Prompt
      isRunningPrompt={isRunningPrompt}
      value={prompt}
      onChange={(e) => setPrompt(e.target.value)}
      onSubmitPrompt={handleSubmitPrompt}
      onCancelPrompt={() => setIsRunningPrompt(false)}
      topContent={
        <>
          <FileTag
            isLoading={true}
            icon={<DocumentIconOutline />}
            fileName="Science Fiction Bestsellers"
            fileType="pdf"
            isRemovable={true}
            onClick={() => {
              console.info('remove file');
            }}
          />
          <ImageTag
            isLoading={true}
            src="https://plus.unsplash.com/premium_photo-1676496046182-356a6a0ed002?q=80&w=2952&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
            alt="Landscape image"
            fileName="Landscape image"
            fileType="jpg"
            isRemovable={true}
            onClick={() => {
              console.info('remove image');
            }}
          />
          <FileTag
            icon={<DocumentIconOutline />}
            fileName="Science Fiction Bestsellers"
            fileType="pdf"
            isRemovable={true}
            onClick={() => {
              console.info('remove file');
            }}
          />
          <ImageTag
            src="https://plus.unsplash.com/premium_photo-1676496046182-356a6a0ed002?q=80&w=2952&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
            alt="Landscape image"
            fileName="Landscape image"
            fileType="jpg"
            isRemovable={true}
            onClick={() => {
              console.info('remove image');
            }}
          />
        </>
      }
      bottomContent={
        <>
          <CleanIconButton description="Add stuff" size="small">
            <PlusIconOutline />
          </CleanIconButton>
        </>
      }
      bottomTrailingContent={
        <Prompt.Select
          value={selectedOption}
          options={options}
          onChange={setSelectedOption}
        />
      }
    />
  );
};

export default Component;
```

### Context

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { CleanIconButton } from '@neo4j-ndl/react';
import { Prompt } from '@neo4j-ndl/react/ai';
import { PlusIconOutline } from '@neo4j-ndl/react/icons';
import { useState } from 'react';

const Component = () => {
  const [prompt, setPrompt] = useState('');
  const [isRunningPrompt, setIsRunningPrompt] = useState(false);

  const handleSubmitPrompt = () => {
    setIsRunningPrompt(true);
    alert(`You submitted the following prompt: ${prompt}`);
    setPrompt('');
  };

  return (
    <Prompt
      isRunningPrompt={isRunningPrompt}
      value={prompt}
      onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) =>
        setPrompt(e.target.value)
      }
      onSubmitPrompt={handleSubmitPrompt}
      onCancelPrompt={() => setIsRunningPrompt(false)}
      topContent={
        <>
          <Prompt.ContextTag
            onClose={() => {
              alert('remove node label context');
            }}
          >
            Node label
          </Prompt.ContextTag>
          <Prompt.ContextTag
            onClose={() => {
              alert('remove cypher query context');
            }}
          >
            Cypher query
          </Prompt.ContextTag>
          <Prompt.ContextTag
            onClose={() => {
              alert('remove long context');
            }}
          >
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do
            eiusmod tempor incididunt ut labore et dolore magna aliqua.
          </Prompt.ContextTag>
        </>
      }
      bottomContent={
        <CleanIconButton description="Add files" size="small">
          <PlusIconOutline />
        </CleanIconButton>
      }
    />
  );
};

export default Component;
```

### Disabled

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { CleanIconButton } from '@neo4j-ndl/react';
import { Prompt } from '@neo4j-ndl/react/ai';
import { PlusIconOutline } from '@neo4j-ndl/react/icons';
import { useState } from 'react';

const Component = () => {
  const [prompt, _setPrompt] = useState<string>('');

  return (
    <Prompt
      value={prompt}
      isDisabled={true}
      isSubmitDisabled={true}
      bottomContent={
        <CleanIconButton description="Add files" size="small" isDisabled={true}>
          <PlusIconOutline />
        </CleanIconButton>
      }
    />
  );
};

export default Component;
```

### Header

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { CleanIconButton, TextButton, Typography } from '@neo4j-ndl/react';
import { Prompt } from '@neo4j-ndl/react/ai';
import { PlusIconOutline } from '@neo4j-ndl/react/icons';
import { useState } from 'react';

const Component = () => {
  const [prompt, setPrompt] = useState('');
  const [isRunningPrompt, setIsRunningPrompt] = useState(false);

  const handleSubmitPrompt = () => {
    setIsRunningPrompt(true);
    setPrompt('');
  };

  return (
    <Prompt
      isRunningPrompt={isRunningPrompt}
      value={prompt}
      onChange={(e: React.ChangeEvent<HTMLTextAreaElement>) =>
        setPrompt(e.target.value)
      }
      onSubmitPrompt={handleSubmitPrompt}
      onCancelPrompt={() => setIsRunningPrompt(false)}
      headerContent={
        <>
          <Typography variant="body-medium">
            We would like your feedback
          </Typography>
          <TextButton
            size="small"
            style={{ marginLeft: 'auto' }}
            onClick={() => alert('Thanks for the feedback!')}
          >
            Give feedback
          </TextButton>
        </>
      }
      bottomContent={
        <CleanIconButton description="Add files" size="small">
          <PlusIconOutline />
        </CleanIconButton>
      }
    />
  );
};

export default Component;
```

### Loading

```tsx
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';

import { CleanIconButton } from '@neo4j-ndl/react';
import { Prompt } from '@neo4j-ndl/react/ai';
import { PlusIconOutline } from '@neo4j-ndl/react/icons';
import { useState } from 'react';

const Component = () => {
  const [isRunningPrompt, setIsRunningPrompt] = useState(true);

  return (
    <Prompt
      isRunningPrompt={isRunningPrompt}
      onSubmitPrompt={() => setIsRunningPrompt(true)}
      onCancelPrompt={() => setIsRunningPrompt(false)}
      bottomContent={
        <CleanIconButton description="Add files" size="small">
          <PlusIconOutline />
        </CleanIconButton>
      }
    />
  );
};

export default Component;
```
