diff --git a/packages/react-scroll-section/src/ScrollingProvider.tsx b/packages/react-scroll-section/src/ScrollingProvider.tsx index 0ba4d3f..9dfa621 100644 --- a/packages/react-scroll-section/src/ScrollingProvider.tsx +++ b/packages/react-scroll-section/src/ScrollingProvider.tsx @@ -1,14 +1,13 @@ -import React, { +import { ReactNode, createRef, useEffect, useMemo, useState, - RefObject, useCallback, } from 'react'; import { debounce } from './utils'; -import { Provider } from './context'; +import { Provider, Section } from './context'; import smoothscroll from 'smoothscroll-polyfill'; type Props = { @@ -18,12 +17,6 @@ type Props = { children: ReactNode; }; -type Section = { - id: string; - ref: RefObject; - meta: unknown; -}; - if (typeof window !== 'undefined') { smoothscroll.polyfill(); } @@ -35,7 +28,7 @@ export const ScrollingProvider = ({ children, }: Props) => { const [selected, setSelected] = useState(''); - const [sections, setSections] = useState([]); + const [sections, setSections] = useState>({}); useEffect(() => { document.addEventListener('scroll', debounceScroll, true); @@ -46,12 +39,12 @@ export const ScrollingProvider = ({ }, [sections]); const handleScroll = useCallback(() => { - const selectedSection = sections.reduce( - (acc, curr) => { - const sectionRef = curr.ref.current; + const selectedSection = Object.keys(sections).reduce( + (acc, id) => { + const sectionRef = sections[id].ref.current; if (!sectionRef) { return { - id: curr.id, + id, differenceFromTop: 0, }; } @@ -62,13 +55,13 @@ export const ScrollingProvider = ({ if (differenceFromTop >= acc.differenceFromTop) return acc; return { + id, differenceFromTop, - id: curr.id, }; }, { - differenceFromTop: 9999, id: '', + differenceFromTop: 9999, }, ); @@ -77,19 +70,19 @@ export const ScrollingProvider = ({ const debounceScroll = debounce(handleScroll, debounceDelay); - const registerRef = ({ id, meta }: Omit) => { + const registerRef = ({ id, meta }: { id: string; meta: unknown }) => { const ref = createRef(); - setSections((prev) => [...prev, { id, ref, meta }]); + setSections((prev) => ({ ...prev, [id]: { ref, meta } })); return ref; }; const unregisterRef = (id: string) => { - setSections((prev) => prev.filter((section) => section.id !== id)); + setSections(({ [id]: toRemove, ...rest }) => rest); }; const scrollTo = useCallback( (id: string) => { - const section = sections.find((section) => section.id === id); + const section = sections[id]; if (!section) return console.warn('Section ID not recognized!'); // eslint-disable-line setSelected(id); diff --git a/packages/react-scroll-section/src/Section.tsx b/packages/react-scroll-section/src/Section.tsx index 9641754..adcc164 100644 --- a/packages/react-scroll-section/src/Section.tsx +++ b/packages/react-scroll-section/src/Section.tsx @@ -1,11 +1,11 @@ -import React, { useMemo, useContext, useEffect } from 'react'; +import { useMemo, useContext, useEffect, ReactNode, HTMLProps } from 'react'; import { ScrollContext } from './context'; type Props = { id: string; meta?: unknown; - children: React.ReactNode; -} & React.HTMLProps; + children: ReactNode; +} & HTMLProps; export const Section = ({ id, children, meta, ...rest }: Props) => { const { registerRef, unregisterRef } = useContext(ScrollContext); diff --git a/packages/react-scroll-section/src/context.ts b/packages/react-scroll-section/src/context.ts index 06b3634..5199dd3 100644 --- a/packages/react-scroll-section/src/context.ts +++ b/packages/react-scroll-section/src/context.ts @@ -1,7 +1,6 @@ import { createContext, RefObject } from 'react'; export type Section = { - id: string; ref: RefObject; meta: unknown; }; @@ -13,7 +12,7 @@ export type ScrollContextType = { }) => RefObject | null; unregisterRef: (id: string) => void; scrollTo: (section: string) => void; - sections: Section[]; + sections: Record; selected: string; }; @@ -21,7 +20,7 @@ const DEFAULT_CONTEXT: ScrollContextType = { registerRef: () => null, unregisterRef: () => {}, scrollTo: () => {}, - sections: [], + sections: {}, selected: '', }; diff --git a/packages/react-scroll-section/src/hooks.ts b/packages/react-scroll-section/src/hooks.ts index f210bd4..3a88632 100644 --- a/packages/react-scroll-section/src/hooks.ts +++ b/packages/react-scroll-section/src/hooks.ts @@ -15,9 +15,9 @@ export const useScrollSections = () => { sections, } = useContext(ScrollContext); - return sections.map(({ id, meta }) => ({ + return Object.keys(sections).map((id) => ({ id, - meta, + meta: sections[id].meta, onClick: () => scrollTo(id), selected: selectedSection === id, }));