{"version":3,"file":"dialog-container-Btgzkwy7.mjs","names":["updated: Dialog","dialog: Dialog","targetId: DialogId | undefined","ctx: PromptContext<T>","ctx: ConfirmContext","ctx: AlertContext","ctx: ChoiceContext<K>","DEFAULT_SIZE: DialogSize","DEFAULT_SIZES: Record<DialogSize, number>","effectiveSize: DialogSize"],"sources":["../src/manager.ts","../../utils/src/utils/opacity.ts","../../utils/src/utils/padding.ts","../../utils/src/utils/styles.ts","../src/renderables/backdrop.ts","../src/constants.ts","../src/utils/style.ts","../src/renderables/dialog.ts","../src/types.ts","../src/renderables/dialog-container.ts"],"sourcesContent":["import type { Renderable, RenderContext } from \"@opentui/core\";\nimport type {\n  AlertContext,\n  ChoiceContext,\n  ConfirmContext,\n  PromptContext,\n} from \"./prompts\";\nimport type {\n  AsyncDialogOptions,\n  BaseAlertOptions,\n  BaseChoiceOptions,\n  BaseConfirmOptions,\n  BasePromptOptions,\n  Dialog,\n  DialogId,\n  DialogShowOptions,\n  DialogToClose,\n} from \"./types\";\n\ntype DialogSubscriber = (data: Dialog | DialogToClose) => void;\n\n// ============================================================================\n// Core Prompt Types (for imperative/non-framework usage)\n// ============================================================================\n// These extend the generic base types with core-specific content signatures.\n// Core content functions receive both the context and RenderContext.\n\n/** Content factory for prompt dialogs. */\ntype PromptContent<T> = (\n  renderCtx: RenderContext,\n  promptCtx: PromptContext<T>,\n) => Renderable;\n\n/** Content factory for confirm dialogs. */\ntype ConfirmContent = (\n  renderCtx: RenderContext,\n  confirmCtx: ConfirmContext,\n) => Renderable;\n\n/** Content factory for alert dialogs. */\ntype AlertContent = (\n  renderCtx: RenderContext,\n  alertCtx: AlertContext,\n) => Renderable;\n\n/** Content factory for choice dialogs. */\ntype ChoiceContent<K> = (\n  renderCtx: RenderContext,\n  choiceCtx: ChoiceContext<K>,\n) => Renderable;\n\n/**\n * Options for a generic prompt dialog using core renderables.\n * @template T The type of value the prompt resolves to.\n */\nexport interface PromptOptions<T>\n  extends BasePromptOptions<T, PromptContent<T>> {}\n\n/**\n * Options for a confirm dialog using core renderables.\n */\nexport interface ConfirmOptions extends BaseConfirmOptions<ConfirmContent> {}\n\n/**\n * Options for an alert dialog using core renderables.\n */\nexport interface AlertOptions extends BaseAlertOptions<AlertContent> {}\n\n/**\n * Options for a choice dialog using core renderables.\n * @template K The type of keys for the available choices.\n */\nexport interface ChoiceOptions<K>\n  extends BaseChoiceOptions<ChoiceContent<K>, K> {}\n\n/**\n * Extended DialogShowOptions for async dialog factory functions.\n * @template T The type of value returned on dismiss.\n */\nexport interface AsyncShowOptions<T> extends DialogShowOptions {\n  /** Fallback value when dialog is dismissed via ESC or backdrop click. */\n  fallback?: T;\n}\n\n/**\n * Manages dialog state and lifecycle for a DialogContainerRenderable.\n *\n * @example\n * ```ts\n * const manager = new DialogManager(renderer);\n * const container = new DialogContainerRenderable(renderer, { manager });\n *\n * manager.show({\n *   content: (ctx) => new TextRenderable(ctx, { content: \"Hello\" }),\n * });\n * ```\n */\nexport class DialogManager {\n  private dialogs: Dialog[] = [];\n  private subscribers = new Set<DialogSubscriber>();\n  private idCounter = 1;\n  private savedFocus: Renderable | null = null;\n  private ctx: RenderContext;\n  private focusRestoreTimeout?: ReturnType<typeof setTimeout>;\n  private destroyed = false;\n\n  constructor(ctx: RenderContext) {\n    this.ctx = ctx;\n  }\n\n  private saveFocus(): void {\n    this.cancelPendingFocusRestore();\n    this.savedFocus = this.ctx.currentFocusedRenderable;\n    this.savedFocus?.blur();\n  }\n\n  private cancelPendingFocusRestore(): void {\n    if (this.focusRestoreTimeout) {\n      clearTimeout(this.focusRestoreTimeout);\n      this.focusRestoreTimeout = undefined;\n    }\n  }\n\n  private restoreFocus(): void {\n    this.cancelPendingFocusRestore();\n\n    if (this.savedFocus && !this.savedFocus.isDestroyed) {\n      // Defer to next tick to ensure dialog is fully removed from render tree\n      this.focusRestoreTimeout = setTimeout(() => {\n        if (\n          !this.destroyed &&\n          this.savedFocus &&\n          !this.savedFocus.isDestroyed\n        ) {\n          this.savedFocus.focus();\n        }\n        this.savedFocus = null;\n        this.focusRestoreTimeout = undefined;\n      }, 1);\n    } else {\n      this.savedFocus = null;\n    }\n  }\n\n  /** Subscribe to dialog state changes. Returns an unsubscribe function. */\n  subscribe(subscriber: DialogSubscriber): () => void {\n    this.subscribers.add(subscriber);\n    return () => {\n      this.subscribers.delete(subscriber);\n    };\n  }\n\n  private publish(data: Dialog | DialogToClose): void {\n    for (const subscriber of this.subscribers) {\n      try {\n        subscriber(data);\n      } catch (error) {\n        console.error(\"[@opentui-ui/dialog] Subscriber threw an error:\", error);\n      }\n    }\n  }\n\n  private addDialog(data: Dialog): void {\n    this.dialogs = [...this.dialogs, data];\n    this.publish(data);\n  }\n\n  /**\n   * Show a new dialog.\n   *\n   * @example\n   * ```ts\n   * manager.show({\n   *   content: (ctx) => new TextRenderable(ctx, { content: \"Hello\" }),\n   *   size: \"medium\",\n   * });\n   * ```\n   */\n  show(options: DialogShowOptions): DialogId {\n    if (this.destroyed) {\n      throw new Error(\n        \"[@opentui-ui/dialog] Cannot show dialog: DialogManager has been destroyed.\",\n      );\n    }\n\n    if (options.content === undefined || options.content === null) {\n      throw new Error(\n        `[@opentui-ui/dialog] Missing required 'content' property.\\n\\n` +\n          `The 'content' property must be a factory function that returns a Renderable:\\n\\n` +\n          `  manager.show({\\n` +\n          `    content: (ctx) => new TextRenderable(ctx, { content: \"Hello\" }),\\n` +\n          `  });\\n\\n` +\n          `For React, use: import { useDialog } from '@opentui-ui/dialog/react'\\n` +\n          `For Solid, use: import { useDialog } from '@opentui-ui/dialog/solid'`,\n      );\n    }\n\n    if (typeof options.content !== \"function\") {\n      throw new Error(\n        `[@opentui-ui/dialog] Invalid 'content' type: expected function, got ${typeof options.content}.\\n\\n` +\n          `The 'content' property must be a factory function that receives a RenderContext\\n` +\n          `and returns a Renderable:\\n\\n` +\n          `  manager.show({\\n` +\n          `    content: (ctx) => new TextRenderable(ctx, { content: \"Hello\" }),\\n` +\n          `  });\\n\\n` +\n          `If you're using React or Solid, make sure you're importing from\\n` +\n          `the correct entry point:\\n` +\n          `  - React: import { useDialog } from '@opentui-ui/dialog/react'\\n` +\n          `  - Solid: import { useDialog } from '@opentui-ui/dialog/solid'`,\n      );\n    }\n\n    const id =\n      options.id !== undefined && options.id !== null\n        ? options.id\n        : this.idCounter++;\n\n    const existingIndex = this.dialogs.findIndex((d) => d.id === id);\n\n    if (existingIndex !== -1) {\n      const existing = this.dialogs[existingIndex];\n      if (existing) {\n        const updated: Dialog = { ...existing, ...options, id };\n        this.dialogs = [\n          ...this.dialogs.slice(0, existingIndex),\n          updated,\n          ...this.dialogs.slice(existingIndex + 1),\n        ];\n        this.publish(updated);\n      }\n    } else {\n      if (this.dialogs.length === 0) {\n        this.saveFocus();\n      }\n\n      const dialog: Dialog = {\n        ...options,\n        id,\n      };\n      this.addDialog(dialog);\n      dialog.onOpen?.();\n    }\n\n    return id;\n  }\n\n  /** Close a dialog by ID, or the top-most dialog if no ID provided. */\n  close(id?: DialogId): DialogId | undefined {\n    let targetId: DialogId | undefined;\n\n    if (id !== undefined) {\n      targetId = id;\n    } else {\n      const topDialog = this.dialogs[this.dialogs.length - 1];\n      targetId = topDialog?.id;\n    }\n\n    if (targetId === undefined) {\n      return undefined;\n    }\n\n    const dialogIndex = this.dialogs.findIndex((d) => d.id === targetId);\n    if (dialogIndex === -1) {\n      return undefined;\n    }\n\n    const dialog = this.dialogs[dialogIndex];\n\n    // Update dialogs before publishing to keep state in sync\n    this.dialogs = [\n      ...this.dialogs.slice(0, dialogIndex),\n      ...this.dialogs.slice(dialogIndex + 1),\n    ];\n\n    this.publish({ id: targetId, close: true });\n\n    dialog?.onClose?.();\n\n    if (this.dialogs.length === 0) {\n      this.restoreFocus();\n    }\n\n    return targetId;\n  }\n\n  /** Close all open dialogs. */\n  closeAll(): void {\n    const dialogsToClose = [...this.dialogs].reverse();\n    for (const d of dialogsToClose) {\n      this.close(d.id);\n    }\n  }\n\n  /** Close all dialogs and show a new one. */\n  replace(options: DialogShowOptions): DialogId {\n    this.closeAll();\n    return this.show(options);\n  }\n\n  /**\n   * Get all active dialogs (oldest first).\n   *\n   * Returns a stable reference that only changes when dialogs are\n   * added/removed/updated.\n   */\n  getDialogs(): readonly Dialog[] {\n    return this.dialogs;\n  }\n\n  /** Get the top-most active dialog. */\n  getTopDialog(): Dialog | undefined {\n    if (this.dialogs.length === 0) {\n      return undefined;\n    }\n    return this.dialogs[this.dialogs.length - 1];\n  }\n\n  /** Check if any dialogs are open. */\n  isOpen(): boolean {\n    return this.dialogs.length > 0;\n  }\n\n  // ===========================================================================\n  // Async Dialog Helpers\n  // ===========================================================================\n\n  /**\n   * Builds DialogShowOptions from either a factory function or a CoreOptions object.\n   * Used by confirm, alert, and choice methods to reduce duplication.\n   */\n  private buildShowOptions<\n    TCtx,\n    TOptions extends AsyncDialogOptions & {\n      content: (renderCtx: RenderContext, ctx: TCtx) => Renderable;\n    },\n  >(\n    input: TOptions | ((ctx: TCtx) => DialogShowOptions),\n    ctx: TCtx,\n  ): DialogShowOptions {\n    if (typeof input === \"function\") {\n      return input(ctx);\n    }\n    const { content, ...rest } = input;\n    return {\n      ...rest,\n      content: (renderCtx: RenderContext) => content(renderCtx, ctx),\n    };\n  }\n\n  /**\n   * Internal helper that handles common async dialog logic:\n   * - Promise creation\n   * - Safe double-resolve protection\n   * - Dialog show/close lifecycle\n   * - Fallback value handling for ESC/backdrop dismissal\n   */\n  private showAsyncDialog<T>(\n    createContextAndOptions: (\n      safeResolve: (value: T) => void,\n      dialogId: DialogId,\n    ) => {\n      showOptions: DialogShowOptions;\n      fallback?: T;\n    },\n    defaultDismissValue: T,\n  ): Promise<T> {\n    return new Promise<T>((resolve) => {\n      let resolved = false;\n\n      // Pre-generate the dialog ID so it can be passed to the context factory\n      const dialogId = this.idCounter++;\n\n      // Guard to ensure the promise resolves only once, since onClose always fires (even after explicit close)\n      const safeResolve = (value: T) => {\n        if (resolved) return;\n        resolved = true;\n        resolve(value);\n        this.close(dialogId);\n      };\n\n      const { showOptions, fallback } = createContextAndOptions(\n        safeResolve,\n        dialogId,\n      );\n\n      this.show({\n        ...showOptions,\n        id: dialogId,\n        onClose: () => {\n          showOptions.onClose?.();\n          safeResolve(fallback ?? defaultDismissValue);\n        },\n      });\n    });\n  }\n\n  // ===========================================================================\n  // Async Prompt Methods\n  // ===========================================================================\n\n  /**\n   * Show a generic prompt dialog and wait for a response.\n   *\n   * @template T The type of value the prompt resolves to.\n   *\n   * Accepts either PromptOptions (for imperative usage) or a factory function\n   * that receives the prompt context and returns AsyncShowOptions (for framework adapters).\n   *\n   * @example\n   * ```ts\n   * // Core/imperative usage\n   * const result = await manager.prompt<string>({\n   *   content: (renderCtx, { resolve, dismiss }) => {\n   *     const box = new BoxRenderable(renderCtx, { flexDirection: \"row\" });\n   *     const cancelBtn = new TextRenderable(renderCtx, { content: \"Cancel\" });\n   *     cancelBtn.on(\"mouseUp\", dismiss);\n   *     const okBtn = new TextRenderable(renderCtx, { content: \"OK\" });\n   *     okBtn.on(\"mouseUp\", () => resolve(\"some-value\"));\n   *     box.add(cancelBtn);\n   *     box.add(okBtn);\n   *     return box;\n   *   },\n   * });\n   * ```\n   */\n  prompt<T>(options: PromptOptions<T>): Promise<T | undefined>;\n  prompt<T>(\n    showFactory: (ctx: PromptContext<T>) => AsyncShowOptions<T | undefined>,\n  ): Promise<T | undefined>;\n  prompt<T>(\n    input:\n      | PromptOptions<T>\n      | ((ctx: PromptContext<T>) => AsyncShowOptions<T | undefined>),\n  ): Promise<T | undefined> {\n    return this.showAsyncDialog<T | undefined>((safeResolve, dialogId) => {\n      const ctx: PromptContext<T> = {\n        resolve: safeResolve,\n        dismiss: () => safeResolve(undefined),\n        dialogId,\n      };\n\n      if (typeof input === \"function\") {\n        const result = input(ctx);\n        return { showOptions: result, fallback: result.fallback };\n      }\n\n      const { fallback, ...rest } = input;\n      return {\n        showOptions: this.buildShowOptions(rest, ctx),\n        fallback,\n      };\n    }, undefined);\n  }\n\n  /**\n   * Show a confirmation dialog and wait for the user to confirm or cancel.\n   *\n   * @returns `true` if confirmed, `false` if cancelled or dismissed.\n   *\n   * Accepts either ConfirmOptions (for imperative usage) or a factory function\n   * that receives the confirm context and returns AsyncShowOptions (for framework adapters).\n   *\n   * @example\n   * ```ts\n   * // Core/imperative usage\n   * const confirmed = await manager.confirm({\n   *   content: (renderCtx, { resolve }) => {\n   *     const box = new BoxRenderable(renderCtx, { flexDirection: \"column\" });\n   *     const title = new TextRenderable(renderCtx, { content: \"Delete file?\" });\n   *     box.add(title);\n   *\n   *     const buttons = new BoxRenderable(renderCtx, { flexDirection: \"row\" });\n   *     const cancelBtn = new TextRenderable(renderCtx, { content: \"Cancel\" });\n   *     cancelBtn.on(\"mouseUp\", () => resolve(false));\n   *     const confirmBtn = new TextRenderable(renderCtx, { content: \"Confirm\" });\n   *     confirmBtn.on(\"mouseUp\", () => resolve(true));\n   *     buttons.add(cancelBtn);\n   *     buttons.add(confirmBtn);\n   *     box.add(buttons);\n   *\n   *     return box;\n   *   }\n   * });\n   * ```\n   */\n  confirm(options: ConfirmOptions): Promise<boolean>;\n  confirm(\n    showFactory: (ctx: ConfirmContext) => AsyncShowOptions<boolean>,\n  ): Promise<boolean>;\n  confirm(\n    input:\n      | ConfirmOptions\n      | ((ctx: ConfirmContext) => AsyncShowOptions<boolean>),\n  ): Promise<boolean> {\n    return this.showAsyncDialog<boolean>((safeResolve, dialogId) => {\n      const ctx: ConfirmContext = {\n        resolve: safeResolve,\n        dismiss: () => safeResolve(false),\n        dialogId,\n      };\n\n      if (typeof input === \"function\") {\n        const result = input(ctx);\n        return { showOptions: result, fallback: result.fallback };\n      }\n\n      const { fallback, ...rest } = input;\n      return {\n        showOptions: this.buildShowOptions(rest, ctx),\n        fallback,\n      };\n    }, false);\n  }\n\n  /**\n   * Show an alert dialog and wait for the user to dismiss it.\n   *\n   * Accepts either AlertOptions (for imperative usage) or a factory function\n   * that receives the alert context and returns DialogShowOptions (for framework adapters).\n   *\n   * @example\n   * ```ts\n   * // Core/imperative usage\n   * await manager.alert({\n   *   content: (renderCtx, { dismiss }) => {\n   *     const box = new BoxRenderable(renderCtx, { flexDirection: \"column\" });\n   *     const text = new TextRenderable(renderCtx, { content: \"Operation complete!\" });\n   *     box.add(text);\n   *\n   *     const okBtn = new TextRenderable(renderCtx, { content: \"OK\" });\n   *     okBtn.on(\"mouseUp\", dismiss);\n   *     box.add(okBtn);\n   *\n   *     return box;\n   *   }\n   * });\n   * ```\n   */\n  alert(options: AlertOptions): Promise<void>;\n  alert(showFactory: (ctx: AlertContext) => DialogShowOptions): Promise<void>;\n  alert(\n    input: AlertOptions | ((ctx: AlertContext) => DialogShowOptions),\n  ): Promise<void> {\n    return this.showAsyncDialog<void>((safeResolve, dialogId) => {\n      const ctx: AlertContext = {\n        dismiss: safeResolve,\n        dialogId,\n      };\n      return { showOptions: this.buildShowOptions(input, ctx) };\n    }, undefined);\n  }\n\n  /**\n   * Show a choice dialog and wait for the user to select an option.\n   *\n   * @template K The type of keys for the available choices.\n   * @returns The selected key, or `undefined` if cancelled or dismissed.\n   *\n   * Accepts either ChoiceOptions (for imperative usage) or a factory function\n   * that receives the choice context and returns AsyncShowOptions (for framework adapters).\n   *\n   * @example\n   * ```ts\n   * // Core/imperative usage\n   * const action = await manager.choice<\"save\" | \"discard\">({\n   *   content: (renderCtx, { resolve, dismiss }) => {\n   *     const box = new BoxRenderable(renderCtx, { flexDirection: \"column\" });\n   *     const title = new TextRenderable(renderCtx, { content: \"Unsaved changes\" });\n   *     box.add(title);\n   *\n   *     const saveBtn = new TextRenderable(renderCtx, { content: \"Save\" });\n   *     saveBtn.on(\"mouseUp\", () => resolve(\"save\"));\n   *     const discardBtn = new TextRenderable(renderCtx, { content: \"Discard\" });\n   *     discardBtn.on(\"mouseUp\", () => resolve(\"discard\"));\n   *     const cancelBtn = new TextRenderable(renderCtx, { content: \"Cancel\" });\n   *     cancelBtn.on(\"mouseUp\", dismiss);\n   *\n   *     box.add(saveBtn);\n   *     box.add(discardBtn);\n   *     box.add(cancelBtn);\n   *\n   *     return box;\n   *   }\n   * });\n   * ```\n   */\n  choice<K>(options: ChoiceOptions<K>): Promise<K | undefined>;\n  choice<K>(\n    showFactory: (ctx: ChoiceContext<K>) => AsyncShowOptions<K | undefined>,\n  ): Promise<K | undefined>;\n  choice<K>(\n    input:\n      | ChoiceOptions<K>\n      | ((ctx: ChoiceContext<K>) => AsyncShowOptions<K | undefined>),\n  ): Promise<K | undefined> {\n    return this.showAsyncDialog<K | undefined>((safeResolve, dialogId) => {\n      const ctx: ChoiceContext<K> = {\n        resolve: safeResolve,\n        dismiss: () => safeResolve(undefined),\n        dialogId,\n      };\n\n      if (typeof input === \"function\") {\n        const result = input(ctx);\n        return { showOptions: result, fallback: result.fallback };\n      }\n\n      const { fallback, ...rest } = input;\n      return {\n        showOptions: this.buildShowOptions(rest, ctx),\n        fallback,\n      };\n    }, undefined);\n  }\n\n  /** Destroy the manager and clean up resources. */\n  destroy(): void {\n    if (this.destroyed) return;\n    this.destroyed = true;\n\n    this.cancelPendingFocusRestore();\n    this.savedFocus = null;\n    this.subscribers.clear();\n    this.dialogs = [];\n  }\n\n  get isDestroyed(): boolean {\n    return this.destroyed;\n  }\n}\n","/**\n * Opacity normalization utilities\n *\n * Converts CSS-like opacity values to terminal-compatible formats.\n */\n\n/**\n * Default opacity value (100% - fully opaque)\n */\nexport const DEFAULT_OPACITY = 255;\n\n/**\n * Normalize opacity to 0-255 integer range using CSS-like semantics.\n *\n * Accepts the following formats (aligned with CSS opacity behavior):\n * - **0-1 (number)**: Float value where 0 = transparent, 1 = opaque\n * - **\"50%\" (string)**: Percentage string where \"0%\" = transparent, \"100%\" = opaque\n *\n * Values are clamped to valid ranges automatically.\n *\n * @param value - The opacity value to normalize\n * @param defaultValue - Default value if undefined (defaults to DEFAULT_OPACITY)\n * @returns Normalized opacity as integer 0-255\n *\n * @example\n * ```ts\n * normalizeOpacity(0.5);       // 128 (50% opacity)\n * normalizeOpacity(1);         // 255 (fully opaque)\n * normalizeOpacity(0);         // 0 (fully transparent)\n * normalizeOpacity(\"50%\");     // 128 (50% opacity)\n * normalizeOpacity(\"100%\");    // 255 (fully opaque)\n * normalizeOpacity(undefined); // DEFAULT_OPACITY (~60%)\n * ```\n *\n * @throws {Error} If value is a number outside 0-1 range\n */\nexport function normalizeOpacity(\n  value: number | string | undefined,\n  defaultValue: number = DEFAULT_OPACITY,\n  caller: string = \"@opentui-ui/utils\",\n): number {\n  if (value === undefined) {\n    return defaultValue;\n  }\n\n  // Handle percentage string (CSS-like: \"50%\")\n  if (typeof value === \"string\") {\n    if (value.endsWith(\"%\")) {\n      const percent = parseFloat(value);\n      if (!Number.isNaN(percent)) {\n        // Clamp to 0-100 range, then convert to 0-255\n        const clamped = Math.min(100, Math.max(0, percent));\n        return Math.round((clamped / 100) * 255);\n      }\n    }\n\n    // Try parsing as a decimal number string (e.g., \"0.5\")\n    const parsed = parseFloat(value);\n    if (!Number.isNaN(parsed)) {\n      if (parsed < 0 || parsed > 1) {\n        throw new Error(\n          `[${caller}] Invalid opacity value \"${value}\". ` +\n            `Numeric opacity must be between 0 and 1, or use a percentage string like \"50%\".`,\n        );\n      }\n      return Math.round(parsed * 255);\n    }\n\n    // Invalid string format - warn and return default\n    console.warn(\n      `[${caller}] Invalid opacity string \"${value}\", using default. ` +\n        `Use a number (0-1) or percentage string (\"50%\").`,\n    );\n    return defaultValue;\n  }\n\n  // Handle numeric value (CSS-like: 0-1)\n  if (typeof value === \"number\") {\n    if (value < 0 || value > 1) {\n      throw new Error(\n        `[${caller}] Invalid opacity value ${value}. ` +\n          `Opacity must be between 0 and 1 (CSS-like), where 0 = transparent and 1 = opaque. ` +\n          `For percentage, use a string like \"50%\".`,\n      );\n    }\n    return Math.round(value * 255);\n  }\n\n  return defaultValue;\n}\n\n/**\n * Convert a 0-255 opacity value to a 0-1 float\n *\n * @param value - Opacity as 0-255 integer\n * @returns Opacity as 0-1 float\n */\nexport function opacityToFloat(value: number): number {\n  return Math.min(1, Math.max(0, value / 255));\n}\n\n/**\n * Convert a 0-255 opacity value to a percentage string\n *\n * @param value - Opacity as 0-255 integer\n * @returns Opacity as percentage string (e.g., \"50%\")\n */\nexport function opacityToPercent(value: number): string {\n  const percent = Math.round((value / 255) * 100);\n  return `${percent}%`;\n}\n","/**\n * Padding resolution utilities\n *\n * Provides CSS-like padding shorthand support for terminal UI components.\n */\n\nimport type { Padding, PaddingInput } from \"../types\";\n\n/**\n * Resolve padding values with shorthand support\n *\n * Priority (highest to lowest):\n * 1. Specific side (paddingTop, paddingRight, etc.)\n * 2. Axis (paddingX, paddingY)\n * 3. Uniform (padding)\n * 4. Default values\n *\n * @param style - Style object containing padding properties\n * @param defaults - Default padding values (defaults to 0 for all sides)\n * @returns Resolved padding for each side\n *\n * @example\n * ```ts\n * resolvePadding({ padding: 1 })\n * // => { top: 1, right: 1, bottom: 1, left: 1 }\n *\n * resolvePadding({ paddingX: 2, paddingY: 1 })\n * // => { top: 1, right: 2, bottom: 1, left: 2 }\n *\n * resolvePadding({ padding: 1, paddingLeft: 3 })\n * // => { top: 1, right: 1, bottom: 1, left: 3 }\n *\n * resolvePadding({ paddingTop: 2 }, { top: 0, right: 1, bottom: 0, left: 1 })\n * // => { top: 2, right: 1, bottom: 0, left: 1 }\n * ```\n */\nexport function resolvePadding(\n  style?: PaddingInput,\n  defaults: Padding = { top: 0, right: 0, bottom: 0, left: 0 },\n): Padding {\n  if (!style) {\n    return { ...defaults };\n  }\n\n  const uniform = style.padding;\n  const axisX = style.paddingX;\n  const axisY = style.paddingY;\n\n  return {\n    top: style.paddingTop ?? axisY ?? uniform ?? defaults.top,\n    right: style.paddingRight ?? axisX ?? uniform ?? defaults.right,\n    bottom: style.paddingBottom ?? axisY ?? uniform ?? defaults.bottom,\n    left: style.paddingLeft ?? axisX ?? uniform ?? defaults.left,\n  };\n}\n","/**\n * Style merging utilities\n *\n * Provides helpers for combining style objects with proper precedence.\n */\n\n/**\n * Merge multiple style objects (later wins)\n *\n * Uses shallow Object.assign, so later styles completely\n * override earlier values for the same property.\n *\n * @param styles - Style objects to merge (undefined values are skipped)\n * @returns Merged style object\n *\n * @example\n * ```ts\n * mergeStyles(\n *   { borderColor: \"red\", padding: 1 },\n *   { borderColor: \"blue\" }\n * )\n * // => { borderColor: \"blue\", padding: 1 }\n *\n * mergeStyles(\n *   { padding: 1 },\n *   undefined,\n *   { paddingLeft: 2 }\n * )\n * // => { padding: 1, paddingLeft: 2 }\n * ```\n */\nexport function mergeStyles<T extends object>(\n  ...styles: (Partial<T> | undefined)[]\n): T {\n  const result = {} as T;\n\n  for (const style of styles) {\n    if (!style) continue;\n    Object.assign(result, style);\n  }\n\n  return result;\n}\n","import {\n  BoxRenderable,\n  parseColor,\n  type RenderContext,\n  type RGBA,\n} from \"@opentui/core\";\nimport { normalizeOpacity } from \"@opentui-ui/utils\";\nimport { DEFAULT_BACKDROP_COLOR, DEFAULT_BACKDROP_OPACITY } from \"../themes\";\nimport type { DialogContainerOptions, InternalDialog } from \"../types\";\n\nexport interface BackdropRenderableOptions {\n  containerOptions: DialogContainerOptions;\n  onClick: () => void;\n}\n\nexport class BackdropRenderable extends BoxRenderable {\n  private _containerOptions: DialogContainerOptions;\n\n  constructor(ctx: RenderContext, options: BackdropRenderableOptions) {\n    super(ctx, {\n      id: \"dialog-backdrop\",\n      position: \"absolute\",\n      left: 0,\n      top: 0,\n      width: ctx.width,\n      height: ctx.height,\n      backgroundColor: BackdropRenderable.computeColor(\n        undefined,\n        options.containerOptions,\n      ),\n      visible: false,\n      onMouseUp: options.onClick,\n    });\n    this._containerOptions = options.containerOptions;\n  }\n\n  public updateStyle(dialog?: InternalDialog): void {\n    this.backgroundColor = BackdropRenderable.computeColor(\n      dialog,\n      this._containerOptions,\n    );\n  }\n\n  public updateDimensions(width: number, height: number): void {\n    this.width = width;\n    this.height = height;\n  }\n\n  public updateContainerOptions(options: DialogContainerOptions): void {\n    this._containerOptions = options;\n  }\n\n  private static computeColor(\n    dialog: InternalDialog | undefined,\n    containerOptions: DialogContainerOptions,\n  ): RGBA {\n    const color =\n      dialog?.backdropColor ??\n      containerOptions.backdropColor ??\n      DEFAULT_BACKDROP_COLOR;\n    const opacity = normalizeOpacity(\n      dialog?.backdropOpacity ?? containerOptions.backdropOpacity,\n      DEFAULT_BACKDROP_OPACITY,\n      \"@opentui-ui/dialog\",\n    );\n    const rgba = parseColor(color);\n    rgba.a = opacity / 255;\n    return rgba;\n  }\n}\n","import type { DialogSize } from \"./types\";\n\nexport const DEFAULT_SIZE: DialogSize = \"medium\";\n\nexport const DEFAULT_SIZES: Record<DialogSize, number> = {\n  small: 40,\n  medium: 60,\n  large: 80,\n  full: -1,\n};\n\nexport const FULL_SIZE_OFFSET = 4;\n\nexport const DIALOG_Z_INDEX = 9998;\n\n/** @internal Used by React/Solid bindings for JSX portals */\nexport const JSX_CONTENT_KEY = Symbol(\"dialog-jsx-content\");\n","import { mergeStyles, resolvePadding } from \"@opentui-ui/utils\";\nimport { DEFAULT_SIZE, DEFAULT_SIZES, FULL_SIZE_OFFSET } from \"../constants\";\nimport { DEFAULT_PADDING, DEFAULT_STYLE } from \"../themes\";\nimport type {\n  Dialog,\n  DialogContainerOptions,\n  DialogSize,\n  DialogStyle,\n} from \"../types\";\n\nexport interface ComputeDialogStyleInput {\n  dialog: Dialog;\n  containerOptions?: DialogContainerOptions;\n}\n\nexport interface ComputedDialogStyle extends DialogStyle {\n  resolvedPadding: {\n    top: number;\n    right: number;\n    bottom: number;\n    left: number;\n  };\n}\n\nexport function computeDialogStyle(\n  input: ComputeDialogStyleInput,\n): ComputedDialogStyle {\n  const { dialog, containerOptions } = input;\n\n  const isUnstyled = dialog.unstyled ?? containerOptions?.unstyled ?? false;\n\n  const baseStyle = isUnstyled ? {} : DEFAULT_STYLE;\n\n  const computed = mergeStyles(\n    baseStyle,\n    containerOptions?.dialogOptions?.style,\n    dialog.style,\n  );\n\n  const defaultPadding = isUnstyled\n    ? { top: 0, right: 0, bottom: 0, left: 0 }\n    : DEFAULT_PADDING;\n\n  const resolvedPadding = isUnstyled\n    ? { top: 0, right: 0, bottom: 0, left: 0 }\n    : resolvePadding(computed, defaultPadding);\n\n  return {\n    ...computed,\n    resolvedPadding,\n  };\n}\n\nexport function getDialogWidth(\n  size: DialogSize | undefined,\n  containerOptions?: DialogContainerOptions,\n  terminalWidth?: number,\n): number {\n  const effectiveSize: DialogSize =\n    size ?? containerOptions?.size ?? DEFAULT_SIZE;\n\n  const customWidth = containerOptions?.sizePresets?.[effectiveSize];\n  if (customWidth !== undefined && customWidth > 0) {\n    return customWidth;\n  }\n\n  const defaultWidth = DEFAULT_SIZES[effectiveSize];\n\n  if (defaultWidth === -1) {\n    return terminalWidth ? terminalWidth - FULL_SIZE_OFFSET : 80;\n  }\n\n  return defaultWidth;\n}\n","import { BoxRenderable, type RenderContext } from \"@opentui/core\";\nimport { JSX_CONTENT_KEY } from \"../constants\";\nimport type { DialogContainerOptions, InternalDialog } from \"../types\";\nimport {\n  type ComputedDialogStyle,\n  computeDialogStyle,\n  getDialogWidth,\n} from \"../utils\";\n\nexport interface DialogRenderableOptions {\n  dialog: InternalDialog;\n  containerOptions: DialogContainerOptions;\n}\n\nexport class DialogRenderable extends BoxRenderable {\n  private _dialog: InternalDialog;\n  private _computedStyle: ComputedDialogStyle;\n  private _containerOptions: DialogContainerOptions;\n\n  constructor(ctx: RenderContext, options: DialogRenderableOptions) {\n    const { dialog, containerOptions } = options;\n    const isDeferred = dialog.deferred === true;\n\n    const computedStyle = computeDialogStyle({ dialog, containerOptions });\n    const dialogWidth = getDialogWidth(\n      dialog.size,\n      containerOptions,\n      ctx.width,\n    );\n    const padding = computedStyle.resolvedPadding;\n\n    const panelWidth =\n      typeof computedStyle.width === \"number\"\n        ? computedStyle.width\n        : dialogWidth;\n\n    super(ctx, {\n      id: `dialog-${dialog.id}`,\n      position: \"absolute\",\n      width: panelWidth,\n      maxWidth: computedStyle.maxWidth ?? ctx.width - 2,\n      minWidth: computedStyle.minWidth,\n      maxHeight: computedStyle.maxHeight,\n      backgroundColor: computedStyle.backgroundColor,\n      border: computedStyle.border,\n      borderColor: computedStyle.borderColor,\n      borderStyle: computedStyle.borderStyle,\n      paddingTop: padding.top,\n      paddingRight: padding.right,\n      paddingBottom: padding.bottom,\n      paddingLeft: padding.left,\n      visible: !isDeferred,\n    });\n\n    this._dialog = dialog;\n    this._containerOptions = containerOptions;\n    this._computedStyle = computedStyle;\n\n    if (dialog?.[JSX_CONTENT_KEY]) {\n      // Reconcilers take over rendering the tree from here\n      return;\n    }\n\n    this.createContent();\n  }\n\n  private createContent(): void {\n    try {\n      const contentRenderable = this._dialog.content(this.ctx);\n      this.add(contentRenderable);\n    } catch (error) {\n      const dialogId = this._dialog.id;\n      const originalMessage =\n        error instanceof Error ? error.message : String(error);\n      const originalStack = error instanceof Error ? error.stack : undefined;\n\n      const enhancedError = new Error(\n        `[@opentui-ui/dialog] Failed to create content for dialog \"${dialogId}\".\\n\\n` +\n          `Root cause: ${originalMessage}\\n\\n` +\n          `This error occurred while executing the content factory function. ` +\n          `Check that your content factory returns a valid Renderable and doesn't throw.\\n\\n` +\n          `Example of a valid content factory:\\n` +\n          `  content: (ctx) => new TextRenderable(ctx, { content: \"Hello\" })`,\n      );\n\n      if (originalStack) {\n        enhancedError.stack = `${enhancedError.message}\\n\\nOriginal stack trace:\\n${originalStack}`;\n      }\n\n      throw enhancedError;\n    }\n  }\n\n  public updateDimensions(width: number, _height?: number): void {\n    const dialogWidth = getDialogWidth(\n      this._dialog.size,\n      this._containerOptions,\n      width,\n    );\n    const panelWidth =\n      typeof this._computedStyle.width === \"number\"\n        ? this._computedStyle.width\n        : dialogWidth;\n\n    this.width = panelWidth;\n    this.maxWidth = this._computedStyle.maxWidth ?? width - 2;\n    this.requestRender();\n  }\n\n  public get dialog(): InternalDialog {\n    return this._dialog;\n  }\n}\n","import type { BorderStyle, Renderable, RenderContext } from \"@opentui/core\";\nimport { JSX_CONTENT_KEY } from \"./constants\";\n\nexport type DialogId = string | number;\n\nexport type DialogSize = \"small\" | \"medium\" | \"large\" | \"full\";\n\nexport interface DialogStyle {\n  backgroundColor?: string;\n  borderColor?: string;\n  borderStyle?: BorderStyle;\n  border?: boolean;\n  width?: number | string;\n  maxWidth?: number;\n  minWidth?: number;\n  maxHeight?: number;\n  padding?: number;\n  paddingX?: number;\n  paddingY?: number;\n  paddingTop?: number;\n  paddingRight?: number;\n  paddingBottom?: number;\n  paddingLeft?: number;\n}\n\n/** Factory function that creates dialog content from a RenderContext. */\nexport type DialogContentFactory = (ctx: RenderContext) => Renderable;\n\nexport interface Dialog {\n  id: DialogId;\n  content: DialogContentFactory;\n  size?: DialogSize;\n  style?: DialogStyle;\n  unstyled?: boolean;\n  /** @default true */\n  closeOnEscape?: boolean;\n  /** @default false */\n  closeOnClickOutside?: boolean;\n  /** Per-dialog backdrop color override. */\n  backdropColor?: string;\n  /** Per-dialog backdrop opacity override. 0-1 (number) or \"50%\" (string). */\n  backdropOpacity?: number | string;\n  onClose?: () => void;\n  onOpen?: () => void;\n  onBackdropClick?: () => void;\n}\n\n/**\n * Internal dialog type with adapter-specific properties.\n * Used by React for deferred visibility.\n * @internal\n */\nexport interface InternalDialog extends Dialog {\n  /** @internal Used by React/Solid bindings to store JSX portal content. */\n  [JSX_CONTENT_KEY]?: unknown;\n  /**\n   * When true, the dialog is initially hidden until visibility is updated.\n   * Used by adapter(s) to prevent flicker when JSX content is\n   * injected via portals after the dialog renderable is created.\n   */\n  deferred?: boolean;\n}\n\nexport interface DialogToClose {\n  id: DialogId;\n  close: true;\n}\n\nexport interface DialogShowOptions extends Omit<Dialog, \"id\"> {\n  id?: DialogId;\n}\n\nexport interface InternalDialogShowOptions extends Omit<InternalDialog, \"id\"> {\n  id?: DialogId;\n}\n\nexport interface DialogOptions {\n  style?: DialogStyle;\n}\n\nexport interface DialogContainerOptions {\n  /** @default \"medium\" */\n  size?: DialogSize;\n  dialogOptions?: DialogOptions;\n  sizePresets?: Partial<Record<DialogSize, number>>;\n  /** @default true */\n  closeOnEscape?: boolean;\n  /** @default false */\n  closeOnClickOutside?: boolean;\n  /** @default \"#000000\" */\n  backdropColor?: string;\n  /** 0-1 (number) or \"50%\" (string). @default 0.35 */\n  backdropOpacity?: number | string;\n  unstyled?: boolean;\n}\n\n// =============================================================================\n// Async Dialog Base Types\n// =============================================================================\n// These generic types reduce duplication between core and framework adapters.\n// Framework adapters (React, Solid, etc.) extend these with their content types.\n\n/**\n * Base options for async dialog methods (prompt, confirm, alert, choice).\n * Excludes `content` (replaced by context-specific content) and `id` (auto-generated).\n * Note: `onClose` is supported - it will be called before the Promise resolves.\n */\nexport interface AsyncDialogOptions\n  extends Omit<DialogShowOptions, \"content\" | \"id\"> {}\n\n/**\n * Generic base for prompt dialog options.\n * @template T The type of value the prompt resolves to.\n * @template TContent The content type (varies by adapter).\n */\nexport interface BasePromptOptions<T, TContent> extends AsyncDialogOptions {\n  /** Content factory that receives the prompt context. */\n  content: TContent;\n  /** Fallback value when dialog is dismissed via ESC or backdrop click. */\n  fallback?: T;\n}\n\n/**\n * Generic base for confirm dialog options.\n * @template TContent The content type (varies by adapter).\n */\nexport interface BaseConfirmOptions<TContent> extends AsyncDialogOptions {\n  /** Content factory that receives the confirm context. */\n  content: TContent;\n  /** Fallback value when dialog is dismissed via ESC or backdrop click. @default false */\n  fallback?: boolean;\n}\n\n/**\n * Generic base for alert dialog options.\n * @template TContent The content type (varies by adapter).\n */\nexport interface BaseAlertOptions<TContent> extends AsyncDialogOptions {\n  /** Content factory that receives the alert context. */\n  content: TContent;\n}\n\n/**\n * Generic base for choice dialog options.\n * @template TContent The content type (varies by adapter).\n * @template K The type of keys for the available choices.\n */\nexport interface BaseChoiceOptions<TContent, K = unknown>\n  extends AsyncDialogOptions {\n  /** Content factory that receives the choice context. */\n  content: TContent;\n  /** Fallback value when dialog is dismissed via ESC or backdrop click. @default undefined */\n  fallback?: K;\n}\n\n/**\n * Base interface for dialog actions returned by useDialog() hooks.\n * Contains the non-generic methods shared by all framework adapters.\n * Framework adapters extend this and add the generic prompt/confirm/alert/choice methods.\n * @template TShowOptions Options for show/replace methods.\n */\nexport interface BaseDialogActions<TShowOptions> {\n  /** Show a new dialog and return its ID. */\n  show: (options: TShowOptions) => DialogId;\n  /** Close a specific dialog by ID, or the top-most dialog if no ID provided. */\n  close: (id?: DialogId) => DialogId | undefined;\n  /** Close all open dialogs. */\n  closeAll: () => void;\n  /** Close all dialogs and show a new one. */\n  replace: (options: TShowOptions) => DialogId;\n}\n\nexport function isDialogToClose(\n  value: Dialog | DialogToClose,\n): value is DialogToClose {\n  return \"close\" in value && value.close === true;\n}\n","import { BoxRenderable, type RenderContext } from \"@opentui/core\";\nimport { DIALOG_Z_INDEX } from \"../constants\";\nimport type { DialogManager } from \"../manager\";\nimport type {\n  DialogContainerOptions,\n  DialogId,\n  DialogOptions,\n  DialogSize,\n  InternalDialog,\n} from \"../types\";\nimport { isDialogToClose } from \"../types\";\nimport { BackdropRenderable } from \"./backdrop\";\nimport { DialogRenderable } from \"./dialog\";\n\nexport interface DialogContainerRenderableOptions\n  extends DialogContainerOptions {\n  manager: DialogManager;\n}\n\nexport interface DialogKeyboardEvent {\n  name?: string;\n  preventDefault?: () => void;\n}\n\n/**\n * Container that renders dialogs from a DialogManager.\n *\n * @example\n * ```ts\n * const manager = new DialogManager(renderer);\n * const container = new DialogContainerRenderable(ctx, { manager });\n * ctx.root.add(container);\n *\n * manager.show({ content: (ctx) => new TextRenderable(ctx, { content: \"Hi\" }) });\n * ```\n */\nexport class DialogContainerRenderable extends BoxRenderable {\n  private _manager: DialogManager;\n  private _options: DialogContainerOptions;\n  private _backdrop: BackdropRenderable;\n  private _dialogRenderables: Map<DialogId, DialogRenderable> = new Map();\n  private _unsubscribe: (() => void) | null = null;\n  private _destroyed: boolean = false;\n\n  constructor(ctx: RenderContext, options: DialogContainerRenderableOptions) {\n    super(ctx, {\n      id: \"dialog-container\",\n      position: \"absolute\",\n      left: 0,\n      top: 0,\n      width: ctx.width,\n      height: ctx.height,\n      zIndex: DIALOG_Z_INDEX,\n      alignItems: \"center\",\n      justifyContent: \"center\",\n      backgroundColor: \"transparent\",\n      visible: false,\n    });\n\n    this._manager = options.manager;\n    const { manager: _, ...containerOptions } = options;\n    this._options = containerOptions;\n\n    this._backdrop = new BackdropRenderable(ctx, {\n      containerOptions: this._options,\n      onClick: () => this.handleBackdropClick(),\n    });\n    this.add(this._backdrop);\n\n    this._ctx.keyInput.on(\"keypress\", this.handleKeyboard);\n\n    this.subscribe();\n  }\n\n  private subscribe(): void {\n    this._unsubscribe?.();\n\n    this._unsubscribe = this._manager.subscribe((data) => {\n      if (this._destroyed) return;\n\n      if (isDialogToClose(data)) {\n        this.removeDialog(data.id);\n      } else {\n        this.addOrUpdateDialog(data);\n      }\n    });\n  }\n\n  /**\n   * Handle keyboard events. Returns true if handled (e.g., ESC closed a dialog).\n   */\n  private handleKeyboard = (evt: DialogKeyboardEvent): boolean => {\n    const key = evt.name;\n    if (key === \"escape\" && this._dialogRenderables.size > 0) {\n      const topDialog = this.getTopDialogRenderable();\n      if (topDialog) {\n        // Per-dialog closeOnEscape takes precedence over container-level\n        const closeOnEscape =\n          topDialog.dialog.closeOnEscape ?? this._options.closeOnEscape;\n        if (closeOnEscape === false) {\n          return false;\n        }\n        evt.preventDefault?.();\n        this._manager.close(topDialog.dialog.id);\n        return true;\n      }\n    }\n\n    return false;\n  };\n\n  private getTopDialogRenderable(): DialogRenderable | undefined {\n    if (this._dialogRenderables.size === 0) {\n      return undefined;\n    }\n\n    const ids = Array.from(this._dialogRenderables.keys());\n    const topId = ids[ids.length - 1];\n    return topId !== undefined ? this._dialogRenderables.get(topId) : undefined;\n  }\n\n  public getDialogRenderable(id: DialogId): DialogRenderable | undefined {\n    return this._dialogRenderables.get(id);\n  }\n\n  public getDialogRenderables(): Map<DialogId, DialogRenderable> {\n    return this._dialogRenderables;\n  }\n\n  private addOrUpdateDialog(dialog: InternalDialog): void {\n    const existing = this._dialogRenderables.get(dialog.id);\n\n    if (existing) {\n      // TODO: Support updating existing dialogs in-place\n      this.removeDialog(dialog.id);\n    }\n\n    const dialogRenderable = new DialogRenderable(this.ctx, {\n      dialog,\n      containerOptions: this._options,\n    });\n\n    this._dialogRenderables.set(dialog.id, dialogRenderable);\n    this.add(dialogRenderable);\n\n    this.updateBackdropVisibility();\n    this.updateBackdropStyle();\n\n    this.requestRender();\n  }\n\n  private removeDialog(id: DialogId): void {\n    const renderable = this._dialogRenderables.get(id);\n    if (renderable) {\n      this._dialogRenderables.delete(id);\n      this.remove(renderable.id);\n      renderable.destroyRecursively();\n\n      this.updateBackdropVisibility();\n      this.updateBackdropStyle();\n\n      this.requestRender();\n    }\n  }\n\n  public updateDimensions(width: number, height?: number): void {\n    const h = height ?? this._ctx.height;\n\n    // Update container dimensions\n    this.width = width;\n    this.height = h;\n\n    // Update backdrop dimensions\n    this._backdrop.updateDimensions(width, h);\n\n    // Update dialog dimensions\n    for (const [, renderable] of this._dialogRenderables) {\n      renderable.updateDimensions(width, h);\n    }\n  }\n\n  public set size(value: DialogSize) {\n    this._options.size = value;\n  }\n\n  public set dialogOptions(value: DialogOptions) {\n    this._options.dialogOptions = value;\n  }\n\n  public set sizePresets(value: Partial<Record<DialogSize, number>>) {\n    this._options.sizePresets = value;\n  }\n\n  public set closeOnEscape(value: boolean) {\n    this._options.closeOnEscape = value;\n  }\n\n  public set closeOnClickOutside(value: boolean) {\n    this._options.closeOnClickOutside = value;\n  }\n\n  public set backdropColor(value: string) {\n    this._options.backdropColor = value;\n    this._backdrop.updateContainerOptions(this._options);\n    this.updateBackdropStyle();\n  }\n\n  public set backdropOpacity(value: number | string) {\n    this._options.backdropOpacity = value;\n    this._backdrop.updateContainerOptions(this._options);\n    this.updateBackdropStyle();\n  }\n\n  private updateBackdropVisibility(): void {\n    const hasDialogs = this._dialogRenderables.size > 0;\n    this._backdrop.visible = hasDialogs;\n    this.visible = hasDialogs;\n  }\n\n  private updateBackdropStyle(): void {\n    const topDialog = this.getTopDialogRenderable();\n    this._backdrop.updateStyle(topDialog?.dialog);\n  }\n\n  private handleBackdropClick(): void {\n    const topDialog = this.getTopDialogRenderable();\n    if (!topDialog) return;\n\n    // Call per-dialog callback first\n    topDialog.dialog.onBackdropClick?.();\n\n    // Check per-dialog setting, fall back to container setting\n    const closeOnClickOutside =\n      topDialog.dialog.closeOnClickOutside ?? this._options.closeOnClickOutside;\n\n    if (closeOnClickOutside === true) {\n      this._manager.close(topDialog.dialog.id);\n    }\n  }\n\n  public set unstyled(value: boolean) {\n    this._options.unstyled = value;\n  }\n\n  public override destroy(): void {\n    if (this._destroyed) return;\n    this._destroyed = true;\n\n    this._unsubscribe?.();\n    this._unsubscribe = null;\n\n    this._ctx.keyInput.off(\"keypress\", this.handleKeyboard);\n\n    // Clean up dialog renderables\n    for (const [, renderable] of this._dialogRenderables) {\n      renderable.destroyRecursively();\n    }\n    this._dialogRenderables.clear();\n\n    // Clean up backdrop\n    this._backdrop.destroyRecursively();\n\n    super.destroy();\n  }\n}\n"],"mappings":"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"}