or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

built-in-modifiers.mdcore-positioning.mdindex.mdvariants-tree-shaking.mdvirtual-elements.md

built-in-modifiers.mddocs/

0

# Built-in Modifiers

1

2

Nine built-in modifiers that control positioning behavior including automatic flipping, overflow prevention, offsetting, arrow positioning, and style application.

3

4

## Capabilities

5

6

### flip Modifier

7

8

Flips the popper to the opposite placement when it would overflow the boundary.

9

10

```javascript { .api }

11

interface FlipOptions {

12

/** Check overflow on main axis */

13

mainAxis: boolean;

14

/** Check overflow on alternate axis */

15

altAxis: boolean;

16

/** Custom fallback placements to try in order */

17

fallbackPlacements: Array<Placement>;

18

/** Padding around boundary for overflow detection */

19

padding: Padding;

20

/** Boundary element(s) or boundary type */

21

boundary: Boundary;

22

/** Root boundary for overflow checking */

23

rootBoundary: RootBoundary;

24

/** Use alternate boundary context */

25

altBoundary: boolean;

26

/** Allow flipping to variation placements */

27

flipVariations: boolean;

28

/** Allowed auto placements when using 'auto' */

29

allowedAutoPlacements: Array<Placement>;

30

}

31

32

type Boundary = Element | Array<Element> | 'clippingParents';

33

type RootBoundary = 'viewport' | 'document';

34

type Padding = number | { top?: number; right?: number; bottom?: number; left?: number };

35

```

36

37

**Usage Examples:**

38

39

```javascript

40

import { createPopper } from '@popperjs/core';

41

42

// Enable flip with default options

43

const popper = createPopper(button, tooltip, {

44

modifiers: [

45

{

46

name: 'flip',

47

enabled: true,

48

},

49

],

50

});

51

52

// Custom flip configuration

53

const popper = createPopper(button, tooltip, {

54

modifiers: [

55

{

56

name: 'flip',

57

options: {

58

fallbackPlacements: ['top', 'right', 'bottom'],

59

boundary: document.querySelector('.container'),

60

padding: 5,

61

},

62

},

63

],

64

});

65

66

// Disable main axis flipping but allow alt axis

67

const popper = createPopper(button, tooltip, {

68

modifiers: [

69

{

70

name: 'flip',

71

options: {

72

mainAxis: false,

73

altAxis: true,

74

},

75

},

76

],

77

});

78

```

79

80

### preventOverflow Modifier

81

82

Prevents the popper from overflowing its boundary by adjusting its position.

83

84

```javascript { .api }

85

interface PreventOverflowOptions {

86

/** Prevent overflow on main axis */

87

mainAxis: boolean;

88

/** Prevent overflow on alternate axis */

89

altAxis: boolean;

90

/** Boundary for overflow detection */

91

boundary: Boundary;

92

/** Root boundary context */

93

rootBoundary: RootBoundary;

94

/** Use alternate boundary context */

95

altBoundary: boolean;

96

/** Allow popper to overflow to stay near reference */

97

tether: boolean;

98

/** Offset when tether option activates */

99

tetherOffset: TetherOffset;

100

/** Padding around boundary */

101

padding: Padding;

102

}

103

104

type TetherOffset =

105

| number

106

| { mainAxis: number; altAxis: number }

107

| ((args: { popper: Rect; reference: Rect; placement: Placement }) => number | { mainAxis: number; altAxis: number });

108

```

109

110

**Usage Examples:**

111

112

```javascript

113

// Basic overflow prevention

114

const popper = createPopper(button, tooltip, {

115

modifiers: [

116

{

117

name: 'preventOverflow',

118

options: {

119

boundary: 'clippingParents',

120

padding: 8,

121

},

122

},

123

],

124

});

125

126

// Tethering to keep popper near reference

127

const popper = createPopper(button, tooltip, {

128

modifiers: [

129

{

130

name: 'preventOverflow',

131

options: {

132

tether: true,

133

tetherOffset: 10,

134

},

135

},

136

],

137

});

138

139

// Prevent overflow only on main axis

140

const popper = createPopper(button, tooltip, {

141

modifiers: [

142

{

143

name: 'preventOverflow',

144

options: {

145

mainAxis: true,

146

altAxis: false,

147

},

148

},

149

],

150

});

151

```

