Relevant source files
The following files were used as context for generating this wiki page:
- packages/api-docs/src/schema/sample.ts
- packages/api-docs/src/components/schema/client.tsx
- packages/openapi/src/ui/base.tsx
- packages/openapi/src/ui/operation/index.tsx
- packages/api-docs/src/components/schema/index.tsx
- packages/asyncapi/src/ui/index.tsx
- packages/api-docs/package.json
- packages/openapi/src/server/index.tsx
- packages/cli/src/commands/shared.ts
- packages/api-docs/src/schema/index.ts
- packages/openapi/src/utils/document/dereference.ts
- packages/openapi/src/utils/schema.ts
- packages/asyncapi/src/ui/bindings/shared.tsx
- packages/openapi/src/utils/get-example-requests.ts
- packages/asyncapi/src/server/index.tsx
- packages/openapi/src/ui/index.tsx
- packages/openapi/src/ui/operation/response-tabs.tsx
- packages/api-docs/src/schema/to-string.ts
- packages/asyncapi/src/utils/document/dereference.ts
- packages/openapi/src/types.ts
- packages/python/src/components/index.tsx
- packages/openapi/src/scalar/client.tsx
- packages/asyncapi/src/utils/schema.ts
- packages/openapi/css/preset.css
- packages/openapi/src/index.ts
- packages/base-ui/registry/index.ts
- packages/openapi/package.json
- packages/api-docs/src/codegen.ts
- packages/api-docs/src/schema/bundle.ts
- packages/api-docs/src/auto-anchor/index.ts
Overview
API Docs Primitives (@fumadocs/api-docs) provides the underlying schema parsing, type formatting, mocking, rendering, and navigation infrastructure shared across Fumadocs API documentation packages like OpenAPI Interactive UI and AsyncAPI Document Processing. By establishing a unified runtime foundation, it solves the fragmentation of handling complex JSON Schema specifications across different protocol adapters and frontend layouts. Key design decisions include synchronous reference resolution, recursive AST generation for hierarchical properties, and decoupled client-server component splitting that maintains interactive deep-linking and state preservation. It interfaces directly with specification document parsers and UI layout renderers to power interactive schema property exploration, code sample integration, and deep-linkable slug generation.
Sources: packages/api-docs/package.json:1-45, packages/api-docs/src/components/schema/client.tsx:73-114, packages/api-docs/src/components/schema/index.tsx:89-112
Package architecture and shared contracts
Package exports and module layout
The @fumadocs/api-docs package exposes a modular export structure defined in package.json, mapping internal build outputs to explicit subpath imports for schema processing, interactive components, code generation, and utilities.
"exports": {
"./auto-anchor": "./dist/auto-anchor/index.js",
"./auto-anchor/client": "./dist/auto-anchor/client.js",
"./codegen": "./dist/codegen.js",
"./components/accordion": "./dist/components/accordion.js",
"./components/dialog": "./dist/components/dialog.js",
"./components/input": "./dist/components/input.js",
"./components/playground/inputs": "./dist/components/playground/inputs.js",
"./components/playground/schema": "./dist/components/playground/schema.js",
"./components/schema": "./dist/components/schema/index.js",
"./components/schema/client": "./dist/components/schema/client.js",
"./components/select": "./dist/components/select.js",
"./components/select-tab": "./dist/components/select-tab.js",
"./components/spinner": "./dist/components/spinner.js",
"./i18n": "./dist/i18n.js",
"./schema": "./dist/schema/index.js",
"./schema/bundle": "./dist/schema/bundle.js",
"./schema/dereference": "./dist/schema/dereference.js",
"./schema/merge": "./dist/schema/merge.js",
"./schema/ref": "./dist/schema/ref.js",
"./schema/resolve-ref": "./dist/schema/resolve-ref.js",
"./schema/sample": "./dist/schema/sample.js",
"./schema/to-string": "./dist/schema/to-string.js",
"./utils/id-to-title": "./dist/utils/id-to-title.js",
"./utils/url": "./dist/utils/url.js",
"./package.json": "./package.json",
"./css/*": "./css/*"
},Sources: packages/api-docs/package.json:18-45
Core type definitions and runtime contracts
The core schema architecture relies on utility types and type guards that handle JSON Schema definitions (following draft 2020-12) and reference stripping. NoReference<T> recursively eliminates $ref reference objects from arbitrary types, while ParsedSchema unions standard JSON Schema definitions with extension properties such as x-playground-lazy and discriminator mappings.
import type { JSONSchema } from 'json-schema-typed/draft-2020-12';
type ReferenceObject = { $ref: string };
export type NoReference<T> = T extends (infer I)[]
? NoReference<I>[]
: T extends ReferenceObject
? Exclude<T, ReferenceObject>
: T extends object
? {
[K in keyof T]: NoReference<T[K]>;
}
: T;
export type NoReferenceSwallow<T> = T extends ReferenceObject ? Exclude<T, ReferenceObject> : T;
export type ParsedSchema =
| (JSONSchema & {
'x-playground-lazy'?: boolean;
discriminator?: {
propertyName?: string;
mapping?: Record<string, string>;
};
})
| boolean;Sources: packages/api-docs/src/schema/index.ts:1-25
The SchemaResolver contract defines the shape for functions that take a ParsedSchema and return a shallowly dereferenced schema alongside an optional $ref string.
export type SchemaResolver = (schema: ParsedSchema) => {
/** shallowly dereferenced schema */
dereferenced: ParsedSchema;
/** the ref value (if dereferenced) */
$ref?: string;
};Sources: packages/api-docs/src/schema/index.ts:27-32
Note
SchemaResolver performs a shallow dereference step rather than a deep recursive unrolling, preserving reference boundaries until explicit traversal or sampling occurs.
Bundling primitives and code generation registries
Schema bundling relies on re-exporting the bundle function directly from @apidevtools/json-schema-ref-parser to combine external JSON reference files into a unified document structure.
export { bundle } from '@apidevtools/json-schema-ref-parser';Sources: packages/api-docs/src/schema/bundle.ts:1-1
To support Code Sample Generators, the package provides CodeUsageGeneratorRegistry and createCodeUsageGeneratorRegistry, managing language-specific code generators through registration, retrieval, inline definition, and removal operations.
export interface CodeUsageGeneratorRegistry<Data = unknown, Context = unknown> {
add: (id: string, generator: CodeUsageGenerator<Data, Context>) => void;
get: (id: string) => CodeUsageGenerator<Data, Context> | undefined;
addInline: (generator: InlineCodeUsageGenerator<Data, Context>) => void;
/**
* @returns if the generator is removed
*/
remove: (id: string) => boolean;
map: () => Map<string, CodeUsageGenerator<Data, Context>>;
}
/**
* Generate code example for given programming language
*/
export interface CodeUsageGenerator<Data = unknown, Context = unknown> {
generate: (data: Data, context: Context) => string;
lang: string;
label?: string;
}
/**
* Generate code example for given programming language
*/
export interface InlineCodeUsageGenerator<Data = unknown, Context = unknown> {
id?: string;
lang: string;
label?: string;
/**
* either:
* - code
* - a function imported from a file with "use client" directive
* - false (disabled)
*/
source?: string | CodeUsageGeneratorFn<Data, Context> | false;
}
export function createCodeUsageGeneratorRegistry<Data, Context>(
inherit?: CodeUsageGeneratorRegistry<Data, Context>,
): CodeUsageGeneratorRegistry<Data, Context> {Sources: packages/api-docs/src/codegen.ts:1-39
Important
When adding inline code usage generators via addInline, if the source property evaluates to falsy or false, the registry automatically deletes the generator entry matching the language or identifier.
Synchronous schema dereferencing
Dereferencing mechanics in OpenAPI documents
OpenAPI document processing relies on synchronous schema dereferencing via dereferenceBundledDocument, which converts a bundled specification document into a fully resolved structure devoid of local or external reference pointers. This function initializes a Map<object, string> instance to track original reference strings ($ref) mapped to their corresponding schema objects.
export function dereferenceBundledDocument(bundled: Document): DereferencedDocument {
const dereferenceMap = new Map<object, string>();
return {
bundled,
dereferenced: dereferenceSync(bundled as JSONSchema, {
setOriginalRef(schema, ref) {
dereferenceMap.set(schema as object, ref);
},
}) as NoReference<Document>,
getRawRef(obj: object) {
return dereferenceMap.get(obj);
},
};
}Sources: packages/openapi/src/utils/document/dereference.ts:20-34
The underlying dereference implementation uses dereferenceSync from @apidevtools/json-schema-ref-parser (re-exported via @fumadocs/api-docs/schema/dereference) cast to JSONSchema from json-schema-typed/draft-2020-12. During this traversal, the setOriginalRef callback intercepts each resolved schema node and populates the tracking map with dereferenceMap.set(schema as object, ref), enabling downstream lookups of raw reference identifiers via getRawRef(obj).
export interface DereferencedDocument {
/**
* dereferenced document
*/
dereferenced: NoReference<Document>;
/**
* Get raw $ref from dereferenced object
*/
getRawRef: (obj: object) => string | undefined;
bundled: Document;
}Sources: packages/openapi/src/utils/document/dereference.ts:6-18
Note
DereferencedDocument exposes three properties: bundled for the original specification, dereferenced typed as NoReference<Document> for the fully unrolled AST, and getRawRef to retrieve original reference strings from any dereferenced object instance.
AsyncAPI document dereferencing contracts
AsyncAPI document processing adopts an identical architectural pattern for synchronous reference resolution through packages/asyncapi/src/utils/document/dereference.ts. It wraps dereferenceSync to process AsyncAPIObject definitions, maintaining a dedicated dereferenceMap to track source references across asynchronous message schemas and protocol components.
export function dereferenceBundledDocument(bundled: AsyncAPIObject): DereferencedDocument {
const dereferenceMap = new Map<object, string>();
return {
bundled,
dereferenced: dereferenceSync(bundled as JSONSchema, {
setOriginalRef(schema, ref) {
dereferenceMap.set(schema as object, ref);
},
}) as NoReference<AsyncAPIObject>,
getRawRef(obj: object) {
return dereferenceMap.get(obj);
},
};
}Sources: packages/asyncapi/src/utils/document/dereference.ts:20-34
The resulting DereferencedDocument interface for AsyncAPI returns NoReference<AsyncAPIObject> alongside the raw reference lookup utility and the original bundled specification object.
export interface DereferencedDocument {
/**
* dereferenced document
*/
dereferenced: NoReference<AsyncAPIObject>;
/**
* Get raw $ref from dereferenced object
*/
getRawRef: (obj: object) => string | undefined;
bundled: AsyncAPIObject;
}Sources: packages/asyncapi/src/utils/document/dereference.ts:6-18
Warning
Both OpenAPI and AsyncAPI dereference pipelines cast their respective document types to JSONSchema during dereferenceSync invocation, requiring structural compatibility with JSON Schema Draft 2020-12 definitions.
Reference bundling primitives
Underpinning both protocol dereferencing utilities, reference bundling relies on the core bundle export from @apidevtools/json-schema-ref-parser to aggregate distributed references into a cohesive self-contained specification file prior to synchronous traversal.
export { bundle } from '@apidevtools/json-schema-ref-parser';Sources: packages/api-docs/src/schema/bundle.ts:1-1
Important
Bundling must precede synchronous dereferencing whenever specification files reference external file paths or network URIs, as dereferenceSync operates entirely in-memory on the consolidated document structure.
Mock data sampling and traversal
Sample options and type inference
Mock data generation converts JSON schema definitions into concrete payloads through sample and internal traversal routines. The configuration accepts specific flags defined in JsonSchemaSampleOptions, governing object traversal depths, schema property omissions, and pattern generation.
| Option | Type | Default | Purpose |
|---|---|---|---|
skipNonRequired | boolean | — | Omits schema properties not marked as required |
skipReadOnly | boolean | false | Omits properties designated as read-only |
skipWriteOnly | boolean | — | Omits properties designated as write-only |
quiet | boolean | — | Suppresses warnings during sampling |
enablePatterns | boolean | — | Enables generation from regular expressions |
maxSampleDepth | number | 15 | Limits recursion depth during traversal |
Sources: packages/api-docs/src/schema/sample.ts:21-37
When schemas omit explicit type declarations, inferType inspects validation keywords to deduce the expected data type. It maps attributes like multipleOf, maximum, minimum, maxLength, pattern, items, properties, and required to primitive types such as 'number', 'string', 'array', or 'object'.
function inferType(schema: SchemaDoc): string | null {
if (schema.type !== undefined) {
const t = schema.type;
return Array.isArray(t) ? (t.length === 0 ? null : String(t[0])) : String(t);
}
const keywordTypes: Record<string, string> = {
multipleOf: 'number',
maximum: 'number',
exclusiveMaximum: 'number',
minimum: 'number',
exclusiveMinimum: 'number',
maxLength: 'string',
minLength: 'string',
pattern: 'string',
items: 'array',
maxItems: 'array',
minItems: 'array',
uniqueItems: 'array',
additionalItems: 'array',
maxProperties: 'object',
minProperties: 'object',
required: 'object',
additionalProperties: 'object',
properties: 'object',
patternProperties: 'object',
dependencies: 'object',
};
for (const [kw, ty] of Object.entries(keywordTypes)) {
if (schema[kw] !== undefined) return ty;
}
return null;
}Sources: packages/api-docs/src/schema/sample.ts:51-84
Note
If a schema defines an array of types, inferType evaluates the first array element after checking for empty type arrays, returning null if no type determination is possible.
Request example generation workflow
Request example generation uses getExampleRequests to construct client payloads from operation definitions, parameter lists, and request bodies. It extracts media types using getPreferredType and populates path, query, header, and cookie parameters by resolving examples or invoking sample on parameter schemas.
export function getExampleRequests({
path,
method,
ctx,
operation,
pathItem,
}: {
path: string;
pathItem: NoReference<PathItemObject>;
method: HttpMethods;
operation: NoReference<OperationObject>;
ctx: RenderContext;
}): ExampleRequestItem[] {
const requestBody = operation.requestBody;
const media = requestBody?.content ? getPreferredType(requestBody.content) : null;
const bodyOfType = media ? requestBody!.content![media] : null;
const parameters = [...(operation.parameters ?? []), ...(pathItem.parameters ?? [])];
if (bodyOfType?.examples) {
const result: ExampleRequestItem[] = [];
for (const [key, value] of Object.entries(bodyOfType.examples)) {
const data = getRequestData({
path,
body: operation.requestBody,
parameters,
sampleKey: key,
method,
});
result.push({
id: key,
name: value.summary || key,
description: value.description,
data,
encoded: encodeRequestData(data, ctx.mediaAdapters, parameters),
});
}
if (result.length > 0) return result;
}
const data = getRequestData({ path, body: operation.requestBody, method, parameters });
return [
{
id: '_default',
name: 'Default',
description:
typeof bodyOfType?.schema === 'object' ? bodyOfType.schema.description : undefined,
data,
encoded: encodeRequestData(data, ctx.mediaAdapters, parameters),
},
];
}Sources: packages/openapi/src/utils/get-example-requests.ts:23-76
When processing request bodies, getRequestData checks for explicit examples or individual example values before falling back to programmatic sampling via sample. HTTP methods dictate the read-only and write-only sampling flags passed to the sampler.
function getRequestData({
method,
path,
parameters,
sampleKey,
body,
}: {
path: string;
sampleKey?: string;
method: HttpMethods;
parameters: NoReference<ParameterObject>[];
body?: NoReference<RequestBodyObject>;
}): RawRequestData {
const result: RawRequestData = {
path: {},
cookie: {},
header: {},
query: {},
method: method,
};
for (const param of parameters) {
let value = pickExample(param as never);
if (value === undefined && param.required) {
if (param.schema) {
value = sample(param.schema as object);
} else if (param.content) {
const type = getPreferredType(param.content);
const content = type ? param.content[type] : undefined;
if (!content || !content.schema)
throw new Error(
`Cannot find "${param.name}" parameter info for media type "${type}" in ${path} ${method}`,
);
value = sample(content.schema as object);
}
}
switch (param.in) {
case 'cookie':
result.cookie[param.name!] = value;
break;
case 'header':
result.header[param.name!] = value;
break;
case 'query':
result.query[param.name!] = value;
break;
default:
result.path[param.name!] = value;
}
}
if (body?.content) {
const type = getPreferredType(body.content);
if (!type) throw new Error(`Cannot find body schema for ${path} ${method}: missing media type`);
result.bodyMediaType = type as RawRequestData['bodyMediaType'];
const bodyOfType = body.content[type];
if (bodyOfType.examples && sampleKey) {
result.body = bodyOfType.examples[sampleKey].value;
} else if (bodyOfType.example) {
result.body = bodyOfType.example;
} else {
result.body = sample((bodyOfType?.schema ?? {}) as object, {
skipReadOnly: method !== 'get',
skipWriteOnly: method === 'get',
skipNonRequired: true,
});
}
}
return result;
}Sources: packages/openapi/src/utils/get-example-requests.ts:78-152
Warning
For HTTP GET requests, getRequestData explicitly configures skipReadOnly: false and skipWriteOnly: true, while mutating these flags inversely for methods that transmit write payloads.
Schema string conversion and formatting
Format flags and string conversion logic
The schemaToString utility transforms parsed schema objects into readable string representations. It accepts an optional SchemaResolver function and formatting flags defined in FormatFlags.
export enum FormatFlags {
None = 0,
UseAlias = 1 << 0,
}
export function schemaToString(
value: ParsedSchema,
resolver?: SchemaResolver,
flags: FormatFlags = FormatFlags.None,
): string {Sources: packages/api-docs/src/schema/to-string.ts:3-12
| Constant | Value | Purpose |
|---|---|---|
FormatFlags.None | 0 | Default formatting without special alias resolution |
FormatFlags.UseAlias | 1 | Resolves schema titles or reference identifiers |
Sources: packages/api-docs/src/schema/to-string.ts:3-6
Note
When FormatFlags.UseAlias is active, schemaToString checks for a schema.title property or parses the trailing segment of a raw $ref string before falling back to type-level serialization.
Type resolution and composition rules
The internal run function handles boolean schemas, returning 'any' for true and 'never' for false. Array types are formatted recursively into array<T> structures where inner item types are evaluated with alias resolution enabled.
if (schema.type === 'array')
return `array<${schema.items ? run(schema.items, flags | FormatFlags.UseAlias) : 'unknown'}>`;
Sources: packages/api-docs/src/schema/to-string.ts:59-61
Composed schemas like oneOf, anyOf, and allOf utilize a helper union function to aggregate distinct member types. When both oneOf and anyOf are present on a schema, they combine with an intersection operator.
if (schema.oneOf && schema.anyOf) {
return `(${union(schema.oneOf, ' | ', flags)}) & (${union(schema.anyOf, ' | ', flags)})`;
}Sources: packages/api-docs/src/schema/to-string.ts:62-64
Warning
Binary string formats (schema.type === 'string' and schema.format === 'binary') are explicitly converted to the 'file' type keyword rather than retaining their underlying schema representation.
Interactive schema renderer components
Server and client component tree generation
The interactive schema renderer architecture is split between server-side generation utilities and client-side tree navigation components. The server entry point invokes generateSchemaUI to build a normalized schema record (SchemaUIGeneratedData) containing a root reference pointer $root and a dictionary of dereferenced types refs. During this phase, property visibility flags like readOnly and writeOnly dictate which fields are included in object property lists, while scanRefs recursively traverses object properties, array items, and union types.
export interface SchemaUIGeneratedData {
$root: string;
refs: Record<string, SchemaData>;
}
export function Schema({
client,
root,
readOnly,
writeOnly,
resolver,
showExample,
renderMarkdown,
}: SchemaUIOptions) {
const translations = useTranslations().translations;
const generated = useMemo(() => {
return generateSchemaUI({
root,
resolver,
readOnly,
writeOnly,
showExample,
renderMarkdown,
translations,
});
}, [root, readOnly, writeOnly, resolver, showExample, renderMarkdown, translations]);
return <SchemaUI {...client} generated={generated} />;
}
export function generateSchemaUI({
root,
resolver,
renderMarkdown,
readOnly = false,
writeOnly = false,
showExample = false,
translations = {},
}: Omit<SchemaUIOptions, 'client'> & {
translations?: Partial<Record<string, string>>;
}): SchemaUIGeneratedData {Sources: packages/api-docs/src/components/schema/index.tsx:84-124
The generated schema record is passed into the SchemaUI client component, which manages the active navigation path (PathItemType[]) and anchor state. When rendered via AsyncAPI or OpenAPI bindings, the execution flows through specific integration wrappers that resolve schema identifiers and translation contexts.
Sources: packages/api-docs/src/components/schema/client.tsx:73-114, packages/asyncapi/src/ui/index.tsx:197-203, packages/openapi/src/ui/base.tsx:118-125
createAsyncAPIPageorcreateOpenAPIPageBaseinitializes the rendering context and delegates to theSchemacomponent.SchemaexecutesgenerateSchemaUIto produce the normalized reference dictionary and root identifier.SchemaUImounts the client state provider, initializing the path stack with the root schema reference and root anchor ID.
Sources: packages/api-docs/src/components/schema/client.tsx:83-114, packages/api-docs/src/components/schema/index.tsx:89-112, packages/asyncapi/src/ui/index.tsx:197-203, packages/openapi/src/ui/base.tsx:118-125
Note
SchemaUI registers an useEffect hook that inspects window.location.search for a path parameter and s-highlight slug, automatically decoding the traversal stack and scrolling the target property container into view upon initial hydration.
Schema property visibility and filtering
Object schema property generation incorporates strict filtering rules based on visibility flags and property types. When iterating over schema properties, pattern properties, and additional properties, generateSchemaUI evaluates each candidate property against visibility criteria.
if (schema.type === 'object') {
const out: SchemaData = {
type: 'object',
props: [],
...base(schema),
};
refs[id] = out;
const { properties = {}, patternProperties, additionalProperties } = schema;
const props = Object.entries(properties);
if (patternProperties) props.push(...Object.entries(patternProperties));
for (const [key, prop] of props) {
if (!prop || !isVisible(prop)) continue;
const $type = getSchemaId(prop);
scanRefs($type, prop);
out.props.push({
$type,
name: key,
required: schema.required?.includes(key) ?? false,
});
}
if (additionalProperties && isVisible(additionalProperties)) {
const $type = getSchemaId(additionalProperties);
scanRefs($type, additionalProperties);
out.props.push({
$type,
name: '[key: string]',
required: false,
});
}
return;Sources: packages/api-docs/src/components/schema/index.tsx:351-384
| Property Type / Field | Inclusion Condition | Default Behavior |
|---|---|---|
Standard Properties (properties) | prop is defined and isVisible(prop) returns true | Evaluated and pushed to object properties |
Pattern Properties (patternProperties) | Appended to property entries when present | Evaluated alongside standard properties |
Additional Properties (additionalProperties) | additionalProperties is truthy and visible | Appended as [key: string] with required: false |
Sources: packages/api-docs/src/components/schema/index.tsx:359-383
Warning
If a property schema evaluates to invisible under current readOnly or writeOnly configurations, it is skipped entirely during reference scanning, preventing hidden data fields from populating client popovers and generated type trees.
Navigation anchoring and UI controls
Anchor slug generation and prefixing
Fumadocs api-docs uses github-slugger to produce deep-link anchor slugs for schema components and properties. The anchorSegments utility function accepts an arbitrary list of string segments, applying slug() mapping to each non-empty segment unless prefixed with a null character (\0), which forces the segment to be preserved verbatim.
import { slug } from 'github-slugger';
/** slugify segments, append `\0` to keep segment as-is */
export function anchorSegments(...segs: string[]): string {
const mapped: string[] = [];
for (const seg of segs) {
if (seg.startsWith('\0')) {
mapped.push(seg.slice(1));
} else if (seg.length > 0) {
mapped.push(slug(seg));
}
}
return mapped.join('.');
}Sources: packages/api-docs/src/auto-anchor/index.ts:1-14
| Function / Helper | Signature | Description |
|---|---|---|
anchorSegments | (...segs: string[]) => string | Slugifies segments, joining them with dots (.), while verbatim segments are unmasked via \0 prefix slicing. |
anchorIdStartsWith | (id1: string, id2: string) => boolean | Evaluates hierarchical prefix matches between anchor IDs, returning true if id1 equals id2 or starts with id2.. |
Sources: packages/api-docs/src/auto-anchor/index.ts:4-21
Note
When SchemaUI mounts, it registers its root identifier using useAnchorId([name]). It tracks ExcludedFromAutoAnchor caches to ensure initial URL deep-link parameters (path and s-highlight) trigger smooth scrolling into view only on the first hydration pass.
Interactive popover state and scroll management
The interactive schema renderer uses a React context provider (StateContextType) to manage the current traversal path (path array of PathItemType objects), root anchor ID, and popover triggers. When users click nested object types, renderTypeInfoTrigger controls a Radix UI Popover whose open state depends on whether the path length exceeds 1, matching the target reference and name while the root container is not closed.
interface PathItemType {
name: string;
$ref: string;
scrollTop?: number;
/** property name of highlighted field, only applicable for objects */
highlighted?: string;
tabValues?: string[];
/** popover state, only applicable for root */
closed?: boolean;
}
interface StateContextType {
rootId: string;
/** the first tiem will always be the root item */
path: PathItemType[];
setPath: (path: PathItemType[]) => void;
generated: SchemaUIGeneratedData;
renderTypeInfoTrigger: (props: {
pathName: string;
$ref: string;
children: ReactNode;
}) => ReactNode;
}Sources: packages/api-docs/src/components/schema/client.tsx:34-56
Warning
Popover elements attach a popoverRef callback that preserves container scroll positions (scrollTop) across nested view switches, enforcing a dynamic minimum height of 200px (or higher based on client height calculations) and autofocusing inputs marked with data-object-search-input.
Protocol bindings and helper controls
AsyncAPI protocol binding UI modules share a common set of layout primitives, formatting utilities, and summary builders to render message headers, channel targets, and operation properties consistently.
export function formatBindingScalar(value: unknown): string {
if (value === null || value === undefined) return '';
if (typeof value === 'boolean') return value ? 'Yes' : 'No';
if (typeof value === 'number') return String(value);
if (typeof value === 'string') return value;
if (Array.isArray(value)) {
return value.map((item) => formatBindingScalar(item)).join(', ');
}
return JSON.stringify(value);
}
export function hasBindingFields(
binding: Record<string, unknown>,
ignore: string[] = ['bindingVersion'],
): boolean {
return Object.keys(binding).some(
(key) => !ignore.includes(key) && !key.startsWith('x-') && binding[key] !== undefined,
);
}
export function joinBindingSummary(
...parts: (string | undefined | null | false)[]
): string | undefined {
const filtered = parts.filter((part): part is string => Boolean(part));
return filtered.length > 0 ? filtered.join(' · ') : undefined;
}Sources: packages/asyncapi/src/ui/bindings/shared.tsx:24-50
| Utility Function | Parameter Type | Return Type | Behavior |
|---|---|---|---|
formatBindingScalar | unknown | string | Converts booleans to 'Yes' / 'No', serializes arrays recursively, or falls back to JSON.stringify. |
hasBindingFields | Record<string, unknown>, string[] | boolean | Verifies object keys exist while ignoring fields like 'bindingVersion' and x-* extensions. |
joinBindingSummary | (string | undefined | null | false)[] | string | undefined | Filters falsy items and joins summary segments using ' · ' separators. |
Sources: packages/asyncapi/src/ui/bindings/shared.tsx:24-50
Tip
Components such as BindingGroup, BindingFieldRow, and BindingScalarValue automatically adapt boolean state badges (rendering emerald styles for true values and muted styles for false) and wrap scalar codes inside responsive definition lists (<dl>).
Related
On This Page
OverviewPackage architecture and shared contractsPackage exports and module layoutCore type definitions and runtime contractsBundling primitives and code generation registriesSynchronous schema dereferencingDereferencing mechanics in OpenAPI documentsAsyncAPI document dereferencing contractsReference bundling primitivesMock data sampling and traversalSample options and type inferenceRequest example generation workflowSchema string conversion and formattingFormat flags and string conversion logicType resolution and composition rulesInteractive schema renderer componentsServer and client component tree generationSchema property visibility and filteringNavigation anchoring and UI controlsAnchor slug generation and prefixingInteractive popover state and scroll managementProtocol bindings and helper controlsRelated