NUXTJS + Vuetify - Colors in SCSS - vue.js

I'm trying to get the colors from the nuxt.config.js file and put them directly in variables.scss
Currently my variables.scss look like this
#import '~vuetify/src/styles/styles.sass';
.button-blue {
background-color: map-get($blue, darken-2) !important;
color: map-get($blue-grey, lighten-5) !important;
}
I would like to assign the color directly from nuxt.config, more or less this way:
#import '~vuetify/src/styles/styles.sass';
.button-blue {
background-color: primary!important;
color: seconday !important;
}
My nuxt.config.js
css: ['~/assets/variables.scss'],
vuetify: {
customVariables: ['~/assets/variables.scss'],
theme: {
dark: false,
themes: {
light: {
primary: colors.blue.darken2,
secondary: colors.orange.darken1,
tertiary: colors.green.darken1,
accent: colors.shades.black,
error: colors.red.accent3,
info: colors.green.darken3,
background: '#EAEBEE'
},
dark: {
primary: colors.blue.darken2,
accent: colors.orange.darken3,
secondary: colors.amber.darken3,
info: colors.teal.lighten1,
warning: colors.amber.base,
error: colors.deepOrange.accent4,
success: colors.green.accent3,
background: colors.red.accent3
}
}
}
}
Any suggestion? I'm using Vue + Vuetify + Nuxt

Like this:
.default-box-layout {
padding: 15px;
border: 1px solid var(--v-primary);
background-color: var(--v-background);
width: 100%;
margin: 0;
}

From the docs:
Enabling customProperties will also generate a css variable for each theme color, which you can then use in your components’ blocks.
So, when you add:
theme: {
options: { customProperties: true }, // this line
},
to your Vuetify config, variables will get injected at the css root variables. Now, you can use things like --v-primary-base, like this:
.button-blue {
background-color: var(--v-primary-base);
color: var(--v-secondary-base) !important;
}
More?
See https://vuetifyjs.com/en/features/theme/#custom-properties

Related

Vue 3 cli-service app: "Slot "default" invoked outside of the render function" warning when component with slots is imported from other component

MCVE
I have a Tabpane component that takes slots as input. When imported from the template it works as expected.
<Tabpane>
<div caption="I am div 1">Div 1</div>
<div caption="I am div 2">Div 2</div>
</Tabpane>
However when imported from an other component ( Composite in the example ), then it triggers the following warning:
Slot "default" invoked outside of the render function:
this will not track dependencies used in the slot. Invoke the slot function inside the render function instead.
// src/components/Composite.js
import { defineComponent, h } from "vue";
import Tabpane from "./Tabpane.vue";
export default defineComponent({
name: "Composite",
setup() {
const slots = [
h("div", { caption: "I am div 1" }, ["Div 1"]),
h("div", { caption: "I am div 2" }, ["Div 2"])
];
return () => h(Tabpane, {}, () => slots);
}
});
Solved.
The problem was that I called slots.default() from within setup, but not within the returned render function.
Also this component reflected a very beginner approach to reactivity. By now I know better. The old problematic solution is still there in src/components/Tabpane.vue.
The right solution that triggers no warning is:
// src/components/Tabpane2.vue
<script>
import { defineComponent, h, reactive } from "vue";
export default defineComponent({
name: "Tabpane2",
props: {
width: {
type: Number,
default: 400,
},
height: {
type: Number,
default: 200,
},
},
setup(props, { slots }) {
const react = reactive({
selectedTab: 0,
});
return () =>
h("div", { class: ["vertcont"] }, [
h(
"div",
{
class: ["tabs"],
},
slots.default().map((tab, i) =>
h(
"div",
{
class: {
tab: true,
selected: i === react.selectedTab,
},
onClick: () => {
react.selectedTab = i;
},
},
[tab.props.caption]
)
)
),
h(
"div",
{
class: ["slotscont"],
style: {
width: `${props.width}px`,
height: `${props.height}px`,
},
},
slots.default().map((slot, i) =>
h(
"div",
{
class: {
slot: true,
active: react.selectedTab === i,
},
},
[slot]
)
)
),
]);
},
});
</script>
<style>
.tab.selected {
background-color: #efe;
border: solid 2px #afa !important;
border-bottom: transparent !important;
}
.tab {
background-color: #eee;
}
.tabs .tab {
padding: 5px;
margin: 2px;
border: solid 2px #aaa;
border-radius: 8px;
border-bottom: transparent;
cursor: pointer;
user-select: none;
transition: all 0.5s;
color: #007;
}
.tabs {
display: flex;
align-items: center;
margin-left: 5px;
}
.vertcont {
display: flex;
flex-direction: column;
margin: 3px;
}
.slotscont {
position: relative;
overflow: scroll;
padding: 5px;
border: solid 1px #777;
}
.slot {
visibility: hidden;
position: absolute;
}
.slot.active {
visibility: visible;
}
</style>
Slots need to be invoked within the render function and or the <template> box to ensure they keep their reactivity.
A full explanation can be found in this post: https://zelig880.com/how-to-fix-slot-invoked-outside-of-the-render-function-in-vue-3

