Dropdown Menu
Displays a menu to the user—such as a set of actions or functions—triggered by a button. Supports submenus, checkable items, radio groups, and full keyboard navigation.
Features
Can be controlled or uncontrolled. Supports submenus with configurable reading direction. Supports items, labels, groups of items. Supports checkable items (single or multiple) with optional indeterminate state. Supports modal and non-modal modes. Customize side, alignment, offsets, collision handling. Optionally render a pointing arrow. Focus is fully managed. Full keyboard navigation. Typeahead support. Dismissing and layering behavior is highly customizable.
Installation
Install the component from your command line.
ng g @ng-cn/core:c dropdown-menuAnatomy
Import all parts and piece them together.
import {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuLabel,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuCheckboxItem,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuSeparator,
DropdownMenuShortcut,
DropdownMenuSub,
DropdownMenuSubTrigger,
DropdownMenuSubContent,
DropdownMenuPortal
} from '@/ui/dropdown-menu';<DropdownMenu>
<DropdownMenuTrigger>Open</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuItem>Action</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuLabel>Group Label</DropdownMenuLabel>
<DropdownMenuGroup>
<DropdownMenuItem>Sub Action</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuCheckboxItem checked={true}>
Checkbox Item
</DropdownMenuCheckboxItem>
<DropdownMenuRadioGroup value="option1">
<DropdownMenuRadioItem value="option1">
Radio Option 1
</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
<DropdownMenuSub>
<DropdownMenuSubTrigger>Submenu</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuItem>Sub Item</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
</DropdownMenuContent>
</DropdownMenu>API Reference
Root
Contains all the parts of a dropdown menu.
| Prop | Type | Default |
|---|---|---|
| open | boolean | — |
| The controlled open state of the dropdown menu. Use with (openChange). | ||
| defaultOpen | boolean | false |
| The open state when the dropdown menu is initially rendered. Use when you do not need to control its open state. | ||
| modal | boolean | true |
| When true, the menu operates in modal mode (prevents interaction outside). When false, allows interaction with other elements. | ||
| dir | 'ltr' | 'rtl' | — |
| The reading direction of the dropdown menu when its content overflows. Defaults to inheriting from the document. |
Data Attributes
| Attribute | Values |
|---|---|
| [data-state] | "open" | "closed" |
Trigger
The button that toggles the dropdown menu. By default, the DropdownMenuContent will position itself against the trigger.
| Prop | Type | Default |
|---|---|---|
| asChild | boolean | false |
| Change the default rendered element for the one passed as a child, merging their props and behavior. |
Data Attributes
| Attribute | Values |
|---|---|
| [data-state] | "open" | "closed" |
| [data-disabled] | Present when disabled |
Portal
When used, portals the content part into the body. This is useful for avoiding stacking context issues.
| Prop | Type | Default |
|---|---|---|
| forceMount | boolean | — |
| Used to force mounting when more control is needed. | ||
| container | HTMLElement | document.body |
| The element to portal into. Defaults to the body. |
Content
The component that pops out when the dropdown menu is open.
| Prop | Type | Default |
|---|---|---|
| asChild | boolean | false |
| Change the default rendered element for the one passed as a child, merging their props and behavior. | ||
| loop | boolean | false |
| When true, keyboard navigation will loop from last item to first, and vice versa. | ||
| side | 'top' | 'right' | 'bottom' | 'left' | 'bottom' |
| The preferred side of the trigger to render against. | ||
| sideOffset | number | 0 |
| The distance in pixels from the trigger to the content. | ||
| align | 'start' | 'center' | 'end' | 'start' |
| The preferred alignment against the trigger. May change when collisions occur. | ||
| alignOffset | number | 0 |
| An offset in pixels from the start or end alignment option. | ||
| avoidCollisions | boolean | true |
| When true, overrides the side and align preferences to avoid collisions with boundary edges. | ||
| collisionBoundary | Element | null | Element[] | [] |
| Element used to calculate available space. By default uses the viewport. Pass null to disable boundary checks. | ||
| collisionPadding | number | Partial<Record<Side, number>> | 0 |
| The distance in pixels from the boundary edges where collision detection should occur. | ||
| arrowPadding | number | 0 |
| The padding between the arrow and the edges of the content. If your content has border-radius, this will prevent it from overflowing the corners. | ||
| sticky | 'partial' | 'always' | 'partial' |
| The sticky behavior of the content. "partial" will keep the content in the viewport as the user scrolls. | ||
| hideWhenDetached | boolean | false |
| When true, hides the content when the trigger becomes hidden. | ||
| forceMount | boolean | — |
| Used to force mounting when more control is needed. | ||
| class | string | — |
| Additional CSS classes to apply to the content. |
Data Attributes
| Attribute | Values |
|---|---|
| [data-state] | "open" | "closed" |
| [data-side] | "left" | "right" | "bottom" | "top" |
| [data-align] | "start" | "end" | "center" |
| [data-orientation] | "vertical" | "horizontal" |
CSS Variables
| Variable | Description |
|---|---|
| --radix-dropdown-menu-content-transform-origin | The transform-origin computed from the content and arrow positions/offsets. |
| --radix-dropdown-menu-content-available-width | The remaining width between the trigger and the boundary edge. |
| --radix-dropdown-menu-content-available-height | The remaining height between the trigger and the boundary edge. |
| --radix-dropdown-menu-trigger-width | The width of the trigger. |
| --radix-dropdown-menu-trigger-height | The height of the trigger. |
Item
The component that contains the dropdown menu items.
| Prop | Type | Default |
|---|---|---|
| asChild | boolean | false |
| Change the default rendered element for the one passed as a child, merging their props and behavior. | ||
| disabled | boolean | — |
| When true, prevents the user from interacting with this item. | ||
| onSelect | (event: Event) => void | — |
| Callback fired when the user selects the item. | ||
| textValue | string | — |
| Optional text used for typeahead purposes. By default the typeahead will use the .textContent of the item. | ||
| class | string | — |
| Additional CSS classes to apply to the item. |
Data Attributes
| Attribute | Values |
|---|---|
| [data-orientation] | "vertical" | "horizontal" |
| [data-highlighted] | Present when highlighted |
| [data-disabled] | Present when disabled |
Group
Used to group multiple DropdownMenuItems.
| Prop | Type | Default |
|---|---|---|
| asChild | boolean | false |
| Change the default rendered element for the one passed as a child, merging their props and behavior. |
Label
Used to render a label. It won't be focusable using arrow keys. Can be used to describe a group of items.
| Prop | Type | Default |
|---|---|---|
| asChild | boolean | false |
| Change the default rendered element for the one passed as a child, merging their props and behavior. |
CheckboxItem
An item that can be controlled and rendered like a checkbox.
| Prop | Type | Default |
|---|---|---|
| asChild | boolean | false |
| Change the default rendered element for the one passed as a child, merging their props and behavior. | ||
| checked | boolean | 'indeterminate' | — |
| The controlled checked state of the checkbox item. | ||
| onCheckedChange | (checked: boolean | 'indeterminate') => void | — |
| Callback fired when the checked state changes. | ||
| disabled | boolean | — |
| When true, prevents the user from interacting with this item. | ||
| onSelect | (event: Event) => void | — |
| Callback fired when the user selects the item. | ||
| textValue | string | — |
| Optional text used for typeahead purposes. |
Data Attributes
| Attribute | Values |
|---|---|
| [data-state] | "checked" | "unchecked" | "indeterminate" |
| [data-highlighted] | Present when highlighted |
| [data-disabled] | Present when disabled |
RadioGroup
Used to group multiple DropdownMenuRadioItems.
| Prop | Type | Default |
|---|---|---|
| value | string | — |
| The value of the selected radio item. | ||
| onValueChange | (value: string) => void | — |
| Callback fired when the value changes. | ||
| asChild | boolean | false |
| Change the default rendered element for the one passed as a child, merging their props and behavior. |
RadioItem
An item that can be controlled and rendered like a radio.
| Prop | Type | Default |
|---|---|---|
| value * | string | — |
| The value of the radio item. | ||
| asChild | boolean | false |
| Change the default rendered element for the one passed as a child, merging their props and behavior. | ||
| disabled | boolean | — |
| When true, prevents the user from interacting with this item. | ||
| onSelect | (event: Event) => void | — |
| Callback fired when the user selects the item. | ||
| textValue | string | — |
| Optional text used for typeahead purposes. |
Data Attributes
| Attribute | Values |
|---|---|
| [data-state] | "checked" | "unchecked" |
| [data-highlighted] | Present when highlighted |
| [data-disabled] | Present when disabled |
ItemIndicator
Renders when the parent DropdownMenuCheckboxItem or DropdownMenuRadioItem is checked. Can be used as a wrapper for an icon.
| Prop | Type | Default |
|---|---|---|
| asChild | boolean | false |
| Change the default rendered element for the one passed as a child, merging their props and behavior. | ||
| forceMount | boolean | — |
| Used to force mounting when more control is needed. |
Data Attributes
| Attribute | Values |
|---|---|
| [data-state] | "checked" | "unchecked" | "indeterminate" |
Separator
Used to visually separate items in the dropdown menu.
| Prop | Type | Default |
|---|---|---|
| asChild | boolean | false |
| Change the default rendered element for the one passed as a child, merging their props and behavior. |
Shortcut
Used to render keyboard shortcut hints alongside menu items.
| Prop | Type | Default |
|---|---|---|
| class | string | — |
| Additional CSS classes to apply to the shortcut. |
Sub
Contains all the parts of a submenu.
| Prop | Type | Default |
|---|---|---|
| open | boolean | — |
| The controlled open state of the submenu. | ||
| defaultOpen | boolean | — |
| The open state when the submenu is initially rendered. Use when you do not need to control its open state. | ||
| onOpenChange | (open: boolean) => void | — |
| Callback fired when the open state changes. |
SubTrigger
An item that opens a submenu. Must be rendered inside DropdownMenuSub.
| Prop | Type | Default |
|---|---|---|
| asChild | boolean | false |
| Change the default rendered element for the one passed as a child, merging their props and behavior. | ||
| disabled | boolean | — |
| When true, prevents the user from interacting with this item. | ||
| textValue | string | — |
| Optional text used for typeahead purposes. |
Data Attributes
| Attribute | Values |
|---|---|
| [data-state] | "open" | "closed" |
| [data-highlighted] | Present when highlighted |
| [data-disabled] | Present when disabled |
SubContent
The component that pops out when a submenu is open. Must be rendered inside DropdownMenuSub.
| Prop | Type | Default |
|---|---|---|
| asChild | boolean | false |
| Change the default rendered element for the one passed as a child, merging their props and behavior. | ||
| loop | boolean | false |
| When true, keyboard navigation will loop from last item to first, and vice versa. | ||
| sideOffset | number | 0 |
| The distance in pixels from the trigger to the content. | ||
| alignOffset | number | 0 |
| An offset in pixels from the start or end alignment option. | ||
| avoidCollisions | boolean | true |
| When true, overrides the side and align preferences to avoid collisions. | ||
| collisionBoundary | Element | null | Element[] | [] |
| Element used to calculate available space. | ||
| collisionPadding | number | Partial<Record<Side, number>> | 0 |
| The distance in pixels from the boundary edges where collision detection should occur. | ||
| arrowPadding | number | 0 |
| The padding between the arrow and the edges of the content. | ||
| sticky | 'partial' | 'always' | 'partial' |
| The sticky behavior of the content. | ||
| hideWhenDetached | boolean | false |
| When true, hides the content when the trigger becomes hidden. | ||
| forceMount | boolean | — |
| Used to force mounting when more control is needed. |
Data Attributes
| Attribute | Values |
|---|---|
| [data-state] | "open" | "closed" |
| [data-side] | "left" | "right" | "bottom" | "top" |
| [data-align] | "start" | "end" | "center" |
| [data-orientation] | "vertical" | "horizontal" |
Examples
Basic
A simple dropdown menu with basic items and actions.
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@/ui/dropdown-menu';
import { Button } from '@/ui/button';
export function DropdownMenuDemo() {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">Open</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56" align="start">
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuItem>Billing</DropdownMenuItem>
<DropdownMenuItem>Team</DropdownMenuItem>
<DropdownMenuItem>Subscription</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}With Checkboxes
Use checkbox items for toggling options on and off.
import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from '@/ui/dropdown-menu';
import { Button } from '@/ui/button';
import { signal } from '@angular/core';
import { CheckIcon } from 'lucide-angular';
export function DropdownMenuCheckboxes() {
const showStatusBar = signal(true);
const showActivityBar = signal(false);
const showPanel = signal(false);
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">Open</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56">
<DropdownMenuLabel>Appearance</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuCheckboxItem
checked={showStatusBar()}
onCheckedChange={() => showStatusBar.update(v => !v)}
>
Status Bar
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem
checked={showActivityBar()}
onCheckedChange={() => showActivityBar.update(v => !v)}
disabled
>
Activity Bar
</DropdownMenuCheckboxItem>
<DropdownMenuCheckboxItem
checked={showPanel()}
onCheckedChange={() => showPanel.update(v => !v)}
>
Panel
</DropdownMenuCheckboxItem>
</DropdownMenuContent>
</DropdownMenu>
);
}With Radio Group
Use radio items for mutually exclusive options.
import { DropdownMenu, DropdownMenuContent, DropdownMenuLabel, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuTrigger } from '@/ui/dropdown-menu';
import { Button } from '@/ui/button';
import { signal } from '@angular/core';
export function DropdownMenuRadioGroupDemo() {
const position = signal('bottom');
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">Open</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56">
<DropdownMenuLabel>Panel Position</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuRadioGroup value={position()} onValueChange={(val) => position.set(val)}>
<DropdownMenuRadioItem value="top">Top</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="bottom">Bottom</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="right">Right</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
</DropdownMenuContent>
</DropdownMenu>
);
}With Submenus
Create nested submenus with the Sub component.
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger } from '@/ui/dropdown-menu';
import { Button } from '@/ui/button';
import { ChevronRightIcon } from 'lucide-angular';
export function DropdownMenuSubmenus() {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">Open</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56" align="start">
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem>Profile</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
More Tools
<ChevronRightIcon className="ml-auto h-4 w-4" />
</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent sideOffset={-4}>
<DropdownMenuItem>Save Page As...</DropdownMenuItem>
<DropdownMenuItem>Create Shortcut...</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>Developer Tools</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
<DropdownMenuSeparator />
<DropdownMenuItem>Log out</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}With Disabled Items
Disable items to prevent user interaction.
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/ui/dropdown-menu';
import { Button } from '@/ui/button';
export function DropdownMenuDisabled() {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">Open</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-48">
<DropdownMenuItem>Edit</DropdownMenuItem>
<DropdownMenuItem>Duplicate</DropdownMenuItem>
<DropdownMenuItem disabled>Archive</DropdownMenuItem>
<DropdownMenuItem>Delete</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}With Shortcuts
Display keyboard shortcuts alongside menu items.
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuTrigger } from '@/ui/dropdown-menu';
import { Button } from '@/ui/button';
export function DropdownMenuShortcuts() {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">Open</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56" align="start">
<DropdownMenuLabel>My Account</DropdownMenuLabel>
<DropdownMenuGroup>
<DropdownMenuItem>
Profile
<DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
Billing
<DropdownMenuShortcut>⌘B</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
Settings
<DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
</DropdownMenuItem>
<DropdownMenuItem>
Keyboard shortcuts
<DropdownMenuShortcut>⌘K</DropdownMenuShortcut>
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
);
}With Complex Items
Render rich content inside menu items.
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/ui/dropdown-menu';
import { Button } from '@/ui/button';
import { Avatar, AvatarFallback, AvatarImage } from '@/ui/avatar';
import { NgFor } from '@angular/common';
export function DropdownMenuComplex() {
const users = [
{ name: 'Adolfo Hess', avatar: 'AH' },
{ name: 'Miyah Myles', avatar: 'MM' },
];
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">Open</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-56">
<NgFor [ngForOf]="users">
<DropdownMenuItem className="gap-2">
<Avatar className="h-6 w-6">
<AvatarImage src="..." />
<AvatarFallback>{{ user.avatar }}</AvatarFallback>
</Avatar>
{{ user.name }}
</DropdownMenuItem>
</NgFor>
</DropdownMenuContent>
</DropdownMenu>
);
}Controlling Position
Use side, align, and sideOffset to control content positioning.
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/ui/dropdown-menu';
import { Button } from '@/ui/button';
export function DropdownMenuPositioning() {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">Open</Button>
</DropdownMenuTrigger>
<DropdownMenuContent
side="right"
align="end"
sideOffset={8}
className="w-48"
>
<DropdownMenuItem>New Tab</DropdownMenuItem>
<DropdownMenuItem>New Window</DropdownMenuItem>
<DropdownMenuItem>New Private Window</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}Origin-Aware Animations
Use CSS custom properties to create animations that originate from the correct position.
// Component
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from '@/ui/dropdown-menu';
import { Button } from '@/ui/button';
export function DropdownMenuAnimated() {
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">Open</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-48 animate-in fade-in-0 zoom-in-95" sideOffset={5}>
<DropdownMenuItem>New Tab</DropdownMenuItem>
<DropdownMenuItem>New Window</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
);
}
// Tailwind config for custom animation
export const tailwindConfig = {
theme: {
extend: {
animation: {
'content-show': 'content-show 0.16s cubic-bezier(0.16, 1, 0.3, 1)',
},
keyframes: {
'content-show': {
from: {
opacity: '0',
transform: 'scale(0.96) translate(0, -2px)',
},
to: {
opacity: '1',
transform: 'scale(1)',
},
},
},
},
},
};/* Using CSS custom properties for origin-aware animations */
[data-radix-dropdown-menu-content] {
transform-origin: var(--radix-dropdown-menu-content-transform-origin);
animation: scaleIn 0.2s ease-out;
}
@keyframes scaleIn {
from {
opacity: 0;
transform: scale(0.95);
}
to {
opacity: 1;
transform: scale(1);
}
}
/* Collision-aware animations */
[data-radix-dropdown-menu-content][data-side="top"] {
animation: slideDown 0.2s ease-out;
}
[data-radix-dropdown-menu-content][data-side="bottom"] {
animation: slideUp 0.2s ease-out;
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(2px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-2px);
}
to {
opacity: 1;
transform: translateY(0);
}
}Accessibility
Adheres to the Menu Button WAI-ARIA design pattern .
Keyboard Interactions
| Key | Description |
|---|---|
| Space | When focus is on DropdownMenuTrigger, opens the dropdown menu and focuses the first item. When focus is on an item, activates the focused item. |
| Enter | When focus is on DropdownMenuTrigger, opens the dropdown menu and focuses the first item. When focus is on an item, activates the focused item. |
| ArrowDown | When focus is on DropdownMenuTrigger, opens the dropdown menu. When focus is on an item, moves focus to the next item. |
| ArrowUp | When focus is on an item, moves focus to the previous item. |
| ArrowRight | When focus is on DropdownMenuSubTrigger, opens or closes the submenu depending on reading direction. |
| ArrowLeft | When focus is on DropdownMenuSubTrigger, opens or closes the submenu depending on reading direction. |
| Esc | Closes the dropdown menu and moves focus to DropdownMenuTrigger. |
| Tab | Moves focus to the next focusable element. Does not move focus within the dropdown menu items. |
| Typeahead | When focus is within the dropdown menu, typing a character moves focus to the next menu item that starts with that character. |