Update and Style Components

Beta

These docs rely on Slice Machine, which is in active development and subject to change. Content Relationships are not currently supported with Slices.

This article will show you how to build and style components in isolation using the mock data generated in The Slice Builder and Storybook.


🕙  Before You Start

If you haven't generated a component, along with the model and data, then please visit the Create and Model a Component article first.

Launch the Prismic Builder

Before you start reading this article, launch the Prismic Builder in a new terminal window, if you haven't yet, with the prismic sm --develop command.

It should open by default at http://localhost:9999.

Add Storybook

Storybook is a UI component explorer for front-end developers.

It combines the local mock data and a vue.js component to generate a preview of how it will look without having to publish content in the CMS, thus speeding up your development process. Check our dedicated article to learn how to install and run it in your project:

Update your component code

Updating your components to display the fields and adding styles is the step that will make your Slices in the Builder synchronize with your local project.

Open your component

Each Slice created in the Slice builder and saved into the filesystem has its own index.vue file. This is where you can begin to work on the look and feel of your components.

You can find these files in your project's slicesLibrary > SliceName > index.vue.

To explain this better, let's rejoin the TextImageRight Slice example built in the Create and Model a Component article. Look at the following file structure:

Copy
└── 📁 slices 
    └── 📁 TextImageRight
       ├── 📄 index.vue
       └── 📃 model.json

The slices folder houses your Slice components. If you change the default 'slices' name or path of the directory, you need to update it also in the sm.json file.

Then, the TextImageRight folder represents the name of your Slice. Inside this directory, you'll find two files: model.json, which is automatically updated with your Slice model when you save it from the Slice Builder, and index.vue, which is where you'll add the code, logic, and style for your components.

Add fields to your component

The Slice Builder shows suggested code snippets in Nuxt.js for each of your fields.

  • Click on the  '</> Show code widgets' button to reveal these snippets.

Copy each code snippet and paste it into your component index.vue file.

  • The code snippets in the repeatable zone come wrapped in a loop, you should compile all of these fields into the same loop when pasting them into your project.

Let's go back to our example from the previous article. First, launch the Prismic builder in a new terminal window with the prismic sm --develop command, if you haven't yet. Next, open the TextImageRight Slice and its code widgets.

Here's the template section with the code snippets for the fields we added in The Slice Builder. We use the code snippets in the index.vue file of our TextImageRight Slice component:

Copy
<template>
  <section>
    <div>
      <prismic-rich-text :field="slice.primary.textField" />
    </div>
    <div>
      <prismic-image :field="slice.primary.image" />
    </div>
  </section>
</template>

Coding & Styling Variations

As described in the Create and Model a component article, we have different variations of the 'TextImageRight Slice':

Default Slice: In the Default Slice view, we will show Image should float to the right in a text.

TextImageLeft: In the TextImageLeft view, we will show Image should float to the left in a text.

TitleImage: In this variation, we will show the title and image at the centre.

The slice.variation property

The slice.variation property is what is returned by the API to tell you which Variation is in use in the document by the content creators. The slice.variation will be the Variation ID of the Slice. You will find Variation ID in the Slice Builder when you select the slice variation from the dropdown.

For the example we created earlier these are the options that will be returned by the API:

Slice variation

Variation ID

Default Slice

default-slice

TextImageLeft

textImageLeft

TitleImage

titleImage

Conditionally render variations

If your Slice variations have different fields, you’ll need to cover the cases using a conditional statement.

For example, in our TextImageRight Slice, we created two variations. One has the name of TextImageLeft, and the other one TitleImage, which has a title field. We need to render these Variations conditionally, so the component knows which one to display when it exists in a document.

Here's the updated template section with the conditional statements:

Copy
<template>
  <section>
    <prismic-rich-text
      v-if="slice.variation === 'titleImage'"
      :field="slice.primary.title"
    />
    <prismic-rich-text
      v-if="slice.variation !== 'titleImage'"
      :field="slice.primary.textField"
    />
    <div>
      <prismic-image :field="slice.primary.image" />
    </div>
  </section>