152

153

### offset Modifier

154

155

Applies offset to the popper position along main and alternate axes.

156

157

```javascript { .api }

158

interface OffsetOptions {

159

/** Offset specification as array [skidding, distance] or function */

160

offset: OffsetsFunction | [number?, number?];

161

}

162

163

type OffsetsFunction = (args: {

164

popper: Rect;

165

reference: Rect;

166

placement: Placement;

167

}) => [number?, number?];

168

```

169

170

**Usage Examples:**

171

172

```javascript

173

// Static offset [skidding, distance]

174

const popper = createPopper(button, tooltip, {

175

modifiers: [

176

{

177

name: 'offset',

178

options: {

179

offset: [0, 8], // 0 skidding, 8px distance

180

},

181

},

182

],

183

});

184

185

// Dynamic offset based on context

186

const popper = createPopper(button, tooltip, {

187

modifiers: [

188

{

189

name: 'offset',

190

options: {

191

offset: ({ reference, popper, placement }) => {

192

// Larger offset for larger references

193

const distance = reference.width > 100 ? 12 : 6;

194

return [0, distance];

195

},

196

},

197

},

198

],

199

});

200

```

201

202

### arrow Modifier

203

204

Positions an arrow element to point to the reference element.

205

206

```javascript { .api }

207

interface ArrowOptions {

208

/** Arrow element or selector */

209

element: HTMLElement | string | null;

210

/** Padding around arrow positioning */

211

padding: Padding | ((args: { popper: Rect; reference: Rect; placement: Placement }) => Padding);

212

}

213

```

214

215

**Usage Examples:**

216

217

```javascript

218

// Arrow with element reference

219

const arrowElement = tooltip.querySelector('.arrow');

220

const popper = createPopper(button, tooltip, {

221

modifiers: [

222

{

223

name: 'arrow',

224

options: {

225

element: arrowElement,

226

padding: 5,

227

},

228

},

229

],

230

});

231

232

// Arrow with CSS selector

233

const popper = createPopper(button, tooltip, {

234

modifiers: [

235

{

236

name: 'arrow',

237

options: {

238

element: '.arrow',

239

padding: { left: 10, right: 10 },

240

},

241

},

242

],

243

});

244

245

// Dynamic arrow padding

246

const popper = createPopper(button, tooltip, {

247

modifiers: [

248

{

249

name: 'arrow',

250

options: {

251

element: '.arrow',

252

padding: ({ placement }) => placement.startsWith('top') ? 8 : 4,

253

},

254

},

255

],

256

});

257

```

258

259

### computeStyles Modifier

260

261

Computes CSS styles for positioning the popper element.

262

263

```javascript { .api }

264

interface ComputeStylesOptions {

265

/** GPU acceleration using transform3d */

266

gpuAcceleration: boolean;

267

/** Adaptive positioning that adjusts for device pixel ratio */

268

adaptive: boolean;

269

/** Round pixel values to avoid blurry rendering */

270

roundOffsets: boolean;

271

}

272

```

273

274

**Usage Examples:**

275

276

```javascript

277

// Disable GPU acceleration

278

const popper = createPopper(button, tooltip, {

279

modifiers: [

280

{

281

name: 'computeStyles',

282

options: {

283

gpuAcceleration: false,

284

},

285

},

286

],

287

});

288

289

// Configure pixel rounding

290

const popper = createPopper(button, tooltip, {

291

modifiers: [

292

{

293

name: 'computeStyles',

294

options: {

295

roundOffsets: true,

296

adaptive: false,

297

},

298

},

299

],

300

});

301

```

302

303

### applyStyles Modifier

304

305

Applies computed styles to the popper and arrow elements.

306

307

```javascript { .api }

308

// applyStyles has no configurable options

309

// It automatically applies styles from computeStyles modifier

310

```

311

312

**Usage Examples:**

313

314

```javascript

315

// applyStyles is included by default in full createPopper

316

// Disable if you want to handle styles manually

317

const popper = createPopper(button, tooltip, {

318

modifiers: [

319

{

320

name: 'applyStyles',

321

enabled: false,

322

},

323

],

324

});

325

326

// Access computed styles from state instead

327

const styles = popper.state.styles.popper;

328

Object.assign(tooltip.style, styles);

329

```

