mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2026-01-15 08:22:59 -05:00
add accessible skip-to-content link
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import commaNumber from "comma-number";
|
import commaNumber from "comma-number";
|
||||||
import Loading from "../Loading";
|
import Loading from "../Loading";
|
||||||
import { fetcher } from "../../lib/helpers/fetcher";
|
import fetcher from "../../lib/helpers/fetcher";
|
||||||
|
|
||||||
export type HitCounterProps = {
|
export type HitCounterProps = {
|
||||||
slug: string;
|
slug: string;
|
||||||
|
|||||||
@@ -34,6 +34,35 @@ const FlexedFooter = styled(Footer, {
|
|||||||
flex: 1,
|
flex: 1,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const SkipNavLink = styled("a", {
|
||||||
|
// accessible invisibility stuff pulled from @reach/skip-nav:
|
||||||
|
// https://github.com/reach/reach-ui/blob/main/packages/skip-nav/styles.css
|
||||||
|
border: 0,
|
||||||
|
clip: "rect(0 0 0 0)",
|
||||||
|
height: "1px",
|
||||||
|
width: "1px",
|
||||||
|
margin: "-1px",
|
||||||
|
padding: 0,
|
||||||
|
overflow: "hidden",
|
||||||
|
position: "absolute",
|
||||||
|
|
||||||
|
"&:focus": {
|
||||||
|
padding: "1rem",
|
||||||
|
position: "fixed",
|
||||||
|
top: "10px",
|
||||||
|
left: "10px",
|
||||||
|
zIndex: 99999,
|
||||||
|
width: "auto",
|
||||||
|
height: "auto",
|
||||||
|
clip: "auto",
|
||||||
|
background: "$superDuperLight",
|
||||||
|
color: "$link",
|
||||||
|
border: "2px solid $kindaLight",
|
||||||
|
borderRadius: "$rounded",
|
||||||
|
textDecoration: "underline",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export type LayoutProps = ComponentProps<typeof Flex> & {
|
export type LayoutProps = ComponentProps<typeof Flex> & {
|
||||||
container?: boolean; // pass false to disable default `<main>` container styles with padding, etc.
|
container?: boolean; // pass false to disable default `<main>` container styles with padding, etc.
|
||||||
};
|
};
|
||||||
@@ -48,16 +77,26 @@ const Layout = ({ container = true, children, ...rest }: LayoutProps) => {
|
|||||||
<meta name="theme-color" content={themeColors[activeTheme === "dark" ? "dark" : "light"]} />
|
<meta name="theme-color" content={themeColors[activeTheme === "dark" ? "dark" : "light"]} />
|
||||||
</Head>
|
</Head>
|
||||||
|
|
||||||
|
<SkipNavLink href="#skip-nav" role="link" tabIndex={0}>
|
||||||
|
Skip to content
|
||||||
|
</SkipNavLink>
|
||||||
|
|
||||||
<Flex {...rest}>
|
<Flex {...rest}>
|
||||||
<StickyHeader />
|
<StickyHeader />
|
||||||
|
|
||||||
{/* passing `container={false}` to Layout allows 100% control of the content area on a per-page basis */}
|
{/* passing `container={false}` to Layout allows 100% control of the content area on a per-page basis */}
|
||||||
{container ? (
|
{container ? (
|
||||||
<Default>
|
<Default>
|
||||||
<Container>{children}</Container>
|
<Container>
|
||||||
|
<div id="skip-nav" />
|
||||||
|
{children}
|
||||||
|
</Container>
|
||||||
</Default>
|
</Default>
|
||||||
) : (
|
) : (
|
||||||
<>{children}</>
|
<>
|
||||||
|
<div id="skip-nav" />
|
||||||
|
{children}
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<FlexedFooter />
|
<FlexedFooter />
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import { ErrorBoundary } from "react-error-boundary";
|
|
||||||
import NextLink from "next/link";
|
import NextLink from "next/link";
|
||||||
import Time from "../Time";
|
import Time from "../Time";
|
||||||
import HitCounter from "../HitCounter";
|
import HitCounter from "../HitCounter";
|
||||||
@@ -107,17 +106,15 @@ const NoteMeta = ({ slug, date, title, htmlTitle, tags = [] }: NoteMetaProps) =>
|
|||||||
|
|
||||||
{/* only count hits on production site */}
|
{/* only count hits on production site */}
|
||||||
{process.env.NEXT_PUBLIC_VERCEL_ENV === "production" && (
|
{process.env.NEXT_PUBLIC_VERCEL_ENV === "production" && (
|
||||||
<ErrorBoundary fallback={null}>
|
<MetaItem
|
||||||
<MetaItem
|
// fix potential layout shift when number of hits loads
|
||||||
// fix potential layout shift when number of hits loads
|
css={{ minWidth: "7em", marginRight: 0 }}
|
||||||
css={{ minWidth: "7em", marginRight: 0 }}
|
>
|
||||||
>
|
<span>
|
||||||
<span>
|
<Icon as={ViewsIcon} />
|
||||||
<Icon as={ViewsIcon} />
|
</span>
|
||||||
</span>
|
<HitCounter slug={`notes/${slug}`} />
|
||||||
<HitCounter slug={`notes/${slug}`} />
|
</MetaItem>
|
||||||
</MetaItem>
|
|
||||||
</ErrorBoundary>
|
|
||||||
)}
|
)}
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
|
|
||||||
|
|||||||
@@ -3,5 +3,10 @@
|
|||||||
// note: fetch does *not* need to be poly/ponyfilled in Next.js:
|
// note: fetch does *not* need to be poly/ponyfilled in Next.js:
|
||||||
// https://nextjs.org/blog/next-9-1-7#new-built-in-polyfills-fetch-url-and-objectassign
|
// https://nextjs.org/blog/next-9-1-7#new-built-in-polyfills-fetch-url-and-objectassign
|
||||||
|
|
||||||
// eslint-disable-next-line no-undef
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
export const fetcher = (url: RequestInfo) => fetch(url).then((res) => res.json());
|
const fetcher = async (input: RequestInfo, init?: RequestInit): Promise<any> => {
|
||||||
|
const res = await fetch(input, init);
|
||||||
|
return res.json();
|
||||||
|
};
|
||||||
|
|
||||||
|
export default fetcher;
|
||||||
|
|||||||
@@ -90,8 +90,8 @@
|
|||||||
"@types/remove-markdown": "^0.3.1",
|
"@types/remove-markdown": "^0.3.1",
|
||||||
"@types/sanitize-html": "^2.6.2",
|
"@types/sanitize-html": "^2.6.2",
|
||||||
"@types/uglify-js": "^3.13.2",
|
"@types/uglify-js": "^3.13.2",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.26.0",
|
"@typescript-eslint/eslint-plugin": "^5.27.0",
|
||||||
"@typescript-eslint/parser": "^5.26.0",
|
"@typescript-eslint/parser": "^5.27.0",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"eslint": "~8.16.0",
|
"eslint": "~8.16.0",
|
||||||
"eslint-config-next": "12.1.7-canary.24",
|
"eslint-config-next": "12.1.7-canary.24",
|
||||||
|
|||||||
102
yarn.lock
102
yarn.lock
@@ -1754,14 +1754,14 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d"
|
resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d"
|
||||||
integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==
|
integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==
|
||||||
|
|
||||||
"@typescript-eslint/eslint-plugin@^5.26.0":
|
"@typescript-eslint/eslint-plugin@^5.27.0":
|
||||||
version "5.26.0"
|
version "5.27.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.26.0.tgz#c1f98ccba9d345e38992975d3ca56ed6260643c2"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.27.0.tgz#23d82a4f21aaafd8f69dbab7e716323bb6695cc8"
|
||||||
integrity sha512-oGCmo0PqnRZZndr+KwvvAUvD3kNE4AfyoGCwOZpoCncSh4MVD06JTE8XQa2u9u+NX5CsyZMBTEc2C72zx38eYA==
|
integrity sha512-DDrIA7GXtmHXr1VCcx9HivA39eprYBIFxbQEHI6NyraRDxCGpxAFiYQAT/1Y0vh1C+o2vfBiy4IuPoXxtTZCAQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/scope-manager" "5.26.0"
|
"@typescript-eslint/scope-manager" "5.27.0"
|
||||||
"@typescript-eslint/type-utils" "5.26.0"
|
"@typescript-eslint/type-utils" "5.27.0"
|
||||||
"@typescript-eslint/utils" "5.26.0"
|
"@typescript-eslint/utils" "5.27.0"
|
||||||
debug "^4.3.4"
|
debug "^4.3.4"
|
||||||
functional-red-black-tree "^1.0.1"
|
functional-red-black-tree "^1.0.1"
|
||||||
ignore "^5.2.0"
|
ignore "^5.2.0"
|
||||||
@@ -1769,69 +1769,69 @@
|
|||||||
semver "^7.3.7"
|
semver "^7.3.7"
|
||||||
tsutils "^3.21.0"
|
tsutils "^3.21.0"
|
||||||
|
|
||||||
"@typescript-eslint/parser@^5.21.0", "@typescript-eslint/parser@^5.26.0":
|
"@typescript-eslint/parser@^5.21.0", "@typescript-eslint/parser@^5.27.0":
|
||||||
version "5.26.0"
|
version "5.27.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.26.0.tgz#a61b14205fe2ab7533deb4d35e604add9a4ceee2"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.27.0.tgz#62bb091ed5cf9c7e126e80021bb563dcf36b6b12"
|
||||||
integrity sha512-n/IzU87ttzIdnAH5vQ4BBDnLPly7rC5VnjN3m0xBG82HK6rhRxnCb3w/GyWbNDghPd+NktJqB/wl6+YkzZ5T5Q==
|
integrity sha512-8oGjQF46c52l7fMiPPvX4It3u3V3JipssqDfHQ2hcR0AeR8Zge+OYyKUCm5b70X72N1qXt0qgHenwN6Gc2SXZA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/scope-manager" "5.26.0"
|
"@typescript-eslint/scope-manager" "5.27.0"
|
||||||
"@typescript-eslint/types" "5.26.0"
|
"@typescript-eslint/types" "5.27.0"
|
||||||
"@typescript-eslint/typescript-estree" "5.26.0"
|
"@typescript-eslint/typescript-estree" "5.27.0"
|
||||||
debug "^4.3.4"
|
debug "^4.3.4"
|
||||||
|
|
||||||
"@typescript-eslint/scope-manager@5.26.0":
|
"@typescript-eslint/scope-manager@5.27.0":
|
||||||
version "5.26.0"
|
version "5.27.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.26.0.tgz#44209c7f649d1a120f0717e0e82da856e9871339"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.27.0.tgz#a272178f613050ed62f51f69aae1e19e870a8bbb"
|
||||||
integrity sha512-gVzTJUESuTwiju/7NiTb4c5oqod8xt5GhMbExKsCTp6adU3mya6AGJ4Pl9xC7x2DX9UYFsjImC0mA62BCY22Iw==
|
integrity sha512-VnykheBQ/sHd1Vt0LJ1JLrMH1GzHO+SzX6VTXuStISIsvRiurue/eRkTqSrG0CexHQgKG8shyJfR4o5VYioB9g==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/types" "5.26.0"
|
"@typescript-eslint/types" "5.27.0"
|
||||||
"@typescript-eslint/visitor-keys" "5.26.0"
|
"@typescript-eslint/visitor-keys" "5.27.0"
|
||||||
|
|
||||||
"@typescript-eslint/type-utils@5.26.0":
|
"@typescript-eslint/type-utils@5.27.0":
|
||||||
version "5.26.0"
|
version "5.27.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.26.0.tgz#937dee97702361744a3815c58991acf078230013"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.27.0.tgz#36fd95f6747412251d79c795b586ba766cf0974b"
|
||||||
integrity sha512-7ccbUVWGLmcRDSA1+ADkDBl5fP87EJt0fnijsMFTVHXKGduYMgienC/i3QwoVhDADUAPoytgjbZbCOMj4TY55A==
|
integrity sha512-vpTvRRchaf628Hb/Xzfek+85o//zEUotr1SmexKvTfs7czXfYjXVT/a5yDbpzLBX1rhbqxjDdr1Gyo0x1Fc64g==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/utils" "5.26.0"
|
"@typescript-eslint/utils" "5.27.0"
|
||||||
debug "^4.3.4"
|
debug "^4.3.4"
|
||||||
tsutils "^3.21.0"
|
tsutils "^3.21.0"
|
||||||
|
|
||||||
"@typescript-eslint/types@5.26.0":
|
"@typescript-eslint/types@5.27.0":
|
||||||
version "5.26.0"
|
version "5.27.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.26.0.tgz#cb204bb154d3c103d9cc4d225f311b08219469f3"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.27.0.tgz#c3f44b9dda6177a9554f94a74745ca495ba9c001"
|
||||||
integrity sha512-8794JZFE1RN4XaExLWLI2oSXsVImNkl79PzTOOWt9h0UHROwJedNOD2IJyfL0NbddFllcktGIO2aOu10avQQyA==
|
integrity sha512-lY6C7oGm9a/GWhmUDOs3xAVRz4ty/XKlQ2fOLr8GAIryGn0+UBOoJDWyHer3UgrHkenorwvBnphhP+zPmzmw0A==
|
||||||
|
|
||||||
"@typescript-eslint/typescript-estree@5.26.0":
|
"@typescript-eslint/typescript-estree@5.27.0":
|
||||||
version "5.26.0"
|
version "5.27.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.26.0.tgz#16cbceedb0011c2ed4f607255f3ee1e6e43b88c3"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.27.0.tgz#7965f5b553c634c5354a47dcce0b40b94611e995"
|
||||||
integrity sha512-EyGpw6eQDsfD6jIqmXP3rU5oHScZ51tL/cZgFbFBvWuCwrIptl+oueUZzSmLtxFuSOQ9vDcJIs+279gnJkfd1w==
|
integrity sha512-QywPMFvgZ+MHSLRofLI7BDL+UczFFHyj0vF5ibeChDAJgdTV8k4xgEwF0geFhVlPc1p8r70eYewzpo6ps+9LJQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/types" "5.26.0"
|
"@typescript-eslint/types" "5.27.0"
|
||||||
"@typescript-eslint/visitor-keys" "5.26.0"
|
"@typescript-eslint/visitor-keys" "5.27.0"
|
||||||
debug "^4.3.4"
|
debug "^4.3.4"
|
||||||
globby "^11.1.0"
|
globby "^11.1.0"
|
||||||
is-glob "^4.0.3"
|
is-glob "^4.0.3"
|
||||||
semver "^7.3.7"
|
semver "^7.3.7"
|
||||||
tsutils "^3.21.0"
|
tsutils "^3.21.0"
|
||||||
|
|
||||||
"@typescript-eslint/utils@5.26.0":
|
"@typescript-eslint/utils@5.27.0":
|
||||||
version "5.26.0"
|
version "5.27.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.26.0.tgz#896b8480eb124096e99c8b240460bb4298afcfb4"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.27.0.tgz#d0021cbf686467a6a9499bd0589e19665f9f7e71"
|
||||||
integrity sha512-PJFwcTq2Pt4AMOKfe3zQOdez6InIDOjUJJD3v3LyEtxHGVVRK3Vo7Dd923t/4M9hSH2q2CLvcTdxlLPjcIk3eg==
|
integrity sha512-nZvCrkIJppym7cIbP3pOwIkAefXOmfGPnCM0LQfzNaKxJHI6VjI8NC662uoiPlaf5f6ymkTy9C3NQXev2mdXmA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@types/json-schema" "^7.0.9"
|
"@types/json-schema" "^7.0.9"
|
||||||
"@typescript-eslint/scope-manager" "5.26.0"
|
"@typescript-eslint/scope-manager" "5.27.0"
|
||||||
"@typescript-eslint/types" "5.26.0"
|
"@typescript-eslint/types" "5.27.0"
|
||||||
"@typescript-eslint/typescript-estree" "5.26.0"
|
"@typescript-eslint/typescript-estree" "5.27.0"
|
||||||
eslint-scope "^5.1.1"
|
eslint-scope "^5.1.1"
|
||||||
eslint-utils "^3.0.0"
|
eslint-utils "^3.0.0"
|
||||||
|
|
||||||
"@typescript-eslint/visitor-keys@5.26.0":
|
"@typescript-eslint/visitor-keys@5.27.0":
|
||||||
version "5.26.0"
|
version "5.27.0"
|
||||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.26.0.tgz#7195f756e367f789c0e83035297c45b417b57f57"
|
resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.27.0.tgz#97aa9a5d2f3df8215e6d3b77f9d214a24db269bd"
|
||||||
integrity sha512-wei+ffqHanYDOQgg/fS6Hcar6wAWv0CUPQ3TZzOWd2BLfgP539rb49bwua8WRAs7R6kOSLn82rfEu2ro6Llt8Q==
|
integrity sha512-46cYrteA2MrIAjv9ai44OQDUoCZyHeGIc4lsjCUX2WT6r4C+kidz1bNiR4017wHOPUythYeH+Sc7/cFP97KEAA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@typescript-eslint/types" "5.26.0"
|
"@typescript-eslint/types" "5.27.0"
|
||||||
eslint-visitor-keys "^3.3.0"
|
eslint-visitor-keys "^3.3.0"
|
||||||
|
|
||||||
"@xobotyi/scrollbar-width@^1.9.5":
|
"@xobotyi/scrollbar-width@^1.9.5":
|
||||||
@@ -2589,9 +2589,9 @@ eastasianwidth@^0.2.0:
|
|||||||
integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
|
integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
|
||||||
|
|
||||||
electron-to-chromium@^1.4.118:
|
electron-to-chromium@^1.4.118:
|
||||||
version "1.4.141"
|
version "1.4.142"
|
||||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.141.tgz#4dd9119e8a99f1c83c51dfcf1bed79ea541f08d6"
|
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.142.tgz#70cc8871f7c0122b29256089989e67cee637b40d"
|
||||||
integrity sha512-mfBcbqc0qc6RlxrsIgLG2wCqkiPAjEezHxGTu7p3dHHFOurH4EjS9rFZndX5axC8264rI1Pcbw8uQP39oZckeA==
|
integrity sha512-ea8Q1YX0JRp4GylOmX4gFHIizi0j9GfRW4EkaHnkZp0agRCBB4ZGeCv17IEzIvBkiYVwfoKVhKZJbTfqCRdQdg==
|
||||||
|
|
||||||
emoji-regex@^8.0.0:
|
emoji-regex@^8.0.0:
|
||||||
version "8.0.0"
|
version "8.0.0"
|
||||||
@@ -4246,7 +4246,7 @@ mdn-data@2.0.14:
|
|||||||
mdurl@^1.0.0:
|
mdurl@^1.0.0:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
|
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
|
||||||
integrity sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=
|
integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==
|
||||||
|
|
||||||
memoize-one@^5.1.1:
|
memoize-one@^5.1.1:
|
||||||
version "5.2.1"
|
version "5.2.1"
|
||||||
|
|||||||
Reference in New Issue
Block a user