0

Currently, I'm trying to use jsonforms to create different forms for my website, and I'm using custom buttons and input fields (using custom renderers) to render the form, currently I'm interested in making the UI right, this is how my schemas are defined:

import { Button } from '@/src/components/Button';
import { Input } from '@/src/components/Input';

export const schema = {
  type: 'object',
  properties: {
    name: {
      type: 'string',
      minLength: 3,
      description: 'Please enter your name',
    },
  },
};

export const uiSchema = {
  type: 'VerticalLayout',
  elements: [
    {
      type: 'HorizontalLayout',

      elements: [
        { type: 'Control', label: 'Primary button', scope: `#/properties/${Button.displayName!}` },
        {
          type: 'Control',
          label: 'Input text',
          options: { placeholder: 'Please input your text' },
          scope: `#/properties/${Input.displayName}`,
        },
        {
          type: 'VerticalLayout',
          elements: [
            {
              type: 'Control',
              label: 'Secondary Button',
              scope: `#/properties/${Button.displayName!}`,
            },
            {
              type: 'Control',
              label: 'Ternary Button',
              scope: `#/properties/${Button.displayName!}`,
            },
          ],
        },
      ],
    },
  ],
};

my renderers are components from shadcn, defined something like this:

import * as React from 'react';
import { Input as BaseInput } from '@/components/ui/input';
import { cn } from '@/lib/utils';

import styles from './Input.module.scss';
import { ControlProps } from '@jsonforms/core';
import { Label } from './Label';
import { withJsonFormsControlProps } from '@jsonforms/react';

export interface InputProps extends React.ComponentProps<'input'> {
  isError?: boolean;
  errorMsg?: string;
  label?: string;
}

export const Input = React.forwardRef<HTMLInputElement, InputProps>(
  ({ className, errorMsg, isError, label, id, required, ...props }, ref) => {
    return (
      <div className="flex flex-col">
        {label && (
          <Label htmlFor={id} className={'mb-2 font-bold'}>
            <>{label}</>
            {required && <>*</>}
          </Label>
        )}
        <BaseInput
          id={id}
          ref={ref}
          className={cn(
            'h-12 focus-visible:ring-0',
            styles.input,
            { [styles.error]: isError },
            className,
          )}
          placeholder={'Enter your text here'}
          {...props}
        />
        {errorMsg && isError && <div className={cn('mt-2', styles.errorTxt)}>{errorMsg}</div>}
      </div>
    );
  },
);

Input.displayName = 'Input';

const Renderer = (props: ControlProps) => {
  const {
    visible,
    uischema: { label, options },
    id,
    errors,
  } = props;

  if (!visible) return null;

  const inputId = `${id}-input`;

  return (
    <Input
      id={inputId}
      errorMsg={errors}
      type={options?.inputType}
      label={label as string}
      required={options?.required}
      placeholder={options?.placeholder}
    />
  );
};

export const FormInput = withJsonFormsControlProps(Renderer);
import { rankWith, scopeEndsWith } from '@jsonforms/core';
import { Button, FormButton } from '@/src/components/Button';
import { FormInput, Input } from '@/src/components/Input';
import { materialRenderers } from '@jsonforms/material-renderers';

const PRIORITY = 10;

const InputTester = rankWith(PRIORITY, scopeEndsWith(Input.displayName!));

const Renderers = [
  ...materialRenderers,
  { tester: InputTester, renderer: FormInput },
];

export default Renderers;

and, this is how my UI looks like: enter image description here

as you can see , I'm not being able to align the field Input text and Primary button (horizontal layout) and also between Secondary and Ternary buttons (Vertical Layout).

I can't find an option clearly mentioned in the docs for this, and some forums mention things about themes on material UI, however, I'm not using those.

What is the best way to achieve this?

1
  • Best way to achieve what exactly? You haven't explained what you what your expected outcome should be or what you have tried (minimal reproducible example) in trying to achieve it. Please edit to clearly and specifically define the problem you are trying to solve, what you have tried, and what doesn't or is not working as expected. Keep in mind that "best way to..." is generally subjective and off-topic. You will need to rephrase your post to be more objective. This will help readers better understand what you are asking. Commented yesterday

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.