agentation-vue 0.2.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.
Files changed (111) hide show
  1. package/LICENSE +27 -0
  2. package/dist/AgentationVue.d.vue.ts +27 -0
  3. package/dist/AgentationVue.vue +839 -0
  4. package/dist/AgentationVue.vue.d.ts +27 -0
  5. package/dist/components/AgentationToolbar.d.vue.ts +36 -0
  6. package/dist/components/AgentationToolbar.vue +233 -0
  7. package/dist/components/AgentationToolbar.vue.d.ts +36 -0
  8. package/dist/components/AnnotationInput.d.vue.ts +21 -0
  9. package/dist/components/AnnotationInput.vue +105 -0
  10. package/dist/components/AnnotationInput.vue.d.ts +21 -0
  11. package/dist/components/AnnotationMarker.d.vue.ts +15 -0
  12. package/dist/components/AnnotationMarker.vue +46 -0
  13. package/dist/components/AnnotationMarker.vue.d.ts +15 -0
  14. package/dist/components/ComponentChain.d.vue.ts +10 -0
  15. package/dist/components/ComponentChain.vue +91 -0
  16. package/dist/components/ComponentChain.vue.d.ts +10 -0
  17. package/dist/components/ElementHighlight.d.vue.ts +9 -0
  18. package/dist/components/ElementHighlight.vue +33 -0
  19. package/dist/components/ElementHighlight.vue.d.ts +9 -0
  20. package/dist/components/SettingsPanel.d.vue.ts +10 -0
  21. package/dist/components/SettingsPanel.vue +143 -0
  22. package/dist/components/SettingsPanel.vue.d.ts +10 -0
  23. package/dist/components/SettingsPopover.d.vue.ts +14 -0
  24. package/dist/components/SettingsPopover.vue +235 -0
  25. package/dist/components/SettingsPopover.vue.d.ts +14 -0
  26. package/dist/components/VaButton.d.vue.ts +23 -0
  27. package/dist/components/VaButton.vue +19 -0
  28. package/dist/components/VaButton.vue.d.ts +23 -0
  29. package/dist/components/VaIcon.d.vue.ts +6 -0
  30. package/dist/components/VaIcon.vue +18 -0
  31. package/dist/components/VaIcon.vue.d.ts +6 -0
  32. package/dist/components/VaIconButton.d.vue.ts +25 -0
  33. package/dist/components/VaIconButton.vue +43 -0
  34. package/dist/components/VaIconButton.vue.d.ts +25 -0
  35. package/dist/components/VaToggle.d.vue.ts +10 -0
  36. package/dist/components/VaToggle.vue +23 -0
  37. package/dist/components/VaToggle.vue.d.ts +10 -0
  38. package/dist/composables/useAnimationPause.d.ts +7 -0
  39. package/dist/composables/useAnimationPause.js +52 -0
  40. package/dist/composables/useAnimationPause.mjs +43 -0
  41. package/dist/composables/useAnnotations.d.ts +105 -0
  42. package/dist/composables/useAnnotations.js +106 -0
  43. package/dist/composables/useAnnotations.mjs +108 -0
  44. package/dist/composables/useAreaSelect.d.ts +21 -0
  45. package/dist/composables/useAreaSelect.js +62 -0
  46. package/dist/composables/useAreaSelect.mjs +41 -0
  47. package/dist/composables/useElementDetection.d.ts +22 -0
  48. package/dist/composables/useElementDetection.js +85 -0
  49. package/dist/composables/useElementDetection.mjs +82 -0
  50. package/dist/composables/useInteractionMode.d.ts +5 -0
  51. package/dist/composables/useInteractionMode.js +29 -0
  52. package/dist/composables/useInteractionMode.mjs +20 -0
  53. package/dist/composables/useKeyboardShortcuts.d.ts +43 -0
  54. package/dist/composables/useKeyboardShortcuts.js +202 -0
  55. package/dist/composables/useKeyboardShortcuts.mjs +223 -0
  56. package/dist/composables/useMarkerPositions.d.ts +5 -0
  57. package/dist/composables/useMarkerPositions.js +45 -0
  58. package/dist/composables/useMarkerPositions.mjs +36 -0
  59. package/dist/composables/useMultiSelect.d.ts +20 -0
  60. package/dist/composables/useMultiSelect.js +108 -0
  61. package/dist/composables/useMultiSelect.mjs +85 -0
  62. package/dist/composables/useOutputFormatter.d.ts +5 -0
  63. package/dist/composables/useOutputFormatter.js +100 -0
  64. package/dist/composables/useOutputFormatter.mjs +91 -0
  65. package/dist/composables/useSettings.d.ts +14 -0
  66. package/dist/composables/useSettings.js +48 -0
  67. package/dist/composables/useSettings.mjs +38 -0
  68. package/dist/composables/useTextSelection.d.ts +11 -0
  69. package/dist/composables/useTextSelection.js +33 -0
  70. package/dist/composables/useTextSelection.mjs +22 -0
  71. package/dist/composables/useToolbarAutoHide.d.ts +19 -0
  72. package/dist/composables/useToolbarAutoHide.js +270 -0
  73. package/dist/composables/useToolbarAutoHide.mjs +208 -0
  74. package/dist/composables/useToolbarDragSnap.d.ts +30 -0
  75. package/dist/composables/useToolbarDragSnap.js +296 -0
  76. package/dist/composables/useToolbarDragSnap.mjs +245 -0
  77. package/dist/constants.d.ts +2 -0
  78. package/dist/constants.js +8 -0
  79. package/dist/constants.mjs +2 -0
  80. package/dist/directives/vaTooltip.d.ts +22 -0
  81. package/dist/directives/vaTooltip.js +241 -0
  82. package/dist/directives/vaTooltip.mjs +257 -0
  83. package/dist/icons.d.ts +16 -0
  84. package/dist/icons.js +21 -0
  85. package/dist/icons.mjs +15 -0
  86. package/dist/index.d.ts +31 -0
  87. package/dist/index.js +168 -0
  88. package/dist/index.mjs +30 -0
  89. package/dist/styles/agentation.css +1 -0
  90. package/dist/types.d.ts +70 -0
  91. package/dist/types.js +1 -0
  92. package/dist/types.mjs +0 -0
  93. package/dist/utils/clipboard.d.ts +1 -0
  94. package/dist/utils/clipboard.js +22 -0
  95. package/dist/utils/clipboard.mjs +16 -0
  96. package/dist/utils/dom-inspector.d.ts +7 -0
  97. package/dist/utils/dom-inspector.js +168 -0
  98. package/dist/utils/dom-inspector.mjs +242 -0
  99. package/dist/utils/math.d.ts +1 -0
  100. package/dist/utils/math.js +9 -0
  101. package/dist/utils/math.mjs +3 -0
  102. package/dist/utils/portal.d.ts +2 -0
  103. package/dist/utils/portal.js +18 -0
  104. package/dist/utils/portal.mjs +11 -0
  105. package/dist/utils/selectors.d.ts +3 -0
  106. package/dist/utils/selectors.js +103 -0
  107. package/dist/utils/selectors.mjs +105 -0
  108. package/dist/utils/style.d.ts +2 -0
  109. package/dist/utils/style.js +14 -0
  110. package/dist/utils/style.mjs +8 -0
  111. package/package.json +49 -0
