From dfd33ceddcd30cff09ec75db469f2b9939327ee5 Mon Sep 17 00:00:00 2001 From: Per-Kristian Nordnes Date: Tue, 6 Dec 2022 01:18:07 +0100 Subject: [PATCH] refactor(types): refactor Block schemas for new component extension api --- .../@sanity/types/src/schema/asserters.ts | 29 +++++++++----- .../src/schema/definition/schemaDefinition.ts | 7 ++-- .../types/src/schema/definition/type/block.ts | 40 +++++++++++++------ .../types/src/schema/definition/type/index.ts | 1 - .../types/src/schema/definition/type/span.ts | 13 ------ .../types/src/schema/test/block.test.ts | 26 ++++++------ packages/@sanity/types/src/schema/types.ts | 28 +++++++------ 7 files changed, 78 insertions(+), 66 deletions(-) delete mode 100644 packages/@sanity/types/src/schema/definition/type/span.ts diff --git a/packages/@sanity/types/src/schema/asserters.ts b/packages/@sanity/types/src/schema/asserters.ts index 0e5be1f9eae..4f1550d1ce5 100644 --- a/packages/@sanity/types/src/schema/asserters.ts +++ b/packages/@sanity/types/src/schema/asserters.ts @@ -1,18 +1,18 @@ import type {CrossDatasetReferenceSchemaType} from '../crossDatasetReference' import {TitledListValue} from './definition' import type { - BlockSchemaType, ArraySchemaType, - ObjectSchemaType, - ReferenceSchemaType, - SpanSchemaType, BlockChildrenObjectField, - StyleObjectField, - ListObjectField, + BlockListObjectField, + BlockSchemaType, + BlockStyleObjectField, BooleanSchemaType, - StringSchemaType, NumberSchemaType, + ObjectSchemaType, + ReferenceSchemaType, SchemaType, + SpanSchemaType, + StringSchemaType, } from './types' function isRecord(value: unknown): value is Record { @@ -56,6 +56,13 @@ export function isArraySchemaType(type: unknown): type is ArraySchemaType { return type.jsonType === 'array' } +/** @internal */ +export function isArrayOfBlocksSchemaType( + type: unknown +): type is ArraySchemaType { + return isArraySchemaType(type) && type.of.some((memberType) => isBlockSchemaType(memberType)) +} + /** @internal */ export function isArrayOfObjectsSchemaType( type: unknown @@ -129,20 +136,20 @@ export function isBlockSchemaType(type: unknown): type is BlockSchemaType { const [maybeSpanChildren, maybeStyle, maybeList] = type.fields return ( isBlockChildrenObjectField(maybeSpanChildren) && - isStyleObjectField(maybeStyle) && - isListObjectField(maybeList) + isBlockStyleObjectField(maybeStyle) && + isBlockListObjectField(maybeList) ) } /** @internal */ -export function isStyleObjectField(field: unknown): field is StyleObjectField { +export function isBlockStyleObjectField(field: unknown): field is BlockStyleObjectField { if (!isRecord(field)) return false if (field.name !== 'style') return false return isRecord(field.type) && field.type.jsonType === 'string' } /** @internal */ -export function isListObjectField(field: unknown): field is ListObjectField { +export function isBlockListObjectField(field: unknown): field is BlockListObjectField { if (!isRecord(field)) return false if (field.name !== 'list') return false return isRecord(field.type) && field.type.jsonType === 'string' diff --git a/packages/@sanity/types/src/schema/definition/schemaDefinition.ts b/packages/@sanity/types/src/schema/definition/schemaDefinition.ts index 7c718005a1e..d17c45c36c7 100644 --- a/packages/@sanity/types/src/schema/definition/schemaDefinition.ts +++ b/packages/@sanity/types/src/schema/definition/schemaDefinition.ts @@ -1,4 +1,4 @@ -import {ComponentType} from 'react' +import {ComponentType, ReactNode} from 'react' import {PreviewConfig} from '../preview' import {InitialValueProperty, SchemaValidationValue} from '../types' import { @@ -16,7 +16,6 @@ import { ObjectDefinition, ReferenceDefinition, SlugDefinition, - SpanDefinition, StringDefinition, TextDefinition, UrlDefinition, @@ -54,7 +53,6 @@ export interface IntrinsicDefinitions { reference: ReferenceDefinition crossDatasetReference: CrossDatasetReferenceDefinition slug: SlugDefinition - span: SpanDefinition string: StringDefinition text: TextDefinition url: UrlDefinition @@ -92,6 +90,7 @@ export type SchemaTypeDefinition + block?: ComponentType diff?: ComponentType field?: ComponentType input?: ComponentType diff --git a/packages/@sanity/types/src/schema/definition/type/block.ts b/packages/@sanity/types/src/schema/definition/type/block.ts index 5bfd68aabbd..237240605f0 100644 --- a/packages/@sanity/types/src/schema/definition/type/block.ts +++ b/packages/@sanity/types/src/schema/definition/type/block.ts @@ -1,9 +1,9 @@ import {ComponentType, ReactNode} from 'react' import {RuleDef, ValidationBuilder} from '../../ruleBuilder' import {InitialValueProperty} from '../../types' -import {SchemaTypeDefinition, TypeReference} from '../schemaDefinition' import {ArrayOfType} from './array' import {BaseSchemaDefinition} from './common' +import {ObjectDefinition} from './object' /** @public */ export interface BlockOptions { @@ -15,28 +15,42 @@ export interface BlockOptions { export interface BlockRule extends RuleDef {} /** @public */ -export interface DecoratorDefinition { +export interface BlockDecoratorDefinition { title: string value: string - icon?: ReactNode | ComponentType - blockEditor?: { - icon?: ReactNode | ComponentType - render?: ComponentType - } + icon?: ReactNode | ComponentType } /** @public */ -export interface MarksDefinition { - decorators?: DecoratorDefinition[] - annotations?: (SchemaTypeDefinition | TypeReference)[] +export interface BlockStyleDefinition { + title: string + value: string +} + +/** @public */ +export interface BlockListDefinition { + title: string + value: string + icon?: ReactNode | ComponentType +} + +/** @public */ +export interface BlockAnnotationDefinition extends ObjectDefinition { + icon?: ReactNode | ComponentType +} + +/** @public */ +export interface BlockMarksDefinition { + decorators?: BlockDecoratorDefinition[] + annotations?: ArrayOfType<'object' | 'reference'>[] } /** @public */ export interface BlockDefinition extends BaseSchemaDefinition { type: 'block' - styles?: Array<{title: string; value: string}> - lists?: Array<{title: string; value: string}> - marks?: MarksDefinition + styles?: BlockStyleDefinition[] + lists?: BlockListDefinition[] + marks?: BlockMarksDefinition of?: ArrayOfType[] initialValue?: InitialValueProperty options?: BlockOptions diff --git a/packages/@sanity/types/src/schema/definition/type/index.ts b/packages/@sanity/types/src/schema/definition/type/index.ts index 69284ba9ac4..97b66ad7538 100644 --- a/packages/@sanity/types/src/schema/definition/type/index.ts +++ b/packages/@sanity/types/src/schema/definition/type/index.ts @@ -12,7 +12,6 @@ export * from './number' export * from './object' export * from './reference' export * from './slug' -export * from './span' export * from './string' export * from './text' export * from './url' diff --git a/packages/@sanity/types/src/schema/definition/type/span.ts b/packages/@sanity/types/src/schema/definition/type/span.ts deleted file mode 100644 index 4a35c709d01..00000000000 --- a/packages/@sanity/types/src/schema/definition/type/span.ts +++ /dev/null @@ -1,13 +0,0 @@ -import {BaseSchemaDefinition} from './common' -import {StringOptions} from './string' - -/** @public */ -// exists only to allow fo extensions. span is not really a user-land type, so probably unused though -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface SpanOptions extends StringOptions {} - -/** @public */ -export interface SpanDefinition extends BaseSchemaDefinition { - type: 'span' - options?: SpanOptions -} diff --git a/packages/@sanity/types/src/schema/test/block.test.ts b/packages/@sanity/types/src/schema/test/block.test.ts index 82a7abad794..4904af908c3 100644 --- a/packages/@sanity/types/src/schema/test/block.test.ts +++ b/packages/@sanity/types/src/schema/test/block.test.ts @@ -35,13 +35,19 @@ describe('block types', () => { { title: 'Sup', value: 'sup', - blockEditor: { - icon: () => null, - render: (props) => props, - }, + icon: () => null, + }, + ], + annotations: [ + { + name: 'authorInline', + title: 'Author', + type: 'reference', + to: {type: 'author'}, }, + {type: 'author', initialValue: {}}, + {type: 'object', fields: [{name: 'title', type: 'string'}]}, ], - annotations: [{name: 'author', title: 'Author', type: 'reference', to: {type: 'author'}}], }, of: [{type: 'string'}], options: { @@ -70,10 +76,7 @@ describe('block types', () => { { title: 'Sup', value: 'sup', - blockEditor: { - icon: () => null, - render: (props) => props, - }, + icon: () => null, }, ], annotations: [{name: 'author', title: 'Author', type: 'reference', to: {type: 'author'}}], @@ -96,10 +99,7 @@ describe('block types', () => { { title: 'Sup', value: 'sup', - blockEditor: { - icon: () => null, - render: (props) => props, - }, + icon: () => null, }, ], annotations: [{name: 'author', title: 'Author', type: 'reference', to: {type: 'author'}}], diff --git a/packages/@sanity/types/src/schema/types.ts b/packages/@sanity/types/src/schema/types.ts index 90f061c2fd0..ad2d942e053 100644 --- a/packages/@sanity/types/src/schema/types.ts +++ b/packages/@sanity/types/src/schema/types.ts @@ -7,6 +7,7 @@ import type {PreviewConfig} from './preview' import {SchemaTypeDefinition} from './definition/schemaDefinition' import {ArrayOptions} from './definition/type/array' import { + BlockDecoratorDefinition, BlockOptions, BooleanOptions, DateOptions, @@ -19,7 +20,6 @@ import { StringOptions, TextOptions, } from './definition/type' -import {TitledListValue} from './definition/type/common' export {defineType, defineField, defineArrayMember, typed} from './define' @@ -183,6 +183,8 @@ export interface BaseSchemaType { /** @beta */ components?: { + block?: ComponentType + annotation?: ComponentType diff?: ComponentType field?: ComponentType input?: ComponentType @@ -248,7 +250,9 @@ export type ArraySchemaTypeOf * * @internal */ -export type MarksObjectField = {name: 'marks'} & ObjectField> +export type SpanMarksObjectField = {name: 'marks'} & ObjectField< + ArraySchemaTypeOf +> /** * A specific `ObjectField` for `text` in `SpanSchemaType` @@ -256,7 +260,7 @@ export type MarksObjectField = {name: 'marks'} & ObjectField +export type SpanTextObjectField = {name: 'text'} & ObjectField /** * A specific `ObjectField` for `style` in `BlockSchemaType` @@ -264,7 +268,7 @@ export type TextObjectField = {name: 'text'} & ObjectField * * @internal */ -export type StyleObjectField = {name: 'style'} & ObjectField +export type BlockStyleObjectField = {name: 'style'} & ObjectField /** * A specific `ObjectField` for `list` in `BlockSchemaType` @@ -272,7 +276,7 @@ export type StyleObjectField = {name: 'style'} & ObjectField * * @internal */ -export type ListObjectField = {name: 'list'} & ObjectField +export type BlockListObjectField = {name: 'list'} & ObjectField /** * The specific `children` field of a `block` type (`BlockSchemaType`) @@ -291,15 +295,15 @@ export type BlockChildrenObjectField = {name: 'children'} & ObjectField { annotations: (ObjectSchemaType & { - blockEditor?: { - icon?: string | ComponentType - render?: ComponentType + icon?: string | ComponentType + components?: { + item?: ComponentType } })[] - decorators: TitledListValue[] + decorators: BlockDecoratorDefinition[] // the first field will always be the `marks` field and the second will // always be the `text` field - fields: [MarksObjectField, TextObjectField] + fields: [SpanMarksObjectField, SpanTextObjectField] } /** @@ -313,8 +317,8 @@ export interface BlockSchemaType extends ObjectSchemaType { fields: [ // the first 3 field are always block children, styles, and lists BlockChildrenObjectField, - StyleObjectField, - ListObjectField, + BlockStyleObjectField, + BlockListObjectField, // then it could be any additional fields the user could add ...ObjectField[] ]