-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add basic CssVars implementation
- Loading branch information
Showing
3 changed files
with
160 additions
and
8 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,74 @@ | ||
import {Component} from 'react'; | ||
import {Provider, Consumer} from '../context'; | ||
import {h} from '../util'; | ||
import renderProp from '../util/renderProp'; | ||
|
||
const vars = { | ||
color: 'red' | ||
}; | ||
let idCnt = 0; | ||
|
||
// export class CssVarsProvider extends Component<any, any> { | ||
// render () { | ||
// return this.props.children; | ||
// } | ||
// } | ||
const supportsCssVariables = typeof window === 'object' && (window as any).CSS && CSS.supports && CSS.supports('--a', '0'); | ||
|
||
export type TVars = {[name: string]: string}; | ||
|
||
export interface ICssVarsProviderProps { | ||
ns?: string; | ||
prefix?: string; | ||
vars: TVars; | ||
} | ||
|
||
export interface ICssVarsProviderState { | ||
} | ||
|
||
export class CssVarsProvider extends Component<ICssVarsProviderProps, ICssVarsProviderState> { | ||
vars: TVars = {}; | ||
|
||
constructor (props, context) { | ||
super(props, context); | ||
|
||
this.updateVars(props.vars); | ||
} | ||
|
||
updateVars (vars: TVars) { | ||
if (supportsCssVariables) { | ||
const {prefix = ''} = this.props; | ||
const {style} = document.documentElement; | ||
|
||
for (const name in vars) { | ||
const id = (idCnt++).toString(36); | ||
const varName = `---${prefix}${id}`; | ||
|
||
this.vars[name] = `var(${varName})`; | ||
style.setProperty(varName, String(vars[name])); | ||
} | ||
} else { | ||
this.vars = vars; | ||
} | ||
} | ||
|
||
render () { | ||
return h(Provider, { | ||
name: 'css/' + this.props.ns, | ||
value: this.vars | ||
}, | ||
this.props.children | ||
); | ||
} | ||
} | ||
|
||
export interface ICssVarsProps { | ||
children?: any; | ||
render?: any; | ||
component?: any; | ||
comp?: any; | ||
ns?: string; | ||
} | ||
|
||
export interface ICssVarsState { | ||
} | ||
|
||
export class CssVars extends Component<ICssVarsProps, ICssVarsState> { | ||
render () { | ||
return h(Consumer, {name: 'css/' + this.props.ns}, (vars) => { | ||
return renderProp(this.props, vars); | ||
}); | ||
} | ||
} |
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,50 @@ | ||
import {Component, createElement as h} from 'react'; | ||
import {CssVarsProvider, CssVars} from '..'; | ||
|
||
const Print = (props) => <pre style={{fontFamily: 'monospace'}}>{JSON.stringify(props, null, 4)}</pre>; | ||
|
||
export class Example1 extends Component<any, any> { | ||
el; | ||
vars; | ||
|
||
ref = (el) => { | ||
this.el = el; | ||
}; | ||
|
||
componentDidMount () { | ||
this.applyCssVars(); | ||
} | ||
|
||
componentDidUpdate () { | ||
this.applyCssVars(); | ||
} | ||
|
||
applyCssVars () { | ||
if (this.el && this.vars) { | ||
for (const name in this.vars) { | ||
console.log('name, this.vars[name]', name, this.vars[name]); | ||
this.el.style.setProperty(name, this.vars[name]); | ||
} | ||
} | ||
} | ||
|
||
render () { | ||
return ( | ||
<CssVarsProvider vars={{ | ||
color: 'tomato', | ||
border: '1px solid tomato' | ||
}}> | ||
<CssVars>{(vars) => { | ||
this.vars = vars; | ||
|
||
return ( | ||
<div> | ||
<Print {...vars} /> | ||
<button ref={this.ref}>Click me!</button> | ||
</div> | ||
); | ||
}}</CssVars> | ||
</CssVarsProvider> | ||
); | ||
} | ||
} |
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,39 @@ | ||
import {createElement as h} from 'react'; | ||
import {storiesOf} from '@storybook/react'; | ||
import {action} from '@storybook/addon-actions'; | ||
import {linkTo} from '@storybook/addon-links'; | ||
import ShowDocs from '../../../.storybook/ShowDocs' | ||
import {CssVarsProvider, CssVars} from '..'; | ||
import {Example1} from './Example1'; | ||
|
||
const Print = (props) => <pre style={{fontFamily: 'monospace'}}>{JSON.stringify(props, null, 4)}</pre>; | ||
|
||
storiesOf('Context/CSS Variables', module) | ||
// .add('Documentation', () => h(ShowDocs, {md: require('../../../docs/en/FocusSensor.md')})) | ||
.add('Basic example', () => <Example1 />) | ||
.add('Inline style', () => | ||
<CssVarsProvider vars={{ | ||
color: 'tomato', | ||
border: '1px solid tomato' | ||
}}> | ||
<CssVars>{(vars) => | ||
<div> | ||
<Print {...vars} /> | ||
<button style={vars}>Click me!</button> | ||
</div> | ||
}</CssVars> | ||
</CssVarsProvider> | ||
) | ||
.add('With namespace', () => | ||
<CssVarsProvider ns='namespace' prefix='prefix-' vars={{ | ||
color: 'tomato', | ||
border: '1px solid tomato' | ||
}}> | ||
<CssVars ns='namespace'>{(vars) => | ||
<div> | ||
<Print {...vars} /> | ||
<button style={vars}>Click me!</button> | ||
</div> | ||
}</CssVars> | ||
</CssVarsProvider> | ||
) |