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

fix: make sure a subsequent empty action set can't trigger a default action #453

Merged
merged 4 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
11 changes: 10 additions & 1 deletion packages/editor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ In order to provide a robust and consistent end-user experience, the editor is b
> [!WARNING]
> The `@portabletext/editor` is currently on the path to deprecate legacy APIs and introduce new ones. The end goals are to make the editor easier to use outside of `Sanity` (and without `@sanity/*` libraries) as well as providing a brand new API to configure the behavior of the editor.
>
> This means that the `defineSchema` and `useEditor` APIs showcased here are still experimental APIs tagged with `@alpha` and cannot be considered stable yet. At the same time, the examples below showcase usages of legacy static methods on the `PortableTextEditor` (for example, `PortableTextEditor.isMarkActive(...)` and `PortableTextEditor.toggleMark(...)`) that will soon be discouraged and deprecrated.
> This means that the `defineSchema` and `EditorProvider` APIs showcased here are still experimental APIs tagged with `@alpha` and cannot be considered stable yet. At the same time, the examples below showcase usages of legacy static methods on the `PortableTextEditor` (for example, `PortableTextEditor.isMarkActive(...)` and `PortableTextEditor.toggleMark(...)`) that will soon be discouraged and deprecrated.

Check [/examples/basic/src/App.tsx](/examples/basic/src/App.tsx) for a basic example of how to set up the edior. Most of the source code from this example app can also be found in the instructions below.

