Skip to content

Commit

Permalink
Merge a59da70 into 7167ce1
Browse files Browse the repository at this point in the history
  • Loading branch information
nasaownsky committed May 11, 2022
2 parents 7167ce1 + a59da70 commit 5c8be2f
Show file tree
Hide file tree
Showing 18 changed files with 456 additions and 217 deletions.
1 change: 1 addition & 0 deletions spotlight-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
"react-simple-maps": "^2.3.0",
"react-spring": "^8.0.27",
"react-stickyfill": "^0.2.5",
"react-swipeable": "^7.0.0",
"react-use-clipboard": "^1.0.7",
"semiotic": "^1.20.6",
"smoothscroll-polyfill": "^0.4.4",
Expand Down
17 changes: 1 addition & 16 deletions spotlight-client/src/GlobalStyles/GlobalStyles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,18 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =============================================================================

import { rem } from "polished";
import React from "react";
import { Helmet } from "react-helmet-async";
import { createGlobalStyle, css } from "styled-components/macro";
import { createGlobalStyle } from "styled-components/macro";
import reset from "styled-reset";
import { NAV_BAR_HEIGHT } from "../constants";
import { colors, typefaces } from "../UiLibrary";

const scrollSnapStyles = css`
scroll-padding-top: ${rem(NAV_BAR_HEIGHT)};
scroll-snap-type: y proximity;
`;

