UNPKG

@modern-kit/react

Version:
1 lines 6.06 kB
{"version":3,"file":"index.cjs","sources":["../../../src/components/InView/index.tsx"],"sourcesContent":["import React from 'react';\nimport {\n useIntersectionObserver,\n UseIntersectionObserverProps,\n} from '../../hooks/useIntersectionObserver';\nimport { polymorphicForwardRef } from '../../utils/polymorphicForwardRef';\nimport { useMergeRefs } from '../../hooks/useMergeRefs';\nimport { Slot } from '../../components/Slot';\n\ninterface InViewProps extends UseIntersectionObserverProps {\n children: React.ReactNode;\n asChild?: boolean;\n}\n\nconst IN_VIEW_ERROR_MESSAGE =\n 'InView는 asChild가 true일 경우 children으로 유효한 React 요소만을 허용합니다. 또한, 단일 요소만 허용합니다.';\n\n/**\n * @description `InView`는 `IntersectionObserver`를 선언적으로 활용 할 수 있는 컴포넌트입니다.\n *\n * 관찰 대상이 `viewport`에 노출될 때(`onIntersectStart`) 혹은 나갈 때(`onIntersectEnd`) 특정 action 함수를 호출 할 수 있는 컴포넌트입니다.\n *\n * `@modern-kit/react`의 `useIntersectionObserver` 훅을 사용하여 구현되었습니다.\n *\n * @see https://modern-agile-team.github.io/modern-kit/docs/react/hooks/useIntersectionObserver\n *\n * `as` 속성을 통해 `다형성(polymorphism)`을 지원합니다:\n * - 기본적으로 `div` 태그로 자식 요소를 감싸서 렌더링하며, `as` 속성을 통해 감싸는 Wrapper 요소의 태그를 변경해 렌더링할 수 있습니다. (ex. div -> article)\n * - 이때 해당 Wrapper 요소가 `IntersectionObserver`의 관찰 대상입니다.\n *\n * `asChild` 속성을 통해 `합성(Composition)`, `렌더링 위임(Rendering Delegation)` 패턴을 지원합니다:\n * - `asChild` 속성이 `true`라면 `Slot`을 통해 래퍼 요소 없이 자식 요소를 렌더링합니다.\n * - 이때, 자식 요소가 `IntersectionObserver`의 관찰 대상입니다.\n * - `asChild`를 사용 할 경우 아래 링크를 참고하세요.\n *\n * @see https://modern-agile-team.github.io/modern-kit/docs/react/components/Slot\n *\n *\n * @param {InViewProps} props - 컴포넌트에 전달되는 속성들입니다.\n * @param {React.ReactNode} props.children - 관찰할 자식 요소입니다.\n * @param {string} props.as - 관찰할 요소의 타입입니다. 기본값은 `div`입니다.\n * @param {boolean} [props.asChild=false] - 자식 요소를 래퍼 요소 없이 렌더링하고, 관찰 대상으로 설정할지 여부입니다. `true`일 경우 `Slot` 컴포넌트를 통해 자식 요소에 직접 props를 전달합니다.\n * @param {(entry: IntersectionObserverEntry) => void} props.onIntersectStart - 타겟 요소가 viewport 내에 들어갈 때 호출되는 콜백 함수입니다.\n * @param {(entry: IntersectionObserverEntry) => void} props.onIntersectEnd - 타겟 요소가 viewport에서 나갈 때 호출되는 콜백 함수입니다.\n * @param {number | number[]} props.threshold - 관찰을 시작할 viewport의 가시성 비율입니다.\n * @param {Element | Document | null} props.root - 교차할 때 기준이 되는 root 요소입니다. 기본값은 `null`이며 이는 viewport를 의미합니다.\n * @param {string} props.rootMargin - 루트 요소에 대한 마진을 지정합니다. 이는 뷰포트 또는 루트 요소의 경계를 확장하거나 축소하는데 사용됩니다.\n * @param {boolean} props.enabled - Observer를 활성화할지 여부를 나타냅니다. `false`일 경우 Observer가 작동하지 않습니다.\n * @param {boolean} props.calledOnce - 요소가 교차할 때 콜백을 `한 번`만 호출할지 여부를 나타냅니다.\n *\n * @returns {JSX.Element}\n *\n * @example\n * ```tsx\n * // default\n * <InView onIntersectStart={onIntersectStart} onIntersectEnd={onIntersectEnd}>\n * <div>Contents</div>\n * </InView>\n * ```\n *\n * @example\n * ```tsx\n * // as: ul\n * <InView as=\"ul\" onIntersectStart={onIntersectStart} onIntersectEnd={onIntersectEnd}>\n * <li>List Item1</li>\n * <li>List Item2</li>\n * </InView>\n * ```\n *\n * @example\n * ```tsx\n * // asChild\n * <InView asChild onIntersectStart={onIntersectStart} onIntersectEnd={onIntersectEnd}>\n * <div>Contents</div>\n * </InView>\n * ```\n */\n\nexport const InView = polymorphicForwardRef<'div', InViewProps>(\n ({ children, as = 'div', asChild = false, ...props }, ref) => {\n const {\n onIntersectStart,\n onIntersectEnd,\n calledOnce,\n enabled,\n root,\n threshold,\n rootMargin,\n ...restProps\n } = props;\n\n const InViewWrapper = asChild ? Slot : as;\n\n const { ref: intersectionObserverRef } = useIntersectionObserver({\n onIntersectStart,\n onIntersectEnd,\n calledOnce,\n enabled,\n root,\n threshold,\n rootMargin,\n });\n\n if (asChild && !React.isValidElement(children)) {\n throw new Error(IN_VIEW_ERROR_MESSAGE);\n }\n\n return (\n <InViewWrapper\n ref={useMergeRefs(ref, intersectionObserverRef)}\n {...restProps}>\n {children}\n </InViewWrapper>\n );\n }\n);\n"],"names":["polymorphicForwardRef","Slot","useIntersectionObserver","jsx","useMergeRefs"],"mappings":";;;;;;;;;;;;AAcA,MAAM,qBAAA,GACJ,yOAAA;AA+DK,MAAM,MAAA,GAASA,gDAAA;AAAA,EACpB,CAAC,EAAE,QAAA,EAAU,EAAA,GAAK,KAAA,EAAO,UAAU,KAAA,EAAO,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AAC5D,IAAA,MAAM;AAAA,MACJ,gBAAA;AAAA,MACA,cAAA;AAAA,MACA,UAAA;AAAA,MACA,OAAA;AAAA,MACA,IAAA;AAAA,MACA,SAAA;AAAA,MACA,UAAA;AAAA,MACA,GAAG;AAAA,KACL,GAAI,KAAA;AAEJ,IAAA,MAAM,aAAA,GAAgB,UAAUC,mBAAA,GAAO,EAAA;AAEvC,IAAA,MAAM,EAAE,GAAA,EAAK,uBAAA,EAAwB,GAAIC,oDAAA,CAAwB;AAAA,MAC/D,gBAAA;AAAA,MACA,cAAA;AAAA,MACA,UAAA;AAAA,MACA,OAAA;AAAA,MACA,IAAA;AAAA,MACA,SAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAA,IAAI,OAAA,IAAW,CAAC,KAAA,CAAM,cAAA,CAAe,QAAQ,CAAA,EAAG;AAC9C,MAAA,MAAM,IAAI,MAAM,qBAAqB,CAAA;AAAA,IACvC;AAEA,IAAA,uBACEC,cAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACC,GAAA,EAAKC,8BAAA,CAAa,GAAA,EAAK,uBAAuB,CAAA;AAAA,QAC7C,GAAG,SAAA;AAAA,QACH;AAAA;AAAA,KACH;AAAA,EAEJ;AACF;;;;"}