Skip to content
KajayDocs
CreatorTypeScript SDKReactextension

Customize Creator UI

Use your design system, vocabulary, theme, and property editors without forking Kajay.

Use design-system components

Pass a partial Creator component map to replace buttons, inputs, selects, checkboxes, textareas, and menus. Missing entries keep the Kajay defaults.

Creator and survey component maps
import type { CreatorComponents } from '@kajay/creator-react';

const creatorComponents = {
  Button: DesignSystemButton,
  Input: DesignSystemInput,
  Select: DesignSystemSelect,
  Checkbox: DesignSystemCheckbox,
  Textarea: DesignSystemTextarea,
  Menu: DesignSystemMenu,
} satisfies CreatorComponents;

<SurveyCreator
  value={definition}
  onChange={setDefinition}
  components={creatorComponents}
  surveyComponents={surveyComponents}
/>

Creator chrome and the previewed survey use separate component maps. Pass components for Creator controls and surveyComponents for the survey renderer.

Customize words and theme

Register only the Creator strings you want to replace; all other messages retain their built-in values. Creator locale is separate from the survey locale, and creatorTheme styles the tool rather than the survey being designed.

White-label the Creator
import { CreatorStringDictionary } from '@kajay/creator-core';

const strings = new CreatorStringDictionary();
strings.register('en', {
  tabDesign: 'Build',
  tabPreview: 'Try it',
  addPage: 'Add a section',
  toolboxSearch: 'Find a field',
});

<SurveyCreator
  value={definition}
  onChange={setDefinition}
  strings={strings}
  locale="en"
  creatorTheme={{ '--kajay-color-accent': '#6d28d9' }}
/>

Replace a property editor

Use a resolver when a deployment knows more about a property than its registered primitive type. A resolver can match a property name, an editor kind, or both.

A domain-specific property editor
import {
  PropertyEditorProvider,
  useCreatorComponents,
} from '@kajay/creator-react';
import type {
  PropertyEditorProps,
  PropertyEditorResolver,
} from '@kajay/creator-react';

function TitleLocationEditor(props: PropertyEditorProps) {
  const { Select } = useCreatorComponents();
  const { surface, element, row, id, hint, testId } = props;

  return (
    <Select
      id={id}
      aria-describedby={hint}
      data-testid={testId}
      value={typeof row.value === 'string' ? row.value : 'default'}
      options={['default', 'top', 'left', 'hidden'].map((value) => ({
        value,
        label: value,
      }))}
      onValueChange={(value) => {
        surface.setProperty(element, row.name, value);
      }}
    />
  );
}

const resolveEditor: PropertyEditorResolver = (row) =>
  row.name === 'titleLocation' ? TitleLocationEditor : undefined;

<PropertyEditorProvider resolve={resolveEditor}>
  <SurveyCreator value={definition} onChange={setDefinition} />
</PropertyEditorProvider>

Put the supplied id on the control and wire aria-describedby to the supplied hint. Write through the provided design surface so restrictions, undo, serialization, and notices remain intact.