Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/webark/ember-component-css
An Ember CLI addon which allows you to specify styles for individual components
https://github.com/webark/ember-component-css
Last synced: 2 months ago
JSON representation
An Ember CLI addon which allows you to specify styles for individual components
- Host: GitHub
- URL: https://github.com/webark/ember-component-css
- Owner: webark
- License: mit
- Created: 2015-03-04T22:06:24.000Z (almost 10 years ago)
- Default Branch: master
- Last Pushed: 2023-03-04T15:14:08.000Z (almost 2 years ago)
- Last Synced: 2024-05-19T05:35:03.012Z (8 months ago)
- Language: JavaScript
- Homepage:
- Size: 1.94 MB
- Stars: 542
- Watchers: 16
- Forks: 115
- Open Issues: 56
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE.md
Awesome Lists containing this project
- awesome-ember - ember-component-css - An Ember CLI addon which allows you to specify styles for individual components. (Packages / CSS & etc)
README
# ember-component-css [![Build Status](https://github.com/ebryn/ember-component-css/actions/workflows/ci.yml/badge.svg)](https://github.com/ebryn/ember-component-css/actions/workflows/ci.yml) [![Ember Observer Score](https://emberobserver.com/badges/ember-component-css.svg)](https://emberobserver.com/addons/ember-component-css)
An Ember CLI addon which allows you to specify component-specific style sheets in an app, addon, engine, or in-repo addon.
Contributions are welcome! Feel free to open up a pull request or issue, and join the **#e-component-css** channel on the [official Ember Discord server](https://discord.gg/zT3asNS) if you have further questions, concerns, or ideas. Thanks! :smile:
## Installation
`ember install ember-component-css`
## Usage
Rules defined in the style-sheets will automatically be namespaced with an autogenerated class. That autogenerated class will also be injected into your component's `classNames` property. This enables you to worry less about rules clashing across component styles.
For example, given this `app/my-component/styles.scss` file for 'pods',
or this `app/styles/component-styles/my-component.scss` file for 'classic':
```scss
& { // ampersand refers to the component itself (parent selector)
padding: 2px;
}
.urgent {
color: red;span {
text-decoration: underline;
}
}
```Your generated CSS output will look something like:
```css
.__my-component__a34fba {
padding: 2px;
}
.__my-component__a34fba .urgent {
color: red;
}
.__my-component__a34fba .urgent span {
text-decoration: underline;
}
```A typical component invocation that looks like this:
`{{my-component}}`
will generated markup like:
`
`### Inclusion
To use this addon you *MUST*, import `pod-styles` into your base stylesheet.
```scss
// app/styles/app.scss
@import "pod-styles";
``````scss
// app/styles/app.less
@import "pod-styles";
``````scss
// app/styles/app.styl
@import 'pod-styles'
``````css
/* app/styles/app.css */
@import "pod-styles.css";
```And that is it! The `pod-styles` file is generated during the build and will then be pulled into your other stylesheet to be processed like normal.
Note: If you are using more than one type of component style files (ie a .less file and a .scss file) then you will need to add the extension to the @import. Otherwise the extension can be left off.
### Usage with pods structure
To use this with pods, you just need to include a style file in your component pods directory alongside your `template.hbs` or `component.js` files.
### Usage with routes
To use this with routes you need to use pods for the routes and modify the `application.hbs` template a little bit.
Let's assume your `application.hbs` template looks like this:```hbs
{{outlet}}
```To be able to use this for routes, you need to add a wrapping `div` around the outlet:
```hbs
{{outlet}}
```After that it's quite easy: add a style file in your route directory alongside your `route.js` or `template.hbs` files.
An individual controller also has access to a `styleNamespace` property that is the namespace for a given route. This can be used for various use cases. (like enabling BEM style similar to how the `styleNamespace` is used in a component)
### Usage with classic (non pod) structure
You can use classic Ember app structure by placing component styles in
`app/styles/component-styles`. Name your style files after the component name,
for example `my-component.scss`. The directory where styles are fetched from can
be configured as shown [below](#configuration). It's possible to use a mixture
of classic and pod structured styles in the same app, if you use both styles for
the same component both are included but the pod style will take precedence.### Use in addons
In order to use this inside of an addon, you need to add your style files inside of the components in the
addon directory. You will then be able to import the 'pod-styles' file inside of your addon style file which
is in the `/addon/styles` directory. These styles will then be added to the `vendor.css` file like normal.If you are using classic (non pod) structure, your addon directory structure might look like:
```
yourAddonDirectory
│ index.js
│ ... etc
└───addon
│ └───components
│ │ yourAddonComponent.js
│ └───templates
│ │ yourAddonComponent.hbs
│ └───styles
│ │ addon.scss (includes the 'pod-styles' import)
│ └───component-styles (this dir name is configurable)
│ │ yourAddonComponent.scss
└───app
└───components
│ yourAddonComponent.js
```If you are extending the `include` method in your addon, please make sure you call the super like this
```js
included: function(app) {
this._super.included.apply(this, arguments);
...
}
```Be sure "ember-component-css" is listed under the "dependencies" key of your addon's `package.json` file, rather than "devDependencies". Don't forget, if you are using `ember-cli-sass` for your addon's styles, it will need to be in "dependencies" as well.
Finally, if your addon is compiling the expected CSS into the host's `vendor.css` output, but the expected classes are not being set on your components' HTML elements, you will need to [run your addon _after_ ember-component-css](https://ember-cli.com/extending/#configuring-your-ember-addon-properties):
```js
// package.json
{
// ...
"dependencies": {
// ...
"ember-component-css": ">= 0.6.4",
// ...
},
// ...
"ember-addon": {
"configPath": "tests/dummy/config",
"after": "ember-component-css"
}
}
```### Plain css usage
In order to use this with plain css files, you need to install [`ember-cli-postcss`](https://github.com/jeffjewiss/ember-cli-postcss) and configure it with [`postcss-import`](https://github.com/postcss/postcss-import).```
ember install ember-component-css
ember install ember-cli-postcss
npm install postcss-import --save-dev
```
Then in your `ember-cli-build.js` you can configure it as such.
```js
var EmberAddon = require('ember-cli/lib/broccoli/ember-addon');
var CssImport = require('postcss-import');module.exports = function(defaults) {
var app = new EmberAddon(defaults, {
postcssOptions: {
compile: {
enabled: true,
plugins: [{
module: CssImport,
}]
}
}
});return app.toTree();
};
```You can also add in [`postcss-cssnext`](https://github.com/MoOx/postcss-cssnext) or any other
postcss plugins in this way too.*Things like [`ember-cli-autoprefixer`](https://github.com/kimroen/ember-cli-autoprefixer) will work out of the box and do not need to be added in as a postcss plugin.*
### Getting the generated class name
You also have access to the generated class name to use in your templates. There is a computed property `styleNamespace` This can be used to pass the class name to things like [`ember-wormhole`](https://github.com/yapplabs/ember-wormhole) or for use in BEM style classnames.
An example of BEM usage would be`my-component/template.hbs`
```handlebarsNormal button
Success button
Danger button
```
`my-component/styles.scss`
```scss
&__button {
display: inline-block;
border-radius: 3px;
padding: 7px 12px;
border: 1px solid #D5D5D5;
background-image: linear-gradient(#EEE, #DDD);
font: 700 13px/18px Helvetica, arial;&--state-success {
color: #FFF;
background: #569E3D linear-gradient(#79D858, #569E3D) repeat-x;
border-color: #4A993E;
}&--state-danger {
color: #900;
}
}
```*`componentCssClassName` will be officially deprecated, then removed in future versions. Will be migrating to the more appropriately named `styleNamespace`*
#### Using the generated class name in `classNameBindings`
You can build your own computed properties on top of `styleNamespace`. One use case is using it to build a `classNameBinding`:
`my-component/component.hbs`
```js
classNameBindings: ['customBinding'],
stateProperty: false,
customBinding: computed('styleNamespace', 'stateProperty', function() {
if (this.get('stateProperty')) {
return `${this.get('styleNamespace')}--state`;
} else {
return '';
}
}),
```
`my-component/styles.scss`
```scss
& {
background: blue;
}
&--state {
background: red;
}
```### Special Tag-less components
On the special cases of tag-less components (this functionality is used putting a `tagName: ''` value in the component), the styles are not attached to the DOM, as this addon needs a tag to attach the generated class name. In those special cases, you can use the `styleNamespace`* classname if you want to attach to a another element in the application (or more coherently inside the tag-less component).
### Configuration
You can set the following configuration options in your `config/environment.js` file:
```js
ENV['ember-component-css'] = {
option: 'value'
}
```**namespacing(_enabled_)**
Defaults to true. Set this option to `false` to disable the namespacing feature of Ember Component CSS.
```js
ENV['ember-component-css'] = {
namespacing: false
}
```This changes the default behavior in two ways:
1. The autogenerated component class is no longer added to your component's HTML
2. Your pod CSS files are no longer namespaced using the autogenerated component class.**classicStyleDir**
Defaults to `component-styles`. Set this to the directory where your classically
structured styles live (within `/app/styles`). For example:```js
ENV['ember-component-css'] = {
classicStyleDir: 'my-styles'
}
```**excludeFromManifest**
Defaults to `[]`. Set this option to one or more matcher expression (regular expression, glob string, or function).
Style files matching the expresion(s) will be namespaced but not imported in the `pod-styles` manifest. You will
need to import the matching style files manually in your CSS. This can be useful when you need to control the order
in which specific style files need to be imported.Example:
You want to have a separate style file for each media-query breakpoint. You want to be sure that `_style-1366.scss`
will be imported before `_style-960.scss````
.
└── my-component/
├── _style-1366.scss
├── _style-960.scss
├── main.scss
├── component.js
└── template.hbs
``````sass
// main.scss
@import "./_style-1366"
@import "./_style-960"
``````js
ENV['ember-component-css'] = {
excludeFromManifest: ['**/_style-*']
}
```**patchClassicComponent**
Set this option to `false` to prevent automatic `Component.reopen()` call which injects
the autogenerated class into component's `classNames` property.You would need to use {{this.styleNamespace}} in *all* of your templates instead:
```hbs
Content goes here.
```This is required to use `ember-component-css` with Ember 4+ since `Component.reopen()` was removed from Ember.js codebase.
For more details you may refer to [deprecation page](https://deprecations.emberjs.com/v3.x#toc_ember-component-reopen).### [The announcement from EmberConf 2015](https://youtu.be/T1zxaEKeq3E)
[![CSS is hard - EmberConf 2015](http://f.cl.ly/items/1a3a3r1C1y0D060D3j3u/EmberConf%202015%20-%20CSS%20Is%20Hard%20-%20YouTube%202015-03-22%2018-33-41.jpg)](https://youtu.be/T1zxaEKeq3E)