Theme studio

Design a theme, preview it live, then export it. Saved in this browser.

Quick picks #10b981
Generated scale
50100200300400500600700800900
Some text is below AA

RTELinkPopover

  • Stable
  • WCAG 2.2 evidence
  • RTL

The link editor of a rich-text editor. Mode=Edit is a small form: the address field (the library Input, with the link icon), "Open in new tab" (CheckboxField), Cancel and Apply (Button). Mode=Preview shows the address as a link that opens in a new tab, with Edit and Remove (IconButton). Built on a non-modal React Aria Popover holding a role="dialog" panel named "Edit link" / "Link". Open it from the link tool inside a React Aria DialogTrigger (the tool gets aria-expanded), or anchor it with triggerRef and isOpen. In edit mode focus moves into the address field when it opens (WCAG 2.4.3); the address is checked when Apply or Enter is pressed and an invalid one shows an inline error with an icon, linked to the field, and keeps focus there (3.3.1, 3.3.3, 4.1.2, 1.4.1). Escape, Cancel, Apply and Remove close it and focus returns to the trigger or the editor (2.1.1); nothing is trapped and a click outside closes it (2.1.2). It flips and stays inside the viewport. Preview mode does not take focus, so typing continues in the editor; keyboard users reach the same actions through the link tool (edit mode). The library ships no editor engine: apply and remove the link in onSubmit / onRemove. Consumer duties: texts in your locale (labels), and opening edit mode from the toolbar.

import { RTELinkPopover } from "@nexera-ui/react";
Loading example…
5
examples
30
props
5
live controls
1
platform
11
WCAG criteria
1
block uses it

Try every prop. Copy the code.

Change the props and the code updates. Check light and dark, LTR and RTL, and phone width.

Loading…
mode
defaultMode
openInNewTab
hasTextField
placement
Generated code
import { RTELinkPopover } from "@nexera-ui/react";

<RTELinkPopover />

Examples 4

The same examples as Storybook, rendered live. Open Code to copy one.

With text field

hasTextField: a "Text to display" field under the address, for links inserted without selected text.

Loading example…

Preview

Figma Mode=Preview, anchored to a link in the text (triggerRef): the address opens in a new tab; Edit switches to the form, Remove removes the link. It does not take focus, so typing continues in the editor.

Loading example…

Right to left

Right-to-left with translated texts, and a long address that wraps instead of being cut.

Loading example…

In editor

A realistic composed editor with a plain contenteditable element (Ctrl+K or the Link tool opens the popover over the selected text).

Loading example…

Props 30

Press "Try it" on a card to load that prop into the playground.

30 props shown

modeNexera
"edit" | "preview"

Figma Mode: edit shows the address form, preview shows the link with Edit and Remove buttons (for example when the caret is inside a link). Controlled; use with onModeChange. Edit in preview switches to edit.

Default –
defaultModeNexera
"edit" | "preview"

Mode on first render (uncontrolled).

Default edit
onModeChangeNexera
(mode: RTELinkPopoverMode) => void

