Skip to content

Commit d33f566

Browse files
committed
Add validator option for useStrongFrom and use it in few places
1 parent 41f5dbe commit d33f566

File tree

4 files changed

+41
-7
lines changed

4 files changed

+41
-7
lines changed

apps/cyberstorm-remix/app/settings/teams/Teams.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ function CreateTeamForm(props: { config: () => RequestConfig }) {
163163
InputErrors
164164
>({
165165
inputs: formInputs,
166+
validators: { name: { required: true } },
166167
submitor,
167168
onSubmitSuccess: (fi) => {
168169
createTeamRevalidate();
@@ -223,10 +224,11 @@ function CreateTeamForm(props: { config: () => RequestConfig }) {
223224
</Modal.Body>
224225
<Modal.Footer>
225226
<NewButton
227+
disabled={!strongForm.isReady}
228+
csVariant="accent"
226229
onClick={() => {
227230
strongForm.submit().then(() => setOpen(false));
228231
}}
229-
csVariant="accent"
230232
>
231233
Create
232234
</NewButton>

apps/cyberstorm-remix/app/settings/teams/team/tabs/Members/MemberAddForm.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ export function MemberAddForm(props: {
7474
InputErrors
7575
>({
7676
inputs: formInputs,
77+
validators: { username: { required: true } },
7778
submitor,
7879
onSubmitSuccess: () => {
7980
props.updateTrigger();
@@ -151,7 +152,11 @@ export function MemberAddForm(props: {
151152
</div>
152153
</Modal.Body>
153154
<Modal.Footer>
154-
<NewButton csVariant="accent" onClick={strongForm.submit}>
155+
<NewButton
156+
csVariant="accent"
157+
disabled={!strongForm.isReady}
158+
onClick={strongForm.submit}
159+
>
155160
Add member
156161
</NewButton>
157162
</Modal.Footer>

apps/cyberstorm-remix/app/settings/teams/team/tabs/ServiceAccounts/ServiceAccounts.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,6 @@ function AddServiceAccountForm(props: {
114114
nickname: "",
115115
});
116116

117-
const isValid = formInputs.nickname.trim().length > 0;
118-
119117
type SubmitorOutput = Awaited<ReturnType<typeof teamAddServiceAccount>>;
120118

121119
async function submitor(data: typeof formInputs): Promise<SubmitorOutput> {
@@ -140,6 +138,7 @@ function AddServiceAccountForm(props: {
140138
InputErrors
141139
>({
142140
inputs: formInputs,
141+
validators: { nickname: { required: true } },
143142
submitor,
144143
onSubmitSuccess: (result) => {
145144
onSuccess(result);
@@ -203,7 +202,7 @@ function AddServiceAccountForm(props: {
203202
className="service-accounts__form"
204203
onSubmit={(e) => {
205204
e.preventDefault();
206-
if (isValid) {
205+
if (strongForm.isReady) {
207206
strongForm.submit();
208207
}
209208
}}
@@ -234,7 +233,7 @@ function AddServiceAccountForm(props: {
234233
)}
235234
{serviceAccountAdded ? null : (
236235
<Modal.Footer>
237-
<NewButton onClick={strongForm.submit} disabled={!isValid}>
236+
<NewButton onClick={strongForm.submit} disabled={!strongForm.isReady}>
238237
Add Service Account
239238
</NewButton>
240239
</Modal.Footer>

apps/cyberstorm-remix/cyberstorm/utils/StrongForm/useStrongForm.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1-
import { useEffect, useState } from "react";
1+
import { useEffect, useMemo, useState } from "react";
22
import {
33
ParseError,
44
RequestBodyParseError,
55
RequestQueryParamsParseError,
66
} from "../../../../../packages/thunderstore-api/src";
77

8+
type Validator = {
9+
required?: boolean;
10+
};
11+
812
interface UseStrongFormProps<
913
Inputs,
1014
SubmissionDataShape,
@@ -13,6 +17,15 @@ interface UseStrongFormProps<
1317
SubmissionError,
1418
> {
1519
inputs: Inputs;
20+
/**
21+
* Validators for the form inputs.
22+
*
23+
* NOTE: If you add new validator types here, make sure to implement the
24+
* validation logic in the `isReady` memo inside `useStrongForm`.
25+
*/
26+
validators?: {
27+
[K in keyof Inputs]?: Validator;
28+
};
1629
refiner?: (inputs: Inputs) => Promise<SubmissionDataShape>;
1730
onRefineSuccess?: (output: SubmissionDataShape) => void;
1831
onRefineError?: (error: RefinerError) => void;
@@ -45,6 +58,20 @@ export function useStrongForm<
4558
const [submitError, setSubmitError] = useState<SubmissionError>();
4659
const [inputErrors, setInputErrors] = useState<InputErrors>();
4760

61+
const isReady = useMemo(() => {
62+
if (!props.validators) return true;
63+
for (const key in props.validators) {
64+
const validator = props.validators[key];
65+
const value = props.inputs[key];
66+
// NOTE: Expand the checks as more validators are added
67+
if (validator?.required) {
68+
if (typeof value === "string" && value.trim() === "") return false;
69+
if (value === undefined || value === null) return false;
70+
}
71+
}
72+
return true;
73+
}, [props.inputs]);
74+
4875
useEffect(() => {
4976
if (refining || submitting) {
5077
return;
@@ -165,5 +192,6 @@ export function useStrongForm<
165192
refining,
166193
refineError,
167194
inputErrors,
195+
isReady,
168196
};
169197
}

0 commit comments

Comments
 (0)