Add target and prefetch to a link (#1117)

## Description

Adding target and prefetch to initial properties of a Link component
along with the defaults

## Steps for reproduction

1. add a link
2. try target prop
3. try prefetch options

## Code Review

- [ ] hi @rpominov, I need you to do
  - conceptual review (architecture, feature-correctness)
  - detailed review (read every line)
  - test it on preview

## Before requesting a review

- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")

## Before merging

- [ ] tested locally and on preview environment (preview dev login:
5de6)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio-builder/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env.example`
and the `builder/env-check.js` if mandatory
This commit is contained in:
Oleg Isonen authored and GitHub committed 2023-02-24 10:17:40 +01:00
1 parent 1f2475b9f4
commit afa83c8d55
27 files changed
+100 -61

No files matched your search

@@ -11,10 +11,10 @@ import { preserveSearchBuildParams } from "~/shared/router-utils";
const isAbsoluteUrl = (href: string) => {
try {
new URL(href);
return true;
} catch (e) {
} catch {
return false;
}
return true;
};
export const preserveBuildParams = (href: string, sourceSearch: string) => {
@@ -33,7 +33,7 @@ export const preserveBuildParams = (href: string, sourceSearch: string) => {
sourceSearchParams = new URLSearchParams(sourceSearch);
// eslint-disable-next-line no-empty
} catch (e) {}
} catch {}
if (url === undefined || sourceSearchParams === undefined) {
return href;
@@ -46,7 +46,12 @@ export const preserveBuildParams = (href: string, sourceSearch: string) => {
return `${url.pathname}${search === "" ? "" : `?${search}`}`;
};
type Props = Omit<ComponentProps<"a">, "href"> & { href?: string };
// @todo this copy-paste has to go away, along with this wrapper component
type Props = Omit<ComponentProps<"a">, "href" | "target"> & {
href?: string;
target?: "self" | "blank" | "parent" | "top";
prefetch?: "none" | "intent" | "render";
};
type Ref = ElementRef<"a">;
+1 -1
View File
@@ -88,7 +88,7 @@ export const getArgType = (propItem: PropItem): PropMeta | undefined => {
);
return makePropMeta(
"string",
options.length <= 5 ? "radio" : "select",
options.length <= 3 ? "radio" : "select",
{ options }
);
}
@@ -6,12 +6,13 @@ import type {
ForwardRefExoticComponent,
} from "react";
import { forwardRef } from "react";
import type { Link as BaseLink } from "../../../components/link";
const isAbsoluteUrl = (href: string) => {
try {
new URL(href);
return true;
} catch (e) {
} catch {
return false;
}
};
@@ -21,7 +22,7 @@ const isAbsoluteUrl = (href: string) => {
const isAbsoluteUrlRemix = (href: string) =>
/^[a-z+]+:\/\//i.test(href) || href.startsWith("//");
type Props = Omit<ComponentProps<"a">, "href"> & { href?: string };
type Props = ComponentProps<typeof BaseLink>;
type Ref = ElementRef<"a">;
@@ -41,7 +42,7 @@ export const wrapLinkComponent = (
if (isAbsolute || willRemixTryToTreatAsAbsoluteAndCrash) {
return (
<a
<BaseLink
{...props}
href={willRemixTryToTreatAsAbsoluteAndCrash ? "" : href}
ref={ref}
@@ -104,7 +104,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["list", "none", "inline", "both"],
},
@@ -406,7 +406,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates if items in a table or grid are sorted in ascending or descending order.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["none", "ascending", "descending", "other"],
},
@@ -103,7 +103,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["list", "none", "inline", "both"],
},
@@ -405,7 +405,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates if items in a table or grid are sorted in ascending or descending order.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["none", "ascending", "descending", "other"],
},
@@ -103,7 +103,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["list", "none", "inline", "both"],
},
@@ -405,7 +405,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates if items in a table or grid are sorted in ascending or descending order.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["none", "ascending", "descending", "other"],
},
@@ -103,7 +103,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["list", "none", "inline", "both"],
},
@@ -405,7 +405,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates if items in a table or grid are sorted in ascending or descending order.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["none", "ascending", "descending", "other"],
},
@@ -120,7 +120,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["list", "none", "inline", "both"],
},
@@ -422,7 +422,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates if items in a table or grid are sorted in ascending or descending order.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["none", "ascending", "descending", "other"],
},
@@ -104,7 +104,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["inline", "list", "none", "both"],
},
@@ -406,7 +406,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates if items in a table or grid are sorted in ascending or descending order.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["none", "ascending", "descending", "other"],
},
@@ -111,7 +111,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["list", "none", "inline", "both"],
},
@@ -413,7 +413,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates if items in a table or grid are sorted in ascending or descending order.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["none", "ascending", "descending", "other"],
},
@@ -103,7 +103,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["list", "none", "inline", "both"],
},
@@ -405,7 +405,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates if items in a table or grid are sorted in ascending or descending order.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["none", "ascending", "descending", "other"],
},
@@ -144,7 +144,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["list", "none", "inline", "both"],
},
@@ -446,7 +446,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates if items in a table or grid are sorted in ascending or descending order.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["none", "ascending", "descending", "other"],
},
@@ -141,7 +141,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["list", "none", "inline", "both"],
},
@@ -443,7 +443,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates if items in a table or grid are sorted in ascending or descending order.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["none", "ascending", "descending", "other"],
},
@@ -103,7 +103,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["list", "none", "inline", "both"],
},
@@ -405,7 +405,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates if items in a table or grid are sorted in ascending or descending order.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["none", "ascending", "descending", "other"],
},
+15 -3
View File
@@ -10,7 +10,13 @@ export const props: Record<string, PropMeta> = {
media: { required: false, control: "text", type: "string" },
ping: { required: false, control: "text", type: "string" },
rel: { required: false, control: "text", type: "string" },
target: { required: false, control: "text", type: "string" },
target: {
required: false,
control: "select",
type: "string",
defaultValue: "self",
options: ["self", "blank", "parent", "top"],
},
type: { required: false, control: "text", type: "string" },
referrerPolicy: {
required: false,
@@ -127,7 +133,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["list", "none", "inline", "both"],
},
@@ -429,7 +435,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates if items in a table or grid are sorted in ascending or descending order.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["none", "ascending", "descending", "other"],
},
@@ -459,4 +465,10 @@ export const props: Record<string, PropMeta> = {
control: "text",
type: "string",
},
prefetch: {
required: false,
control: "radio",
type: "string",
options: ["none", "intent", "render"],
},
};
@@ -104,7 +104,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["list", "none", "inline", "both"],
},
@@ -406,7 +406,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates if items in a table or grid are sorted in ascending or descending order.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["none", "ascending", "descending", "other"],
},
@@ -103,7 +103,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["list", "none", "inline", "both"],
},
@@ -405,7 +405,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates if items in a table or grid are sorted in ascending or descending order.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["none", "ascending", "descending", "other"],
},
@@ -439,7 +439,7 @@ export const props: Record<string, PropMeta> = {
start: { required: false, control: "number", type: "number" },
type: {
required: false,
control: "radio",
control: "select",
type: "string",
options: ["a", "i", "1", "A", "I"],
},
@@ -103,7 +103,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["list", "none", "inline", "both"],
},
@@ -405,7 +405,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates if items in a table or grid are sorted in ascending or descending order.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["none", "ascending", "descending", "other"],
},
@@ -5,12 +5,17 @@ export const props: Record<string, PropMeta> = {
style: { required: false, control: "text", type: "string" },
title: { required: false, control: "text", type: "string" },
download: { required: false, control: "text", type: "string" },
href: { required: false, control: "text", type: "string", defaultValue: "" },
href: { required: false, control: "text", type: "string" },
hrefLang: { required: false, control: "text", type: "string" },
media: { required: false, control: "text", type: "string" },
ping: { required: false, control: "text", type: "string" },
rel: { required: false, control: "text", type: "string" },
target: { required: false, control: "text", type: "string" },
target: {
required: false,
control: "select",
type: "string",
options: ["self", "blank", "parent", "top"],
},
type: { required: false, control: "text", type: "string" },
referrerPolicy: {
required: false,
@@ -127,7 +132,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["list", "none", "inline", "both"],
},
@@ -429,7 +434,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates if items in a table or grid are sorted in ascending or descending order.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["none", "ascending", "descending", "other"],
},
@@ -459,4 +464,10 @@ export const props: Record<string, PropMeta> = {
control: "text",
type: "string",
},
prefetch: {
required: false,
control: "radio",
type: "string",
options: ["none", "intent", "render"],
},
};
@@ -103,7 +103,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["list", "none", "inline", "both"],
},
@@ -405,7 +405,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates if items in a table or grid are sorted in ascending or descending order.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["none", "ascending", "descending", "other"],
},
@@ -103,7 +103,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["list", "none", "inline", "both"],
},
@@ -405,7 +405,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates if items in a table or grid are sorted in ascending or descending order.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["none", "ascending", "descending", "other"],
},
@@ -103,7 +103,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["list", "none", "inline", "both"],
},
@@ -405,7 +405,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates if items in a table or grid are sorted in ascending or descending order.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["none", "ascending", "descending", "other"],
},
@@ -103,7 +103,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["list", "none", "inline", "both"],
},
@@ -405,7 +405,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates if items in a table or grid are sorted in ascending or descending order.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["none", "ascending", "descending", "other"],
},
@@ -103,7 +103,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates whether inputting text could trigger display of one or more predictions of the user's intended value for an input and specifies how predictions would be\npresented if they are made.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["list", "none", "inline", "both"],
},
@@ -405,7 +405,7 @@ export const props: Record<string, PropMeta> = {
description:
"Indicates if items in a table or grid are sorted in ascending or descending order.",
required: false,
control: "radio",
control: "select",
type: "string",
options: ["none", "ascending", "descending", "other"],
},
+11 -2
View File
@@ -1,9 +1,18 @@
import { forwardRef, type ElementRef, type ComponentProps } from "react";
type Props = Omit<ComponentProps<"a">, "href"> & { href?: string };
// @todo props that come from remix link, shouldn't be here at all
// - prefetch should be only on remix component and it already is
// - props meta should be generated from Remix link
type Props = Omit<ComponentProps<"a">, "href" | "target"> & {
href?: string;
target?: "self" | "blank" | "parent" | "top";
prefetch?: "none" | "intent" | "render";
};
export const Link = forwardRef<ElementRef<"a">, Props>(
({ href = "", ...props }, ref) => <a {...props} href={href} ref={ref} />
({ href = "", target = "self", ...props }, ref) => {
return <a {...props} target={`_${target}`} href={href} ref={ref} />;
}
);
Link.displayName = "Link";
@@ -24,5 +24,5 @@ export const meta: WsComponentMeta = {
export const propsMeta: WsComponentPropsMeta = {
props,
initialProps: ["href"],
initialProps: ["href", "target", "prefetch"],
};
@@ -1,9 +1,10 @@
import { forwardRef, type ElementRef, type ComponentProps } from "react";
import { Link } from "./link";
type Props = Omit<ComponentProps<"a">, "href"> & { href?: string };
type Props = ComponentProps<typeof Link>;
export const RichTextLink = forwardRef<ElementRef<"a">, Props>(
({ href = "", ...props }, ref) => <a {...props} href={href} ref={ref} />
);
export const RichTextLink = forwardRef<ElementRef<"a">, Props>((props, ref) => (
<Link {...props} ref={ref} />
));
RichTextLink.displayName = "RichTextLink";