const BaseStyles = createGlobalStyle`
${reset}
html {
box-sizing: border-box;
font-family: ${typefaces.body};
/* most browsers support full-page scroll snapping with this element */
${scrollSnapStyles}
*, *:before, *:after {
box-sizing: inherit;
Expand All @@ -46,12 +37,6 @@ const BaseStyles = createGlobalStyle`
body {
background-color: ${colors.background};
color: ${colors.text};
/*
Safari only supports full-page scroll snapping with this element for some reason;
see https://stackoverflow.com/a/60470570.
Setting it on both elements does not appear to create any conflicts
*/
${scrollSnapStyles}
}
strong {
Expand Down
52 changes: 8 additions & 44 deletions spotlight-client/src/NarrativeLayout/NarrativeLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,35 +15,18 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =============================================================================

import useBreakpoint from "@w11r/use-breakpoint";
import { observer } from "mobx-react-lite";
import { rem } from "polished";
import React from "react";
import Sticker from "react-stickyfill";
import styled from "styled-components/macro";
import { NAV_BAR_HEIGHT } from "../constants";
import { X_PADDING } from "../SystemNarrativePage/constants";
import NarrativeNavigation from "./NarrativeNavigation";
import Wayfinder from "./NarrativeNavigation";
import NarrativeSection from "./NarrativeSection";
import { LayoutSection } from "./types";
import { useInternalNavigation } from "./useInternalNavigation";

const Wrapper = styled.article`
const Wrapper = styled.div`
display: flex;
`;

const NavWrapper = styled.div`
flex: 0 0 auto;
width: ${rem(X_PADDING)};
`;

const NavStickyWrapper = styled.div`
display: flex;
height: calc(100vh - ${rem(NAV_BAR_HEIGHT)});
position: sticky;
top: ${rem(NAV_BAR_HEIGHT)};
`;

const SectionsWrapper = styled.div`
/* flex-basis needs to be set or contents may overflow in IE 11 */
flex: 1 1 100%;
Expand All @@ -56,51 +39,32 @@ type NarrativeLayoutProps = {
};

const NarrativeLayout: React.FC<NarrativeLayoutProps> = ({ sections }) => {
const showSectionNavigation = useBreakpoint(true, ["mobile-", false]);

const {
alwaysExpanded,
currentSectionNumber,
enableSnapping,
fixedHeightSections,
scrollToSection,
sectionsContainerRef,
getOnSectionExpanded,
onSectionInViewChange,
} = useInternalNavigation();

return (
<Wrapper>
{showSectionNavigation && (
<NavWrapper>
<Sticker>
<NavStickyWrapper>
<NarrativeNavigation
activeSection={currentSectionNumber}
goToSection={scrollToSection}
sections={sections}
/>
</NavStickyWrapper>
</Sticker>
</NavWrapper>
)}
<Wayfinder
activeSection={currentSectionNumber}
sections={sections}
goToSection={scrollToSection}
/>
<SectionsWrapper ref={sectionsContainerRef}>
{sections.map((section, index) => {
// 1-indexed for human readability
const sectionNumber = index + 1;

return (
<div
id={`section${sectionNumber}`}
key={sectionNumber}
style={{
scrollSnapAlign: enableSnapping ? "start" : undefined,
}}
>
<div id={`section${sectionNumber}`} key={sectionNumber}>
<NarrativeSection
alwaysExpanded={alwaysExpanded}
onInViewChange={onSectionInViewChange}
onSectionExpanded={getOnSectionExpanded(sectionNumber)}
restrictHeight={fixedHeightSections.includes(sectionNumber)}
sectionNumber={sectionNumber}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,45 +15,55 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =============================================================================

import { rem } from "polished";
import React, { useState } from "react";
import styled from "styled-components/macro";
import { Icon, IconSVG } from "@recidiviz/design-system";
import React, { useState, useEffect } from "react";
import { track } from "../../analytics";
import { colors, Chevron, UnStyledButton } from "../../UiLibrary";
import { SectionNavProps } from "./types";

const NavLink = styled(UnStyledButton)`
padding: ${rem(8)};
`;
import { Button } from "./Wayfinder";

type AdvanceLinkProps = SectionNavProps & {
disabled: boolean;
type: "previous" | "next";
flashing?: boolean;
};

const AdvanceLink: React.FC<AdvanceLinkProps> = ({
activeSection,
disabled,
goToSection,
type,
flashing,
}) => {
const [isFlashing, setFlashing] = useState(false);

useEffect(() => {
const timer = setTimeout(() => {
setFlashing(true);
}, 5000);

return () => {
clearTimeout(timer);
setFlashing(false);
};
}, [activeSection]);

let targetSection: number;
let direction: "up" | "down";
let rotate: 0 | 180;

if (type === "previous") {
targetSection = activeSection - 1;
direction = "up";
rotate = 180;
} else {
targetSection = activeSection + 1;
direction = "down";
rotate = 0;
}

const [hovered, setHovered] = useState(false);

const color = hovered && !disabled ? colors.accent : undefined;

return (
<NavLink
<Button
rounded
kind="borderless"
active={!disabled && flashing && isFlashing}
flashing={!disabled && flashing && isFlashing}
disabled={disabled}
onClick={() => {
if (!disabled) {
Expand All @@ -65,14 +75,14 @@ const AdvanceLink: React.FC<AdvanceLinkProps> = ({
}
}}
aria-label={`${type} section`}
onMouseOver={() => setHovered(true)}
onFocus={() => setHovered(true)}
onMouseOut={() => setHovered(false)}
onBlur={() => setHovered(false)}
>
<Chevron direction={direction} faded={disabled} color={color} />
</NavLink>
<Icon
kind={IconSVG.Arrow}
width={20}
rotate={rotate}
style={{ rotate: `${rotate}deg` }}
/>
</Button>
);
};

export default AdvanceLink;

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Recidiviz - a data platform for criminal justice reform
// Copyright (C) 2022 Recidiviz, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
// =============================================================================

import React, { useState, useEffect, useCallback } from "react";
import styled from "styled-components/macro";
import { rem } from "polished";
import { FOOTER_HEIGHT, PROGRESS_BAR_HEIGHT } from "../../constants";
import { colors } from "../../UiLibrary";

const Container = styled.div`
background: ${colors.checkbox};
height: ${rem(PROGRESS_BAR_HEIGHT)};
width: 100%;
`;

const Bar = styled.div<{ scrolled: number }>`
background: ${colors.link};
height: ${rem(PROGRESS_BAR_HEIGHT)};
max-width: 100%;
width: ${(props) => props.scrolled}%;
transition: width 0.5s ease;
`;

const ProgressBar: React.FC<{
percent?: number;
onScroll: (scrolled: number) => void;
}> = ({ percent, onScroll }) => {
const [scrolledPercent, setScrolled] = useState(0);

const scrollProgress = useCallback(() => {
const scrollPx = document.documentElement.scrollTop;
const winHeightPx =
document.documentElement.scrollHeight -
document.documentElement.clientHeight -
FOOTER_HEIGHT;
const scrolled = (scrollPx / winHeightPx) * 100;
setScrolled(scrolled);
onScroll(scrolled);
}, [onScroll]);

useEffect(() => {
window.addEventListener("scroll", scrollProgress);

return () => {
window.removeEventListener("scroll", scrollProgress);
};
});

return (
<Container>
<Bar scrolled={percent || scrolledPercent} />
</Container>
);
};

export default ProgressBar;
Loading

0 comments on commit 5c8be2f

Please sign in to comment.