如何实现标签不可知风格的组件?

时间:2017-02-13 12:37:31

标签: javascript css reactjs styled-components

如果我想要一个按钮,但只有表示部分,所以如果我这样做:

import styled from 'styled-components'

const Button = styled.button`
  color: red;
  text-align: center;
`

我被迫渲染一个button标签,但是如果在语义上我需要一个锚点呢?

6 个答案:

答案 0 :(得分:5)

你也可以将它与锚标签一起使用,没有什么能阻止你。

import styled from 'styled-components'

const Button = styled.a`
  color: red;
  text-align: center;
`

如果你想同时保留这两种风格,你可以通过拉出来重复使用这些风格:

import styled from 'styled-components'

const styles = `
  color: red;
  text-align: center;
`

const Button = styled.button`
  ${styles}
`

const LinkButton = styled.a`
  ${styles}
`

答案 1 :(得分:5)

我在样式组件问题跟踪器上问了同样的问题:https://github.com/styled-components/styled-components/issues/494

当前"解决方案"我发现的是:

#include <chrono>
#include <iostream>

...

using namespace std;
using namespace chrono;
int repeats_count{};
decltype(cin.get()) last_char{};
decltype(high_resolution_clock::now()) last_input_time{};
auto const max_delay{200ms};
for(;;)
{
    auto const c{cin.get()};
    auto const now{high_resolution_clock::now()};
    auto const char_repeats{c == last_char};
    auto const delay_is_small_enough{(now - last_input_time) < max_delay};
    //  TODO print key based on pressed char and repeats count...
    if(char_repeats && delay_is_small_enough)
    {
        ++repeats_count;
    }
    else
    {
        repeats_count = 0;
    }
    last_char = c;
    last_input_time = now;
}

然后当你需要它时:

// agnosticStyled.js
import React from 'react'
import styled from 'styled-components'

export default styled(
  ({tag = 'div', children, ...props}) =>
    React.createElement(tag, props, children)
)

最后:

import React from 'react'
import styled from './agnosticStyled'

 const Button = styled`
   color: palevioletred;
   text-transform: uppercase;
 `

 export default Button

这是一个功能齐全的示例:https://codesandbox.io/s/6881pjMLQ

答案 2 :(得分:3)

使用"as" polymorphic prop in v4

从文档中的示例复制/粘贴:

const Component = styled.div`
  color: red;
`;

render(
  <Component
    as="button"
    onClick={() => alert('It works!')}
  >
    Hello World!
  </Component>
)

答案 3 :(得分:2)

由于我们只是使用JavaScript,为什么不使用函数?

const myButtonStyle = (styled, tag) => {
  return styled[tag]`
    color: red;
    text-align: center;
  `
}

const Button = myButtonStyle(styled, 'button')

答案 4 :(得分:2)

正如@typeoneerror所指出的,样式组件提供了WithComponent。您可以使用它来创建基于包含标记的prop的新组件。抄袭示例,它看起来像这样:

&#13;
&#13;
const _Button = styled.button`
  color: palevioletred;
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;
`;

const Button = ({ as: tag = 'button', children, ...props }) => {

  // We're replacing the <button> tag with whatever tag is assigned to the 'as' prop (renamed to 'tag' and defaulted to button), but reuse all the same styles
  
  const Composed = _Button.withComponent(tag);
  
  // We return the newly-created component with all its props and children
  
  return <Composed {...props}>{children}</Composed>;
};

render(
  <div>
    <Button>Normal Button</Button>
    <Button as='a'>Normal Link</Button>
  </div>
);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
&#13;
&#13;
&#13;

答案 5 :(得分:1)

样式化组件提供withComponent,这对于您希望对组件使用不同标记的情况非常有用。这类似于@siddharthkp的功能答案,但使用的是API。

文档中的示例:

const Button = styled.button`
  color: palevioletred;
  font-size: 1em;
  margin: 1em;
  padding: 0.25em 1em;
  border: 2px solid palevioletred;
  border-radius: 3px;
`;

// We're replacing the <button> tag with an <a> tag, but reuse all the same styles
const Link = Button.withComponent('a')

// Use .withComponent together with .extend to both change the tag and use additional styles
const TomatoLink = Link.extend`
  color: tomato;
  border-color: tomato;
`;

render(
  <div>
    <Button>Normal Button</Button>
    <Link>Normal Link</Link>
    <TomatoLink>Tomato Link</TomatoLink>
  </div>
);