@zag-js/popover 0.82.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -8,8 +8,8 @@ var core = require('@zag-js/core');
8
8
  var dismissable = require('@zag-js/dismissable');
9
9
  var focusTrap = require('@zag-js/focus-trap');
10
10
  var removeScroll = require('@zag-js/remove-scroll');
11
- var utils = require('@zag-js/utils');
12
11
  var types = require('@zag-js/types');
12
+ var utils = require('@zag-js/utils');
13
13
 
14
14
  // src/popover.anatomy.ts
15
15
  var anatomy = anatomy$1.createAnatomy("popover").parts(
@@ -25,33 +25,30 @@ var anatomy = anatomy$1.createAnatomy("popover").parts(
25
25
  "closeTrigger"
26
26
  );
27
27
  var parts = anatomy.build();
28
- var dom = domQuery.createScope({
29
- getAnchorId: (ctx) => ctx.ids?.anchor ?? `popover:${ctx.id}:anchor`,
30
- getTriggerId: (ctx) => ctx.ids?.trigger ?? `popover:${ctx.id}:trigger`,
31
- getContentId: (ctx) => ctx.ids?.content ?? `popover:${ctx.id}:content`,
32
- getPositionerId: (ctx) => ctx.ids?.positioner ?? `popover:${ctx.id}:popper`,
33
- getArrowId: (ctx) => ctx.ids?.arrow ?? `popover:${ctx.id}:arrow`,
34
- getTitleId: (ctx) => ctx.ids?.title ?? `popover:${ctx.id}:title`,
35
- getDescriptionId: (ctx) => ctx.ids?.description ?? `popover:${ctx.id}:desc`,
36
- getCloseTriggerId: (ctx) => ctx.ids?.closeTrigger ?? `popover:${ctx.id}:close`,
37
- getAnchorEl: (ctx) => dom.getById(ctx, dom.getAnchorId(ctx)),
38
- getTriggerEl: (ctx) => dom.getById(ctx, dom.getTriggerId(ctx)),
39
- getContentEl: (ctx) => dom.getById(ctx, dom.getContentId(ctx)),
40
- getPositionerEl: (ctx) => dom.getById(ctx, dom.getPositionerId(ctx)),
41
- getTitleEl: (ctx) => dom.getById(ctx, dom.getTitleId(ctx)),
42
- getDescriptionEl: (ctx) => dom.getById(ctx, dom.getDescriptionId(ctx)),
43
- getFocusableEls: (ctx) => domQuery.getFocusables(dom.getContentEl(ctx)),
44
- getFirstFocusableEl: (ctx) => dom.getFocusableEls(ctx)[0]
45
- });
28
+ var getAnchorId = (scope) => scope.ids?.anchor ?? `popover:${scope.id}:anchor`;
29
+ var getTriggerId = (scope) => scope.ids?.trigger ?? `popover:${scope.id}:trigger`;
30
+ var getContentId = (scope) => scope.ids?.content ?? `popover:${scope.id}:content`;
31
+ var getPositionerId = (scope) => scope.ids?.positioner ?? `popover:${scope.id}:popper`;
32
+ var getArrowId = (scope) => scope.ids?.arrow ?? `popover:${scope.id}:arrow`;
33
+ var getTitleId = (scope) => scope.ids?.title ?? `popover:${scope.id}:title`;
34
+ var getDescriptionId = (scope) => scope.ids?.description ?? `popover:${scope.id}:desc`;
35
+ var getCloseTriggerId = (scope) => scope.ids?.closeTrigger ?? `popover:${scope.id}:close`;
36
+ var getAnchorEl = (scope) => scope.getById(getAnchorId(scope));
37
+ var getTriggerEl = (scope) => scope.getById(getTriggerId(scope));
38
+ var getContentEl = (scope) => scope.getById(getContentId(scope));
39
+ var getPositionerEl = (scope) => scope.getById(getPositionerId(scope));
40
+ var getTitleEl = (scope) => scope.getById(getTitleId(scope));
41
+ var getDescriptionEl = (scope) => scope.getById(getDescriptionId(scope));
46
42
 
47
43
  // src/popover.connect.ts
48
- function connect(state, send, normalize) {
44
+ function connect(service, normalize) {
45
+ const { state, context, send, computed, prop, scope } = service;
49
46
  const open = state.matches("open");
50
- const currentPlacement = state.context.currentPlacement;
51
- const portalled = state.context.currentPortalled;
52
- const rendered = state.context.renderedElements;
47
+ const currentPlacement = context.get("currentPlacement");
48
+ const portalled = computed("currentPortalled");
49
+ const rendered = context.get("renderedElements");
53
50
  const popperStyles = popper.getPlacementStyles({
54
- ...state.context.positioning,
51
+ ...prop("positioning"),
55
52
  placement: currentPlacement
56
53
  });
57
54
  return {
@@ -59,44 +56,44 @@ function connect(state, send, normalize) {
59
56
  open,
60
57
  setOpen(nextOpen) {
61
58
  if (nextOpen === open) return;
62
- send(nextOpen ? "OPEN" : "CLOSE");
59
+ send({ type: nextOpen ? "OPEN" : "CLOSE" });
63
60
  },
64
61
  reposition(options = {}) {
65
62
  send({ type: "POSITIONING.SET", options });
66
63
  },
67
64
  getArrowProps() {
68
65
  return normalize.element({
69
- id: dom.getArrowId(state.context),
66
+ id: getArrowId(scope),
70
67
  ...parts.arrow.attrs,
71
- dir: state.context.dir,
68
+ dir: prop("dir"),
72
69
  style: popperStyles.arrow
73
70
  });
74
71
  },
75
72
  getArrowTipProps() {
76
73
  return normalize.element({
77
74
  ...parts.arrowTip.attrs,
78
- dir: state.context.dir,
75
+ dir: prop("dir"),
79
76
  style: popperStyles.arrowTip
80
77
  });
81
78
  },
82
79
  getAnchorProps() {
83
80
  return normalize.element({
84
81
  ...parts.anchor.attrs,
85
- dir: state.context.dir,
86
- id: dom.getAnchorId(state.context)
82
+ dir: prop("dir"),
83
+ id: getAnchorId(scope)
87
84
  });
88
85
  },
89
86
  getTriggerProps() {
90
87
  return normalize.button({
91
88
  ...parts.trigger.attrs,
92
- dir: state.context.dir,
89
+ dir: prop("dir"),
93
90
  type: "button",
94
91
  "data-placement": currentPlacement,
95
- id: dom.getTriggerId(state.context),
92
+ id: getTriggerId(scope),
96
93
  "aria-haspopup": "dialog",
97
94
  "aria-expanded": open,
98
95
  "data-state": open ? "open" : "closed",
99
- "aria-controls": dom.getContentId(state.context),
96
+ "aria-controls": getContentId(scope),
100
97
  onPointerDown(event) {
101
98
  if (domQuery.isSafari()) {
102
99
  event.currentTarget.focus();
@@ -104,7 +101,7 @@ function connect(state, send, normalize) {
104
101
  },
105
102
  onClick(event) {
106
103
  if (event.defaultPrevented) return;
107
- send("TOGGLE");
104
+ send({ type: "TOGGLE" });
108
105
  },
109
106
  onBlur(event) {
110
107
  send({ type: "TRIGGER_BLUR", target: event.relatedTarget });
@@ -114,293 +111,299 @@ function connect(state, send, normalize) {
114
111
  getIndicatorProps() {
115
112
  return normalize.element({
116
113
  ...parts.indicator.attrs,
117
- dir: state.context.dir,
114
+ dir: prop("dir"),
118
115
  "data-state": open ? "open" : "closed"
119
116
  });
120
117
  },
121
118
  getPositionerProps() {
122
119
  return normalize.element({
123
- id: dom.getPositionerId(state.context),
120
+ id: getPositionerId(scope),
124
121
  ...parts.positioner.attrs,
125
- dir: state.context.dir,
122
+ dir: prop("dir"),
126
123
  style: popperStyles.floating
127
124
  });
128
125
  },
129
126
  getContentProps() {
130
127
  return normalize.element({
131
128
  ...parts.content.attrs,
132
- dir: state.context.dir,
133
- id: dom.getContentId(state.context),
129
+ dir: prop("dir"),
130
+ id: getContentId(scope),
134
131
  tabIndex: -1,
135
132
  role: "dialog",
136
133
  hidden: !open,
137
134
  "data-state": open ? "open" : "closed",
138
135
  "data-expanded": domQuery.dataAttr(open),
139
- "aria-labelledby": rendered.title ? dom.getTitleId(state.context) : void 0,
140
- "aria-describedby": rendered.description ? dom.getDescriptionId(state.context) : void 0,
136
+ "aria-labelledby": rendered.title ? getTitleId(scope) : void 0,
137
+ "aria-describedby": rendered.description ? getDescriptionId(scope) : void 0,
141
138
  "data-placement": currentPlacement
142
139
  });
143
140
  },
144
141
  getTitleProps() {
145
142
  return normalize.element({
146
143
  ...parts.title.attrs,
147
- id: dom.getTitleId(state.context),
148
- dir: state.context.dir
144
+ id: getTitleId(scope),
145
+ dir: prop("dir")
149
146
  });
150
147
  },
151
148
  getDescriptionProps() {
152
149
  return normalize.element({
153
150
  ...parts.description.attrs,
154
- id: dom.getDescriptionId(state.context),
155
- dir: state.context.dir
151
+ id: getDescriptionId(scope),
152
+ dir: prop("dir")
156
153
  });
157
154
  },
158
155
  getCloseTriggerProps() {
159
156
  return normalize.button({
160
157
  ...parts.closeTrigger.attrs,
161
- dir: state.context.dir,
162
- id: dom.getCloseTriggerId(state.context),
158
+ dir: prop("dir"),
159
+ id: getCloseTriggerId(scope),
163
160
  type: "button",
164
161
  "aria-label": "close",
165
162
  onClick(event) {
166
163
  if (event.defaultPrevented) return;
167
- send("CLOSE");
164
+ send({ type: "CLOSE" });
168
165
  }
169
166
  });
170
167
  }
171
168
  };
172
169
  }
173
- function machine(userContext) {
174
- const ctx = utils.compact(userContext);
175
- return core.createMachine(
176
- {
177
- id: "popover",
178
- initial: ctx.open ? "open" : "closed",
179
- context: {
180
- closeOnInteractOutside: true,
181
- closeOnEscape: true,
182
- autoFocus: true,
183
- modal: false,
184
- portalled: true,
185
- positioning: {
186
- placement: "bottom",
187
- ...ctx.positioning
170
+ var machine = core.createMachine({
171
+ props({ props: props2 }) {
172
+ return {
173
+ closeOnInteractOutside: true,
174
+ closeOnEscape: true,
175
+ autoFocus: true,
176
+ modal: false,
177
+ portalled: true,
178
+ ...props2,
179
+ positioning: {
180
+ placement: "bottom",
181
+ ...props2.positioning
182
+ }
183
+ };
184
+ },
185
+ initialState({ prop }) {
186
+ const open = prop("open") || prop("defaultOpen");
187
+ return open ? "open" : "closed";
188
+ },
189
+ context({ bindable }) {
190
+ return {
191
+ currentPlacement: bindable(() => ({
192
+ defaultValue: void 0
193
+ })),
194
+ renderedElements: bindable(() => ({
195
+ defaultValue: { title: true, description: true }
196
+ }))
197
+ };
198
+ },
199
+ computed: {
200
+ currentPortalled: ({ prop }) => !!prop("modal") || !!prop("portalled")
201
+ },
202
+ watch({ track, prop, action }) {
203
+ track([() => prop("open")], () => {
204
+ action(["toggleVisibility"]);
205
+ });
206
+ },
207
+ entry: ["checkRenderedElements"],
208
+ states: {
209
+ closed: {
210
+ on: {
211
+ "CONTROLLED.OPEN": {
212
+ target: "open",
213
+ actions: ["setInitialFocus"]
188
214
  },
189
- currentPlacement: void 0,
190
- ...ctx,
191
- renderedElements: {
192
- title: true,
193
- description: true
194
- }
195
- },
196
- computed: {
197
- currentPortalled: (ctx2) => !!ctx2.modal || !!ctx2.portalled
198
- },
199
- watch: {
200
- open: ["toggleVisibility"]
201
- },
202
- entry: ["checkRenderedElements"],
203
- states: {
204
- closed: {
205
- on: {
206
- "CONTROLLED.OPEN": {
207
- target: "open",
208
- actions: ["setInitialFocus"]
209
- },
210
- TOGGLE: [
211
- {
212
- guard: "isOpenControlled",
213
- actions: ["invokeOnOpen"]
214
- },
215
- {
216
- target: "open",
217
- actions: ["invokeOnOpen", "setInitialFocus"]
218
- }
219
- ],
220
- OPEN: [
221
- {
222
- guard: "isOpenControlled",
223
- actions: ["invokeOnOpen"]
224
- },
225
- {
226
- target: "open",
227
- actions: ["invokeOnOpen", "setInitialFocus"]
228
- }
229
- ]
215
+ TOGGLE: [
216
+ {
217
+ guard: "isOpenControlled",
218
+ actions: ["invokeOnOpen"]
219
+ },
220
+ {
221
+ target: "open",
222
+ actions: ["invokeOnOpen", "setInitialFocus"]
223
+ }
224
+ ],
225
+ OPEN: [
226
+ {
227
+ guard: "isOpenControlled",
228
+ actions: ["invokeOnOpen"]
229
+ },
230
+ {
231
+ target: "open",
232
+ actions: ["invokeOnOpen", "setInitialFocus"]
230
233
  }
234
+ ]
235
+ }
236
+ },
237
+ open: {
238
+ effects: [
239
+ "trapFocus",
240
+ "preventScroll",
241
+ "hideContentBelow",
242
+ "trackPositioning",
243
+ "trackDismissableElement",
244
+ "proxyTabFocus"
245
+ ],
246
+ on: {
247
+ "CONTROLLED.CLOSE": {
248
+ target: "closed",
249
+ actions: ["setFinalFocus"]
231
250
  },
232
- open: {
233
- activities: [
234
- "trapFocus",
235
- "preventScroll",
236
- "hideContentBelow",
237
- "trackPositioning",
238
- "trackDismissableElement",
239
- "proxyTabFocus"
240
- ],
241
- on: {
242
- "CONTROLLED.CLOSE": {
243
- target: "closed",
244
- actions: ["setFinalFocus"]
245
- },
246
- CLOSE: [
247
- {
248
- guard: "isOpenControlled",
249
- actions: ["invokeOnClose"]
250
- },
251
- {
252
- target: "closed",
253
- actions: ["invokeOnClose", "setFinalFocus"]
254
- }
255
- ],
256
- TOGGLE: [
257
- {
258
- guard: "isOpenControlled",
259
- actions: ["invokeOnClose"]
260
- },
261
- {
262
- target: "closed",
263
- actions: ["invokeOnClose"]
264
- }
265
- ],
266
- "POSITIONING.SET": {
267
- actions: "reposition"
268
- }
251
+ CLOSE: [
252
+ {
253
+ guard: "isOpenControlled",
254
+ actions: ["invokeOnClose"]
255
+ },
256
+ {
257
+ target: "closed",
258
+ actions: ["invokeOnClose", "setFinalFocus"]
259
+ }
260
+ ],
261
+ TOGGLE: [
262
+ {
263
+ guard: "isOpenControlled",
264
+ actions: ["invokeOnClose"]
265
+ },
266
+ {
267
+ target: "closed",
268
+ actions: ["invokeOnClose"]
269
269
  }
270
+ ],
271
+ "POSITIONING.SET": {
272
+ actions: ["reposition"]
270
273
  }
271
274
  }
275
+ }
276
+ },
277
+ implementations: {
278
+ guards: {
279
+ isOpenControlled: ({ prop }) => prop("open") != void 0
272
280
  },
273
- {
274
- guards: {
275
- isOpenControlled: (ctx2) => !!ctx2["open.controlled"]
281
+ effects: {
282
+ trackPositioning({ context, prop, scope }) {
283
+ context.set("currentPlacement", prop("positioning").placement);
284
+ const anchorEl = getAnchorEl(scope) ?? getTriggerEl(scope);
285
+ const getPositionerEl2 = () => getPositionerEl(scope);
286
+ return popper.getPlacement(anchorEl, getPositionerEl2, {
287
+ ...prop("positioning"),
288
+ defer: true,
289
+ onComplete(data) {
290
+ context.set("currentPlacement", data.placement);
291
+ }
292
+ });
276
293
  },
277
- activities: {
278
- trackPositioning(ctx2) {
279
- ctx2.currentPlacement = ctx2.positioning.placement;
280
- const anchorEl = dom.getAnchorEl(ctx2) ?? dom.getTriggerEl(ctx2);
281
- const getPositionerEl = () => dom.getPositionerEl(ctx2);
282
- return popper.getPlacement(anchorEl, getPositionerEl, {
283
- ...ctx2.positioning,
284
- defer: true,
285
- onComplete(data) {
286
- ctx2.currentPlacement = data.placement;
287
- }
288
- });
289
- },
290
- trackDismissableElement(ctx2, _evt, { send }) {
291
- const getContentEl = () => dom.getContentEl(ctx2);
292
- let restoreFocus = true;
293
- return dismissable.trackDismissableElement(getContentEl, {
294
- pointerBlocking: ctx2.modal,
295
- exclude: dom.getTriggerEl(ctx2),
296
- defer: true,
297
- onEscapeKeyDown(event) {
298
- ctx2.onEscapeKeyDown?.(event);
299
- if (ctx2.closeOnEscape) return;
294
+ trackDismissableElement({ send, prop, scope }) {
295
+ const getContentEl2 = () => getContentEl(scope);
296
+ let restoreFocus = true;
297
+ return dismissable.trackDismissableElement(getContentEl2, {
298
+ pointerBlocking: prop("modal"),
299
+ exclude: getTriggerEl(scope),
300
+ defer: true,
301
+ onEscapeKeyDown(event) {
302
+ prop("onEscapeKeyDown")?.(event);
303
+ if (prop("closeOnEscape")) return;
304
+ event.preventDefault();
305
+ },
306
+ onInteractOutside(event) {
307
+ prop("onInteractOutside")?.(event);
308
+ if (event.defaultPrevented) return;
309
+ restoreFocus = !(event.detail.focusable || event.detail.contextmenu);
310
+ if (!prop("closeOnInteractOutside")) {
300
311
  event.preventDefault();
301
- },
302
- onInteractOutside(event) {
303
- ctx2.onInteractOutside?.(event);
304
- if (event.defaultPrevented) return;
305
- restoreFocus = !(event.detail.focusable || event.detail.contextmenu);
306
- if (!ctx2.closeOnInteractOutside) {
307
- event.preventDefault();
308
- }
309
- },
310
- onPointerDownOutside: ctx2.onPointerDownOutside,
311
- onFocusOutside: ctx2.onFocusOutside,
312
- persistentElements: ctx2.persistentElements,
313
- onDismiss() {
314
- send({ type: "CLOSE", src: "interact-outside", restoreFocus });
315
- }
316
- });
317
- },
318
- proxyTabFocus(ctx2) {
319
- if (ctx2.modal || !ctx2.portalled) return;
320
- const getContentEl = () => dom.getContentEl(ctx2);
321
- return domQuery.proxyTabFocus(getContentEl, {
322
- triggerElement: dom.getTriggerEl(ctx2),
323
- defer: true,
324
- onFocus(el) {
325
- el.focus({ preventScroll: true });
326
312
  }
327
- });
328
- },
329
- hideContentBelow(ctx2) {
330
- if (!ctx2.modal) return;
331
- const getElements = () => [dom.getContentEl(ctx2), dom.getTriggerEl(ctx2)];
332
- return ariaHidden.ariaHidden(getElements, { defer: true });
333
- },
334
- preventScroll(ctx2) {
335
- if (!ctx2.modal) return;
336
- return removeScroll.preventBodyScroll(dom.getDoc(ctx2));
337
- },
338
- trapFocus(ctx2) {
339
- if (!ctx2.modal) return;
340
- const contentEl = () => dom.getContentEl(ctx2);
341
- return focusTrap.trapFocus(contentEl, {
342
- initialFocus: () => domQuery.getInitialFocus({
343
- root: dom.getContentEl(ctx2),
344
- getInitialEl: ctx2.initialFocusEl,
345
- enabled: ctx2.autoFocus
346
- })
347
- });
348
- }
313
+ },
314
+ onPointerDownOutside: prop("onPointerDownOutside"),
315
+ onFocusOutside: prop("onFocusOutside"),
316
+ persistentElements: prop("persistentElements"),
317
+ onDismiss() {
318
+ send({ type: "CLOSE", src: "interact-outside", restoreFocus });
319
+ }
320
+ });
349
321
  },
350
- actions: {
351
- reposition(ctx2, evt) {
352
- const anchorEl = dom.getAnchorEl(ctx2) ?? dom.getTriggerEl(ctx2);
353
- const getPositionerEl = () => dom.getPositionerEl(ctx2);
354
- popper.getPlacement(anchorEl, getPositionerEl, {
355
- ...ctx2.positioning,
356
- ...evt.options,
357
- defer: true,
358
- listeners: false,
359
- onComplete(data) {
360
- ctx2.currentPlacement = data.placement;
361
- }
362
- });
363
- },
364
- checkRenderedElements(ctx2) {
365
- domQuery.raf(() => {
366
- Object.assign(ctx2.renderedElements, {
367
- title: !!dom.getTitleEl(ctx2),
368
- description: !!dom.getDescriptionEl(ctx2)
369
- });
370
- });
371
- },
372
- setInitialFocus(ctx2) {
373
- if (ctx2.modal) return;
374
- domQuery.raf(() => {
375
- const element = domQuery.getInitialFocus({
376
- root: dom.getContentEl(ctx2),
377
- getInitialEl: ctx2.initialFocusEl,
378
- enabled: ctx2.autoFocus
379
- });
380
- element?.focus({ preventScroll: true });
322
+ proxyTabFocus({ prop, scope }) {
323
+ if (prop("modal") || !prop("portalled")) return;
324
+ const getContentEl2 = () => getContentEl(scope);
325
+ return domQuery.proxyTabFocus(getContentEl2, {
326
+ triggerElement: getTriggerEl(scope),
327
+ defer: true,
328
+ onFocus(el) {
329
+ el.focus({ preventScroll: true });
330
+ }
331
+ });
332
+ },
333
+ hideContentBelow({ prop, scope }) {
334
+ if (!prop("modal")) return;
335
+ const getElements = () => [getContentEl(scope), getTriggerEl(scope)];
336
+ return ariaHidden.ariaHidden(getElements, { defer: true });
337
+ },
338
+ preventScroll({ prop, scope }) {
339
+ if (!prop("modal")) return;
340
+ return removeScroll.preventBodyScroll(scope.getDoc());
341
+ },
342
+ trapFocus({ prop, scope }) {
343
+ if (!prop("modal")) return;
344
+ const contentEl = () => getContentEl(scope);
345
+ return focusTrap.trapFocus(contentEl, {
346
+ initialFocus: () => domQuery.getInitialFocus({
347
+ root: getContentEl(scope),
348
+ getInitialEl: prop("initialFocusEl"),
349
+ enabled: prop("autoFocus")
350
+ })
351
+ });
352
+ }
353
+ },
354
+ actions: {
355
+ reposition({ event, prop, scope, context }) {
356
+ const anchorEl = getAnchorEl(scope) ?? getTriggerEl(scope);
357
+ const getPositionerEl2 = () => getPositionerEl(scope);
358
+ popper.getPlacement(anchorEl, getPositionerEl2, {
359
+ ...prop("positioning"),
360
+ ...event.options,
361
+ defer: true,
362
+ listeners: false,
363
+ onComplete(data) {
364
+ context.set("currentPlacement", data.placement);
365
+ }
366
+ });
367
+ },
368
+ checkRenderedElements({ context, scope }) {
369
+ domQuery.raf(() => {
370
+ Object.assign(context.get("renderedElements"), {
371
+ title: !!getTitleEl(scope),
372
+ description: !!getDescriptionEl(scope)
381
373
  });
382
- },
383
- setFinalFocus(ctx2, evt) {
384
- const restoreFocus = evt.restoreFocus ?? evt.previousEvent?.restoreFocus;
385
- if (restoreFocus != null && !restoreFocus) return;
386
- domQuery.raf(() => {
387
- const element = dom.getTriggerEl(ctx2);
388
- element?.focus({ preventScroll: true });
374
+ });
375
+ },
376
+ setInitialFocus({ prop, scope }) {
377
+ if (prop("modal")) return;
378
+ domQuery.raf(() => {
379
+ const element = domQuery.getInitialFocus({
380
+ root: getContentEl(scope),
381
+ getInitialEl: prop("initialFocusEl"),
382
+ enabled: prop("autoFocus")
389
383
  });
390
- },
391
- invokeOnOpen(ctx2) {
392
- ctx2.onOpenChange?.({ open: true });
393
- },
394
- invokeOnClose(ctx2) {
395
- ctx2.onOpenChange?.({ open: false });
396
- },
397
- toggleVisibility(ctx2, evt, { send }) {
398
- send({ type: ctx2.open ? "CONTROLLED.OPEN" : "CONTROLLED.CLOSE", previousEvent: evt });
399
- }
384
+ element?.focus({ preventScroll: true });
385
+ });
386
+ },
387
+ setFinalFocus({ event, scope }) {
388
+ const restoreFocus = event.restoreFocus ?? event.previousEvent?.restoreFocus;
389
+ if (restoreFocus != null && !restoreFocus) return;
390
+ domQuery.raf(() => {
391
+ const element = getTriggerEl(scope);
392
+ element?.focus({ preventScroll: true });
393
+ });
394
+ },
395
+ invokeOnOpen({ prop }) {
396
+ prop("onOpenChange")?.({ open: true });
397
+ },
398
+ invokeOnClose({ prop }) {
399
+ prop("onOpenChange")?.({ open: false });
400
+ },
401
+ toggleVisibility({ event, send, prop }) {
402
+ send({ type: prop("open") ? "CONTROLLED.OPEN" : "CONTROLLED.CLOSE", previousEvent: event });
400
403
  }
401
404
  }
402
- );
403
- }
405
+ }
406
+ });
404
407
  var props = types.createProps()([
405
408
  "autoFocus",
406
409
  "closeOnEscape",
@@ -416,7 +419,7 @@ var props = types.createProps()([
416
419
  "onInteractOutside",
417
420
  "onOpenChange",
418
421
  "onPointerDownOutside",
419
- "open.controlled",
422
+ "defaultOpen",
420
423
  "open",
421
424
  "persistentElements",
422
425
  "portalled",