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

Theme bridge to v5.0.0 #2373

Open
wants to merge 50 commits into
base: r/private-css-vars
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
17f2f4d
🛫
r100-stack Dec 16, 2024
cd6e72c
Leftover
r100-stack Dec 16, 2024
7a1a845
Partial fixes
r100-stack Dec 16, 2024
44d3e9b
Fixed theme toggles
r100-stack Dec 17, 2024
4b0836c
Merge branch 'r/private-css-vars' into r/bridge
r100-stack Dec 17, 2024
7b35137
Fixes
r100-stack Dec 17, 2024
950f796
Fixes
r100-stack Dec 17, 2024
8b213e9
Cleanup
r100-stack Dec 17, 2024
ca20e05
Simplification
r100-stack Dec 17, 2024
ee51d4b
Leftover
r100-stack Dec 17, 2024
3303613
Merge branch 'r/private-css-vars' into r/bridge
r100-stack Dec 17, 2024
ba8e6df
nit
r100-stack Dec 18, 2024
7c778a1
Merge remote-tracking branch 'origin/r/private-css-vars' into r/bridge
r100-stack Dec 18, 2024
864fbe2
`pnpm-lock.yml`
r100-stack Dec 18, 2024
808056b
Comments
r100-stack Dec 18, 2024
cd9dedb
Remove `*` by unlayering
r100-stack Dec 18, 2024
a216d1b
no dep on
r100-stack Dec 18, 2024
666f197
Comments
r100-stack Dec 19, 2024
2e3e503
Fix layer order in css workshop
r100-stack Dec 19, 2024
1375402
Re-add variables dep in react-workshop
r100-stack Dec 19, 2024
65a0cba
Into separate layer
r100-stack Dec 19, 2024
7733e97
Fix order
r100-stack Dec 19, 2024
535ff3f
Text color from base to faded.
r100-stack Dec 19, 2024
0a3b283
Border's "subtle" improvements.
r100-stack Dec 19, 2024
677806b
Removed override for background-transparent-hover and field backgroun…
r100-stack Dec 19, 2024
f987e8b
Button improvements.
r100-stack Dec 19, 2024
c1c865b
Reorder bridge components overrides.
r100-stack Dec 19, 2024
d5910a4
Breadcrumbs remove overrides.
r100-stack Dec 19, 2024
2be9fa8
Testing and simplifications
r100-stack Dec 19, 2024
1eb5b25
Contrast improvements, TODOs
r100-stack Dec 20, 2024
de35da6
Merge branch 'r/private-css-vars' into r/bridge
r100-stack Dec 20, 2024
c45806f
Backgrounds, status borders, non-current breadcrumbs
r100-stack Dec 20, 2024
2eb99bf
Button group fix
r100-stack Dec 20, 2024
4ccd98c
scoping, few hsl variables
r100-stack Dec 20, 2024
b9d90ce
HSL, fix tree selection background and others.
r100-stack Dec 20, 2024
55fbde0
nit
r100-stack Dec 20, 2024
9307ef9
Bumping to dev version.
r100-stack Dec 20, 2024
2199938
`future.themeBridge` prop
r100-stack Dec 24, 2024
3dea59e
Comments
r100-stack Dec 24, 2024
a338de9
`bridge.scss` simplification
r100-stack Dec 24, 2024
52020e8
Other comments
r100-stack Dec 24, 2024
af04c6d
Merge branch 'r/private-css-vars' into r/bridge
r100-stack Dec 24, 2024
162008f
Leftover
r100-stack Dec 24, 2024
52252cf
Bump `@astrojs/react`
r100-stack Dec 24, 2024
0bcb005
Pass `future` to portal container
r100-stack Dec 24, 2024
46eb69d
More comments
r100-stack Dec 24, 2024
be0762e
Remove unnecessary hardcoded theme
r100-stack Dec 24, 2024
1412dac
More comments in bridge
r100-stack Dec 24, 2024
fc42aea
Default prop value for `future`
r100-stack Dec 24, 2024
5ac59aa
Update `itwinui-react` dev version
r100-stack Dec 24, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion apps/css-workshop/astro.config.mjs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { defineConfig } from 'astro/config';
import relativeLinks from 'astro-relative-links';
import react from '@astrojs/react';