Vuetify how to override sass variable for pagination component

I am having some issue while modifying the existing sass variables inside my vue application.
I have gone through a few SO questions where there are good amount of information on overriding the existing sass variables but nothing seems be working for me. I am pretty sure I am doing some thing wrong.
I have implemented a custom pagination control which works fine but I want to override the sass variables for it so that the size of pagination control button would be little smaller than the default button size.
This is my webpack.config.js
//webapack.config.js
module.exports = {
module: {
rules: [
// SASS has different line endings than SCSS
// and cannot use semicolons in the markup
{
test: /\.sass$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'sass-loader',
// Requires sass-loader#^7.0.0
options: {
// This is the path to your variables
data: "#import '#/scss/variables.scss'"
},
// Requires sass-loader#^8.0.0
options: {
// This is the path to your variables
prependData: "#import '#/scss/variables.scss'"
},
},
],
},
// SCSS has different line endings than SASS
// and needs a semicolon after the import.
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'sass-loader',
// Requires sass-loader#^7.0.0
options: {
// This is the path to your variables
data: "#import '#/scss/variables.scss';"
},
// Requires sass-loader#^8.0.0
options: {
// This is the path to your variables
prependData: "#import '#/scss/variables.scss';"
},
},
],
},
],
},
}
Following is the variables.scss inside src/scss directory, I use it to override the font-family and stuff.
// src/scss/variables.scss
#import url("https://fonts.googleapis.com/css?family=Hind+Siliguri:400,500,600,700&display=swap");
$body-font-family: "Hind Siliguri", sans-serif !important;
$typoOptions: display-4, display-3, display-2, display-1, headline, title,
subtitle-1, subtitle-2, body-1, body-2, caption, overline;
#app {
font-family: $body-font-family, sans-serif !important;
#each $typoOption in $typoOptions {
.#{$typoOption} {
font-family: $body-font-family, sans-serif !important;
}
}
}
// $pagination-item-font-size: 2px !important;
// $pagination-item-height: 10px !important;
// $pagination-item-margin: 1px !important;
// $pagination-item-min-width: 10px !important;
// $pagination-item-padding: 0 10px !important;
// $pagination-more-height: x !important;
// $pagination-navigation-height: 10px !important;
// $pagination-navigation-width: 10px !important;
#import "~vuetify/src/styles/styles.sass";
I want to override the sass variables given by vuetify but when I add them variables.scss (commented line on the above code), it doesn't work for some reason. Any help or pointer is much appreciated.
.v-pagination__item {
height: 25px;
min-width: 25px;
margin: 0px !important;
padding: 0px !important;
font-size: 14px;
}
try use this class, and for nav
.v-pagination__navigation
it work for me
I faced a similar problem with the total visible pages not being consistent. A work around is to create logic based upon data set size and update a reactive property for the column size.

Some strange errors when using less

