Skip to content
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

Configure darkmode with props #28

Merged
merged 5 commits into from
Apr 18, 2024

Conversation

bpingris
Copy link
Contributor

@bpingris bpingris commented Apr 9, 2024

hey!
this is a follow up pr after this tweet

I though about such api where we would only need to pass a darkMode: bool prop, if none is given we still use the useColorScheme hook call etc.

what do you think?

I haven't had the time to test it yet though! so I leave it as a draft for now, thanks!

Copy link

changeset-bot bot commented Apr 9, 2024

🦋 Changeset detected

Latest commit: dd68c15

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@marceloterreiro/flash-calendar Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@bpingris bpingris force-pushed the feat/dark-mode-optional branch from 8c0f39c to 7a27f49 Compare April 9, 2024 16:46
Copy link
Owner

@MarceloPrado MarceloPrado left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work @bpingris, I really appreciate the contribution ❤️
Left some feedbacks to increase the flexibility of the code.

We'll also need to:

  1. Forward the prop in Calendar.List
  2. Add a Calendar story to showcase/test the functionality.

Let me know if you have any FUP questions!

Comment on lines 79 to 88
export const useCalendarContext = () => {
const context = useContext(calendarContext);

if (!context) {
throw new Error(
"useCalendarContext must be called inside <calendarContext.Provider>"
);
}
return context;
};
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we move this to a useCalendarTheme file?

@@ -68,8 +68,25 @@ export interface CalendarProps extends UseCalendarParams {
calendarMonthHeaderHeight?: number;
/** Theme to customize the calendar component. */
theme?: CalendarTheme;
/** Enable dark mode */
darkMode?: boolean;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make this more flexible by changing to:

  
  /**
   * When set, Flash Calendar will use this color scheme instead of the system's
   * value (`light|dark`). This is useful if your app doesn't support dark-mode,
   * for example.
   *
   * We don't advise using this prop - ideally, your app should reflect the
   * user's preferences.
   */
  colorSchemeToOverride?: ColorSchemeName;

Comment on lines 75 to 77
const calendarContext = createContext<{ darkMode?: boolean } | undefined>(
undefined
);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we move this to a useCalendarTheme.ts file?

}

const calendarContext = createContext<{ darkMode?: boolean } | undefined>(
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of darkMode, let's use the idea from above:

type CalendarContextType = {
  /** The overridden color scheme */
  colorScheme?: ColorSchemeName
}

const calendarThemeContext = createContext<CalendarContextType | undefined>(undefined)


if (!context) {
throw new Error(
"useCalendarContext must be called inside <calendarContext.Provider>"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: let's also change the error message to reflect the new context name

@@ -168,7 +190,11 @@ export const Calendar = memo(
*/
}, [calendarActiveDateRanges, calendarMonthId]);

return <BaseCalendar {...props} calendarMonthId={calendarMonthId} />;
return (
<calendarContext.Provider value={{ darkMode }}>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to memo this value to avoid re-renders:

const calendarThemeContextValue = useMemo<CalendarThemeContext>(() => ({ colorScheme: colorSchemeToOverride }), [colorSchemeToOverride])

@bpingris
Copy link
Contributor Author

@MarceloPrado I've made the changes but I think I'm stuck with the storybook
which command should I run to launch it?
for now I've cd in /apps/example and ran bun run ios, it launched the storybook on my ios simulator but the code seems buggy (for instance my context is not set it seems (perhaps it just my code that does not work and not the way I launched sb)
thanks!

@MarceloPrado
Copy link
Owner

MarceloPrado commented Apr 12, 2024

@bpingris bun run dev at the root is everything that's required to run both storybook and the documentation site.

I ran your PR locally and saw this error:
CleanShot 2024-04-12 at 15 00 01

One thing I realized: we don't want to throw an error if someone forgets to add the context. One of Flash Calendar's principles is that's easy to customize/compose. Adding a context consumers have to wrap is a step against that direction. What do you think of this approach?

import { createContext, useContext } from "react";
import type { ColorSchemeName } from "react-native";

export interface CalendarThemeContext {
  /** The overridden color scheme */
  colorScheme?: ColorSchemeName;
}

export const calendarThemeContext = createContext<CalendarThemeContext>({
  colorScheme: undefined,
});

export const useCalendarThemeContext = () => {
  const context = useContext(calendarThemeContext);
  return context;
};

I ran your code using the context above and everything seems to work as expected (the calendar stops listening to the theme):

CleanShot.2024-04-12.at.15.03.05.mp4

@MarceloPrado MarceloPrado marked this pull request as ready for review April 12, 2024 22:07
@bpingris
Copy link
Contributor Author

hey sorry for the delay!
oh yea you're right that's why I had the error! I forgot about the composability stuff and could not understand how this error could happen as both Calendar and CalendarList were returning the context
and of course you're right we should add the default value undefined for the context

@MarceloPrado MarceloPrado changed the title wip: configure darkmode with props Configure darkmode with props Apr 18, 2024
@MarceloPrado MarceloPrado force-pushed the feat/dark-mode-optional branch from e30d38e to dd68c15 Compare April 18, 2024 16:52
@MarceloPrado
Copy link
Owner

Hi @bpingris!
I pushed a few changes to this commit to ensure it's ready for release. Here are the notable changes:

  • add changeset + docs
  • Fix Calendar.List usage - instead of using the context in this component, we just had to forward it to Calendar
  • Renamed prop to better match the prop pattern (always prefixed with calendar - theme is the only deviation of this)
  • Moved hook to a custom file

let me know if you have further questions!

@MarceloPrado MarceloPrado merged commit 6d00992 into MarceloPrado:main Apr 18, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants