agentation-vue 0.2.2 → 0.2.3

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.
@@ -1,223 +1,192 @@
1
- <script setup lang="ts">
2
- import type { BoundingBox, Settings } from '../types'
3
- import { nextTick, onBeforeUnmount, ref, watch } from 'vue-demi'
4
- import { clamp } from '../utils/math'
5
- import SettingsPanel from './SettingsPanel.vue'
6
-
7
- type Placement = 'top-start' | 'top-end' | 'bottom-start' | 'bottom-end' | 'left-start' | 'left-end' | 'right-start' | 'right-end'
8
-
9
- const props = defineProps<{
10
- open: boolean
11
- settings: Settings
12
- anchorEl: HTMLElement | null
13
- }>()
14
-
15
- const emit = defineEmits<{
16
- close: []
17
- update: [settings: Partial<Settings>]
18
- }>()
19
-
20
- const panelEl = ref<HTMLElement | null>(null)
21
- const placement = ref<Placement>('bottom-start')
22
- const style = ref<Record<string, string>>({
23
- left: '-9999px',
24
- top: '-9999px',
25
- visibility: 'hidden',
26
- })
27
-
28
- const GAP = 8
29
- const VIEWPORT_PADDING = 8
30
- let rafId: number | null = null
31
-
32
- function getPlacementCandidates(anchorRect: DOMRect): Placement[] {
33
- const isOnBottomHalf = anchorRect.top > window.innerHeight / 2
34
- const isOnRightHalf = anchorRect.left > window.innerWidth / 2
35
- const preferredVertical = isOnBottomHalf ? 'top' : 'bottom'
36
- const secondaryVertical = isOnBottomHalf ? 'bottom' : 'top'
37
- const preferredAlign = isOnRightHalf ? 'end' : 'start'
38
- const secondaryAlign = isOnRightHalf ? 'start' : 'end'
39
- const preferredHorizontal = isOnRightHalf ? 'left' : 'right'
40
- const secondaryHorizontal = isOnRightHalf ? 'right' : 'left'
41
-
1
+ <script setup>
2
+ import { nextTick, onBeforeUnmount, ref, watch } from "vue-demi";
3
+ import { clamp } from "../utils/math";
4
+ import SettingsPanel from "./SettingsPanel.vue";
5
+ const props = defineProps({
6
+ open: { type: Boolean, required: true },
7
+ settings: { type: Object, required: true },
8
+ anchorEl: { type: null, required: true }
9
+ });
10
+ const emit = defineEmits(["close", "update"]);
11
+ const panelEl = ref(null);
12
+ const placement = ref("bottom-start");
13
+ const style = ref({
14
+ left: "-9999px",
15
+ top: "-9999px",
16
+ visibility: "hidden"
17
+ });
18
+ const GAP = 8;
19
+ const VIEWPORT_PADDING = 8;
20
+ let rafId = null;
21
+ function getPlacementCandidates(anchorRect) {
22
+ const isOnBottomHalf = anchorRect.top > window.innerHeight / 2;
23
+ const isOnRightHalf = anchorRect.left > window.innerWidth / 2;
24
+ const preferredVertical = isOnBottomHalf ? "top" : "bottom";
25
+ const secondaryVertical = isOnBottomHalf ? "bottom" : "top";
26
+ const preferredAlign = isOnRightHalf ? "end" : "start";
27
+ const secondaryAlign = isOnRightHalf ? "start" : "end";
28
+ const preferredHorizontal = isOnRightHalf ? "left" : "right";
29
+ const secondaryHorizontal = isOnRightHalf ? "right" : "left";
42
30
  return [
43
- `${preferredVertical}-${preferredAlign}` as Placement,
44
- `${preferredVertical}-${secondaryAlign}` as Placement,
45
- `${secondaryVertical}-${preferredAlign}` as Placement,
46
- `${secondaryVertical}-${secondaryAlign}` as Placement,
47
- `${preferredHorizontal}-start` as Placement,
48
- `${preferredHorizontal}-end` as Placement,
49
- `${secondaryHorizontal}-start` as Placement,
50
- `${secondaryHorizontal}-end` as Placement,
51
- ]
31
+ `${preferredVertical}-${preferredAlign}`,
32
+ `${preferredVertical}-${secondaryAlign}`,
33
+ `${secondaryVertical}-${preferredAlign}`,
34
+ `${secondaryVertical}-${secondaryAlign}`,
35
+ `${preferredHorizontal}-start`,
36
+ `${preferredHorizontal}-end`,
37
+ `${secondaryHorizontal}-start`,
38
+ `${secondaryHorizontal}-end`
39
+ ];
52
40
  }
53
-
54
- function getCoordinates(anchorRect: DOMRect, panelRect: BoundingBox, value: Placement): { x: number, y: number } {
41
+ function getCoordinates(anchorRect, panelRect, value) {
55
42
  switch (value) {
56
- case 'top-start':
57
- return { x: anchorRect.left, y: anchorRect.top - GAP - panelRect.height }
58
- case 'top-end':
59
- return { x: anchorRect.right - panelRect.width, y: anchorRect.top - GAP - panelRect.height }
60
- case 'bottom-start':
61
- return { x: anchorRect.left, y: anchorRect.bottom + GAP }
62
- case 'bottom-end':
63
- return { x: anchorRect.right - panelRect.width, y: anchorRect.bottom + GAP }
64
- case 'left-start':
65
- return { x: anchorRect.left - GAP - panelRect.width, y: anchorRect.top }
66
- case 'left-end':
67
- return { x: anchorRect.left - GAP - panelRect.width, y: anchorRect.bottom - panelRect.height }
68
- case 'right-start':
69
- return { x: anchorRect.right + GAP, y: anchorRect.top }
70
- case 'right-end':
71
- return { x: anchorRect.right + GAP, y: anchorRect.bottom - panelRect.height }
43
+ case "top-start":
44
+ return { x: anchorRect.left, y: anchorRect.top - GAP - panelRect.height };
45
+ case "top-end":
46
+ return { x: anchorRect.right - panelRect.width, y: anchorRect.top - GAP - panelRect.height };
47
+ case "bottom-start":
48
+ return { x: anchorRect.left, y: anchorRect.bottom + GAP };
49
+ case "bottom-end":
50
+ return { x: anchorRect.right - panelRect.width, y: anchorRect.bottom + GAP };
51
+ case "left-start":
52
+ return { x: anchorRect.left - GAP - panelRect.width, y: anchorRect.top };
53
+ case "left-end":
54
+ return { x: anchorRect.left - GAP - panelRect.width, y: anchorRect.bottom - panelRect.height };
55
+ case "right-start":
56
+ return { x: anchorRect.right + GAP, y: anchorRect.top };
57
+ case "right-end":
58
+ return { x: anchorRect.right + GAP, y: anchorRect.bottom - panelRect.height };
72
59
  default:
73
- return { x: anchorRect.left, y: anchorRect.bottom + GAP }
60
+ return { x: anchorRect.left, y: anchorRect.bottom + GAP };
74
61
  }
75
62
  }
76
-
77
- function getOverflow(x: number, y: number, panelRect: BoundingBox) {
78
- const rightLimit = window.innerWidth - VIEWPORT_PADDING
79
- const bottomLimit = window.innerHeight - VIEWPORT_PADDING
63
+ function getOverflow(x, y, panelRect) {
64
+ const rightLimit = window.innerWidth - VIEWPORT_PADDING;
65
+ const bottomLimit = window.innerHeight - VIEWPORT_PADDING;
80
66
  return {
81
67
  left: Math.max(0, VIEWPORT_PADDING - x),
82
68
  right: Math.max(0, x + panelRect.width - rightLimit),
83
69
  top: Math.max(0, VIEWPORT_PADDING - y),
84
- bottom: Math.max(0, y + panelRect.height - bottomLimit),
85
- }
70
+ bottom: Math.max(0, y + panelRect.height - bottomLimit)
71
+ };
86
72
  }
87
-
88
- function getOverflowScore(overflow: ReturnType<typeof getOverflow>) {
89
- return overflow.left + overflow.right + overflow.top + overflow.bottom
73
+ function getOverflowScore(overflow) {
74
+ return overflow.left + overflow.right + overflow.top + overflow.bottom;
90
75
  }
91
-
92
76
  function applyPosition() {
93
77
  if (!props.open)
94
- return
95
-
96
- const anchorEl = props.anchorEl
97
- const panel = panelEl.value
78
+ return;
79
+ const anchorEl = props.anchorEl;
80
+ const panel = panelEl.value;
98
81
  if (!anchorEl || !panel) {
99
- style.value = { left: '-9999px', top: '-9999px', visibility: 'hidden' }
100
- return
82
+ style.value = { left: "-9999px", top: "-9999px", visibility: "hidden" };
83
+ return;
101
84
  }
102
-
103
85
  if (!anchorEl.isConnected) {
104
- emit('close')
105
- return
86
+ emit("close");
87
+ return;
106
88
  }
107
-
108
- const anchorRect = anchorEl.getBoundingClientRect()
109
- const panelRect: BoundingBox = {
89
+ const anchorRect = anchorEl.getBoundingClientRect();
90
+ const panelRect = {
110
91
  x: 0,
111
92
  y: 0,
112
93
  width: panel.offsetWidth,
113
- height: panel.offsetHeight,
114
- }
115
-
116
- const candidates = getPlacementCandidates(anchorRect)
117
- let best = candidates[0]
118
- let bestCoords = getCoordinates(anchorRect, panelRect, best)
119
- let bestOverflow = getOverflow(bestCoords.x, bestCoords.y, panelRect)
120
- let bestScore = getOverflowScore(bestOverflow)
121
-
94
+ height: panel.offsetHeight
95
+ };
96
+ const candidates = getPlacementCandidates(anchorRect);
97
+ let best = candidates[0];
98
+ let bestCoords = getCoordinates(anchorRect, panelRect, best);
99
+ let bestOverflow = getOverflow(bestCoords.x, bestCoords.y, panelRect);
100
+ let bestScore = getOverflowScore(bestOverflow);
122
101
  for (let i = 1; i < candidates.length; i++) {
123
- const candidate = candidates[i]
124
- const coords = getCoordinates(anchorRect, panelRect, candidate)
125
- const overflow = getOverflow(coords.x, coords.y, panelRect)
126
- const score = getOverflowScore(overflow)
102
+ const candidate = candidates[i];
103
+ const coords = getCoordinates(anchorRect, panelRect, candidate);
104
+ const overflow = getOverflow(coords.x, coords.y, panelRect);
105
+ const score = getOverflowScore(overflow);
127
106
  if (score < bestScore) {
128
- best = candidate
129
- bestCoords = coords
130
- bestOverflow = overflow
131
- bestScore = score
107
+ best = candidate;
108
+ bestCoords = coords;
109
+ bestOverflow = overflow;
110
+ bestScore = score;
132
111
  }
133
112
  }
134
-
135
113
  const x = clamp(
136
114
  bestCoords.x,
137
115
  VIEWPORT_PADDING,
138
- Math.max(VIEWPORT_PADDING, window.innerWidth - VIEWPORT_PADDING - panelRect.width),
139
- )
116
+ Math.max(VIEWPORT_PADDING, window.innerWidth - VIEWPORT_PADDING - panelRect.width)
117
+ );
140
118
  const y = clamp(
141
119
  bestCoords.y,
142
120
  VIEWPORT_PADDING,
143
- Math.max(VIEWPORT_PADDING, window.innerHeight - VIEWPORT_PADDING - panelRect.height),
144
- )
145
-
146
- placement.value = best
121
+ Math.max(VIEWPORT_PADDING, window.innerHeight - VIEWPORT_PADDING - panelRect.height)
122
+ );
123
+ placement.value = best;
147
124
  style.value = {
148
125
  left: `${Math.round(x)}px`,
149
126
  top: `${Math.round(y)}px`,
150
- visibility: 'visible',
151
- }
127
+ visibility: "visible"
128
+ };
152
129
  }
153
-
154
130
  function schedulePositionUpdate() {
155
131
  if (rafId != null)
156
- return
132
+ return;
157
133
  rafId = window.requestAnimationFrame(() => {
158
- rafId = null
159
- applyPosition()
160
- })
134
+ rafId = null;
135
+ applyPosition();
136
+ });
161
137
  }
162
-
163
- function onDocumentPointerDown(e: PointerEvent) {
138
+ function onDocumentPointerDown(e) {
164
139
  if (!props.open)
165
- return
166
- const target = e.target as Node | null
140
+ return;
141
+ const target = e.target;
167
142
  if (!target)
168
- return
143
+ return;
169
144
  if (panelEl.value?.contains(target))
170
- return
145
+ return;
171
146
  if (props.anchorEl?.contains(target))
172
- return
173
- emit('close')
147
+ return;
148
+ emit("close");
174
149
  }
175
-
176
150
  function addGlobalListeners() {
177
- window.addEventListener('resize', schedulePositionUpdate)
178
- window.addEventListener('scroll', schedulePositionUpdate, true)
179
- document.addEventListener('pointerdown', onDocumentPointerDown, true)
151
+ window.addEventListener("resize", schedulePositionUpdate);
152
+ window.addEventListener("scroll", schedulePositionUpdate, true);
153
+ document.addEventListener("pointerdown", onDocumentPointerDown, true);
180
154
  }
181
-
182
155
  function removeGlobalListeners() {
183
- window.removeEventListener('resize', schedulePositionUpdate)
184
- window.removeEventListener('scroll', schedulePositionUpdate, true)
185
- document.removeEventListener('pointerdown', onDocumentPointerDown, true)
156
+ window.removeEventListener("resize", schedulePositionUpdate);
157
+ window.removeEventListener("scroll", schedulePositionUpdate, true);
158
+ document.removeEventListener("pointerdown", onDocumentPointerDown, true);
186
159
  }
187
-
188
160
  watch(
189
161
  () => props.open,
190
162
  async (isOpen) => {
191
163
  if (isOpen) {
192
- await nextTick()
193
- applyPosition()
194
- addGlobalListeners()
195
- }
196
- else {
197
- removeGlobalListeners()
198
- style.value = { left: '-9999px', top: '-9999px', visibility: 'hidden' }
164
+ await nextTick();
165
+ applyPosition();
166
+ addGlobalListeners();
167
+ } else {
168
+ removeGlobalListeners();
169
+ style.value = { left: "-9999px", top: "-9999px", visibility: "hidden" };
199
170
  }
200
171
  },
201
- { immediate: true },
202
- )
203
-
172
+ { immediate: true }
173
+ );
204
174
  watch(
205
175
  () => props.anchorEl,
206
176
  async () => {
207
177
  if (!props.open)
208
- return
209
- await nextTick()
210
- applyPosition()
211
- },
212
- )
213
-
178
+ return;
179
+ await nextTick();
180
+ applyPosition();
181
+ }
182
+ );
214
183
  onBeforeUnmount(() => {
215
- removeGlobalListeners()
184
+ removeGlobalListeners();
216
185
  if (rafId != null) {
217
- window.cancelAnimationFrame(rafId)
218
- rafId = null
186
+ window.cancelAnimationFrame(rafId);
187
+ rafId = null;
219
188
  }
220
- })
189
+ });
221
190
  </script>
222
191
 
223
192
  <template>
@@ -1,15 +1,9 @@
1
- <script setup lang="ts">
2
- withDefaults(defineProps<{
3
- variant?: 'primary' | 'secondary'
4
- disabled?: boolean
5
- }>(), {
6
- variant: 'primary',
7
- disabled: false,
8
- })
9
-
10
- defineEmits<{
11
- click: [event: MouseEvent]
12
- }>()
1
+ <script setup>
2
+ defineProps({
3
+ variant: { type: String, required: false, default: "primary" },
4
+ disabled: { type: Boolean, required: false, default: false }
5
+ });
6
+ defineEmits(["click"]);
13
7
  </script>
14
8
 
15
9
  <template>
@@ -1,8 +1,8 @@
1
- <script setup lang="ts">
2
- import type { IconName } from '../icons'
3
- import { icons } from '../icons'
4
-
5
- defineProps<{ name: IconName }>()
1
+ <script setup>
2
+ import { icons } from "../icons";
3
+ defineProps({
4
+ name: { type: null, required: true }
5
+ });
6
6
  </script>
7
7
 
8
8
  <template>
@@ -1,31 +1,23 @@
1
- <script setup lang="ts">
2
- import { computed } from 'vue-demi'
3
- import { vaTooltipDirective } from '../directives/vaTooltip'
4
-
5
- const props = withDefaults(defineProps<{
6
- active?: boolean
7
- disabled?: boolean
8
- title?: string
9
- shortcut?: string
10
- }>(), {
11
- active: false,
12
- disabled: false,
13
- })
14
-
15
- defineEmits<{
16
- click: [event: MouseEvent]
17
- }>()
18
-
19
- const vVaTooltip = vaTooltipDirective
1
+ <script setup>
2
+ import { computed } from "vue-demi";
3
+ import { vaTooltipDirective } from "../directives/vaTooltip";
4
+ const props = defineProps({
5
+ active: { type: Boolean, required: false, default: false },
6
+ disabled: { type: Boolean, required: false, default: false },
7
+ title: { type: String, required: false },
8
+ shortcut: { type: String, required: false }
9
+ });
10
+ defineEmits(["click"]);
11
+ const vVaTooltip = vaTooltipDirective;
20
12
  const tooltipValue = computed(() => {
21
13
  if (!props.title)
22
- return null
14
+ return null;
23
15
  return {
24
16
  text: props.title,
25
17
  shortcut: props.shortcut,
26
- disabled: props.disabled,
27
- }
28
- })
18
+ disabled: props.disabled
19
+ };
20
+ });
29
21
  </script>
