Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add typecheck and fix type #633

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/conform-dom/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ function shouldNotify<Schema>(
return false;
}

export function createFormContext<
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this helps comparing to setting an alias on the entry file?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you as the author know its unstable, but as the contributor I might not if I don't look at the export boundary (index) that I would read this as stable code

export function unstable_createFormContext<
Schema extends Record<string, any>,
FormError = string[],
FormValue = Schema,
Expand Down
2 changes: 1 addition & 1 deletion packages/conform-dom/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export {
type FormContext,
type SubscriptionSubject,
type SubscriptionScope,
createFormContext as unstable_createFormContext,
unstable_createFormContext,
} from './form';
export { type FieldElement, isFieldElement } from './dom';
export {
Expand Down
5 changes: 3 additions & 2 deletions packages/conform-dom/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
},
"scripts": {
"build:js": "rollup -c",
"build:ts": "tsc",
"build:ts": "tsc --emitDeclarationOnly",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to remove emitDeclarationOnly from the tsconfig?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when running tsc with --noEmit and --emitDeclarationOnly is set in the tsconfig, tsc throws an error saying only one can be set at a time.

"build": "pnpm run \"/^build:.*/\"",
"dev:js": "pnpm run build:js --watch",
"dev:ts": "pnpm run build:ts --watch",
"dev": "pnpm run \"/^dev:.*/\"",
"prepare": "pnpm run build"
"prepare": "pnpm run build",
"typecheck": "tsc --noEmit"
},
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion packages/conform-dom/submission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export type SubmissionState = {
validated: Record<string, boolean>;
};

