# JSON Forms - More Forms. Less Code

_Complex Forms in the blink of an eye_

JSON Forms eliminates the tedious task of writing fully-featured forms by hand by leveraging the capabilities of JSON, JSON Schema and Javascript.

## Vue Vuetify Renderers

This is the JSON Forms Vue Vuetify renderers package which provides a Vuetify based renderer set for [JSON Forms Vue](https://github.com/eclipsesource/jsonforms/blob/master/packages/vue).
The renderers are in a preview state.

### Quick start

Install JSON Forms Core, Vue 3 and Vue 3 Vuetify Renderers.

```bash
npm i --save @jsonforms/core @jsonforms/vue @jsonforms/vue-vuetify
```

Also add the packages to the transpile dependencies in the `vite.config.js` file:

```js
// https://vitejs.dev/config/
export default defineConfig({
  optimizeDeps: {
    // Exclude vuetify since it has an issue with vite dev - TypeError: makeVExpansionPanelTextProps is not a function - the makeVExpansionPanelTextProps is used before it is defined
    exclude: ['vuetify'],
  },

  // more config....
});
```

Use the `json-forms` component for each form you want to render and hand over the renderer set.

```vue
<script>
import { JsonForms } from '@jsonforms/vue';
import { extendedVuetifyRenderers } from '@jsonforms/vue-vuetify';
import { markRaw } from 'vue';

const renderers = markRaw([
  ...extendedVuetifyRenderers,
  // here you can add custom renderers
]);

export default defineComponent({
  name: 'app',
  components: {
    JsonForms,
  },
  data() {
    return {
      renderers: Object.freeze(renderers),
      data,
      schema,
      uischema,
    };
  },
  methods: {
    onChange(event) {
      this.data = event.data;
    },
  },
});
</script>

<template>
  <json-forms
    :data="data"
    :schema="schema"
    :uischema="uischema"
    :renderers="renderers"
    @change="onChange"
  />
</template>

<style>
@import '@jsonforms/vue-vuetify/lib/jsonforms-vue-vuetify.css';
</style>
```

In your vuetify creation specify the icons used

Material Design Icons (mdi)

```js
import { mdi, aliases as mdiAliases } from 'vuetify/iconsets/mdi';
import { createVuetify } from 'vuetify';

import { mdiIconAliases } from '@jsonforms/vue-vuetify';
import '@mdi/font/css/materialdesignicons.css';

createVuetify({
    icons: {
      defaultSet: 'mdi',
      sets: {
        mdi,
      },
      aliases: { ...mdiAliases, ...mdiIconAliases };,
    },
  });
```

Font Awesome (fa)

```js
import { fa, aliases as faAliases } from 'vuetify/iconsets/fa';
import { createVuetify } from 'vuetify';

import { faIconAliases } from '@jsonforms/vue-vuetify';
import '@fortawesome/fontawesome-free/css/all.css';

createVuetify({
    icons: {
      defaultSet: 'fa',
      sets: {
        fa,
      },
      aliases: { ...faAliases, ...faIconAliases };,
    },
  });
```

If note done yet, please [install Vuetify for Vue](https://vuetifyjs.com/en/getting-started/installation/).

For more information on how JSON Forms can be configured, please see the [README of `@jsonforms/vue`](https://github.com/eclipsesource/jsonforms/blob/master/packages/vue/README.md).

## Customization

### Prepend and Append Slots

All control renderers now support `prepend` and `append` slots, allowing you to add custom content before or after input fields without creating entirely custom renderers.

**Example:**

```vue
<template>
  <string-control-renderer v-bind="$props">
    <template #prepend>
      <v-icon>mdi-help-circle</v-icon>
    </template>
  </string-control-renderer>
</template>
```

See the "Prepend/Append Slots (Basic)" example in the dev app.

## Override the ControlWrapper component

All control renderers wrap their components with a **`ControlWrapper`** component, which by default uses **`DefaultControlWrapper`** to render the wrapper element around each control.

If you want to:

- Replace the **`DefaultControlWrapper`** with your own implementation, or
- Provide custom renderers that render their child controls differently,

you can use Vue’s **`provide` / `inject` mechanism** to supply your own wrapper under the **`ControlWrapperSymbol`**.

For example, the demo application includes a custom wrapper that can be enabled from the **Example App Settings**. It is registered like this:

```ts
import { provide, type DefineComponent } from 'vue';
import {
  ControlWrapperSymbol,
  type ControlWrapperProps,
} from '@jsonforms/vue-vuetify';

import ControlWrapper from './components/ControlWrapper.vue';

provide(
  ControlWrapperSymbol,
  ControlWrapper as DefineComponent<ControlWrapperProps>,
);
```

## Testing in CJS-transformed environments

When writing tests for custom renderers in a Jest/Vitest CJS-transformed environment, `vue` should be imported first in your custom renderers. See [Testing with Jest / Vitest](../vue/README.md#testing-with-jest--vitest) in the `@jsonforms/vue` README.

## License

The JSONForms project is licensed under the MIT License. See the [LICENSE file](https://github.com/eclipsesource/jsonforms/blob/master/LICENSE) for more information.
