Feedback Laraform is now in maintenance mode. Read more on our GitHub.

Creating Theme

#Creating Theme File

To create a custom theme, first create a new theme file at resources/js/themes/my_theme/index.js with the following contents:

import utils from '@laraform/laraform/src/utils'
import bs4 from '@laraform/laraform/src/themes/bs4'

export default utils.extendTheme(bs4, {
  classes: {},
  elements: {},
  components: {},
  layouts: {},
  grid: {},
})

By default this will be completely identical to the original bs4 theme as we are not overwriting any of its properties. Before you proceed you can check out Style & Theme chapter to learn the basics of these properties.

#Registering Theme File

To register your newly created theme file, simply call .theme() before installing Laraform:

import Vue from 'vue'
import Laraform from '@laraform/laraform/src'
import MyTheme from './themes/my_theme'

Laraform.theme('my-theme', MyTheme)

Vue.use(Laraform)

const app = new Vue({
  el: '#app'
})
Note that we importing @laraform/laraform/src instead of @laraform/laraform because of a conflict that might occur due to importing Trix twice.

That's it, now you can use your theme at any of your form instances:

<?php

namespace App\Forms;

class ThemedForm extends \Laraform
{
  public $theme = 'my-theme';

  public function schema() {
    // ...
  }
}

#Creating Styles

To extend an existing theme's style create a new file at resources/js/themes/my_theme/scss/index.scss:

.my-theme {
  @import '~laraform/src/themes/bs4/scss/vars';
  @import '~laraform/src/themes/bs4/scss/mixins';
  @import '~laraform/src/themes/bs4/scss/components';
}

These will import all the default styles of the existing bs4 theme and you are free to add any custom styles or variables:

.my-theme {
  @import '~laraform/src/themes/bs4/scss/vars';
  @import '~laraform/src/themes/bs4/scss/mixins';
  @import '~laraform/src/themes/bs4/scss/components';

  $lf-primary-color: #00aaff;

  background-color: #f5f7f9;
}

The list of available variables can be found here.

#Registering Theme Styles

After creating your theme style, you need to import the .scss in resources/sass/app.scss or app main stylesheet, where it can access CSS framework variables (if any used):

// Bootstrap
@import '~bootstrap/scss/bootstrap';

// Laraform
@import './../js/themes/my_theme/scss/index.scss'

The last thing you need to do is to overwrite the form class property in the theme file's classes object, so that my-theme class will be used for the form:

import utils from '@laraform/laraform/src/utils'
import bs4 from '@laraform/laraform/src/themes/bs4'

export default utils.extendTheme(bs4, {
  classes: {
    form: 'my-theme'
  },
  elements: {},
  components: {},
  layouts: {},
  grid: {},
})

#Overriding Elements

If you created a new theme as described previously, your theme is almost identical to the bs4 theme as both theme file and theme styles were extended from it. This means that all the elements and components are rendered with Bootstrap 4 views as they are not overridden by your theme. In this section we will see how you can replace any of them.

Create Element

For a very basic example let's see how we could have a custom TextElement. Let's create resources/js/themes/my_theme/components/elements/TextElement

<template>
  <div class="my-text-element">
    <label
      :for="name"
    >{{ label }}</label>

    <input
      v-model="model"
      :type="inputType"
    />
  </div>
</template>

<script>
  import TextElement from '@laraform/laraform/components/elements/TextElement'

  export default {
    mixins: [TextElement]
  }
</script>

As you can see we've imported the TextElement core element from Laraform and used it as a mixin for our own view implemantation. Properties like name, label, inputType and model can be used because we are extending the core TextElement which has the <script> part of the component and therefore its API can be used.

Override Element

Now to override the TextElement provided by the bs4 theme, we need to let the theme know that we want to use our custom component for TextElement and therefore we need to add it in the theme file:

import utils from '@laraform/laraform/src/utils'
import bs4 from '@laraform/laraform/src/themes/bs4'

import TextElement from './../components/elements/TextElement'

export default utils.extendTheme(bs4, {
  classes: {
    form: 'my-theme'
  },
  elements: {
    TextElement
  },
  components: {},
  layouts: {},
  grid: {},
})

From now on, when you are using a text type element within a form using my-theme as theme, this template will be rendered.

#Overriding Components

You might need to replace existing components in your theme, like ElementLabel with a custom solution. Let's see how we can do that.

Create Component

First let's create a new component at resources/js/themes/my_theme/components/ElementLabel.vue:

<template>
  <label
    :class="theme.classes.label"
    :for="name"
  >
    <slot></slot>
  </label>
</template>

<script>
  import ElementLabel from '@laraform/laraform/src/components/ElementLabel'

  export default {
    mixins: [ElementLabel]
  }
</script>

Override Component

Then override the it within out theme file's components object:

import utils from '@laraform/laraform/src/utils'
import bs4 from '@laraform/laraform/src/themes/bs4'

import TextElement from './../components/elements/TextElement'
import ElementLabel from './../components/elements/ElementLabel'

export default utils.extendTheme(bs4, {
  classes: {
    form: 'my-theme'
  },
  elements: {
    TextElement
  },
  components: {
    ElementLabel
  },
  layouts: {},
  grid: {},
})

Use Custom Component

Now we can use it within out custom TextElement, but instead of rendering component by name we'll render it dynamically accessing the theme.components object:

// resources/js/themes/my_theme/components/elements/TextElement

<template>
  <div class="my-text-element">
    <component
      :is="theme.components.ElementLabel"
      :for="id"
      v-html="label"
    />

    <input
      v-model="model"
      :type="inputType"
    />
  </div>
</template>

<script>
  import TextElement from '@laraform/laraform/src/components/elements/TextElement'

  export default {
    mixins: [TextElement]
  }
</script>