@portabletext/editor 1.19.0 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/selectors/selector.get-active-list-item.ts","../../src/selectors/selector.get-active-style.ts","../../src/selectors/selector.get-selected-spans.ts","../../src/selectors/selector.is-active-annotation.ts","../../src/selectors/selector.is-selection-expanded.ts","../../src/selectors/selector.is-active-decorator.ts","../../src/selectors/selector.is-active-list-item.ts","../../src/selectors/selector.is-active-style.ts"],"sourcesContent":["import type {PortableTextListBlock} from '@sanity/types'\nimport {createGuards} from '../behavior-actions/behavior.guards'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedBlocks} from './selectors'\n\n/**\n * @public\n */\nexport const getActiveListItem: EditorSelector<\n PortableTextListBlock['listItem'] | undefined\n> = ({context}) => {\n if (!context.selection) {\n return undefined\n }\n\n const guards = createGuards(context)\n const selectedBlocks = getSelectedBlocks({context}).map((block) => block.node)\n const selectedTextBlocks = selectedBlocks.filter(guards.isTextBlock)\n\n const firstTextBlock = selectedTextBlocks.at(0)\n\n if (!firstTextBlock) {\n return undefined\n }\n\n const firstListItem = firstTextBlock.listItem\n\n if (!firstListItem) {\n return undefined\n }\n\n if (selectedTextBlocks.every((block) => block.listItem === firstListItem)) {\n return firstListItem\n }\n\n return undefined\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\nimport {createGuards} from '../behavior-actions/behavior.guards'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedBlocks} from './selectors'\n\n/**\n * @public\n */\nexport const getActiveStyle: EditorSelector<PortableTextTextBlock['style']> = ({\n context,\n}) => {\n if (!context.selection) {\n return undefined\n }\n\n const guards = createGuards(context)\n const selectedBlocks = getSelectedBlocks({context}).map((block) => block.node)\n const selectedTextBlocks = selectedBlocks.filter(guards.isTextBlock)\n\n const firstTextBlock = selectedTextBlocks.at(0)\n\n if (!firstTextBlock) {\n return undefined\n }\n\n const firstStyle = firstTextBlock.style\n\n if (!firstStyle) {\n return undefined\n }\n\n if (selectedTextBlocks.every((block) => block.style === firstStyle)) {\n return firstStyle\n }\n\n return undefined\n}\n","import {\n isKeySegment,\n isPortableTextSpan,\n isPortableTextTextBlock,\n type KeyedSegment,\n type PortableTextSpan,\n} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\n\n/**\n * @public\n */\nexport const getSelectedSpans: EditorSelector<\n Array<{\n node: PortableTextSpan\n path: [KeyedSegment, 'children', KeyedSegment]\n }>\n> = ({context}) => {\n if (!context.selection) {\n return []\n }\n\n const selectedSpans: Array<{\n node: PortableTextSpan\n path: [KeyedSegment, 'children', KeyedSegment]\n }> = []\n\n const startPoint = context.selection.backward\n ? context.selection.focus\n : context.selection.anchor\n const endPoint = context.selection.backward\n ? context.selection.anchor\n : context.selection.focus\n\n const startBlockKey = isKeySegment(startPoint.path[0])\n ? startPoint.path[0]._key\n : undefined\n const endBlockKey = isKeySegment(endPoint.path[0])\n ? endPoint.path[0]._key\n : undefined\n\n if (!startBlockKey || !endBlockKey) {\n return selectedSpans\n }\n\n const startSpanKey = isKeySegment(startPoint.path[2])\n ? startPoint.path[2]._key\n : undefined\n const endSpanKey = isKeySegment(endPoint.path[2])\n ? endPoint.path[2]._key\n : undefined\n\n for (const block of context.value) {\n if (!isPortableTextTextBlock(block)) {\n continue\n }\n\n if (block._key === startBlockKey) {\n for (const child of block.children) {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n if (startSpanKey && child._key === startSpanKey) {\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n\n if (startSpanKey === endSpanKey) {\n break\n }\n\n continue\n }\n\n if (endSpanKey && child._key === endSpanKey) {\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n break\n }\n\n if (selectedSpans.length > 0) {\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n }\n }\n\n if (startBlockKey === endBlockKey) {\n break\n }\n\n continue\n }\n\n if (block._key === endBlockKey) {\n for (const child of block.children) {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n if (endSpanKey && child._key === endSpanKey) {\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n break\n }\n\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n }\n\n break\n }\n\n if (selectedSpans.length > 0) {\n for (const child of block.children) {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n }\n }\n }\n\n return selectedSpans\n}\n","import {isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedSpans} from './selector.get-selected-spans'\nimport {getSelectedBlocks} from './selectors'\n\n/**\n * @public\n */\nexport function isActiveAnnotation(\n annotation: string,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selectedBlocks = getSelectedBlocks(snapshot)\n const selectedSpans = getSelectedSpans(snapshot)\n\n if (selectedSpans.length === 0) {\n return false\n }\n\n if (\n selectedSpans.some(\n (span) => !span.node.marks || span.node.marks?.length === 0,\n )\n ) {\n return false\n }\n\n const selectionMarkDefs = selectedBlocks.flatMap((block) =>\n isPortableTextTextBlock(block.node) ? (block.node.markDefs ?? []) : [],\n )\n\n return selectedSpans.every((span) => {\n const spanMarkDefs =\n span.node.marks?.flatMap((mark) => {\n const markDef = selectionMarkDefs.find(\n (markDef) => markDef._key === mark,\n )\n\n return markDef ? [markDef._type] : []\n }) ?? []\n\n return spanMarkDefs.includes(annotation)\n })\n }\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {isSelectionCollapsed} from './selector.is-selection-collapsed'\n\n/**\n * @public\n */\nexport const isSelectionExpanded: EditorSelector<boolean> = ({context}) => {\n return !isSelectionCollapsed({context})\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedSpans} from './selector.get-selected-spans'\nimport {isSelectionExpanded} from './selector.is-selection-expanded'\n\n/**\n * @public\n */\nexport function isActiveDecorator(decorator: string): EditorSelector<boolean> {\n return (snapshot) => {\n if (isSelectionExpanded(snapshot)) {\n const selectedSpans = getSelectedSpans(snapshot)\n\n return (\n selectedSpans.length > 0 &&\n selectedSpans.every((span) => span.node.marks?.includes(decorator))\n )\n }\n\n return snapshot.context.activeDecorators.includes(decorator)\n }\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getActiveListItem} from './selector.get-active-list-item'\n\n/**\n * @public\n */\nexport function isActiveListItem(listItem: string): EditorSelector<boolean> {\n return (snapshot) => {\n const activeListItem = getActiveListItem(snapshot)\n\n return activeListItem === listItem\n }\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getActiveStyle} from './selector.get-active-style'\n\n/**\n * @public\n */\nexport function isActiveStyle(style: string): EditorSelector<boolean> {\n return (snapshot) => {\n const activeStyle = getActiveStyle(snapshot)\n\n return activeStyle === style\n }\n}\n"],"names":["getActiveListItem","context","selection","guards","createGuards","selectedTextBlocks","getSelectedBlocks","map","block","node","filter","isTextBlock","firstTextBlock","at","firstListItem","listItem","every","getActiveStyle","firstStyle","style","getSelectedSpans","selectedSpans","startPoint","backward","focus","anchor","endPoint","startBlockKey","isKeySegment","path","_key","undefined","endBlockKey","startSpanKey","endSpanKey","value","isPortableTextTextBlock","child","children","isPortableTextSpan","push","length","isActiveAnnotation","annotation","snapshot","selectedBlocks","some","span","marks","selectionMarkDefs","flatMap","markDefs","mark","markDef","find","_type","includes","isSelectionExpanded","isSelectionCollapsed","isActiveDecorator","decorator","activeDecorators","isActiveListItem","isActiveStyle"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/selectors/selector.get-active-list-item.ts","../../src/selectors/selector.get-active-style.ts","../../src/selectors/selector.get-selected-spans.ts","../../src/selectors/selector.is-active-annotation.ts","../../src/selectors/selector.is-selection-expanded.ts","../../src/selectors/selector.is-active-decorator.ts","../../src/selectors/selector.is-active-list-item.ts","../../src/selectors/selector.is-active-style.ts"],"sourcesContent":["import type {PortableTextListBlock} from '@sanity/types'\nimport {createGuards} from '../behavior-actions/behavior.guards'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedBlocks} from './selectors'\n\n/**\n * @public\n */\nexport const getActiveListItem: EditorSelector<\n PortableTextListBlock['listItem'] | undefined\n> = ({context}) => {\n if (!context.selection) {\n return undefined\n }\n\n const guards = createGuards(context)\n const selectedBlocks = getSelectedBlocks({context}).map((block) => block.node)\n const selectedTextBlocks = selectedBlocks.filter(guards.isTextBlock)\n\n const firstTextBlock = selectedTextBlocks.at(0)\n\n if (!firstTextBlock) {\n return undefined\n }\n\n const firstListItem = firstTextBlock.listItem\n\n if (!firstListItem) {\n return undefined\n }\n\n if (selectedTextBlocks.every((block) => block.listItem === firstListItem)) {\n return firstListItem\n }\n\n return undefined\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\nimport {createGuards} from '../behavior-actions/behavior.guards'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedBlocks} from './selectors'\n\n/**\n * @public\n */\nexport const getActiveStyle: EditorSelector<PortableTextTextBlock['style']> = ({\n context,\n}) => {\n if (!context.selection) {\n return undefined\n }\n\n const guards = createGuards(context)\n const selectedBlocks = getSelectedBlocks({context}).map((block) => block.node)\n const selectedTextBlocks = selectedBlocks.filter(guards.isTextBlock)\n\n const firstTextBlock = selectedTextBlocks.at(0)\n\n if (!firstTextBlock) {\n return undefined\n }\n\n const firstStyle = firstTextBlock.style\n\n if (!firstStyle) {\n return undefined\n }\n\n if (selectedTextBlocks.every((block) => block.style === firstStyle)) {\n return firstStyle\n }\n\n return undefined\n}\n","import {\n isKeySegment,\n isPortableTextSpan,\n isPortableTextTextBlock,\n type KeyedSegment,\n type PortableTextSpan,\n} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\n\n/**\n * @public\n */\nexport const getSelectedSpans: EditorSelector<\n Array<{\n node: PortableTextSpan\n path: [KeyedSegment, 'children', KeyedSegment]\n }>\n> = ({context}) => {\n if (!context.selection) {\n return []\n }\n\n const selectedSpans: Array<{\n node: PortableTextSpan\n path: [KeyedSegment, 'children', KeyedSegment]\n }> = []\n\n const startPoint = context.selection.backward\n ? context.selection.focus\n : context.selection.anchor\n const endPoint = context.selection.backward\n ? context.selection.anchor\n : context.selection.focus\n\n const startBlockKey = isKeySegment(startPoint.path[0])\n ? startPoint.path[0]._key\n : undefined\n const endBlockKey = isKeySegment(endPoint.path[0])\n ? endPoint.path[0]._key\n : undefined\n\n if (!startBlockKey || !endBlockKey) {\n return selectedSpans\n }\n\n const startSpanKey = isKeySegment(startPoint.path[2])\n ? startPoint.path[2]._key\n : undefined\n const endSpanKey = isKeySegment(endPoint.path[2])\n ? endPoint.path[2]._key\n : undefined\n\n for (const block of context.value) {\n if (!isPortableTextTextBlock(block)) {\n continue\n }\n\n if (block._key === startBlockKey) {\n for (const child of block.children) {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n if (startSpanKey && child._key === startSpanKey) {\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n\n if (startSpanKey === endSpanKey) {\n break\n }\n\n continue\n }\n\n if (endSpanKey && child._key === endSpanKey) {\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n break\n }\n\n if (selectedSpans.length > 0) {\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n }\n }\n\n if (startBlockKey === endBlockKey) {\n break\n }\n\n continue\n }\n\n if (block._key === endBlockKey) {\n for (const child of block.children) {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n if (endSpanKey && child._key === endSpanKey) {\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n break\n }\n\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n }\n\n break\n }\n\n if (selectedSpans.length > 0) {\n for (const child of block.children) {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n }\n }\n }\n\n return selectedSpans\n}\n","import {isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedSpans} from './selector.get-selected-spans'\nimport {getSelectedBlocks} from './selectors'\n\n/**\n * @public\n */\nexport function isActiveAnnotation(\n annotation: string,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selectedBlocks = getSelectedBlocks(snapshot)\n const selectedSpans = getSelectedSpans(snapshot)\n\n if (selectedSpans.length === 0) {\n return false\n }\n\n if (\n selectedSpans.some(\n (span) => !span.node.marks || span.node.marks?.length === 0,\n )\n ) {\n return false\n }\n\n const selectionMarkDefs = selectedBlocks.flatMap((block) =>\n isPortableTextTextBlock(block.node) ? (block.node.markDefs ?? []) : [],\n )\n\n return selectedSpans.every((span) => {\n const spanMarkDefs =\n span.node.marks?.flatMap((mark) => {\n const markDef = selectionMarkDefs.find(\n (markDef) => markDef._key === mark,\n )\n\n return markDef ? [markDef._type] : []\n }) ?? []\n\n return spanMarkDefs.includes(annotation)\n })\n }\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {isSelectionCollapsed} from './selector.is-selection-collapsed'\n\n/**\n * @public\n */\nexport const isSelectionExpanded: EditorSelector<boolean> = ({context}) => {\n return !isSelectionCollapsed({context})\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedSpans} from './selector.get-selected-spans'\nimport {isSelectionExpanded} from './selector.is-selection-expanded'\n\n/**\n * @public\n */\nexport function isActiveDecorator(decorator: string): EditorSelector<boolean> {\n return (snapshot) => {\n if (isSelectionExpanded(snapshot)) {\n const selectedSpans = getSelectedSpans(snapshot)\n\n return (\n selectedSpans.length > 0 &&\n selectedSpans.every((span) => span.node.marks?.includes(decorator))\n )\n }\n\n return snapshot.context.activeDecorators.includes(decorator)\n }\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getActiveListItem} from './selector.get-active-list-item'\n\n/**\n * @public\n */\nexport function isActiveListItem(listItem: string): EditorSelector<boolean> {\n return (snapshot) => {\n const activeListItem = getActiveListItem(snapshot)\n\n return activeListItem === listItem\n }\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getActiveStyle} from './selector.get-active-style'\n\n/**\n * @public\n */\nexport function isActiveStyle(style: string): EditorSelector<boolean> {\n return (snapshot) => {\n const activeStyle = getActiveStyle(snapshot)\n\n return activeStyle === style\n }\n}\n"],"names":["getActiveListItem","context","selection","guards","createGuards","selectedTextBlocks","getSelectedBlocks","map","block","node","filter","isTextBlock","firstTextBlock","at","firstListItem","listItem","every","getActiveStyle","firstStyle","style","getSelectedSpans","selectedSpans","startPoint","backward","focus","anchor","endPoint","startBlockKey","isKeySegment","path","_key","undefined","endBlockKey","startSpanKey","endSpanKey","value","isPortableTextTextBlock","child","children","isPortableTextSpan","push","length","isActiveAnnotation","annotation","snapshot","selectedBlocks","some","span","marks","selectionMarkDefs","flatMap","markDefs","mark","markDef","find","_type","includes","isSelectionExpanded","isSelectionCollapsed","isActiveDecorator","decorator","activeDecorators","isActiveListItem","isActiveStyle"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portabletext/editor",
3
- "version": "1.19.0",
3
+ "version": "1.20.0",
4
4
  "description": "Portable Text Editor made in React",
5
5
  "keywords": [
6
6
  "sanity",
@@ -72,7 +72,7 @@
72
72
  "@portabletext/toolkit": "^2.0.16",
73
73
  "@sanity/block-tools": "^3.68.3",
74
74
  "@sanity/diff-match-patch": "^3.1.2",
75
- "@sanity/pkg-utils": "^6.12.3",
75
+ "@sanity/pkg-utils": "^6.13.1",
76
76
  "@sanity/schema": "^3.68.3",
77
77
  "@sanity/types": "^3.68.3",
78
78
  "@testing-library/jest-dom": "^6.6.3",
@@ -87,15 +87,14 @@
87
87
  "@vitejs/plugin-react": "^4.3.4",
88
88
  "@vitest/browser": "^2.1.8",
89
89
  "@vitest/coverage-istanbul": "^2.1.8",
90
- "babel-plugin-react-compiler": "19.0.0-beta-55955c9-20241229",
90
+ "babel-plugin-react-compiler": "19.0.0-beta-63e3235-20250105",
91
91
  "eslint": "8.57.1",
92
- "eslint-plugin-react-compiler": "19.0.0-beta-55955c9-20241229",
92
+ "eslint-plugin-react-compiler": "19.0.0-beta-63e3235-20250105",
93
93
  "eslint-plugin-react-hooks": "^5.1.0",
94
94
  "jsdom": "^25.0.1",
95
95
  "react": "^19.0.0",
96
96
  "react-dom": "^19.0.0",
97
97
  "rxjs": "^7.8.1",
98
- "styled-components": "^6.1.13",
99
98
  "typescript": "5.7.2",
100
99
  "vite": "^6.0.4",
101
100
  "vitest": "^2.1.8",
@@ -107,8 +106,7 @@
107
106
  "@sanity/schema": "^3.68.3",
108
107
  "@sanity/types": "^3.68.3",
109
108
  "react": "^16.9 || ^17 || ^18 || ^19",
110
- "rxjs": "^7.8.1",
111
- "styled-components": "^6.1.13"
109
+ "rxjs": "^7.8.1"
112
110
  },
113
111
  "engines": {
114
112
  "node": ">=18"
@@ -296,9 +296,9 @@ export type BehaviorActionIntendSet<
296
296
  * @beta
297
297
  */
298
298
  export function defineBehavior<
299
- TAnyBehaviorEventType extends BehaviorEvent['type'],
299
+ TBehaviorEventType extends BehaviorEvent['type'],
300
300
  TGuardResponse = true,
301
- >(behavior: Behavior<TAnyBehaviorEventType, TGuardResponse>): Behavior {
301
+ >(behavior: Behavior<TBehaviorEventType, TGuardResponse>): Behavior {
302
302
  return behavior as unknown as Behavior
303
303
  }
304
304
 
@@ -30,11 +30,6 @@ import {debugWithName} from '../../utils/debug'
30
30
  import {fromSlateValue} from '../../utils/values'
31
31
  import {KEY_TO_VALUE_ELEMENT} from '../../utils/weakMaps'
32
32
  import ObjectNode from '../nodes/DefaultObject'
33
- import {
34
- DefaultBlockObject,
35
- DefaultListItem,
36
- DefaultListItemInner,
37
- } from '../nodes/index'
38
33
  import {DraggableBlock} from './DraggableBlock'
39
34
 
40
35
  const debug = debugWithName('components:Element')
@@ -185,12 +180,14 @@ export const Element: FunctionComponent<ElementProps> = ({
185
180
  })
186
181
  }
187
182
  let level: number | undefined
183
+
188
184
  if (isListItem) {
189
185
  if (typeof element.level === 'number') {
190
186
  level = element.level
191
187
  }
192
188
  className += ` pt-list-item pt-list-item-${element.listItem} pt-list-item-level-${level || 1}`
193
189
  }
190
+
194
191
  if (editor.isListBlock(value) && isListItem && element.listItem) {
195
192
  const listType = schemaTypes.lists.find(
196
193
  (item) => item.value === element.listItem,
@@ -207,17 +204,9 @@ export const Element: FunctionComponent<ElementProps> = ({
207
204
  level: value.level || 1,
208
205
  editorElementRef: blockRef,
209
206
  })
210
- } else {
211
- renderedBlock = (
212
- <DefaultListItem
213
- listStyle={value.listItem || schemaTypes.lists[0].value}
214
- listLevel={value.level || 1}
215
- >
216
- <DefaultListItemInner>{renderedBlock}</DefaultListItemInner>
217
- </DefaultListItem>
218
- )
219
207
  }
220
208
  }
209
+
221
210
  const renderProps: Omit<BlockRenderProps, 'type'> = Object.defineProperty(
222
211
  {
223
212
  children: renderedBlock,
@@ -263,24 +252,31 @@ export const Element: FunctionComponent<ElementProps> = ({
263
252
  </div>
264
253
  )
265
254
  }
255
+
266
256
  const schemaType = schemaTypes.blockObjects.find(
267
257
  (_type) => _type.name === element._type,
268
258
  )
259
+
269
260
  if (!schemaType) {
270
261
  throw new Error(
271
262
  `Could not find schema type for block element of _type ${element._type}`,
272
263
  )
273
264
  }
265
+
274
266
  if (debugRenders) {
275
267
  debug(`Render ${element._key} (object block)`)
276
268
  }
269
+
277
270
  className = 'pt-block pt-object-block'
271
+
278
272
  const block = fromSlateValue(
279
273
  [element],
280
274
  schemaTypes.block.name,
281
275
  KEY_TO_VALUE_ELEMENT.get(editor),
282
276
  )[0]
277
+
283
278
  let renderedBlockFromProps: JSX.Element | undefined
279
+
284
280
  if (renderBlock) {
285
281
  const _props: Omit<BlockRenderProps, 'type'> = Object.defineProperty(
286
282
  {
@@ -305,20 +301,18 @@ export const Element: FunctionComponent<ElementProps> = ({
305
301
  )
306
302
  renderedBlockFromProps = renderBlock(_props as BlockRenderProps)
307
303
  }
304
+
308
305
  return (
309
306
  <div key={element._key} {...attributes} className={className}>
310
307
  {children}
311
308
  <DraggableBlock element={element} readOnly={readOnly} blockRef={blockRef}>
312
- {renderedBlockFromProps && (
313
- <div ref={blockRef} contentEditable={false}>
314
- {renderedBlockFromProps}
315
- </div>
316
- )}
317
- {!renderedBlockFromProps && (
318
- <DefaultBlockObject selected={selected}>
309
+ <div ref={blockRef} contentEditable={false}>
310
+ {renderedBlockFromProps ? (
311
+ renderedBlockFromProps
312
+ ) : (
319
313
  <ObjectNode value={value} />
320
- </DefaultBlockObject>
321
- )}
314
+ )}
315
+ </div>
322
316
  </DraggableBlock>
323
317
  </div>
324
318
  )
@@ -82,6 +82,10 @@ export type EditorEvent = PickFromUnion<
82
82
  */
83
83
  export type Editor = {
84
84
  getSnapshot: () => EditorSnapshot
85
+ /**
86
+ * @beta
87
+ */
88
+ registerBehavior: (config: {behavior: Behavior}) => () => void
85
89
  send: (event: EditorEvent) => void
86
90
  on: ActorRef<Snapshot<unknown>, EventObject, EditorEmittedEvent>['on']
87
91
  _internal: {
@@ -135,6 +139,19 @@ function createEditorFromActor(editorActor: EditorActor): Editor {
135
139
  editorActorSnapshot: editorActor.getSnapshot(),
136
140
  slateEditorInstance: slateEditor.instance,
137
141
  }),
142
+ registerBehavior: (config) => {
143
+ editorActor.send({
144
+ type: 'add behavior',
145
+ behavior: config.behavior,
146
+ })
147
+
148
+ return () => {
149
+ editorActor.send({
150
+ type: 'remove behavior',
151
+ behavior: config.behavior,
152
+ })
153
+ }
154
+ },
138
155
  send: (event) => {
139
156
  editorActor.send(event)
140
157
  },
@@ -79,6 +79,14 @@ export type InternalEditorEvent =
79
79
  editor: PortableTextSlateEditor
80
80
  nativeEvent?: {preventDefault: () => void}
81
81
  }
82
+ | {
83
+ type: 'add behavior'
84
+ behavior: Behavior
85
+ }
86
+ | {
87
+ type: 'remove behavior'
88
+ behavior: Behavior
89
+ }
82
90
  | {
83
91
  type: 'update readOnly'
84
92
  readOnly: boolean
@@ -181,7 +189,7 @@ export type InternalEditorEmittedEvent =
181
189
  export const editorMachine = setup({
182
190
  types: {
183
191
  context: {} as {
184
- behaviors: Array<Behavior>
192
+ behaviors: Set<Behavior>
185
193
  keyGenerator: () => string
186
194
  pendingEvents: Array<PatchEvent | MutationEvent>
187
195
  schema: EditorSchema
@@ -202,10 +210,26 @@ export const editorMachine = setup({
202
210
  },
203
211
  },
204
212
  actions: {
213
+ 'add behavior to context': assign({
214
+ behaviors: ({context, event}) => {
215
+ assertEvent(event, 'add behavior')
216
+
217
+ return new Set([...context.behaviors, event.behavior])
218
+ },
219
+ }),
220
+ 'remove behavior from context': assign({
221
+ behaviors: ({context, event}) => {
222
+ assertEvent(event, 'remove behavior')
223
+
224
+ context.behaviors.delete(event.behavior)
225
+
226
+ return new Set([...context.behaviors])
227
+ },
228
+ }),
205
229
  'assign behaviors': assign({
206
230
  behaviors: ({event}) => {
207
231
  assertEvent(event, 'update behaviors')
208
- return event.behaviors
232
+ return new Set(event.behaviors)
209
233
  },
210
234
  }),
211
235
  'assign schema': assign({
@@ -253,7 +277,7 @@ export const editorMachine = setup({
253
277
  editor: event.editor,
254
278
  } satisfies BehaviorAction)
255
279
 
256
- const eventBehaviors = context.behaviors.filter(
280
+ const eventBehaviors = [...context.behaviors.values()].filter(
257
281
  (behavior) => behavior.on === event.behaviorEvent.type,
258
282
  )
259
283
 
@@ -375,7 +399,7 @@ export const editorMachine = setup({
375
399
  }).createMachine({
376
400
  id: 'editor',
377
401
  context: ({input}) => ({
378
- behaviors: input.behaviors ?? coreBehaviors,
402
+ behaviors: new Set(input.behaviors ?? coreBehaviors),
379
403
  keyGenerator: input.keyGenerator,
380
404
  pendingEvents: [],
381
405
  schema: input.schema,
@@ -385,6 +409,8 @@ export const editorMachine = setup({
385
409
  value: input.value,
386
410
  }),
387
411
  on: {
412
+ 'add behavior': {actions: 'add behavior to context'},
413
+ 'remove behavior': {actions: 'remove behavior from context'},
388
414
  'unset': {actions: emit(({event}) => event)},
389
415
  'value changed': {actions: emit(({event}) => event)},
390
416
  'invalid value': {actions: emit(({event}) => event)},
@@ -7,8 +7,8 @@ type Props = {
7
7
 
8
8
  const DefaultObject = (props: Props): JSX.Element => {
9
9
  return (
10
- <div>
11
- <pre>{JSON.stringify(props.value, null, 2)}</pre>
10
+ <div style={{userSelect: 'none'}}>
11
+ [{props.value._type}: {props.value._key}]
12
12
  </div>
13
13
  )
14
14
  }
@@ -1,189 +0,0 @@
1
- import {styled} from 'styled-components'
2
-
3
- export const DefaultBlockObject = styled.div<{selected: boolean}>`
4
- user-select: none;
5
- border: ${(props) => {
6
- if (props.selected) {
7
- return '1px solid blue'
8
- }
9
- return '1px solid transparent'
10
- }};
11
- `
12
-
13
- export const DefaultInlineObject = styled.span<{selected: boolean}>`
14
- background: #999;
15
- border: ${(props) => {
16
- if (props.selected) {
17
- return '1px solid blue'
18
- }
19
- return '1px solid transparent'
20
- }};
21
- `
22
-
23
- type ListItemProps = {listLevel: number; listStyle: string}
24
-
25
- export const DefaultListItem = styled.div<ListItemProps>`
26
- &.pt-list-item {
27
- width: fit-content;
28
- position: relative;
29
- display: block;
30
-
31
- /* Important 'transform' in order to force refresh the ::before and ::after rules
32
- in Webkit: https://stackoverflow.com/a/21947628/831480
33
- */
34
- transform: translateZ(0);
35
- margin-left: ${(props: ListItemProps) => getLeftPositionForListLevel(props.listLevel)};
36
- }
37
- &.pt-list-item > .pt-list-item-inner {
38
- display: flex;
39
- margin: 0;
40
- padding: 0;
41
- &:before {
42
- justify-content: flex-start;
43
- vertical-align: top;
44
- }
45
- }
46
- &.pt-list-item-bullet > .pt-list-item-inner:before {
47
- content: '${(props: ListItemProps) =>
48
- getContentForListLevelAndStyle(props.listLevel, props.listStyle)}';
49
- font-size: 0.4375rem; /* 7px */
50
- line-height: 1.5rem; /* Same as body text */
51
- /* Optical alignment */
52
- position: relative;
53
- }
54
- }
55
- &.pt-list-item-bullet > .pt-list-item-inner {
56
- &:before {
57
- min-width: 1.5rem; /* Make sure space between bullet and text never shrinks */
58
- }
59
- }
60
- &.pt-list-item-number {
61
- counter-increment: ${(props: {listLevel: number}) =>
62
- getCounterIncrementForListLevel(props.listLevel)};
63
- counter-reset: ${(props: {listLevel: number}) => getCounterResetForListLevel(props.listLevel)};
64
- }
65
- & + :not(.pt-list-item-number) {
66
- counter-reset: listItemNumber;
67
- }
68
- &.pt-list-item-number > .pt-list-item-inner:before {
69
- content: ${(props) => getCounterContentForListLevel(props.listLevel)};
70
- min-width: 1.5rem; /* Make sure space between number and text never shrinks */
71
- /* Optical alignment */
72
- position: relative;
73
- top: 1px;
74
- }
75
- `
76
-
77
- export const DefaultListItemInner = styled.div``
78
-
79
- function getLeftPositionForListLevel(level: number) {
80
- switch (Number(level)) {
81
- case 1:
82
- return '1.5em'
83
- case 2:
84
- return '3em'
85
- case 3:
86
- return '4.5em'
87
- case 4:
88
- return '6em'
89
- case 5:
90
- return '7.5em'
91
- case 6:
92
- return '9em'
93
- case 7:
94
- return '10.5em'
95
- case 8:
96
- return '12em'
97
- case 9:
98
- return '13.5em'
99
- case 10:
100
- return '15em'
101
- default:
102
- return '0em'
103
- }
104
- }
105
-
106
- const bullets = ['●', '○', '■']
107
-
108
- function getContentForListLevelAndStyle(level: number, style: string) {
109
- const normalizedLevel = (level - 1) % 3
110
- if (style === 'bullet') {
111
- return bullets[normalizedLevel]
112
- }
113
- return '*'
114
- }
115
-
116
- function getCounterIncrementForListLevel(level: number) {
117
- switch (level) {
118
- case 1:
119
- return 'listItemNumber'
120
- case 2:
121
- return 'listItemAlpha'
122
- case 3:
123
- return 'listItemRoman'
124
- case 4:
125
- return 'listItemNumberNext'
126
- case 5:
127
- return 'listItemLetterNext'
128
- case 6:
129
- return 'listItemRomanNext'
130
- case 7:
131
- return 'listItemNumberNextNext'
132
- case 8:
133
- return 'listItemAlphaNextNext'
134
- case 9:
135
- return 'listItemRomanNextNext'
136
- default:
137
- return 'listItemNumberNextNextNext'
138
- }
139
- }
140
-
141
- function getCounterResetForListLevel(level: number) {
142
- switch (level) {
143
- case 1:
144
- return 'listItemAlpha'
145
- case 2:
146
- return 'listItemRoman'
147
- case 3:
148
- return 'listItemNumberNext'
149
- case 4:
150
- return 'listItemLetterNext'
151
- case 5:
152
- return 'listItemRomanNext'
153
- case 6:
154
- return 'listItemNumberNextNext'
155
- case 7:
156
- return 'listItemAlphaNextNext'
157
- case 8:
158
- return 'listItemRomanNextNext'
159
- case 9:
160
- return 'listItemNumberNextNextNext'
161
- default:
162
- return 'listItemNumberNextNextNext'
163
- }
164
- }
165
-
166
- function getCounterContentForListLevel(level: number) {
167
- switch (level) {
168
- case 1:
169
- return `counter(listItemNumber) '. '`
170
- case 2:
171
- return `counter(listItemAlpha, lower-alpha) '. '`
172
- case 3:
173
- return `counter(listItemRoman, lower-roman) '. '`
174
- case 4:
175
- return `counter(listItemNumberNext) '. '`
176
- case 5:
177
- return `counter(listItemLetterNext, lower-alpha) '. '`
178
- case 6:
179
- return `counter(listItemRomanNext, lower-roman) '. '`
180
- case 7:
181
- return `counter(listItemNumberNextNext) '. '`
182
- case 8:
183
- return `counter(listItemAlphaNextNext, lower-alpha) '. '`
184
- case 9:
185
- return `counter(listItemRomanNextNext, lower-roman) '. '`
186
- default:
187
- return `counter(listItemNumberNextNextNext) '. '`
188
- }
189
- }