@pipe0/react 0.0.14 → 0.0.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @pipe0/elements-react
2
2
 
3
+ ## 0.0.16
4
+
5
+ ### Patch Changes
6
+
7
+ - e5781b6: Make search payloads as optional
8
+ - 3333671: Update client to use search instead of searches
9
+ - Updated dependencies [e5781b6]
10
+ - Updated dependencies [3333671]
11
+ - @pipe0/base@0.1.3
12
+
13
+ ## 0.0.15
14
+
15
+ ### Patch Changes
16
+
17
+ - dcfa37f: Add github pipe
18
+ - Updated dependencies [dcfa37f]
19
+ - @pipe0/base@0.1.2
20
+
3
21
  ## 0.0.14
4
22
 
5
23
  ### Patch Changes
@@ -20,7 +20,7 @@ function SearchFormSubmitButton({ className, children, render, disabled: disable
20
20
  props: mergeProps({
21
21
  type: "submit",
22
22
  disabled,
23
- className: cn(buttonVariants({}), "pz:mt-4", className),
23
+ className: cn(buttonVariants({}), "", className),
24
24
  children: children ?? (isSubmitting ? "Submitting..." : "Submit"),
25
25
  "data-p0": "submit"
26
26
  }, props)
@@ -1 +1 @@
1
- {"version":3,"file":"submit-button.mjs","names":[],"sources":["../../../../src/components/compound/search-form/submit-button.tsx"],"sourcesContent":["import { mergeProps } from \"@base-ui/react/merge-props\";\nimport { useRender } from \"@base-ui/react/use-render\";\nimport { useSearchFormContext } from \"../../../context/search-form-context.js\";\nimport { cn } from \"../../../lib/utils.js\";\nimport { buttonVariants } from \"../../ui/button.js\";\n\nexport interface SearchFormSubmitButtonState {\n isSubmitting: boolean;\n isFieldLoaderLoading: boolean;\n disabled: boolean;\n}\n\nexport interface SearchFormSubmitButtonProps\n extends useRender.ComponentProps<\"button\", SearchFormSubmitButtonState> {}\n\nexport function SearchFormSubmitButton({\n className,\n children,\n render,\n disabled: disabledProp,\n ...props\n}: SearchFormSubmitButtonProps) {\n const { form, isFieldLoaderLoading } = useSearchFormContext();\n const isSubmitting = form.formState.isSubmitting;\n const disabled = disabledProp ?? (isSubmitting || isFieldLoaderLoading);\n\n return useRender({\n defaultTagName: \"button\",\n render,\n state: { isSubmitting, isFieldLoaderLoading, disabled },\n props: mergeProps<\"button\">(\n {\n type: \"submit\",\n disabled,\n className: cn(buttonVariants({}), \"pz:mt-4\", className),\n children: children ?? (isSubmitting ? \"Submitting...\" : \"Submit\"),\n ...({ \"data-p0\": \"submit\" } as Record<string, string>),\n },\n props,\n ),\n });\n}\n"],"mappings":";;;;;;;AAeA,SAAgB,uBAAuB,EACrC,WACA,UACA,QACA,UAAU,cACV,GAAG,SAC2B;CAC9B,MAAM,EAAE,MAAM,yBAAyB,sBAAsB;CAC7D,MAAM,eAAe,KAAK,UAAU;CACpC,MAAM,WAAW,iBAAiB,gBAAgB;AAElD,QAAO,UAAU;EACf,gBAAgB;EAChB;EACA,OAAO;GAAE;GAAc;GAAsB;GAAU;EACvD,OAAO,WACL;GACE,MAAM;GACN;GACA,WAAW,GAAG,eAAe,EAAE,CAAC,EAAE,WAAW,UAAU;GACvD,UAAU,aAAa,eAAe,kBAAkB;GAClD,WAAW;GAClB,EACD,MACD;EACF,CAAC"}
1
+ {"version":3,"file":"submit-button.mjs","names":[],"sources":["../../../../src/components/compound/search-form/submit-button.tsx"],"sourcesContent":["import { mergeProps } from \"@base-ui/react/merge-props\";\nimport { useRender } from \"@base-ui/react/use-render\";\nimport { useSearchFormContext } from \"../../../context/search-form-context.js\";\nimport { cn } from \"../../../lib/utils.js\";\nimport { buttonVariants } from \"../../ui/button.js\";\n\nexport interface SearchFormSubmitButtonState {\n isSubmitting: boolean;\n isFieldLoaderLoading: boolean;\n disabled: boolean;\n}\n\nexport interface SearchFormSubmitButtonProps\n extends useRender.ComponentProps<\"button\", SearchFormSubmitButtonState> {}\n\nexport function SearchFormSubmitButton({\n className,\n children,\n render,\n disabled: disabledProp,\n ...props\n}: SearchFormSubmitButtonProps) {\n const { form, isFieldLoaderLoading } = useSearchFormContext();\n const isSubmitting = form.formState.isSubmitting;\n const disabled = disabledProp ?? (isSubmitting || isFieldLoaderLoading);\n\n return useRender({\n defaultTagName: \"button\",\n render,\n state: { isSubmitting, isFieldLoaderLoading, disabled },\n props: mergeProps<\"button\">(\n {\n type: \"submit\",\n disabled,\n className: cn(buttonVariants({}), \"\", className),\n children: children ?? (isSubmitting ? \"Submitting...\" : \"Submit\"),\n ...({ \"data-p0\": \"submit\" } as Record<string, string>),\n },\n props,\n ),\n });\n}\n"],"mappings":";;;;;;;AAeA,SAAgB,uBAAuB,EACrC,WACA,UACA,QACA,UAAU,cACV,GAAG,SAC2B;CAC9B,MAAM,EAAE,MAAM,yBAAyB,sBAAsB;CAC7D,MAAM,eAAe,KAAK,UAAU;CACpC,MAAM,WAAW,iBAAiB,gBAAgB;AAElD,QAAO,UAAU;EACf,gBAAgB;EAChB;EACA,OAAO;GAAE;GAAc;GAAsB;GAAU;EACvD,OAAO,WACL;GACE,MAAM;GACN;GACA,WAAW,GAAG,eAAe,EAAE,CAAC,EAAE,IAAI,UAAU;GAChD,UAAU,aAAa,eAAe,kBAAkB;GAClD,WAAW;GAClB,EACD,MACD;EACF,CAAC"}
@@ -171,7 +171,7 @@ function LiquidEditor({ value, onChange, inputFields, searchSecrets, searchConst
171
171
  });
172
172
  if (supportsOutput) legendEntries.push({
173
173
  key: "@",
174
- label: "to insert a directive"
174
+ label: "to add an output field"
175
175
  });
176
176
  return /* @__PURE__ */ jsxs(EditorContext.Provider, {
177
177
  value: { editor },
@@ -1 +1 @@
1
- {"version":3,"file":"LiquidEditor.mjs","names":[],"sources":["../../../../src/components/internal/LiquidEditor/LiquidEditor.tsx"],"sourcesContent":["import {\n type PipesFieldDefinitionWithName,\n RECORD_FIELD_TYPES,\n type RecordFieldType,\n} from \"@pipe0/base\";\nimport type { EditorProps } from \"@tiptap/pm/view\";\nimport { EditorContent, EditorContext, useEditor } from \"@tiptap/react\";\nimport StarterKit from \"@tiptap/starter-kit\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useAsyncRemoteSource } from \"../../../hooks/use-async-remote-source.js\";\nimport { cn } from \"../../../lib/utils.js\";\nimport type { ConstantSuggestion, SecretSuggestion } from \"../../../types/field-props.js\";\nimport { FieldLegend, type LegendEntry } from \"../field-legend.js\";\nimport { SuggestionMenu } from \"../suggestion-menu/suggestion-menu.js\";\nimport type { SuggestionItem } from \"../suggestion-menu/suggestion-menu-types.js\";\nimport { type ChipHit, TagChipDecoration } from \"../tag-chip-decoration.js\";\nimport { ChipEditPopover, type ChipEditTarget } from \"./ChipEditPopover.js\";\nimport {\n buildReferenceItems,\n parseQuery,\n type ReferenceContext,\n SECTION_CAP,\n UnifiedReferencePicker,\n} from \"./UnifiedReferencePicker.js\";\n\nexport type DirectiveKind = \"output\";\n\nexport interface LiquidEditorProps {\n value: string;\n onChange: (v: string) => void;\n inputFields: PipesFieldDefinitionWithName[];\n /**\n * Per-keystroke async searcher for secrets. Called from the `/` reference\n * picker as the user types. Calls are debounced and race-guarded — only\n * the response for the latest query is rendered.\n */\n searchSecrets?: (query: string) => Promise<SecretSuggestion[]>;\n /**\n * Per-keystroke async searcher for constants. Mirrors `searchSecrets`.\n */\n searchConstants?: (query: string) => Promise<ConstantSuggestion[]>;\n multiline?: boolean;\n /**\n * When true, the editor renders within `min-h`/`max-h` bounds. When\n * false, callers control the height via `className`. Default: true.\n */\n autoGrow?: boolean;\n directives?: DirectiveKind[];\n expectedFieldType?: RecordFieldType;\n placeholder?: string;\n className?: string;\n editorProps?: EditorProps;\n /**\n * Suppress the per-editor legend. Used by `key_value_list_input` which\n * renders a single legend below the entire list rather than per-cell.\n */\n hideLegend?: boolean;\n}\n\nfunction escapeHtml(s: string): string {\n return s.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n}\n\n/**\n * Reconciles single- and multi-line text into Tiptap-friendly HTML.\n * - Single-line: collapses whitespace runs containing newlines into a\n * single space and renders as one paragraph.\n * - Multi-line: paragraphs separated by blank lines (`\\n\\n+`); soft\n * breaks within a paragraph render as `<br>`. Leading spaces on each\n * line are preserved with `&nbsp;` so JSON-shaped payloads round-trip\n * through the editor.\n */\nfunction textToTiptapHTML(text: string, multiline: boolean): string {\n if (!multiline) {\n return `<p>${escapeHtml(text.replace(/\\s*\\n+\\s*/g, \" \"))}</p>`;\n }\n return escapeHtml(text)\n .split(/\\n\\n+/)\n .map((block) => {\n const lines = block.split(/\\n/);\n const htmlLines = lines\n .map((line) => line.replace(/^ +/, (spaces) => \"&nbsp;\".repeat(spaces.length)))\n .join(\"<br>\");\n return `<p>${htmlLines}</p>`;\n })\n .join(\"\");\n}\n\nconst OUTPUT_TEMPLATE = (fieldType: RecordFieldType): string => {\n if (fieldType === \"json\") {\n return `{% output FIELD_NAME, type: \"json\", schema: \"SCHEMA_NAME\", description: \"\" %}`;\n }\n return `{% output FIELD_NAME, type: \"${fieldType}\", description: \"\" %}`;\n};\n\n/**\n * Single editor surface for every form field that accepts Liquid tags.\n * Two triggers, two cognitive categories:\n *\n * - `/` opens a unified reference picker (Fields, Secrets, Constants).\n * Prefix syntax `/f/`, `/s/`, `/c/` filters to one source. Picking\n * emits the corresponding `{{ … }}` Liquid Output.\n *\n * - `@` opens a directives picker (only when `directives.length > 0`).\n * Today the only directive is `output`, which inserts a templated\n * `{% output FIELD_NAME, type: \"...\", description: \"\" %}` block.\n *\n * Chips render via the `TagChipDecoration` extension. Click or\n * Enter/Space on a chip mounts the contextual `ChipEditPopover`.\n *\n * Backwards compat: the persisted value is plain Liquid text,\n * byte-identical to what the legacy `TagEditor` / `TextPromptEditor`\n * produced. No engine, analyzer, or metadata changes.\n */\nexport function LiquidEditor({\n value,\n onChange,\n inputFields,\n searchSecrets,\n searchConstants,\n multiline = false,\n autoGrow = true,\n directives = [],\n expectedFieldType,\n placeholder,\n className,\n editorProps,\n hideLegend = false,\n}: LiquidEditorProps) {\n const blockSeparator = multiline ? \"\\n\" : \"\";\n const supportsOutput = directives.includes(\"output\");\n const hasSecretsResolver = !!searchSecrets;\n const hasConstantsResolver = !!searchConstants;\n\n const secretSource = useAsyncRemoteSource<SecretSuggestion>({ search: searchSecrets });\n const constantSource = useAsyncRemoteSource<ConstantSuggestion>({ search: searchConstants });\n\n // Warm caches once per resolver identity so the empty-query open is hot.\n useEffect(() => {\n secretSource.prefetch();\n }, [secretSource.prefetch]);\n\n useEffect(() => {\n constantSource.prefetch();\n }, [constantSource.prefetch]);\n\n const [chipTarget, setChipTarget] = useState<ChipEditTarget | null>(null);\n\n const tagChipExtension = useMemo(\n () =>\n TagChipDecoration.configure({\n onChipClick: (hit: ChipHit, el: HTMLElement) => {\n setChipTarget({\n kind: hit.kind,\n raw: hit.raw,\n from: hit.from,\n to: hit.to,\n rect: el.getBoundingClientRect(),\n });\n },\n }),\n [],\n );\n\n const editor = useEditor({\n extensions: [\n StarterKit.configure({ hardBreak: !multiline ? false : undefined }),\n tagChipExtension,\n ],\n parseOptions: { preserveWhitespace: \"full\" },\n editorProps: {\n ...editorProps,\n attributes: {\n class: cn(\n \"pz:px-2.5 pz:py-1 pz:text-sm pz:outline-none pz:break-words\",\n multiline\n ? autoGrow\n ? \"pz:min-h-24 pz:max-h-96 pz:overflow-auto pz:whitespace-pre-wrap\"\n : \"pz:overflow-auto pz:whitespace-pre-wrap\"\n : \"pz:min-h-8\",\n className,\n ),\n ...(placeholder ? { \"data-placeholder\": placeholder } : {}),\n ...editorProps?.attributes,\n },\n handleKeyDown(view, event) {\n if (editorProps?.handleKeyDown?.(view, event)) return true;\n // Single-line: Enter must not split the document. Multi-line: let\n // StarterKit handle Enter so paragraphs and blocks behave normally.\n if (!multiline && event.key === \"Enter\") return true;\n return false;\n },\n },\n content: textToTiptapHTML(value || \"\", multiline),\n onUpdate({ editor }) {\n onChange(editor.getText({ blockSeparator }));\n },\n });\n\n // Sync the editor's document when `value` changes from outside (e.g.\n // form reset, programmatic setValue). `useEditor` only reads `content`\n // at mount; without this hook the visible UI drifts from form state.\n // The early-return short-circuits the loop that the editor's own\n // `onUpdate` would otherwise create.\n useEffect(() => {\n if (!editor) return;\n const current = editor.getText({ blockSeparator });\n if (current === (value ?? \"\")) return;\n editor.commands.setContent(textToTiptapHTML(value ?? \"\", multiline), false);\n }, [editor, value, multiline, blockSeparator]);\n\n const insertField = useCallback((name: string) => `{{ ${name} }}`, []);\n\n // Tracks the current query in the open reference picker. Drives the\n // `liveItems` recomputation below — when the async sources resolve, we\n // re-render the picker against this query without waiting for Tiptap to\n // re-call items().\n const [referenceQuery, setReferenceQuery] = useState(\"\");\n\n // In sectioned (empty-query) view, cap each kind at SECTION_CAP visible\n // rows. Users see a compact summary and type to filter; the act of\n // filtering switches to flat mode where all matches are shown.\n // Caps are applied at this layer (not inside the picker) so the array\n // passed to SuggestionMenu matches what's rendered — keyboard nav\n // operates on the visible set and never lands on a hidden row.\n const buildVisibleItems = useCallback(\n (\n query: string,\n ): {\n items: SuggestionItem<ReferenceContext>[];\n overflow: Record<ReferenceContext[\"kind\"], number>;\n } => {\n const all = buildReferenceItems(\n query,\n {\n inputFields,\n secretSuggestions: secretSource.items,\n constantSuggestions: constantSource.items,\n },\n expectedFieldType,\n insertField,\n );\n const { prefix, residual } = parseQuery(query);\n const isFlat = !!residual.trim() || prefix !== null;\n if (isFlat) {\n return { items: all, overflow: { field: 0, secret: 0, constant: 0 } };\n }\n const fields = all.filter((i) => i.context?.kind === \"field\");\n const secrets = all.filter((i) => i.context?.kind === \"secret\");\n const constants = all.filter((i) => i.context?.kind === \"constant\");\n return {\n items: [\n ...fields.slice(0, SECTION_CAP),\n ...secrets.slice(0, SECTION_CAP),\n ...constants.slice(0, SECTION_CAP),\n ],\n overflow: {\n field: Math.max(0, fields.length - SECTION_CAP),\n secret: Math.max(0, secrets.length - SECTION_CAP),\n constant: Math.max(0, constants.length - SECTION_CAP),\n },\n };\n },\n [inputFields, expectedFieldType, insertField, secretSource.items, constantSource.items],\n );\n\n const referenceItems = useCallback(\n ({ query }: { query: string }): SuggestionItem<ReferenceContext>[] => {\n setReferenceQuery(query);\n // Fire-and-forget: results land via React state in `secretSource.items`\n // / `constantSource.items` and trigger a re-render. The popup reads\n // them through `liveItems` (see below).\n secretSource.ensure(query);\n constantSource.ensure(query);\n return buildVisibleItems(query).items;\n },\n [secretSource.ensure, constantSource.ensure, buildVisibleItems],\n );\n\n // Live items derived from the current query + cached source items. This is\n // recomputed whenever an async source resolves (which updates\n // `secretSource.items` / `constantSource.items` via setState). Passed to\n // SuggestionMenu via `liveItems` so the open popup re-renders without\n // needing the user to type — Tiptap's items() callback alone cannot\n // deliver async results that arrive between keystrokes.\n const { items: liveReferenceItems, overflow: liveOverflow } = useMemo(\n () => buildVisibleItems(referenceQuery),\n [referenceQuery, buildVisibleItems],\n );\n\n const directiveItems = useCallback(\n () =>\n RECORD_FIELD_TYPES.map<SuggestionItem>((fieldType) => ({\n title: `output: ${fieldType}`,\n keywords: [fieldType, \"output\"],\n onSelect: ({ editor: ed, range }) => {\n ed.chain().focus().insertContentAt(range, OUTPUT_TEMPLATE(fieldType)).run();\n },\n })),\n [],\n );\n\n const legendEntries: LegendEntry[] = [];\n legendEntries.push({ key: \"/\", label: \"to insert a reference\" });\n if (supportsOutput) legendEntries.push({ key: \"@\", label: \"to insert a directive\" });\n\n return (\n <EditorContext.Provider value={{ editor }}>\n <EditorContent editor={editor} />\n\n {!hideLegend && <FieldLegend entries={legendEntries} />}\n\n <SuggestionMenu\n editor={editor}\n char=\"/\"\n pluginKey=\"liquidEditorReferencePicker\"\n items={referenceItems}\n liveItems={liveReferenceItems}\n >\n {(props) => (\n <UnifiedReferencePicker\n items={props.items as SuggestionItem<ReferenceContext>[]}\n selectedIndex={props.selectedIndex}\n onSelect={props.onSelect as (item: SuggestionItem<ReferenceContext>) => void}\n query={props.query}\n hasSecretsResolver={hasSecretsResolver}\n hasConstantsResolver={hasConstantsResolver}\n inputFieldsCount={inputFields.length}\n secretsPending={secretSource.pending}\n constantsPending={constantSource.pending}\n overflow={liveOverflow}\n />\n )}\n </SuggestionMenu>\n\n {supportsOutput && (\n <SuggestionMenu\n editor={editor}\n char=\"@\"\n pluginKey=\"liquidEditorDirectivePicker\"\n items={directiveItems}\n >\n {({ items, selectedIndex, onSelect }) => (\n <div className=\"pz:flex pz:flex-col pz:gap-0.5 pz:p-1 pz:min-w-56\" role=\"listbox\">\n <div className=\"pz:px-2 pz:pt-1 pz:pb-0.5 pz:text-[10px] pz:font-medium pz:uppercase pz:tracking-wide pz:text-muted-foreground\">\n Add output declaration\n </div>\n {items.map((item, index) => (\n <button\n key={item.title}\n type=\"button\"\n role=\"option\"\n aria-selected={selectedIndex === index}\n onClick={() => onSelect(item)}\n className={cn(\n \"pz:flex pz:w-full pz:items-center pz:rounded-sm pz:px-2 pz:py-1.5 pz:text-sm pz:text-left pz:cursor-pointer\",\n selectedIndex === index\n ? \"pz:bg-accent pz:text-accent-foreground\"\n : \"pz:hover:bg-accent pz:hover:text-accent-foreground\",\n )}\n >\n {item.title}\n </button>\n ))}\n </div>\n )}\n </SuggestionMenu>\n )}\n\n {chipTarget && editor && (\n <ChipEditPopover editor={editor} target={chipTarget} onClose={() => setChipTarget(null)} />\n )}\n </EditorContext.Provider>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"LiquidEditor.mjs","names":[],"sources":["../../../../src/components/internal/LiquidEditor/LiquidEditor.tsx"],"sourcesContent":["import {\n type PipesFieldDefinitionWithName,\n RECORD_FIELD_TYPES,\n type RecordFieldType,\n} from \"@pipe0/base\";\nimport type { EditorProps } from \"@tiptap/pm/view\";\nimport { EditorContent, EditorContext, useEditor } from \"@tiptap/react\";\nimport StarterKit from \"@tiptap/starter-kit\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useAsyncRemoteSource } from \"../../../hooks/use-async-remote-source.js\";\nimport { cn } from \"../../../lib/utils.js\";\nimport type { ConstantSuggestion, SecretSuggestion } from \"../../../types/field-props.js\";\nimport { FieldLegend, type LegendEntry } from \"../field-legend.js\";\nimport { SuggestionMenu } from \"../suggestion-menu/suggestion-menu.js\";\nimport type { SuggestionItem } from \"../suggestion-menu/suggestion-menu-types.js\";\nimport { type ChipHit, TagChipDecoration } from \"../tag-chip-decoration.js\";\nimport { ChipEditPopover, type ChipEditTarget } from \"./ChipEditPopover.js\";\nimport {\n buildReferenceItems,\n parseQuery,\n type ReferenceContext,\n SECTION_CAP,\n UnifiedReferencePicker,\n} from \"./UnifiedReferencePicker.js\";\n\nexport type DirectiveKind = \"output\";\n\nexport interface LiquidEditorProps {\n value: string;\n onChange: (v: string) => void;\n inputFields: PipesFieldDefinitionWithName[];\n /**\n * Per-keystroke async searcher for secrets. Called from the `/` reference\n * picker as the user types. Calls are debounced and race-guarded — only\n * the response for the latest query is rendered.\n */\n searchSecrets?: (query: string) => Promise<SecretSuggestion[]>;\n /**\n * Per-keystroke async searcher for constants. Mirrors `searchSecrets`.\n */\n searchConstants?: (query: string) => Promise<ConstantSuggestion[]>;\n multiline?: boolean;\n /**\n * When true, the editor renders within `min-h`/`max-h` bounds. When\n * false, callers control the height via `className`. Default: true.\n */\n autoGrow?: boolean;\n directives?: DirectiveKind[];\n expectedFieldType?: RecordFieldType;\n placeholder?: string;\n className?: string;\n editorProps?: EditorProps;\n /**\n * Suppress the per-editor legend. Used by `key_value_list_input` which\n * renders a single legend below the entire list rather than per-cell.\n */\n hideLegend?: boolean;\n}\n\nfunction escapeHtml(s: string): string {\n return s.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n}\n\n/**\n * Reconciles single- and multi-line text into Tiptap-friendly HTML.\n * - Single-line: collapses whitespace runs containing newlines into a\n * single space and renders as one paragraph.\n * - Multi-line: paragraphs separated by blank lines (`\\n\\n+`); soft\n * breaks within a paragraph render as `<br>`. Leading spaces on each\n * line are preserved with `&nbsp;` so JSON-shaped payloads round-trip\n * through the editor.\n */\nfunction textToTiptapHTML(text: string, multiline: boolean): string {\n if (!multiline) {\n return `<p>${escapeHtml(text.replace(/\\s*\\n+\\s*/g, \" \"))}</p>`;\n }\n return escapeHtml(text)\n .split(/\\n\\n+/)\n .map((block) => {\n const lines = block.split(/\\n/);\n const htmlLines = lines\n .map((line) => line.replace(/^ +/, (spaces) => \"&nbsp;\".repeat(spaces.length)))\n .join(\"<br>\");\n return `<p>${htmlLines}</p>`;\n })\n .join(\"\");\n}\n\nconst OUTPUT_TEMPLATE = (fieldType: RecordFieldType): string => {\n if (fieldType === \"json\") {\n return `{% output FIELD_NAME, type: \"json\", schema: \"SCHEMA_NAME\", description: \"\" %}`;\n }\n return `{% output FIELD_NAME, type: \"${fieldType}\", description: \"\" %}`;\n};\n\n/**\n * Single editor surface for every form field that accepts Liquid tags.\n * Two triggers, two cognitive categories:\n *\n * - `/` opens a unified reference picker (Fields, Secrets, Constants).\n * Prefix syntax `/f/`, `/s/`, `/c/` filters to one source. Picking\n * emits the corresponding `{{ … }}` Liquid Output.\n *\n * - `@` opens a directives picker (only when `directives.length > 0`).\n * Today the only directive is `output`, which inserts a templated\n * `{% output FIELD_NAME, type: \"...\", description: \"\" %}` block.\n *\n * Chips render via the `TagChipDecoration` extension. Click or\n * Enter/Space on a chip mounts the contextual `ChipEditPopover`.\n *\n * Backwards compat: the persisted value is plain Liquid text,\n * byte-identical to what the legacy `TagEditor` / `TextPromptEditor`\n * produced. No engine, analyzer, or metadata changes.\n */\nexport function LiquidEditor({\n value,\n onChange,\n inputFields,\n searchSecrets,\n searchConstants,\n multiline = false,\n autoGrow = true,\n directives = [],\n expectedFieldType,\n placeholder,\n className,\n editorProps,\n hideLegend = false,\n}: LiquidEditorProps) {\n const blockSeparator = multiline ? \"\\n\" : \"\";\n const supportsOutput = directives.includes(\"output\");\n const hasSecretsResolver = !!searchSecrets;\n const hasConstantsResolver = !!searchConstants;\n\n const secretSource = useAsyncRemoteSource<SecretSuggestion>({ search: searchSecrets });\n const constantSource = useAsyncRemoteSource<ConstantSuggestion>({ search: searchConstants });\n\n // Warm caches once per resolver identity so the empty-query open is hot.\n useEffect(() => {\n secretSource.prefetch();\n }, [secretSource.prefetch]);\n\n useEffect(() => {\n constantSource.prefetch();\n }, [constantSource.prefetch]);\n\n const [chipTarget, setChipTarget] = useState<ChipEditTarget | null>(null);\n\n const tagChipExtension = useMemo(\n () =>\n TagChipDecoration.configure({\n onChipClick: (hit: ChipHit, el: HTMLElement) => {\n setChipTarget({\n kind: hit.kind,\n raw: hit.raw,\n from: hit.from,\n to: hit.to,\n rect: el.getBoundingClientRect(),\n });\n },\n }),\n [],\n );\n\n const editor = useEditor({\n extensions: [\n StarterKit.configure({ hardBreak: !multiline ? false : undefined }),\n tagChipExtension,\n ],\n parseOptions: { preserveWhitespace: \"full\" },\n editorProps: {\n ...editorProps,\n attributes: {\n class: cn(\n \"pz:px-2.5 pz:py-1 pz:text-sm pz:outline-none pz:break-words\",\n multiline\n ? autoGrow\n ? \"pz:min-h-24 pz:max-h-96 pz:overflow-auto pz:whitespace-pre-wrap\"\n : \"pz:overflow-auto pz:whitespace-pre-wrap\"\n : \"pz:min-h-8\",\n className,\n ),\n ...(placeholder ? { \"data-placeholder\": placeholder } : {}),\n ...editorProps?.attributes,\n },\n handleKeyDown(view, event) {\n if (editorProps?.handleKeyDown?.(view, event)) return true;\n // Single-line: Enter must not split the document. Multi-line: let\n // StarterKit handle Enter so paragraphs and blocks behave normally.\n if (!multiline && event.key === \"Enter\") return true;\n return false;\n },\n },\n content: textToTiptapHTML(value || \"\", multiline),\n onUpdate({ editor }) {\n onChange(editor.getText({ blockSeparator }));\n },\n });\n\n // Sync the editor's document when `value` changes from outside (e.g.\n // form reset, programmatic setValue). `useEditor` only reads `content`\n // at mount; without this hook the visible UI drifts from form state.\n // The early-return short-circuits the loop that the editor's own\n // `onUpdate` would otherwise create.\n useEffect(() => {\n if (!editor) return;\n const current = editor.getText({ blockSeparator });\n if (current === (value ?? \"\")) return;\n editor.commands.setContent(textToTiptapHTML(value ?? \"\", multiline), false);\n }, [editor, value, multiline, blockSeparator]);\n\n const insertField = useCallback((name: string) => `{{ ${name} }}`, []);\n\n // Tracks the current query in the open reference picker. Drives the\n // `liveItems` recomputation below — when the async sources resolve, we\n // re-render the picker against this query without waiting for Tiptap to\n // re-call items().\n const [referenceQuery, setReferenceQuery] = useState(\"\");\n\n // In sectioned (empty-query) view, cap each kind at SECTION_CAP visible\n // rows. Users see a compact summary and type to filter; the act of\n // filtering switches to flat mode where all matches are shown.\n // Caps are applied at this layer (not inside the picker) so the array\n // passed to SuggestionMenu matches what's rendered — keyboard nav\n // operates on the visible set and never lands on a hidden row.\n const buildVisibleItems = useCallback(\n (\n query: string,\n ): {\n items: SuggestionItem<ReferenceContext>[];\n overflow: Record<ReferenceContext[\"kind\"], number>;\n } => {\n const all = buildReferenceItems(\n query,\n {\n inputFields,\n secretSuggestions: secretSource.items,\n constantSuggestions: constantSource.items,\n },\n expectedFieldType,\n insertField,\n );\n const { prefix, residual } = parseQuery(query);\n const isFlat = !!residual.trim() || prefix !== null;\n if (isFlat) {\n return { items: all, overflow: { field: 0, secret: 0, constant: 0 } };\n }\n const fields = all.filter((i) => i.context?.kind === \"field\");\n const secrets = all.filter((i) => i.context?.kind === \"secret\");\n const constants = all.filter((i) => i.context?.kind === \"constant\");\n return {\n items: [\n ...fields.slice(0, SECTION_CAP),\n ...secrets.slice(0, SECTION_CAP),\n ...constants.slice(0, SECTION_CAP),\n ],\n overflow: {\n field: Math.max(0, fields.length - SECTION_CAP),\n secret: Math.max(0, secrets.length - SECTION_CAP),\n constant: Math.max(0, constants.length - SECTION_CAP),\n },\n };\n },\n [inputFields, expectedFieldType, insertField, secretSource.items, constantSource.items],\n );\n\n const referenceItems = useCallback(\n ({ query }: { query: string }): SuggestionItem<ReferenceContext>[] => {\n setReferenceQuery(query);\n // Fire-and-forget: results land via React state in `secretSource.items`\n // / `constantSource.items` and trigger a re-render. The popup reads\n // them through `liveItems` (see below).\n secretSource.ensure(query);\n constantSource.ensure(query);\n return buildVisibleItems(query).items;\n },\n [secretSource.ensure, constantSource.ensure, buildVisibleItems],\n );\n\n // Live items derived from the current query + cached source items. This is\n // recomputed whenever an async source resolves (which updates\n // `secretSource.items` / `constantSource.items` via setState). Passed to\n // SuggestionMenu via `liveItems` so the open popup re-renders without\n // needing the user to type — Tiptap's items() callback alone cannot\n // deliver async results that arrive between keystrokes.\n const { items: liveReferenceItems, overflow: liveOverflow } = useMemo(\n () => buildVisibleItems(referenceQuery),\n [referenceQuery, buildVisibleItems],\n );\n\n const directiveItems = useCallback(\n () =>\n RECORD_FIELD_TYPES.map<SuggestionItem>((fieldType) => ({\n title: `output: ${fieldType}`,\n keywords: [fieldType, \"output\"],\n onSelect: ({ editor: ed, range }) => {\n ed.chain().focus().insertContentAt(range, OUTPUT_TEMPLATE(fieldType)).run();\n },\n })),\n [],\n );\n\n const legendEntries: LegendEntry[] = [];\n legendEntries.push({ key: \"/\", label: \"to insert a reference\" });\n if (supportsOutput) legendEntries.push({ key: \"@\", label: \"to add an output field\" });\n\n return (\n <EditorContext.Provider value={{ editor }}>\n <EditorContent editor={editor} />\n\n {!hideLegend && <FieldLegend entries={legendEntries} />}\n\n <SuggestionMenu\n editor={editor}\n char=\"/\"\n pluginKey=\"liquidEditorReferencePicker\"\n items={referenceItems}\n liveItems={liveReferenceItems}\n >\n {(props) => (\n <UnifiedReferencePicker\n items={props.items as SuggestionItem<ReferenceContext>[]}\n selectedIndex={props.selectedIndex}\n onSelect={props.onSelect as (item: SuggestionItem<ReferenceContext>) => void}\n query={props.query}\n hasSecretsResolver={hasSecretsResolver}\n hasConstantsResolver={hasConstantsResolver}\n inputFieldsCount={inputFields.length}\n secretsPending={secretSource.pending}\n constantsPending={constantSource.pending}\n overflow={liveOverflow}\n />\n )}\n </SuggestionMenu>\n\n {supportsOutput && (\n <SuggestionMenu\n editor={editor}\n char=\"@\"\n pluginKey=\"liquidEditorDirectivePicker\"\n items={directiveItems}\n >\n {({ items, selectedIndex, onSelect }) => (\n <div className=\"pz:flex pz:flex-col pz:gap-0.5 pz:p-1 pz:min-w-56\" role=\"listbox\">\n <div className=\"pz:px-2 pz:pt-1 pz:pb-0.5 pz:text-[10px] pz:font-medium pz:uppercase pz:tracking-wide pz:text-muted-foreground\">\n Add output declaration\n </div>\n {items.map((item, index) => (\n <button\n key={item.title}\n type=\"button\"\n role=\"option\"\n aria-selected={selectedIndex === index}\n onClick={() => onSelect(item)}\n className={cn(\n \"pz:flex pz:w-full pz:items-center pz:rounded-sm pz:px-2 pz:py-1.5 pz:text-sm pz:text-left pz:cursor-pointer\",\n selectedIndex === index\n ? \"pz:bg-accent pz:text-accent-foreground\"\n : \"pz:hover:bg-accent pz:hover:text-accent-foreground\",\n )}\n >\n {item.title}\n </button>\n ))}\n </div>\n )}\n </SuggestionMenu>\n )}\n\n {chipTarget && editor && (\n <ChipEditPopover editor={editor} target={chipTarget} onClose={() => setChipTarget(null)} />\n )}\n </EditorContext.Provider>\n );\n}\n"],"mappings":"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"}
@@ -133,7 +133,8 @@ const SuggestionMenu = ({ editor: providedEditor, floatingOptions, selector = "t
133
133
  editor,
134
134
  query: internalQuery,
135
135
  items: renderedItems,
136
- onSelect
136
+ onSelect,
137
+ enabled: show
137
138
  });
138
139
  if (!isMounted || !show || !editor) return null;
139
140
  return /* @__PURE__ */ jsx("div", {
@@ -1 +1 @@
1
- {"version":3,"file":"suggestion-menu.mjs","names":[],"sources":["../../../../src/components/internal/suggestion-menu/suggestion-menu.tsx"],"sourcesContent":["import { flip, offset, shift, size } from \"@floating-ui/react\";\nimport { PluginKey } from \"@tiptap/pm/state\";\nimport type { Range } from \"@tiptap/react\";\nimport {\n Suggestion,\n type SuggestionKeyDownProps,\n SuggestionPluginKey,\n type SuggestionProps,\n} from \"@tiptap/suggestion\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { useFloatingElement } from \"../../../hooks/use-floating-element.js\";\nimport { useMenuNavigation } from \"../../../hooks/use-menu-navigation.js\";\nimport type { SuggestionItem, SuggestionMenuProps } from \"./suggestion-menu-types.js\";\nimport { calculateStartPosition } from \"./suggestion-menu-utils.js\";\n\nexport const SuggestionMenu = ({\n editor: providedEditor,\n floatingOptions,\n selector = \"tiptap-suggestion-menu\",\n children,\n maxHeight = 384,\n pluginKey = SuggestionPluginKey,\n liveItems,\n ...internalSuggestionProps\n}: SuggestionMenuProps) => {\n const editor = providedEditor ?? null;\n\n const [show, setShow] = useState<boolean>(false);\n const [internalClientRect, setInternalClientRect] = useState<DOMRect | null>(null);\n const [internalCommand, setInternalCommand] = useState<((item: SuggestionItem) => void) | null>(\n null,\n );\n const [internalItems, setInternalItems] = useState<SuggestionItem[]>([]);\n const [internalQuery, setInternalQuery] = useState<string>(\"\");\n const [, setInternalRange] = useState<Range | null>(null);\n\n const { ref, style, getFloatingProps, isMounted } = useFloatingElement(\n show,\n internalClientRect,\n 1000,\n {\n placement: \"bottom-start\",\n middleware: [\n offset(10),\n flip({ mainAxis: true, crossAxis: false }),\n shift(),\n size({\n apply({ availableHeight, elements }) {\n if (elements.floating) {\n const maxHeightValue = maxHeight\n ? Math.min(maxHeight, availableHeight)\n : availableHeight;\n elements.floating.style.setProperty(\n \"--suggestion-menu-max-height\",\n `${maxHeightValue}px`,\n );\n }\n },\n }),\n ],\n onOpenChange(open) {\n if (!open) setShow(false);\n },\n ...floatingOptions,\n },\n );\n\n const internalSuggestionPropsRef = useRef(internalSuggestionProps);\n\n useEffect(() => {\n internalSuggestionPropsRef.current = internalSuggestionProps;\n }, [internalSuggestionProps]);\n\n const closePopup = useCallback(() => {\n setShow(false);\n }, []);\n\n useEffect(() => {\n if (!editor || editor.isDestroyed) return;\n\n const existingPlugin = editor.state.plugins.find((plugin) => plugin.spec.key === pluginKey);\n if (existingPlugin) {\n editor.unregisterPlugin(pluginKey);\n }\n\n type ItemsFn = NonNullable<typeof internalSuggestionPropsRef.current.items>;\n type ItemsArgs = Parameters<ItemsFn>[0];\n type ItemsReturn = ReturnType<ItemsFn>;\n\n const suggestion = Suggestion({\n pluginKey: pluginKey instanceof PluginKey ? pluginKey : new PluginKey(pluginKey),\n editor,\n\n command({ editor, range, props }) {\n if (!range) return;\n\n const { view, state } = editor;\n const { selection } = state;\n\n const isMention = editor.extensionManager.extensions.some(\n (extension) =>\n extension.name === \"mention\" &&\n extension.options?.suggestion?.char === internalSuggestionPropsRef.current.char,\n );\n\n // Track the position where the inserted content should land. For the\n // non-mention path we delete the typed query first; after that, the\n // suggestion's original `range` is stale (its `to` may now point past\n // the doc end), so we collapse to the deletion start. For mentions\n // the typed text is preserved and we keep the original range.\n let insertRange: { from: number; to: number };\n\n if (!isMention) {\n const cursorPosition = selection.$from.pos;\n const previousNode = selection.$head?.nodeBefore;\n\n const startPosition = previousNode\n ? calculateStartPosition(\n cursorPosition,\n previousNode,\n internalSuggestionPropsRef.current.char,\n )\n : selection.$from.start();\n\n const transaction = state.tr.deleteRange(startPosition, cursorPosition);\n view.dispatch(transaction);\n\n insertRange = { from: startPosition, to: startPosition };\n } else {\n insertRange = { from: range.from, to: range.to };\n }\n\n const nodeAfter = view.state.selection.$to.nodeAfter;\n const overrideSpace = nodeAfter?.text?.startsWith(\" \");\n if (overrideSpace) insertRange.to += 1;\n\n props.onSelect({ editor, range: insertRange, context: props.context });\n },\n\n render: () => ({\n onStart: (props: SuggestionProps<SuggestionItem>) => {\n setInternalCommand(() => props.command);\n setInternalItems(props.items);\n setInternalQuery(props.query);\n setInternalRange(props.range);\n setInternalClientRect(props.clientRect?.() ?? null);\n setShow(true);\n },\n onUpdate: (props: SuggestionProps<SuggestionItem>) => {\n setInternalCommand(() => props.command);\n setInternalItems(props.items);\n setInternalQuery(props.query);\n setInternalRange(props.range);\n setInternalClientRect(props.clientRect?.() ?? null);\n },\n onKeyDown: (props: SuggestionKeyDownProps) => {\n if (props.event.key === \"Escape\") {\n closePopup();\n return true;\n }\n return false;\n },\n onExit: () => {\n setInternalCommand(null);\n setInternalItems([]);\n setInternalQuery(\"\");\n setInternalRange(null);\n setInternalClientRect(null);\n setShow(false);\n },\n }),\n ...internalSuggestionPropsRef.current,\n // Override `items` to always read from the live ref. The Suggestion\n // plugin captures its options once at registration, but parents update\n // `items` asynchronously (e.g. when `getSecrets` resolves). Without\n // this delegation, items computed after registration never reach the\n // menu and the user sees an empty list.\n items: ((args: ItemsArgs): ItemsReturn => {\n const fn = internalSuggestionPropsRef.current.items;\n return (fn ? fn(args) : ([] as unknown as ItemsReturn)) as ItemsReturn;\n }) as ItemsFn,\n });\n\n editor.registerPlugin(suggestion);\n\n return () => {\n if (!editor.isDestroyed) {\n editor.unregisterPlugin(pluginKey);\n }\n };\n }, [editor, pluginKey, closePopup]);\n\n const onSelect = useCallback(\n (item: SuggestionItem) => {\n closePopup();\n if (internalCommand) internalCommand(item);\n },\n [closePopup, internalCommand],\n );\n\n // `liveItems` (when provided) takes precedence over `internalItems` for\n // both rendering and keyboard navigation. This lets parents push fresh\n // items into the open popup as async sources resolve — without waiting on\n // the Tiptap suggestion plugin to re-call items() (it only does so on\n // query change).\n const renderedItems = liveItems ?? internalItems;\n\n const { selectedIndex } = useMenuNavigation({\n editor,\n query: internalQuery,\n items: renderedItems,\n onSelect,\n });\n\n if (!isMounted || !show || !editor) return null;\n\n return (\n <div\n ref={ref}\n style={style}\n {...getFloatingProps()}\n data-selector={selector}\n className=\"pz:z-50 pz:overflow-hidden pz:rounded-md pz:border pz:border-input pz:bg-popover pz:text-popover-foreground pz:shadow-md\"\n role=\"listbox\"\n aria-label=\"Suggestions\"\n onPointerDown={(e) => e.preventDefault()}\n >\n {children({ items: renderedItems, selectedIndex, onSelect, query: internalQuery })}\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"suggestion-menu.mjs","names":[],"sources":["../../../../src/components/internal/suggestion-menu/suggestion-menu.tsx"],"sourcesContent":["import { flip, offset, shift, size } from \"@floating-ui/react\";\nimport { PluginKey } from \"@tiptap/pm/state\";\nimport type { Range } from \"@tiptap/react\";\nimport {\n Suggestion,\n type SuggestionKeyDownProps,\n SuggestionPluginKey,\n type SuggestionProps,\n} from \"@tiptap/suggestion\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\n\nimport { useFloatingElement } from \"../../../hooks/use-floating-element.js\";\nimport { useMenuNavigation } from \"../../../hooks/use-menu-navigation.js\";\nimport type { SuggestionItem, SuggestionMenuProps } from \"./suggestion-menu-types.js\";\nimport { calculateStartPosition } from \"./suggestion-menu-utils.js\";\n\nexport const SuggestionMenu = ({\n editor: providedEditor,\n floatingOptions,\n selector = \"tiptap-suggestion-menu\",\n children,\n maxHeight = 384,\n pluginKey = SuggestionPluginKey,\n liveItems,\n ...internalSuggestionProps\n}: SuggestionMenuProps) => {\n const editor = providedEditor ?? null;\n\n const [show, setShow] = useState<boolean>(false);\n const [internalClientRect, setInternalClientRect] = useState<DOMRect | null>(null);\n const [internalCommand, setInternalCommand] = useState<((item: SuggestionItem) => void) | null>(\n null,\n );\n const [internalItems, setInternalItems] = useState<SuggestionItem[]>([]);\n const [internalQuery, setInternalQuery] = useState<string>(\"\");\n const [, setInternalRange] = useState<Range | null>(null);\n\n const { ref, style, getFloatingProps, isMounted } = useFloatingElement(\n show,\n internalClientRect,\n 1000,\n {\n placement: \"bottom-start\",\n middleware: [\n offset(10),\n flip({ mainAxis: true, crossAxis: false }),\n shift(),\n size({\n apply({ availableHeight, elements }) {\n if (elements.floating) {\n const maxHeightValue = maxHeight\n ? Math.min(maxHeight, availableHeight)\n : availableHeight;\n elements.floating.style.setProperty(\n \"--suggestion-menu-max-height\",\n `${maxHeightValue}px`,\n );\n }\n },\n }),\n ],\n onOpenChange(open) {\n if (!open) setShow(false);\n },\n ...floatingOptions,\n },\n );\n\n const internalSuggestionPropsRef = useRef(internalSuggestionProps);\n\n useEffect(() => {\n internalSuggestionPropsRef.current = internalSuggestionProps;\n }, [internalSuggestionProps]);\n\n const closePopup = useCallback(() => {\n setShow(false);\n }, []);\n\n useEffect(() => {\n if (!editor || editor.isDestroyed) return;\n\n const existingPlugin = editor.state.plugins.find((plugin) => plugin.spec.key === pluginKey);\n if (existingPlugin) {\n editor.unregisterPlugin(pluginKey);\n }\n\n type ItemsFn = NonNullable<typeof internalSuggestionPropsRef.current.items>;\n type ItemsArgs = Parameters<ItemsFn>[0];\n type ItemsReturn = ReturnType<ItemsFn>;\n\n const suggestion = Suggestion({\n pluginKey: pluginKey instanceof PluginKey ? pluginKey : new PluginKey(pluginKey),\n editor,\n\n command({ editor, range, props }) {\n if (!range) return;\n\n const { view, state } = editor;\n const { selection } = state;\n\n const isMention = editor.extensionManager.extensions.some(\n (extension) =>\n extension.name === \"mention\" &&\n extension.options?.suggestion?.char === internalSuggestionPropsRef.current.char,\n );\n\n // Track the position where the inserted content should land. For the\n // non-mention path we delete the typed query first; after that, the\n // suggestion's original `range` is stale (its `to` may now point past\n // the doc end), so we collapse to the deletion start. For mentions\n // the typed text is preserved and we keep the original range.\n let insertRange: { from: number; to: number };\n\n if (!isMention) {\n const cursorPosition = selection.$from.pos;\n const previousNode = selection.$head?.nodeBefore;\n\n const startPosition = previousNode\n ? calculateStartPosition(\n cursorPosition,\n previousNode,\n internalSuggestionPropsRef.current.char,\n )\n : selection.$from.start();\n\n const transaction = state.tr.deleteRange(startPosition, cursorPosition);\n view.dispatch(transaction);\n\n insertRange = { from: startPosition, to: startPosition };\n } else {\n insertRange = { from: range.from, to: range.to };\n }\n\n const nodeAfter = view.state.selection.$to.nodeAfter;\n const overrideSpace = nodeAfter?.text?.startsWith(\" \");\n if (overrideSpace) insertRange.to += 1;\n\n props.onSelect({ editor, range: insertRange, context: props.context });\n },\n\n render: () => ({\n onStart: (props: SuggestionProps<SuggestionItem>) => {\n setInternalCommand(() => props.command);\n setInternalItems(props.items);\n setInternalQuery(props.query);\n setInternalRange(props.range);\n setInternalClientRect(props.clientRect?.() ?? null);\n setShow(true);\n },\n onUpdate: (props: SuggestionProps<SuggestionItem>) => {\n setInternalCommand(() => props.command);\n setInternalItems(props.items);\n setInternalQuery(props.query);\n setInternalRange(props.range);\n setInternalClientRect(props.clientRect?.() ?? null);\n },\n onKeyDown: (props: SuggestionKeyDownProps) => {\n if (props.event.key === \"Escape\") {\n closePopup();\n return true;\n }\n return false;\n },\n onExit: () => {\n setInternalCommand(null);\n setInternalItems([]);\n setInternalQuery(\"\");\n setInternalRange(null);\n setInternalClientRect(null);\n setShow(false);\n },\n }),\n ...internalSuggestionPropsRef.current,\n // Override `items` to always read from the live ref. The Suggestion\n // plugin captures its options once at registration, but parents update\n // `items` asynchronously (e.g. when `getSecrets` resolves). Without\n // this delegation, items computed after registration never reach the\n // menu and the user sees an empty list.\n items: ((args: ItemsArgs): ItemsReturn => {\n const fn = internalSuggestionPropsRef.current.items;\n return (fn ? fn(args) : ([] as unknown as ItemsReturn)) as ItemsReturn;\n }) as ItemsFn,\n });\n\n editor.registerPlugin(suggestion);\n\n return () => {\n if (!editor.isDestroyed) {\n editor.unregisterPlugin(pluginKey);\n }\n };\n }, [editor, pluginKey, closePopup]);\n\n const onSelect = useCallback(\n (item: SuggestionItem) => {\n closePopup();\n if (internalCommand) internalCommand(item);\n },\n [closePopup, internalCommand],\n );\n\n // `liveItems` (when provided) takes precedence over `internalItems` for\n // both rendering and keyboard navigation. This lets parents push fresh\n // items into the open popup as async sources resolve — without waiting on\n // the Tiptap suggestion plugin to re-call items() (it only does so on\n // query change).\n const renderedItems = liveItems ?? internalItems;\n\n const { selectedIndex } = useMenuNavigation({\n editor,\n query: internalQuery,\n items: renderedItems,\n onSelect,\n // Only intercept keys while the popup is open. `renderedItems` (via\n // `liveItems`) can be non-empty even when closed, so without this gate the\n // capture-phase handler would swallow Enter and block newlines in the editor.\n enabled: show,\n });\n\n if (!isMounted || !show || !editor) return null;\n\n return (\n <div\n ref={ref}\n style={style}\n {...getFloatingProps()}\n data-selector={selector}\n className=\"pz:z-50 pz:overflow-hidden pz:rounded-md pz:border pz:border-input pz:bg-popover pz:text-popover-foreground pz:shadow-md\"\n role=\"listbox\"\n aria-label=\"Suggestions\"\n onPointerDown={(e) => e.preventDefault()}\n >\n {children({ items: renderedItems, selectedIndex, onSelect, query: internalQuery })}\n </div>\n );\n};\n"],"mappings":"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"}
@@ -6,7 +6,7 @@ import * as _$class_variance_authority_types0 from "class-variance-authority/typ
6
6
  //#region src/components/ui/button.d.ts
7
7
  declare const buttonVariants: (props?: ({
8
8
  variant?: "default" | "link" | "outline" | "secondary" | "ghost" | "destructive" | null | undefined;
9
- size?: "default" | "icon" | "xs" | "sm" | "lg" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
9
+ size?: "default" | "icon" | "sm" | "lg" | "xs" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
10
10
  } & _$class_variance_authority_types0.ClassProp) | undefined) => string;
11
11
  declare function Button$1({
12
12
  className,
@@ -4,6 +4,14 @@ import { FormHandle } from "../types/form-handle.mjs";
4
4
  /**
5
5
  * Resolves a nested field error by its full dot-notation path.
6
6
  * Only returns an error after the form has been submitted at least once.
7
+ *
8
+ * Subscribes via `useFormState({ name })` so the calling adapter re-renders
9
+ * itself when validation touches `path` — even for nested paths that don't
10
+ * surface on the parent field handle's `error` (e.g. `config.prompt.template`).
11
+ * Reading `form.formState` directly would NOT establish a subscription: RHF's
12
+ * proxy only re-renders the component that called `useForm`, and `FieldRenderer`
13
+ * memoizes on the handle's top-level `error`, so the inline message would
14
+ * otherwise appear only after a remount.
7
15
  */
8
16
  declare function useFieldError(form: FormHandle, path: string): string | undefined;
9
17
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"use-field-error.d.mts","names":[],"sources":["../../src/hooks/use-field-error.ts"],"mappings":";;;;;AAMA;;iBAAgB,aAAA,CAAc,IAAA,EAAM,UAAA,EAAY,IAAA"}
1
+ {"version":3,"file":"use-field-error.d.mts","names":[],"sources":["../../src/hooks/use-field-error.ts"],"mappings":";;;;;AAgBA;;;;;;;;;;iBAAgB,aAAA,CAAc,IAAA,EAAM,UAAA,EAAY,IAAA"}
@@ -1,10 +1,25 @@
1
+ import { asInternalForm } from "../utils/internal-form.mjs";
2
+ import { useFormState } from "react-hook-form";
3
+
1
4
  //#region src/hooks/use-field-error.ts
2
5
  /**
3
6
  * Resolves a nested field error by its full dot-notation path.
4
7
  * Only returns an error after the form has been submitted at least once.
8
+ *
9
+ * Subscribes via `useFormState({ name })` so the calling adapter re-renders
10
+ * itself when validation touches `path` — even for nested paths that don't
11
+ * surface on the parent field handle's `error` (e.g. `config.prompt.template`).
12
+ * Reading `form.formState` directly would NOT establish a subscription: RHF's
13
+ * proxy only re-renders the component that called `useForm`, and `FieldRenderer`
14
+ * memoizes on the handle's top-level `error`, so the inline message would
15
+ * otherwise appear only after a remount.
5
16
  */
6
17
  function useFieldError(form, path) {
7
- const { isSubmitted, errors } = form.formState;
18
+ const { control } = asInternalForm(form);
19
+ const { isSubmitted, errors } = useFormState({
20
+ control,
21
+ name: path
22
+ });
8
23
  if (!isSubmitted) return void 0;
9
24
  return resolveError(errors, path);
10
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"use-field-error.mjs","names":[],"sources":["../../src/hooks/use-field-error.ts"],"sourcesContent":["import type { FormErrors, FormHandle } from \"../types/form-handle.js\";\n\n/**\n * Resolves a nested field error by its full dot-notation path.\n * Only returns an error after the form has been submitted at least once.\n */\nexport function useFieldError(form: FormHandle, path: string): string | undefined {\n // Read both `isSubmitted` and `errors` so the underlying form's reactive\n // tracking registers the dependency regardless of the current submit state.\n const { isSubmitted, errors } = form.formState;\n if (!isSubmitted) return undefined;\n return resolveError(errors, path);\n}\n\nfunction resolveError(errors: FormErrors, path: string): string | undefined {\n const segments = path.split(\".\");\n let node: unknown = errors;\n for (const seg of segments) {\n if (node == null || typeof node !== \"object\") return undefined;\n node = (node as Record<string, unknown>)[seg];\n if (node == null) return undefined;\n }\n if (node != null && typeof node === \"object\" && \"message\" in node) {\n const msg = (node as { message?: unknown }).message;\n return typeof msg === \"string\" ? msg : undefined;\n }\n return undefined;\n}\n"],"mappings":";;;;;AAMA,SAAgB,cAAc,MAAkB,MAAkC;CAGhF,MAAM,EAAE,aAAa,WAAW,KAAK;AACrC,KAAI,CAAC,YAAa,QAAO;AACzB,QAAO,aAAa,QAAQ,KAAK;;AAGnC,SAAS,aAAa,QAAoB,MAAkC;CAC1E,MAAM,WAAW,KAAK,MAAM,IAAI;CAChC,IAAI,OAAgB;AACpB,MAAK,MAAM,OAAO,UAAU;AAC1B,MAAI,QAAQ,QAAQ,OAAO,SAAS,SAAU,QAAO;AACrD,SAAQ,KAAiC;AACzC,MAAI,QAAQ,KAAM,QAAO;;AAE3B,KAAI,QAAQ,QAAQ,OAAO,SAAS,YAAY,aAAa,MAAM;EACjE,MAAM,MAAO,KAA+B;AAC5C,SAAO,OAAO,QAAQ,WAAW,MAAM"}
1
+ {"version":3,"file":"use-field-error.mjs","names":[],"sources":["../../src/hooks/use-field-error.ts"],"sourcesContent":["import { type FieldValues, useFormState } from \"react-hook-form\";\nimport type { FormErrors, FormHandle } from \"../types/form-handle.js\";\nimport { asInternalForm } from \"../utils/internal-form.js\";\n\n/**\n * Resolves a nested field error by its full dot-notation path.\n * Only returns an error after the form has been submitted at least once.\n *\n * Subscribes via `useFormState({ name })` so the calling adapter re-renders\n * itself when validation touches `path` even for nested paths that don't\n * surface on the parent field handle's `error` (e.g. `config.prompt.template`).\n * Reading `form.formState` directly would NOT establish a subscription: RHF's\n * proxy only re-renders the component that called `useForm`, and `FieldRenderer`\n * memoizes on the handle's top-level `error`, so the inline message would\n * otherwise appear only after a remount.\n */\nexport function useFieldError(form: FormHandle, path: string): string | undefined {\n const { control } = asInternalForm(form as FormHandle<FieldValues>);\n const { isSubmitted, errors } = useFormState({ control, name: path });\n if (!isSubmitted) return undefined;\n return resolveError(errors as FormErrors, path);\n}\n\nfunction resolveError(errors: FormErrors, path: string): string | undefined {\n const segments = path.split(\".\");\n let node: unknown = errors;\n for (const seg of segments) {\n if (node == null || typeof node !== \"object\") return undefined;\n node = (node as Record<string, unknown>)[seg];\n if (node == null) return undefined;\n }\n if (node != null && typeof node === \"object\" && \"message\" in node) {\n const msg = (node as { message?: unknown }).message;\n return typeof msg === \"string\" ? msg : undefined;\n }\n return undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,SAAgB,cAAc,MAAkB,MAAkC;CAChF,MAAM,EAAE,YAAY,eAAe,KAAgC;CACnE,MAAM,EAAE,aAAa,WAAW,aAAa;EAAE;EAAS,MAAM;EAAM,CAAC;AACrE,KAAI,CAAC,YAAa,QAAO;AACzB,QAAO,aAAa,QAAsB,KAAK;;AAGjD,SAAS,aAAa,QAAoB,MAAkC;CAC1E,MAAM,WAAW,KAAK,MAAM,IAAI;CAChC,IAAI,OAAgB;AACpB,MAAK,MAAM,OAAO,UAAU;AAC1B,MAAI,QAAQ,QAAQ,OAAO,SAAS,SAAU,QAAO;AACrD,SAAQ,KAAiC;AACzC,MAAI,QAAQ,KAAM,QAAO;;AAE3B,KAAI,QAAQ,QAAQ,OAAO,SAAS,YAAY,aAAa,MAAM;EACjE,MAAM,MAAO,KAA+B;AAC5C,SAAO,OAAO,QAAQ,WAAW,MAAM"}
@@ -1,9 +1,10 @@
1
1
  import { useEffect, useState } from "react";
2
2
 
3
3
  //#region src/hooks/use-menu-navigation.ts
4
- function useMenuNavigation({ editor, containerRef, query, items, onSelect, onClose, orientation = "vertical", autoSelectFirstItem = true }) {
4
+ function useMenuNavigation({ editor, containerRef, query, items, onSelect, onClose, orientation = "vertical", autoSelectFirstItem = true, enabled = true }) {
5
5
  const [selectedIndex, setSelectedIndex] = useState(autoSelectFirstItem ? 0 : -1);
6
6
  useEffect(() => {
7
+ if (!enabled) return void 0;
7
8
  const handleKeyboardNavigation = (event) => {
8
9
  if (!items.length) return false;
9
10
  const moveNext = () => setSelectedIndex((i) => i === -1 ? 0 : (i + 1) % items.length);
@@ -64,6 +65,7 @@ function useMenuNavigation({ editor, containerRef, query, items, onSelect, onClo
64
65
  };
65
66
  }
66
67
  }, [
68
+ enabled,
67
69
  editor,
68
70
  containerRef,
69
71
  items,
@@ -1 +1 @@
1
- {"version":3,"file":"use-menu-navigation.mjs","names":[],"sources":["../../src/hooks/use-menu-navigation.ts"],"sourcesContent":["import type { Editor } from \"@tiptap/react\";\nimport { type RefObject, useEffect, useState } from \"react\";\n\ntype Orientation = \"horizontal\" | \"vertical\" | \"both\";\n\ninterface MenuNavigationOptions<T> {\n editor?: Editor | null;\n containerRef?: RefObject<HTMLElement | null>;\n query?: string;\n items: T[];\n onSelect?: (item: T) => void;\n onClose?: () => void;\n orientation?: Orientation;\n autoSelectFirstItem?: boolean;\n}\n\nexport function useMenuNavigation<T>({\n editor,\n containerRef,\n query,\n items,\n onSelect,\n onClose,\n orientation = \"vertical\",\n autoSelectFirstItem = true,\n}: MenuNavigationOptions<T>) {\n const [selectedIndex, setSelectedIndex] = useState<number>(autoSelectFirstItem ? 0 : -1);\n\n useEffect(() => {\n const handleKeyboardNavigation = (event: KeyboardEvent) => {\n if (!items.length) return false;\n\n const moveNext = () => setSelectedIndex((i) => (i === -1 ? 0 : (i + 1) % items.length));\n const movePrev = () =>\n setSelectedIndex((i) =>\n i === -1 ? items.length - 1 : (i - 1 + items.length) % items.length,\n );\n\n switch (event.key) {\n case \"ArrowUp\":\n if (orientation === \"horizontal\") return false;\n event.preventDefault();\n movePrev();\n return true;\n case \"ArrowDown\":\n if (orientation === \"horizontal\") return false;\n event.preventDefault();\n moveNext();\n return true;\n case \"ArrowLeft\":\n if (orientation === \"vertical\") return false;\n event.preventDefault();\n movePrev();\n return true;\n case \"ArrowRight\":\n if (orientation === \"vertical\") return false;\n event.preventDefault();\n moveNext();\n return true;\n case \"Tab\":\n event.preventDefault();\n if (event.shiftKey) movePrev();\n else moveNext();\n return true;\n case \"Home\":\n event.preventDefault();\n setSelectedIndex(0);\n return true;\n case \"End\":\n event.preventDefault();\n setSelectedIndex(items.length - 1);\n return true;\n case \"Enter\":\n if (event.isComposing) return false;\n event.preventDefault();\n if (selectedIndex !== -1 && items[selectedIndex]) {\n onSelect?.(items[selectedIndex]);\n }\n return true;\n case \"Escape\":\n event.preventDefault();\n onClose?.();\n return true;\n default:\n return false;\n }\n };\n\n let targetElement: HTMLElement | null = null;\n\n if (editor) {\n targetElement = editor.view.dom;\n } else if (containerRef?.current) {\n targetElement = containerRef.current;\n }\n\n if (targetElement) {\n targetElement.addEventListener(\"keydown\", handleKeyboardNavigation, true);\n return () => {\n targetElement?.removeEventListener(\"keydown\", handleKeyboardNavigation, true);\n };\n }\n\n return undefined;\n }, [editor, containerRef, items, selectedIndex, onSelect, onClose, orientation]);\n\n useEffect(() => {\n if (query) {\n setSelectedIndex(autoSelectFirstItem ? 0 : -1);\n }\n }, [query, autoSelectFirstItem]);\n\n return {\n selectedIndex: items.length ? selectedIndex : undefined,\n setSelectedIndex,\n };\n}\n"],"mappings":";;;AAgBA,SAAgB,kBAAqB,EACnC,QACA,cACA,OACA,OACA,UACA,SACA,cAAc,YACd,sBAAsB,QACK;CAC3B,MAAM,CAAC,eAAe,oBAAoB,SAAiB,sBAAsB,IAAI,GAAG;AAExF,iBAAgB;EACd,MAAM,4BAA4B,UAAyB;AACzD,OAAI,CAAC,MAAM,OAAQ,QAAO;GAE1B,MAAM,iBAAiB,kBAAkB,MAAO,MAAM,KAAK,KAAK,IAAI,KAAK,MAAM,OAAQ;GACvF,MAAM,iBACJ,kBAAkB,MAChB,MAAM,KAAK,MAAM,SAAS,KAAK,IAAI,IAAI,MAAM,UAAU,MAAM,OAC9D;AAEH,WAAQ,MAAM,KAAd;IACE,KAAK;AACH,SAAI,gBAAgB,aAAc,QAAO;AACzC,WAAM,gBAAgB;AACtB,eAAU;AACV,YAAO;IACT,KAAK;AACH,SAAI,gBAAgB,aAAc,QAAO;AACzC,WAAM,gBAAgB;AACtB,eAAU;AACV,YAAO;IACT,KAAK;AACH,SAAI,gBAAgB,WAAY,QAAO;AACvC,WAAM,gBAAgB;AACtB,eAAU;AACV,YAAO;IACT,KAAK;AACH,SAAI,gBAAgB,WAAY,QAAO;AACvC,WAAM,gBAAgB;AACtB,eAAU;AACV,YAAO;IACT,KAAK;AACH,WAAM,gBAAgB;AACtB,SAAI,MAAM,SAAU,WAAU;SACzB,WAAU;AACf,YAAO;IACT,KAAK;AACH,WAAM,gBAAgB;AACtB,sBAAiB,EAAE;AACnB,YAAO;IACT,KAAK;AACH,WAAM,gBAAgB;AACtB,sBAAiB,MAAM,SAAS,EAAE;AAClC,YAAO;IACT,KAAK;AACH,SAAI,MAAM,YAAa,QAAO;AAC9B,WAAM,gBAAgB;AACtB,SAAI,kBAAkB,MAAM,MAAM,eAChC,YAAW,MAAM,eAAe;AAElC,YAAO;IACT,KAAK;AACH,WAAM,gBAAgB;AACtB,gBAAW;AACX,YAAO;IACT,QACE,QAAO;;;EAIb,IAAI,gBAAoC;AAExC,MAAI,OACF,iBAAgB,OAAO,KAAK;WACnB,cAAc,QACvB,iBAAgB,aAAa;AAG/B,MAAI,eAAe;AACjB,iBAAc,iBAAiB,WAAW,0BAA0B,KAAK;AACzE,gBAAa;AACX,mBAAe,oBAAoB,WAAW,0BAA0B,KAAK;;;IAKhF;EAAC;EAAQ;EAAc;EAAO;EAAe;EAAU;EAAS;EAAY,CAAC;AAEhF,iBAAgB;AACd,MAAI,MACF,kBAAiB,sBAAsB,IAAI,GAAG;IAE/C,CAAC,OAAO,oBAAoB,CAAC;AAEhC,QAAO;EACL,eAAe,MAAM,SAAS,gBAAgB;EAC9C;EACD"}
1
+ {"version":3,"file":"use-menu-navigation.mjs","names":[],"sources":["../../src/hooks/use-menu-navigation.ts"],"sourcesContent":["import type { Editor } from \"@tiptap/react\";\nimport { type RefObject, useEffect, useState } from \"react\";\n\ntype Orientation = \"horizontal\" | \"vertical\" | \"both\";\n\ninterface MenuNavigationOptions<T> {\n editor?: Editor | null;\n containerRef?: RefObject<HTMLElement | null>;\n query?: string;\n items: T[];\n onSelect?: (item: T) => void;\n onClose?: () => void;\n orientation?: Orientation;\n autoSelectFirstItem?: boolean;\n /**\n * When false, no keydown listener is attached. Callers must gate this on the\n * menu's open state — otherwise the capture-phase handler would swallow keys\n * like Enter (preventing newlines) whenever `items` is non-empty, even with\n * the menu closed.\n */\n enabled?: boolean;\n}\n\nexport function useMenuNavigation<T>({\n editor,\n containerRef,\n query,\n items,\n onSelect,\n onClose,\n orientation = \"vertical\",\n autoSelectFirstItem = true,\n enabled = true,\n}: MenuNavigationOptions<T>) {\n const [selectedIndex, setSelectedIndex] = useState<number>(autoSelectFirstItem ? 0 : -1);\n\n useEffect(() => {\n if (!enabled) return undefined;\n\n const handleKeyboardNavigation = (event: KeyboardEvent) => {\n if (!items.length) return false;\n\n const moveNext = () => setSelectedIndex((i) => (i === -1 ? 0 : (i + 1) % items.length));\n const movePrev = () =>\n setSelectedIndex((i) =>\n i === -1 ? items.length - 1 : (i - 1 + items.length) % items.length,\n );\n\n switch (event.key) {\n case \"ArrowUp\":\n if (orientation === \"horizontal\") return false;\n event.preventDefault();\n movePrev();\n return true;\n case \"ArrowDown\":\n if (orientation === \"horizontal\") return false;\n event.preventDefault();\n moveNext();\n return true;\n case \"ArrowLeft\":\n if (orientation === \"vertical\") return false;\n event.preventDefault();\n movePrev();\n return true;\n case \"ArrowRight\":\n if (orientation === \"vertical\") return false;\n event.preventDefault();\n moveNext();\n return true;\n case \"Tab\":\n event.preventDefault();\n if (event.shiftKey) movePrev();\n else moveNext();\n return true;\n case \"Home\":\n event.preventDefault();\n setSelectedIndex(0);\n return true;\n case \"End\":\n event.preventDefault();\n setSelectedIndex(items.length - 1);\n return true;\n case \"Enter\":\n if (event.isComposing) return false;\n event.preventDefault();\n if (selectedIndex !== -1 && items[selectedIndex]) {\n onSelect?.(items[selectedIndex]);\n }\n return true;\n case \"Escape\":\n event.preventDefault();\n onClose?.();\n return true;\n default:\n return false;\n }\n };\n\n let targetElement: HTMLElement | null = null;\n\n if (editor) {\n targetElement = editor.view.dom;\n } else if (containerRef?.current) {\n targetElement = containerRef.current;\n }\n\n if (targetElement) {\n targetElement.addEventListener(\"keydown\", handleKeyboardNavigation, true);\n return () => {\n targetElement?.removeEventListener(\"keydown\", handleKeyboardNavigation, true);\n };\n }\n\n return undefined;\n }, [enabled, editor, containerRef, items, selectedIndex, onSelect, onClose, orientation]);\n\n useEffect(() => {\n if (query) {\n setSelectedIndex(autoSelectFirstItem ? 0 : -1);\n }\n }, [query, autoSelectFirstItem]);\n\n return {\n selectedIndex: items.length ? selectedIndex : undefined,\n setSelectedIndex,\n };\n}\n"],"mappings":";;;AAuBA,SAAgB,kBAAqB,EACnC,QACA,cACA,OACA,OACA,UACA,SACA,cAAc,YACd,sBAAsB,MACtB,UAAU,QACiB;CAC3B,MAAM,CAAC,eAAe,oBAAoB,SAAiB,sBAAsB,IAAI,GAAG;AAExF,iBAAgB;AACd,MAAI,CAAC,QAAS,QAAO;EAErB,MAAM,4BAA4B,UAAyB;AACzD,OAAI,CAAC,MAAM,OAAQ,QAAO;GAE1B,MAAM,iBAAiB,kBAAkB,MAAO,MAAM,KAAK,KAAK,IAAI,KAAK,MAAM,OAAQ;GACvF,MAAM,iBACJ,kBAAkB,MAChB,MAAM,KAAK,MAAM,SAAS,KAAK,IAAI,IAAI,MAAM,UAAU,MAAM,OAC9D;AAEH,WAAQ,MAAM,KAAd;IACE,KAAK;AACH,SAAI,gBAAgB,aAAc,QAAO;AACzC,WAAM,gBAAgB;AACtB,eAAU;AACV,YAAO;IACT,KAAK;AACH,SAAI,gBAAgB,aAAc,QAAO;AACzC,WAAM,gBAAgB;AACtB,eAAU;AACV,YAAO;IACT,KAAK;AACH,SAAI,gBAAgB,WAAY,QAAO;AACvC,WAAM,gBAAgB;AACtB,eAAU;AACV,YAAO;IACT,KAAK;AACH,SAAI,gBAAgB,WAAY,QAAO;AACvC,WAAM,gBAAgB;AACtB,eAAU;AACV,YAAO;IACT,KAAK;AACH,WAAM,gBAAgB;AACtB,SAAI,MAAM,SAAU,WAAU;SACzB,WAAU;AACf,YAAO;IACT,KAAK;AACH,WAAM,gBAAgB;AACtB,sBAAiB,EAAE;AACnB,YAAO;IACT,KAAK;AACH,WAAM,gBAAgB;AACtB,sBAAiB,MAAM,SAAS,EAAE;AAClC,YAAO;IACT,KAAK;AACH,SAAI,MAAM,YAAa,QAAO;AAC9B,WAAM,gBAAgB;AACtB,SAAI,kBAAkB,MAAM,MAAM,eAChC,YAAW,MAAM,eAAe;AAElC,YAAO;IACT,KAAK;AACH,WAAM,gBAAgB;AACtB,gBAAW;AACX,YAAO;IACT,QACE,QAAO;;;EAIb,IAAI,gBAAoC;AAExC,MAAI,OACF,iBAAgB,OAAO,KAAK;WACnB,cAAc,QACvB,iBAAgB,aAAa;AAG/B,MAAI,eAAe;AACjB,iBAAc,iBAAiB,WAAW,0BAA0B,KAAK;AACzE,gBAAa;AACX,mBAAe,oBAAoB,WAAW,0BAA0B,KAAK;;;IAKhF;EAAC;EAAS;EAAQ;EAAc;EAAO;EAAe;EAAU;EAAS;EAAY,CAAC;AAEzF,iBAAgB;AACd,MAAI,MACF,kBAAiB,sBAAsB,IAAI,GAAG;IAE/C,CAAC,OAAO,oBAAoB,CAAC;AAEhC,QAAO;EACL,eAAe,MAAM,SAAS,gBAAgB;EAC9C;EACD"}
@@ -32,14 +32,14 @@ declare function usePipeCatalogTable(config?: {
32
32
  removeColumnFilter: (id: "inputFields" | "outputFields" | "tags" | "providers") => void;
33
33
  resetFilters: () => void;
34
34
  getColumnFilterValue: (id: "inputFields" | "outputFields" | "tags" | "providers") => string;
35
- sortedInputFieldEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
36
- sortedOutputFieldEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
37
- sortedTagEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
38
- sortedProviderEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
39
- pipeIdsByInputField: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
40
- pipeIdsByOutputField: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
41
- pipeIdsByProvider: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
42
- pipeIdsByTag: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
35
+ sortedInputFieldEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
36
+ sortedOutputFieldEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
37
+ sortedTagEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
38
+ sortedProviderEntries: [string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]][];
39
+ pipeIdsByInputField: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
40
+ pipeIdsByOutputField: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
41
+ pipeIdsByProvider: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
42
+ pipeIdsByTag: Record<string, ("prompt:run@1" | "company:newssummary:website@1" | "company:newssummary:domain@1" | "company:techstack:builtwith@1" | "company:techstack:builtwith@2" | "company:websiteurl:email@1" | "company:domain:workemail@1" | "company:funding:leadmagic@1" | "company:funding:leadmagic@2" | "people:workemail:waterfall@1" | "person:workemail:waterfall@1" | "people:email:iswork@1" | "email:iswork@1" | "people:name:split@1" | "person:name:split@1" | "person:name:join@1" | "people:validate:email:zerobounce@1" | "people:email:validate:zerobounce@2" | "email:validate:zerobounce@1" | "people:mobilenumber:workemail:waterfall@1" | "company:overview@1" | "company:overview@2" | "company:overview@3" | "json:extract:multi@1" | "email:write@1" | "message:write@1" | "email:send:resend@1" | "email:send:gmail@1" | "message:send:slack@1" | "template:fill@1" | "contact:create:resend@1" | "people:match:role:waterfall@1" | "person:match:role:waterfall@1" | "person:identity:amplemarket@1" | "company:identity@2" | "company:identity@3" | "person:match:amplemarket@1" | "people:phone:profile:waterfall@1" | "person:mobile:profileurl:waterfall@1" | "people:personalemail:profile:waterfall@1" | "person:personalemail:profileurl:waterfall@1" | "people:profile:waterfall@1" | "person:profile:waterfall@1" | "people:profileurl:email:waterfall@1" | "person:profileurl:email:waterfall@1" | "person:profileurl:name@1" | "people:email:validate:zerobounce@1" | "person:email:validate:millionverifier@1" | "people:phone:workemail:waterfall@1" | "person:mobile:workemail:waterfall@1" | "fields:merge@1" | "field:slugify@1" | "field:domainify@1" | "website:scrape:firecrawl@1" | "website:scrapelist:firecrawl@1" | "website:extract:firecrawl@1" | "website:maplinks:firecrawl@1" | "sheet:row:append@1" | "sheet:row:expandappend@1" | "company:lookalikes:companyenrich@1" | "company:lookalikes:companyenrich@2" | "company:match:logodev@1" | "company:match:logodev@2" | "person:posts:crustdata@1" | "company:match:crustdata@1" | "company:match:crustdata@2" | "people:profile:workemail:crustdata@1" | "person:profile:workemail:crustdata@1" | "people:workemail:profileurl:waterfall@1" | "person:workemail:profileurl:waterfall@1" | "people:identity:email:waterfall@1" | "person:identity:email:waterfall@1" | "person:devprofileurl:profileurl:waterfall@1" | "http:request@1" | "company:identity@1" | "people:professionalprofile:waterfall@1" | "people:professionalprofileurl:name@1" | "people:professionalprofileurl:email:waterfall@1" | "people:mobilenumber:professionalprofile:waterfall@1")[]>;
43
43
  };
44
44
  type UsePipeCatalogTableReturn = ReturnType<typeof usePipeCatalogTable>;
45
45
  //#endregion
@@ -6,7 +6,7 @@ import * as _$class_variance_authority_types0 from "class-variance-authority/typ
6
6
 
7
7
  //#region src/widgets/avatar-group.d.ts
8
8
  declare const avatarGroupVariants: (props?: ({
9
- size?: "sm" | "lg" | "md" | null | undefined;
9
+ size?: "sm" | "md" | "lg" | null | undefined;
10
10
  } & _$class_variance_authority_types0.ClassProp) | undefined) => string;
11
11
  interface AvatarGroupState {
12
12
  overflows: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipe0/react",
3
- "version": "0.0.14",
3
+ "version": "0.0.16",
4
4
  "description": "React component library for building forms and catalogs powered by pipe0 pipes and searches.",
5
5
  "license": "MIT",
6
6
  "author": "pipe0",
@@ -84,7 +84,7 @@
84
84
  "lucide-react": "^0.475.0",
85
85
  "swr": "^2.4.1",
86
86
  "tailwind-merge": "^3.3.1",
87
- "@pipe0/base": "0.1.1"
87
+ "@pipe0/base": "0.1.3"
88
88
  },
89
89
  "devDependencies": {
90
90
  "@dnd-kit/core": "^6.3.1",