// https://astro.build/config
export default defineConfig({
Expand All @@ -13,5 +14,5 @@ export default defineConfig({
server: {
port: 3050,
},
integrations: [relativeLinks()],
integrations: [relativeLinks(), react()],
});
7 changes: 6 additions & 1 deletion apps/css-workshop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@
"astro": "^4",
"astro-relative-links": "^0.3.7",
"backstopjs": "~6.2.1",
"npm-run-all": "^4.1.5"
"npm-run-all": "^4.1.5",
"@astrojs/react": "^4.1.0",
smmr-dn marked this conversation as resolved.
Show resolved Hide resolved
"@types/react": "^18",
"@types/react-dom": "^18",
"react": "^18",
"react-dom": "^18"
},
"scripts": {
"dev": "astro dev",
Expand Down
34 changes: 29 additions & 5 deletions apps/css-workshop/src/components/theme.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class ThemeButton extends HTMLElement {
<label tabindex="-1"><input type="radio" name="theme" value="dark" /><span>Dark</span></label>
<label tabindex="-1"><input type="radio" name="theme" value="light-hc" /><span>High contrast light</span></label>
<label tabindex="-1"><input type="radio" name="theme" value="dark-hc" /><span>High contrast dark</span></label>
<br />
<label tabindex="-1"><input type="checkbox" name="theme-bridge" /><span>Theme Bridge</span></label>
</fieldset>

<fieldset>
Expand Down Expand Up @@ -137,16 +139,26 @@ class ThemeButton extends HTMLElement {
this.shadowRoot.querySelector(
`input[value=${prefersDark ? 'dark' : 'light'}${prefersHC ? '-hc' : ''}`,
).checked = true;
document.body.dataset.iuiTheme = prefersDark ? 'dark' : 'light';
document.body.dataset.iuiContrast = prefersHC ? 'high' : undefined;
document.body.classList.toggle('iui-root', true);

const root = document.body;
const v5Root = document.documentElement;
const theme = prefersDark ? 'dark' : 'light';

root.dataset.iuiTheme = theme;
v5Root.dataset.colorScheme = theme;
root.dataset.iuiContrast = prefersHC ? 'high' : undefined;
root.classList.toggle('iui-root', true);
}

changeTheme = ({ target: { value: _theme } }) => {
const root = document.body;
const v5Root = document.documentElement;
Comment on lines +154 to +155
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar comment here as Ladle: can we set all attributes on the same element (<body> or <html>) instead of mixing and matching?

Copy link
Member Author

Choose a reason for hiding this comment

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

iui-root cannot be on html since iui-root sets a font-size of 0.875rem (code) which would make the root font-size as 0.875rem and not 1rem.

We can set the data attributes on html without adding iui-root as we are currently doing in react-workshop for the page background ((code)). However, then iui-root + its theme related data attributes will still need to be placed somewhere.

To just have one place with the data attributes + the iui-root class, we chose <body> as that place in css-workshop.


Regarding the selected lines, the reason we set color-scheme on <html> and not <body> is because when placed on <html> those iTwinUI v5 variables are available throughout the page and not just within 🥝-root.

image


const isHighContrast = _theme.endsWith('-hc');
const theme = isHighContrast ? _theme.split('-')[0] : _theme;
document.body.dataset.iuiTheme = theme;
document.body.dataset.iuiContrast = isHighContrast ? 'high' : undefined;
root.dataset.iuiTheme = theme;
v5Root.dataset.colorScheme = theme;
root.dataset.iuiContrast = isHighContrast ? 'high' : undefined;
this.shadowRoot.querySelector('#theme-color-scheme').innerHTML = `
:host {
color-scheme: ${theme.includes('light') ? 'light' : 'dark'};
Expand All @@ -162,6 +174,10 @@ class ThemeButton extends HTMLElement {
}
};

changeBridge = ({ target: { checked } }) => {
document.body.dataset.iuiBridge = checked ? 'true' : 'false';
};

connectedCallback() {
this.shadowRoot.querySelectorAll('input[name="theme"]').forEach((radio) => {
radio.addEventListener('change', this.changeTheme);
Expand All @@ -170,6 +186,10 @@ class ThemeButton extends HTMLElement {
this.shadowRoot.querySelectorAll('input[name="background"]').forEach((radio) => {
radio.addEventListener('change', this.changeBackground);
});

this.shadowRoot
.querySelector('input[name="theme-bridge"]')
.addEventListener('change', this.changeBridge);
}

disconnectedCallback() {
Expand All @@ -180,6 +200,10 @@ class ThemeButton extends HTMLElement {
this.shadowRoot.querySelectorAll('input[name="background"]').forEach((radio) => {
radio.removeEventListener('change', this.changeBackground);
});

this.shadowRoot
.querySelector('input[name="theme-bridge"]')
.removeEventListener('change', this.changeBridge);
}
}
customElements.define('theme-button', ThemeButton);
6 changes: 5 additions & 1 deletion apps/css-workshop/src/pages/_layout.astro
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
---
import { Root as ITwinUIV5Root } from '@itwin/itwinui-react-v5/bricks';

type Props = { title?: string };
const { title } = Astro.props;

Expand Down Expand Up @@ -39,6 +41,7 @@ const slug = Astro.url.pathname.replace('/', '');
<link rel='canonical' href=`https://itwin.github.io/iTwinUI/${slug}` />

<style is:global>
@layer reset, kiwi, variables, itwinui;
@import '/assets/demo.css' layer(demo);
@import '@itwin/itwinui-variables' layer(variables);
@import '@itwin/itwinui-css/css/all.css';
Expand All @@ -50,7 +53,8 @@ const slug = Astro.url.pathname.replace('/', '');
<slot name='head' />
</head>

<body class='iui-root' data-iui-theme>
<body class='iui-root' data-iui-theme='dark'>
<ITwinUIV5Root client:load colorScheme='dark' density='dense' />
<theme-button></theme-button>
<slot />
</body>
Expand Down
7 changes: 7 additions & 0 deletions apps/css-workshop/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "astro/tsconfigs/base",
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "react"
}
}
34 changes: 24 additions & 10 deletions apps/react-workshop/.ladle/components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,24 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import { ThemeProvider } from '@itwin/itwinui-react';
import {
useLadleContext,
ActionType,
ThemeState,
type GlobalProvider,
} from '@ladle/react';
import '@itwin/itwinui-variables';
import '@itwin/itwinui-react/styles.css';
import './global.css';
import '@itwin/itwinui-react/styles.css';
import { ThemeProvider } from '@itwin/itwinui-react';
import { Root as ITwinUiV5Root } from '@itwin/itwinui-react-v5/bricks';

const prefersDark = matchMedia('(prefers-color-scheme: dark)').matches;

export const Provider: GlobalProvider = ({ children }) => {
const { globalState, dispatch } = useLadleContext();
const theme = globalState.theme === 'dark' ? 'dark' : 'light';
const highContrast = globalState.control?.['high-contrast']?.value;
const futureThemeBridge = globalState.control?.['future.themeBridge']?.value;

// default to OS theme
React.useLayoutEffect(() => {
Expand All @@ -31,11 +32,12 @@ export const Provider: GlobalProvider = ({ children }) => {

// propagate theme to <html> element for page background
React.useLayoutEffect(() => {
document.documentElement.dataset.colorScheme = theme;
document.documentElement.dataset.iuiTheme = theme;
document.documentElement.dataset.iuiContrast = highContrast
? 'high'
: 'default';
}, [theme, highContrast]);
}, [theme, highContrast, futureThemeBridge]);

// redirect old storybook paths to new ones
React.useEffect(() => {
Expand All @@ -51,12 +53,20 @@ export const Provider: GlobalProvider = ({ children }) => {

return (
<React.StrictMode>
<ThemeProvider
theme={theme}
themeOptions={{ applyBackground: false, highContrast }}
>
{children}
</ThemeProvider>
<ITwinUiV5Root colorScheme={theme} density='dense'>
<ThemeProvider
theme={theme}
themeOptions={{
applyBackground: false,
highContrast,
}}
future={{
themeBridge: futureThemeBridge,
}}
>
{children}
</ThemeProvider>
</ITwinUiV5Root>
</React.StrictMode>
);
};
Expand All @@ -74,4 +84,8 @@ export const argTypes = {
control: { type: 'boolean' },
defaultValue: false,
},
'future.themeBridge': {
control: { type: 'boolean' },
defaultValue: false,
},
};
4 changes: 4 additions & 0 deletions apps/react-workshop/.ladle/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/

@layer reset, kiwi, variables, itwinui;

@import '@itwin/itwinui-variables' layer(variables);

@import '@fontsource/noto-sans';
@import '@fontsource/noto-sans-mono';
@import '@fontsource/noto-sans/400-italic.css';
Expand Down
1 change: 1 addition & 0 deletions apps/react-workshop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"@fontsource/noto-sans-mono": "5",
"@itwin/itwinui-icons-react": "2.8.0",
"@itwin/itwinui-variables": "*",
"@itwin/itwinui-react-v5": "npm:@itwin/itwinui-react@5.0.0-alpha.1",
"@itwin/itwinui-react": "*",
"@ladle/react": "^4.1.2",
"@types/node": "*",
Expand Down
4 changes: 4 additions & 0 deletions packages/itwinui-css/src/all.scss
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,7 @@
@include meta.load-css('utils/utils');
@include meta.load-css('workflow-diagram/workflow-diagram');
}

@layer itwinui.bridge {
@include meta.load-css('./bridge');
}
Loading
Loading