UNPKG

@swrve/core

Version:

Core set of Swrve UI Components

59 lines (49 loc) 1.58 kB
import React, { useRef, useState } from 'react' import { bool, func, string } from 'prop-types' import { Icon } from '@swrve/icons' const CollapsibleButton = ({ label = 'Toggle content', onChange, open }) => { const itemIcon = open ? 'minus' : 'plus' return ( <button aria-expanded={open} className="flex items-center text-sm select-none text-secondary-100 hover:text-secondary-120 focus:outline-none ml-auto py-2 mr-1" onClick={onChange} > <span className="flex items-center justify-center w-4 h-4 mr-2 rounded-full bg-secondary-10"> <Icon name={itemIcon} size="xsmall" /> </span> {label} </button> ) } const Collapsible = ({ defaultIsOpen = false, children, isOpen, label, onChange, ...props }) => { const { current: isControlled } = useRef(isOpen != null) const [open, toggleOpen] = useState(() => (isControlled ? isOpen : defaultIsOpen)) function handleToggle(e) { e.preventDefault() onChange && onChange() if (!isControlled) { toggleOpen(!open) } } if (isControlled && isOpen !== open) { toggleOpen(isOpen) } return ( <div {...props}> {open && children} <CollapsibleButton label={label} open={open} onChange={handleToggle} /> </div> ) } export default Collapsible Collapsible.propTypes = { // Used to set initial state for uncontrolled version defaultIsOpen: bool, // isOpen & onChange used for controlled version isOpen: bool, onChange: func, // Text to show on toggle button label: string } Collapsible.displayName = 'Collapsible'