UNPKG

orcs-design-system

Version:
205 lines (203 loc) 8.4 kB
import React, { useMemo, useState } from "react"; import styled, { ThemeProvider } from "styled-components"; import PropTypes from "prop-types"; import Flex from "../Flex"; import Typography from "../Typography"; import Badge from "../Badge"; import { themeGet } from "@styled-system/theme-get"; import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; const Item = styled.div.withConfig({ displayName: "Expandable__Item", componentId: "sc-na4gdb-0" })(["margin:4px 0;"]); const Button = styled.button.withConfig({ displayName: "Expandable__Button", componentId: "sc-na4gdb-1" })(["position:relative;display:block;border:none;-moz-appearance:none;-webkit-appearance:none;appearance:none;box-shadow:none;font-family:\"Open Sans\",\"Helvetica Neue\",Helvetica,Arial,sans-serif;cursor:pointer;width:100%;margin:0;font-size:", ";text-align:left;color:", ";padding:", ";}border-left:solid 3px ", ";border-radius:", ";background:", ";transition:", ";&:hover{background:", ";border-left:solid 3px ", ";}&:focus{outline:0;border-left:solid 3px ", ";}&:after,&:before{content:\"\";position:absolute;top:50%;transform:translateY(-50%);width:2px;height:12px;right:", ";background-color:", ";transition:", ";}&:before{transform:", ";}&:after{transform:translateY(-50%) rotate(90deg);}"], props => themeGet("fontSizes.3")(props), props => themeGet("colors.greyDarker")(props), props => props.small ? "8px 33px 8px 8px" : "18px 48px 18px 16px", props => themeGet("colors.greyLightest")(props), props => themeGet("radii.1")(props), props => themeGet("colors.greyLightest")(props), props => themeGet("transition.transitionDefault")(props), props => themeGet("colors.greyLighter")(props), props => themeGet("colors.greyLighter")(props), props => themeGet("colors.primary")(props), props => props.small ? "16px" : "24px", props => themeGet("colors.greyDark")(props), props => themeGet("transition.transitionDefault")(props), props => props.open ? "translateY(-50%) rotate(90deg)" : "translateY(-50%)"); const Text = styled.div.withConfig({ displayName: "Expandable__Text", componentId: "sc-na4gdb-2" })(["padding-right:18px;"]); const SubTitle = styled(Typography.Small).withConfig({ displayName: "Expandable__SubTitle", componentId: "sc-na4gdb-3" })(["display:block;"]); const Content = styled.div.withConfig({ displayName: "Expandable__Content", componentId: "sc-na4gdb-4" })(["padding:", ";transition:", ";display:", ";"], props => themeGet("space.r")(props), props => themeGet("transition.transitionDefault")(props), props => props.open ? "block" : "none"); /** * This component is to be used when there is a lot of content to present on a page that can instead be split into expandable sections to aid in user comprehension and explorability, rather than overwhelming the user with a whole page of content. * * A single expandable can also be used, for example if you had some content, but wanted to also have some additional less important subsidiary content hidden away unless the user wants to explore further, e.g. A few paragraphs on a company description, followed by an expandable with the title 'Read more about the history of this company'. * * This component supports any child elements, not just text, can be other components or any content you like. */ export default function Expandable(_ref) { let { children, title, subtitle, badge, badgeColour, isOpen, small, theme, ...props } = _ref; const [baseState, setBase] = useState(isOpen); const [toggleState, setToggle] = useState(false); const Heading = useMemo(() => { return small ? Typography.H5 : Typography.H4; }, [small]); const onToggle = () => { if (!toggleState) setToggle(true);else setToggle(false); if (!baseState) setBase(true);else setBase(false); }; const component = /*#__PURE__*/_jsxs(Item, { ...props, children: [/*#__PURE__*/_jsx(Heading, { children: /*#__PURE__*/_jsx(Button, { open: baseState, small: small, "aria-expanded": baseState, onClick: onToggle, children: /*#__PURE__*/_jsxs(Flex, { alignItems: "center", justifyContent: "space-between", children: [/*#__PURE__*/_jsxs(Text, { children: [title, subtitle && /*#__PURE__*/_jsx(SubTitle, { grey: true, children: subtitle })] }), badge && /*#__PURE__*/_jsx(Badge, { variant: badgeColour, children: badge })] }) }) }), /*#__PURE__*/_jsx(Content, { open: baseState, expanded: toggleState, children: children })] }); return theme ? /*#__PURE__*/_jsx(ThemeProvider, { theme: theme, children: component }) : component; } Expandable.propTypes = { /** Sets expandable to open state by default */ isOpen: PropTypes.bool, /** Sets the styling to be a smaller version of the expandable */ small: PropTypes.bool, /** Expandable title */ title: PropTypes.oneOfType([PropTypes.string, PropTypes.func, PropTypes.object]), /** Expandable subtitle */ subtitle: PropTypes.oneOfType([PropTypes.string, PropTypes.func, PropTypes.object]), /** Adds a badge with text as string */ badge: PropTypes.string, /** Specifies badge colour */ badgeColour: PropTypes.oneOf(["success", "warning", "danger", "primaryLight", "primaryDark", "primaryDarkest"]), /** Contents of expandable are rendered as a child element. */ children: PropTypes.element, /** Specifies the system design theme. */ theme: PropTypes.object }; Expandable.__docgenInfo = { "description": "This component is to be used when there is a lot of content to present on a page that can instead be split into expandable sections to aid in user comprehension and explorability, rather than overwhelming the user with a whole page of content.\n\nA single expandable can also be used, for example if you had some content, but wanted to also have some additional less important subsidiary content hidden away unless the user wants to explore further, e.g. A few paragraphs on a company description, followed by an expandable with the title 'Read more about the history of this company'.\n\nThis component supports any child elements, not just text, can be other components or any content you like.", "methods": [], "displayName": "Expandable", "props": { "isOpen": { "description": "Sets expandable to open state by default", "type": { "name": "bool" }, "required": false }, "small": { "description": "Sets the styling to be a smaller version of the expandable", "type": { "name": "bool" }, "required": false }, "title": { "description": "Expandable title", "type": { "name": "union", "value": [{ "name": "string" }, { "name": "func" }, { "name": "object" }] }, "required": false }, "subtitle": { "description": "Expandable subtitle", "type": { "name": "union", "value": [{ "name": "string" }, { "name": "func" }, { "name": "object" }] }, "required": false }, "badge": { "description": "Adds a badge with text as string", "type": { "name": "string" }, "required": false }, "badgeColour": { "description": "Specifies badge colour", "type": { "name": "enum", "value": [{ "value": "\"success\"", "computed": false }, { "value": "\"warning\"", "computed": false }, { "value": "\"danger\"", "computed": false }, { "value": "\"primaryLight\"", "computed": false }, { "value": "\"primaryDark\"", "computed": false }, { "value": "\"primaryDarkest\"", "computed": false }] }, "required": false }, "children": { "description": "Contents of expandable are rendered as a child element.", "type": { "name": "element" }, "required": false }, "theme": { "description": "Specifies the system design theme.", "type": { "name": "object" }, "required": false } } };