import {Dispatch, RefObject, SetStateAction, useEffect, useState} from 'react'; import {Popper} from 'react-popper'; import styled from '@emotion/styled'; import Code from 'docs-ui/components/code'; import SelectField from 'sentry/components/forms/selectField'; import space from 'sentry/styles/space'; import BooleanField from 'sentry/views/settings/components/forms/booleanField'; import {iconProps} from './data'; import IconSample from './sample'; import {ExtendedIconData, SelectedIcon} from './searchPanel'; type Props = { icon: ExtendedIconData; setSelectedIcon: Dispatch>; boxRef: RefObject; }; const IconPopper = ({icon, setSelectedIcon, boxRef}: Props) => { /** * Editable icon props */ const [size, setSize] = useState(iconProps.size.default); const [direction, setDirection] = useState( icon.defaultProps?.direction ?? iconProps.direction.default ); const [type, setType] = useState(icon.defaultProps?.type ?? iconProps.type.default); const [isCircled, setIsCircled] = useState(icon.defaultProps?.isCircled ?? false); const [isSolid, setIsSolid] = useState(icon.defaultProps?.isSolid ?? false); /** * Generate and update code sample based on prop states */ const getCodeSample = () => { return ``; }; const [codeSample, setCodeSample] = useState(getCodeSample()); useEffect(() => { setCodeSample(getCodeSample()); }, [size, isCircled, isSolid]); /** * Deselect icon box on outside click */ const clickAwayHandler = e => { if (e.target !== boxRef && !boxRef?.contains?.(e.target)) { setSelectedIcon({group: '', icon: ''}); } }; useEffect(() => { document.addEventListener('click', clickAwayHandler); return () => document.removeEventListener('click', clickAwayHandler); }, []); return ( {({ref: popperRef, style, placement}) => { return ( , * otherwise it would trigger setSelectedIcon and deselect the icon box. */ onClick={e => e.stopPropagation()} > Size setSize(value as string)} clearable={false} /> {icon.additionalProps?.includes('direction') && ( Direction setDirection(value as string)} clearable={false} /> )} {icon.additionalProps?.includes('type') && ( Type setType(value as string)} clearable={false} /> )} {icon.additionalProps?.includes('isCircled') && ( setIsCircled(value)} /> )} {icon.additionalProps?.includes('isSolid') && ( setIsSolid(value)} /> )} {codeSample} ); }} ); }; export default IconPopper; const Wrap = styled('div')` text-align: left; max-width: 20rem; padding: ${space(2)}; padding-bottom: 0; background: ${p => p.theme.background}; border: solid 1px ${p => p.theme.border}; box-shadow: ${p => p.theme.dropShadowHeavy}; border-radius: ${p => p.theme.borderRadius}; z-index: ${p => p.theme.zIndex.modal}; cursor: initial; `; const SampleWrap = styled('div')` width: 100%; height: 4rem; display: flex; justify-content: center; align-items: center; margin: 0 auto ${space(3)}; `; const PropsWrap = styled('div')``; const SelectorWrap = styled('div')` display: flex; align-items: center; justify-content: space-between; &:not(:first-of-type) { padding-top: ${space(2)}; } &:not(:last-of-type) { padding-bottom: ${space(2)}; border-bottom: solid 1px ${p => p.theme.innerBorder}; } `; const SelectorLabel = styled('p')` margin-bottom: 0; `; const StyledSelectField = styled(SelectField)` width: 50%; padding-left: 10px; `; const StyledBooleanField = styled(BooleanField)` padding-left: 0; `;