@portabletext/plugin-typeahead-picker 1.0.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/define-typeahead-picker.ts","../src/extract-keyword.ts","../src/typeahead-picker-machine.tsx","../src/use-typeahead-picker.ts"],"sourcesContent":["import type {\n AutoCompleteMatch,\n TypeaheadPickerDefinition,\n TypeaheadSelectActionSet,\n} from './typeahead-picker.types'\n\ntype BaseConfigWithoutAutoComplete<TMatch extends object> = {\n pattern: RegExp\n autoCompleteWith?: undefined\n actions: Array<TypeaheadSelectActionSet<TMatch>>\n}\n\ntype BaseConfigWithAutoComplete<TMatch extends AutoCompleteMatch> = {\n pattern: RegExp\n autoCompleteWith: string\n actions: Array<TypeaheadSelectActionSet<TMatch>>\n}\n\ntype SyncConfigWithoutAutoComplete<TMatch extends object> =\n BaseConfigWithoutAutoComplete<TMatch> & {\n mode?: 'sync'\n debounceMs?: number\n getMatches: (context: {keyword: string}) => Array<TMatch>\n }\n\ntype SyncConfigWithAutoComplete<TMatch extends AutoCompleteMatch> =\n BaseConfigWithAutoComplete<TMatch> & {\n mode?: 'sync'\n debounceMs?: number\n getMatches: (context: {keyword: string}) => Array<TMatch>\n }\n\ntype AsyncConfigWithoutAutoComplete<TMatch extends object> =\n BaseConfigWithoutAutoComplete<TMatch> & {\n mode: 'async'\n debounceMs?: number\n getMatches: (context: {keyword: string}) => Promise<Array<TMatch>>\n }\n\ntype AsyncConfigWithAutoComplete<TMatch extends AutoCompleteMatch> =\n BaseConfigWithAutoComplete<TMatch> & {\n mode: 'async'\n debounceMs?: number\n getMatches: (context: {keyword: string}) => Promise<Array<TMatch>>\n }\n\n/**\n * Creates a typeahead picker definition to use with {@link useTypeaheadPicker}.\n *\n * @example Emoji picker with auto-complete\n * ```ts\n * const emojiPicker = defineTypeaheadPicker({\n * pattern: /:(\\S*)/,\n * autoCompleteWith: ':',\n * getMatches: ({keyword}) => searchEmojis(keyword),\n * actions: [({event}) => [\n * raise({type: 'delete', at: event.patternSelection}),\n * raise({type: 'insert.text', text: event.match.emoji}),\n * ]],\n * })\n * ```\n *\n * @example Async mention picker\n * ```ts\n * const mentionPicker = defineTypeaheadPicker({\n * mode: 'async',\n * pattern: /@(\\w*)/,\n * debounceMs: 200,\n * getMatches: async ({keyword}) => api.searchUsers(keyword),\n * actions: [({event}) => [\n * raise({type: 'delete', at: event.patternSelection}),\n * raise({type: 'insert.text', text: event.match.name}),\n * ]],\n * })\n * ```\n *\n * @example Slash commands at start of block\n * ```ts\n * const slashCommandPicker = defineTypeaheadPicker({\n * pattern: /^\\/(\\w*)/, // ^ anchors to start of block\n * getMatches: ({keyword}) => filterCommands(keyword),\n * actions: [({event}) => [\n * raise({type: 'delete', at: event.patternSelection}),\n * raise(event.match.action),\n * ]],\n * })\n * ```\n *\n * @public\n */\nexport function defineTypeaheadPicker<TMatch extends object>(\n config: SyncConfigWithoutAutoComplete<TMatch>,\n): TypeaheadPickerDefinition<TMatch>\n/** @public */\nexport function defineTypeaheadPicker<TMatch extends AutoCompleteMatch>(\n config: SyncConfigWithAutoComplete<TMatch>,\n): TypeaheadPickerDefinition<TMatch>\n/** @public */\nexport function defineTypeaheadPicker<TMatch extends object>(\n config: AsyncConfigWithoutAutoComplete<TMatch>,\n): TypeaheadPickerDefinition<TMatch>\n/** @public */\nexport function defineTypeaheadPicker<TMatch extends AutoCompleteMatch>(\n config: AsyncConfigWithAutoComplete<TMatch>,\n): TypeaheadPickerDefinition<TMatch>\n/** @public */\nexport function defineTypeaheadPicker<TMatch extends object>(\n config:\n | SyncConfigWithoutAutoComplete<TMatch>\n | SyncConfigWithAutoComplete<TMatch & AutoCompleteMatch>\n | AsyncConfigWithoutAutoComplete<TMatch>\n | AsyncConfigWithAutoComplete<TMatch & AutoCompleteMatch>,\n): TypeaheadPickerDefinition<TMatch> {\n return {\n ...config,\n _id: Symbol('typeahead-picker'),\n } as TypeaheadPickerDefinition<TMatch>\n}\n","/**\n * Extract keyword from matched text using the pattern's capture group.\n * Strips the autoCompleteWith from the end before matching if present.\n * Returns capture group 1 if present, otherwise the full match (minus autoCompleteWith).\n * Falls back to non-stripped match if stripping results in empty keyword.\n */\nexport function extractKeywordFromPattern(\n matchedText: string,\n pattern: RegExp,\n autoCompleteWith?: string,\n): string {\n if (autoCompleteWith && matchedText.endsWith(autoCompleteWith)) {\n const strippedText = matchedText.slice(0, -autoCompleteWith.length)\n const strippedMatch = strippedText.match(pattern)\n const strippedKeyword = strippedMatch\n ? (strippedMatch[1] ?? strippedMatch[0])\n : ''\n\n if (strippedKeyword.length > 0) {\n return strippedKeyword\n }\n }\n\n const match = matchedText.match(pattern)\n\n if (!match) {\n return matchedText\n }\n\n return match[1] ?? match[0]\n}\n","import type {\n ChildPath,\n Editor,\n EditorSelector,\n EditorSnapshot,\n PortableTextSpan,\n} from '@portabletext/editor'\nimport {\n defineBehavior,\n effect,\n forward,\n raise,\n} from '@portabletext/editor/behaviors'\nimport {\n getFocusSpan,\n getMarkState,\n getNextSpan,\n getPreviousSpan,\n isPointAfterSelection,\n isPointBeforeSelection,\n isSelectionCollapsed,\n type MarkState,\n} from '@portabletext/editor/selectors'\nimport {isEqualPaths, isEqualSelectionPoints} from '@portabletext/editor/utils'\nimport {createKeyboardShortcut} from '@portabletext/keyboard-shortcuts'\nimport {\n defineInputRule,\n defineInputRuleBehavior,\n type InputRuleMatch,\n} from '@portabletext/plugin-input-rule'\nimport {\n assign,\n fromCallback,\n fromPromise,\n sendTo,\n setup,\n type AnyEventObject,\n type CallbackLogicFunction,\n} from 'xstate'\nimport {extractKeywordFromPattern} from './extract-keyword'\nimport type {\n AutoCompleteMatch,\n TypeaheadPickerDefinition,\n} from './typeahead-picker.types'\n\nfunction escapeRegExp(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\n/**\n * Normalize a RegExp by stripping user-provided flags.\n *\n * The input rule system always uses 'gd' flags internally, ignoring any\n * user-provided flags. We normalize patterns to match this behavior and\n * ensure consistency across all pattern usage in the picker.\n */\nfunction normalizePattern(pattern: RegExp): RegExp {\n return new RegExp(pattern.source)\n}\n\n/**\n * Build the complete pattern by appending autoCompleteWith to the base pattern.\n */\nfunction buildCompletePattern<TMatch extends object>(\n definition: TypeaheadPickerDefinition<TMatch>,\n): RegExp | undefined {\n if (!definition.autoCompleteWith) {\n return undefined\n }\n const autoCompleteWith = escapeRegExp(definition.autoCompleteWith)\n return new RegExp(`${definition.pattern.source}${autoCompleteWith}`)\n}\n\nconst arrowUpShortcut = createKeyboardShortcut({\n default: [{key: 'ArrowUp'}],\n})\nconst arrowDownShortcut = createKeyboardShortcut({\n default: [{key: 'ArrowDown'}],\n})\nconst enterShortcut = createKeyboardShortcut({\n default: [{key: 'Enter'}],\n})\nconst tabShortcut = createKeyboardShortcut({\n default: [{key: 'Tab'}],\n})\nconst escapeShortcut = createKeyboardShortcut({\n default: [{key: 'Escape'}],\n})\n\nconst getTriggerState: EditorSelector<\n | {\n focusSpan: {\n node: PortableTextSpan\n path: ChildPath\n }\n markState: MarkState\n focusSpanTextBefore: string\n focusSpanTextAfter: string\n previousSpan:\n | {\n node: PortableTextSpan\n path: ChildPath\n }\n | undefined\n nextSpan:\n | {\n node: PortableTextSpan\n path: ChildPath\n }\n | undefined\n }\n | undefined\n> = (snapshot) => {\n const focusSpan = getFocusSpan(snapshot)\n const markState = getMarkState(snapshot)\n\n if (!focusSpan || !markState || !snapshot.context.selection) {\n return undefined\n }\n\n const focusSpanTextBefore = focusSpan.node.text.slice(\n 0,\n snapshot.context.selection.focus.offset,\n )\n const focusSpanTextAfter = focusSpan.node.text.slice(\n snapshot.context.selection.focus.offset,\n )\n const previousSpan = getPreviousSpan(snapshot)\n const nextSpan = getNextSpan(snapshot)\n\n return {\n focusSpan,\n markState,\n focusSpanTextBefore,\n focusSpanTextAfter,\n previousSpan,\n nextSpan,\n }\n}\n\ntype FocusSpanData = {\n node: PortableTextSpan\n path: ChildPath\n textBefore: string\n textAfter: string\n}\n\nfunction createTriggerActions({\n snapshot,\n payload,\n keywordState,\n pickerId,\n}: {\n snapshot: EditorSnapshot\n payload: TriggerPayload\n keywordState: 'partial' | 'complete'\n pickerId: symbol\n}) {\n if (payload.markState.state === 'unchanged') {\n const textBeforeMatch = payload.focusSpanTextBefore.slice(\n 0,\n payload.lastMatch.targetOffsets.anchor.offset,\n )\n const focusSpan = {\n node: {\n _key: payload.focusSpan.node._key,\n _type: payload.focusSpan.node._type,\n text: `${textBeforeMatch}${payload.lastMatch.text}${payload.focusSpanTextAfter}`,\n marks: payload.markState.marks,\n },\n path: payload.focusSpan.path,\n textBefore: textBeforeMatch,\n textAfter: payload.focusSpanTextAfter,\n }\n\n if (keywordState === 'complete') {\n return [\n raise(\n createKeywordFoundEvent({\n focusSpan,\n extractedKeyword: payload.extractedKeyword,\n pickerId,\n }),\n ),\n ]\n }\n\n return [\n raise(\n createTriggerFoundEvent({\n focusSpan,\n extractedKeyword: payload.extractedKeyword,\n pickerId,\n }),\n ),\n ]\n }\n\n const newSpan = {\n _key: snapshot.context.keyGenerator(),\n _type: payload.focusSpan.node._type,\n text: payload.lastMatch.text,\n marks: payload.markState.marks,\n }\n\n let focusSpan: FocusSpanData = {\n node: {\n _key: newSpan._key,\n _type: newSpan._type,\n text: `${newSpan.text}${payload.nextSpan?.node.text ?? payload.focusSpanTextAfter}`,\n marks: payload.markState.marks,\n },\n path: [\n {_key: payload.focusSpan.path[0]._key},\n 'children',\n {_key: newSpan._key},\n ] satisfies ChildPath,\n textBefore: '',\n textAfter: payload.nextSpan?.node.text ?? payload.focusSpanTextAfter,\n }\n\n if (\n payload.previousSpan &&\n payload.focusSpanTextBefore.length === 0 &&\n JSON.stringify(payload.previousSpan.node.marks ?? []) ===\n JSON.stringify(payload.markState.marks)\n ) {\n focusSpan = {\n node: {\n _key: payload.previousSpan.node._key,\n _type: newSpan._type,\n text: `${payload.previousSpan.node.text}${newSpan.text}`,\n marks: newSpan.marks,\n },\n path: payload.previousSpan.path,\n textBefore: payload.previousSpan.node.text,\n textAfter: '',\n }\n }\n\n return [\n raise({type: 'select', at: payload.lastMatch.targetOffsets}),\n raise({type: 'delete', at: payload.lastMatch.targetOffsets}),\n raise({type: 'insert.child', child: newSpan}),\n ...(keywordState === 'complete'\n ? [\n raise(\n createKeywordFoundEvent({\n focusSpan,\n extractedKeyword: payload.extractedKeyword,\n pickerId,\n }),\n ),\n ]\n : [\n raise(\n createTriggerFoundEvent({\n focusSpan,\n extractedKeyword: payload.extractedKeyword,\n pickerId,\n }),\n ),\n ]),\n ]\n}\n\ntype TriggerFoundEvent = {\n type: 'custom.typeahead trigger found'\n focusSpan: FocusSpanData\n extractedKeyword: string\n pickerId: symbol\n}\n\nfunction createTriggerFoundEvent(payload: {\n focusSpan: FocusSpanData\n extractedKeyword: string\n pickerId: symbol\n}): TriggerFoundEvent {\n return {\n type: 'custom.typeahead trigger found',\n ...payload,\n }\n}\n\ntype KeywordFoundEvent = {\n type: 'custom.typeahead keyword found'\n focusSpan: FocusSpanData\n extractedKeyword: string\n pickerId: symbol\n}\n\nfunction createKeywordFoundEvent(payload: {\n focusSpan: FocusSpanData\n extractedKeyword: string\n pickerId: symbol\n}): KeywordFoundEvent {\n return {\n type: 'custom.typeahead keyword found',\n ...payload,\n }\n}\n\ntype TypeaheadPickerMachineContext<TMatch extends object> = {\n editor: Editor\n definition: TypeaheadPickerDefinition<TMatch>\n partialPattern: RegExp\n completePattern: RegExp | undefined\n matches: ReadonlyArray<TMatch>\n selectedIndex: number\n focusSpan: FocusSpanData | undefined\n fullMatch: string\n keyword: string\n loadingFullMatch: string\n error: Error | undefined\n isLoading: boolean\n}\n\ntype TypeaheadPickerMachineEvent<TMatch extends object> =\n | TriggerFoundEvent\n | KeywordFoundEvent\n | {type: 'selection changed'}\n | {type: 'dismiss'}\n | {type: 'navigate down'}\n | {type: 'navigate up'}\n | {type: 'navigate to'; index: number}\n | {type: 'select'}\n | {type: 'matches loaded'; matches: ReadonlyArray<TMatch>}\n | {type: 'matches error'; error: Error}\n\ntype TriggerPayload = ReturnType<typeof getTriggerState> & {\n lastMatch: InputRuleMatch\n extractedKeyword: string\n}\n\n/**\n * Extract the full match (trigger + keyword) from focus span data.\n */\nfunction extractFullMatchFromFocusSpan(focusSpan: FocusSpanData): string {\n if (focusSpan.textBefore.length > 0 && focusSpan.textAfter.length > 0) {\n return focusSpan.node.text.slice(\n focusSpan.textBefore.length,\n -focusSpan.textAfter.length,\n )\n }\n if (focusSpan.textBefore.length > 0) {\n return focusSpan.node.text.slice(focusSpan.textBefore.length)\n }\n if (focusSpan.textAfter.length > 0) {\n return focusSpan.node.text.slice(0, -focusSpan.textAfter.length)\n }\n return focusSpan.node.text\n}\n\n/**\n * Validate and update focus span based on current editor state.\n * Returns updated focus span or undefined if invalid.\n */\nfunction validateFocusSpan(\n currentFocusSpan: FocusSpanData,\n editor: Editor,\n partialPattern: RegExp,\n completePattern: RegExp | undefined,\n): FocusSpanData | undefined {\n const snapshot = editor.getSnapshot()\n const focusSpan = getFocusSpan(snapshot)\n\n if (!snapshot.context.selection || !focusSpan) {\n return undefined\n }\n\n const nextSpan = getNextSpan({\n ...snapshot,\n context: {\n ...snapshot.context,\n selection: {\n anchor: {path: currentFocusSpan.path, offset: 0},\n focus: {path: currentFocusSpan.path, offset: 0},\n },\n },\n })\n\n if (!isEqualPaths(focusSpan.path, currentFocusSpan.path)) {\n if (\n nextSpan &&\n currentFocusSpan.textAfter.length === 0 &&\n snapshot.context.selection.focus.offset === 0 &&\n isSelectionCollapsed(snapshot)\n ) {\n return currentFocusSpan\n }\n\n return undefined\n }\n\n if (!focusSpan.node.text.startsWith(currentFocusSpan.textBefore)) {\n return undefined\n }\n\n if (!focusSpan.node.text.endsWith(currentFocusSpan.textAfter)) {\n return undefined\n }\n\n const keywordAnchor = {\n path: focusSpan.path,\n offset: currentFocusSpan.textBefore.length,\n }\n const keywordFocus = {\n path: focusSpan.path,\n offset: focusSpan.node.text.length - currentFocusSpan.textAfter.length,\n }\n\n const selectionIsBeforeKeyword =\n isPointAfterSelection(keywordAnchor)(snapshot)\n const selectionIsAfterKeyword = isPointBeforeSelection(keywordFocus)(snapshot)\n\n if (selectionIsBeforeKeyword || selectionIsAfterKeyword) {\n return undefined\n }\n\n const keywordText = focusSpan.node.text.slice(\n currentFocusSpan.textBefore.length,\n currentFocusSpan.textAfter.length > 0\n ? -currentFocusSpan.textAfter.length\n : undefined,\n )\n const patternMatch = keywordText.match(partialPattern)\n\n if (!patternMatch || patternMatch.index !== 0) {\n return undefined\n }\n\n let matchEnd = currentFocusSpan.textBefore.length + patternMatch[0].length\n\n if (completePattern) {\n const completeMatch = keywordText.match(completePattern)\n\n if (\n completeMatch &&\n completeMatch.index === 0 &&\n completeMatch[0] === keywordText\n ) {\n matchEnd = currentFocusSpan.textBefore.length + completeMatch[0].length\n }\n }\n\n if (snapshot.context.selection.focus.offset > matchEnd) {\n return undefined\n }\n\n return {\n node: focusSpan.node,\n path: focusSpan.path,\n textBefore: currentFocusSpan.textBefore,\n textAfter: currentFocusSpan.textAfter,\n }\n}\n\n/**\n * Extract keyword from input rule match using groupMatches when available.\n * Falls back to extractKeywordFromPattern for patterns without capture groups\n * or when the capture group is empty (which can happen with patterns like\n * `/:(\\S*):/` matching `::` where the capture group matches empty string).\n */\nfunction extractKeywordFromMatch(\n match: InputRuleMatch,\n pattern: RegExp,\n autoCompleteWith?: string,\n): string {\n const firstGroupMatch = match.groupMatches[0]\n if (firstGroupMatch && firstGroupMatch.text.length > 0) {\n return firstGroupMatch.text\n }\n return extractKeywordFromPattern(match.text, pattern, autoCompleteWith)\n}\n\nfunction createInputRules<TMatch extends object>(\n definition: TypeaheadPickerDefinition<TMatch>,\n) {\n const rules: Array<ReturnType<typeof defineInputRule<TriggerPayload>>> = []\n\n const partialPattern = definition.pattern\n const completePattern = buildCompletePattern(definition)\n\n if (completePattern) {\n const completeTriggerRule = defineInputRule<TriggerPayload>({\n on: completePattern,\n guard: ({snapshot, event}) => {\n const lastMatch = event.matches.at(-1)\n\n if (!lastMatch) {\n return false\n }\n\n if (lastMatch.targetOffsets.anchor.offset < event.textBefore.length) {\n return false\n }\n\n const triggerState = getTriggerState(snapshot)\n\n if (!triggerState) {\n return false\n }\n\n return {\n ...triggerState,\n lastMatch,\n extractedKeyword: extractKeywordFromMatch(\n lastMatch,\n partialPattern,\n definition.autoCompleteWith,\n ),\n }\n },\n actions: [\n ({snapshot}, payload) =>\n createTriggerActions({\n snapshot,\n payload,\n keywordState: 'complete',\n pickerId: definition._id,\n }),\n ],\n })\n\n rules.push(completeTriggerRule)\n }\n\n const partialTriggerRule = defineInputRule<TriggerPayload>({\n on: partialPattern,\n guard: ({snapshot, event}) => {\n const lastMatch = event.matches.at(-1)\n\n if (!lastMatch) {\n return false\n }\n\n if (lastMatch.targetOffsets.anchor.offset < event.textBefore.length) {\n return false\n }\n\n const triggerState = getTriggerState(snapshot)\n\n if (!triggerState) {\n return false\n }\n\n if (completePattern) {\n const fullText = triggerState.focusSpan.node.text\n const textFromMatchStart = fullText.slice(\n lastMatch.targetOffsets.anchor.offset,\n )\n\n const completeMatch = textFromMatchStart.match(completePattern)\n if (completeMatch && completeMatch.index === 0) {\n return false\n }\n }\n\n return {\n ...triggerState,\n lastMatch,\n extractedKeyword: extractKeywordFromMatch(\n lastMatch,\n partialPattern,\n definition.autoCompleteWith,\n ),\n }\n },\n actions: [\n ({snapshot}, payload) =>\n createTriggerActions({\n snapshot,\n payload,\n keywordState: 'partial',\n pickerId: definition._id,\n }),\n ],\n })\n\n rules.push(partialTriggerRule)\n\n return rules\n}\n\nconst triggerListenerCallback = <\n TMatch extends object,\n>(): CallbackLogicFunction<\n AnyEventObject,\n TypeaheadPickerMachineEvent<TMatch>,\n {editor: Editor; definition: TypeaheadPickerDefinition<TMatch>}\n> => {\n return ({sendBack, input}) => {\n const rules = createInputRules(input.definition)\n\n const unregisterBehaviors = [\n input.editor.registerBehavior({\n behavior: defineInputRuleBehavior({rules}),\n }),\n input.editor.registerBehavior({\n behavior: defineBehavior<KeywordFoundEvent, KeywordFoundEvent['type']>({\n on: 'custom.typeahead keyword found',\n guard: ({event}) => event.pickerId === input.definition._id,\n actions: [\n ({event}) => [\n effect(() => {\n sendBack(event)\n }),\n ],\n ],\n }),\n }),\n input.editor.registerBehavior({\n behavior: defineBehavior<TriggerFoundEvent, TriggerFoundEvent['type']>({\n on: 'custom.typeahead trigger found',\n guard: ({event}) => event.pickerId === input.definition._id,\n actions: [\n ({event}) => [\n effect(() => {\n sendBack(event)\n }),\n ],\n ],\n }),\n }),\n ]\n\n return () => {\n for (const unregister of unregisterBehaviors) {\n unregister()\n }\n }\n }\n}\n\nconst escapeListenerCallback = <TMatch extends object>(): CallbackLogicFunction<\n AnyEventObject,\n TypeaheadPickerMachineEvent<TMatch>,\n {editor: Editor}\n> => {\n return ({sendBack, input}) => {\n return input.editor.registerBehavior({\n behavior: defineBehavior({\n on: 'keyboard.keydown',\n guard: ({event}) => escapeShortcut.guard(event.originEvent),\n actions: [\n () => [\n effect(() => {\n sendBack({type: 'dismiss'})\n }),\n ],\n ],\n }),\n })\n }\n}\n\nconst arrowListenerCallback = <TMatch extends object>(): CallbackLogicFunction<\n AnyEventObject,\n TypeaheadPickerMachineEvent<TMatch>,\n {editor: Editor}\n> => {\n return ({sendBack, input}) => {\n const unregisterBehaviors = [\n input.editor.registerBehavior({\n behavior: defineBehavior({\n on: 'keyboard.keydown',\n guard: ({event}) => arrowDownShortcut.guard(event.originEvent),\n actions: [\n () => [\n effect(() => {\n sendBack({type: 'navigate down'})\n }),\n ],\n ],\n }),\n }),\n input.editor.registerBehavior({\n behavior: defineBehavior({\n on: 'keyboard.keydown',\n guard: ({event}) => arrowUpShortcut.guard(event.originEvent),\n actions: [\n () => [\n effect(() => {\n sendBack({type: 'navigate up'})\n }),\n ],\n ],\n }),\n }),\n ]\n\n return () => {\n for (const unregister of unregisterBehaviors) {\n unregister()\n }\n }\n }\n}\n\nconst selectionListenerCallback = <\n TMatch extends object,\n>(): CallbackLogicFunction<\n AnyEventObject,\n TypeaheadPickerMachineEvent<TMatch>,\n {editor: Editor}\n> => {\n return ({sendBack, input}) => {\n const subscription = input.editor.on('selection', () => {\n sendBack({type: 'selection changed'})\n })\n\n return subscription.unsubscribe\n }\n}\n\nconst submitListenerCallback = <TMatch extends object>(): CallbackLogicFunction<\n {type: 'context changed'; context: TypeaheadPickerMachineContext<TMatch>},\n TypeaheadPickerMachineEvent<TMatch>,\n {context: TypeaheadPickerMachineContext<TMatch>}\n> => {\n return ({sendBack, input, receive}) => {\n let context = input.context\n\n receive((event) => {\n context = event.context\n })\n\n const unregisterBehaviors = [\n input.context.editor.registerBehavior({\n behavior: defineBehavior({\n on: 'keyboard.keydown',\n guard: ({event}) => {\n if (\n !enterShortcut.guard(event.originEvent) &&\n !tabShortcut.guard(event.originEvent)\n ) {\n return false\n }\n\n const focusSpan = context.focusSpan\n const match = context.matches[context.selectedIndex]\n\n return match && focusSpan ? {focusSpan, match} : false\n },\n actions: [\n () => [\n effect(() => {\n sendBack({type: 'select'})\n }),\n ],\n ],\n }),\n }),\n input.context.editor.registerBehavior({\n behavior: defineBehavior({\n on: 'keyboard.keydown',\n guard: ({event}) =>\n (enterShortcut.guard(event.originEvent) ||\n tabShortcut.guard(event.originEvent)) &&\n context.fullMatch.length === 1,\n actions: [\n ({event}) => [\n forward(event),\n effect(() => {\n sendBack({type: 'dismiss'})\n }),\n ],\n ],\n }),\n }),\n input.context.editor.registerBehavior({\n behavior: defineBehavior({\n on: 'keyboard.keydown',\n guard: ({event}) =>\n (enterShortcut.guard(event.originEvent) ||\n tabShortcut.guard(event.originEvent)) &&\n context.fullMatch.length > 1 &&\n context.matches.length === 0,\n actions: [\n () => [\n effect(() => {\n sendBack({type: 'dismiss'})\n }),\n ],\n ],\n }),\n }),\n ]\n\n return () => {\n for (const unregister of unregisterBehaviors) {\n unregister()\n }\n }\n }\n}\n\nconst textInsertionListenerCallback = <\n TMatch extends object,\n>(): CallbackLogicFunction<\n {type: 'context changed'; context: TypeaheadPickerMachineContext<TMatch>},\n TypeaheadPickerMachineEvent<TMatch>,\n {context: TypeaheadPickerMachineContext<TMatch>}\n> => {\n return ({sendBack, input, receive}) => {\n let context = input.context\n\n receive((event) => {\n context = event.context\n })\n\n return input.context.editor.registerBehavior({\n behavior: defineBehavior({\n on: 'insert.text',\n guard: ({snapshot}) => {\n if (!context.focusSpan) {\n return false\n }\n if (!snapshot.context.selection) {\n return false\n }\n\n const keywordAnchor = {\n path: context.focusSpan.path,\n offset: context.focusSpan.textBefore.length,\n }\n\n return isEqualSelectionPoints(\n snapshot.context.selection.focus,\n keywordAnchor,\n )\n },\n actions: [\n ({event}) => [\n forward(event),\n effect(() => {\n sendBack({type: 'dismiss'})\n }),\n ],\n ],\n }),\n })\n }\n}\n\ntype InsertMatchEvent<TMatch extends object> = {\n type: 'custom.typeahead insert match'\n match: TMatch\n focusSpan: FocusSpanData\n keyword: string\n pickerId: symbol\n}\n\nconst insertMatchListenerCallback = <\n TMatch extends object,\n>(): CallbackLogicFunction<\n AnyEventObject,\n TypeaheadPickerMachineEvent<TMatch>,\n {context: TypeaheadPickerMachineContext<TMatch>}\n> => {\n return ({sendBack, input}) => {\n return input.context.editor.registerBehavior({\n behavior: defineBehavior<InsertMatchEvent<TMatch>>({\n on: 'custom.typeahead insert match',\n guard: ({event}) => event.pickerId === input.context.definition._id,\n actions: [\n ({event, snapshot, dom}) => {\n const patternSelection = {\n anchor: {\n path: event.focusSpan.path,\n offset: event.focusSpan.textBefore.length,\n },\n focus: {\n path: event.focusSpan.path,\n offset:\n event.focusSpan.node.text.length -\n event.focusSpan.textAfter.length,\n },\n }\n\n const allActions: Array<\n ReturnType<typeof raise> | ReturnType<typeof effect>\n > = [\n effect(() => {\n sendBack({type: 'dismiss'})\n }),\n ]\n\n for (const actionSet of input.context.definition.actions) {\n const actions = actionSet(\n {\n snapshot,\n dom,\n event: {\n type: 'typeahead.select',\n match: event.match,\n keyword: event.keyword,\n patternSelection,\n },\n },\n true,\n )\n for (const action of actions) {\n allActions.push(\n action as\n | ReturnType<typeof raise>\n | ReturnType<typeof effect>,\n )\n }\n }\n\n // Dispatch a select event after all actions complete to exit\n // input-rule's \"input rule applied\" state. We use queueMicrotask\n // to ensure this runs after the cursor has moved to its final position.\n allActions.push(\n effect(() => {\n queueMicrotask(() => {\n const currentSelection =\n input.context.editor.getSnapshot().context.selection\n if (currentSelection) {\n input.context.editor.send({\n type: 'select',\n at: currentSelection,\n })\n }\n })\n }),\n )\n\n return allActions\n },\n ],\n }),\n })\n }\n}\n\nexport function createTypeaheadPickerMachine<TMatch extends object>() {\n return setup({\n types: {\n context: {} as TypeaheadPickerMachineContext<TMatch>,\n input: {} as {\n editor: Editor\n definition: TypeaheadPickerDefinition<TMatch>\n },\n events: {} as TypeaheadPickerMachineEvent<TMatch>,\n },\n delays: {\n DEBOUNCE: ({context}) => context.definition.debounceMs ?? 0,\n },\n actors: {\n 'trigger listener': fromCallback(triggerListenerCallback<TMatch>()),\n 'escape listener': fromCallback(escapeListenerCallback<TMatch>()),\n 'arrow listener': fromCallback(arrowListenerCallback<TMatch>()),\n 'selection listener': fromCallback(selectionListenerCallback<TMatch>()),\n 'submit listener': fromCallback(submitListenerCallback<TMatch>()),\n 'text insertion listener': fromCallback(\n textInsertionListenerCallback<TMatch>(),\n ),\n 'insert match listener': fromCallback(\n insertMatchListenerCallback<TMatch>(),\n ),\n 'get matches': fromPromise(\n async ({\n input,\n }: {\n input: {\n keyword: string\n getMatches: TypeaheadPickerDefinition<TMatch>['getMatches']\n }\n }) => {\n const result = input.getMatches({keyword: input.keyword})\n const matches = await Promise.resolve(result)\n return {keyword: input.keyword, matches}\n },\n ),\n },\n actions: {\n 'handle trigger found': assign(({context, event}) => {\n if (\n event.type !== 'custom.typeahead trigger found' &&\n event.type !== 'custom.typeahead keyword found'\n ) {\n return {}\n }\n\n const focusSpan = event.focusSpan\n const fullMatch = extractFullMatchFromFocusSpan(focusSpan)\n const keyword = event.extractedKeyword\n\n if (\n context.definition.mode === 'async' ||\n context.definition.debounceMs\n ) {\n return {\n focusSpan,\n fullMatch,\n keyword,\n isLoading: true,\n selectedIndex: 0,\n }\n }\n\n const matches = context.definition.getMatches({\n keyword,\n }) as Array<TMatch>\n\n return {\n focusSpan,\n fullMatch,\n keyword,\n matches,\n loadingFullMatch: fullMatch,\n isLoading: false,\n selectedIndex: 0,\n }\n }),\n 'handle selection changed': assign(({context}) => {\n if (!context.focusSpan) {\n return {\n focusSpan: undefined,\n fullMatch: '',\n keyword: '',\n matches: [],\n selectedIndex: 0,\n isLoading: false,\n }\n }\n\n const updatedFocusSpan = validateFocusSpan(\n context.focusSpan,\n context.editor,\n context.partialPattern,\n context.completePattern,\n )\n\n if (!updatedFocusSpan) {\n return {\n focusSpan: undefined,\n fullMatch: '',\n keyword: '',\n matches: [],\n selectedIndex: 0,\n isLoading: false,\n }\n }\n\n const fullMatch = extractFullMatchFromFocusSpan(updatedFocusSpan)\n\n if (fullMatch === context.fullMatch) {\n return {focusSpan: updatedFocusSpan}\n }\n\n const keyword = extractKeywordFromPattern(\n fullMatch,\n context.definition.pattern,\n context.definition.autoCompleteWith,\n )\n\n if (\n context.definition.mode === 'async' ||\n context.definition.debounceMs\n ) {\n return {\n focusSpan: updatedFocusSpan,\n fullMatch,\n keyword,\n selectedIndex: 0,\n isLoading:\n context.isLoading || context.loadingFullMatch !== fullMatch,\n }\n }\n\n const matches = context.definition.getMatches({\n keyword,\n }) as Array<TMatch>\n\n return {\n focusSpan: updatedFocusSpan,\n fullMatch,\n keyword,\n matches,\n loadingFullMatch: fullMatch,\n selectedIndex: 0,\n isLoading: false,\n }\n }),\n 'handle async load complete': assign(({context, event}) => {\n const output = (\n event as unknown as {\n output: {keyword: string; matches: ReadonlyArray<TMatch>}\n }\n ).output\n\n if (output.keyword !== context.keyword) {\n return {isLoading: context.fullMatch !== context.loadingFullMatch}\n }\n\n return {\n matches: output.matches,\n isLoading: context.fullMatch !== context.loadingFullMatch,\n }\n }),\n 'reset': assign({\n fullMatch: '',\n keyword: '',\n matches: [],\n selectedIndex: 0,\n isLoading: false,\n loadingFullMatch: '',\n focusSpan: undefined,\n error: undefined,\n }),\n 'navigate': assign(({context, event}) => {\n if (context.matches.length === 0) {\n return {selectedIndex: 0}\n }\n\n if (event.type === 'navigate to') {\n return {selectedIndex: event.index}\n }\n\n if (event.type === 'navigate up') {\n return {\n selectedIndex:\n (context.selectedIndex - 1 + context.matches.length) %\n context.matches.length,\n }\n }\n\n return {\n selectedIndex: (context.selectedIndex + 1) % context.matches.length,\n }\n }),\n 'insert match': ({context}, params: {exact?: boolean}) => {\n if (!context.focusSpan) {\n return\n }\n\n const match = params.exact\n ? getExactMatch(context.matches)\n : context.matches[context.selectedIndex]\n\n if (!match) {\n return\n }\n\n context.editor.send({\n type: 'custom.typeahead insert match',\n match,\n focusSpan: context.focusSpan,\n keyword: context.keyword,\n pickerId: context.definition._id,\n })\n },\n 'update submit listener context': sendTo(\n 'submit listener',\n ({context}) => ({type: 'context changed', context}),\n ),\n 'update text insertion listener context': sendTo(\n 'text insertion listener',\n ({context}) => ({type: 'context changed', context}),\n ),\n 'handle error': assign({\n isLoading: false,\n error: ({event}) => (event as {error: Error}).error,\n }),\n },\n guards: {\n 'no focus span': ({context}) => !context.focusSpan,\n 'no debounce': ({context}) =>\n !context.definition.debounceMs || context.definition.debounceMs === 0,\n 'is complete keyword': ({context}) => {\n if (!context.completePattern || !context.focusSpan) {\n return false\n }\n const fullKeywordText = context.focusSpan.node.text.slice(\n context.focusSpan.textBefore.length,\n context.focusSpan.textAfter.length > 0\n ? -context.focusSpan.textAfter.length\n : undefined,\n )\n const completeMatch = fullKeywordText.match(context.completePattern)\n if (\n !completeMatch ||\n completeMatch.index !== 0 ||\n completeMatch[0] !== fullKeywordText\n ) {\n return false\n }\n return hasExactlyOneExactMatch(context.matches)\n },\n 'has matches': ({context}) => context.matches.length > 0,\n 'no matches': ({context}) => context.matches.length === 0,\n 'is loading': ({context}) => context.isLoading,\n },\n }).createMachine({\n id: 'typeahead picker',\n context: ({input}) => ({\n editor: input.editor,\n definition: input.definition,\n partialPattern: normalizePattern(input.definition.pattern),\n completePattern: buildCompletePattern(input.definition),\n matches: [],\n selectedIndex: 0,\n focusSpan: undefined,\n fullMatch: '',\n keyword: '',\n loadingFullMatch: '',\n error: undefined,\n isLoading: false,\n }),\n initial: 'idle',\n states: {\n 'idle': {\n entry: ['reset'],\n invoke: {\n src: 'trigger listener',\n input: ({context}) => ({\n editor: context.editor,\n definition: context.definition,\n }),\n },\n on: {\n 'custom.typeahead trigger found': {\n target: 'active',\n actions: ['handle trigger found'],\n },\n 'custom.typeahead keyword found': {\n target: 'checking complete',\n actions: ['handle trigger found'],\n },\n },\n },\n 'checking complete': {\n invoke: [\n {\n src: 'insert match listener',\n input: ({context}) => ({context}),\n },\n {\n src: 'get matches',\n input: ({context}) => ({\n keyword: context.keyword,\n getMatches: context.definition.getMatches,\n }),\n onDone: [\n {\n guard: ({event}) =>\n hasExactlyOneExactMatch(event.output.matches),\n target: 'idle',\n actions: [\n assign({matches: ({event}) => event.output.matches}),\n {type: 'insert match', params: {exact: true}},\n ],\n },\n {\n target: 'active',\n actions: [assign({matches: ({event}) => event.output.matches})],\n },\n ],\n onError: {\n target: 'active.no matches',\n actions: ['handle error'],\n },\n },\n ],\n },\n 'active': {\n invoke: [\n {\n src: 'insert match listener',\n input: ({context}) => ({context}),\n },\n {\n src: 'escape listener',\n input: ({context}) => ({editor: context.editor}),\n },\n {\n src: 'selection listener',\n input: ({context}) => ({editor: context.editor}),\n },\n {\n src: 'submit listener',\n id: 'submit listener',\n input: ({context}) => ({context}),\n },\n {\n src: 'text insertion listener',\n id: 'text insertion listener',\n input: ({context}) => ({context}),\n },\n ],\n on: {\n 'dismiss': {\n target: 'idle',\n },\n 'selection changed': {\n actions: [\n 'handle selection changed',\n 'update submit listener context',\n 'update text insertion listener context',\n ],\n },\n },\n always: [\n {\n guard: 'no focus span',\n target: 'idle',\n },\n {\n guard: 'is complete keyword',\n actions: [{type: 'insert match', params: {exact: false}}],\n target: 'idle',\n },\n ],\n initial: 'evaluating',\n states: {\n 'evaluating': {\n always: [\n {\n guard: 'is loading',\n target: 'loading',\n },\n {\n guard: 'has matches',\n target: 'showing matches',\n },\n {\n target: 'no matches',\n },\n ],\n },\n 'loading': {\n entry: [\n assign({loadingFullMatch: ({context}) => context.fullMatch}),\n ],\n initial: 'debouncing',\n states: {\n debouncing: {\n always: [{guard: 'no debounce', target: 'fetching'}],\n after: {\n DEBOUNCE: 'fetching',\n },\n },\n fetching: {\n invoke: {\n src: 'get matches',\n input: ({context}) => ({\n keyword: context.keyword,\n getMatches: context.definition.getMatches,\n }),\n onDone: {\n target: '#typeahead picker.active.evaluating',\n actions: [\n assign(({context, event}) => {\n if (event.output.keyword !== context.keyword) {\n return {\n isLoading:\n context.fullMatch !== context.loadingFullMatch,\n }\n }\n\n return {\n matches: event.output.matches,\n isLoading:\n context.fullMatch !== context.loadingFullMatch,\n }\n }),\n ],\n },\n onError: {\n target: '#typeahead picker.active.no matches',\n actions: ['handle error'],\n },\n },\n },\n },\n },\n 'no matches': {\n entry: [assign({selectedIndex: 0})],\n always: [\n {\n guard: 'has matches',\n target: 'showing matches',\n },\n ],\n initial: 'idle',\n states: {\n idle: {\n always: [{guard: 'is loading', target: 'loading'}],\n },\n loading: {\n entry: [\n assign({loadingFullMatch: ({context}) => context.fullMatch}),\n ],\n initial: 'debouncing',\n states: {\n debouncing: {\n always: [{guard: 'no debounce', target: 'fetching'}],\n after: {\n DEBOUNCE: 'fetching',\n },\n },\n fetching: {\n invoke: {\n src: 'get matches',\n input: ({context}) => ({\n keyword: context.keyword,\n getMatches: context.definition.getMatches,\n }),\n onDone: {\n target: '#typeahead picker.active.no matches.idle',\n actions: ['handle async load complete'],\n },\n onError: {\n target: '#typeahead picker.active.no matches.idle',\n actions: ['handle error'],\n },\n },\n },\n },\n },\n },\n },\n 'showing matches': {\n entry: [\n 'update submit listener context',\n 'update text insertion listener context',\n ],\n invoke: {\n src: 'arrow listener',\n input: ({context}) => ({editor: context.editor}),\n },\n always: [\n {\n guard: 'no matches',\n target: 'no matches',\n },\n ],\n on: {\n 'navigate down': {\n actions: [\n 'navigate',\n 'update submit listener context',\n 'update text insertion listener context',\n ],\n },\n 'navigate up': {\n actions: [\n 'navigate',\n 'update submit listener context',\n 'update text insertion listener context',\n ],\n },\n 'navigate to': {\n actions: [\n 'navigate',\n 'update submit listener context',\n 'update text insertion listener context',\n ],\n },\n 'select': {\n target: '#typeahead picker.idle',\n actions: [{type: 'insert match', params: {exact: false}}],\n },\n },\n initial: 'idle',\n states: {\n idle: {\n always: [{guard: 'is loading', target: 'loading'}],\n },\n loading: {\n entry: [\n assign({loadingFullMatch: ({context}) => context.fullMatch}),\n ],\n initial: 'debouncing',\n states: {\n debouncing: {\n always: [{guard: 'no debounce', target: 'fetching'}],\n after: {\n DEBOUNCE: 'fetching',\n },\n },\n fetching: {\n invoke: {\n src: 'get matches',\n input: ({context}) => ({\n keyword: context.keyword,\n getMatches: context.definition.getMatches,\n }),\n onDone: {\n target: '#typeahead picker.active.showing matches.idle',\n actions: ['handle async load complete'],\n },\n onError: {\n target: '#typeahead picker.active.showing matches.idle',\n actions: ['handle error'],\n },\n },\n },\n },\n },\n },\n },\n },\n },\n },\n })\n}\n\n/**\n * Check if matches contain exactly one exact match.\n */\nfunction hasExactlyOneExactMatch<TMatch extends object>(\n matches: ReadonlyArray<TMatch>,\n): boolean {\n return (\n matches.filter(\n (match) =>\n (match as unknown as AutoCompleteMatch | undefined)?.type === 'exact',\n ).length === 1\n )\n}\n\n/**\n * Get the single exact match from matches, if there is exactly one.\n */\nfunction getExactMatch<TMatch extends object>(\n matches: ReadonlyArray<TMatch>,\n): TMatch | undefined {\n const exactMatches = matches.filter(\n (match) =>\n (match as unknown as AutoCompleteMatch | undefined)?.type === 'exact',\n )\n\n return exactMatches.length === 1 ? exactMatches[0] : undefined\n}\n","import {useEditor} from '@portabletext/editor'\nimport {useActor} from '@xstate/react'\nimport {createTypeaheadPickerMachine} from './typeahead-picker-machine'\nimport type {\n TypeaheadPicker,\n TypeaheadPickerDefinition,\n TypeaheadPickerEvent,\n TypeaheadPickerState,\n} from './typeahead-picker.types'\n\n/**\n * React hook that activates a typeahead picker and returns its current state.\n *\n * Call inside a component rendered within an `EditorProvider`.\n * The picker automatically monitors the editor for trigger patterns.\n *\n * @example\n * ```tsx\n * function MentionPickerUI() {\n * const picker = useTypeaheadPicker(mentionPickerDefinition)\n *\n * if (picker.snapshot.matches('idle')) return null\n * if (picker.snapshot.matches({active: 'loading'})) return <Spinner />\n * if (picker.snapshot.matches({active: 'no matches'})) return <NoResults />\n *\n * const {matches, selectedIndex} = picker.snapshot.context\n *\n * return (\n * <ul>\n * {matches.map((match, index) => (\n * <li\n * key={match.key}\n * aria-selected={index === selectedIndex}\n * onMouseEnter={() => picker.send({type: 'navigate to', index})}\n * onClick={() => picker.send({type: 'select'})}\n * >\n * {match.name}\n * </li>\n * ))}\n * </ul>\n * )\n * }\n * ```\n *\n * @public\n */\nexport function useTypeaheadPicker<TMatch extends object>(\n definition: TypeaheadPickerDefinition<TMatch>,\n): TypeaheadPicker<TMatch> {\n const editor = useEditor()\n const [actorSnapshot, send] = useActor(\n createTypeaheadPickerMachine<TMatch>(),\n {\n input: {\n editor,\n definition,\n },\n },\n )\n\n return {\n snapshot: {\n matches: (state: TypeaheadPickerState) => actorSnapshot.matches(state),\n context: {\n keyword: actorSnapshot.context.keyword,\n matches: actorSnapshot.context.matches as Array<TMatch>,\n selectedIndex: actorSnapshot.context.selectedIndex,\n error: actorSnapshot.context.error,\n },\n },\n send: (event: TypeaheadPickerEvent) => {\n send(event)\n },\n }\n}\n"],"names":["defineTypeaheadPicker","config","_id","extractKeywordFromPattern","matchedText","pattern","autoCompleteWith","endsWith","strippedMatch","slice","length","match","strippedKeyword","escapeRegExp","str","replace","normalizePattern","RegExp","source","buildCompletePattern","definition","arrowUpShortcut","createKeyboardShortcut","default","key","arrowDownShortcut","enterShortcut","tabShortcut","escapeShortcut","getTriggerState","snapshot","focusSpan","getFocusSpan","markState","getMarkState","context","selection","focusSpanTextBefore","node","text","focus","offset","focusSpanTextAfter","previousSpan","getPreviousSpan","nextSpan","getNextSpan","createTriggerActions","payload","keywordState","pickerId","state","textBeforeMatch","lastMatch","targetOffsets","anchor","_key","_type","marks","path","textBefore","textAfter","raise","createKeywordFoundEvent","extractedKeyword","createTriggerFoundEvent","newSpan","keyGenerator","JSON","stringify","type","at","child","extractFullMatchFromFocusSpan","validateFocusSpan","currentFocusSpan","editor","partialPattern","completePattern","getSnapshot","isEqualPaths","isSelectionCollapsed","startsWith","keywordAnchor","keywordFocus","selectionIsBeforeKeyword","isPointAfterSelection","selectionIsAfterKeyword","isPointBeforeSelection","keywordText","undefined","patternMatch","index","matchEnd","completeMatch","extractKeywordFromMatch","firstGroupMatch","groupMatches","createInputRules","rules","completeTriggerRule","defineInputRule","on","guard","event","matches","triggerState","actions","push","partialTriggerRule","triggerListenerCallback","sendBack","input","unregisterBehaviors","registerBehavior","behavior","defineInputRuleBehavior","defineBehavior","effect","unregister","escapeListenerCallback","originEvent","arrowListenerCallback","selectionListenerCallback","unsubscribe","submitListenerCallback","receive","selectedIndex","fullMatch","forward","textInsertionListenerCallback","isEqualSelectionPoints","insertMatchListenerCallback","dom","patternSelection","allActions","actionSet","keyword","action","queueMicrotask","currentSelection","send","createTypeaheadPickerMachine","setup","types","events","delays","DEBOUNCE","debounceMs","actors","fromCallback","fromPromise","result","getMatches","Promise","resolve","assign","mode","isLoading","loadingFullMatch","updatedFocusSpan","output","error","insert match","params","exact","getExactMatch","sendTo","guards","no focus span","no debounce","is complete keyword","fullKeywordText","hasExactlyOneExactMatch","has matches","no matches","is loading","createMachine","id","initial","states","entry","invoke","src","target","onDone","onError","always","debouncing","after","fetching","idle","loading","filter","exactMatches","useTypeaheadPicker","$","_c","useEditor","t0","Symbol","for","t1","actorSnapshot","useActor","t2","t3","t4","t5","t6","t7"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,87 @@
1
+ {
2
+ "name": "@portabletext/plugin-typeahead-picker",
3
+ "version": "1.0.0",
4
+ "description": "Generic typeahead picker infrastructure for the Portable Text Editor",
5
+ "keywords": [
6
+ "portabletext",
7
+ "plugin",
8
+ "typeahead",
9
+ "picker",
10
+ "autocomplete"
11
+ ],
12
+ "homepage": "https://www.portabletext.org/",
13
+ "bugs": {
14
+ "url": "https://github.com/portabletext/editor/issues"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/portabletext/editor.git",
19
+ "directory": "packages/plugin-typeahead-picker"
20
+ },
21
+ "license": "MIT",
22
+ "author": "Sanity.io <hello@sanity.io>",
23
+ "sideEffects": false,
24
+ "type": "module",
25
+ "exports": {
26
+ ".": "./dist/index.js",
27
+ "./package.json": "./package.json"
28
+ },
29
+ "main": "./dist/index.js",
30
+ "types": "./dist/index.d.ts",
31
+ "files": [
32
+ "dist"
33
+ ],
34
+ "dependencies": {
35
+ "@xstate/react": "^6.0.0",
36
+ "xstate": "^5.25.0",
37
+ "@portabletext/keyboard-shortcuts": "^2.1.2",
38
+ "@portabletext/plugin-input-rule": "^2.0.15"
39
+ },
40
+ "devDependencies": {
41
+ "@sanity/pkg-utils": "^10.2.1",
42
+ "@sanity/tsconfig": "^2.1.0",
43
+ "@types/react": "^19.2.7",
44
+ "@vitejs/plugin-react": "^5.1.1",
45
+ "@vitest/browser": "^4.0.16",
46
+ "@vitest/browser-playwright": "^4.0.16",
47
+ "babel-plugin-react-compiler": "^1.0.0",
48
+ "eslint": "^9.39.1",
49
+ "eslint-formatter-gha": "^1.6.0",
50
+ "eslint-plugin-react-hooks": "^7.0.1",
51
+ "react": "^19.2.3",
52
+ "typescript": "5.9.3",
53
+ "typescript-eslint": "^8.48.0",
54
+ "vitest": "^4.0.16",
55
+ "@portabletext/schema": "2.1.1",
56
+ "@portabletext/editor": "4.3.0",
57
+ "racejar": "2.0.2"
58
+ },
59
+ "peerDependencies": {
60
+ "@portabletext/editor": "^4.2.4",
61
+ "react": "^19.2"
62
+ },
63
+ "engines": {
64
+ "node": ">=20.19 <22 || >=22.12"
65
+ },
66
+ "scripts": {
67
+ "build": "pkg-utils build --strict --check --clean",
68
+ "check:lint": "biome lint .",
69
+ "check:react-compiler": "eslint --cache .",
70
+ "check:types": "tsc",
71
+ "check:types:watch": "tsc --watch",
72
+ "clean": "del .turbo && del lib && del node_modules",
73
+ "dev": "pkg-utils watch",
74
+ "lint:fix": "biome lint --write .",
75
+ "test": "vitest --run",
76
+ "test:browser": "vitest --run --project browser",
77
+ "test:browser:chromium": "vitest run --project \"browser (chromium)\"",
78
+ "test:browser:chromium:watch": "vitest watch --project \"browser (chromium)\"",
79
+ "test:browser:firefox": "vitest run --project \"browser (firefox)\"",
80
+ "test:browser:firefox:watch": "vitest watch --project \"browser (firefox)\"",
81
+ "test:browser:webkit": "vitest run --project \"browser (webkit)\"",
82
+ "test:browser:webkit:watch": "vitest watch --project \"browser (webkit)\"",
83
+ "test:unit": "vitest --run --project unit",
84
+ "test:unit:watch": "vitest --project unit",
85
+ "test:watch": "vitest"
86
+ }
87
+ }