{"version":3,"file":"toast-Tw69SY7E.cjs","names":[],"sources":["../src/components/toast/BqToast.ts"],"sourcesContent":["/**\r\n * Toast / notification snackbar.\r\n * @element bq-toast\r\n * @prop {string}  variant    - success | error | warning | info\r\n * @prop {string}  message\r\n * @prop {number}  duration   - Auto-dismiss ms. 0 = persistent.\r\n * @prop {boolean} dismissible\r\n * @fires bq-close\r\n */\r\nimport type { ComponentDefinition } from '@bquery/bquery/component';\r\nimport { component, html } from '@bquery/bquery/component';\r\nimport { escapeHtml } from '@bquery/bquery/security';\r\nimport { t } from '../../i18n/index.js';\r\nimport { getBaseStyles } from '../../utils/styles.js';\r\n\r\ntype BqToastProps = {\r\n  variant: string;\r\n  message: string;\r\n  duration: number;\r\n  dismissible: boolean;\r\n};\r\n\r\nconst definition: ComponentDefinition<BqToastProps> = {\r\n  props: {\r\n    variant: { type: String, default: 'info' },\r\n    message: { type: String, default: '' },\r\n    duration: { type: Number, default: 4000 },\r\n    dismissible: { type: Boolean, default: true },\r\n  },\r\n  styles: `\r\n    ${getBaseStyles()}\r\n    *, *::before, *::after { box-sizing: border-box; }\r\n    :host { display: block; }\r\n    .toast {\r\n      display: flex; align-items: flex-start; gap: 0.75rem;\r\n      padding: 0.875rem var(--bq-space-4,1rem); border-radius: var(--bq-radius-lg,0.5rem);\r\n      border: 1.5px solid transparent; font-family: var(--bq-font-family-sans);\r\n      box-shadow: var(--bq-shadow-lg); min-width: 18rem; max-width: 28rem;\r\n      animation: slideIn var(--bq-duration-normal,200ms) var(--bq-easing-decelerate);\r\n    }\r\n    @keyframes slideIn { from { opacity: 0; transform: translateY(-0.5rem); } to { opacity: 1; transform: translateY(0); } }\r\n    .toast[data-variant=\"success\"] { background: var(--bq-color-success-50,#f0fdf4); border-color: var(--bq-color-success-500,#22c55e); color: var(--bq-color-success-700,#15803d); }\r\n    .toast[data-variant=\"error\"]   { background: var(--bq-color-danger-50,#fef2f2);  border-color: var(--bq-color-danger-500,#ef4444);  color: var(--bq-color-danger-700,#b91c1c); }\r\n    .toast[data-variant=\"warning\"] { background: var(--bq-color-warning-50,#fffbeb); border-color: var(--bq-color-warning-500,#f59e0b); color: var(--bq-color-warning-700,#b45309); }\r\n    .toast[data-variant=\"info\"]    { background: var(--bq-color-info-50,#eff6ff);    border-color: var(--bq-color-info-500,#3b82f6);    color: var(--bq-color-info-700,#1d4ed8); }\r\n    .icon { font-size: 1.1em; flex-shrink: 0; margin-top: 0.05em; }\r\n    .content { flex: 1; min-width: 0; font-size: var(--bq-font-size-sm,0.875rem); line-height: var(--bq-line-height-normal,1.5); }\r\n    .close { flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; background: none; border: none; cursor: pointer; color: inherit; padding: 0.125rem; border-radius: var(--bq-radius-sm,0.25rem); opacity: 0.7; font-size: 0.875rem; }\r\n    .close:hover { opacity: 1; background: rgba(0,0,0,0.08); }\r\n    .close:focus-visible { outline: 2px solid transparent; box-shadow: var(--bq-focus-ring); }\r\n    @media (prefers-reduced-motion: reduce) {\r\n      .toast { animation: none; }\r\n    }\r\n  `,\r\n  connected() {\r\n    const self = this;\r\n    const close = () => {\r\n      self.dispatchEvent(\r\n        new CustomEvent('bq-close', { bubbles: true, composed: true })\r\n      );\r\n      self.remove();\r\n    };\r\n    const ch = (e: Event) => {\r\n      if ((e.target as Element).closest('.close')) close();\r\n    };\r\n    const dur = parseInt(self.getAttribute('duration') ?? '4000', 10);\r\n    if (dur > 0) {\r\n      const timer = setTimeout(close, dur);\r\n      (self as unknown as Record<string, unknown>)['_timer'] = timer;\r\n    }\r\n    (self as unknown as Record<string, unknown>)['_ch'] = ch;\r\n    self.shadowRoot?.addEventListener('click', ch);\r\n  },\r\n  disconnected() {\r\n    const s = this as unknown as Record<string, unknown>;\r\n    const timer = s['_timer'] as ReturnType<typeof setTimeout> | undefined;\r\n    if (timer) clearTimeout(timer);\r\n    const ch = s['_ch'] as EventListener | undefined;\r\n    if (ch) this.shadowRoot?.removeEventListener('click', ch);\r\n  },\r\n  render({ props }) {\r\n    const icons: Record<string, string> = {\r\n      success: '✓',\r\n      error: '✕',\r\n      warning: '⚠',\r\n      info: 'ℹ',\r\n    };\r\n    const icon = icons[props.variant] ?? 'ℹ';\r\n    const isAlert = props.variant === 'error' || props.variant === 'warning';\r\n    return html`\r\n      <div\r\n        part=\"toast\"\r\n        class=\"toast\"\r\n        data-variant=\"${escapeHtml(props.variant)}\"\r\n        role=\"${isAlert ? 'alert' : 'status'}\"\r\n        aria-live=\"${isAlert ? 'assertive' : 'polite'}\"\r\n        aria-atomic=\"true\"\r\n      >\r\n        <span class=\"icon\" aria-hidden=\"true\">${icon}</span>\r\n        <span class=\"content\" part=\"content\"\r\n          ><slot>${escapeHtml(props.message)}</slot></span\r\n        >\r\n        ${props.dismissible\r\n          ? `<button type=\"button\" class=\"close\" aria-label=\"${t('toast.close')}\">&#10005;</button>`\r\n          : ''}\r\n      </div>\r\n    `;\r\n  },\r\n};\r\n\r\n/** Imperative toast API */\r\nexport type ToastPosition =\r\n  | 'top-left'\r\n  | 'top-right'\r\n  | 'top-center'\r\n  | 'bottom-left'\r\n  | 'bottom-right'\r\n  | 'bottom-center';\r\n\r\nexport interface ToastOptions {\r\n  message: string;\r\n  variant?: 'success' | 'error' | 'warning' | 'info';\r\n  duration?: number;\r\n  /** Where the toast container is anchored (default: 'top-right'). */\r\n  position?: ToastPosition;\r\n}\r\n\r\nconst TOAST_CONTAINER_ID = 'bq-toast-container';\r\nconst POSITIONS: Record<ToastPosition, string> = {\r\n  'top-left': 'top: 1rem; left: 1rem;',\r\n  'top-right': 'top: 1rem; right: 1rem;',\r\n  'top-center': 'top: 1rem; left: 50%; transform: translateX(-50%);',\r\n  'bottom-left': 'bottom: 1rem; left: 1rem;',\r\n  'bottom-right': 'bottom: 1rem; right: 1rem;',\r\n  'bottom-center': 'bottom: 1rem; left: 50%; transform: translateX(-50%);',\r\n};\r\n\r\nfunction getOrCreateContainer(\r\n  position: ToastPosition = 'top-right'\r\n): HTMLElement {\r\n  const id = `${TOAST_CONTAINER_ID}-${position}`;\r\n  let container = document.getElementById(id);\r\n  if (!container) {\r\n    container = document.createElement('div');\r\n    container.id = id;\r\n    container.setAttribute('role', 'region');\r\n    container.setAttribute('aria-label', 'Notifications');\r\n    container.dataset['bqToastPosition'] = position;\r\n    container.style.cssText = `\r\n      position: fixed; ${POSITIONS[position]} z-index: var(--bq-z-toast, 600);\r\n      display: flex; flex-direction: column; gap: 0.5rem; pointer-events: none;\r\n      max-height: 100vh; overflow: hidden;\r\n    `.replace(/\\s+/g, ' ');\r\n    document.body.appendChild(container);\r\n  }\r\n  return container;\r\n}\r\n\r\nexport function showToast(\r\n  options: ToastOptions,\r\n  container?: HTMLElement\r\n): HTMLElement {\r\n  const host = container ?? getOrCreateContainer(options.position);\r\n  const toast = document.createElement('bq-toast');\r\n  toast.style.pointerEvents = 'auto';\r\n  toast.setAttribute('message', options.message);\r\n  if (options.variant) toast.setAttribute('variant', options.variant);\r\n  if (options.duration !== undefined)\r\n    toast.setAttribute('duration', String(options.duration));\r\n  host.appendChild(toast);\r\n  return toast;\r\n}\r\n\r\ncomponent<BqToastProps>('bq-toast', definition);\r\n"],"mappings":";;;;AAsBA,IAAM,aAAgD;CACpD,OAAO;EACL,SAAS;GAAE,MAAM;GAAQ,SAAS;GAAQ;EAC1C,SAAS;GAAE,MAAM;GAAQ,SAAS;GAAI;EACtC,UAAU;GAAE,MAAM;GAAQ,SAAS;GAAM;EACzC,aAAa;GAAE,MAAM;GAAS,SAAS;GAAM;EAC9C;CACD,QAAQ;MACJ,eAAA,eAAe,CAAC;;;;;;;;;;;;;;;;;;;;;;;;CAwBpB,YAAY;EACV,MAAM,OAAO;EACb,MAAM,cAAc;AAClB,QAAK,cACH,IAAI,YAAY,YAAY;IAAE,SAAS;IAAM,UAAU;IAAM,CAAC,CAC/D;AACD,QAAK,QAAQ;;EAEf,MAAM,MAAM,MAAa;AACvB,OAAK,EAAE,OAAmB,QAAQ,SAAS,CAAE,QAAO;;EAEtD,MAAM,MAAM,SAAS,KAAK,aAAa,WAAW,IAAI,QAAQ,GAAG;AACjE,MAAI,MAAM,EAEP,MAA4C,YAD/B,WAAW,OAAO,IACyB;AAE1D,OAA4C,SAAS;AACtD,OAAK,YAAY,iBAAiB,SAAS,GAAG;;CAEhD,eAAe;EACb,MAAM,IAAI;EACV,MAAM,QAAQ,EAAE;AAChB,MAAI,MAAO,cAAa,MAAM;EAC9B,MAAM,KAAK,EAAE;AACb,MAAI,GAAI,MAAK,YAAY,oBAAoB,SAAS,GAAG;;CAE3D,OAAO,EAAE,SAAS;EAOhB,MAAM,OAAO;GALX,SAAS;GACT,OAAO;GACP,SAAS;GACT,MAAM;GAEK,CAAM,MAAM,YAAY;EACrC,MAAM,UAAU,MAAM,YAAY,WAAW,MAAM,YAAY;AAC/D,SAAO,2BAAA,CAAI;;;;wBAIS,2BAAA,GAAW,MAAM,QAAQ,CAAC;gBAClC,UAAU,UAAU,SAAS;qBACxB,UAAU,cAAc,SAAS;;;gDAGN,KAAK;;mBAElC,2BAAA,GAAW,MAAM,QAAQ,CAAC;;UAEnC,MAAM,cACJ,mDAAmD,aAAA,EAAE,cAAc,CAAC,uBACpE,GAAG;;;;CAId;AAmBD,IAAM,qBAAqB;AAC3B,IAAM,YAA2C;CAC/C,YAAY;CACZ,aAAa;CACb,cAAc;CACd,eAAe;CACf,gBAAgB;CAChB,iBAAiB;CAClB;AAED,SAAS,qBACP,WAA0B,aACb;CACb,MAAM,KAAK,GAAG,mBAAmB,GAAG;CACpC,IAAI,YAAY,SAAS,eAAe,GAAG;AAC3C,KAAI,CAAC,WAAW;AACd,cAAY,SAAS,cAAc,MAAM;AACzC,YAAU,KAAK;AACf,YAAU,aAAa,QAAQ,SAAS;AACxC,YAAU,aAAa,cAAc,gBAAgB;AACrD,YAAU,QAAQ,qBAAqB;AACvC,YAAU,MAAM,UAAU;yBACL,UAAU,UAAU;;;MAGvC,QAAQ,QAAQ,IAAI;AACtB,WAAS,KAAK,YAAY,UAAU;;AAEtC,QAAO;;AAGT,SAAgB,UACd,SACA,WACa;CACb,MAAM,OAAO,aAAa,qBAAqB,QAAQ,SAAS;CAChE,MAAM,QAAQ,SAAS,cAAc,WAAW;AAChD,OAAM,MAAM,gBAAgB;AAC5B,OAAM,aAAa,WAAW,QAAQ,QAAQ;AAC9C,KAAI,QAAQ,QAAS,OAAM,aAAa,WAAW,QAAQ,QAAQ;AACnE,KAAI,QAAQ,aAAa,KAAA,EACvB,OAAM,aAAa,YAAY,OAAO,QAAQ,SAAS,CAAC;AAC1D,MAAK,YAAY,MAAM;AACvB,QAAO;;AAGT,2BAAA,EAAwB,YAAY,WAAW"}