-
Notifications
You must be signed in to change notification settings - Fork 92
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
chore: dark mode POC #1673
chore: dark mode POC #1673
Conversation
const colorStyles = (props: IStyledHeaderProps) => { | ||
const backgroundColor = props.theme.colors.background; | ||
const borderColor = getColor( | ||
'neutralHue', | ||
props.theme.colors.base === 'dark' ? 700 : 300, | ||
props.theme | ||
); | ||
const boxShadow = props.theme.shadows.lg( | ||
'0', | ||
`${props.theme.space.base * 2.5}px`, | ||
getColor('chromeHue', 600, props.theme, 0.15)! | ||
); | ||
const foregroundColor = getColor('neutralHue', 600, props.theme); | ||
|
||
return css` | ||
border-bottom-color: ${borderColor}; | ||
box-shadow: ${props.isStandalone && boxShadow}; | ||
background-color: ${backgroundColor}; | ||
color: ${foregroundColor}; | ||
`; | ||
}; | ||
|
||
const sizeStyles = (props: IStyledHeaderProps) => { | ||
const border = props.theme.borders.sm; | ||
const fontSize = props.theme.fontSizes.md; | ||
const height = getNavItemHeight(props); | ||
const padding = `${props.theme.space.base}px`; | ||
|
||
return css` | ||
border-bottom: ${border}; | ||
padding: 0 ${padding}; | ||
height: ${height}; | ||
font-size: ${fontSize}; | ||
`; |
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.
This is an example of following the documented colorStyles
and sizeStyles
for view components. We'll expect to see this structure more fastidiously followed during dark mode development
${sizeStyles}; | ||
${colorStyles}; |
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.
ditto re: sizeStyles
& colorStyles
refactor
/** | ||
* Provides values for component styling. See styled-components | ||
* [`ThemeProvider`](https://styled-components.com/docs/api#themeprovider) | ||
* for details. | ||
*/ | ||
theme?: IGardenTheme; | ||
theme?: IGardenTheme | ((theme: IGardenTheme) => IGardenTheme); |
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.
Updated to allow the same theme
typing as styled-components
@@ -20,7 +20,7 @@ export const ThemeProvider = ({ | |||
...other | |||
}: PropsWithChildren<IThemeProviderProps>) => { |
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.
Ultimately, I think we'll expect to see createGlobalStyle here with a listing of CSS variables pulled from the default theme.
const theme = (parentTheme: DefaultTheme) => | ||
({ | ||
...parentTheme, | ||
colors: { | ||
...parentTheme.colors, | ||
base: 'dark', | ||
background: getColor('neutralHue', 900, parentTheme), | ||
foreground: getColor('neutralHue', 200, parentTheme), | ||
primaryHue: '#50a1e1' | ||
} | ||
}) as IGardenTheme; |
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.
For the POC, this is the main theming setup for dark mode – affecting a major portion of the UI as expected.
prefix: 'zdg', | ||
variables: { | ||
buttons: {} | ||
} |
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.
Defaults for what will be added by ThemeProvider.
--${prefix}--buttons--shade--hover: ${buttons.shades.hover}; | ||
--${prefix}--buttons--shade--active: ${buttons.shades.active}; | ||
--${prefix}--buttons--shade--color--disabled: ${buttons.shades.disabledColor}; | ||
--${prefix}--buttons--shades--bg--disabled: ${buttons.shades.disabledBgColor}; |
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.
These are set after semantic variables are created in ThemeProvider.
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.
I'm also realizing now, if we were to lazily generate semantic variables in component instances, it would throw a wrench in generating these variables on page load. Not sure how/if we can wiggle around that issue.
disabledBgColor: 200 | ||
} | ||
}; | ||
}, |
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.
A sample of what we can do in the semantic generation model... The key thing to takeaway is the theme values aren't referenced statically, but from the provided theme object when ThemeProvider is instantiated.
variables = { | ||
buttons: getButtonVariables(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.
This object here is an example of the expected value for this new variables
.
line-height: ${lineHeight}; | ||
font-size: ${fontSize}; | ||
font-size: var(--${prefix}--buttons_${fontSize}--fontSize, ${sizes[fontSize].fontSize}); |
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 might serve us well to isolate custom property definitions like this in a separate file, so we can reference exactly which properties a component has tied to theming. Especially if we have custom properties not tied directly to specific properties (i.e. shades).
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.
Regardless of how that works, it felt natural to have the custom properties take priority should a consumer want to override them from that direction, with the theme object value as a fallback.
@@ -49,7 +58,8 @@ export const getHeight = (props: IButtonProps & ThemeProps<DefaultTheme>) => { | |||
* 3. shifting :focus-visible from LVHFA order to preserve `color` on hover | |||
* 4. set default outline-color for smooth transition without artifacts | |||
*/ | |||
const colorStyles = (props: IButtonProps & ThemeProps<DefaultTheme>) => { | |||
const colorStyles = (props: IButtonProps & ThemeProps<IGardenTheme>) => { | |||
const { shades } = props.theme.variables.buttons; |
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.
Not married to shades being themeable this way - but I found it clunky and anti-thetical to how getColor
works to fully define colors, with shades, in semantic variable generation. If we move that generation step into the component, this might be less of an issue (aka, lazy semantic loading, as we were discussing).
3a48060
to
700c0aa
Compare
700c0aa
to
120598e
Compare
Description
This PR is a brute force POC (not intended for merge) that demonstrates how the existing
theme.colors.base
value might be used to impact styling for the how-to-react sandbox. Ultimately, we'll look at a combination of CSS variables together with a'light'
vs'dark'
toggle to handle a richer color theming experience.Detail
The story can be found under "Chrome -> [patterns] -> Dark". A
hue
control is included to observe the affect of Garden's existing branding control.