@aipanel/ui 1.2.0-beta.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/es/AI-panel-widget/composables/use-inspector.d.ts +52 -0
- package/es/AI-panel-widget/composables/use-inspector.mjs +437 -0
- package/es/AI-panel-widget/composables/use-persist-state.d.ts +32 -0
- package/es/AI-panel-widget/composables/use-persist-state.mjs +83 -0
- package/es/AI-panel-widget/composables/use-selection.d.ts +19 -0
- package/es/AI-panel-widget/composables/use-selection.mjs +112 -0
- package/es/AI-panel-widget/composables/use-session.d.ts +16 -0
- package/es/AI-panel-widget/composables/use-session.mjs +47 -0
- package/es/AI-panel-widget/composables/use-split.d.ts +30 -0
- package/es/AI-panel-widget/composables/use-split.mjs +133 -0
- package/es/AI-panel-widget/composables/use-widget.d.ts +27 -0
- package/es/AI-panel-widget/composables/use-widget.mjs +78 -0
- package/es/AI-panel-widget/index.d.ts +5 -0
- package/es/AI-panel-widget/index.mjs +9 -0
- package/es/AI-panel-widget/src/assets/logo.svg +13 -0
- package/es/AI-panel-widget/src/components/AIPanelLogo-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/AIPanelLogo.vue.d.ts +8 -0
- package/es/AI-panel-widget/src/components/AIPanelLogo.vue.mjs +40 -0
- package/es/AI-panel-widget/src/components/ChatPanel-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/ChatPanel.vue.d.ts +179 -0
- package/es/AI-panel-widget/src/components/ChatPanel.vue.mjs +308 -0
- package/es/AI-panel-widget/src/components/FloatingBubble/FloatingBubble-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/FloatingBubble/FloatingBubble.vue.d.ts +44 -0
- package/es/AI-panel-widget/src/components/FloatingBubble/FloatingBubble.vue.mjs +311 -0
- package/es/AI-panel-widget/src/components/FloatingBubble/index.d.ts +3 -0
- package/es/AI-panel-widget/src/components/FloatingBubble/index.mjs +5 -0
- package/es/AI-panel-widget/src/components/FloatingBubble/types.d.ts +24 -0
- package/es/AI-panel-widget/src/components/FloatingBubble/types.mjs +0 -0
- package/es/AI-panel-widget/src/components/Frame-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/Frame.vue.d.ts +22 -0
- package/es/AI-panel-widget/src/components/Frame.vue.mjs +143 -0
- package/es/AI-panel-widget/src/components/Header-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/Header.vue.d.ts +27 -0
- package/es/AI-panel-widget/src/components/Header.vue.mjs +683 -0
- package/es/AI-panel-widget/src/components/ResizeHandle-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/ResizeHandle.vue.d.ts +22 -0
- package/es/AI-panel-widget/src/components/ResizeHandle.vue.mjs +79 -0
- package/es/AI-panel-widget/src/components/SelectHint-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/SelectHint.vue.d.ts +3 -0
- package/es/AI-panel-widget/src/components/SelectHint.vue.mjs +40 -0
- package/es/AI-panel-widget/src/components/SelectedBubbles-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/SelectedBubbles.vue.d.ts +3 -0
- package/es/AI-panel-widget/src/components/SelectedBubbles.vue.mjs +84 -0
- package/es/AI-panel-widget/src/components/SelectedNodes-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/SelectedNodes.vue.d.ts +3 -0
- package/es/AI-panel-widget/src/components/SelectedNodes.vue.mjs +103 -0
- package/es/AI-panel-widget/src/components/SessionList-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/SessionList.vue.d.ts +13 -0
- package/es/AI-panel-widget/src/components/SessionList.vue.mjs +222 -0
- package/es/AI-panel-widget/src/components/SplitTrigger-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/SplitTrigger.vue.d.ts +18 -0
- package/es/AI-panel-widget/src/components/SplitTrigger.vue.mjs +112 -0
- package/es/AI-panel-widget/src/components/Trigger-sfc.css +1 -0
- package/es/AI-panel-widget/src/components/Trigger.vue.d.ts +28 -0
- package/es/AI-panel-widget/src/components/Trigger.vue.mjs +74 -0
- package/es/AI-panel-widget/src/context.d.ts +67 -0
- package/es/AI-panel-widget/src/context.mjs +16 -0
- package/es/AI-panel-widget/src/index-sfc.css +1 -0
- package/es/AI-panel-widget/src/index.vue.d.ts +69 -0
- package/es/AI-panel-widget/src/index.vue.mjs +782 -0
- package/es/AI-panel-widget/src/types.d.ts +2 -0
- package/es/AI-panel-widget/src/types.mjs +0 -0
- package/es/AI-panel-widget/style/index-pure.d.ts +0 -0
- package/es/AI-panel-widget/style/index-pure.mjs +0 -0
- package/es/AI-panel-widget/style/index.d.ts +0 -0
- package/es/AI-panel-widget/style/index.mjs +0 -0
- package/es/AI-panel-widget/style/less-pure.d.ts +0 -0
- package/es/AI-panel-widget/style/less-pure.mjs +0 -0
- package/es/AI-panel-widget/style/less.d.ts +0 -0
- package/es/AI-panel-widget/style/less.mjs +0 -0
- package/es/env.d.ts +15 -0
- package/es/index.d.ts +7 -0
- package/es/index.mjs +22 -0
- package/es/setup.d.ts +1 -0
- package/es/setup.mjs +4 -0
- package/lib/AI-panel-widget/composables/use-inspector.cjs +466 -0
- package/lib/AI-panel-widget/composables/use-inspector.d.ts +52 -0
- package/lib/AI-panel-widget/composables/use-persist-state.cjs +102 -0
- package/lib/AI-panel-widget/composables/use-persist-state.d.ts +32 -0
- package/lib/AI-panel-widget/composables/use-selection.cjs +131 -0
- package/lib/AI-panel-widget/composables/use-selection.d.ts +19 -0
- package/lib/AI-panel-widget/composables/use-session.cjs +66 -0
- package/lib/AI-panel-widget/composables/use-session.d.ts +16 -0
- package/lib/AI-panel-widget/composables/use-split.cjs +152 -0
- package/lib/AI-panel-widget/composables/use-split.d.ts +30 -0
- package/lib/AI-panel-widget/composables/use-widget.cjs +97 -0
- package/lib/AI-panel-widget/composables/use-widget.d.ts +27 -0
- package/lib/AI-panel-widget/index.cjs +39 -0
- package/lib/AI-panel-widget/index.d.ts +5 -0
- package/lib/AI-panel-widget/src/assets/logo.svg +13 -0
- package/lib/AI-panel-widget/src/components/AIPanelLogo-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/AIPanelLogo.vue.cjs +69 -0
- package/lib/AI-panel-widget/src/components/AIPanelLogo.vue.d.ts +8 -0
- package/lib/AI-panel-widget/src/components/ChatPanel-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/ChatPanel.vue.cjs +337 -0
- package/lib/AI-panel-widget/src/components/ChatPanel.vue.d.ts +179 -0
- package/lib/AI-panel-widget/src/components/FloatingBubble/FloatingBubble-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/FloatingBubble/FloatingBubble.vue.cjs +330 -0
- package/lib/AI-panel-widget/src/components/FloatingBubble/FloatingBubble.vue.d.ts +44 -0
- package/lib/AI-panel-widget/src/components/FloatingBubble/index.cjs +35 -0
- package/lib/AI-panel-widget/src/components/FloatingBubble/index.d.ts +3 -0
- package/lib/AI-panel-widget/src/components/FloatingBubble/types.cjs +15 -0
- package/lib/AI-panel-widget/src/components/FloatingBubble/types.d.ts +24 -0
- package/lib/AI-panel-widget/src/components/Frame-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/Frame.vue.cjs +162 -0
- package/lib/AI-panel-widget/src/components/Frame.vue.d.ts +22 -0
- package/lib/AI-panel-widget/src/components/Header-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/Header.vue.cjs +702 -0
- package/lib/AI-panel-widget/src/components/Header.vue.d.ts +27 -0
- package/lib/AI-panel-widget/src/components/ResizeHandle-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/ResizeHandle.vue.cjs +98 -0
- package/lib/AI-panel-widget/src/components/ResizeHandle.vue.d.ts +22 -0
- package/lib/AI-panel-widget/src/components/SelectHint-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/SelectHint.vue.cjs +59 -0
- package/lib/AI-panel-widget/src/components/SelectHint.vue.d.ts +3 -0
- package/lib/AI-panel-widget/src/components/SelectedBubbles-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/SelectedBubbles.vue.cjs +103 -0
- package/lib/AI-panel-widget/src/components/SelectedBubbles.vue.d.ts +3 -0
- package/lib/AI-panel-widget/src/components/SelectedNodes-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/SelectedNodes.vue.cjs +122 -0
- package/lib/AI-panel-widget/src/components/SelectedNodes.vue.d.ts +3 -0
- package/lib/AI-panel-widget/src/components/SessionList-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/SessionList.vue.cjs +241 -0
- package/lib/AI-panel-widget/src/components/SessionList.vue.d.ts +13 -0
- package/lib/AI-panel-widget/src/components/SplitTrigger-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/SplitTrigger.vue.cjs +131 -0
- package/lib/AI-panel-widget/src/components/SplitTrigger.vue.d.ts +18 -0
- package/lib/AI-panel-widget/src/components/Trigger-sfc.css +1 -0
- package/lib/AI-panel-widget/src/components/Trigger.vue.cjs +103 -0
- package/lib/AI-panel-widget/src/components/Trigger.vue.d.ts +28 -0
- package/lib/AI-panel-widget/src/context.cjs +35 -0
- package/lib/AI-panel-widget/src/context.d.ts +67 -0
- package/lib/AI-panel-widget/src/index-sfc.css +1 -0
- package/lib/AI-panel-widget/src/index.vue.cjs +811 -0
- package/lib/AI-panel-widget/src/index.vue.d.ts +69 -0
- package/lib/AI-panel-widget/src/types.cjs +15 -0
- package/lib/AI-panel-widget/src/types.d.ts +2 -0
- package/lib/AI-panel-widget/style/index-pure.cjs +0 -0
- package/lib/AI-panel-widget/style/index-pure.d.ts +0 -0
- package/lib/AI-panel-widget/style/index.cjs +0 -0
- package/lib/AI-panel-widget/style/index.d.ts +0 -0
- package/lib/AI-panel-widget/style/less-pure.cjs +0 -0
- package/lib/AI-panel-widget/style/less-pure.d.ts +0 -0
- package/lib/AI-panel-widget/style/less.cjs +0 -0
- package/lib/AI-panel-widget/style/less.d.ts +0 -0
- package/lib/env.d.ts +15 -0
- package/lib/index.cjs +42 -0
- package/lib/index.css +0 -0
- package/lib/index.d.ts +7 -0
- package/lib/index.less +0 -0
- package/lib/setup.cjs +23 -0
- package/lib/setup.d.ts +1 -0
- package/package.json +42 -0
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import "./FloatingBubble-sfc.css";
|
|
2
|
+
import { defineComponent as _defineComponent } from "vue";
|
|
3
|
+
import { ref, computed, watch, onMounted, onUnmounted } from "vue";
|
|
4
|
+
const __vue_sfc__ = /* @__PURE__ */ _defineComponent({
|
|
5
|
+
...{
|
|
6
|
+
name: "FloatingBubble"
|
|
7
|
+
},
|
|
8
|
+
__name: "FloatingBubble",
|
|
9
|
+
props: {
|
|
10
|
+
offset: { type: Object, required: false, default: void 0 },
|
|
11
|
+
axis: { type: String, required: false, default: "xy" },
|
|
12
|
+
magnetic: { type: String, required: false, default: void 0 },
|
|
13
|
+
gap: { type: [Number, Object], required: false, default: 24 },
|
|
14
|
+
teleport: { type: null, required: false, default: "body" }
|
|
15
|
+
},
|
|
16
|
+
emits: ["update:offset", "click", "offset-change", "drag-start", "drag-end"],
|
|
17
|
+
setup(__props, { expose: __expose, emit: __emit }) {
|
|
18
|
+
const props = __props;
|
|
19
|
+
const emit = __emit;
|
|
20
|
+
const rootRef = ref(null);
|
|
21
|
+
const state = ref({
|
|
22
|
+
x: 0,
|
|
23
|
+
y: 0,
|
|
24
|
+
width: 0,
|
|
25
|
+
height: 0
|
|
26
|
+
});
|
|
27
|
+
const isObject = (val) => val !== null && typeof val === "object";
|
|
28
|
+
const gapX = computed(
|
|
29
|
+
() => isObject(props.gap) ? props.gap.x : props.gap
|
|
30
|
+
);
|
|
31
|
+
const gapY = computed(
|
|
32
|
+
() => isObject(props.gap) ? props.gap.y : props.gap
|
|
33
|
+
);
|
|
34
|
+
const windowWidth = ref(typeof window !== "undefined" ? window.innerWidth : 0);
|
|
35
|
+
const windowHeight = ref(typeof window !== "undefined" ? window.innerHeight : 0);
|
|
36
|
+
const boundary = computed(() => ({
|
|
37
|
+
top: gapY.value,
|
|
38
|
+
right: windowWidth.value - state.value.width - gapX.value,
|
|
39
|
+
bottom: windowHeight.value - state.value.height - gapY.value,
|
|
40
|
+
left: gapX.value
|
|
41
|
+
}));
|
|
42
|
+
const closest = (arr, target) => {
|
|
43
|
+
return arr.reduce(
|
|
44
|
+
(pre, cur) => Math.abs(pre - target) < Math.abs(cur - target) ? pre : cur
|
|
45
|
+
);
|
|
46
|
+
};
|
|
47
|
+
const applyMagnetic = () => {
|
|
48
|
+
if (props.magnetic === "x") {
|
|
49
|
+
if (magneticSide.value === "left") {
|
|
50
|
+
state.value.x = boundary.value.left;
|
|
51
|
+
} else if (magneticSide.value === "right") {
|
|
52
|
+
state.value.x = boundary.value.right;
|
|
53
|
+
} else {
|
|
54
|
+
const nextX = closest(
|
|
55
|
+
[boundary.value.left, boundary.value.right],
|
|
56
|
+
state.value.x
|
|
57
|
+
);
|
|
58
|
+
state.value.x = nextX;
|
|
59
|
+
magneticSide.value = nextX === boundary.value.left ? "left" : "right";
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (props.magnetic === "y") {
|
|
63
|
+
const nextY = closest(
|
|
64
|
+
[boundary.value.top, boundary.value.bottom],
|
|
65
|
+
state.value.y
|
|
66
|
+
);
|
|
67
|
+
state.value.y = nextY;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const dragging = ref(false);
|
|
71
|
+
const initialized = ref(false);
|
|
72
|
+
const magneticSide = ref(null);
|
|
73
|
+
const rootStyle = computed(() => {
|
|
74
|
+
const style = {};
|
|
75
|
+
const x = `${state.value.x}px`;
|
|
76
|
+
const y = `${state.value.y}px`;
|
|
77
|
+
style.transform = `translate3d(${x}, ${y}, 0)`;
|
|
78
|
+
if (dragging.value || !initialized.value) {
|
|
79
|
+
style.transition = "none";
|
|
80
|
+
} else {
|
|
81
|
+
style.transition = "transform 0.3s ease";
|
|
82
|
+
}
|
|
83
|
+
return style;
|
|
84
|
+
});
|
|
85
|
+
const updateState = () => {
|
|
86
|
+
if (!rootRef.value || typeof window === "undefined") return;
|
|
87
|
+
const rect = rootRef.value.getBoundingClientRect();
|
|
88
|
+
const { offset } = props;
|
|
89
|
+
let x = offset ? offset.x : windowWidth.value - rect.width - gapX.value;
|
|
90
|
+
let y = offset ? offset.y : windowHeight.value - rect.height - gapY.value;
|
|
91
|
+
const maxX = windowWidth.value - rect.width - gapX.value;
|
|
92
|
+
const maxY = windowHeight.value - rect.height - gapY.value;
|
|
93
|
+
if (x < gapX.value) x = gapX.value;
|
|
94
|
+
if (x > maxX) x = maxX;
|
|
95
|
+
if (y < gapY.value) y = gapY.value;
|
|
96
|
+
if (y > maxY) y = maxY;
|
|
97
|
+
const oldX = state.value.x;
|
|
98
|
+
const oldY = state.value.y;
|
|
99
|
+
state.value = {
|
|
100
|
+
x,
|
|
101
|
+
y,
|
|
102
|
+
width: rect.width,
|
|
103
|
+
height: rect.height
|
|
104
|
+
};
|
|
105
|
+
if (!dragging.value) {
|
|
106
|
+
if (props.magnetic === "x" && magneticSide.value) {
|
|
107
|
+
if (magneticSide.value === "left") {
|
|
108
|
+
state.value.x = boundary.value.left;
|
|
109
|
+
} else {
|
|
110
|
+
state.value.x = boundary.value.right;
|
|
111
|
+
}
|
|
112
|
+
} else {
|
|
113
|
+
applyMagnetic();
|
|
114
|
+
}
|
|
115
|
+
if (state.value.x !== oldX || state.value.y !== oldY) {
|
|
116
|
+
const offset2 = { x: state.value.x, y: state.value.y };
|
|
117
|
+
emit("update:offset", offset2);
|
|
118
|
+
emit("offset-change", offset2);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
const touch = {
|
|
123
|
+
startX: ref(0),
|
|
124
|
+
startY: ref(0),
|
|
125
|
+
deltaX: ref(0),
|
|
126
|
+
deltaY: ref(0),
|
|
127
|
+
offsetX: ref(0),
|
|
128
|
+
offsetY: ref(0),
|
|
129
|
+
isTap: ref(true),
|
|
130
|
+
start(e) {
|
|
131
|
+
this.startX.value = "touches" in e ? e.touches[0].clientX : e.clientX;
|
|
132
|
+
this.startY.value = "touches" in e ? e.touches[0].clientY : e.clientY;
|
|
133
|
+
this.deltaX.value = 0;
|
|
134
|
+
this.deltaY.value = 0;
|
|
135
|
+
this.offsetX.value = 0;
|
|
136
|
+
this.offsetY.value = 0;
|
|
137
|
+
this.isTap.value = true;
|
|
138
|
+
},
|
|
139
|
+
move(e) {
|
|
140
|
+
const clientX = "touches" in e ? e.touches[0].clientX : e.clientX;
|
|
141
|
+
const clientY = "touches" in e ? e.touches[0].clientY : e.clientY;
|
|
142
|
+
this.deltaX.value = clientX - this.startX.value;
|
|
143
|
+
this.deltaY.value = clientY - this.startY.value;
|
|
144
|
+
this.offsetX.value = Math.abs(this.deltaX.value);
|
|
145
|
+
this.offsetY.value = Math.abs(this.deltaY.value);
|
|
146
|
+
const TAP_OFFSET = 5;
|
|
147
|
+
if (this.isTap.value && (this.offsetX.value > TAP_OFFSET || this.offsetY.value > TAP_OFFSET)) {
|
|
148
|
+
this.isTap.value = false;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
let prevX = 0;
|
|
153
|
+
let prevY = 0;
|
|
154
|
+
const onTouchStart = (e) => {
|
|
155
|
+
touch.start(e);
|
|
156
|
+
dragging.value = true;
|
|
157
|
+
prevX = state.value.x;
|
|
158
|
+
prevY = state.value.y;
|
|
159
|
+
document.body.classList.add("floating-bubble-dragging");
|
|
160
|
+
if (!("touches" in e)) {
|
|
161
|
+
window.addEventListener("mousemove", onTouchMove, { passive: false });
|
|
162
|
+
window.addEventListener("mouseup", onTouchEnd);
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
const onTouchMove = (e) => {
|
|
166
|
+
if (e.cancelable) {
|
|
167
|
+
e.preventDefault();
|
|
168
|
+
}
|
|
169
|
+
const wasTap = touch.isTap.value;
|
|
170
|
+
touch.move(e);
|
|
171
|
+
if (wasTap && !touch.isTap.value) {
|
|
172
|
+
emit("drag-start");
|
|
173
|
+
}
|
|
174
|
+
if (props.axis === "lock") return;
|
|
175
|
+
if (!touch.isTap.value) {
|
|
176
|
+
if (props.axis === "x" || props.axis === "xy") {
|
|
177
|
+
let nextX = prevX + touch.deltaX.value;
|
|
178
|
+
if (nextX < boundary.value.left) nextX = boundary.value.left;
|
|
179
|
+
if (nextX > boundary.value.right) nextX = boundary.value.right;
|
|
180
|
+
state.value.x = nextX;
|
|
181
|
+
}
|
|
182
|
+
if (props.axis === "y" || props.axis === "xy") {
|
|
183
|
+
let nextY = prevY + touch.deltaY.value;
|
|
184
|
+
if (nextY < boundary.value.top) nextY = boundary.value.top;
|
|
185
|
+
if (nextY > boundary.value.bottom) nextY = boundary.value.bottom;
|
|
186
|
+
state.value.y = nextY;
|
|
187
|
+
}
|
|
188
|
+
const offset = { x: state.value.x, y: state.value.y };
|
|
189
|
+
emit("update:offset", offset);
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
const onTouchEnd = (e) => {
|
|
193
|
+
dragging.value = false;
|
|
194
|
+
document.body.classList.remove("floating-bubble-dragging");
|
|
195
|
+
if (e && !("touches" in e) && e.type === "mouseup") {
|
|
196
|
+
window.removeEventListener("mousemove", onTouchMove);
|
|
197
|
+
window.removeEventListener("mouseup", onTouchEnd);
|
|
198
|
+
}
|
|
199
|
+
requestAnimationFrame(() => {
|
|
200
|
+
if (props.magnetic === "x" && !touch.isTap.value) {
|
|
201
|
+
const centerX = state.value.x + state.value.width / 2;
|
|
202
|
+
const windowCenterX = windowWidth.value / 2;
|
|
203
|
+
magneticSide.value = centerX < windowCenterX ? "left" : "right";
|
|
204
|
+
}
|
|
205
|
+
applyMagnetic();
|
|
206
|
+
if (!touch.isTap.value) {
|
|
207
|
+
emit("drag-end");
|
|
208
|
+
const offset = { x: state.value.x, y: state.value.y };
|
|
209
|
+
emit("update:offset", offset);
|
|
210
|
+
if (prevX !== offset.x || prevY !== offset.y) {
|
|
211
|
+
emit("offset-change", offset);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
};
|
|
216
|
+
const onClick = (e) => {
|
|
217
|
+
if (touch.isTap.value) {
|
|
218
|
+
emit("click", e);
|
|
219
|
+
} else {
|
|
220
|
+
e.stopPropagation();
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
const handleResize = () => {
|
|
224
|
+
if (typeof window !== "undefined") {
|
|
225
|
+
windowWidth.value = window.innerWidth;
|
|
226
|
+
windowHeight.value = window.innerHeight;
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
onMounted(() => {
|
|
230
|
+
updateState();
|
|
231
|
+
requestAnimationFrame(() => {
|
|
232
|
+
initialized.value = true;
|
|
233
|
+
});
|
|
234
|
+
if (typeof window !== "undefined") {
|
|
235
|
+
window.addEventListener("resize", handleResize);
|
|
236
|
+
}
|
|
237
|
+
if (rootRef.value) {
|
|
238
|
+
rootRef.value.addEventListener("touchmove", onTouchMove, {
|
|
239
|
+
passive: false
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
onUnmounted(() => {
|
|
244
|
+
document.body.classList.remove("floating-bubble-dragging");
|
|
245
|
+
if (typeof window !== "undefined") {
|
|
246
|
+
window.removeEventListener("resize", handleResize);
|
|
247
|
+
window.removeEventListener("mousemove", onTouchMove);
|
|
248
|
+
window.removeEventListener("mouseup", onTouchEnd);
|
|
249
|
+
}
|
|
250
|
+
if (rootRef.value) {
|
|
251
|
+
rootRef.value.removeEventListener("touchmove", onTouchMove);
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
watch(
|
|
255
|
+
[windowWidth, windowHeight, gapX, gapY],
|
|
256
|
+
updateState
|
|
257
|
+
);
|
|
258
|
+
watch(
|
|
259
|
+
() => props.offset,
|
|
260
|
+
(newOffset) => {
|
|
261
|
+
if (newOffset) {
|
|
262
|
+
magneticSide.value = null;
|
|
263
|
+
}
|
|
264
|
+
updateState();
|
|
265
|
+
},
|
|
266
|
+
{ deep: true }
|
|
267
|
+
);
|
|
268
|
+
__expose({
|
|
269
|
+
offset: computed(() => ({ x: state.value.x, y: state.value.y }))
|
|
270
|
+
});
|
|
271
|
+
const __returned__ = { props, emit, rootRef, state, isObject, gapX, gapY, windowWidth, windowHeight, boundary, closest, applyMagnetic, dragging, initialized, magneticSide, rootStyle, updateState, touch, get prevX() {
|
|
272
|
+
return prevX;
|
|
273
|
+
}, set prevX(v) {
|
|
274
|
+
prevX = v;
|
|
275
|
+
}, get prevY() {
|
|
276
|
+
return prevY;
|
|
277
|
+
}, set prevY(v) {
|
|
278
|
+
prevY = v;
|
|
279
|
+
}, onTouchStart, onTouchMove, onTouchEnd, onClick, handleResize };
|
|
280
|
+
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
|
|
281
|
+
return __returned__;
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
import { renderSlot as _renderSlot, normalizeStyle as _normalizeStyle, createElementVNode as _createElementVNode, Teleport as _Teleport, openBlock as _openBlock, createBlock as _createBlock } from "vue";
|
|
285
|
+
function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
|
|
286
|
+
return _openBlock(), _createBlock(_Teleport, { to: $props.teleport }, [
|
|
287
|
+
_createElementVNode(
|
|
288
|
+
"div",
|
|
289
|
+
{
|
|
290
|
+
ref: "rootRef",
|
|
291
|
+
class: "floating-bubble",
|
|
292
|
+
style: _normalizeStyle($setup.rootStyle),
|
|
293
|
+
onTouchstartPassive: $setup.onTouchStart,
|
|
294
|
+
onTouchend: $setup.onTouchEnd,
|
|
295
|
+
onTouchcancel: $setup.onTouchEnd,
|
|
296
|
+
onMousedown: $setup.onTouchStart,
|
|
297
|
+
onClickCapture: $setup.onClick
|
|
298
|
+
},
|
|
299
|
+
[
|
|
300
|
+
_renderSlot(_ctx.$slots, "default")
|
|
301
|
+
],
|
|
302
|
+
36
|
|
303
|
+
/* STYLE, NEED_HYDRATION */
|
|
304
|
+
)
|
|
305
|
+
], 8, ["to"]);
|
|
306
|
+
}
|
|
307
|
+
__vue_sfc__.render = __vue_render__;
|
|
308
|
+
var FloatingBubble_vue_default = __vue_sfc__;
|
|
309
|
+
export {
|
|
310
|
+
FloatingBubble_vue_default as default
|
|
311
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type FloatingBubbleAxis = "x" | "y" | "xy" | "lock";
|
|
2
|
+
export type FloatingBubbleMagnetic = "x" | "y";
|
|
3
|
+
export interface FloatingBubbleOffset {
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
}
|
|
7
|
+
export interface FloatingBubbleGap {
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
}
|
|
11
|
+
export interface FloatingBubbleProps {
|
|
12
|
+
offset?: FloatingBubbleOffset;
|
|
13
|
+
axis?: FloatingBubbleAxis;
|
|
14
|
+
magnetic?: FloatingBubbleMagnetic;
|
|
15
|
+
gap?: number | FloatingBubbleGap;
|
|
16
|
+
teleport?: string | Element;
|
|
17
|
+
}
|
|
18
|
+
export type FloatingBubbleEmits = {
|
|
19
|
+
(e: "update:offset", value: FloatingBubbleOffset): void;
|
|
20
|
+
(e: "click", event: MouseEvent): void;
|
|
21
|
+
(e: "offset-change", offset: FloatingBubbleOffset): void;
|
|
22
|
+
(e: "drag-start"): void;
|
|
23
|
+
(e: "drag-end"): void;
|
|
24
|
+
};
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.aipanel-iframe-container{flex:1;position:relative;overflow:hidden;display:flex;flex-direction:column}.aipanel-loading-overlay{position:absolute;inset:0;background:var(--ap-overlay-bg);flex-direction:column;align-items:center;justify-content:center;z-index:10;display:flex;opacity:0;visibility:hidden}.aipanel-loading-overlay.visible{opacity:1;visibility:visible}.aipanel-loading-spinner{width:40px;height:40px;border:3px solid var(--ap-border-primary);border-top-color:var(--ap-primary);border-radius:50%;animation:spin .8s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}.aipanel-loading-text{margin-top:12px;font-size:14px;color:var(--ap-text-placeholder)}.aipanel-error-overlay{position:absolute;inset:0;z-index:15;display:flex;opacity:0;visibility:hidden;transition:opacity .2s ease,visibility .2s ease}.aipanel-error-overlay.visible{opacity:1;visibility:visible}.aipanel-empty-state-overlay{position:absolute;inset:0;background:var(--ap-bg-secondary);flex-direction:column;align-items:center;justify-content:center;z-index:5;display:flex;opacity:0;visibility:hidden;transition:opacity .2s ease,visibility .2s ease}.aipanel-empty-state-overlay.visible{opacity:1;visibility:visible}.aipanel-empty-state-icon{color:var(--ap-text-placeholder);margin-bottom:16px}.aipanel-empty-state-text{color:var(--ap-text-primary);font-size:16px;font-weight:500;margin-bottom:24px}.aipanel-empty-state-btn{padding:10px 24px;border-radius:8px;border:none;background:var(--ap-primary);color:#fff;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s;box-shadow:var(--ap-shadow-primary)}.aipanel-empty-state-btn:hover{background:var(--ap-primary-hover);transform:translateY(-1px);box-shadow:var(--ap-shadow-primary-hover)}.aipanel-empty-state-btn:active{transform:translateY(0)}.aipanel-iframe{width:100%;height:100%;border:none;opacity:0;transition:none}.aipanel-iframe.loaded{opacity:1;transition:opacity .3s ease}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
declare function sendMessageToIframe(type: string, data?: Record<string, unknown>): void;
|
|
2
|
+
declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {}, __VLS_7: {};
|
|
3
|
+
type __VLS_Slots = {} & {
|
|
4
|
+
'empty-state'?: (props: typeof __VLS_1) => any;
|
|
5
|
+
} & {
|
|
6
|
+
loading?: (props: typeof __VLS_3) => any;
|
|
7
|
+
} & {
|
|
8
|
+
error?: (props: typeof __VLS_5) => any;
|
|
9
|
+
} & {
|
|
10
|
+
content?: (props: typeof __VLS_7) => any;
|
|
11
|
+
};
|
|
12
|
+
declare const __VLS_base: import("vue").DefineComponent<{}, {
|
|
13
|
+
sendMessageToIframe: typeof sendMessageToIframe;
|
|
14
|
+
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
15
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
16
|
+
declare const _default: typeof __VLS_export;
|
|
17
|
+
export default _default;
|
|
18
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
19
|
+
new (): {
|
|
20
|
+
$slots: S;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import "./Frame-sfc.css";
|
|
2
|
+
import { defineComponent as _defineComponent } from "vue";
|
|
3
|
+
import { ref } from "vue";
|
|
4
|
+
import { useAIPanelWidgetContext } from "../context.mjs";
|
|
5
|
+
const __vue_sfc__ = /* @__PURE__ */ _defineComponent({
|
|
6
|
+
__name: "Frame",
|
|
7
|
+
setup(__props, { expose: __expose }) {
|
|
8
|
+
const iframeRef = ref(null);
|
|
9
|
+
const {
|
|
10
|
+
frameLoading,
|
|
11
|
+
showEmptyState,
|
|
12
|
+
showError,
|
|
13
|
+
iframeSource: iframeSrc,
|
|
14
|
+
emptyStateText,
|
|
15
|
+
emptyStateActionText,
|
|
16
|
+
handleEmptyAction,
|
|
17
|
+
handleFrameLoaded
|
|
18
|
+
} = useAIPanelWidgetContext();
|
|
19
|
+
function sendMessageToIframe(type, data) {
|
|
20
|
+
if (!iframeRef.value?.contentWindow) return;
|
|
21
|
+
iframeRef.value.contentWindow.postMessage({ type, ...data }, "*");
|
|
22
|
+
}
|
|
23
|
+
__expose({
|
|
24
|
+
sendMessageToIframe
|
|
25
|
+
});
|
|
26
|
+
const __returned__ = { iframeRef, frameLoading, showEmptyState, showError, iframeSrc, emptyStateText, emptyStateActionText, handleEmptyAction, handleFrameLoaded, sendMessageToIframe };
|
|
27
|
+
Object.defineProperty(__returned__, "__isScriptSetup", { enumerable: false, value: true });
|
|
28
|
+
return __returned__;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
import { renderSlot as _renderSlot, createElementVNode as _createElementVNode, toDisplayString as _toDisplayString, normalizeClass as _normalizeClass, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue";
|
|
32
|
+
const _hoisted_1 = { class: "aipanel-iframe-container" };
|
|
33
|
+
const _hoisted_2 = { class: "aipanel-empty-state-text" };
|
|
34
|
+
const _hoisted_3 = ["src"];
|
|
35
|
+
function __vue_render__(_ctx, _cache, $props, $setup, $data, $options) {
|
|
36
|
+
return _openBlock(), _createElementBlock("div", _hoisted_1, [
|
|
37
|
+
_createElementVNode(
|
|
38
|
+
"div",
|
|
39
|
+
{
|
|
40
|
+
class: _normalizeClass(["aipanel-empty-state-overlay", { visible: $setup.showEmptyState }])
|
|
41
|
+
},
|
|
42
|
+
[
|
|
43
|
+
_renderSlot(_ctx.$slots, "empty-state", {}, () => [
|
|
44
|
+
_cache[2] || (_cache[2] = _createElementVNode(
|
|
45
|
+
"div",
|
|
46
|
+
{ class: "aipanel-empty-state-icon" },
|
|
47
|
+
[
|
|
48
|
+
_createElementVNode("svg", {
|
|
49
|
+
viewBox: "0 0 24 24",
|
|
50
|
+
width: "48",
|
|
51
|
+
height: "48",
|
|
52
|
+
fill: "none",
|
|
53
|
+
stroke: "currentColor",
|
|
54
|
+
"stroke-width": "1.5",
|
|
55
|
+
"aria-hidden": "true"
|
|
56
|
+
}, [
|
|
57
|
+
_createElementVNode("path", {
|
|
58
|
+
"stroke-linecap": "round",
|
|
59
|
+
"stroke-linejoin": "round",
|
|
60
|
+
d: "M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 0 1-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
|
|
61
|
+
})
|
|
62
|
+
])
|
|
63
|
+
],
|
|
64
|
+
-1
|
|
65
|
+
/* CACHED */
|
|
66
|
+
)),
|
|
67
|
+
_createElementVNode(
|
|
68
|
+
"div",
|
|
69
|
+
_hoisted_2,
|
|
70
|
+
_toDisplayString($setup.emptyStateText),
|
|
71
|
+
1
|
|
72
|
+
/* TEXT */
|
|
73
|
+
),
|
|
74
|
+
_createElementVNode(
|
|
75
|
+
"button",
|
|
76
|
+
{
|
|
77
|
+
class: "aipanel-empty-state-btn",
|
|
78
|
+
type: "button",
|
|
79
|
+
onClick: _cache[0] || (_cache[0] = (...args) => $setup.handleEmptyAction && $setup.handleEmptyAction(...args))
|
|
80
|
+
},
|
|
81
|
+
_toDisplayString($setup.emptyStateActionText),
|
|
82
|
+
1
|
|
83
|
+
/* TEXT */
|
|
84
|
+
)
|
|
85
|
+
])
|
|
86
|
+
],
|
|
87
|
+
2
|
|
88
|
+
/* CLASS */
|
|
89
|
+
),
|
|
90
|
+
_createElementVNode(
|
|
91
|
+
"div",
|
|
92
|
+
{
|
|
93
|
+
class: _normalizeClass(["aipanel-loading-overlay", { visible: $setup.frameLoading }])
|
|
94
|
+
},
|
|
95
|
+
[
|
|
96
|
+
_renderSlot(_ctx.$slots, "loading", {}, () => [
|
|
97
|
+
_cache[3] || (_cache[3] = _createElementVNode(
|
|
98
|
+
"div",
|
|
99
|
+
{ class: "aipanel-loading-spinner" },
|
|
100
|
+
null,
|
|
101
|
+
-1
|
|
102
|
+
/* CACHED */
|
|
103
|
+
)),
|
|
104
|
+
_cache[4] || (_cache[4] = _createElementVNode(
|
|
105
|
+
"div",
|
|
106
|
+
{ class: "aipanel-loading-text" },
|
|
107
|
+
"\u52A0\u8F7D\u4E2D...",
|
|
108
|
+
-1
|
|
109
|
+
/* CACHED */
|
|
110
|
+
))
|
|
111
|
+
])
|
|
112
|
+
],
|
|
113
|
+
2
|
|
114
|
+
/* CLASS */
|
|
115
|
+
),
|
|
116
|
+
_createElementVNode(
|
|
117
|
+
"div",
|
|
118
|
+
{
|
|
119
|
+
class: _normalizeClass(["aipanel-error-overlay", { visible: $setup.showError }])
|
|
120
|
+
},
|
|
121
|
+
[
|
|
122
|
+
_renderSlot(_ctx.$slots, "error")
|
|
123
|
+
],
|
|
124
|
+
2
|
|
125
|
+
/* CLASS */
|
|
126
|
+
),
|
|
127
|
+
_renderSlot(_ctx.$slots, "content", {}, () => [
|
|
128
|
+
_createElementVNode("iframe", {
|
|
129
|
+
ref: "iframeRef",
|
|
130
|
+
class: _normalizeClass(["aipanel-iframe", { loaded: !$setup.frameLoading }]),
|
|
131
|
+
src: $setup.iframeSrc,
|
|
132
|
+
allow: "clipboard-write; clipboard-read",
|
|
133
|
+
referrerpolicy: "origin",
|
|
134
|
+
onLoad: _cache[1] || (_cache[1] = (...args) => $setup.handleFrameLoaded && $setup.handleFrameLoaded(...args))
|
|
135
|
+
}, null, 42, _hoisted_3)
|
|
136
|
+
])
|
|
137
|
+
]);
|
|
138
|
+
}
|
|
139
|
+
__vue_sfc__.render = __vue_render__;
|
|
140
|
+
var Frame_vue_default = __vue_sfc__;
|
|
141
|
+
export {
|
|
142
|
+
Frame_vue_default as default
|
|
143
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.aipanel-chat-header{position:relative;flex-shrink:0;display:flex;align-items:center;justify-content:space-between;padding:0 12px;height:40px;background:var(--ap-bg-secondary);border-bottom:1px solid var(--ap-border-primary);z-index:5}.aipanel-chat-header-left{display:flex;align-items:center;gap:4px}.aipanel-chat-header-title{font-size:14px;font-weight:600;color:var(--ap-text-primary);position:absolute;left:50%;transform:translate(-50%)}.aipanel-chat-header-actions{display:flex;gap:4px}.aipanel-header-btn{width:28px;height:28px;border-radius:6px;border:none;background:transparent;color:var(--ap-text-placeholder);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s}.aipanel-header-btn:hover{background:var(--ap-bg-tertiary);color:var(--ap-text-primary)}.aipanel-header-btn.close:hover{background:var(--ap-danger);color:#fff}.aipanel-header-btn.select-btn.active,.aipanel-header-btn.session-toggle.active,.aipanel-header-btn.review-panel.active{background:var(--ap-primary);color:#fff}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
declare var __VLS_1: {}, __VLS_3: {}, __VLS_5: {}, __VLS_7: {}, __VLS_9: {}, __VLS_11: {}, __VLS_13: {}, __VLS_15: {};
|
|
2
|
+
type __VLS_Slots = {} & {
|
|
3
|
+
'session-toggle-icon'?: (props: typeof __VLS_1) => any;
|
|
4
|
+
} & {
|
|
5
|
+
'select-icon'?: (props: typeof __VLS_3) => any;
|
|
6
|
+
} & {
|
|
7
|
+
'theme-icon'?: (props: typeof __VLS_5) => any;
|
|
8
|
+
} & {
|
|
9
|
+
'display-mode-icon'?: (props: typeof __VLS_7) => any;
|
|
10
|
+
} & {
|
|
11
|
+
'split-position-icon'?: (props: typeof __VLS_9) => any;
|
|
12
|
+
} & {
|
|
13
|
+
'prompt-dock-icon'?: (props: typeof __VLS_11) => any;
|
|
14
|
+
} & {
|
|
15
|
+
'minimize-icon'?: (props: typeof __VLS_13) => any;
|
|
16
|
+
} & {
|
|
17
|
+
'close-icon'?: (props: typeof __VLS_15) => any;
|
|
18
|
+
};
|
|
19
|
+
declare const __VLS_base: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
20
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
21
|
+
declare const _default: typeof __VLS_export;
|
|
22
|
+
export default _default;
|
|
23
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
24
|
+
new (): {
|
|
25
|
+
$slots: S;
|
|
26
|
+
};
|
|
27
|
+
};
|