Command center components for react and Mantine
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
The compound components provide granular control for building custom spotlight interfaces. Each component handles a specific aspect of the spotlight functionality and can be combined to create fully customized implementations.
When using individual compound components, you must import the required styles:
/* Standard styles */
@import "@mantine/spotlight/styles.css";
/* Or layer styles (alternative) */
@import "@mantine/spotlight/styles.layer.css";Root container component that provides the modal overlay, keyboard handling, and context for child components.
/**
* Root container component with modal functionality and keyboard handling
* @param props - Configuration props for the root component
* @returns JSX element containing the modal container and context provider
*/
function SpotlightRoot(props: SpotlightRootProps): JSX.Element;
interface SpotlightRootProps extends StylesApiProps<SpotlightRootFactory>, Omit<ModalProps, 'opened' | 'onClose' | 'withCloseButton'> {
/** Spotlight store, can be used to create multiple instances */
store?: SpotlightStore;
/** Controlled Spotlight search query */
query?: string;
/** Called when query changes */
onQueryChange?: (query: string) => void;
/** Determines whether the search query should be cleared when the spotlight is closed */
clearQueryOnClose?: boolean;
/** Keyboard shortcut or list of shortcuts to trigger spotlight */
shortcut?: string | string[] | null;
/** List of tags which when focused will be ignored by shortcut */
tagsToIgnore?: string[];
/** Determines whether shortcut should trigger based in contentEditable */
triggerOnContentEditable?: boolean;
/** If set, spotlight will not be rendered */
disabled?: boolean;
/** Called when spotlight opens */
onSpotlightOpen?: () => void;
/** Called when spotlight closes */
onSpotlightClose?: () => void;
/** Forces opened state, useful for tests */
forceOpened?: boolean;
/** Determines whether spotlight should be closed when one of the actions is triggered */
closeOnActionTrigger?: boolean;
/** Spotlight content max-height. Ignored unless scrollable prop is set */
maxHeight?: React.CSSProperties['maxHeight'];
/** Determines whether the actions list should be scrollable */
scrollable?: boolean;
}Search input component with keyboard navigation support for arrow keys and Enter.
/**
* Search input component with keyboard navigation
* @param props - Configuration props for the search input
* @returns JSX element containing the search input
*/
function SpotlightSearch(props: SpotlightSearchProps): JSX.Element;
interface SpotlightSearchProps extends BoxProps, Omit<InputProps, 'classNames' | 'styles' | 'vars' | 'variant'>, CompoundStylesApiProps<SpotlightSearchFactory>, ElementProps<'input', 'size'> {}Scrollable container component for displaying actions with auto-sizing and scroll area management.
/**
* Scrollable container for actions with auto-sizing
* @param props - Configuration props for the actions list
* @returns JSX element containing the scrollable actions container
*/
function SpotlightActionsList(props: SpotlightActionsListProps): JSX.Element;
interface SpotlightActionsListProps extends BoxProps, CompoundStylesApiProps<SpotlightActionsListFactory>, ElementProps<'div'> {}Individual action button component with highlighting, sections, and click handling.
/**
* Individual action button with highlighting and sections
* @param props - Configuration props for the action button
* @returns JSX element containing the action button
*/
function SpotlightAction(props: SpotlightActionProps): JSX.Element;
interface SpotlightActionProps extends BoxProps, CompoundStylesApiProps<SpotlightActionFactory>, ElementProps<'button'> {
/** Action label, pass string to use in default filter */
label?: string;
/** Action description, pass string to use in default filter */
description?: string;
/** Section displayed on the left side of the label, for example, icon */
leftSection?: React.ReactNode;
/** Section displayed on the right side of the label, for example, hotkey */
rightSection?: React.ReactNode;
/** Children override default action elements, if passed, label, description and sections are hidden */
children?: React.ReactNode;
/** Determines whether left and right sections should have dimmed styles */
dimmedSections?: boolean;
/** Determines whether search query should be highlighted in action label */
highlightQuery?: boolean;
/** Key of theme.colors of any valid CSS color that will be used to highlight search query */
highlightColor?: MantineColor;
/** Determines whether the spotlight should be closed when action is triggered, overrides closeOnActionTrigger prop set on Spotlight */
closeSpotlightOnTrigger?: boolean;
/** Keywords that are used for default filtering, not displayed anywhere, can be a string: "react,router,javascript" or an array: ['react', 'router', 'javascript'] */
keywords?: string | string[];
}Empty state component displayed when no actions match the current search query.
/**
* Empty state component when no actions match
* @param props - Configuration props for the empty state
* @returns JSX element containing the empty state content
*/
function SpotlightEmpty(props: SpotlightEmptyProps): JSX.Element;
interface SpotlightEmptyProps extends BoxProps, CompoundStylesApiProps<SpotlightEmptyFactory>, ElementProps<'div'> {}Footer area component for displaying additional information or controls.
/**
* Footer area component
* @param props - Configuration props for the footer
* @returns JSX element containing the footer content
*/
function SpotlightFooter(props: SpotlightFooterProps): JSX.Element;
interface SpotlightFooterProps extends BoxProps, CompoundStylesApiProps<SpotlightFooterFactory>, ElementProps<'div'> {}Group container component for organizing related actions with a label.
/**
* Group container for related actions with label
* @param props - Configuration props for the actions group
* @returns JSX element containing the grouped actions
*/
function SpotlightActionsGroup(props: SpotlightActionsGroupProps): JSX.Element;
interface SpotlightActionsGroupProps extends BoxProps, CompoundStylesApiProps<SpotlightActionsGroupFactory>, ElementProps<'div'> {
/** Spotlight.Action components */
children?: React.ReactNode;
/** Group label */
label?: string;
}import {
SpotlightRoot,
SpotlightSearch,
SpotlightActionsList,
SpotlightAction,
SpotlightEmpty,
SpotlightFooter,
createSpotlight
} from "@mantine/spotlight";
function CustomSpotlight() {
const [store, spotlight] = createSpotlight();
const actions = [
{ id: "1", label: "Home", description: "Go home" },
{ id: "2", label: "Settings", description: "Open settings" },
];
return (
<div>
<button onClick={spotlight.open}>Open Custom Spotlight</button>
<SpotlightRoot store={store} shortcut="ctrl + k">
<SpotlightSearch placeholder="Type to search..." />
<SpotlightActionsList>
{actions.map((action) => (
<SpotlightAction
key={action.id}
label={action.label}
description={action.description}
onClick={() => console.log(action.label)}
/>
))}
<SpotlightEmpty>No results found</SpotlightEmpty>
</SpotlightActionsList>
<SpotlightFooter>
Press ↵ to select, ↑↓ to navigate
</SpotlightFooter>
</SpotlightRoot>
</div>
);
}import { SpotlightAction } from "@mantine/spotlight";
import { IconHome, IconKeyboard } from "@tabler/icons-react";
function ActionWithSections() {
return (
<SpotlightAction
label="Home"
description="Navigate to home page"
leftSection={<IconHome size={16} />}
rightSection={<IconKeyboard size={16} />}
keywords={["home", "main", "start"]}
highlightQuery
onClick={() => navigate("/")}
/>
);
}import { SpotlightActionsGroup, SpotlightAction } from "@mantine/spotlight";
function GroupedActions() {
return (
<SpotlightActionsGroup label="Navigation">
<SpotlightAction
label="Home"
description="Go to home page"
onClick={() => navigate("/")}
/>
<SpotlightAction
label="Settings"
description="Open settings"
onClick={() => navigate("/settings")}
/>
</SpotlightActionsGroup>
);
}// SpotlightRoot defaults
const rootDefaults = {
size: 600,
yOffset: 80,
zIndex: getDefaultZIndex('max'),
overlayProps: { backgroundOpacity: 0.35, blur: 7 },
transitionProps: { duration: 200, transition: 'pop' },
clearQueryOnClose: true,
closeOnActionTrigger: true,
shortcut: 'mod + K',
maxHeight: 400,
};
// SpotlightSearch defaults
const searchDefaults = {
size: 'lg',
};
// SpotlightAction defaults
const actionDefaults = {
dimmedSections: true,
highlightQuery: false,
};