Files
outline/app/components/Tabs.tsx
忽如寄 9f400af73b refactor: ♻️ refactor isHosted && type clean up (#3290)
* refactor: ♻️ refactor isHosted && type clean up

Change-Id: I4dfbad8a07607432801de78920ce42bf81e46498

* refactor: ♻️ code clean up

Change-Id: I8f487a33d332a2acaff84397a97371b56ace28a1

* feat: 💄 lint

Change-Id: I776b1a5e249bdb542f8e6da7cb2277821cf91094

* feat:  ci type

Change-Id: I486dde7bf60321238e9a394c40ad8cdb8bfc54c8

* feat: some code sugession

Change-Id: I4761d057344b95a98e99068d312a42292977875b
2022-03-27 15:18:37 -07:00

94 lines
2.2 KiB
TypeScript

import { AnimateSharedLayout } from "framer-motion";
import { transparentize } from "polished";
import * as React from "react";
import styled from "styled-components";
import useWindowSize from "~/hooks/useWindowSize";
const Nav = styled.nav<{ $shadowVisible?: boolean }>`
border-bottom: 1px solid ${(props) => props.theme.divider};
margin: 12px 0;
overflow-y: auto;
white-space: nowrap;
-ms-overflow-style: none;
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
&:after {
content: "";
position: absolute;
top: 0;
right: 0;
width: 50px;
height: 100%;
pointer-events: none;
background: ${(props) =>
props.$shadowVisible
? `linear-gradient(
90deg,
${transparentize(1, props.theme.background)} 0%,
${props.theme.background} 100%
)`
: `transparent`};
}
`;
// When sticky we need extra background coverage around the sides otherwise
// items that scroll past can "stick out" the sides of the heading
const Sticky = styled.div`
position: sticky;
top: 54px;
margin: 0 -8px;
padding: 0 8px;
background: ${(props) => props.theme.background};
transition: ${(props) => props.theme.backgroundTransition};
z-index: 1;
`;
export const Separator = styled.span`
border-left: 1px solid ${(props) => props.theme.divider};
position: relative;
top: 2px;
margin-right: 24px;
margin-top: 6px;
`;
const Tabs: React.FC = ({ children }) => {
const ref = React.useRef<any>();
const [shadowVisible, setShadow] = React.useState(false);
const { width } = useWindowSize();
const updateShadows = React.useCallback(() => {
const c = ref.current;
if (!c) {
return;
}
const scrollLeft = c.scrollLeft;
const wrapperWidth = c.scrollWidth - c.clientWidth;
const fade = !!(wrapperWidth - scrollLeft !== 0);
if (fade !== shadowVisible) {
setShadow(fade);
}
}, [shadowVisible]);
React.useEffect(() => {
updateShadows();
}, [width, updateShadows]);
return (
<AnimateSharedLayout>
<Sticky>
<Nav ref={ref} onScroll={updateShadows} $shadowVisible={shadowVisible}>
{children}
</Nav>
</Sticky>
</AnimateSharedLayout>
);
};
export default Tabs;