UNPKG

react-font-style

Version:
207 lines (192 loc) 6.46 kB
// @flow import * as React from 'react'; import ButtonGroup from './ui/ButtonGroup'; import IconButton from './ui/IconButton'; import Dropdown from './ui/Dropdown'; import FontFamilyDropdown from './ui/FontFamilyDropdown'; import Palette from './Palette'; import {generateConfig, generateConfigState, stateToStyle} from './config'; type toobacConfigType = { type: string, label: string, style: Object } type Props = { defaultStyle?: Object, customConfig?: Object, text?: string, customizedPlugin?: React.Element<*>, textComponent?: React.Element<*>, onChange: (style: Object) => void }; type State = { showPalette: false | 'highlight' | 'font', activeInlineStyle: Object, activeFontSize: number, activeColor: string, activeBackgroundColor: string, activeLineHeight: number, activeAlign: string, activeFontFamily: string, config: { ALIGN_DROPDOWN: Array<toobacConfigType>, FONT_FAMILY_DROPDOWN: Array<toobacConfigType>, FONT_SIZE_DROPDOWN: Array<toobacConfigType>, INLINE_STYLE_BUTTONS: Array<toobacConfigType>, LINE_HEIGHT_DROPDOWN: Array<toobacConfigType>, alignObj: Object, display: Array<string>, fontFamiltyObj: Object, fontSizeObj: Object, inlineStyleObj: Object, lineHeightObj: Object }, fontStyle: Object }; export default class ReactFontStyle extends React.Component<Props, State> { constructor(props: Props) { super(props); const config = generateConfig(props.customConfig); const state = generateConfigState(config, props.defaultStyle); this.state = { ...state, showPalette: false, config, fontStyle: stateToStyle({...state, config}) }; } static defaultProps = { defaultStyle: {}, text: 'ABCD' } togglePalette = (show: false | 'highlight' | 'font') => { const {showPalette} = this.state; let newShowPalette; if (show === showPalette) { newShowPalette = false; } else { newShowPalette = show; } this.setState({showPalette: newShowPalette}); } handleInlineStyleChange = (type: string) => { const {activeInlineStyle} = this.state; activeInlineStyle[type] = !activeInlineStyle[type]; this.onChange(activeInlineStyle); } handleChangeFontSize = (label: number) => { this.onChange({activeFontSize: label}); } handleChangeFontFamily = (label: number) => { this.onChange({activeFontFamily: label}); } handleLineHeight = (label: number) => { this.onChange({activeLineHeight: label}); } handleAlign = (label: string) => { this.onChange({activeAlign: label}); } handleColorChange = (color: {hex: string, rgba: Object}) => { const {showPalette} = this.state; const {hex} = color; if (showPalette === 'font') { this.onChange({activeColor: hex}); } else if (showPalette === 'highlight') { this.onChange({activeBackgroundColor: hex}); } } onChange = (updated: Object) => { const newState = {...this.state, ...updated}; const fontStyle = stateToStyle(newState); this.setState({...newState, fontStyle}); if (this.props.onChange) { this.props.onChange(fontStyle); } } render() { const { activeInlineStyle, activeFontSize, activeColor, activeBackgroundColor, activeLineHeight, activeAlign, activeFontFamily, showPalette, config, fontStyle } = this.state; const {text, customizedPlugin, textComponent} = this.props; return ( <div> {config.display.includes('INLINE_STYLE_BUTTONS') ? <ButtonGroup> {config.INLINE_STYLE_BUTTONS.map((item: toobacConfigType) => ( <IconButton key={item.type} iconName={item.type} isActive={activeInlineStyle[item.type]} onMouseDown={() => this.handleInlineStyleChange(item.type)} /> ))} </ButtonGroup> : null} {config.display.includes('FONT_COLOR_BUTTON') || config.display.includes('FONT_HIGHLIGHT_BUTTON')? <ButtonGroup> {config.display.includes('FONT_HIGHLIGHT_BUTTON') ? <IconButton iconName="mark" onMouseDown={() => this.togglePalette('highlight')} isActive={showPalette === 'highlight'}/> : null} {config.display.includes('FONT_COLOR_BUTTON') ? <IconButton iconName="color" onMouseDown={() => this.togglePalette('font')} isActive={showPalette === 'font'}/> : null} </ButtonGroup> : null} {config.display.includes('FONT_SIZE_DROPDOWN') ? <Dropdown choices={config.FONT_SIZE_DROPDOWN} selectedKey={activeFontSize} onChange={this.handleChangeFontSize} icon='font' /> : null} {config.display.includes('FONT_FAMILY_DROPDOWN') ? <FontFamilyDropdown choices={config.FONT_FAMILY_DROPDOWN} selectedKey={activeFontFamily} onChange={this.handleChangeFontFamily} icon='font' /> : null} {config.display.includes('LINE_HEIGHT_DROPDOWN') ? <Dropdown choices={config.LINE_HEIGHT_DROPDOWN} selectedKey={activeLineHeight} icon='lineheight' onChange={this.handleLineHeight} /> : null} {config.display.includes('ALIGN_DROPDOWN') ? <Dropdown choices={config.ALIGN_DROPDOWN} selectedKey={activeAlign} icon={ activeAlign === 'Align Left' ? 'align-left' : activeAlign === 'Align Center' ? 'align-center' : 'align-right' } onChange={this.handleAlign} /> : null} {customizedPlugin ? customizedPlugin : null} {showPalette ? <Palette color={showPalette === 'font' ? activeColor : activeBackgroundColor} onChange={this.handleColorChange}/> : null} {textComponent ? textComponent : <div style={{padding: '20px 10px', backgroundColor: '#eee'}}> <div style={fontStyle}> {text} </div> </div> } </div> ); } }