30
22
 
31
23
  <template>
@@ -1,12 +1,11 @@
1
- <script setup lang="ts">
2
- const props = defineProps<{
3
- modelValue: boolean
4
- ariaLabel?: string
5
- }>()
6
- const emit = defineEmits<{ 'update:model-value': [value: boolean] }>()
7
-
1
+ <script setup>
2
+ const props = defineProps({
3
+ modelValue: { type: Boolean, required: true },
4
+ ariaLabel: { type: String, required: false }
5
+ });
6
+ const emit = defineEmits(["update:model-value"]);
8
7
  function toggle() {
9
- emit('update:model-value', !props.modelValue)
8
+ emit("update:model-value", !props.modelValue);
10
9
  }
11
10
  </script>
12
11
 
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "agentation-vue",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Visual feedback tool for AI coding agents — Vue 2.7 & 3",
5
5
  "author": "Dorian Becker",
6
6
  "license": "PolyForm-Shield-1.0.0",
7
7
  "homepage": "https://github.com/Blaked84/agentation-vue",
8
8
  "repository": {
9
9
  "type": "git",
10
- "url": "https://github.com/Blaked84/agentation-vue.git",
10
+ "url": "git+https://github.com/Blaked84/agentation-vue.git",
11
11
  "directory": "packages/agentation-vue"
12
12
  },
13
13
  "keywords": [
@@ -54,6 +54,7 @@
54
54
  },
55
55
  "devDependencies": {
56
56
  "unbuild": "^3.0.0",
57
- "vue": "^3.5.0"
57
+ "vue": "^3.5.0",
58
+ "vue-sfc-transformer": "^0.1.17"
58
59
  }
59
60
  }