-
Notifications
You must be signed in to change notification settings - Fork 6
/
AddLink.tsx
123 lines (105 loc) · 3.2 KB
/
AddLink.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import { useTranslation } from "next-i18next";
import prependHttp from "prepend-http";
// Form
import { yupResolver } from "@hookform/resolvers/yup";
import { isRequired } from "lib/isFieldRequired";
import { url } from "lib/regex";
import { Controller, useForm } from "react-hook-form";
import * as yup from "yup";
// Components
import { Button, Card, Icon, Stack, TextField } from "@bbtgnn/polaris-interfacer";
import { CancelMinor, PlusMinor } from "@shopify/polaris-icons";
import useYupLocaleObject from "hooks/useYupLocaleObject";
//
export interface Link {
url: string;
label: string;
}
export interface Props {
onSubmit?: (value: Link) => void;
onDiscard?: () => void;
textLabel?: string;
urlLabel?: string;
addButtonLabel?: string;
}
//
export default function AddLink(props: Props) {
const { t } = useTranslation("common");
const {
onSubmit = () => {},
onDiscard = () => {},
textLabel = t("Link title"),
urlLabel = t("External data"),
addButtonLabel = t("Add link"),
} = props;
const defaultValues: Link = {
url: "",
label: "",
};
const yupLocaleObject = useYupLocaleObject();
yup.setLocale(yupLocaleObject);
const schema = (() =>
yup.object().shape({
url: yup.string().matches(url, t("URL shape is not valid")).required(),
label: yup.string().required(),
}))();
const form = useForm<Link>({
mode: "all",
resolver: yupResolver(schema),
defaultValues,
});
const { formState, control, watch, reset } = form;
const { isValid, errors, isSubmitting } = formState;
function submit() {
onSubmit({ label: watch("label"), url: prependHttp(watch("url")) });
reset();
}
//
return (
<Card sectioned>
<Stack vertical spacing="loose">
<Controller
control={control}
name="label"
render={({ field: { onChange, onBlur, name, value } }) => (
<TextField
label={textLabel}
autoComplete="off"
onChange={onChange}
onBlur={onBlur}
value={value}
error={errors[name]?.message}
requiredIndicator={isRequired(schema, name)}
/>
)}
/>
<Controller
control={control}
name="url"
render={({ field: { onChange, onBlur, name, value } }) => (
<TextField
label={urlLabel}
helpText={t(
"Add here a link to the repository or page where the projects files are contained. The link will be visible in the project page."
)}
autoComplete="off"
value={value}
onBlur={onBlur}
onChange={onChange}
error={errors[name]?.message}
requiredIndicator={isRequired(schema, name)}
/>
)}
/>
<div className="flex justify-end pt-4 space-x-2">
<Button onClick={onDiscard} icon={<Icon source={CancelMinor} />}>
{t("Discard")}
</Button>
<Button onClick={submit} disabled={!isValid || isSubmitting} icon={<Icon source={PlusMinor} />}>
{addButtonLabel}
</Button>
</div>
</Stack>
</Card>
);
}