330

331

### eventListeners Modifier

332

333

Manages scroll and resize event listeners for automatic position updates.

334

335

```javascript { .api }

336

interface EventListenersOptions {

337

/** Listen for scroll events */

338

scroll: boolean;

339

/** Listen for resize events */

340

resize: boolean;

341

}

342

```

343

344

**Usage Examples:**

345

346

```javascript

347

// Disable automatic resize handling

348

const popper = createPopper(button, tooltip, {

349

modifiers: [

350

{

351

name: 'eventListeners',

352

options: {

353

resize: false,

354

scroll: true,

355

},

356

},

357

],

358

});

359

360

// Disable all automatic event handling

361

const popper = createPopper(button, tooltip, {

362

modifiers: [

363

{

364

name: 'eventListeners',

365

enabled: false,

366

},

367

],

368

});

369

```

370

371

### hide Modifier

372

373

Detects when the reference element is not visible and hides the popper.

374

375

```javascript { .api }

376

// hide modifier has no configurable options

377

// It sets data-popper-reference-hidden and data-popper-escaped attributes

378

```

379

380

**Usage Examples:**

381

382

```javascript

383

// hide modifier is included by default

384

// Access visibility state from modifiersData

385

const hideData = popper.state.modifiersData.hide;

386

if (hideData?.isReferenceHidden) {

387

console.log('Reference element is not visible');

388

}

389

390

// Style based on visibility attributes

391

const css = `

392

[data-popper-reference-hidden] {

393

visibility: hidden;

394

pointer-events: none;

395

}

396

397

[data-popper-escaped] {

398

opacity: 0.5;

399

}

400

`;

401

```

402

403

### popperOffsets Modifier

404

405

Computes the basic positioning offsets for the popper element.

406

407

```javascript { .api }

408

// popperOffsets modifier has no configurable options

409

// It computes the base x, y coordinates for popper positioning

410

```

411

412

**Usage Examples:**

413

414

```javascript

415

// popperOffsets is a core modifier required by most others

416

// Access computed offsets from state

417

const offsets = popper.state.modifiersData.popperOffsets;

418

console.log('Popper position:', offsets.x, offsets.y);

419

420

// This modifier should not be disabled as it's foundational

421

```

422

423

## Modifier System

424

425

### Modifier Interface

426

427

Structure that all modifiers must follow.

428

429

```javascript { .api }

430

interface Modifier<Name, Options> {

431

/** Unique name identifier */

432

name: Name;

433

/** Whether the modifier is enabled */

434

enabled: boolean;

435

/** Execution phase during update cycle */

436

phase: ModifierPhases;

437

/** Required modifier names that must run before this one */

438

requires?: Array<string>;

439

/** Optional modifier names that should run before if present */

440

requiresIfExists?: Array<string>;

441

/** Main modifier function executed during updates */

442

fn: (args: ModifierArguments<Options>) => State | void;

443

/** Effect function for setup/cleanup (runs once) */

444

effect?: (args: ModifierArguments<Options>) => (() => void) | void;

445

/** Default options for the modifier */

446

options?: Partial<Options>;

447

/** Static data for the modifier */

448

data?: any;

449

}

450

451

interface ModifierArguments<Options> {

452

state: State;

453

instance: Instance;

454

options: Partial<Options>;

455

name: string;

456

}

457

458

type ModifierPhases =

459

| 'beforeRead' | 'read' | 'afterRead'

460

| 'beforeMain' | 'main' | 'afterMain'

461

| 'beforeWrite' | 'write' | 'afterWrite';

462

```

463

464

**Usage Examples:**

465

466

```javascript

467

// Custom modifier example

468

const customModifier = {

469

name: 'customOffset',

470

enabled: true,

471

phase: 'main',

472

requires: ['popperOffsets'],

473

fn({ state }) {

474

// Apply custom offset logic

475

state.modifiersData.popperOffsets.y += 10;

476

},

477

};

478

479

const popper = createPopper(button, tooltip, {

480

modifiers: [customModifier],

481

});

482

```