Skip to content

Commit

Permalink
prefer dependency injection for slate-react
Browse files Browse the repository at this point in the history
  • Loading branch information
dcousens committed May 23, 2024
1 parent e41bfab commit bb34f61
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 26 deletions.
15 changes: 12 additions & 3 deletions docs/components/docs/DocumentEditorDemo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@ import React, { type ReactNode, useContext, useEffect, useMemo, useState } from
import { type DocumentFeatures } from '@keystone-6/fields-document/views'
import {
type ComponentBlock,
fields,
type InferRenderersForComponentBlocks,
fields,
} from '@keystone-6/fields-document/component-blocks'
import { Global, jsx } from '@emotion/react'

import { getInitialPropsValue } from '../../../packages/fields-document/src/DocumentEditor/component-blocks/initial-values'
import { DocumentEditor, } from '../../../packages/fields-document/src/DocumentEditor'
import { createDocumentEditor, Editor } from '../../../packages/fields-document/src/DocumentEditor/editor-shared'
import {
createDocumentEditor,
Editor,
ReactEditor,
withReact
} from '../../../packages/fields-document/src/DocumentEditor/demo'
import { FormValueContentFromPreviewProps } from '../../../packages/fields-document/src/DocumentEditor/component-blocks/form-from-preview'
import { createGetPreviewProps } from '../../../packages/fields-document/src/DocumentEditor/component-blocks/preview-props'
import { componentBlocks as componentBlocksInSandboxProject } from '../../../tests/sandbox/component-blocks'
Expand Down Expand Up @@ -276,7 +282,10 @@ export const DocumentEditorDemo = () => {
useEffect(() => {
// we want to force normalize when the document features change so
// that no invalid things exist after a user changes something
const editor = createDocumentEditor(documentFeatures, componentBlocks, emptyObj)
const editor = createDocumentEditor(documentFeatures, componentBlocks, emptyObj, {
ReactEditor: ReactEditor as any, // TODO: somehow incompatible
withReact
})
editor.children = value
Editor.normalize(editor, { force: true })
setValue(editor.children)
Expand Down
12 changes: 12 additions & 0 deletions packages/fields-document/src/DocumentEditor/demo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// the docs site needs access to Editor and importing slate would use the version from the content field
// so we're exporting it from here (note that this is not at all visible in the published version)
export { Editor } from 'slate'

export {
ReactEditor,
withReact,
} from 'slate-react'

export {
createDocumentEditor
} from './editor-shared'
17 changes: 8 additions & 9 deletions packages/fields-document/src/DocumentEditor/editor-shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
createEditor,
} from 'slate'
import { withHistory } from 'slate-history'
import { withReact } from 'slate-react'

import { type ComponentBlock } from './component-blocks/api-shared'
import { type DocumentFeatures } from '../views-shared'
Expand All @@ -36,10 +35,6 @@ import { withInsertMenu } from './insert-menu-shared'
import { withBlockMarkdownShortcuts } from './block-markdown-shortcuts'
import { withPasting } from './pasting'

// the docs site needs access to Editor and importing slate would use the version from the content field
// so we're exporting it from here (note that this is not at all visible in the published version)
export { Editor } from 'slate'

export type Block = Exclude<Element, { type: 'relationship' | 'link' }>

const blockquoteChildren = [
Expand Down Expand Up @@ -139,7 +134,13 @@ export function isInlineContainer (node: Node): node is Block & { type: InlineCo
export function createDocumentEditor (
documentFeatures: DocumentFeatures,
componentBlocks: Record<string, ComponentBlock>,
relationships: Relationships
relationships: Relationships,
slate?: {
withReact: (editor: Editor) => any,
ReactEditor: {
focus: (editor: Editor) => void,
},
},
) {
return withPasting(
withSoftBreaks(
Expand Down Expand Up @@ -170,7 +171,7 @@ export function createDocumentEditor (
withDocumentFeaturesNormalization(
documentFeatures,
relationships,
withHistory(withReact(createEditor()))
withHistory(slate?.withReact(createEditor()) ?? createEditor())
)
)
)
Expand Down Expand Up @@ -289,9 +290,7 @@ function handleNodeInInvalidPosition (
const childNodeInfo = editorSchema[nodeType]
// the parent of a block will never be an inline so this casting is okay
const parentNode = Node.get(editor, parentPath) as Block | Editor

const parentNodeType = Editor.isEditor(parentNode) ? 'editor' : parentNode.type

const parentNodeInfo = editorSchema[parentNodeType]

if (!childNodeInfo || childNodeInfo.invalidPositionHandleMode === 'unwrap') {
Expand Down
13 changes: 11 additions & 2 deletions packages/fields-document/src/DocumentEditor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@ import {
Element,
Text,
} from 'slate'
import { Editable, ReactEditor, Slate, useSlate } from 'slate-react'
import {
Editable,
ReactEditor,
Slate,
withReact,
useSlate,
} from 'slate-react'

import { type EditableProps } from 'slate-react/dist/components/editable'
import { type ComponentBlock } from '../component-blocks'
Expand Down Expand Up @@ -140,7 +146,10 @@ export function DocumentEditor ({
const { radii, colors, spacing, fields } = useTheme()
const [expanded, setExpanded] = useState(initialExpanded)
const editor = useMemo(
() => createDocumentEditor(documentFeatures, componentBlocks, relationships),
() => createDocumentEditor(documentFeatures, componentBlocks, relationships, {
ReactEditor,
withReact
}),
[documentFeatures, componentBlocks, relationships]
)

Expand Down
25 changes: 16 additions & 9 deletions packages/fields-document/src/DocumentEditor/tests/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ import {
Range,
Text,
} from 'slate'
import { Slate } from 'slate-react'
import {
Slate,
ReactEditor,
withReact,
} from 'slate-react'

import React from 'react'
import { act, render } from '@testing-library/react'
import { diff } from 'jest-diff'
Expand Down Expand Up @@ -70,7 +75,6 @@ function formatEditor (editor: Node) {

declare global {
namespace jest {

interface Matchers<R, T> {
toEqualEditor(
expected: [T] extends [Editor] ? Editor : 'toEqualEditor only accepts an Editor'
Expand Down Expand Up @@ -191,7 +195,7 @@ function EditorComp ({
)
}

export const makeEditor = (
export function makeEditor (
node: Node,
{
documentFeatures = defaultDocumentFeatures,
Expand All @@ -207,15 +211,17 @@ export const makeEditor = (
isShiftPressedRef?: MutableRefObject<boolean>
skipRenderingDOM?: boolean
} = {}
): Editor & { container?: HTMLElement } => {
): Editor & { container?: HTMLElement } {
if (!Editor.isEditor(node)) {
throw new Error('Unexpected non-editor passed to makeEditor')
}
let editor = createDocumentEditor(documentFeatures, componentBlocks, relationships) as Editor & {
container?: HTMLElement
};
const editor = createDocumentEditor(documentFeatures, componentBlocks, relationships, {
ReactEditor,
withReact
})

// for validation
(editor as any).__config = {
;(editor as any).__config = {
documentFeatures,
componentBlocks,
relationships,
Expand Down Expand Up @@ -277,7 +283,8 @@ export const makeEditor = (
relationships={relationships}
/>
)
editor.container = container

;(editor as any).container = container
}
return editor
}
Expand Down
10 changes: 7 additions & 3 deletions packages/fields-document/src/DocumentEditor/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
Text,
Transforms,
} from 'slate'
import { ReactEditor } from 'slate-react'
import { type ElementFromValidation } from '../structure-validation'

export type Mark =
Expand Down Expand Up @@ -77,7 +76,12 @@ export function moveChildren (

export function insertNodesButReplaceIfSelectionIsAtEmptyParagraphOrHeading (
editor: Editor,
nodes: Node | Node[]
nodes: Node | Node[],
slate?: {
ReactEditor: {
focus: (editor: Editor) => void,
},
},
) {
let pathRefForEmptyNodeAtCursor: PathRef | undefined
const entry = Editor.above(editor, {
Expand All @@ -92,7 +96,7 @@ export function insertNodesButReplaceIfSelectionIsAtEmptyParagraphOrHeading (
Transforms.removeNodes(editor, { at: path })
// even though the selection is in the right place after the removeNodes
// for some reason the editor blurs so we need to focus it again
ReactEditor.focus(editor)
slate?.ReactEditor.focus(editor)
}
}

Expand Down

0 comments on commit bb34f61

Please sign in to comment.