-
-
Notifications
You must be signed in to change notification settings - Fork 397
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Styled API #1094
Merged
Merged
Styled API #1094
Changes from 22 commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
79f9723
wip styled
kof 568c5b2
more tests, lint
kof c98e9c1
add styled system tests
kof 18c9a62
switch back to style-system v3, until v4 changes the format back
kof ddfd381
switch back to style-system v3, until v4 changes the format back
kof 92fa857
switch back to style-system v3, until v4 changes the format back, bet…
kof 6778dc1
upgrade to styled-system@4.2.0-0
kof e3c8db2
upgrade flow and react
kof 7858e7c
upgrade theming
kof 3c34638
flow types
kof 302f1cf
Merge branch 'master' into react-jss/feature/styled
kof d6cc7e4
migrate to hooks
kof f284c0e
Fix tests
9f3691f
Update size snapshot
53e7f6e
Merge branch 'master' into react-jss/feature/styled
kof 69fcfb7
more tests
kof 1b3f9c9
accept multiple static and dynamic style declarations
kof 4fe6114
implement shouldForwardProp
kof 6833bb9
merge the styles arguments passed to styled
kof 85d0c65
add test for empty values returned from function rules
kof a8c792e
optimize perf, better types
kof 21ff93f
support label
kof 42d950a
Update changelog.md
kof c9a0361
skip the tests for now on the ci
kof 3de05e7
Merge branch 'master' into react-jss/feature/styled
kof File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
declare function describe(string, Function): void | ||
declare function it(string, Function): void |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -96,7 +96,8 @@ const createUseStyles = <Theme: {}>(styles: Styles<Theme>, options?: HookOptions | |
|
||
useEffectOrLayoutEffect( | ||
() => { | ||
if (state.sheet && state.dynamicRules) { | ||
// We only need to update the rules on a subsequent update and not in the first mount | ||
if (state.sheet && state.dynamicRules && !isFirstMount.current) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this can be in changelog |
||
updateDynamicRules(data, state.sheet, state.dynamicRules) | ||
} | ||
}, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
// @flow | ||
/* eslint-disable react/prop-types, react/require-default-props */ | ||
|
||
import React from 'react' | ||
import isPropValid from '@emotion/is-prop-valid' | ||
import type {StatelessFunctionalComponent, ComponentType} from 'react' | ||
import {ThemeContext as DefaultThemeContext} from 'theming' | ||
|
||
import createUseStyles from './createUseStyles' | ||
import type {HookOptions, StaticStyle, DynamicStyle} from './types' | ||
|
||
type StyledProps = { | ||
className?: string, | ||
as?: string | ||
} | ||
|
||
type StyleArg<Theme> = StaticStyle | DynamicStyle<Theme> | null | void | '' | ||
|
||
const parseStyles = <Theme>(args: {[string]: StyleArg<Theme>}) => { | ||
const dynamicStyles = [] | ||
let staticStyle | ||
let label = 'css' | ||
|
||
// Not using ...rest to optimize perf. | ||
for (const key in args) { | ||
const style = args[key] | ||
if (!style) continue | ||
if (typeof style === 'function') { | ||
dynamicStyles.push(style) | ||
} else { | ||
if (!staticStyle) staticStyle = {} | ||
Object.assign(staticStyle, style) | ||
if ('label' in staticStyle) { | ||
// Label could potentially be defined in each style object, | ||
// so we take the first one and ignore every subsequent one. | ||
if (label === 'css') label = staticStyle.label | ||
// Label should not leak to the core. | ||
delete staticStyle.label | ||
} | ||
} | ||
} | ||
|
||
const styles = {} | ||
|
||
if (staticStyle) styles[label] = staticStyle | ||
|
||
// When there is only one function rule, we don't need to wrap it. | ||
if (dynamicStyles.length === 1) { | ||
styles.cssd = dynamicStyles[0] | ||
} | ||
|
||
// We create a new function rule which will call all other function rules | ||
// and merge the styles they return. | ||
if (dynamicStyles.length > 1) { | ||
styles.cssd = props => { | ||
const merged = {} | ||
for (let i = 0; i < dynamicStyles.length; i++) { | ||
const dynamicStyle = dynamicStyles[i](props) | ||
if (dynamicStyle) Object.assign(merged, dynamicStyle) | ||
} | ||
return merged | ||
} | ||
} | ||
|
||
return {styles, label} | ||
} | ||
|
||
type StyledOptions<Theme> = HookOptions<Theme> & { | ||
shouldForwardProp?: string => boolean | ||
} | ||
|
||
export default <Theme: {}>( | ||
type: string | StatelessFunctionalComponent<StyledProps> | ComponentType<StyledProps>, | ||
options?: StyledOptions<Theme> = {} | ||
) => { | ||
const {theming, shouldForwardProp} = options | ||
const isTagName = typeof type === 'string' | ||
const ThemeContext = theming ? theming.context : DefaultThemeContext | ||
|
||
return function StyledFactory(/* :: ...args: StyleArg<Theme>[] */): StatelessFunctionalComponent< | ||
StyledProps | ||
> { | ||
// eslint-disable-next-line prefer-rest-params | ||
const {styles, label} = parseStyles(arguments) | ||
|
||
const useStyles = createUseStyles(styles, label ? {...options, name: label} : options) | ||
|
||
const Styled = (props: StyledProps) => { | ||
const {as, className} = props | ||
// $FlowFixMe theming ThemeContext types need to be fixed. | ||
const theme = React.useContext(ThemeContext) | ||
const classes = useStyles({...props, theme}) | ||
const childProps: StyledProps = ({}: any) | ||
|
||
for (const prop in props) { | ||
// We don't want to pass non-dom props to the DOM, | ||
// but we still want to forward them to a users component. | ||
if (isTagName && !isPropValid(prop)) continue | ||
if (shouldForwardProp && shouldForwardProp(prop) === false) continue | ||
childProps[prop] = props[prop] | ||
} | ||
// $FlowIgnore we don't care label might not exist in classes. | ||
const classNames = `${classes[label] || classes.css || ''} ${classes.cssd || ''}`.trim() | ||
childProps.className = className ? `${className} ${classNames}` : classNames | ||
|
||
return React.createElement(as || type, childProps) | ||
} | ||
|
||
return Styled | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be used for things which need to be ignored but need no fixing