react-jsonschema-form icon indicating copy to clipboard operation
react-jsonschema-form copied to clipboard

Tailwind support

Open c0ncentus opened this issue 2 years ago • 13 comments

Prerequisites

What theme are you using?

other

Is your feature request related to a problem? Please describe.

Tailwind is yeat an another css libraries but have such flexibility, popularity for dark mode or other things more simple to do with tailwind. It will be nice to have this library for having such flexibility to design inputs.

Describe the solution you'd like

tailwind implemented and dark mode with "dark:bg-blue-600" for exemple.

Describe alternatives you've considered

Get components on https://tailwindcomponents.com/ and FlowBite for integrate them directly (will be dirctly the className string).

c0ncentus avatar Oct 17 '22 13:10 c0ncentus

@c0ncentus We are open to contributions of new themes assuming those themes support the current features provided in other themes

heath-freenome avatar Oct 17 '22 17:10 heath-freenome

Would love this! Also related one would be shadcn or other component libs that are built on top of tailwind.

tonyxiao avatar May 01 '23 13:05 tonyxiao

For those looking, I ended up adding the following snippet into my global.css and it worked like a charm. Not a full integration, just hacking the css classes that came with bootstrap3.


@layer components {
  .schema-form {
    /* Left side is not needed due to fieldset left margin */
    @apply mr-2;
  }
  /* Aka sections */
  .schema-form fieldset > legend {
    /* Display block doesn't work for some reason. Does not fill parent width which is still a div, not sure why */
    @apply mb-3 pb-1 w-full border-b pt-4 text-xl font-semibold;
  }
  .schema-form fieldset > div {
    /* Offset to indicate hierarchy */
    @apply ml-3;
  }
  /* Label + component = group */
  .schema-form .form-group {
    @apply mb-2;
  }
  .schema-form label.control-label {
    @apply block mb-1 font-bold;
  }
  .schema-form p.field-description {
    @apply mb-1;
  }
  /* Select component, and maybe other .form-control too */
  .schema-form .form-control {
    @apply block w-full rounded-md border border-input p-2;
  }
  /* Input component */
  .schema-form input {
    @apply flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50;
  }

  /* Array elements */
  .schema-form .array-item {
    /* @apply grid grid-cols-12; */
    @apply flex flex-row items-end gap-4;
  }
  .schema-form .array-item .col-xs-9 {
    /* @apply col-span-9; */
    @apply grow;
  }
  .schema-form .array-item .col-xs-3 {
    /* @apply col-span-3; */
    @apply shrink-0;
  }
  .schema-form .array-item .array-item-toolbox {
    /* mb-4 to match .form-group */
    @apply mb-4 flex items-center justify-end;
  }
  /* Icons */
  .schema-form .glyphicon {
    @apply font-normal not-italic;
  }
  .schema-form .glyphicon-remove::before {
    content: 'Remove';
  }
  .schema-form .glyphicon-arrow-up::before {
    content: 'Up';
  }
  .schema-form .glyphicon-arrow-down::before {
    content: 'Down';
  }
  .schema-form .glyphicon-plus::before {
    content: 'Add';
  }
  /* Buttons (tends to be icon buttons */
  .schema-form .btn {
    @apply rounded-md p-2 border mx-1;
  }
  .schema-form .btn-danger {
    @apply border-red-200;
  }
  .schema-form .btn-add {
    @apply border-blue-200;
  }
  .schema-form button[type='submit'] {
    @apply bg-primary text-primary-foreground hover:bg-primary/90;
  }
}

tonyxiao avatar May 01 '23 15:05 tonyxiao

For proper tailwind support all that would be needed is an easy way to override className for every widget (without the need for reimplementing the whole widget)

phaux avatar Nov 14 '23 12:11 phaux

For proper tailwind support all that would be needed is an easy way to override className for every widget (without the need for reimplementing the whole widget)

So basically we'd need a utility function similar to cn from shadcn/ui? See usage here e.g.

Interested in a PR?

NixBiks avatar May 27 '24 11:05 NixBiks

So basically we'd need a utility function similar to cn

That shouldn't be necessary.

My idea was to just:

- className='form-control'
+ className={'form-control ' + customClassName}

For example in https://github.com/rjsf-team/react-jsonschema-form/blob/ec932db942dd046640303056c89e3501b16ec469/packages/core/src/components/templates/BaseInputTemplate.tsx#L79

and allow specifying that custom className somewhere for every component. Similar to how there's a component registry that you can override by specifying your own component implementations, there should be something like a className registry.

phaux avatar May 28 '24 12:05 phaux

Hi, integrating rizzui library is the great option to support tailwindcss

burakakca avatar May 31 '24 15:05 burakakca

Hi, integrating rizzui library is the best option to support tailwindcss

Using tailwindcss to support rizzui doesn't mean it supports tailwindcss

NixBiks avatar May 31 '24 15:05 NixBiks

what about shadcn?

tonyxiao avatar May 31 '24 16:05 tonyxiao

@tonyxiao thanks, shadcn also great

burakakca avatar Jun 01 '24 10:06 burakakca

My solution to pull in all your default components & customize them for shadcn/ui (+ maybe others):

'use client'

import {Checkbox} from '@/components/ui/checkbox'
import {Input} from '@/components/ui/input'
import Form from '@rjsf/core'
import {RegistryWidgetsType, WidgetProps} from '@rjsf/utils'
import validator from '@rjsf/validator-ajv8'

const widgets: RegistryWidgetsType = {
    CheckboxWidget: function (props: WidgetProps) {
        return <Checkbox checked={props.value} onChange={props.onChange} />
    },
    TextWidget: function (props: WidgetProps) {
        return <Input onChange={e => props.onChange(e.target.value)} value={props.value} className='text-red-500'/>
    },

    // add the rest of your desired components here
}

export const MyComponent = () => {
    return (
        <Form
            schema={{type: 'object'}}
            validator={validator}
            widgets={widgets}
        />
    )
}

result (note the red text specified via Tailwind in widgets above):

image

kevinschaich avatar Jun 11 '24 22:06 kevinschaich

Tailwind support is critical as it seems to be the preferred styling solution now for all new Next/React websites. I noticed this repo: https://github.com/m6io/rjsf-tailwind - can this be integrated?

osseonews avatar Jul 22 '24 11:07 osseonews

@osseonews You can either do it yourself or reach out to the author and ask them to do it

heath-freenome avatar Jul 26 '24 00:07 heath-freenome