UNPKG

@retailmenot/anchor

Version:

A React UI Library by RetailMeNot

167 lines (153 loc) 5.93 kB
var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; // REACT import * as React from 'react'; // VENDOR import classNames from 'classnames'; import styled, { css } from '@xstyled/styled-components'; import { variant as createVariant, th, space as spaceStyles, } from '@xstyled/system'; // Components import { ChevronDown, ChevronUp } from '../Icon'; export const DEFAULT_OPENED_TEXT = 'Close'; export const DEFAULT_CLOSED_TEXT = 'Open'; const DEFAULT_VARIANT = 'comfortable'; const variants = { comfortable: css ` padding: 1rem 2rem; border-top: solid thin ${th.color('borders.base')}; border-bottom: solid thin ${th.color('borders.base')}; .anchor-collapse-button { appearance: none; background-color: transparent; /* All but Chrome show a grey button bg color despite 'appearance: none' */ cursor: pointer; display: flex; justify-content: space-between; width: 100%; text-align: left; border-style: none; font-weight: 500; font-size: 0.875rem; padding: 0.5rem 0; user-select: none; &:focus { outline: none; } > *:last-child { flex: 0 0 auto; margin-left: 0.5em; } } .anchor-collapse-content { font-size: 1rem; text-align: left; padding: 0.5rem 0; } `, compact: css ` color: text.light; .anchor-collapse-button { appearance: none; background-color: white; /* All but Chrome show a grey button bg color despite 'appearance: none' */ border-style: none; border-bottom: light; border-top: light; color: text.light; cursor: pointer; display: flex; justify-content: space-between; font-weight: bold; height: 3rem; padding: 0 1.3125rem; text-align: left; user-select: none; width: 100%; &:focus { outline: none; } > *:last-child { flex: 0 0 auto; margin-left: 0.5em; } } .anchor-collapse-content { background-color: background.light; ul { padding: 0; margin: 0; list-style-type: none; } // TODO: we shouldn't be using as many fragile nested selectors and we should be using Typography li a { display: block; padding-left: 3.4375rem; height: 2.6875rem; line-height: 2.6875rem; cursor: pointer; font-size: 0.875rem; color: #222; &:hover { background-color: rgba(0, 126, 205, 0.1); } } } `, none: css({}), }; const variantStyles = createVariant({ key: 'collapse.variants', prop: 'variant', default: DEFAULT_VARIANT, variants: variants, }); const StyledCollapse = styled('div') ` display: block; box-sizing: border-box; font-family: base; ${variantStyles} &.no-bottom-border { border-bottom-style: none; .anchor-collapse-button { border-bottom-style: none; } } .anchor-collapse-content.inactive { display: none; } ${spaceStyles} `; StyledCollapse.displayName = 'StyledCollapse'; export const Collapse = (_a) => { var { isOpen = false, openedText = DEFAULT_OPENED_TEXT, closedText = DEFAULT_CLOSED_TEXT, openedIcon, closedIcon, variant = DEFAULT_VARIANT, onClick, hasBottomBorder = true, removeInactive = true, className, children } = _a, props = __rest(_a, ["isOpen", "openedText", "closedText", "openedIcon", "closedIcon", "variant", "onClick", "hasBottomBorder", "removeInactive", "className", "children"]); const [open, toggleOpen] = React.useState(isOpen); const IconOpened = openedIcon || React.createElement(ChevronUp, null); const IconClosed = closedIcon || React.createElement(ChevronDown, null); // If the user provides custom openedText but not custom closedText // then use openedText for closedText as well const textClosed = openedText !== DEFAULT_OPENED_TEXT && closedText === DEFAULT_CLOSED_TEXT ? openedText : closedText; // Allows for the programmatic opening/closing of the Collapse // without a user having to click it React.useEffect(() => { toggleOpen(isOpen); }, [isOpen]); return (React.createElement(StyledCollapse, Object.assign({ variant: variant, className: classNames('anchor-collapse', open && 'open', variant, !hasBottomBorder && 'no-bottom-border', className) }, props), React.createElement("button", { onClick: onClick || (() => toggleOpen(!open)), className: "anchor-collapse-button" }, open ? (React.createElement(React.Fragment, null, openedText, " ", IconOpened)) : (React.createElement(React.Fragment, null, textClosed, " ", IconClosed))), (open || !removeInactive) && (React.createElement("section", { className: classNames('anchor-collapse-content', !open && 'inactive') }, children)))); }; //# sourceMappingURL=Collapse.component.js.map