@pipe0/react 1.0.1 → 1.0.2
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
|
@@ -57,7 +57,7 @@ function buildSecretItem(s) {
|
|
|
57
57
|
function buildConstantItem(c) {
|
|
58
58
|
return {
|
|
59
59
|
title: c.label,
|
|
60
|
-
subtext: c.ownershipLevel,
|
|
60
|
+
subtext: c.format === "text" ? `${c.ownershipLevel} · multi-line` : c.ownershipLevel,
|
|
61
61
|
keywords: [c.publicId],
|
|
62
62
|
context: { kind: "constant" },
|
|
63
63
|
onSelect: ({ editor, range }) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UnifiedReferencePicker.mjs","names":[],"sources":["../../../../src/components/internal/LiquidEditor/UnifiedReferencePicker.tsx"],"sourcesContent":["import type { PipesFieldDefinitionWithName } from \"@pipe0/base\";\nimport { Hash, Key } from \"lucide-react\";\nimport type { ConstantSuggestion, SecretSuggestion } from \"../../../types/field-props.js\";\nimport type {\n SuggestionItem,\n SuggestionMenuRenderProps,\n} from \"../suggestion-menu/suggestion-menu-types.js\";\n\nexport const SECTION_CAP = 5;\n\nexport type ReferenceKind = \"field\" | \"secret\" | \"constant\";\n\nexport interface ReferenceContext {\n kind: ReferenceKind;\n}\n\nexport interface ReferenceSources {\n inputFields: PipesFieldDefinitionWithName[];\n secretSuggestions: SecretSuggestion[];\n constantSuggestions: ConstantSuggestion[];\n}\n\nconst PREFIX_RE = /^([fsc])\\/(.*)$/;\n\n/**\n * Parses a typed query into `(prefix, residual)`. Lets users filter\n * directly to a single source: `f/email`, `s/STRIPE`, `c/REGION`.\n * Without a prefix, all sources are searched.\n */\nexport function parseQuery(query: string): {\n prefix: ReferenceKind | null;\n residual: string;\n} {\n const m = query.match(PREFIX_RE);\n if (!m) return { prefix: null, residual: query };\n const map = { f: \"field\", s: \"secret\", c: \"constant\" } as const;\n return { prefix: map[m[1] as \"f\" | \"s\" | \"c\"], residual: m[2] };\n}\n\nfunction score(haystack: string, needle: string): number {\n if (!needle) return 1;\n const h = haystack.toLowerCase();\n const n = needle.toLowerCase();\n if (h === n) return 100;\n if (h.startsWith(n)) return 50;\n if (h.includes(n)) return 10;\n return 0;\n}\n\nfunction buildFieldItem(\n f: PipesFieldDefinitionWithName,\n insertField: (name: string) => string,\n): SuggestionItem<ReferenceContext> {\n return {\n title: f.resolvedName,\n subtext: f.type,\n keywords: [f.type],\n context: { kind: \"field\" },\n onSelect: ({ editor, range }) => {\n editor.chain().focus().insertContentAt(range, insertField(f.resolvedName)).run();\n },\n };\n}\n\nfunction buildSecretItem(s: SecretSuggestion): SuggestionItem<ReferenceContext> {\n return {\n title: s.label,\n subtext: `${s.mask} · ${s.ownershipLevel}${s.providerHint ? ` · ${s.providerHint}` : \"\"}`,\n keywords: [s.publicId, s.providerHint ?? \"\"],\n context: { kind: \"secret\" },\n onSelect: ({ editor, range }) => {\n editor.chain().focus().insertContentAt(range, `{{ SECRETS.${s.publicId} }}`).run();\n },\n };\n}\n\nfunction buildConstantItem(c: ConstantSuggestion): SuggestionItem<ReferenceContext> {\n return {\n title: c.label,\n subtext: c.ownershipLevel,\n keywords: [c.publicId],\n context: { kind: \"constant\" },\n onSelect: ({ editor, range }) => {\n editor.chain().focus().insertContentAt(range, `{{ CONSTANTS.${c.publicId} }}`).run();\n },\n };\n}\n\n/**\n * Builds the suggestion list for a given query against the three sources.\n * Behavior:\n * - empty query → returns all items in source order (Fields, then\n * Secrets, then Constants). Header rows are rendered separately by\n * the picker UI — this function returns a flat list of items only.\n * - non-empty query → ranks across all sources with a simple\n * starts-with > includes scoring. Items with a zero score are\n * dropped.\n * - prefix syntax `f/`, `s/`, `c/` filters to a single source before\n * scoring with the residual.\n */\nexport function buildReferenceItems(\n query: string,\n sources: ReferenceSources,\n expectedFieldType: string | undefined,\n insertField: (name: string) => string,\n): SuggestionItem<ReferenceContext>[] {\n const { prefix, residual } = parseQuery(query);\n\n const fieldsAll = expectedFieldType\n ? sources.inputFields.filter((f) => f.type === expectedFieldType)\n : sources.inputFields;\n\n const fieldItems = fieldsAll.map((f) => buildFieldItem(f, insertField));\n const secretItems = sources.secretSuggestions.map(buildSecretItem);\n const constantItems = sources.constantSuggestions.map(buildConstantItem);\n\n const pool: SuggestionItem<ReferenceContext>[] =\n prefix === \"field\"\n ? fieldItems\n : prefix === \"secret\"\n ? secretItems\n : prefix === \"constant\"\n ? constantItems\n : [...fieldItems, ...secretItems, ...constantItems];\n\n if (!residual.trim()) return pool;\n\n return pool\n .map((item) => {\n const titleScore = score(item.title, residual);\n const keywordScore = (item.keywords ?? []).reduce(\n (best, kw) => Math.max(best, score(kw, residual)),\n 0,\n );\n const subtextScore = item.subtext ? score(item.subtext, residual) * 0.5 : 0;\n const total = Math.max(titleScore, keywordScore, subtextScore);\n return { item, total };\n })\n .filter(({ total }) => total > 0)\n .sort((a, b) => b.total - a.total)\n .map(({ item }) => item);\n}\n\nfunction KindIcon({ kind }: { kind: ReferenceKind }) {\n // Fields are the default category and don't need a marker — the section\n // header and the type column on the right convey the kind.\n if (kind === \"field\") return null;\n if (kind === \"secret\") return <Key className=\"pz:size-3.5 pz:text-amber-700\" aria-hidden />;\n return <Hash className=\"pz:size-3.5 pz:text-violet-700\" aria-hidden />;\n}\n\nfunction SectionHeader({ children }: { children: React.ReactNode }) {\n return (\n <div className=\"pz:px-2 pz:pt-1.5 pz:pb-0.5 pz:text-[10px] pz:font-medium pz:uppercase pz:tracking-wide pz:text-muted-foreground\">\n {children}\n </div>\n );\n}\n\nfunction ItemRow({\n item,\n active,\n onSelect,\n}: {\n item: SuggestionItem<ReferenceContext>;\n active: boolean;\n onSelect: (item: SuggestionItem<ReferenceContext>) => void;\n}) {\n return (\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={active}\n onClick={() => onSelect(item)}\n className={[\n \"pz:flex pz:w-full pz:items-center pz:gap-2 pz:rounded-sm pz:px-2 pz:py-1 pz:text-sm pz:text-left pz:cursor-pointer\",\n active\n ? \"pz:bg-accent pz:text-accent-foreground\"\n : \"pz:hover:bg-accent pz:hover:text-accent-foreground\",\n ].join(\" \")}\n >\n <KindIcon kind={item.context?.kind ?? \"field\"} />\n <span className=\"pz:truncate\">{item.title}</span>\n {item.subtext && (\n <span className=\"pz:ml-auto pz:shrink-0 pz:truncate pz:text-xs pz:text-muted-foreground\">\n {item.subtext}\n </span>\n )}\n </button>\n );\n}\n\n/**\n * Picker UI rendered inside the SuggestionMenu's children render-prop.\n *\n * - Empty query → sectioned view (Fields, Secrets, Constants).\n * - Non-empty query → flat ranked list.\n *\n * The selected-index pointer from `SuggestionMenuRenderProps` always maps\n * to the flat `items` order. Sectioned mode uses the same flat order but\n * inserts headers between the boundaries, so highlight tracking still\n * works without bespoke navigation.\n */\nexport interface OverflowCounts {\n field: number;\n secret: number;\n constant: number;\n}\n\nexport function UnifiedReferencePicker({\n items,\n selectedIndex,\n onSelect,\n query,\n hasSecretsResolver,\n hasConstantsResolver,\n inputFieldsCount,\n secretsPending,\n constantsPending,\n overflow,\n}: SuggestionMenuRenderProps<ReferenceContext> & {\n query: string;\n hasSecretsResolver: boolean;\n hasConstantsResolver: boolean;\n inputFieldsCount: number;\n secretsPending: boolean;\n constantsPending: boolean;\n overflow: OverflowCounts;\n}) {\n const { prefix, residual } = parseQuery(query);\n const isFlat = !!residual.trim() || prefix !== null;\n\n if (isFlat) {\n if (items.length === 0) {\n const isPendingForPrefix =\n (prefix === \"secret\" && secretsPending) ||\n (prefix === \"constant\" && constantsPending) ||\n (prefix === null && (secretsPending || constantsPending));\n return (\n <div className=\"pz:flex pz:flex-col pz:gap-0.5 pz:p-1 pz:min-w-72\" role=\"listbox\">\n {prefix && (\n <SectionHeader>\n {prefix === \"field\" ? \"Fields\" : prefix === \"secret\" ? \"Secrets\" : \"Constants\"}\n </SectionHeader>\n )}\n <div className=\"pz:px-2 pz:py-1.5 pz:text-sm pz:text-muted-foreground\">\n {isPendingForPrefix ? \"Searching…\" : describeEmpty(prefix)}\n </div>\n </div>\n );\n }\n return (\n <div className=\"pz:flex pz:flex-col pz:gap-0.5 pz:p-1 pz:min-w-72\" role=\"listbox\">\n {prefix && (\n <SectionHeader>\n {prefix === \"field\" ? \"Fields\" : prefix === \"secret\" ? \"Secrets\" : \"Constants\"}\n </SectionHeader>\n )}\n {items.map((item, index) => (\n <ItemRow\n key={`${item.context?.kind}-${item.title}`}\n item={item}\n active={selectedIndex === index}\n onSelect={onSelect}\n />\n ))}\n </div>\n );\n }\n\n // Sectioned view — always render Fields and Secrets headers in fixed\n // order, with empty-state hints when a section has no items. Constants\n // only appear when there are any to show.\n //\n // Items here are pre-capped per kind (LiquidEditor applies SECTION_CAP).\n // The selectedIndex maps to this capped flat order — no hidden rows.\n const fieldItems = items.filter((it) => it.context?.kind === \"field\");\n const secretItems = items.filter((it) => it.context?.kind === \"secret\");\n const constantItems = items.filter((it) => it.context?.kind === \"constant\");\n\n return (\n <div className=\"pz:flex pz:flex-col pz:gap-0.5 pz:p-1 pz:min-w-72\" role=\"listbox\">\n <Section\n label=\"Fields\"\n kind=\"field\"\n items={fieldItems}\n startIndex={0}\n selectedIndex={selectedIndex}\n onSelect={onSelect}\n emptyHint={\n inputFieldsCount === 0 ? \"No input fields available.\" : \"No matching input fields.\"\n }\n overflow={overflow.field}\n overflowHelper=\"Type to filter.\"\n />\n {hasSecretsResolver && (\n <Section\n label=\"Secrets\"\n kind=\"secret\"\n items={secretItems}\n startIndex={fieldItems.length}\n selectedIndex={selectedIndex}\n onSelect={onSelect}\n emptyHint={secretsPending ? \"Searching…\" : \"No matching secrets.\"}\n helperHint=\"Type /s/ to filter to secrets only.\"\n pending={secretsPending}\n overflow={overflow.secret}\n overflowHelper=\"Type to filter, or /s/ for secrets only.\"\n />\n )}\n {hasConstantsResolver && (\n <Section\n label=\"Constants\"\n kind=\"constant\"\n items={constantItems}\n startIndex={fieldItems.length + secretItems.length}\n selectedIndex={selectedIndex}\n onSelect={onSelect}\n emptyHint={constantsPending ? \"Searching…\" : \"No matching constants.\"}\n helperHint=\"Type /c/ to filter to constants only.\"\n pending={constantsPending}\n overflow={overflow.constant}\n overflowHelper=\"Type to filter, or /c/ for constants only.\"\n />\n )}\n </div>\n );\n}\n\nfunction Section({\n label,\n kind,\n items,\n startIndex,\n selectedIndex,\n onSelect,\n emptyHint,\n helperHint,\n pending,\n overflow = 0,\n overflowHelper,\n}: {\n label: string;\n kind: ReferenceKind;\n items: SuggestionItem<ReferenceContext>[];\n startIndex: number;\n selectedIndex?: number;\n onSelect: (item: SuggestionItem<ReferenceContext>) => void;\n emptyHint: string;\n helperHint?: string;\n pending?: boolean;\n overflow?: number;\n overflowHelper?: string;\n}) {\n return (\n <div className=\"pz:flex pz:flex-col\">\n <SectionHeader>\n {label}\n {items.length > 0 && (\n <span className=\"pz:ml-1 pz:normal-case pz:tracking-normal\">\n ({items.length}\n {overflow > 0 && ` of ${items.length + overflow}`})\n </span>\n )}\n {pending && (\n <span className=\"pz:ml-1 pz:normal-case pz:tracking-normal pz:opacity-70\">\n · Searching…\n </span>\n )}\n </SectionHeader>\n {items.length === 0 ? (\n <div className=\"pz:px-2 pz:py-1 pz:text-xs pz:text-muted-foreground\">\n {emptyHint}\n {helperHint && <span className=\"pz:block pz:opacity-70\">{helperHint}</span>}\n </div>\n ) : (\n <>\n {items.map((item, i) => (\n <ItemRow\n key={`${kind}-${item.title}`}\n item={item}\n active={selectedIndex === startIndex + i}\n onSelect={onSelect}\n />\n ))}\n {overflow > 0 && overflowHelper && (\n <div className=\"pz:px-2 pz:py-0.5 pz:text-[11px] pz:text-muted-foreground pz:opacity-70\">\n +{overflow} more — {overflowHelper}\n </div>\n )}\n </>\n )}\n </div>\n );\n}\n\nfunction describeEmpty(prefix: ReferenceKind | null): string {\n if (prefix === \"secret\") return \"No matching secrets.\";\n if (prefix === \"constant\") return \"No matching constants.\";\n if (prefix === \"field\") return \"No matching fields.\";\n return \"No matches.\";\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"UnifiedReferencePicker.mjs","names":[],"sources":["../../../../src/components/internal/LiquidEditor/UnifiedReferencePicker.tsx"],"sourcesContent":["import type { PipesFieldDefinitionWithName } from \"@pipe0/base\";\nimport { Hash, Key } from \"lucide-react\";\nimport type { ConstantSuggestion, SecretSuggestion } from \"../../../types/field-props.js\";\nimport type {\n SuggestionItem,\n SuggestionMenuRenderProps,\n} from \"../suggestion-menu/suggestion-menu-types.js\";\n\nexport const SECTION_CAP = 5;\n\nexport type ReferenceKind = \"field\" | \"secret\" | \"constant\";\n\nexport interface ReferenceContext {\n kind: ReferenceKind;\n}\n\nexport interface ReferenceSources {\n inputFields: PipesFieldDefinitionWithName[];\n secretSuggestions: SecretSuggestion[];\n constantSuggestions: ConstantSuggestion[];\n}\n\nconst PREFIX_RE = /^([fsc])\\/(.*)$/;\n\n/**\n * Parses a typed query into `(prefix, residual)`. Lets users filter\n * directly to a single source: `f/email`, `s/STRIPE`, `c/REGION`.\n * Without a prefix, all sources are searched.\n */\nexport function parseQuery(query: string): {\n prefix: ReferenceKind | null;\n residual: string;\n} {\n const m = query.match(PREFIX_RE);\n if (!m) return { prefix: null, residual: query };\n const map = { f: \"field\", s: \"secret\", c: \"constant\" } as const;\n return { prefix: map[m[1] as \"f\" | \"s\" | \"c\"], residual: m[2] };\n}\n\nfunction score(haystack: string, needle: string): number {\n if (!needle) return 1;\n const h = haystack.toLowerCase();\n const n = needle.toLowerCase();\n if (h === n) return 100;\n if (h.startsWith(n)) return 50;\n if (h.includes(n)) return 10;\n return 0;\n}\n\nfunction buildFieldItem(\n f: PipesFieldDefinitionWithName,\n insertField: (name: string) => string,\n): SuggestionItem<ReferenceContext> {\n return {\n title: f.resolvedName,\n subtext: f.type,\n keywords: [f.type],\n context: { kind: \"field\" },\n onSelect: ({ editor, range }) => {\n editor.chain().focus().insertContentAt(range, insertField(f.resolvedName)).run();\n },\n };\n}\n\nfunction buildSecretItem(s: SecretSuggestion): SuggestionItem<ReferenceContext> {\n return {\n title: s.label,\n subtext: `${s.mask} · ${s.ownershipLevel}${s.providerHint ? ` · ${s.providerHint}` : \"\"}`,\n keywords: [s.publicId, s.providerHint ?? \"\"],\n context: { kind: \"secret\" },\n onSelect: ({ editor, range }) => {\n editor.chain().focus().insertContentAt(range, `{{ SECRETS.${s.publicId} }}`).run();\n },\n };\n}\n\nfunction buildConstantItem(c: ConstantSuggestion): SuggestionItem<ReferenceContext> {\n return {\n title: c.label,\n // Flag multi-line constants — the reference is a single chip here but\n // expands to several lines at render time. A hint only; inserting one into\n // a single-line field is allowed.\n subtext: c.format === \"text\" ? `${c.ownershipLevel} · multi-line` : c.ownershipLevel,\n keywords: [c.publicId],\n context: { kind: \"constant\" },\n onSelect: ({ editor, range }) => {\n editor.chain().focus().insertContentAt(range, `{{ CONSTANTS.${c.publicId} }}`).run();\n },\n };\n}\n\n/**\n * Builds the suggestion list for a given query against the three sources.\n * Behavior:\n * - empty query → returns all items in source order (Fields, then\n * Secrets, then Constants). Header rows are rendered separately by\n * the picker UI — this function returns a flat list of items only.\n * - non-empty query → ranks across all sources with a simple\n * starts-with > includes scoring. Items with a zero score are\n * dropped.\n * - prefix syntax `f/`, `s/`, `c/` filters to a single source before\n * scoring with the residual.\n */\nexport function buildReferenceItems(\n query: string,\n sources: ReferenceSources,\n expectedFieldType: string | undefined,\n insertField: (name: string) => string,\n): SuggestionItem<ReferenceContext>[] {\n const { prefix, residual } = parseQuery(query);\n\n const fieldsAll = expectedFieldType\n ? sources.inputFields.filter((f) => f.type === expectedFieldType)\n : sources.inputFields;\n\n const fieldItems = fieldsAll.map((f) => buildFieldItem(f, insertField));\n const secretItems = sources.secretSuggestions.map(buildSecretItem);\n const constantItems = sources.constantSuggestions.map(buildConstantItem);\n\n const pool: SuggestionItem<ReferenceContext>[] =\n prefix === \"field\"\n ? fieldItems\n : prefix === \"secret\"\n ? secretItems\n : prefix === \"constant\"\n ? constantItems\n : [...fieldItems, ...secretItems, ...constantItems];\n\n if (!residual.trim()) return pool;\n\n return pool\n .map((item) => {\n const titleScore = score(item.title, residual);\n const keywordScore = (item.keywords ?? []).reduce(\n (best, kw) => Math.max(best, score(kw, residual)),\n 0,\n );\n const subtextScore = item.subtext ? score(item.subtext, residual) * 0.5 : 0;\n const total = Math.max(titleScore, keywordScore, subtextScore);\n return { item, total };\n })\n .filter(({ total }) => total > 0)\n .sort((a, b) => b.total - a.total)\n .map(({ item }) => item);\n}\n\nfunction KindIcon({ kind }: { kind: ReferenceKind }) {\n // Fields are the default category and don't need a marker — the section\n // header and the type column on the right convey the kind.\n if (kind === \"field\") return null;\n if (kind === \"secret\") return <Key className=\"pz:size-3.5 pz:text-amber-700\" aria-hidden />;\n return <Hash className=\"pz:size-3.5 pz:text-violet-700\" aria-hidden />;\n}\n\nfunction SectionHeader({ children }: { children: React.ReactNode }) {\n return (\n <div className=\"pz:px-2 pz:pt-1.5 pz:pb-0.5 pz:text-[10px] pz:font-medium pz:uppercase pz:tracking-wide pz:text-muted-foreground\">\n {children}\n </div>\n );\n}\n\nfunction ItemRow({\n item,\n active,\n onSelect,\n}: {\n item: SuggestionItem<ReferenceContext>;\n active: boolean;\n onSelect: (item: SuggestionItem<ReferenceContext>) => void;\n}) {\n return (\n <button\n type=\"button\"\n role=\"option\"\n aria-selected={active}\n onClick={() => onSelect(item)}\n className={[\n \"pz:flex pz:w-full pz:items-center pz:gap-2 pz:rounded-sm pz:px-2 pz:py-1 pz:text-sm pz:text-left pz:cursor-pointer\",\n active\n ? \"pz:bg-accent pz:text-accent-foreground\"\n : \"pz:hover:bg-accent pz:hover:text-accent-foreground\",\n ].join(\" \")}\n >\n <KindIcon kind={item.context?.kind ?? \"field\"} />\n <span className=\"pz:truncate\">{item.title}</span>\n {item.subtext && (\n <span className=\"pz:ml-auto pz:shrink-0 pz:truncate pz:text-xs pz:text-muted-foreground\">\n {item.subtext}\n </span>\n )}\n </button>\n );\n}\n\n/**\n * Picker UI rendered inside the SuggestionMenu's children render-prop.\n *\n * - Empty query → sectioned view (Fields, Secrets, Constants).\n * - Non-empty query → flat ranked list.\n *\n * The selected-index pointer from `SuggestionMenuRenderProps` always maps\n * to the flat `items` order. Sectioned mode uses the same flat order but\n * inserts headers between the boundaries, so highlight tracking still\n * works without bespoke navigation.\n */\nexport interface OverflowCounts {\n field: number;\n secret: number;\n constant: number;\n}\n\nexport function UnifiedReferencePicker({\n items,\n selectedIndex,\n onSelect,\n query,\n hasSecretsResolver,\n hasConstantsResolver,\n inputFieldsCount,\n secretsPending,\n constantsPending,\n overflow,\n}: SuggestionMenuRenderProps<ReferenceContext> & {\n query: string;\n hasSecretsResolver: boolean;\n hasConstantsResolver: boolean;\n inputFieldsCount: number;\n secretsPending: boolean;\n constantsPending: boolean;\n overflow: OverflowCounts;\n}) {\n const { prefix, residual } = parseQuery(query);\n const isFlat = !!residual.trim() || prefix !== null;\n\n if (isFlat) {\n if (items.length === 0) {\n const isPendingForPrefix =\n (prefix === \"secret\" && secretsPending) ||\n (prefix === \"constant\" && constantsPending) ||\n (prefix === null && (secretsPending || constantsPending));\n return (\n <div className=\"pz:flex pz:flex-col pz:gap-0.5 pz:p-1 pz:min-w-72\" role=\"listbox\">\n {prefix && (\n <SectionHeader>\n {prefix === \"field\" ? \"Fields\" : prefix === \"secret\" ? \"Secrets\" : \"Constants\"}\n </SectionHeader>\n )}\n <div className=\"pz:px-2 pz:py-1.5 pz:text-sm pz:text-muted-foreground\">\n {isPendingForPrefix ? \"Searching…\" : describeEmpty(prefix)}\n </div>\n </div>\n );\n }\n return (\n <div className=\"pz:flex pz:flex-col pz:gap-0.5 pz:p-1 pz:min-w-72\" role=\"listbox\">\n {prefix && (\n <SectionHeader>\n {prefix === \"field\" ? \"Fields\" : prefix === \"secret\" ? \"Secrets\" : \"Constants\"}\n </SectionHeader>\n )}\n {items.map((item, index) => (\n <ItemRow\n key={`${item.context?.kind}-${item.title}`}\n item={item}\n active={selectedIndex === index}\n onSelect={onSelect}\n />\n ))}\n </div>\n );\n }\n\n // Sectioned view — always render Fields and Secrets headers in fixed\n // order, with empty-state hints when a section has no items. Constants\n // only appear when there are any to show.\n //\n // Items here are pre-capped per kind (LiquidEditor applies SECTION_CAP).\n // The selectedIndex maps to this capped flat order — no hidden rows.\n const fieldItems = items.filter((it) => it.context?.kind === \"field\");\n const secretItems = items.filter((it) => it.context?.kind === \"secret\");\n const constantItems = items.filter((it) => it.context?.kind === \"constant\");\n\n return (\n <div className=\"pz:flex pz:flex-col pz:gap-0.5 pz:p-1 pz:min-w-72\" role=\"listbox\">\n <Section\n label=\"Fields\"\n kind=\"field\"\n items={fieldItems}\n startIndex={0}\n selectedIndex={selectedIndex}\n onSelect={onSelect}\n emptyHint={\n inputFieldsCount === 0 ? \"No input fields available.\" : \"No matching input fields.\"\n }\n overflow={overflow.field}\n overflowHelper=\"Type to filter.\"\n />\n {hasSecretsResolver && (\n <Section\n label=\"Secrets\"\n kind=\"secret\"\n items={secretItems}\n startIndex={fieldItems.length}\n selectedIndex={selectedIndex}\n onSelect={onSelect}\n emptyHint={secretsPending ? \"Searching…\" : \"No matching secrets.\"}\n helperHint=\"Type /s/ to filter to secrets only.\"\n pending={secretsPending}\n overflow={overflow.secret}\n overflowHelper=\"Type to filter, or /s/ for secrets only.\"\n />\n )}\n {hasConstantsResolver && (\n <Section\n label=\"Constants\"\n kind=\"constant\"\n items={constantItems}\n startIndex={fieldItems.length + secretItems.length}\n selectedIndex={selectedIndex}\n onSelect={onSelect}\n emptyHint={constantsPending ? \"Searching…\" : \"No matching constants.\"}\n helperHint=\"Type /c/ to filter to constants only.\"\n pending={constantsPending}\n overflow={overflow.constant}\n overflowHelper=\"Type to filter, or /c/ for constants only.\"\n />\n )}\n </div>\n );\n}\n\nfunction Section({\n label,\n kind,\n items,\n startIndex,\n selectedIndex,\n onSelect,\n emptyHint,\n helperHint,\n pending,\n overflow = 0,\n overflowHelper,\n}: {\n label: string;\n kind: ReferenceKind;\n items: SuggestionItem<ReferenceContext>[];\n startIndex: number;\n selectedIndex?: number;\n onSelect: (item: SuggestionItem<ReferenceContext>) => void;\n emptyHint: string;\n helperHint?: string;\n pending?: boolean;\n overflow?: number;\n overflowHelper?: string;\n}) {\n return (\n <div className=\"pz:flex pz:flex-col\">\n <SectionHeader>\n {label}\n {items.length > 0 && (\n <span className=\"pz:ml-1 pz:normal-case pz:tracking-normal\">\n ({items.length}\n {overflow > 0 && ` of ${items.length + overflow}`})\n </span>\n )}\n {pending && (\n <span className=\"pz:ml-1 pz:normal-case pz:tracking-normal pz:opacity-70\">\n · Searching…\n </span>\n )}\n </SectionHeader>\n {items.length === 0 ? (\n <div className=\"pz:px-2 pz:py-1 pz:text-xs pz:text-muted-foreground\">\n {emptyHint}\n {helperHint && <span className=\"pz:block pz:opacity-70\">{helperHint}</span>}\n </div>\n ) : (\n <>\n {items.map((item, i) => (\n <ItemRow\n key={`${kind}-${item.title}`}\n item={item}\n active={selectedIndex === startIndex + i}\n onSelect={onSelect}\n />\n ))}\n {overflow > 0 && overflowHelper && (\n <div className=\"pz:px-2 pz:py-0.5 pz:text-[11px] pz:text-muted-foreground pz:opacity-70\">\n +{overflow} more — {overflowHelper}\n </div>\n )}\n </>\n )}\n </div>\n );\n}\n\nfunction describeEmpty(prefix: ReferenceKind | null): string {\n if (prefix === \"secret\") return \"No matching secrets.\";\n if (prefix === \"constant\") return \"No matching constants.\";\n if (prefix === \"field\") return \"No matching fields.\";\n return \"No matches.\";\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pipe0/react",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
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
|
"react-hook-form": "^7.62.0",
|
|
85
85
|
"swr": "^2.4.1",
|
|
86
86
|
"tailwind-merge": "^3.3.1",
|
|
87
|
-
"@pipe0/base": "1.0.
|
|
87
|
+
"@pipe0/base": "1.0.2"
|
|
88
88
|
},
|
|
89
89
|
"devDependencies": {
|
|
90
90
|
"@base-ui/react": "^1.6.0",
|