{"version":3,"file":"LiveRegion.mjs","sources":["../../../src/common/liveRegion/LiveRegion.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\nimport type { HTMLAttributes, ReactNode } from 'react';\n\nimport { WDS_LIVE_REGION_DELAY_MS } from '../constants';\n\nexport type AriaLive = 'off' | 'polite' | 'assertive';\n\ntype LivePoliteness = Exclude<AriaLive, 'off'>;\n\nconst LIVE_REGION_ROLE_BY_POLITENESS: Record<LivePoliteness, 'status' | 'alert'> = {\n  assertive: 'alert',\n  polite: 'status',\n};\n\nlet nextPoliteAnnouncementAt = 0;\nlet nextAssertiveAnnouncementAt = 0;\n\nconst getNextAnnouncementAt = (politeness: LivePoliteness): number => {\n  if (politeness === 'polite') {\n    return nextPoliteAnnouncementAt;\n  }\n\n  return nextAssertiveAnnouncementAt;\n};\n\nconst setNextAnnouncementAt = (politeness: LivePoliteness, value: number): void => {\n  if (politeness === 'polite') {\n    nextPoliteAnnouncementAt = value;\n    return;\n  }\n\n  nextAssertiveAnnouncementAt = value;\n};\n\nexport const resetLiveRegionAnnouncementQueue = (): void => {\n  nextPoliteAnnouncementAt = 0;\n  nextAssertiveAnnouncementAt = 0;\n};\n\nconst calcAnnouncementDelayMs = (politeness: LivePoliteness, now: number): number => {\n  return Math.max(now + WDS_LIVE_REGION_DELAY_MS, getNextAnnouncementAt(politeness)) - now;\n};\n\nconst scheduleAnnouncement = (politeness: LivePoliteness): number => {\n  const now = Date.now();\n  const delayMs = calcAnnouncementDelayMs(politeness, now);\n  setNextAnnouncementAt(politeness, now + delayMs + WDS_LIVE_REGION_DELAY_MS);\n  return delayMs;\n};\n\nexport interface LiveRegionProps extends Omit<\n  HTMLAttributes<HTMLDivElement>,\n  'role' | 'aria-live' | 'aria-atomic'\n> {\n  /**\n   * Determines urgency: 'assertive' interrupts, 'polite' waits for idle, 'off' disables live region.\n   */\n  'aria-live': AriaLive;\n  /** Optional stable key that triggers a new announcement when it changes. */\n  announceOnChange?: string | number;\n  /** Test ID for testing tools */\n  'data-testid'?: string;\n  children?: ReactNode;\n}\n\n/**\n * Renders an ARIA live region with the correct implicit role.\n *\n * - `aria-live=\"polite\"` → `role=\"status\"`\n * - `aria-live=\"assertive\"` → `role=\"alert\"`\n * - `aria-live=\"off\"` → no live region (renders children unwrapped)\n *\n * The `role` prop is intentionally excluded from the public API\n * to prevent mismatches between `aria-live` and `role`.\n */\nexport const LiveRegion = ({\n  'aria-live': ariaLive,\n  announceOnChange,\n  children,\n  className,\n  ...props\n}: LiveRegionProps) => {\n  const [shouldAnnounce, setShouldAnnounce] = useState(false);\n  const announcementTrigger =\n    announceOnChange ??\n    (typeof children === 'string' || typeof children === 'number' ? children : undefined);\n\n  useEffect(() => {\n    setShouldAnnounce(false);\n\n    if (ariaLive === 'off') {\n      return;\n    }\n\n    const timeoutId = window.setTimeout(\n      () => setShouldAnnounce(true),\n      scheduleAnnouncement(ariaLive),\n    );\n\n    return () => window.clearTimeout(timeoutId);\n  }, [ariaLive, announcementTrigger]);\n\n  if (ariaLive === 'off') {\n    return <>{children}</>;\n  }\n\n  return (\n    <div\n      role={LIVE_REGION_ROLE_BY_POLITENESS[ariaLive]}\n      aria-live={ariaLive}\n      aria-atomic=\"true\"\n      className={`wds-LiveRegion ${className ?? ''}`}\n      {...props}\n    >\n      <div aria-hidden={shouldAnnounce ? undefined : 'true'}>{children}</div>\n    </div>\n  );\n};\n"],"names":["LIVE_REGION_ROLE_BY_POLITENESS","assertive","polite","nextPoliteAnnouncementAt","nextAssertiveAnnouncementAt","getNextAnnouncementAt","politeness","setNextAnnouncementAt","value","calcAnnouncementDelayMs","now","Math","max","WDS_LIVE_REGION_DELAY_MS","scheduleAnnouncement","Date","delayMs","LiveRegion","ariaLive","announceOnChange","children","className","props","shouldAnnounce","setShouldAnnounce","useState","announcementTrigger","undefined","useEffect","timeoutId","window","setTimeout","clearTimeout","_jsx","_Fragment","role"],"mappings":";;;;AASA,MAAMA,8BAA8B,GAA+C;AACjFC,EAAAA,SAAS,EAAE,OAAO;AAClBC,EAAAA,MAAM,EAAE;CACT;AAED,IAAIC,wBAAwB,GAAG,CAAC;AAChC,IAAIC,2BAA2B,GAAG,CAAC;AAEnC,MAAMC,qBAAqB,GAAIC,UAA0B,IAAY;EACnE,IAAIA,UAAU,KAAK,QAAQ,EAAE;AAC3B,IAAA,OAAOH,wBAAwB;AACjC,EAAA;AAEA,EAAA,OAAOC,2BAA2B;AACpC,CAAC;AAED,MAAMG,qBAAqB,GAAGA,CAACD,UAA0B,EAAEE,KAAa,KAAU;EAChF,IAAIF,UAAU,KAAK,QAAQ,EAAE;AAC3BH,IAAAA,wBAAwB,GAAGK,KAAK;AAChC,IAAA;AACF,EAAA;AAEAJ,EAAAA,2BAA2B,GAAGI,KAAK;AACrC,CAAC;AAOD,MAAMC,uBAAuB,GAAGA,CAACH,UAA0B,EAAEI,GAAW,KAAY;AAClF,EAAA,OAAOC,IAAI,CAACC,GAAG,CAACF,GAAG,GAAGG,wBAAwB,EAAER,qBAAqB,CAACC,UAAU,CAAC,CAAC,GAAGI,GAAG;AAC1F,CAAC;AAED,MAAMI,oBAAoB,GAAIR,UAA0B,IAAY;AAClE,EAAA,MAAMI,GAAG,GAAGK,IAAI,CAACL,GAAG,EAAE;AACtB,EAAA,MAAMM,OAAO,GAAGP,uBAAuB,CAACH,UAAU,EAAEI,GAAG,CAAC;EACxDH,qBAAqB,CAACD,UAAU,EAAEI,GAAG,GAAGM,OAAO,GAAGH,wBAAwB,CAAC;AAC3E,EAAA,OAAOG,OAAO;AAChB,CAAC;AAiBD;;;;;;;;;AASG;AACI,MAAMC,UAAU,GAAGA,CAAC;AACzB,EAAA,WAAW,EAAEC,QAAQ;EACrBC,gBAAgB;EAChBC,QAAQ;EACRC,SAAS;EACT,GAAGC;AAAK,CACQ,KAAI;EACpB,MAAM,CAACC,cAAc,EAAEC,iBAAiB,CAAC,GAAGC,QAAQ,CAAC,KAAK,CAAC;AAC3D,EAAA,MAAMC,mBAAmB,GACvBP,gBAAgB,KACf,OAAOC,QAAQ,KAAK,QAAQ,IAAI,OAAOA,QAAQ,KAAK,QAAQ,GAAGA,QAAQ,GAAGO,SAAS,CAAC;AAEvFC,EAAAA,SAAS,CAAC,MAAK;IACbJ,iBAAiB,CAAC,KAAK,CAAC;IAExB,IAAIN,QAAQ,KAAK,KAAK,EAAE;AACtB,MAAA;AACF,IAAA;AAEA,IAAA,MAAMW,SAAS,GAAGC,MAAM,CAACC,UAAU,CACjC,MAAMP,iBAAiB,CAAC,IAAI,CAAC,EAC7BV,oBAAoB,CAACI,QAAQ,CAAC,CAC/B;AAED,IAAA,OAAO,MAAMY,MAAM,CAACE,YAAY,CAACH,SAAS,CAAC;AAC7C,EAAA,CAAC,EAAE,CAACX,QAAQ,EAAEQ,mBAAmB,CAAC,CAAC;EAEnC,IAAIR,QAAQ,KAAK,KAAK,EAAE;IACtB,oBAAOe,GAAA,CAAAC,QAAA,EAAA;AAAAd,MAAAA,QAAA,EAAGA;AAAQ,MAAI;AACxB,EAAA;AAEA,EAAA,oBACEa,GAAA,CAAA,KAAA,EAAA;AACEE,IAAAA,IAAI,EAAEnC,8BAA8B,CAACkB,QAAQ,CAAE;AAC/C,IAAA,WAAA,EAAWA,QAAS;AACpB,IAAA,aAAA,EAAY,MAAM;AAClBG,IAAAA,SAAS,EAAE,CAAA,eAAA,EAAkBA,SAAS,IAAI,EAAE,CAAA,CAAG;AAAA,IAAA,GAC3CC,KAAK;AAAAF,IAAAA,QAAA,eAETa,GAAA,CAAA,KAAA,EAAA;AAAK,MAAA,aAAA,EAAaV,cAAc,GAAGI,SAAS,GAAG,MAAO;AAAAP,MAAAA,QAAA,EAAEA;KAAc;AACxE,GAAK,CAAC;AAEV;;;;"}