{"version":3,"file":"RefreshIndicator.cjs","names":[],"sources":["../../../src/components/RefreshIndicator/RefreshIndicator.tsx"],"sourcesContent":["/**\n * @tempest-limits function-lines — pull-to-refresh is a gesture with a threshold, a\n * rubber-band offset and a release animation, and the body is those three reading\n * one pointer delta.\n */\nimport { useRef, useState, type ReactNode, type TouchEvent } from \"react\";\nimport { Spinner } from \"@/components/Spinner\";\nimport { cn } from \"@/utils/cn\";\nimport styles from \"./RefreshIndicator.module.css\";\n\nexport interface RefreshIndicatorProps {\n    /** Invoked when the user pulls past `threshold` and releases. May be async. */\n    onRefresh: () => void | Promise<void>;\n    /** Scrollable content to wrap. */\n    children: ReactNode;\n    /** Pixels the user must pull past to trigger a refresh. Defaults to `80`. */\n    threshold?: number;\n    /** When true, pull-to-refresh is inert. */\n    disabled?: boolean;\n    className?: string;\n}\n\n/** Apply resistance so the content lags behind the finger and the pull never runs away. */\nfunction applyResistance(distance: number, threshold: number): number {\n    const cap = threshold * 1.5;\n    return Math.min(distance / 2, cap);\n}\n\n/**\n * RefreshIndicator — pull-to-refresh wrapper for touch devices.\n *\n * Wraps scrollable `children` and listens for a downward drag that starts while the\n * container is scrolled to the top. Pulling past `threshold` and releasing triggers\n * `onRefresh`; the SDK {@link Spinner} is shown while pulling and during the refresh.\n */\nexport function RefreshIndicator({\n    onRefresh,\n    children,\n    threshold = 80,\n    disabled,\n    className,\n}: RefreshIndicatorProps) {\n    const containerRef = useRef<HTMLDivElement>(null);\n    const startYRef = useRef<number | null>(null);\n    const [pull, setPull] = useState(0);\n    const [refreshing, setRefreshing] = useState(false);\n    /**\n     * Whether a drag is in progress. Kept in state, not derived from\n     * `startYRef.current`: a ref is not reactive, so reading it during render ties\n     * the rendered class to a value React never re-renders for — it only looked\n     * correct here because the touch handlers happen to call `setPull` too.\n     */\n    const [engaged, setEngaged] = useState(false);\n\n    const handleTouchStart = (event: TouchEvent<HTMLDivElement>): void => {\n        if (disabled || refreshing) return;\n        const container = containerRef.current;\n        if (!container || container.scrollTop > 0) return;\n        const touch = event.touches[0];\n        if (!touch) return;\n        startYRef.current = touch.clientY;\n        setEngaged(true);\n    };\n\n    const handleTouchMove = (event: TouchEvent<HTMLDivElement>): void => {\n        if (disabled || refreshing) return;\n        const startY = startYRef.current;\n        if (startY === null) return;\n        const touch = event.touches[0];\n        if (!touch) return;\n        const delta = touch.clientY - startY;\n        if (delta <= 0) {\n            setPull(0);\n            return;\n        }\n        setPull(applyResistance(delta, threshold));\n    };\n\n    const reset = (): void => {\n        startYRef.current = null;\n        setEngaged(false);\n        setPull(0);\n    };\n\n    const handleTouchEnd = async (): Promise<void> => {\n        if (disabled || refreshing) {\n            reset();\n            return;\n        }\n        const startY = startYRef.current;\n        const triggered = startY !== null && pull >= threshold;\n        if (!triggered) {\n            reset();\n            return;\n        }\n        startYRef.current = null;\n        setEngaged(false);\n        setRefreshing(true);\n        setPull(threshold);\n        try {\n            await onRefresh();\n        } finally {\n            setRefreshing(false);\n            setPull(0);\n        }\n    };\n\n    const showIndicator = refreshing || pull > 0;\n    const progress = Math.min(1, pull / threshold);\n\n    return (\n        <div\n            ref={containerRef}\n            className={cn(styles.wrapper, className)}\n            data-refreshing={refreshing}\n            onTouchStart={handleTouchStart}\n            onTouchMove={handleTouchMove}\n            onTouchEnd={handleTouchEnd}\n        >\n            <div\n                className={styles.indicator}\n                aria-hidden={!showIndicator}\n                style={{\n                    opacity: refreshing ? 1 : progress,\n                    transform: `translateX(-50%) translateY(${showIndicator ? pull : 0}px) rotate(${progress * 360}deg)`,\n                }}\n            >\n                <Spinner size=\"sm\" label=\"Atualizando\" />\n            </div>\n            <div\n                className={cn(styles.content, (engaged || refreshing) && styles.dragging)}\n                style={{ transform: `translateY(${showIndicator ? pull : 0}px)` }}\n            >\n                {children}\n            </div>\n        </div>\n    );\n}\n"],"mappings":"2KAuBA,SAAS,EAAgB,EAAkB,EAA2B,CAClE,IAAM,EAAM,EAAY,IACxB,OAAO,KAAK,IAAI,EAAW,EAAG,CAAG,CACrC,CASA,SAAgB,EAAiB,CAC7B,YACA,WACA,YAAY,GACZ,WACA,aACsB,CACtB,IAAM,GAAA,EAAe,EAAA,OAAA,CAAuB,IAAI,EAC1C,GAAA,EAAY,EAAA,OAAA,CAAsB,IAAI,EACtC,CAAC,EAAM,IAAA,EAAW,EAAA,SAAA,CAAS,CAAC,EAC5B,CAAC,EAAY,IAAA,EAAiB,EAAA,SAAA,CAAS,EAAK,EAO5C,CAAC,EAAS,IAAA,EAAc,EAAA,SAAA,CAAS,EAAK,EAEtC,EAAoB,GAA4C,CAClE,GAAI,GAAY,EAAY,OAC5B,IAAM,EAAY,EAAa,QAC/B,GAAI,CAAC,GAAa,EAAU,UAAY,EAAG,OAC3C,IAAM,EAAQ,EAAM,QAAQ,GACvB,IACL,EAAU,QAAU,EAAM,QAC1B,EAAW,EAAI,EACnB,EAEM,EAAmB,GAA4C,CACjE,GAAI,GAAY,EAAY,OAC5B,IAAM,EAAS,EAAU,QACzB,GAAI,IAAW,KAAM,OACrB,IAAM,EAAQ,EAAM,QAAQ,GAC5B,GAAI,CAAC,EAAO,OACZ,IAAM,EAAQ,EAAM,QAAU,EAC9B,GAAI,GAAS,EAAG,CACZ,EAAQ,CAAC,EACT,MACJ,CACA,EAAQ,EAAgB,EAAO,CAAS,CAAC,CAC7C,EAEM,MAAoB,CACtB,EAAU,QAAU,KACpB,EAAW,EAAK,EAChB,EAAQ,CAAC,CACb,EAEM,EAAiB,SAA2B,CAC9C,GAAI,GAAY,EAAY,CACxB,EAAM,EACN,MACJ,CAGA,GAAI,EAFW,EAAU,UACI,MAAQ,GAAQ,GAC7B,CACZ,EAAM,EACN,MACJ,CACA,EAAU,QAAU,KACpB,EAAW,EAAK,EAChB,EAAc,EAAI,EAClB,EAAQ,CAAS,EACjB,GAAI,CACA,MAAM,EAAU,CACpB,QAAU,CACN,EAAc,EAAK,EACnB,EAAQ,CAAC,CACb,CACJ,EAEM,EAAgB,GAAc,EAAO,EACrC,EAAW,KAAK,IAAI,EAAG,EAAO,CAAS,EAE7C,OACI,EAAA,EAAA,KAAA,CAAC,MAAD,CACI,IAAK,EACL,UAAW,EAAA,GAAG,EAAA,QAAO,QAAS,CAAS,EACvC,kBAAiB,EACjB,aAAc,EACd,YAAa,EACb,WAAY,EANhB,SAAA,EAQI,EAAA,EAAA,IAAA,CAAC,MAAD,CACI,UAAW,EAAA,QAAO,UAClB,cAAa,CAAC,EACd,MAAO,CACH,QAAS,EAAa,EAAI,EAC1B,UAAW,+BAA+B,EAAgB,EAAO,EAAE,aAAa,EAAW,IAAI,KACnG,EAEA,UAAA,EAAA,EAAA,IAAA,CAAC,EAAA,QAAD,CAAS,KAAK,KAAK,MAAM,aAAe,CAAA,CACvC,CAAA,GACL,EAAA,EAAA,IAAA,CAAC,MAAD,CACI,UAAW,EAAA,GAAG,EAAA,QAAO,SAAU,GAAW,IAAe,EAAA,QAAO,QAAQ,EACxE,MAAO,CAAE,UAAW,cAAc,EAAgB,EAAO,EAAE,IAAK,EAE/D,UACA,CAAA,CACJ,GAEb"}