Skip to content

Commit

Permalink
Merge pull request #357 from vordgi/rd-356
Browse files Browse the repository at this point in the history
rd-356 external mark in header and sidebar links
  • Loading branch information
vordgi authored Oct 18, 2024
2 parents 95967cc + aad300e commit deea136
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 26 deletions.
2 changes: 1 addition & 1 deletion packages/robindoc/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "robindoc",
"version": "2.2.0",
"version": "2.2.1",
"description": "",
"main": "./lib/index.js",
"scripts": {
Expand Down
12 changes: 10 additions & 2 deletions packages/robindoc/src/components/blocks/nav-link/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { usePathname } from "next/navigation";
import clsx from "clsx";

import { useNavigate } from "@src/components/contexts/navigate/use-navigate";
import { ExternalMark } from "@src/components/ui/external-mark";
import { checkIsLinkExternal } from "@src/core/utils/path-tools";

type NavLinkProps = React.AnchorHTMLAttributes<HTMLAnchorElement> &
React.PropsWithChildren<LinkProps> & {
Expand All @@ -14,14 +16,16 @@ type NavLinkProps = React.AnchorHTMLAttributes<HTMLAnchorElement> &
};

export const NavLink = forwardRef<HTMLAnchorElement, NavLinkProps>(
({ onClick, className, href, targetClassName, activeClassName, ...props }, ref) => {
({ onClick, className, href, targetClassName, activeClassName, children, ...props }, ref) => {
const { listeners } = useNavigate();
const pathname = usePathname();

const clickHandler = (e: React.MouseEvent<HTMLAnchorElement>) => {
[...listeners].forEach((el) => el.listener());
if (onClick) onClick(e);
};
const isLinkExternal = checkIsLinkExternal(href);
const additionalProps = isLinkExternal ? { target: "_blank", rel: "noopener noreferrer" } : {};

return (
<Link
Expand All @@ -33,8 +37,12 @@ export const NavLink = forwardRef<HTMLAnchorElement, NavLinkProps>(
)}
ref={ref}
onClick={clickHandler}
{...additionalProps}
{...props}
/>
>
{children}
{isLinkExternal && <ExternalMark />}
</Link>
);
},
);
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { usePathname } from "next/navigation";
import clsx from "clsx";

import { NavLink } from "@src/components/blocks/nav-link";

import { type TreeItem } from "../types";
import { checkIsTargetPathname, collectItems } from "../tools";

Expand Down
10 changes: 4 additions & 6 deletions packages/robindoc/src/components/ui/content-link/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import React from "react";
import Link, { type LinkProps } from "next/link";
import clsx from "clsx";

import { ExternalMark } from "../external-mark";

import "./content-link.scss";

export interface ContentLinkProps
Expand All @@ -12,15 +14,11 @@ export interface ContentLinkProps

export const ContentLink: React.FC<ContentLinkProps> = ({ className, external, children, ...props }) => {
const additionalProps = external ? { target: "_blank", rel: "noopener noreferrer" } : {};

return (
<Link className={clsx("r-content-link", className)} {...additionalProps} {...props}>
{children}
{external && (
<>
&nbsp;
<span className="r-content-link-external" />
</>
)}
{external && <ExternalMark />}
</Link>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
.r-external-mark {
position: relative;
vertical-align: text-top;
display: inline-block;
margin-left: -4px;
margin-right: 2px;
width: 6px;
height: 6px;

&::after {
content: "";
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
border-top: 1px solid currentColor;
border-right: 1px solid currentColor;
}

&::before {
content: "";
position: absolute;
top: 0;
right: 0;
width: 3px;
height: 3px;
background-color: currentColor;
border-radius: 0 0 0 4px;
}
}
10 changes: 10 additions & 0 deletions packages/robindoc/src/components/ui/external-mark/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from "react";

import "./external-mark.scss";

export const ExternalMark = () => (
<>
&nbsp;
<span className="r-external-mark" />
</>
);
36 changes: 19 additions & 17 deletions packages/robindoc/src/core/utils/parse-structure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { type Pages, type Crumbs, type Configuration } from "../types/content";
import { type TreeItem } from "../../components/elements/sidebar/types";
import { getConfiguration } from "./get-configuration";
import { getMeta } from "./get-meta";
import { generatePseudoTitle, normalizePathname } from "./path-tools";
import { generatePseudoTitle, checkIsLinkExternal, mergePathname, normalizePathname } from "./path-tools";
import { loadContent } from "./load-content";

const parseJSONStructure = async (
Expand All @@ -28,21 +28,23 @@ const parseJSONStructure = async (
const clientPath = normalizePathname(
segment === "index" ? parentPathname : parentPathname + "/" + segment,
);
const pathname = (parentConfiguration.basePath || "") + clientPath;
const pathname = mergePathname(parentConfiguration.basePath, clientPath);
const pathnameNormalized = normalizePathname(pathname);

const origPath = await parentConfiguration.provider?.getPageSourcePathname(
clientPath,
pathnameNormalized,
);
if (origPath) {
pages[pathnameNormalized] = {
title: data.title,
uri: clientPath,
configuration: parentConfiguration,
origPath,
crumbs,
};
if (!checkIsLinkExternal(pathnameNormalized)) {
const origPath = await parentConfiguration.provider?.getPageSourcePathname(
clientPath,
pathnameNormalized,
);
if (origPath) {
pages[pathnameNormalized] = {
title: data.title,
uri: clientPath,
configuration: parentConfiguration,
origPath,
crumbs,
};
}
}

let subTree: TreeItem[] | undefined;
Expand Down Expand Up @@ -109,7 +111,7 @@ const parseAutoStructure = async (
}

const { clientPath } = generatedItem;
const pathname = (parentConfiguration.basePath || "") + clientPath;
const pathname = mergePathname(parentConfiguration.basePath, clientPath);
const pathnameNormalized = normalizePathname(pathname);

const meta = await getMeta({ provider: parentConfiguration.provider, uri: clientPath });
Expand Down Expand Up @@ -178,10 +180,10 @@ const parseStaticStructure = async (
let subCrumbs = crumbs;
const configuration = getConfiguration(item.configuration || {}, parentConfiguration);
const clientPath = item.href;
const pathname = clientPath && configuration.basePath ? configuration.basePath + clientPath : clientPath;
const pathname = mergePathname(configuration.basePath, clientPath);
const pathnameNormalized = normalizePathname(pathname);

if (clientPath) {
if (!checkIsLinkExternal(pathnameNormalized) && clientPath) {
const origPath = await configuration.provider?.getPageSourcePathname(clientPath, pathnameNormalized);

if (origPath) {
Expand Down
9 changes: 9 additions & 0 deletions packages/robindoc/src/core/utils/path-tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,12 @@ export const generatePseudoTitle = (path?: string | null) => {
const lastSegmentWords = lastSegment.split("-");
return lastSegmentWords.map((word) => word[0].toUpperCase() + word.substring(1)).join(" ");
};

export const checkIsLinkExternal = (href: string) => {
const url = new URL(href, "http://r");
return url.host !== "r";
};

export const mergePathname = (basePath?: string, href?: string) => {
return !href || checkIsLinkExternal(href) ? href : (basePath || "") + href;
};

0 comments on commit deea136

Please sign in to comment.