mirror of
https://github.com/BradNut/react-hooks-library
synced 2025-09-08 17:40:20 +00:00
Creating custom hook to set cookies, measure component size with ref, scroll freeze on component, get window width.
This commit is contained in:
parent
05fe1d93e7
commit
5cab62fd7e
13 changed files with 211 additions and 66 deletions
|
|
@ -5,6 +5,9 @@ import Toggle from './components/Toggle';
|
|||
import Inc from './components/Inc';
|
||||
import Mount from './components/Mount';
|
||||
import Hover from './components/Hover';
|
||||
import Cookie from "./components/Cookie";
|
||||
import { PageWrapper } from "./state";
|
||||
import Nav from "./components/Nav";
|
||||
import Menu from "./Menu";
|
||||
import blue from "./blue.png";
|
||||
import purp from "./purp.png";
|
||||
|
|
@ -13,16 +16,19 @@ import green from "./green.png";
|
|||
|
||||
function App() {
|
||||
return (
|
||||
<PageWrapper>
|
||||
<div>
|
||||
<Header>
|
||||
<Menu />
|
||||
<h1>Header</h1>
|
||||
</Header>
|
||||
<Nav />
|
||||
<Container>
|
||||
<h2>Super Cool</h2>
|
||||
<Toggle />
|
||||
<Inc />
|
||||
<Mount />
|
||||
<Cookie />
|
||||
<Hover />
|
||||
|
||||
<CardGrid>
|
||||
|
|
@ -45,6 +51,7 @@ function App() {
|
|||
</CardGrid>
|
||||
</Container>
|
||||
</div>
|
||||
</PageWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
11
src/Menu.js
11
src/Menu.js
|
|
@ -1,6 +1,10 @@
|
|||
import React from "react";
|
||||
import { useAppState } from "./state";
|
||||
|
||||
const Menu = () => (
|
||||
const Menu = () => {
|
||||
const { toggleMenu } = useAppState();
|
||||
|
||||
return (
|
||||
<button onClick={toggleMenu}>
|
||||
<svg viewBox="0 0 18 15" width="20">
|
||||
<path
|
||||
fill="#fff"
|
||||
|
|
@ -15,6 +19,7 @@ const Menu = () => (
|
|||
d="M18,13.516C18,14.335,17.335,15,16.516,15H1.484C0.665,15,0,14.335,0,13.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.031C17.335,12.031,18,12.696,18,13.516L18,13.516z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
</button>
|
||||
)};
|
||||
|
||||
export default Menu;
|
||||
|
|
|
|||
22
src/components/Cookie.js
Normal file
22
src/components/Cookie.js
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import { useCookies } from "../hooks";
|
||||
|
||||
const Cookie = () => {
|
||||
const [ cookie, setCookie ] = useCookies({ key: "tester" });
|
||||
|
||||
return (
|
||||
<div>
|
||||
<h1>{cookie || ''}</h1>
|
||||
<input type="text" value={cookie} onChange={(e) => setCookie(e.target.value)} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Cookie;
|
||||
|
||||
// Different types of api
|
||||
// const { value, get, set } = useCookie({key, value})
|
||||
// value
|
||||
// const { value, get, set } = useCookie({key: anotherKey, value})
|
||||
|
||||
// const { get, set } = useCookie()
|
||||
// get("theme")
|
||||
|
|
@ -1,15 +1,23 @@
|
|||
import React from 'react';
|
||||
import { Card } from '../Elements';
|
||||
import black from "../black.png"
|
||||
import { useHover } from '../hooks';
|
||||
import { useHover, useWindowWidth, useMeasure } from '../hooks';
|
||||
|
||||
export const Hover = () => {
|
||||
const [ isHovered, bind ] = useHover();
|
||||
console.log('isHovered', isHovered);
|
||||
const width = useWindowWidth();
|
||||
const [{ref}, bounds] = useMeasure();
|
||||
console.log('bounds', bounds);
|
||||
|
||||
if (width < 500) return null;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Card {...bind} style={{ background: isHovered ? "var(--purp)" : "var(--black)" }}>
|
||||
<Card
|
||||
ref={ref}
|
||||
{...bind}
|
||||
style={{ background: isHovered ? "var(--purp)" : "var(--black)" }}
|
||||
>
|
||||
<h3>Some card</h3>
|
||||
<img src={black} />
|
||||
</Card>
|
||||
|
|
|
|||
30
src/components/Nav.js
Normal file
30
src/components/Nav.js
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import { useAppState } from "../state";
|
||||
import { useScrollFreeze } from "../hooks";
|
||||
|
||||
const NavWrapper = () => {
|
||||
const { isMenuOpen } = useAppState();
|
||||
if (!isMenuOpen) return null;
|
||||
return <Nav />
|
||||
}
|
||||
|
||||
export const Nav = () => {
|
||||
const { toggleMenu } = useAppState();
|
||||
useScrollFreeze ();
|
||||
|
||||
return (
|
||||
<nav style={{
|
||||
background: 'var(--black)',
|
||||
color: 'white',
|
||||
position: 'fixed',
|
||||
width: '100vw',
|
||||
height: '100vh',
|
||||
left: 0,
|
||||
right: 0
|
||||
}}>
|
||||
<h1>Hello</h1>
|
||||
<button onClick={toggleMenu}>Close</button>
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
|
||||
export default NavWrapper;
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
import React, { createConext, useState } from 'react';
|
||||
import { useToggle } from '../hooks';
|
||||
|
||||
const AppContext = createConext({
|
||||
isMenuOpen: false,
|
||||
});
|
||||
|
||||
const PageWrapper = ({children}) => {
|
||||
const {isToggled, toggle} = useToggle();
|
||||
return <AppContext.Provider
|
||||
value={{ isMenuOpen: false}}>
|
||||
{children}
|
||||
</AppContext.Provider>
|
||||
};
|
||||
|
|
@ -1,4 +1,8 @@
|
|||
export * from './useCookie';
|
||||
export * from './useHover';
|
||||
export * from './useInc';
|
||||
export * from './useMeasure';
|
||||
export * from './useMount';
|
||||
export * from './useScrollFreeze';
|
||||
export * from './useToggle';
|
||||
export * from './useWindowWidth';
|
||||
|
|
|
|||
13
src/hooks/useCookie.js
Normal file
13
src/hooks/useCookie.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { useState, useEffect } from 'react';
|
||||
import Cookies from 'js-cookie';
|
||||
|
||||
export const useCookies = ({ key }) => {
|
||||
const initial = Cookies.get(key);
|
||||
const [ cookie, setStateCookie ] = useState(initial);
|
||||
|
||||
useEffect(() => {
|
||||
Cookies.set(key, cookie)
|
||||
}, [cookie, key]);
|
||||
|
||||
return [ cookie, setStateCookie ];
|
||||
};
|
||||
23
src/hooks/useMeasure.js
Normal file
23
src/hooks/useMeasure.js
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import { useState, useRef, useEffect } from 'react';
|
||||
|
||||
export const useMeasure = () => {
|
||||
const ref = useRef();
|
||||
|
||||
const [bounds, setBounds] = useState({ left: 0, top: 0, width: 0, height: 0 });
|
||||
|
||||
const [ resizeO ] = useState(() => {
|
||||
return new ResizeObserver(([entry]) => setBounds(entry.contentRect))
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (ref.current) {
|
||||
resizeO.observe(ref.current);
|
||||
}
|
||||
|
||||
return () => {
|
||||
return resizeO.disconnect();
|
||||
};
|
||||
}, [resizeO]);
|
||||
|
||||
return [{ ref }, bounds];
|
||||
}
|
||||
12
src/hooks/useScrollFreeze.js
Normal file
12
src/hooks/useScrollFreeze.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import { useLayoutEffect } from 'react';
|
||||
|
||||
export const useScrollFreeze = () => {
|
||||
useLayoutEffect(() => {
|
||||
const original = window.getComputedStyle(document.body).overflow;
|
||||
document.body.style.overflow = 'hidden';
|
||||
|
||||
return () => {
|
||||
document.body.style.overflow = original;
|
||||
};
|
||||
}, [])
|
||||
};
|
||||
17
src/hooks/useWindowWidth.js
Normal file
17
src/hooks/useWindowWidth.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { useState, useEffect } from "react";
|
||||
|
||||
export const useWindowWidth = () => {
|
||||
const [width, setWidth] = useState(window.innerWidth);
|
||||
|
||||
useEffect(() => {
|
||||
const handleResize = () => {
|
||||
setWidth(window.innerWidth);
|
||||
}
|
||||
window.addEventListener('resize', handleResize);
|
||||
return () => {
|
||||
window.removeEventListener('resize', handleResize);
|
||||
};
|
||||
});
|
||||
|
||||
return width;
|
||||
}
|
||||
17
src/state/PageWrapper.js
Normal file
17
src/state/PageWrapper.js
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import { createContext, useContext } from 'react';
|
||||
import { useToggle } from '../hooks';
|
||||
|
||||
export const AppContext = createContext({
|
||||
isMenuOpen: false,
|
||||
});
|
||||
|
||||
export const PageWrapper = ({children}) => {
|
||||
const { isToggled, toggle } = useToggle(false);
|
||||
return (
|
||||
<AppContext.Provider value={{ isMenuOpen: isToggled, toggleMenu: toggle }}>
|
||||
{children}
|
||||
</AppContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useAppState = () => useContext(AppContext);
|
||||
1
src/state/index.js
Normal file
1
src/state/index.js
Normal file
|
|
@ -0,0 +1 @@
|
|||
export * from './PageWrapper';
|
||||
Loading…
Reference in a new issue