@narrative.io/jsonforms-provider-protocols
Version:
Dynamic data provider capabilities for JSONForms with Vue 3 integration
89 lines (77 loc) • 2.96 kB
text/typescript
import type { UISchemaElement } from "@jsonforms/core";
import {
and,
isNumberControl,
isStringControl,
or,
rankWith,
isControl,
} from "@jsonforms/core";
import ProviderAutocomplete from "./components/ProviderAutocomplete.vue";
import ProviderSelect from "./components/ProviderSelect.vue";
import ProviderMultiSelect from "./components/ProviderMultiSelect.vue";
// Custom tester that checks if provider option exists (as object or boolean)
const hasProvider = (uischema: UISchemaElement) => {
return uischema?.options?.provider !== undefined;
};
// Create specific testers for each component type
const providerSelectTester = rankWith(
106, // Higher than PrimeVue base (100) to ensure providers take precedence
and(
or(isStringControl, isNumberControl, and(isControl, (uischema: unknown, schema: unknown) => {
const s = schema as { type?: string };
return s && s.type === "integer";
})),
hasProvider,
(uischema) => !uischema?.options?.autocomplete,
),
);
const providerAutocompleteTester = rankWith(
107, // Higher than PrimeVue base (100) to ensure providers take precedence
and(
or(isStringControl, isNumberControl, and(isControl, (uischema: unknown, schema: unknown) => {
const s = schema as { type?: string };
return s && s.type === "integer";
})),
hasProvider,
(uischema) => uischema?.options?.autocomplete === true,
),
);
// Custom array tester - check both uischema control type and schema type
const isArrayControl = (uischema: UISchemaElement, schema: unknown) => {
const controlSchema = uischema as { type: string; scope?: string };
if (controlSchema.type !== "Control" || !controlSchema.scope) {
return false;
}
// Extract the property schema from the root schema
const rootSchema = schema as { properties?: Record<string, unknown> };
const propertyPath = controlSchema.scope.replace("#/properties/", "");
const propertySchema = rootSchema?.properties?.[propertyPath] as {
type?: string;
};
return propertySchema?.type === "array";
};
const providerMultiSelectTester = rankWith(
108, // Highest priority for array controls with providers
and(isArrayControl, hasProvider),
);
export const providerRenderers = [
{ tester: providerMultiSelectTester, renderer: ProviderMultiSelect },
{ tester: providerAutocompleteTester, renderer: ProviderAutocomplete },
{ tester: providerSelectTester, renderer: ProviderSelect },
];
// Export PrimeVue renderers (styles are auto-injected)
export { primevueRenderers, registerPrimevueRenderers } from "./primevue";
// Export individual components
export { ProviderAutocomplete, ProviderSelect, ProviderMultiSelect };
export { useProvider } from "./composables/useProvider";
export * from "./testers";
// Export individual PrimeVue components using lazy evaluation to avoid circular deps
export {
JfText,
JfTextArea,
JfNumber,
JfEnum,
JfEnumArray,
JfBoolean,
} from "./primevue";