UNPKG

@wordpress/components

Version:
233 lines (214 loc) 6.06 kB
/** * External dependencies */ import { View, Text, TouchableWithoutFeedback } from 'react-native'; /** * WordPress dependencies */ import { __ } from '@wordpress/i18n'; import { useState, useContext } from '@wordpress/element'; import { usePreferredColorSchemeStyle } from '@wordpress/compose'; import { useRoute, useNavigation } from '@react-navigation/native'; /** * Internal dependencies */ import ColorPalette from '../../color-palette'; import ColorIndicator from '../../color-indicator'; import NavBar from '../bottom-sheet/nav-bar'; import SegmentedControls from '../segmented-control'; import { colorsUtils } from './utils'; import PanelBody from '../../panel/body'; import { BottomSheetContext } from '../bottom-sheet/bottom-sheet-context'; import ColorControl from '../../color-control'; import styles from './style.scss'; const HIT_SLOP = { top: 8, bottom: 8, left: 8, right: 8 }; const PaletteScreen = () => { const route = useRoute(); const navigation = useNavigation(); const { shouldEnableBottomSheetScroll } = useContext( BottomSheetContext ); const { label, onColorChange, onGradientChange, onColorCleared, colorValue, defaultSettings, hideNavigation = false, } = route.params || {}; const { segments, isGradient } = colorsUtils; const [ currentValue, setCurrentValue ] = useState( colorValue ); const isGradientColor = isGradient( currentValue ); const selectedSegmentIndex = isGradientColor ? 1 : 0; const [ currentSegment, setCurrentSegment ] = useState( segments[ selectedSegmentIndex ] ); const isGradientSegment = currentSegment === colorsUtils.segments[ 1 ]; const currentSegmentColors = ! isGradientSegment ? defaultSettings.colors : defaultSettings.gradients; const allAvailableColors = defaultSettings?.allAvailableColors || []; const allAvailableGradients = currentSegmentColors .flatMap( ( { gradients } ) => gradients ) .filter( Boolean ); const horizontalSeparatorStyle = usePreferredColorSchemeStyle( styles.horizontalSeparator, styles.horizontalSeparatorDark ); const clearButtonStyle = usePreferredColorSchemeStyle( styles.clearButton, styles.clearButtonDark ); const selectedColorTextStyle = usePreferredColorSchemeStyle( styles.colorText, styles.colorTextDark ); const isSolidSegment = currentSegment === segments[ 0 ]; const isCustomGadientShown = ! isSolidSegment && isGradientColor; const setColor = ( color ) => { setCurrentValue( color ); if ( isSolidSegment && onColorChange && onGradientChange ) { onColorChange( color ); } else if ( isSolidSegment && onColorChange ) { onColorChange( color ); } else if ( ! isSolidSegment && onGradientChange ) { onGradientChange( color ); } }; function onClear() { setCurrentValue( undefined ); if ( onColorCleared ) { onColorCleared(); } } function onCustomPress() { if ( isSolidSegment ) { navigation.navigate( colorsUtils.screens.picker, { currentValue, setColor, } ); } else { navigation.navigate( colorsUtils.screens.gradientPicker, { setColor, isGradientColor, currentValue, } ); } } function getClearButton() { return ( <TouchableWithoutFeedback accessibilityLabel={ __( 'Clear selected color' ) } onPress={ onClear } hitSlop={ HIT_SLOP } > <View style={ styles.clearButtonContainer }> <Text style={ clearButtonStyle }>{ __( 'Reset' ) }</Text> </View> </TouchableWithoutFeedback> ); } function getFooter() { if ( onGradientChange ) { return ( <SegmentedControls segments={ segments } segmentHandler={ setCurrentSegment } selectedIndex={ segments.indexOf( currentSegment ) } addonLeft={ currentValue && ( <ColorIndicator color={ currentValue } style={ styles.colorIndicator } /> ) } addonRight={ currentValue && getClearButton() } /> ); } return ( <View style={ styles.footer }> <View style={ styles.flex }> { currentValue && ( <ColorIndicator color={ currentValue } style={ styles.colorIndicator } /> ) } </View> { currentValue ? ( <Text style={ selectedColorTextStyle } maxFontSizeMultiplier={ 2 } selectable > { currentValue.toUpperCase() } </Text> ) : ( <Text style={ styles.selectColorText } maxFontSizeMultiplier={ 2 } > { __( 'Select a color above' ) } </Text> ) } <View style={ styles.flex }> { currentValue && getClearButton() } </View> </View> ); } return ( <View> { ! hideNavigation && ( <NavBar> <NavBar.BackButton onPress={ navigation.goBack } /> <NavBar.Heading>{ label } </NavBar.Heading> </NavBar> ) } <View style={ styles.colorPalettes }> { currentSegmentColors.map( ( palette, paletteKey ) => { const paletteSettings = { colors: palette.colors, gradients: palette.gradients, allColors: allAvailableColors, allGradients: allAvailableGradients, }; // Limit to show the custom indicator to the first available palette const enableCustomColor = paletteKey === 0; return ( <ColorPalette enableCustomColor={ enableCustomColor } label={ palette.name } key={ paletteKey } setColor={ setColor } activeColor={ currentValue } isGradientColor={ isGradientColor } currentSegment={ currentSegment } onCustomPress={ onCustomPress } shouldEnableBottomSheetScroll={ shouldEnableBottomSheetScroll } defaultSettings={ paletteSettings } /> ); } ) } </View> { isCustomGadientShown && ( <> <View style={ horizontalSeparatorStyle } /> <PanelBody> <ColorControl label={ __( 'Customize Gradient' ) } onPress={ onCustomPress } withColorIndicator={ false } /> </PanelBody> </> ) } <View style={ horizontalSeparatorStyle } /> { getFooter() } </View> ); }; export default PaletteScreen;