{"mappings":"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","sources":["packages/@react-spectrum/ai/src/loader/react.tsx"],"sourcesContent":["/*\n * Copyright 2026 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n// React pixel-fall loader. Renders plain HTML divs and lets the browser\n// drive the animation natively via generated CSS @keyframes. Multi-icon\n// sequences (presets) play one icon per 2.4s cycle and\n// advance via a single timer — only the current icon's cells are in the\n// DOM. A single-icon loader stays a pure infinite CSS loop with no JS.\n\nimport {aiLogo, type Cell} from './data';\nimport * as React from 'react';\n\n// Easing control points, formatted into `cubic-bezier(...)` in the\n// generated keyframes. `fade` is intentionally linear — its control\n// points lie on y=x.\nconst EASE = {\n  drop: [0.333, 0, 0.667, 1],\n  recover: [0.333, 0, 0.833, 1],\n  exit: [0.563, 0, 0.906, 0.757],\n  fade: [0.167, 0.167, 0.833, 0.833]\n};\n\n// One full cycle is 72 frames at 30fps (2.4s).\nconst TOTAL_FRAMES = 72;\nconst FPS = 30;\nconst DURATION_MS = (TOTAL_FRAMES / FPS) * 1000;\n\n// Per-cell vertical offsets in the 24-unit space: start off\n// the top, overshoot just past the settled position, exit off the bottom.\nconst Y_START = -26;\nconst Y_OVERSHOOT = 1;\nconst Y_EXIT = 26;\n\n// The animation lives in a fixed VIEWBOX-sized coordinate space that is scaled down to the\n// rendered `size`. Cells are absolutely positioned in this space, so all\n// the translateY offsets below are in these units — identical to the old\n// SVG viewBox math, just on HTML elements the compositor can accelerate.\nconst VIEWBOX = 480;\nconst CELL = VIEWBOX / 12;\n\n// ─────────────────────────────────────────────────────────────\n// CSS @keyframes generation. Each piecewise segment of the motion\n// becomes one keyframe stop whose `animation-timing-function` is the\n// matching cubic-bezier (from EASE), so the browser interpolates the\n// drop/recover/exit/fade curves natively.\n// ─────────────────────────────────────────────────────────────\n\nfunction pct(frame) {\n  // Frame → keyframe offset percentage, trimmed of noise.\n  return `${+((frame / TOTAL_FRAMES) * 100).toFixed(4)}%`;\n}\n\nfunction cb(coeffs) {\n  return `cubic-bezier(${coeffs.join(',')})`;\n}\n\n// stops: ordered [{f, decl, ease}]. `decl` is the CSS declarations for\n// that stop; `ease` (optional) is the timing function for the segment\n// starting at it. Stops sharing a frame are de-duped (first wins).\ntype Stop = {f: number; decl: string; ease?: readonly number[] | null};\n\nfunction emitKeyframes(name: string, stops: Stop[]) {\n  let body = '';\n  let lastPct: string | null = null;\n  for (const s of stops) {\n    const p = pct(s.f);\n    if (p === lastPct) continue;\n    lastPct = p;\n    const ease = s.ease ? `animation-timing-function:${cb(s.ease)};` : '';\n    body += `${p}{${s.decl}${ease}}`;\n  }\n  return `@keyframes ${name}{${body}}`;\n}\n\nconst ty = v => `transform:translateY(${v}px);`;\nconst op = v => `opacity:${v};`;\n\nfunction cellYKeyframes(name, c) {\n  const s = c.stagger;\n  const e = c.exitStart;\n  const stops: Stop[] = [{f: 0, decl: ty(Y_START), ease: s > 0 ? null : EASE.drop}];\n  if (s > 0) {\n    stops.push({f: s, decl: ty(Y_START), ease: EASE.drop});\n  }\n  stops.push({f: s + 10, decl: ty(Y_OVERSHOOT), ease: EASE.recover});\n  stops.push({f: s + 13, decl: ty(0)}); // settled — hold until exit\n  stops.push({f: e, decl: ty(0), ease: EASE.exit});\n  stops.push({f: e + 12, decl: ty(Y_EXIT)});\n  stops.push({f: TOTAL_FRAMES, decl: ty(Y_EXIT)}); // hold offscreen until wrap\n  return emitKeyframes(name, stops);\n}\n\nfunction cellOpacityKeyframes(name, c) {\n  const [fi0, fi1] = c.fadeIn;\n  const [fo0, fo1] = c.fadeOut;\n  return emitKeyframes(name, [\n    {f: 0, decl: op(0)},\n    {f: fi0, decl: op(0), ease: EASE.fade},\n    {f: fi1, decl: op(1)},\n    {f: fo0, decl: op(1), ease: EASE.fade},\n    {f: fo1, decl: op(0)},\n    {f: TOTAL_FRAMES, decl: op(0)}\n  ]);\n}\n\n// Stable per-icon id, keyed by the cell-array reference (icons are\n// module-level consts, so the reference is stable). Used to namespace\n// each icon's @keyframes and to cache its generated CSS.\nlet nextIconId = 0;\nconst iconIds = new WeakMap<object, string>();\nfunction iconId(cells: object): string {\n  let id = iconIds.get(cells);\n  if (id === undefined) {\n    id = `pl${nextIconId++}`;\n    iconIds.set(cells, id);\n  }\n  return id;\n}\n\nconst cssCache = new WeakMap<object, string>();\nfunction keyframesFor(cells: Cell[]): string {\n  let css = cssCache.get(cells);\n  if (css === undefined) {\n    const id = iconId(cells);\n    css = cells\n      .map((c, i) => cellYKeyframes(`${id}-${i}-y`, c) + cellOpacityKeyframes(`${id}-${i}-o`, c))\n      .join('');\n    cssCache.set(cells, css);\n  }\n  return css;\n}\n\nexport interface PixelLoaderProps {\n  /**\n   * Size of the loader in pixels. Multiples of 7 render evenly on the pixel grid.\n   */\n  size?: number;\n  /**\n   * Whether the animation is playing.\n   */\n  isPlaying?: boolean;\n  /**\n   * The icon or sequence of icons to display. These should be imported from\n   * '@react-spectrum/ai/loader'.\n   */\n  icon?: Cell[] | Cell[][];\n  /**\n   * The color of the icon.\n   *\n   * @default 'currentColor'\n   */\n  color?: string;\n  /**\n   * A custom CSS class to apply.\n   */\n  className?: string;\n}\n\nexport function PixelLoader(props: PixelLoaderProps) {\n  const {\n    size = 21,\n    isPlaying = true,\n    icon = aiLogo,\n    color = 'currentColor',\n    className,\n    ...rest\n  } = props;\n\n  // Normalize to a sequence.\n  const sequence = React.useMemo(\n    () => (Array.isArray(icon[0]) ? icon : [icon]) as Cell[][],\n    [icon]\n  );\n  const isSequence = sequence.length > 1;\n  const duration = DURATION_MS;\n\n  // `tick` increments once per cycle; the current icon is `tick % len`.\n  const [tick, setTick] = React.useState(0);\n\n  // Restart from the first icon whenever the sequence changes.\n  let [lastSequence, setLastSequence] = React.useState(sequence);\n  if (lastSequence !== sequence) {\n    setLastSequence(sequence);\n    setTick(0);\n  }\n\n  // Advance the sequence one icon per cycle while playing. Single-icon\n  // loaders never start a timer — they're a pure infinite CSS loop.\n  React.useEffect(() => {\n    if (!isPlaying || !isSequence) {\n      return undefined;\n    }\n    const id = setInterval(() => setTick(t => t + 1), duration);\n    return () => clearInterval(id);\n  }, [isPlaying, isSequence, duration, sequence]);\n\n  const cells = sequence[isSequence ? tick % sequence.length : 0];\n  const animId = iconId(cells);\n  const css = keyframesFor(cells);\n  // Sequences play each icon once and hold its faded-out final frame\n  // (`forwards`) until the next remount; a single icon loops forever.\n  const iteration = isSequence ? '1 forwards' : 'infinite';\n\n  const cellSize = size / 7;\n  const offset = (size - cellSize * 7) / 2;\n  const matrix = Array.from({length: 7}, () => Array.from({length: 7}, () => false));\n  for (let c of cells) {\n    let x = (c.cx - 120) / CELL;\n    let y = (c.cy - 120) / CELL;\n    matrix[y][x] = true;\n  }\n\n  const isHighDPI = window.devicePixelRatio >= 2;\n\n  return (\n    <div\n      aria-hidden=\"true\"\n      className={className}\n      style={{\n        display: 'inline-block',\n        width: size,\n        height: size,\n        lineHeight: 0,\n        position: 'relative'\n      }}\n      {...rest}>\n      {isPlaying ? <style>{css}</style> : null}\n      {cells.map((c, i) => {\n        let x = (c.cx - 120) / CELL;\n        let y = (c.cy - 120) / CELL;\n\n        // Convex-corner rounding: round a corner only when both orthogonal neighbors toward it are absent.\n        let left = matrix[y][x - 1];\n        let right = matrix[y][x + 1];\n        let top = matrix[y - 1]?.[x];\n        let bottom = matrix[y + 1]?.[x];\n        let corner = (a, b) => (!a && !b ? '1px' : '0px');\n\n        // Adjust position for outer cells on high DPI displays.\n        let xPx = x * cellSize + offset;\n        let yPx = y * cellSize + offset;\n        if (isHighDPI && c.outer && xPx > size / 2) {\n          xPx -= 0.5;\n        }\n        if (isHighDPI && c.outer && yPx > size / 2) {\n          yPx -= 0.5;\n        }\n\n        return (\n          <div\n            key={i}\n            style={{\n              position: 'absolute',\n              left: xPx,\n              top: yPx,\n              width: cellSize + (isHighDPI && c.outer ? 0.5 : 0),\n              height: cellSize + (isHighDPI && c.outer ? 0.5 : 0),\n              borderRadius: `${corner(left, top)} ${corner(right, top)} ${corner(right, bottom)} ${corner(left, bottom)}`,\n              backgroundColor: color,\n              ...(isPlaying && {\n                animation:\n                  `${animId}-${i}-y ${duration}ms linear ${iteration}, ` +\n                  `${animId}-${i}-o ${duration}ms linear ${iteration}`,\n                willChange: 'transform, opacity'\n              })\n            }}\n          />\n        );\n      })}\n    </div>\n  );\n}\n"],"names":[],"version":3,"file":"react.mjs.map"}