Theming in Vue apps
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9048000/00b.png)
Can it be DYNAMIC?
@mayashavin
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9047999/01b.png)
![](https://res.cloudinary.com/mayashavin/image/upload/v1571089888/mayashavin/Maya_new.jpg)
@mayashavin
Senior Software Engineer at
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/8851721/Microsoft_logo.svg.png)
OSS Maintainer
author, community organizer & speaker
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9048077/google_developers_logomark_color.png)
Web
![](https://gantlaborde.com/wp-content/uploads/2020/04/MDE-Logo-Dark-01.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9048132/colored-text.png)
Ambassador
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6759373/600_479598039.jpeg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9047999/01b.png)
What is Theming ?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9047999/01b.png)
Theming is
The process of designing and constructing styles based on specific idea
recognizable & Memorable Experience for user
brand look & Feel
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9047999/01b.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9049217/1161107.jpeg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9049223/jingle-bells-event-making-holiday-party-website-wordpress-theme_74802-0-original.jpeg)
Source: Wordpress
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9049231/Screen_Shot_2021-10-25_at_9.18.58.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9049251/maxresdefault.jpeg)
theming for applications
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9047999/01b.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9047999/01b.png)
Theming is about
Color
Typography
ICONS
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9049416/Screen_Shot_2021-10-25_at_10.14.19.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/6982529/styleguide-sizes.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9049435/FA5_icons.png)
and more...
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9047999/01b.png)
static theming
configurations based
Pre-processed styles
limited customization
Dynamic theming
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9048000/00b.png)
Default configurations
run-time generating styles
full customization
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9047999/01b.png)
Static theming
boilerplate + clients' configurations
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9049638/ecommerce-wireframe-2.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9049681/fashi-free-template.jpeg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9049684/coloshop-free-bootstrap-ecommerce-website-template.jpeg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9049688/winter-free-template.jpeg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9047999/01b.png)
Dynamic theming
Theme is loaded on run-time based on user's choice
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9047999/01b.png)
Dynamic theming
single & consistent theme provider for components
communicate with css on run-time
Extendable with other styles
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9047999/01b.png)
the techniques
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9047999/01b.png)
dynamic theme - single theme provider
State Management
Provide/Inject
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
isDarkMode: isDarkMode(),
},
mutations: {
toggleDarkMode(state, darkMode) {
state.isDarkMode = darkMode;
},
},
});
<template>
<theme-provider :theme="theme">
<layout :isDarkMode="isDarkMode">
<slot/>
</layout>
</theme-provider>
</template>
<script>
import styled, { ThemeProvider } from 'vue-styled-components';
import theme from '@/plugins/theme';
import { LightLayout, DarkLayout } from './ModeLayouts';
const layoutProps = { isDarkMode: Boolean };
const Layout = styled('div', layoutProps)`
${({ isDarkMode }) => (isDarkMode ? DarkLayout : LightLayout)}
`;
export default {
components: { Layout, ThemeProvider },
data() {
return { theme }
},
computed: {
isDarkMode() { return this.$store.state.isDarkMode },
},
};
</script>
/* plugins/theme.js */
const theme = {
dark: {
background: '#2d3239',
title: '#e9d970',
text: '#fff',
subLabelText: '#cfcfcf',
},
light: {
background: '#fff',
title: '#333',
text: '#2c3e50',
subLabelText: '#757575',
},
};
Single configurations
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9047999/01b.png)
dynamic theme - communicate CSS on run-time
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9049761/Screen_Shot_2021-10-25_at_12.00.15.png)
vue-styled-component
CSS Variables for common theme
polished
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9047999/01b.png)
communicate CSS on run-time
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9049761/Screen_Shot_2021-10-25_at_12.00.15.png)
import styled from 'vue-styled-components';
import {
getStyledTitle
} from '@/components/PokemonItem/StyledPokemonTitle';
import {
DarkLayout,
LightLayout
} from '@/layouts/ModeLayouts';
import { lighten } from 'polished';
const itemProps = {
themeColor: String,
isDarkMode: Boolean,
};
export const InfoSection = styled('section', itemProps)`
border-left: 1px solid ${(props) => props.themeColor};
border-right: 1px solid ${(props) => props.themeColor};
background: var(--page-background);
`;
export const SectionTab = styled('h3', itemProps)`
border-bottom: 1px solid ${(props) => props.themeColor};
color: ${(props) => lighten(0.1, props.themeColor)};
`;
const StyledView = styled('div', itemProps)`
${({ isDarkMode }) => (isDarkMode ? DarkLayout : LightLayout)};
background: ${(props) => props.themeColor};
`;
<template>
<styled-view :themeColor="color" :isDarkMode="isDarkMode">
<div class="pokemon-main-view">
<section class="pokemon-view--top-section">
<!--...-->
<cld-image
type="fetch"
:public-id="pokemon.avatar"
width="220"
crop="scale"
class="pokemon-view--image"
/>
<info-section :themeColor="color">
<section-tab :themeColor="color">About</section-tab>
<tab-details>
<details-row>
<!--something-->
</details-row>
</tab-details>
</info-section>
</div>
</styled-view>
</template>
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9047999/01b.png)
dynamic theme - extendable styles
import { css } from 'vue-styled-components';
export const LightLayout = css`
--page-background: ${(props) => props.theme.light.background};
--page-title: ${(props) => props.theme.light.title};
--page-text: ${(props) => props.theme.light.text};
--page-sub-label-text: ${(props) => props.theme.light.subLabelText};
`;
export const DarkLayout = css`
--page-background: ${(props) => props.theme.dark.background};
--page-title: ${(props) => props.theme.dark.title};
--page-text: ${(props) => props.theme.dark.text};
--page-sub-label-text: ${(props) => props.theme.dark.subLabelText};
`;
import StyledButton from './StyledButton';
const TomatoButton = StyledButton.extend`
color: tomato;
border-color: tomato;
`;
export default TomatoButton;
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9047999/01b.png)
With tailwindcss?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9047999/01b.png)
With tailwindcss?
import tw from 'tailwind.macro';
const StyledTitle = styled('h3')`
${() => tw("text-red-500")}
`;
using Babel macro
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9047999/01b.png)
RESOURCES
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9047999/01b.png)
@mayashavin
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9047999/01b.png)
RESOURCES
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9048000/00b.png)
@mayashavin
summary
Create single theme System (VueX, XState, etc)
USE built-in css properties
vue styled component for dynamic component styling
Plan configuration before developing
![](https://s3.amazonaws.com/media-p.slid.es/uploads/1005381/images/9048001/03b.png)
thank you!
Theming in Vue Apps
By Maya Shavin
Theming in Vue Apps
- 82