Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

Sorry, you do not have permission to ask a question, You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please type your username.

Please type your E-Mail.

Please choose an appropriate title for the post.

Please choose the appropriate section so your post can be easily searched.

Please choose suitable Keywords Ex: post, video.

Browse

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Logo

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Navigation

  • Home
  • About Us
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • About Us
  • Contact Us
Home/ Questions/Q 9045

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise Latest Questions

Author
  • 60k
Author
Asked: November 28, 20242024-11-28T06:45:11+00:00 2024-11-28T06:45:11+00:00

Create a custom theme editor with HyperTheme

  • 60k

In this tutorial you'll learn how to create a custom theme editor and a simple Color Panel Editor.

In this tutorial you'll use:

  • ThemeEditor component
  • ThemeEditorButton component
  • ThemeEditorDrawer component
  • useThemeEditor hook

Prerequisites

You need HyperTheme Editor installed and working on your Chakra UI Project.

If you still not have installed HyperTheme, follow the installation instructions here.

HyperThemeEditor component

In the Installation page we have added the HyperThemeEditor component that gives us a plug&play editor on the page through a Button.

The source code of HyperThemeEditor itself it's very simple as you can see here:

import React, { FC } from 'react' import {   ThemeEditor,   ThemeEditorButton,   ThemeEditorButtonProps,   ThemeEditorDrawer, } from '@hypertheme-editor/chakra-ui-core' import { ThemeEditorColors } from '@hypertheme-editor/chakra-ui-colors' import { ThemeEditorFontSizes } from '@hypertheme-editor/chakra-ui-font-sizes' import { CgColorPicker } from 'react-icons/cg' import { ImFontSize } from 'react-icons/im'  export type DefaultThemeEditorProps = ThemeEditorButtonProps  export const HyperThemeEditor: FC<DefaultThemeEditorProps> = (props) => {   return (     <ThemeEditor>       <ThemeEditorButton {...props} />       <ThemeEditorDrawer>         <ThemeEditorColors icon={CgColorPicker} title="Colors" />         <ThemeEditorFontSizes icon={ImFontSize} title="Font Sizes" />       </ThemeEditorDrawer>     </ThemeEditor>   ) } 
Enter fullscreen mode Exit fullscreen mode

Read more about HyperThemeEditor component here.

Creating a Custom ThemeEditor

Based on the source code of HyperThemeEditor we can create a custom ThemeEditor.

To do so, create a new MyThemeEditor component with this content:

import React, { FC } from 'react' import {   ThemeEditor,   ThemeEditorButton,   ThemeEditorButtonProps,   ThemeEditorColors,   ThemeEditorFontSizes, } from '@hypertheme-editor/chakra-ui' import { CgColorPicker } from 'react-icons/cg' import { BiText } from 'react-icons/bi'  export const MyThemeEditor = (props) => {   return (     <ThemeEditor>       <ThemeEditorButton {...props} />       <ThemeEditorDrawer>         <ThemeEditorColors icon={CgColorPicker} title="Colors" />         <ThemeEditorFontSizes icon={BiText} title="Typography" />       </ThemeEditorDrawer>     </ThemeEditor>   ) } 
Enter fullscreen mode Exit fullscreen mode

As you can see, you can change the order of the panels, the icons and the labels.

HyperTheme uses react-icons for rendering the icons on the editor, here you can search for the icon you need.

Read more about: ThemeEditor, ThemeEditorDrawer and ThemeEditorButton.

Creating a custom Panel

Now that we have a custom ThemeEditor component we can start creating our custom editor panel.

Create a new MyColorEditor component:

import React from 'react' import { Box } from '@chakra-ui/react'  export default function MyCustomPanel(props) {   return <Box>Testing Custom Panel</Box> } 
Enter fullscreen mode Exit fullscreen mode

Add it as a new Panel to our MyThemeEditor component:

import React, { FC } from 'react' import {   ThemeEditor,   ThemeEditorButton,   ThemeEditorButtonProps,   ThemeEditorColors,   ThemeEditorFontSizes, } from '@hypertheme-editor/chakra-ui' import { CgColorPicker } from 'react-icons/cg' import { BiText } from 'react-icons/bi' import MyCustomPanel from './MyCustomPanel'  export default function MyThemeEditor(props) {   return (     <ThemeEditor>       <ThemeEditorButton {...props} />       <ThemeEditorDrawer>         {/* Add the MyCustomPanel to our theme editor */}         <MyCustomPanel icon={CgColorPicker} title="My Panel" />         <ThemeEditorColors icon={CgColorPicker} title="Colors" />         <ThemeEditorFontSizes icon={BiText} title="Typography" />       </ThemeEditorDrawer>     </ThemeEditor>   ) } 
Enter fullscreen mode Exit fullscreen mode

Now you have a custom panel inside the ThemeEditorDrawer component, your theme editor should look like the example below:

function MyCustomPanel(props) {   return <Box>Testing Custom Panel</Box> }  function MyThemeEditor(props) {   return (     <ThemeEditor>       <ThemeEditorButton {...props} />       <ThemeEditorDrawer>         {/* Add the MyCustomPanel to our theme editor */}         <MyCustomPanel icon={CgColorPicker} title="My Panel" />         <ThemeEditorColors icon={CgColorPicker} title="Colors" />         <ThemeEditorFontSizes icon={BiText} title="Typography" />       </ThemeEditorDrawer>     </ThemeEditor>   ) }  render(<MyThemeEditor />) 
Enter fullscreen mode Exit fullscreen mode

useThemeEditor hook

Now that we have a theme editor with a custom editor panel, it's time to start retrieving and live edit the theme.

HyperTheme Editor provides the useThemeEditor hook to:

  • maintaint the current theme state
  • live edit the current theme
  • manage changes history

Check out more on the documentation.

Retrieving and show the current theme

In this section we're creating a ThemeColorBox that shows a color for the theme.

Create a new ThemeColorBox component with this content:

import React from 'react' import { Box } from '@chakra-ui/react' import { useThemeEditor } from '@hypertheme-editor/chakra-ui'  export default function ThemeColorBox({ token, paletteIndex = 500, ...props }) {   const { theme } = useThemeEditor()    const color = useMemo(() => {     // in Chakra UI colors could objects     // with an index (100, 200, 300, etc) or a single color     if (theme && theme.colors[token]) {       // if the color is a string, return it       if (typeof theme.colors[token] === 'string') {         return theme.colors[token]         // if it's an object return the current paletteIndex for that color       } else if (theme.colors[token][paletteIndex]) {         return theme.colors[token][paletteIndex]       }     }      return 'gray'   }, [theme, token, paletteIndex])    return <Box w="40px" h="40px" borderRadius="md" bgColor={color} {...props} /> } 
Enter fullscreen mode Exit fullscreen mode

Let's check our new component with some different theme colors, try to change the colors from the editor to check that is working correctly:

<HStack>   <HyperThemeEditor />   <ThemeColorBox token="blue" paletteIndex={500} />   <ThemeColorBox token="red" paletteIndex={500} />   <ThemeColorBox token="green" paletteIndex={500} />   <ThemeColorBox token="orange" paletteIndex={500} />   <ThemeColorBox token="yellow" paletteIndex={500} />   <ThemeColorBox token="purple" paletteIndex={500} /> </HStack> 
Enter fullscreen mode Exit fullscreen mode

Live edit the current theme

It's time to live edit the current theme.

Let's create a SimpleColorEditor component that shows the current color and set a new one through an Input:

import React from 'react' import { useThemeEditor } from '@hypertheme-editor/chakra-ui' import { Input } from '@chakra-ui/react' import { useDebouncyEffect } from 'use-debouncy' import { colord } from 'colord'  export default function SimpleColorEditor({ token, paletteIndex, ...props }) {   const { theme, setTheme } = useThemeEditor()   const [inputValue, setInputValue] = useState<string>(theme.colors[token][paletteIndex] || '')    const handleOnChange = useCallback((event) => {     setInputValue(event.target.value)   }, [])    // use a debounced effect so the UI is not blocked   // while the value are changed through the Input   useDebouncyEffect(     () => {       // check that the input color is valid       if (colord(inputValue).isValid()) {         // the color token could be a simple color or a palette object,         // so we have to check it.         // We also check that the input value differ from         // the one from the theme, this is necessary         // for undo/redo functionality to work correctly         if (typeof theme.colors[token] === 'string' && theme.colors[token] !== inputValue) {           // live edit the current theme           setTheme({             ...theme,             colors: {               ...theme.colors,               [token]: inputValue,             },           })         } else if (           theme.colors[token][paletteIndex] &&           theme.colors[token][paletteIndex] !== inputValue         ) {           // live edit the current theme           setTheme({             ...theme,             colors: {               ...theme.colors,               [token]: {                 ...theme.colors.token,                 [paletteIndex]: inputValue,               },             },           })         }       }     },     500,     [inputValue]   )    // update internal state if another panel change this value   useEffect(() => {     if (       theme.colors[token] &&       theme.colors[token][paletteIndex] &&       theme.colors[token][paletteIndex] !== inputValue     ) {       setInputValue(theme.colors[token][paletteIndex])     }     // eslint-disable-next-line react-hooks/exhaustive-deps   }, [theme.colors, token, paletteIndex])    return (     <HStack>       {/* add the ThemeColorBox we've created before */}       <ThemeColorBox token={token} paletteIndex={paletteIndex} />       <Input onChange={handleOnChange} value={inputValue} />     </HStack>   ) } 
Enter fullscreen mode Exit fullscreen mode

Let's try our new SimpleColorEditor component.

If you change a value (using HEX notation) you should see the new color in current theme.

Compare the edited colors with the value provided by HyperThemeEditor.

<VStack>   <HyperThemeEditor />   <SimpleColorEditor token="blue" paletteIndex={500} />   <SimpleColorEditor token="red" paletteIndex={500} />   <SimpleColorEditor token="green" paletteIndex={500} />   <SimpleColorEditor token="orange" paletteIndex={500} />   <SimpleColorEditor token="yellow" paletteIndex={500} />   <SimpleColorEditor token="purple" paletteIndex={500} /> </VStack> 
Enter fullscreen mode Exit fullscreen mode

Final mounting

Finally, we can mount our SimpleColorEditor into our custom theme editor.

Edit the MyPanel component like this:

import React from 'react' import { Box } from '@chakra-ui/react'  export default function MyCustomPanel(props) {   return (     <VStack>       <SimpleColorEditor token="blue" paletteIndex={500} />       <SimpleColorEditor token="red" paletteIndex={500} />       <SimpleColorEditor token="green" paletteIndex={500} />       <SimpleColorEditor token="orange" paletteIndex={500} />       <SimpleColorEditor token="yellow" paletteIndex={500} />       <SimpleColorEditor token="purple" paletteIndex={500} />     </VStack>   ) } 
Enter fullscreen mode Exit fullscreen mode

The final result should be like this:

function MyCustomPanel(props) {   return (     <VStack>       <SimpleColorEditor token="blue" paletteIndex={500} />       <SimpleColorEditor token="red" paletteIndex={500} />       <SimpleColorEditor token="green" paletteIndex={500} />       <SimpleColorEditor token="orange" paletteIndex={500} />       <SimpleColorEditor token="yellow" paletteIndex={500} />       <SimpleColorEditor token="purple" paletteIndex={500} />     </VStack>   ) }  function MyThemeEditor(props) {   return (     <ThemeEditor>       <ThemeEditorButton {...props} />       <ThemeEditorDrawer>         {/* Add the MyCustomPanel to our theme editor */}         <MyCustomPanel icon={CgColorPicker} title="My Panel" />         <ThemeEditorColors icon={CgColorPicker} title="Colors" />         <ThemeEditorFontSizes icon={BiText} title="Typography" />       </ThemeEditorDrawer>     </ThemeEditor>   ) }  render(<MyThemeEditor />) 
Enter fullscreen mode Exit fullscreen mode

Congratulations! You have created your first working custom panel.

javascriptreactshowdevwebdev
  • 0 0 Answers
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

Sidebar

Ask A Question

Stats

  • Questions 4k
  • Answers 0
  • Best Answers 0
  • Users 1k
  • Popular
  • Answers
  • Author

    How to ensure that all the routes on my Symfony ...

    • 0 Answers
  • Author

    Insights into Forms in Flask

    • 0 Answers
  • Author

    Kick Start Your Next Project With Holo Theme

    • 0 Answers

Top Members

Samantha Carter

Samantha Carter

  • 0 Questions
  • 20 Points
Begginer
Ella Lewis

Ella Lewis

  • 0 Questions
  • 20 Points
Begginer
Isaac Anderson

Isaac Anderson

  • 0 Questions
  • 20 Points
Begginer

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help

Footer

Querify Question Shop: Explore Expert Solutions and Unique Q&A Merchandise

Querify Question Shop: Explore, ask, and connect. Join our vibrant Q&A community today!

About Us

  • About Us
  • Contact Us
  • All Users

Legal Stuff

  • Terms of Use
  • Privacy Policy
  • Cookie Policy

Help

  • Knowledge Base
  • Support

Follow

© 2022 Querify Question. All Rights Reserved

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.