Skip to content

Commit

Permalink
Merge pull request FormidableLabs#646 from FormidableLabs/feature-sco…
Browse files Browse the repository at this point in the history
…pingSelectorsAllOver

Make scopeSelector work without nested selectors
  • Loading branch information
ianobermiller committed Mar 28, 2016
2 parents 38344ae + 28ce305 commit 48ee293
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 4 deletions.
27 changes: 27 additions & 0 deletions docs/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,33 @@ The `<Style>` component renders an HTML `<style>` tag containing a set of CSS ru
Without the `<Style>` component, it is prohibitively difficult to write a `<style>` element in React. To write a normal `<style>` element, you need to write your CSS as a multiline string inside of the element. `<Style>` simplifies this process, and adds prefixing and the ability to scope selectors.
If you include a `scopeSelector`, you can include CSS rules that should apply to that selector as well as any nested selectors. For example, the following
```
<Style
scopeSelector=".scoping-class"
rules={{
color: 'blue',
span: {
fontFamily: 'Lucida Console, Monaco, monospace'
}
}}
/>
```
will return:
```
<style>
.scoping-class {
color: 'blue';
}
.scoping-class span {
font-family: 'Lucida Console, Monaco, monospace'
}
</style>
```
### Props
#### rules
Expand Down
3 changes: 2 additions & 1 deletion examples/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ var App = React.createClass({
rules={{
span: {
fontFamily: 'Lucida Console, Monaco, monospace'
}
},
color: 'blue'
}}
/>
<span>This content has scoped styles</span>
Expand Down
28 changes: 28 additions & 0 deletions src/__tests__/style-component-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,32 @@ describe('<Style> component', () => {
}
`);
});

it('adds scopeSelector if no selectors are present', () => {
const output = TestUtils.renderIntoDocument(
<Style
rules={{
color: 'red',
backgroundColor: 'white',
div: {
color: 'blue',
backgroundColor: 'black'
}
}}
scopeSelector=".scope"
/>
);

const style = getElement(output, 'style');
expectCSS(style, `
.scope {
color: red;
background-color: white;
}
.scope div {
color: blue;
background-color: black;
}
`);
});
});
17 changes: 14 additions & 3 deletions src/components/style.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,24 @@ const Style = React.createClass({
this.context._radiumConfig.userAgent
);

return Object.keys(styles).reduce((accumulator, selector) => {
const {scopeSelector} = this.props;
const {scopeSelector} = this.props;
const rootRules = Object.keys(styles).reduce((accumulator, selector) => {
if (typeof styles[selector] !== 'object') {
accumulator[selector] = styles[selector];
}

return accumulator;
}, {});
const rootStyles = Object.keys(rootRules).length ?
cssRuleSetToString(scopeSelector || '', rootRules, userAgent) :
'';

return rootStyles + Object.keys(styles).reduce((accumulator, selector) => {
const rules = styles[selector];

if (selector === 'mediaQueries') {
accumulator += this._buildMediaQueryString(rules);
} else {
} else if (typeof styles[selector] === 'object') {
const completeSelector = scopeSelector
? selector
.split(',')
Expand Down

0 comments on commit 48ee293

Please sign in to comment.