or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

compound-components.mdindex.mdmain-component.mdstore-management.mdutilities.md

compound-components.mddocs/

0

# Compound Components

1

2

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.

3

4

## CSS Imports

5

6

When using individual compound components, you must import the required styles:

7

8

```css

9

/* Standard styles */

10

@import "@mantine/spotlight/styles.css";

11

12

/* Or layer styles (alternative) */

13

@import "@mantine/spotlight/styles.layer.css";

14

```

15

16

## Capabilities

17

18

### SpotlightRoot

19

20

Root container component that provides the modal overlay, keyboard handling, and context for child components.

21

22

```typescript { .api }

23

/**

24

* Root container component with modal functionality and keyboard handling

25

* @param props - Configuration props for the root component

26

* @returns JSX element containing the modal container and context provider

27

*/

28

function SpotlightRoot(props: SpotlightRootProps): JSX.Element;

29

30

interface SpotlightRootProps extends StylesApiProps<SpotlightRootFactory>, Omit<ModalProps, 'opened' | 'onClose' | 'withCloseButton'> {

31

/** Spotlight store, can be used to create multiple instances */

32

store?: SpotlightStore;

33

/** Controlled Spotlight search query */

34

query?: string;

35

/** Called when query changes */

36

onQueryChange?: (query: string) => void;

37

/** Determines whether the search query should be cleared when the spotlight is closed */

38

clearQueryOnClose?: boolean;

39

/** Keyboard shortcut or list of shortcuts to trigger spotlight */

40

shortcut?: string | string[] | null;

41

/** List of tags which when focused will be ignored by shortcut */

42

tagsToIgnore?: string[];

43

/** Determines whether shortcut should trigger based in contentEditable */

44

triggerOnContentEditable?: boolean;

45

/** If set, spotlight will not be rendered */

46

disabled?: boolean;

47

/** Called when spotlight opens */

48

onSpotlightOpen?: () => void;

49

/** Called when spotlight closes */

50

onSpotlightClose?: () => void;

51

/** Forces opened state, useful for tests */

52

forceOpened?: boolean;

53

/** Determines whether spotlight should be closed when one of the actions is triggered */

54

closeOnActionTrigger?: boolean;

55

/** Spotlight content max-height. Ignored unless scrollable prop is set */

56

maxHeight?: React.CSSProperties['maxHeight'];

57

/** Determines whether the actions list should be scrollable */

58

scrollable?: boolean;

59

}

60

```

61

62

### SpotlightSearch

63

64

Search input component with keyboard navigation support for arrow keys and Enter.

65

66

```typescript { .api }

67

/**

68

* Search input component with keyboard navigation

69

* @param props - Configuration props for the search input

70

* @returns JSX element containing the search input

71

*/

72

function SpotlightSearch(props: SpotlightSearchProps): JSX.Element;

73

74

interface SpotlightSearchProps extends BoxProps, Omit<InputProps, 'classNames' | 'styles' | 'vars' | 'variant'>, CompoundStylesApiProps<SpotlightSearchFactory>, ElementProps<'input', 'size'> {}

75

```

76

77

### SpotlightActionsList

78

79

Scrollable container component for displaying actions with auto-sizing and scroll area management.

80

81

```typescript { .api }

82

/**

83

* Scrollable container for actions with auto-sizing

84

* @param props - Configuration props for the actions list

85

* @returns JSX element containing the scrollable actions container

86

*/

87

function SpotlightActionsList(props: SpotlightActionsListProps): JSX.Element;

88

89

interface SpotlightActionsListProps extends BoxProps, CompoundStylesApiProps<SpotlightActionsListFactory>, ElementProps<'div'> {}

90

```

91

92

### SpotlightAction

93

94

Individual action button component with highlighting, sections, and click handling.

95

96

```typescript { .api }

97

/**

98

* Individual action button with highlighting and sections

99

* @param props - Configuration props for the action button

100

* @returns JSX element containing the action button

101

*/

102

function SpotlightAction(props: SpotlightActionProps): JSX.Element;

103

104

interface SpotlightActionProps extends BoxProps, CompoundStylesApiProps<SpotlightActionFactory>, ElementProps<'button'> {

105

/** Action label, pass string to use in default filter */

106

label?: string;

107

/** Action description, pass string to use in default filter */

108

description?: string;

109

/** Section displayed on the left side of the label, for example, icon */

110

leftSection?: React.ReactNode;

111

/** Section displayed on the right side of the label, for example, hotkey */

112

rightSection?: React.ReactNode;

113

/** Children override default action elements, if passed, label, description and sections are hidden */

114

children?: React.ReactNode;

115

/** Determines whether left and right sections should have dimmed styles */

116

dimmedSections?: boolean;

117

/** Determines whether search query should be highlighted in action label */

118

highlightQuery?: boolean;

119

/** Key of theme.colors of any valid CSS color that will be used to highlight search query */

120

highlightColor?: MantineColor;

121

/** Determines whether the spotlight should be closed when action is triggered, overrides closeOnActionTrigger prop set on Spotlight */

122

closeSpotlightOnTrigger?: boolean;

123

/** Keywords that are used for default filtering, not displayed anywhere, can be a string: "react,router,javascript" or an array: ['react', 'router', 'javascript'] */

124

keywords?: string | string[];

125

}

126

```

