Skip to content

Commit

Permalink
fix: use object instead of array to keep sections
Browse files Browse the repository at this point in the history
  • Loading branch information
Emanuel Suriano committed Oct 16, 2022
1 parent c9d4121 commit 467f625
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 28 deletions.
33 changes: 13 additions & 20 deletions packages/react-scroll-section/src/ScrollingProvider.tsx
Original file line number Diff line number Diff line change
@@ -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 = {
Expand All @@ -18,12 +17,6 @@ type Props = {
children: ReactNode;
};

type Section = {
id: string;
ref: RefObject<HTMLElement>;
meta: unknown;
};

if (typeof window !== 'undefined') {
smoothscroll.polyfill();
}
Expand All @@ -35,7 +28,7 @@ export const ScrollingProvider = ({
children,
}: Props) => {
const [selected, setSelected] = useState('');
const [sections, setSections] = useState<Section[]>([]);
const [sections, setSections] = useState<Record<string, Section>>({});

useEffect(() => {
document.addEventListener('scroll', debounceScroll, true);
Expand All @@ -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,
};
}
Expand All @@ -62,13 +55,13 @@ export const ScrollingProvider = ({
if (differenceFromTop >= acc.differenceFromTop) return acc;

return {
id,
differenceFromTop,
id: curr.id,
};
},
{
differenceFromTop: 9999,
id: '',
differenceFromTop: 9999,
},
);

Expand All @@ -77,19 +70,19 @@ export const ScrollingProvider = ({

const debounceScroll = debounce(handleScroll, debounceDelay);

const registerRef = ({ id, meta }: Omit<Section, 'ref'>) => {
const registerRef = ({ id, meta }: { id: string; meta: unknown }) => {
const ref = createRef<HTMLElement>();
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);
Expand Down
6 changes: 3 additions & 3 deletions packages/react-scroll-section/src/Section.tsx
Original file line number Diff line number Diff line change
@@ -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<HTMLDetailsElement>;
children: ReactNode;
} & HTMLProps<HTMLDetailsElement>;

export const Section = ({ id, children, meta, ...rest }: Props) => {
const { registerRef, unregisterRef } = useContext(ScrollContext);
Expand Down
5 changes: 2 additions & 3 deletions packages/react-scroll-section/src/context.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { createContext, RefObject } from 'react';

export type Section = {
id: string;
ref: RefObject<HTMLElement>;
meta: unknown;
};
Expand All @@ -13,15 +12,15 @@ export type ScrollContextType = {
}) => RefObject<HTMLElement> | null;
unregisterRef: (id: string) => void;
scrollTo: (section: string) => void;
sections: Section[];
sections: Record<string, Section>;
selected: string;
};

const DEFAULT_CONTEXT: ScrollContextType = {
registerRef: () => null,
unregisterRef: () => {},
scrollTo: () => {},
sections: [],
sections: {},
selected: '',
};

Expand Down
4 changes: 2 additions & 2 deletions packages/react-scroll-section/src/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}));
Expand Down

0 comments on commit 467f625

Please sign in to comment.