Customize angular component metadata (JIT)
npm install angular-restyle-loaderAllows replacing template & styles metadata in 3rd party components.
This allows complete restyling of components shipped with hard coded templates & styles.
Originally built to customize Material 2 components.
Since HTML templates are statically analyzed when compiling AOT we get some level of assurance.
For styles its not the case, so make sure you know what you're doing.
> ngc-webpack provides the infrastructure but you will have to build a logic using NgcWebpackPlugin to replace
paths related to material resources (css, html)
#Example: Restyling Material2
Add the loader to Webpack configuration:
```
{
test: /node_modules\/@angular\/material\/.*\.js$/,
use: [
{
loader: 'angular2-restyle-loader',
options: require('src/material-restyle/material-restyle.config.js')
}
]
}
Note that the test is selecting only the material library, for webpack performance reasons only target the directory/ies containing components you want to restyle
The options are imported from a module.
This is the config module:
`
const reMeta = require('angular2-restyle-loader');
const config = {
context: __dirname,
components: [
{
selector: 'md-slide-toggle',
template: reMeta.uri('./slide-toggle/slide-toggle.html'),
styles: [
'.some { position: relative; }',
reMeta.uri('./slide-toggle/slide-toggle.scss')
]
}
]
};
module.exports = config;
`
- context: the directory absolute to all resources. (Default: root)
- components: an array of components config items to restyle
- -- selector: the exect selector of the component you wish to restyle.
- -- template: The new template (optional)
- -- styles: New styles (optional)
The template and styles properties represent a replacement for
their corresponding properties in the component metadata.
The template property can be a string or a uri expression.
The styles property is an array where each item can be a string or a uri expression.
In addition you can set template or styles to a function.
The function accepts 1 parameters: original template / original styles (array)
The function returns string or a uri expression for template or array of string or a uri expression for styles.
The function can also return a Promise of the above.
###URI Expressions
Working with strings is limited. Sometimes we want to work with modules.
For examples, if we want to use SASS to define the styles.
Since the configuration executes in a different context we can't require the scss files directly. template: reMeta.uri('./slide-toggle/slide-toggle.html')
We can't use strings since they are literal templates/styles.
Instead we just use the uri function to tell angular2-restyle-loader that it's a resource.
The loader will add the resource to the source code making it run through all the loaders.
You can think that reMeta.uri === require
When you need to restyle:
1) Try to use existing tools (SASS, component features, etc)
2) Try to use restyle but only to re-compile SCSS while declaring variables
3) Try Adding styles after (in addition) to the original files
> To sum up - try not to rewrite original code.
If 1, 2 & didn't help try replacing templates/styles.
Before: !image
`
$md-slide-toggle-width: 48px !default;
$md-slide-toggle-height: 24px !default;
$md-slide-toggle-bar-height: 24px !default;
$md-slide-toggle-thumb-size: 20px !default;
$md-slide-toggle-margin: 0px !default;
$md-slide-toggle-spacing: 10px !default;
@import '~@angular/material/core/theming/all-theme';
@import '~@angular/material/slide-toggle/slide-toggle-theme';
@import '~@angular/material/slide-toggle/slide-toggle';
.md-slide-toggle-bar {
border-radius: 46px;
}
.md-slide-toggle-thumb-container {
left: $md-slide-toggle-bar-height - $md-slide-toggle-thumb-size;
}
md-slide-toggle {
&.md-checked {
.md-slide-toggle-thumb-container {
left: - ($md-slide-toggle-bar-height - $md-slide-toggle-thumb-size);
}
}
}
``
We can also get this working by using CSS overrides but it will be hard, dirty and painful.
This approach separates the restyling from the app.