Files
windmill/frontend/src/lib/actions/triggerableByAI.svelte.ts
T
centdix 5d3d28915f internal: nits for claude demo (#6141)
* nits for claude demo

* better prompt
2025-07-08 10:53:26 +00:00

91 lines
2.1 KiB
TypeScript

import { triggerablesByAi } from '$lib/components/copilot/chat/sharedChatState.svelte'
export interface TriggerableByAIOptions {
id?: string
description?: string
callback?: (value?: string) => void
disabled?: boolean
showAnimation?: boolean
}
export function triggerableByAI(element: HTMLElement, options: TriggerableByAIOptions = {}) {
let { id, description, callback, showAnimation = true } = options
// Component is not discoverable if id or description is not provided
const isDisabled = !id || !description
function createPulseEffect() {
if (!showAnimation) return
// Get the bounding rect of the element
const rect = element.getBoundingClientRect()
if (rect.width === 0 && rect.height === 0) return // Skip if no dimensions
const centerX = rect.left + rect.width / 2
const centerY = rect.top + rect.height / 2
// Create pulse element
const pulse = document.createElement('div')
pulse.className = 'fixed w-10 h-10 bg-blue-500/90 rounded-full pointer-events-none animate-ping'
pulse.style.cssText = `
left: ${centerX - 20}px;
top: ${centerY - 20}px;
z-index: 9999;
`
// Add to body
document.body.appendChild(pulse)
// Remove after animation
setTimeout(() => {
if (pulse && pulse.parentNode) {
pulse.parentNode.removeChild(pulse)
}
}, 2000)
}
function handleTrigger(value?: string) {
if (!callback) return
if (!showAnimation) {
callback(value)
return
}
createPulseEffect()
callback(value)
}
function register() {
if (isDisabled || !id || !description) return
// register the triggerable
const currentData = { description, onTrigger: handleTrigger }
triggerablesByAi[id] = currentData
element.setAttribute('ai-description', description)
}
function unregister() {
if (isDisabled || !id) return
element.removeAttribute('ai-description')
// unregister the triggerable
if (triggerablesByAi[id]) {
delete triggerablesByAi[id]
}
}
// Initial registration
register()
return {
update(newOptions: TriggerableByAIOptions) {
;({ id, description, callback, showAnimation = true } = newOptions)
register()
},
destroy() {
unregister()
}
}
}