UNPKG

lightweight-charts-react-components

Version:
1 lines 80.9 kB
{"version":3,"file":"lightweight-charts-react-components.mjs","sources":["webpack://lightweight-charts-react-components/./src/chart/ChartContext.ts","webpack://lightweight-charts-react-components/./src/chart/defaultChartOptions.ts","webpack://lightweight-charts-react-components/./src/chart/useChart.ts","webpack://lightweight-charts-react-components/./src/chart/ChartComponent.tsx","webpack://lightweight-charts-react-components/./src/chart/ChartWrapper.tsx","webpack://lightweight-charts-react-components/./src/scales/TimeScaleContext.ts","webpack://lightweight-charts-react-components/./src/version.ts","webpack://lightweight-charts-react-components/./src/_shared/InternalError.ts","webpack://lightweight-charts-react-components/./src/_shared/docsBaseUrl.ts","webpack://lightweight-charts-react-components/./src/_shared/useSafeContext.ts","webpack://lightweight-charts-react-components/./src/scales/useTimeScale.ts","webpack://lightweight-charts-react-components/./src/scales/TimeScale.tsx","webpack://lightweight-charts-react-components/./src/pane/PaneContext.ts","webpack://lightweight-charts-react-components/./src/pane/usePaneContext.ts","webpack://lightweight-charts-react-components/./src/scales/usePriceScale.ts","webpack://lightweight-charts-react-components/./src/scales/PriceScale.tsx","webpack://lightweight-charts-react-components/./src/scales/useTimeScaleFitContentTrigger.ts","webpack://lightweight-charts-react-components/./src/scales/TimeScaleFitContentTrigger.tsx","webpack://lightweight-charts-react-components/./src/series/SeriesContext.ts","webpack://lightweight-charts-react-components/./src/series/useSeries.ts","webpack://lightweight-charts-react-components/./src/series/SeriesTemplate.tsx","webpack://lightweight-charts-react-components/./src/series/LineSeries.tsx","webpack://lightweight-charts-react-components/./src/series/HistogramSeries.tsx","webpack://lightweight-charts-react-components/./src/series/CandlestickSeries.tsx","webpack://lightweight-charts-react-components/./src/series/AreaSeries.tsx","webpack://lightweight-charts-react-components/./src/series/BaselineSeries.tsx","webpack://lightweight-charts-react-components/./src/series/BarSeries.tsx","webpack://lightweight-charts-react-components/./src/series/CustomSeries.tsx","webpack://lightweight-charts-react-components/./src/priceLine/usePriceLine.ts","webpack://lightweight-charts-react-components/./src/priceLine/PriceLine.tsx","webpack://lightweight-charts-react-components/./src/markers/useMarkers.ts","webpack://lightweight-charts-react-components/./src/markers/Markers.tsx","webpack://lightweight-charts-react-components/./src/watermark/useWatermark.ts","webpack://lightweight-charts-react-components/./src/watermark/Watermark.tsx","webpack://lightweight-charts-react-components/./src/primitives/useSeriesPrimitive.ts","webpack://lightweight-charts-react-components/./src/primitives/SeriesPrimitive.tsx","webpack://lightweight-charts-react-components/./src/pane/usePane.ts","webpack://lightweight-charts-react-components/./src/pane/Pane.tsx"],"sourcesContent":["import { createContext } from \"react\";\nimport { type IChartContext } from \"./types\";\n\nconst ChartContext = createContext<IChartContext | null>(null);\n\nChartContext.displayName = \"ChartContext\";\nexport { ChartContext };\n","import type { ChartOptions, DeepPartial } from \"lightweight-charts\";\n\nconst defaultChartOptions: DeepPartial<ChartOptions> = {\n addDefaultPane: false,\n};\n\nexport { defaultChartOptions };\n","import { createChart } from \"lightweight-charts\";\nimport { useLayoutEffect, useRef, useState } from \"react\";\nimport { defaultChartOptions } from \"./defaultChartOptions\";\nimport type { ChartApiRef, UseChartOptions } from \"./types\";\n\nexport const useChart = ({\n container,\n onClick,\n onCrosshairMove,\n onInit,\n options = {},\n onDblClick,\n}: UseChartOptions) => {\n const [isReady, setIsReady] = useState(false);\n\n const chartApiRef = useRef<ChartApiRef>({\n _chart: null,\n api() {\n return this._chart;\n },\n init() {\n if (this._chart === null) {\n const chart = createChart(container, {\n ...defaultChartOptions,\n ...options,\n });\n this._chart = chart;\n\n if (onInit) {\n onInit(this._chart);\n }\n }\n\n if (!isReady) {\n setIsReady(true);\n }\n\n return this._chart;\n },\n clear() {\n if (this._chart !== null) {\n setIsReady(false);\n this._chart.remove();\n this._chart = null;\n }\n },\n });\n\n useLayoutEffect(() => {\n chartApiRef.current.init();\n\n return () => {\n chartApiRef.current.clear();\n };\n }, []);\n\n useLayoutEffect(() => {\n if (!container) return;\n\n if (onClick) {\n chartApiRef.current.api()?.subscribeClick(onClick);\n }\n\n return () => {\n if (onClick) {\n chartApiRef.current.api()?.unsubscribeClick(onClick);\n }\n };\n }, [onClick]);\n\n useLayoutEffect(() => {\n if (!container) return;\n\n if (onCrosshairMove) {\n chartApiRef.current.api()?.subscribeCrosshairMove(onCrosshairMove);\n }\n\n return () => {\n if (onCrosshairMove) {\n chartApiRef.current.api()?.unsubscribeCrosshairMove(onCrosshairMove);\n }\n };\n }, [onCrosshairMove]);\n\n useLayoutEffect(() => {\n if (!container) return;\n\n if (onDblClick) {\n chartApiRef.current.api()?.subscribeDblClick(onDblClick);\n }\n\n return () => {\n if (onDblClick) {\n chartApiRef.current.api()?.unsubscribeDblClick(onDblClick);\n }\n };\n }, [onDblClick]);\n\n useLayoutEffect(() => {\n if (!container) return;\n\n chartApiRef.current.api()?.applyOptions({\n ...defaultChartOptions,\n ...options,\n });\n }, [options]);\n\n return { chartApiRef, isReady };\n};\n","import React from \"react\";\nimport { ChartContext } from \"./ChartContext\";\nimport { useChart } from \"./useChart\";\nimport type { ChartComponentProps } from \"./types\";\n\nconst ChartComponent: React.FC<ChartComponentProps> = ({\n children,\n container,\n onClick,\n onCrosshairMove,\n onInit,\n options,\n}) => {\n const {\n chartApiRef: { current: chartApiRef },\n isReady,\n } = useChart({ container, onClick, onCrosshairMove, onInit, options });\n\n return (\n <ChartContext.Provider\n value={{\n chartApiRef,\n isReady,\n }}\n >\n {children}\n </ChartContext.Provider>\n );\n};\n\nexport { ChartComponent };\n","import { forwardRef, useCallback, useState } from \"react\";\nimport React from \"react\";\nimport { ChartComponent } from \"./ChartComponent\";\nimport type { ChartProps } from \"./types\";\nimport type {\n ForwardRefExoticComponent,\n ForwardRefRenderFunction,\n RefAttributes,\n} from \"react\";\n\nconst ChartRenderFunction: ForwardRefRenderFunction<HTMLDivElement, ChartProps> = (\n { children, containerProps, ...rest },\n ref\n) => {\n const [container, setContainer] = useState<HTMLDivElement>();\n const containerRef = useCallback(\n (r: HTMLDivElement) => {\n setContainer(r);\n\n if (ref) {\n if (typeof ref === \"function\") {\n containerRef(r);\n } else {\n ref.current = r;\n }\n }\n },\n [ref]\n );\n\n return (\n <div ref={containerRef} {...containerProps}>\n {!!container && (\n <ChartComponent container={container} {...rest}>\n {children}\n </ChartComponent>\n )}\n </div>\n );\n};\n\n/**\n * Chart component that can be used to create a chart.\n *\n * @param props - The properties for the chart.\n * @param ref - The ref to access the chart API.\n * @returns A React component that renders the chart.\n * @see {@link https://ukorvl.github.io/lightweight-charts-react-components/docs/chart | Chart documentation}\n * @see {@link https://tradingview.github.io/lightweight-charts/docs/chart-types | TradingView documentation for charts}\n * @example\n * ```tsx\n * <Chart>\n * <Pane stretchFactor={2}>\n * ...\n * </Pane>\n * </Chart>\n * ```\n */\nexport const ChartWrapper: ForwardRefExoticComponent<\n ChartProps & RefAttributes<HTMLDivElement>\n> = forwardRef(ChartRenderFunction);\nChartWrapper.displayName = \"ChartWrapper\";\n","import { createContext } from \"react\";\nimport { type ITimeScaleContext } from \"./types\";\n\nconst TimeScaleContext = createContext<ITimeScaleContext | null>(null);\nTimeScaleContext.displayName = \"TimeScaleContext\";\nexport { TimeScaleContext };\n","export const version = \"1.3.0\";\n","import { version } from \"../version\";\nimport { docsBaseUrl } from \"./docsBaseUrl\";\n\ntype IBaseErrorParameters = {\n /**\n * An operational error refers to an error that occurs during normal program operation\n * due to external factors or expected failures, not due to bugs in the code itself.\n */\n isOperational?: boolean;\n /**\n * The cause of the error, if any.\n * This can be used to provide additional context or information about the error.\n */\n cause?: Error | BaseInternalError;\n /**\n * A path to the documentation that can help resolve the error.\n * This is useful for providing users with guidance on how to fix or understand the error.\n */\n docsPath?: string;\n};\n\nclass BaseInternalError extends Error {\n public isOperational: boolean;\n public override cause?: Error | BaseInternalError;\n\n constructor(\n message?: string,\n { isOperational = true, cause, docsPath }: IBaseErrorParameters = {}\n ) {\n super(message);\n\n this.name = this.constructor.name ?? \"InternalError\";\n this.isOperational = isOperational;\n this.cause = cause;\n\n this.message = `${message ?? \"An error occurred\"}`;\n\n if (docsPath) {\n this.message = `${this.message}\\n\\nDocs: see ${docsBaseUrl + docsPath}`;\n }\n\n if (version) {\n this.message = `${this.message}\\n\\nVersion: lightweight-charts-react-components@${version}`;\n }\n\n Object.setPrototypeOf(this, BaseInternalError.prototype);\n }\n}\n\nexport { BaseInternalError };\n","const docsBaseUrl = \"https://ukorvl.github.io/lightweight-charts-react-components/docs/\";\nexport { docsBaseUrl };\n","import { type Context, useContext } from \"react\";\nimport { BaseInternalError } from \"./InternalError\";\n\nconst useSafeContext = <T>(context: Context<T>, errorMessage?: string) => {\n const currentContextValue = useContext(context);\n\n if (!currentContextValue) {\n const ctxName = context.name ?? context.displayName ?? \"Context\";\n throw new BaseInternalError(errorMessage ?? `${ctxName} not found.`, {\n isOperational: true,\n });\n }\n\n return currentContextValue;\n};\n\nexport { useSafeContext };\n","import { useLayoutEffect, useRef, useState } from \"react\";\nimport { useSafeContext } from \"@/_shared/useSafeContext\";\nimport { ChartContext } from \"@/chart/ChartContext\";\nimport type { TimeScaleApiRef, TimeScaleProps } from \"./types\";\n\nexport const useTimeScale = ({\n onVisibleTimeRangeChange,\n onVisibleLogicalRangeChange,\n onSizeChange,\n visibleRange,\n visibleLogicalRange,\n options = {},\n}: Omit<TimeScaleProps, \"children\">) => {\n const { isReady: chartIsReady, chartApiRef: chart } = useSafeContext(ChartContext);\n const [isReady, setIsReady] = useState(false);\n\n const timeScaleApiRef = useRef<TimeScaleApiRef>({\n _timeScale: null,\n api() {\n return this._timeScale;\n },\n init() {\n if (this._timeScale) {\n return this._timeScale;\n }\n\n const chartApi = chart?.api();\n\n if (!chartApi) {\n return null;\n }\n\n this._timeScale = chartApi.timeScale();\n\n this._timeScale.applyOptions(options);\n\n if (visibleRange) {\n this._timeScale.setVisibleRange(visibleRange);\n }\n\n if (visibleLogicalRange) {\n this._timeScale.setVisibleLogicalRange(visibleLogicalRange);\n }\n\n if (onVisibleTimeRangeChange) {\n this._timeScale.subscribeVisibleTimeRangeChange(onVisibleTimeRangeChange);\n }\n\n if (onVisibleLogicalRangeChange) {\n this._timeScale.subscribeVisibleLogicalRangeChange(onVisibleLogicalRangeChange);\n }\n\n if (onSizeChange) {\n this._timeScale.subscribeSizeChange(onSizeChange);\n }\n\n setIsReady(true);\n\n return this._timeScale;\n },\n clear() {\n this._timeScale = null;\n setIsReady(false);\n },\n });\n\n useLayoutEffect(() => {\n if (!chartIsReady) return;\n\n timeScaleApiRef.current.init();\n }, [chartIsReady]);\n\n useLayoutEffect(() => {\n return () => {\n timeScaleApiRef.current.clear();\n };\n }, []);\n\n useLayoutEffect(() => {\n if (!chart) return;\n\n if (options) {\n timeScaleApiRef.current?.api()?.applyOptions(options);\n }\n }, [options]);\n\n useLayoutEffect(() => {\n if (!chart) return;\n\n if (onSizeChange) {\n timeScaleApiRef.current?.api()?.subscribeSizeChange(onSizeChange);\n }\n\n return () => {\n if (onSizeChange) {\n timeScaleApiRef.current?.api()?.unsubscribeSizeChange(onSizeChange);\n }\n };\n }, [onSizeChange]);\n\n useLayoutEffect(() => {\n if (!chart) return;\n\n if (onVisibleLogicalRangeChange) {\n timeScaleApiRef.current\n ?.api()\n ?.subscribeVisibleLogicalRangeChange(onVisibleLogicalRangeChange);\n }\n\n return () => {\n if (onVisibleLogicalRangeChange) {\n timeScaleApiRef.current\n ?.api()\n ?.unsubscribeVisibleLogicalRangeChange(onVisibleLogicalRangeChange);\n }\n };\n }, [onVisibleLogicalRangeChange]);\n\n useLayoutEffect(() => {\n if (!chart) return;\n\n if (onVisibleTimeRangeChange) {\n timeScaleApiRef.current\n ?.api()\n ?.subscribeVisibleTimeRangeChange(onVisibleTimeRangeChange);\n }\n\n return () => {\n if (onVisibleTimeRangeChange) {\n timeScaleApiRef.current\n ?.api()\n ?.unsubscribeVisibleTimeRangeChange(onVisibleTimeRangeChange);\n }\n };\n }, [onVisibleTimeRangeChange]);\n\n useLayoutEffect(() => {\n if (!chart) return;\n\n if (visibleRange) {\n timeScaleApiRef.current?.api()?.setVisibleRange(visibleRange);\n }\n }, [visibleRange]);\n\n useLayoutEffect(() => {\n if (!chart) return;\n\n if (visibleLogicalRange) {\n timeScaleApiRef.current?.api()?.setVisibleLogicalRange(visibleLogicalRange);\n }\n }, [visibleLogicalRange]);\n\n return { timeScaleApiRef, isReady };\n};\n","import { forwardRef, useImperativeHandle } from \"react\";\nimport React from \"react\";\nimport { TimeScaleContext } from \"./TimeScaleContext\";\nimport { useTimeScale } from \"./useTimeScale\";\nimport type { TimeScaleApiRef, TimeScaleProps } from \"./types\";\nimport type { ForwardedRef, ForwardRefExoticComponent, JSX, RefAttributes } from \"react\";\n\nconst TimeScaleRenderFunction = (\n { children, ...props }: TimeScaleProps,\n ref: ForwardedRef<TimeScaleApiRef>\n): JSX.Element => {\n const {\n timeScaleApiRef: { current: timeScaleApiRef },\n isReady,\n } = useTimeScale(props);\n useImperativeHandle(ref, () => timeScaleApiRef, [timeScaleApiRef]);\n\n return (\n <TimeScaleContext.Provider\n value={{\n timeScaleApiRef,\n isReady,\n }}\n >\n {children}\n </TimeScaleContext.Provider>\n );\n};\n\n/**\n * TimeScale component that can be used to create/customize time scale in a chart.\n *\n * @param props - The properties for the time scale.\n * @param ref - The ref to access the time scale API.\n * @returns A React component that renders the time scale.\n * @see {@link https://ukorvl.github.io/lightweight-charts-react-components/docs/time-scale | Time Scale documentation}\n * @see {@link https://tradingview.github.io/lightweight-charts/docs/time-scale | TradingView documentation for time scale}\n * @example\n * ```tsx\n * <TimeScale visibleRange={{ from: 0, to: 100 }} onVisibleRangeChanged={() => {}} />\n * ```\n */\nexport const TimeScale: ForwardRefExoticComponent<\n TimeScaleProps & RefAttributes<TimeScaleApiRef>\n> = forwardRef(TimeScaleRenderFunction);\nTimeScale.displayName = \"TimeScale\";\n","import { createContext } from \"react\";\nimport { type IPaneContext } from \"./types\";\n\nconst PaneContext = createContext<IPaneContext | null>(null);\n\nPaneContext.displayName = \"PaneContext\";\nexport { PaneContext };\n","import { useContext } from \"react\";\nimport { PaneContext } from \"./PaneContext\";\n\nconst usePaneContext = () => {\n const paneContext = useContext(PaneContext);\n\n const isInsidePane = !!paneContext;\n const isPaneReady = !!paneContext?.isReady;\n const paneApiRef = paneContext?.paneApiRef;\n\n return { isInsidePane, isPaneReady, paneApiRef };\n};\n\nexport { usePaneContext };\n","import { useLayoutEffect, useRef } from \"react\";\nimport { BaseInternalError } from \"@/_shared/InternalError\";\nimport { useSafeContext } from \"@/_shared/useSafeContext\";\nimport { ChartContext } from \"@/chart/ChartContext\";\nimport { usePaneContext } from \"@/pane/usePaneContext\";\nimport type { PriceScaleProps, PriceScaleApiRef } from \"./types\";\n\nexport const usePriceScale = ({ options = {}, id }: PriceScaleProps) => {\n const { isReady: chartIsReady, chartApiRef: chart } = useSafeContext(ChartContext);\n const { isInsidePane, isPaneReady } = usePaneContext();\n\n const priceScaleApiRef = useRef<PriceScaleApiRef>({\n _priceScale: null,\n api() {\n return this._priceScale;\n },\n init() {\n if (!this._priceScale) {\n const chartApi = chart?.api();\n\n if (!chartApi) {\n return null;\n }\n\n this._priceScale = chartApi.priceScale(id);\n\n this._priceScale.applyOptions(options);\n }\n\n return this._priceScale;\n },\n setId(idToSet) {\n if (this._priceScale === null || chart === null) {\n return;\n }\n\n this._priceScale = chart.api()!.priceScale(idToSet);\n this._priceScale.applyOptions(options);\n },\n clear() {\n this._priceScale = null;\n },\n });\n\n useLayoutEffect(() => {\n if (!chartIsReady) return;\n\n if (!isInsidePane) {\n throw new BaseInternalError(\n \"PriceScale must be used inside a pane. Please ensure that the component is wrapped in a pane component.\",\n {\n isOperational: true,\n docsPath: \"\",\n }\n );\n }\n\n if (!isPaneReady) {\n return;\n }\n\n priceScaleApiRef.current.init();\n }, [chartIsReady, isInsidePane, isPaneReady]);\n\n useLayoutEffect(() => {\n return () => {\n priceScaleApiRef.current.clear();\n };\n }, []);\n\n useLayoutEffect(() => {\n if (!chart) return;\n\n priceScaleApiRef.current?.setId(id);\n }, [id]);\n\n useLayoutEffect(() => {\n if (!chart) return;\n\n if (options) {\n priceScaleApiRef.current?.api()?.applyOptions(options);\n }\n }, [options]);\n\n return priceScaleApiRef;\n};\n","import { forwardRef, useImperativeHandle } from \"react\";\nimport { usePriceScale } from \"./usePriceScale\";\nimport type { PriceScaleApiRef, PriceScaleProps } from \"./types\";\nimport type { ForwardedRef, ForwardRefExoticComponent, JSX, RefAttributes } from \"react\";\n\nconst PriceScaleRenderFunction = (\n props: PriceScaleProps,\n ref: ForwardedRef<PriceScaleApiRef>\n): JSX.Element | null => {\n const priceScaleApiRef = usePriceScale(props);\n useImperativeHandle(ref, () => priceScaleApiRef.current, [priceScaleApiRef]);\n\n return null;\n};\n\n/**\n * PriceScale component that can be used to create/customize price scale in a chart.\n *\n * @param props - The properties for the price scale.\n * @param ref - The ref to access the price scale API.\n * @returns A React component that renders the price scale.\n * @see {@link https://ukorvl.github.io/lightweight-charts-react-components/docs/price-scale | Price Scale documentation}\n * @see {@link https://tradingview.github.io/lightweight-charts/docs/price-scale | TradingView documentation for price scale}\n * @example\n * ```tsx\n * <PriceScale id=\"right\" options={{}} />\n * ```\n */\nexport const PriceScale: ForwardRefExoticComponent<\n PriceScaleProps & RefAttributes<PriceScaleApiRef>\n> = forwardRef(PriceScaleRenderFunction);\nPriceScale.displayName = \"PriceScale\";\n","import { useLayoutEffect } from \"react\";\nimport { useSafeContext } from \"@/_shared/useSafeContext\";\nimport { TimeScaleContext } from \"./TimeScaleContext\";\nimport type { TimeScaleFitContentTriggerProps } from \"./types\";\n\nconst useTimeScaleFitContentTrigger = ({ deps }: TimeScaleFitContentTriggerProps) => {\n const timeScaleContext = useSafeContext(TimeScaleContext);\n const { timeScaleApiRef, isReady } = timeScaleContext;\n\n useLayoutEffect(() => {\n if (!isReady || !timeScaleApiRef) {\n return;\n }\n\n const timeScale = timeScaleApiRef.api();\n queueMicrotask(() => {\n if (timeScale) {\n timeScale.fitContent();\n }\n });\n }, [...deps, isReady]);\n};\n\nexport { useTimeScaleFitContentTrigger };\n","import { useTimeScaleFitContentTrigger } from \"./useTimeScaleFitContentTrigger\";\nimport type { TimeScaleFitContentTriggerProps } from \"./types\";\nimport type { JSX } from \"react\";\n\n/**\n * TimeScaleFitContentTrigger component that triggers a fit content operation on the time scale.\n *\n * @param props - The properties for the time scale fit content trigger.\n * @returns A React component that triggers a fit content operation on the time scale.\n * @see {@link https://ukorvl.github.io/lightweight-charts-react-components/docs/time-scale-fit-content-trigger | Time Scale Fit Content Trigger documentation}\n * @example\n * ```tsx\n * <TimeScaleFitContentTrigger deps={[...]} />\n * ```\n */\nexport const TimeScaleFitContentTrigger = ({\n deps,\n}: TimeScaleFitContentTriggerProps): JSX.Element | null => {\n useTimeScaleFitContentTrigger({ deps });\n\n return null;\n};\n","import { createContext } from \"react\";\nimport { type ISeriesContext } from \"./types\";\n\nconst SeriesContext = createContext<ISeriesContext>({\n seriesApiRef: null,\n isReady: false,\n});\nSeriesContext.displayName = \"SeriesContext\";\nexport { SeriesContext };\n","import {\n LineSeries,\n CandlestickSeries,\n HistogramSeries,\n AreaSeries,\n BaselineSeries,\n BarSeries,\n} from \"lightweight-charts\";\nimport { useLayoutEffect, useRef, useState } from \"react\";\nimport { BaseInternalError } from \"@/_shared/InternalError\";\nimport { useSafeContext } from \"@/_shared/useSafeContext\";\nimport { ChartContext } from \"@/chart/ChartContext\";\nimport { usePaneContext } from \"@/pane/usePaneContext\";\nimport type { CustomSeriesUniqueProps, SeriesApiRef, SeriesTemplateProps } from \"./types\";\nimport type { SeriesDefinition, ISeriesApi, SeriesType } from \"lightweight-charts\";\n\ntype SeriesTypeWithoutCustom = Exclude<SeriesType, \"Custom\">;\n\nexport const useSeries = <T extends SeriesType>({\n type,\n data,\n options = {},\n reactive = true,\n seriesOrder,\n alwaysReplaceData = false,\n ...rest\n}: Omit<SeriesTemplateProps<T>, \"children\">) => {\n const { isReady: chartIsReady, chartApiRef: chart } = useSafeContext(ChartContext);\n const { isPaneReady, isInsidePane, paneApiRef } = usePaneContext();\n const [isReady, setIsReady] = useState(false);\n\n const seriesApiRef = useRef<SeriesApiRef<T>>({\n _series: null,\n api() {\n return this._series;\n },\n init() {\n if (!this._series) {\n const chartApi = chart?.api();\n\n if (!chartApi) {\n return null;\n }\n\n const paneIndex = isInsidePane ? paneApiRef?.api()?.paneIndex() : undefined;\n\n if (type === \"Custom\") {\n const plugin = (rest as CustomSeriesUniqueProps).plugin;\n if (!plugin) {\n throw new BaseInternalError(\"Custom series requires a plugin to be defined\");\n }\n\n // TODO: Fix this type cast and infer the correct type\n (this._series as unknown as ISeriesApi<\"Custom\">) = chartApi.addCustomSeries(\n plugin,\n options,\n paneIndex\n );\n } else {\n this._series = chartApi.addSeries(\n seriesMap[type as SeriesTypeWithoutCustom] as SeriesDefinition<T>,\n options,\n paneIndex\n );\n }\n\n this._series?.setData(data);\n if (seriesOrder !== undefined) {\n this._series?.setSeriesOrder(seriesOrder);\n }\n setIsReady(true);\n }\n\n return this._series;\n },\n clear() {\n if (this._series !== null) {\n chart?.api()?.removeSeries(this._series);\n this._series = null;\n setIsReady(false);\n }\n },\n });\n\n useLayoutEffect(() => {\n if (!chartIsReady) return;\n\n if (isInsidePane && !isPaneReady) {\n return;\n }\n\n seriesApiRef.current.init();\n }, [chartIsReady, isInsidePane, isPaneReady]);\n\n useLayoutEffect(() => {\n return () => {\n seriesApiRef.current.clear();\n };\n }, []);\n\n useLayoutEffect(() => {\n if (!chart) return;\n\n if (data && reactive) {\n const seriesApi = seriesApiRef.current.api();\n\n if (!seriesApi) {\n return;\n }\n\n const currentData = seriesApi.data();\n const dataLengthDifference = data.length - currentData.length;\n const maxIncrementalUpdateThreshold = 1;\n const shouldReplaceData =\n alwaysReplaceData ||\n currentData.length === 0 ||\n data.length === 0 ||\n dataLengthDifference < 0 ||\n dataLengthDifference > maxIncrementalUpdateThreshold;\n\n if (shouldReplaceData) {\n seriesApi.setData(data);\n return;\n }\n\n const lastDataPoint = { ...data[data.length - 1] };\n seriesApi.update(lastDataPoint);\n }\n }, [data, reactive, alwaysReplaceData]);\n\n useLayoutEffect(() => {\n if (!chart) return;\n\n if (options) {\n seriesApiRef.current.api()?.applyOptions(options);\n }\n }, [options]);\n\n useLayoutEffect(() => {\n if (!chart) return;\n\n if (seriesOrder !== undefined) {\n seriesApiRef.current.api()?.setSeriesOrder(seriesOrder);\n }\n }, [seriesOrder]);\n\n return { isReady, seriesApiRef };\n};\n\nconst seriesMap: Record<\n SeriesTypeWithoutCustom,\n SeriesDefinition<SeriesTypeWithoutCustom>\n> = {\n Line: LineSeries,\n Candlestick: CandlestickSeries,\n Histogram: HistogramSeries,\n Area: AreaSeries,\n Baseline: BaselineSeries,\n Bar: BarSeries,\n};\n","import { forwardRef, useImperativeHandle } from \"react\";\nimport React from \"react\";\nimport { SeriesContext } from \"./SeriesContext\";\nimport { useSeries } from \"./useSeries\";\nimport type { SeriesTemplateProps, SeriesApiRef } from \"./types\";\nimport type { SeriesType } from \"lightweight-charts\";\nimport type { ForwardedRef } from \"react\";\n\ntype GenericSeriesComponent = (<T extends SeriesType>(\n props: SeriesTemplateProps<T> & {\n ref?: ForwardedRef<SeriesApiRef<T>>;\n }\n) => ReturnType<typeof SeriesTemplateRenderFunction>) & {\n displayName: string;\n};\n\nconst SeriesTemplateRenderFunction = <T extends SeriesType>(\n { children, ...rest }: SeriesTemplateProps<T>,\n ref: ForwardedRef<SeriesApiRef<T>>\n) => {\n const {\n seriesApiRef: { current: seriesApiRef },\n isReady,\n } = useSeries(rest);\n useImperativeHandle(ref, () => seriesApiRef, [seriesApiRef]);\n\n return (\n <SeriesContext.Provider\n value={{\n seriesApiRef,\n isReady,\n }}\n >\n {children}\n </SeriesContext.Provider>\n );\n};\n\nconst SeriesTemplate = forwardRef(SeriesTemplateRenderFunction) as GenericSeriesComponent;\nSeriesTemplate.displayName = \"SeriesTemplate\";\nexport { SeriesTemplate };\n","import { forwardRef } from \"react\";\nimport React from \"react\";\nimport { SeriesTemplate } from \"./SeriesTemplate\";\nimport type { SeriesApiRef, SeriesProps } from \"./types\";\nimport type { ForwardedRef, ForwardRefExoticComponent, JSX, RefAttributes } from \"react\";\n\nconst LineSeriesRenderFunction = (\n { children, ...rest }: SeriesProps<\"Line\">,\n ref: ForwardedRef<SeriesApiRef<\"Line\">>\n): JSX.Element => {\n return (\n <SeriesTemplate type=\"Line\" ref={ref} {...rest}>\n {children}\n </SeriesTemplate>\n );\n};\n\n/**\n * LineSeries component that can be used to create a line series in a chart.\n *\n * @param props - The properties for the line series.\n * @param ref - The ref to access the line series API.\n * @returns A React component that renders the line series.\n * @see {@link https://ukorvl.github.io/lightweight-charts-react-components/docs/series | Series documentation}\n * @see {@link https://tradingview.github.io/lightweight-charts/docs/series-types#line | TradingView documentation for line series}\n * @example\n * ```tsx\n * <LineSeries\n * data={[\n * { time: '2021-01-01', value: 100 },\n * { time: '2021-01-02', value: 200 }\n * ]}\n * options={{}}\n * />\n * ```\n */\nexport const LineSeries: ForwardRefExoticComponent<\n SeriesProps<\"Line\"> & RefAttributes<SeriesApiRef<\"Line\">>\n> = forwardRef(LineSeriesRenderFunction);\nLineSeries.displayName = \"LineSeries\";\n","import { forwardRef } from \"react\";\nimport React from \"react\";\nimport { SeriesTemplate } from \"./SeriesTemplate\";\nimport type { SeriesApiRef, SeriesProps } from \"./types\";\nimport type { ForwardedRef, ForwardRefExoticComponent, JSX, RefAttributes } from \"react\";\n\nconst HistogramSeriesRenderFunction = (\n { children, ...rest }: SeriesProps<\"Histogram\">,\n ref: ForwardedRef<SeriesApiRef<\"Histogram\">>\n): JSX.Element => {\n return (\n <SeriesTemplate type=\"Histogram\" ref={ref} {...rest}>\n {children}\n </SeriesTemplate>\n );\n};\n\n/**\n * HistogramSeries component that can be used to create a histogram series in a chart.\n *\n * @param props - The properties for the histogram series.\n * @param ref - The ref to access the histogram series API.\n * @returns A React component that renders the histogram series.\n * @see {@link https://ukorvl.github.io/lightweight-charts-react-components/docs/series | Series documentation}\n * @see {@link https://tradingview.github.io/lightweight-charts/docs/series-types#histogram | TradingView documentation for histogram series}\n * @example\n * ```tsx\n * <HistogramSeries\n * data={[\n * { time: '2021-01-01', value: 100 },\n * { time: '2021-01-02', value: 200 }\n * ]}\n * options={{}}\n * />\n * ```\n */\nexport const HistogramSeries: ForwardRefExoticComponent<\n SeriesProps<\"Histogram\"> & RefAttributes<SeriesApiRef<\"Histogram\">>\n> = forwardRef(HistogramSeriesRenderFunction);\nHistogramSeries.displayName = \"HistogramSeries\";\n","import { forwardRef } from \"react\";\nimport React from \"react\";\nimport { SeriesTemplate } from \"./SeriesTemplate\";\nimport type { SeriesApiRef, SeriesProps } from \"./types\";\nimport type { ForwardedRef, ForwardRefExoticComponent, JSX, RefAttributes } from \"react\";\n\nconst CandlestickSeriesRenderFunction = (\n { children, ...rest }: SeriesProps<\"Candlestick\">,\n ref: ForwardedRef<SeriesApiRef<\"Candlestick\">>\n): JSX.Element => {\n return (\n <SeriesTemplate type=\"Candlestick\" ref={ref} {...rest}>\n {children}\n </SeriesTemplate>\n );\n};\n\n/**\n * CandlestickSeries component that can be used to create a candlestick series in a chart.\n *\n * @param props - The properties for the candlestick series.\n * @param ref - The ref to access the candlestick series API.\n * @returns A React component that renders the candlestick series.\n * @see {@link https://ukorvl.github.io/lightweight-charts-react-components/docs/series | Series documentation}\n * @see {@link https://tradingview.github.io/lightweight-charts/docs/series-types#candlestick | TradingView documentation for candlestick series}\n * @example\n * ```tsx\n * <CandlestickSeries\n * data={[\n * { time: '2021-01-01', open: 100, high: 110, low: 90, close: 105 },\n * { time: '2021-01-02', open: 105, high: 115, low: 95, close: 110 }\n * ]}\n * options={{}}\n * />\n * ```\n */\nexport const CandlestickSeries: ForwardRefExoticComponent<\n SeriesProps<\"Candlestick\"> & RefAttributes<SeriesApiRef<\"Candlestick\">>\n> = forwardRef(CandlestickSeriesRenderFunction);\nCandlestickSeries.displayName = \"CandlestickSeries\";\n","import { forwardRef } from \"react\";\nimport React from \"react\";\nimport { SeriesTemplate } from \"./SeriesTemplate\";\nimport type { SeriesApiRef, SeriesProps } from \"./types\";\nimport type { ForwardedRef, ForwardRefExoticComponent, JSX, RefAttributes } from \"react\";\n\nconst AreaSeriesRenderFunction = (\n { children, ...rest }: SeriesProps<\"Area\">,\n ref: ForwardedRef<SeriesApiRef<\"Area\">>\n): JSX.Element => {\n return (\n <SeriesTemplate type=\"Area\" ref={ref} {...rest}>\n {children}\n </SeriesTemplate>\n );\n};\n\n/**\n * AreaSeries component that can be used to create an area series in a chart.\n *\n * @param props - The properties for the area series.\n * @param ref - The ref to access the area series API.\n * @returns A React component that renders the area series.\n * @see {@link https://ukorvl.github.io/lightweight-charts-react-components/docs/series | Series documentation}\n * @see {@link https://tradingview.github.io/lightweight-charts/docs/series-types#area | TradingView documentation for area series}\n * @example\n * ```tsx\n * <AreaSeries\n * data={[\n * { time: '2021-01-01', value: 100 },\n * { time: '2021-01-02', value: 200 }\n * ]}\n * options={{}}\n * />\n * ```\n */\nexport const AreaSeries: ForwardRefExoticComponent<\n SeriesProps<\"Area\"> & RefAttributes<SeriesApiRef<\"Area\">>\n> = forwardRef(AreaSeriesRenderFunction);\nAreaSeries.displayName = \"AreaSeries\";\n","import { forwardRef } from \"react\";\nimport React from \"react\";\nimport { SeriesTemplate } from \"./SeriesTemplate\";\nimport type { SeriesApiRef, SeriesProps } from \"./types\";\nimport type { ForwardedRef, ForwardRefExoticComponent, JSX, RefAttributes } from \"react\";\n\nconst BaselineSeriesRenderFunction = (\n { children, ...rest }: SeriesProps<\"Baseline\">,\n ref: ForwardedRef<SeriesApiRef<\"Baseline\">>\n): JSX.Element => {\n return (\n <SeriesTemplate type=\"Baseline\" ref={ref} {...rest}>\n {children}\n </SeriesTemplate>\n );\n};\n\n/**\n * BaselineSeries component that can be used to create a baseline series in a chart.\n *\n * @param props - The properties for the baseline series.\n * @param ref - The ref to access the baseline series API.\n * @returns A React component that renders the baseline series.\n * @see {@link https://ukorvl.github.io/lightweight-charts-react-components/docs/series | Series documentation}\n * @see {@link https://tradingview.github.io/lightweight-charts/docs/series-types#baseline | TradingView documentation for baseline series}\n * @example\n * ```tsx\n * <BaselineSeries\n * data={[\n * { time: '2021-01-01', value: 100 },\n * { time: '2021-01-02', value: 200 }\n * ]}\n * options={{}}\n * />\n * ```\n */\nexport const BaselineSeries: ForwardRefExoticComponent<\n SeriesProps<\"Baseline\"> & RefAttributes<SeriesApiRef<\"Baseline\">>\n> = forwardRef(BaselineSeriesRenderFunction);\nBaselineSeries.displayName = \"BaselineSeries\";\n","import { forwardRef } from \"react\";\nimport React from \"react\";\nimport { SeriesTemplate } from \"./SeriesTemplate\";\nimport type { SeriesApiRef, SeriesProps } from \"./types\";\nimport type { ForwardedRef, ForwardRefExoticComponent, JSX, RefAttributes } from \"react\";\n\nconst BarSeriesRenderFunction = (\n { children, ...rest }: SeriesProps<\"Bar\">,\n ref: ForwardedRef<SeriesApiRef<\"Bar\">>\n): JSX.Element => {\n return (\n <SeriesTemplate type=\"Bar\" ref={ref} {...rest}>\n {children}\n </SeriesTemplate>\n );\n};\n\n/**\n * BarSeries component that can be used to create a bar series in a chart.\n *\n * @param props - The properties for the bar series.\n * @param ref - The ref to access the bar series API.\n * @returns A React component that renders the bar series.\n * @see {@link https://ukorvl.github.io/lightweight-charts-react-components/docs/series | Series documentation}\n * @see {@link https://tradingview.github.io/lightweight-charts/docs/series-types#bar | TradingView documentation for bar series}\n * @example\n * ```tsx\n * <BarSeries\n * data={[\n * { time: '2021-01-01', open: 100, high: 110, low: 90, close: 105 },\n * { time: '2021-01-02', open: 105, high: 115, low: 95, close: 110 }\n * ]}\n * options={{}}\n * />\n * ```\n */\nexport const BarSeries: ForwardRefExoticComponent<\n SeriesProps<\"Bar\"> & RefAttributes<SeriesApiRef<\"Bar\">>\n> = forwardRef(BarSeriesRenderFunction);\nBarSeries.displayName = \"BarSeries\";\n","import { forwardRef } from \"react\";\nimport React from \"react\";\nimport { SeriesTemplate } from \"./SeriesTemplate\";\nimport type { SeriesApiRef, SeriesProps } from \"./types\";\nimport type { ForwardedRef, ForwardRefExoticComponent, JSX, RefAttributes } from \"react\";\n\nconst CustomSeriesRenderFunction = (\n { children, ...rest }: SeriesProps<\"Custom\">,\n ref: ForwardedRef<SeriesApiRef<\"Custom\">>\n): JSX.Element => {\n return (\n <SeriesTemplate type=\"Custom\" ref={ref} {...rest}>\n {children}\n </SeriesTemplate>\n );\n};\n\n/**\n * CustomSeries component that can be used to create a custom series in a chart.\n *\n * @param props - The properties for the custom series.\n * @param ref - The ref to access the custom series API.\n * @returns A React component that renders the custom series.\n * @see {@link https://ukorvl.github.io/lightweight-charts-react-components/docs/series | Series documentation}\n * @see {@link https://tradingview.github.io/lightweight-charts/docs/series-types#custom-series-plugins | TradingView documentation for custom series}\n * @example\n * ```tsx\n * <CustomSeries\n * data={[\n * { time: '2021-01-01', value: 100 },\n * { time: '2021-01-02', value: 200 }\n * ]}\n * options={{}}\n * plugin={{}}\n * />\n * ```\n */\nexport const CustomSeries: ForwardRefExoticComponent<\n SeriesProps<\"Custom\"> & RefAttributes<SeriesApiRef<\"Custom\">>\n> = forwardRef(CustomSeriesRenderFunction);\nCustomSeries.displayName = \"CustomSeries\";\n","import { useLayoutEffect, useRef } from \"react\";\nimport { useSafeContext } from \"@/_shared/useSafeContext\";\nimport { SeriesContext } from \"@/series/SeriesContext\";\nimport type { PriceLineApiRef, PriceLineProps } from \"./types\";\n\nexport const usePriceLine = ({ options, price }: PriceLineProps) => {\n const { isReady: seriesIsReady, seriesApiRef: series } = useSafeContext(SeriesContext);\n\n const priceLineApiRef = useRef<PriceLineApiRef>({\n _priceLine: null,\n api() {\n return this._priceLine;\n },\n init() {\n if (!this._priceLine) {\n const seriesApi = series?.api();\n\n if (!seriesApi) {\n return null;\n }\n\n this._priceLine = seriesApi.createPriceLine({\n price,\n ...options,\n });\n }\n\n return this._priceLine;\n },\n clear() {\n if (this._priceLine !== null) {\n series?.api()?.removePriceLine(this._priceLine);\n this._priceLine = null;\n }\n },\n });\n\n useLayoutEffect(() => {\n if (!seriesIsReady) return;\n\n priceLineApiRef.current.init();\n }, [seriesIsReady]);\n\n useLayoutEffect(() => {\n return () => {\n priceLineApiRef.current.clear();\n };\n }, []);\n\n useLayoutEffect(() => {\n if (!series) return;\n\n if (options) {\n priceLineApiRef.current.api()?.applyOptions(options);\n }\n }, [options]);\n\n useLayoutEffect(() => {\n if (!series) return;\n\n if (price) {\n priceLineApiRef.current.api()?.applyOptions({ price });\n }\n }, [price]);\n\n return priceLineApiRef;\n};\n","import { forwardRef, useImperativeHandle } from \"react\";\nimport { usePriceLine } from \"./usePriceLine\";\nimport type { PriceLineApiRef, PriceLineProps } from \"./types\";\nimport type { ForwardedRef, ForwardRefExoticComponent, JSX, RefAttributes } from \"react\";\n\nconst PriceLineRenderFunction = (\n props: PriceLineProps,\n ref: ForwardedRef<PriceLineApiRef>\n): JSX.Element | null => {\n const priceLineApiRef = usePriceLine(props);\n useImperativeHandle(ref, () => priceLineApiRef.current, [priceLineApiRef]);\n\n return null;\n};\n\n/**\n * PriceLine component that can be used to add a price line to a chart pane.\n *\n * @param props - The properties for the price line.\n * @param ref - The ref to access the price line API.\n * @returns A React component that renders the price line.\n * @see {@link https://ukorvl.github.io/lightweight-charts-react-components/docs/price-lines | Price Lines documentation}\n * @see {@link https://tradingview.github.io/lightweight-charts/tutorials/how_to/price-line | TradingView documentation for price lines}\n * @example\n * ```tsx\n * <PriceLine price={100} options={{}} />\n * ```\n */\nexport const PriceLine: ForwardRefExoticComponent<\n PriceLineProps & RefAttributes<PriceLineApiRef>\n> = forwardRef(PriceLineRenderFunction);\nPriceLine.displayName = \"PriceLine\";\n","import { createSeriesMarkers } from \"lightweight-charts\";\nimport { useLayoutEffect, useRef } from \"react\";\nimport { useSafeContext } from \"@/_shared/useSafeContext\";\nimport { SeriesContext } from \"@/series/SeriesContext\";\nimport type { MarkersApiRef, MarkersProps } from \"./types\";\n\nexport const useMarkers = ({ reactive = true, markers }: MarkersProps) => {\n const { isReady: seriesIsReady, seriesApiRef: series } = useSafeContext(SeriesContext);\n\n const markersApiRef = useRef<MarkersApiRef>({\n _markers: null,\n api() {\n return this._markers;\n },\n init() {\n if (this._markers === null) {\n const seriesApi = series?.api();\n\n if (!seriesApi) {\n return null;\n }\n\n this._markers = createSeriesMarkers(seriesApi, markers);\n }\n\n return this._markers;\n },\n clear() {\n if (this._markers !== null) {\n this._markers.detach();\n this._markers = null;\n }\n },\n });\n\n useLayoutEffect(() => {\n if (!seriesIsReady) return;\n\n markersApiRef.current.init();\n }, [seriesIsReady]);\n\n useLayoutEffect(() => {\n return () => {\n markersApiRef.current.clear();\n };\n }, []);\n\n useLayoutEffect(() => {\n if (!series) return;\n\n if (markers && reactive) {\n markersApiRef.current.api()?.setMarkers(markers);\n }\n }, [markers, reactive]);\n\n return markersApiRef;\n};\n","import { forwardRef, useImperativeHandle } from \"react\";\nimport { useMarkers } from \"./useMarkers\";\nimport type { MarkersApiRef, MarkersProps } from \"./types\";\nimport type { ForwardedRef, ForwardRefExoticComponent, JSX, RefAttributes } from \"react\";\n\nconst MarkersRenderFunction = (\n { ...rest }: MarkersProps,\n ref: ForwardedRef<MarkersApiRef>\n): JSX.Element | null => {\n const markersApiRef = useMarkers(rest);\n useImperativeHandle(ref, () => markersApiRef.current, [markersApiRef]);\n\n return null;\n};\n\n/**\n * Markers component that can be used to add markers to a chart pane.\n *\n * @param props - The properties for the markers.\n * @param ref - The ref to access the markers API.\n * @returns A React component that renders the markers.\n * @see {@link https://tradingview.github.io/lightweight-charts/tutorials/how_to/series-markers | Markers documentation}\n * @see {@link https://tradingview.github.io/lightweight-charts/docs/markers | TradingView documentation for markers}\n * @example\n * ```tsx\n * <Markers\n * markers={[\n * { time: 1622548800, position: \"aboveBar\", color: \"red\", shape: \"arrowUp\" },\n * { time: 1622548800, position: \"belowBar\", color: \"green\", shape: \"arrowDown\" },\n * ]}\n * />\n * ```\n */\nexport const Markers: ForwardRefExoticComponent<\n MarkersProps & RefAttributes<MarkersApiRef>\n> = forwardRef(MarkersRenderFunction);\nMarkers.displayName = \"Markers\";\n","import { createTextWatermark, createImageWatermark } from \"lightweight-charts\";\nimport { useLayoutEffect, useRef } from \"react\";\nimport { BaseInternalError } from \"@/_shared/InternalError\";\nimport { useSafeContext } from \"@/_shared/useSafeContext\";\nimport { ChartContext } from \"@/chart/ChartContext\";\nimport { usePaneContext } from \"@/pane/usePaneContext\";\nimport type { WatermarkApiRef, WatermarkProps, WatermarkType } from \"./types\";\n\nconst useWatermark = <T extends WatermarkType>(props: WatermarkProps<T>) => {\n const { isReady: chartIsReady, chartApiRef: chart } = useSafeContext(ChartContext);\n const { isPaneReady, isInsidePane, paneApiRef } = usePaneContext();\n\n const watermarkApiRef = useRef<WatermarkApiRef<T>>({\n _watermark: null,\n api() {\n return this._watermark;\n },\n init() {\n if (this._watermark === null) {\n const chartApi = chart?.api();\n\n const pane = paneApiRef?.api();\n\n if (!chartApi || !pane) return null;\n\n if (isTextWatermark(props)) {\n const { type: _, ...rest } = props;\n this._watermark = createTextWatermark(pane, rest);\n } else {\n const { type: _, src, ...rest } = props as WatermarkProps<\"image\">;\n this._watermark = createImageWatermark(pane, src, rest);\n }\n }\n\n return this._watermark;\n },\n clear() {\n if (this._watermark !== null) {\n this._watermark.detach();\n this._watermark = null;\n }\n },\n } as WatermarkApiRef<T>);\n\n useLayoutEffect(() => {\n if (!chartIsReady) return;\n\n if (!isInsidePane) {\n throw new BaseInternalError(\n \"Watermark must be used inside a pane. Please ensure that the component is wrapped in a pane component.\",\n {\n isOperational: true,\n docsPath: \"\",\n }\n );\n }\n\n if (!isPaneReady) {\n return;\n }\n\n watermarkApiRef.current.init();\n }, [chartIsReady, isPaneReady, isInsidePane]);\n\n useLayoutEffect(() => {\n return () => {\n watermarkApiRef.current.clear();\n };\n }, []);\n\n useLayoutEffect(() => {\n if (!chart || !props) return;\n\n const { type: _, ...rest } = props;\n watermarkApiRef.current.api()?.applyOptions(rest);\n }, [props]);\n\n return watermarkApiRef;\n};\n\nconst isTextWatermark = (\n props: WatermarkProps<WatermarkType>\n): props is WatermarkProps<\"text\"> => {\n return props.type === \"text\";\n};\n\nexport { useWatermark };\n","import { forwardRef, useImperativeHandle } from \"react\";\nimport { useWatermark } from \"./useWatermark\";\nimport type {\n ImageWatermarkProps,\n TextWatermarkProps,\n WatermarkApiRef,\n WatermarkProps,\n WatermarkType,\n} from \"./types\";\nimport type { ForwardedRef, ForwardRefExoticComponent, RefAttributes } from \"react\";\n\nconst WatermarkRenderFunction = <T extends WatermarkType>(\n props: WatermarkProps<T>,\n ref: ForwardedRef<WatermarkApiRef<T>>\n) => {\n const watermarkApi = useWatermark(props);\n useImperativeHandle(ref, () => watermarkApi.current, [watermarkApi]);\n\n return null;\n};\n\n/**\n * Watermark component that can be used to add a text or image watermark to a chart pane.\n *\n * @param props - The properties for the watermark.\n * @param ref - The ref to access the watermark API.\n * @returns A React component that renders the watermark.\n * @see {@link https://ukorvl.github.io/lightweight-charts-react-components/docs/watermarks | Watermarks documentation}\n * @see {@link https://tradingview.github.io/lightweight-charts/tutorials/how_to/watermark | TradingView documentation for watermarks}\n * @example\n * ```tsx\n * <WatermarkText\n * lines={[\n * { text: \"Your chart name\", color: \"blue\", fontSize: 24 },\n * { text: \"Some other text\", color: \"pink\", fontSize: 16 },\n * ]}\n * horzAlign=\"center\"\n * />\n * ```\n */\nexport const WatermarkText: ForwardRefExoticComponent<\n TextWatermarkProps & RefAttributes<WatermarkApiRef<\"text\">>\n> = forwardRef<WatermarkApiRef<\"text\">, TextWatermarkProps>((props, ref) => {\n return WatermarkRenderFunction({ ...props, type: \"text\" }, ref);\n});\n\n/**\n * Watermark component that can be used to add an image watermark to a chart pane.\n *\n * @param props - The properties for the image watermark.\n * @param ref - The ref to access the watermark API.\n * @returns A React component that renders the image watermark.\n * @see {@link https://ukorvl.github.io/lightweight-charts-react-components/docs/watermarks | Watermarks documentation}\n * @see {@link https://tradingview.github.io/lightweight-charts/tutorials/how_to/watermark | TradingView documentation for watermarks}\n * @example\n * ```tsx\n * <WatermarkImage\n * src=\"data:image/svg+xml;base64,...\"\n * alpha={0.5}\n * padding={20}\n * />\n * ```\n */\nexport const WatermarkImage: ForwardRefExoticComponent<\n ImageWatermarkProps & RefAttributes<WatermarkApiRef<\"image\">>\n> = forwardRef<WatermarkApiRef<\"image\">, ImageWatermarkProps>((props, ref) => {\n return WatermarkRenderFunction({ ...props, type: \"image\" }, ref);\n});\n\nWatermarkText.displayName = \"WatermarkText\";\nWatermarkImage.displayName = \"WatermarkImage\";\n","import { useLayoutEffect, useRef } from \"react\";\nimport { useSafeContext } from \"@/_shared/useSafeContext\";\nimport { ChartContext } from \"@/chart/ChartContext\";\nimport { SeriesContext