Created
February 23, 2018 15:53
-
-
Save robinsandborg/3646d7aa22a39be6a8729c381ecb8be6 to your computer and use it in GitHub Desktop.
Weird styled-components bug
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
import React from "react" | |
import PropTypes from "prop-types" | |
import styled from "styled-components" | |
const CaretIcon = styled.svg` | |
width: 12px; | |
transition: fill 0.2s ease; | |
` | |
const Caret = ({ className }) => ( | |
<CaretIcon className={className} viewBox="0 0 24 16"> | |
<path d="M3.81 0a.54.54 0 0 0-.38.16L.16 3.47a.56.56 0 0 0 0 .78l11.45 11.59a.54.54 0 0 0 .78 0L23.84 4.25a.56.56 0 0 0 0-.78L20.57.17a.54.54 0 0 0-.77 0L12 8.04 4.2.16A.54.54 0 0 0 3.81 0z" /> | |
</CaretIcon> | |
) | |
Caret.propTypes = { className: PropTypes.string } | |
export default Caret |
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
import React from "react" | |
import PropTypes from "prop-types" | |
import styled from "styled-components" | |
const CloseIcon = styled.svg` | |
width: 12px; | |
transition: fill 0.2s ease; | |
` | |
const Close = ({ className }) => ( | |
<CloseIcon viewBox="0 0 24 24"> | |
<path d="M11.96 8a.54.54 0 0 1 .08 0L19.8.17a.54.54 0 0 1 .77 0l3.27 3.3c.21.22.21.56 0 .78L16.18 12l7.66 7.76c.2.21.2.56 0 .78l-3.27 3.3a.54.54 0 0 1-.77 0L12.04 16a.54.54 0 0 1-.08 0L4.2 23.85a.54.54 0 0 1-.77 0L.16 20.54a.56.56 0 0 1 0-.78L7.82 12 .16 4.25a.56.56 0 0 1 0-.78L3.43.16a.54.54 0 0 1 .77 0L11.96 8z" /> | |
</CloseIcon> | |
) | |
Close.propTypes = { className: PropTypes.string } | |
export default Close |
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
import React from "react" | |
import PropTypes from "prop-types" | |
import styled from "styled-components" | |
import Downshift from "downshift" | |
import multiplyPixelValue from "../../../functions/multiplyPixelValue" | |
import Label from "../Label/Label" | |
import Input from "../Input/Input" | |
import Caret from "../../Icons/Caret" | |
import Close from "../../Icons/Close" | |
const DefaultOptionElementWrapper = styled.div` | |
border: 1px solid ${p => p.theme.color.line}; | |
border-top-width: 0; | |
` | |
const SelectedWrapper = styled.div` | |
position: relative; | |
` | |
const IconButton = styled.button` | |
position: absolute; | |
right: ${p => p.theme.spacing.small}; | |
bottom: ${p => multiplyPixelValue(p.theme.targetSize.normal, 0.5)}; | |
width: ${p => p.theme.targetSize.small}; | |
height: ${p => p.theme.targetSize.small}; | |
border: 0; | |
padding: 0 ${p => p.theme.spacing.tiny}; | |
text-align: center; | |
background-color: transparent; | |
fill: ${p => p.theme.color.gray}; | |
transform: translateY(50%); | |
transition: fill 0.2s ease; | |
&:active, | |
&:hover, | |
&:focus { | |
outline: none; | |
svg { | |
fill: ${p => p.theme.color.primary}; | |
} | |
} | |
` | |
const DefaultPlaceholderElement = Input | |
const Select = ({ | |
children, | |
onChange, | |
label, | |
renderSelectedElement, | |
selectedElement, | |
renderOptionsWrapperElement, | |
optionsWrapperElement, | |
renderPlaceHolderElement, | |
placeHolderElement, | |
placeHolderLabel, | |
iconCaret, | |
iconClose | |
}) => { | |
const Selected = renderSelectedElement || selectedElement | |
const OptionsWrapper = | |
renderOptionsWrapperElement || | |
optionsWrapperElement || | |
DefaultOptionElementWrapper | |
const Placeholder = | |
renderPlaceHolderElement || placeHolderElement || DefaultPlaceholderElement | |
const CaretIcon = iconCaret || Caret | |
const CloseIcon = iconClose || Close | |
return ( | |
<Downshift | |
onChange={onChange} | |
itemToString={item => (item ? item.text : "")} | |
render={({ | |
getInputProps, | |
getButtonProps, | |
getItemProps, | |
isOpen, | |
inputValue, | |
selectedItem, | |
highlightedIndex, | |
toggleMenu, | |
clearSelection | |
}) => ( | |
<div> | |
<Label>{label}</Label> | |
{selectedItem ? ( | |
<SelectedWrapper> | |
<Selected | |
onClick={() => toggleMenu()} | |
selectedItem={selectedItem} | |
buttonProps={{ ...getButtonProps() }} | |
inputProps={{ ...getInputProps() }} | |
toggleMenu={toggleMenu} | |
/> | |
<IconButton onClick={() => clearSelection()}> | |
<CloseIcon /> | |
</IconButton> | |
</SelectedWrapper> | |
) : ( | |
<SelectedWrapper> | |
<Placeholder | |
{...getInputProps({ | |
placeholder: placeHolderLabel || "" | |
})} | |
onClick={() => toggleMenu()} | |
/> | |
<IconButton onClick={() => toggleMenu()}> | |
<CaretIcon /> | |
</IconButton> | |
</SelectedWrapper> | |
)} | |
{isOpen && ( | |
<OptionsWrapper> | |
{children.map((child, index) => { | |
const item = child.props.data | |
return React.cloneElement(child, { | |
...getItemProps({ item }), | |
...child.props, | |
highlighted: highlightedIndex === index, | |
selected: selectedItem === child | |
}) | |
})} | |
</OptionsWrapper> | |
)} | |
</div> | |
)} | |
/> | |
) | |
} | |
Select.propTypes = { | |
children: PropTypes.arrayOf(PropTypes.element).isRequired, | |
renderSelectedElement: (props, propName, componentName) => { | |
if (!props.renderSelectedElement && !props.selectedElement) { | |
return new Error( | |
`One of props 'renderSelectedElement' or 'selectedElement' was not specified in '${componentName}'.` | |
) | |
} | |
}, | |
selectedElement: (props, propName, componentName) => { | |
if (!props.renderSelectedElement && !props.selectedElement) { | |
return new Error( | |
`One of props 'renderSelectedElement' or 'selectedElement' was not specified in '${componentName}'.` | |
) | |
} | |
}, | |
items: PropTypes.array, | |
onChange: PropTypes.func, | |
optionsWrapperElement: PropTypes.func, | |
renderOptionsWrapperElement: PropTypes.func, | |
label: PropTypes.string, | |
placeHolderLabel: PropTypes.string, | |
renderPlaceHolderElement: PropTypes.func, | |
placeHolderElement: PropTypes.func, | |
iconCaret: PropTypes.element, | |
iconClose: PropTypes.element | |
} | |
export default Select |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment