Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ const Container = div({
const PrimaryButton = styled(Button)({
color: 'red'
})

// Component Selectors.
const ButtonContainer = styled(Container)({
[`& ${PrimaryButton}`]: {
color: 'green'
}
})
```

## Base Style Sheet
Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"coveralls": "^3.0.0",
"enzyme": "^3.1.0",
"enzyme-adapter-react-16": "^1.0.1",
"enzyme-to-json": "^3.1.2",
"eslint": "^3.13.0",
"eslint-config-airbnb": "^14.1.0",
"eslint-config-jss": "^3.0.0",
Expand Down Expand Up @@ -92,6 +93,9 @@
"coverageDirectory": "../coverage",
"setupFiles": [
"raf/polyfill"
],
"snapshotSerializers": [
"enzyme-to-json/serializer"
]
}
}
2 changes: 1 addition & 1 deletion src/createStyled.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const createStyled = (jss: Function) => (baseStyles: BaseStylesType = {}): Style
const {tagName, style} = getStyledArgs(tagNameOrStyledElement)
const elementStyle = {...style, ...ownStyle}

return styled({tagName, baseStyles, elementStyle, mountSheet})
return styled({tagName, baseStyles, elementStyle, mountSheet, jss})
}

Object.defineProperty(styledWrapper, 'sheet', ({
Expand Down
36 changes: 29 additions & 7 deletions src/styled.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,30 @@ import type {
type StyledArgs = {
tagName: string,
elementStyle: ComponentStyleType,
mountSheet: Function
mountSheet: Function,
jss: Function
}

const styled = ({tagName, elementStyle, mountSheet}: StyledArgs) => {
const styled = ({tagName, elementStyle, mountSheet, jss}: StyledArgs) => {
const {dynamicStyle, staticStyle} = getSeparatedStyles(elementStyle)
const staticTagName = staticStyle && generateTagName(tagName)

const availableDynamicTagNames = []
const classMap = {}

return class StyledElement extends Component<StyledElementPropsType> {
let staticClassName

class StyledElement extends Component<StyledElementPropsType> {
static tagName: string = tagName
static style: ComponentStyleType = elementStyle

dynamicTagName = ''

sheet: JssSheet

constructor(props: StyledElementPropsType) {
super(props)
if (!this.dynamicTagName && dynamicStyle) {
this.dynamicTagName = availableDynamicTagNames.pop() || generateTagName(tagName)
}

this.staticClassName = staticClassName
}

componentWillMount() {
Expand Down Expand Up @@ -66,6 +67,10 @@ const styled = ({tagName, elementStyle, mountSheet}: StyledArgs) => {
availableDynamicTagNames.push(this.dynamicTagName)
}

dynamicTagName = ''
sheet: JssSheet
staticClassName = ''

updateSheet(props: StyledElementPropsType) {
let rule
let ruleIndex = 0
Expand All @@ -83,6 +88,7 @@ const styled = ({tagName, elementStyle, mountSheet}: StyledArgs) => {

const props = filterProps(tagName, attrs)
const tagClass = composeClasses([
this.staticClassName,
staticTagName && this.sheet.classes[staticTagName],
this.dynamicTagName && this.sheet.classes[this.dynamicTagName],
className
Expand All @@ -91,6 +97,22 @@ const styled = ({tagName, elementStyle, mountSheet}: StyledArgs) => {
return createElement(tagName, {...props, className: tagClass}, children)
}
}

// $FlowIgnore
StyledElement.valueOf = () => {
if (!staticClassName) {
staticClassName = `.${jss.generateClassName({
key: generateTagName('static')
})}`
}

return staticClassName
}

// $FlowIgnore
StyledElement.toString = StyledElement.valueOf

return StyledElement
}

export default styled
42 changes: 42 additions & 0 deletions src/tests/__snapshots__/functional.spec.jsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,48 @@ exports[`functional tests should update props and unmount 2`] = `
}"
`;

exports[`functional tests should use Styled Component classname in string 1`] = `
".div-4-id:not(:first-child) .static-2-id {
display: none;
}
.div-4-id:not(:last-child) .static-3-id {
visibility: hidden;
}
.div-4-id .static-2-id {
color: green;
}
.div-1-id {
color: red;
}
.img-5-id {
width: 30px;
}"
`;

exports[`functional tests should use Styled Component classname in string 2`] = `
<StyledElement>
<div
className="div-4-id"
>
<StyledElement>
<div
className=".static-2-id div-1-id"
>
name
</div>
</StyledElement>
<StyledElement
width={30}
>
<img
className=".static-3-id img-5-id"
width={30}
/>
</StyledElement>
</div>
</StyledElement>
`;

exports[`functional tests should use props on remount 1`] = `
".button-1-id {
color: black;
Expand Down
32 changes: 32 additions & 0 deletions src/tests/functional.spec.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,36 @@ describe('functional tests', () => {

wrapper.unmount()
})

it('should use Styled Component classname in string', () => {
const AuthorName = styled('div')({color: 'red'})
const Avatar = styled('img')({width: props => props.width})

const Message = styled('div')({
[`&:not(:first-child) ${AuthorName}`]: {
display: 'none'
},
[`&:not(:last-child) ${Avatar}`]: {
visibility: 'hidden'
},
[`& ${AuthorName}`]: {
color: 'green'
}
})

const wrapper = mount(
<Message>
<AuthorName>name</AuthorName>
<Avatar width={30} />
</Message>
)

const {sheet} = styled

assertSheet(sheet)

expect(wrapper).toMatchSnapshot()

wrapper.unmount()
})
})
6 changes: 6 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1433,6 +1433,12 @@ enzyme-adapter-utils@^1.0.0:
object.assign "^4.0.4"
prop-types "^15.5.10"

enzyme-to-json@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/enzyme-to-json/-/enzyme-to-json-3.1.2.tgz#7681e04c5747bb140c4c658ba7f07a6679e1f3b6"
dependencies:
lodash "^4.17.4"

enzyme@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/enzyme/-/enzyme-3.1.0.tgz#d8ca84085790fbcec6ed40badd14478faee4c25a"
Expand Down