@zag-js/popover 2.0.0-next.0 → 2.0.0-next.2
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.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/popover.connect.js +47 -15
- package/dist/popover.connect.mjs +47 -15
- package/dist/popover.machine.js +97 -78
- package/dist/popover.machine.mjs +98 -79
- package/dist/popover.props.js +0 -1
- package/dist/popover.props.mjs +0 -1
- package/dist/popover.types.d.mts +84 -38
- package/dist/popover.types.d.ts +84 -38
- package/package.json +16 -13
package/dist/index.d.mts
CHANGED
|
@@ -3,7 +3,7 @@ export { anatomy } from './popover.anatomy.mjs';
|
|
|
3
3
|
export { connect } from './popover.connect.mjs';
|
|
4
4
|
export { machine } from './popover.machine.mjs';
|
|
5
5
|
export { props, splitProps } from './popover.props.mjs';
|
|
6
|
-
export { PopoverApi as Api, ElementIds, IntlTranslations, PopoverMachine as Machine, OpenChangeDetails, PopoverProps as Props, PopoverService as Service, TriggerProps, TriggerValueChangeDetails } from './popover.types.mjs';
|
|
6
|
+
export { PopoverApi as Api, ContentState, ElementIds, IntlTranslations, PopoverMachine as Machine, OpenChangeDetails, PositionerState, PopoverProps as Props, PopoverService as Service, TriggerProps, TriggerState, TriggerValueChangeDetails } from './popover.types.mjs';
|
|
7
7
|
export { Placement, PositioningOptions } from '@zag-js/popper';
|
|
8
8
|
import '@zag-js/anatomy';
|
|
9
9
|
import '@zag-js/types';
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export { anatomy } from './popover.anatomy.js';
|
|
|
3
3
|
export { connect } from './popover.connect.js';
|
|
4
4
|
export { machine } from './popover.machine.js';
|
|
5
5
|
export { props, splitProps } from './popover.props.js';
|
|
6
|
-
export { PopoverApi as Api, ElementIds, IntlTranslations, PopoverMachine as Machine, OpenChangeDetails, PopoverProps as Props, PopoverService as Service, TriggerProps, TriggerValueChangeDetails } from './popover.types.js';
|
|
6
|
+
export { PopoverApi as Api, ContentState, ElementIds, IntlTranslations, PopoverMachine as Machine, OpenChangeDetails, PositionerState, PopoverProps as Props, PopoverService as Service, TriggerProps, TriggerState, TriggerValueChangeDetails } from './popover.types.js';
|
|
7
7
|
export { Placement, PositioningOptions } from '@zag-js/popper';
|
|
8
8
|
import '@zag-js/anatomy';
|
|
9
9
|
import '@zag-js/types';
|
package/dist/popover.connect.js
CHANGED
|
@@ -33,26 +33,47 @@ __export(popover_connect_exports, {
|
|
|
33
33
|
connect: () => connect
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(popover_connect_exports);
|
|
36
|
+
var import_dismissable = require("@zag-js/dismissable");
|
|
36
37
|
var import_dom_query = require("@zag-js/dom-query");
|
|
37
38
|
var import_popper = require("@zag-js/popper");
|
|
39
|
+
var import_utils = require("@zag-js/utils");
|
|
38
40
|
var import_popover = require("./popover.anatomy.js");
|
|
39
41
|
var dom = __toESM(require("./popover.dom.js"));
|
|
42
|
+
var defaultTranslations = {
|
|
43
|
+
closeTriggerLabel: "close"
|
|
44
|
+
};
|
|
40
45
|
function connect(service, normalize) {
|
|
41
|
-
const { state, context, send,
|
|
42
|
-
const
|
|
46
|
+
const { state, context, send, prop, scope } = service;
|
|
47
|
+
const layer = context.get("layer");
|
|
48
|
+
const translations = (0, import_utils.mergeWithDefault)(defaultTranslations, prop("translations"));
|
|
43
49
|
const open = state.matches("open");
|
|
44
50
|
const currentPlacement = context.get("currentPlacement");
|
|
45
51
|
const currentPlacementSide = currentPlacement ? (0, import_popper.getPlacementSide)(currentPlacement) : void 0;
|
|
46
|
-
const portalled = computed("currentPortalled");
|
|
47
52
|
const rendered = context.get("renderedElements");
|
|
48
53
|
const triggerValue = context.get("triggerValue");
|
|
49
54
|
const popperStyles = (0, import_popper.getPlacementStyles)({
|
|
50
55
|
...prop("positioning"),
|
|
51
|
-
placement: currentPlacement
|
|
52
|
-
positioned: context.get("positioned")
|
|
56
|
+
placement: currentPlacement
|
|
53
57
|
});
|
|
58
|
+
function getTriggerState(props = {}) {
|
|
59
|
+
const { value } = props;
|
|
60
|
+
const current = value == null ? false : triggerValue === value;
|
|
61
|
+
return { value, current, open: value == null ? open : open && current };
|
|
62
|
+
}
|
|
63
|
+
function getPositionerState() {
|
|
64
|
+
return { nested: !!layer?.nested, hasNested: !!layer?.hasNested };
|
|
65
|
+
}
|
|
66
|
+
function getContentState() {
|
|
67
|
+
return {
|
|
68
|
+
open,
|
|
69
|
+
modal: !!prop("modal"),
|
|
70
|
+
nested: !!layer?.nested,
|
|
71
|
+
hasNested: !!layer?.hasNested,
|
|
72
|
+
placement: currentPlacement,
|
|
73
|
+
side: currentPlacementSide
|
|
74
|
+
};
|
|
75
|
+
}
|
|
54
76
|
return {
|
|
55
|
-
portalled,
|
|
56
77
|
open,
|
|
57
78
|
setOpen(nextOpen) {
|
|
58
79
|
const open2 = state.matches("open");
|
|
@@ -86,9 +107,11 @@ function connect(service, normalize) {
|
|
|
86
107
|
dir: prop("dir")
|
|
87
108
|
});
|
|
88
109
|
},
|
|
110
|
+
getTriggerState,
|
|
89
111
|
getTriggerProps(props = {}) {
|
|
90
112
|
const { value } = props;
|
|
91
|
-
const
|
|
113
|
+
const triggerState = getTriggerState(props);
|
|
114
|
+
const { current } = triggerState;
|
|
92
115
|
return normalize.button({
|
|
93
116
|
...import_popover.parts.trigger.attrs(scope.id),
|
|
94
117
|
dir: prop("dir"),
|
|
@@ -98,7 +121,7 @@ function connect(service, normalize) {
|
|
|
98
121
|
"data-value": value,
|
|
99
122
|
"data-current": (0, import_dom_query.dataAttr)(current),
|
|
100
123
|
"aria-haspopup": "dialog",
|
|
101
|
-
"aria-expanded":
|
|
124
|
+
"aria-expanded": triggerState.open,
|
|
102
125
|
"data-state": open ? "open" : "closed",
|
|
103
126
|
"aria-controls": dom.getContentId(scope),
|
|
104
127
|
onPointerDown(event) {
|
|
@@ -124,28 +147,37 @@ function connect(service, normalize) {
|
|
|
124
147
|
"data-state": open ? "open" : "closed"
|
|
125
148
|
});
|
|
126
149
|
},
|
|
150
|
+
getPositionerState,
|
|
127
151
|
getPositionerProps() {
|
|
128
152
|
return normalize.element({
|
|
129
153
|
...import_popover.parts.positioner.attrs(scope.id),
|
|
130
154
|
dir: prop("dir"),
|
|
131
|
-
|
|
155
|
+
...(0, import_dismissable.getDismissableLayerAttrs)(layer),
|
|
156
|
+
style: {
|
|
157
|
+
...popperStyles.floating,
|
|
158
|
+
...(0, import_dismissable.getDismissableLayerStyle)(layer, { zIndex: true })
|
|
159
|
+
}
|
|
132
160
|
});
|
|
133
161
|
},
|
|
162
|
+
getContentState,
|
|
134
163
|
getContentProps() {
|
|
164
|
+
const contentState = getContentState();
|
|
135
165
|
return normalize.element({
|
|
136
166
|
...import_popover.parts.content.attrs(scope.id),
|
|
137
167
|
dir: prop("dir"),
|
|
138
168
|
id: dom.getContentId(scope),
|
|
139
169
|
tabIndex: -1,
|
|
140
170
|
role: "dialog",
|
|
141
|
-
"aria-modal": (0, import_dom_query.ariaAttr)(
|
|
142
|
-
hidden: !open,
|
|
143
|
-
"data-state": open ? "open" : "closed",
|
|
144
|
-
"data-expanded": (0, import_dom_query.dataAttr)(open),
|
|
171
|
+
"aria-modal": (0, import_dom_query.ariaAttr)(contentState.modal),
|
|
172
|
+
hidden: !contentState.open,
|
|
173
|
+
"data-state": contentState.open ? "open" : "closed",
|
|
174
|
+
"data-expanded": (0, import_dom_query.dataAttr)(contentState.open),
|
|
145
175
|
"aria-labelledby": rendered.title ? dom.getTitleId(scope) : void 0,
|
|
146
176
|
"aria-describedby": rendered.description ? dom.getDescriptionId(scope) : void 0,
|
|
147
|
-
"data-placement":
|
|
148
|
-
"data-side":
|
|
177
|
+
"data-placement": contentState.placement,
|
|
178
|
+
"data-side": contentState.side,
|
|
179
|
+
...(0, import_dismissable.getDismissableLayerAttrs)(layer),
|
|
180
|
+
style: (0, import_dismissable.getDismissableLayerStyle)(layer, { pointerEvents: true })
|
|
149
181
|
});
|
|
150
182
|
},
|
|
151
183
|
getTitleProps() {
|
package/dist/popover.connect.mjs
CHANGED
|
@@ -1,24 +1,45 @@
|
|
|
1
1
|
// src/popover.connect.ts
|
|
2
|
+
import { getDismissableLayerAttrs, getDismissableLayerStyle } from "@zag-js/dismissable";
|
|
2
3
|
import { ariaAttr, dataAttr, isLeftClick, isSafari } from "@zag-js/dom-query";
|
|
3
4
|
import { getPlacementSide, getPlacementStyles } from "@zag-js/popper";
|
|
5
|
+
import { mergeWithDefault } from "@zag-js/utils";
|
|
4
6
|
import { parts } from "./popover.anatomy.mjs";
|
|
5
7
|
import * as dom from "./popover.dom.mjs";
|
|
8
|
+
var defaultTranslations = {
|
|
9
|
+
closeTriggerLabel: "close"
|
|
10
|
+
};
|
|
6
11
|
function connect(service, normalize) {
|
|
7
|
-
const { state, context, send,
|
|
8
|
-
const
|
|
12
|
+
const { state, context, send, prop, scope } = service;
|
|
13
|
+
const layer = context.get("layer");
|
|
14
|
+
const translations = mergeWithDefault(defaultTranslations, prop("translations"));
|
|
9
15
|
const open = state.matches("open");
|
|
10
16
|
const currentPlacement = context.get("currentPlacement");
|
|
11
17
|
const currentPlacementSide = currentPlacement ? getPlacementSide(currentPlacement) : void 0;
|
|
12
|
-
const portalled = computed("currentPortalled");
|
|
13
18
|
const rendered = context.get("renderedElements");
|
|
14
19
|
const triggerValue = context.get("triggerValue");
|
|
15
20
|
const popperStyles = getPlacementStyles({
|
|
16
21
|
...prop("positioning"),
|
|
17
|
-
placement: currentPlacement
|
|
18
|
-
positioned: context.get("positioned")
|
|
22
|
+
placement: currentPlacement
|
|
19
23
|
});
|
|
24
|
+
function getTriggerState(props = {}) {
|
|
25
|
+
const { value } = props;
|
|
26
|
+
const current = value == null ? false : triggerValue === value;
|
|
27
|
+
return { value, current, open: value == null ? open : open && current };
|
|
28
|
+
}
|
|
29
|
+
function getPositionerState() {
|
|
30
|
+
return { nested: !!layer?.nested, hasNested: !!layer?.hasNested };
|
|
31
|
+
}
|
|
32
|
+
function getContentState() {
|
|
33
|
+
return {
|
|
34
|
+
open,
|
|
35
|
+
modal: !!prop("modal"),
|
|
36
|
+
nested: !!layer?.nested,
|
|
37
|
+
hasNested: !!layer?.hasNested,
|
|
38
|
+
placement: currentPlacement,
|
|
39
|
+
side: currentPlacementSide
|
|
40
|
+
};
|
|
41
|
+
}
|
|
20
42
|
return {
|
|
21
|
-
portalled,
|
|
22
43
|
open,
|
|
23
44
|
setOpen(nextOpen) {
|
|
24
45
|
const open2 = state.matches("open");
|
|
@@ -52,9 +73,11 @@ function connect(service, normalize) {
|
|
|
52
73
|
dir: prop("dir")
|
|
53
74
|
});
|
|
54
75
|
},
|
|
76
|
+
getTriggerState,
|
|
55
77
|
getTriggerProps(props = {}) {
|
|
56
78
|
const { value } = props;
|
|
57
|
-
const
|
|
79
|
+
const triggerState = getTriggerState(props);
|
|
80
|
+
const { current } = triggerState;
|
|
58
81
|
return normalize.button({
|
|
59
82
|
...parts.trigger.attrs(scope.id),
|
|
60
83
|
dir: prop("dir"),
|
|
@@ -64,7 +87,7 @@ function connect(service, normalize) {
|
|
|
64
87
|
"data-value": value,
|
|
65
88
|
"data-current": dataAttr(current),
|
|
66
89
|
"aria-haspopup": "dialog",
|
|
67
|
-
"aria-expanded":
|
|
90
|
+
"aria-expanded": triggerState.open,
|
|
68
91
|
"data-state": open ? "open" : "closed",
|
|
69
92
|
"aria-controls": dom.getContentId(scope),
|
|
70
93
|
onPointerDown(event) {
|
|
@@ -90,28 +113,37 @@ function connect(service, normalize) {
|
|
|
90
113
|
"data-state": open ? "open" : "closed"
|
|
91
114
|
});
|
|
92
115
|
},
|
|
116
|
+
getPositionerState,
|
|
93
117
|
getPositionerProps() {
|
|
94
118
|
return normalize.element({
|
|
95
119
|
...parts.positioner.attrs(scope.id),
|
|
96
120
|
dir: prop("dir"),
|
|
97
|
-
|
|
121
|
+
...getDismissableLayerAttrs(layer),
|
|
122
|
+
style: {
|
|
123
|
+
...popperStyles.floating,
|
|
124
|
+
...getDismissableLayerStyle(layer, { zIndex: true })
|
|
125
|
+
}
|
|
98
126
|
});
|
|
99
127
|
},
|
|
128
|
+
getContentState,
|
|
100
129
|
getContentProps() {
|
|
130
|
+
const contentState = getContentState();
|
|
101
131
|
return normalize.element({
|
|
102
132
|
...parts.content.attrs(scope.id),
|
|
103
133
|
dir: prop("dir"),
|
|
104
134
|
id: dom.getContentId(scope),
|
|
105
135
|
tabIndex: -1,
|
|
106
136
|
role: "dialog",
|
|
107
|
-
"aria-modal": ariaAttr(
|
|
108
|
-
hidden: !open,
|
|
109
|
-
"data-state": open ? "open" : "closed",
|
|
110
|
-
"data-expanded": dataAttr(open),
|
|
137
|
+
"aria-modal": ariaAttr(contentState.modal),
|
|
138
|
+
hidden: !contentState.open,
|
|
139
|
+
"data-state": contentState.open ? "open" : "closed",
|
|
140
|
+
"data-expanded": dataAttr(contentState.open),
|
|
111
141
|
"aria-labelledby": rendered.title ? dom.getTitleId(scope) : void 0,
|
|
112
142
|
"aria-describedby": rendered.description ? dom.getDescriptionId(scope) : void 0,
|
|
113
|
-
"data-placement":
|
|
114
|
-
"data-side":
|
|
143
|
+
"data-placement": contentState.placement,
|
|
144
|
+
"data-side": contentState.side,
|
|
145
|
+
...getDismissableLayerAttrs(layer),
|
|
146
|
+
style: getDismissableLayerStyle(layer, { pointerEvents: true })
|
|
115
147
|
});
|
|
116
148
|
},
|
|
117
149
|
getTitleProps() {
|
package/dist/popover.machine.js
CHANGED
|
@@ -48,13 +48,8 @@ var machine = (0, import_core.createMachine)({
|
|
|
48
48
|
closeOnEscape: true,
|
|
49
49
|
autoFocus: true,
|
|
50
50
|
modal: false,
|
|
51
|
-
portalled: true,
|
|
52
51
|
restoreFocus: true,
|
|
53
52
|
...props,
|
|
54
|
-
translations: {
|
|
55
|
-
closeTriggerLabel: "close",
|
|
56
|
-
...props.translations
|
|
57
|
-
},
|
|
58
53
|
positioning: {
|
|
59
54
|
placement: "bottom",
|
|
60
55
|
...props.positioning
|
|
@@ -67,6 +62,9 @@ var machine = (0, import_core.createMachine)({
|
|
|
67
62
|
},
|
|
68
63
|
context({ bindable, prop, scope }) {
|
|
69
64
|
return {
|
|
65
|
+
layer: bindable(() => ({
|
|
66
|
+
defaultValue: null
|
|
67
|
+
})),
|
|
70
68
|
currentPlacement: bindable(() => ({
|
|
71
69
|
defaultValue: void 0
|
|
72
70
|
})),
|
|
@@ -82,13 +80,9 @@ var machine = (0, import_core.createMachine)({
|
|
|
82
80
|
const triggerElement = dom.getActiveTriggerEl(scope, value);
|
|
83
81
|
onTriggerValueChange({ value, triggerElement });
|
|
84
82
|
}
|
|
85
|
-
}))
|
|
86
|
-
positioned: bindable(() => ({ defaultValue: false }))
|
|
83
|
+
}))
|
|
87
84
|
};
|
|
88
85
|
},
|
|
89
|
-
computed: {
|
|
90
|
-
currentPortalled: ({ prop }) => !!prop("modal") || !!prop("portalled")
|
|
91
|
-
},
|
|
92
86
|
watch({ track, prop, action }) {
|
|
93
87
|
track([() => prop("open")], () => {
|
|
94
88
|
action(["toggleVisibility"]);
|
|
@@ -184,85 +178,110 @@ var machine = (0, import_core.createMachine)({
|
|
|
184
178
|
defer: true,
|
|
185
179
|
onComplete(data) {
|
|
186
180
|
context.set("currentPlacement", data.placement);
|
|
187
|
-
context.set("positioned", true);
|
|
188
181
|
}
|
|
189
182
|
});
|
|
190
183
|
},
|
|
191
|
-
trackDismissableElement({ send, prop, scope }) {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
if (event.defaultPrevented) return;
|
|
207
|
-
restoreFocus = !(event.detail.focusable || event.detail.contextmenu);
|
|
208
|
-
if (!prop("closeOnInteractOutside")) {
|
|
184
|
+
trackDismissableElement({ send, prop, scope, context, watchEffect }) {
|
|
185
|
+
return watchEffect([() => prop("modal")], () => {
|
|
186
|
+
const getContentEl2 = () => dom.getContentEl(scope);
|
|
187
|
+
let restoreFocus = true;
|
|
188
|
+
return (0, import_dismissable.trackDismissableElement)(getContentEl2, {
|
|
189
|
+
type: "popover",
|
|
190
|
+
pointerBlocking: prop("modal"),
|
|
191
|
+
onLayerChange(layer) {
|
|
192
|
+
context.set("layer", layer);
|
|
193
|
+
},
|
|
194
|
+
exclude: dom.getTriggerEls(scope),
|
|
195
|
+
defer: true,
|
|
196
|
+
onEscapeKeyDown(event) {
|
|
197
|
+
prop("onEscapeKeyDown")?.(event);
|
|
198
|
+
if (prop("closeOnEscape")) return;
|
|
209
199
|
event.preventDefault();
|
|
200
|
+
},
|
|
201
|
+
onInteractOutside(event) {
|
|
202
|
+
prop("onInteractOutside")?.(event);
|
|
203
|
+
if (event.defaultPrevented) return;
|
|
204
|
+
restoreFocus = !(event.detail.focusable || event.detail.contextmenu);
|
|
205
|
+
if (!prop("closeOnInteractOutside")) {
|
|
206
|
+
event.preventDefault();
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
onPointerDownOutside: prop("onPointerDownOutside"),
|
|
210
|
+
onFocusOutside: prop("onFocusOutside"),
|
|
211
|
+
persistentElements: prop("persistentElements"),
|
|
212
|
+
onRequestDismiss: prop("onRequestDismiss"),
|
|
213
|
+
onDismiss() {
|
|
214
|
+
send({ type: "CLOSE", src: "interact-outside", restoreFocus });
|
|
210
215
|
}
|
|
211
|
-
}
|
|
212
|
-
onPointerDownOutside: prop("onPointerDownOutside"),
|
|
213
|
-
onFocusOutside: prop("onFocusOutside"),
|
|
214
|
-
persistentElements: prop("persistentElements"),
|
|
215
|
-
onRequestDismiss: prop("onRequestDismiss"),
|
|
216
|
-
onDismiss() {
|
|
217
|
-
send({ type: "CLOSE", src: "interact-outside", restoreFocus });
|
|
218
|
-
}
|
|
216
|
+
});
|
|
219
217
|
});
|
|
220
218
|
},
|
|
221
|
-
proxyTabFocus({ prop, scope, context }) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
219
|
+
proxyTabFocus({ prop, scope, context, watchEffect }) {
|
|
220
|
+
return watchEffect([() => prop("modal")], () => {
|
|
221
|
+
if (prop("modal")) return;
|
|
222
|
+
const getContentEl2 = () => dom.getContentEl(scope);
|
|
223
|
+
let cleanup;
|
|
224
|
+
const rafCleanup = (0, import_dom_query.raf)(() => {
|
|
225
|
+
const triggerEl = dom.getActiveTriggerEl(scope, context.get("triggerValue"));
|
|
226
|
+
const contentEl = getContentEl2();
|
|
227
|
+
if (!triggerEl || !contentEl || (0, import_dom_query.contains)(triggerEl.parentElement, contentEl)) return;
|
|
228
|
+
cleanup = (0, import_dom_query.proxyTabFocus)(getContentEl2, {
|
|
229
|
+
triggerElement: triggerEl,
|
|
230
|
+
getShadowRoot: true,
|
|
231
|
+
onFocus(el) {
|
|
232
|
+
el.focus({ preventScroll: true });
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
return () => {
|
|
237
|
+
rafCleanup();
|
|
238
|
+
cleanup?.();
|
|
239
|
+
};
|
|
231
240
|
});
|
|
232
241
|
},
|
|
233
|
-
hideContentBelow({ prop, scope, context }) {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
242
|
+
hideContentBelow({ prop, scope, context, watchEffect }) {
|
|
243
|
+
return watchEffect([() => prop("modal")], () => {
|
|
244
|
+
if (!prop("modal")) return;
|
|
245
|
+
const getElements = () => [
|
|
246
|
+
dom.getContentEl(scope),
|
|
247
|
+
dom.getActiveTriggerEl(scope, context.get("triggerValue"))
|
|
248
|
+
];
|
|
249
|
+
return (0, import_aria_hidden.ariaHidden)(getElements, { defer: true });
|
|
250
|
+
});
|
|
237
251
|
},
|
|
238
|
-
preventScroll({ prop, scope }) {
|
|
239
|
-
|
|
240
|
-
|
|
252
|
+
preventScroll({ prop, scope, watchEffect }) {
|
|
253
|
+
return watchEffect([() => prop("modal")], () => {
|
|
254
|
+
if (!prop("modal")) return;
|
|
255
|
+
return (0, import_remove_scroll.preventBodyScroll)(scope.getDoc());
|
|
256
|
+
});
|
|
241
257
|
},
|
|
242
|
-
trapFocus({ prop, scope, context }) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
258
|
+
trapFocus({ prop, scope, context, watchEffect }) {
|
|
259
|
+
return watchEffect([() => prop("modal")], () => {
|
|
260
|
+
if (!prop("modal")) return;
|
|
261
|
+
const contentEl = () => dom.getContentEl(scope);
|
|
262
|
+
const destroy = (0, import_focus_trap.trapFocus)(contentEl, {
|
|
263
|
+
preventScroll: true,
|
|
264
|
+
returnFocusOnDeactivate: !!prop("restoreFocus"),
|
|
265
|
+
initialFocus: () => (0, import_dom_query.getInitialFocus)({
|
|
266
|
+
root: dom.getContentEl(scope),
|
|
267
|
+
getInitialEl: prop("initialFocusEl"),
|
|
268
|
+
enabled: prop("autoFocus")
|
|
269
|
+
}),
|
|
270
|
+
setReturnFocus: (el) => {
|
|
271
|
+
const finalFocusEl = prop("finalFocusEl")?.();
|
|
272
|
+
if (finalFocusEl) return finalFocusEl;
|
|
273
|
+
const triggerValue = context.get("triggerValue");
|
|
274
|
+
if (triggerValue) {
|
|
275
|
+
const activeTriggerEl = dom.getActiveTriggerEl(scope, triggerValue);
|
|
276
|
+
if (activeTriggerEl) return activeTriggerEl;
|
|
277
|
+
}
|
|
278
|
+
const fallbackTrigger = dom.getTriggerEls(scope)[0];
|
|
279
|
+
if (fallbackTrigger) return fallbackTrigger;
|
|
280
|
+
return el;
|
|
281
|
+
},
|
|
282
|
+
getShadowRoot: true
|
|
283
|
+
});
|
|
284
|
+
return () => destroy({ returnFocus: !!prop("restoreFocus") && !!prop("modal") });
|
|
266
285
|
});
|
|
267
286
|
}
|
|
268
287
|
},
|
package/dist/popover.machine.mjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { ariaHidden } from "@zag-js/aria-hidden";
|
|
3
3
|
import { createMachine } from "@zag-js/core";
|
|
4
4
|
import { trackDismissableElement } from "@zag-js/dismissable";
|
|
5
|
-
import { getInitialFocus, proxyTabFocus, raf } from "@zag-js/dom-query";
|
|
5
|
+
import { contains, getInitialFocus, proxyTabFocus, raf } from "@zag-js/dom-query";
|
|
6
6
|
import { trapFocus } from "@zag-js/focus-trap";
|
|
7
7
|
import { getPlacement } from "@zag-js/popper";
|
|
8
8
|
import { preventBodyScroll } from "@zag-js/remove-scroll";
|
|
@@ -14,13 +14,8 @@ var machine = createMachine({
|
|
|
14
14
|
closeOnEscape: true,
|
|
15
15
|
autoFocus: true,
|
|
16
16
|
modal: false,
|
|
17
|
-
portalled: true,
|
|
18
17
|
restoreFocus: true,
|
|
19
18
|
...props,
|
|
20
|
-
translations: {
|
|
21
|
-
closeTriggerLabel: "close",
|
|
22
|
-
...props.translations
|
|
23
|
-
},
|
|
24
19
|
positioning: {
|
|
25
20
|
placement: "bottom",
|
|
26
21
|
...props.positioning
|
|
@@ -33,6 +28,9 @@ var machine = createMachine({
|
|
|
33
28
|
},
|
|
34
29
|
context({ bindable, prop, scope }) {
|
|
35
30
|
return {
|
|
31
|
+
layer: bindable(() => ({
|
|
32
|
+
defaultValue: null
|
|
33
|
+
})),
|
|
36
34
|
currentPlacement: bindable(() => ({
|
|
37
35
|
defaultValue: void 0
|
|
38
36
|
})),
|
|
@@ -48,13 +46,9 @@ var machine = createMachine({
|
|
|
48
46
|
const triggerElement = dom.getActiveTriggerEl(scope, value);
|
|
49
47
|
onTriggerValueChange({ value, triggerElement });
|
|
50
48
|
}
|
|
51
|
-
}))
|
|
52
|
-
positioned: bindable(() => ({ defaultValue: false }))
|
|
49
|
+
}))
|
|
53
50
|
};
|
|
54
51
|
},
|
|
55
|
-
computed: {
|
|
56
|
-
currentPortalled: ({ prop }) => !!prop("modal") || !!prop("portalled")
|
|
57
|
-
},
|
|
58
52
|
watch({ track, prop, action }) {
|
|
59
53
|
track([() => prop("open")], () => {
|
|
60
54
|
action(["toggleVisibility"]);
|
|
@@ -150,85 +144,110 @@ var machine = createMachine({
|
|
|
150
144
|
defer: true,
|
|
151
145
|
onComplete(data) {
|
|
152
146
|
context.set("currentPlacement", data.placement);
|
|
153
|
-
context.set("positioned", true);
|
|
154
147
|
}
|
|
155
148
|
});
|
|
156
149
|
},
|
|
157
|
-
trackDismissableElement({ send, prop, scope }) {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if (event.defaultPrevented) return;
|
|
173
|
-
restoreFocus = !(event.detail.focusable || event.detail.contextmenu);
|
|
174
|
-
if (!prop("closeOnInteractOutside")) {
|
|
150
|
+
trackDismissableElement({ send, prop, scope, context, watchEffect }) {
|
|
151
|
+
return watchEffect([() => prop("modal")], () => {
|
|
152
|
+
const getContentEl2 = () => dom.getContentEl(scope);
|
|
153
|
+
let restoreFocus = true;
|
|
154
|
+
return trackDismissableElement(getContentEl2, {
|
|
155
|
+
type: "popover",
|
|
156
|
+
pointerBlocking: prop("modal"),
|
|
157
|
+
onLayerChange(layer) {
|
|
158
|
+
context.set("layer", layer);
|
|
159
|
+
},
|
|
160
|
+
exclude: dom.getTriggerEls(scope),
|
|
161
|
+
defer: true,
|
|
162
|
+
onEscapeKeyDown(event) {
|
|
163
|
+
prop("onEscapeKeyDown")?.(event);
|
|
164
|
+
if (prop("closeOnEscape")) return;
|
|
175
165
|
event.preventDefault();
|
|
166
|
+
},
|
|
167
|
+
onInteractOutside(event) {
|
|
168
|
+
prop("onInteractOutside")?.(event);
|
|
169
|
+
if (event.defaultPrevented) return;
|
|
170
|
+
restoreFocus = !(event.detail.focusable || event.detail.contextmenu);
|
|
171
|
+
if (!prop("closeOnInteractOutside")) {
|
|
172
|
+
event.preventDefault();
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
onPointerDownOutside: prop("onPointerDownOutside"),
|
|
176
|
+
onFocusOutside: prop("onFocusOutside"),
|
|
177
|
+
persistentElements: prop("persistentElements"),
|
|
178
|
+
onRequestDismiss: prop("onRequestDismiss"),
|
|
179
|
+
onDismiss() {
|
|
180
|
+
send({ type: "CLOSE", src: "interact-outside", restoreFocus });
|
|
176
181
|
}
|
|
177
|
-
}
|
|
178
|
-
onPointerDownOutside: prop("onPointerDownOutside"),
|
|
179
|
-
onFocusOutside: prop("onFocusOutside"),
|
|
180
|
-
persistentElements: prop("persistentElements"),
|
|
181
|
-
onRequestDismiss: prop("onRequestDismiss"),
|
|
182
|
-
onDismiss() {
|
|
183
|
-
send({ type: "CLOSE", src: "interact-outside", restoreFocus });
|
|
184
|
-
}
|
|
182
|
+
});
|
|
185
183
|
});
|
|
186
184
|
},
|
|
187
|
-
proxyTabFocus({ prop, scope, context }) {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
185
|
+
proxyTabFocus({ prop, scope, context, watchEffect }) {
|
|
186
|
+
return watchEffect([() => prop("modal")], () => {
|
|
187
|
+
if (prop("modal")) return;
|
|
188
|
+
const getContentEl2 = () => dom.getContentEl(scope);
|
|
189
|
+
let cleanup;
|
|
190
|
+
const rafCleanup = raf(() => {
|
|
191
|
+
const triggerEl = dom.getActiveTriggerEl(scope, context.get("triggerValue"));
|
|
192
|
+
const contentEl = getContentEl2();
|
|
193
|
+
if (!triggerEl || !contentEl || contains(triggerEl.parentElement, contentEl)) return;
|
|
194
|
+
cleanup = proxyTabFocus(getContentEl2, {
|
|
195
|
+
triggerElement: triggerEl,
|
|
196
|
+
getShadowRoot: true,
|
|
197
|
+
onFocus(el) {
|
|
198
|
+
el.focus({ preventScroll: true });
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
return () => {
|
|
203
|
+
rafCleanup();
|
|
204
|
+
cleanup?.();
|
|
205
|
+
};
|
|
197
206
|
});
|
|
198
207
|
},
|
|
199
|
-
hideContentBelow({ prop, scope, context }) {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
208
|
+
hideContentBelow({ prop, scope, context, watchEffect }) {
|
|
209
|
+
return watchEffect([() => prop("modal")], () => {
|
|
210
|
+
if (!prop("modal")) return;
|
|
211
|
+
const getElements = () => [
|
|
212
|
+
dom.getContentEl(scope),
|
|
213
|
+
dom.getActiveTriggerEl(scope, context.get("triggerValue"))
|
|
214
|
+
];
|
|
215
|
+
return ariaHidden(getElements, { defer: true });
|
|
216
|
+
});
|
|
203
217
|
},
|
|
204
|
-
preventScroll({ prop, scope }) {
|
|
205
|
-
|
|
206
|
-
|
|
218
|
+
preventScroll({ prop, scope, watchEffect }) {
|
|
219
|
+
return watchEffect([() => prop("modal")], () => {
|
|
220
|
+
if (!prop("modal")) return;
|
|
221
|
+
return preventBodyScroll(scope.getDoc());
|
|
222
|
+
});
|
|
207
223
|
},
|
|
208
|
-
trapFocus({ prop, scope, context }) {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
224
|
+
trapFocus({ prop, scope, context, watchEffect }) {
|
|
225
|
+
return watchEffect([() => prop("modal")], () => {
|
|
226
|
+
if (!prop("modal")) return;
|
|
227
|
+
const contentEl = () => dom.getContentEl(scope);
|
|
228
|
+
const destroy = trapFocus(contentEl, {
|
|
229
|
+
preventScroll: true,
|
|
230
|
+
returnFocusOnDeactivate: !!prop("restoreFocus"),
|
|
231
|
+
initialFocus: () => getInitialFocus({
|
|
232
|
+
root: dom.getContentEl(scope),
|
|
233
|
+
getInitialEl: prop("initialFocusEl"),
|
|
234
|
+
enabled: prop("autoFocus")
|
|
235
|
+
}),
|
|
236
|
+
setReturnFocus: (el) => {
|
|
237
|
+
const finalFocusEl = prop("finalFocusEl")?.();
|
|
238
|
+
if (finalFocusEl) return finalFocusEl;
|
|
239
|
+
const triggerValue = context.get("triggerValue");
|
|
240
|
+
if (triggerValue) {
|
|
241
|
+
const activeTriggerEl = dom.getActiveTriggerEl(scope, triggerValue);
|
|
242
|
+
if (activeTriggerEl) return activeTriggerEl;
|
|
243
|
+
}
|
|
244
|
+
const fallbackTrigger = dom.getTriggerEls(scope)[0];
|
|
245
|
+
if (fallbackTrigger) return fallbackTrigger;
|
|
246
|
+
return el;
|
|
247
|
+
},
|
|
248
|
+
getShadowRoot: true
|
|
249
|
+
});
|
|
250
|
+
return () => destroy({ returnFocus: !!prop("restoreFocus") && !!prop("modal") });
|
|
232
251
|
});
|
|
233
252
|
}
|
|
234
253
|
},
|
package/dist/popover.props.js
CHANGED
package/dist/popover.props.mjs
CHANGED
package/dist/popover.types.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Machine, EventObject, Service } from '@zag-js/core';
|
|
2
|
-
import { DismissableElementHandlers, PersistentElementOptions } from '@zag-js/dismissable';
|
|
3
|
-
import { PositioningOptions, Placement } from '@zag-js/popper';
|
|
2
|
+
import { DismissableElementHandlers, PersistentElementOptions, LayerSnapshot } from '@zag-js/dismissable';
|
|
3
|
+
import { PositioningOptions, Placement, PlacementSide } from '@zag-js/popper';
|
|
4
4
|
export { Placement, PositioningOptions } from '@zag-js/popper';
|
|
5
|
-
import { PropTypes,
|
|
5
|
+
import { PropTypes, CommonProperties, DirectionProperty, MaybeElement } from '@zag-js/types';
|
|
6
6
|
|
|
7
7
|
interface OpenChangeDetails {
|
|
8
8
|
open: boolean;
|
|
@@ -20,16 +20,16 @@ interface TriggerValueChangeDetails {
|
|
|
20
20
|
interface IntlTranslations {
|
|
21
21
|
closeTriggerLabel?: string | undefined;
|
|
22
22
|
}
|
|
23
|
-
|
|
24
|
-
anchor
|
|
25
|
-
trigger
|
|
26
|
-
content
|
|
27
|
-
title
|
|
28
|
-
description
|
|
29
|
-
closeTrigger
|
|
30
|
-
positioner
|
|
31
|
-
arrow
|
|
32
|
-
}
|
|
23
|
+
interface ElementIds {
|
|
24
|
+
anchor?: string | undefined;
|
|
25
|
+
trigger?: (string | ((value?: string) => string)) | undefined;
|
|
26
|
+
content?: string | undefined;
|
|
27
|
+
title?: string | undefined;
|
|
28
|
+
description?: string | undefined;
|
|
29
|
+
closeTrigger?: string | undefined;
|
|
30
|
+
positioner?: string | undefined;
|
|
31
|
+
arrow?: string | undefined;
|
|
32
|
+
}
|
|
33
33
|
interface PopoverProps extends CommonProperties, DirectionProperty, DismissableElementHandlers, PersistentElementOptions {
|
|
34
34
|
/**
|
|
35
35
|
* Specifies the localized strings that identifies the accessibility elements and their states
|
|
@@ -49,13 +49,6 @@ interface PopoverProps extends CommonProperties, DirectionProperty, DismissableE
|
|
|
49
49
|
* @default false
|
|
50
50
|
*/
|
|
51
51
|
modal?: boolean | undefined;
|
|
52
|
-
/**
|
|
53
|
-
* Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position
|
|
54
|
-
* of the popover content.
|
|
55
|
-
*
|
|
56
|
-
* @default true
|
|
57
|
-
*/
|
|
58
|
-
portalled?: boolean | undefined;
|
|
59
52
|
/**
|
|
60
53
|
* Whether to automatically set focus on the first focusable
|
|
61
54
|
* content within the popover when opened.
|
|
@@ -66,7 +59,7 @@ interface PopoverProps extends CommonProperties, DirectionProperty, DismissableE
|
|
|
66
59
|
/**
|
|
67
60
|
* The element to focus on when the popover is opened.
|
|
68
61
|
*/
|
|
69
|
-
initialFocusEl?: (() => HTMLElement | null) | undefined;
|
|
62
|
+
initialFocusEl?: (() => HTMLElement | null) | null | undefined;
|
|
70
63
|
/**
|
|
71
64
|
* Element to receive focus when the popover is closed.
|
|
72
65
|
*/
|
|
@@ -118,14 +111,12 @@ interface PopoverProps extends CommonProperties, DirectionProperty, DismissableE
|
|
|
118
111
|
*/
|
|
119
112
|
onTriggerValueChange?: ((details: TriggerValueChangeDetails) => void) | undefined;
|
|
120
113
|
}
|
|
121
|
-
type PropsWithDefault = "closeOnInteractOutside" | "closeOnEscape" | "modal" | "
|
|
122
|
-
|
|
114
|
+
type PropsWithDefault = "closeOnInteractOutside" | "closeOnEscape" | "modal" | "autoFocus" | "restoreFocus" | "positioning" | "translations";
|
|
115
|
+
interface PrivateContext {
|
|
123
116
|
/**
|
|
124
|
-
* The computed
|
|
117
|
+
* The computed layer stack state used for declarative styles and attributes.
|
|
125
118
|
*/
|
|
126
|
-
|
|
127
|
-
}>;
|
|
128
|
-
interface PrivateContext {
|
|
119
|
+
layer: LayerSnapshot | null;
|
|
129
120
|
/**
|
|
130
121
|
* The elements that are rendered on mount
|
|
131
122
|
*/
|
|
@@ -141,16 +132,13 @@ interface PrivateContext {
|
|
|
141
132
|
* The trigger value
|
|
142
133
|
*/
|
|
143
134
|
triggerValue: string | null;
|
|
144
|
-
/**
|
|
145
|
-
* Whether the popover has been positioned
|
|
146
|
-
*/
|
|
147
|
-
positioned: boolean;
|
|
148
135
|
}
|
|
149
136
|
interface PopoverSchema {
|
|
150
|
-
props:
|
|
137
|
+
props: PopoverProps;
|
|
138
|
+
defaultPropKey: PropsWithDefault;
|
|
151
139
|
state: "open" | "closed";
|
|
152
140
|
context: PrivateContext;
|
|
153
|
-
computed:
|
|
141
|
+
computed: {};
|
|
154
142
|
event: EventObject;
|
|
155
143
|
action: string;
|
|
156
144
|
effect: string;
|
|
@@ -162,13 +150,59 @@ interface TriggerProps {
|
|
|
162
150
|
/**
|
|
163
151
|
* The value that identifies this specific trigger
|
|
164
152
|
*/
|
|
165
|
-
value?: string;
|
|
153
|
+
value?: string | undefined;
|
|
166
154
|
}
|
|
167
|
-
interface
|
|
155
|
+
interface TriggerState {
|
|
168
156
|
/**
|
|
169
|
-
*
|
|
157
|
+
* The value that identifies this specific trigger
|
|
170
158
|
*/
|
|
171
|
-
|
|
159
|
+
value: string | undefined;
|
|
160
|
+
/**
|
|
161
|
+
* Whether this trigger is the one that opened the popover
|
|
162
|
+
*/
|
|
163
|
+
current: boolean;
|
|
164
|
+
/**
|
|
165
|
+
* Whether the popover is open
|
|
166
|
+
*/
|
|
167
|
+
open: boolean;
|
|
168
|
+
}
|
|
169
|
+
interface PositionerState {
|
|
170
|
+
/**
|
|
171
|
+
* Whether the popover is nested within another layered element
|
|
172
|
+
*/
|
|
173
|
+
nested: boolean;
|
|
174
|
+
/**
|
|
175
|
+
* Whether the popover has nested layered elements within it
|
|
176
|
+
*/
|
|
177
|
+
hasNested: boolean;
|
|
178
|
+
}
|
|
179
|
+
interface ContentState {
|
|
180
|
+
/**
|
|
181
|
+
* Whether the popover is open
|
|
182
|
+
*/
|
|
183
|
+
open: boolean;
|
|
184
|
+
/**
|
|
185
|
+
* Whether the popover is modal
|
|
186
|
+
*/
|
|
187
|
+
modal: boolean;
|
|
188
|
+
/**
|
|
189
|
+
* Whether the popover is nested within another layered element
|
|
190
|
+
*/
|
|
191
|
+
nested: boolean;
|
|
192
|
+
/**
|
|
193
|
+
* Whether the popover has nested layered elements within it
|
|
194
|
+
*/
|
|
195
|
+
hasNested: boolean;
|
|
196
|
+
/**
|
|
197
|
+
* The current placement of the content relative to the trigger
|
|
198
|
+
*/
|
|
199
|
+
placement: Placement | undefined;
|
|
200
|
+
/**
|
|
201
|
+
* The side of the trigger the content is placed on
|
|
202
|
+
*/
|
|
203
|
+
side: PlacementSide | undefined;
|
|
204
|
+
}
|
|
205
|
+
interface PopoverApi<T extends PropTypes = PropTypes> {
|
|
172
206
|
/**
|
|
173
207
|
* Whether the popover is open
|
|
174
208
|
*/
|
|
@@ -192,13 +226,25 @@ interface PopoverApi<T extends PropTypes = PropTypes> {
|
|
|
192
226
|
getArrowProps: () => T["element"];
|
|
193
227
|
getArrowTipProps: () => T["element"];
|
|
194
228
|
getAnchorProps: () => T["element"];
|
|
229
|
+
/**
|
|
230
|
+
* Returns the state of a specific trigger, including whether it's the currently active one
|
|
231
|
+
*/
|
|
232
|
+
getTriggerState: (props?: TriggerProps) => TriggerState;
|
|
195
233
|
getTriggerProps: (props?: TriggerProps) => T["button"];
|
|
196
234
|
getIndicatorProps: () => T["element"];
|
|
235
|
+
/**
|
|
236
|
+
* Returns the state of the positioner
|
|
237
|
+
*/
|
|
238
|
+
getPositionerState: () => PositionerState;
|
|
197
239
|
getPositionerProps: () => T["element"];
|
|
240
|
+
/**
|
|
241
|
+
* Returns the state of the content
|
|
242
|
+
*/
|
|
243
|
+
getContentState: () => ContentState;
|
|
198
244
|
getContentProps: () => T["element"];
|
|
199
245
|
getTitleProps: () => T["element"];
|
|
200
246
|
getDescriptionProps: () => T["element"];
|
|
201
247
|
getCloseTriggerProps: () => T["button"];
|
|
202
248
|
}
|
|
203
249
|
|
|
204
|
-
export type { ElementIds, IntlTranslations, OpenChangeDetails, PopoverApi, PopoverMachine, PopoverProps, PopoverSchema, PopoverService, TriggerProps, TriggerValueChangeDetails };
|
|
250
|
+
export type { ContentState, ElementIds, IntlTranslations, OpenChangeDetails, PopoverApi, PopoverMachine, PopoverProps, PopoverSchema, PopoverService, PositionerState, TriggerProps, TriggerState, TriggerValueChangeDetails };
|
package/dist/popover.types.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Machine, EventObject, Service } from '@zag-js/core';
|
|
2
|
-
import { DismissableElementHandlers, PersistentElementOptions } from '@zag-js/dismissable';
|
|
3
|
-
import { PositioningOptions, Placement } from '@zag-js/popper';
|
|
2
|
+
import { DismissableElementHandlers, PersistentElementOptions, LayerSnapshot } from '@zag-js/dismissable';
|
|
3
|
+
import { PositioningOptions, Placement, PlacementSide } from '@zag-js/popper';
|
|
4
4
|
export { Placement, PositioningOptions } from '@zag-js/popper';
|
|
5
|
-
import { PropTypes,
|
|
5
|
+
import { PropTypes, CommonProperties, DirectionProperty, MaybeElement } from '@zag-js/types';
|
|
6
6
|
|
|
7
7
|
interface OpenChangeDetails {
|
|
8
8
|
open: boolean;
|
|
@@ -20,16 +20,16 @@ interface TriggerValueChangeDetails {
|
|
|
20
20
|
interface IntlTranslations {
|
|
21
21
|
closeTriggerLabel?: string | undefined;
|
|
22
22
|
}
|
|
23
|
-
|
|
24
|
-
anchor
|
|
25
|
-
trigger
|
|
26
|
-
content
|
|
27
|
-
title
|
|
28
|
-
description
|
|
29
|
-
closeTrigger
|
|
30
|
-
positioner
|
|
31
|
-
arrow
|
|
32
|
-
}
|
|
23
|
+
interface ElementIds {
|
|
24
|
+
anchor?: string | undefined;
|
|
25
|
+
trigger?: (string | ((value?: string) => string)) | undefined;
|
|
26
|
+
content?: string | undefined;
|
|
27
|
+
title?: string | undefined;
|
|
28
|
+
description?: string | undefined;
|
|
29
|
+
closeTrigger?: string | undefined;
|
|
30
|
+
positioner?: string | undefined;
|
|
31
|
+
arrow?: string | undefined;
|
|
32
|
+
}
|
|
33
33
|
interface PopoverProps extends CommonProperties, DirectionProperty, DismissableElementHandlers, PersistentElementOptions {
|
|
34
34
|
/**
|
|
35
35
|
* Specifies the localized strings that identifies the accessibility elements and their states
|
|
@@ -49,13 +49,6 @@ interface PopoverProps extends CommonProperties, DirectionProperty, DismissableE
|
|
|
49
49
|
* @default false
|
|
50
50
|
*/
|
|
51
51
|
modal?: boolean | undefined;
|
|
52
|
-
/**
|
|
53
|
-
* Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position
|
|
54
|
-
* of the popover content.
|
|
55
|
-
*
|
|
56
|
-
* @default true
|
|
57
|
-
*/
|
|
58
|
-
portalled?: boolean | undefined;
|
|
59
52
|
/**
|
|
60
53
|
* Whether to automatically set focus on the first focusable
|
|
61
54
|
* content within the popover when opened.
|
|
@@ -66,7 +59,7 @@ interface PopoverProps extends CommonProperties, DirectionProperty, DismissableE
|
|
|
66
59
|
/**
|
|
67
60
|
* The element to focus on when the popover is opened.
|
|
68
61
|
*/
|
|
69
|
-
initialFocusEl?: (() => HTMLElement | null) | undefined;
|
|
62
|
+
initialFocusEl?: (() => HTMLElement | null) | null | undefined;
|
|
70
63
|
/**
|
|
71
64
|
* Element to receive focus when the popover is closed.
|
|
72
65
|
*/
|
|
@@ -118,14 +111,12 @@ interface PopoverProps extends CommonProperties, DirectionProperty, DismissableE
|
|
|
118
111
|
*/
|
|
119
112
|
onTriggerValueChange?: ((details: TriggerValueChangeDetails) => void) | undefined;
|
|
120
113
|
}
|
|
121
|
-
type PropsWithDefault = "closeOnInteractOutside" | "closeOnEscape" | "modal" | "
|
|
122
|
-
|
|
114
|
+
type PropsWithDefault = "closeOnInteractOutside" | "closeOnEscape" | "modal" | "autoFocus" | "restoreFocus" | "positioning" | "translations";
|
|
115
|
+
interface PrivateContext {
|
|
123
116
|
/**
|
|
124
|
-
* The computed
|
|
117
|
+
* The computed layer stack state used for declarative styles and attributes.
|
|
125
118
|
*/
|
|
126
|
-
|
|
127
|
-
}>;
|
|
128
|
-
interface PrivateContext {
|
|
119
|
+
layer: LayerSnapshot | null;
|
|
129
120
|
/**
|
|
130
121
|
* The elements that are rendered on mount
|
|
131
122
|
*/
|
|
@@ -141,16 +132,13 @@ interface PrivateContext {
|
|
|
141
132
|
* The trigger value
|
|
142
133
|
*/
|
|
143
134
|
triggerValue: string | null;
|
|
144
|
-
/**
|
|
145
|
-
* Whether the popover has been positioned
|
|
146
|
-
*/
|
|
147
|
-
positioned: boolean;
|
|
148
135
|
}
|
|
149
136
|
interface PopoverSchema {
|
|
150
|
-
props:
|
|
137
|
+
props: PopoverProps;
|
|
138
|
+
defaultPropKey: PropsWithDefault;
|
|
151
139
|
state: "open" | "closed";
|
|
152
140
|
context: PrivateContext;
|
|
153
|
-
computed:
|
|
141
|
+
computed: {};
|
|
154
142
|
event: EventObject;
|
|
155
143
|
action: string;
|
|
156
144
|
effect: string;
|
|
@@ -162,13 +150,59 @@ interface TriggerProps {
|
|
|
162
150
|
/**
|
|
163
151
|
* The value that identifies this specific trigger
|
|
164
152
|
*/
|
|
165
|
-
value?: string;
|
|
153
|
+
value?: string | undefined;
|
|
166
154
|
}
|
|
167
|
-
interface
|
|
155
|
+
interface TriggerState {
|
|
168
156
|
/**
|
|
169
|
-
*
|
|
157
|
+
* The value that identifies this specific trigger
|
|
170
158
|
*/
|
|
171
|
-
|
|
159
|
+
value: string | undefined;
|
|
160
|
+
/**
|
|
161
|
+
* Whether this trigger is the one that opened the popover
|
|
162
|
+
*/
|
|
163
|
+
current: boolean;
|
|
164
|
+
/**
|
|
165
|
+
* Whether the popover is open
|
|
166
|
+
*/
|
|
167
|
+
open: boolean;
|
|
168
|
+
}
|
|
169
|
+
interface PositionerState {
|
|
170
|
+
/**
|
|
171
|
+
* Whether the popover is nested within another layered element
|
|
172
|
+
*/
|
|
173
|
+
nested: boolean;
|
|
174
|
+
/**
|
|
175
|
+
* Whether the popover has nested layered elements within it
|
|
176
|
+
*/
|
|
177
|
+
hasNested: boolean;
|
|
178
|
+
}
|
|
179
|
+
interface ContentState {
|
|
180
|
+
/**
|
|
181
|
+
* Whether the popover is open
|
|
182
|
+
*/
|
|
183
|
+
open: boolean;
|
|
184
|
+
/**
|
|
185
|
+
* Whether the popover is modal
|
|
186
|
+
*/
|
|
187
|
+
modal: boolean;
|
|
188
|
+
/**
|
|
189
|
+
* Whether the popover is nested within another layered element
|
|
190
|
+
*/
|
|
191
|
+
nested: boolean;
|
|
192
|
+
/**
|
|
193
|
+
* Whether the popover has nested layered elements within it
|
|
194
|
+
*/
|
|
195
|
+
hasNested: boolean;
|
|
196
|
+
/**
|
|
197
|
+
* The current placement of the content relative to the trigger
|
|
198
|
+
*/
|
|
199
|
+
placement: Placement | undefined;
|
|
200
|
+
/**
|
|
201
|
+
* The side of the trigger the content is placed on
|
|
202
|
+
*/
|
|
203
|
+
side: PlacementSide | undefined;
|
|
204
|
+
}
|
|
205
|
+
interface PopoverApi<T extends PropTypes = PropTypes> {
|
|
172
206
|
/**
|
|
173
207
|
* Whether the popover is open
|
|
174
208
|
*/
|
|
@@ -192,13 +226,25 @@ interface PopoverApi<T extends PropTypes = PropTypes> {
|
|
|
192
226
|
getArrowProps: () => T["element"];
|
|
193
227
|
getArrowTipProps: () => T["element"];
|
|
194
228
|
getAnchorProps: () => T["element"];
|
|
229
|
+
/**
|
|
230
|
+
* Returns the state of a specific trigger, including whether it's the currently active one
|
|
231
|
+
*/
|
|
232
|
+
getTriggerState: (props?: TriggerProps) => TriggerState;
|
|
195
233
|
getTriggerProps: (props?: TriggerProps) => T["button"];
|
|
196
234
|
getIndicatorProps: () => T["element"];
|
|
235
|
+
/**
|
|
236
|
+
* Returns the state of the positioner
|
|
237
|
+
*/
|
|
238
|
+
getPositionerState: () => PositionerState;
|
|
197
239
|
getPositionerProps: () => T["element"];
|
|
240
|
+
/**
|
|
241
|
+
* Returns the state of the content
|
|
242
|
+
*/
|
|
243
|
+
getContentState: () => ContentState;
|
|
198
244
|
getContentProps: () => T["element"];
|
|
199
245
|
getTitleProps: () => T["element"];
|
|
200
246
|
getDescriptionProps: () => T["element"];
|
|
201
247
|
getCloseTriggerProps: () => T["button"];
|
|
202
248
|
}
|
|
203
249
|
|
|
204
|
-
export type { ElementIds, IntlTranslations, OpenChangeDetails, PopoverApi, PopoverMachine, PopoverProps, PopoverSchema, PopoverService, TriggerProps, TriggerValueChangeDetails };
|
|
250
|
+
export type { ContentState, ElementIds, IntlTranslations, OpenChangeDetails, PopoverApi, PopoverMachine, PopoverProps, PopoverSchema, PopoverService, PositionerState, TriggerProps, TriggerState, TriggerValueChangeDetails };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zag-js/popover",
|
|
3
|
-
"version": "2.0.0-next.
|
|
3
|
+
"version": "2.0.0-next.2",
|
|
4
4
|
"description": "Core logic for the popover widget implemented as a state machine",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"js",
|
|
@@ -14,7 +14,10 @@
|
|
|
14
14
|
"author": "Segun Adebayo <sage@adebayosegun.com>",
|
|
15
15
|
"homepage": "https://github.com/chakra-ui/zag#readme",
|
|
16
16
|
"license": "MIT",
|
|
17
|
-
"repository":
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/chakra-ui/zag/tree/main/packages/popover"
|
|
20
|
+
},
|
|
18
21
|
"sideEffects": false,
|
|
19
22
|
"files": [
|
|
20
23
|
"dist"
|
|
@@ -26,16 +29,16 @@
|
|
|
26
29
|
"url": "https://github.com/chakra-ui/zag/issues"
|
|
27
30
|
},
|
|
28
31
|
"dependencies": {
|
|
29
|
-
"@zag-js/anatomy": "2.0.0-next.
|
|
30
|
-
"@zag-js/aria-hidden": "2.0.0-next.
|
|
31
|
-
"@zag-js/core": "2.0.0-next.
|
|
32
|
-
"@zag-js/dom-query": "2.0.0-next.
|
|
33
|
-
"@zag-js/utils": "2.0.0-next.
|
|
34
|
-
"@zag-js/dismissable": "2.0.0-next.
|
|
35
|
-
"@zag-js/popper": "2.0.0-next.
|
|
36
|
-
"@zag-js/remove-scroll": "2.0.0-next.
|
|
37
|
-
"@zag-js/types": "2.0.0-next.
|
|
38
|
-
"@zag-js/focus-trap": "2.0.0-next.
|
|
32
|
+
"@zag-js/anatomy": "2.0.0-next.2",
|
|
33
|
+
"@zag-js/aria-hidden": "2.0.0-next.2",
|
|
34
|
+
"@zag-js/core": "2.0.0-next.2",
|
|
35
|
+
"@zag-js/dom-query": "2.0.0-next.2",
|
|
36
|
+
"@zag-js/utils": "2.0.0-next.2",
|
|
37
|
+
"@zag-js/dismissable": "2.0.0-next.2",
|
|
38
|
+
"@zag-js/popper": "2.0.0-next.2",
|
|
39
|
+
"@zag-js/remove-scroll": "2.0.0-next.2",
|
|
40
|
+
"@zag-js/types": "2.0.0-next.2",
|
|
41
|
+
"@zag-js/focus-trap": "2.0.0-next.2"
|
|
39
42
|
},
|
|
40
43
|
"devDependencies": {
|
|
41
44
|
"clean-package": "2.2.0"
|
|
@@ -69,7 +72,7 @@
|
|
|
69
72
|
},
|
|
70
73
|
"scripts": {
|
|
71
74
|
"build": "tsup",
|
|
72
|
-
"lint": "
|
|
75
|
+
"lint": "oxlint src",
|
|
73
76
|
"typecheck": "tsc --noEmit"
|
|
74
77
|
}
|
|
75
78
|
}
|