@portabletext/plugin-markdown-shortcuts 2.0.1 → 3.0.1

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.
package/README.md CHANGED
@@ -14,6 +14,7 @@ import {MarkdownShortcutsPlugin} from '@portabletext/plugin-markdown-shortcuts'
14
14
 
15
15
  const schemaDefinition = defineSchema({
16
16
  blockObjects: [{name: 'break'}],
17
+ annotations: [{name: 'link', fields: [{name: 'href', type: 'string'}]}]
17
18
  decorators: [
18
19
  {name: 'em'},
19
20
  {name: 'code'},
@@ -70,16 +71,32 @@ function App() {
70
71
  schema.lists.find((s) => s.name === 'bullet')?.name
71
72
  }
72
73
  horizontalRuleObject={({schema}) => {
73
- const name = schema.blockObjects.find(
74
- (blockObject) => blockObject.name === 'break',
75
- )?.name
76
- return name ? {name} : undefined
74
+ const schemaType = schema.blockObjects.find(
75
+ (object) => object.name === 'break',
76
+ )
77
+
78
+ if (!schemaType) {
79
+ return undefined
80
+ }
81
+
82
+ return {_type: schemaType.name}
77
83
  }}
78
84
  linkObject={({schema, href}) => {
79
- const name = schema.annotations.find(
85
+ const schemaType = schema.annotations.find(
80
86
  (annotation) => annotation.name === 'link',
81
- )?.name
82
- return name ? {name, value: {href}} : undefined
87
+ )
88
+ const hrefField = schemaType?.fields.find(
89
+ (field) => field.name === 'href' && field.type === 'string',
90
+ )
91
+
92
+ if (!schemaType || !hrefField) {
93
+ return undefined
94
+ }
95
+
96
+ return {
97
+ _type: schemaType.name,
98
+ [hrefField.name]: href,
99
+ }
83
100
  }}
84
101
  />
85
102
  </EditorProvider>
package/dist/index.d.ts CHANGED
@@ -1,20 +1,26 @@
1
- import type {EditorSchema} from '@portabletext/editor'
1
+ import type {EditorContext} from '@portabletext/editor'
2
2
  import {JSX} from 'react'
3
3
 
4
4
  declare type MarkdownBehaviorsConfig = {
5
- horizontalRuleObject?: (context: {schema: EditorSchema}) =>
6
- | {
7
- name: string
8
- value?: {
9
- [prop: string]: unknown
10
- }
11
- }
12
- | undefined
13
- defaultStyle?: (context: {schema: EditorSchema}) => string | undefined
5
+ horizontalRuleObject?: ({
6
+ context,
7
+ }: {
8
+ context: Pick<EditorContext, 'schema' | 'keyGenerator'>
9
+ }) => ObjectWithOptionalKey | undefined
10
+ defaultStyle?: ({
11
+ context,
12
+ schema,
13
+ }: {
14
+ context: Pick<EditorContext, 'schema'>
15
+ /**
16
+ * @deprecated Use `context.schema` instead
17
+ */
18
+ schema: EditorContext['schema']
19
+ }) => string | undefined
14
20
  }
15
21
 
16
22
  /**
17
- * @beta
23
+ * @public
18
24
  */
19
25
  export declare function MarkdownShortcutsPlugin({
20
26
  blockquoteStyle,
@@ -31,33 +37,123 @@ export declare function MarkdownShortcutsPlugin({
31
37
  }: MarkdownShortcutsPluginProps): JSX.Element
32
38
 
33
39
  /**
34
- * @beta
40
+ * @public
35
41
  */
36
42
  export declare type MarkdownShortcutsPluginProps = MarkdownBehaviorsConfig & {
37
- blockquoteStyle?: (context: {schema: EditorSchema}) => string | undefined
38
- defaultStyle?: (context: {schema: EditorSchema}) => string | undefined
39
- headingStyle?: (context: {
40
- schema: EditorSchema
43
+ blockquoteStyle?: ({
44
+ context,
45
+ schema,
46
+ }: {
47
+ context: Pick<EditorContext, 'schema'>
48
+ /**
49
+ * @deprecated Use `context.schema` instead
50
+ */
51
+ schema: EditorContext['schema']
52
+ }) => string | undefined
53
+ defaultStyle?: ({
54
+ context,
55
+ schema,
56
+ }: {
57
+ context: Pick<EditorContext, 'schema'>
58
+ /**
59
+ * @deprecated Use `context.schema` instead
60
+ */
61
+ schema: EditorContext['schema']
62
+ }) => string | undefined
63
+ headingStyle?: ({
64
+ context,
65
+ schema,
66
+ props,
67
+ level,
68
+ }: {
69
+ context: Pick<EditorContext, 'schema'>
70
+ /**
71
+ * @deprecated Use `context.schema` instead
72
+ */
73
+ schema: EditorContext['schema']
74
+ props: {
75
+ level: number
76
+ }
77
+ /**
78
+ * @deprecated Use `props.level` instead
79
+ */
41
80
  level: number
42
81
  }) => string | undefined
43
- linkObject?: (context: {schema: EditorSchema; href: string}) =>
44
- | {
45
- name: string
46
- value?: {
47
- [prop: string]: unknown
48
- }
49
- }
50
- | undefined
51
- unorderedList?: (context: {schema: EditorSchema}) => string | undefined
52
- orderedList?: (context: {schema: EditorSchema}) => string | undefined
53
- boldDecorator?: ({schema}: {schema: EditorSchema}) => string | undefined
54
- codeDecorator?: ({schema}: {schema: EditorSchema}) => string | undefined
55
- italicDecorator?: ({schema}: {schema: EditorSchema}) => string | undefined
82
+ linkObject?: ({
83
+ context,
84
+ props,
85
+ }: {
86
+ context: Pick<EditorContext, 'schema' | 'keyGenerator'>
87
+ props: {
88
+ href: string
89
+ }
90
+ }) => ObjectWithOptionalKey | undefined
91
+ unorderedList?: ({
92
+ context,
93
+ schema,
94
+ }: {
95
+ context: Pick<EditorContext, 'schema'>
96
+ /**
97
+ * @deprecated Use `context.schema` instead
98
+ */
99
+ schema: EditorContext['schema']
100
+ }) => string | undefined
101
+ orderedList?: ({
102
+ context,
103
+ schema,
104
+ }: {
105
+ context: Pick<EditorContext, 'schema'>
106
+ /**
107
+ * @deprecated Use `context.schema` instead
108
+ */
109
+ schema: EditorContext['schema']
110
+ }) => string | undefined
111
+ boldDecorator?: ({
112
+ context,
113
+ schema,
114
+ }: {
115
+ context: Pick<EditorContext, 'schema'>
116
+ /**
117
+ * @deprecated Use `context.schema` instead
118
+ */
119
+ schema: EditorContext['schema']
120
+ }) => string | undefined
121
+ codeDecorator?: ({
122
+ context,
123
+ schema,
124
+ }: {
125
+ context: Pick<EditorContext, 'schema'>
126
+ /**
127
+ * @deprecated Use `context.schema` instead
128
+ */
129
+ schema: EditorContext['schema']
130
+ }) => string | undefined
131
+ italicDecorator?: ({
132
+ context,
133
+ schema,
134
+ }: {
135
+ context: Pick<EditorContext, 'schema'>
136
+ /**
137
+ * @deprecated Use `context.schema` instead
138
+ */
139
+ schema: EditorContext['schema']
140
+ }) => string | undefined
56
141
  strikeThroughDecorator?: ({
142
+ context,
57
143
  schema,
58
144
  }: {
59
- schema: EditorSchema
145
+ context: Pick<EditorContext, 'schema'>
146
+ /**
147
+ * @deprecated Use `context.schema` instead
148
+ */
149
+ schema: EditorContext['schema']
60
150
  }) => string | undefined
61
151
  }
62
152
 
153
+ declare type ObjectWithOptionalKey = {
154
+ _type: string
155
+ _key?: string
156
+ [other: string]: unknown
157
+ }
158
+
63
159
  export {}
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import { useEditor } from "@portabletext/editor";
4
4
  import { CharacterPairDecoratorPlugin } from "@portabletext/plugin-character-pair-decorator";
5
5
  import { defineInputRule, InputRulePlugin } from "@portabletext/plugin-input-rule";
6
6
  import { useEffect } from "react";
7
- import { defineBehavior, execute, raise } from "@portabletext/editor/behaviors";
7
+ import { defineBehavior, raise } from "@portabletext/editor/behaviors";
8
8
  import * as selectors from "@portabletext/editor/selectors";
9
9
  import { getPreviousInlineObject } from "@portabletext/editor/selectors";
10
10
  function createMarkdownBehaviors(config) {
@@ -15,7 +15,10 @@ function createMarkdownBehaviors(config) {
15
15
  event
16
16
  }) => {
17
17
  const text = event.originEvent.dataTransfer.getData("text/plain"), hrRegExp = /^(---)$|^(—-)$|^(___)$|^(\*\*\*)$/, hrCharacters = text.match(hrRegExp)?.[0], hrObject = config.horizontalRuleObject?.({
18
- schema: snapshot.context.schema
18
+ context: {
19
+ schema: snapshot.context.schema,
20
+ keyGenerator: snapshot.context.keyGenerator
21
+ }
19
22
  }), focusBlock = selectors.getFocusBlock(snapshot), focusTextBlock = selectors.getFocusTextBlock(snapshot);
20
23
  return !hrCharacters || !hrObject || !focusBlock ? !1 : {
21
24
  hrCharacters,
@@ -26,7 +29,7 @@ function createMarkdownBehaviors(config) {
26
29
  },
27
30
  actions: [(_, {
28
31
  hrCharacters
29
- }) => [execute({
32
+ }) => [raise({
30
33
  type: "insert.text",
31
34
  text: hrCharacters
32
35
  })], ({
@@ -35,29 +38,23 @@ function createMarkdownBehaviors(config) {
35
38
  hrObject,
36
39
  focusBlock,
37
40
  focusTextBlock
38
- }) => focusTextBlock ? [execute({
41
+ }) => focusTextBlock ? [raise({
39
42
  type: "insert.block",
40
43
  block: {
41
44
  _type: snapshot.context.schema.block.name,
42
45
  children: focusTextBlock.node.children
43
46
  },
44
47
  placement: "after"
45
- }), execute({
48
+ }), raise({
46
49
  type: "insert.block",
47
- block: {
48
- _type: hrObject.name,
49
- ...hrObject.value ?? {}
50
- },
50
+ block: hrObject,
51
51
  placement: "after"
52
- }), execute({
52
+ }), raise({
53
53
  type: "delete.block",
54
54
  at: focusBlock.path
55
- })] : [execute({
55
+ })] : [raise({
56
56
  type: "insert.block",
57
- block: {
58
- _type: hrObject.name,
59
- ...hrObject.value ?? {}
60
- },
57
+ block: hrObject,
61
58
  placement: "after"
62
59
  })]]
63
60
  }), clearStyleOnBackspace = defineBehavior({
@@ -69,6 +66,9 @@ function createMarkdownBehaviors(config) {
69
66
  if (!selectionCollapsed || !focusTextBlock || !focusSpan)
70
67
  return !1;
71
68
  const atTheBeginningOfBLock = focusTextBlock.node.children[0]._key === focusSpan.node._key && snapshot.context.selection?.focus.offset === 0, defaultStyle = config.defaultStyle?.({
69
+ context: {
70
+ schema: snapshot.context.schema
71
+ },
72
72
  schema: snapshot.context.schema
73
73
  });
74
74
  return atTheBeginningOfBLock && defaultStyle && focusTextBlock.node.style !== defaultStyle ? {
@@ -79,7 +79,7 @@ function createMarkdownBehaviors(config) {
79
79
  actions: [(_, {
80
80
  defaultStyle,
81
81
  focusTextBlock
82
- }) => [execute({
82
+ }) => [raise({
83
83
  type: "block.set",
84
84
  props: {
85
85
  style: defaultStyle
@@ -97,6 +97,9 @@ function createBlockquoteRule(config) {
97
97
  event
98
98
  }) => {
99
99
  const style = config.blockquoteStyle({
100
+ context: {
101
+ schema: snapshot.context.schema
102
+ },
100
103
  schema: snapshot.context.schema
101
104
  });
102
105
  if (!style || getPreviousInlineObject(snapshot))
@@ -141,7 +144,13 @@ function createHeadingRule(config) {
141
144
  if (!match)
142
145
  return !1;
143
146
  const level = match.text.length - 1, style = config.headingStyle({
147
+ context: {
148
+ schema: snapshot.context.schema
149
+ },
144
150
  schema: snapshot.context.schema,
151
+ props: {
152
+ level
153
+ },
145
154
  level
146
155
  });
147
156
  return style ? {
@@ -178,7 +187,10 @@ function createHorizontalRuleRule(config) {
178
187
  event
179
188
  }) => {
180
189
  const hrObject = config.horizontalRuleObject({
181
- schema: snapshot.context.schema
190
+ context: {
191
+ schema: snapshot.context.schema,
192
+ keyGenerator: snapshot.context.keyGenerator
193
+ }
182
194
  });
183
195
  if (!hrObject || getPreviousInlineObject(snapshot))
184
196
  return !1;
@@ -193,10 +205,7 @@ function createHorizontalRuleRule(config) {
193
205
  match
194
206
  }) => [raise({
195
207
  type: "insert.block",
196
- block: {
197
- _type: hrObject.name,
198
- ...hrObject.value ?? {}
199
- },
208
+ block: hrObject,
200
209
  placement: "before",
201
210
  select: "none"
202
211
  }), raise({
@@ -221,12 +230,21 @@ function createMarkdownLinkRule(config) {
221
230
  continue;
222
231
  textLengthDelta = textLengthDelta - (match.targetOffsets.focus.offset - match.targetOffsets.anchor.offset - textMatch.text.length);
223
232
  const linkObject = config.linkObject({
224
- schema: snapshot.context.schema,
225
- href: hrefMatch.text
233
+ context: {
234
+ schema: snapshot.context.schema,
235
+ keyGenerator: snapshot.context.keyGenerator
236
+ },
237
+ props: {
238
+ href: hrefMatch.text
239
+ }
226
240
  });
227
241
  if (!linkObject)
228
242
  continue;
229
- const leftSideOffsets = {
243
+ const {
244
+ _type,
245
+ _key,
246
+ ...value
247
+ } = linkObject, leftSideOffsets = {
230
248
  anchor: match.targetOffsets.anchor,
231
249
  focus: textMatch.targetOffsets.anchor
232
250
  }, rightSideOffsets = {
@@ -239,8 +257,9 @@ function createMarkdownLinkRule(config) {
239
257
  })), actions.push(raise({
240
258
  type: "annotation.add",
241
259
  annotation: {
242
- name: linkObject.name,
243
- value: linkObject.value ?? {}
260
+ name: _type,
261
+ _key,
262
+ value
244
263
  }
245
264
  })), actions.push(raise({
246
265
  type: "delete",
@@ -272,6 +291,9 @@ function createOrderedListRule(config) {
272
291
  event
273
292
  }) => {
274
293
  const orderedList = config.orderedList({
294
+ context: {
295
+ schema: snapshot.context.schema
296
+ },
275
297
  schema: snapshot.context.schema
276
298
  });
277
299
  if (!orderedList || getPreviousInlineObject(snapshot))
@@ -312,6 +334,9 @@ function createUnorderedListRule(config) {
312
334
  event
313
335
  }) => {
314
336
  const unorderedList = config.unorderedList({
337
+ context: {
338
+ schema: snapshot.context.schema
339
+ },
315
340
  schema: snapshot.context.schema
316
341
  });
317
342
  if (!unorderedList || getPreviousInlineObject(snapshot))
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/behavior.markdown-shortcuts.ts","../src/rule.blockquote.ts","../src/rule.heading.ts","../src/rule.horizontal-rule.ts","../src/rule.markdown-link.ts","../src/rule.ordered-list.ts","../src/rule.unordered-list.ts","../src/plugin.markdown-shortcuts.tsx"],"sourcesContent":["import type {EditorSchema} from '@portabletext/editor'\nimport {defineBehavior, execute} from '@portabletext/editor/behaviors'\nimport * as selectors from '@portabletext/editor/selectors'\n\nexport type MarkdownBehaviorsConfig = {\n horizontalRuleObject?: (context: {\n schema: EditorSchema\n }) => {name: string; value?: {[prop: string]: unknown}} | undefined\n defaultStyle?: (context: {schema: EditorSchema}) => string | undefined\n}\n\nexport function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {\n const automaticHrOnPaste = defineBehavior({\n on: 'clipboard.paste',\n guard: ({snapshot, event}) => {\n const text = event.originEvent.dataTransfer.getData('text/plain')\n const hrRegExp = /^(---)$|^(—-)$|^(___)$|^(\\*\\*\\*)$/\n const hrCharacters = text.match(hrRegExp)?.[0]\n const hrObject = config.horizontalRuleObject?.({\n schema: snapshot.context.schema,\n })\n const focusBlock = selectors.getFocusBlock(snapshot)\n const focusTextBlock = selectors.getFocusTextBlock(snapshot)\n\n if (!hrCharacters || !hrObject || !focusBlock) {\n return false\n }\n\n return {hrCharacters, hrObject, focusBlock, focusTextBlock}\n },\n actions: [\n (_, {hrCharacters}) => [\n execute({\n type: 'insert.text',\n text: hrCharacters,\n }),\n ],\n ({snapshot}, {hrObject, focusBlock, focusTextBlock}) =>\n focusTextBlock\n ? [\n execute({\n type: 'insert.block',\n block: {\n _type: snapshot.context.schema.block.name,\n children: focusTextBlock.node.children,\n },\n placement: 'after',\n }),\n execute({\n type: 'insert.block',\n block: {\n _type: hrObject.name,\n ...(hrObject.value ?? {}),\n },\n placement: 'after',\n }),\n execute({\n type: 'delete.block',\n at: focusBlock.path,\n }),\n ]\n : [\n execute({\n type: 'insert.block',\n block: {\n _type: hrObject.name,\n ...(hrObject.value ?? {}),\n },\n placement: 'after',\n }),\n ],\n ],\n })\n\n const clearStyleOnBackspace = defineBehavior({\n on: 'delete.backward',\n guard: ({snapshot}) => {\n const selectionCollapsed = selectors.isSelectionCollapsed(snapshot)\n const focusTextBlock = selectors.getFocusTextBlock(snapshot)\n const focusSpan = selectors.getFocusSpan(snapshot)\n\n if (!selectionCollapsed || !focusTextBlock || !focusSpan) {\n return false\n }\n\n const atTheBeginningOfBLock =\n focusTextBlock.node.children[0]._key === focusSpan.node._key &&\n snapshot.context.selection?.focus.offset === 0\n\n const defaultStyle = config.defaultStyle?.({\n schema: snapshot.context.schema,\n })\n\n if (\n atTheBeginningOfBLock &&\n defaultStyle &&\n focusTextBlock.node.style !== defaultStyle\n ) {\n return {defaultStyle, focusTextBlock}\n }\n\n return false\n },\n actions: [\n (_, {defaultStyle, focusTextBlock}) => [\n execute({\n type: 'block.set',\n props: {style: defaultStyle},\n at: focusTextBlock.path,\n }),\n ],\n ],\n })\n\n const markdownBehaviors = [automaticHrOnPaste, clearStyleOnBackspace]\n\n return markdownBehaviors\n}\n","import type {EditorSchema} from '@portabletext/editor'\nimport {raise} from '@portabletext/editor/behaviors'\nimport {getPreviousInlineObject} from '@portabletext/editor/selectors'\nimport {defineInputRule} from '@portabletext/plugin-input-rule'\n\nexport function createBlockquoteRule(config: {\n blockquoteStyle: (context: {schema: EditorSchema}) => string | undefined\n}) {\n return defineInputRule({\n on: /^> /,\n guard: ({snapshot, event}) => {\n const style = config.blockquoteStyle({\n schema: snapshot.context.schema,\n })\n\n if (!style) {\n return false\n }\n\n const previousInlineObject = getPreviousInlineObject(snapshot)\n\n if (previousInlineObject) {\n return false\n }\n\n const match = event.matches.at(0)\n\n if (!match) {\n return false\n }\n\n return {style, match}\n },\n actions: [\n ({event}, {style, match}) => [\n raise({\n type: 'block.unset',\n props: ['listItem', 'level'],\n at: event.focusTextBlock.path,\n }),\n raise({\n type: 'block.set',\n props: {style},\n at: event.focusTextBlock.path,\n }),\n raise({\n type: 'delete',\n at: match.targetOffsets,\n }),\n ],\n ],\n })\n}\n","import type {EditorSchema} from '@portabletext/editor'\nimport {raise} from '@portabletext/editor/behaviors'\nimport {getPreviousInlineObject} from '@portabletext/editor/selectors'\nimport {defineInputRule} from '@portabletext/plugin-input-rule'\n\nexport function createHeadingRule(config: {\n headingStyle: (context: {\n schema: EditorSchema\n level: number\n }) => string | undefined\n}) {\n return defineInputRule({\n on: /^#+ /,\n guard: ({snapshot, event}) => {\n const previousInlineObject = getPreviousInlineObject(snapshot)\n\n if (previousInlineObject) {\n return false\n }\n\n const match = event.matches.at(0)\n\n if (!match) {\n return false\n }\n\n const level = match.text.length - 1\n\n const style = config.headingStyle({\n schema: snapshot.context.schema,\n level,\n })\n\n if (!style) {\n return false\n }\n\n return {match, style}\n },\n actions: [\n ({event}, {match, style}) => [\n raise({\n type: 'block.unset',\n props: ['listItem', 'level'],\n at: event.focusTextBlock.path,\n }),\n raise({\n type: 'block.set',\n props: {style},\n at: event.focusTextBlock.path,\n }),\n raise({\n type: 'delete',\n at: match.targetOffsets,\n }),\n ],\n ],\n })\n}\n","import type {EditorSchema} from '@portabletext/editor'\nimport {raise} from '@portabletext/editor/behaviors'\nimport {getPreviousInlineObject} from '@portabletext/editor/selectors'\nimport {defineInputRule} from '@portabletext/plugin-input-rule'\n\nexport function createHorizontalRuleRule(config: {\n horizontalRuleObject: (context: {\n schema: EditorSchema\n }) => {name: string; value?: {[prop: string]: unknown}} | undefined\n}) {\n return defineInputRule({\n on: /^(---)|^(—-)|^(___)|^(\\*\\*\\*)/,\n guard: ({snapshot, event}) => {\n const hrObject = config.horizontalRuleObject({\n schema: snapshot.context.schema,\n })\n\n if (!hrObject) {\n // If no horizontal rule object is provided, then we can safely skip\n // this rule.\n return false\n }\n\n const previousInlineObject = getPreviousInlineObject(snapshot)\n\n if (previousInlineObject) {\n // Input Rules only look at the plain text of the text block. This\n // means that the RegExp is matched even if there is a leading inline\n // object.\n return false\n }\n\n // In theory, an Input Rule could return multiple matches. But in this\n // case we only expect one match.\n const match = event.matches.at(0)\n\n if (!match) {\n return false\n }\n\n return {hrObject, match}\n },\n actions: [\n (_, {hrObject, match}) => [\n raise({\n type: 'insert.block',\n block: {\n _type: hrObject.name,\n ...(hrObject.value ?? {}),\n },\n placement: 'before',\n select: 'none',\n }),\n raise({\n type: 'delete',\n at: match.targetOffsets,\n }),\n ],\n ],\n })\n}\n","import type {EditorSchema} from '@portabletext/editor'\nimport {raise, type BehaviorAction} from '@portabletext/editor/behaviors'\nimport {defineInputRule} from '@portabletext/plugin-input-rule'\n\nexport function createMarkdownLinkRule(config: {\n linkObject: (context: {\n schema: EditorSchema\n href: string\n }) => {name: string; value?: {[prop: string]: unknown}} | undefined\n}) {\n return defineInputRule({\n on: /\\[([^[\\]]+)]\\((.+)\\)/,\n actions: [\n ({snapshot, event}) => {\n const newText = event.textBefore + event.textInserted\n let textLengthDelta = 0\n const actions: Array<BehaviorAction> = []\n\n for (const match of event.matches.reverse()) {\n const textMatch = match.groupMatches.at(0)\n const hrefMatch = match.groupMatches.at(1)\n\n if (textMatch === undefined || hrefMatch === undefined) {\n continue\n }\n\n textLengthDelta =\n textLengthDelta -\n (match.targetOffsets.focus.offset -\n match.targetOffsets.anchor.offset -\n textMatch.text.length)\n\n const linkObject = config.linkObject({\n schema: snapshot.context.schema,\n href: hrefMatch.text,\n })\n\n if (!linkObject) {\n continue\n }\n\n const leftSideOffsets = {\n anchor: match.targetOffsets.anchor,\n focus: textMatch.targetOffsets.anchor,\n }\n const rightSideOffsets = {\n anchor: textMatch.targetOffsets.focus,\n focus: match.targetOffsets.focus,\n }\n\n actions.push(\n raise({\n type: 'select',\n at: textMatch.targetOffsets,\n }),\n )\n actions.push(\n raise({\n type: 'annotation.add',\n annotation: {\n name: linkObject.name,\n value: linkObject.value ?? {},\n },\n }),\n )\n actions.push(\n raise({\n type: 'delete',\n at: rightSideOffsets,\n }),\n )\n actions.push(\n raise({\n type: 'delete',\n at: leftSideOffsets,\n }),\n )\n }\n\n const endCaretPosition = {\n path: event.focusTextBlock.path,\n offset: newText.length - textLengthDelta * -1,\n }\n\n return [\n ...actions,\n raise({\n type: 'select',\n at: {\n anchor: endCaretPosition,\n focus: endCaretPosition,\n },\n }),\n ]\n },\n ],\n })\n}\n","import type {EditorSchema} from '@portabletext/editor'\nimport {raise} from '@portabletext/editor/behaviors'\nimport {getPreviousInlineObject} from '@portabletext/editor/selectors'\nimport {defineInputRule} from '@portabletext/plugin-input-rule'\n\nexport function createOrderedListRule(config: {\n orderedList: (context: {schema: EditorSchema}) => string | undefined\n}) {\n return defineInputRule({\n on: /^1\\. /,\n guard: ({snapshot, event}) => {\n const orderedList = config.orderedList({\n schema: snapshot.context.schema,\n })\n\n if (!orderedList) {\n return false\n }\n\n const previousInlineObject = getPreviousInlineObject(snapshot)\n\n if (previousInlineObject) {\n return false\n }\n\n const match = event.matches.at(0)\n\n if (!match) {\n return false\n }\n\n return {match, orderedList}\n },\n actions: [\n ({event}, {match, orderedList}) => [\n raise({\n type: 'block.unset',\n props: ['style'],\n at: event.focusTextBlock.path,\n }),\n raise({\n type: 'block.set',\n props: {\n listItem: orderedList,\n level: event.focusTextBlock.node.level ?? 1,\n },\n at: event.focusTextBlock.path,\n }),\n raise({\n type: 'delete',\n at: match.targetOffsets,\n }),\n ],\n ],\n })\n}\n","import type {EditorSchema} from '@portabletext/editor'\nimport {raise} from '@portabletext/editor/behaviors'\nimport {getPreviousInlineObject} from '@portabletext/editor/selectors'\nimport {defineInputRule} from '@portabletext/plugin-input-rule'\n\nexport function createUnorderedListRule(config: {\n unorderedList: (context: {schema: EditorSchema}) => string | undefined\n}) {\n return defineInputRule({\n on: /^(-|\\*) /,\n guard: ({snapshot, event}) => {\n const unorderedList = config.unorderedList({\n schema: snapshot.context.schema,\n })\n\n if (!unorderedList) {\n return false\n }\n\n const previousInlineObject = getPreviousInlineObject(snapshot)\n\n if (previousInlineObject) {\n return false\n }\n\n const match = event.matches.at(0)\n\n if (!match) {\n return false\n }\n\n return {match, unorderedList}\n },\n actions: [\n ({event}, {match, unorderedList}) => [\n raise({\n type: 'block.unset',\n props: ['style'],\n at: event.focusTextBlock.path,\n }),\n raise({\n type: 'block.set',\n props: {\n listItem: unorderedList,\n level: event.focusTextBlock.node.level ?? 1,\n },\n at: event.focusTextBlock.path,\n }),\n raise({\n type: 'delete',\n at: match.targetOffsets,\n }),\n ],\n ],\n })\n}\n","import type {EditorSchema} from '@portabletext/editor'\nimport {useEditor} from '@portabletext/editor'\nimport {CharacterPairDecoratorPlugin} from '@portabletext/plugin-character-pair-decorator'\nimport {InputRulePlugin} from '@portabletext/plugin-input-rule'\nimport {useEffect, useMemo} from 'react'\nimport {\n createMarkdownBehaviors,\n type MarkdownBehaviorsConfig,\n} from './behavior.markdown-shortcuts'\nimport {createBlockquoteRule} from './rule.blockquote'\nimport {createHeadingRule} from './rule.heading'\nimport {createHorizontalRuleRule} from './rule.horizontal-rule'\nimport {createMarkdownLinkRule} from './rule.markdown-link'\nimport {createOrderedListRule} from './rule.ordered-list'\nimport {createUnorderedListRule} from './rule.unordered-list'\n\n/**\n * @beta\n */\nexport type MarkdownShortcutsPluginProps = MarkdownBehaviorsConfig & {\n blockquoteStyle?: (context: {schema: EditorSchema}) => string | undefined\n defaultStyle?: (context: {schema: EditorSchema}) => string | undefined\n headingStyle?: (context: {\n schema: EditorSchema\n level: number\n }) => string | undefined\n linkObject?: (context: {\n schema: EditorSchema\n href: string\n }) => {name: string; value?: {[prop: string]: unknown}} | undefined\n unorderedList?: (context: {schema: EditorSchema}) => string | undefined\n orderedList?: (context: {schema: EditorSchema}) => string | undefined\n boldDecorator?: ({schema}: {schema: EditorSchema}) => string | undefined\n codeDecorator?: ({schema}: {schema: EditorSchema}) => string | undefined\n italicDecorator?: ({schema}: {schema: EditorSchema}) => string | undefined\n strikeThroughDecorator?: ({\n schema,\n }: {\n schema: EditorSchema\n }) => string | undefined\n}\n\n/**\n * @beta\n */\nexport function MarkdownShortcutsPlugin({\n blockquoteStyle,\n boldDecorator,\n codeDecorator,\n defaultStyle,\n headingStyle,\n horizontalRuleObject,\n linkObject,\n italicDecorator,\n orderedList,\n strikeThroughDecorator,\n unorderedList,\n}: MarkdownShortcutsPluginProps) {\n const editor = useEditor()\n\n useEffect(() => {\n const behaviors = createMarkdownBehaviors({\n defaultStyle,\n })\n\n const unregisterBehaviors = behaviors.map((behavior) =>\n editor.registerBehavior({behavior}),\n )\n\n return () => {\n for (const unregisterBehavior of unregisterBehaviors) {\n unregisterBehavior()\n }\n }\n }, [defaultStyle, editor])\n\n const inputRules = useMemo(() => {\n const rules = []\n if (blockquoteStyle) {\n rules.push(createBlockquoteRule({blockquoteStyle}))\n }\n if (headingStyle) {\n rules.push(createHeadingRule({headingStyle}))\n }\n if (horizontalRuleObject) {\n rules.push(createHorizontalRuleRule({horizontalRuleObject}))\n }\n if (linkObject) {\n rules.push(createMarkdownLinkRule({linkObject}))\n }\n if (orderedList) {\n rules.push(createOrderedListRule({orderedList}))\n }\n if (unorderedList) {\n rules.push(createUnorderedListRule({unorderedList}))\n }\n return rules.length > 0 ? rules : null\n }, [\n blockquoteStyle,\n headingStyle,\n horizontalRuleObject,\n linkObject,\n orderedList,\n unorderedList,\n ])\n\n return (\n <>\n {boldDecorator ? (\n <>\n <CharacterPairDecoratorPlugin\n decorator={boldDecorator}\n pair={{char: '*', amount: 2}}\n />\n <CharacterPairDecoratorPlugin\n decorator={boldDecorator}\n pair={{char: '_', amount: 2}}\n />\n </>\n ) : null}\n {codeDecorator ? (\n <CharacterPairDecoratorPlugin\n decorator={codeDecorator}\n pair={{char: '`', amount: 1}}\n />\n ) : null}\n {italicDecorator ? (\n <>\n <CharacterPairDecoratorPlugin\n decorator={italicDecorator}\n pair={{char: '*', amount: 1}}\n />\n <CharacterPairDecoratorPlugin\n decorator={italicDecorator}\n pair={{char: '_', amount: 1}}\n />\n </>\n ) : null}\n {strikeThroughDecorator ? (\n <CharacterPairDecoratorPlugin\n decorator={strikeThroughDecorator}\n pair={{char: '~', amount: 2}}\n />\n ) : null}\n {inputRules ? <InputRulePlugin rules={inputRules} /> : null}\n </>\n )\n}\n"],"names":["createMarkdownBehaviors","config","automaticHrOnPaste","defineBehavior","on","guard","snapshot","event","text","originEvent","dataTransfer","getData","hrRegExp","hrCharacters","match","hrObject","horizontalRuleObject","schema","context","focusBlock","selectors","getFocusBlock","focusTextBlock","getFocusTextBlock","actions","_","execute","type","block","_type","name","children","node","placement","value","at","path","clearStyleOnBackspace","selectionCollapsed","isSelectionCollapsed","focusSpan","getFocusSpan","atTheBeginningOfBLock","_key","selection","focus","offset","defaultStyle","style","props","createBlockquoteRule","defineInputRule","blockquoteStyle","getPreviousInlineObject","matches","raise","targetOffsets","createHeadingRule","level","length","headingStyle","createHorizontalRuleRule","select","createMarkdownLinkRule","newText","textBefore","textInserted","textLengthDelta","reverse","textMatch","groupMatches","hrefMatch","undefined","anchor","linkObject","href","leftSideOffsets","rightSideOffsets","push","annotation","endCaretPosition","createOrderedListRule","orderedList","listItem","createUnorderedListRule","unorderedList","MarkdownShortcutsPlugin","t0","$","_c","boldDecorator","codeDecorator","italicDecorator","strikeThroughDecorator","editor","useEditor","t1","t2","unregisterBehaviors","map","behavior","registerBehavior","unregisterBehavior","useEffect","rules","t3","inputRules","char","amount","t4","t5","t6","t7","t8"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/behavior.markdown-shortcuts.ts","../src/rule.blockquote.ts","../src/rule.heading.ts","../src/rule.horizontal-rule.ts","../src/rule.markdown-link.ts","../src/rule.ordered-list.ts","../src/rule.unordered-list.ts","../src/plugin.markdown-shortcuts.tsx"],"sourcesContent":["import type {EditorContext} from '@portabletext/editor'\nimport {defineBehavior, raise} from '@portabletext/editor/behaviors'\nimport * as selectors from '@portabletext/editor/selectors'\n\nexport type ObjectWithOptionalKey = {\n _type: string\n _key?: string\n [other: string]: unknown\n}\n\nexport type MarkdownBehaviorsConfig = {\n horizontalRuleObject?: ({\n context,\n }: {\n context: Pick<EditorContext, 'schema' | 'keyGenerator'>\n }) => ObjectWithOptionalKey | undefined\n defaultStyle?: ({\n context,\n schema,\n }: {\n context: Pick<EditorContext, 'schema'>\n /**\n * @deprecated Use `context.schema` instead\n */\n schema: EditorContext['schema']\n }) => string | undefined\n}\n\nexport function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {\n const automaticHrOnPaste = defineBehavior({\n on: 'clipboard.paste',\n guard: ({snapshot, event}) => {\n const text = event.originEvent.dataTransfer.getData('text/plain')\n const hrRegExp = /^(---)$|^(—-)$|^(___)$|^(\\*\\*\\*)$/\n const hrCharacters = text.match(hrRegExp)?.[0]\n const hrObject = config.horizontalRuleObject?.({\n context: {\n schema: snapshot.context.schema,\n keyGenerator: snapshot.context.keyGenerator,\n },\n })\n const focusBlock = selectors.getFocusBlock(snapshot)\n const focusTextBlock = selectors.getFocusTextBlock(snapshot)\n\n if (!hrCharacters || !hrObject || !focusBlock) {\n return false\n }\n\n return {hrCharacters, hrObject, focusBlock, focusTextBlock}\n },\n actions: [\n (_, {hrCharacters}) => [\n raise({\n type: 'insert.text',\n text: hrCharacters,\n }),\n ],\n ({snapshot}, {hrObject, focusBlock, focusTextBlock}) =>\n focusTextBlock\n ? [\n raise({\n type: 'insert.block',\n block: {\n _type: snapshot.context.schema.block.name,\n children: focusTextBlock.node.children,\n },\n placement: 'after',\n }),\n raise({\n type: 'insert.block',\n block: hrObject,\n placement: 'after',\n }),\n raise({\n type: 'delete.block',\n at: focusBlock.path,\n }),\n ]\n : [\n raise({\n type: 'insert.block',\n block: hrObject,\n placement: 'after',\n }),\n ],\n ],\n })\n\n const clearStyleOnBackspace = defineBehavior({\n on: 'delete.backward',\n guard: ({snapshot}) => {\n const selectionCollapsed = selectors.isSelectionCollapsed(snapshot)\n const focusTextBlock = selectors.getFocusTextBlock(snapshot)\n const focusSpan = selectors.getFocusSpan(snapshot)\n\n if (!selectionCollapsed || !focusTextBlock || !focusSpan) {\n return false\n }\n\n const atTheBeginningOfBLock =\n focusTextBlock.node.children[0]._key === focusSpan.node._key &&\n snapshot.context.selection?.focus.offset === 0\n\n const defaultStyle = config.defaultStyle?.({\n context: {schema: snapshot.context.schema},\n schema: snapshot.context.schema,\n })\n\n if (\n atTheBeginningOfBLock &&\n defaultStyle &&\n focusTextBlock.node.style !== defaultStyle\n ) {\n return {defaultStyle, focusTextBlock}\n }\n\n return false\n },\n actions: [\n (_, {defaultStyle, focusTextBlock}) => [\n raise({\n type: 'block.set',\n props: {style: defaultStyle},\n at: focusTextBlock.path,\n }),\n ],\n ],\n })\n\n const markdownBehaviors = [automaticHrOnPaste, clearStyleOnBackspace]\n\n return markdownBehaviors\n}\n","import type {EditorContext} from '@portabletext/editor'\nimport {raise} from '@portabletext/editor/behaviors'\nimport {getPreviousInlineObject} from '@portabletext/editor/selectors'\nimport {defineInputRule} from '@portabletext/plugin-input-rule'\n\nexport function createBlockquoteRule(config: {\n blockquoteStyle: ({\n context,\n schema,\n }: {\n context: Pick<EditorContext, 'schema'>\n /**\n * @deprecated Use `context.schema` instead\n */\n schema: EditorContext['schema']\n }) => string | undefined\n}) {\n return defineInputRule({\n on: /^> /,\n guard: ({snapshot, event}) => {\n const style = config.blockquoteStyle({\n context: {schema: snapshot.context.schema},\n schema: snapshot.context.schema,\n })\n\n if (!style) {\n return false\n }\n\n const previousInlineObject = getPreviousInlineObject(snapshot)\n\n if (previousInlineObject) {\n return false\n }\n\n const match = event.matches.at(0)\n\n if (!match) {\n return false\n }\n\n return {style, match}\n },\n actions: [\n ({event}, {style, match}) => [\n raise({\n type: 'block.unset',\n props: ['listItem', 'level'],\n at: event.focusTextBlock.path,\n }),\n raise({\n type: 'block.set',\n props: {style},\n at: event.focusTextBlock.path,\n }),\n raise({\n type: 'delete',\n at: match.targetOffsets,\n }),\n ],\n ],\n })\n}\n","import type {EditorContext} from '@portabletext/editor'\nimport {raise} from '@portabletext/editor/behaviors'\nimport {getPreviousInlineObject} from '@portabletext/editor/selectors'\nimport {defineInputRule} from '@portabletext/plugin-input-rule'\n\nexport function createHeadingRule(config: {\n headingStyle: ({\n context,\n schema,\n props,\n level,\n }: {\n context: Pick<EditorContext, 'schema'>\n /**\n * @deprecated Use `context.schema` instead\n */\n schema: EditorContext['schema']\n props: {level: number}\n /**\n * @deprecated Use `props.level` instead\n */\n level: number\n }) => string | undefined\n}) {\n return defineInputRule({\n on: /^#+ /,\n guard: ({snapshot, event}) => {\n const previousInlineObject = getPreviousInlineObject(snapshot)\n\n if (previousInlineObject) {\n return false\n }\n\n const match = event.matches.at(0)\n\n if (!match) {\n return false\n }\n\n const level = match.text.length - 1\n\n const style = config.headingStyle({\n context: {schema: snapshot.context.schema},\n schema: snapshot.context.schema,\n props: {level},\n level,\n })\n\n if (!style) {\n return false\n }\n\n return {match, style}\n },\n actions: [\n ({event}, {match, style}) => [\n raise({\n type: 'block.unset',\n props: ['listItem', 'level'],\n at: event.focusTextBlock.path,\n }),\n raise({\n type: 'block.set',\n props: {style},\n at: event.focusTextBlock.path,\n }),\n raise({\n type: 'delete',\n at: match.targetOffsets,\n }),\n ],\n ],\n })\n}\n","import type {EditorContext} from '@portabletext/editor'\nimport {raise} from '@portabletext/editor/behaviors'\nimport {getPreviousInlineObject} from '@portabletext/editor/selectors'\nimport {defineInputRule} from '@portabletext/plugin-input-rule'\nimport type {ObjectWithOptionalKey} from './behavior.markdown-shortcuts'\n\nexport function createHorizontalRuleRule(config: {\n horizontalRuleObject: ({\n context,\n }: {\n context: Pick<EditorContext, 'schema' | 'keyGenerator'>\n }) => ObjectWithOptionalKey | undefined\n}) {\n return defineInputRule({\n on: /^(---)|^(—-)|^(___)|^(\\*\\*\\*)/,\n guard: ({snapshot, event}) => {\n const hrObject = config.horizontalRuleObject({\n context: {\n schema: snapshot.context.schema,\n keyGenerator: snapshot.context.keyGenerator,\n },\n })\n\n if (!hrObject) {\n // If no horizontal rule object is provided, then we can safely skip\n // this rule.\n return false\n }\n\n const previousInlineObject = getPreviousInlineObject(snapshot)\n\n if (previousInlineObject) {\n // Input Rules only look at the plain text of the text block. This\n // means that the RegExp is matched even if there is a leading inline\n // object.\n return false\n }\n\n // In theory, an Input Rule could return multiple matches. But in this\n // case we only expect one match.\n const match = event.matches.at(0)\n\n if (!match) {\n return false\n }\n\n return {hrObject, match}\n },\n actions: [\n (_, {hrObject, match}) => [\n raise({\n type: 'insert.block',\n block: hrObject,\n placement: 'before',\n select: 'none',\n }),\n raise({\n type: 'delete',\n at: match.targetOffsets,\n }),\n ],\n ],\n })\n}\n","import type {EditorContext} from '@portabletext/editor'\nimport {raise, type BehaviorAction} from '@portabletext/editor/behaviors'\nimport {defineInputRule} from '@portabletext/plugin-input-rule'\nimport type {ObjectWithOptionalKey} from './behavior.markdown-shortcuts'\n\nexport function createMarkdownLinkRule(config: {\n linkObject: ({\n context,\n props,\n }: {\n context: Pick<EditorContext, 'schema' | 'keyGenerator'>\n props: {href: string}\n }) => ObjectWithOptionalKey | undefined\n}) {\n return defineInputRule({\n on: /\\[([^[\\]]+)]\\((.+)\\)/,\n actions: [\n ({snapshot, event}) => {\n const newText = event.textBefore + event.textInserted\n let textLengthDelta = 0\n const actions: Array<BehaviorAction> = []\n\n for (const match of event.matches.reverse()) {\n const textMatch = match.groupMatches.at(0)\n const hrefMatch = match.groupMatches.at(1)\n\n if (textMatch === undefined || hrefMatch === undefined) {\n continue\n }\n\n textLengthDelta =\n textLengthDelta -\n (match.targetOffsets.focus.offset -\n match.targetOffsets.anchor.offset -\n textMatch.text.length)\n\n const linkObject = config.linkObject({\n context: {\n schema: snapshot.context.schema,\n keyGenerator: snapshot.context.keyGenerator,\n },\n props: {href: hrefMatch.text},\n })\n\n if (!linkObject) {\n continue\n }\n\n const {_type, _key, ...value} = linkObject\n\n const leftSideOffsets = {\n anchor: match.targetOffsets.anchor,\n focus: textMatch.targetOffsets.anchor,\n }\n const rightSideOffsets = {\n anchor: textMatch.targetOffsets.focus,\n focus: match.targetOffsets.focus,\n }\n\n actions.push(\n raise({\n type: 'select',\n at: textMatch.targetOffsets,\n }),\n )\n actions.push(\n raise({\n type: 'annotation.add',\n annotation: {\n name: _type,\n _key,\n value,\n },\n }),\n )\n actions.push(\n raise({\n type: 'delete',\n at: rightSideOffsets,\n }),\n )\n actions.push(\n raise({\n type: 'delete',\n at: leftSideOffsets,\n }),\n )\n }\n\n const endCaretPosition = {\n path: event.focusTextBlock.path,\n offset: newText.length - textLengthDelta * -1,\n }\n\n return [\n ...actions,\n raise({\n type: 'select',\n at: {\n anchor: endCaretPosition,\n focus: endCaretPosition,\n },\n }),\n ]\n },\n ],\n })\n}\n","import type {EditorContext} from '@portabletext/editor'\nimport {raise} from '@portabletext/editor/behaviors'\nimport {getPreviousInlineObject} from '@portabletext/editor/selectors'\nimport {defineInputRule} from '@portabletext/plugin-input-rule'\n\nexport function createOrderedListRule(config: {\n orderedList: ({\n context,\n schema,\n }: {\n context: Pick<EditorContext, 'schema'>\n /**\n * @deprecated Use `context.schema` instead\n */\n schema: EditorContext['schema']\n }) => string | undefined\n}) {\n return defineInputRule({\n on: /^1\\. /,\n guard: ({snapshot, event}) => {\n const orderedList = config.orderedList({\n context: {schema: snapshot.context.schema},\n schema: snapshot.context.schema,\n })\n\n if (!orderedList) {\n return false\n }\n\n const previousInlineObject = getPreviousInlineObject(snapshot)\n\n if (previousInlineObject) {\n return false\n }\n\n const match = event.matches.at(0)\n\n if (!match) {\n return false\n }\n\n return {match, orderedList}\n },\n actions: [\n ({event}, {match, orderedList}) => [\n raise({\n type: 'block.unset',\n props: ['style'],\n at: event.focusTextBlock.path,\n }),\n raise({\n type: 'block.set',\n props: {\n listItem: orderedList,\n level: event.focusTextBlock.node.level ?? 1,\n },\n at: event.focusTextBlock.path,\n }),\n raise({\n type: 'delete',\n at: match.targetOffsets,\n }),\n ],\n ],\n })\n}\n","import type {EditorContext} from '@portabletext/editor'\nimport {raise} from '@portabletext/editor/behaviors'\nimport {getPreviousInlineObject} from '@portabletext/editor/selectors'\nimport {defineInputRule} from '@portabletext/plugin-input-rule'\n\nexport function createUnorderedListRule(config: {\n unorderedList: ({\n context,\n schema,\n }: {\n context: Pick<EditorContext, 'schema'>\n /**\n * @deprecated Use `context.schema` instead\n */\n schema: EditorContext['schema']\n }) => string | undefined\n}) {\n return defineInputRule({\n on: /^(-|\\*) /,\n guard: ({snapshot, event}) => {\n const unorderedList = config.unorderedList({\n context: {schema: snapshot.context.schema},\n schema: snapshot.context.schema,\n })\n\n if (!unorderedList) {\n return false\n }\n\n const previousInlineObject = getPreviousInlineObject(snapshot)\n\n if (previousInlineObject) {\n return false\n }\n\n const match = event.matches.at(0)\n\n if (!match) {\n return false\n }\n\n return {match, unorderedList}\n },\n actions: [\n ({event}, {match, unorderedList}) => [\n raise({\n type: 'block.unset',\n props: ['style'],\n at: event.focusTextBlock.path,\n }),\n raise({\n type: 'block.set',\n props: {\n listItem: unorderedList,\n level: event.focusTextBlock.node.level ?? 1,\n },\n at: event.focusTextBlock.path,\n }),\n raise({\n type: 'delete',\n at: match.targetOffsets,\n }),\n ],\n ],\n })\n}\n","import type {EditorContext} from '@portabletext/editor'\nimport {useEditor} from '@portabletext/editor'\nimport {CharacterPairDecoratorPlugin} from '@portabletext/plugin-character-pair-decorator'\nimport {InputRulePlugin} from '@portabletext/plugin-input-rule'\nimport {useEffect, useMemo} from 'react'\nimport {\n createMarkdownBehaviors,\n type MarkdownBehaviorsConfig,\n type ObjectWithOptionalKey,\n} from './behavior.markdown-shortcuts'\nimport {createBlockquoteRule} from './rule.blockquote'\nimport {createHeadingRule} from './rule.heading'\nimport {createHorizontalRuleRule} from './rule.horizontal-rule'\nimport {createMarkdownLinkRule} from './rule.markdown-link'\nimport {createOrderedListRule} from './rule.ordered-list'\nimport {createUnorderedListRule} from './rule.unordered-list'\n\n/**\n * @public\n */\nexport type MarkdownShortcutsPluginProps = MarkdownBehaviorsConfig & {\n blockquoteStyle?: ({\n context,\n schema,\n }: {\n context: Pick<EditorContext, 'schema'>\n /**\n * @deprecated Use `context.schema` instead\n */\n schema: EditorContext['schema']\n }) => string | undefined\n defaultStyle?: ({\n context,\n schema,\n }: {\n context: Pick<EditorContext, 'schema'>\n /**\n * @deprecated Use `context.schema` instead\n */\n schema: EditorContext['schema']\n }) => string | undefined\n headingStyle?: ({\n context,\n schema,\n props,\n level,\n }: {\n context: Pick<EditorContext, 'schema'>\n /**\n * @deprecated Use `context.schema` instead\n */\n schema: EditorContext['schema']\n props: {level: number}\n /**\n * @deprecated Use `props.level` instead\n */\n level: number\n }) => string | undefined\n linkObject?: ({\n context,\n props,\n }: {\n context: Pick<EditorContext, 'schema' | 'keyGenerator'>\n props: {href: string}\n }) => ObjectWithOptionalKey | undefined\n unorderedList?: ({\n context,\n schema,\n }: {\n context: Pick<EditorContext, 'schema'>\n /**\n * @deprecated Use `context.schema` instead\n */\n schema: EditorContext['schema']\n }) => string | undefined\n orderedList?: ({\n context,\n schema,\n }: {\n context: Pick<EditorContext, 'schema'>\n /**\n * @deprecated Use `context.schema` instead\n */\n schema: EditorContext['schema']\n }) => string | undefined\n boldDecorator?: ({\n context,\n schema,\n }: {\n context: Pick<EditorContext, 'schema'>\n /**\n * @deprecated Use `context.schema` instead\n */\n schema: EditorContext['schema']\n }) => string | undefined\n codeDecorator?: ({\n context,\n schema,\n }: {\n context: Pick<EditorContext, 'schema'>\n /**\n * @deprecated Use `context.schema` instead\n */\n schema: EditorContext['schema']\n }) => string | undefined\n italicDecorator?: ({\n context,\n schema,\n }: {\n context: Pick<EditorContext, 'schema'>\n /**\n * @deprecated Use `context.schema` instead\n */\n schema: EditorContext['schema']\n }) => string | undefined\n strikeThroughDecorator?: ({\n context,\n schema,\n }: {\n context: Pick<EditorContext, 'schema'>\n /**\n * @deprecated Use `context.schema` instead\n */\n schema: EditorContext['schema']\n }) => string | undefined\n}\n\n/**\n * @public\n */\nexport function MarkdownShortcutsPlugin({\n blockquoteStyle,\n boldDecorator,\n codeDecorator,\n defaultStyle,\n headingStyle,\n horizontalRuleObject,\n linkObject,\n italicDecorator,\n orderedList,\n strikeThroughDecorator,\n unorderedList,\n}: MarkdownShortcutsPluginProps) {\n const editor = useEditor()\n\n useEffect(() => {\n const behaviors = createMarkdownBehaviors({\n defaultStyle,\n })\n\n const unregisterBehaviors = behaviors.map((behavior) =>\n editor.registerBehavior({behavior}),\n )\n\n return () => {\n for (const unregisterBehavior of unregisterBehaviors) {\n unregisterBehavior()\n }\n }\n }, [defaultStyle, editor])\n\n const inputRules = useMemo(() => {\n const rules = []\n if (blockquoteStyle) {\n rules.push(createBlockquoteRule({blockquoteStyle}))\n }\n if (headingStyle) {\n rules.push(createHeadingRule({headingStyle}))\n }\n if (horizontalRuleObject) {\n rules.push(createHorizontalRuleRule({horizontalRuleObject}))\n }\n if (linkObject) {\n rules.push(createMarkdownLinkRule({linkObject}))\n }\n if (orderedList) {\n rules.push(createOrderedListRule({orderedList}))\n }\n if (unorderedList) {\n rules.push(createUnorderedListRule({unorderedList}))\n }\n return rules.length > 0 ? rules : null\n }, [\n blockquoteStyle,\n headingStyle,\n horizontalRuleObject,\n linkObject,\n orderedList,\n unorderedList,\n ])\n\n return (\n <>\n {boldDecorator ? (\n <>\n <CharacterPairDecoratorPlugin\n decorator={boldDecorator}\n pair={{char: '*', amount: 2}}\n />\n <CharacterPairDecoratorPlugin\n decorator={boldDecorator}\n pair={{char: '_', amount: 2}}\n />\n </>\n ) : null}\n {codeDecorator ? (\n <CharacterPairDecoratorPlugin\n decorator={codeDecorator}\n pair={{char: '`', amount: 1}}\n />\n ) : null}\n {italicDecorator ? (\n <>\n <CharacterPairDecoratorPlugin\n decorator={italicDecorator}\n pair={{char: '*', amount: 1}}\n />\n <CharacterPairDecoratorPlugin\n decorator={italicDecorator}\n pair={{char: '_', amount: 1}}\n />\n </>\n ) : null}\n {strikeThroughDecorator ? (\n <CharacterPairDecoratorPlugin\n decorator={strikeThroughDecorator}\n pair={{char: '~', amount: 2}}\n />\n ) : null}\n {inputRules ? <InputRulePlugin rules={inputRules} /> : null}\n </>\n )\n}\n"],"names":["createMarkdownBehaviors","config","automaticHrOnPaste","defineBehavior","on","guard","snapshot","event","text","originEvent","dataTransfer","getData","hrRegExp","hrCharacters","match","hrObject","horizontalRuleObject","context","schema","keyGenerator","focusBlock","selectors","getFocusBlock","focusTextBlock","getFocusTextBlock","actions","_","raise","type","block","_type","name","children","node","placement","at","path","clearStyleOnBackspace","selectionCollapsed","isSelectionCollapsed","focusSpan","getFocusSpan","atTheBeginningOfBLock","_key","selection","focus","offset","defaultStyle","style","props","createBlockquoteRule","defineInputRule","blockquoteStyle","getPreviousInlineObject","matches","targetOffsets","createHeadingRule","level","length","headingStyle","createHorizontalRuleRule","select","createMarkdownLinkRule","newText","textBefore","textInserted","textLengthDelta","reverse","textMatch","groupMatches","hrefMatch","undefined","anchor","linkObject","href","value","leftSideOffsets","rightSideOffsets","push","annotation","endCaretPosition","createOrderedListRule","orderedList","listItem","createUnorderedListRule","unorderedList","MarkdownShortcutsPlugin","t0","$","_c","boldDecorator","codeDecorator","italicDecorator","strikeThroughDecorator","editor","useEditor","t1","t2","unregisterBehaviors","map","behavior","registerBehavior","unregisterBehavior","useEffect","rules","t3","inputRules","char","amount","t4","t5","t6","t7","t8"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portabletext/plugin-markdown-shortcuts",
3
- "version": "2.0.1",
3
+ "version": "3.0.1",
4
4
  "description": "Adds helpful Markdown shortcuts to the editor",
5
5
  "keywords": [
6
6
  "portabletext",
@@ -36,8 +36,8 @@
36
36
  "dist"
37
37
  ],
38
38
  "dependencies": {
39
- "@portabletext/plugin-character-pair-decorator": "^2.0.1",
40
- "@portabletext/plugin-input-rule": "~0.5.1"
39
+ "@portabletext/plugin-character-pair-decorator": "^3.0.1",
40
+ "@portabletext/plugin-input-rule": "~0.5.2"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/react": "^19.2.2",
@@ -51,12 +51,12 @@
51
51
  "typescript": "5.9.3",
52
52
  "typescript-eslint": "^8.46.1",
53
53
  "vitest": "^4.0.6",
54
- "@portabletext/editor": "^2.18.1",
54
+ "@portabletext/editor": "^2.19.0",
55
55
  "racejar": "2.0.0"
56
56
  },
57
57
  "peerDependencies": {
58
58
  "react": "^19",
59
- "@portabletext/editor": "^2.18.1"
59
+ "@portabletext/editor": "^2.19.0"
60
60
  },
61
61
  "engines": {
62
62
  "node": ">=20.19 <22 || >=22.12"
@@ -1,12 +1,29 @@
1
- import type {EditorSchema} from '@portabletext/editor'
2
- import {defineBehavior, execute} from '@portabletext/editor/behaviors'
1
+ import type {EditorContext} from '@portabletext/editor'
2
+ import {defineBehavior, raise} from '@portabletext/editor/behaviors'
3
3
  import * as selectors from '@portabletext/editor/selectors'
4
4
 
5
+ export type ObjectWithOptionalKey = {
6
+ _type: string
7
+ _key?: string
8
+ [other: string]: unknown
9
+ }
10
+
5
11
  export type MarkdownBehaviorsConfig = {
6
- horizontalRuleObject?: (context: {
7
- schema: EditorSchema
8
- }) => {name: string; value?: {[prop: string]: unknown}} | undefined
9
- defaultStyle?: (context: {schema: EditorSchema}) => string | undefined
12
+ horizontalRuleObject?: ({
13
+ context,
14
+ }: {
15
+ context: Pick<EditorContext, 'schema' | 'keyGenerator'>
16
+ }) => ObjectWithOptionalKey | undefined
17
+ defaultStyle?: ({
18
+ context,
19
+ schema,
20
+ }: {
21
+ context: Pick<EditorContext, 'schema'>
22
+ /**
23
+ * @deprecated Use `context.schema` instead
24
+ */
25
+ schema: EditorContext['schema']
26
+ }) => string | undefined
10
27
  }
11
28
 
12
29
  export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
@@ -17,7 +34,10 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
17
34
  const hrRegExp = /^(---)$|^(—-)$|^(___)$|^(\*\*\*)$/
18
35
  const hrCharacters = text.match(hrRegExp)?.[0]
19
36
  const hrObject = config.horizontalRuleObject?.({
20
- schema: snapshot.context.schema,
37
+ context: {
38
+ schema: snapshot.context.schema,
39
+ keyGenerator: snapshot.context.keyGenerator,
40
+ },
21
41
  })
22
42
  const focusBlock = selectors.getFocusBlock(snapshot)
23
43
  const focusTextBlock = selectors.getFocusTextBlock(snapshot)
@@ -30,7 +50,7 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
30
50
  },
31
51
  actions: [
32
52
  (_, {hrCharacters}) => [
33
- execute({
53
+ raise({
34
54
  type: 'insert.text',
35
55
  text: hrCharacters,
36
56
  }),
@@ -38,7 +58,7 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
38
58
  ({snapshot}, {hrObject, focusBlock, focusTextBlock}) =>
39
59
  focusTextBlock
40
60
  ? [
41
- execute({
61
+ raise({
42
62
  type: 'insert.block',
43
63
  block: {
44
64
  _type: snapshot.context.schema.block.name,
@@ -46,26 +66,20 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
46
66
  },
47
67
  placement: 'after',
48
68
  }),
49
- execute({
69
+ raise({
50
70
  type: 'insert.block',
51
- block: {
52
- _type: hrObject.name,
53
- ...(hrObject.value ?? {}),
54
- },
71
+ block: hrObject,
55
72
  placement: 'after',
56
73
  }),
57
- execute({
74
+ raise({
58
75
  type: 'delete.block',
59
76
  at: focusBlock.path,
60
77
  }),
61
78
  ]
62
79
  : [
63
- execute({
80
+ raise({
64
81
  type: 'insert.block',
65
- block: {
66
- _type: hrObject.name,
67
- ...(hrObject.value ?? {}),
68
- },
82
+ block: hrObject,
69
83
  placement: 'after',
70
84
  }),
71
85
  ],
@@ -88,6 +102,7 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
88
102
  snapshot.context.selection?.focus.offset === 0
89
103
 
90
104
  const defaultStyle = config.defaultStyle?.({
105
+ context: {schema: snapshot.context.schema},
91
106
  schema: snapshot.context.schema,
92
107
  })
93
108
 
@@ -103,7 +118,7 @@ export function createMarkdownBehaviors(config: MarkdownBehaviorsConfig) {
103
118
  },
104
119
  actions: [
105
120
  (_, {defaultStyle, focusTextBlock}) => [
106
- execute({
121
+ raise({
107
122
  type: 'block.set',
108
123
  props: {style: defaultStyle},
109
124
  at: focusTextBlock.path,
@@ -0,0 +1,108 @@
1
+ Feature: Markdown Behaviors
2
+
3
+ Background:
4
+ Given a global keymap
5
+
6
+ Scenario: Automatic blockquote
7
+ Given the text ">"
8
+ When "{Space}" is pressed
9
+ Then the text is "q:"
10
+
11
+ Scenario: Automatic blockquote not toggled by space in the beginning
12
+ Given the text ">"
13
+ When the caret is put before ">"
14
+ When "{Space}" is pressed
15
+ Then the text is " >"
16
+
17
+ Scenario: Automatic blockquote in non-empty block
18
+ Given the text ">foo"
19
+ When the caret is put before "f"
20
+ And "{Space}" is pressed
21
+ Then the text is "q:foo"
22
+
23
+ Scenario Outline: Automatic headings
24
+ Given the text <text>
25
+ When "{Space}" is pressed
26
+ Then the text is <new text>
27
+
28
+ Examples:
29
+ | text | new text |
30
+ | "#" | "h1:" |
31
+ | "##" | "h2:" |
32
+ | "###" | "h3:" |
33
+ | "####" | "h4:" |
34
+ | "#####" | "h5:" |
35
+ | "######" | "h6:" |
36
+ | "#######" | "####### " |
37
+
38
+ Scenario Outline: Automatic headings not toggled by space in the beginning
39
+ Given the text <text>
40
+ When the caret is put <position>
41
+ When "{Space}" is pressed
42
+ Then the text is <new text>
43
+
44
+ Examples:
45
+ | text | position | new text |
46
+ | "#" | before "#" | " #" |
47
+ | "##" | before "##" | " ##" |
48
+ | "###" | before "###" | " ###" |
49
+
50
+ Scenario Outline: Automatic headings toggled by space mid-heading
51
+ Given the text <text>
52
+ When the caret is put <position>
53
+ When "{ArrowRight}" is pressed
54
+ When "{Space}" is pressed
55
+ Then the text is <new text>
56
+
57
+ Examples:
58
+ | text | position | new text |
59
+ | "##" | before "##" | "h1:#" |
60
+ | "###" | before "###" | "h1:##" |
61
+
62
+ Scenario Outline: Automatic headings in non-empty block
63
+ Given the text <text>
64
+ When the caret is put <position>
65
+ And "{Space}" is pressed
66
+ Then the text is <new text>
67
+
68
+ Examples:
69
+ | text | position | new text |
70
+ | "foo" | before "foo" | " foo" |
71
+ | "#foo" | before "foo" | "h1:foo" |
72
+ | "##foo" | before "foo" | "h2:foo" |
73
+ | "###foo" | before "foo" | "h3:foo" |
74
+ | "####foo" | before "foo" | "h4:foo" |
75
+ | "#####foo" | before "foo" | "h5:foo" |
76
+ | "######foo" | before "foo" | "h6:foo" |
77
+ | "#######foo" | before "foo" | "####### foo" |
78
+
79
+ Scenario Outline: Clear style on Backspace
80
+ Given the text "foo"
81
+ When <style> is toggled
82
+ And "{Backspace}" is pressed 4 times
83
+ Then the text is ""
84
+
85
+ Examples:
86
+ | style |
87
+ | "h1" |
88
+ | "h2" |
89
+ | "h3" |
90
+ | "h4" |
91
+ | "h5" |
92
+ | "h6" |
93
+
94
+ Scenario Outline: Clear style on Backspace in empty block
95
+ Given the text "foo"
96
+ When <style> is toggled
97
+ And "{Backspace}" is pressed 4 times
98
+ And "bar" is typed
99
+ Then the text is "bar"
100
+
101
+ Examples:
102
+ | style |
103
+ | "h1" |
104
+ | "h2" |
105
+ | "h3" |
106
+ | "h4" |
107
+ | "h5" |
108
+ | "h6" |
@@ -0,0 +1,63 @@
1
+ import {defineSchema} from '@portabletext/editor'
2
+ import {parameterTypes} from '@portabletext/editor/test'
3
+ import {
4
+ createTestEditor,
5
+ stepDefinitions,
6
+ type Context,
7
+ } from '@portabletext/editor/test/vitest'
8
+ import {Before} from 'racejar'
9
+ import {Feature} from 'racejar/vitest'
10
+ import behaviorMarkdownFeature from './behavior.markdown.feature?raw'
11
+ import {MarkdownShortcutsPlugin} from './plugin.markdown-shortcuts'
12
+
13
+ Feature({
14
+ hooks: [
15
+ Before(async (context: Context) => {
16
+ const {editor, locator} = await createTestEditor({
17
+ children: (
18
+ <MarkdownShortcutsPlugin
19
+ defaultStyle={({context}) => context.schema.styles[0]?.name}
20
+ headingStyle={({context, props}) =>
21
+ context.schema.styles.find(
22
+ (style) => style.name === `h${props.level}`,
23
+ )?.name
24
+ }
25
+ blockquoteStyle={({context}) =>
26
+ context.schema.styles.find((style) => style.name === 'blockquote')
27
+ ?.name
28
+ }
29
+ unorderedList={({context}) =>
30
+ context.schema.lists.find((list) => list.name === 'bullet')?.name
31
+ }
32
+ orderedList={({context}) =>
33
+ context.schema.lists.find((list) => list.name === 'number')?.name
34
+ }
35
+ />
36
+ ),
37
+ schemaDefinition: defineSchema({
38
+ annotations: [{name: 'comment'}, {name: 'link'}],
39
+ decorators: [{name: 'em'}, {name: 'strong'}],
40
+ blockObjects: [{name: 'image'}, {name: 'break'}],
41
+ inlineObjects: [{name: 'stock-ticker'}],
42
+ lists: [{name: 'bullet'}, {name: 'number'}],
43
+ styles: [
44
+ {name: 'normal'},
45
+ {name: 'h1'},
46
+ {name: 'h2'},
47
+ {name: 'h3'},
48
+ {name: 'h4'},
49
+ {name: 'h5'},
50
+ {name: 'h6'},
51
+ {name: 'blockquote'},
52
+ ],
53
+ }),
54
+ })
55
+
56
+ context.locator = locator
57
+ context.editor = editor
58
+ }),
59
+ ],
60
+ featureText: behaviorMarkdownFeature,
61
+ stepDefinitions: stepDefinitions,
62
+ parameterTypes,
63
+ })
@@ -1,4 +1,4 @@
1
- import type {EditorSchema} from '@portabletext/editor'
1
+ import type {EditorContext} from '@portabletext/editor'
2
2
  import {useEditor} from '@portabletext/editor'
3
3
  import {CharacterPairDecoratorPlugin} from '@portabletext/plugin-character-pair-decorator'
4
4
  import {InputRulePlugin} from '@portabletext/plugin-input-rule'
@@ -6,6 +6,7 @@ import {useEffect, useMemo} from 'react'
6
6
  import {
7
7
  createMarkdownBehaviors,
8
8
  type MarkdownBehaviorsConfig,
9
+ type ObjectWithOptionalKey,
9
10
  } from './behavior.markdown-shortcuts'
10
11
  import {createBlockquoteRule} from './rule.blockquote'
11
12
  import {createHeadingRule} from './rule.heading'
@@ -15,33 +16,117 @@ import {createOrderedListRule} from './rule.ordered-list'
15
16
  import {createUnorderedListRule} from './rule.unordered-list'
16
17
 
17
18
  /**
18
- * @beta
19
+ * @public
19
20
  */
20
21
  export type MarkdownShortcutsPluginProps = MarkdownBehaviorsConfig & {
21
- blockquoteStyle?: (context: {schema: EditorSchema}) => string | undefined
22
- defaultStyle?: (context: {schema: EditorSchema}) => string | undefined
23
- headingStyle?: (context: {
24
- schema: EditorSchema
22
+ blockquoteStyle?: ({
23
+ context,
24
+ schema,
25
+ }: {
26
+ context: Pick<EditorContext, 'schema'>
27
+ /**
28
+ * @deprecated Use `context.schema` instead
29
+ */
30
+ schema: EditorContext['schema']
31
+ }) => string | undefined
32
+ defaultStyle?: ({
33
+ context,
34
+ schema,
35
+ }: {
36
+ context: Pick<EditorContext, 'schema'>
37
+ /**
38
+ * @deprecated Use `context.schema` instead
39
+ */
40
+ schema: EditorContext['schema']
41
+ }) => string | undefined
42
+ headingStyle?: ({
43
+ context,
44
+ schema,
45
+ props,
46
+ level,
47
+ }: {
48
+ context: Pick<EditorContext, 'schema'>
49
+ /**
50
+ * @deprecated Use `context.schema` instead
51
+ */
52
+ schema: EditorContext['schema']
53
+ props: {level: number}
54
+ /**
55
+ * @deprecated Use `props.level` instead
56
+ */
25
57
  level: number
26
58
  }) => string | undefined
27
- linkObject?: (context: {
28
- schema: EditorSchema
29
- href: string
30
- }) => {name: string; value?: {[prop: string]: unknown}} | undefined
31
- unorderedList?: (context: {schema: EditorSchema}) => string | undefined
32
- orderedList?: (context: {schema: EditorSchema}) => string | undefined
33
- boldDecorator?: ({schema}: {schema: EditorSchema}) => string | undefined
34
- codeDecorator?: ({schema}: {schema: EditorSchema}) => string | undefined
35
- italicDecorator?: ({schema}: {schema: EditorSchema}) => string | undefined
59
+ linkObject?: ({
60
+ context,
61
+ props,
62
+ }: {
63
+ context: Pick<EditorContext, 'schema' | 'keyGenerator'>
64
+ props: {href: string}
65
+ }) => ObjectWithOptionalKey | undefined
66
+ unorderedList?: ({
67
+ context,
68
+ schema,
69
+ }: {
70
+ context: Pick<EditorContext, 'schema'>
71
+ /**
72
+ * @deprecated Use `context.schema` instead
73
+ */
74
+ schema: EditorContext['schema']
75
+ }) => string | undefined
76
+ orderedList?: ({
77
+ context,
78
+ schema,
79
+ }: {
80
+ context: Pick<EditorContext, 'schema'>
81
+ /**
82
+ * @deprecated Use `context.schema` instead
83
+ */
84
+ schema: EditorContext['schema']
85
+ }) => string | undefined
86
+ boldDecorator?: ({
87
+ context,
88
+ schema,
89
+ }: {
90
+ context: Pick<EditorContext, 'schema'>
91
+ /**
92
+ * @deprecated Use `context.schema` instead
93
+ */
94
+ schema: EditorContext['schema']
95
+ }) => string | undefined
96
+ codeDecorator?: ({
97
+ context,
98
+ schema,
99
+ }: {
100
+ context: Pick<EditorContext, 'schema'>
101
+ /**
102
+ * @deprecated Use `context.schema` instead
103
+ */
104
+ schema: EditorContext['schema']
105
+ }) => string | undefined
106
+ italicDecorator?: ({
107
+ context,
108
+ schema,
109
+ }: {
110
+ context: Pick<EditorContext, 'schema'>
111
+ /**
112
+ * @deprecated Use `context.schema` instead
113
+ */
114
+ schema: EditorContext['schema']
115
+ }) => string | undefined
36
116
  strikeThroughDecorator?: ({
117
+ context,
37
118
  schema,
38
119
  }: {
39
- schema: EditorSchema
120
+ context: Pick<EditorContext, 'schema'>
121
+ /**
122
+ * @deprecated Use `context.schema` instead
123
+ */
124
+ schema: EditorContext['schema']
40
125
  }) => string | undefined
41
126
  }
42
127
 
43
128
  /**
44
- * @beta
129
+ * @public
45
130
  */
46
131
  export function MarkdownShortcutsPlugin({
47
132
  blockquoteStyle,
@@ -1,15 +1,25 @@
1
- import type {EditorSchema} from '@portabletext/editor'
1
+ import type {EditorContext} from '@portabletext/editor'
2
2
  import {raise} from '@portabletext/editor/behaviors'
3
3
  import {getPreviousInlineObject} from '@portabletext/editor/selectors'
4
4
  import {defineInputRule} from '@portabletext/plugin-input-rule'
5
5
 
6
6
  export function createBlockquoteRule(config: {
7
- blockquoteStyle: (context: {schema: EditorSchema}) => string | undefined
7
+ blockquoteStyle: ({
8
+ context,
9
+ schema,
10
+ }: {
11
+ context: Pick<EditorContext, 'schema'>
12
+ /**
13
+ * @deprecated Use `context.schema` instead
14
+ */
15
+ schema: EditorContext['schema']
16
+ }) => string | undefined
8
17
  }) {
9
18
  return defineInputRule({
10
19
  on: /^> /,
11
20
  guard: ({snapshot, event}) => {
12
21
  const style = config.blockquoteStyle({
22
+ context: {schema: snapshot.context.schema},
13
23
  schema: snapshot.context.schema,
14
24
  })
15
25
 
@@ -1,11 +1,24 @@
1
- import type {EditorSchema} from '@portabletext/editor'
1
+ import type {EditorContext} from '@portabletext/editor'
2
2
  import {raise} from '@portabletext/editor/behaviors'
3
3
  import {getPreviousInlineObject} from '@portabletext/editor/selectors'
4
4
  import {defineInputRule} from '@portabletext/plugin-input-rule'
5
5
 
6
6
  export function createHeadingRule(config: {
7
- headingStyle: (context: {
8
- schema: EditorSchema
7
+ headingStyle: ({
8
+ context,
9
+ schema,
10
+ props,
11
+ level,
12
+ }: {
13
+ context: Pick<EditorContext, 'schema'>
14
+ /**
15
+ * @deprecated Use `context.schema` instead
16
+ */
17
+ schema: EditorContext['schema']
18
+ props: {level: number}
19
+ /**
20
+ * @deprecated Use `props.level` instead
21
+ */
9
22
  level: number
10
23
  }) => string | undefined
11
24
  }) {
@@ -27,7 +40,9 @@ export function createHeadingRule(config: {
27
40
  const level = match.text.length - 1
28
41
 
29
42
  const style = config.headingStyle({
43
+ context: {schema: snapshot.context.schema},
30
44
  schema: snapshot.context.schema,
45
+ props: {level},
31
46
  level,
32
47
  })
33
48
 
@@ -1,18 +1,24 @@
1
- import type {EditorSchema} from '@portabletext/editor'
1
+ import type {EditorContext} from '@portabletext/editor'
2
2
  import {raise} from '@portabletext/editor/behaviors'
3
3
  import {getPreviousInlineObject} from '@portabletext/editor/selectors'
4
4
  import {defineInputRule} from '@portabletext/plugin-input-rule'
5
+ import type {ObjectWithOptionalKey} from './behavior.markdown-shortcuts'
5
6
 
6
7
  export function createHorizontalRuleRule(config: {
7
- horizontalRuleObject: (context: {
8
- schema: EditorSchema
9
- }) => {name: string; value?: {[prop: string]: unknown}} | undefined
8
+ horizontalRuleObject: ({
9
+ context,
10
+ }: {
11
+ context: Pick<EditorContext, 'schema' | 'keyGenerator'>
12
+ }) => ObjectWithOptionalKey | undefined
10
13
  }) {
11
14
  return defineInputRule({
12
15
  on: /^(---)|^(—-)|^(___)|^(\*\*\*)/,
13
16
  guard: ({snapshot, event}) => {
14
17
  const hrObject = config.horizontalRuleObject({
15
- schema: snapshot.context.schema,
18
+ context: {
19
+ schema: snapshot.context.schema,
20
+ keyGenerator: snapshot.context.keyGenerator,
21
+ },
16
22
  })
17
23
 
18
24
  if (!hrObject) {
@@ -44,10 +50,7 @@ export function createHorizontalRuleRule(config: {
44
50
  (_, {hrObject, match}) => [
45
51
  raise({
46
52
  type: 'insert.block',
47
- block: {
48
- _type: hrObject.name,
49
- ...(hrObject.value ?? {}),
50
- },
53
+ block: hrObject,
51
54
  placement: 'before',
52
55
  select: 'none',
53
56
  }),
@@ -12,11 +12,9 @@ import {createMarkdownLinkRule} from './rule.markdown-link'
12
12
  import markdownLinkFeature from './rule.markdown-link.feature?raw'
13
13
 
14
14
  const markdownLinkRule = createMarkdownLinkRule({
15
- linkObject: (context) => ({
16
- name: 'link',
17
- value: {
18
- href: context.href,
19
- },
15
+ linkObject: ({props}) => ({
16
+ _type: 'link',
17
+ href: props.href,
20
18
  }),
21
19
  })
22
20
 
@@ -1,12 +1,16 @@
1
- import type {EditorSchema} from '@portabletext/editor'
1
+ import type {EditorContext} from '@portabletext/editor'
2
2
  import {raise, type BehaviorAction} from '@portabletext/editor/behaviors'
3
3
  import {defineInputRule} from '@portabletext/plugin-input-rule'
4
+ import type {ObjectWithOptionalKey} from './behavior.markdown-shortcuts'
4
5
 
5
6
  export function createMarkdownLinkRule(config: {
6
- linkObject: (context: {
7
- schema: EditorSchema
8
- href: string
9
- }) => {name: string; value?: {[prop: string]: unknown}} | undefined
7
+ linkObject: ({
8
+ context,
9
+ props,
10
+ }: {
11
+ context: Pick<EditorContext, 'schema' | 'keyGenerator'>
12
+ props: {href: string}
13
+ }) => ObjectWithOptionalKey | undefined
10
14
  }) {
11
15
  return defineInputRule({
12
16
  on: /\[([^[\]]+)]\((.+)\)/,
@@ -31,14 +35,19 @@ export function createMarkdownLinkRule(config: {
31
35
  textMatch.text.length)
32
36
 
33
37
  const linkObject = config.linkObject({
34
- schema: snapshot.context.schema,
35
- href: hrefMatch.text,
38
+ context: {
39
+ schema: snapshot.context.schema,
40
+ keyGenerator: snapshot.context.keyGenerator,
41
+ },
42
+ props: {href: hrefMatch.text},
36
43
  })
37
44
 
38
45
  if (!linkObject) {
39
46
  continue
40
47
  }
41
48
 
49
+ const {_type, _key, ...value} = linkObject
50
+
42
51
  const leftSideOffsets = {
43
52
  anchor: match.targetOffsets.anchor,
44
53
  focus: textMatch.targetOffsets.anchor,
@@ -58,8 +67,9 @@ export function createMarkdownLinkRule(config: {
58
67
  raise({
59
68
  type: 'annotation.add',
60
69
  annotation: {
61
- name: linkObject.name,
62
- value: linkObject.value ?? {},
70
+ name: _type,
71
+ _key,
72
+ value,
63
73
  },
64
74
  }),
65
75
  )
@@ -1,15 +1,25 @@
1
- import type {EditorSchema} from '@portabletext/editor'
1
+ import type {EditorContext} from '@portabletext/editor'
2
2
  import {raise} from '@portabletext/editor/behaviors'
3
3
  import {getPreviousInlineObject} from '@portabletext/editor/selectors'
4
4
  import {defineInputRule} from '@portabletext/plugin-input-rule'
5
5
 
6
6
  export function createOrderedListRule(config: {
7
- orderedList: (context: {schema: EditorSchema}) => string | undefined
7
+ orderedList: ({
8
+ context,
9
+ schema,
10
+ }: {
11
+ context: Pick<EditorContext, 'schema'>
12
+ /**
13
+ * @deprecated Use `context.schema` instead
14
+ */
15
+ schema: EditorContext['schema']
16
+ }) => string | undefined
8
17
  }) {
9
18
  return defineInputRule({
10
19
  on: /^1\. /,
11
20
  guard: ({snapshot, event}) => {
12
21
  const orderedList = config.orderedList({
22
+ context: {schema: snapshot.context.schema},
13
23
  schema: snapshot.context.schema,
14
24
  })
15
25
 
@@ -1,15 +1,25 @@
1
- import type {EditorSchema} from '@portabletext/editor'
1
+ import type {EditorContext} from '@portabletext/editor'
2
2
  import {raise} from '@portabletext/editor/behaviors'
3
3
  import {getPreviousInlineObject} from '@portabletext/editor/selectors'
4
4
  import {defineInputRule} from '@portabletext/plugin-input-rule'
5
5
 
6
6
  export function createUnorderedListRule(config: {
7
- unorderedList: (context: {schema: EditorSchema}) => string | undefined
7
+ unorderedList: ({
8
+ context,
9
+ schema,
10
+ }: {
11
+ context: Pick<EditorContext, 'schema'>
12
+ /**
13
+ * @deprecated Use `context.schema` instead
14
+ */
15
+ schema: EditorContext['schema']
16
+ }) => string | undefined
8
17
  }) {
9
18
  return defineInputRule({
10
19
  on: /^(-|\*) /,
11
20
  guard: ({snapshot, event}) => {
12
21
  const unorderedList = config.unorderedList({
22
+ context: {schema: snapshot.context.schema},
13
23
  schema: snapshot.context.schema,
14
24
  })
15
25