{"version":3,"sources":["../src/react-plotly.js","../src/factory.js","../src/events.js"],"sourcesContent":["import plotComponentFactory from './factory';\nimport Plotly from 'plotly.js/dist/plotly';\n\nconst PlotComponent = plotComponentFactory(Plotly);\n\nexport default PlotComponent;\n","import React, {forwardRef, useCallback, useEffect, useRef} from 'react';\n\nimport {eventNames, getPlotlyEventName, getPropName, updateEvents} from './events.js';\n\n// Check if a window is available since SSR (server-side rendering)\n// breaks unnecessarily if you try to use it server-side.\nconst isBrowser = typeof window !== 'undefined';\n\n// Module-level frozen defaults so identity stays stable across renders when a\n// consumer omits the prop. Without this, the `===` checks in the update\n// effect would always see \"changed\" and trigger a needless Plotly.react.\nconst DEFAULT_DATA = Object.freeze([]);\nconst DEFAULT_STYLE = Object.freeze({position: 'relative', display: 'inline-block'});\n\nexport default function plotComponentFactory(Plotly) {\n  return forwardRef(function PlotlyComponent(\n    {\n      data = DEFAULT_DATA,\n      layout,\n      config,\n      frames,\n      revision,\n      onInitialized,\n      onUpdate,\n      onPurge,\n      onError,\n      debug = false,\n      style = DEFAULT_STYLE,\n      className,\n      useResizeHandler = false,\n      divId,\n      ...eventProps\n    },\n    forwardedRef\n  ) {\n    const elRef = useRef(null);\n    const promiseRef = useRef(Promise.resolve());\n    const handlersRef = useRef({});\n    const resizeHandlerRef = useRef(null);\n    const unmountingRef = useRef(false);\n    const prevRef = useRef(null);\n\n    // Refs that mirror the latest values of callbacks consumed by listeners\n    // attached during mount (which must keep stable identity across renders).\n    const onUpdateRef = useRef(onUpdate);\n    onUpdateRef.current = onUpdate;\n    const onPurgeRef = useRef(onPurge);\n    onPurgeRef.current = onPurge;\n\n    // Stable closure for plotly update events. Reads latest `onUpdate` via the\n    // ref so the listener identity stays the same across renders — we need the\n    // same function reference for both `.on(...)` and `.removeListener(...)`.\n    const handleUpdate = useRef(() => {\n      const cb = onUpdateRef.current;\n      if (typeof cb !== 'function' || !elRef.current) {\n        return;\n      }\n      const el = elRef.current;\n      const frames = el._transitionData ? el._transitionData._frames : null;\n      cb({data: el.data, layout: el.layout, frames}, el);\n    }).current;\n\n    const setRef = useCallback(\n      (el) => {\n        elRef.current = el;\n        if (typeof forwardedRef === 'function') {\n          forwardedRef(el);\n        } else if (forwardedRef) {\n          forwardedRef.current = el;\n        }\n        if (debug && isBrowser && el) {\n          window.gd = el;\n        }\n      },\n      [forwardedRef, debug]\n    );\n\n    // Mount + update effect: no deps array, so it runs after every render —\n    // mirroring the original componentDidMount + componentDidUpdate flow.\n    useEffect(() => {\n      unmountingRef.current = false;\n\n      if (prevRef.current === null) {\n        prevRef.current = {data, layout, config, frames, revision};\n        runPlotlyReact(true, onInitialized, true);\n        return;\n      }\n\n      const prev = prevRef.current;\n      const numPrev = prev.frames && prev.frames.length ? prev.frames.length : 0;\n      const numNext = frames && frames.length ? frames.length : 0;\n\n      const figureChanged = !(\n        prev.layout === layout &&\n        prev.data === data &&\n        prev.config === config &&\n        numPrev === numNext\n      );\n      const revisionWasDefined = prev.revision !== void 0;\n      const revisionChanged = prev.revision !== revision;\n\n      prevRef.current = {data, layout, config, frames, revision};\n\n      if (!figureChanged && (!revisionWasDefined || !revisionChanged)) {\n        return;\n      }\n\n      runPlotlyReact(false, onUpdate, false);\n    });\n\n    // Cleanup effect — runs on unmount only.\n    useEffect(() => {\n      const el = elRef.current;\n      return () => {\n        unmountingRef.current = true;\n        if (el) {\n          if (typeof onPurgeRef.current === 'function') {\n            const frames = el._transitionData ? el._transitionData._frames : null;\n            onPurgeRef.current({data: el.data, layout: el.layout, frames}, el);\n          }\n          if (el.removeListener) {\n            updateEvents.forEach((evt) => el.removeListener(evt, handleUpdate));\n          }\n          Plotly.purge(el);\n        }\n        if (resizeHandlerRef.current && isBrowser) {\n          window.removeEventListener('resize', resizeHandlerRef.current);\n          resizeHandlerRef.current = null;\n        }\n        // Reset refs so StrictMode's re-setup looks like a fresh mount\n        prevRef.current = null;\n        promiseRef.current = Promise.resolve();\n        handlersRef.current = {};\n      };\n    }, []);\n\n    function runPlotlyReact(shouldInvokeResize, figureCallback, shouldAttachUpdateEvents) {\n      promiseRef.current = promiseRef.current\n        .then(() => {\n          if (unmountingRef.current) {\n            return void 0;\n          }\n          if (!elRef.current) {\n            throw new Error('Missing element reference');\n          }\n          return Plotly.react(elRef.current, {data, layout, config, frames});\n        })\n        .then(() => {\n          if (unmountingRef.current) {\n            return;\n          }\n          syncWindowResize(shouldInvokeResize);\n          syncEventHandlers();\n          invokeFigureCallback(figureCallback);\n          if (shouldAttachUpdateEvents) {\n            attachUpdateEvents();\n          }\n        })\n        .catch((err) => {\n          if (typeof onError === 'function') {\n            onError(err);\n          }\n        });\n    }\n\n    function invokeFigureCallback(callback) {\n      if (typeof callback !== 'function' || !elRef.current) {\n        return;\n      }\n      const el = elRef.current;\n      const f = el._transitionData ? el._transitionData._frames : null;\n      callback({data: el.data, layout: el.layout, frames: f}, el);\n    }\n\n    function attachUpdateEvents() {\n      if (!elRef.current || !elRef.current.removeListener) {\n        return;\n      }\n      updateEvents.forEach((evt) => elRef.current.on(evt, handleUpdate));\n    }\n\n    function syncWindowResize(invoke) {\n      if (!isBrowser) {\n        return;\n      }\n      if (useResizeHandler && !resizeHandlerRef.current) {\n        resizeHandlerRef.current = () => Plotly.Plots.resize(elRef.current);\n        window.addEventListener('resize', resizeHandlerRef.current);\n        if (invoke) {\n          resizeHandlerRef.current();\n        }\n      } else if (!useResizeHandler && resizeHandlerRef.current) {\n        window.removeEventListener('resize', resizeHandlerRef.current);\n        resizeHandlerRef.current = null;\n      }\n    }\n\n    function syncEventHandlers() {\n      eventNames.forEach((eventName) => {\n        const prop = eventProps[getPropName(eventName)];\n        const handler = handlersRef.current[eventName];\n        const hasHandler = Boolean(handler);\n        if (prop && !hasHandler) {\n          addEventHandler(eventName, prop);\n        } else if (!prop && hasHandler) {\n          removeEventHandler(eventName);\n        } else if (prop && hasHandler && prop !== handler) {\n          removeEventHandler(eventName);\n          addEventHandler(eventName, prop);\n        }\n      });\n    }\n\n    function addEventHandler(eventName, prop) {\n      handlersRef.current[eventName] = prop;\n      elRef.current.on(getPlotlyEventName(eventName), prop);\n    }\n\n    function removeEventHandler(eventName) {\n      elRef.current.removeListener(getPlotlyEventName(eventName), handlersRef.current[eventName]);\n      delete handlersRef.current[eventName];\n    }\n\n    return <div id={divId} style={style} ref={setRef} className={className} />;\n  });\n}\n","// The single source of truth for the plotly.js events this wrapper forwards.\n//\n// The naming convention is:\n//   - events are attached as `'plotly_' + name.toLowerCase()`\n//   - react props are `'on' + name`\n//\n// `triggersUpdate` marks events plotly.js emits *after* changing the figure;\n// the wrapper listens to those and fires `onUpdate`. Never set it on a\n// cancelable event — that adds a second listener alongside the consumer's,\n// and plotly keeps only the last listener's return value, so a consumer's\n// `return false` could be discarded. The drill-down clicks rely on\n// `plotly_animated` instead.\n//\n// The `on*` prop types in `factory.d.ts` are maintained by hand against this list\nexport const events = [\n  {name: 'AfterExport'},\n  {name: 'AfterPlot'},\n  {name: 'Animated', triggersUpdate: true},\n  {name: 'Animating'},\n  {name: 'AnimatingFrame'},\n  {name: 'AnimationInterrupted'},\n  {name: 'AutoSize'},\n  {name: 'BeforeExport'},\n  {name: 'BeforeHover'},\n  {name: 'BeforePlot'},\n  {name: 'ButtonClicked'},\n  {name: 'Click'},\n  {name: 'ClickAnnotation'},\n  {name: 'Deselect'},\n  {name: 'DoubleClick', triggersUpdate: true},\n  {name: 'Framework'},\n  {name: 'Hover'},\n  {name: 'IcicleClick'},\n  {name: 'LegendClick'},\n  {name: 'LegendDoubleClick'},\n  {name: 'LegendTitleClick'},\n  {name: 'LegendTitleDoubleClick'},\n  {name: 'Relayout', triggersUpdate: true},\n  {name: 'Relayouting', triggersUpdate: true},\n  {name: 'Restyle', triggersUpdate: true},\n  {name: 'Redraw', triggersUpdate: true},\n  {name: 'Selected'},\n  {name: 'Selecting'},\n  {name: 'SliderChange'},\n  {name: 'SliderEnd'},\n  {name: 'SliderStart'},\n  {name: 'SunburstClick'},\n  {name: 'Transitioned'},\n  {name: 'Transitioning'},\n  {name: 'TransitionInterrupted'},\n  {name: 'TreemapClick'},\n  {name: 'Unhover'},\n  {name: 'WebGlContextLost'},\n];\n\n/** The plotly.js event name a given entry is attached as. */\nexport function getPlotlyEventName(eventName) {\n  return 'plotly_' + eventName.toLowerCase();\n}\n\n/** The React prop name a given entry is read from. */\nexport function getPropName(eventName) {\n  return 'on' + eventName;\n}\n\nexport const eventNames = events.map((event) => event.name);\n\nexport const updateEvents = events\n  .filter((event) => event.triggersUpdate)\n  .map((event) => getPlotlyEventName(event.name));\n"],"mappings":"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","names":["Plotly","frames","React","Plotly"]}