├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── INLINING.md ├── LICENSE.md ├── README.md ├── build.js ├── karma.conf.js ├── license-banner.txt ├── package-lock.json ├── package.json ├── public_api.ts ├── rollup.config.js ├── rollup.es.config.js ├── spec.bundle.js ├── src ├── css-vars-module.ts └── css-vars │ ├── css-vars.module.ts │ ├── directive │ └── css-vars.directive.ts │ ├── service │ └── css-vars.service.ts │ └── types.ts ├── tests └── services │ ├── css-vars.directive.spec.ts │ ├── css-vars.module.spec.ts │ └── css-vars.service.spec.ts ├── tsconfig-build.json ├── tsconfig.json └── tslint.json /.gitignore: -------------------------------------------------------------------------------- 1 | $ cat .gitignore 2 | .idea 3 | /node_modules 4 | /dist 5 | /documentation 6 | /coverage 7 | 8 | *.log 9 | *.tgz 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | dist: trusty 3 | addons: 4 | apt: 5 | sources: 6 | - google-chrome 7 | packages: 8 | - google-chrome-stable 9 | language: node_js 10 | node_js: 11 | - "8" 12 | before_install: 13 | - npm i npm@^4 -g 14 | install: 15 | - npm install 16 | script: 17 | - npm test 18 | - npm run build 19 | before_script: 20 | - export DISPLAY=:99.0 21 | - sh -e /etc/init.d/xvfb start 22 | - sleep 3 23 | notifications: 24 | email: false 25 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## Ngx CSS Variables Changelog -------------------------------------------------------------------------------- /INLINING.md: -------------------------------------------------------------------------------- 1 | ## Inlining of templates and stylesheets 2 | 3 | To use external templates & stylesheets, you can: 4 | - process your `scss` files (if you have them) 5 | - use an external library (or a custom function) to inline the `html/css` files 6 | 7 | Following are the steps to adapt the library to the use of external templates and stylesheets (thanks to Paul Ryan @paullryan for his suggestion): 8 | 9 | - Install the following packages: 10 | 11 | ``` 12 | npm i node-sass --save-dev 13 | ``` 14 | ``` 15 | npm i angular2-inline-template-style --save-dev 16 | ``` 17 | > Note that you could use different packages. 18 | 19 | - `build.js` file: 20 | 21 | Add the `BUILD_DIR` constant: 22 | ``` 23 | const BUILD_DIR = `build`; 24 | ``` 25 | Add to the start: 26 | ``` 27 | shell.rm(`-Rf`, `${BUILD_DIR}/**`); 28 | shell.mkdir(`-p`, `./${BUILD_DIR}`); 29 | ``` 30 | Add before the _Aot Compilation_: 31 | ``` 32 | /* Process scss files */ 33 | shell.echo(`Process scss files`); 34 | shell.cp(`-Rf`, [`src`, `*.ts`, `*.json`], `${BUILD_DIR}`); 35 | shell.exec(`node-sass -r ${BUILD_DIR} -o ${BUILD_DIR}`); 36 | shell.rm(`-Rf`, `${BUILD_DIR}/**/*.scss`); 37 | shell.ls(`${BUILD_DIR}/**/*.css`).forEach(function (file) { 38 | shell.mv(file, file.replace('.css', '.scss')); 39 | }); 40 | 41 | /* Inline templates & stylesheets */ 42 | shell.echo(`Inline templates & stylesheets`); 43 | shell.exec(`ng2-inline -b ${BUILD_DIR} --silent --relative --compress -o . \"${BUILD_DIR}/**/*.ts\"`); 44 | ``` 45 | > Note that you could skip the processing of `scss` files if you don't have them. 46 | 47 | Then change all `ngc -p tsconfig-build.json` with `ngc -p ${BUILD_DIR}/tsconfig-build.json` and finally remove the `build` folder: 48 | ``` 49 | shell.rm(`-Rf`, `${BUILD_DIR}`); 50 | ``` 51 | 52 | - `tsconfig-build.js` file: 53 | 54 | Change: 55 | 56 | - `"node_modules/@angular/*"` => `"../node_modules/@angular/*"` 57 | - `"dist"` => `"../dist"` 58 | - `"node_modules/zone.js/dist/zone.js.d.ts"` => `"../node_modules/zone.js/dist/zone.js.d.ts"` 59 | 60 | > After bundling, make sure that your bundles & `metadata.json` contain the inline templates & styles. 61 | 62 | > If you want test your components that use external templates & stylesheets, you must also update the _webpack_ configuration in _karma.conf.js_ file. 63 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Liron Boberman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [](https://github.com/lironbob/ngx-css-variables/blob/master/LICENSE.md) 2 | 3 | # ngx-css-variables 4 | This is the repository for ngx-css-variables. 5 | 6 | Ngx-css-variables is a css variables module for Angular 2/4/5 7 | 8 | ## Installation 9 | Install ngx-css-variables via NPM, using the command below. 10 | 11 | ### NPM 12 | ```shell 13 | npm install --save ngx-css-variables 14 | ``` 15 | 16 | ## Getting started 17 | Import the `CssVarsModule` in your root application module: 18 | 19 | ```typescript 20 | import { BrowserModule } from '@angular/platform-browser'; 21 | import { NgModule } from '@angular/core'; 22 | import { CoreModule } from './core/core.module'; 23 | import { CssVarsModule } from 'ngx-css-variables'; 24 | 25 | @NgModule({ 26 | //... 27 | imports: [ 28 | //... 29 | CssVarsModule.forRoot() 30 | ], 31 | //... 32 | }) 33 | export class AppModule { } 34 | ``` 35 | 36 | ## Use css-vars as a directive 37 | 38 | ```typescript 39 | import { Component, OnInit } from '@angular/core'; 40 | import { CssVars } from 'ngx-css-variables'; 41 | 42 | @Component({ 43 | template: `
` 44 | //... 45 | }) 46 | export class CustomComponent { 47 | //... 48 | public customCssVars: CssVars; 49 | 50 | constructor() { 51 | this.customCssVars = { 52 | '--font-size': '12px', 53 | '--bg-color': '#000', 54 | '--text-color': '#eee' 55 | }; 56 | } 57 | } 58 | ``` 59 | 60 | ## Set global css variables with css-vars service 61 | 62 | ```typescript 63 | import { Component, OnInit } from '@angular/core'; 64 | import { CssVarsService } from 'ngx-css-variables'; 65 | 66 | @Component({ 67 | //... 68 | }) 69 | export class AppComponent { 70 | //... 71 | 72 | constructor(cssService: CssVarsService) { 73 | cssService.setVariables({ 74 | '--font-size': '12px', 75 | '--bg-color': '#000', 76 | '--text-color': '#eee' 77 | }); 78 | } 79 | } 80 | ``` 81 | 82 | ## Directive input parameters 83 | The ngx-css-variables input parameters are displayed below. 84 | 85 | | Input | Required | Details | 86 | | ---- | ---- | ---- | 87 | | css-vars | Required | CssVars type - css key value object | 88 | 89 | ## Contributing 90 | 91 | * Before adding any new feature or a fix make sure to open an issue first! 92 | 93 | Make sure you have `angular-cli` & `karma` installed globally. 94 | 95 | ```bash 96 | $ npm install -g angular-cli karma 97 | ``` 98 | 99 | Clone the project, and install dependencies. 100 | 101 | ```bash 102 | $ git clone https://github.com/lironbob/ngx-css-variables.git 103 | $ npm install 104 | ``` 105 | 106 | Create a new branch 107 | 108 | ```bash 109 | $ git checkout -b feat/someFeature 110 | ``` 111 | 112 | Add tests & make sure everything is running properly 113 | ```bash 114 | $ npm test 115 | ``` 116 | 117 | Commit & push, and make a pull request! 118 | -------------------------------------------------------------------------------- /build.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const shell = require('shelljs'); 4 | const chalk = require('chalk'); 5 | 6 | const PACKAGE = `ngx-css-variables`; 7 | const NPM_DIR = `dist`; 8 | const ESM2015_DIR = `${NPM_DIR}/esm2015`; 9 | const ESM5_DIR = `${NPM_DIR}/esm5`; 10 | const BUNDLES_DIR = `${NPM_DIR}/bundles`; 11 | const OUT_DIR_ESM5 = `${NPM_DIR}/package/esm5`; 12 | 13 | shell.echo(`Start building...`); 14 | 15 | shell.rm(`-Rf`, `${NPM_DIR}/*`); 16 | shell.mkdir(`-p`, `./${ESM2015_DIR}`); 17 | shell.mkdir(`-p`, `./${ESM5_DIR}`); 18 | shell.mkdir(`-p`, `./${BUNDLES_DIR}`); 19 | 20 | /* TSLint with Codelyzer */ 21 | // https://github.com/palantir/tslint/blob/master/src/configs/recommended.ts 22 | // https://github.com/mgechev/codelyzer 23 | shell.echo(`Start TSLint`); 24 | shell.exec(`tslint -p tslint.json -t stylish src/**/*.ts`); 25 | shell.echo(chalk.green(`TSLint completed`)); 26 | 27 | /* AoT compilation */ 28 | shell.echo(`Start AoT compilation`); 29 | if (shell.exec(`ngc -p tsconfig-build.json`).code !== 0) { 30 | shell.echo(chalk.red(`Error: AoT compilation failed`)); 31 | shell.exit(1); 32 | } 33 | shell.echo(chalk.green(`AoT compilation completed`)); 34 | 35 | /* BUNDLING PACKAGE */ 36 | shell.echo(`Start bundling`); 37 | shell.echo(`Rollup package`); 38 | if (shell.exec(`rollup -c rollup.es.config.js -i ${NPM_DIR}/${PACKAGE}.js -o ${ESM2015_DIR}/${PACKAGE}.js`).code !== 0) { 39 | shell.echo(chalk.red(`Error: Rollup package failed`)); 40 | shell.exit(1); 41 | } 42 | 43 | shell.echo(`Produce ESM5 version`); 44 | shell.exec(`ngc -p tsconfig-build.json --target es5 -d false --outDir ${OUT_DIR_ESM5} --importHelpers true --sourceMap`); 45 | if (shell.exec(`rollup -c rollup.es.config.js -i ${OUT_DIR_ESM5}/${PACKAGE}.js -o ${ESM5_DIR}/${PACKAGE}.js`).code !== 0) { 46 | shell.echo(chalk.red(`Error: ESM5 version failed`)); 47 | shell.exit(1); 48 | } 49 | 50 | shell.echo(`Run Rollup conversion on package`); 51 | if (shell.exec(`rollup -c rollup.config.js -i ${ESM5_DIR}/${PACKAGE}.js -o ${BUNDLES_DIR}/${PACKAGE}.umd.js`).code !== 0) { 52 | shell.echo(chalk.red(`Error: Rollup conversion failed`)); 53 | shell.exit(1); 54 | } 55 | 56 | shell.echo(`Minifying`); 57 | shell.cd(`${BUNDLES_DIR}`); 58 | shell.exec(`uglifyjs ${PACKAGE}.umd.js -c --comments -o ${PACKAGE}.umd.min.js --source-map "filename='${PACKAGE}.umd.min.js.map', includeSources"`); 59 | shell.cd(`..`); 60 | shell.cd(`..`); 61 | 62 | shell.echo(chalk.green(`Bundling completed`)); 63 | 64 | shell.rm(`-Rf`, `${NPM_DIR}/package`); 65 | shell.rm(`-Rf`, `${NPM_DIR}/node_modules`); 66 | shell.rm(`-Rf`, `${NPM_DIR}/*.js`); 67 | shell.rm(`-Rf`, `${NPM_DIR}/*.js.map`); 68 | shell.rm(`-Rf`, `${NPM_DIR}/src/**/*.js`); 69 | shell.rm(`-Rf`, `${NPM_DIR}/src/**/*.js.map`); 70 | 71 | shell.cp(`-Rf`, [`package.json`, `LICENSE`, `README.md`], `${NPM_DIR}`); 72 | 73 | shell.sed('-i', `"private": true,`, `"private": false,`, `./${NPM_DIR}/package.json`); 74 | 75 | shell.echo(chalk.green(`End building`)); 76 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration for Unit testing 2 | 3 | const path = require('path'); 4 | 5 | module.exports = function (config) { 6 | 7 | const configuration = { 8 | 9 | // base path that will be used to resolve all patterns (eg. files, exclude) 10 | basePath: '', 11 | 12 | // frameworks to use 13 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter 14 | frameworks: ['jasmine'], 15 | 16 | plugins: [ 17 | require('karma-jasmine'), 18 | require('karma-chrome-launcher'), 19 | require('karma-webpack'), 20 | require('karma-sourcemap-loader'), 21 | require('karma-spec-reporter'), 22 | require('karma-coverage-istanbul-reporter'), 23 | require("istanbul-instrumenter-loader") 24 | ], 25 | 26 | // list of files / patterns to load in the browser 27 | files: [ 28 | { pattern: 'spec.bundle.js', watched: false } 29 | ], 30 | 31 | // list of files to exclude 32 | exclude: [ 33 | ], 34 | 35 | // preprocess matching files before serving them to the browser 36 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 37 | preprocessors: { 38 | 'spec.bundle.js': ['webpack', 'sourcemap'] 39 | }, 40 | 41 | // webpack 42 | webpack: { 43 | resolve: { 44 | extensions: ['.ts', '.js'] 45 | }, 46 | module: { 47 | rules: [ 48 | { 49 | test: /\.ts/, 50 | use: [ 51 | { loader: 'ts-loader' }, 52 | { loader: 'source-map-loader' } 53 | ], 54 | exclude: /node_modules/ 55 | }, 56 | { 57 | enforce: 'post', 58 | test: /\.ts/, 59 | use: [ 60 | { 61 | loader: 'istanbul-instrumenter-loader', 62 | options: { esModules: true } 63 | } 64 | ], 65 | exclude: [ 66 | /\.spec.ts/, 67 | /node_modules/ 68 | ] 69 | } 70 | ], 71 | exprContextCritical: false 72 | }, 73 | devtool: 'inline-source-map', 74 | performance: { hints: false } 75 | }, 76 | 77 | webpackServer: { 78 | noInfo: true 79 | }, 80 | 81 | 82 | // test results reporter to use 83 | // possible values: 'dots', 'progress' 84 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter 85 | reporters: ['spec', 'coverage-istanbul'], 86 | 87 | coverageIstanbulReporter: { 88 | reports: ['html', 'lcovonly'], 89 | dir: path.join(__dirname, 'coverage'), 90 | fixWebpackSourcePaths: true 91 | }, 92 | 93 | 94 | // web server port 95 | port: 9876, 96 | 97 | 98 | // enable / disable colors in the output (reporters and logs) 99 | colors: true, 100 | 101 | 102 | // level of logging 103 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 104 | logLevel: config.LOG_INFO, 105 | 106 | 107 | // enable / disable watching file and executing tests whenever any file changes 108 | autoWatch: true, 109 | 110 | 111 | // start these browsers 112 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 113 | browsers: ['Chrome'], 114 | 115 | 116 | // Continuous Integration mode 117 | // if true, Karma captures browsers, runs the tests and exits 118 | singleRun: true 119 | 120 | }; 121 | 122 | config.set(configuration); 123 | 124 | } 125 | -------------------------------------------------------------------------------- /license-banner.txt: -------------------------------------------------------------------------------- 1 | /** 2 | * @license ngx-css-variables 3 | * MIT license 4 | */ 5 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ngx-css-variables", 3 | "private": true, 4 | "version": "1.0.1", 5 | "description": "Css variables module for Angular 2/4/5", 6 | "main": "./bundles/ngx-css-variables.umd.js", 7 | "module": "./esm5/ngx-css-variables.js", 8 | "es2015": "./esm2015/ngx-css-variables.js", 9 | "scripts": { 10 | "build": "node build.js", 11 | "test": "karma start", 12 | "test:watch": "karma start karma.conf.js --single-run false", 13 | "pack:lib": "npm run build && npm pack ./dist", 14 | "publish:lib": "npm run build && npm publish ./dist", 15 | "publish:lib:next": "npm run build && npm publish --tag next ./dist", 16 | "compodoc": "compodoc -p tsconfig.json", 17 | "compodoc:serve": "compodoc -s" 18 | }, 19 | "typings": "./ngx-css-variables.d.ts", 20 | "author": "Liron Boberman", 21 | "repository": { 22 | "type": "git", 23 | "url": "https://github.com/lironbob/ngx-css-variables.git" 24 | }, 25 | "bugs": { 26 | "url": "https://github.com/lironbob/ngx-css-variables/issues" 27 | }, 28 | "homepage": "https://github.com/lironbob/ngx-css-variables", 29 | "keywords": [ 30 | "angular", 31 | "angular 2", 32 | "angular 2+", 33 | "angular 4", 34 | "angular 5", 35 | "ngx", 36 | "javascript", 37 | "typescript", 38 | "css", 39 | "css3", 40 | "css variables" 41 | ], 42 | "license": "MIT", 43 | "dependencies": { 44 | "tslib": "^1.7.1" 45 | }, 46 | "peerDependencies": { 47 | "@angular/common": ">= 2.4.0", 48 | "@angular/core": ">= 2.4.0" 49 | }, 50 | "devDependencies": { 51 | "@angular/animations": "5.0.0", 52 | "@angular/common": "5.0.0", 53 | "@angular/compiler": "5.0.0", 54 | "@angular/compiler-cli": "5.0.0", 55 | "@angular/core": "5.0.0", 56 | "@angular/platform-browser": "5.0.0", 57 | "@angular/platform-browser-dynamic": "5.0.0", 58 | "@angular/platform-server": "5.0.0", 59 | "@compodoc/compodoc": "1.0.3", 60 | "@types/jasmine": "2.6.2", 61 | "@types/node": "8.0.47", 62 | "chalk": "2.3.0", 63 | "codelyzer": "4.0.2", 64 | "core-js": "2.5.1", 65 | "istanbul-instrumenter-loader": "3.0.0", 66 | "jasmine-core": "2.8.0", 67 | "karma": "1.7.1", 68 | "karma-chrome-launcher": "2.2.0", 69 | "karma-coverage-istanbul-reporter": "1.3.0", 70 | "karma-jasmine": "1.1.0", 71 | "karma-sourcemap-loader": "0.3.7", 72 | "karma-spec-reporter": "0.0.31", 73 | "karma-webpack": "2.0.5", 74 | "reflect-metadata": "0.1.10", 75 | "rollup": "0.50.0", 76 | "rollup-plugin-license": "0.6.0", 77 | "rollup-plugin-node-resolve": "3.0.0", 78 | "rollup-plugin-sourcemaps": "0.4.2", 79 | "rxjs": "5.5.2", 80 | "shelljs": "0.7.8", 81 | "source-map-loader": "0.2.3", 82 | "ts-loader": "3.1.1", 83 | "tslint": "5.8.0", 84 | "tslint-angular": "1.0.0", 85 | "typescript": "2.4.2", 86 | "uglify-js": "3.1.6", 87 | "webpack": "3.8.1", 88 | "zone.js": "0.8.18" 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /public_api.ts: -------------------------------------------------------------------------------- 1 | export * from './src/css-vars-module'; -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import resolve from 'rollup-plugin-node-resolve'; 2 | import sourcemaps from 'rollup-plugin-sourcemaps'; 3 | 4 | /** 5 | * Add here external dependencies that actually you use. 6 | * 7 | * Angular dependencies 8 | * - '@angular/animations' => 'ng.animations' 9 | * - '@angular/animations/browser': 'ng.animations.browser' 10 | * - '@angular/common' => 'ng.common' 11 | * - '@angular/compiler' => 'ng.compiler' 12 | * - '@angular/core' => 'ng.core' 13 | * - '@angular/forms' => 'ng.forms' 14 | * - '@angular/common/http' => 'ng.common.http' 15 | * - '@angular/platform-browser-dynamic' => 'ng.platformBrowserDynamic' 16 | * - '@angular/platform-browser' => 'ng.platformBrowser' 17 | * - '@angular/platform-browser/animations' => 'ng.platformBrowser.animations' 18 | * - '@angular/platform-server' => 'ng.platformServer' 19 | * - '@angular/router' => 'ng.router' 20 | * 21 | * RxJS dependencies 22 | * Each RxJS functionality that you use in the library must be added as external dependency. 23 | * - For main classes use 'Rx': 24 | * e.g. import { Observable } from 'rxjs/Observable'; => 'rxjs/Observable': 'Rx' 25 | * - For observable methods use 'Rx.Observable': 26 | * e.g. import 'rxjs/add/observable/merge'; => 'rxjs/add/observable/merge': 'Rx.Observable' 27 | * or for lettable operators: 28 | * e.g. import { merge } from 'rxjs/observable/merge'; => 'rxjs/observable/merge': 'Rx.Observable' 29 | * - For operators use 'Rx.Observable.prototype': 30 | * e.g. import 'rxjs/add/operator/map'; => 'rxjs/add/operator/map': 'Rx.Observable.prototype' 31 | * or for lettable operators: 32 | * e.g. import { map } from 'rxjs/operators'; => 'rxjs/operators': 'Rx.Observable.prototype' 33 | * 34 | * Other dependencies 35 | * - Angular libraries: refer to their global namespace 36 | * - TypeScript/JavaScript libraries: 37 | * e.g. lodash: 'lodash' => 'lodash' 38 | * 39 | * Also, if the dependency uses CommonJS modules, such as lodash, 40 | * you should also use a plugin like rollup-plugin-commonjs, 41 | * to explicitly specify unresolvable "named exports". 42 | * 43 | */ 44 | const globals = { 45 | '@angular/core': 'ng.core', 46 | '@angular/common': 'ng.common', 47 | 'rxjs/Observable': 'Rx', 48 | 'rxjs/Observer': 'Rx' 49 | }; 50 | 51 | export default { 52 | external: Object.keys(globals), 53 | plugins: [resolve(), sourcemaps()], 54 | onwarn: () => { return }, 55 | output: { 56 | format: 'umd', 57 | name: 'ng.NgxCssVariablesModule', 58 | globals: globals, 59 | sourcemap: true, 60 | exports: 'named', 61 | amd: { id: 'ngx-css-variables' } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /rollup.es.config.js: -------------------------------------------------------------------------------- 1 | import sourcemaps from 'rollup-plugin-sourcemaps'; 2 | import license from 'rollup-plugin-license'; 3 | 4 | const path = require('path'); 5 | 6 | export default { 7 | output: { 8 | format: 'es', 9 | sourcemap: true 10 | }, 11 | plugins: [ 12 | sourcemaps(), 13 | license({ 14 | sourceMap: true, 15 | 16 | banner: { 17 | file: path.join(__dirname, 'license-banner.txt'), 18 | encoding: 'utf-8', 19 | } 20 | }) 21 | ], 22 | onwarn: () => { return } 23 | } 24 | -------------------------------------------------------------------------------- /spec.bundle.js: -------------------------------------------------------------------------------- 1 | import 'core-js'; 2 | import 'zone.js/dist/zone'; 3 | import 'zone.js/dist/long-stack-trace-zone'; 4 | import 'zone.js/dist/proxy.js'; 5 | import 'zone.js/dist/sync-test'; 6 | import 'zone.js/dist/jasmine-patch'; 7 | import 'zone.js/dist/async-test'; 8 | import 'zone.js/dist/fake-async-test'; 9 | 10 | import { getTestBed } from '@angular/core/testing'; 11 | import { 12 | BrowserDynamicTestingModule, 13 | platformBrowserDynamicTesting 14 | } from '@angular/platform-browser-dynamic/testing'; 15 | 16 | import 'rxjs'; 17 | 18 | getTestBed().initTestEnvironment( 19 | BrowserDynamicTestingModule, 20 | platformBrowserDynamicTesting() 21 | ); 22 | 23 | const testContext = require.context('./tests', true, /\.spec\.ts/); 24 | 25 | function requireAll(requireContext) { 26 | return requireContext.keys().map(requireContext); 27 | } 28 | 29 | const modules = requireAll(testContext); 30 | -------------------------------------------------------------------------------- /src/css-vars-module.ts: -------------------------------------------------------------------------------- 1 | export * from './css-vars/css-vars.module'; 2 | export * from './css-vars/directive/css-vars.directive'; 3 | export * from './css-vars/service/css-vars.service'; 4 | export * from './css-vars/types'; -------------------------------------------------------------------------------- /src/css-vars/css-vars.module.ts: -------------------------------------------------------------------------------- 1 | import {ModuleWithProviders, NgModule} from '@angular/core'; 2 | import {CommonModule} from '@angular/common'; 3 | import {CssVarsDirective} from './directive/css-vars.directive'; 4 | import {CssVarsService} from './service/css-vars.service'; 5 | 6 | @NgModule({ 7 | imports: [ 8 | CommonModule 9 | ], 10 | declarations: [CssVarsDirective], 11 | exports: [CssVarsDirective] 12 | }) 13 | export class CssVarsModule { 14 | public static forRoot(): ModuleWithProviders { 15 | return { 16 | ngModule: CssVarsModule, 17 | providers: [CssVarsService] 18 | }; 19 | } 20 | 21 | public static forChild(): ModuleWithProviders { 22 | return { 23 | ngModule: CssVarsModule, 24 | providers: [CssVarsService] 25 | }; 26 | } 27 | } -------------------------------------------------------------------------------- /src/css-vars/directive/css-vars.directive.ts: -------------------------------------------------------------------------------- 1 | import {Directive, ElementRef, Input, OnInit} from '@angular/core'; 2 | import {CssVars} from '../types'; 3 | 4 | @Directive({ 5 | selector: '[css-vars]' 6 | }) 7 | export class CssVarsDirective implements OnInit { 8 | 9 | @Input('css-vars') cssVars: CssVars; 10 | 11 | constructor(private el: ElementRef) { 12 | } 13 | 14 | ngOnInit() { 15 | if (!this.cssVars) return; 16 | Object.keys(this.cssVars).forEach(key => { 17 | this.el.nativeElement.style.setProperty(key, this.cssVars[key]); 18 | }); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/css-vars/service/css-vars.service.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | import {CssVars} from '../types'; 3 | 4 | @Injectable() 5 | export class CssVarsService { 6 | 7 | private head: HTMLHeadElement; 8 | 9 | constructor() { 10 | this.head = document.head || document.getElementsByTagName('head')[0]; 11 | } 12 | 13 | public setVariables(vars: CssVars): string { 14 | const style: HTMLStyleElement = document.createElement('style'); 15 | style.type = 'text/css'; 16 | 17 | const styles: string[] = []; 18 | Object.keys(vars).forEach((property: string) => { 19 | styles.push(`${property}: ${vars[property]}`); 20 | }); 21 | 22 | const css = `:root {${styles.join('; ')}}`; 23 | 24 | style.appendChild(document.createTextNode(css)); 25 | this.head.appendChild(style); 26 | return css; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/css-vars/types.ts: -------------------------------------------------------------------------------- 1 | export interface CssVars { 2 | [key: string]: string; 3 | } 4 | -------------------------------------------------------------------------------- /tests/services/css-vars.directive.spec.ts: -------------------------------------------------------------------------------- 1 | import {TestBed, ComponentFixture, async} from '@angular/core/testing'; 2 | import {Component, DebugElement} from '@angular/core'; 3 | import {By} from '@angular/platform-browser'; 4 | import {CssVarsDirective} from './../../src/css-vars-module'; 5 | import {CssVars} from '../../src/css-vars/types'; 6 | 7 | @Component({ 8 | template: ` 9 | ` 10 | }) 11 | class TestDummyComponent { 12 | public cssVars: CssVars; 13 | } 14 | 15 | 16 | describe('Directive: CssVars', () => { 17 | 18 | let component: TestDummyComponent; 19 | let fixture: ComponentFixture