UNPKG

use-theme-editor

Version:

Zero configuration CSS variables based theme editor

142 lines (134 loc) 3.83 kB
import React, {useState} from 'react'; import { TextControl } from '../controls/TextControl'; export const sizeLikeProperties = [ 'font-size', 'border', 'border-width', 'border-bottom', 'border-bottom-width', 'line-height', 'border-radius', 'margin', 'margin-bottom', 'margin-top', 'margin-left', 'margin-right', 'padding', 'padding-bottom', 'padding-left', 'padding-right', 'padding-top', 'width', 'height', 'min-width', 'max-width', 'min-height', 'max-height', 'letter-spacing', 'outline-offset', 'top', 'bottom', 'left', 'right', 'outline-width', 'outline-offset', 'gap', ]; const remSize = 16; const convertRemToPixels = (rem) => rem * remSize; const convertPixelsToRem = (px) => px / remSize; const isPx = value => value && value.match(/[\d.]+px$/); const isRem = value => value && value.match(/[\d.]+rem$/); const isPercent = value => value && value.match(/\d%$/); const isVh = value => value && value.match(/vh$/); const isVw = value => value && value.match(/vw$/); export const SizeControl = props => { const {onChange, value} = props; const [step, setStep] = useState(.1); const pxValue = isPx(value) ? value.replace('px', '') : isRem(value) ? convertRemToPixels(parseFloat(value.replace('rem', ''))) : ''; const remValue = isRem(value) ? value.replace('rem', '') : isPx(value) ? convertPixelsToRem(parseFloat(value.replace('px', ''))) : ''; return <div className='theme-length-controls'> <div className={'theme-length-control control-px'} style={{clear: 'both'}}> <input type={ 'number' } value={pxValue} onChange={ event => { onChange(`${ event.currentTarget.value }px`); } } /> <span>px</span> </div> <div className={'theme-length-control control-rem'} > <input step={.1} type={ 'number' } value={remValue} onChange={ event => { onChange(`${ event.currentTarget.value }rem`); } } /> <span>rem</span> </div> <div className={'theme-length-control control-pct'}> <input type={ 'number' } value={ isPercent(value) ? value.replace('%', '') : ''} onChange={ event => { onChange(`${ event.currentTarget.value }%`); } } /> <span>%</span> </div> <div className={'theme-length-control control-vh'}> <input type={ 'number' } value={ isVh(value) ? value.replace('vh', '') : ''} onChange={ event => { onChange(`${ event.currentTarget.value }vh`); } } /> <span>vh</span> </div> <div className={'theme-length-control control-vw'}> <input type={ 'number' } value={ isVw(value) ? value.replace('vw', '') : ''} onChange={ event => { onChange(`${ event.currentTarget.value }vw`); } } /> <span>vw</span> </div> <div className={'theme-length-control control-no-unit'}> <input {...{step}} type={ 'number' } value={ /(^\d+(\.\d*)?$|^\.\d+$)/.test(value) ? value : ''} onChange={ event => { onChange(event.currentTarget.value); } } /> <span>[no unit]</span> <input type={ 'number' } value={ step } style={{fontSize: '10px'}} onChange={ event => { setStep(event.currentTarget.value); } } /> step </div> <button disabled={value === 0 || value === '0'} onClick={() => { onChange('0'); }} >0 </button> <TextControl value={ value } onChange={ onChange } /> </div>; };