Skip to content

Commit fb92e0f

Browse files
committed
merge master
2 parents 0abd98b + 43ec343 commit fb92e0f

6 files changed

Lines changed: 181 additions & 158 deletions

File tree

packages/react-jss/.size-snapshot.json

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
{
22
"dist/react-jss.js": {
3-
"bundled": 124943,
4-
"minified": 43246,
5-
"gzipped": 13007
3+
"bundled": 147373,
4+
"minified": 48848,
5+
"gzipped": 14465
66
},
77
"dist/react-jss.min.js": {
8-
"bundled": 101535,
9-
"minified": 36075,
10-
"gzipped": 10916
8+
"bundled": 112549,
9+
"minified": 38146,
10+
"gzipped": 11757
1111
},
1212
"dist/react-jss.cjs.js": {
13-
"bundled": 16617,
14-
"minified": 6893,
15-
"gzipped": 2410
13+
"bundled": 16530,
14+
"minified": 6928,
15+
"gzipped": 2402
1616
},
1717
"dist/react-jss.esm.js": {
18-
"bundled": 16063,
19-
"minified": 6420,
20-
"gzipped": 2295,
18+
"bundled": 16058,
19+
"minified": 6535,
20+
"gzipped": 2297,
2121
"treeshaked": {
2222
"rollup": {
2323
"code": 1866,

packages/react-jss/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,6 @@
4646
"jss": "^9.7.0",
4747
"jss-preset-default": "^4.3.0",
4848
"prop-types": "^15.6.0",
49-
"theming": "^1.3.0"
49+
"theming": "^2.1.2"
5050
}
5151
}

packages/react-jss/src/createHoc.js

Lines changed: 97 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,14 @@
22
/* eslint-disable react/destructuring-assignment */
33
import React, {Component, type ComponentType} from 'react'
44
import PropTypes from 'prop-types'
5-
import defaultTheming from 'theming'
5+
import {withTheme} from 'theming'
66
import type {StyleSheet} from 'jss'
77
import jss, {getDynamicStyles, SheetsManager} from './jss'
88
import compose from './compose'
99
import getDisplayName from './getDisplayName'
1010
import * as ns from './ns'
1111
import contextTypes from './contextTypes'
12-
import type {
13-
Options,
14-
Theme,
15-
StylesOrCreator,
16-
InnerProps,
17-
OuterProps,
18-
Context,
19-
SubscriptionId
20-
} from './types'
12+
import type {Options, Theme, StylesOrCreator, InnerProps, OuterProps, Context} from './types'
2113

2214
const env = process.env.NODE_ENV
2315

@@ -44,11 +36,11 @@ const dynamicStylesNs = Math.random()
4436
*
4537
*/
4638

47-
type State = {
48-
theme: Theme,
49-
dynamicSheet?: StyleSheet,
39+
type State = {|
40+
dynamicSheet: StyleSheet | null,
41+
staticSheet: StyleSheet | null,
5042
classes: {}
51-
}
43+
|}
5244

5345
const getStyles = (stylesOrCreator: StylesOrCreator, theme: Theme) => {
5446
if (typeof stylesOrCreator !== 'function') {
@@ -85,56 +77,56 @@ export default function createHOC<
8577
options: Options
8678
): ComponentType<OuterPropsType> {
8779
const isThemingEnabled = typeof stylesOrCreator === 'function'
88-
const {theming = defaultTheming, inject, jss: optionsJss, ...sheetOptions} = options
80+
const {theming, inject, jss: optionsJss, ...sheetOptions} = options
8981
const injectMap = inject ? toMap(inject) : defaultInjectProps
90-
const {themeListener} = theming
9182
const displayName = getDisplayName(InnerComponent)
9283
const defaultClassNamePrefix = env === 'production' ? '' : `${displayName}-`
9384
const noTheme = {}
9485
const managerId = managersCounter++
9586
const manager = new SheetsManager()
96-
// $FlowFixMe defaultProps are not defined in React$Component
97-
const defaultProps: InnerPropsType = {...InnerComponent.defaultProps}
98-
delete defaultProps.classes
87+
88+
// $FlowFixMe: DefaultProps is missing in type definitions
89+
const {classes: defaultClasses = {}, ...defaultProps} = {...InnerComponent.defaultProps}
9990

10091
class Jss extends Component<OuterPropsType, State> {
10192
static displayName = `Jss(${displayName})`
10293

10394
static InnerComponent = InnerComponent
10495

105-
static contextTypes = {
106-
...contextTypes,
107-
...(isThemingEnabled ? themeListener.contextTypes : {})
108-
}
96+
static contextTypes = contextTypes
10997

11098
static propTypes = {
11199
innerRef: PropTypes.func
112100
}
113101

114-
static defaultProps = defaultProps
102+
static defaultProps = {
103+
...defaultProps,
104+
theme: noTheme
105+
}
106+
107+
classNamePrefix: string = defaultClassNamePrefix
115108

116109
constructor(props: OuterPropsType, context: Context) {
117110
super(props, context)
118-
const theme = isThemingEnabled ? themeListener.initial(context) : noTheme
119111

120-
this.state = this.createState({theme, classes: {}}, props)
121-
this.manage(this.state)
122-
}
112+
const contextSheetOptions = context[ns.sheetOptions]
123113

124-
componentDidMount() {
125-
if (isThemingEnabled) {
126-
this.unsubscribeId = themeListener.subscribe(this.context, this.setTheme)
114+
if (contextSheetOptions && contextSheetOptions.classNamePrefix) {
115+
this.classNamePrefix = contextSheetOptions.classNamePrefix + this.classNamePrefix
127116
}
117+
118+
this.state = this.createState()
119+
this.manage(this.state)
128120
}
129121

130122
componentDidUpdate(prevProps: OuterPropsType, prevState: State) {
131123
const {dynamicSheet} = this.state
132124
if (dynamicSheet) dynamicSheet.update(this.props)
133125

134-
if (isThemingEnabled && this.state.theme !== prevState.theme) {
135-
const newState = this.createState(this.state, this.props)
126+
if (isThemingEnabled && this.props.theme !== prevProps.theme) {
127+
const newState = this.createState()
136128
this.manage(newState)
137-
this.manager.unmanage(prevState.theme)
129+
this.manager.unmanage(prevProps.theme)
138130
// eslint-disable-next-line react/no-did-update-set-state
139131
this.setState(newState)
140132
}
@@ -146,17 +138,15 @@ export default function createHOC<
146138
}
147139

148140
componentWillUnmount() {
149-
if (isThemingEnabled && this.unsubscribeId) {
150-
themeListener.unsubscribe(this.context, this.unsubscribeId)
151-
}
152-
153-
this.manager.unmanage(this.state.theme)
141+
this.manager.unmanage(this.theme)
154142
if (this.state.dynamicSheet) {
155143
this.jss.removeStyleSheet(this.state.dynamicSheet)
156144
}
157145
}
158146

159-
setTheme = (theme: Theme) => this.setState({theme})
147+
get theme() {
148+
return isThemingEnabled ? this.props.theme : noTheme
149+
}
160150

161151
get jss() {
162152
return this.context[ns.jss] || optionsJss || jss
@@ -177,92 +167,99 @@ export default function createHOC<
177167
return manager
178168
}
179169

180-
manage({theme, dynamicSheet}: State) {
181-
const contextSheetOptions = this.context[ns.sheetOptions]
182-
if (contextSheetOptions && contextSheetOptions.disableStylesGeneration) {
183-
return
184-
}
185-
const registry = this.context[ns.sheetsRegistry]
186-
187-
const staticSheet = this.manager.manage(theme)
188-
if (registry) registry.add(staticSheet)
170+
getStaticSheet() {
171+
const theme = this.theme
172+
let staticSheet = this.manager.get(theme)
189173

190-
if (dynamicSheet) {
191-
dynamicSheet.update(this.props).attach()
192-
if (registry) registry.add(dynamicSheet)
174+
if (staticSheet) {
175+
return staticSheet
193176
}
194-
}
195177

196-
createState(state: State, {classes: userClasses}): State {
197178
const contextSheetOptions = this.context[ns.sheetOptions]
198-
if (contextSheetOptions && contextSheetOptions.disableStylesGeneration) {
199-
return {...state, classes: {}}
200-
}
201-
202-
let classNamePrefix = defaultClassNamePrefix
203-
let staticSheet = this.manager.get(state.theme)
204-
205-
if (contextSheetOptions && contextSheetOptions.classNamePrefix) {
206-
classNamePrefix = contextSheetOptions.classNamePrefix + classNamePrefix
207-
}
208-
209-
if (!staticSheet) {
210-
const styles = getStyles(stylesOrCreator, state.theme)
211-
staticSheet = this.jss.createStyleSheet(styles, {
212-
...sheetOptions,
213-
...contextSheetOptions,
214-
meta: `${displayName}, ${isThemingEnabled ? 'Themed' : 'Unthemed'}, Static`,
215-
classNamePrefix
216-
})
217-
this.manager.add(state.theme, staticSheet)
218-
// $FlowFixMe Cannot add random fields to instance of class StyleSheet
219-
staticSheet[dynamicStylesNs] = getDynamicStyles(styles)
220-
}
179+
const styles = getStyles(stylesOrCreator, theme)
180+
staticSheet = this.jss.createStyleSheet(styles, {
181+
...sheetOptions,
182+
...contextSheetOptions,
183+
meta: `${displayName}, ${isThemingEnabled ? 'Themed' : 'Unthemed'}, Static`,
184+
classNamePrefix: this.classNamePrefix
185+
})
186+
this.manager.add(theme, staticSheet)
187+
// $FlowFixMe Cannot add random fields to instance of class StyleSheet
188+
staticSheet[dynamicStylesNs] = getDynamicStyles(styles)
189+
190+
return staticSheet
191+
}
221192

193+
getDynamicSheet(staticSheet) {
222194
// $FlowFixMe Cannot access random fields on instance of class StyleSheet
223195
const dynamicStyles = staticSheet[dynamicStylesNs]
224-
let dynamicSheet
225196

226197
if (dynamicStyles) {
227-
dynamicSheet = this.jss.createStyleSheet(dynamicStyles, {
198+
const contextSheetOptions = this.context[ns.sheetOptions]
199+
200+
return this.jss.createStyleSheet(dynamicStyles, {
228201
...sheetOptions,
229202
...contextSheetOptions,
230203
meta: `${displayName}, ${isThemingEnabled ? 'Themed' : 'Unthemed'}, Dynamic`,
231-
classNamePrefix,
204+
classNamePrefix: this.classNamePrefix,
232205
link: true
233206
})
234207
}
235208

236-
// $FlowFixMe InnerComponent can be class or stateless, the latter doesn't have a defaultProps property
237-
const defaultClasses = InnerComponent.defaultProps
238-
? InnerComponent.defaultProps.classes
239-
: undefined
209+
return null
210+
}
211+
212+
manage({dynamicSheet, staticSheet}: State) {
213+
const registry = this.context[ns.sheetsRegistry]
214+
215+
this.manager.manage(this.theme)
216+
if (staticSheet && registry) registry.add(staticSheet)
217+
218+
if (dynamicSheet !== null) {
219+
dynamicSheet.update(this.props).attach()
220+
if (registry) registry.add(dynamicSheet)
221+
}
222+
}
223+
224+
computeClasses(staticSheet, dynamicSheet) {
240225
const jssClasses = dynamicSheet
241226
? compose(
242227
staticSheet.classes,
243228
dynamicSheet.classes
244229
)
245230
: staticSheet.classes
246-
const classes = {
231+
return {
247232
...defaultClasses,
248233
...jssClasses,
249-
...userClasses
234+
...this.props.classes
250235
}
251-
252-
return {theme: state.theme, dynamicSheet, classes}
253236
}
254237

255-
unsubscribeId: SubscriptionId
238+
createState(): State {
239+
const contextSheetOptions = this.context[ns.sheetOptions]
240+
if (contextSheetOptions && contextSheetOptions.disableStylesGeneration) {
241+
return {
242+
classes: {},
243+
dynamicSheet: null,
244+
staticSheet: null
245+
}
246+
}
247+
248+
const staticSheet = this.getStaticSheet()
249+
const dynamicSheet = this.getDynamicSheet(staticSheet)
250+
251+
return {staticSheet, dynamicSheet, classes: this.computeClasses(staticSheet, dynamicSheet)}
252+
}
256253

257254
context: Context
258255

259256
render() {
260-
const {theme, dynamicSheet, classes} = this.state
261-
const {innerRef, ...props}: OuterPropsType = this.props
262-
const sheet = dynamicSheet || this.manager.get(theme)
257+
const {dynamicSheet, classes, staticSheet} = this.state
258+
const {innerRef, theme, ...props}: OuterPropsType = this.props
259+
const sheet = dynamicSheet || staticSheet
263260

264-
if (injectMap.sheet && !props.sheet) props.sheet = sheet
265-
if (isThemingEnabled && injectMap.theme && !props.theme) props.theme = theme
261+
if (injectMap.sheet && !props.sheet && sheet) props.sheet = sheet
262+
if (injectMap.theme) props.theme = theme
266263

267264
// We have merged classes already.
268265
if (injectMap.classes) props.classes = classes
@@ -271,5 +268,11 @@ export default function createHOC<
271268
}
272269
}
273270

271+
if (isThemingEnabled || injectMap.theme) {
272+
return theming
273+
? theming.withTheme(Jss, {forwardInnerRef: true})
274+
: withTheme(Jss, {forwardInnerRef: true})
275+
}
276+
274277
return Jss
275278
}

packages/react-jss/src/types.js

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,9 @@
11
// @flow
2-
import type {StyleSheetFactoryOptions, Jss, SheetsRegistry, SheetsManager} from 'jss'
3-
import type {ComponentType, Node, ElementRef} from 'react'
2+
import type {StyleSheet, StyleSheetFactoryOptions, Jss, SheetsRegistry, SheetsManager} from 'jss'
3+
import type {Node, ElementRef} from 'react'
4+
import {type Theming} from 'theming'
45

56
export type Theme = {}
6-
export type SubscriptionId = string
7-
type Theming = {
8-
channel: string,
9-
withTheme: <P>(comp: ComponentType<P>) => ComponentType<P & {theme: Theme}>,
10-
ThemeProvider: ComponentType<{
11-
theme: Theme | ((outerTheme: Theme) => Theme),
12-
children: Node
13-
}>,
14-
themeListener: {
15-
contextTypes: {},
16-
initial: (context: {}) => Theme,
17-
subscribe: (context: {}, cb: (theme: Theme) => void) => SubscriptionId,
18-
unsubscribe: (context: {}, id: SubscriptionId) => void
19-
}
20-
}
217

228
export type Options = {
239
theming?: Theming,
@@ -27,8 +13,8 @@ export type Options = {
2713
export type InnerProps = {
2814
children?: Node,
2915
classes?: {},
30-
theme?: Theme,
31-
sheet?: {}
16+
theme: Theme,
17+
sheet?: StyleSheet | null
3218
}
3319
// Needs to be hard coded for stricter types
3420
export type Context = {

0 commit comments

Comments
 (0)