# Callout
**Also known as:** Popover, Popup
## Description
Callout is an anchored surface for any content - a tip, a form, a filter panel, a menu - placed next to an anchor of its own, any element on the page, or a point on the screen. It picks the side with room, follows its anchor while open, points at it with an optional arrow, opens on a click or on hover, closes on an outside click or Escape, and can trap the keyboard, dim the page, nest, and become a swipeable panel on small screens.
## Parameters
| Name | Type | Default Value | Description |
| :--- | :--- | :------------ | :---------- |
| Alignment | `BitPlacement?` | null | How the callout is lined up with its anchor along the axis it is not placed on. It defaults to Start. Start, Center and End work on either axis, following the reading direction on the horizontal one; Left and Right only mean something above or below the anchor, and Top and Bottom beside it. A physical value used off its own axis, like the two combined values, falls back to Start. |
| AlignmentOffset | `int` | 0 | The distance in pixels the callout is slid along the axis it is aligned on, inwards from the edge of the anchor the Alignment lined it up with. A centered callout has no edge for it to run from. |
| Anchor | `RenderFragment?` | null | The content of the anchor element of the callout. The anchor is rendered as a plain container, so the content given here should hold the focusable element the user activates. |
| AnchorEl | `Func<ElementReference>?` | null | The setter function for element reference to the external anchor element. |
| AnchorId | `string?` | null | The id of the external anchor element. |
| AriaDescribedBy | `string?` | null | The id of an element that describes the callout, read by screen readers after its name. |
| AriaLabelledBy | `string?` | null | The id of an element that names the callout, such as a heading in its content. It takes the place of the Header and of the AriaLabel as the name. |
| ArrowPadding | `int?` | null | The distance in pixels the arrow drawn by ShowArrow is kept away from the corners of the callout, so that the rounding never cuts it. It defaults to 16, and never drops below the size of the arrow itself. |
| ArrowSize | `int?` | null | The size in pixels of the arrow drawn by ShowArrow, which is the length of the side of the square the beak is cut out of. It defaults to 12. |
| AutoClose | `bool` | false | Closes the callout as soon as a click lands anywhere inside it. |
| AutoFocus | `bool` | false | Moves the focus into the callout as soon as it opens, to its first focusable element, or to the callout itself when it holds none. |
| Background | `BitColorKind?` | null | The color kind of the background of the callout. |
| Border | `BitColorKind?` | null | The color kind of the border of the callout. |
| ChildContent | `RenderFragment?` | null | The content of the callout. |
| Classes | `BitCalloutClassStyles?` | null | Custom CSS classes for different parts of the callout. |
| CollisionPadding | `int` | 0 | The distance in pixels the callout keeps from the edges of the screen when it is placed and when it is slid back onto it. |
| Content | `RenderFragment?` | null | Alias for ChildContent. |
| DefaultIsOpen | `bool?` | null | The initial opening state of the callout in the uncontrolled mode, which is when the IsOpen parameter is not set. |
| Direction | `BitDropDirection?` | null | Determines the allowed directions in which the callout should decide to be opened. |
| FixedCalloutWidth | `bool` | false | Holds the callout to the width of its anchor, so that a content wider than the anchor wraps inside it instead of stretching it. |
| Footer | `RenderFragment?` | null | The content of a footer that stays at the bottom of the callout while the rest of it scrolls. |
| FooterId | `string?` | null | The id of the footer element that renders at the end of the scrolling container of the callout content. It wins over the Footer parameter. |
| Gap | `int` | 0 | The distance in pixels between the anchor and the callout, on whichever side the callout ends up being placed. |
| Header | `RenderFragment?` | null | The content of a header that stays at the top of the callout while the rest of it scrolls. |
| HeaderId | `string?` | null | The id of the header element that renders at the top of the scrolling container of the callout content. It wins over the Header parameter. |
| HoverCloseDelay | `int` | 150 | The delay in milliseconds before the callout closes once the pointer leaves the callout and its anchor in the OpenOnHover mode. |
| HoverOpenDelay | `int` | 0 | The delay in milliseconds before the callout opens once the pointer enters the anchor in the OpenOnHover mode. |
| IsOpen | `bool` | false | Determines the opening state of the callout. |
| LazyRender | `bool` | false | Keeps the content of the callout out of the page until the callout is opened for the first time. Once rendered it stays, so whatever state the content holds survives the callout closing. |
| MaxHeight | `string?` | null | The maximum height of the callout as a CSS value, beyond which its content scrolls. |
| MaxWidth | `string?` | null | The maximum width of the callout as a CSS value, beyond which its content wraps. |
| MaxWindowWidth | `int?` | null | The window width in pixels below which the callout is allowed to hang off the end of the screen rather than being slid back onto it. |
| MinWidth | `string?` | null | The minimum width of the callout as a CSS value, so that a narrow content does not end up in a cramped callout. |
| Modal | `bool` | false | Dims the page behind the callout and holds it still while the callout is open, so that the callout reads as the only thing in play. It implies TrapFocus. |
| NoDismissOnEscape | `bool` | false | Keeps the Escape key from dismissing the callout. |
| NoDismissOnOutsideClick | `bool` | false | Keeps the callout open when a click lands outside of it, and when the page is scrolled or resized under it. |
| NoDismissOnScroll | `bool` | false | Keeps the callout open when the page is scrolled or resized under it: it follows its anchor instead, while an outside click still closes it. |
| NoFlip | `bool` | false | Keeps the callout on the Placement it was asked for even when there is not enough room for it there, instead of flipping it to the opposite side. |
| NoOverlay | `bool` | false | Leaves the page its own clicks while the callout is open, by not rendering the overlay that otherwise covers it. A Modal callout keeps its overlay. |
| NoShadow | `bool` | false | Removes the box-shadow from the callout. |
| OnDismiss | `EventCallback` | | The callback that is called when the callout is dismissed. |
| OnOpen | `EventCallback` | | The callback that is called when the callout is opened. |
| OnToggle | `EventCallback<bool>` | | The callback that is called when the callout opens or closes. |
| OpenOnHover | `bool` | false | Opens the callout when the pointer enters the anchor and closes it when the pointer leaves both the anchor and the callout. |
| PanelPlacement | `BitPlacement?` | null | The edge of the screen the responsive panel slides in from, for a ResponsiveMode of Panel. It defaults to End. Start and End follow the text direction, Left and Right stay where they are named in both; Center and the two combined values fall back to End. |
| ResponsiveMode | `BitResponsiveMode?` | null | Configures the responsive mode of the callout for the small screens. |
| Role | `string?` | null | The ARIA role of the callout. It defaults to dialog for a callout that traps the focus (TrapFocus or Modal), and to nothing for the others. |
| ScrollContainerId | `string?` | null | The id of the element which needs to be scrollable in the content of the callout. |
| ScrollOffset | `int?` | null | The vertical offset of the scroll container to consider in the positioning and height calculation of the callout. |
| SetCalloutWidth | `bool` | false | Widens the callout to at least the width of its anchor, so that a callout with little in it still reads as belonging to what it was opened from. |
| ShowArrow | `bool` | false | Draws an arrow on the edge of the callout that faces the anchor, pointing at it. |
| Placement | `BitPlacement?` | null | The side of the anchor the callout is placed on when there is room for it there. It wins over Direction, falls back to the opposite side, and then to Direction. Top, Bottom, Left and Right are honoured as they are named, Start and End against the reading direction; Center and the two combined values leave the choice to Direction, exactly as leaving this unset does. |
| Styles | `BitCalloutClassStyles?` | null | Custom CSS styles for different parts of the callout. |
| TrapFocus | `bool` | false | Keeps the keyboard inside the callout while it is open and reports it as a modal dialog to the screen readers. It implies AutoFocus. |
| Width | `string?` | null | The width of the callout as a CSS value. SetCalloutWidth and FixedCalloutWidth take precedence over it. |
| AriaLabel | `string?` | null | Gets or sets the accessible label for the component, used by assistive technologies. |
| Class | `string?` | null | Gets or sets the CSS class name(s) to apply to the rendered element. |
| Dir | `BitDir?` | null | Gets or sets the text directionality for the component's content. |
| Disabled | `bool` | false | Gets or sets a value indicating whether the component is disabled and cannot respond to user interaction. |
| ForceAnimation | `bool` | false | Gets or sets a value indicating whether the component's animations play at their full duration even when reduced motion is requested. |
| HtmlAttributes | `Dictionary<string, object>` | new Dictionary<string, object>() | Captures additional HTML attributes to be applied to the rendered element, in addition to the component's parameters. An attribute written on the component wins over an entry of the same name. |
| Id | `string?` | null | Gets or sets the unique identifier for the component's root element. |
| Style | `string?` | null | Gets or sets the CSS style string to apply to the rendered element. |
| TabIndex | `string?` | null | Gets or sets the tab order index for the component when navigating with the keyboard. |
| Visibility | `BitVisibility` | BitVisibility.Visible | Gets or sets the visibility state (visible, hidden, or collapsed) of the component. |
## Public Members
| Name | Type | Default Value | Description |
| :--- | :--- | :------------ | :---------- |
| Open | `Task` | | Opens the callout programmatically, unless it is disabled. |
| OpenAt | `Task` | | Opens the callout at a point on the screen rather than against an anchor, which is what a context menu needs. It takes the coordinates (double x, double y) or the MouseEventArgs they came from, and moves an already open callout to the new point. |
| Close | `Task` | | Closes the callout programmatically. |
| Toggle | `Task` | | Toggles the callout to open/close it. |
| Reposition | `Task` | | Lays the open callout out again against what it is placed on, without reopening it or replaying its entry animation. It is for what the callout cannot see on its own: a content that has grown or shrunk, or an anchor moved by something other than a resize of it. |
| UniqueId | `Guid` | Guid.NewGuid() | Gets the readonly unique identifier for the component's root element, assigned when the component instance is constructed. |
| RootElement | `ElementReference` | | Gets the reference to the root HTML element associated with this component. |
## Enums
### BitDropDirection Enum
| Name | Value | Description |
| :--- | :--- | :---------- |
| All | 0 | The direction determined automatically based on the available spaces in all directions. |
| TopAndBottom | 1 | The direction determined automatically based on the available spaces in only top and bottom directions. |
### BitResponsiveMode Enum
| Name | Value | Description |
| :--- | :--- | :---------- |
| None | 0 | Disables the responsive mode. |
| Panel | 1 | Enables the panel responsive mode, whose edge comes from the PanelPlacement parameter. |
| Top | 2 | Enables the responsive mode as a sheet that comes down from the top of the screen. |
| Bottom | 3 | Enables the responsive mode as a sheet that comes up from the bottom of the screen. |
### BitPlacement Enum
| Name | Value | Description |
| :--- | :--- | :---------- |
| Top | 0 | The top edge. |
| Bottom | 1 | The bottom edge. |
| Start | 2 | The edge the reading direction starts from - the left in LTR, the right in RTL. On the vertical axis, which does not turn around, it is the top. |
| End | 3 | The edge the reading direction ends at - the right in LTR, the left in RTL. On the vertical axis, which does not turn around, it is the bottom. |
| Left | 4 | The left edge, in both reading directions. |
| Right | 5 | The right edge, in both reading directions. |
| Center | 6 | The middle of the axis, against neither edge. |
| TopAndBottom | 7 | Both edges of the block axis at once. |
| StartAndEnd | 8 | Both edges of the inline axis at once, following the reading direction the way Start and End do. |
### BitColorKind Enum
| Name | Value | Description |
| :--- | :--- | :---------- |
| Primary | 0 | The primary color kind. |
| Secondary | 1 | The secondary color kind. |
| Tertiary | 2 | The tertiary color kind. |
| Transparent | 3 | The transparent color kind. |
### BitVisibility Enum
| Name | Value | Description |
| :--- | :--- | :---------- |
| Visible | 0 | The content of the component is visible. |
| Hidden | 1 | The content of the component is hidden, but the space it takes on the page remains (visibility:hidden). |
| Collapsed | 2 | The component is hidden (display:none). |
### BitDir Enum
| Name | Value | Description |
| :--- | :--- | :---------- |
| Ltr | 0 | Ltr (left to right) is to be used for languages that are written from the left to the right (like English). |
| Rtl | 1 | Rtl (right to left) is to be used for languages that are written from the right to the left (like Arabic). |
| Auto | 2 | Auto lets the user agent decide. It uses a basic algorithm as it parses the characters inside the element until it finds a character with a strong directionality, then applies that directionality to the whole element. |
## Sub Classes
### BitCalloutClassStyles Properties
| Name | Type | Default Value | Description |
| :--- | :--- | :------------ | :---------- |
| Root | `string?` | null | Custom CSS classes/styles for the root element of the BitCallout. |
| AnchorContainer | `string?` | null | Custom CSS classes/styles for the anchor container element of the BitCallout. |
| Arrow | `string?` | null | Custom CSS classes/styles for the arrow (beak) element of the BitCallout. |
| Opened | `string?` | null | Custom CSS classes/styles for the opened callout state of the BitCallout. |
| Content | `string?` | null | Custom CSS classes/styles for the content of the BitCallout. |
| Header | `string?` | null | Custom CSS classes/styles for the header element of the BitCallout, which is rendered when the Header parameter is set. |
| Body | `string?` | null | Custom CSS classes/styles for the scrolling body element of the BitCallout, which is rendered when the Header or the Footer parameter is set. |
| Footer | `string?` | null | Custom CSS classes/styles for the footer element of the BitCallout, which is rendered when the Footer parameter is set. |
| Overlay | `string?` | null | Custom CSS classes/styles for the overlay of the BitCallout. |
## CSS Variables
Public CSS custom properties read off the component's root. Set one on `:root` to restyle every instance, on any ancestor to restyle the ones inside it, or on the `Style` of one instance to restyle it and every instance nested inside it, which inherits the value too - a parameter changes one alone, as does the real CSS property on its `Style` / `Styles` when that property does not inherit (`opacity`); an inherited one (`color`, `font-family`) reaches the nested instances that do not set it themselves.
| Name | Default Value | Description |
| :--- | :------------ | :---------- |
| `--bit-Callout-background` | $clr-bg-pri | Background of the callout and its arrow. The Background parameter wins over it. |
| `--bit-Callout-color` | $clr-fg-pri | Text color of the callout. |
| `--bit-Callout-border-width` | 0 ($shp-border-width with Border) | Border width of the callout and its arrow; setting it draws a border without the Border parameter. |
| `--bit-Callout-border-color` | $clr-brd-pri | Border color of the callout and its arrow. The Border parameter wins over it. |
| `--bit-Callout-radius` | $shp-radius-popup | Corner radius of the callout. |
| `--bit-Callout-shadow` | $box-shadow-popup | Elevation of the callout. NoShadow wins over it. |
| `--bit-Callout-padding` | 0 | Room inside the callout, or inside each of its header, body and footer when it has them. |
| `--bit-Callout-arrow-size` | spacing(1.5) | Side of the square the arrow is cut out of. ArrowSize wins over it. |
| `--bit-Callout-divider-color` | $clr-brd-sec | The hairline under the header and above the footer. |
| `--bit-Callout-focus-color` | $clr-pri-focus | Focus ring of the callout itself, shown when it takes the focus while holding nothing focusable. |
| `--bit-Callout-overlay-background` | $clr-bg-overlay | The dimmed backdrop of a Modal callout. |
## Examples
\n**Basic**:
```razor
Show callout
NoOverlay
DefaultIsOpen
Disabled
```
\n**External anchor**:
```razor
AnchorId
```
```csharp
private ElementReference anchorEl;
private BitCallout callout1;
private BitCallout callout2;
```
\n**Binding**:
```razor
Show callout
Anchor
Done
Cancel
Hover me
Delayed (500ms)
```
\n**Dismissal**:
```razor
AutoClose (@autoCloseAction)
Rename
Duplicate
Delete
NoDismissOnScroll
No auto dismiss
Close
```
```csharp
private BitCallout callout3;
private string autoCloseAction = "none";
```
\n**Context menu**:
```razor
Cut
Copy
Paste
A wide anchor to place against
Direction: All
CollisionPadding of 24px
Reposition
@for (int i = 1; i <= repositionRows; i++)
{
Add a row
```
```csharp
private string placementSide = "Auto";
private BitPlacement placementAlignment = BitPlacement.Start;
private int placementGap = 8;
private int placementOffset;
private bool placementNoFlip;
private BitPlacement? PlacementSide => Enum.TryParse(placementSide, out var side) ? side : null;
private BitCallout callout4 = default!;
private int repositionRows = 2;
private bool repositionAfterRender;
private void AddRepositionRow()
{
repositionRows++;
// The callout is laid out against what is actually in it, so the reposition waits for the render
// that puts the new row there rather than measuring the content the callout still holds.
repositionAfterRender = true;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);
if (repositionAfterRender)
{
repositionAfterRender = false;
await callout4.Reposition();
}
}
```
\n**Surface**:
```razor
Background
Border
NoShadow
```
\n**Arrow**:
```razor
With an arrow
Beside, with a border
ArrowSize of 20px
ArrowPadding of 64px
```
\n**Sizing**:
```razor
Width
MaxWidth
MaxHeight & MinWidth
A wide anchor with SetCalloutWidth
A wide anchor with FixedCalloutWidth
```
\n**Header & footer**:
```razor
Header & Footer
Wired up by hand
```
\n**Responsive**:
```razor
End panel
Filters
Start panel
Filters
Top sheet
Bottom sheet
```
\n**Focus & modal**:
```razor
AutoFocus
Dismiss
TrapFocus
Submit
Modal
Heads up
OK
Role & AriaLabel
```
```csharp
private BitCallout modalCallout;
```
\n**Nesting**:
```razor
Filters
Filters
More options
The panel behind is still open.
One more level
```
\n**Lazy rendering**:
```razor
LazyRender
Rendered up front
```
```csharp
private DateTimeOffset? lazyDate;
private DateTimeOffset? eagerDate;
```
\n**Events**:
```razor
Show callout
Cascaded
Cascaded too
Own Placement, no arrow
Outside the cascade
```
```csharp
private readonly BitCalloutParams[] calloutParams =
[
new()
{
ShowArrow = true,
Gap = 8,
Placement = BitPlacement.End,
Border = BitColorKind.Secondary,
NoShadow = true,
}
];
```
\n**Style & Class**:
```razor
Inverted
A dark surface, rounder corners and a bigger beak.
Outlined
Outlined
A border instead of elevation; the padding goes inside the header, the body and the footer.
Component's Style
Component's Class
Styles
Classes
```
\n**RTL**:
```razor
نمایش کالاوت
همه جهتها
```
This is the callout content.
The page keeps its own clicks.
Open from the start.
Never shown.
Close it from inside.
IsOpen: @isOpen
```
```csharp
private bool isOpen;
```
\n**Open on hover**:
```razor
Opened on hover.
Opening and closing both waited half a second.
Scroll the page: this one follows its anchor.
Neither Escape nor an outside click closes this one.
contextCallout.OpenAt(e)" @oncontextmenu:preventDefault>
Right-click anywhere in here
Last action: @contextAction
```
```csharp
private BitCallout contextCallout;
private string contextAction = "none";
```
\n**Placement**:
```razor
Placed by the options above.
@for (int i = 1; i < 23; i++)
{
Callout content @i
}
@for (int i = 1; i < 25; i++)
{
Callout content @i
}
Callout content @i
}
A secondary background.
A primary border.
No elevation, only a border.
Points at its anchor.
The beak takes the border too.
A bigger beak.
The beak is held 64px away from the corners of the callout.
A callout of a fixed width.
A long line of text that wraps inside the callout instead of stretching it across the page.
@for (int i = 1; i < 25; i++)
{
Callout content @i
}
Short content.
A long line of text that wraps rather than making the callout wider than its anchor.
@for (int i = 1; i < 69; i++)
{
Callout content @i
}
@for (int i = 1; i < 69; i++)
{
Callout content @i
}
Swipe up to dismiss it.
Swipe down to dismiss it.
The page behind is dimmed and holds still.
Everything is up to date.
And so is this one.
This is the callout content.
Toggled: @toggleCount, Opened: @openCount, Dismissed: @dismissCount
```
```csharp
private int openCount;
private int toggleCount;
private int dismissCount;
```
\n**Cascading parameters**:
```razor
Arrow, gap, border and side come from the cascade.
The same defaults.
Its own values win.
No defaults here.
This is the callout content.
This is the callout content.
This is the callout content.
This is the callout content.
این محتوای کالاوت است.
@for (int i = 1; i < 13; i++)
{
محتوای کالاوت @i
}