export type SubmissionContext<Value = null, FormError = string[]> = {
export type SubmissionContext<Value = unknown, FormError = string[]> = {
Copy link
Contributor Author

@lifeiscontent lifeiscontent May 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

null here seems wrong because when running tests the value property isn't even set via parse

intent: Intent | null;
payload: Record<string, unknown>;
fields: Set<string>;
Expand Down
1 change: 0 additions & 1 deletion packages/conform-dom/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"noUncheckedIndexedAccess": true,
"strict": true,
"declaration": true,
"emitDeclarationOnly": true,
"composite": true,
"skipLibCheck": true
}
Expand Down
62 changes: 16 additions & 46 deletions packages/conform-react/context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,14 @@ import {
type SubscriptionScope,
type SubscriptionSubject,
type FormOptions as BaseFormOptions,
unstable_createFormContext as createBaseFormContext,
unstable_createFormContext,
formatPaths,
getPaths,
isPrefix,
STATE,
INTENT,
} from '@conform-to/dom';
import {
type FormEvent,
type ReactElement,
type ReactNode,
type MutableRefObject,
createContext,
useMemo,
useCallback,
Expand All @@ -32,15 +28,7 @@ import {

export type Pretty<T> = { [K in keyof T]: T[K] } & {};

export type Primitive =
| string
| number
| bigint
| boolean
| Date
| File
| null
| undefined;
export type Primitive = string | number | bigint | boolean | null | undefined;

export type Metadata<
Schema,
Expand Down Expand Up @@ -83,7 +71,7 @@ type SubfieldMetadata<
Schema,
FormSchema extends Record<string, any>,
FormError,
> = [Schema] extends [Primitive]
> = [Schema] extends [Primitive | Date | File]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@edmundhung this seems to be the only place Primitive is being used, whats the intent for overloading the term "Primitive" here with Date and File?

maybe another term like FormValue or something along those lines might be better here

? {}
: [Schema] extends [Array<infer Item> | null | undefined]
? {
Expand Down Expand Up @@ -144,7 +132,7 @@ export function useFormContext<Schema extends Record<string, any>, FormError>(

export function useFormState<FormError>(
form: FormContext<any, FormError>,
subjectRef?: MutableRefObject<SubscriptionSubject>,
subjectRef?: React.MutableRefObject<SubscriptionSubject>,
): FormState<FormError> {
const subscribe = useCallback(
(callback: () => void) =>
Expand All @@ -157,8 +145,8 @@ export function useFormState<FormError>(

export function FormProvider(props: {
context: Wrapped<FormContext<any, any>>;
children: ReactNode;
}): ReactElement {
children: React.ReactNode;
}): React.ReactElement {
const forms = useContext(Form);
const context = getWrappedFormContext(props.context);
const value = useMemo(
Expand All @@ -184,7 +172,7 @@ export function FormStateInput(props: { formId?: string }): React.ReactElement {

export function useSubjectRef(
initialSubject: SubscriptionSubject = {},
): MutableRefObject<SubscriptionSubject> {
): React.MutableRefObject<SubscriptionSubject> {
const subjectRef = useRef(initialSubject);

// Reset the subject everytime the component is rerendered
Expand All @@ -195,17 +183,17 @@ export function useSubjectRef(
}

export function updateSubjectRef(
ref: MutableRefObject<SubscriptionSubject>,
ref: React.MutableRefObject<SubscriptionSubject>,
subject: 'status' | 'formId',
): void;
export function updateSubjectRef(
ref: MutableRefObject<SubscriptionSubject>,
ref: React.MutableRefObject<SubscriptionSubject>,
subject: Exclude<keyof SubscriptionSubject, 'status' | 'formId'>,
scope: keyof SubscriptionScope,
name: string,
): void;
export function updateSubjectRef(
ref: MutableRefObject<SubscriptionSubject>,
ref: React.MutableRefObject<SubscriptionSubject>,
subject: keyof SubscriptionSubject,
scope?: keyof SubscriptionScope,
name?: string,
Expand All @@ -226,7 +214,7 @@ export function getMetadata<
FormSchema extends Record<string, any>,
>(
context: FormContext<FormSchema, FormError, any>,
subjectRef: MutableRefObject<SubscriptionSubject>,
subjectRef: React.MutableRefObject<SubscriptionSubject>,
stateSnapshot: FormState<FormError>,
name: FieldName<Schema, FormSchema, FormError> = '',
): Metadata<Schema, FormSchema, FormError> {
Expand Down Expand Up @@ -272,24 +260,6 @@ export function getMetadata<

return result;
},
get getFieldset() {
return () =>
new Proxy({} as any, {
get(target, key, receiver) {
if (typeof key === 'string') {
return getFieldMetadata(
context,
subjectRef,
stateSnapshot,
name,
key,
);
}

return Reflect.get(target, key, receiver);
},
});
},
Comment on lines -275 to -292
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Contributor Author

@lifeiscontent lifeiscontent May 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@edmundhung based off the type it says getFieldset doesn't exist so I removed it to see if tests would still pass I can revert, but we should probably update the types too

},
{
get(target, key, receiver) {
Expand Down Expand Up @@ -334,7 +304,7 @@ export function getFieldMetadata<
FormError,
>(
context: FormContext<FormSchema, FormError, any>,
subjectRef: MutableRefObject<SubscriptionSubject>,
subjectRef: React.MutableRefObject<SubscriptionSubject>,
stateSnapshot: FormState<FormError>,
prefix = '',
key?: string | number,
Expand Down Expand Up @@ -404,7 +374,7 @@ export function getFormMetadata<
FormValue = Schema,
>(
context: FormContext<Schema, FormError, FormValue>,
subjectRef: MutableRefObject<SubscriptionSubject>,
subjectRef: React.MutableRefObject<SubscriptionSubject>,
stateSnapshot: FormState<FormError>,
noValidate: boolean,
): FormMetadata<Schema, FormError> {
Expand Down Expand Up @@ -450,7 +420,7 @@ export type FormOptions<
* A function to be called before the form is submitted.
*/
onSubmit?: (
event: FormEvent<HTMLFormElement>,
event: React.FormEvent<HTMLFormElement>,
context: ReturnType<
BaseFormContext<Schema, FormError, FormValue>['submit']
>,
Expand All @@ -465,7 +435,7 @@ export type FormContext<
BaseFormContext<Schema, FormError, FormValue>,
'submit' | 'onUpdate'
> & {
submit: (event: FormEvent<HTMLFormElement>) => void;
submit: (event: React.FormEvent<HTMLFormElement>) => void;
onUpdate: (
options: Partial<FormOptions<Schema, FormError, FormValue>>,
) => void;
Expand All @@ -479,7 +449,7 @@ export function createFormContext<
options: FormOptions<Schema, FormError, FormValue>,
): FormContext<Schema, FormError, FormValue> {
let { onSubmit, ...rest } = options;
const context = createBaseFormContext(rest);
const context = unstable_createFormContext(rest);

return {
...context,
Expand Down
4 changes: 2 additions & 2 deletions packages/conform-react/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export {
} from './context';
export { useForm, useFormMetadata, useField } from './hooks';
export {
Control as unstable_Control,
useControl as unstable_useControl,
unstable_Control,
unstable_useControl,
useInputControl,
} from './integrations';
export {
Expand Down
12 changes: 8 additions & 4 deletions packages/conform-react/integrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,10 +294,12 @@ export function useInputValue<
return [value, setValue] as const;
}

export function useControl<
export function unstable_useControl<
Value extends string | string[] | Array<string | undefined>,
>(meta: { key?: Key | null | undefined; initialValue?: Value | undefined }) {
// eslint-disable-next-line react-hooks/rules-of-hooks
const [value, setValue] = useInputValue(meta);
// eslint-disable-next-line react-hooks/rules-of-hooks
Comment on lines +300 to +302
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Err.. why?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since the name of the function doesn't start with use it complains, I'm not sure what remix team does with thier unstable APIs to get around this but I could look into it. I'm guessing they might have lint rules turned off for things marked as unstable_

const { register, change, focus, blur } = useInputEvent();
const handleChange = (
value: Value extends string ? Value : string | string[],
Expand Down Expand Up @@ -377,13 +379,15 @@ export function useInputControl<
};
}

export function Control<
export function unstable_Control<
Value extends string | string[] | Array<string | undefined>,
>(props: {
meta: { key?: Key | null | undefined; initialValue?: Value | undefined };
render: (control: ReturnType<typeof useControl<Value>>) => React.ReactNode;
render: (
control: ReturnType<typeof unstable_useControl<Value>>,
) => React.ReactNode;
}) {
const control = useControl(props.meta);
const control = unstable_useControl(props.meta);

return props.render(control);
}
5 changes: 3 additions & 2 deletions packages/conform-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
},
"scripts": {
"build:js": "rollup -c",
"build:ts": "tsc",
"build:ts": "tsc --emitDeclarationOnly",
"build": "pnpm run \"/^build:.*/\"",
"dev:js": "pnpm run build:js --watch",
"dev:ts": "pnpm run build:ts --watch",
"dev": "pnpm run \"/^dev:.*/\"",
"prepare": "pnpm run build"
"prepare": "pnpm run build",
"typecheck": "tsc --noEmit"
},
"repository": {
"type": "git",
Expand Down
1 change: 0 additions & 1 deletion packages/conform-react/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
"noUncheckedIndexedAccess": true,
"strict": true,
"declaration": true,
"emitDeclarationOnly": true,
"composite": true,
"skipLibCheck": true
}
Expand Down
5 changes: 3 additions & 2 deletions packages/conform-validitystate/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
},
"scripts": {
"build:js": "rollup -c",
"build:ts": "tsc",
"build:ts": "tsc --emitDeclarationOnly",
"build": "pnpm run \"/^build:.*/\"",
"dev:js": "pnpm run build:js --watch",
"dev:ts": "pnpm run build:ts --watch",
"dev": "pnpm run \"/^dev:.*/\"",
"prepare": "pnpm run build"
"prepare": "pnpm run build",
"typecheck": "tsc --noEmit"
},
"repository": {
"type": "git",
Expand Down
1 change: 0 additions & 1 deletion packages/conform-validitystate/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
"allowSyntheticDefaultImports": true,
"strict": true,
"declaration": true,
"emitDeclarationOnly": true,
"composite": true,
"skipLibCheck": true
}
Expand Down
5 changes: 3 additions & 2 deletions packages/conform-yup/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
},
"scripts": {
"build:js": "rollup -c",
"build:ts": "tsc",
"build:ts": "tsc --emitDeclarationOnly",
"build": "pnpm run \"/^build:.*/\"",
"dev:js": "pnpm run build:js --watch",
"dev:ts": "pnpm run build:ts --watch",
"dev": "pnpm run \"/^dev:.*/\"",
"prepare": "pnpm run build"
"prepare": "pnpm run build",
"typecheck": "tsc --noEmit"
},
"repository": {
"type": "git",
Expand Down
1 change: 0 additions & 1 deletion packages/conform-yup/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"noUncheckedIndexedAccess": true,
"strict": true,
"declaration": true,
"emitDeclarationOnly": true,
"composite": true,
"skipLibCheck": true
}
Expand Down
5 changes: 3 additions & 2 deletions packages/conform-zod/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
},
"scripts": {
"build:js": "rollup -c",
"build:ts": "tsc",
"build:ts": "tsc --emitDeclarationOnly",
"build": "pnpm run \"/^build:.*/\"",
"dev:js": "pnpm run build:js --watch",
"dev:ts": "pnpm run build:ts --watch",
"dev": "pnpm run \"/^dev:.*/\"",
"prepare": "pnpm run build"
"prepare": "pnpm run build",
"typecheck": "tsc --noEmit"
},
"repository": {
"type": "git",
Expand Down
1 change: 0 additions & 1 deletion packages/conform-zod/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"noUncheckedIndexedAccess": true,
"strict": true,
"declaration": true,
"emitDeclarationOnly": true,
"composite": true,
"skipLibCheck": true
}
Expand Down
10 changes: 5 additions & 5 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"references": [
{ "path": "packages/conform-dom" },
{ "path": "packages/conform-yup" },
{ "path": "packages/conform-zod" },
{ "path": "packages/conform-react" },
{ "path": "packages/conform-validitystate" }
{ "path": "./packages/conform-dom" },
{ "path": "./packages/conform-yup" },
{ "path": "./packages/conform-zod" },
{ "path": "./packages/conform-react" },
{ "path": "./packages/conform-validitystate" }
Comment on lines +3 to +7
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@edmundhung both of these work, but now if we ctrl+click the paths in vscode they goto the file

],
"files": []
}
Loading