1.0.5 • Published 6 years ago

react-css-pseudo v1.0.5

Weekly downloads
2
License
ISC
Repository
github
Last release
6 years ago

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的状态我们修改 divinnerText:

<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-nativeView

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.
1.0.5

6 years ago

1.0.3

6 years ago

1.0.2

6 years ago

1.0.1

6 years ago