mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2025-04-26 15:28:28 -04:00
73 lines
2.1 KiB
TypeScript
73 lines
2.1 KiB
TypeScript
import innerText from "react-innertext";
|
|
import HeadingAnchor from "../HeadingAnchor/HeadingAnchor";
|
|
import { styled } from "../../lib/styles/stitches.config";
|
|
import type { ComponentProps } from "react";
|
|
|
|
const Anchor = styled(HeadingAnchor, {
|
|
margin: "0 0.25em",
|
|
padding: "0 0.25em",
|
|
color: "$mediumLight",
|
|
fontWeight: 300,
|
|
opacity: 0, // overridden on hover below (except on small screens)
|
|
|
|
"&:hover": {
|
|
color: "$link",
|
|
},
|
|
|
|
// don't require hover to show anchor link on small (likely touch) screens
|
|
"@medium": {
|
|
opacity: 1,
|
|
},
|
|
});
|
|
|
|
const H = styled("h1", {
|
|
marginTop: "1em",
|
|
marginBottom: "0.5em",
|
|
lineHeight: 1.5,
|
|
|
|
// offset (approximately) with sticky header so jumped-to content isn't hiding behind it.
|
|
// note: use rem so it isn't based on the heading's font size.
|
|
scrollMarginTop: "5.5rem",
|
|
|
|
"@medium": {
|
|
scrollMarginTop: "6.5rem",
|
|
},
|
|
|
|
[`&:hover ${Anchor}`]: {
|
|
opacity: 1,
|
|
},
|
|
|
|
variants: {
|
|
underline: {
|
|
true: {
|
|
paddingBottom: "0.25em",
|
|
borderBottom: "1px solid $kindaLight",
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
export type HeadingProps = ComponentProps<typeof H> & {
|
|
as: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
|
|
};
|
|
|
|
const Heading = ({ as, id, children, ...rest }: HeadingProps) => {
|
|
return (
|
|
<H as={as} underline={as === "h2"} id={id} {...rest}>
|
|
{children}
|
|
|
|
{/* add anchor link to H2s and H3s. ID is already generated by rehype-slug. `#` character inserted via CSS. */}
|
|
{id && (as === "h2" || as === "h3") && <Anchor id={id} title={innerText(children)} />}
|
|
</H>
|
|
);
|
|
};
|
|
|
|
export const H1 = (props: Omit<HeadingProps, "as">) => <Heading as="h1" {...props} />;
|
|
export const H2 = (props: Omit<HeadingProps, "as">) => <Heading as="h2" {...props} />;
|
|
export const H3 = (props: Omit<HeadingProps, "as">) => <Heading as="h3" {...props} />;
|
|
export const H4 = (props: Omit<HeadingProps, "as">) => <Heading as="h4" {...props} />;
|
|
export const H5 = (props: Omit<HeadingProps, "as">) => <Heading as="h5" {...props} />;
|
|
export const H6 = (props: Omit<HeadingProps, "as">) => <Heading as="h6" {...props} />;
|
|
|
|
export default Heading;
|