@@ -0,0 +1,9 @@
1
+ import type { BoundingBox } from '../types';
2
+ type __VLS_Props = {
3
+ rect: BoundingBox | null;
4
+ elementName: string;
5
+ visible: boolean;
6
+ componentChain?: string;
7
+ };
8
+ declare const _default: import("vue-demi").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue-demi").ComponentOptionsMixin, import("vue-demi").ComponentOptionsMixin, {}, string, import("vue-demi").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue-demi").ComponentProvideOptions, false, {}, any>;
9
+ export default _default;
@@ -0,0 +1,33 @@
1
+ <script setup lang="ts">
2
+ import type { BoundingBox } from '../types'
3
+ import { computed } from 'vue-demi'
4
+ import { boundingBoxToStyle } from '../utils/style'
5
+ import ComponentChain from './ComponentChain.vue'
6
+
7
+ const props = defineProps<{
8
+ rect: BoundingBox | null
9
+ elementName: string
10
+ visible: boolean
11
+ componentChain?: string
12
+ }>()
13
+
14
+ const highlightStyle = computed(() => {
15
+ if (!props.rect)
16
+ return {}
17
+ return boundingBoxToStyle(props.rect)
18
+ })
19
+ </script>
20
+
21
+ <template>
22
+ <div
23
+ v-if="visible && rect"
24
+ class="__va-highlight"
25
+ :style="highlightStyle"
26
+ data-agentation-vue
27
+ >
28
+ <div v-if="componentChain" class="__va-highlight-label __va-highlight-label--chain">
29
+ <ComponentChain :chain="componentChain" variant="dark" truncate="auto" />
30
+ </div>
31
+ <span v-else class="__va-highlight-label">{{ elementName }}</span>
32
+ </div>
33
+ </template>
@@ -0,0 +1,9 @@
1
+ import type { BoundingBox } from '../types';
2
+ type __VLS_Props = {
3
+ rect: BoundingBox | null;
4
+ elementName: string;
5
+ visible: boolean;
6
+ componentChain?: string;
7
+ };
8
+ declare const _default: import("vue-demi").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue-demi").ComponentOptionsMixin, import("vue-demi").ComponentOptionsMixin, {}, string, import("vue-demi").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue-demi").ComponentProvideOptions, false, {}, any>;
9
+ export default _default;
@@ -0,0 +1,10 @@
1
+ import type { Settings } from '../types';
2
+ type __VLS_Props = {
3
+ settings: Settings;
4
+ };
5
+ declare const _default: import("vue-demi").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue-demi").ComponentOptionsMixin, import("vue-demi").ComponentOptionsMixin, {
6
+ update: (settings: Partial<Settings>) => any;
7
+ }, string, import("vue-demi").PublicProps, Readonly<__VLS_Props> & Readonly<{
8
+ onUpdate?: ((settings: Partial<Settings>) => any) | undefined;
9
+ }>, {}, {}, {}, {}, string, import("vue-demi").ComponentProvideOptions, false, {}, any>;
10
+ export default _default;
@@ -0,0 +1,143 @@
1
+ <script setup lang="ts">
2
+ import type { Settings } from '../types'
3
+ import { computed, toRef } from 'vue-demi'
4
+ import { vaTooltipDirective } from '../directives/vaTooltip'
5
+ import VaIcon from './VaIcon.vue'
6
+ import VaToggle from './VaToggle.vue'
7
+
8
+ const props = defineProps<{
9
+ settings: Settings
10
+ }>()
11
+ const emit = defineEmits<{
12
+ update: [settings: Partial<Settings>]
13
+ }>()
14
+ const settings = toRef(props, 'settings')
15
+
16
+ const presetColors = ['#8B5CF6', '#3B82F6', '#06B6D4', '#10B981', '#EAB308', '#FF5C00', '#EF4444']
17
+ const isMac = typeof navigator !== 'undefined' && /Mac|iPhone|iPad|iPod/.test(navigator.userAgent)
18
+
19
+ function update(key: keyof Settings, value: any) {
20
+ emit('update', { [key]: value })
21
+ }
22
+
23
+ function onSelectChange(key: keyof Settings, event: Event) {
24
+ const target = event.currentTarget as HTMLSelectElement | null
25
+ if (!target)
26
+ return
27
+ update(key, target.value)
28
+ }
29
+
30
+ const isDarkTheme = computed(() => {
31
+ if (settings.value.theme === 'dark')
32
+ return true
33
+ if (settings.value.theme === 'light')
34
+ return false
35
+ return typeof window !== 'undefined'
36
+ && typeof window.matchMedia === 'function'
37
+ && window.matchMedia('(prefers-color-scheme: dark)').matches
38
+ })
39
+
40
+ const themeIcon = computed(() => (isDarkTheme.value ? 'sun' : 'moon'))
41
+ const vVaTooltip = vaTooltipDirective
42
+
43
+ function toggleTheme() {
44
+ update('theme', isDarkTheme.value ? 'light' : 'dark')
45
+ }
46
+ </script>
47
+
48
+ <template>
49
+ <div class="__va-settings" data-agentation-vue @click.stop>
50
+ <div class="__va-settings-top">
51
+ <button v-va-tooltip="'Toggle theme'" type="button" class="__va-theme-toggle" @click="toggleTheme">
52
+ <VaIcon :name="themeIcon" />
53
+ </button>
54
+ </div>
55
+
56
+ <div class="__va-settings-row">
57
+ <span class="__va-settings-label">Output Detail</span>
58
+ <select :value="settings.outputDetail" @change="onSelectChange('outputDetail', $event)">
59
+ <option value="standard">
60
+ Standard
61
+ </option>
62
+ <option value="forensic">
63
+ Forensic
64
+ </option>
65
+ </select>
66
+ </div>
67
+
68
+ <div class="__va-settings-row">
69
+ <span class="__va-settings-label">Vue component tree</span>
70
+ <VaToggle
71
+ :model-value="settings.showComponentTree"
72
+ aria-label="Vue component tree"
73
+ @update:model-value="update('showComponentTree', $event)"
74
+ />
75
+ </div>
76
+
77
+ <div class="__va-settings-divider" />
78
+
79
+ <div class="__va-settings-row __va-settings-row--stack">
80
+ <span class="__va-settings-label">Marker Color</span>
81
+ <div class="__va-color-swatches">
82
+ <button
83
+ v-for="color in presetColors"
84
+ :key="color"
85
+ type="button"
86
+ class="__va-color-swatch"
87
+ :class="{ '__va-color-swatch--active': settings.markerColor === color }"
88
+ :style="{ background: color }"
89
+ @click="update('markerColor', color)"
90
+ />
91
+ </div>
92
+ </div>
93
+
94
+ <div class="__va-settings-divider" />
95
+
96
+ <div class="__va-settings-row">
97
+ <span class="__va-settings-label">Clear on copy/send</span>
98
+ <VaToggle
99
+ :model-value="settings.clearAfterCopy"
100
+ aria-label="Clear on copy/send"
101
+ @update:model-value="update('clearAfterCopy', $event)"
102
+ />
103
+ </div>
104
+
105
+ <div class="__va-settings-row">
106
+ <span class="__va-settings-label">Block page interactions</span>
107
+ <VaToggle
108
+ :model-value="settings.blockPageInteractions"
109
+ aria-label="Block page interactions"
110
+ @update:model-value="update('blockPageInteractions', $event)"
111
+ />
112
+ </div>
113
+
114
+ <div class="__va-settings-row">
115
+ <span class="__va-settings-label">Auto-hide floating button</span>
116
+ <VaToggle
117
+ :model-value="settings.autoHideToolbar"
118
+ aria-label="Auto-hide floating button"
119
+ @update:model-value="update('autoHideToolbar', $event)"
120
+ />
121
+ </div>
122
+
123
+ <div class="__va-settings-divider" />
124
+
125
+ <div class="__va-settings-row">
126
+ <span class="__va-settings-label">Activate with double tap</span>
127
+ <select :value="settings.activationKey" @change="onSelectChange('activationKey', $event)">
128
+ <option value="none">
129
+ Off
130
+ </option>
131
+ <option value="Meta">
132
+ {{ isMac ? '&#8984; Cmd' : 'Ctrl' }}
133
+ </option>
134
+ <option value="Alt">
135
+ {{ isMac ? '&#8997; Option' : 'Alt' }}
136
+ </option>
137
+ <option value="Shift">
138
+ Shift
139
+ </option>
140
+ </select>
141
+ </div>
142
+ </div>
143
+ </template>
@@ -0,0 +1,10 @@
1
+ import type { Settings } from '../types';
2
+ type __VLS_Props = {
3
+ settings: Settings;
4
+ };
5
+ declare const _default: import("vue-demi").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue-demi").ComponentOptionsMixin, import("vue-demi").ComponentOptionsMixin, {
6
+ update: (settings: Partial<Settings>) => any;
7
+ }, string, import("vue-demi").PublicProps, Readonly<__VLS_Props> & Readonly<{
8
+ onUpdate?: ((settings: Partial<Settings>) => any) | undefined;
9
+ }>, {}, {}, {}, {}, string, import("vue-demi").ComponentProvideOptions, false, {}, any>;
10
+ export default _default;
@@ -0,0 +1,14 @@
1
+ import type { Settings } from '../types';
2
+ type __VLS_Props = {
3
+ open: boolean;
4
+ settings: Settings;
5
+ anchorEl: HTMLElement | null;
6
+ };
7
+ declare const _default: import("vue-demi").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue-demi").ComponentOptionsMixin, import("vue-demi").ComponentOptionsMixin, {
8
+ close: () => any;
9
+ update: (settings: Partial<Settings>) => any;
10
+ }, string, import("vue-demi").PublicProps, Readonly<__VLS_Props> & Readonly<{
11
+ onClose?: (() => any) | undefined;
12
+ onUpdate?: ((settings: Partial<Settings>) => any) | undefined;
13
+ }>, {}, {}, {}, {}, string, import("vue-demi").ComponentProvideOptions, false, {}, any>;
14
+ export default _default;
@@ -0,0 +1,235 @@
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
+
42
+ 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
+ ]
52
+ }
53
+
54
+ function getCoordinates(anchorRect: DOMRect, panelRect: BoundingBox, value: Placement): { x: number, y: number } {
55
+ 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 }
72
+ default:
73
+ return { x: anchorRect.left, y: anchorRect.bottom + GAP }
74
+ }
75
+ }
76
+
77
+ function getOverflow(x: number, y: number, panelRect: BoundingBox) {
78
+ const rightLimit = window.innerWidth - VIEWPORT_PADDING
79
+ const bottomLimit = window.innerHeight - VIEWPORT_PADDING
80
+ return {
81
+ left: Math.max(0, VIEWPORT_PADDING - x),
82
+ right: Math.max(0, x + panelRect.width - rightLimit),
83
+ top: Math.max(0, VIEWPORT_PADDING - y),
84
+ bottom: Math.max(0, y + panelRect.height - bottomLimit),
85
+ }
86
+ }
87
+
88
+ function getOverflowScore(overflow: ReturnType<typeof getOverflow>) {
89
+ return overflow.left + overflow.right + overflow.top + overflow.bottom
90
+ }
91
+
92
+ function applyPosition() {
93
+ if (!props.open)
94
+ return
95
+
96
+ const anchorEl = props.anchorEl
97
+ const panel = panelEl.value
98
+ if (!anchorEl || !panel) {
99
+ style.value = { left: '-9999px', top: '-9999px', visibility: 'hidden' }
100
+ return
101
+ }
102
+
103
+ if (!anchorEl.isConnected) {
104
+ emit('close')
105
+ return
106
+ }
107
+
108
+ const anchorRect = anchorEl.getBoundingClientRect()
109
+ const panelRect: BoundingBox = {
110
+ x: 0,
111
+ y: 0,
112
+ 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
+
122
+ 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)
127
+ if (score < bestScore) {
128
+ best = candidate
129
+ bestCoords = coords
130
+ bestOverflow = overflow
131
+ bestScore = score
132
+ }
133
+ }
134
+
135
+ const x = clamp(
136
+ bestCoords.x,
137
+ VIEWPORT_PADDING,
138
+ Math.max(VIEWPORT_PADDING, window.innerWidth - VIEWPORT_PADDING - panelRect.width),
139
+ )
140
+ const y = clamp(
141
+ bestCoords.y,
142
+ VIEWPORT_PADDING,
143
+ Math.max(VIEWPORT_PADDING, window.innerHeight - VIEWPORT_PADDING - panelRect.height),
144
+ )
145
+
146
+ placement.value = best
147
+ style.value = {
148
+ left: `${Math.round(x)}px`,
149
+ top: `${Math.round(y)}px`,
150
+ visibility: 'visible',
151
+ }
152
+ }
153
+
154
+ function schedulePositionUpdate() {
155
+ if (rafId != null)
156
+ return
157
+ rafId = window.requestAnimationFrame(() => {
158
+ rafId = null
159
+ applyPosition()
160
+ })
161
+ }
162
+
163
+ function onDocumentPointerDown(e: PointerEvent) {
164
+ if (!props.open)
165
+ return
166
+ const target = e.target as Node | null
167
+ if (!target)
168
+ return
169
+ if (panelEl.value?.contains(target))
170
+ return
171
+ if (props.anchorEl?.contains(target))
172
+ return
173
+ emit('close')
174
+ }
175
+
176
+ function addGlobalListeners() {
177
+ window.addEventListener('resize', schedulePositionUpdate)
178
+ window.addEventListener('scroll', schedulePositionUpdate, true)
179
+ document.addEventListener('pointerdown', onDocumentPointerDown, true)
180
+ }
181
+
182
+ function removeGlobalListeners() {
183
+ window.removeEventListener('resize', schedulePositionUpdate)
184
+ window.removeEventListener('scroll', schedulePositionUpdate, true)
185
+ document.removeEventListener('pointerdown', onDocumentPointerDown, true)
186
+ }
187
+
188
+ watch(
189
+ () => props.open,
190
+ async (isOpen) => {
191
+ if (isOpen) {
192
+ await nextTick()
193
+ applyPosition()
194
+ addGlobalListeners()
195
+ }
196
+ else {
197
+ removeGlobalListeners()
198
+ style.value = { left: '-9999px', top: '-9999px', visibility: 'hidden' }
199
+ }
200
+ },
201
+ { immediate: true },
202
+ )
203
+
204
+ watch(
205
+ () => props.anchorEl,
206
+ async () => {
207
+ if (!props.open)
208
+ return
209
+ await nextTick()
210
+ applyPosition()
211
+ },
212
+ )
213
+
214
+ onBeforeUnmount(() => {
215
+ removeGlobalListeners()
216
+ if (rafId != null) {
217
+ window.cancelAnimationFrame(rafId)
218
+ rafId = null
219
+ }
220
+ })
221
+ </script>
222
+
223
+ <template>
224
+ <div
225
+ v-if="open"
226
+ ref="panelEl"
227
+ class="__va-settings-popover"
228
+ :data-placement="placement"
229
+ :style="style"
230
+ data-agentation-vue
231
+ @click.stop
232
+ >
233
+ <SettingsPanel :settings="settings" @update="$emit('update', $event)" />
234
+ </div>
235
+ </template>
@@ -0,0 +1,14 @@
1
+ import type { Settings } from '../types';
2
+ type __VLS_Props = {
3
+ open: boolean;
4
+ settings: Settings;
5
+ anchorEl: HTMLElement | null;
6
+ };
7
+ declare const _default: import("vue-demi").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue-demi").ComponentOptionsMixin, import("vue-demi").ComponentOptionsMixin, {
8
+ close: () => any;
9
+ update: (settings: Partial<Settings>) => any;
10
+ }, string, import("vue-demi").PublicProps, Readonly<__VLS_Props> & Readonly<{
11
+ onClose?: (() => any) | undefined;
12
+ onUpdate?: ((settings: Partial<Settings>) => any) | undefined;
13
+ }>, {}, {}, {}, {}, string, import("vue-demi").ComponentProvideOptions, false, {}, any>;
14
+ export default _default;
@@ -0,0 +1,23 @@
1
+ type __VLS_Props = {
2
+ variant?: 'primary' | 'secondary';
3
+ disabled?: boolean;
4
+ };
5
+ declare var __VLS_1: {};
6
+ type __VLS_Slots = {} & {
7
+ default?: (props: typeof __VLS_1) => any;
8
+ };
9
+ declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
10
+ click: (event: MouseEvent) => any;
11
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
12
+ onClick?: ((event: MouseEvent) => any) | undefined;
13
+ }>, {
14
+ disabled: boolean;
15
+ variant: "primary" | "secondary";
16
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
17
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
18
+ export default _default;
19
+ type __VLS_WithSlots<T, S> = T & {
20
+ new (): {
21
+ $slots: S;
22
+ };
23
+ };
@@ -0,0 +1,19 @@
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
+ }>()
13
+ </script>
14
+
15
+ <template>
16
+ <button type="button" class="__va-btn" :class="`__va-btn--${variant}`" :disabled="disabled" @click="$emit('click', $event)">
17
+ <slot />
18
+ </button>
19
+ </template>
@@ -0,0 +1,23 @@
1
+ type __VLS_Props = {
2
+ variant?: 'primary' | 'secondary';
3
+ disabled?: boolean;
4
+ };
5
+ declare var __VLS_1: {};
6
+ type __VLS_Slots = {} & {
7
+ default?: (props: typeof __VLS_1) => any;
8
+ };
9
+ declare const __VLS_component: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
10
+ click: (event: MouseEvent) => any;
11
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
12
+ onClick?: ((event: MouseEvent) => any) | undefined;
13
+ }>, {
14
+ disabled: boolean;
15
+ variant: "primary" | "secondary";
16
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
17
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
18
+ export default _default;
19
+ type __VLS_WithSlots<T, S> = T & {
20
+ new (): {
21
+ $slots: S;
22
+ };
23
+ };
@@ -0,0 +1,6 @@
1
+ import type { IconName } from '../icons';
2
+ type __VLS_Props = {
3
+ name: IconName;
4
+ };
5
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
+ export default _default;
@@ -0,0 +1,18 @@
1
+ <script setup lang="ts">
2
+ import type { IconName } from '../icons'
3
+ import { icons } from '../icons'
4
+
5
+ defineProps<{ name: IconName }>()
6
+ </script>
7
+
8
+ <template>
9
+ <svg
10
+ viewBox="0 0 24 24"
11
+ fill="none"
12
+ stroke="currentColor"
13
+ stroke-width="2"
14
+ stroke-linecap="round"
15
+ stroke-linejoin="round"
16
+ v-html="icons[name]"
17
+ />
18
+ </template>
@@ -0,0 +1,6 @@
1
+ import type { IconName } from '../icons';
2
+ type __VLS_Props = {
3
+ name: IconName;
4
+ };
5
+ declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
+ export default _default;
@@ -0,0 +1,25 @@
1
+ type __VLS_Props = {
2
+ active?: boolean;
3
+ disabled?: boolean;
4
+ title?: string;
5
+ shortcut?: string;
6
+ };
7
+ declare var __VLS_1: {};
8
+ type __VLS_Slots = {} & {
9
+ default?: (props: typeof __VLS_1) => any;
10
+ };
11
+ declare const __VLS_component: import("vue-demi").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue-demi").ComponentOptionsMixin, import("vue-demi").ComponentOptionsMixin, {
12
+ click: (event: MouseEvent) => any;
13
+ }, string, import("vue-demi").PublicProps, Readonly<__VLS_Props> & Readonly<{
14
+ onClick?: ((event: MouseEvent) => any) | undefined;
15
+ }>, {
16
+ disabled: boolean;
17
+ active: boolean;
18
+ }, {}, {}, {}, string, import("vue-demi").ComponentProvideOptions, false, {}, any>;
19
+ declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
20
+ export default _default;
21
+ type __VLS_WithSlots<T, S> = T & {
22
+ new (): {
23
+ $slots: S;
24
+ };
25
+ };
@@ -0,0 +1,43 @@
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
20
+ const tooltipValue = computed(() => {
21
+ if (!props.title)
22
+ return null
23
+ return {
24
+ text: props.title,
25
+ shortcut: props.shortcut,
26
+ disabled: props.disabled,
27
+ }
28
+ })
29
+ </script>
30
+
31
+ <template>
32
+ <button
33
+ v-va-tooltip="tooltipValue"
34
+ type="button"
35
+ class="__va-icon-btn"
36
+ :class="{ '__va-icon-btn--active': active }"
37
+ :aria-label="title"
38
+ :disabled="disabled"
39
+ @click="$emit('click', $event)"
40
+ >
41
+ <slot />
42
+ </button>
43
+ </template>