127

128

### SpotlightEmpty

129

130

Empty state component displayed when no actions match the current search query.

131

132

```typescript { .api }

133

/**

134

* Empty state component when no actions match

135

* @param props - Configuration props for the empty state

136

* @returns JSX element containing the empty state content

137

*/

138

function SpotlightEmpty(props: SpotlightEmptyProps): JSX.Element;

139

140

interface SpotlightEmptyProps extends BoxProps, CompoundStylesApiProps<SpotlightEmptyFactory>, ElementProps<'div'> {}

141

```

142

143

### SpotlightFooter

144

145

Footer area component for displaying additional information or controls.

146

147

```typescript { .api }

148

/**

149

* Footer area component

150

* @param props - Configuration props for the footer

151

* @returns JSX element containing the footer content

152

*/

153

function SpotlightFooter(props: SpotlightFooterProps): JSX.Element;

154

155

interface SpotlightFooterProps extends BoxProps, CompoundStylesApiProps<SpotlightFooterFactory>, ElementProps<'div'> {}

156

```

157

158

### SpotlightActionsGroup

159

160

Group container component for organizing related actions with a label.

161

162

```typescript { .api }

163

/**

164

* Group container for related actions with label

165

* @param props - Configuration props for the actions group

166

* @returns JSX element containing the grouped actions

167

*/

168

function SpotlightActionsGroup(props: SpotlightActionsGroupProps): JSX.Element;

169

170

interface SpotlightActionsGroupProps extends BoxProps, CompoundStylesApiProps<SpotlightActionsGroupFactory>, ElementProps<'div'> {

171

/** Spotlight.Action components */

172

children?: React.ReactNode;

173

/** Group label */

174

label?: string;

175

}

176

```

177

178

## Usage Examples

179

180

### Custom Spotlight Implementation

181

182

```typescript

183

import {

184

SpotlightRoot,

185

SpotlightSearch,

186

SpotlightActionsList,

187

SpotlightAction,

188

SpotlightEmpty,

189

SpotlightFooter,

190

createSpotlight

191

} from "@mantine/spotlight";

192

193

function CustomSpotlight() {

194

const [store, spotlight] = createSpotlight();

195

const actions = [

196

{ id: "1", label: "Home", description: "Go home" },

197

{ id: "2", label: "Settings", description: "Open settings" },

198

];

199

200

return (

201

<div>

202

<button onClick={spotlight.open}>Open Custom Spotlight</button>

203

204

<SpotlightRoot store={store} shortcut="ctrl + k">

205

<SpotlightSearch placeholder="Type to search..." />

206

207

<SpotlightActionsList>

208

{actions.map((action) => (

209

<SpotlightAction

210

key={action.id}

211

label={action.label}

212

description={action.description}

213

onClick={() => console.log(action.label)}

214

/>

215

))}

216

<SpotlightEmpty>No results found</SpotlightEmpty>

217

</SpotlightActionsList>

218

219

<SpotlightFooter>

220

Press ↵ to select, ↑↓ to navigate

221

</SpotlightFooter>

222

</SpotlightRoot>

223

</div>

224

);

225

}

226

```

227

228

### Actions with Sections

229

230

```typescript

231

import { SpotlightAction } from "@mantine/spotlight";

232

import { IconHome, IconKeyboard } from "@tabler/icons-react";

233

234

function ActionWithSections() {

235

return (

236

<SpotlightAction

237

label="Home"

238

description="Navigate to home page"

239

leftSection={<IconHome size={16} />}

240

rightSection={<IconKeyboard size={16} />}

241

keywords={["home", "main", "start"]}

242

highlightQuery

243

onClick={() => navigate("/")}

244

/>

245

);

246

}

247

```

248

249

### Grouped Actions

250

251

```typescript

252

import { SpotlightActionsGroup, SpotlightAction } from "@mantine/spotlight";

253

254

function GroupedActions() {

255

return (

256

<SpotlightActionsGroup label="Navigation">

257

<SpotlightAction

258

label="Home"

259

description="Go to home page"

260

onClick={() => navigate("/")}

261

/>

262

<SpotlightAction

263

label="Settings"

264

description="Open settings"

265

onClick={() => navigate("/settings")}

266

/>

267

</SpotlightActionsGroup>

268

);

269

}

270

```

271

272

## Default Props

273

274

```typescript { .api }

275

// SpotlightRoot defaults

276

const rootDefaults = {

277

size: 600,

278

yOffset: 80,

279

zIndex: getDefaultZIndex('max'),

280

overlayProps: { backgroundOpacity: 0.35, blur: 7 },

281

transitionProps: { duration: 200, transition: 'pop' },

282

clearQueryOnClose: true,

283

closeOnActionTrigger: true,

284

shortcut: 'mod + K',

285

maxHeight: 400,

286

};

287

288

// SpotlightSearch defaults

289

const searchDefaults = {

290

size: 'lg',

291

};

292

293

// SpotlightAction defaults

294

const actionDefaults = {

295

dimmedSections: true,

296

highlightQuery: false,

297

};

298

```