{
  "version": 3,
  "sources": ["../src/main.ts", "../src/lib/handler.ts", "../src/lib/signal.ts", "../src/lib/element.ts", "../src/lib/utils.ts"],
  "sourcesContent": ["import { packageTracer } from '@alwatr/package-tracer';\n\n__dev_mode__: packageTracer.add(__package_name__, __package_version__);\n\nimport './lib/handler.js';\n\nexport * from './lib/element.js';\nexport { snackbarSignal } from './lib/signal.js';\n", "import { delay } from '@alwatr/delay';\nimport { createLogger } from '@alwatr/logger';\nimport debounce from 'debounce';\n\nimport { snackbarActionButtonClickedSignal, snackbarCloseButtonClickedSignal, snackbarSignal } from './signal.js';\n\nimport type { SnackbarElement } from './element.js';\nimport type { SnackbarActionHandler, SnackbarOptions } from './type.js';\n\nconst logger = createLogger(__package_name__);\n\n/**\n * Store the function to close the last snackbar.\n */\nlet closeLastSnackbar: (() => MaybePromise<void>) | null = null;\n\n/**\n * Store the function to unsubscribe the action button handler after close or action button clicked.\n */\nlet unsubscribeActionButtonHandler: (() => void) | null = null;\n\n/**\n * Store the function to unsubscribe the close button handler after close or action button clicked.\n */\nlet unsubscribeCloseButtonHandler: (() => void) | null = null;\n\n/**\n * Create snackbar element with given options.\n *\n * @param options - Options for configuring the snackbar.\n * @returns The created snackbar element.\n */\nfunction createSnackbarElement(options: SnackbarOptions): SnackbarElement {\n  const element = document.createElement('snack-bar');\n  element.setAttribute('content', options.content);\n\n  if (options.addCloseButton === true) {\n    element.setAttribute('add-close-button', '');\n  }\n\n  if (options.action != null) {\n    element.setAttribute('action-button-label', options.action.label);\n  }\n\n  return element;\n}\n\n/**\n * Handle action button click.\n *\n * @param closeSnackbar - Function to close the snackbar.\n * @param handler - Handler to be called when the action button is clicked.\n */\nfunction handleActionButtonClick(closeSnackbar: () => Promise<void>, handler?: SnackbarActionHandler): Promise<void> {\n  logger.logMethod?.('handleActionButtonClick');\n\n  // non-blocking to handler done\n  (async () => {\n    try {\n      await handler!();\n    }\n    catch (error) {\n      logger.error('handleActionButtonClick', 'call_handler_failed', error);\n    }\n  })();\n\n  return closeSnackbar();\n}\n\n/**\n * Displays the snackbar with the given options.\n *\n * @param options - Options for configuring the snackbar.\n */\nasync function showSnackbar(options: SnackbarOptions): Promise<void> {\n  logger.logMethodArgs?.('showSnackbar', { options });\n\n  // Set default duration if not provided\n  options.duration ??= '5s';\n\n  const element = createSnackbarElement(options);\n\n  let closed = false;\n  const closeSnackbar = async () => {\n    if (closed) return;\n    logger.logMethodArgs?.('closeSnackbar', { options });\n\n    await element.close();\n    unsubscribeActionButtonHandler?.();\n    unsubscribeCloseButtonHandler?.();\n\n    closed = true;\n  };\n\n  await closeLastSnackbar?.();\n  closeLastSnackbar = closeSnackbar;\n\n  if (options.action != null) {\n    /**\n     * Store the function to unsubscribe the action button handler after close or action button clicked.\n     *\n     * TODO: check why once not work\n     */\n    unsubscribeActionButtonHandler = snackbarActionButtonClickedSignal.subscribe(\n      handleActionButtonClick.bind(null, closeSnackbar, options.action.handler),\n    ).unsubscribe;\n  }\n\n  if (options.addCloseButton === true) {\n    // TODO: check why once not work\n    unsubscribeCloseButtonHandler = snackbarCloseButtonClickedSignal.subscribe(closeSnackbar.bind(null)).unsubscribe;\n  }\n\n  // Close the last snackbar if it exists\n  document.body.appendChild(element);\n\n  // Set a timeout to close the snackbar if duration is not infinite\n  if (options.duration !== 'infinite') {\n    delay.by(options.duration).then(closeSnackbar);\n  }\n}\n\n// Debounce utility to only process the last signal value within a short interval.\nconst debouncedShowSnackbar = debounce((options: SnackbarOptions) => {\n  showSnackbar(options);\n}, 50);\n\nsnackbarSignal.subscribe((options) => {\n  debouncedShowSnackbar(options);\n});\n", "import { AlwatrSignal, AlwatrTrigger } from '@alwatr/flux';\n\nimport type { SnackbarOptions } from './type.js';\n\n/**\n * Signal triggered when the snackbar action button is clicked to close snackbar.\n */\nexport const snackbarActionButtonClickedSignal = /* @__PURE__ */ new AlwatrTrigger({\n  name: 'snackbar-action-button-click',\n});\n\n/**\n * Signal triggered when the snackbar close button is clicked to close snackbar.\n */\nexport const snackbarCloseButtonClickedSignal = /* @__PURE__ */ new AlwatrTrigger({\n  name: 'snackbar-close-button-click',\n});\n\n/**\n * Signal for displaying the snackbar.\n *\n * @example\n * import \\{snackbarSignal\\} from '\\@nexim/snackbar';\n *\n * snackbarSignal.notify(\\{\n *   content: 'This is a snackbar message',\n *   action: \\{\n *     label: 'Undo',\n *     handler: () =\\> \\{\n *       console.log('Action button clicked');\n *     \\},\n *   \\},\n *   duration: '5s',\n *   addCloseButton: true,\n * \\});\n */\nexport const snackbarSignal = /* @__PURE__ */ new AlwatrSignal<SnackbarOptions>({ name: 'snackbar' });\n", "import { delay } from '@alwatr/delay';\nimport { lightDomMixin, loggerMixin } from '@nexim/element';\nimport { html, LitElement, nothing, type PropertyValues, type TemplateResult } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\n\nimport { snackbarActionButtonClickedSignal, snackbarCloseButtonClickedSignal } from './signal.js';\nimport { waitForNextFrame } from './utils.js';\n\ndeclare global {\n  interface HTMLElementTagNameMap {\n    'snack-bar': SnackbarElement;\n  }\n}\n\n@customElement('snack-bar')\nexport class SnackbarElement extends lightDomMixin(loggerMixin(LitElement)) {\n  /**\n   * The content to be displayed inside the snackbar.\n   */\n  @property({ type: String }) content = '';\n\n  /**\n   * The label for the action button. If null, the action button will not be rendered.\n   */\n  @property({ type: String, attribute: 'action-button-label' }) actionButtonLabel: string | null = null;\n\n  /**\n   * Whether to add a close button to the snackbar.\n   */\n  @property({ type: Boolean, attribute: 'add-close-button' }) addCloseButton = false;\n\n  /**\n   * Duration for the open and close animation in milliseconds.\n   */\n  private static openAndCloseAnimationDuration__ = 200; // ms\n\n  protected override firstUpdated(changedProperties: PropertyValues): void {\n    super.firstUpdated(changedProperties);\n\n    // wait for render complete, then open the snackbar to start the opening animation\n    waitForNextFrame().then(() => {\n      this.setAttribute('open', '');\n    });\n  }\n\n  /**\n   * Close the snackbar and remove it from the DOM.\n   * Waits for the closing animation to end before removing the element.\n   *\n   * @internal\n   * This method should be used by the package API, not directly, to ensure proper signal unsubscription.\n   */\n  async close(): Promise<void> {\n    this.logger_.logMethod?.('close');\n\n    this.removeAttribute('open');\n\n    await delay.by(SnackbarElement.openAndCloseAnimationDuration__);\n    this.remove();\n  }\n\n  /**\n   * Handle the close button click event.\n   * Sends a signal when the action button is clicked.\n   */\n  private closeButtonClickHandler__(): void {\n    this.logger_.logMethod?.('closeButtonClickHandler__');\n\n    snackbarCloseButtonClickedSignal.notify();\n  }\n\n  /**\n   * Handle the action button click event.\n   * Sends a signal when the action button is clicked.\n   */\n  private actionButtonClickHandler__(): void {\n    this.logger_.logMethod?.('actionButtonClickHandler__');\n\n    snackbarActionButtonClickedSignal.notify();\n  }\n\n  /**\n   * Render the snackbar component.\n   */\n  protected override render(): unknown {\n    super.render();\n\n    const actionButtonHtml = this.renderActionButton__();\n    const closeButtonHtml = this.renderCloseButton__();\n\n    let actionButtonHandler: TemplateResult | typeof nothing = nothing;\n    if (actionButtonHtml != nothing || closeButtonHtml != nothing) {\n      actionButtonHandler = html`<div>${actionButtonHtml} ${closeButtonHtml}</div>`;\n    }\n\n    return [ html`<span>${this.content}</span>`, actionButtonHandler ];\n  }\n\n  /**\n   * Render the action button.\n   */\n  private renderActionButton__(): TemplateResult | typeof nothing {\n    if (this.actionButtonLabel == null) return nothing;\n    this.logger_.logMethodArgs?.('renderActionButton__', { actionLabel: this.actionButtonLabel });\n\n    return html` <button class=\"action-button\" @click=${this.actionButtonClickHandler__.bind(this)}>${this.actionButtonLabel}</button> `;\n  }\n\n  /**\n   * Render the close button.\n   */\n  private renderCloseButton__(): TemplateResult | typeof nothing {\n    if (!this.addCloseButton) return nothing;\n    this.logger_.logMethod?.('renderCloseButton__');\n\n    return html`\n      <button class=\"close-button\" @click=${this.closeButtonClickHandler__.bind(this)}>\n        <span class=\"icon\">close</span>\n      </button>\n    `;\n  }\n}\n", "import { delay } from '@alwatr/delay';\n\n/**\n * Waits for the next frame to ensure the DOM has been fully calculated.\n * This minimizes the chance that querying the DOM will cause a costly reflow.\n *\n * This function uses `requestAnimationFrame` to schedule code to run immediately before the repaint,\n * followed by `setTimeout` with a delay of 0 to execute code as soon as possible after the repaint.\n *\n * @see https://stackoverflow.com/a/47184426\n */\nexport function waitForNextFrame(): Promise<void> {\n  return new Promise((resolve) => {\n    delay.untilNextAnimationFrame().then(() => {\n      delay.immediate().then(resolve);\n    });\n  });\n}\n"],
  "mappings": ";;;;;;;;;;;;;AAAA,SAAS,qBAAqB;;;ACA9B,SAAS,aAAa;AACtB,SAAS,oBAAoB;AAC7B,OAAO,cAAc;;;ACFrB,SAAS,cAAc,qBAAqB;AAOrC,IAAM,oCAAoD,oBAAI,cAAc;AAAA,EACjF,MAAM;AACR,CAAC;AAKM,IAAM,mCAAmD,oBAAI,cAAc;AAAA,EAChF,MAAM;AACR,CAAC;AAoBM,IAAM,iBAAiC,oBAAI,aAA8B,EAAE,MAAM,WAAW,CAAC;;;AD3BpG,IAAM,SAAS,aAAa,iBAAgB;AAK5C,IAAI,oBAAuD;AAK3D,IAAI,iCAAsD;AAK1D,IAAI,gCAAqD;AAQzD,SAAS,sBAAsB,SAA2C;AACxE,QAAM,UAAU,SAAS,cAAc,WAAW;AAClD,UAAQ,aAAa,WAAW,QAAQ,OAAO;AAE/C,MAAI,QAAQ,mBAAmB,MAAM;AACnC,YAAQ,aAAa,oBAAoB,EAAE;AAAA,EAC7C;AAEA,MAAI,QAAQ,UAAU,MAAM;AAC1B,YAAQ,aAAa,uBAAuB,QAAQ,OAAO,KAAK;AAAA,EAClE;AAEA,SAAO;AACT;AAQA,SAAS,wBAAwB,eAAoC,SAAgD;AACnH,SAAO,YAAY,yBAAyB;AAG5C,GAAC,YAAY;AACX,QAAI;AACF,YAAM,QAAS;AAAA,IACjB,SACO,OAAO;AACZ,aAAO,MAAM,2BAA2B,uBAAuB,KAAK;AAAA,IACtE;AAAA,EACF,GAAG;AAEH,SAAO,cAAc;AACvB;AAOA,eAAe,aAAa,SAAyC;AACnE,SAAO,gBAAgB,gBAAgB,EAAE,QAAQ,CAAC;AAGlD,UAAQ,aAAR,QAAQ,WAAa;AAErB,QAAM,UAAU,sBAAsB,OAAO;AAE7C,MAAI,SAAS;AACb,QAAM,gBAAgB,YAAY;AAChC,QAAI,OAAQ;AACZ,WAAO,gBAAgB,iBAAiB,EAAE,QAAQ,CAAC;AAEnD,UAAM,QAAQ,MAAM;AACpB,qCAAiC;AACjC,oCAAgC;AAEhC,aAAS;AAAA,EACX;AAEA,QAAM,oBAAoB;AAC1B,sBAAoB;AAEpB,MAAI,QAAQ,UAAU,MAAM;AAM1B,qCAAiC,kCAAkC;AAAA,MACjE,wBAAwB,KAAK,MAAM,eAAe,QAAQ,OAAO,OAAO;AAAA,IAC1E,EAAE;AAAA,EACJ;AAEA,MAAI,QAAQ,mBAAmB,MAAM;AAEnC,oCAAgC,iCAAiC,UAAU,cAAc,KAAK,IAAI,CAAC,EAAE;AAAA,EACvG;AAGA,WAAS,KAAK,YAAY,OAAO;AAGjC,MAAI,QAAQ,aAAa,YAAY;AACnC,UAAM,GAAG,QAAQ,QAAQ,EAAE,KAAK,aAAa;AAAA,EAC/C;AACF;AAGA,IAAM,wBAAwB,SAAS,CAAC,YAA6B;AACnE,eAAa,OAAO;AACtB,GAAG,EAAE;AAEL,eAAe,UAAU,CAAC,YAAY;AACpC,wBAAsB,OAAO;AAC/B,CAAC;;;AEjID,SAAS,SAAAA,cAAa;AACtB,SAAS,eAAe,mBAAmB;AAC3C,SAAS,MAAM,YAAY,eAAyD;AACpF,SAAS,eAAe,gBAAgB;;;ACHxC,SAAS,SAAAC,cAAa;AAWf,SAAS,mBAAkC;AAChD,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,IAAAA,OAAM,wBAAwB,EAAE,KAAK,MAAM;AACzC,MAAAA,OAAM,UAAU,EAAE,KAAK,OAAO;AAAA,IAChC,CAAC;AAAA,EACH,CAAC;AACH;;;ADFO,IAAM,kBAAN,cAA8B,cAAc,YAAY,UAAU,CAAC,EAAE;AAAA,EAArE;AAAA;AAIuB,mBAAU;AAKwB,6BAAmC;AAKrC,0BAAiB;AAAA;AAAA;AAAA,EAO1D,aAAa,mBAAyC;AACvE,UAAM,aAAa,iBAAiB;AAGpC,qBAAiB,EAAE,KAAK,MAAM;AAC5B,WAAK,aAAa,QAAQ,EAAE;AAAA,IAC9B,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,QAAuB;AAC3B,SAAK,QAAQ,YAAY,OAAO;AAEhC,SAAK,gBAAgB,MAAM;AAE3B,UAAMC,OAAM,GAAG,gBAAgB,+BAA+B;AAC9D,SAAK,OAAO;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,4BAAkC;AACxC,SAAK,QAAQ,YAAY,2BAA2B;AAEpD,qCAAiC,OAAO;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,6BAAmC;AACzC,SAAK,QAAQ,YAAY,4BAA4B;AAErD,sCAAkC,OAAO;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA,EAKmB,SAAkB;AACnC,UAAM,OAAO;AAEb,UAAM,mBAAmB,KAAK,qBAAqB;AACnD,UAAM,kBAAkB,KAAK,oBAAoB;AAEjD,QAAI,sBAAuD;AAC3D,QAAI,oBAAoB,WAAW,mBAAmB,SAAS;AAC7D,4BAAsB,YAAY,gBAAgB,IAAI,eAAe;AAAA,IACvE;AAEA,WAAO,CAAE,aAAa,KAAK,OAAO,WAAW,mBAAoB;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA,EAKQ,uBAAwD;AAC9D,QAAI,KAAK,qBAAqB,KAAM,QAAO;AAC3C,SAAK,QAAQ,gBAAgB,wBAAwB,EAAE,aAAa,KAAK,kBAAkB,CAAC;AAE5F,WAAO,6CAA6C,KAAK,2BAA2B,KAAK,IAAI,CAAC,IAAI,KAAK,iBAAiB;AAAA,EAC1H;AAAA;AAAA;AAAA;AAAA,EAKQ,sBAAuD;AAC7D,QAAI,CAAC,KAAK,eAAgB,QAAO;AACjC,SAAK,QAAQ,YAAY,qBAAqB;AAE9C,WAAO;AAAA,4CACiC,KAAK,0BAA0B,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,EAInF;AACF;AAAA;AAAA;AAAA;AA1Ga,gBAmBI,kCAAkC;AAfrB;AAAA,EAA3B,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAJf,gBAIiB;AAKkC;AAAA,EAA7D,SAAS,EAAE,MAAM,QAAQ,WAAW,sBAAsB,CAAC;AAAA,GATjD,gBASmD;AAKF;AAAA,EAA3D,SAAS,EAAE,MAAM,SAAS,WAAW,mBAAmB,CAAC;AAAA,GAd/C,gBAciD;AAdjD,kBAAN;AAAA,EADN,cAAc,WAAW;AAAA,GACb;;;AHbb,aAAc,eAAc,IAAI,mBAAkB,OAAmB;",
  "names": ["delay", "delay", "delay"]
}
