diff --git a/package.json b/package.json index 8d24ed83cb..215238e774 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,9 @@ "dependencies": { "@bugsnag/js": "^6.5.2", "@bugsnag/plugin-react": "^6.5.0", - "@chakra-ui/icons": "^1.0.1", - "@chakra-ui/react": "^1.0.1", - "@chakra-ui/theme": "^1.0.1", + "@chakra-ui/icons": "^1.0.4", + "@chakra-ui/react": "^1.2.1", + "@chakra-ui/theme": "^1.5.0", "@emotion/react": "^11.1.1", "@emotion/styled": "^11.0.0", "@mdx-js/react": "^1.5.5", @@ -18,7 +18,7 @@ "codesandbox": "^2.1.11", "coloreact": "^0.3.1", "copy-to-clipboard": "^3.2.1", - "framer-motion": "^2.9.4", + "framer-motion": "^3.3.0", "lodash": "^4.17.15", "lodash-es": "^4.17.15", "lz-string": "^1.4.4", diff --git a/src/components/CodePanel.tsx b/src/components/CodePanel.tsx index 45105abceb..ebb07665b7 100644 --- a/src/components/CodePanel.tsx +++ b/src/components/CodePanel.tsx @@ -23,7 +23,7 @@ const CodePanel = () => { return ( Promise +} + +const ColorPickerControl = (props: ColorPickerPropType) => { + const theme = useTheme() + const themeColors: any = omit(theme.colors, [ + 'transparent', + 'current', + 'black', + 'white', + ]) + + const { setValue, setValueFromEvent } = useForm() + const value = usePropsSelector(props.name) + + let propsIconButton: any = { bg: value } + if (value && themeColors[value]) { + propsIconButton = { colorScheme: value } + } + + return ( + <> + + + {props.gradient ? ( + + ) : ( + + )} + + + + + + {props.withFullColor ? ( + + + Theme + All + + + + {props.gradient ? ( + + ) : ( + + )} + + + + + { + props.gradient + ? props.updateGradient!( + `#${color.hex}`, + props.index!, + ) + : setValue(props.name, `#${color.hex}`) + }} + /> + ); + + + + + ) : props.gradient ? ( + + ) : ( + + )} + + + + + {props.gradient ? ( + + ) : ( + + )} + + ) +} + +export default ColorPickerControl diff --git a/src/components/inspector/controls/ColorsControl.tsx b/src/components/inspector/controls/ColorsControl.tsx index 0d47cb9b8e..7530bb6f1d 100644 --- a/src/components/inspector/controls/ColorsControl.tsx +++ b/src/components/inspector/controls/ColorsControl.tsx @@ -1,31 +1,6 @@ -import React, { ReactNode, useState, memo } from 'react' -import { - Popover, - PopoverTrigger, - PopoverContent, - PopoverArrow, - Grid, - PopoverBody, - IconButton, - SliderTrack, - SliderFilledTrack, - SliderThumb, - Box, - Tabs, - TabList, - Tab, - TabPanels, - TabPanel, - Input, - useTheme, - Slider, - Portal, -} from '@chakra-ui/react' +import React, { ReactNode, memo } from 'react' import FormControl from './FormControl' -import { useForm } from '~hooks/useForm' -import omit from 'lodash/omit' -import ColorPicker from 'coloreact' -import usePropsSelector from '~hooks/usePropsSelector' +import ColorPickerControl from './ColorPickerControl' type ColorControlPropsType = { name: string @@ -35,126 +10,12 @@ type ColorControlPropsType = { } const ColorsControl = (props: ColorControlPropsType) => { - const { setValue, setValueFromEvent } = useForm() - const [hue, setHue] = useState(500) - const value = usePropsSelector(props.name) - const theme = useTheme() - - const themeColors: any = omit(theme.colors, [ - 'transparent', - 'current', - 'black', - 'white', - ]) - - let propsIconButton: any = { bg: value } - if (value && themeColors[value]) { - propsIconButton = { colorScheme: value } - } - - const huesPicker = ( - <> - - {Object.keys(themeColors).map(colorName => ( - - setValue( - props.name, - props.enableHues ? `${colorName}.${hue}` : colorName, - ) - } - mt={2} - borderRadius="full" - height="30px" - width="30px" - /> - ))} - - - {props.enableHues && ( - <> - { - value = value === 0 ? 50 : value - setHue(value) - }} - min={0} - max={900} - step={100} - value={hue} - > - - - - - - {hue} - - - - - )} - - ) - return ( - - - - - - - - - {props.withFullColor ? ( - - - Theme - All - - - {huesPicker} - - - - { - setValue(props.name, `#${color.hex}`) - }} - /> - ); - - - - - ) : ( - huesPicker - )} - - - - - ) diff --git a/src/components/inspector/controls/GradientControl.tsx b/src/components/inspector/controls/GradientControl.tsx new file mode 100644 index 0000000000..e3f0627776 --- /dev/null +++ b/src/components/inspector/controls/GradientControl.tsx @@ -0,0 +1,145 @@ +import React, { ReactNode, useState, memo, useEffect } from 'react' +import { Box, Select, Button, IconButton } from '@chakra-ui/react' +import { SmallCloseIcon } from '@chakra-ui/icons' +import FormControl from './FormControl' +import { useForm } from '~hooks/useForm' +import ColorPickerControl from './ColorPickerControl' +import usePropsSelector from '~hooks/usePropsSelector' + +export type Gradient = + | 'to top' + | 'to top right' + | 'to right' + | 'to bottom right' + | 'to bottom' + | 'to bottom left' + | 'to left' + | 'to top left' +type GradientControlPropsType = { + name: string + label: string | ReactNode + enableHues?: boolean + withFullColor?: boolean + options?: Gradient[] +} + +const GradientControl = (props: GradientControlPropsType) => { + const { setValue } = useForm() + const [gradientColor, setGradientColor] = useState(['green.200']) + const [directionValue, setDirectionValue] = useState('to right') + const gradient = usePropsSelector(props.name) + + const choices = props.options + + const updateValue = () => { + if ( + gradientColor.length >= 2 && + gradient !== `linear(${directionValue}, ${gradientColor.toString()})` + ) { + setValue( + props.name, + `linear(${directionValue}, ${gradientColor.toString()})`, + ) + } + } + + useEffect(() => { + updateValue() + //eslint-disable-next-line + }, [directionValue, gradientColor]) + + useEffect(() => { + if (gradient === '' || gradient === null) { + setGradientColor(['green.200']) + } else { + let gradientValue = gradient.split('(')[1] + let actualDirection = gradientValue.split(',')[0] + let actualColor = gradientValue.split(',') + let colorArray = actualColor.splice(1, actualColor.length) + colorArray[colorArray.length - 1] = colorArray[ + colorArray.length - 1 + ].split(')')[0] + colorArray[0] = colorArray[0].split(' ')[1] + setDirectionValue(actualDirection) + setGradientColor(colorArray) + } + }, [gradient]) + + const updateGradient = async (value: string, index: number) => { + let colorCopy = [...gradientColor] + colorCopy[index] = value + setGradientColor(colorCopy) + } + + const removeGradient = async (index: number) => { + let colorCopy = [...gradientColor] + colorCopy.splice(index, 1) + if (colorCopy.length >= 2) { + setGradientColor(colorCopy) + } else { + setGradientColor(colorCopy) + setValue(props.name, null) + } + } + + return ( + <> + + + + + {gradientColor.map((e, i) => ( + + {i >= 1 && ( + removeGradient(i)} + variant="ghost" + marginRight={2} + size="xs" + aria-label="delete" + icon={} + /> + )} + + + + ))} + + + + + + ) +} + +export default memo(GradientControl) diff --git a/src/components/inspector/controls/HuesPickerControl.tsx b/src/components/inspector/controls/HuesPickerControl.tsx new file mode 100644 index 0000000000..5b12234ecb --- /dev/null +++ b/src/components/inspector/controls/HuesPickerControl.tsx @@ -0,0 +1,94 @@ +import React, { useState } from 'react' +import { + Grid, + SliderTrack, + SliderFilledTrack, + SliderThumb, + Box, + Slider, +} from '@chakra-ui/react' + +type HuesPickerPropType = { + name: string + themeColors: any + enableHues: boolean + gradient: boolean + index?: number + setValue: (name: string, value: any) => void + updateGradient?: (value: string, index: number) => void +} + +const HuesPickerControl = (props: HuesPickerPropType) => { + const [hue, setHue] = useState(500) + + return ( + <> + + {Object.keys(props.themeColors).map(colorName => + props.gradient ? ( + { + if (props.updateGradient) { + props.updateGradient(`${colorName}.${hue}`, props.index!) + } + }} + mt={2} + borderRadius="full" + height="30px" + width="30px" + /> + ) : ( + + props.setValue( + props.name, + props.enableHues ? `${colorName}.${hue}` : colorName, + ) + } + mt={2} + borderRadius="full" + height="30px" + width="30px" + /> + ), + )} + + + {props.enableHues && ( + <> + { + value = value === 0 ? 50 : value + setHue(value) + }} + min={0} + max={900} + step={100} + value={hue} + > + + + + + + {hue} + + + + + )} + + ) +} + +export default HuesPickerControl diff --git a/src/components/inspector/panels/StylesPanel.tsx b/src/components/inspector/panels/StylesPanel.tsx index 7b65fab4c4..493de86bef 100644 --- a/src/components/inspector/panels/StylesPanel.tsx +++ b/src/components/inspector/panels/StylesPanel.tsx @@ -8,6 +8,7 @@ import DisplayPanel from '~components/inspector/panels/styles/DisplayPanel' import TextPanel from '~components/inspector/panels/styles/TextPanel' import AccordionContainer from '~components/inspector/AccordionContainer' import ColorsControl from '~components/inspector/controls/ColorsControl' +import GradientControl from '~components/inspector/controls/GradientControl' import EffectsPanel from './styles/EffectsPanel' import ChildrenInspector from '~components/inspector/ChildrenInspector' import ParentInspector from '~components/inspector/ParentInspector' @@ -68,6 +69,24 @@ const StylesPanel: React.FC = ({ name="backgroundColor" enableHues /> + {!isRoot && ( + + )} {!isRoot && (