{"version":3,"file":"emit.cjs","names":[],"sources":["../../src/utils/emit.ts"],"sourcesContent":["/**\n * Type-safe custom event emission for components.\n */\n\nimport { getHost } from '../runtime';\n\ntype NoDetail = undefined | undefined | never;\ntype KeysWithoutDetail<T extends Record<string, unknown>> = {\n  [P in keyof T]: [T[P]] extends [NoDetail] ? P : never;\n}[keyof T];\n\n/**\n * Typed emit function: only declared event names type-check, and `detail` is\n * required exactly when its payload type is non-void. Dynamic event names must\n * be cast at the call site — an intentional speed bump, not a silent escape.\n */\nexport type EmitFn<T extends Record<string, unknown>> = {\n  <K extends KeysWithoutDetail<T>>(event: K): boolean;\n  <K extends Exclude<keyof T, KeysWithoutDetail<T>>>(event: K, detail: T[K]): boolean;\n};\n\nconst DEFAULT_FIRE_OPTIONS = { bubbles: true, cancelable: true, composed: false };\n\n/**\n * Returns a typed `emit()` function bound to the current component's host element.\n * Call once during `setup()` — the `Emits` type parameter maps event names to\n * their `detail` payload type.\n *\n * Every event is dispatched `cancelable: true`, and `emit()` returns `dispatchEvent`'s\n * own boolean result — `false` when a listener called `preventDefault()`. Components\n * that need to know whether a listener cancelled an event (e.g. to skip a default\n * action) read this return value directly instead of hand-rolling `dispatchEvent`.\n *\n * Events do **not** cross the shadow boundary by default (`composed: false`) — a\n * listener outside the component's shadow root will not observe them. Dispatch a\n * `CustomEvent` with `composed: true` by hand if an event must escape the shadow root.\n *\n * @example\n * ```ts\n * type Events = { close: undefined; change: { value: string } };\n *\n * setup(props) {\n *   const emit = useEmit<Events>();\n *   emit('close');\n *\n *   const notCancelled = emit('change', { value: 'ok' });\n *   if (notCancelled) props.value.value = 'ok';\n * }\n * ```\n */\nexport const useEmit = <T extends Record<string, unknown> = Record<string, never>>(): EmitFn<T> => {\n  const host = getHost();\n\n  return ((event: keyof T, ...rest: unknown[]) => {\n    const customEventInit = rest.length > 0 ? { ...DEFAULT_FIRE_OPTIONS, detail: rest[0] } : DEFAULT_FIRE_OPTIONS;\n\n    return host.dispatchEvent(new CustomEvent<unknown>(String(event), customEventInit));\n  }) as EmitFn<T>;\n};\n"],"mappings":"kCAqBA,IAAM,EAAuB,CAAE,QAAS,GAAM,WAAY,GAAM,SAAU,EAAM,EA6BnE,MAAsF,CACjG,IAAM,EAAO,EAAA,QAAQ,EAErB,QAAS,EAAgB,GAAG,IAAoB,CAC9C,IAAM,EAAkB,EAAK,OAAS,EAAI,CAAE,GAAG,EAAsB,OAAQ,EAAK,EAAG,EAAI,EAEzF,OAAO,EAAK,cAAc,IAAI,YAAqB,OAAO,CAAK,EAAG,CAAe,CAAC,CACpF,EACF"}