</template>

Here, we use a v-if directive expression. The title will only render for the titleImage variation, and the textField will render when the variation is not equal to titleImage.

Style Your Component

Now that you've added the code of your fields, you're going to want to add styles to your component to match your design. Also, if you've added variations to your Slices, you can use the slice.variation property to render different class names to reflect the changes in your style for the variations.

You can add styles with Nuxt using inline styles, global CSS files, modules, libraries. It's up to you to choose the structure that best fits your needs.

Following the previous example, we'll use scoped CSS in the <style> element to target each specific class.

We want to make the text and image switch from left to right in the textImageRight and textImageRight Slices, and to center everything when the titleImage Variation is in use.

To do this, we'll use a :class object syntax to dynamically assign the Variation as the class name for the <section> element. Then, we add other classes to the title, text, and image:

  • <template>
  • <style>
  • Full component
Copy
<template>
  <section class="text-image" :class="slice.variation">
    <prismic-rich-text
      class="title"
      v-if="slice.variation === 'titleImage'"
      :field="slice.primary.title"
    />
    <prismic-rich-text
      class="text"
      v-if="slice.variation !== 'titleImage'"
      :field="slice.primary.textField"
    />
    <div :class="slice.variation === 'titleImage' ? 'center' : 'image'">
      <prismic-image :field="slice.primary.image" />
    </div>
  </section>
</template>
Copy
<style scoped>
.text-image {
  overflow: auto;
  display: flex;
  margin: 10px auto;
}

.default-slice {
  flex-direction: row;
  height: 130px;
}

.textImageLeft {
  flex-direction: row-reverse;
  height: 130px;
}

.titleImage {
  flex-direction: column;
  text-align: center;
  /* height: 300px; */
}

.image {
  float: right;
  width: 20%;
}

.center {
  height: 150px;
}

img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 9%;
}
.text {
  padding: 2% 5%;
  width: 80%;
}

.title {
  text-align: center;
}
</style>
Copy
<template>
  <section class="text-image" :class="slice.variation">
    <prismic-rich-text
      class="title"
      v-if="slice.variation === 'titleImage'"
      :field="slice.primary.title"
    />
    <prismic-rich-text
      class="text"
      v-if="slice.variation !== 'titleImage'"
      :field="slice.primary.textField"
    />
    <div :class="slice.variation === 'titleImage' ? 'center' : 'image'">
      <prismic-image :field="slice.primary.image" />
    </div>
  </section>
</template>


<script>
export default {
  name: "TextImageRight",
  props: {
    slice: {
      type: Object,
      required: true,
      default() {
        return {};
      },
    },
  },
};
</script>

<style scoped>
.text-image {
  overflow: auto;
  display: flex;
  margin: 10px auto;
}

.default-slice {
  flex-direction: row;
  height: 130px;
}

.textImageLeft {
  flex-direction: row-reverse;
  height: 130px;
}

.titleImage {
  flex-direction: column;
  text-align: center;
  /* height: 300px; */
}

.image {
  float: right;
  width: 20%;
}

.center {
  height: 150px;
}

img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 9%;
}
.text {
  padding: 2% 5%;
  width: 80%;
}

.title {
  text-align: center;
}
</style>

Preview with Mock Data

Once you've made your changes to the components, visit the Storybook interface at http://localhost:8888. You'll see what your component with the updated styles looks like using the mock data from The Slice Builder.

Here's a preview of the example textImageRight Slice we've been working on:

Component editing example video:

Send your Slice to Prismic

In the following article where you'll learn how to add your Slice to a Custom Type model and then sync it to your Prismic repository so that you and your content editors can begin to create documents.


Was this article helpful?
Not really
Yes, Thanks

Can't find what you're looking for? Get in touch with us on our Community Forum.