packages/react/src/panels/SettingsPanel.tsx (83 lines of code) (raw):

import React, { useEffect, useState } from 'react' import { requestIdle } from '@designable/shared' import { observer } from '@formily/reactive-react' import { TextWidget, IconWidget } from '../widgets' import { usePrefix, useWorkbench } from '../hooks' import cls from 'classnames' export interface ISettingPanelProps { title?: React.ReactNode extra?: React.ReactNode } export const SettingsPanel: React.FC<ISettingPanelProps> = observer((props) => { const prefix = usePrefix('settings-panel') const workbench = useWorkbench() const [innerVisible, setInnerVisible] = useState(true) const [pinning, setPinning] = useState(false) const [visible, setVisible] = useState(true) useEffect(() => { if (visible || workbench.type === 'DESIGNABLE') { if (!innerVisible) { requestIdle(() => { requestAnimationFrame(() => { setInnerVisible(true) }) }) } } }, [visible, workbench.type]) if (workbench.type !== 'DESIGNABLE') { if (innerVisible) setInnerVisible(false) return null } if (!visible) { if (innerVisible) setInnerVisible(false) return ( <div className={prefix + '-opener'} onClick={() => { setVisible(true) }} > <IconWidget infer="Setting" size={20} /> </div> ) } return ( <div className={cls(prefix, { pinning })}> <div className={prefix + '-header'}> <div className={prefix + '-header-title'}> <TextWidget>{props.title}</TextWidget> </div> <div className={prefix + '-header-actions'}> <div className={prefix + '-header-extra'}>{props.extra}</div> {!pinning && ( <IconWidget infer="PushPinOutlined" className={prefix + '-header-pin'} onClick={() => { setPinning(!pinning) }} /> )} {pinning && ( <IconWidget infer="PushPinFilled" className={prefix + '-pin-filled'} onClick={() => { setPinning(!pinning) }} /> )} <IconWidget infer="Close" className={prefix + '-header-close'} onClick={() => { setVisible(false) }} /> </div> </div> <div className={prefix + '-body'}>{innerVisible && props.children}</div> </div> ) })