@destyler/popper 0.0.1-beta.7

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.cjs ADDED
@@ -0,0 +1,412 @@
1
+ 'use strict';
2
+
3
+ const vue = require('vue');
4
+ const shared = require('@destyler/shared');
5
+ const primitive = require('@destyler/primitive');
6
+ const composition = require('@destyler/composition');
7
+ const vue$1 = require('@floating-ui/vue');
8
+ const arrow = require('@destyler/arrow');
9
+
10
+ const [injectPopperRootContext, providePopperRootContext] = shared.createContext("DestylerPopperRoot");
11
+ const DestylerPopperRoot = vue.defineComponent({
12
+ name: "DestylerPopperRoot",
13
+ setup() {
14
+ const anchor = vue.ref();
15
+ providePopperRootContext({
16
+ anchor,
17
+ onAnchorChange: (element) => anchor.value = element
18
+ });
19
+ },
20
+ render() {
21
+ return this.$slots.default?.();
22
+ }
23
+ });
24
+
25
+ const destylerPopperAnchorProps = {
26
+ ...primitive.destylerPrimitiveProps,
27
+ element: {
28
+ type: Object
29
+ }
30
+ };
31
+ const DestylerPopperAnchor = vue.defineComponent({
32
+ name: "DestylerPopperAnchor",
33
+ props: destylerPopperAnchorProps,
34
+ setup(props) {
35
+ const { customElement, currentElement } = composition.useCustomElement();
36
+ const rootContext = injectPopperRootContext();
37
+ vue.watch(currentElement, () => {
38
+ rootContext.onAnchorChange(props.element ?? currentElement.value);
39
+ });
40
+ return {
41
+ customElement
42
+ };
43
+ },
44
+ render() {
45
+ return vue.h(primitive.DestylerPrimitive, {
46
+ as: this.$props.as,
47
+ asChild: this.$props.asChild,
48
+ ref: "customElement"
49
+ }, this.$slots.default?.());
50
+ }
51
+ });
52
+
53
+ function isNotNull(value) {
54
+ return value !== null;
55
+ }
56
+ function transformOrigin(options) {
57
+ return {
58
+ name: "transformOrigin",
59
+ options,
60
+ fn(data) {
61
+ const { placement, rects, middlewareData } = data;
62
+ const cannotCenterArrow = middlewareData.arrow?.centerOffset !== 0;
63
+ const isArrowHidden = cannotCenterArrow;
64
+ const arrowWidth = isArrowHidden ? 0 : options.arrowWidth;
65
+ const arrowHeight = isArrowHidden ? 0 : options.arrowHeight;
66
+ const [placedSide, placedAlign] = getSideAndAlignFromPlacement(placement);
67
+ const noArrowAlign = { start: "0%", center: "50%", end: "100%" }[placedAlign];
68
+ const arrowXCenter = (middlewareData.arrow?.x ?? 0) + arrowWidth / 2;
69
+ const arrowYCenter = (middlewareData.arrow?.y ?? 0) + arrowHeight / 2;
70
+ let x = "";
71
+ let y = "";
72
+ if (placedSide === "bottom") {
73
+ x = isArrowHidden ? noArrowAlign : `${arrowXCenter}px`;
74
+ y = `${-arrowHeight}px`;
75
+ } else if (placedSide === "top") {
76
+ x = isArrowHidden ? noArrowAlign : `${arrowXCenter}px`;
77
+ y = `${rects.floating.height + arrowHeight}px`;
78
+ } else if (placedSide === "right") {
79
+ x = `${-arrowHeight}px`;
80
+ y = isArrowHidden ? noArrowAlign : `${arrowYCenter}px`;
81
+ } else if (placedSide === "left") {
82
+ x = `${rects.floating.width + arrowHeight}px`;
83
+ y = isArrowHidden ? noArrowAlign : `${arrowYCenter}px`;
84
+ }
85
+ return { data: { x, y } };
86
+ }
87
+ };
88
+ }
89
+ function getSideAndAlignFromPlacement(placement) {
90
+ const [side, align = "center"] = placement.split("-");
91
+ return [side, align];
92
+ }
93
+
94
+ const [injectPopperContentContext, providePopperContentContext] = shared.createContext("DestylerPopperContent");
95
+ const destylerPopperContentProps = {
96
+ ...primitive.destylerPrimitiveProps,
97
+ side: {
98
+ type: String,
99
+ required: false,
100
+ default: "bottom"
101
+ },
102
+ sideOffset: {
103
+ type: Number,
104
+ required: false,
105
+ default: 0
106
+ },
107
+ align: {
108
+ type: String,
109
+ required: false,
110
+ default: "center"
111
+ },
112
+ alignOffset: {
113
+ type: Number,
114
+ required: false,
115
+ default: 0
116
+ },
117
+ avoidCollisions: {
118
+ type: Boolean,
119
+ required: false,
120
+ default: true
121
+ },
122
+ collisionBoundary: {
123
+ type: [Object, Array, null],
124
+ required: false,
125
+ default: () => []
126
+ },
127
+ collisionPadding: {
128
+ type: [Number, Object],
129
+ required: false,
130
+ default: 0
131
+ },
132
+ arrowPadding: {
133
+ type: Number,
134
+ required: false,
135
+ default: 0
136
+ },
137
+ sticky: {
138
+ type: String,
139
+ required: false,
140
+ default: "partial"
141
+ },
142
+ hideWhenDetached: {
143
+ type: Boolean,
144
+ required: false,
145
+ default: false
146
+ },
147
+ updatePositionStrategy: {
148
+ type: String,
149
+ required: false,
150
+ default: "optimized"
151
+ },
152
+ onPlaced: {
153
+ type: Function,
154
+ required: false
155
+ },
156
+ prioritizePosition: {
157
+ type: Boolean,
158
+ required: false,
159
+ default: false
160
+ }
161
+ };
162
+ const DestylerPopperContent = vue.defineComponent({
163
+ name: "DestylerPopperContent",
164
+ inheritAttrs: false,
165
+ props: destylerPopperContentProps,
166
+ setup(props, { attrs }) {
167
+ const rootContext = injectPopperRootContext();
168
+ const forwardRef = composition.useForwardRef();
169
+ const { customElement, currentElement: contentElement } = composition.useCustomElement();
170
+ const floatingRef = vue.ref();
171
+ const arrow = vue.ref();
172
+ const { width: arrowWidth, height: arrowHeight } = composition.useSize(arrow);
173
+ const desiredPlacement = vue.computed(() => props.side + (props.align !== "center" ? `-${props.align}` : ""));
174
+ const collisionPadding = vue.computed(() => {
175
+ return typeof props.collisionPadding === "number" ? props.collisionPadding : { top: 0, right: 0, bottom: 0, left: 0, ...props.collisionPadding };
176
+ });
177
+ const boundary = vue.computed(() => {
178
+ return Array.isArray(props.collisionBoundary) ? props.collisionBoundary : [props.collisionBoundary];
179
+ });
180
+ const detectOverflowOptions = vue.computed(() => {
181
+ return {
182
+ padding: collisionPadding.value,
183
+ boundary: boundary.value.filter(isNotNull),
184
+ // with `strategy: 'fixed'`, this is the only way to get it to respect boundaries
185
+ altBoundary: boundary.value.length > 0
186
+ };
187
+ });
188
+ const computedMiddleware = shared.computedEager(() => {
189
+ return [
190
+ vue$1.offset({
191
+ mainAxis: props.sideOffset + arrowHeight.value,
192
+ alignmentAxis: props.alignOffset
193
+ }),
194
+ props.avoidCollisions && vue$1.shift({
195
+ mainAxis: true,
196
+ crossAxis: !!props.prioritizePosition,
197
+ limiter: props.sticky === "partial" ? vue$1.limitShift() : void 0,
198
+ ...detectOverflowOptions.value
199
+ }),
200
+ !props.prioritizePosition && props.avoidCollisions && vue$1.flip({
201
+ ...detectOverflowOptions.value
202
+ }),
203
+ vue$1.size({
204
+ ...detectOverflowOptions.value,
205
+ apply: ({ elements, rects, availableWidth, availableHeight }) => {
206
+ const { width: anchorWidth, height: anchorHeight } = rects.reference;
207
+ const contentStyle = elements.floating.style;
208
+ Object.assign(elements.floating.style, {
209
+ maxWidth: `${availableWidth}px`,
210
+ maxHeight: `${availableHeight}px`
211
+ });
212
+ contentStyle.setProperty(
213
+ "--destyler_popper_available_width",
214
+ `${availableWidth}px`
215
+ );
216
+ contentStyle.setProperty(
217
+ "--destyler_popper_available_height",
218
+ `${availableHeight}px`
219
+ );
220
+ contentStyle.setProperty(
221
+ "--destyler_popper_anchor_width",
222
+ `${anchorWidth}px`
223
+ );
224
+ contentStyle.setProperty(
225
+ "--destyler_popper_anchor_height",
226
+ `${anchorHeight}px`
227
+ );
228
+ }
229
+ }),
230
+ arrow.value && vue$1.arrow({ element: arrow.value, padding: props.arrowPadding }),
231
+ transformOrigin({
232
+ arrowWidth: arrowWidth.value,
233
+ arrowHeight: arrowHeight.value
234
+ }),
235
+ props.hideWhenDetached && vue$1.hide({ strategy: "referenceHidden", ...detectOverflowOptions.value })
236
+ ];
237
+ });
238
+ const { floatingStyles, placement, isPositioned, middlewareData } = vue$1.useFloating(
239
+ rootContext.anchor,
240
+ floatingRef,
241
+ {
242
+ strategy: "fixed",
243
+ placement: desiredPlacement,
244
+ whileElementsMounted: (...args) => {
245
+ const cleanup = vue$1.autoUpdate(...args, {
246
+ animationFrame: props.updatePositionStrategy === "always"
247
+ });
248
+ return cleanup;
249
+ },
250
+ middleware: computedMiddleware
251
+ }
252
+ );
253
+ const placedSide = vue.computed(() => getSideAndAlignFromPlacement(placement.value)[0]);
254
+ const placedAlign = vue.computed(() => getSideAndAlignFromPlacement(placement.value)[1]);
255
+ vue.watchEffect(() => {
256
+ if (isPositioned.value)
257
+ props.onPlaced?.();
258
+ });
259
+ const cannotCenterArrow = vue.computed(
260
+ () => middlewareData.value.arrow?.centerOffset !== 0
261
+ );
262
+ const contentZIndex = vue.ref("");
263
+ vue.watchEffect(() => {
264
+ if (contentElement.value)
265
+ contentZIndex.value = window.getComputedStyle(contentElement.value).zIndex;
266
+ });
267
+ const arrowX = vue.computed(() => middlewareData.value.arrow?.x ?? 0);
268
+ const arrowY = vue.computed(() => middlewareData.value.arrow?.y ?? 0);
269
+ providePopperContentContext({
270
+ placedSide,
271
+ onArrowChange: (element) => arrow.value = element,
272
+ arrowX,
273
+ arrowY,
274
+ shouldHideArrow: cannotCenterArrow
275
+ });
276
+ return {
277
+ floatingRef,
278
+ floatingStyles,
279
+ isPositioned,
280
+ contentZIndex,
281
+ middlewareData,
282
+ forwardRef,
283
+ customElement,
284
+ placedSide,
285
+ placedAlign,
286
+ attrStyle: attrs.style
287
+ };
288
+ },
289
+ render() {
290
+ return vue.h("div", vue.mergeProps(this.$attrs, {
291
+ "data-destyler-popper-content-wrapper": "",
292
+ "ref": "floatingRef",
293
+ "style": {
294
+ ...this.floatingStyles,
295
+ transform: this.isPositioned ? this.floatingStyles.transform : "translate(0, -200%)",
296
+ minWidth: "max-content",
297
+ zIndex: this.contentZIndex,
298
+ ["--destyler_popper_transform_origin"]: [
299
+ this.middlewareData.transformOrigin?.x,
300
+ this.middlewareData.transformOrigin?.y
301
+ ].join(" ")
302
+ }
303
+ }), vue.h(primitive.DestylerPrimitive, vue.mergeProps(this.$attrs, {
304
+ "ref": (vnode) => {
305
+ this.forwardRef(vnode);
306
+ this.customElement = vnode;
307
+ },
308
+ "as": this.$props.as,
309
+ "asChild": this.$props.asChild,
310
+ "data-side": this.placedSide,
311
+ "data-align": this.placedAlign,
312
+ "style": {
313
+ animation: !this.isPositioned ? "none" : void 0,
314
+ opacity: this.middlewareData.hide?.referenceHidden ? 0 : void 0
315
+ }
316
+ }), this.$slots.default?.()));
317
+ }
318
+ });
319
+
320
+ const OPPOSITE_SIDE = {
321
+ top: "bottom",
322
+ right: "left",
323
+ bottom: "top",
324
+ left: "right"
325
+ };
326
+ const destylerPopperArrowProps = {
327
+ ...primitive.destylerPrimitiveProp,
328
+ ...arrow.destylerArrowProps,
329
+ as: {
330
+ type: [String, Object],
331
+ required: false,
332
+ default: "svg"
333
+ }
334
+ };
335
+ const DestylerPopperArrow = vue.defineComponent({
336
+ name: "DestylerPopperArrow",
337
+ inheritAttrs: false,
338
+ props: destylerPopperArrowProps,
339
+ setup() {
340
+ const contentContext = injectPopperContentContext();
341
+ const baseSide = vue.computed(() => OPPOSITE_SIDE[contentContext.placedSide.value]);
342
+ return {
343
+ contentContext,
344
+ baseSide
345
+ };
346
+ },
347
+ render() {
348
+ return vue.h("span", {
349
+ ref: (el) => {
350
+ this.contentContext.onArrowChange(el);
351
+ return void 0;
352
+ },
353
+ style: {
354
+ position: "absolute",
355
+ left: this.contentContext.arrowX?.value ? `${this.contentContext.arrowX?.value}px` : void 0,
356
+ top: this.contentContext.arrowY?.value ? `${this.contentContext.arrowY?.value}px` : void 0,
357
+ [this.baseSide]: 0,
358
+ transformOrigin: {
359
+ top: "",
360
+ right: "0 0",
361
+ bottom: "center 0",
362
+ left: "100% 0"
363
+ }[this.contentContext.placedSide.value],
364
+ transform: {
365
+ top: "translateY(100%)",
366
+ right: "translateY(50%) rotate(90deg) translateX(-50%)",
367
+ bottom: `rotate(180deg)`,
368
+ left: "translateY(50%) rotate(-90deg) translateX(50%)"
369
+ }[this.contentContext.placedSide.value],
370
+ visibility: this.contentContext.shouldHideArrow.value ? "hidden" : void 0
371
+ }
372
+ }, vue.h(arrow.DestylerArrow, vue.mergeProps(this.$attrs, {
373
+ as: this.$props.as,
374
+ asChild: this.$props.asChild,
375
+ width: this.$props.width,
376
+ height: this.$props.height,
377
+ style: {
378
+ display: "block"
379
+ }
380
+ }), this.$slots.default?.()));
381
+ }
382
+ });
383
+
384
+ const name = "@destyler/popper";
385
+
386
+ const packageName = name;
387
+ function DestylerPopperResolver() {
388
+ return {
389
+ type: "component",
390
+ resolve: (name2) => {
391
+ if (name2 === "DestylerTemplate")
392
+ return { name: name2, from: packageName };
393
+ }
394
+ };
395
+ }
396
+
397
+ exports.DestylerPopperAnchor = DestylerPopperAnchor;
398
+ exports.DestylerPopperArrow = DestylerPopperArrow;
399
+ exports.DestylerPopperContent = DestylerPopperContent;
400
+ exports.DestylerPopperResolver = DestylerPopperResolver;
401
+ exports.DestylerPopperRoot = DestylerPopperRoot;
402
+ exports.OPPOSITE_SIDE = OPPOSITE_SIDE;
403
+ exports.destylerPopperAnchorProps = destylerPopperAnchorProps;
404
+ exports.destylerPopperArrowProps = destylerPopperArrowProps;
405
+ exports.destylerPopperContentProps = destylerPopperContentProps;
406
+ exports.getSideAndAlignFromPlacement = getSideAndAlignFromPlacement;
407
+ exports.injectPopperContentContext = injectPopperContentContext;
408
+ exports.injectPopperRootContext = injectPopperRootContext;
409
+ exports.isNotNull = isNotNull;
410
+ exports.providePopperContentContext = providePopperContentContext;
411
+ exports.providePopperRootContext = providePopperRootContext;
412
+ exports.transformOrigin = transformOrigin;