ContextInput
A rich text input component with context-aware suggestions, mentions, and inline editing capabilities
Installation
Terminal
Import
Component.tsx
Basic
Basic: Simple context input with user mentions using @ trigger.
- Type @ to search and mention users
- Arrow keys navigation and Enter/Tab to select
- Returns structured data with text and mention metadata
- Real-time search filtering
```tsx
const [value, setValue] = useState({ text: "", mentions: [] })
<ContextInput
value={value}
placeholder="Type @ to mention someone..."
triggers={[{
char: "@",
onSearch: async (query) => {
return users.filter(user =>
user.label.toLowerCase().includes(query.toLowerCase())
)
}
}]}
onChange={setValue}
onMentionSelect={(mention, trigger) => {
console.log("Selected:", mention, trigger)
}}
/>
```
Disabled
Disabled: Shows context input in disabled state.
- All interactions are prevented
- Visual styling indicates disabled state
- Useful for read-only scenarios or conditional editing
```tsx
<ContextInput
disabled
value={value}
placeholder="This input is disabled..."
triggers={triggers}
onChange={setValue}
/>
```
Read Only
ReadOnly: Demonstrates the ContextInput component in readOnly mode.
- Prevents value changes while allowing focus and selection
- Maintains normal visual appearance (unlike disabled)
- Useful for displaying non-editable context input information
Variants
Variants: Demonstrates different visual variants of the context input component.
- default: Follows the page theme dynamically (light/dark mode)
- light: Fixed light appearance regardless of theme
- dark: Fixed dark appearance regardless of theme
- reset: Removes variant styling, no Variant settings applied
```tsx
<ContextInput
variant="default" // Adapts to current theme
value={value}
placeholder="Type @ to mention..."
triggers={triggers}
onChange={setValue}
/>
```
Large Size
Large: Context input with large size variant.
- Increased padding and font size
- Better for prominent input areas
- More comfortable for extended typing
```tsx
<ContextInput
size="large"
value={value}
placeholder="Large size input..."
triggers={triggers}
onChange={setValue}
/>
```
Min Height
MinHeight: Context input with custom minimum height.
- Set minHeight prop to control initial height
- Useful for ensuring consistent layout
- Input will grow beyond minHeight if needed
```tsx
<ContextInput
minHeight={128}
size="large"
value={value}
placeholder="Min height 128px..."
triggers={triggers}
onChange={setValue}
/>
```
With Header
WithHeader: Context input with custom header section.
- Header section automatically inherits size prop
- Useful for titles, actions, or additional controls
- Header content can include buttons and text
```tsx
<ContextInput value={value} onChange={setValue}>
<ContextInput.Header>
<h3>Header Title</h3>
<IconButton>
<ExpandSmall />
</IconButton>
</ContextInput.Header>
</ContextInput>
```
Header
Max Length
MaxLength: Context input with character limit enforcement.
- Set maxLength prop to limit input characters
- Prevents typing/pasting beyond the limit
- Character count display shows current/max length
- Visual indicator when approaching limit
```tsx
<ContextInput
maxLength={100}
value={value}
onChange={setValue}
>
<ContextInput.Footer>
<span className={value.text.length === 100 ? "text-red-500" : ""}>
{value.text.length}/100
</span>
</ContextInput.Footer>
</ContextInput>
```
0/100
Max Suggestions
MaxSuggestions: Context input with limited suggestion count.
- Set maxSuggestions prop to limit displayed options
- Useful for keeping suggestion lists manageable
- Search results are truncated to the specified limit
```tsx
<ContextInput
maxSuggestions={3}
value={value}
placeholder="Max 3 suggestions"
triggers={triggers}
onChange={setValue}
/>
```
Multiple Triggers
MultipleTriggers: Context input with multiple mention triggers.
- Use @ to mention users and / to mention channels
- Different search functions for each trigger type
- Demonstrates versatile mention system
- Use arrow keys to navigate suggestions
- Press Enter or Tab to select
```tsx
<ContextInput
value={value}
placeholder="Try @ for users, / for channels..."
triggers={[
{
char: "@",
onSearch: async (query) => searchUsers(query)
},
{
char: "/",
onSearch: async (query) => searchChannels(query)
}
]}
onChange={setValue}
/>
```
Custom Mention Prefix
CustomMentionPrefix: Demonstrates customizable mention prefix.
- Use # instead of @ for mentions display
- Configurable via mentionPrefix prop
- Supports any string as prefix (e.g., "+", "~", "#", etc.)
- Useful for different contexts like hashtags or custom notations
- Mentions will appear as `#JohnDoe` instead of `@JohnDoe`
```tsx
<ContextInput
mentionPrefix="#"
placeholder="Type @ to mention with # prefix..."
triggers={[
{
char: "@",
onSearch: async (query) => searchUsers(query)
}
]}
/>
```
Clear Function Test
ClearFunctionTest: Test the clear function of the context input.
- Click the clear button to clear the input
- The input should be cleared and the value should be an empty object
- Demonstrates programmatic clearing of content and mentions
```tsx
const handleClear = () => {
setValue({ text: "", mentions: [] })
}
```
Controlled Value
ControlledValue: Context input with external value control.
- Demonstrates controlled value state management
- External buttons can modify input content and mentions
- Shows programmatic content insertion and clearing
- Auto-focuses editor when value changes externally (when autoFocus is enabled)
- Cursor always moves to end position after value changes
- Useful for form integration and external state management
- Real-time character and mention counts
- Preset content examples for quick testing
- Full bidirectional data binding
```tsx
const [value, setValue] = useState<ContextInputValue>({ text: "", mentions: [] })
<ContextInput
value={value}
autoFocus
onChange={setValue}
triggers={triggers}
/>
<Button onClick={() => setValue({ text: "Hello world!", mentions: [] })}>
Set Content
</Button>
```
Value Control Buttons
Dynamic Actions
Characters: 0Mentions: 0
Custom Mention Component
CustomMentionComponent: Example showing how to use customMentionComponent for customization.
- Create custom Mention component with different styling
- Custom component has gradient background and emoji decoration
- Passed via `customMentionComponent` prop
- Receives same props as default Mention component
- Useful for branding or visual differentiation
```tsx
const CustomMention = (props) => {
const { attributes, children, element, mentionPrefix } = props
return (
<span {...attributes} contentEditable={false} className="custom-styles">
{children}
{mentionPrefix}{element.mentionLabel}
</span>
)
}
<ContextInput customMentionComponent={CustomMention} />
```
Imperative Focus
ImperativeFocus: Demonstrates how to programmatically focus the input using ref.
- Use ref to get access to the focus method
- Call ref.current.focus() to focus the input from outside
- Useful for keyboard shortcuts or external button triggers
```tsx
const inputRef = useRef<ContextInputRef>(null)
<ContextInput ref={inputRef} />
<Button onClick={() => inputRef.current?.focus()}>
Focus Input
</Button>
```
API reference
| ContextInputHeader | Type | Default |
|---|---|---|
className | string |undefined | - |
handleClick | (() => void) |undefined | - |
size | undefined |"default" |"large" | - |
ref | ((instance: HTMLDivElement |null) => void) |RefObject<HTMLDivElement> |null |undefined | - |
| ContextInputFooter | Type | Default |
className | string |undefined | - |
handleClick | (() => void) |undefined | - |
size | undefined |"default" |"large" | - |
ref | ((instance: HTMLDivElement |null) => void) |RefObject<HTMLDivElement> |null |undefined | - |
| CopyButton | Type | Default |
className | string |undefined | - |
size | undefined |"default" |"reset" |"large" | - |
disabled | boolean |undefined | false |
onClick | ((copiedText: string) => void) |undefined | - |
as | ElementType<any, keyof IntrinsicElements> |undefined | - |
readOnly | boolean |undefined | - |
active | boolean |undefined | - |
asChild | boolean |undefined | - |
focused | boolean |undefined | - |
loading | boolean |undefined | - |
tooltip | TooltipProps |undefined | - |
variant | undefined |"default" |"dark" |"reset" |"secondary" |"solid" |"highlight" |"ghost" |"submit" | - |
successDuration | number |undefined | 2000 |
ref | ((instance: HTMLElement |null) => void) |RefObject<HTMLElement> |null |undefined | - |
| MentionMenu | Type | Default |
disabled | boolean |undefined | - |
onSelect | (mention: ContextMentionItemProps, index: number) => void | - |
loading | boolean | - |
isOpen | boolean | - |
onClose | () => void | - |
position | MentionMenuPosition |null | - |
renderSuggestion | ((item: ContextMentionItemProps, isSelected: boolean) => ReactNode) |undefined | - |
root | HTMLElement |null |undefined | - |
suggestions | ContextMentionItemProps[] | - |
ref | ((instance: MentionMenuRef |null) => void) |RefObject<MentionMenuRef> |null |undefined | - |
| SlateEditor | Type | Default |
className | string |undefined | - |
size | "default" |"large" | - |
disabled | boolean |undefined | false |
maxLength | number |undefined | - |
placeholder | string |undefined | Type someone... |
readOnly | boolean |undefined | false |
autoFocus | boolean |undefined | false |
onCompositionEnd | ((event: CompositionEvent<Element>) => void) |undefined | - |
onCompositionStart | ((event: CompositionEvent<Element>) => void) |undefined | - |
onFocus | (() => void) |undefined | - |
onBlur | (() => void) |undefined | - |
onChange | (value: Descendant[]) => void | - |
onKeyDown | (event: KeyboardEvent<Element>) => void | - |
variant | undefined |"default" |"light" |"dark" |"reset" | default |
renderMention | ((mention: MentionMatch) => ReactNode) |undefined | - |
mentionPrefix | string |undefined | - |
customMentionComponent | ComponentType<ContextMentionProps> |undefined | - |
editor | ReactEditor | - |
footer | ReactNode | - |
hasFooter | boolean | - |
hasHeader | boolean | - |
minHeight | number | 80 |
slateValue | Descendant[] | - |
ref | ((instance: HTMLDivElement |null) => void) |RefObject<HTMLDivElement> |null |undefined | - |
| ContextMentionElement | Type | Default |
mentionPrefix | string |undefined | - |
renderMention | ((mention: MentionMatch) => ReactNode) |undefined | - |
variant | undefined |"default" |"light" |"dark" |"reset" | - |
| useMentions | Type | Default |
editor | ContextEditor | - |
maxSuggestions | number |undefined | 10 |
mentionPrefix | string |undefined | @ |
onMentionSelect | ((mention: ContextMentionItemProps, trigger: string) => void) |undefined | - |
onSearchClose | (() => void) |undefined | - |
triggers | ContextMentionTrigger[] | - |
| useContextInput | Type | Default |
autoFocus | boolean |undefined | - |
editor | ContextEditor |undefined | - |
onChange | ((value: ContextInputValue) => void) |undefined | - |
value | ContextInputValue |undefined | - |