diff --git a/packages/fields-document/src/DocumentEditor/component-blocks/api.tsx b/packages/fields-document/src/DocumentEditor/component-blocks/api.tsx index 4b2fd78a7cb..095606a15dc 100644 --- a/packages/fields-document/src/DocumentEditor/component-blocks/api.tsx +++ b/packages/fields-document/src/DocumentEditor/component-blocks/api.tsx @@ -1,5 +1,6 @@ /** @jsxRuntime classic */ /** @jsx jsx */ +import { graphql } from '@keystone-6/core'; import { jsx } from '@keystone-ui/core'; import { FieldContainer, @@ -50,6 +51,22 @@ export type FormField = { * a potentially malicious client */ validate(value: unknown): boolean; + preview?: PreviewComponent; +}; + +export type FormFieldWithGraphQLField = FormField< + Value, + Options +> & { + graphql: { + output: graphql.Field< + { value: Value }, + Record>, + graphql.OutputType, + 'value' + >; + input: graphql.NullableInputType; + }; }; type InlineMarksConfig = @@ -100,6 +117,7 @@ export type ChildField = { export type ArrayField = { kind: 'array'; element: ElementField; + preview?: PreviewComponent; }; export type RelationshipField = { @@ -108,6 +126,7 @@ export type RelationshipField = { selection: string | undefined; label: string; many: Many; + preview?: PreviewComponent; }; export interface ObjectField< @@ -115,6 +134,7 @@ export interface ObjectField< > { kind: 'object'; fields: Fields; + preview?: PreviewComponent; } export type ConditionalField< @@ -126,8 +146,14 @@ export type ConditionalField< kind: 'conditional'; discriminant: DiscriminantField; values: ConditionalValues; + preview?: PreviewComponent; }; +type PreviewComponent = (props: unknown) => ReactElement | null; +type TypedPreviewComponent = ( + props: PreviewProps & { autoFocus?: boolean } +) => ReactElement | null; + export type ComponentSchema = | ChildField | FormField @@ -135,16 +161,29 @@ export type ComponentSchema = | ConditionalField, { [key: string]: ComponentSchema }> | RelationshipField // this is written like this rather than ArrayField to avoid TypeScript erroring about circularity - | { kind: 'array'; element: ComponentSchema }; + | { kind: 'array'; element: ComponentSchema; preview?: PreviewComponent }; + +export type ComponentSchemaForGraphQL = + | FormFieldWithGraphQLField + | ObjectField> + | ConditionalField< + FormFieldWithGraphQLField, + { [key: string]: ComponentSchemaForGraphQL } + > + | RelationshipField + // this is written like this rather than ArrayField to avoid TypeScript erroring about circularity + | { kind: 'array'; element: ComponentSchemaForGraphQL; preview?: PreviewComponent }; export const fields = { text({ label, defaultValue = '', + preview, }: { label: string; defaultValue?: string; - }): FormField { + preview?: TypedPreviewComponent>; + }): FormFieldWithGraphQLField { return { kind: 'form', Input({ value, onChange, autoFocus }) { @@ -166,15 +205,22 @@ export const fields = { validate(value) { return typeof value === 'string'; }, + graphql: { + input: graphql.String, + output: graphql.field({ type: graphql.String }), + }, + preview: preview as PreviewComponent, }; }, url({ label, defaultValue = '', + preview, }: { label: string; defaultValue?: string; - }): FormField { + preview?: TypedPreviewComponent>; + }): FormFieldWithGraphQLField { const validate = (value: unknown) => { return typeof value === 'string' && (value === '' || isValidURL(value)); }; @@ -203,17 +249,24 @@ export const fields = { options: undefined, defaultValue, validate, + graphql: { + input: graphql.String, + output: graphql.field({ type: graphql.String }), + }, + preview: preview as PreviewComponent, }; }, select