react-css-pseudo
v1.0.5
Published
CSS in JS 很棒, 但是如何处理方便的处理伪类(Pseudo-classes)? **react-css-pseudo** 提供一个类似 `react-motion` 方式的组件,方便的为 `react-dom` 对象提供类似 CSS 的伪类.
Downloads
1
Readme
react-css-pseudo
CSS in JS 很棒, 但是如何处理方便的处理伪类(Pseudo-classes)? react-css-pseudo 提供一个类似 react-motion
方式的组件,方便的为 react-dom
对象提供类似 CSS 的伪类.
我们首先用 npm
安装:
$ npm install --save react-css-pseudo
使用
react-css-pseudo 支持以下伪类:
- :hover: 对应
hoverStyle
; - :focus: 对应
focusStyle
; - :active: 对应
activeStyle
; - :link: 对应
linkStyle
; - :visited: 对应
visitedStyle
;
import Pseudo from 'react-css-pseudo';
export default () => {
return (
<div>
<div>
- 当我们需要给一个 input 组件添加 :focus 和 :hover伪类时, -
我们用Pseudo将 input 组件包裹起来,并且用 renderProps 的方式把 events
传递到 input 组件中 - 如下例子, 我们添加 hoverStyle、focusStyle 来达到
:hover 和 :focus 伪类
</div>
<Pseudo
style={sheet.input}
hoverStyle={sheet.inputHover}
focusStyle={sheet.inputFocus}
>
{events => <input {...events} />}
</Pseudo>
</div>
);
};
// CSS in js
const sheet = {
input: {
fontSize: '14px',
border: '1px solid rgba(0,0,0,0)',
background: '#f3f3f3',
transition: 'all 0.2s ease-out',
},
inputHover: {
background: '#f0f0f0',
},
inputFocus: {
border: '1px solid rgba(0,0,0,0.1)',
background: '#f0f0f3',
transitionTimingFunction: 'ease-in',
},
};
我们在浏览器里预览一下,很轻松的达到了我们的目的
原理
Pseudo 的 renderProps 中包含以下事件
- onClick: 用来模拟 :link 和 :visited 伪类
- onFocus\Blur: 用来模拟 :focus 伪类
- onMouseEnter\Leave: 用来模拟 :hover 伪类
- onMouseDown\Up: 用来模拟 :active 伪类
如果项目在移动端执行,就会把 onMouse?
相关的事件替换成 onTouch?
以兼容移动端
renderProps 的方式相比我直接定一个 Input
组件有什么优势?
我们先看看如果我们直接定义一个 Input 组件,来模拟 :hover 伪类
// 以下代码直接在 markdown 中编写,并无经过运行,仅用于阐述观点
class Input extend React.Component {
state = {
hover: false
}
handleMouseEnter = ()=>{
this.setState({ hover: true });
}
handleMouseLeave = ()=>{
this.setState({ hover: false });
}
render(){
return <input style={this.state.hover?{...this.props.style, ...this.props.hoverStyle}:this.props.style} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} />
}
}
然后我们在项目中使用:
<Input style={inputStyle} hover={inputHoverStyle} />
一切看起来不错,但是它不利于扩展, 例如:我们如果需要给一个 div
也添加以上功能,我们需要再写一个 Div 组件, 还是需要重写以上的代码,同理如果我们要给其他已存在的 SignButton
, LoginButton
等组件添加功能,也需要创建一个新的类似于 SignButtonHover
的组件
<Input style={inputStyle} hover={inputHoverStyle} />
<Div style={inputStyle} hover={inputHoverStyle} />
<SignButtonHover style={inputStyle} hover={inputHoverStyle} />
当然,我们也可以使用 HOC 的方式, 编写一个 withHover
的组件:
const SignButton = withHover(SignButton);
对比之下,就没有 RenderProps
的方式优雅:
<Pseudo style={inputStyle} hoverStyle={inputHoverStyle}>
{events => <input {...events} />}
</Pseudo>
<Pseudo style={inputStyle} hoverStyle={inputHoverStyle}>
{events => <div {...events} />}
</Pseudo>
<Pseudo style={inputStyle} hoverStyle={inputHoverStyle}>
{events => <SignButton {...events} />}
</Pseudo>
react-css-pseudo
还可以更简化么?
由于如果子对象是一个 div
或是一个 数组
时,觉得使用 childrenFuncion
的意义不大,所以可以把简写:
// 可以简写成如下, 此时 Pseudo 是一个 div组件
<Pseudo style={inputStyle} hoverStyle={inputHoverStyle} />
// 同理,多个子元素,也可以这样
<Pseudo style={inputStyle} hoverStyle={inputHoverStyle}>
<p>多个子元素</p>
<img src="xxx"/>
<div>父级相当于一个div</div>
</Pseudo>
我如何获取 hover、active 等状态,做除了样式之外的其他事件?
renderProps 的参数还有第二个,是 Pseudo
内部的 state
, 我们可以获取它之后做其他事件, 如下面的例子,根据hover的状态我们修改 div
的 innerText
:
<Pseudo style={inputStyle} hoverStyle={inputHoverStyle}>
{(events, state) => {
const mouseState = state.hover ? 'mouseIn' : 'mouseOut';
return <div>{mouseState}</div>;
}}
</Pseudo>
react-css-pseudo
支持 react-native
吗?
由于 react-css-pseudo
用到了 ReactDOM
的事件,所以不支持 react-native
, 当然欢迎有这类需求的朋友 fork 一份,把 ReactDOM
事件改成 touchable
事件,把 div
改成 react-native
的 View
react-css-pseudo
仅仅是参考了 react-motion
的风格提供了一种模拟 css 伪类的思路
License
MIT License
Copyright (c) 2013-present, Facebook, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.