Theme switching in a vue based project with sass - vue.js

I have a simple sass variables declarations as below
$theme-primary-dom: #181818ff
$theme-primary-sub: #29292Bff
$theme-secondary-dom: #FAFAFAff
$theme-secondary-sub: #C4C4C4ff
$theme-primary-sub-transparent: #29292B22
This is what I need for dark theme that is a default theme. BUt I want to add a light theme as well. In my brain it is very simple.
if .wrapper.darktheme{
$theme-primary-dom: #181818ff
$theme-primary-sub: #29292Bff
$theme-secondary-dom: #FAFAFAff
$theme-secondary-sub: #C4C4C4ff
$theme-primary-sub-transparent: #29292B22
} else {
$theme-primary-dom: #FAFAFAff
$theme-primary-sub: #C4C4C4ff
$theme-secondary-dom: #181818ff
$theme-secondary-sub: #29292Bff
$theme-primary-sub-transparent: #C4C4C422
}
Now I have no idea how to do this in SASS.
Also, I have
<button class="theme__switch theme__switch--light">theme is light</button>
in header component
and,
<div class="wrapper darktheme"></div>
in main app.vue. which increase complecations as the trigger button and the trigger area are in different components.
I can easily get this using jquery of course, But since I am using vue.cli, adding jquery code didn't felt right. I have been searching all over stackoverflow and google for past 3 days but I haven't found a relative solution yet.

Related

How to use vuetify color props with custom theme variations

I'm using vuetify (2.5.8) with our own custom theme colors. We've defined our own color names via String, or Object if we need more control over which variations are generated and to have fewer css variables.
However, I haven't been able to get these variations to work with the color prop of vuetify elements, specifically v-expansion-panel-header.
In the docs I saw example use of color=”purple darken-2" and color="success darken-2", separating the theme color and its variation by a space. This works, when a color in my theme is defined as a string and its variations are generated by vuetify as (darken|lighten)-{n}.
But when I define my own variations, this doesn't work anymore. For example: if I define the color success: { base: '#1CC234', muted: '#2AAC9B', }' in my theme, I can't use color="success muted", it will always display the base color. This is also true when I try to name my variations the way vuetify describes them, for example success: { base: '#1CC234', 'darken-2': '#2AAC9B', }'. In this case, color="success darken-2" no longer works.
I've tried working around it by naming my variations 'darken-2' and the like, as well as nested syntax (success.muted) as the name of the generated color variable (success-muted), but to no avail. Does anyone have a way to pass these variations via the color prop, without having to use a v-deep selector and restyling the entire component everywhere I use it? Or should I use a computed to reach into this.$vuetify.theme and see if I can get the hexcode that way?
Thanks in advance.
color="success muted"
Only base and lighten/darken variations are used.
You can work around this by defining it as { success: '#1CC234', 'success-muted': '#2AAC9B' }
In this case, color="success darken-2" no longer works.
The keys in the theme configuration should be in camelCase: darken2

How to interpolate with variables in pug?

I have a pug view
section#about.about
.container
.about__inner
.about__content
h3.about__title About me
h2.about__bigtitle Who am I
.about__text !{about}
a.btn(href="#" data-modal="#modal_hire_me") Hire me
button.btn(type="button" data-modal="#modal_resume") My resume
In express server I render it with "about", "works" and "reviewsAmount" variables.
The "about" variable value is
const about = `
<p>
I have #{works.length} works and #{reviewsAmount} reviews.
</p>
`;
But in page it renders like "I have #{works.length} works and #{reviewsAmount} reviews.". Variable values do not interpolate in paragraph tag. So, how to do that?
You are mixing up pug interpolation and JavaScript template strings. When the code is in your node/express route (and not in the template) you need to use JavaScript template strings.
If you use the ${} syntax this will fix it.
const about = `
<p>
I have ${works.length} works and ${reviewsAmount} reviews.
</p>
`;
With that said, I'd recommend against doing this and leaving all of your HTML in pug and not moving it into the node/express code. This will make your web pages more difficult to debug when something goes wrong, and also require more effort to maintain longer term.
Just pass those variables on to Pug and do the interpolation there:
section#about.about
.container
.about__inner
.about__content
h3.about__title About me
h2.about__bigtitle Who am I
.about__text
p I have #{works.length} works and #{reviewsAmount} reviews.
a.btn(href="#" data-modal="#modal_hire_me") Hire me
button.btn(type="button" data-modal="#modal_resume") My resume

Nuxt.js ignore (Is there any way to ignore original tags)

