@sanity/block-insert-picker

1.0.41.0.5
dist/index.js.map
~dist/index.js.mapModified
+1−1
Index: package/dist/index.js.map
===================================================================
--- package/dist/index.js.map
+++ package/dist/index.js.map
@@ -1,1 +1,1 @@
-{"version":3,"file":"index.js","names":["PickerItem","PickerItemMetadata","PickerItemsContext","typeNameChain","memberType","name","type","names","current","push","undefined","derivePickerItems","context","metadata","memberTypes","map","schemaIndex","chain","nameRank","findIndex","entry","rank","includes","Number","MAX_SAFE_INTEGER","filter","hidden","sort","a","b","action","blockType","const","badge","description","group","id","keywords","openOnInsert","title","trigger","unknownMetadataTypes","known","Set","flatMap","has","PickerItem","filterPickerItems","items","query","queryLower","toLowerCase","bareQuery","startsWith","slice","filter","item","bareTrigger","trigger","replace","title","includes","description","keywords","some","kw","PickerItem","PickerSection","group","items","flattenSections","sections","flatMap","section","groupPickerItems","order","byGroup","Map","item","key","bucket","get","set","push","map","Editor","EditorSelection","EditorSnapshot","defineBehavior","raise","blockOffsetsToSelection","getTextBlockText","isTextBlock","PickerMode","InsertGuardResult","anchor","block","InsertPickerItemPayload","cleanup","placement","anchorBlockKey","_key","_type","Record","mode","query","createInsertBehavior","actions","_","at","type","select","guard","event","snapshot","anchorBlockExists","context","value","some","candidate","offsets","offset","path","focus","resolveQueryCleanup","const","on","sendInsertPickerItem","editor","payload","send","CleanupQueryPayload","Omit","createCleanupQueryBehavior","NonNullable","sendCleanupQuery","length","anchorBlock","find","schema","startsWith","Editor","sendInsertPickerItem","PickerMode","InsertContext","blockType","mode","editor","anchorBlockKey","query","keyGenerator","initialValue","Record","onInsertedKey","key","insertPickerItem","ctx","blockKey","block","_key","_type","BlockInsertPickerLabels","title","noMatches","positionAnnouncement","ungroupedSection","footerNavigate","footerInsert","footerDismiss","footerAnywhere","insertError","insertAnchorRemoved","DEFAULT_LABELS","resolveLabels","overrides","Partial","formatNoMatches","labels","query","replace","formatPosition","index","count","String","ContextType","useContext","useMemo","ObjectSchemaType","useSchema","PortableTextMemberSchemaTypesContext","PickerItemsContext","MemberSchemaTypes","NonNullable","usePickerItemsContext","arrayTypeName","$","_c","memberSchemaTypes","schema","t0","bb0","t1","blockObjects","portableText","memberTypes","schemaType","arrayType","get","undefined","jsonType","of","filter","_temp","member","isTextBlockMember","memberType","name","type","current","useCallback","useContext","useEffect","useRef","useFormCallbacks","PortableTextMemberItemsContext","useOpenBlockOnInsert","$","_c","memberItems","onPathOpen","onSetPathCollapsed","pendingKeyRef","t0","t1","key","current","item","find","m","member","path","t2","Symbol","for","blockKey","defineBehavior","effect","forward","BehaviorEvent","BehaviorGuard","getBlockTextBefore","getFirstBlock","getFocusBlock","getFocusTextBlock","isSelectionCollapsed","PickerIntent","PickerState","GuardResult","blockEvent","intent","PickerBehaviorRefs","onIntent","getState","isShortcutEnabled","createPickerBehavior","guard","event","snapshot","state","mode","type","text","focus","anchorBlockKey","node","_key","query","originEvent","key","metaKey","ctrlKey","fallback","anchorBlock","length","unit","slice","delta","actions","payload","guardResponse","sideEffect","on","PickerIntent","PickerState","pickerReducer","state","intent","type","mode","highlightedIndex","delta","anchorBlockKey","query","index","unhandled","effect","raise","blockOffsetsToSelection","defineInputRule","InputRule","KeyGenerator","MarkdownInputRuleConfig","pattern","RegExp","blockType","buildValue","context","matchText","keyGenerator","Record","BuildRulesDeps","onInserted","block","InsertableBlock","_key","_type","createMarkdownInputRules","allowedBlockTypes","rules","ReadonlySet","filter","config","has","map","createInsertRule","CODE_FENCE_PATTERN","BLOCKQUOTE_PATTERN","LanguageEntry","value","aliases","filename","blockquoteRule","options","createValue","codeFenceRule","languages","defaultLanguage","language","normalizeFenceLanguage","fenceLanguageFromMatch","find","entry","undefined","replace","trim","raw","token","lower","toLowerCase","some","alias","actions","event","snapshot","match","matches","text","at","offsets","anchor","targetOffsets","focus","selection","type","placement","select","on","typeNameChain","codeFenceRule","MarkdownInputRuleConfig","PickerItem","PickerItemMetadata","PickerItemsContext","standardBlockPresets","keywords","trigger","type","wellKnownInputRules","blockType","createValue","language","applyPresetMetadata","items","context","presets","presetByType","Map","map","preset","item","action","undefined","memberType","memberTypes","find","candidate","name","get","Boolean","BlockElementIcon","ComponentType","PickerItem","ItemPresentation","title","icon","description","SchemaTypeLike","name","type","to","ReadonlyArray","resolveItemPresentation","item","schemaType","action","blockType","id","upperFirst","value","charAt","toUpperCase","slice","useEditor","Box","Card","Flex","Hotkeys","Popover","Stack","Text","useToast","CSSProperties","useEffect","useId","useLayoutEffect","useMemo","useReducer","useRef","useState","useResolveInitialValueForType","useSchema","SchemaType","derivePickerItems","unknownMetadataTypes","filterPickerItems","flattenSections","groupPickerItems","createCleanupQueryBehavior","createInsertBehavior","sendCleanupQuery","insertPickerItem","BlockInsertPickerLabels","formatNoMatches","formatPosition","resolveLabels","usePickerItemsContext","useOpenBlockOnInsert","createPickerBehavior","pickerReducer","applyPresetMetadata","resolveItemPresentation","PickerInsertEvent","PickerIntent","PickerItem","PickerItemMetadata","PickerItemsContext","PickerItemsResolver","PickerState","BlockInsertPickerProps","items","arrayTypeName","resolveItems","filter","query","labels","Partial","onInsert","event","openOnInsert","shortcut","presets","BlockInsertPicker","labelOverrides","editor","openBlockOnInsert","itemsContext","schema","resolveInitialValueForType","toast","instanceId","listboxId","optionId","id","pickerItems","derived","presented","map","item","action","type","schemaType","memberTypeFor","blockType","presentation","Object","assign","description","icon","title","hasItems","length","warnedRef","context","empty","unknown","process","env","warned","current","console","warn","join","state","dispatch","mode","stateRef","shortcutRef","open","filterItems","filterQuery","bareQuery","sections","filtered","sectionOffsets","offsets","total","section","push","showGroupHeaders","insertInFlightRef","insertItemAtIndex","Exclude","idx","visible","clamped","Math","max","min","chosen","anchorBlockKey","onSelect","closePicker","initialValue","Record","undefined","snapshot","getSnapshot","anchorStillExists","value","some","b","_key","closable","insertAnchorRemoved","status","insertError","keyGenerator","onInsertedKey","key","blockKey","via","error","Error","message","String","selectItemAtIndex","handleIntent","intent","lastIndex","base","highlightedIndex","next","delta","index","handleIntentRef","behavior","getState","isShortcutEnabled","onIntent","unregisterPicker","registerBehavior","unregisterInsert","unregisterCleanup","highlightedItem","announcement","Boolean","cursorRect","setCursorRect","DOMRect","rect","dom","getSelectionRect","x","y","width","height","blockRect","getStartBlockElement","getBoundingClientRect","popoverContentRef","HTMLDivElement","handlePointerDown","PointerEvent","target","Node","contains","editorElement","getEditorElement","handleFocusOut","Event","FocusEvent","relatedTarget","document","addEventListener","removeEventListener","highlightedRowRef","lastPointerRef","highlightOnPointerMove","last","scrollIntoView","block","cursorElement","HTMLElement","preventFocusSteal","display","flexDirection","maxHeight","minWidth","SR_ONLY","letterSpacing","textTransform","flex","minHeight","overflowY","sectionIndex","sectionLabel","group","ungroupedSection","sectionKey","rows","rowIndex","Icon","isHighlighted","clientX","clientY","cursor","alignItems","justifyContent","badge","trigger","footerNavigate","footerInsert","footerDismiss","OPEN_MODIFIER","footerAnywhere","FooterHint","t0","$","_c","keys","label","t1","t2","t3","get","name","member","memberTypes","find","candidate","startsWith","slice","preventDefault","border","clipPath","margin","overflow","padding","position","whiteSpace","IS_APPLE_PLATFORM","navigator","test","platform","userAgent","useEditor","defineInputRuleBehavior","useEffect","useLayoutEffect","useMemo","useRef","typeNameChain","createMarkdownInputRules","MarkdownInputRuleConfig","usePickerItemsContext","useOpenBlockOnInsert","PickerInsertEvent","MarkdownInputRulesProps","arrayTypeName","rules","onInsert","event","openOnInsert","MarkdownInputRules","t0","$","_c","t1","undefined","editor","itemsContext","openBlockOnInsert","t2","memberTypes","t3","t4","rule","member","find","candidate_0","candidate","name","blockType","includes","flatMap","resolvedRules","onInsertedRef","_temp","current","block","_key","blockKey","_type","via","t5","t6","inputRules","allowedBlockTypes","Set","map","_temp2","keyGenerator","getSnapshot","context","onInserted","block_0","length","registerBehavior","behavior","rule_0","ComponentType","PortableTextPluginsProps","BlockInsertPicker","MarkdownInputRuleConfig","BlockInsertPickerLabels","MarkdownInputRules","PickerInsertEvent","PickerItem","PickerItemMetadata","PickerItemsResolver","BlockInsertPickerConfig","items","resolveItems","inputRules","filter","query","labels","Partial","onInsert","event","openOnInsert","shortcut","presets","arrayTypeName","blockInsertPicker","config","BlockInsertPickerPlugins","props","renderDefault","length"],"sources":["../src/deriveItems.ts","../src/filterItems.ts","../src/groupItems.ts","../src/insertBehavior.ts","../src/insertPickerItem.ts","../src/labels.ts","../src/memberSchemaTypes.ts","../src/openBlockOnInsert.ts","../src/pickerBehavior.ts","../src/pickerReducer.ts","../src/inputRules.ts","../src/presets.ts","../src/resolveItemPresentation.ts","../src/blockInsertPicker.tsx","../src/markdownInputRules.tsx","../src/plugin.tsx"],"sourcesContent":["import type {PickerItem, PickerItemMetadata, PickerItemsContext} from './types'\n\n/**\n * The member's own name plus every name up its compiled `type` chain, most\n * specific first: `{type: 'image', name: 'photo'}` yields `['photo',\n * 'image', ...]`. Metadata and presets match against this chain so curation\n * can target either the member name or the underlying type name.\n */\nexport function typeNameChain(memberType: {\n  name: string\n  type?: {name: string; type?: unknown} | undefined\n}): string[] {\n  const names: string[] = []\n  let current: {name: string; type?: unknown} | undefined = memberType\n  while (current && typeof current.name === 'string') {\n    names.push(current.name)\n    current =\n      current.type && typeof current.type === 'object' && 'name' in current.type\n        ? // oxlint-disable-next-line no-unsafe-type-assertion\n          (current.type as {name: string; type?: unknown})\n        : undefined\n  }\n  return names\n}\n\n/**\n * Derives picker items from a portable-text array's insertable member types\n * (see PickerItemsContext), so the picker automatically covers every object\n * block the schema allows. The optional metadata list curates triggers,\n * keywords, grouping, badges, visibility, and descriptions per member type;\n * its array order is the sort rank (see PickerItemMetadata). Titles and\n * icons intentionally stay unresolved here: BlockInsertPicker resolves\n * presentation from the member schema type, which carries member-level\n * config (a member-specific icon, a per-member title override).\n */\nexport function derivePickerItems(\n  context: PickerItemsContext,\n  metadata: readonly PickerItemMetadata[] = [],\n): PickerItem[] {\n  return context.memberTypes\n    .map((memberType, schemaIndex) => {\n      const chain = typeNameChain(memberType)\n      // The member's own name wins over a resolved-chain match, so an entry\n      // for `photo` beats an entry for `image` on `{type: 'image', name:\n      // 'photo'}` — but whichever matches, its array position is the rank.\n      const nameRank = metadata.findIndex((entry) => entry.type === memberType.name)\n      const rank =\n        nameRank === -1 ? metadata.findIndex((entry) => chain.includes(entry.type)) : nameRank\n      const entry = rank === -1 ? undefined : metadata[rank]\n      return {\n        entry,\n        name: memberType.name,\n        rank: rank === -1 ? Number.MAX_SAFE_INTEGER : rank,\n        schemaIndex,\n      }\n    })\n    .filter(({entry}) => !entry?.hidden)\n    .sort((a, b) => a.rank - b.rank || a.schemaIndex - b.schemaIndex)\n    .map(({entry, name}) => ({\n      action: {blockType: name, type: 'insertBlock' as const},\n      badge: entry?.badge,\n      description: entry?.description,\n      group: entry?.group,\n      id: name,\n      keywords: entry?.keywords,\n      openOnInsert: entry?.openOnInsert,\n      title: '',\n      trigger: entry?.trigger,\n    }))\n}\n\n/**\n * Metadata entries whose `type` matches neither a member name nor any name\n * in a member's resolved type chain — almost always a typo. Surfaced as a\n * dev-mode warning by BlockInsertPicker.\n */\nexport function unknownMetadataTypes(\n  context: PickerItemsContext,\n  metadata: readonly PickerItemMetadata[],\n): string[] {\n  const known = new Set(context.memberTypes.flatMap((memberType) => typeNameChain(memberType)))\n  return metadata.map((entry) => entry.type).filter((type) => !known.has(type))\n}\n","import type {PickerItem} from './types'\n\nexport function filterPickerItems(\n  items: readonly PickerItem[],\n  query: string,\n): readonly PickerItem[] {\n  if (query === '' || query === '/') return items\n\n  const queryLower = query.toLowerCase()\n  // Slash-mode queries always carry the leading \"/\", which titles and\n  // keywords never contain — strip it before substring matching.\n  const bareQuery = queryLower.startsWith('/') ? queryLower.slice(1) : queryLower\n\n  return items.filter((item) => {\n    // Triggers match with the slash stripped from both sides so that bare\n    // shortcut-mode queries (\"cta\") reach them, not just slash-mode ones.\n    const bareTrigger = item.trigger?.toLowerCase().replace(/^\\//, '')\n    if (bareTrigger && bareQuery !== '' && bareTrigger.startsWith(bareQuery)) return true\n    if (bareQuery === '') return false\n    if (item.title.toLowerCase().includes(bareQuery)) return true\n    if (item.description?.toLowerCase().includes(bareQuery)) return true\n    if (item.keywords?.some((kw) => kw.toLowerCase().includes(bareQuery))) return true\n    return false\n  })\n}\n","import type {PickerItem} from './types'\n\ntype PickerSection = {\n  /** Category label, or null for items that carry no group. */\n  group: null | string\n  items: readonly PickerItem[]\n}\n\n/**\n * Flattens sections back into the single index space that keyboard navigation,\n * selection, and scroll-into-view all share. Rendering the sections and\n * indexing this array must stay derived from the same `groupPickerItems` call\n * so Enter inserts exactly the highlighted row.\n */\nexport function flattenSections(sections: readonly PickerSection[]): readonly PickerItem[] {\n  return sections.flatMap((section) => section.items)\n}\n\n/**\n * Partitions items into sections by their `group`, preserving the incoming\n * order within each section and ordering the sections by first appearance.\n *\n * Because the caller feeds rank-ordered items (see derivePickerItems), the\n * first-appearance rule places the section holding the most-used block first,\n * without a separate ordering constant to drift out of sync. Items without a\n * group collapse into a single `group: null` section (e.g. a curated `items`\n * prop), so the flat/ungrouped case stays a no-op reordering.\n */\nexport function groupPickerItems(items: readonly PickerItem[]): PickerSection[] {\n  const order: (null | string)[] = []\n  const byGroup = new Map<null | string, PickerItem[]>()\n  for (const item of items) {\n    const key = item.group ?? null\n    let bucket = byGroup.get(key)\n    if (!bucket) {\n      bucket = []\n      byGroup.set(key, bucket)\n      order.push(key)\n    }\n    bucket.push(item)\n  }\n  return order.map((key) => ({group: key, items: byGroup.get(key)!}))\n}\n","import type {Editor, EditorSelection, EditorSnapshot} from '@portabletext/editor'\nimport {defineBehavior, raise} from '@portabletext/editor/behaviors'\nimport {blockOffsetsToSelection, getTextBlockText, isTextBlock} from '@portabletext/editor/utils'\n\nimport type {PickerMode} from './types'\n\ntype InsertGuardResult = {\n  anchor: EditorSelection\n  block: InsertPickerItemPayload['block']\n  cleanup: EditorSelection\n  placement: 'after' | 'auto'\n}\n\ntype InsertPickerItemPayload = {\n  anchorBlockKey: string\n  block: {_key: string; _type: string} & Record<string, unknown>\n  mode: PickerMode\n  query: string\n}\n\n/**\n * Performs the picker insertion as a single behavior action set so the whole\n * operation is one undo step, and cleans up the typed \"/query\" text with\n * delete.text over exactly that range (never delete.block) so text that\n * already existed in the anchor block can't be destroyed: the caret can sit\n * at offset 0 of a populated block and still open the picker.\n */\nexport function createInsertBehavior() {\n  return defineBehavior<\n    InsertPickerItemPayload,\n    'custom.blockInsertPicker.insert',\n    InsertGuardResult\n  >({\n    actions: [\n      (_, {anchor, block, cleanup, placement}) => [\n        ...(cleanup ? [raise({at: cleanup, type: 'delete.text'})] : []),\n        raise({\n          block,\n          placement,\n          select: 'start',\n          type: 'insert.block',\n          // Pin the insert to the anchor block: the live selection may have\n          // moved (e.g. input arriving during the select-time initial-value\n          // await) and placement resolves relative to `at` when provided.\n          ...(anchor ? {at: anchor} : {}),\n        }),\n      ],\n    ],\n    guard: ({event, snapshot}) => {\n      const {anchorBlockKey, block, mode} = event\n      const anchorBlockExists = snapshot.context.value.some(\n        (candidate) => candidate._key === anchorBlockKey,\n      )\n      const anchor = anchorBlockExists\n        ? blockOffsetsToSelection({\n            offsets: {\n              anchor: {offset: 0, path: [{_key: anchorBlockKey}]},\n              focus: {offset: 0, path: [{_key: anchorBlockKey}]},\n            },\n            snapshot,\n          })\n        : null\n      return {\n        anchor,\n        block,\n        cleanup: resolveQueryCleanup(event, snapshot),\n        placement: mode === 'slash' ? ('auto' as const) : ('after' as const),\n      }\n    },\n    on: 'custom.blockInsertPicker.insert',\n  })\n}\n\nexport function sendInsertPickerItem(editor: Editor, payload: InsertPickerItemPayload): void {\n  editor.send({type: 'custom.blockInsertPicker.insert', ...payload})\n}\n\ntype CleanupQueryPayload = Omit<InsertPickerItemPayload, 'block'>\n\n/**\n * The query-cleanup half of the insert behavior on its own, for `custom`\n * picker actions that don't insert a block: the typed \"/query\" text still\n * leaves the document before the host's `onSelect` runs, under the same\n * only-if-unchanged guard as a real insert.\n */\nexport function createCleanupQueryBehavior() {\n  return defineBehavior<\n    CleanupQueryPayload,\n    'custom.blockInsertPicker.cleanupQuery',\n    NonNullable<EditorSelection>\n  >({\n    actions: [(_, cleanup) => [raise({at: cleanup, type: 'delete.text'})]],\n    guard: ({event, snapshot}) => resolveQueryCleanup(event, snapshot) ?? false,\n    on: 'custom.blockInsertPicker.cleanupQuery',\n  })\n}\n\nexport function sendCleanupQuery(editor: Editor, payload: CleanupQueryPayload): void {\n  editor.send({type: 'custom.blockInsertPicker.cleanupQuery', ...payload})\n}\n\n/**\n * The selection spanning the typed \"/query\" text in the anchor block, when it\n * is safe to delete. Only slash mode leaves query text in the document, and\n * only when the anchor block still starts with the typed query; if it changed\n * underneath us (collaborator edit, uncaptured caret movement) the action is\n * still the user's intent, but nothing may be deleted.\n */\nfunction resolveQueryCleanup(\n  event: {anchorBlockKey: string; mode: PickerMode; query: string},\n  snapshot: EditorSnapshot,\n): EditorSelection {\n  const {anchorBlockKey, mode, query} = event\n  if (mode !== 'slash' || query.length === 0) return null\n  const anchorBlock = snapshot.context.value.find((candidate) => candidate._key === anchorBlockKey)\n  if (\n    !anchorBlock ||\n    !isTextBlock({schema: snapshot.context.schema}, anchorBlock) ||\n    !getTextBlockText(anchorBlock).startsWith(query)\n  ) {\n    return null\n  }\n  return blockOffsetsToSelection({\n    offsets: {\n      anchor: {offset: 0, path: [{_key: anchorBlockKey}]},\n      focus: {offset: query.length, path: [{_key: anchorBlockKey}]},\n    },\n    snapshot,\n  })\n}\n","import type {Editor} from '@portabletext/editor'\n\nimport {sendInsertPickerItem} from './insertBehavior'\nimport type {PickerMode} from './types'\n\ntype InsertContext = {\n  /** The `_type` of the block to insert — an `insertBlock` action's target. */\n  blockType: string\n  mode: PickerMode\n  editor: Editor\n  anchorBlockKey: string\n  query: string\n  keyGenerator: () => string\n  initialValue?: Record<string, unknown>\n  onInsertedKey?: (key: string) => void\n}\n\nexport function insertPickerItem(ctx: InsertContext): void {\n  const blockKey = ctx.keyGenerator()\n  // One custom event; the registered insert behavior performs the query\n  // cleanup and the insertion in a single action set (single undo step).\n  sendInsertPickerItem(ctx.editor, {\n    anchorBlockKey: ctx.anchorBlockKey,\n    block: {\n      // Spread the resolved initial value first so the generated `_key` and\n      // the target `_type` always win: Sanity's initial-value resolver sets\n      // `_type` on object values, and a schema's initialValue could carry\n      // stray meta keys. In this flow the resolved `_type` matches\n      // `ctx.blockType` by construction, but ordering it last keeps the\n      // insert correct even when that assumption doesn't hold.\n      ...ctx.initialValue,\n      _key: blockKey,\n      _type: ctx.blockType,\n    },\n    mode: ctx.mode,\n    query: ctx.query,\n  })\n  ctx.onInsertedKey?.(blockKey)\n}\n","/**\n * Every user-facing string in the picker chrome, centralized so hosts can\n * translate or reword them via the `labels` option (the same pattern\n * `@sanity/insert-menu` uses for its label overrides). Item titles and\n * descriptions are schema/metadata content, not chrome — localize those\n * through `items` or `resolveItems` instead.\n */\nexport type BlockInsertPickerLabels = {\n  /** Popover header; also the listbox aria-label. */\n  title: string\n  /** Empty state; `{query}` is replaced with the typed filter text. */\n  noMatches: string\n  /**\n   * Screen-reader position announcement for the highlighted row; `{index}`\n   * and `{count}` are replaced with the 1-based position and list length.\n   */\n  positionAnnouncement: string\n  /**\n   * Section header for items without a `group`, shown only when grouped\n   * sections are also present.\n   */\n  ungroupedSection: string\n  /** Footer legend verbs. */\n  footerNavigate: string\n  footerInsert: string\n  footerDismiss: string\n  footerAnywhere: string\n  /** Toast title when resolving a block's initial value fails. */\n  insertError: string\n  /**\n   * Toast description when the block the picker was anchored to is deleted\n   * before the insert completes.\n   */\n  insertAnchorRemoved: string\n}\n\nconst DEFAULT_LABELS: BlockInsertPickerLabels = {\n  footerAnywhere: 'Anywhere',\n  footerDismiss: 'Dismiss',\n  footerInsert: 'Insert',\n  footerNavigate: 'Navigate',\n  insertAnchorRemoved: 'The block you were inserting into was removed',\n  insertError: 'Could not insert block',\n  noMatches: 'No matches for \"{query}\"',\n  positionAnnouncement: '{index} of {count}',\n  title: 'Insert block',\n  ungroupedSection: 'Other blocks',\n}\n\nexport function resolveLabels(\n  overrides: Partial<BlockInsertPickerLabels> | undefined,\n): BlockInsertPickerLabels {\n  return overrides ? {...DEFAULT_LABELS, ...overrides} : DEFAULT_LABELS\n}\n\n/** Fills the `{query}` placeholder in the no-matches label. */\nexport function formatNoMatches(labels: BlockInsertPickerLabels, query: string): string {\n  // Function replacement: a query containing replacement patterns (\"$&\")\n  // must land verbatim, not be interpreted by String.replace.\n  return labels.noMatches.replace('{query}', () => query)\n}\n\n/** Fills `{index}`/`{count}` in the screen-reader position announcement. */\nexport function formatPosition(\n  labels: BlockInsertPickerLabels,\n  index: number,\n  count: number,\n): string {\n  return labels.positionAnnouncement\n    .replace('{index}', () => String(index))\n    .replace('{count}', () => String(count))\n}\n","import {type ContextType, useContext, useMemo} from 'react'\nimport {type ObjectSchemaType, useSchema} from 'sanity'\nimport {PortableTextMemberSchemaTypesContext} from 'sanity/_singletons'\n\nimport type {PickerItemsContext} from './types'\n\n/**\n * Resolves the Portable Text array type and its insertable member types from\n * where this plugin renders — inside the PT input's `EditorProvider`.\n *\n * Primary source: Studio's own member-schema context, which the PT input\n * provides above the plugins slot. It carries the containing array type and\n * its non-text-block members as full Studio schema types, so aliased members\n * (`{type: 'image', name: 'photo'}`), inline-declared members, and arrays\n * defined inline on a field all resolve with member-level fidelity and no\n * configuration. Fallback: an explicit `arrayTypeName` looked up in the\n * workspace schema — the escape hatch for environments where the context is\n * unavailable. With neither, callers get `null` and must render nothing\n * (never an empty picker).\n *\n * Together with openBlockOnInsert.ts, this module is one of exactly two\n * importers of `sanity/_singletons` — an internal subpath with no stability\n * guarantee (the context exists since sanity 5.6.0, which the peer range\n * pins). The dependency stays quarantined here so it can be swapped for a\n * public API (an exported `usePortableTextMemberSchemaTypes`, or a\n * `schemaType` on `PortableTextPluginsProps`) in one place.\n */\n\n// The context's value type lives in @portabletext/sanity-bridge, which\n// consumer studios cannot resolve directly (it is sanity's own dependency) —\n// extract it from the context instead of importing the bridge.\ntype MemberSchemaTypes = NonNullable<ContextType<typeof PortableTextMemberSchemaTypesContext>>\n\nexport function usePickerItemsContext(arrayTypeName?: string): PickerItemsContext | null {\n  const memberSchemaTypes: MemberSchemaTypes | null = useContext(\n    PortableTextMemberSchemaTypesContext,\n  )\n  const schema = useSchema()\n\n  return useMemo(() => {\n    if (memberSchemaTypes) {\n      return {\n        memberTypes: memberSchemaTypes.blockObjects,\n        schemaType: memberSchemaTypes.portableText,\n      }\n    }\n    const arrayType = arrayTypeName ? schema.get(arrayTypeName) : undefined\n    if (!arrayType || arrayType.jsonType !== 'array') return null\n    return {\n      memberTypes: arrayType.of.filter(\n        (member): member is ObjectSchemaType =>\n          member.jsonType === 'object' && !isTextBlockMember(member),\n      ),\n      schemaType: arrayType,\n    }\n  }, [arrayTypeName, memberSchemaTypes, schema])\n}\n\n/**\n * Whether a member resolves to the built-in text block: walk the compiled\n * `type` chain to its root and compare the root's name — the same algorithm\n * Studio's schema bridge uses to bucketize `of`. A literal `name === 'block'`\n * check would miss aliased text blocks (`{name: 'myBlock', type: 'block'}`)\n * and wrongly offer them as object inserts.\n */\nfunction isTextBlockMember(memberType: {\n  name: string\n  type?: {name: string; type?: unknown} | undefined\n}): boolean {\n  let current: {name: string; type?: unknown} = memberType\n  while (current.type && typeof current.type === 'object' && 'name' in current.type) {\n    // oxlint-disable-next-line no-unsafe-type-assertion\n    current = current.type as {name: string; type?: unknown}\n  }\n  return current.name === 'block'\n}\n","import {useCallback, useContext, useEffect, useRef} from 'react'\nimport {useFormCallbacks} from 'sanity'\nimport {PortableTextMemberItemsContext} from 'sanity/_singletons'\n\n/**\n * Opens a just-inserted block's editing UI (dialog/popover per the member's\n * config) once its member item mounts. An insert lands synchronously, but the\n * member item only exists on a later render — so callers schedule the key and\n * the effect opens it when it appears.\n *\n * Together with memberSchemaTypes.ts, this module is one of exactly two\n * importers of `sanity/_singletons` in this plugin: the subpath is internal\n * with no stability guarantee, so each dependency stays quarantined where it\n * can be swapped for a public API in one place. Consumers that need to react\n * to inserts without this internal should use the `onInsert` seam on the\n * plugin components instead.\n */\nexport function useOpenBlockOnInsert(): (blockKey: string) => void {\n  const memberItems = useContext(PortableTextMemberItemsContext)\n  const {onPathOpen, onSetPathCollapsed} = useFormCallbacks()\n  const pendingKeyRef = useRef<null | string>(null)\n\n  useEffect(() => {\n    const key = pendingKeyRef.current\n    if (!key) return\n    const item = memberItems.find((m) => m.member.key === key)\n    if (item) {\n      onPathOpen(item.member.item.path)\n      onSetPathCollapsed(item.member.item.path, false)\n      pendingKeyRef.current = null\n    }\n  }, [memberItems, onPathOpen, onSetPathCollapsed])\n\n  // Stable identity: callers hold this in effect dependency arrays, so it must\n  // keep a constant reference — an unstable return would re-run (and re-register\n  // behaviors in) every effect that lists it, on every render. The empty-dep\n  // `useCallback` states that contract explicitly rather than relying on the\n  // React Compiler to infer it.\n  return useCallback((blockKey: string) => {\n    pendingKeyRef.current = blockKey\n  }, [])\n}\n","import {defineBehavior, effect, forward} from '@portabletext/editor/behaviors'\nimport type {BehaviorEvent, BehaviorGuard} from '@portabletext/editor/behaviors'\nimport {\n  getBlockTextBefore,\n  getFirstBlock,\n  getFocusBlock,\n  getFocusTextBlock,\n  isSelectionCollapsed,\n} from '@portabletext/editor/selectors'\n\nimport type {PickerIntent, PickerState} from './types'\n\ntype GuardResult = {\n  // true = block the native/default editor handling; false = allow it to proceed\n  blockEvent: boolean\n  intent: PickerIntent\n}\n\ntype PickerBehaviorRefs = {\n  onIntent: (intent: PickerIntent) => void\n  getState: () => PickerState\n  /**\n   * Whether Cmd/Ctrl+/ may open the picker. Read per keystroke (not captured\n   * at registration) so the host toggling `shortcut` doesn't force a\n   * re-registration, which would re-sort the editor's behavior chain.\n   */\n  isShortcutEnabled: () => boolean\n}\n\nexport function createPickerBehavior({getState, isShortcutEnabled, onIntent}: PickerBehaviorRefs) {\n  const guard: BehaviorGuard<BehaviorEvent, GuardResult> = ({event, snapshot}) => {\n    const state = getState()\n\n    // Picker is closed — only the two open triggers can fire.\n    if (state.mode === 'closed') {\n      if (event.type === 'insert.text' && event.text === '/') {\n        const focus = getFocusTextBlock(snapshot)\n        if (!focus || !isSelectionCollapsed(snapshot) || getBlockTextBefore(snapshot) !== '') {\n          return false\n        }\n        return {\n          blockEvent: false,\n          intent: {\n            anchorBlockKey: focus.node._key,\n            mode: 'slash',\n            query: '/',\n            type: 'open',\n          } satisfies PickerIntent,\n        }\n      }\n      if (\n        event.type === 'keyboard.keydown' &&\n        event.originEvent.key === '/' &&\n        (event.originEvent.metaKey || event.originEvent.ctrlKey) &&\n        isShortcutEnabled()\n      ) {\n        // For the shortcut mode, anchor to the focused block whether it is a\n        // text block or a block object (image, callout); fall back to the\n        // first block only when there is no selection at all (e.g. when\n        // triggered via a toolbar button before the editor is DOM-focused).\n        const focus = getFocusBlock(snapshot)\n        const fallback = getFirstBlock(snapshot)\n        const anchorBlock = focus ?? fallback\n        if (!anchorBlock) return false\n        return {\n          blockEvent: true,\n          intent: {\n            anchorBlockKey: anchorBlock.node._key,\n            mode: 'shortcut',\n            query: '',\n            type: 'open',\n          } satisfies PickerIntent,\n        }\n      }\n      return false\n    }\n\n    // Picker is open — capture editing/navigation events.\n    if (event.type === 'insert.text') {\n      if (state.mode === 'slash') {\n        if (event.text === ' ') {\n          // Space while open: close picker, let the space insert proceed.\n          return {blockEvent: false, intent: {type: 'close'}}\n        }\n        // Character typed while in slash mode: update query; let the editor\n        // insert the character into the document as well.\n        return {\n          blockEvent: false,\n          intent: {query: state.query + event.text, type: 'updateQuery'},\n        }\n      }\n      // Shortcut-mode type-to-filter: the query is picker-only state that\n      // never entered the document, so capture the character (spaces\n      // included — titles contain them) and block the insertion.\n      return {\n        blockEvent: true,\n        intent: {query: state.query + event.text, type: 'updateQuery'},\n      }\n    }\n\n    if (event.type === 'delete.backward') {\n      if (state.mode === 'shortcut') {\n        // Backspace edits the picker-only query, never the document.\n        if (state.query.length === 0) {\n          return {blockEvent: true, intent: {type: 'close'}}\n        }\n        return {\n          blockEvent: true,\n          intent: {\n            // Word/line deletes clear the whole query rather than desyncing.\n            query: event.unit === 'character' ? state.query.slice(0, -1) : '',\n            type: 'updateQuery',\n          },\n        }\n      }\n      // Slash mode: the deletion proceeds in the document, so shrink the\n      // query in sync. Deleting the opening \"/\" itself closes, and word/line\n      // deletes can outrun the query — close and let them proceed.\n      if (event.unit === 'character' && state.query.length > 1) {\n        return {\n          blockEvent: false,\n          intent: {query: state.query.slice(0, -1), type: 'updateQuery'},\n        }\n      }\n      return {blockEvent: false, intent: {type: 'close'}}\n    }\n\n    if (event.type === 'delete.forward') {\n      // Forward delete edits content ahead of the caret, not the query;\n      // close and let the deletion proceed in the editor normally.\n      return {blockEvent: false, intent: {type: 'close'}}\n    }\n\n    if (event.type === 'keyboard.keydown') {\n      const key = event.originEvent.key\n      if (key === 'ArrowDown') {\n        return {blockEvent: true, intent: {delta: 1, type: 'navigate'}}\n      }\n      if (key === 'ArrowUp') {\n        return {blockEvent: true, intent: {delta: -1, type: 'navigate'}}\n      }\n      if (key === 'Enter') {\n        return {blockEvent: true, intent: {type: 'select'}}\n      }\n      if (key === 'Escape') {\n        return {blockEvent: true, intent: {type: 'close'}}\n      }\n      if (\n        key === 'ArrowLeft' ||\n        key === 'ArrowRight' ||\n        key === 'Home' ||\n        key === 'End' ||\n        key === 'PageUp' ||\n        key === 'PageDown'\n      ) {\n        // The caret is moving off the typed query; close and let the caret\n        // move normally so the picker's query can't desync from the document.\n        return {blockEvent: false, intent: {type: 'close'}}\n      }\n    }\n\n    return false\n  }\n\n  return defineBehavior({\n    actions: [\n      (payload, guardResponse) => {\n        // Actions only run when the guard returned a value, so guardResponse\n        // is the GuardResult the guard produced.\n        const {blockEvent, intent} = guardResponse\n        const sideEffect = effect(() => onIntent(intent))\n        if (blockEvent) {\n          // Stopping propagation: only run the side effect, no forward.\n          return [sideEffect]\n        }\n        // Non-blocking: run side effect and forward the original event so\n        // PTE's default handling still executes.\n        return [sideEffect, forward(payload.event)]\n      },\n    ],\n    guard,\n    on: '*',\n  })\n}\n","import type {PickerIntent, PickerState} from './types'\n\nexport function pickerReducer(state: PickerState, intent: PickerIntent): PickerState {\n  switch (intent.type) {\n    case 'close':\n    case 'select':\n      return {mode: 'closed'}\n    case 'navigate':\n      if (state.mode === 'closed') return state\n      return {\n        ...state,\n        highlightedIndex: state.highlightedIndex + intent.delta,\n      }\n    case 'open':\n      if (state.mode !== 'closed') return state\n      return {\n        anchorBlockKey: intent.anchorBlockKey,\n        highlightedIndex: 0,\n        mode: intent.mode,\n        query: intent.query,\n      }\n    case 'setHighlightedIndex':\n      if (state.mode === 'closed') return state\n      // Like `navigate`, the reducer does not clamp — the caller (which knows\n      // the filtered list length) is responsible for staying in range.\n      return {...state, highlightedIndex: intent.index}\n    case 'updateQuery':\n      if (state.mode === 'closed') return state\n      return {...state, highlightedIndex: 0, query: intent.query}\n    default: {\n      // All intents are handled above; this arm satisfies consistent-return\n      // while keeping the omission of a future variant a compile error.\n      const unhandled: never = intent\n      return unhandled\n    }\n  }\n}\n","import {effect, raise} from '@portabletext/editor/behaviors'\nimport {blockOffsetsToSelection} from '@portabletext/editor/utils'\nimport {defineInputRule, type InputRule} from '@portabletext/plugin-input-rule'\n\n/**\n * Generic machinery for markdown-style input rules that replace typed text\n * with an inserted object block, complementing the slash/⌘+/ picker with a\n * keyboard-only path that mirrors what writers already type in markdown.\n *\n * The rules run through `@portabletext/plugin-input-rule` (see\n * `markdownInputRules.tsx`), which applies the delete + insert as a single\n * behavior action set — so each transform is one undo step.\n *\n * Block values are built synchronously via each config's `buildValue` rather\n * than resolved from the schema's async initial values: the insert has to\n * happen inside the rule's action set for that single-undo guarantee to hold,\n * so anything the writer would otherwise have to fill in (language, filename,\n * callout type) is seeded from the host's rule config.\n */\n\nexport type KeyGenerator = () => string\n\n/**\n * One markdown input rule: when `pattern` matches the block text, the match\n * is deleted and a block of `blockType` is inserted in its place, carrying\n * the fields `buildValue` returns. `buildValue` must stay synchronous so the\n * delete + insert land in one action set (one undo step).\n */\nexport type MarkdownInputRuleConfig = {\n  pattern: RegExp\n  blockType: string\n  buildValue: (context: {matchText: string; keyGenerator: KeyGenerator}) => Record<string, unknown>\n}\n\ntype BuildRulesDeps = {\n  keyGenerator: KeyGenerator\n  /** Called with the inserted block so the caller can open it for editing. */\n  onInserted: (block: InsertableBlock) => void\n}\n\ntype InsertableBlock = {_key: string; _type: string} & Record<string, unknown>\n\n/**\n * Builds InputRules for the configs whose block type the host array actually\n * allows, so a rule can't insert a block the field would reject.\n */\nexport function createMarkdownInputRules({\n  allowedBlockTypes,\n  keyGenerator,\n  onInserted,\n  rules,\n}: BuildRulesDeps & {\n  allowedBlockTypes: ReadonlySet<string>\n  rules: readonly MarkdownInputRuleConfig[]\n}): InputRule[] {\n  return rules\n    .filter((config) => allowedBlockTypes.has(config.blockType))\n    .map((config) => createInsertRule(config, keyGenerator, onInserted))\n}\n\n// The plugin matches its regex against the block text AFTER the pending\n// insertion. The trailing \"\\s\" is the space the writer types to commit the\n// fence/quote; it is part of the match and gets deleted along with it.\nexport const CODE_FENCE_PATTERN = /^`{3}\\S*\\s$/\nexport const BLOCKQUOTE_PATTERN = /^>\\s$/\n\n/**\n * A row of a code-fence language table: the stored `value`, the markdown\n * fence tokens that should resolve to it, and an optional tab filename.\n */\nexport type LanguageEntry = {\n  value: string\n  aliases?: readonly string[]\n  filename?: string\n}\n\n/** Sugar: a blockquote rule (\"> \" at the start of a block) for `blockType`. */\nexport function blockquoteRule(options: {\n  blockType: string\n  createValue?: (context: {keyGenerator: KeyGenerator}) => Record<string, unknown>\n}): MarkdownInputRuleConfig {\n  return {\n    blockType: options.blockType,\n    buildValue: ({keyGenerator}) => options.createValue?.({keyGenerator}) ?? {},\n    pattern: BLOCKQUOTE_PATTERN,\n  }\n}\n\n/**\n * Sugar: a code-fence rule (\"```lang␣\") for `blockType`. The language table\n * resolves fence tokens (aliases included) to the values the block's language\n * selector stores, plus an optional filename; tokens outside the table pass\n * through as typed so nothing the writer means is lost. `createValue` turns\n * the resolved language and filename into the block's fields.\n */\nexport function codeFenceRule(options: {\n  blockType: string\n  languages?: readonly LanguageEntry[]\n  defaultLanguage?: string\n  createValue: (context: {\n    filename: string | undefined\n    keyGenerator: KeyGenerator\n    language: string | undefined\n  }) => Record<string, unknown>\n}): MarkdownInputRuleConfig {\n  const languages = options.languages ?? []\n  return {\n    blockType: options.blockType,\n    buildValue: ({keyGenerator, matchText}) => {\n      const language = normalizeFenceLanguage(\n        fenceLanguageFromMatch(matchText),\n        languages,\n        options.defaultLanguage,\n      )\n      const filename = language\n        ? languages.find((entry) => entry.value === language)?.filename\n        : undefined\n      return options.createValue({filename, keyGenerator, language})\n    },\n    pattern: CODE_FENCE_PATTERN,\n  }\n}\n\n/** Strips the leading \"```\" fence and surrounding whitespace from a match. */\nexport function fenceLanguageFromMatch(matchText: string): string {\n  return matchText.replace(/^`{3}/, '').trim()\n}\n\n/**\n * Resolves a typed fence token against a language table: a canonical value,\n * an alias (`py`→python, `yml`→yaml), or — for anything the table doesn't\n * know — the token as typed. An empty token yields `defaultLanguage`.\n */\nexport function normalizeFenceLanguage(\n  raw: string,\n  languages: readonly LanguageEntry[],\n  defaultLanguage?: string,\n): string | undefined {\n  const token = raw.trim()\n  const lower = token.toLowerCase()\n  if (!lower) return defaultLanguage\n  // Match case-insensitively on both sides so a table with mixed-case values\n  // or aliases still resolves (and yields its canonical `value`, casing\n  // preserved) rather than falling through to the typed token.\n  for (const {aliases, value} of languages) {\n    if (value.toLowerCase() === lower || aliases?.some((alias) => alias.toLowerCase() === lower))\n      return value\n  }\n  // Unknown token: pass it through as typed (case preserved) per the contract\n  // above — not the lowercased form used for matching.\n  return token\n}\n\nfunction createInsertRule(\n  config: MarkdownInputRuleConfig,\n  keyGenerator: KeyGenerator,\n  onInserted: (block: InsertableBlock) => void,\n): InputRule {\n  return defineInputRule({\n    actions: [\n      ({event, snapshot}) => {\n        const match = event.matches[0]\n        if (!match) return []\n        const block: InsertableBlock = {\n          // Spread the host-built fields first so the generated `_key` and the\n          // resolved `_type` always win (mirrors insertPickerItem): a stray\n          // `_key`/`_type` from buildValue can't hijack the block identity.\n          ...config.buildValue({keyGenerator, matchText: match.text}),\n          _key: keyGenerator(),\n          _type: config.blockType,\n        }\n        // `match.selection` is clamped to the text that existed *before* the\n        // triggering space, so it stops short of that space and would leave it\n        // orphaned as a stray paragraph next to the inserted block.\n        // `match.targetOffsets` spans the full match (space included); convert\n        // it to a selection so the whole fence/quote is removed cleanly.\n        const at =\n          blockOffsetsToSelection({\n            offsets: {\n              anchor: match.targetOffsets.anchor,\n              focus: match.targetOffsets.focus,\n            },\n            snapshot,\n          }) ?? match.selection\n        return [\n          // Remove the typed fence/quote text, then insert the block in its\n          // place. Both raises land in one action set (one undo step).\n          raise({at, type: 'delete.text'}),\n          raise({\n            block,\n            placement: 'auto',\n            select: 'start',\n            type: 'insert.block',\n          }),\n          effect(() => onInserted(block)),\n        ]\n      },\n    ],\n    on: config.pattern,\n  })\n}\n","import {typeNameChain} from './deriveItems'\nimport {codeFenceRule, type MarkdownInputRuleConfig} from './inputRules'\nimport type {PickerItem, PickerItemMetadata, PickerItemsContext} from './types'\n\n/**\n * Default triggers and search keywords for block types with fixed, official\n * names: Studio's intrinsic types (`image`, `file`), first-party plugin\n * types (`code`, `table`, `color`, `latex`, `mux.video`), and the Media\n * Library's `sanity.video`. Presets are deliberately presentation-only —\n * they never add items (a type must actually be a member of the array),\n * never set groups (partial grouping would strand unmatched items in an\n * \"Other\" bucket), never affect rank, and always lose to a host's `items`\n * entry for the same type. Opt out entirely with `presets: false`.\n */\nexport const standardBlockPresets: readonly PickerItemMetadata[] = [\n  {keywords: ['photo', 'picture', 'figure', 'media'], trigger: '/image', type: 'image'},\n  {keywords: ['attachment', 'download', 'document'], trigger: '/file', type: 'file'},\n  {keywords: ['snippet', 'syntax', 'fence', 'pre'], trigger: '/code', type: 'code'},\n  {keywords: ['grid', 'rows', 'columns', 'spreadsheet'], trigger: '/table', type: 'table'},\n  {keywords: ['swatch', 'palette'], trigger: '/color', type: 'color'},\n  {keywords: ['formula', 'equation', 'math', 'tex', 'katex'], trigger: '/latex', type: 'latex'},\n  {keywords: ['video', 'player', 'mux'], trigger: '/video', type: 'mux.video'},\n  {keywords: ['video', 'player', 'media'], trigger: '/video', type: 'sanity.video'},\n]\n\n/**\n * Opt-in input rules for well-known block types — spread into `inputRules`\n * (`inputRules: [...wellKnownInputRules]`) rather than applied by default.\n * Today: a code fence for `@sanity/code-input`'s `code` type that stores the\n * typed fence token as the language. Like all rules, each resolves against\n * the array's members by name or resolved type chain (so an aliased\n * `{type: 'code', name: 'snippet'}` member still gets the fence, inserted\n * with the member's `_type`) and is ignored when nothing matches.\n */\nexport const wellKnownInputRules: readonly MarkdownInputRuleConfig[] = [\n  codeFenceRule({\n    blockType: 'code',\n    createValue: ({language}) => (language ? {language} : {}),\n  }),\n]\n\n/**\n * Fills preset triggers and keywords into derived items that don't already\n * have them, matching presets against each member's resolved type chain so\n * `{type: 'image', name: 'photo'}` still gets the image preset. Host `items`\n * metadata has already been folded in by derivePickerItems, so anything it\n * set wins by construction.\n */\nexport function applyPresetMetadata(\n  items: readonly PickerItem[],\n  context: PickerItemsContext,\n  presets: readonly PickerItemMetadata[] = standardBlockPresets,\n): PickerItem[] {\n  const presetByType = new Map(presets.map((preset) => [preset.type, preset]))\n  return items.map((item) => {\n    if (item.action.type !== 'insertBlock') return item\n    if (item.trigger !== undefined && item.keywords !== undefined) return item\n    const blockType = item.action.blockType\n    const memberType = context.memberTypes.find((candidate) => candidate.name === blockType)\n    if (!memberType) return item\n    const preset = typeNameChain(memberType)\n      .map((name) => presetByType.get(name))\n      .find(Boolean)\n    if (!preset) return item\n    return {\n      ...item,\n      keywords: item.keywords ?? preset.keywords,\n      trigger: item.trigger ?? preset.trigger,\n    }\n  })\n}\n","import {BlockElementIcon} from '@sanity/icons/BlockElement'\nimport type {ComponentType} from 'react'\n\nimport type {PickerItem} from './types'\n\ntype ItemPresentation = {\n  title: string\n  icon: ComponentType\n  description: string | undefined\n}\n\ntype SchemaTypeLike = {\n  name: string\n  title?: string\n  description?: string\n  icon?: ComponentType\n  type?: SchemaTypeLike\n  /** Reference types carry their targets here; core reads `to[0].icon`. */\n  to?: ReadonlyArray<{icon?: ComponentType}>\n}\n\n/**\n * Resolves what a picker row shows for an item, following the same fallback\n * chains Studio's built-in insert menu uses: icon from the member type, its\n * parent type, a reference target, then the generic block icon; title from\n * the member type or its capitalized name. The curated description (from\n * `items` metadata) wins over the schema type's own — curation is the more\n * specific intent.\n */\nexport function resolveItemPresentation(\n  item: PickerItem,\n  schemaType: SchemaTypeLike | undefined,\n): ItemPresentation {\n  if (!schemaType) {\n    return {\n      description: item.description,\n      icon: item.icon ?? BlockElementIcon,\n      title: item.title || (item.action.type === 'insertBlock' ? item.action.blockType : item.id),\n    }\n  }\n  return {\n    description: item.description ?? schemaType.description,\n    icon: schemaType.icon ?? schemaType.type?.icon ?? schemaType.to?.[0]?.icon ?? BlockElementIcon,\n    title: schemaType.title ?? upperFirst(schemaType.name),\n  }\n}\n\n// Matches core's lodash `upperFirst`: capitalize the first character, leave\n// the rest untouched (`codeBlock` -> `CodeBlock`, not `Codeblock`).\nfunction upperFirst(value: string): string {\n  return value.charAt(0).toUpperCase() + value.slice(1)\n}\n","import {useEditor} from '@portabletext/editor'\nimport {Box, Card, Flex, Hotkeys, Popover, Stack, Text, useToast} from '@sanity/ui'\nimport type {CSSProperties} from 'react'\nimport {useEffect, useId, useLayoutEffect, useMemo, useReducer, useRef, useState} from 'react'\nimport {useResolveInitialValueForType, useSchema} from 'sanity'\nimport type {SchemaType} from 'sanity'\n\nimport {derivePickerItems, unknownMetadataTypes} from './deriveItems'\nimport {filterPickerItems} from './filterItems'\nimport {flattenSections, groupPickerItems} from './groupItems'\nimport {createCleanupQueryBehavior, createInsertBehavior, sendCleanupQuery} from './insertBehavior'\nimport {insertPickerItem} from './insertPickerItem'\nimport {\n  type BlockInsertPickerLabels,\n  formatNoMatches,\n  formatPosition,\n  resolveLabels,\n} from './labels'\nimport {usePickerItemsContext} from './memberSchemaTypes'\nimport {useOpenBlockOnInsert} from './openBlockOnInsert'\nimport {createPickerBehavior} from './pickerBehavior'\nimport {pickerReducer} from './pickerReducer'\nimport {applyPresetMetadata} from './presets'\nimport {resolveItemPresentation} from './resolveItemPresentation'\nimport type {\n  PickerInsertEvent,\n  PickerIntent,\n  PickerItem,\n  PickerItemMetadata,\n  PickerItemsContext,\n  PickerItemsResolver,\n  PickerState,\n} from './types'\n\nexport type BlockInsertPickerProps = {\n  /**\n   * Per-member curation (trigger, keywords, group, description, badge,\n   * hidden, openOnInsert) merged into the items derived from the array's\n   * members; array order is the rank. Members without an entry still get\n   * items, in schema order.\n   */\n  items?: readonly PickerItemMetadata[]\n  /**\n   * Escape hatch: names the portable-text array type to resolve items from\n   * when Studio's member-schema context is unavailable. With the context\n   * present (any supported sanity version) this is ignored — the containing\n   * array and its members are detected automatically.\n   */\n  arrayTypeName?: string\n  /**\n   * Programmatic seam over the derived-and-curated item list: reorder,\n   * remove, relabel, or append items (including `custom`-action items).\n   */\n  resolveItems?: PickerItemsResolver\n  /**\n   * Replaces the built-in matching (see filterPickerItems). Receives the\n   * bare query in both modes — the slash-mode \"/\" prefix is stripped.\n   */\n  filter?: (items: readonly PickerItem[], query: string) => readonly PickerItem[]\n  /** Overrides for the picker chrome's user-facing strings. */\n  labels?: Partial<BlockInsertPickerLabels>\n  /** Notified after each successful insert, alongside open-on-insert. */\n  onInsert?: (event: PickerInsertEvent) => void\n  /**\n   * Whether an inserted block opens for editing (default true). Items can\n   * override per member via their metadata's `openOnInsert`.\n   */\n  openOnInsert?: boolean\n  /** Whether Cmd/Ctrl+/ opens the picker (default true). */\n  shortcut?: boolean\n  /**\n   * Whether well-known block types (image, file, code, table, ...) get\n   * default triggers and keywords when the host's `items` doesn't cover\n   * them (default true). See standardBlockPresets.\n   */\n  presets?: boolean\n}\n\nexport function BlockInsertPicker({\n  arrayTypeName,\n  filter,\n  items,\n  labels: labelOverrides,\n  onInsert,\n  openOnInsert = true,\n  presets = true,\n  resolveItems,\n  shortcut = true,\n}: BlockInsertPickerProps) {\n  const editor = useEditor()\n  const openBlockOnInsert = useOpenBlockOnInsert()\n  const itemsContext = usePickerItemsContext(arrayTypeName)\n  const schema = useSchema()\n  const resolveInitialValueForType = useResolveInitialValueForType()\n  const toast = useToast()\n  const labels = useMemo(() => resolveLabels(labelOverrides), [labelOverrides])\n  // Instance-scoped so ARIA option ids stay unique when several PTE fields\n  // (each with their own picker) mount on the same document.\n  const instanceId = useId()\n  const listboxId = `${instanceId}-listbox`\n  const optionId = (id: string) => `${instanceId}-option-${id}`\n\n  // Items derive from the array's member types (via Studio's member-schema\n  // context, or the arrayTypeName fallback), curated by the metadata in\n  // `items` and decorated by presets. Titles and icons are then enriched\n  // ONCE from the member type — not the global type of the same name — so\n  // member-level config wins: a member that redefines a core type's name\n  // shows its own icon and title rather than the global type's. Enriching\n  // before filtering keeps query matching aligned with what the popover\n  // displays, and `resolveItems` runs last over the fully-presented list so\n  // hosts relabel or append against what would actually render.\n  const pickerItems = useMemo(() => {\n    if (!itemsContext) return []\n    const derived = presets\n      ? applyPresetMetadata(derivePickerItems(itemsContext, items), itemsContext)\n      : derivePickerItems(itemsContext, items)\n    const presented = derived.map((item) => {\n      if (item.action.type !== 'insertBlock') return item\n      const schemaType = memberTypeFor(itemsContext, schema, item.action.blockType)\n      const presentation = resolveItemPresentation(item, schemaType)\n      // The derived items are fresh objects owned by this memo, so in-place\n      // assignment is safe (and satisfies oxc's no-map-spread).\n      return Object.assign(item, {\n        description: presentation.description,\n        icon: presentation.icon,\n        title: presentation.title,\n      })\n    })\n    return resolveItems ? [...resolveItems(presented, itemsContext)] : presented\n  }, [items, itemsContext, presets, resolveItems, schema])\n\n  const hasItems = pickerItems.length > 0\n\n  // Dev-mode configuration diagnostics, once per mount per category: a\n  // silent picker (no context, or nothing derivable) and typo'd metadata\n  // keys are the two misconfigurations schema-derived items can't surface\n  // on their own.\n  const warnedRef = useRef<{context?: boolean; empty?: boolean; unknown?: boolean}>({})\n  useEffect(() => {\n    if (process.env['NODE_ENV'] === 'production') return\n    const warned = warnedRef.current\n    if (!itemsContext && !warned.context) {\n      warned.context = true\n      console.warn(\n        '[@sanity/block-insert-picker] No Portable Text member schema context found and no ' +\n          '`arrayTypeName` resolved to an array type — the picker is disabled for this field.',\n      )\n      return\n    }\n    if (itemsContext && items && !warned.unknown) {\n      const unknown = unknownMetadataTypes(itemsContext, items)\n      if (unknown.length > 0) {\n        warned.unknown = true\n        console.warn(\n          `[@sanity/block-insert-picker] \\`items\\` metadata references types that are not ` +\n            `members of this array: ${unknown.join(', ')}`,\n        )\n      }\n    }\n    if (itemsContext && !hasItems && !warned.empty) {\n      warned.empty = true\n      console.warn(\n        '[@sanity/block-insert-picker] No insertable items: the array has no non-text-block ' +\n          'members (and `resolveItems` added none) — the picker is disabled for this field.',\n      )\n    }\n  }, [hasItems, items, itemsContext])\n\n  const [state, dispatch] = useReducer(pickerReducer, {mode: 'closed'})\n\n  // stateRef gives behavior callbacks synchronous access to the latest state\n  // without needing to re-register the behavior on every state change.\n  // useLayoutEffect (vs useEffect) ensures the ref is in sync before paint,\n  // closing a stale-read window for chained behavior events within a tick.\n  const stateRef = useRef<PickerState>(state)\n  useLayoutEffect(() => {\n    stateRef.current = state\n  })\n\n  // The shortcut flag is read through a ref for the same reason: the guard\n  // consults it per keystroke, so toggling it must not re-register (and\n  // re-sort) the behavior chain.\n  const shortcutRef = useRef(shortcut)\n  useLayoutEffect(() => {\n    shortcutRef.current = shortcut\n  })\n\n  const open = state.mode !== 'closed'\n  const query = open ? state.query : ''\n  const mode = open ? state.mode : null\n\n  const filterItems = filter ?? filterPickerItems\n  // The filter seam receives the query without the slash-mode \"/\" prefix, so\n  // a custom `filter` sees the same bare text in both modes. The raw query\n  // keeps driving the empty-state label, the shortcut echo, and onInsert.\n  const filterQuery = mode === 'slash' ? bareQuery(query) : query\n\n  // Sections drive the rendered layout (group headers); `filtered` is the same\n  // items flattened into the single index space navigation and selection share.\n  const sections = useMemo(\n    () => groupPickerItems(filterItems(pickerItems, filterQuery)),\n    [filterItems, filterQuery, pickerItems],\n  )\n  const filtered = useMemo(() => flattenSections(sections), [sections])\n  // Rows resolve their flat index positionally (section offset + row index),\n  // never by item id: a resolveItems-appended item may reuse a derived id,\n  // and an id-keyed map would point both rows at one index.\n  const sectionOffsets = useMemo(() => {\n    const offsets: number[] = []\n    let total = 0\n    for (const section of sections) {\n      offsets.push(total)\n      total += section.items.length\n    }\n    return offsets\n  }, [sections])\n  // A lone section carries no useful category label (e.g. a curated `items`\n  // prop, or a filter that matched a single group) — skip the header chrome.\n  const showGroupHeaders = sections.length > 1\n\n  // Guards the async select path: a second select arriving while a slow\n  // initial-value resolution is in flight must not double-insert.\n  const insertInFlightRef = useRef(false)\n\n  // Plain functions below (no useCallback): the React Compiler memoizes\n  // them, and its lint rule rejects hand-written dependency arrays here.\n  // Core selection logic: given a resolved item index into the filtered list for\n  // `current` state, perform the insertion. Extracted so both keyboard-Enter\n  // (via handleIntent) and mouse-click (via selectItemAtIndex) share the same\n  // path without reading a potentially-stale highlightedIndex from stateRef.\n  // The initial value resolves at select time (mirroring Studio's own toolbar\n  // handleInsertBlock flow) so the first select in a session can't race an\n  // eager cache, and resolution errors surface instead of being swallowed.\n  const insertItemAtIndex = async (\n    current: Exclude<PickerState, {mode: 'closed'}>,\n    idx: number,\n  ) => {\n    if (insertInFlightRef.current) {\n      // A prior select is still resolving; bail to avoid a double-insert. Still\n      // close, because the user may have reopened the picker mid-flight and a\n      // stuck-open menu that swallows this Enter looks broken.\n      dispatch({type: 'close'})\n      return\n    }\n    insertInFlightRef.current = true\n    try {\n      // Index into the grouped display order (not the raw rank-flat order)\n      // so the row the user sees highlighted is the one that gets inserted.\n      const visible = flattenSections(\n        groupPickerItems(\n          filterItems(\n            pickerItems,\n            current.mode === 'slash' ? bareQuery(current.query) : current.query,\n          ),\n        ),\n      )\n      const clamped = Math.max(0, Math.min(visible.length - 1, idx))\n      const chosen = visible[clamped]\n      // Close immediately for a snappy response; the insert continues from\n      // the captured `current` state.\n      dispatch({type: 'close'})\n      if (!chosen) return\n      if (chosen.action.type === 'custom') {\n        // No block to insert: clean up the typed \"/query\" text (slash mode)\n        // and hand the editor to the host's action.\n        sendCleanupQuery(editor, {\n          anchorBlockKey: current.anchorBlockKey,\n          mode: current.mode,\n          query: current.query,\n        })\n        chosen.action.onSelect({\n          closePicker: () => dispatch({type: 'close'}),\n          editor,\n        })\n        return\n      }\n      const blockType = chosen.action.blockType\n      let initialValue: Record<string, unknown> | undefined\n      const schemaType = memberTypeFor(itemsContext, schema, blockType)\n      if (schemaType) {\n        initialValue = (await resolveInitialValueForType(schemaType, {})) ?? undefined\n      }\n      // Re-take the snapshot after the await; the document may have changed.\n      // A null selection is fine: the insert behavior anchors the block via\n      // `at` from anchorBlockKey, so a blur during a slow resolution (or a\n      // shortcut-mode open with no selection) must not abort the insert.\n      const snapshot = editor.getSnapshot()\n      // Confirm the anchor block still exists in the document; if it was\n      // deleted while the picker was open we have nothing to anchor against.\n      const anchorStillExists = snapshot.context.value.some(\n        (b) => b._key === current.anchorBlockKey,\n      )\n      if (!anchorStillExists) {\n        toast.push({\n          closable: true,\n          description: labels.insertAnchorRemoved,\n          status: 'warning',\n          title: labels.insertError,\n        })\n        return\n      }\n      insertPickerItem({\n        anchorBlockKey: current.anchorBlockKey,\n        blockType,\n        editor,\n        initialValue,\n        keyGenerator: () => snapshot.context.keyGenerator(),\n        mode: current.mode,\n        onInsertedKey: (key) => {\n          if (chosen.openOnInsert ?? openOnInsert) openBlockOnInsert(key)\n          onInsert?.({\n            blockKey: key,\n            blockType,\n            mode: current.mode,\n            query: current.query,\n            via: 'picker',\n          })\n        },\n        query: current.query,\n      })\n    } catch (error) {\n      // insertItemAtIndex is fire-and-forget (`void insertItemAtIndex(...)`),\n      // so anything thrown here — initial-value resolution, a host `filter`,\n      // a custom action's onSelect, a host onInsert — would otherwise become\n      // an unhandled rejection with no user feedback.\n      toast.push({\n        closable: true,\n        description: error instanceof Error ? error.message : String(error),\n        status: 'error',\n        title: labels.insertError,\n      })\n    } finally {\n      insertInFlightRef.current = false\n    }\n  }\n\n  // Rows call this from onClick with their own index rather than reading\n  // highlightedIndex: the onMouseMove highlight update for the row under the\n  // cursor may not have flushed yet, so passing idx avoids inserting the\n  // previously-highlighted row.\n  const selectItemAtIndex = (idx: number) => {\n    const current = stateRef.current\n    if (current.mode === 'closed') return\n    void insertItemAtIndex(current, idx)\n  }\n\n  const handleIntent = (intent: PickerIntent) => {\n    if (intent.type === 'navigate') {\n      // The reducer deliberately doesn't clamp (it can't know the filtered\n      // list length), so resolve the move here. Clamping the base index too\n      // self-heals any stored value that has drifted out of range — an\n      // unclamped store makes reversed arrow presses appear \"dead\" while a\n      // hidden out-of-bounds index counts back into range.\n      const current = stateRef.current\n      if (current.mode === 'closed') return\n      const lastIndex = filtered.length - 1\n      const base = Math.max(0, Math.min(lastIndex, current.highlightedIndex))\n      const next = Math.max(0, Math.min(lastIndex, base + intent.delta))\n      dispatch({index: next, type: 'setHighlightedIndex'})\n      return\n    }\n    if (intent.type !== 'select') {\n      dispatch(intent)\n      return\n    }\n    // Resolve the currently-highlighted item against the filtered list.\n    const current = stateRef.current\n    if (current.mode === 'closed') return\n    void insertItemAtIndex(current, current.highlightedIndex)\n  }\n\n  // handleIntentRef lets the behavior always call the latest handleIntent\n  // without needing to re-register the behavior when items changes.\n  // useLayoutEffect for the same stale-read-window reason as stateRef above.\n  const handleIntentRef = useRef<(intent: PickerIntent) => void>(handleIntent)\n  useLayoutEffect(() => {\n    handleIntentRef.current = handleIntent\n  })\n\n  // Register behaviors imperatively so their lifecycle follows this\n  // component's — and only while there is anything to offer: with zero\n  // items the picker must never open (no empty popover, no swallowed \"/\").\n  // The picker behavior watches typing/keys; the insert behavior performs\n  // the atomic cleanup + insert when a custom.blockInsertPicker.insert\n  // event arrives; the cleanup behavior serves `custom` item actions.\n  useEffect(() => {\n    if (!hasItems) return undefined\n    const behavior = createPickerBehavior({\n      getState: () => stateRef.current,\n      isShortcutEnabled: () => shortcutRef.current,\n      onIntent: (intent) => handleIntentRef.current(intent),\n    })\n    const unregisterPicker = editor.registerBehavior({behavior})\n    const unregisterInsert = editor.registerBehavior({\n      behavior: createInsertBehavior(),\n    })\n    const unregisterCleanup = editor.registerBehavior({\n      behavior: createCleanupQueryBehavior(),\n    })\n    return () => {\n      unregisterPicker()\n      unregisterInsert()\n      unregisterCleanup()\n    }\n  }, [editor, hasItems])\n\n  // If the item list empties while the picker is open (a resolveItems change,\n  // a schema hot-reload), the behaviors above unregister — close the popover\n  // rather than leaving a zombie that no behavior can drive.\n  useEffect(() => {\n    if (!hasItems && stateRef.current.mode !== 'closed') dispatch({type: 'close'})\n  }, [hasItems])\n\n  // --- UI ---\n\n  const highlightedIndex = open\n    ? Math.max(0, Math.min(filtered.length - 1, state.highlightedIndex))\n    : 0\n\n  // Announced to screen readers via a polite live region: the focus stays in\n  // the editor, so aria-selected alone would never be read aloud. Recomputing\n  // this on every highlight/filter change lets assistive tech track the list.\n  const highlightedItem = open ? filtered[highlightedIndex] : undefined\n  const announcement = highlightedItem\n    ? [\n        highlightedItem.title,\n        highlightedItem.description,\n        formatPosition(labels, highlightedIndex + 1, filtered.length),\n      ]\n        .filter(Boolean)\n        .join(', ')\n    : ''\n\n  // Capture the caret DOMRect once when the picker opens and hand Popover a\n  // virtual reference element wrapping it. The rect\n  // is intentionally pinned at the opening position — re-capturing on every\n  // `state` change (e.g. each keystroke that updates `query`) would make the\n  // popover drift right as the caret advances through typed characters.\n  // editor.dom is the supported anchoring API; a collapsed caret in an empty\n  // block can yield an all-zero rect in some browsers, so fall back to the\n  // block element's rect in that case.\n  const [cursorRect, setCursorRect] = useState<DOMRect | null>(null)\n\n  useLayoutEffect(() => {\n    if (!open) {\n      // oxlint-disable-next-line react/react-compiler\n      setCursorRect(null)\n      return\n    }\n    const snapshot = editor.getSnapshot()\n    const rect = editor.dom.getSelectionRect(snapshot)\n    if (rect && (rect.x || rect.y || rect.width || rect.height)) {\n      setCursorRect(rect)\n      return\n    }\n    const blockRect = editor.dom.getStartBlockElement(snapshot)?.getBoundingClientRect()\n    if (blockRect) setCursorRect(blockRect)\n  }, [editor, open])\n\n  // Close on any pointerdown outside the popover (clicking into another block\n  // must not leave a zombie picker that later intercepts Enter), and when\n  // focus leaves the editor entirely (e.g. Tab). @sanity/ui's Popover has no\n  // onClickOutside prop — that lives on Menu/Dialog — so listen manually.\n  const popoverContentRef = useRef<HTMLDivElement | null>(null)\n\n  useEffect(() => {\n    if (!open) return undefined\n    const handlePointerDown = (event: PointerEvent) => {\n      const target = event.target\n      if (target instanceof Node && popoverContentRef.current?.contains(target)) return\n      dispatch({type: 'close'})\n    }\n    // getEditorElement is typed as Element, whose addEventListener overload\n    // hands the listener a plain Event; narrow to FocusEvent inside instead\n    // of asserting the element type.\n    const editorElement = editor.dom.getEditorElement()\n    const handleFocusOut = (event: Event) => {\n      const next = event instanceof FocusEvent ? event.relatedTarget : null\n      if (\n        next instanceof Node &&\n        (editorElement?.contains(next) || popoverContentRef.current?.contains(next))\n      )\n        return\n      dispatch({type: 'close'})\n    }\n    document.addEventListener('pointerdown', handlePointerDown, true)\n    editorElement?.addEventListener('focusout', handleFocusOut)\n    return () => {\n      document.removeEventListener('pointerdown', handlePointerDown, true)\n      editorElement?.removeEventListener('focusout', handleFocusOut)\n    }\n  }, [editor, open])\n\n  // Keep the highlighted row visible inside the scrolling list.\n  const highlightedRowRef = useRef<HTMLDivElement | null>(null)\n\n  // Hover may only move the highlight on genuine pointer movement. When\n  // keyboard navigation scrolls the list (scrollIntoView below), rows slide\n  // under a stationary cursor and the browser fires mouseenter — and, in some\n  // engines, a coordinate-identical mousemove — on whichever row lands there.\n  // Honoring those synthetic events hijacks the keyboard highlight back to\n  // wherever the mouse happens to rest. Track the last seen coordinates and\n  // require them to change before hover wins; the first event only seeds.\n  const lastPointerRef = useRef<null | {x: number; y: number}>(null)\n\n  const highlightOnPointerMove = (idx: number, x: number, y: number) => {\n    const last = lastPointerRef.current\n    lastPointerRef.current = {x, y}\n    if (!last || (last.x === x && last.y === y)) return\n    const current = stateRef.current\n    if (current.mode !== 'closed' && idx !== current.highlightedIndex) {\n      dispatch({index: idx, type: 'setHighlightedIndex'})\n    }\n  }\n\n  useEffect(() => {\n    highlightedRowRef.current?.scrollIntoView({block: 'nearest'})\n  }, [highlightedIndex])\n\n  // Stable virtual element derived from the captured rect — keeps Popover\n  // positioning stable even as `state` changes while the picker is open.\n  const cursorElement = useMemo(() => {\n    if (!cursorRect) return null\n    // Popover types referenceElement as HTMLElement, but its positioning\n    // only ever reads getBoundingClientRect — the standard virtual-element\n    // escape hatch for anchoring to a caret rect.\n    // oxlint-disable-next-line no-unsafe-type-assertion\n    return {\n      getBoundingClientRect: () => cursorRect,\n    } as unknown as HTMLElement\n  }, [cursorRect])\n\n  if (!open) return null\n\n  if (filtered.length === 0) {\n    return (\n      <Popover\n        constrainSize\n        content={\n          <Card\n            aria-live=\"polite\"\n            onMouseDown={preventFocusSteal}\n            padding={3}\n            radius={2}\n            ref={popoverContentRef}\n            // Card renders (and refs) a div; an <output> would change the\n            // element type the outside-pointerdown ref relies on.\n            // oxlint-disable-next-line prefer-tag-over-role\n            role=\"status\"\n          >\n            <Text muted size={1}>\n              {formatNoMatches(labels, query)}\n            </Text>\n          </Card>\n        }\n        fallbackPlacements={['top-start']}\n        open\n        placement=\"bottom-start\"\n        portal\n        preventOverflow\n        referenceElement={cursorElement}\n      />\n    )\n  }\n\n  return (\n    <Popover\n      constrainSize\n      content={\n        <Card\n          onMouseDown={preventFocusSteal}\n          padding={1}\n          radius={2}\n          ref={popoverContentRef}\n          style={{\n            display: 'flex',\n            flexDirection: 'column',\n            maxHeight: '100%',\n            minWidth: 300,\n          }}\n        >\n          {/* Focus stays in the editor, so aria-selected on rows is never read\n              aloud on its own. This polite region carries the open state and\n              each highlight change to assistive tech. */}\n          <output aria-live=\"polite\" style={SR_ONLY}>\n            {announcement}\n          </output>\n          <Flex align=\"center\" flex=\"none\" gap={2} padding={2}>\n            <Box flex={1}>\n              <Text\n                muted\n                size={0}\n                style={{letterSpacing: '0.05em', textTransform: 'uppercase'}}\n                weight=\"medium\"\n              >\n                {labels.title}\n              </Text>\n            </Box>\n            {mode === 'shortcut' && query !== '' ? (\n              // Shortcut-mode typing never reaches the document, so echo the\n              // captured query here — otherwise keystrokes appear to vanish.\n              <Text muted size={1} textOverflow=\"ellipsis\">\n                {query}\n              </Text>\n            ) : null}\n          </Flex>\n          <Box\n            aria-label={labels.title}\n            id={listboxId}\n            // A custom ARIA listbox: <select>/<datalist> cannot host rich\n            // rows (icons, descriptions, hotkey chips) or grouped sections.\n            // oxlint-disable-next-line prefer-tag-over-role\n            role=\"listbox\"\n            style={{flex: 1, maxHeight: 320, minHeight: 0, overflowY: 'auto'}}\n          >\n            {sections.map((section, sectionIndex) => {\n              const sectionLabel = section.group ?? labels.ungroupedSection\n              // Key on the raw group (namespaced), not the display label: a\n              // curated group named the same as `ungroupedSection` would\n              // otherwise share a React key with the null-group section.\n              const sectionKey = section.group === null ? 'ungrouped' : `group:${section.group}`\n              const rows = section.items.map((item, rowIndex) => {\n                const idx = (sectionOffsets[sectionIndex] ?? 0) + rowIndex\n                const Icon = item.icon\n                const isHighlighted = idx === highlightedIndex\n                return (\n                  <Card\n                    aria-selected={isHighlighted}\n                    id={optionId(String(idx))}\n                    key={`${item.id}-${idx}`}\n                    onClick={() => selectItemAtIndex(idx)}\n                    onMouseMove={(event) =>\n                      highlightOnPointerMove(idx, event.clientX, event.clientY)\n                    }\n                    padding={2}\n                    radius={1}\n                    ref={isHighlighted ? highlightedRowRef : undefined}\n                    // A native <option> only works inside <select>; these are\n                    // ARIA options in a custom listbox rendered from Cards.\n                    // oxlint-disable-next-line prefer-tag-over-role\n                    role=\"option\"\n                    style={{cursor: 'pointer'}}\n                    // Focusable in principle (never via Tab): DOM focus stays\n                    // in the editor and the live region does the announcing.\n                    tabIndex={-1}\n                    tone={isHighlighted ? 'primary' : 'default'}\n                  >\n                    <Flex align=\"center\" gap={3}>\n                      <Box\n                        style={{\n                          alignItems: 'center',\n                          display: 'flex',\n                          height: 22,\n                          justifyContent: 'center',\n                          width: 22,\n                        }}\n                      >\n                        {Icon ? <Icon /> : null}\n                      </Box>\n                      <Stack flex={1} gap={2}>\n                        <Text size={1} textOverflow=\"ellipsis\">\n                          {item.title}\n                        </Text>\n                        {item.description ? (\n                          <Text muted size={0} textOverflow=\"ellipsis\">\n                            {item.description}\n                          </Text>\n                        ) : null}\n                      </Stack>\n                      {item.badge ? (\n                        <Box flex=\"none\">\n                          <Text muted size={0}>\n                            {item.badge}\n                          </Text>\n                        </Box>\n                      ) : null}\n                      {item.trigger ? (\n                        <Box flex=\"none\">\n                          <Hotkeys fontSize={0} keys={[item.trigger]} />\n                        </Box>\n                      ) : null}\n                    </Flex>\n                  </Card>\n                )\n              })\n              if (!showGroupHeaders) {\n                return (\n                  <Stack key={sectionKey} gap={1}>\n                    {rows}\n                  </Stack>\n                )\n              }\n              return (\n                <Box\n                  aria-label={sectionLabel}\n                  key={sectionKey}\n                  paddingTop={sectionIndex === 0 ? 0 : 2}\n                  // Grouped options inside a listbox: role=\"group\" is the\n                  // valid ARIA structure here; the tags the rule suggests\n                  // (fieldset, address, …) are not permitted in a listbox.\n                  // oxlint-disable-next-line prefer-tag-over-role\n                  role=\"group\"\n                >\n                  <Box paddingBottom={1} paddingTop={2} paddingX={2}>\n                    <Text\n                      muted\n                      size={0}\n                      style={{\n                        letterSpacing: '0.05em',\n                        textTransform: 'uppercase',\n                      }}\n                      weight=\"medium\"\n                    >\n                      {sectionLabel}\n                    </Text>\n                  </Box>\n                  <Stack gap={1}>{rows}</Stack>\n                </Box>\n              )\n            })}\n          </Box>\n          <Card borderTop flex=\"none\" padding={2} radius={0}>\n            <Flex align=\"center\" gap={3} wrap=\"wrap\">\n              <FooterHint keys={['↑', '↓']} label={labels.footerNavigate} />\n              <FooterHint keys={['↵']} label={labels.footerInsert} />\n              <FooterHint keys={['Esc']} label={labels.footerDismiss} />\n              {shortcut ? (\n                <FooterHint keys={[OPEN_MODIFIER, '/']} label={labels.footerAnywhere} />\n              ) : null}\n            </Flex>\n          </Card>\n        </Card>\n      }\n      fallbackPlacements={['top-start']}\n      open\n      placement=\"bottom-start\"\n      portal\n      preventOverflow\n      referenceElement={cursorElement}\n    />\n  )\n}\n\n// A single key legend in the teaching footer: the key chips plus a short verb.\nfunction FooterHint({keys, label}: {keys: string[]; label: string}) {\n  return (\n    <Flex align=\"center\" gap={2}>\n      <Hotkeys fontSize={0} keys={keys} />\n      <Text muted size={0}>\n        {label}\n      </Text>\n    </Flex>\n  )\n}\n\n// Module-level (not a component closure) so useMemo dependency arrays don't\n// need a function that the react-hooks lint flags as changing every render.\n// Member types resolve from the picker's items context first (member-level\n// config wins), then from the global type of the same name — the same\n// fallback the previous arrayTypeName-only lookup used.\nfunction memberTypeFor(\n  itemsContext: PickerItemsContext | null,\n  schema: {get(name: string): SchemaType | undefined},\n  blockType: string,\n): SchemaType | undefined {\n  const member = itemsContext?.memberTypes.find((candidate) => candidate.name === blockType)\n  return member ?? schema.get(blockType)\n}\n\n// Slash-mode queries carry the leading \"/\" the writer typed; the filter seam\n// works on the bare text (see filterQuery above).\nfunction bareQuery(query: string): string {\n  return query.startsWith('/') ? query.slice(1) : query\n}\n\n// Interacting with any popover surface (header, padding, the scroll\n// container's scrollbar) must not steal DOM focus from the editor: the blur\n// would trip the focusout close listener and dismiss the picker mid-use.\nfunction preventFocusSteal(event: {preventDefault: () => void}) {\n  event.preventDefault()\n}\n\n// Visually hidden but present in the accessibility tree — used for the live\n// region so announcements don't disturb the popover layout.\nconst SR_ONLY: CSSProperties = {\n  border: 0,\n  clipPath: 'inset(50%)',\n  height: 1,\n  margin: -1,\n  overflow: 'hidden',\n  padding: 0,\n  position: 'absolute',\n  whiteSpace: 'nowrap',\n  width: 1,\n}\n\n// The Cmd+/ shortcut symbol matches the platform: ⌘ on Apple, Ctrl elsewhere.\n// navigator.platform is deprecated but still the most reliable signal here;\n// fall back to the user agent, then to Ctrl when neither is available.\nconst IS_APPLE_PLATFORM =\n  typeof navigator !== 'undefined' &&\n  /mac|iphone|ipad|ipod/i.test(navigator.platform || navigator.userAgent || '')\nconst OPEN_MODIFIER = IS_APPLE_PLATFORM ? '⌘' : 'Ctrl'\n","import {useEditor} from '@portabletext/editor'\nimport {defineInputRuleBehavior} from '@portabletext/plugin-input-rule'\nimport {useEffect, useLayoutEffect, useMemo, useRef} from 'react'\n\nimport {typeNameChain} from './deriveItems'\nimport {createMarkdownInputRules, type MarkdownInputRuleConfig} from './inputRules'\nimport {usePickerItemsContext} from './memberSchemaTypes'\nimport {useOpenBlockOnInsert} from './openBlockOnInsert'\nimport type {PickerInsertEvent} from './types'\n\nexport type MarkdownInputRulesProps = {\n  /**\n   * Escape hatch: names the portable-text array type when Studio's\n   * member-schema context is unavailable (see BlockInsertPickerProps).\n   * Rules are only enabled for block types the array actually allows.\n   */\n  arrayTypeName?: string\n  /** The markdown transforms to enable (see inputRules.ts). */\n  rules: readonly MarkdownInputRuleConfig[]\n  /** Notified after each successful insert, alongside open-on-insert. */\n  onInsert?: (event: PickerInsertEvent) => void\n  /** Whether an inserted block opens for editing (default true). */\n  openOnInsert?: boolean\n}\n\n/**\n * Mounts markdown input rules on the PTE and opens each inserted block for\n * editing once its member item mounts — the same open-on-insert behavior the\n * picker uses, so a fenced code block lands ready to type into.\n */\nexport function MarkdownInputRules({\n  arrayTypeName,\n  onInsert,\n  openOnInsert = true,\n  rules,\n}: MarkdownInputRulesProps) {\n  const editor = useEditor()\n  const itemsContext = usePickerItemsContext(arrayTypeName)\n  const openBlockOnInsert = useOpenBlockOnInsert()\n\n  // Rules resolve against the array's insertable members with the same\n  // precedence as picker item metadata: a rule's blockType matches a member\n  // by name first, then by any name in the member's resolved type chain — so\n  // wellKnownInputRules' `code` fence also serves `{type: 'code', name:\n  // 'snippet'}`, with the inserted `_type` rewritten to the member name the\n  // array actually accepts. Rules matching nothing are dropped here, which\n  // also keeps `block` itself (and aliased text blocks) unreachable.\n  const resolvedRules = useMemo(() => {\n    const memberTypes = itemsContext?.memberTypes ?? []\n    return rules.flatMap((rule) => {\n      const member =\n        memberTypes.find((candidate) => candidate.name === rule.blockType) ??\n        memberTypes.find((candidate) => typeNameChain(candidate).includes(rule.blockType))\n      if (!member) return []\n      return [rule.blockType === member.name ? rule : {...rule, blockType: member.name}]\n    })\n  }, [itemsContext, rules])\n\n  // The insert callbacks are routed through a ref (same pattern as\n  // BlockInsertPicker's handleIntentRef) so the registration effect below\n  // stays keyed on the rules/schema/editor only: re-registering a behavior\n  // is not free (it tears down and re-sorts the editor's behavior chain, and\n  // moves this behavior after later-registered ones), so a host passing an\n  // inline onInsert must not cause per-render churn.\n  const onInsertedRef = useRef<(block: {_key: string; _type: string}) => void>(() => {})\n  useLayoutEffect(() => {\n    onInsertedRef.current = (block) => {\n      if (openOnInsert) openBlockOnInsert(block._key)\n      onInsert?.({\n        blockKey: block._key,\n        blockType: block._type,\n        via: 'inputRule',\n      })\n    }\n  })\n\n  // Register the input-rule behavior imperatively rather than through the\n  // <InputRulePlugin>\n  // component: the rule closures then live inside an effect and can schedule\n  // the open-on-insert without hitting the React Compiler's \"no refs during\n  // render\" rule. Each transform is still a single undo step (the plugin\n  // applies the delete + insert as one behavior action set).\n  useEffect(() => {\n    const inputRules = createMarkdownInputRules({\n      // resolvedRules are already narrowed to insertable members.\n      allowedBlockTypes: new Set(resolvedRules.map((rule) => rule.blockType)),\n      // The generator is read per insert so keys stay unique across a session.\n      keyGenerator: () => editor.getSnapshot().context.keyGenerator(),\n      onInserted: (block) => onInsertedRef.current(block),\n      rules: resolvedRules,\n    })\n    if (inputRules.length === 0) return undefined\n    return editor.registerBehavior({\n      behavior: defineInputRuleBehavior({rules: inputRules}),\n    })\n  }, [editor, resolvedRules])\n\n  return null\n}\n","import type {ComponentType} from 'react'\nimport type {PortableTextPluginsProps} from 'sanity'\n\nimport {BlockInsertPicker} from './blockInsertPicker'\nimport type {MarkdownInputRuleConfig} from './inputRules'\nimport type {BlockInsertPickerLabels} from './labels'\nimport {MarkdownInputRules} from './markdownInputRules'\nimport type {PickerInsertEvent, PickerItem, PickerItemMetadata, PickerItemsResolver} from './types'\n\nexport interface BlockInsertPickerConfig {\n  /**\n   * Per-member curation (slash trigger, alias keywords, section grouping,\n   * description, badge, visibility, per-item open-on-insert) merged into the\n   * items derived from the array's members; array order is the sort rank.\n   * Members without an entry still get picker items, appended in schema\n   * order. Entries whose `type` matches no member warn in dev mode.\n   */\n  items?: readonly PickerItemMetadata[]\n  /**\n   * Programmatic seam over the derived item list — reorder, remove, relabel,\n   * or append items (including `custom`-action items) — running after schema\n   * derivation, presets, and `items` metadata.\n   */\n  resolveItems?: PickerItemsResolver\n  /**\n   * Markdown-style transforms (for example from the {@link codeFenceRule} and\n   * {@link blockquoteRule} factories) that replace typed text with an\n   * inserted block, as one undo step. Opt-in only; rules targeting block\n   * types the array does not allow are ignored.\n   */\n  inputRules?: readonly MarkdownInputRuleConfig[]\n  /**\n   * Replaces the built-in matching (case-insensitive substring over title,\n   * keywords, and description, plus trigger prefixes). Receives the bare\n   * query in both modes — the slash-mode \"/\" prefix is stripped.\n   */\n  filter?: (items: readonly PickerItem[], query: string) => readonly PickerItem[]\n  /** Overrides for the picker chrome's user-facing strings. */\n  labels?: Partial<BlockInsertPickerLabels>\n  /**\n   * Notified after each successful insert — picker selection or input rule —\n   * alongside the built-in open-for-editing behavior.\n   */\n  onInsert?: (event: PickerInsertEvent) => void\n  /**\n   * Whether an inserted block opens for editing (default true). Items can\n   * override per member via their metadata's `openOnInsert`.\n   */\n  openOnInsert?: boolean\n  /** Whether Cmd/Ctrl+/ opens the picker (default true). */\n  shortcut?: boolean\n  /**\n   * Whether well-known block types (image, file, code, table, ...) get\n   * default triggers and keywords when `items` doesn't cover them\n   * (default true). See {@link standardBlockPresets}.\n   */\n  presets?: boolean\n  /**\n   * Escape hatch: names the portable-text array type to resolve items\n   * against when Studio's member-schema context is unavailable. Normally\n   * unnecessary — the containing array and its members are detected\n   * automatically from where the plugin is mounted.\n   */\n  arrayTypeName?: string\n}\n\n/**\n * Creates the Portable Text editor plugins component for the block-insert\n * picker: a slash-command / Cmd+/ menu of the blocks the host array allows,\n * plus optional markdown input rules. Zero-config is the intended call —\n * items derive from the array the plugin is mounted on. Attach it to the\n * array type's `components.portableText.plugins`:\n *\n * ```ts\n * defineType({\n *   name: 'content',\n *   type: 'array',\n *   of: [{type: 'block'}, {type: 'callout'}],\n *   components: {\n *     portableText: {\n *       plugins: blockInsertPicker(),\n *     },\n *   },\n * })\n * ```\n */\nexport function blockInsertPicker(\n  config: BlockInsertPickerConfig = {},\n): ComponentType<PortableTextPluginsProps> {\n  const {\n    arrayTypeName,\n    filter,\n    inputRules,\n    items,\n    labels,\n    onInsert,\n    openOnInsert,\n    presets,\n    resolveItems,\n    shortcut,\n  } = config\n  return function BlockInsertPickerPlugins(props: PortableTextPluginsProps) {\n    return (\n      <>\n        {props.renderDefault(props)}\n        {inputRules?.length ? (\n          <MarkdownInputRules\n            arrayTypeName={arrayTypeName}\n            onInsert={onInsert}\n            openOnInsert={openOnInsert}\n            rules={inputRules}\n          />\n        ) : null}\n        <BlockInsertPicker\n          arrayTypeName={arrayTypeName}\n          filter={filter}\n          items={items}\n          labels={labels}\n          onInsert={onInsert}\n          openOnInsert={openOnInsert}\n          presets={presets}\n          resolveItems={resolveItems}\n          shortcut={shortcut}\n        />\n      </>\n    )\n  }\n}\n"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"index.js","names":["PickerItem","PickerItemMetadata","PickerItemsContext","typeNameChain","memberType","name","type","names","current","push","undefined","derivePickerItems","context","metadata","memberTypes","map","schemaIndex","chain","nameRank","findIndex","entry","rank","includes","Number","MAX_SAFE_INTEGER","filter","hidden","sort","a","b","action","blockType","const","badge","description","group","id","keywords","openOnInsert","title","trigger","unknownMetadataTypes","known","Set","flatMap","has","PickerItem","filterPickerItems","items","query","queryLower","toLowerCase","bareQuery","startsWith","slice","filter","item","bareTrigger","trigger","replace","title","includes","description","keywords","some","kw","PickerItem","PickerSection","group","items","flattenSections","sections","flatMap","section","groupPickerItems","order","byGroup","Map","item","key","bucket","get","set","push","map","Editor","EditorSelection","EditorSnapshot","defineBehavior","raise","blockOffsetsToSelection","getTextBlockText","isTextBlock","PickerMode","InsertGuardResult","anchor","block","InsertPickerItemPayload","cleanup","placement","anchorBlockKey","_key","_type","Record","mode","query","createInsertBehavior","actions","_","at","type","select","guard","event","snapshot","anchorBlockExists","context","value","some","candidate","offsets","offset","path","focus","resolveQueryCleanup","const","on","sendInsertPickerItem","editor","payload","send","CleanupQueryPayload","Omit","createCleanupQueryBehavior","NonNullable","sendCleanupQuery","length","anchorBlock","find","schema","startsWith","Editor","sendInsertPickerItem","PickerMode","InsertContext","blockType","mode","editor","anchorBlockKey","query","keyGenerator","initialValue","Record","onInsertedKey","key","insertPickerItem","ctx","blockKey","block","_key","_type","BlockInsertPickerLabels","title","noMatches","positionAnnouncement","ungroupedSection","footerNavigate","footerInsert","footerDismiss","footerAnywhere","insertError","insertAnchorRemoved","DEFAULT_LABELS","resolveLabels","overrides","Partial","formatNoMatches","labels","query","replace","formatPosition","index","count","String","ContextType","useContext","useMemo","ObjectSchemaType","useSchema","PortableTextMemberSchemaTypesContext","PickerItemsContext","MemberSchemaTypes","NonNullable","usePickerItemsContext","arrayTypeName","$","_c","memberSchemaTypes","schema","t0","bb0","t1","blockObjects","portableText","memberTypes","schemaType","arrayType","get","undefined","jsonType","of","filter","_temp","member","isTextBlockMember","memberType","name","type","current","useCallback","useContext","useEffect","useRef","useFormCallbacks","PortableTextMemberItemsContext","useOpenBlockOnInsert","$","_c","memberItems","onPathOpen","onSetPathCollapsed","pendingKeyRef","t0","t1","key","current","item","find","m","member","path","t2","Symbol","for","blockKey","defineBehavior","effect","forward","BehaviorEvent","BehaviorGuard","getBlockTextBefore","getFirstBlock","getFocusBlock","getFocusTextBlock","isSelectionCollapsed","PickerIntent","PickerState","GuardResult","blockEvent","intent","PickerBehaviorRefs","onIntent","getState","isShortcutEnabled","createPickerBehavior","guard","event","snapshot","state","mode","type","text","focus","anchorBlockKey","node","_key","query","originEvent","key","metaKey","ctrlKey","fallback","anchorBlock","length","unit","slice","delta","actions","payload","guardResponse","sideEffect","on","PickerIntent","PickerState","pickerReducer","state","intent","type","mode","highlightedIndex","delta","anchorBlockKey","query","index","unhandled","effect","raise","blockOffsetsToSelection","defineInputRule","InputRule","KeyGenerator","MarkdownInputRuleConfig","pattern","RegExp","blockType","buildValue","context","matchText","keyGenerator","Record","BuildRulesDeps","onInserted","block","InsertableBlock","_key","_type","createMarkdownInputRules","allowedBlockTypes","rules","ReadonlySet","filter","config","has","map","createInsertRule","CODE_FENCE_PATTERN","BLOCKQUOTE_PATTERN","LanguageEntry","value","aliases","filename","blockquoteRule","options","createValue","codeFenceRule","languages","defaultLanguage","language","normalizeFenceLanguage","fenceLanguageFromMatch","find","entry","undefined","replace","trim","raw","token","lower","toLowerCase","some","alias","actions","event","snapshot","match","matches","text","at","offsets","anchor","targetOffsets","focus","selection","type","placement","select","on","typeNameChain","codeFenceRule","MarkdownInputRuleConfig","PickerItem","PickerItemMetadata","PickerItemsContext","standardBlockPresets","keywords","trigger","type","wellKnownInputRules","blockType","createValue","language","applyPresetMetadata","items","context","presets","presetByType","Map","map","preset","item","action","undefined","memberType","memberTypes","find","candidate","name","get","Boolean","BlockElementIcon","ComponentType","PickerItem","ItemPresentation","title","icon","description","SchemaTypeLike","name","type","to","ReadonlyArray","resolveItemPresentation","item","schemaType","action","blockType","id","upperFirst","value","charAt","toUpperCase","slice","useEditor","Box","Card","Flex","Hotkeys","Stack","Text","Popover","useToast","CSSProperties","useEffect","useId","useLayoutEffect","useMemo","useReducer","useRef","useState","useResolveInitialValueForType","useSchema","SchemaType","derivePickerItems","unknownMetadataTypes","filterPickerItems","flattenSections","groupPickerItems","createCleanupQueryBehavior","createInsertBehavior","sendCleanupQuery","insertPickerItem","BlockInsertPickerLabels","formatNoMatches","formatPosition","resolveLabels","usePickerItemsContext","useOpenBlockOnInsert","createPickerBehavior","pickerReducer","applyPresetMetadata","resolveItemPresentation","PickerInsertEvent","PickerIntent","PickerItem","PickerItemMetadata","PickerItemsContext","PickerItemsResolver","PickerState","BlockInsertPickerProps","items","arrayTypeName","resolveItems","filter","query","labels","Partial","onInsert","event","openOnInsert","shortcut","presets","BlockInsertPicker","labelOverrides","editor","openBlockOnInsert","itemsContext","schema","resolveInitialValueForType","toast","instanceId","listboxId","optionId","id","pickerItems","derived","presented","map","item","action","type","schemaType","memberTypeFor","blockType","presentation","Object","assign","description","icon","title","hasItems","length","warnedRef","context","empty","unknown","process","env","warned","current","console","warn","join","state","dispatch","mode","stateRef","shortcutRef","open","filterItems","filterQuery","bareQuery","sections","filtered","sectionOffsets","offsets","total","section","push","showGroupHeaders","insertInFlightRef","insertItemAtIndex","Exclude","idx","visible","clamped","Math","max","min","chosen","anchorBlockKey","onSelect","closePicker","initialValue","Record","undefined","snapshot","getSnapshot","anchorStillExists","value","some","b","_key","closable","insertAnchorRemoved","status","insertError","keyGenerator","onInsertedKey","key","blockKey","via","error","Error","message","String","selectItemAtIndex","handleIntent","intent","lastIndex","base","highlightedIndex","next","delta","index","handleIntentRef","behavior","getState","isShortcutEnabled","onIntent","unregisterPicker","registerBehavior","unregisterInsert","unregisterCleanup","highlightedItem","announcement","Boolean","cursorRect","setCursorRect","DOMRect","rect","dom","getSelectionRect","x","y","width","height","blockRect","getStartBlockElement","getBoundingClientRect","popoverContentRef","HTMLDivElement","handlePointerDown","PointerEvent","target","Node","contains","editorElement","getEditorElement","handleFocusOut","Event","FocusEvent","relatedTarget","document","addEventListener","removeEventListener","highlightedRowRef","lastPointerRef","highlightOnPointerMove","last","scrollIntoView","block","cursorElement","HTMLElement","preventFocusSteal","display","flexDirection","maxHeight","minWidth","SR_ONLY","letterSpacing","textTransform","flex","minHeight","overflowY","sectionIndex","sectionLabel","group","ungroupedSection","sectionKey","rows","rowIndex","Icon","isHighlighted","clientX","clientY","cursor","alignItems","justifyContent","badge","trigger","footerNavigate","footerInsert","footerDismiss","OPEN_MODIFIER","footerAnywhere","FooterHint","t0","$","_c","keys","label","t1","t2","t3","get","name","member","memberTypes","find","candidate","startsWith","slice","preventDefault","border","clipPath","margin","overflow","padding","position","whiteSpace","IS_APPLE_PLATFORM","navigator","test","platform","userAgent","useEditor","defineInputRuleBehavior","useEffect","useLayoutEffect","useMemo","useRef","typeNameChain","createMarkdownInputRules","MarkdownInputRuleConfig","usePickerItemsContext","useOpenBlockOnInsert","PickerInsertEvent","MarkdownInputRulesProps","arrayTypeName","rules","onInsert","event","openOnInsert","MarkdownInputRules","t0","$","_c","t1","undefined","editor","itemsContext","openBlockOnInsert","t2","memberTypes","t3","t4","rule","member","find","candidate_0","candidate","name","blockType","includes","flatMap","resolvedRules","onInsertedRef","_temp","current","block","_key","blockKey","_type","via","t5","t6","inputRules","allowedBlockTypes","Set","map","_temp2","keyGenerator","getSnapshot","context","onInserted","block_0","length","registerBehavior","behavior","rule_0","ComponentType","PortableTextPluginsProps","BlockInsertPicker","MarkdownInputRuleConfig","BlockInsertPickerLabels","MarkdownInputRules","PickerInsertEvent","PickerItem","PickerItemMetadata","PickerItemsResolver","BlockInsertPickerConfig","items","resolveItems","inputRules","filter","query","labels","Partial","onInsert","event","openOnInsert","shortcut","presets","arrayTypeName","blockInsertPicker","config","BlockInsertPickerPlugins","props","renderDefault","length"],"sources":["../src/deriveItems.ts","../src/filterItems.ts","../src/groupItems.ts","../src/insertBehavior.ts","../src/insertPickerItem.ts","../src/labels.ts","../src/memberSchemaTypes.ts","../src/openBlockOnInsert.ts","../src/pickerBehavior.ts","../src/pickerReducer.ts","../src/inputRules.ts","../src/presets.ts","../src/resolveItemPresentation.ts","../src/blockInsertPicker.tsx","../src/markdownInputRules.tsx","../src/plugin.tsx"],"sourcesContent":["import type {PickerItem, PickerItemMetadata, PickerItemsContext} from './types'\n\n/**\n * The member's own name plus every name up its compiled `type` chain, most\n * specific first: `{type: 'image', name: 'photo'}` yields `['photo',\n * 'image', ...]`. Metadata and presets match against this chain so curation\n * can target either the member name or the underlying type name.\n */\nexport function typeNameChain(memberType: {\n  name: string\n  type?: {name: string; type?: unknown} | undefined\n}): string[] {\n  const names: string[] = []\n  let current: {name: string; type?: unknown} | undefined = memberType\n  while (current && typeof current.name === 'string') {\n    names.push(current.name)\n    current =\n      current.type && typeof current.type === 'object' && 'name' in current.type\n        ? // oxlint-disable-next-line no-unsafe-type-assertion\n          (current.type as {name: string; type?: unknown})\n        : undefined\n  }\n  return names\n}\n\n/**\n * Derives picker items from a portable-text array's insertable member types\n * (see PickerItemsContext), so the picker automatically covers every object\n * block the schema allows. The optional metadata list curates triggers,\n * keywords, grouping, badges, visibility, and descriptions per member type;\n * its array order is the sort rank (see PickerItemMetadata). Titles and\n * icons intentionally stay unresolved here: BlockInsertPicker resolves\n * presentation from the member schema type, which carries member-level\n * config (a member-specific icon, a per-member title override).\n */\nexport function derivePickerItems(\n  context: PickerItemsContext,\n  metadata: readonly PickerItemMetadata[] = [],\n): PickerItem[] {\n  return context.memberTypes\n    .map((memberType, schemaIndex) => {\n      const chain = typeNameChain(memberType)\n      // The member's own name wins over a resolved-chain match, so an entry\n      // for `photo` beats an entry for `image` on `{type: 'image', name:\n      // 'photo'}` — but whichever matches, its array position is the rank.\n      const nameRank = metadata.findIndex((entry) => entry.type === memberType.name)\n      const rank =\n        nameRank === -1 ? metadata.findIndex((entry) => chain.includes(entry.type)) : nameRank\n      const entry = rank === -1 ? undefined : metadata[rank]\n      return {\n        entry,\n        name: memberType.name,\n        rank: rank === -1 ? Number.MAX_SAFE_INTEGER : rank,\n        schemaIndex,\n      }\n    })\n    .filter(({entry}) => !entry?.hidden)\n    .sort((a, b) => a.rank - b.rank || a.schemaIndex - b.schemaIndex)\n    .map(({entry, name}) => ({\n      action: {blockType: name, type: 'insertBlock' as const},\n      badge: entry?.badge,\n      description: entry?.description,\n      group: entry?.group,\n      id: name,\n      keywords: entry?.keywords,\n      openOnInsert: entry?.openOnInsert,\n      title: '',\n      trigger: entry?.trigger,\n    }))\n}\n\n/**\n * Metadata entries whose `type` matches neither a member name nor any name\n * in a member's resolved type chain — almost always a typo. Surfaced as a\n * dev-mode warning by BlockInsertPicker.\n */\nexport function unknownMetadataTypes(\n  context: PickerItemsContext,\n  metadata: readonly PickerItemMetadata[],\n): string[] {\n  const known = new Set(context.memberTypes.flatMap((memberType) => typeNameChain(memberType)))\n  return metadata.map((entry) => entry.type).filter((type) => !known.has(type))\n}\n","import type {PickerItem} from './types'\n\nexport function filterPickerItems(\n  items: readonly PickerItem[],\n  query: string,\n): readonly PickerItem[] {\n  if (query === '' || query === '/') return items\n\n  const queryLower = query.toLowerCase()\n  // Slash-mode queries always carry the leading \"/\", which titles and\n  // keywords never contain — strip it before substring matching.\n  const bareQuery = queryLower.startsWith('/') ? queryLower.slice(1) : queryLower\n\n  return items.filter((item) => {\n    // Triggers match with the slash stripped from both sides so that bare\n    // shortcut-mode queries (\"cta\") reach them, not just slash-mode ones.\n    const bareTrigger = item.trigger?.toLowerCase().replace(/^\\//, '')\n    if (bareTrigger && bareQuery !== '' && bareTrigger.startsWith(bareQuery)) return true\n    if (bareQuery === '') return false\n    if (item.title.toLowerCase().includes(bareQuery)) return true\n    if (item.description?.toLowerCase().includes(bareQuery)) return true\n    if (item.keywords?.some((kw) => kw.toLowerCase().includes(bareQuery))) return true\n    return false\n  })\n}\n","import type {PickerItem} from './types'\n\ntype PickerSection = {\n  /** Category label, or null for items that carry no group. */\n  group: null | string\n  items: readonly PickerItem[]\n}\n\n/**\n * Flattens sections back into the single index space that keyboard navigation,\n * selection, and scroll-into-view all share. Rendering the sections and\n * indexing this array must stay derived from the same `groupPickerItems` call\n * so Enter inserts exactly the highlighted row.\n */\nexport function flattenSections(sections: readonly PickerSection[]): readonly PickerItem[] {\n  return sections.flatMap((section) => section.items)\n}\n\n/**\n * Partitions items into sections by their `group`, preserving the incoming\n * order within each section and ordering the sections by first appearance.\n *\n * Because the caller feeds rank-ordered items (see derivePickerItems), the\n * first-appearance rule places the section holding the most-used block first,\n * without a separate ordering constant to drift out of sync. Items without a\n * group collapse into a single `group: null` section (e.g. a curated `items`\n * prop), so the flat/ungrouped case stays a no-op reordering.\n */\nexport function groupPickerItems(items: readonly PickerItem[]): PickerSection[] {\n  const order: (null | string)[] = []\n  const byGroup = new Map<null | string, PickerItem[]>()\n  for (const item of items) {\n    const key = item.group ?? null\n    let bucket = byGroup.get(key)\n    if (!bucket) {\n      bucket = []\n      byGroup.set(key, bucket)\n      order.push(key)\n    }\n    bucket.push(item)\n  }\n  return order.map((key) => ({group: key, items: byGroup.get(key)!}))\n}\n","import type {Editor, EditorSelection, EditorSnapshot} from '@portabletext/editor'\nimport {defineBehavior, raise} from '@portabletext/editor/behaviors'\nimport {blockOffsetsToSelection, getTextBlockText, isTextBlock} from '@portabletext/editor/utils'\n\nimport type {PickerMode} from './types'\n\ntype InsertGuardResult = {\n  anchor: EditorSelection\n  block: InsertPickerItemPayload['block']\n  cleanup: EditorSelection\n  placement: 'after' | 'auto'\n}\n\ntype InsertPickerItemPayload = {\n  anchorBlockKey: string\n  block: {_key: string; _type: string} & Record<string, unknown>\n  mode: PickerMode\n  query: string\n}\n\n/**\n * Performs the picker insertion as a single behavior action set so the whole\n * operation is one undo step, and cleans up the typed \"/query\" text with\n * delete.text over exactly that range (never delete.block) so text that\n * already existed in the anchor block can't be destroyed: the caret can sit\n * at offset 0 of a populated block and still open the picker.\n */\nexport function createInsertBehavior() {\n  return defineBehavior<\n    InsertPickerItemPayload,\n    'custom.blockInsertPicker.insert',\n    InsertGuardResult\n  >({\n    actions: [\n      (_, {anchor, block, cleanup, placement}) => [\n        ...(cleanup ? [raise({at: cleanup, type: 'delete.text'})] : []),\n        raise({\n          block,\n          placement,\n          select: 'start',\n          type: 'insert.block',\n          // Pin the insert to the anchor block: the live selection may have\n          // moved (e.g. input arriving during the select-time initial-value\n          // await) and placement resolves relative to `at` when provided.\n          ...(anchor ? {at: anchor} : {}),\n        }),\n      ],\n    ],\n    guard: ({event, snapshot}) => {\n      const {anchorBlockKey, block, mode} = event\n      const anchorBlockExists = snapshot.context.value.some(\n        (candidate) => candidate._key === anchorBlockKey,\n      )\n      const anchor = anchorBlockExists\n        ? blockOffsetsToSelection({\n            offsets: {\n              anchor: {offset: 0, path: [{_key: anchorBlockKey}]},\n              focus: {offset: 0, path: [{_key: anchorBlockKey}]},\n            },\n            snapshot,\n          })\n        : null\n      return {\n        anchor,\n        block,\n        cleanup: resolveQueryCleanup(event, snapshot),\n        placement: mode === 'slash' ? ('auto' as const) : ('after' as const),\n      }\n    },\n    on: 'custom.blockInsertPicker.insert',\n  })\n}\n\nexport function sendInsertPickerItem(editor: Editor, payload: InsertPickerItemPayload): void {\n  editor.send({type: 'custom.blockInsertPicker.insert', ...payload})\n}\n\ntype CleanupQueryPayload = Omit<InsertPickerItemPayload, 'block'>\n\n/**\n * The query-cleanup half of the insert behavior on its own, for `custom`\n * picker actions that don't insert a block: the typed \"/query\" text still\n * leaves the document before the host's `onSelect` runs, under the same\n * only-if-unchanged guard as a real insert.\n */\nexport function createCleanupQueryBehavior() {\n  return defineBehavior<\n    CleanupQueryPayload,\n    'custom.blockInsertPicker.cleanupQuery',\n    NonNullable<EditorSelection>\n  >({\n    actions: [(_, cleanup) => [raise({at: cleanup, type: 'delete.text'})]],\n    guard: ({event, snapshot}) => resolveQueryCleanup(event, snapshot) ?? false,\n    on: 'custom.blockInsertPicker.cleanupQuery',\n  })\n}\n\nexport function sendCleanupQuery(editor: Editor, payload: CleanupQueryPayload): void {\n  editor.send({type: 'custom.blockInsertPicker.cleanupQuery', ...payload})\n}\n\n/**\n * The selection spanning the typed \"/query\" text in the anchor block, when it\n * is safe to delete. Only slash mode leaves query text in the document, and\n * only when the anchor block still starts with the typed query; if it changed\n * underneath us (collaborator edit, uncaptured caret movement) the action is\n * still the user's intent, but nothing may be deleted.\n */\nfunction resolveQueryCleanup(\n  event: {anchorBlockKey: string; mode: PickerMode; query: string},\n  snapshot: EditorSnapshot,\n): EditorSelection {\n  const {anchorBlockKey, mode, query} = event\n  if (mode !== 'slash' || query.length === 0) return null\n  const anchorBlock = snapshot.context.value.find((candidate) => candidate._key === anchorBlockKey)\n  if (\n    !anchorBlock ||\n    !isTextBlock({schema: snapshot.context.schema}, anchorBlock) ||\n    !getTextBlockText(anchorBlock).startsWith(query)\n  ) {\n    return null\n  }\n  return blockOffsetsToSelection({\n    offsets: {\n      anchor: {offset: 0, path: [{_key: anchorBlockKey}]},\n      focus: {offset: query.length, path: [{_key: anchorBlockKey}]},\n    },\n    snapshot,\n  })\n}\n","import type {Editor} from '@portabletext/editor'\n\nimport {sendInsertPickerItem} from './insertBehavior'\nimport type {PickerMode} from './types'\n\ntype InsertContext = {\n  /** The `_type` of the block to insert — an `insertBlock` action's target. */\n  blockType: string\n  mode: PickerMode\n  editor: Editor\n  anchorBlockKey: string\n  query: string\n  keyGenerator: () => string\n  initialValue?: Record<string, unknown>\n  onInsertedKey?: (key: string) => void\n}\n\nexport function insertPickerItem(ctx: InsertContext): void {\n  const blockKey = ctx.keyGenerator()\n  // One custom event; the registered insert behavior performs the query\n  // cleanup and the insertion in a single action set (single undo step).\n  sendInsertPickerItem(ctx.editor, {\n    anchorBlockKey: ctx.anchorBlockKey,\n    block: {\n      // Spread the resolved initial value first so the generated `_key` and\n      // the target `_type` always win: Sanity's initial-value resolver sets\n      // `_type` on object values, and a schema's initialValue could carry\n      // stray meta keys. In this flow the resolved `_type` matches\n      // `ctx.blockType` by construction, but ordering it last keeps the\n      // insert correct even when that assumption doesn't hold.\n      ...ctx.initialValue,\n      _key: blockKey,\n      _type: ctx.blockType,\n    },\n    mode: ctx.mode,\n    query: ctx.query,\n  })\n  ctx.onInsertedKey?.(blockKey)\n}\n","/**\n * Every user-facing string in the picker chrome, centralized so hosts can\n * translate or reword them via the `labels` option (the same pattern\n * `@sanity/insert-menu` uses for its label overrides). Item titles and\n * descriptions are schema/metadata content, not chrome — localize those\n * through `items` or `resolveItems` instead.\n */\nexport type BlockInsertPickerLabels = {\n  /** Popover header; also the listbox aria-label. */\n  title: string\n  /** Empty state; `{query}` is replaced with the typed filter text. */\n  noMatches: string\n  /**\n   * Screen-reader position announcement for the highlighted row; `{index}`\n   * and `{count}` are replaced with the 1-based position and list length.\n   */\n  positionAnnouncement: string\n  /**\n   * Section header for items without a `group`, shown only when grouped\n   * sections are also present.\n   */\n  ungroupedSection: string\n  /** Footer legend verbs. */\n  footerNavigate: string\n  footerInsert: string\n  footerDismiss: string\n  footerAnywhere: string\n  /** Toast title when resolving a block's initial value fails. */\n  insertError: string\n  /**\n   * Toast description when the block the picker was anchored to is deleted\n   * before the insert completes.\n   */\n  insertAnchorRemoved: string\n}\n\nconst DEFAULT_LABELS: BlockInsertPickerLabels = {\n  footerAnywhere: 'Anywhere',\n  footerDismiss: 'Dismiss',\n  footerInsert: 'Insert',\n  footerNavigate: 'Navigate',\n  insertAnchorRemoved: 'The block you were inserting into was removed',\n  insertError: 'Could not insert block',\n  noMatches: 'No matches for \"{query}\"',\n  positionAnnouncement: '{index} of {count}',\n  title: 'Insert block',\n  ungroupedSection: 'Other blocks',\n}\n\nexport function resolveLabels(\n  overrides: Partial<BlockInsertPickerLabels> | undefined,\n): BlockInsertPickerLabels {\n  return overrides ? {...DEFAULT_LABELS, ...overrides} : DEFAULT_LABELS\n}\n\n/** Fills the `{query}` placeholder in the no-matches label. */\nexport function formatNoMatches(labels: BlockInsertPickerLabels, query: string): string {\n  // Function replacement: a query containing replacement patterns (\"$&\")\n  // must land verbatim, not be interpreted by String.replace.\n  return labels.noMatches.replace('{query}', () => query)\n}\n\n/** Fills `{index}`/`{count}` in the screen-reader position announcement. */\nexport function formatPosition(\n  labels: BlockInsertPickerLabels,\n  index: number,\n  count: number,\n): string {\n  return labels.positionAnnouncement\n    .replace('{index}', () => String(index))\n    .replace('{count}', () => String(count))\n}\n","import {type ContextType, useContext, useMemo} from 'react'\nimport {type ObjectSchemaType, useSchema} from 'sanity'\nimport {PortableTextMemberSchemaTypesContext} from 'sanity/_singletons'\n\nimport type {PickerItemsContext} from './types'\n\n/**\n * Resolves the Portable Text array type and its insertable member types from\n * where this plugin renders — inside the PT input's `EditorProvider`.\n *\n * Primary source: Studio's own member-schema context, which the PT input\n * provides above the plugins slot. It carries the containing array type and\n * its non-text-block members as full Studio schema types, so aliased members\n * (`{type: 'image', name: 'photo'}`), inline-declared members, and arrays\n * defined inline on a field all resolve with member-level fidelity and no\n * configuration. Fallback: an explicit `arrayTypeName` looked up in the\n * workspace schema — the escape hatch for environments where the context is\n * unavailable. With neither, callers get `null` and must render nothing\n * (never an empty picker).\n *\n * Together with openBlockOnInsert.ts, this module is one of exactly two\n * importers of `sanity/_singletons` — an internal subpath with no stability\n * guarantee (the context exists since sanity 5.6.0, which the peer range\n * pins). The dependency stays quarantined here so it can be swapped for a\n * public API (an exported `usePortableTextMemberSchemaTypes`, or a\n * `schemaType` on `PortableTextPluginsProps`) in one place.\n */\n\n// The context's value type lives in @portabletext/sanity-bridge, which\n// consumer studios cannot resolve directly (it is sanity's own dependency) —\n// extract it from the context instead of importing the bridge.\ntype MemberSchemaTypes = NonNullable<ContextType<typeof PortableTextMemberSchemaTypesContext>>\n\nexport function usePickerItemsContext(arrayTypeName?: string): PickerItemsContext | null {\n  const memberSchemaTypes: MemberSchemaTypes | null = useContext(\n    PortableTextMemberSchemaTypesContext,\n  )\n  const schema = useSchema()\n\n  return useMemo(() => {\n    if (memberSchemaTypes) {\n      return {\n        memberTypes: memberSchemaTypes.blockObjects,\n        schemaType: memberSchemaTypes.portableText,\n      }\n    }\n    const arrayType = arrayTypeName ? schema.get(arrayTypeName) : undefined\n    if (!arrayType || arrayType.jsonType !== 'array') return null\n    return {\n      memberTypes: arrayType.of.filter(\n        (member): member is ObjectSchemaType =>\n          member.jsonType === 'object' && !isTextBlockMember(member),\n      ),\n      schemaType: arrayType,\n    }\n  }, [arrayTypeName, memberSchemaTypes, schema])\n}\n\n/**\n * Whether a member resolves to the built-in text block: walk the compiled\n * `type` chain to its root and compare the root's name — the same algorithm\n * Studio's schema bridge uses to bucketize `of`. A literal `name === 'block'`\n * check would miss aliased text blocks (`{name: 'myBlock', type: 'block'}`)\n * and wrongly offer them as object inserts.\n */\nfunction isTextBlockMember(memberType: {\n  name: string\n  type?: {name: string; type?: unknown} | undefined\n}): boolean {\n  let current: {name: string; type?: unknown} = memberType\n  while (current.type && typeof current.type === 'object' && 'name' in current.type) {\n    // oxlint-disable-next-line no-unsafe-type-assertion\n    current = current.type as {name: string; type?: unknown}\n  }\n  return current.name === 'block'\n}\n","import {useCallback, useContext, useEffect, useRef} from 'react'\nimport {useFormCallbacks} from 'sanity'\nimport {PortableTextMemberItemsContext} from 'sanity/_singletons'\n\n/**\n * Opens a just-inserted block's editing UI (dialog/popover per the member's\n * config) once its member item mounts. An insert lands synchronously, but the\n * member item only exists on a later render — so callers schedule the key and\n * the effect opens it when it appears.\n *\n * Together with memberSchemaTypes.ts, this module is one of exactly two\n * importers of `sanity/_singletons` in this plugin: the subpath is internal\n * with no stability guarantee, so each dependency stays quarantined where it\n * can be swapped for a public API in one place. Consumers that need to react\n * to inserts without this internal should use the `onInsert` seam on the\n * plugin components instead.\n */\nexport function useOpenBlockOnInsert(): (blockKey: string) => void {\n  const memberItems = useContext(PortableTextMemberItemsContext)\n  const {onPathOpen, onSetPathCollapsed} = useFormCallbacks()\n  const pendingKeyRef = useRef<null | string>(null)\n\n  useEffect(() => {\n    const key = pendingKeyRef.current\n    if (!key) return\n    const item = memberItems.find((m) => m.member.key === key)\n    if (item) {\n      onPathOpen(item.member.item.path)\n      onSetPathCollapsed(item.member.item.path, false)\n      pendingKeyRef.current = null\n    }\n  }, [memberItems, onPathOpen, onSetPathCollapsed])\n\n  // Stable identity: callers hold this in effect dependency arrays, so it must\n  // keep a constant reference — an unstable return would re-run (and re-register\n  // behaviors in) every effect that lists it, on every render. The empty-dep\n  // `useCallback` states that contract explicitly rather than relying on the\n  // React Compiler to infer it.\n  return useCallback((blockKey: string) => {\n    pendingKeyRef.current = blockKey\n  }, [])\n}\n","import {defineBehavior, effect, forward} from '@portabletext/editor/behaviors'\nimport type {BehaviorEvent, BehaviorGuard} from '@portabletext/editor/behaviors'\nimport {\n  getBlockTextBefore,\n  getFirstBlock,\n  getFocusBlock,\n  getFocusTextBlock,\n  isSelectionCollapsed,\n} from '@portabletext/editor/selectors'\n\nimport type {PickerIntent, PickerState} from './types'\n\ntype GuardResult = {\n  // true = block the native/default editor handling; false = allow it to proceed\n  blockEvent: boolean\n  intent: PickerIntent\n}\n\ntype PickerBehaviorRefs = {\n  onIntent: (intent: PickerIntent) => void\n  getState: () => PickerState\n  /**\n   * Whether Cmd/Ctrl+/ may open the picker. Read per keystroke (not captured\n   * at registration) so the host toggling `shortcut` doesn't force a\n   * re-registration, which would re-sort the editor's behavior chain.\n   */\n  isShortcutEnabled: () => boolean\n}\n\nexport function createPickerBehavior({getState, isShortcutEnabled, onIntent}: PickerBehaviorRefs) {\n  const guard: BehaviorGuard<BehaviorEvent, GuardResult> = ({event, snapshot}) => {\n    const state = getState()\n\n    // Picker is closed — only the two open triggers can fire.\n    if (state.mode === 'closed') {\n      if (event.type === 'insert.text' && event.text === '/') {\n        const focus = getFocusTextBlock(snapshot)\n        if (!focus || !isSelectionCollapsed(snapshot) || getBlockTextBefore(snapshot) !== '') {\n          return false\n        }\n        return {\n          blockEvent: false,\n          intent: {\n            anchorBlockKey: focus.node._key,\n            mode: 'slash',\n            query: '/',\n            type: 'open',\n          } satisfies PickerIntent,\n        }\n      }\n      if (\n        event.type === 'keyboard.keydown' &&\n        event.originEvent.key === '/' &&\n        (event.originEvent.metaKey || event.originEvent.ctrlKey) &&\n        isShortcutEnabled()\n      ) {\n        // For the shortcut mode, anchor to the focused block whether it is a\n        // text block or a block object (image, callout); fall back to the\n        // first block only when there is no selection at all (e.g. when\n        // triggered via a toolbar button before the editor is DOM-focused).\n        const focus = getFocusBlock(snapshot)\n        const fallback = getFirstBlock(snapshot)\n        const anchorBlock = focus ?? fallback\n        if (!anchorBlock) return false\n        return {\n          blockEvent: true,\n          intent: {\n            anchorBlockKey: anchorBlock.node._key,\n            mode: 'shortcut',\n            query: '',\n            type: 'open',\n          } satisfies PickerIntent,\n        }\n      }\n      return false\n    }\n\n    // Picker is open — capture editing/navigation events.\n    if (event.type === 'insert.text') {\n      if (state.mode === 'slash') {\n        if (event.text === ' ') {\n          // Space while open: close picker, let the space insert proceed.\n          return {blockEvent: false, intent: {type: 'close'}}\n        }\n        // Character typed while in slash mode: update query; let the editor\n        // insert the character into the document as well.\n        return {\n          blockEvent: false,\n          intent: {query: state.query + event.text, type: 'updateQuery'},\n        }\n      }\n      // Shortcut-mode type-to-filter: the query is picker-only state that\n      // never entered the document, so capture the character (spaces\n      // included — titles contain them) and block the insertion.\n      return {\n        blockEvent: true,\n        intent: {query: state.query + event.text, type: 'updateQuery'},\n      }\n    }\n\n    if (event.type === 'delete.backward') {\n      if (state.mode === 'shortcut') {\n        // Backspace edits the picker-only query, never the document.\n        if (state.query.length === 0) {\n          return {blockEvent: true, intent: {type: 'close'}}\n        }\n        return {\n          blockEvent: true,\n          intent: {\n            // Word/line deletes clear the whole query rather than desyncing.\n            query: event.unit === 'character' ? state.query.slice(0, -1) : '',\n            type: 'updateQuery',\n          },\n        }\n      }\n      // Slash mode: the deletion proceeds in the document, so shrink the\n      // query in sync. Deleting the opening \"/\" itself closes, and word/line\n      // deletes can outrun the query — close and let them proceed.\n      if (event.unit === 'character' && state.query.length > 1) {\n        return {\n          blockEvent: false,\n          intent: {query: state.query.slice(0, -1), type: 'updateQuery'},\n        }\n      }\n      return {blockEvent: false, intent: {type: 'close'}}\n    }\n\n    if (event.type === 'delete.forward') {\n      // Forward delete edits content ahead of the caret, not the query;\n      // close and let the deletion proceed in the editor normally.\n      return {blockEvent: false, intent: {type: 'close'}}\n    }\n\n    if (event.type === 'keyboard.keydown') {\n      const key = event.originEvent.key\n      if (key === 'ArrowDown') {\n        return {blockEvent: true, intent: {delta: 1, type: 'navigate'}}\n      }\n      if (key === 'ArrowUp') {\n        return {blockEvent: true, intent: {delta: -1, type: 'navigate'}}\n      }\n      if (key === 'Enter') {\n        return {blockEvent: true, intent: {type: 'select'}}\n      }\n      if (key === 'Escape') {\n        return {blockEvent: true, intent: {type: 'close'}}\n      }\n      if (\n        key === 'ArrowLeft' ||\n        key === 'ArrowRight' ||\n        key === 'Home' ||\n        key === 'End' ||\n        key === 'PageUp' ||\n        key === 'PageDown'\n      ) {\n        // The caret is moving off the typed query; close and let the caret\n        // move normally so the picker's query can't desync from the document.\n        return {blockEvent: false, intent: {type: 'close'}}\n      }\n    }\n\n    return false\n  }\n\n  return defineBehavior({\n    actions: [\n      (payload, guardResponse) => {\n        // Actions only run when the guard returned a value, so guardResponse\n        // is the GuardResult the guard produced.\n        const {blockEvent, intent} = guardResponse\n        const sideEffect = effect(() => onIntent(intent))\n        if (blockEvent) {\n          // Stopping propagation: only run the side effect, no forward.\n          return [sideEffect]\n        }\n        // Non-blocking: run side effect and forward the original event so\n        // PTE's default handling still executes.\n        return [sideEffect, forward(payload.event)]\n      },\n    ],\n    guard,\n    on: '*',\n  })\n}\n","import type {PickerIntent, PickerState} from './types'\n\nexport function pickerReducer(state: PickerState, intent: PickerIntent): PickerState {\n  switch (intent.type) {\n    case 'close':\n    case 'select':\n      return {mode: 'closed'}\n    case 'navigate':\n      if (state.mode === 'closed') return state\n      return {\n        ...state,\n        highlightedIndex: state.highlightedIndex + intent.delta,\n      }\n    case 'open':\n      if (state.mode !== 'closed') return state\n      return {\n        anchorBlockKey: intent.anchorBlockKey,\n        highlightedIndex: 0,\n        mode: intent.mode,\n        query: intent.query,\n      }\n    case 'setHighlightedIndex':\n      if (state.mode === 'closed') return state\n      // Like `navigate`, the reducer does not clamp — the caller (which knows\n      // the filtered list length) is responsible for staying in range.\n      return {...state, highlightedIndex: intent.index}\n    case 'updateQuery':\n      if (state.mode === 'closed') return state\n      return {...state, highlightedIndex: 0, query: intent.query}\n    default: {\n      // All intents are handled above; this arm satisfies consistent-return\n      // while keeping the omission of a future variant a compile error.\n      const unhandled: never = intent\n      return unhandled\n    }\n  }\n}\n","import {effect, raise} from '@portabletext/editor/behaviors'\nimport {blockOffsetsToSelection} from '@portabletext/editor/utils'\nimport {defineInputRule, type InputRule} from '@portabletext/plugin-input-rule'\n\n/**\n * Generic machinery for markdown-style input rules that replace typed text\n * with an inserted object block, complementing the slash/⌘+/ picker with a\n * keyboard-only path that mirrors what writers already type in markdown.\n *\n * The rules run through `@portabletext/plugin-input-rule` (see\n * `markdownInputRules.tsx`), which applies the delete + insert as a single\n * behavior action set — so each transform is one undo step.\n *\n * Block values are built synchronously via each config's `buildValue` rather\n * than resolved from the schema's async initial values: the insert has to\n * happen inside the rule's action set for that single-undo guarantee to hold,\n * so anything the writer would otherwise have to fill in (language, filename,\n * callout type) is seeded from the host's rule config.\n */\n\nexport type KeyGenerator = () => string\n\n/**\n * One markdown input rule: when `pattern` matches the block text, the match\n * is deleted and a block of `blockType` is inserted in its place, carrying\n * the fields `buildValue` returns. `buildValue` must stay synchronous so the\n * delete + insert land in one action set (one undo step).\n */\nexport type MarkdownInputRuleConfig = {\n  pattern: RegExp\n  blockType: string\n  buildValue: (context: {matchText: string; keyGenerator: KeyGenerator}) => Record<string, unknown>\n}\n\ntype BuildRulesDeps = {\n  keyGenerator: KeyGenerator\n  /** Called with the inserted block so the caller can open it for editing. */\n  onInserted: (block: InsertableBlock) => void\n}\n\ntype InsertableBlock = {_key: string; _type: string} & Record<string, unknown>\n\n/**\n * Builds InputRules for the configs whose block type the host array actually\n * allows, so a rule can't insert a block the field would reject.\n */\nexport function createMarkdownInputRules({\n  allowedBlockTypes,\n  keyGenerator,\n  onInserted,\n  rules,\n}: BuildRulesDeps & {\n  allowedBlockTypes: ReadonlySet<string>\n  rules: readonly MarkdownInputRuleConfig[]\n}): InputRule[] {\n  return rules\n    .filter((config) => allowedBlockTypes.has(config.blockType))\n    .map((config) => createInsertRule(config, keyGenerator, onInserted))\n}\n\n// The plugin matches its regex against the block text AFTER the pending\n// insertion. The trailing \"\\s\" is the space the writer types to commit the\n// fence/quote; it is part of the match and gets deleted along with it.\nexport const CODE_FENCE_PATTERN = /^`{3}\\S*\\s$/\nexport const BLOCKQUOTE_PATTERN = /^>\\s$/\n\n/**\n * A row of a code-fence language table: the stored `value`, the markdown\n * fence tokens that should resolve to it, and an optional tab filename.\n */\nexport type LanguageEntry = {\n  value: string\n  aliases?: readonly string[]\n  filename?: string\n}\n\n/** Sugar: a blockquote rule (\"> \" at the start of a block) for `blockType`. */\nexport function blockquoteRule(options: {\n  blockType: string\n  createValue?: (context: {keyGenerator: KeyGenerator}) => Record<string, unknown>\n}): MarkdownInputRuleConfig {\n  return {\n    blockType: options.blockType,\n    buildValue: ({keyGenerator}) => options.createValue?.({keyGenerator}) ?? {},\n    pattern: BLOCKQUOTE_PATTERN,\n  }\n}\n\n/**\n * Sugar: a code-fence rule (\"```lang␣\") for `blockType`. The language table\n * resolves fence tokens (aliases included) to the values the block's language\n * selector stores, plus an optional filename; tokens outside the table pass\n * through as typed so nothing the writer means is lost. `createValue` turns\n * the resolved language and filename into the block's fields.\n */\nexport function codeFenceRule(options: {\n  blockType: string\n  languages?: readonly LanguageEntry[]\n  defaultLanguage?: string\n  createValue: (context: {\n    filename: string | undefined\n    keyGenerator: KeyGenerator\n    language: string | undefined\n  }) => Record<string, unknown>\n}): MarkdownInputRuleConfig {\n  const languages = options.languages ?? []\n  return {\n    blockType: options.blockType,\n    buildValue: ({keyGenerator, matchText}) => {\n      const language = normalizeFenceLanguage(\n        fenceLanguageFromMatch(matchText),\n        languages,\n        options.defaultLanguage,\n      )\n      const filename = language\n        ? languages.find((entry) => entry.value === language)?.filename\n        : undefined\n      return options.createValue({filename, keyGenerator, language})\n    },\n    pattern: CODE_FENCE_PATTERN,\n  }\n}\n\n/** Strips the leading \"```\" fence and surrounding whitespace from a match. */\nexport function fenceLanguageFromMatch(matchText: string): string {\n  return matchText.replace(/^`{3}/, '').trim()\n}\n\n/**\n * Resolves a typed fence token against a language table: a canonical value,\n * an alias (`py`→python, `yml`→yaml), or — for anything the table doesn't\n * know — the token as typed. An empty token yields `defaultLanguage`.\n */\nexport function normalizeFenceLanguage(\n  raw: string,\n  languages: readonly LanguageEntry[],\n  defaultLanguage?: string,\n): string | undefined {\n  const token = raw.trim()\n  const lower = token.toLowerCase()\n  if (!lower) return defaultLanguage\n  // Match case-insensitively on both sides so a table with mixed-case values\n  // or aliases still resolves (and yields its canonical `value`, casing\n  // preserved) rather than falling through to the typed token.\n  for (const {aliases, value} of languages) {\n    if (value.toLowerCase() === lower || aliases?.some((alias) => alias.toLowerCase() === lower))\n      return value\n  }\n  // Unknown token: pass it through as typed (case preserved) per the contract\n  // above — not the lowercased form used for matching.\n  return token\n}\n\nfunction createInsertRule(\n  config: MarkdownInputRuleConfig,\n  keyGenerator: KeyGenerator,\n  onInserted: (block: InsertableBlock) => void,\n): InputRule {\n  return defineInputRule({\n    actions: [\n      ({event, snapshot}) => {\n        const match = event.matches[0]\n        if (!match) return []\n        const block: InsertableBlock = {\n          // Spread the host-built fields first so the generated `_key` and the\n          // resolved `_type` always win (mirrors insertPickerItem): a stray\n          // `_key`/`_type` from buildValue can't hijack the block identity.\n          ...config.buildValue({keyGenerator, matchText: match.text}),\n          _key: keyGenerator(),\n          _type: config.blockType,\n        }\n        // `match.selection` is clamped to the text that existed *before* the\n        // triggering space, so it stops short of that space and would leave it\n        // orphaned as a stray paragraph next to the inserted block.\n        // `match.targetOffsets` spans the full match (space included); convert\n        // it to a selection so the whole fence/quote is removed cleanly.\n        const at =\n          blockOffsetsToSelection({\n            offsets: {\n              anchor: match.targetOffsets.anchor,\n              focus: match.targetOffsets.focus,\n            },\n            snapshot,\n          }) ?? match.selection\n        return [\n          // Remove the typed fence/quote text, then insert the block in its\n          // place. Both raises land in one action set (one undo step).\n          raise({at, type: 'delete.text'}),\n          raise({\n            block,\n            placement: 'auto',\n            select: 'start',\n            type: 'insert.block',\n          }),\n          effect(() => onInserted(block)),\n        ]\n      },\n    ],\n    on: config.pattern,\n  })\n}\n","import {typeNameChain} from './deriveItems'\nimport {codeFenceRule, type MarkdownInputRuleConfig} from './inputRules'\nimport type {PickerItem, PickerItemMetadata, PickerItemsContext} from './types'\n\n/**\n * Default triggers and search keywords for block types with fixed, official\n * names: Studio's intrinsic types (`image`, `file`), first-party plugin\n * types (`code`, `table`, `color`, `latex`, `mux.video`), and the Media\n * Library's `sanity.video`. Presets are deliberately presentation-only —\n * they never add items (a type must actually be a member of the array),\n * never set groups (partial grouping would strand unmatched items in an\n * \"Other\" bucket), never affect rank, and always lose to a host's `items`\n * entry for the same type. Opt out entirely with `presets: false`.\n */\nexport const standardBlockPresets: readonly PickerItemMetadata[] = [\n  {keywords: ['photo', 'picture', 'figure', 'media'], trigger: '/image', type: 'image'},\n  {keywords: ['attachment', 'download', 'document'], trigger: '/file', type: 'file'},\n  {keywords: ['snippet', 'syntax', 'fence', 'pre'], trigger: '/code', type: 'code'},\n  {keywords: ['grid', 'rows', 'columns', 'spreadsheet'], trigger: '/table', type: 'table'},\n  {keywords: ['swatch', 'palette'], trigger: '/color', type: 'color'},\n  {keywords: ['formula', 'equation', 'math', 'tex', 'katex'], trigger: '/latex', type: 'latex'},\n  {keywords: ['video', 'player', 'mux'], trigger: '/video', type: 'mux.video'},\n  {keywords: ['video', 'player', 'media'], trigger: '/video', type: 'sanity.video'},\n]\n\n/**\n * Opt-in input rules for well-known block types — spread into `inputRules`\n * (`inputRules: [...wellKnownInputRules]`) rather than applied by default.\n * Today: a code fence for `@sanity/code-input`'s `code` type that stores the\n * typed fence token as the language. Like all rules, each resolves against\n * the array's members by name or resolved type chain (so an aliased\n * `{type: 'code', name: 'snippet'}` member still gets the fence, inserted\n * with the member's `_type`) and is ignored when nothing matches.\n */\nexport const wellKnownInputRules: readonly MarkdownInputRuleConfig[] = [\n  codeFenceRule({\n    blockType: 'code',\n    createValue: ({language}) => (language ? {language} : {}),\n  }),\n]\n\n/**\n * Fills preset triggers and keywords into derived items that don't already\n * have them, matching presets against each member's resolved type chain so\n * `{type: 'image', name: 'photo'}` still gets the image preset. Host `items`\n * metadata has already been folded in by derivePickerItems, so anything it\n * set wins by construction.\n */\nexport function applyPresetMetadata(\n  items: readonly PickerItem[],\n  context: PickerItemsContext,\n  presets: readonly PickerItemMetadata[] = standardBlockPresets,\n): PickerItem[] {\n  const presetByType = new Map(presets.map((preset) => [preset.type, preset]))\n  return items.map((item) => {\n    if (item.action.type !== 'insertBlock') return item\n    if (item.trigger !== undefined && item.keywords !== undefined) return item\n    const blockType = item.action.blockType\n    const memberType = context.memberTypes.find((candidate) => candidate.name === blockType)\n    if (!memberType) return item\n    const preset = typeNameChain(memberType)\n      .map((name) => presetByType.get(name))\n      .find(Boolean)\n    if (!preset) return item\n    return {\n      ...item,\n      keywords: item.keywords ?? preset.keywords,\n      trigger: item.trigger ?? preset.trigger,\n    }\n  })\n}\n","import {BlockElementIcon} from '@sanity/icons/BlockElement'\nimport type {ComponentType} from 'react'\n\nimport type {PickerItem} from './types'\n\ntype ItemPresentation = {\n  title: string\n  icon: ComponentType\n  description: string | undefined\n}\n\ntype SchemaTypeLike = {\n  name: string\n  title?: string\n  description?: string\n  icon?: ComponentType\n  type?: SchemaTypeLike\n  /** Reference types carry their targets here; core reads `to[0].icon`. */\n  to?: ReadonlyArray<{icon?: ComponentType}>\n}\n\n/**\n * Resolves what a picker row shows for an item, following the same fallback\n * chains Studio's built-in insert menu uses: icon from the member type, its\n * parent type, a reference target, then the generic block icon; title from\n * the member type or its capitalized name. The curated description (from\n * `items` metadata) wins over the schema type's own — curation is the more\n * specific intent.\n */\nexport function resolveItemPresentation(\n  item: PickerItem,\n  schemaType: SchemaTypeLike | undefined,\n): ItemPresentation {\n  if (!schemaType) {\n    return {\n      description: item.description,\n      icon: item.icon ?? BlockElementIcon,\n      title: item.title || (item.action.type === 'insertBlock' ? item.action.blockType : item.id),\n    }\n  }\n  return {\n    description: item.description ?? schemaType.description,\n    icon: schemaType.icon ?? schemaType.type?.icon ?? schemaType.to?.[0]?.icon ?? BlockElementIcon,\n    title: schemaType.title ?? upperFirst(schemaType.name),\n  }\n}\n\n// Matches core's lodash `upperFirst`: capitalize the first character, leave\n// the rest untouched (`codeBlock` -> `CodeBlock`, not `Codeblock`).\nfunction upperFirst(value: string): string {\n  return value.charAt(0).toUpperCase() + value.slice(1)\n}\n","import {useEditor} from '@portabletext/editor'\nimport {Box, Card, Flex, Hotkeys, Stack, Text} from '@sanity/ui'\nimport {Popover} from '@sanity/ui/popover'\nimport {useToast} from '@sanity/ui/toast'\nimport type {CSSProperties} from 'react'\nimport {useEffect, useId, useLayoutEffect, useMemo, useReducer, useRef, useState} from 'react'\nimport {useResolveInitialValueForType, useSchema} from 'sanity'\nimport type {SchemaType} from 'sanity'\n\nimport {derivePickerItems, unknownMetadataTypes} from './deriveItems'\nimport {filterPickerItems} from './filterItems'\nimport {flattenSections, groupPickerItems} from './groupItems'\nimport {createCleanupQueryBehavior, createInsertBehavior, sendCleanupQuery} from './insertBehavior'\nimport {insertPickerItem} from './insertPickerItem'\nimport {\n  type BlockInsertPickerLabels,\n  formatNoMatches,\n  formatPosition,\n  resolveLabels,\n} from './labels'\nimport {usePickerItemsContext} from './memberSchemaTypes'\nimport {useOpenBlockOnInsert} from './openBlockOnInsert'\nimport {createPickerBehavior} from './pickerBehavior'\nimport {pickerReducer} from './pickerReducer'\nimport {applyPresetMetadata} from './presets'\nimport {resolveItemPresentation} from './resolveItemPresentation'\nimport type {\n  PickerInsertEvent,\n  PickerIntent,\n  PickerItem,\n  PickerItemMetadata,\n  PickerItemsContext,\n  PickerItemsResolver,\n  PickerState,\n} from './types'\n\nexport type BlockInsertPickerProps = {\n  /**\n   * Per-member curation (trigger, keywords, group, description, badge,\n   * hidden, openOnInsert) merged into the items derived from the array's\n   * members; array order is the rank. Members without an entry still get\n   * items, in schema order.\n   */\n  items?: readonly PickerItemMetadata[]\n  /**\n   * Escape hatch: names the portable-text array type to resolve items from\n   * when Studio's member-schema context is unavailable. With the context\n   * present (any supported sanity version) this is ignored — the containing\n   * array and its members are detected automatically.\n   */\n  arrayTypeName?: string\n  /**\n   * Programmatic seam over the derived-and-curated item list: reorder,\n   * remove, relabel, or append items (including `custom`-action items).\n   */\n  resolveItems?: PickerItemsResolver\n  /**\n   * Replaces the built-in matching (see filterPickerItems). Receives the\n   * bare query in both modes — the slash-mode \"/\" prefix is stripped.\n   */\n  filter?: (items: readonly PickerItem[], query: string) => readonly PickerItem[]\n  /** Overrides for the picker chrome's user-facing strings. */\n  labels?: Partial<BlockInsertPickerLabels>\n  /** Notified after each successful insert, alongside open-on-insert. */\n  onInsert?: (event: PickerInsertEvent) => void\n  /**\n   * Whether an inserted block opens for editing (default true). Items can\n   * override per member via their metadata's `openOnInsert`.\n   */\n  openOnInsert?: boolean\n  /** Whether Cmd/Ctrl+/ opens the picker (default true). */\n  shortcut?: boolean\n  /**\n   * Whether well-known block types (image, file, code, table, ...) get\n   * default triggers and keywords when the host's `items` doesn't cover\n   * them (default true). See standardBlockPresets.\n   */\n  presets?: boolean\n}\n\nexport function BlockInsertPicker({\n  arrayTypeName,\n  filter,\n  items,\n  labels: labelOverrides,\n  onInsert,\n  openOnInsert = true,\n  presets = true,\n  resolveItems,\n  shortcut = true,\n}: BlockInsertPickerProps) {\n  const editor = useEditor()\n  const openBlockOnInsert = useOpenBlockOnInsert()\n  const itemsContext = usePickerItemsContext(arrayTypeName)\n  const schema = useSchema()\n  const resolveInitialValueForType = useResolveInitialValueForType()\n  const toast = useToast()\n  const labels = useMemo(() => resolveLabels(labelOverrides), [labelOverrides])\n  // Instance-scoped so ARIA option ids stay unique when several PTE fields\n  // (each with their own picker) mount on the same document.\n  const instanceId = useId()\n  const listboxId = `${instanceId}-listbox`\n  const optionId = (id: string) => `${instanceId}-option-${id}`\n\n  // Items derive from the array's member types (via Studio's member-schema\n  // context, or the arrayTypeName fallback), curated by the metadata in\n  // `items` and decorated by presets. Titles and icons are then enriched\n  // ONCE from the member type — not the global type of the same name — so\n  // member-level config wins: a member that redefines a core type's name\n  // shows its own icon and title rather than the global type's. Enriching\n  // before filtering keeps query matching aligned with what the popover\n  // displays, and `resolveItems` runs last over the fully-presented list so\n  // hosts relabel or append against what would actually render.\n  const pickerItems = useMemo(() => {\n    if (!itemsContext) return []\n    const derived = presets\n      ? applyPresetMetadata(derivePickerItems(itemsContext, items), itemsContext)\n      : derivePickerItems(itemsContext, items)\n    const presented = derived.map((item) => {\n      if (item.action.type !== 'insertBlock') return item\n      const schemaType = memberTypeFor(itemsContext, schema, item.action.blockType)\n      const presentation = resolveItemPresentation(item, schemaType)\n      // The derived items are fresh objects owned by this memo, so in-place\n      // assignment is safe (and satisfies oxc's no-map-spread).\n      return Object.assign(item, {\n        description: presentation.description,\n        icon: presentation.icon,\n        title: presentation.title,\n      })\n    })\n    return resolveItems ? [...resolveItems(presented, itemsContext)] : presented\n  }, [items, itemsContext, presets, resolveItems, schema])\n\n  const hasItems = pickerItems.length > 0\n\n  // Dev-mode configuration diagnostics, once per mount per category: a\n  // silent picker (no context, or nothing derivable) and typo'd metadata\n  // keys are the two misconfigurations schema-derived items can't surface\n  // on their own.\n  const warnedRef = useRef<{context?: boolean; empty?: boolean; unknown?: boolean}>({})\n  useEffect(() => {\n    if (process.env['NODE_ENV'] === 'production') return\n    const warned = warnedRef.current\n    if (!itemsContext && !warned.context) {\n      warned.context = true\n      console.warn(\n        '[@sanity/block-insert-picker] No Portable Text member schema context found and no ' +\n          '`arrayTypeName` resolved to an array type — the picker is disabled for this field.',\n      )\n      return\n    }\n    if (itemsContext && items && !warned.unknown) {\n      const unknown = unknownMetadataTypes(itemsContext, items)\n      if (unknown.length > 0) {\n        warned.unknown = true\n        console.warn(\n          `[@sanity/block-insert-picker] \\`items\\` metadata references types that are not ` +\n            `members of this array: ${unknown.join(', ')}`,\n        )\n      }\n    }\n    if (itemsContext && !hasItems && !warned.empty) {\n      warned.empty = true\n      console.warn(\n        '[@sanity/block-insert-picker] No insertable items: the array has no non-text-block ' +\n          'members (and `resolveItems` added none) — the picker is disabled for this field.',\n      )\n    }\n  }, [hasItems, items, itemsContext])\n\n  const [state, dispatch] = useReducer(pickerReducer, {mode: 'closed'})\n\n  // stateRef gives behavior callbacks synchronous access to the latest state\n  // without needing to re-register the behavior on every state change.\n  // useLayoutEffect (vs useEffect) ensures the ref is in sync before paint,\n  // closing a stale-read window for chained behavior events within a tick.\n  const stateRef = useRef<PickerState>(state)\n  useLayoutEffect(() => {\n    stateRef.current = state\n  })\n\n  // The shortcut flag is read through a ref for the same reason: the guard\n  // consults it per keystroke, so toggling it must not re-register (and\n  // re-sort) the behavior chain.\n  const shortcutRef = useRef(shortcut)\n  useLayoutEffect(() => {\n    shortcutRef.current = shortcut\n  })\n\n  const open = state.mode !== 'closed'\n  const query = open ? state.query : ''\n  const mode = open ? state.mode : null\n\n  const filterItems = filter ?? filterPickerItems\n  // The filter seam receives the query without the slash-mode \"/\" prefix, so\n  // a custom `filter` sees the same bare text in both modes. The raw query\n  // keeps driving the empty-state label, the shortcut echo, and onInsert.\n  const filterQuery = mode === 'slash' ? bareQuery(query) : query\n\n  // Sections drive the rendered layout (group headers); `filtered` is the same\n  // items flattened into the single index space navigation and selection share.\n  const sections = useMemo(\n    () => groupPickerItems(filterItems(pickerItems, filterQuery)),\n    [filterItems, filterQuery, pickerItems],\n  )\n  const filtered = useMemo(() => flattenSections(sections), [sections])\n  // Rows resolve their flat index positionally (section offset + row index),\n  // never by item id: a resolveItems-appended item may reuse a derived id,\n  // and an id-keyed map would point both rows at one index.\n  const sectionOffsets = useMemo(() => {\n    const offsets: number[] = []\n    let total = 0\n    for (const section of sections) {\n      offsets.push(total)\n      total += section.items.length\n    }\n    return offsets\n  }, [sections])\n  // A lone section carries no useful category label (e.g. a curated `items`\n  // prop, or a filter that matched a single group) — skip the header chrome.\n  const showGroupHeaders = sections.length > 1\n\n  // Guards the async select path: a second select arriving while a slow\n  // initial-value resolution is in flight must not double-insert.\n  const insertInFlightRef = useRef(false)\n\n  // Plain functions below (no useCallback): the React Compiler memoizes\n  // them, and its lint rule rejects hand-written dependency arrays here.\n  // Core selection logic: given a resolved item index into the filtered list for\n  // `current` state, perform the insertion. Extracted so both keyboard-Enter\n  // (via handleIntent) and mouse-click (via selectItemAtIndex) share the same\n  // path without reading a potentially-stale highlightedIndex from stateRef.\n  // The initial value resolves at select time (mirroring Studio's own toolbar\n  // handleInsertBlock flow) so the first select in a session can't race an\n  // eager cache, and resolution errors surface instead of being swallowed.\n  const insertItemAtIndex = async (\n    current: Exclude<PickerState, {mode: 'closed'}>,\n    idx: number,\n  ) => {\n    if (insertInFlightRef.current) {\n      // A prior select is still resolving; bail to avoid a double-insert. Still\n      // close, because the user may have reopened the picker mid-flight and a\n      // stuck-open menu that swallows this Enter looks broken.\n      dispatch({type: 'close'})\n      return\n    }\n    insertInFlightRef.current = true\n    try {\n      // Index into the grouped display order (not the raw rank-flat order)\n      // so the row the user sees highlighted is the one that gets inserted.\n      const visible = flattenSections(\n        groupPickerItems(\n          filterItems(\n            pickerItems,\n            current.mode === 'slash' ? bareQuery(current.query) : current.query,\n          ),\n        ),\n      )\n      const clamped = Math.max(0, Math.min(visible.length - 1, idx))\n      const chosen = visible[clamped]\n      // Close immediately for a snappy response; the insert continues from\n      // the captured `current` state.\n      dispatch({type: 'close'})\n      if (!chosen) return\n      if (chosen.action.type === 'custom') {\n        // No block to insert: clean up the typed \"/query\" text (slash mode)\n        // and hand the editor to the host's action.\n        sendCleanupQuery(editor, {\n          anchorBlockKey: current.anchorBlockKey,\n          mode: current.mode,\n          query: current.query,\n        })\n        chosen.action.onSelect({\n          closePicker: () => dispatch({type: 'close'}),\n          editor,\n        })\n        return\n      }\n      const blockType = chosen.action.blockType\n      let initialValue: Record<string, unknown> | undefined\n      const schemaType = memberTypeFor(itemsContext, schema, blockType)\n      if (schemaType) {\n        initialValue = (await resolveInitialValueForType(schemaType, {})) ?? undefined\n      }\n      // Re-take the snapshot after the await; the document may have changed.\n      // A null selection is fine: the insert behavior anchors the block via\n      // `at` from anchorBlockKey, so a blur during a slow resolution (or a\n      // shortcut-mode open with no selection) must not abort the insert.\n      const snapshot = editor.getSnapshot()\n      // Confirm the anchor block still exists in the document; if it was\n      // deleted while the picker was open we have nothing to anchor against.\n      const anchorStillExists = snapshot.context.value.some(\n        (b) => b._key === current.anchorBlockKey,\n      )\n      if (!anchorStillExists) {\n        toast.push({\n          closable: true,\n          description: labels.insertAnchorRemoved,\n          status: 'warning',\n          title: labels.insertError,\n        })\n        return\n      }\n      insertPickerItem({\n        anchorBlockKey: current.anchorBlockKey,\n        blockType,\n        editor,\n        initialValue,\n        keyGenerator: () => snapshot.context.keyGenerator(),\n        mode: current.mode,\n        onInsertedKey: (key) => {\n          if (chosen.openOnInsert ?? openOnInsert) openBlockOnInsert(key)\n          onInsert?.({\n            blockKey: key,\n            blockType,\n            mode: current.mode,\n            query: current.query,\n            via: 'picker',\n          })\n        },\n        query: current.query,\n      })\n    } catch (error) {\n      // insertItemAtIndex is fire-and-forget (`void insertItemAtIndex(...)`),\n      // so anything thrown here — initial-value resolution, a host `filter`,\n      // a custom action's onSelect, a host onInsert — would otherwise become\n      // an unhandled rejection with no user feedback.\n      toast.push({\n        closable: true,\n        description: error instanceof Error ? error.message : String(error),\n        status: 'error',\n        title: labels.insertError,\n      })\n    } finally {\n      insertInFlightRef.current = false\n    }\n  }\n\n  // Rows call this from onClick with their own index rather than reading\n  // highlightedIndex: the onMouseMove highlight update for the row under the\n  // cursor may not have flushed yet, so passing idx avoids inserting the\n  // previously-highlighted row.\n  const selectItemAtIndex = (idx: number) => {\n    const current = stateRef.current\n    if (current.mode === 'closed') return\n    void insertItemAtIndex(current, idx)\n  }\n\n  const handleIntent = (intent: PickerIntent) => {\n    if (intent.type === 'navigate') {\n      // The reducer deliberately doesn't clamp (it can't know the filtered\n      // list length), so resolve the move here. Clamping the base index too\n      // self-heals any stored value that has drifted out of range — an\n      // unclamped store makes reversed arrow presses appear \"dead\" while a\n      // hidden out-of-bounds index counts back into range.\n      const current = stateRef.current\n      if (current.mode === 'closed') return\n      const lastIndex = filtered.length - 1\n      const base = Math.max(0, Math.min(lastIndex, current.highlightedIndex))\n      const next = Math.max(0, Math.min(lastIndex, base + intent.delta))\n      dispatch({index: next, type: 'setHighlightedIndex'})\n      return\n    }\n    if (intent.type !== 'select') {\n      dispatch(intent)\n      return\n    }\n    // Resolve the currently-highlighted item against the filtered list.\n    const current = stateRef.current\n    if (current.mode === 'closed') return\n    void insertItemAtIndex(current, current.highlightedIndex)\n  }\n\n  // handleIntentRef lets the behavior always call the latest handleIntent\n  // without needing to re-register the behavior when items changes.\n  // useLayoutEffect for the same stale-read-window reason as stateRef above.\n  const handleIntentRef = useRef<(intent: PickerIntent) => void>(handleIntent)\n  useLayoutEffect(() => {\n    handleIntentRef.current = handleIntent\n  })\n\n  // Register behaviors imperatively so their lifecycle follows this\n  // component's — and only while there is anything to offer: with zero\n  // items the picker must never open (no empty popover, no swallowed \"/\").\n  // The picker behavior watches typing/keys; the insert behavior performs\n  // the atomic cleanup + insert when a custom.blockInsertPicker.insert\n  // event arrives; the cleanup behavior serves `custom` item actions.\n  useEffect(() => {\n    if (!hasItems) return undefined\n    const behavior = createPickerBehavior({\n      getState: () => stateRef.current,\n      isShortcutEnabled: () => shortcutRef.current,\n      onIntent: (intent) => handleIntentRef.current(intent),\n    })\n    const unregisterPicker = editor.registerBehavior({behavior})\n    const unregisterInsert = editor.registerBehavior({\n      behavior: createInsertBehavior(),\n    })\n    const unregisterCleanup = editor.registerBehavior({\n      behavior: createCleanupQueryBehavior(),\n    })\n    return () => {\n      unregisterPicker()\n      unregisterInsert()\n      unregisterCleanup()\n    }\n  }, [editor, hasItems])\n\n  // If the item list empties while the picker is open (a resolveItems change,\n  // a schema hot-reload), the behaviors above unregister — close the popover\n  // rather than leaving a zombie that no behavior can drive.\n  useEffect(() => {\n    if (!hasItems && stateRef.current.mode !== 'closed') dispatch({type: 'close'})\n  }, [hasItems])\n\n  // --- UI ---\n\n  const highlightedIndex = open\n    ? Math.max(0, Math.min(filtered.length - 1, state.highlightedIndex))\n    : 0\n\n  // Announced to screen readers via a polite live region: the focus stays in\n  // the editor, so aria-selected alone would never be read aloud. Recomputing\n  // this on every highlight/filter change lets assistive tech track the list.\n  const highlightedItem = open ? filtered[highlightedIndex] : undefined\n  const announcement = highlightedItem\n    ? [\n        highlightedItem.title,\n        highlightedItem.description,\n        formatPosition(labels, highlightedIndex + 1, filtered.length),\n      ]\n        .filter(Boolean)\n        .join(', ')\n    : ''\n\n  // Capture the caret DOMRect once when the picker opens and hand Popover a\n  // virtual reference element wrapping it. The rect\n  // is intentionally pinned at the opening position — re-capturing on every\n  // `state` change (e.g. each keystroke that updates `query`) would make the\n  // popover drift right as the caret advances through typed characters.\n  // editor.dom is the supported anchoring API; a collapsed caret in an empty\n  // block can yield an all-zero rect in some browsers, so fall back to the\n  // block element's rect in that case.\n  const [cursorRect, setCursorRect] = useState<DOMRect | null>(null)\n\n  useLayoutEffect(() => {\n    if (!open) {\n      // oxlint-disable-next-line react/react-compiler\n      setCursorRect(null)\n      return\n    }\n    const snapshot = editor.getSnapshot()\n    const rect = editor.dom.getSelectionRect(snapshot)\n    if (rect && (rect.x || rect.y || rect.width || rect.height)) {\n      setCursorRect(rect)\n      return\n    }\n    const blockRect = editor.dom.getStartBlockElement(snapshot)?.getBoundingClientRect()\n    if (blockRect) setCursorRect(blockRect)\n  }, [editor, open])\n\n  // Close on any pointerdown outside the popover (clicking into another block\n  // must not leave a zombie picker that later intercepts Enter), and when\n  // focus leaves the editor entirely (e.g. Tab). @sanity/ui's Popover has no\n  // onClickOutside prop — that lives on Menu/Dialog — so listen manually.\n  const popoverContentRef = useRef<HTMLDivElement | null>(null)\n\n  useEffect(() => {\n    if (!open) return undefined\n    const handlePointerDown = (event: PointerEvent) => {\n      const target = event.target\n      if (target instanceof Node && popoverContentRef.current?.contains(target)) return\n      dispatch({type: 'close'})\n    }\n    // getEditorElement is typed as Element, whose addEventListener overload\n    // hands the listener a plain Event; narrow to FocusEvent inside instead\n    // of asserting the element type.\n    const editorElement = editor.dom.getEditorElement()\n    const handleFocusOut = (event: Event) => {\n      const next = event instanceof FocusEvent ? event.relatedTarget : null\n      if (\n        next instanceof Node &&\n        (editorElement?.contains(next) || popoverContentRef.current?.contains(next))\n      )\n        return\n      dispatch({type: 'close'})\n    }\n    document.addEventListener('pointerdown', handlePointerDown, true)\n    editorElement?.addEventListener('focusout', handleFocusOut)\n    return () => {\n      document.removeEventListener('pointerdown', handlePointerDown, true)\n      editorElement?.removeEventListener('focusout', handleFocusOut)\n    }\n  }, [editor, open])\n\n  // Keep the highlighted row visible inside the scrolling list.\n  const highlightedRowRef = useRef<HTMLDivElement | null>(null)\n\n  // Hover may only move the highlight on genuine pointer movement. When\n  // keyboard navigation scrolls the list (scrollIntoView below), rows slide\n  // under a stationary cursor and the browser fires mouseenter — and, in some\n  // engines, a coordinate-identical mousemove — on whichever row lands there.\n  // Honoring those synthetic events hijacks the keyboard highlight back to\n  // wherever the mouse happens to rest. Track the last seen coordinates and\n  // require them to change before hover wins; the first event only seeds.\n  const lastPointerRef = useRef<null | {x: number; y: number}>(null)\n\n  const highlightOnPointerMove = (idx: number, x: number, y: number) => {\n    const last = lastPointerRef.current\n    lastPointerRef.current = {x, y}\n    if (!last || (last.x === x && last.y === y)) return\n    const current = stateRef.current\n    if (current.mode !== 'closed' && idx !== current.highlightedIndex) {\n      dispatch({index: idx, type: 'setHighlightedIndex'})\n    }\n  }\n\n  useEffect(() => {\n    highlightedRowRef.current?.scrollIntoView({block: 'nearest'})\n  }, [highlightedIndex])\n\n  // Stable virtual element derived from the captured rect — keeps Popover\n  // positioning stable even as `state` changes while the picker is open.\n  const cursorElement = useMemo(() => {\n    if (!cursorRect) return null\n    // Popover types referenceElement as HTMLElement, but its positioning\n    // only ever reads getBoundingClientRect — the standard virtual-element\n    // escape hatch for anchoring to a caret rect.\n    // oxlint-disable-next-line no-unsafe-type-assertion\n    return {\n      getBoundingClientRect: () => cursorRect,\n    } as unknown as HTMLElement\n  }, [cursorRect])\n\n  if (!open) return null\n\n  if (filtered.length === 0) {\n    return (\n      <Popover\n        constrainSize\n        content={\n          <Card\n            aria-live=\"polite\"\n            onMouseDown={preventFocusSteal}\n            padding={3}\n            radius={2}\n            ref={popoverContentRef}\n            // Card renders (and refs) a div; an <output> would change the\n            // element type the outside-pointerdown ref relies on.\n            // oxlint-disable-next-line prefer-tag-over-role\n            role=\"status\"\n          >\n            <Text muted size={1}>\n              {formatNoMatches(labels, query)}\n            </Text>\n          </Card>\n        }\n        fallbackPlacements={['top-start']}\n        open\n        placement=\"bottom-start\"\n        portal\n        preventOverflow\n        referenceElement={cursorElement}\n      />\n    )\n  }\n\n  return (\n    <Popover\n      constrainSize\n      content={\n        <Card\n          onMouseDown={preventFocusSteal}\n          padding={1}\n          radius={2}\n          ref={popoverContentRef}\n          style={{\n            display: 'flex',\n            flexDirection: 'column',\n            maxHeight: '100%',\n            minWidth: 300,\n          }}\n        >\n          {/* Focus stays in the editor, so aria-selected on rows is never read\n              aloud on its own. This polite region carries the open state and\n              each highlight change to assistive tech. */}\n          <output aria-live=\"polite\" style={SR_ONLY}>\n            {announcement}\n          </output>\n          <Flex align=\"center\" flex=\"none\" gap={2} padding={2}>\n            <Box flex={1}>\n              <Text\n                muted\n                size={0}\n                style={{letterSpacing: '0.05em', textTransform: 'uppercase'}}\n                weight=\"medium\"\n              >\n                {labels.title}\n              </Text>\n            </Box>\n            {mode === 'shortcut' && query !== '' ? (\n              // Shortcut-mode typing never reaches the document, so echo the\n              // captured query here — otherwise keystrokes appear to vanish.\n              <Text muted size={1} textOverflow=\"ellipsis\">\n                {query}\n              </Text>\n            ) : null}\n          </Flex>\n          <Box\n            aria-label={labels.title}\n            id={listboxId}\n            // A custom ARIA listbox: <select>/<datalist> cannot host rich\n            // rows (icons, descriptions, hotkey chips) or grouped sections.\n            // oxlint-disable-next-line prefer-tag-over-role\n            role=\"listbox\"\n            style={{flex: 1, maxHeight: 320, minHeight: 0, overflowY: 'auto'}}\n          >\n            {sections.map((section, sectionIndex) => {\n              const sectionLabel = section.group ?? labels.ungroupedSection\n              // Key on the raw group (namespaced), not the display label: a\n              // curated group named the same as `ungroupedSection` would\n              // otherwise share a React key with the null-group section.\n              const sectionKey = section.group === null ? 'ungrouped' : `group:${section.group}`\n              const rows = section.items.map((item, rowIndex) => {\n                const idx = (sectionOffsets[sectionIndex] ?? 0) + rowIndex\n                const Icon = item.icon\n                const isHighlighted = idx === highlightedIndex\n                return (\n                  <Card\n                    aria-selected={isHighlighted}\n                    id={optionId(String(idx))}\n                    key={`${item.id}-${idx}`}\n                    onClick={() => selectItemAtIndex(idx)}\n                    onMouseMove={(event) =>\n                      highlightOnPointerMove(idx, event.clientX, event.clientY)\n                    }\n                    padding={2}\n                    radius={1}\n                    ref={isHighlighted ? highlightedRowRef : undefined}\n                    // A native <option> only works inside <select>; these are\n                    // ARIA options in a custom listbox rendered from Cards.\n                    // oxlint-disable-next-line prefer-tag-over-role\n                    role=\"option\"\n                    style={{cursor: 'pointer'}}\n                    // Focusable in principle (never via Tab): DOM focus stays\n                    // in the editor and the live region does the announcing.\n                    tabIndex={-1}\n                    tone={isHighlighted ? 'primary' : 'default'}\n                  >\n                    <Flex align=\"center\" gap={3}>\n                      <Box\n                        style={{\n                          alignItems: 'center',\n                          display: 'flex',\n                          height: 22,\n                          justifyContent: 'center',\n                          width: 22,\n                        }}\n                      >\n                        {Icon ? <Icon /> : null}\n                      </Box>\n                      <Stack flex={1} gap={2}>\n                        <Text size={1} textOverflow=\"ellipsis\">\n                          {item.title}\n                        </Text>\n                        {item.description ? (\n                          <Text muted size={0} textOverflow=\"ellipsis\">\n                            {item.description}\n                          </Text>\n                        ) : null}\n                      </Stack>\n                      {item.badge ? (\n                        <Box flex=\"none\">\n                          <Text muted size={0}>\n                            {item.badge}\n                          </Text>\n                        </Box>\n                      ) : null}\n                      {item.trigger ? (\n                        <Box flex=\"none\">\n                          <Hotkeys fontSize={0} keys={[item.trigger]} />\n                        </Box>\n                      ) : null}\n                    </Flex>\n                  </Card>\n                )\n              })\n              if (!showGroupHeaders) {\n                return (\n                  <Stack key={sectionKey} gap={1}>\n                    {rows}\n                  </Stack>\n                )\n              }\n              return (\n                <Box\n                  aria-label={sectionLabel}\n                  key={sectionKey}\n                  paddingTop={sectionIndex === 0 ? 0 : 2}\n                  // Grouped options inside a listbox: role=\"group\" is the\n                  // valid ARIA structure here; the tags the rule suggests\n                  // (fieldset, address, …) are not permitted in a listbox.\n                  // oxlint-disable-next-line prefer-tag-over-role\n                  role=\"group\"\n                >\n                  <Box paddingBottom={1} paddingTop={2} paddingX={2}>\n                    <Text\n                      muted\n                      size={0}\n                      style={{\n                        letterSpacing: '0.05em',\n                        textTransform: 'uppercase',\n                      }}\n                      weight=\"medium\"\n                    >\n                      {sectionLabel}\n                    </Text>\n                  </Box>\n                  <Stack gap={1}>{rows}</Stack>\n                </Box>\n              )\n            })}\n          </Box>\n          <Card borderTop flex=\"none\" padding={2} radius={0}>\n            <Flex align=\"center\" gap={3} wrap=\"wrap\">\n              <FooterHint keys={['↑', '↓']} label={labels.footerNavigate} />\n              <FooterHint keys={['↵']} label={labels.footerInsert} />\n              <FooterHint keys={['Esc']} label={labels.footerDismiss} />\n              {shortcut ? (\n                <FooterHint keys={[OPEN_MODIFIER, '/']} label={labels.footerAnywhere} />\n              ) : null}\n            </Flex>\n          </Card>\n        </Card>\n      }\n      fallbackPlacements={['top-start']}\n      open\n      placement=\"bottom-start\"\n      portal\n      preventOverflow\n      referenceElement={cursorElement}\n    />\n  )\n}\n\n// A single key legend in the teaching footer: the key chips plus a short verb.\nfunction FooterHint({keys, label}: {keys: string[]; label: string}) {\n  return (\n    <Flex align=\"center\" gap={2}>\n      <Hotkeys fontSize={0} keys={keys} />\n      <Text muted size={0}>\n        {label}\n      </Text>\n    </Flex>\n  )\n}\n\n// Module-level (not a component closure) so useMemo dependency arrays don't\n// need a function that the react-hooks lint flags as changing every render.\n// Member types resolve from the picker's items context first (member-level\n// config wins), then from the global type of the same name — the same\n// fallback the previous arrayTypeName-only lookup used.\nfunction memberTypeFor(\n  itemsContext: PickerItemsContext | null,\n  schema: {get(name: string): SchemaType | undefined},\n  blockType: string,\n): SchemaType | undefined {\n  const member = itemsContext?.memberTypes.find((candidate) => candidate.name === blockType)\n  return member ?? schema.get(blockType)\n}\n\n// Slash-mode queries carry the leading \"/\" the writer typed; the filter seam\n// works on the bare text (see filterQuery above).\nfunction bareQuery(query: string): string {\n  return query.startsWith('/') ? query.slice(1) : query\n}\n\n// Interacting with any popover surface (header, padding, the scroll\n// container's scrollbar) must not steal DOM focus from the editor: the blur\n// would trip the focusout close listener and dismiss the picker mid-use.\nfunction preventFocusSteal(event: {preventDefault: () => void}) {\n  event.preventDefault()\n}\n\n// Visually hidden but present in the accessibility tree — used for the live\n// region so announcements don't disturb the popover layout.\nconst SR_ONLY: CSSProperties = {\n  border: 0,\n  clipPath: 'inset(50%)',\n  height: 1,\n  margin: -1,\n  overflow: 'hidden',\n  padding: 0,\n  position: 'absolute',\n  whiteSpace: 'nowrap',\n  width: 1,\n}\n\n// The Cmd+/ shortcut symbol matches the platform: ⌘ on Apple, Ctrl elsewhere.\n// navigator.platform is deprecated but still the most reliable signal here;\n// fall back to the user agent, then to Ctrl when neither is available.\nconst IS_APPLE_PLATFORM =\n  typeof navigator !== 'undefined' &&\n  /mac|iphone|ipad|ipod/i.test(navigator.platform || navigator.userAgent || '')\nconst OPEN_MODIFIER = IS_APPLE_PLATFORM ? '⌘' : 'Ctrl'\n","import {useEditor} from '@portabletext/editor'\nimport {defineInputRuleBehavior} from '@portabletext/plugin-input-rule'\nimport {useEffect, useLayoutEffect, useMemo, useRef} from 'react'\n\nimport {typeNameChain} from './deriveItems'\nimport {createMarkdownInputRules, type MarkdownInputRuleConfig} from './inputRules'\nimport {usePickerItemsContext} from './memberSchemaTypes'\nimport {useOpenBlockOnInsert} from './openBlockOnInsert'\nimport type {PickerInsertEvent} from './types'\n\nexport type MarkdownInputRulesProps = {\n  /**\n   * Escape hatch: names the portable-text array type when Studio's\n   * member-schema context is unavailable (see BlockInsertPickerProps).\n   * Rules are only enabled for block types the array actually allows.\n   */\n  arrayTypeName?: string\n  /** The markdown transforms to enable (see inputRules.ts). */\n  rules: readonly MarkdownInputRuleConfig[]\n  /** Notified after each successful insert, alongside open-on-insert. */\n  onInsert?: (event: PickerInsertEvent) => void\n  /** Whether an inserted block opens for editing (default true). */\n  openOnInsert?: boolean\n}\n\n/**\n * Mounts markdown input rules on the PTE and opens each inserted block for\n * editing once its member item mounts — the same open-on-insert behavior the\n * picker uses, so a fenced code block lands ready to type into.\n */\nexport function MarkdownInputRules({\n  arrayTypeName,\n  onInsert,\n  openOnInsert = true,\n  rules,\n}: MarkdownInputRulesProps) {\n  const editor = useEditor()\n  const itemsContext = usePickerItemsContext(arrayTypeName)\n  const openBlockOnInsert = useOpenBlockOnInsert()\n\n  // Rules resolve against the array's insertable members with the same\n  // precedence as picker item metadata: a rule's blockType matches a member\n  // by name first, then by any name in the member's resolved type chain — so\n  // wellKnownInputRules' `code` fence also serves `{type: 'code', name:\n  // 'snippet'}`, with the inserted `_type` rewritten to the member name the\n  // array actually accepts. Rules matching nothing are dropped here, which\n  // also keeps `block` itself (and aliased text blocks) unreachable.\n  const resolvedRules = useMemo(() => {\n    const memberTypes = itemsContext?.memberTypes ?? []\n    return rules.flatMap((rule) => {\n      const member =\n        memberTypes.find((candidate) => candidate.name === rule.blockType) ??\n        memberTypes.find((candidate) => typeNameChain(candidate).includes(rule.blockType))\n      if (!member) return []\n      return [rule.blockType === member.name ? rule : {...rule, blockType: member.name}]\n    })\n  }, [itemsContext, rules])\n\n  // The insert callbacks are routed through a ref (same pattern as\n  // BlockInsertPicker's handleIntentRef) so the registration effect below\n  // stays keyed on the rules/schema/editor only: re-registering a behavior\n  // is not free (it tears down and re-sorts the editor's behavior chain, and\n  // moves this behavior after later-registered ones), so a host passing an\n  // inline onInsert must not cause per-render churn.\n  const onInsertedRef = useRef<(block: {_key: string; _type: string}) => void>(() => {})\n  useLayoutEffect(() => {\n    onInsertedRef.current = (block) => {\n      if (openOnInsert) openBlockOnInsert(block._key)\n      onInsert?.({\n        blockKey: block._key,\n        blockType: block._type,\n        via: 'inputRule',\n      })\n    }\n  })\n\n  // Register the input-rule behavior imperatively rather than through the\n  // <InputRulePlugin>\n  // component: the rule closures then live inside an effect and can schedule\n  // the open-on-insert without hitting the React Compiler's \"no refs during\n  // render\" rule. Each transform is still a single undo step (the plugin\n  // applies the delete + insert as one behavior action set).\n  useEffect(() => {\n    const inputRules = createMarkdownInputRules({\n      // resolvedRules are already narrowed to insertable members.\n      allowedBlockTypes: new Set(resolvedRules.map((rule) => rule.blockType)),\n      // The generator is read per insert so keys stay unique across a session.\n      keyGenerator: () => editor.getSnapshot().context.keyGenerator(),\n      onInserted: (block) => onInsertedRef.current(block),\n      rules: resolvedRules,\n    })\n    if (inputRules.length === 0) return undefined\n    return editor.registerBehavior({\n      behavior: defineInputRuleBehavior({rules: inputRules}),\n    })\n  }, [editor, resolvedRules])\n\n  return null\n}\n","import type {ComponentType} from 'react'\nimport type {PortableTextPluginsProps} from 'sanity'\n\nimport {BlockInsertPicker} from './blockInsertPicker'\nimport type {MarkdownInputRuleConfig} from './inputRules'\nimport type {BlockInsertPickerLabels} from './labels'\nimport {MarkdownInputRules} from './markdownInputRules'\nimport type {PickerInsertEvent, PickerItem, PickerItemMetadata, PickerItemsResolver} from './types'\n\nexport interface BlockInsertPickerConfig {\n  /**\n   * Per-member curation (slash trigger, alias keywords, section grouping,\n   * description, badge, visibility, per-item open-on-insert) merged into the\n   * items derived from the array's members; array order is the sort rank.\n   * Members without an entry still get picker items, appended in schema\n   * order. Entries whose `type` matches no member warn in dev mode.\n   */\n  items?: readonly PickerItemMetadata[]\n  /**\n   * Programmatic seam over the derived item list — reorder, remove, relabel,\n   * or append items (including `custom`-action items) — running after schema\n   * derivation, presets, and `items` metadata.\n   */\n  resolveItems?: PickerItemsResolver\n  /**\n   * Markdown-style transforms (for example from the {@link codeFenceRule} and\n   * {@link blockquoteRule} factories) that replace typed text with an\n   * inserted block, as one undo step. Opt-in only; rules targeting block\n   * types the array does not allow are ignored.\n   */\n  inputRules?: readonly MarkdownInputRuleConfig[]\n  /**\n   * Replaces the built-in matching (case-insensitive substring over title,\n   * keywords, and description, plus trigger prefixes). Receives the bare\n   * query in both modes — the slash-mode \"/\" prefix is stripped.\n   */\n  filter?: (items: readonly PickerItem[], query: string) => readonly PickerItem[]\n  /** Overrides for the picker chrome's user-facing strings. */\n  labels?: Partial<BlockInsertPickerLabels>\n  /**\n   * Notified after each successful insert — picker selection or input rule —\n   * alongside the built-in open-for-editing behavior.\n   */\n  onInsert?: (event: PickerInsertEvent) => void\n  /**\n   * Whether an inserted block opens for editing (default true). Items can\n   * override per member via their metadata's `openOnInsert`.\n   */\n  openOnInsert?: boolean\n  /** Whether Cmd/Ctrl+/ opens the picker (default true). */\n  shortcut?: boolean\n  /**\n   * Whether well-known block types (image, file, code, table, ...) get\n   * default triggers and keywords when `items` doesn't cover them\n   * (default true). See {@link standardBlockPresets}.\n   */\n  presets?: boolean\n  /**\n   * Escape hatch: names the portable-text array type to resolve items\n   * against when Studio's member-schema context is unavailable. Normally\n   * unnecessary — the containing array and its members are detected\n   * automatically from where the plugin is mounted.\n   */\n  arrayTypeName?: string\n}\n\n/**\n * Creates the Portable Text editor plugins component for the block-insert\n * picker: a slash-command / Cmd+/ menu of the blocks the host array allows,\n * plus optional markdown input rules. Zero-config is the intended call —\n * items derive from the array the plugin is mounted on. Attach it to the\n * array type's `components.portableText.plugins`:\n *\n * ```ts\n * defineType({\n *   name: 'content',\n *   type: 'array',\n *   of: [{type: 'block'}, {type: 'callout'}],\n *   components: {\n *     portableText: {\n *       plugins: blockInsertPicker(),\n *     },\n *   },\n * })\n * ```\n */\nexport function blockInsertPicker(\n  config: BlockInsertPickerConfig = {},\n): ComponentType<PortableTextPluginsProps> {\n  const {\n    arrayTypeName,\n    filter,\n    inputRules,\n    items,\n    labels,\n    onInsert,\n    openOnInsert,\n    presets,\n    resolveItems,\n    shortcut,\n  } = config\n  return function BlockInsertPickerPlugins(props: PortableTextPluginsProps) {\n    return (\n      <>\n        {props.renderDefault(props)}\n        {inputRules?.length ? (\n          <MarkdownInputRules\n            arrayTypeName={arrayTypeName}\n            onInsert={onInsert}\n            openOnInsert={openOnInsert}\n            rules={inputRules}\n          />\n        ) : null}\n        <BlockInsertPicker\n          arrayTypeName={arrayTypeName}\n          filter={filter}\n          items={items}\n          labels={labels}\n          onInsert={onInsert}\n          openOnInsert={openOnInsert}\n          presets={presets}\n          resolveItems={resolveItems}\n          shortcut={shortcut}\n        />\n      </>\n    )\n  }\n}\n"],"mappings":"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"}
\ No newline at end of file