0
# Core Positioning
1
2
Core createPopper function and instance management for tooltip and popover positioning with automatic updates and lifecycle management.
3
4
## Capabilities
5
6
### createPopper Function
7
8
Creates a popper instance to position a popper element relative to a reference element.
9
10
```javascript { .api }
11
/**
12
* Creates a popper instance to position a popper element relative to a reference element
13
* @param reference - Reference element or virtual element to position relative to
14
* @param popper - HTML element to be positioned (the tooltip/popover)
15
* @param options - Configuration options for positioning behavior
16
* @returns Instance object with methods to control the popper
17
*/
18
function createPopper(
19
reference: Element | VirtualElement,
20
popper: HTMLElement,
21
options?: Partial<Options>
22
): Instance;
23
```
24
25
**Usage Examples:**
26
27
```javascript
28
import { createPopper } from '@popperjs/core';
29
30
// Basic usage
31
const button = document.querySelector('#button');
32
const tooltip = document.querySelector('#tooltip');
33
const popperInstance = createPopper(button, tooltip);
34
35
// With options
36
const popperInstance = createPopper(button, tooltip, {
37
placement: 'bottom-start',
38
strategy: 'fixed',
39
modifiers: [
40
{
41
name: 'preventOverflow',
42
options: {
43
boundary: 'clippingParents',
44
},
45
},
46
],
47
});
48
49
// With callback on first update
50
const popperInstance = createPopper(button, tooltip, {
51
placement: 'top',
52
onFirstUpdate: (state) => {
53
console.log('Popper positioned at:', state.placement);
54
},
55
});
56
```
57
58
### Instance Management
59
60
The popper instance provides methods for controlling positioning and lifecycle.
61
62
```javascript { .api }
63
interface Instance {
64
/** Current state of the popper */
65
state: State;
66
/** Destroy the popper instance and cleanup event listeners */
67
destroy(): void;
68
/** Force immediate synchronous update of popper position */
69
forceUpdate(): void;
70
/** Asynchronously update popper position (debounced) */
71
update(): Promise<Partial<State>>;
72
/** Update popper options and recalculate position */
73
setOptions(setOptionsAction: SetAction<Partial<Options>>): Promise<Partial<State>>;
74
}
75
76
type SetAction<S> = S | ((prev: S) => S);
77
```
78
79
**Usage Examples:**
80
81
```javascript
82
// Update positioning manually
83
await popperInstance.update();
84
85
// Force immediate update (synchronous)
86
popperInstance.forceUpdate();
87
88
// Update options
89
await popperInstance.setOptions({
90
placement: 'bottom',
91
});
92
93
// Update options with function
94
await popperInstance.setOptions((prevOptions) => ({
95
...prevOptions,
96
modifiers: [...prevOptions.modifiers, { name: 'flip', enabled: true }],
97
}));
98
99
// Cleanup
100
popperInstance.destroy();
101
```
102
103
### Options Configuration
104
105
Configuration object for customizing popper behavior.
106
107
```javascript { .api }
108
interface Options {
109
/** Initial placement of the popper relative to reference */
110
placement: Placement;
111
/** Array of modifiers to customize positioning behavior */
112
modifiers: Array<Partial<Modifier<any, any>>>;
113
/** CSS positioning strategy to use */
114
strategy: PositioningStrategy;
115
/** Callback executed after first update */
116
onFirstUpdate?: (state: Partial<State>) => void;
117
}
118
119
type Placement =
120
| 'auto' | 'auto-start' | 'auto-end'
121
| 'top' | 'top-start' | 'top-end'
122
| 'bottom' | 'bottom-start' | 'bottom-end'
123
| 'right' | 'right-start' | 'right-end'
124
| 'left' | 'left-start' | 'left-end';
125
126
type PositioningStrategy = 'absolute' | 'fixed';
127
```
128
129
**Usage Examples:**
130
131
```javascript
132
// Different placement options
133
const topPopper = createPopper(button, tooltip, { placement: 'top' });
134
const rightStartPopper = createPopper(button, tooltip, { placement: 'right-start' });
135
const autoPopper = createPopper(button, tooltip, { placement: 'auto' });
136
137
// Fixed positioning (useful in modals)
138
const fixedPopper = createPopper(button, tooltip, {
139
strategy: 'fixed',
140
placement: 'bottom',
141
});
142
143
// Custom modifiers
144
const customPopper = createPopper(button, tooltip, {
145
modifiers: [
146
{
147
name: 'offset',
148
options: { offset: [0, 10] },
149
},
150
{
151
name: 'flip',
152
enabled: false,
153
},
154
],
155
});
156
```
157
158
### State Object
159
160
Complete state information about the popper instance.
161
162
```javascript { .api }
163
interface State {
164
/** Reference to DOM elements */
165
elements: {
166
reference: Element | VirtualElement;
167
popper: HTMLElement;
168
arrow?: HTMLElement;
169
};
170
/** Current options configuration */
171
options: Options;
172
/** Current computed placement */
173
placement: Placement;
174
/** CSS positioning strategy being used */
175
strategy: PositioningStrategy;
176
/** Ordered list of active modifiers */
177
orderedModifiers: Array<Modifier<any, any>>;
178
/** Computed rectangles for positioning */
179
rects: StateRects;
180
/** Scroll parent elements for both reference and popper */
181
scrollParents: {
182
reference: Array<Element | Window | VisualViewport>;
183
popper: Array<Element | Window | VisualViewport>;
184
};
185
/** Computed CSS styles to apply */
186
styles: { [key: string]: Partial<CSSStyleDeclaration> };
187
/** HTML attributes to apply */
188
attributes: { [key: string]: { [key: string]: string | boolean } };
189
/** Data from individual modifiers */
190
modifiersData: { [key: string]: any };
191
/** Whether positioning needs to be recalculated */
192
reset: boolean;
193
}
194
195
interface StateRects {
196
reference: Rect;
197
popper: Rect;
198
}
199
200
interface Rect {
201
width: number;
202
height: number;
203
x: number;
204
y: number;
205
}
206
```
207
208
**Usage Examples:**
209
210
```javascript
211
// Access current state
212
const { placement, rects } = popperInstance.state;
213
console.log('Current placement:', placement);
214
console.log('Popper dimensions:', rects.popper);
215
216
// Check modifier data
217
const offsetData = popperInstance.state.modifiersData.offset;
218
console.log('Applied offset:', offsetData);
219
220
// Get applied styles
221
const popperStyles = popperInstance.state.styles.popper;
222
console.log('Transform applied:', popperStyles.transform);
223
```
224
225
### Error Handling
226
227
Common error scenarios and handling patterns.
228
229
```javascript
230
// Check if elements are valid before creating popper
231
function createSafePopper(referenceSelector, popperSelector, options) {
232
const reference = document.querySelector(referenceSelector);
233
const popper = document.querySelector(popperSelector);
234
235
if (!reference || !popper) {
236
throw new Error('Reference or popper element not found');
237
}
238
239
// Popper will handle invalid elements gracefully
240
return createPopper(reference, popper, options);
241
}
242
243
// Handle destroyed instances
244
let popperInstance = createPopper(button, tooltip);
245
246
// Later...
247
popperInstance.destroy();
248
popperInstance = null; // Clear reference
249
250
// Attempting to use destroyed instance will not throw but has no effect
251
```