Spotlight
Installation
Package depends on @asuikit/core and @asuikit/hooks.
Install with yarn:
Install with npm:
Usage
Spotlight component lets you build a popup search interface which can be triggered with keyboard
shortcut or programmatically from anywhere inside your application. To get started, wrap your application
with SpotlightProvider component:
Note that if you are using MantineProvider, SpotlightProvider must be used as its child:
Keyboard shortcuts
SpotlightProvider uses use-hotkeys hook to add keyboard shortcuts,
the default shortcut to trigger popup is mod + K, it means that it will be shown
when users press ⌘ + K on MacOS and Ctrl + K on any other os.
You can setup multiple shortcuts, for example, Mantine documentation uses the following setup:
It means that user will be able to open documentation search with the following shortcuts:
⌘ + K/Ctrl + K⌘ + P/Ctrl + P/– single keys are also supported
Note that provided shortcuts will prevent the default behavior, for example, mod + P will
disable "Print page" native browser function, choose those shortcuts that will not interfere
with desired default browser behavior.
Keyboard shortcuts will not work if:
- focus is not on current page
input,textareaorselectelements are focused (these can be overriden with thetagsToIgnorearg)- elements have
contentEditable=true(can be overriden with thetriggerOnContentEditablearg)
To disabled keyboard shortcuts set shortcut={null}:
Event based functions
@asuikit/spotlight exports spotlight object with functions which can be used to perform certain actions
from any part of your application:
use-spotlight hook
useSpotlight hook lets you control spotlight from anywhere in your application.
For example, it can be used to open spotlight with button click:
useSpotlight returns an object with the following properties:
Spotlight actions
actions is the only required prop of SpotlightProvider. Action shape:
You can import SpotlightAction type from @asuikit/spotlight package:
Controlled query
Use query and onQueryChange props to control search query:
Actions filtering
When user searches, spotlight actions are filtered based on the following action properties:
title–stringdescription–stringkeywords–string | string[]
You can change filtering logic by setting filter prop on SpotlightProvider.
The following example filters actions only by title:
Actions limit
If you have a large list of actions, most of them won't be presented in the initial list (when user have not entered any text yet).
You can control how many actions are displayed at a time with the limit prop:
Register additional actions
You can register any amount of additional actions with registerActions function on useSpotlight hook.
To remove actions from the list use removeActions function. Note that to register/remove actions features
to work you need to store actions array in state:
Group actions
Custom action component
You can provide custom component to render actions, this feature can be used to customize how actions are displayed:
Custom actions wrapper component
With custom actions wrapper component you can customize how actions list is rendered, for example, you can add a footer:
Close spotlight on action trigger
By default, spotlight will be closed when any action is triggered with mouse click or Enter key.
To change this behavior set closeOnActionTrigger={false} prop on SpotlightProvider:
Close spotlight on specific action trigger
Other than with the global closeOnActionTrigger property, the closeOnTrigger property can be defined
for specific actions. The action will then ignore the closeOnActionTrigger property and use its own definition.
Highlight query
Default action component supports highlighting search query with Highlight component.
To enable this option set highlightQuery on SpotlightProvider:
Change transitions
Component presence is animated with Transition component,
it supports all premade and custom transitions. To change transition set Transition component props with transitionProps:
To disable transitions set transitionProps={{ duration: 0 }}:
Fixed elements offset
SpotlightProvider component uses react-remove-scroll
package to lock scroll. To properly size these elements add a className to them (documentation):
SpotlightProvider component props
| Name | Type | Description |
|---|---|---|
| actionComponent | FC<DefaultActionProps> | Component that is used to render actions |
| actions * | SpotlightAction[] | Actions list |
| actionsWrapperComponent | string | FC<{ children: ReactNode; }> | Component that is used to wrap actions list |
| centered | boolean | Determines whether the modal should be centered vertically, false by default |
| children | ReactNode | Your application |
| cleanQueryOnClose | boolean | Should search be cleared when spotlight closes |
| closeButtonProps | ModalBaseCloseButtonProps | Props added to close button |
| closeOnActionTrigger | boolean | Should spotlight be closed when action is triggered |
| closeOnClickOutside | boolean | Determines whether the modal/drawer should be closed when user clicks on the overlay, true by default |
| closeOnEscape | boolean | Determines whether onClose should be called when user presses escape key, true by default |
| disabled | boolean | Spotlight will not render if disabled is set to true |
| filter | (query: string, actions: SpotlightAction[]) => SpotlightAction[] | Function used to determine how actions will be filtered based on user input |
| fullScreen | boolean | Determines whether the modal should take the entire screen |
| highlightColor | MantineColor | The highlight color |
| highlightQuery | boolean | Should user query be highlighted in actions title |
| id | string | Id used to connect modal/drawer with body and title |
| keepMounted | boolean | If set modal/drawer will not be unmounted from the DOM when it is hidden, display: none styles will be added instead |
| limit | number | Number of actions displayed at a time |
| lockScroll | boolean | Determines whether scroll should be locked when opened={true}, defaults to true |
| nothingFoundMessage | ReactNode | Message displayed when actions were not found |
| onActionsChange | (actions: SpotlightAction[]) => void | Called when actions change (registered or removed) |
| onQueryChange | (query: string) => void | Called when user enters text in search input |
| onSpotlightClose | () => void | Called when spotlight closes |
| onSpotlightOpen | () => void | Called when spotlight opens |
| overlayProps | ModalBaseOverlayProps | Props added to Overlay component, use configure opacity, background color, styles and other properties |
| padding | number | "xs" | "sm" | "md" | "lg" | "xl" | Key of theme.spacing or any valid CSS value to set content, header and footer padding, 'md' by default |
| portalProps | Omit<PortalProps, "children" | "target" | "withinPortal"> | Props to pass down to the portal when withinPortal is true |
| query | string | Controlled search query |
| radius | number | "xs" | "sm" | "md" | "lg" | "xl" | Key of theme.radius or any valid CSS value to set border-radius, theme.defaultRadius by default |
| returnFocus | boolean | Determines whether focus should be returned to the last active element onClose is called, true by default |
| scrollAreaComponent | FC<{ children: ReactNode; }> | Component used as scrollable container for actions list, defaults to ScrollArea.Autosize |
| searchIcon | ReactNode | Search input icon |
| searchInputProps | TextInputProps | Props spread to search input |
| searchPlaceholder | string | Search input placeholder |
| shadow | MantineShadow | Key of theme.shadows or any valid css box-shadow value, 'xl' by default |
| shortcut | string | string[] | Keyboard shortcut or list of shortcuts to trigger spotlight |
| size | number | "xs" | "sm" | "md" | "lg" | "xl" | Controls content width, 'md' by default |
| tagsToIgnore | string[] | Tags to ignore shortcut hotkeys on. |
| target | string | HTMLElement | Target element or selector where Portal should be rendered, by default new element is created and appended to the document.body |
| transitionProps | Partial<Omit<TransitionProps, "mounted">> | Props added to Transition component that used to animate overlay and body, use to configure duration and animation type, { duration: 200, transition: 'pop' } by default |
| trapFocus | boolean | Determines whether focus should be trapped, true by default |
| triggerOnContentEditable | boolean | Whether shortcuts should trigger based on contentEditable. |
| withOverlay | boolean | Determines whether overlay should be rendered, true by default |
| withinPortal | boolean | Determines whether component should be rendered inside Portal, true by default |
| xOffset | MarginLeft<string | number> | Left/right modal offset, 5vw by default |
| yOffset | MarginTop<string | number> | Top/bottom modal offset, 5vh by default |
| zIndex | number | z-index CSS property of root element, 200 by default |
SpotlightProvider component Styles API
| Name | Static selector | Description |
|---|---|---|
| root | .asuikit-SpotlightProvider-root | Root element |
| inner | .asuikit-SpotlightProvider-inner | Element used to center spotlight, has fixed position, takes entire screen |
| content | .asuikit-SpotlightProvider-content | Spotlight content root element |
| overlay | .asuikit-SpotlightProvider-overlay | Overlay displayed under the Spotlight |
| body | .asuikit-SpotlightProvider-body | Spotlight body, displayed after header |
| searchInput | .asuikit-SpotlightProvider-searchInput | Search input |
| nothingFound | .asuikit-SpotlightProvider-nothingFound | Nothing found message |
| actions | .asuikit-SpotlightProvider-actions | Actions list |
| actionsGroup | .asuikit-SpotlightProvider-actionsGroup | Actions group label |
| action | .asuikit-SpotlightProvider-action | Default action |
| actionIcon | .asuikit-SpotlightProvider-actionIcon | Default action icon wrapper |
| actionBody | .asuikit-SpotlightProvider-actionBody | Default action body |
| actionDescription | .asuikit-SpotlightProvider-actionDescription | Default action description |
| actionHighlight | .asuikit-SpotlightProvider-actionHighlight | Highlighted query in default action title |