Skip to content

Commit

Permalink
feat: optimize link component
Browse files Browse the repository at this point in the history
  • Loading branch information
sanyuan0704 committed Jan 3, 2023
1 parent ed8f445 commit 1625802
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 22 deletions.
2 changes: 2 additions & 0 deletions packages/island/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"lodash-es": "4.17.21",
"mdast-util-mdxjs-esm": "1.3.0",
"medium-zoom": "1.0.6",
"nprogress": "^0.2.0",
"ora": "6.1.2",
"picocolors": "1.0.0",
"polka": "0.5.2",
Expand Down Expand Up @@ -117,6 +118,7 @@
"@types/koa": "^2.13.5",
"@types/koa-router": "^7.4.4",
"@types/lodash-es": "^4.17.6",
"@types/nprogress": "^0.2.0",
"@types/polka": "^0.5.4",
"@types/react": "^18.0.17",
"@types/react-dom": "^18.0.6",
Expand Down
15 changes: 2 additions & 13 deletions packages/island/src/runtime/Content.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,8 @@
import { useRoutes, useLocation } from 'react-router-dom';
import { useRoutes } from 'react-router-dom';
import { routes } from 'virtual:routes';
import { Suspense } from 'react';

interface LocationState {
from?: string;
}

export const Content = () => {
const routesElement = useRoutes(routes);
const location = useLocation();
let prevRouteElement: React.ReactNode = null;
if (import.meta.env.ENABLE_SPA) {
const prevRoute = (location.state as LocationState)?.from;
// eslint-disable-next-line react-hooks/rules-of-hooks
prevRouteElement = prevRoute ? useRoutes(routes, prevRoute) : null;
}
return <Suspense fallback={prevRouteElement}>{routesElement}</Suspense>;
return <Suspense fallback={null}>{routesElement}</Suspense>;
};
4 changes: 4 additions & 0 deletions packages/island/src/runtime/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,8 @@ export function normalizeHref(url?: string) {
return addLeadingSlash(`${url}${suffix}`);
}

export function normalizeRoutePath(routePath: string) {
return routePath.replace(/\.html$/, '').replace(/\/index$/, '/');
}

export { addLeadingSlash, removeTrailingSlash, normalizeSlash };
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ export function Aside(
}, [headers]);
}
useEffect(() => {
console.log(props.headers);
setHeaders(props.headers);
}, [props.headers, setHeaders, props.pagePath]);

Expand Down
40 changes: 32 additions & 8 deletions packages/island/src/theme-default/components/Link/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,25 @@
import React from 'react';
import styles from './index.module.scss';
import { Link as RouterLink } from 'react-router-dom';
import { withBase } from '@runtime';
import {
matchRoutes,
normalizeRoutePath,
useNavigate,
withBase
} from '@runtime';
import { TARGET_BLANK_WHITE_LIST } from '@shared/constants';
import { inBrowser } from '@shared/utils';
import { EXTERNAL_URL_RE } from '@shared/constants';
import nprogress from 'nprogress';
import { routes } from 'virtual:routes';
import { Route } from 'node/plugin-routes';

export interface LinkProps {
href?: string;
children?: React.ReactNode;
className?: string;
}

nprogress.configure({ showSpinner: false });

export function Link(props: LinkProps) {
const { href = '/', children, className = '' } = props;
const isExternal = EXTERNAL_URL_RE.test(href);
Expand All @@ -20,19 +28,35 @@ export function Link(props: LinkProps) {
);
const target = isExternal && !isWhiteList ? '_blank' : '';
const rel = isExternal ? 'noopener noreferrer' : undefined;
const pathname = inBrowser() ? window.location.pathname : '';
const withBaseUrl = isExternal ? href : withBase(href);
const navigate = useNavigate();

const handleNavigate = async (
e: React.MouseEvent<HTMLAnchorElement, MouseEvent>
) => {
e.preventDefault();
const matchedRoutes = matchRoutes(routes, normalizeRoutePath(withBaseUrl));
if (matchedRoutes?.length) {
const timer = setTimeout(() => {
nprogress.start();
}, 200);
await (matchedRoutes[0].route as Route).preload();
clearTimeout(timer);
nprogress.done();
}
navigate(withBaseUrl, { replace: false });
};
if (import.meta.env.ENABLE_SPA && !isExternal) {
return (
<RouterLink
<a
className={`${styles.link} ${className}`}
to={withBaseUrl}
rel={rel}
target={target}
state={{ from: pathname }}
onClick={handleNavigate}
cursor="pointer"
>
{children}
</RouterLink>
</a>
);
} else {
return (
Expand Down
1 change: 1 addition & 0 deletions packages/island/src/theme-default/layout/Layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { DocLayoutProps } from '../DocLayout/index';
import { HomeLayoutProps } from '../HomeLayout/index';
import type { NavProps } from '../../components/Nav/index';
import { BackTop } from '@back-top';
import 'nprogress/nprogress.css';
import 'virtual:custom-styles';

export type LayoutProps = {
Expand Down
9 changes: 9 additions & 0 deletions packages/island/src/theme-default/styles/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,12 @@ fieldset {
.medium-zoom-image--opened {
z-index: 999;
}

#nprogress .bar {
background: var(--island-c-brand);
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 2px;
}
12 changes: 12 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 1625802

Please sign in to comment.