There are many strange errors when I using less in VSCode. Here is an example:
#library() {
.colors() {
primary: green;
secondary: blue;
}
}
#library() {
.colors() { primary: grey; }
}
.button {
color: #library.colors[primary];
border-color: #library.colors[secondary];
}
compiled file:
.button {
color: #library.colors[primary];
border-color: #library.colors[secondary];
}
line13: error: property value expectedless(css-propertyvalueexpected)
line14: error: { expectedless(css-lcurlyexpected)
line15: error: at-rule or selector expectedless(css-ruleorselectorexpected)
This is an example that I copied from http://lesscss.org on how to use map. I also noticed that map is a new feature which has been enabled since v3.5. But my LESS version is v3.10.

Vuetifyjs how to set custom RGBA color?

As explained here vuetify colors can be customized as
Vue.use(Vuetify, {
theme: {
primary: '#3f51b5',
secondary: '#b0bec5',
accent: '#8c9eff',
error: '#b71c1c'
}
})
but how can I use a custom RGBA color?
Vuetify's creators have said there is not their priorities to implement this feature...
You can use Pseudo-class: ::after or ::before ,set background:var(--v-background-base); and opacity:0.4;.
for example:
.liveServer__title {
position: relative;
&::after {
content: "";
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: var(--v-background-base);
opacity: 0.4;
z-index: -1;
}
}

sass variables right way

I'm creating multiple themes with scss in ionic. I ended up with 2 ways, but which one is better and why?
First way
$colors: (
primary: #bdc3c7,
secondary: #444444,
danger: #7f8c8d,
light: #34495e,
dark: #e74c3c
);
.light-theme {
// main style for all the commi themes app
ion-content {
background-color: color($colors, light);
}
#import "main";
}// light-theme
second way
.light-theme {
$colors: (
primary: #bdc3c7,
secondary: #444444,
danger: #7f8c8d,
light: #34495e,
dark: #e74c3c
);
// main style for all the commi themes app
ion-content {
background-color: color($colors, light);
}
#import "main";
}//
The first way I have the colors outside the class and the second way the colors are inside the class and the both ways are working. I'm thinking about what would happen if we have at least three themes?
Just fantasy. Sassmeister demo.
Let's define an array of themes:
$themes: (
default: ( // theme name
// some colors. colors names are the same for all themes
primary: red,
secondary: blue
),
dark: (
primary: red-dark,
secondary: blue-dark
),
light: (
primary: red-light,
secondary: blue-light
)
);
Then set the $theme variable. It refers to one of the elements of $themes array. We will always get color values form this variable.
$theme: map-get($themes, default);
Boring mixin to get color value by name. $theme used here.
#function color($color-name) {
#return map-get($theme, $color-name);
}
Mixin stylish that redefines the value of $theme variable. We use !global flag to make this variable accessible from any scope. This mixin generates class name .theme-name before our selector for all themes but not default.
#mixin stylish($theme-name: 'default') {
$theme: map-get($themes, $theme-name) !global;
#if ($theme-name == 'default') {
#content;
} #else {
.theme-#{$theme-name} & {
#content;
}
}
}
And now we can write code like this:
.block {
#include stylish() {
color: color(primary);
}
&__element {
#include stylish() {
color: color(primary);
}
#include stylish(dark) {
color: color(primary);
}
#include stylish(light) {
color: color(primary);
}
}
}
Css output:
.block {
color: red;
}
.block__element {
color: red;
}
.theme-dark .block__element {
color: red-dark;
}
.theme-light .block__element {
color: red-light;
}
This mixin can generate all themes. Demo.
#mixin global-stylish() {
#include stylish() {
#content;
}
#include stylish(dark) {
#content;
}
#include stylish(light) {
#content;
}
}
Usage:
&__element {
#include global-stylish() {
color: color(secondary);
}
}
Thank you for opening sass way , here is my end code
$themes:(
theme:(
primary: #032838,
secondary: #868a6f,
danger: #ed4039,
light: #f3f2f2,
dark: #37aad9
),
light:(
primary: #34495e,
secondary: #e74c3c,
danger: #7f8c8d,
light: #bdc3c7,
dark: #444444
),
dark:(
primary: #f3f2f2,
secondary: #3D8EB9,
danger: #e74c3c,
light: #303030,
dark: #212121
),
main:(
black: #000000,
white: #ffffff,
wisteria: #8e44ad,
pomegranate:#c0392b,
orange: #f39c12,
green: #03A678,
)
);
$color-key: primary !default;
#function color(
$theme-name: commi,
$color-key: $color-key,
$opacity: 1
){
$color: null;
$theme: map-get($themes, $theme-name);
#if $theme{
$color: map-get($theme, $color-key );
}
#return $color;
}
#import "light";
#import "dark";
and in my theme i call it like this
.dark-theme{
$theme : dark;
#import "main";
}
in scss style file
ion-content {
color: color($theme, light);
background-color:color($theme, light);
#if($theme == 'dark'){
background-color:color($theme, primary);
}
}