# Pull To Refresh URL: /lynx/components/pull-to-refresh Source: https://github.com/daangn/seed-design/blob/dev/docs/content/lynx/components/pull-to-refresh.mdx 사용자가 화면을 아래로 당겨 콘텐츠를 새로고침하는 컴포넌트입니다. 사용 가능 버전: @seed-design/lynx-react@1.0.0, @seed-design/lynx-css@1.0.0 ## Preview ```tsx import "./styles"; import { PullToRefreshContent, PullToRefreshIndicator, PullToRefreshRoot, } from "@/components/ui/pull-to-refresh"; import { PARAGRAPH, useRefreshObservation } from "./use-refresh-observation"; export default function Example() { const { refreshCount, lastEvent, callbacks } = useRefreshObservation(); return ( Pull To Refresh 최상단에서 아래로 당겨보세요. 짧게 당기면 취소되고, 충분히 당긴 뒤 놓으면 1초 동안 새로고침합니다. {`refresh 횟수: ${refreshCount} · 마지막 이벤트: ${lastEvent}`} {Array.from({ length: 8 }, (_, index) => ( {`${index + 1}. ${PARAGRAPH}`} ))} ); } ``` ## Installation - npm: npx @seed-design/cli@latest add ui:pull-to-refresh - pnpm: pnpm dlx @seed-design/cli@latest add ui:pull-to-refresh - yarn: yarn dlx @seed-design/cli@latest add ui:pull-to-refresh - bun: bun x @seed-design/cli@latest add ui:pull-to-refresh ### 요구 사항 SEED의 최소 지원 Lynx Engine은 `3.6`입니다. PullToRefresh는 `@lynx-js/gesture-runtime`의 `NativeGesture`를 사용하므로 앱의 기존 React 플러그인 설정에 `enableNewGesture: true`를 추가하세요. ```ts title="lynx.config.ts" pluginReactLynx({ engineVersion: "3.6", enableNewGesture: true, }); ``` `enableNewGesture`의 Since `2.16`은 엔진 설정의 도입 기록입니다. SEED의 최소 지원 엔진을 뜻하지 않습니다. 설정 위치와 생략 조건은 [Feature Flags](/lynx/getting-started/feature-flags#이벤트와-제스처)에서 확인하세요. ## Props ### `PullToRefreshRoot` `onPtrRefresh`에 새로고침 작업을 반환하는 비동기 함수를 전달하세요. `threshold`의 기본값은 `88`, `displacementMultiplier`의 기본값은 `0.75`입니다. 당긴 변위가 threshold를 넘은 상태에서 놓으면 새로고침을 시작합니다. Promise가 완료되거나 실패하면 콘텐츠가 원래 위치로 돌아옵니다. ### `PullToRefreshIndicator` 고유 prop이 없습니다. ### `PullToRefreshContent` Content는 세로 ``입니다. Root에 높이를 지정하고 화면의 세로 스크롤은 Content 하나로 구성하세요. 중첩된 세로 스크롤 컨테이너는 당김 제스처와 경합할 수 있습니다. ## Examples ### PTR in Tabs 가로로 넘길 수 있는 Tabs Carousel의 Tab 1에만 PullToRefresh를 배치합니다. Tab 2에서는 새로고침하지 않습니다. ```tsx import "./styles"; import { PullToRefreshContent, PullToRefreshIndicator, PullToRefreshRoot, } from "@/components/ui/pull-to-refresh"; import { TabsCarousel, TabsContent, TabsList, TabsRoot, TabsTrigger } from "@/components/ui/tabs"; import { PARAGRAPH, useRefreshObservation } from "./use-refresh-observation"; export default function Example() { const { refreshCount, lastEvent, callbacks } = useRefreshObservation(); return ( Pull To Refresh {`Tab 1 refresh 횟수: ${refreshCount} · 마지막 이벤트: ${lastEvent}`} Tab 1 Tab 2 {PARAGRAPH} PTR is not available in this tab. ); } ``` ### Disabled `disabled` 속성으로 PTR을 비활성화할 수 있습니다. 당기는 도중 비활성화하면 당김이 취소됩니다. 이미 시작한 새로고침은 반환한 Promise가 끝날 때까지 유지됩니다. ```tsx import "./styles"; import { useState } from "@lynx-js/react"; import { PullToRefreshContent, PullToRefreshIndicator, PullToRefreshRoot, } from "@/components/ui/pull-to-refresh"; import { Switch } from "@/components/ui/switch"; import { useRefreshObservation } from "./use-refresh-observation"; export default function Example() { const [disabled, setDisabled] = useState(false); const { refreshCount, lastEvent, callbacks } = useRefreshObservation(); function onCheckedChange(checked: boolean) { "background only"; setDisabled(checked); } return ( Disabled {`disabled: ${JSON.stringify(disabled)} · refresh 횟수: ${refreshCount} · 마지막 이벤트: ${lastEvent}`} Disabled ); } ``` ### Prevent Pull Root 안의 특정 영역에서 당김을 막으려면 `usePullToRefreshPreventPull()`이 반환한 props를 해당 ``에 전달하세요. 같은 요소에 `main-thread:bindtouchstart`를 함께 지정하지 마세요. ```tsx import "./styles"; import { usePullToRefreshPreventPull } from "@seed-design/lynx-react"; import { PullToRefreshContent, PullToRefreshIndicator, PullToRefreshRoot, } from "@/components/ui/pull-to-refresh"; import { useRefreshObservation } from "./use-refresh-observation"; function ProtectedRegion() { const preventPullProps = usePullToRefreshPreventPull(); return ( 이 영역은 당겨서 새로고침이 불가능합니다. Aliquip ad amet eu dolore id enim excepteur laboris officia anim in. Irure irure nulla sit eiusmod aliqua sint excepteur amet laboris. ); } function PullableRegion() { return ( 이 영역은 당겨서 새로고침이 가능합니다. Amet in laborum proident fugiat mollit quis aute mollit esse nostrud. Excepteur ea proident ipsum duis. Nulla Lorem pariatur exercitation velit anim. ); } export default function Example() { const { refreshCount, lastEvent, callbacks } = useRefreshObservation(); return ( Prevent Pull {`refresh 횟수: ${refreshCount} · 마지막 이벤트: ${lastEvent}`} ); } ``` ## 웹 버전과의 차이 - Lynx는 Root가 배치와 clipping을 맡고 Content가 세로 스크롤을 담당합니다. `asChild`는 지원하지 않습니다. - Content 내부의 중첩 스크롤 영역을 자동으로 탐지하지 않습니다. - 스크롤하다 최상단에 도달한 경우 손을 뗀 뒤 다시 당겨야 새로고침이 시작됩니다.