组件 · 浮层
Lightbox
A full-screen viewer over the scrim for images and attachment previews, with previous and next, thumbnails and one button to close.
import { Lightbox } from "@botiverse/raft-ui";A lightbox shows an image or a file preview at full size over the whole window: the image on a full-screen layer-backdrop, previous and next, and one icon button to close (Built from existing parts). Use it when someone opens an image or an attachment from a message. It is for media and previews only.
When to use
| Situation | Use |
|---|---|
| Viewing an image, a screenshot or a video at full size | Lightbox, image shell |
| Previewing an attached file (an HTML page, a document) at full size | Lightbox, attachment shell |
| A decision, a form or anything that is not media | Dialog |
| Details people read beside the page | Drawer |
| The attachment in the message itself | MessageAttachment |
Anatomy
Lightbox: the root. It holds whether the lightbox is open. Required.LightboxTrigger: what opens it, usually the image or the file card in the message.LightboxContent: the full-screen layer, with the scrim behind it. Required.LightboxTitle: the file name.LightboxClose: the close button. Required.LightboxStage: the area that centers the media. Required.LightboxMedia: the image or video, at most 80% of the window's height and 86% of its width.LightboxNavigationButton: previous (direction="previous") and next (direction="next"), 44px buttons 32px from the left and right edges.LightboxInfoDockwithLightboxInfoBar: a small floating bar near the bottom, onlayer-popoverwithshadow-float, holdingLightboxInfoTitle(the file name) andLightboxInfoActions(such as Download). It is a floating toolbar, 36px tall like the message hover toolbar: its buttons are 28px, 4px inside it and 4px apart, withradius-chip, and a 44px tall hit area on a touch screen that reaches only half the gap toward a neighbour (Shape).LightboxThumbnailStripwithLightboxThumbnails: 48px thumbnails along the bottom;activemarks the one shown.
LightboxToolbar: the attachment shell's top bar instead of the floating close button, onlayer-canvaswith aline-seamunder it. It holdsLightboxHeaderMeta(aLightboxHeaderLabelor Badge naming the preview type, thenLightboxTitle) andLightboxActions, withLightboxCloselast.LightboxHeader: a plain top row for a title and actions, for shells that need neither toolbar nor floating close.
Variants
| Variant | Use for |
|---|---|
Image shell: LightboxClose directly in LightboxContent | Images and video. The close button floats at the top right; the image has the whole window |
Attachment shell: LightboxToolbar above LightboxStage | A file preview that fills the stage, such as an HTML page in an iframe. The toolbar names the file and holds its actions and the close button |
States
- First and last item: previous or next is disabled. It stays focusable (
aria-disabled) and ignores clicks. - Thumbnails: the shown item has a solid edge; the others are dimmed until hovered.
Behavior
- A lightbox appears and disappears without animation, like the other centered overlays (Motion).
- Esc, the close button, a click on the scrim and Cmd+W (Ctrl+W) close it. Cmd+W closes the lightbox, not the browser tab; pass
closeOnModW={false}to leave the shortcut to the browser. - The close button and the bars keep clear of the phone's safe areas.
- The caller keeps which item is shown. Previous, next, the thumbnails and the arrow keys all change that index.
Content
- Title the lightbox with the file name. A long name truncates at the end.
- Name the preview type in the toolbar's label in sentence case: HTML preview.
Accessibility
- Lightbox wraps the Base UI Dialog. It provides the
dialogrole, the focus trap and Esc; raft-ui adds the Cmd+W shortcut. LightboxTitleis plain text, not the dialog's name. Name the dialog yourself:aria-labelonLightboxContent, or arenderelement with one.LightboxContentdoesn't move focus when it opens or return it when it closes (initialFocusandfinalFocusarefalse). Pass them when keyboard users open the lightbox, so focus lands in it and goes back to the trigger.- Give
LightboxClose, eachLightboxNavigationButtonand each icon-only action anaria-label: "Close", "Previous image", "Next image", "Download". - Bind the Left and Right arrow keys to previous and next while the lightbox is open.
- Give each
LightboxThumbnailanaria-label("Show product-shot.png").activechanges only how it looks: mark the shown one witharia-current="true". - Give the image an
altthat describes it, and aniframeatitle.
Rules
- Don't build a media viewer from a Dialog, and don't put anything other than media or a file preview in a Lightbox.
- Give the lightbox one close button, at the top right (Navigation).
- In the toolbar, a framed button ends its shape on the 16px margin; a frameless icon button, as the last action or the close, ends its icon box there and its hit area hangs past it (Alignment).
- In Raft Chat every file opens in the attachment shell, images included, so each file type has the same toolbar (File viewer).
- Don't add colors or lines beyond the scrim, the info bar and the toolbar (Built from existing parts).
API
Lightbox
| Prop | 类型 | 默认值 |
|---|---|---|
| ReactNode | ||
| boolean | true | |
| Whether the dialog is initially open. | boolean | false |
| ID of the trigger that the dialog is associated with. This is useful in conjunction with the `defaultOpen` prop to create an initially open dialog. | string | |
| Whether to prevent the dialog from closing on outside presses. For non-modal dialogs, this also prevents the dialog from closing when focus moves outside of it. | boolean | false |
| Determines if the dialog enters a modal state when open. - `true`: user interaction is limited to just the dialog: focus is trapped, document page scroll is locked, and pointer interactions on outside elements are disabled. - `false`: user interaction with the rest of the document is allowed. - `'trap-focus'`: focus is trapped inside the dialog, but document page scroll is not locked and pointer interactions outside of it remain enabled. | boolean | "trap-focus" | true |
| Event handler called when the dialog is opened or closed. | (open: boolean, eventDetails: Dialog.Root.ChangeEventDetails) => void | |
| Event handler called after any animations complete when the dialog is opened or closed. | (open: boolean) => void | |
| Whether the dialog is currently open. | boolean | |
| ID of the trigger that the dialog is associated with. This is useful in conjunction with the `open` prop to create a controlled dialog. There's no need to specify this prop when the dialog is uncontrolled (that is, when the `open` prop is not set). | string |
LightboxActions
| Prop | 类型 | 默认值 |
|---|---|---|
| Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ReactElement | ((props, state) => ReactElement) |
Also takes the attributes of its element.
LightboxClose
| Prop | 类型 | 默认值 |
|---|---|---|
| Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (for example, `<div>`). | boolean | true |
| Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ReactElement | ((props, state) => ReactElement) |
Also takes the attributes of its element.
LightboxContent
| Prop | 类型 | 默认值 |
|---|---|---|
| Determines the element to focus when the dialog is closed. | boolean | RefObject<HTMLElement | null> | ((closeType: InteractionType) => boolean | HTMLElement | null | void) | false |
| Determines the element to focus when the dialog is opened. By default, focus moves to the first tabbable element inside the popup, except when the dialog is opened by touch — then the popup itself is focused to avoid opening the virtual keyboard. | boolean | RefObject<HTMLElement | null> | ((openType: InteractionType) => boolean | HTMLElement | null | void) | false |
| Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ReactElement | ((props, state) => ReactElement) |
Also takes the attributes of its element.
LightboxHeader, LightboxHeaderLabel, LightboxHeaderMeta, LightboxInfoActions, LightboxInfoBar, LightboxInfoDock, LightboxInfoTitle, LightboxMedia
| Prop | 类型 | 默认值 |
|---|---|---|
| Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ReactElement | ((props, state) => ReactElement) |
Also takes the attributes of its element.
LightboxNavigationButton
| Prop | 类型 | 默认值 |
|---|---|---|
| "next" | "previous" | ||
| boolean | ||
| string | ||
| Whether the button should be focusable when disabled. | boolean | false |
| Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (for example, `<div>`). | boolean | true |
| Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ReactElement | ((props, state) => ReactElement) |
Also takes the attributes of its element.
LightboxPortal
| Prop | 类型 | 默认值 |
|---|---|---|
| A parent element to render the portal element into. | HTMLElement | ShadowRoot | RefObject<HTMLElement | ShadowRoot | null> | |
| Whether to keep the portal mounted in the DOM while the popup is hidden. | boolean | false |
| Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ReactElement | ((props, state) => ReactElement) |
Also takes the attributes of its element.
LightboxStage
| Prop | 类型 | 默认值 |
|---|---|---|
| Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ReactElement | ((props, state) => ReactElement) |
Also takes the attributes of its element.
LightboxThumbnail
| Prop | 类型 | 默认值 |
|---|---|---|
| boolean | false | |
| Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ReactElement | ((props, state) => ReactElement) |
Also takes the attributes of its element.
LightboxThumbnailStrip, LightboxTitle, LightboxToolbar
| Prop | 类型 | 默认值 |
|---|---|---|
| Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ReactElement | ((props, state) => ReactElement) |
Also takes the attributes of its element.
LightboxTrigger
| Prop | 类型 | 默认值 |
|---|---|---|
| A handle to associate the trigger with a dialog. Can be created with the Dialog.createHandle() method. | Dialog.Handle<unknown> | |
| ID of the trigger. In addition to being forwarded to the rendered element, it is also used to specify the active trigger for the dialog in controlled mode (with the DialogRoot `triggerId` prop). | string | |
| Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `false` if the rendered element is not a button (for example, `<div>`). | boolean | true |
| A payload to pass to the dialog when it is opened. | {} | |
| Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ReactElement | ((props, state) => ReactElement) |
Also takes the attributes of its element.
相关组件
改动
- 0.1.0 · AddedExtended
Lightboxwith thumbnail strip and related chrome parts; addedComboboxTriggerCountandContextMenuPopup.