It's going to be awhile that I'm trying to find a solution to use javascript variables has scss value.
Let me explain my issue.
I use VueJs/Vuetify and I've got two entry point for my theme.
The first one is a json file like that :
module.exports = {
primary: { base: '#4d7cff', dark: '#2756d8', light: '#96b0fb' },
secondary: { base: '#00bda5', dark: '#209284', light: '#cef1ec' },
content: { base: '#37467a', dark: '#242c47', light: '#c3cbe6' },
danger: { base: '#e43858', dark: '#d22545', light: '#E36d83' },
success: { base: '#00c28d', dark: '#199c79', light: '#0bebae' },
accent: '#f5f8fa',
gradient: 'linear-gradient(45deg, #00bda5, #4d7cff)'
}
This file is required and use by vuetify two create custom color values and works perfectly.
The second one is a simple scss file :
// Theme colors
$color-primary-base: #4d7cff;
$color-primary-dark: #2756d8;
$color-primary-light: #96b0fb;
$color-secondary-base: #4d7cff;
$color-secondary-dark: #209284;
$color-secondary-light: #cef1ec;
$color-content-base: #37467a;
$color-content-dark: #242c47;
$color-content-light: #c3cbe6;
$color-danger-base: #e43858;
$color-danger-dark: #d22545;
$color-danger-light: #ff8097;
$color-success-base: #00c28d;
$color-success-dark: #199c79;
$color-success-light: #14e1a9;
$color-accent: #f5f8fa;
My goal would be to connect the json file with the scss variables to have one entry point for the entire app.
Why do this ?
Vuetify offers a scss variable overload system to modify the style of the components.
the idea would be to control this overload from the javascript file
In addition to that, due to vuetify limits, there are certains points where I must to control the color in a responsive context (for example a white header on desktop and blue on mobile) and therefore am obliged to use scss variables.
I've find this article on medium who at first sight seems to answers my problem.
But when I try to test it I've got the following error :
in ./src/assets/styles/vuetify.scss
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
ValidationError: Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
- options has an unknown property 'options'. These properties are valid:
object { implementation?, sassOptions?, prependData?, sourceMap?, webpackImporter? }
at validate (C:\Users\33770\Documents\Calimed\novalys-front\node_modules\schema-utils\dist\validate.js:96:11)
at Object.loader (C:\Users\33770\Documents\Calimed\novalys-front\node_modules\sass-loader\dist\index.js:36:28)
Vuetify.scss
#import './novalys/map.scss';
#import '~vuetify/src/styles/main.sass';
vue.config.js
const sass = require('node-sass')
const sassUtils = require('node-sass-utils')(sass)
const sassVars = require(__dirname + '/src/theme/index.js')
module.exports = {
css: {
loaderOptions: {
scss: {
prependData: `#import "#/assets/styles/novalys/map.scss";`,
options: {
functions: {
'get($keys)': function(keys) {
keys = keys.getValue().split('.')
let result = sassVars
let i
for (i = 0; i < keys.length; i++) {
result = result[keys[i]]
}
result = sassUtils.castToSass(result)
return result
}
}
}
}
}
},
transpileDependencies: ['vuetify']
}
Can someone here would help me to find a possible solution ?
I've heard about an inverse solution by exporting a scss variable like that
:export {
some-variable: 'some-value';
}
But my idea is to have the entry point in json not a scss file.
Thank you in advance !
Related
EDIT : the former question was "JHipster Blueprint - How to get default Java package name ?"
I am developing a blueprint with JHipster that overrides the entity-server sub-generator. The desired behaviour is to replace all files in /src/main/java/defaultpackageName/domain/ from the project generated by the blueprint with my generated files. This is my code (files.js):
const entityServerFiles = {
noHibernate: [
//domain files
{
path: 'src/main/java/XXX/domain/',
templates: [
{
file: 'Entity.java',
renameTo: generator => `${generator.persistClass}.java`
}
]
}
]
};
function writeFiles() {
return {
write() {
this.writeFilesToDisk(entityServerFiles, this, false);
}
}
}
module.exports = {
writeFiles
};
For now it just creates a folder XXX in /src/main/java/ with my generated files in it.
What would I need to write in the XXX in path: 'src/main/java/XXX/domain/' in order to generate the files at the right place?
I did some digging on github on the generator-jhipster project and the prompt asking the user for the default java package name is in /generator-jhipster/generators/java/index.cjs/. This is the whole code https://github.com/jhipster/generator-jhipster/blob/main/generators/java/index.cjs
But I just took the important part:
const {
PACKAGE_NAME,
PACKAGE_NAME_DEFAULT_VALUE,
PRETTIER_JAVA_INDENT,
PRETTIER_JAVA_INDENT_DEFAULT_VALUE,
BUILD_TOOL,
BUILD_TOOL_DEFAULT_VALUE,
BUILD_TOOL_PROMPT_CHOICES,
} = require('./constants.cjs');
get prompting() {
return {
async showPrompts() {
if (this.shouldSkipPrompts()) return;
await this.prompt(
[
{
name: PACKAGE_NAME,
type: 'input',
validate: input => this.validatePackageName(input),
message: 'What is your default Java package name?',
default: () => this.sharedData.getConfigDefaultValue(PACKAGE_NAME, PACKAGE_NAME_DEFAULT_VALUE),
},
],
this.config
);
},
};
}
From what I understand, I just need to access the PACKAGE_NAME constant from my blueprint and it should work. Any ideas?
I just found the solution...
const entityServerFiles = {
noHibernate: [
//domain files
{
path: 'src/main/java/',
templates: [
{
file: 'package/domain/Entity.java',
renameTo: generator => `${generator.entityAbsoluteFolder}/domain/${generator.persistClass}.java`
}
]
}
]
};
function writeFiles() {
return {
write() {
this.writeFilesToDisk(entityServerFiles, this, false);
}
}
}
module.exports = {
writeFiles
};
The path property specifies the path inside the templates folder. Meanwhile, you can specify the path you want your files to be generated inside the project in the renameTo property.
So the answer to my question is ${generator.entityAbsoluteFolder} which had nothing to do with my original hypothesis, but this question can also be useful for writing templates in general.
I am working on dynamic color on my project. So i was succeed to store variable on env and passed on vue.config.js in order to render scss color variable from env variable. but i got into problem when i had to render color value from api since api send color variable as a object. so is it possible to pass object on scss prependData as a object ?
Existing code passed from env:
I am using vuejs 2 and i am adding these code on vue.config.js.
module.exports = {
css: {
loaderOptions: {
scss: {
prependData: `$VUE_APP_PRIMARY:${process.env.VUE_APP_PRIMARY};
$VUE_APP_FOOTER_PRIMARY_COLOR:${process.env.VUE_APP_FOOTER_PRIMARY_COLOR};
$VUE_APP_NAV_COLOR:${process.env.VUE_APP_NAV_COLOR};
$VUE_APP_CARD_BANDAGE_COLOR:${process.env.VUE_APP_CARD_BANDAGE_COLOR};
$VUE_APP_TOP_HEADER_COLOR:${process.env.VUE_APP_TOP_HEADER_COLOR};
$VUE_APP_TOP_HEADER_FONT_COLOR:${process.env.VUE_APP_TOP_HEADER_FONT_COLOR};
$VUE_APP_NAV_COLOR:${process.env.VUE_APP_NAV_COLOR};
$VUE_APP_NAV_PRIMARY_COLOR:${process.env.VUE_APP_NAV_PRIMARY_COLOR};
$VUE_APP_DARK_BTN:${process.env.VUE_APP_DARK_BTN};
$VUE_APP_DARK_BTN_COLOR:${process.env.VUE_APP_DARK_BTN_COLOR};
$VUE_APP_BRAND_BTN:${process.env.VUE_APP_BRAND_BTN};
$VUE_APP_BRAND_BTN_COLOR:${process.env.VUE_APP_BRAND_BTN_COLOR};
$VUE_APP_ERROR_MESSAGE_COLOR:${process.env.VUE_APP_ERROR_MESSAGE_COLOR};
$VUE_APP_FONT_FAMILY:${process.env.VUE_APP_FONT_FAMILY};
$VUE_APP_FONT_HEADER:${process.env.VUE_APP_FONT_HEADER};
$VUE_APP_BACKGROUND:${process.env.VUE_APP_BACKGROUND};
$VUE_APP_BACKGROUND_IMAGE:${process.env.VUE_APP_BACKGROUND_IMAGE};
$VUE_APP_CHOOSE_CATEGORY:${process.env.VUE_APP_CHOOSE_CATEGORY};
$VUE_APP_PLACEHOLDER:${process.env.VUE_APP_PLACEHOLDER};
$VUE_APP_BTN:${process.env.VUE_APP_BTN};
$VUE_APP_FOOTER_LINK:${process.env.VUE_APP_FOOTER_LINK};
$VUE_APP_MULTIPLE_TAG:${process.env.VUE_APP_MULTIPLE_TAG};
$VUE_APP_CART_BTN_BACKGROUND:${process.env.VUE_APP_CART_BTN_BACKGROUND};
$VUE_APP_CART_BTN:${process.env.VUE_APP_CART_BTN};
$VUE_APP_ORDER_INFO_CARD:${process.env.VUE_APP_ORDER_INFO_CARD};
$VUE_APP_CARD_BTN_DELETE_BACKGROUND:${process.env.VUE_APP_CARD_BTN_DELETE_BACKGROUND};
$VUE_APP_CARD_BTN_DELETE:${process.env.VUE_APP_CARD_BTN_DELETE};
$VUE_APP_CARD_BTN_HOVER:${process.env.VUE_APP_CARD_BTN_HOVER};
`
}
}
}
}
Code i want but compiler send error:
module.exports = {
css: {
loaderOptions: {
scss: {
prependData: {
'$VUE_APP_FOOTER_PRIMARY_COLOR': process.env.VUE_APP_FOOTER_PRIMARY_COLOR,
'$VUE_APP_NAV_COLOR': process.env.VUE_APP_NAV_COLOR,
'$VUE_APP_CARD_BANDAGE_COLOR': process.env.VUE_APP_CARD_BANDAGE_COLOR,
'$VUE_APP_TOP_HEADER_COLOR': process.env.VUE_APP_TOP_HEADER_COLOR,
'$VUE_APP_TOP_HEADER_FONT_COLOR': process.env.VUE_APP_TOP_HEADER_FONT_COLOR,
'$VUE_APP_NAV_PRIMARY_COLOR': process.env.VUE_APP_NAV_PRIMARY_COLOR,
'$VUE_APP_DARK_BTN': process.env.VUE_APP_DARK_BTN,
'$VUE_APP_DARK_BTN_COLOR': process.env.VUE_APP_DARK_BTN_COLOR,
'$VUE_APP_BRAND_BTN': process.env.VUE_APP_BRAND_BTN,
'$VUE_APP_BRAND_BTN_COLOR': process.env.VUE_APP_BRAND_BTN_COLOR,
'$VUE_APP_ERROR_MESSAGE_COLOR': process.env.VUE_APP_ERROR_MESSAGE_COLOR,
'$VUE_APP_FONT_FAMILY': process.env.VUE_APP_FONT_FAMILY,
'$VUE_APP_FONT_HEADER': process.env.VUE_APP_FONT_HEADER,
'$VUE_APP_BACKGROUND': process.env.VUE_APP_BACKGROUND,
'$VUE_APP_BACKGROUND_IMAGE': process.env.VUE_APP_BACKGROUND_IMAGE,
'$VUE_APP_CHOOSE_CATEGORY': process.env.VUE_APP_CHOOSE_CATEGORY,
'$VUE_APP_PLACEHOLDER': process.env.VUE_APP_PLACEHOLDER,
'$VUE_APP_BTN': process.env.VUE_APP_BTN,
'$VUE_APP_FOOTER_LINK': process.env.VUE_APP_FOOTER_LINK,
'$VUE_APP_MULTIPLE_TAG': process.env.VUE_APP_MULTIPLE_TAG,
'$VUE_APP_CART_BTN_BACKGROUND': process.env.VUE_APP_CART_BTN_BACKGROUND,
'$VUE_APP_CART_BTN': process.env.VUE_APP_CART_BTN,
'$VUE_APP_ORDER_INFO_CARD': process.env.VUE_APP_ORDER_INFO_CARD,
'$VUE_APP_CARD_BTN_DELETE_BACKGROUND': process.env.VUE_APP_CARD_BTN_DELETE_BACKGROUND,
'$VUE_APP_CARD_BTN_DELETE': process.env.VUE_APP_CARD_BTN_DELETE,
'$VUE_APP_CARD_BTN_HOVER': process.env.VUE_APP_CARD_BTN_HOVER
}
}
}
}
}
Error:
Npm issue
The rule that I'm looking should show error in this case:
import {MY_CONSTANT1, MY_CONSTANT2, MY_CONSTANT3}
And considered as fine in this case:
import {
MY_CONSTANT1,
MY_CONSTANT2,
MY_CONSTANT3
}
Is there such eslint rule?
I was looking for such a rule for both import and export declaration.
As a result I've made a plugin with autofix.
So plugin transforms the code
import { k1, k2 } from 'something'
into
import {
k1,
k2
} from 'something'
and code
export { name1, name2, nameN }
into
export {
name1,
name2,
nameN
}
Edit:
Anton Antonov made a plugin that enforces this rule better than object-curly-newline can: https://stackoverflow.com/a/60477269/6179417
Old answer
Add the object-curly-newline rule to your .eslintrc.json, where at least ImportDeclaration is set to always (the other settings have no effect for enforcing newlines in import declarations).
Example:
"object-curly-newline": ["error", {
"ObjectExpression": "always",
"ObjectPattern": { "multiline": true },
"ImportDeclaration": "always",
"ExportDeclaration": { "multiline": true, "minProperties": 3 }
}]
This pattern will now result in an error:
While this is valid:
However, there is a catch - this rule only requires newlines after the opening brace and before the closing brace, so you can still double up on imports as long as they have newlines in between the braces:
Update on Anton Antonov answer for eslint 8
Because Anton Antonovs repository has been archived and gives meta.fixable error with eslint 8. I Recommend to use ruudandriessen fork of the project .
How to use fork:
Install fork
npm install eslint-plugin-modules-newlines --save-dev
Change all references inside eslint config file of modules-newline -> modules-newlines
Error:
ESLint: Fixable rules must set the `meta.fixable` property to "code" or "whitespace".
Occurred while linting ... Rule: "modules-newline/import-declaration-newline".
Please see the 'ESLint' output channel for details.
I was looking for the solution and unfortunately have only found your question. I have decided to learn a bit about how eslint works and how to write your own plugins and created mine. If you know the parsed the AST node structure it is really easy to work with. Here is the plugin's main file. Autofix is more tricky though so I do not include it as it biased towards my formatting standards.
module.exports = {
rules: {
'single-import-per-line': {
create (context) {
return {
ImportDeclaration(node) {
if (node.specifiers.length < 2) {
return;
}
let previousImport = node.specifiers[0];
for (let i = 1; i < node.specifiers.length; i++) {
const currentImport = node.specifiers[i];
// Omit the first condition if you want to put default imports on a new line as well
if (previousImport.type !== 'ImportDefaultSpecifier'
&& currentImport.loc.start.line === previousImport.loc.end.line
) {
context.report({ node, message: 'Your message' });
return;
}
previousImport = currentImport;
}
},
};
},
},
},
};
you can try this
"semicolon": [true, "always"]
Using the same code (see fiddle) and 3 different export URLs I get different export results. The issue is that the left side of the chart is clipping off the category titles but only if the export is JPG, PNG, or PDF - the SVG export is fine.
Current output for JPG, PNG, or PDF:
This the expected output for those types and what SVG does export:
I have set up a jsFiddle - click on the image types at the top to see the issues while changing the exporting.url value.
This is the export code:
window.chartExportLoc = function(chartid, exportType, graphHeader, graphFooter, marginSize) {
var chartToExport = $('#' + chartid).highcharts(),
sourceSpacingBottom = chartToExport.options.chart.spacingBottom;
if (!marginSize) {
marginSize = 15; //HighCharts default
}
chartToExport.exportChart({
type: exportType,
scale: 1,
filename: chartid
}, {
title: {
text: unescape(encodeURI(graphHeader)),
margin: marginSize
},
subtitle: {
y: 10,
text: unescape(encodeURI(graphFooter))
},
chart: {
shadow: false,
width: 800,
spacingBottom: sourceSpacingBottom - 20
}
});
return false;
}
We are running the highchart-export-server nodejs module and it is producing the clipped chart. If we change the exporting.url to use our existsing Java-based exporting application we get the correct/expected output. If we then change to use the export server hosted by highcharts (export.highcharts.com) it also produces the expected output.
I did file a bug on github for this issue but no responses from highcharts and hoping someone here can assist. This is preventing us from moving forward with the nodejs implementation and finally sunsetting the Java-based export app.
Follow the guide at https://vuetifyjs.com/en/style/theme, I changed theme with the code below, and it worked on vuetifyjs version 0.13.0.
I updated recently to vuetifyjs 1.0.5, same code, font still works, but all colors are not working after the update.
I suspect this is due to the change in //node_modules/vuetify/src/stylus/main.styl and //node_modules/vuetify/src/stylus/theme.styl because the variable $theme is defined in v0.13.0 but not v1.0.0?
Appreciate on hint and explanations. Thanks.
# File: //src/stylus/main.styl
/** Stylus Styles */
#import '../../node_modules/vuetify/src/stylus/settings/_colors'
$theme := {
primary: $deep-purple.darken-1
accent: $deep-purple.accent-2
secondary: $deep-orange.darken-1
info: $blue.darken-2
warning: $amber.darken-2
error: $red.darken-2
success: $green.darken-2
}
$body-font-family := 'Share Tech Mono'
#import '../../node_modules/vuetify/src/stylus/main'
Update:
Based on the suggestion of Traxo, modify //src/main.js with code below makes it work.
# Vue.use(Vuetify)
Vue.use(Vuetify, {
theme: {
primary: '#5e35b1', // $deep-purple.darken-1
accent: '#7c4dff', // $deep-purple.accent-2
secondary: '#f4511e', // $deep-orange.darken-1
info: '#1976d2', // $blue.darken-2
warning: '#ffa000', // $amber.darken-2
error: '#d32f2f', // $red.darken-2
success: '#388e3c' // $green.darken-2
}
})
Deprecated since v0.17:
Stylus declared themes are no longer needed (and will not work).
Theme colors are now defined in the Vue.use statement instead of
stylus, docs
Since v0.17 you have to pass a theme property to the Vue.use function
Vue.use(Vuetify, {
theme: {
primary: '#3f51b5',
secondary: '#b0bec5',
accent: '#8c9eff',
error: '#b71c1c'
}
})
(note that values like "red" or "green" will not work, you need hex values)