Expand Down Expand Up @@ -369,3 +369,12 @@ function Toolbar() {
)
}
```

## Behavior API (Coming Soon)

The Behavior API is a new way of interfacing with the Portable Text Editor. It allows you to think of and treat the editor as a state machine by:

1. Declaratively hooking into editor **events** and defining new behaviors using `defineBehavior`. (A "Behavior" (1) listens for an **event**, (2) uses a **guard** to determine whether it should run and (3) raises a set of **actions** to be performed on the editor.)
2. Imperatively trigger **events** using `editor.send(…)` which in turn can trigger behaviors defined using `defineBehavior`.
3. Deriving editor **state** using **pure functions**.
4. Subscribe to **emitted** editor **events** using `editor.on(…)`.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {isEqual} from 'lodash'
import {Editor, Node, Path, Range, Transforms} from 'slate'
import type {SlateTextBlock, VoidElement} from '../../types/slate'
import type {BehaviourActionImplementation} from './behavior.actions'
import type {BehaviorActionImplementation} from './behavior.actions'

export const insertBreakActionImplementation: BehaviourActionImplementation<
export const insertBreakActionImplementation: BehaviorActionImplementation<
'insert break'
> = ({context, action}) => {
const keyGenerator = context.keyGenerator
Expand Down Expand Up @@ -204,7 +204,7 @@ export const insertBreakActionImplementation: BehaviourActionImplementation<
}
}

export const insertSoftBreakActionImplementation: BehaviourActionImplementation<
export const insertSoftBreakActionImplementation: BehaviorActionImplementation<
'insert soft break'
> = ({context, action}) => {
// This mimics Slate's internal which also just does a regular insert break
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {Editor, Transforms} from 'slate'
import type {BehaviourActionImplementation} from './behavior.actions'
import type {BehaviorActionImplementation} from './behavior.actions'

export const insertSpanActionImplementation: BehaviourActionImplementation<
export const insertSpanActionImplementation: BehaviorActionImplementation<
'insert span'
> = ({context, action}) => {
if (!action.editor.selection) {
Expand Down
8 changes: 4 additions & 4 deletions packages/editor/src/editor/behavior/behavior.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export type BehaviorActionContext = {
schema: PortableTextMemberSchemaTypes
}

export type BehaviourActionImplementation<
export type BehaviorActionImplementation<
TBehaviorActionType extends BehaviorAction['type'],
TReturnType = void,
> = ({
Expand All @@ -46,11 +46,11 @@ export type BehaviourActionImplementation<
action: PickFromUnion<BehaviorAction, 'type', TBehaviorActionType>
}) => TReturnType

type BehaviourActionImplementations = {
[TBehaviorActionType in BehaviorAction['type']]: BehaviourActionImplementation<TBehaviorActionType>
type BehaviorActionImplementations = {
[TBehaviorActionType in BehaviorAction['type']]: BehaviorActionImplementation<TBehaviorActionType>
}

const behaviorActionImplementations: BehaviourActionImplementations = {
const behaviorActionImplementations: BehaviorActionImplementations = {
'annotation.add': addAnnotationActionImplementation,
'annotation.remove': removeAnnotationActionImplementation,
'annotation.toggle': toggleAnnotationActionImplementation,
Expand Down
7 changes: 5 additions & 2 deletions packages/editor/src/editor/editor-machine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,11 @@ export const editorMachine = setup({

for (const actionIntends of actionIntendSets) {
behaviorOverwritten =
actionIntends.length > 0 &&
actionIntends.some((actionIntend) => actionIntend.type !== 'effect')
behaviorOverwritten ||
(actionIntends.length > 0 &&
actionIntends.some(
(actionIntend) => actionIntend.type !== 'effect',
))

enqueue.raise({
type: 'behavior action intends',
Expand Down
10 changes: 5 additions & 5 deletions packages/editor/src/editor/plugins/createWithEditableAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import {
KEY_TO_VALUE_ELEMENT,
SLATE_TO_PORTABLE_TEXT_RANGE,
} from '../../utils/weakMaps'
import type {BehaviourActionImplementation} from '../behavior/behavior.actions'
import type {BehaviorActionImplementation} from '../behavior/behavior.actions'
import type {EditorActor} from '../editor-machine'
import {isDecoratorActive} from './createWithPortableTextMarkModel'

Expand Down Expand Up @@ -487,7 +487,7 @@ export function createEditableAPI(
return editableApi
}

export const insertBlockObjectActionImplementation: BehaviourActionImplementation<
export const insertBlockObjectActionImplementation: BehaviorActionImplementation<
'insert block object',
Path
> = ({context, action}) => {
Expand Down Expand Up @@ -640,7 +640,7 @@ export type AddedAnnotationPaths = {
spanPath: Path
}

export const addAnnotationActionImplementation: BehaviourActionImplementation<
export const addAnnotationActionImplementation: BehaviorActionImplementation<
'annotation.add',
AddedAnnotationPaths | undefined
> = ({context, action}) => {
Expand Down Expand Up @@ -761,7 +761,7 @@ export const addAnnotationActionImplementation: BehaviourActionImplementation<
return paths
}

export const removeAnnotationActionImplementation: BehaviourActionImplementation<
export const removeAnnotationActionImplementation: BehaviorActionImplementation<
'annotation.remove'
> = ({action}) => {
const editor = action.editor
Expand Down Expand Up @@ -910,7 +910,7 @@ export const removeAnnotationActionImplementation: BehaviourActionImplementation
}
}

export const toggleAnnotationActionImplementation: BehaviourActionImplementation<
export const toggleAnnotationActionImplementation: BehaviorActionImplementation<
'annotation.toggle',
AddedAnnotationPaths | undefined
> = ({context, action}) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {debugWithName} from '../../utils/debug'
import {getNextSpan, getPreviousSpan} from '../../utils/sibling-utils'
import {isChangingRemotely} from '../../utils/withChanges'
import {isRedoing, isUndoing} from '../../utils/withUndoRedo'
import type {BehaviourActionImplementation} from '../behavior/behavior.actions'
import type {BehaviorActionImplementation} from '../behavior/behavior.actions'
import type {EditorActor} from '../editor-machine'

const debug = debugWithName('plugin:withPortableTextMarkModel')
Expand Down Expand Up @@ -654,7 +654,7 @@ export function createWithPortableTextMarkModel(
}
}

export const addDecoratorActionImplementation: BehaviourActionImplementation<
export const addDecoratorActionImplementation: BehaviorActionImplementation<
'decorator.add'
> = ({action}) => {
const editor = action.editor
Expand Down Expand Up @@ -745,7 +745,7 @@ export const addDecoratorActionImplementation: BehaviourActionImplementation<
}
}

export const removeDecoratorActionImplementation: BehaviourActionImplementation<
export const removeDecoratorActionImplementation: BehaviorActionImplementation<
'decorator.remove'
> = ({action}) => {
const editor = action.editor
Expand Down Expand Up @@ -860,7 +860,7 @@ export function isDecoratorActive({
).includes(decorator)
}

export const toggleDecoratorActionImplementation: BehaviourActionImplementation<
export const toggleDecoratorActionImplementation: BehaviorActionImplementation<
'decorator.toggle'
> = ({context, action}) => {
const isActive = isDecoratorActive({
Expand Down
Loading