Compare commits
No commits in common. "75325472b8aa803699adbd08dbc184ee7989e607" and "34993f7f61ab443e0bf64301e8f00a4ff7c73bce" have entirely different histories.
75325472b8
...
34993f7f61
@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useRef } from "react";
|
import React from "react";
|
||||||
import { defineMessages, useIntl } from "react-intl";
|
import { defineMessages, useIntl } from "react-intl";
|
||||||
|
|
||||||
import { CONTACT_EMAIL, CONTACT_PHONE } from "../../config/environment";
|
import { CONTACT_EMAIL, CONTACT_PHONE } from "../../config/environment";
|
||||||
@ -30,85 +30,10 @@ const messages = defineMessages({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const getTopOffset = (input: HTMLElement) => {
|
|
||||||
let el: HTMLElement | Element | null = input;
|
|
||||||
let o = 0;
|
|
||||||
do {
|
|
||||||
if (!(el instanceof HTMLElement)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isNaN(el.offsetTop)) {
|
|
||||||
o += el.offsetTop;
|
|
||||||
}
|
|
||||||
} while ((el = el.offsetParent));
|
|
||||||
|
|
||||||
return o;
|
|
||||||
};
|
|
||||||
|
|
||||||
const MainNavigation: React.FC = () => {
|
const MainNavigation: React.FC = () => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const ref = useRef<HTMLDivElement>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
const d = ref.current;
|
|
||||||
if (!d) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let { height } = d.getBoundingClientRect();
|
|
||||||
|
|
||||||
const ro = new ResizeObserver((entries) => {
|
|
||||||
if (entries[0]) {
|
|
||||||
height = entries[0].contentRect.height;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
ro.observe(d);
|
|
||||||
|
|
||||||
let scrollPrev = window.scrollY;
|
|
||||||
|
|
||||||
const listener = () => {
|
|
||||||
const down = scrollPrev < window.scrollY;
|
|
||||||
scrollPrev = window.scrollY;
|
|
||||||
const top = getTopOffset(d);
|
|
||||||
|
|
||||||
if (window.innerHeight > height) {
|
|
||||||
d.style.marginTop = `${Math.max(window.scrollY, 0)}px`;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (down) {
|
|
||||||
const delta = top + height;
|
|
||||||
const wDelta = window.scrollY + window.innerHeight;
|
|
||||||
|
|
||||||
const diff = wDelta - delta;
|
|
||||||
if (diff > 0) {
|
|
||||||
const sizeDelta = Math.min(window.innerHeight - height, 0);
|
|
||||||
d.style.marginTop = `${Math.max(top + diff + sizeDelta, 0)}px`;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const delta = top;
|
|
||||||
const wDelta = window.scrollY;
|
|
||||||
|
|
||||||
const diff = wDelta - delta;
|
|
||||||
if (diff < 0) {
|
|
||||||
d.style.marginTop = `${Math.max(top + diff, 0)}px`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
window.addEventListener("scroll", listener);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
window.removeEventListener("scroll", listener);
|
|
||||||
ro.disconnect();
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={ref}>
|
<>
|
||||||
<NavigationHeadline>
|
<NavigationHeadline>
|
||||||
{intl.formatMessage(messages.contact)}
|
{intl.formatMessage(messages.contact)}
|
||||||
</NavigationHeadline>
|
</NavigationHeadline>
|
||||||
@ -117,11 +42,11 @@ const MainNavigation: React.FC = () => {
|
|||||||
|
|
||||||
<Contact email={CONTACT_EMAIL} phoneNumber={CONTACT_PHONE} />
|
<Contact email={CONTACT_EMAIL} phoneNumber={CONTACT_PHONE} />
|
||||||
|
|
||||||
<NavigationHeadline href="#objective">
|
<NavigationHeadline to="#objective">
|
||||||
{intl.formatMessage(messages.objective)}
|
{intl.formatMessage(messages.objective)}
|
||||||
</NavigationHeadline>
|
</NavigationHeadline>
|
||||||
|
|
||||||
<NavigationHeadline href="#skills">
|
<NavigationHeadline to="#skills">
|
||||||
{intl.formatMessage(messages.topSkills)}
|
{intl.formatMessage(messages.topSkills)}
|
||||||
</NavigationHeadline>
|
</NavigationHeadline>
|
||||||
|
|
||||||
@ -138,7 +63,7 @@ const MainNavigation: React.FC = () => {
|
|||||||
|
|
||||||
<Spacer spacing={0} withDivider />
|
<Spacer spacing={0} withDivider />
|
||||||
|
|
||||||
<NavigationHeadline>
|
<NavigationHeadline to="#certifications">
|
||||||
{intl.formatMessage(messages.certifications)}
|
{intl.formatMessage(messages.certifications)}
|
||||||
</NavigationHeadline>
|
</NavigationHeadline>
|
||||||
|
|
||||||
@ -151,10 +76,10 @@ const MainNavigation: React.FC = () => {
|
|||||||
|
|
||||||
<Spacer spacing={0} withDivider />
|
<Spacer spacing={0} withDivider />
|
||||||
|
|
||||||
<NavigationHeadline href="#experience">
|
<NavigationHeadline to="#experience">
|
||||||
{intl.formatMessage(messages.experience)}
|
{intl.formatMessage(messages.experience)}
|
||||||
</NavigationHeadline>
|
</NavigationHeadline>
|
||||||
</div>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -15,25 +15,17 @@ const Link = styled(RouterLink)({
|
|||||||
textDecoration: "none",
|
textDecoration: "none",
|
||||||
});
|
});
|
||||||
|
|
||||||
type NavigationHeadlineProps =
|
type NavigationHeadlineProps = Partial<Pick<RouterLinkProps, "to">>;
|
||||||
| (Partial<Pick<RouterLinkProps, "to">> & {
|
|
||||||
href?: undefined;
|
|
||||||
})
|
|
||||||
| {
|
|
||||||
href?: string;
|
|
||||||
to?: undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
const NavigationHeadline: React.FC<
|
const NavigationHeadline: React.FC<
|
||||||
React.PropsWithChildren<NavigationHeadlineProps>
|
React.PropsWithChildren<NavigationHeadlineProps>
|
||||||
> = (props) => {
|
> = (props) => {
|
||||||
const { children, href, to } = props;
|
const { children, to } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Headline>
|
<Headline>
|
||||||
{to && <Link to={to}>{children}</Link>}
|
{to && <Link to={to}>{children}</Link>}
|
||||||
{href && <a href={href}>{children}</a>}
|
{!to && children}
|
||||||
{!to && !href && children}
|
|
||||||
</Headline>
|
</Headline>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import styled from "@emotion/styled";
|
import styled from "@emotion/styled";
|
||||||
|
|
||||||
const Caption = styled("div")(({ theme }) => ({
|
const Caption = styled("caption")(({ theme }) => ({
|
||||||
color: theme.palette.text.secondary,
|
color: theme.palette.text.secondary,
|
||||||
fontSize: "0.75rem",
|
fontSize: "0.75rem",
|
||||||
lineHeight: 1.5,
|
lineHeight: 1.5,
|
||||||
|
|||||||
@ -55,7 +55,7 @@ const Dashboard: React.FC = () => {
|
|||||||
<Summary />
|
<Summary />
|
||||||
</Content>
|
</Content>
|
||||||
|
|
||||||
<div id="skills" />
|
<div id="experience" />
|
||||||
<Spacer withDivider />
|
<Spacer withDivider />
|
||||||
|
|
||||||
<Headline level={2}>{intl.formatMessage(messages.skillsTitle)}</Headline>
|
<Headline level={2}>{intl.formatMessage(messages.skillsTitle)}</Headline>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user