I am creating a web page using Nuxt.js. (Static file built with the
nuxt generate command)
As a requirement,I need to write the original tag in the static file
that I built. The original tag is for displaying the data obtained
on the server side. Writing an original tag in a vue file naturally
gives an error.
For example, in the image below,
Is there a way to ignore original tags in the vue file?
vue file(example)
// disabled-next-line
{{^ server-side-display-data}}
<button> button </ button>
// disabled-next-line
{{/ server-side-display-data}}
Build file(example)
{{^ server-side-display-data}}
<button> button </ button>
{{/ server-side-display-data}}
Tried
It seemed possible to ignore certain "files" like below, but I haven't found a way to ignore certain "tags"
https://ja.nuxtjs.org/api/configuration-ignore/
Please help
I had the same issue and was looking for a solution... you can try with this solution i've used.
in your nuxt.config.js
...
vue: {
config: {
ignoredElements: [string or regexp],
},
},
...
see this documentation for more details

Conditionally set main color in Vue

I wrote a reusable app in Vue and I compiled it as a library. I set the global variable $brand-color in SCSS file which is a main color of the app (buttons, borders, font colors). I use this variable in other SCSS component files.
I've put my app to my client's website and everything is working fine. Right now I have another client who is willing to use my app. BUT... new client wants to have my app in different $brand-color than my old one. What would be the best way to approach this problem?
One thing which comes to my mind is to set store variable with value of $brand-color which depends on location.host and bind styles of all "branded" elements.
switch (location.host) {
case 'client1.com':
context.commit('setMainColor', '#ff0000');
...
case 'client2.com':
context.commit('setMainColor', '#16c100');
...
}
But this will be very painful. I would need to apply a lot of changes in all my components. Is there any better solution that style-binding all components?
By the way, I can't use CSS variables because code needs to be IE friendly.
You can have 2 files, each file definne scss variable for different customer:
customer1_variables.scss
$brand-color: green
customer2_variables.scss
$brand-color: red
And you can import it in javascript file
main.js
switch (location.host) {
case 'client1.com':
import './customer1_variables.scss'
...
case 'client2.com':
import './customer2_variables.scss'
...
}
Another solution is using vue-style-component. You can check this article for more detail
So finally I set store value depending on my client and prepared set of SCSS classess specified for each client, i.e.:
.btn-client1 {
background: red;
}
.btn-client2 {
background: blue;
}
...
and I binded classes for specific elements:
:class="`btn-${client}`"`

Ng-grid with external data and TypeScript: compile error "Cannot set property 'gridDim' of undefined"

Update #1: after the fix I commented about, now my app starts but the grid is not rendered except for its bounding box and filter button and popup. Yet, I get no error from the console, and as far as I can arrive with the debugger, I can see that data got from the server are OK. If I use Batarang, I can see the scope corresponding to my model, correctly filled with items. I updated the downloadable repro solution accordingly. Could anyone explain why ng-grid is not updating here?
I'm starting to play with ng-grid and TypeScript and I'm finding issues as soon as my test app starts up. See the bottom of this post for a link to a full test solution. Surely I have made tons of errors even in these few files, but I'd like to have something to start with and learn more step by step.
The MVC app has two client-side applications:
app.js for the default view (Home/Index). No typescript here, and the whole code is self-contained in this single file. The code is derived from the paging example in the ng-grid documentation and tries to stay as simplest as possible.
MyApp.js for the more realistic sample in another view (Home/Model). This sample uses services, models and controllers and its JS code is compiled from TypeScript. To keep things simple, I'm just storing these components under Scripts/App, in folders for Controllers, Models and Services, and each file contains just a single class or interface. The generated JS files are manually included in the view.
app.js works, except that it has issues with filtering. I posted about these here:
Server-side filtering with ng-grid: binding issue?
MyApp.js has startup issues with ng-grid. As soon as the app starts, a TypeError is thrown in the grid binding:
TypeError: Cannot set property 'gridDim' of undefined
at ngGridDirectives.directive.ngGridDirective.compile.pre (http://localhost:55203/Scripts/ng-grid-2.0.7.js:2708:37)
at nodeLinkFn (http://localhost:55203/Scripts/angular.js:4392:13)
at compositeLinkFn (http://localhost:55203/Scripts/angular.js:4015:15)
at nodeLinkFn (http://localhost:55203/Scripts/angular.js:4400:24)
at compositeLinkFn (http://localhost:55203/Scripts/angular.js:4015:15)
at publicLinkFn (http://localhost:55203/Scripts/angular.js:3920:30)
at resumeBootstrapInternal (http://localhost:55203/Scripts/angular.js:983:27)
at Object.$get.Scope.$eval (http://localhost:55203/Scripts/angular.js:8057:28)
at Object.$get.Scope.$apply (http://localhost:55203/Scripts/angular.js:8137:23)
at resumeBootstrapInternal (http://localhost:55203/Scripts/angular.js:981:15) <div ng-grid="gridOptions" style="height: 400px" class="ng-scope"> angular.js:5754
The only similar issue I found by googling is https://github.com/angular-ui/ng-grid/issues/60, but it does not seem to be related to my case as there the grid options were setup too late.
The server side just has an API RESTful controller returning server-paged, sorted and filtered items.
You can find the full repro solution here (just save, unzip and open; all the dependencies come from NuGet); see the readme.txt file for more information:
http://sdrv.ms/167gv0F
Just start the app and click MODEL in the upper right corner to run the TypeScript app throwing the error. The whole app is composed of 1 controller, 1 service and 1 model.
For starters like me, it would be nice to have a simple working example like this one. Could anyone help?
This error means gridOptions has not yet been defined by the time that Angular attempts to parse ng-grid="yourArray", where yourArray is the same array supplied to gridOptions. I had the same problem after refactoring a previously working ng-grid.
So gridOptions must be defined before the element which has ng-grid="yourArray" attribute applied to it (rather than within that element's own controller).
I resolved this by defining gridOptions in an outer element somewhere (on global/app scope, for instance).
P.S. Maybe there is a better way, but this has worked for me.
Where you are adding data to your grid?
If you are writing $scope.myGrid={data:"someObj"}; in a success call then it won't work.
See the below reason:(which is listed in https://github.com/angular-ui/ng-grid/issues/60)
You can't define the grid options in the success call. You need to define
them on the scope in your controller and then set the data or column
definitions, etc... from the success call.
What you have to do?, First is to see how this made ​​your project and revizar if your queries or data access, the beams through a service, if so this I must add the file that manages routes app, the client side.
remain so.
'use strict';
angular.module('iseApp', [
'ngCookies',
'ngResource',
'ngSanitize',
'ngRoute',
**'ngGrid',**
'campaignServices',
'dialinglistServices',
'itemServices'
])
.config(function ($routeProvider, $locationProvider, $httpProvider) {
$routeProvider
As you are adding your ng-grid in a directive, you have to make sure the grid options are loaded before it tries to parse your html.
You could set a boolean in your link function :
scope.isDirectiveLoaded=true;
And then, in your template, use a ng-if :
<div ng-if="isDirectiveLoaded">
<div ng-grid="myGrid"/>
</div>
I got to the same issue, empty grid was rendered.
The way I got to it in the end was to setup my this.gridOptions in the constructor of the controller, within the component. In the options everything is referenced with $ctrl like this. So the data references $ctrl.gridData. gridData is specified as a property in my component controller. $ctrl is not defined as a property.
This was done in the constructor before the data was loaded. this.gridData was defined after in the constructor and then populated later in another function. The options were defined first, I think this is important from some things I read.
For the event hooks pass null instead of $scope.
this.gridOptions = {
enableGridMenu: true,
minRowsToShow: 25,
rowHeight: 36,
enableRowHashing: true,
data: '$ctrl.gridData',
rowTemplate: this.$rootScope.blockedRowTemplate,
onRegisterApi: ($ctrl) => {
this.gridApi = $ctrl;
this.gridApi.colMovable.on.columnPositionChanged(null, (colDef, originalPosition, newPosition) => {
this.saveState();
});
this.gridApi.colResizable.on.columnSizeChanged(null, (colDef, deltaChange) => {
this.saveState();
});
this.gridApi.core.on.columnVisibilityChanged(null, (column) => {
this.saveState();
});
this.gridApi.core.on.sortChanged(null, (grid, sortColumns) => {
this.saveState();
});
this.gridApi.core.on.filterChanged(null, (grid, sortColumns) => {
this.saveState();
});
}
};
In the row template I was referencing functions defined in my component. Before conversion to a component I referenced functions like this:
ng-click="grid.appScope.jumpToExport(row.entity);"
After conversion to the component I needed to add the $ctrl before the function name like this
ng-click="grid.appScope.$ctrl.jumpToExport(row.entity);"
And this is how the component is referenced in the html
<div ui-grid="$ctrl.gridOptions" ng-if="$ctrl.gridData.length != undefined && $ctrl.gridData.length > 0" class="data-grid" ui-grid-save-state ui-grid-resize-columns ui-grid-move-columns></div>