Called when the mode changes (the preview's Edit button).

Default –
hrefNexera
string

The current link address: shown in preview, and the starting value of the edit field (empty for a new link).

Default
textNexera
string

The current link text: the starting value of the text field (with hasTextField).

Default
openInNewTabNexera
boolean

Whether the current link opens in a new tab: the starting value of the checkbox.

Default false
hasTextFieldNexera
boolean

Adds a "Text to display" field under the address. Use it when the link has no selected text to wrap.

Default false
onSubmitNexera
(link: RTELinkValue) => void

Called with the validated link when Apply is pressed (or Enter in a field); the popover then closes and focus returns to the trigger or the editor. Apply the link in your editor here.

Default –
onRemoveNexera
() => void

Called when the preview's Remove button is pressed; the popover then closes. Remove the link in your editor here.

Default –
validateNexera
(href: string) => string | null

Extra check of the address after the built-in one (which accepts web, mail and phone links and relative paths). Return an error message to block the submission; it is shown under the field with an icon.

Default –
labelsNexera
Partial<RTELinkPopoverLabels>

The texts the popover renders, merged over the English defaults. Translate them for your locale.

Default –
triggerRefNexera
RefObject<Element | null>

The element the popover is anchored to and gives focus back to, when it is not the trigger of a surrounding DialogTrigger: the link tool, or the link element in the editor for the preview.

Default –
placementNexera
"bottom" | "bottom left" | "bottom right" | "bottom start" | "bottom end" | "top" | "top left" | "top right" | "top start" | "top end" | "left" | "left top" | "left bottom" | "start" | "start top" | "start bottom" | "right" | "right top" | "right bottom" | "end" | "end top" | "end bottom"

Side of the anchor the popover opens on; it flips to stay inside the viewport.

Default bottom start
classNameNexera
string

Extra classes for the surface, merged last so they win over the defaults.

Default –
styleNexera
CSSProperties

Inline style for the surface.

Default –
isOpenReact Aria
boolean

Whether the overlay is open by default (controlled).

Default –
containerPaddingReact Aria
number

The placement padding that should be applied between the element and its surrounding container.

Default 12
offsetReact Aria
number

The additional offset applied along the main axis between the element and its anchor element.

Default 8
crossOffsetReact Aria
number

The additional offset applied along the cross axis between the element and its anchor element.

Default 0
shouldFlipReact Aria
boolean

Whether the element should flip its orientation (e.g. top to bottom or left to right) when there is insufficient room for it to render completely.

Default true
boundaryElementReact Aria
Element

Element that that serves as the positioning boundary.

Default document.body
scrollRefReact Aria
RefObject<Element | null>

A ref for the scrollable region within the overlay.

Default overlayRef
shouldUpdatePositionReact Aria
boolean

Whether the overlay should update its position automatically.

Default true
maxHeightReact Aria
number

The maxHeight specified for the overlay element. By default, it will take all space up to the current viewport height.

Default –
arrowBoundaryOffsetReact Aria
number

The minimum distance the arrow's edge should be from the edge of the overlay element.

Default 0
getTargetRectReact Aria
(target: Element) => DOMRect | null

Overrides the target element's bounding rectangle. Useful for positioning relative to a specific point such as the mouse cursor (e.g. context menus) or text selection. @param target - The target element.

Default target.getBoundingClientRect()
isKeyboardDismissDisabledReact Aria
boolean

Whether pressing the escape key to close the popover should be disabled. Most popovers should not use this option. When set to true, an alternative way to close the popover with a keyboard must be provided.

Default false
shouldCloseOnInteractOutsideReact Aria
(element: Element) => boolean

When user interacts with the argument element outside of the popover ref, return true if onClose should be called. This gives you a chance to filter out interaction with elements that should not dismiss the popover. By default, onClose will always be called on interaction outside the popover ref.

Default –
defaultOpenReact Aria
boolean

Whether the overlay is open by default (uncontrolled).

Default –
onOpenChangeReact Aria
(isOpen: boolean) => void

Handler that is called when the overlay's open state changes.

Default –

* Required. React Aria props shown are the ones most apps use; the component accepts the rest of its React Aria props too.

Accessible by default.

Built on React Aria, and covered by the WCAG 2.2 evidence generated on every build.

WCAG 2.2 evidence

9 direct · 2 supporting
  • 1.3.1Info and RelationshipsLevel A · tested directly
  • 1.3.2Meaningful SequenceLevel A · supporting test
  • 1.4.1Use of ColorLevel A · tested directly
  • 1.4.10ReflowLevel AA · supporting test
  • 2.1.1KeyboardLevel A · tested directly
  • 2.1.2No Keyboard TrapLevel A · tested directly
  • 2.4.3Focus OrderLevel A · tested directly
  • 2.4.4Link Purpose (In Context)Level A · tested directly
  • 3.3.1Error IdentificationLevel A · tested directly
  • 3.3.3Error SuggestionLevel AA · tested directly
  • 4.1.2Name, Role, ValueLevel A · tested directly

Fits any width.

Nexera components respond to the space they are given. Drag the corner of the frame, or pick a width.

0 px · drag the corner

Styling hooks

Pass className to add Tailwind classes (merged last). State is exposed as data attributes, so you can style it with variants like data-pressed:.

  • data-hovered
Usage
<RTELinkPopover className="data-hovered:opacity-90 shadow-sm" />

Used in blocks

Related components