1 | var __create = Object.create;
|
2 | var __defProp = Object.defineProperty;
|
3 | var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
4 | var __getOwnPropNames = Object.getOwnPropertyNames;
|
5 | var __getProtoOf = Object.getPrototypeOf;
|
6 | var __hasOwnProp = Object.prototype.hasOwnProperty;
|
7 | var __export = (target, all) => {
|
8 | for (var name2 in all)
|
9 | __defProp(target, name2, { get: all[name2], enumerable: true });
|
10 | };
|
11 | var __copyProps = (to, from, except, desc) => {
|
12 | if (from && typeof from === "object" || typeof from === "function") {
|
13 | for (let key of __getOwnPropNames(from))
|
14 | if (!__hasOwnProp.call(to, key) && key !== except)
|
15 | __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
16 | }
|
17 | return to;
|
18 | };
|
19 | var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
20 |
|
21 |
|
22 |
|
23 |
|
24 | isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
25 | mod
|
26 | ));
|
27 | var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
28 | var stdin_exports = {};
|
29 | __export(stdin_exports, {
|
30 | default: () => stdin_default,
|
31 | floatingBubbleProps: () => floatingBubbleProps
|
32 | });
|
33 | module.exports = __toCommonJS(stdin_exports);
|
34 | var import_vue = require("vue");
|
35 | var import_utils = require("../utils");
|
36 | var import_use = require("@vant/use");
|
37 | var import_use_touch = require("../composables/use-touch");
|
38 | var import_icon = __toESM(require("../icon"));
|
39 | const floatingBubbleProps = {
|
40 | gap: (0, import_utils.makeNumberProp)(24),
|
41 | icon: String,
|
42 | axis: (0, import_utils.makeStringProp)("y"),
|
43 | magnetic: String,
|
44 | offset: {
|
45 | type: Object,
|
46 | default: () => ({
|
47 | x: -1,
|
48 | y: -1
|
49 | })
|
50 | },
|
51 | teleport: {
|
52 | type: [String, Object],
|
53 | default: "body"
|
54 | }
|
55 | };
|
56 | const [name, bem] = (0, import_utils.createNamespace)("floating-bubble");
|
57 | var stdin_default = (0, import_vue.defineComponent)({
|
58 | name,
|
59 | inheritAttrs: false,
|
60 | props: floatingBubbleProps,
|
61 | emits: ["click", "update:offset", "offsetChange"],
|
62 | setup(props, {
|
63 | slots,
|
64 | emit,
|
65 | attrs
|
66 | }) {
|
67 | const rootRef = (0, import_vue.ref)();
|
68 | const state = (0, import_vue.ref)({
|
69 | x: 0,
|
70 | y: 0,
|
71 | width: 0,
|
72 | height: 0
|
73 | });
|
74 | const boundary = (0, import_vue.computed)(() => ({
|
75 | top: props.gap,
|
76 | right: import_utils.windowWidth.value - state.value.width - props.gap,
|
77 | bottom: import_utils.windowHeight.value - state.value.height - props.gap,
|
78 | left: props.gap
|
79 | }));
|
80 | const dragging = (0, import_vue.ref)(false);
|
81 | let initialized = false;
|
82 | const rootStyle = (0, import_vue.computed)(() => {
|
83 | const style = {};
|
84 | const x = (0, import_utils.addUnit)(state.value.x);
|
85 | const y = (0, import_utils.addUnit)(state.value.y);
|
86 | style.transform = `translate3d(${x}, ${y}, 0)`;
|
87 | if (dragging.value || !initialized) {
|
88 | style.transition = "none";
|
89 | }
|
90 | return style;
|
91 | });
|
92 | const updateState = () => {
|
93 | if (!show.value) return;
|
94 | const {
|
95 | width,
|
96 | height
|
97 | } = (0, import_use.useRect)(rootRef.value);
|
98 | const {
|
99 | offset
|
100 | } = props;
|
101 | state.value = {
|
102 | x: offset.x > -1 ? offset.x : import_utils.windowWidth.value - width - props.gap,
|
103 | y: offset.y > -1 ? offset.y : import_utils.windowHeight.value - height - props.gap,
|
104 | width,
|
105 | height
|
106 | };
|
107 | };
|
108 | const touch = (0, import_use_touch.useTouch)();
|
109 | let prevX = 0;
|
110 | let prevY = 0;
|
111 | const onTouchStart = (e) => {
|
112 | touch.start(e);
|
113 | dragging.value = true;
|
114 | prevX = state.value.x;
|
115 | prevY = state.value.y;
|
116 | };
|
117 | const onTouchMove = (e) => {
|
118 | e.preventDefault();
|
119 | touch.move(e);
|
120 | if (props.axis === "lock") return;
|
121 | if (!touch.isTap.value) {
|
122 | if (props.axis === "x" || props.axis === "xy") {
|
123 | let nextX = prevX + touch.deltaX.value;
|
124 | if (nextX < boundary.value.left) nextX = boundary.value.left;
|
125 | if (nextX > boundary.value.right) nextX = boundary.value.right;
|
126 | state.value.x = nextX;
|
127 | }
|
128 | if (props.axis === "y" || props.axis === "xy") {
|
129 | let nextY = prevY + touch.deltaY.value;
|
130 | if (nextY < boundary.value.top) nextY = boundary.value.top;
|
131 | if (nextY > boundary.value.bottom) nextY = boundary.value.bottom;
|
132 | state.value.y = nextY;
|
133 | }
|
134 | const offset = (0, import_utils.pick)(state.value, ["x", "y"]);
|
135 | emit("update:offset", offset);
|
136 | }
|
137 | };
|
138 | (0, import_use.useEventListener)("touchmove", onTouchMove, {
|
139 | target: rootRef
|
140 | });
|
141 | const onTouchEnd = () => {
|
142 | dragging.value = false;
|
143 | (0, import_vue.nextTick)(() => {
|
144 | if (props.magnetic === "x") {
|
145 | const nextX = (0, import_utils.closest)([boundary.value.left, boundary.value.right], state.value.x);
|
146 | state.value.x = nextX;
|
147 | }
|
148 | if (props.magnetic === "y") {
|
149 | const nextY = (0, import_utils.closest)([boundary.value.top, boundary.value.bottom], state.value.y);
|
150 | state.value.y = nextY;
|
151 | }
|
152 | if (!touch.isTap.value) {
|
153 | const offset = (0, import_utils.pick)(state.value, ["x", "y"]);
|
154 | emit("update:offset", offset);
|
155 | if (prevX !== offset.x || prevY !== offset.y) {
|
156 | emit("offsetChange", offset);
|
157 | }
|
158 | }
|
159 | });
|
160 | };
|
161 | const onClick = (e) => {
|
162 | if (touch.isTap.value) emit("click", e);
|
163 | else e.stopPropagation();
|
164 | };
|
165 | (0, import_vue.onMounted)(() => {
|
166 | updateState();
|
167 | (0, import_vue.nextTick)(() => {
|
168 | initialized = true;
|
169 | });
|
170 | });
|
171 | (0, import_vue.watch)([import_utils.windowWidth, import_utils.windowHeight, () => props.gap, () => props.offset], updateState, {
|
172 | deep: true
|
173 | });
|
174 | const show = (0, import_vue.ref)(true);
|
175 | (0, import_vue.onActivated)(() => {
|
176 | show.value = true;
|
177 | });
|
178 | (0, import_vue.onDeactivated)(() => {
|
179 | if (props.teleport) {
|
180 | show.value = false;
|
181 | }
|
182 | });
|
183 | return () => {
|
184 | const Content = (0, import_vue.withDirectives)((0, import_vue.createVNode)("div", (0, import_vue.mergeProps)({
|
185 | "class": bem(),
|
186 | "ref": rootRef,
|
187 | "onTouchstartPassive": onTouchStart,
|
188 | "onTouchend": onTouchEnd,
|
189 | "onTouchcancel": onTouchEnd,
|
190 | "onClickCapture": onClick,
|
191 | "style": rootStyle.value
|
192 | }, attrs), [slots.default ? slots.default() : (0, import_vue.createVNode)(import_icon.default, {
|
193 | "name": props.icon,
|
194 | "class": bem("icon")
|
195 | }, null)]), [[import_vue.vShow, show.value]]);
|
196 | return props.teleport ? (0, import_vue.createVNode)(import_vue.Teleport, {
|
197 | "to": props.teleport
|
198 | }, {
|
199 | default: () => [Content]
|
200 | }) : Content;
|
201 | };
|
202 | }
|
203 | });
|