UNPKG

pure-styled-components

Version:

Styled Component design system based on Pure CSS for React/Preact

211 lines (178 loc) 4.2 kB
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } import React, { PureComponent } from "react"; import PropTypes from "prop-types"; import styled from "styled-components"; import addPropsToComponent from "../../utils/addPropsToComponent"; import Dropdown from "./Dropdown"; const dropdownArrow = (isHorizontal, isDropdown) => { if (isHorizontal && isDropdown) { return ` & .link:after { content: "\\25BE"; } `; } return ``; }; const scrollableMenu = isScrollable => { if (isScrollable) { return ` overflow-y: scroll; overflow-x: hidden; & .list { display: block; } `; } return ``; }; class BaseItem extends PureComponent { constructor(props) { super(props); _defineProperty(this, "handleDropdown", e => { const { active } = this.state; this.setState({ active: !active }); }); _defineProperty(this, "renderDropdown", () => { const { children } = this.props; const { active } = this.state; /** * Find Dropdown components and add active state as prop */ const propsToAdd = { active }; const elements = addPropsToComponent(children, Dropdown, propsToAdd); if (!elements) { return null; } return elements; }); this.state = { active: false }; } /** * Toggles active state of dropdown * * @memberof BaseItem * @private */ render() { const { className, classes } = this.props; return React.createElement("li", { className: `${className} ${classes}`, onMouseEnter: this.handleDropdown, onMouseLeave: this.handleDropdown, onFocus: this.handleDropdown, onBlur: this.handleDropdown }, this.renderDropdown()); } } BaseItem.propTypes = { /** * Class provided by Styled Components */ className: PropTypes.string.isRequired, /** * Additional classes to append to className */ classes: PropTypes.string, /** * Child components (array or single element) */ children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired }; BaseItem.defaultProps = { classes: "" }; const Item = styled(BaseItem)` position: relative; padding: 0; margin: 0; height: 100%; & .link:hover, & .link:focus { text-decoration: none; background-color: #eee; } & .link { display: block; text-decoration: none; white-space: nowrap; color: #777; padding: 0.5em 1em; } ${props => props.active ? ` & .link { background-color: #eee; }` : ``} ${props => props.disabled ? ` padding: .5em 1em; opacity: .5; & .link { background-color: transparent; }` : ``} ${props => props.dropdown ? ` padding: .5em 1em; opacity: .5; & .link { background-color: transparent; } & .link:after { padding-left: 0.5em; content: "\\25B8"; font-size: small; }` : ``} ${props => props.selected ? ` & > .link, & > .link:visited { color: #000; }` : ``} /* CSS fallback to display nested dropdowns on hover */ :active > .dropdown, :focus > .dropdown, :hover > .dropdown { display: block; position: absolute; } /* Horizontal Menus - show the dropdown arrow */ ${props => dropdownArrow(props.horizontal, props.dropdown)} ${props => scrollableMenu(props.scrollable)} `; Item.propTypes = { /** * Makes links appear active */ active: PropTypes.boolean, /** * Extra class names to append to element */ classes: PropTypes.string, /** * Makes links appear disabled */ disabled: PropTypes.boolean, /** * Adds necessary CSS for a nested Dropdown component */ dropdown: PropTypes.boolean, /** * Makes links appear selected */ selected: PropTypes.boolean }; /** @component */ export default Item; //# sourceMappingURL=Item.js.map