-
-
Notifications
You must be signed in to change notification settings - Fork 247
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
✨ feat: add light/dark theme switch #68
base: main
Are you sure you want to change the base?
Conversation
Include a new switch button that allows users to preview their README files for both light and dark themes (default theme is dark one). This feature aims to reduce the issue with black colored icons (mostly devicons / simple icons) being barely visible on the dark canvas. Also it is a nice UX enhancement for those users who simply prefer light theming. Fixes: maurodesouza#44
Someone is attempting to deploy a commit to a Personal Account owned by @maurodesouza on Vercel. @maurodesouza first needs to authorize it. |
src/types/events.ts
Outdated
@@ -6,6 +6,7 @@ export enum Events { | |||
CANVAS_REORDER_SECTIONS = 'canvas.section.reorder', | |||
CANVAS_DUPLICATE_SECTION = 'canvas.section.duplicate', | |||
CANVAS_CLEAR_SECTIONS = 'canvas.clear', | |||
CANVAS_SWITCH_THEME = 'canvas.switchTheme', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change the event name to APP_SET_THEME = "app.set.theme"
src/app/events/handles/canvas.ts
Outdated
|
||
switchTheme = (theme: boolean) => { | ||
this.emit(Events.CANVAS_SWITCH_THEME, theme); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move it to the app handle (the file need to be created)
import { themes } from "styles"
import { Modals, Events } from 'types';
import { BaseEventHandle } from './base';
class AppHandleEvents extends BaseEventHandle {
constructor() {
super();
this.close = this.close.bind(this);
}
theme(theme: keyof typeof themes) {
this.emit(Events.APP_SET_THEME, theme);
}
}
export { ModalHandleEvents };
Then, include it in the index handles
app = new AppHandleEvents();
src/components/canvas/index.tsx
Outdated
@@ -24,7 +26,7 @@ import { CanvasErrorFallback } from './error'; | |||
|
|||
const Canvas = () => { | |||
const { extensions } = useExtensions(); | |||
const { sections, currentSection, previewMode } = useCanvas(); | |||
const { sections, currentSection, previewMode, lightTheme } = useCanvas(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here, that logic with be moved to the pages/_app.tsx
const { theme } = useTheme();
const curTheme = themes[theme]
return (
<ThemeProvider theme={curTheme }>
...
)
src/components/canvas/index.tsx
Outdated
@@ -41,9 +43,26 @@ const Canvas = () => { | |||
<S.Container | |||
onContextMenu={handleOpenContextMenu} | |||
fullHeight={hasError || !hasSection} | |||
isLightTheme={lightTheme} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be removed
src/components/canvas/index.tsx
Outdated
<S.Wrapper isLeftAligned={false}> | ||
<Tooltip | ||
position="right" | ||
content={`Preview: ${lightTheme ? 'dark' : 'light'} mode`} | ||
variant="info" | ||
> | ||
<S.Button | ||
aria-label={`Preview: ${lightTheme ? 'dark' : 'light'} mode`} | ||
onClick={() => events.canvas.switchTheme(lightTheme)} | ||
variant="success" | ||
> | ||
{lightTheme ? <MoonIcon size={16} /> : <SunIcon size={16} />} | ||
</S.Button> | ||
</Tooltip> | ||
</S.Wrapper> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/components/canvas/index.tsx
Outdated
{hasSection && !previewMode && ( | ||
<S.Wrapper> | ||
<S.Wrapper isLeftAligned={true}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be removed
src/components/canvas/index.tsx
Outdated
@@ -61,7 +80,7 @@ const Canvas = () => { | |||
onChange={setHasError} | |||
> | |||
{previewMode && ( | |||
<S.Wrapper> | |||
<S.Wrapper isLeftAligned={true}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It can be removed
src/contexts/canvas.tsx
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The theme switch logic needs to be separated into another react context, which can be called ThemeContext
src/components/canvas/styles.ts
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All changes in this file can be reverted because we will use the theme feature of the styled-components to make the theme change.
Hi @Martimex I'm delighted with your contribution! Thanks so much! Regarding the PR content, I believe switching to a global theme would be more advantageous. I've requested changes. Please let me know if you can implement them or if you need any more information. Summary:
// styles/themes/index.ts
import { defaultTheme } from './default';
import { lightTheme } from './light';
const themes = {
dark: defaultTheme,
light: lightTheme
}
export { theme } |
Thank you so much for the detailed insight in this PR !
I am definitely going to apply requested changes to the branch and add an updated PR soon, probably within few days time. |
Hey @maurodesouza, I have been trying to implement the changes. So far, the theme change functionality is completed and it works nicely within the whole app. The theme change functionality is implemented by using APP_SET_THEME synthetic event, that finally leads to this function (in const [currTheme, setCurrTheme] = useState(themes['dark']);
const handleSetTheme = (e: CustomEvent) => {
setCurrTheme(themes[e.detail]);
} The <ThemeProvider theme={currTheme}> There is one difficult issue, though. Whenever I try to change the theme, this happens : issue.mp4After some investigation, I found out that the elements with this weird behaviour are ones, which use any transition from Framer Motion. By that I mean those two Reorder Lists visible on the video above. Then, after some trials I came up with only this solution, which minifies (but does not get rid off) the problem : Left part of the image is code from So, after adding the code from the image : current.mp4the problem is not present if user clicks the button with a brief delay. However, as soon as button is being clicked consecutively around 3 times, then the reflow issue appears again. Honestly, I think I am running out of ideas on how to deal with this reflow thing properly. Current approach is more like a workaround IMO. Maybe there is an option to trigger theme change in another way, but it's just me cannot figure it out. Should we try to find a different way to implement the feature then ? Or maybe you have had experienced similiar problem before and you managed to solve it ? Please let me know, I would appreciate any response from you. |
Hi @Martimex! Apologies for my lateness! Could you commit/send me what you have? I can take it from there and finish it up. You've already done a great job! Thanks a lot |
…eat/light-dark-theme-switch
Include a new switch button that allows users to preview their README files for both light and dark themes (default theme is dark one). This feature aims to reduce the issue with black colored icons (mostly devicons / simple icons) being barely visible on the dark canvas. Also it is a nice UX enhancement for those users who simply prefer light theming. Fixes: maurodesouza#44
Hello @maurodesouza, Very sorry for no response lately. A few days ago I came back again to this issue and got another improvement that I want to share. Most of the things you asked me to fix are now finished, with the only exception being that glitch I mentioned earlier. Also I found a way to "minify" its' impact, but still it is not perfect : Left part of the image is code from I believe the glitch still needs some investigation. It happens to impact Framer Motion Reorder Lists only. Anyways, I wanted to submit this PR, because it contains some other changes requested by you. In case of any doubts or issues, please let me know. I am more active recently here on Github, so I will be able to respond much quicker. |
Hello!
For this feature I tried to apply as little changes to codebase as possible. In case of any doubts / questions about this PR, please let me know. Also I would really appreciate any related feedback. If this PR need some fixes before accepting, I am fine making additional changes to it.
Fixes: #44
What type of PR is this? (check all applicable)
What I did
I have added a new button that makes toggling between canvas themes a smooth experience. The button is responsible for changing the canvas background color and text color. No other canvas appliances (like images, icons, etc.) are affected. By hovering over it, user can see a short message of what would happen after pressing the switch.
Take a look at below screenshots to see the feature in action:
Initial state (on load):
Before pressing (on hover):
After pressing (on hover):
Original commit message: