diff --git a/docs/guides/using-theme-overrides.md b/docs/guides/using-theme-overrides.md
index a7e6dad751..a72157cb95 100644
--- a/docs/guides/using-theme-overrides.md
+++ b/docs/guides/using-theme-overrides.md
@@ -27,23 +27,7 @@ type: embed
### How theming works in InstUI
-The theming system in InstUI has three levels:
-
-**The global theme**
-
-Global themes are useful when you have multiple React Application trees and you want to set up themes and overrides on a more global level than application level theming.
-This basically means you don't necessarily have to wrap each application tree with an [InstUISettingsProvider](/#InstUISettingsProvider) to use themes.
-InstUI leverages the [ThemeRegistry](/#ThemeRegistry) package to achieve global theming.
-
-```jsx
----
-type: code
----
-// app/init sets the global theme
-import canvas from '@instructure/ui-themes'
-
-canvas.use()
-```
+The theming system in InstUI has these levels:
**The application level theme**
@@ -95,42 +79,28 @@ const generateStyle = (componentTheme) => {
}
```
-### Global theme overrides
+### Application level theme overrides
-In order to globally register and override themes, simply import the theme you wish to use and call `.use({ overrides })` on it:
+`` accepts full theme objects and override objects too.
```js
---
-type: code
+type: example
---
-import ReactDOM from "react-dom"
-import { canvas } from "@instructure/ui-themes"
-
-canvas.use({
- overrides: {
- colors: {
- primitives: {
- green45: "red"
- }
+
- ...your application code goes here...
+
+ I should have monospace font family from the override
+
-)
+
```
-**Note**: globally overriding themes like this means that every InstUI component will use that theme, unless they are wrapped inside an ``.
-
-You can see more examples [here](/#using-theme-overrides/#using-theme-overrides-examples).
-
-### Application level theme overrides
-
-`` accepts full theme objects and override objects too.
-
#### Full themes
By nesting the `InstUISettingsProvider` you can apply different themes to some sections of you app.
@@ -214,27 +184,27 @@ const Example = () => {
return (
Common variables
-
-
+
+ setIcBrandPrimary(v)}
- messages={[{text:'used for border/background/shadow/focus colors in many places',type:'hint'}]} />
+ messages={[{text:'used for border/background/focus/shadow/.. colors in many places',type:'hint'}]} />
-
+ setIcBrandFontColorDark(v)}
messages={[{text:'used in lots of places for text color',type:'hint'}]} />
Button branding
-
-
+
+ setIcBrandButtonPrimaryBgd(v)}
messages={[{text:"Used by 'primary' color buttons for background",type:'hint'}]} />
setIcBrandButtonPrimaryText(v)}
messages={[{text:"Used by 'primary' color buttons for text color",type:'hint'}]} />
-
+ setIcBrandButtonSecondaryBgd(v)}
messages={[{text:'Unused in InstUI',type:'hint'}]} />
@@ -260,13 +230,17 @@ const Example = () => {
'ic-brand-global-nav-menu-item__text-color--active': icBrandGlobalNavMenuItemTextColorActive
}}}>
-
-
-
+
+
+
+
+
-
-
+
+
+
+
@@ -280,18 +254,18 @@ const Example = () => {
Link colors used by Link and Billboard:
-
-
+
+ setIcLinkColor(v)}
messages={[{text:'Used for non-inverse Link and clickable Billboard',type:'hint'}]} />
-
+ setIcLinkDecoration(v)}
messages={[{text:'Unused in InstUI',type:'hint'}]}/>
-
+
normal link
@@ -301,8 +275,8 @@ const Example = () => {
-
-
+
+ {
hero={(size) => }
/>
-
+ {
SideNavBar branding
-
-
+
+ setIcBrandGlobalNavBgd(v)}/>
setIcGlobalNavLinkHover(v)}/>
setIcBrandGlobalNavIcIconSvgFill(v)}/>
-
+ setIcBrandGlobalNavMenuItemTextColor(v)}/>
setIcBrandGlobalNavMenuItemTextColorActive(v)}/>
setIcBrandGlobalNavIcIconSvgFillActive(v)}/>
@@ -386,3 +360,53 @@ const Example = () => {
render()
```
+
+### (DEPRECATED) Global (window-level) theming
+
+**The global theme**
+
+> This feature is deprecated because it needs to use the [global object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis) that pierces application borders, so it causes issues with running multiple versions of InstUI in a single page.
+
+Global themes are useful when you have multiple React Application trees, and you want to set up themes and overrides on a more global level than application level theming.
+This basically means you don't necessarily have to wrap each application tree with an [InstUISettingsProvider](/#InstUISettingsProvider) to use themes.
+InstUI leverages the [ThemeRegistry](/#ThemeRegistry) package to achieve global theming.
+
+```jsx
+---
+type: code
+---
+// app/init sets the global theme
+import canvas from '@instructure/ui-themes'
+
+canvas.use()
+```
+
+### (DEPRECATED) Global theme overrides
+
+In order to globally register and override themes, simply import the theme you wish to use and call `.use({ overrides })` on it:
+
+```js
+---
+type: code
+---
+import ReactDOM from "react-dom"
+import { canvas } from "@instructure/ui-themes"
+
+canvas.use({
+ overrides: {
+ colors: {
+ primitives: {
+ green45: "red"
+ }
+ }
+ }
+})
+
+ReactDOM.render(
+
+ ...your application code goes here...
+
+)
+```
+
+**Note**: globally overriding themes like this means that every InstUI component will use that theme, unless they are wrapped inside an ``.
diff --git a/packages/__docs__/components.js b/packages/__docs__/components.js
index 5d077e1cad..5cb71d0db0 100644
--- a/packages/__docs__/components.js
+++ b/packages/__docs__/components.js
@@ -130,4 +130,9 @@ export { Drilldown } from '@instructure/ui-drilldown'
export { SourceCodeEditor } from '@instructure/ui-source-code-editor'
export { TopNavBar } from '@instructure/ui-top-nav-bar'
export { TruncateList } from '@instructure/ui-truncate-list'
-export { canvas, canvasHighContrast, instructure } from '@instructure/ui-themes'
+export {
+ canvas,
+ canvasHighContrast,
+ canvasThemeLocal,
+ canvasHighContrastThemeLocal
+} from '@instructure/ui-themes'
diff --git a/packages/__docs__/src/Theme/index.tsx b/packages/__docs__/src/Theme/index.tsx
index 1d53968d01..31ccac32f6 100644
--- a/packages/__docs__/src/Theme/index.tsx
+++ b/packages/__docs__/src/Theme/index.tsx
@@ -279,7 +279,7 @@ class Theme extends Component {
id={`${themeKey}ApplicationUsage`}
content={`
### Usage (before mounting your application)
-##### Global theming
+##### (DEPRECATED) Global theming
${'```javascript\n \
---\n \
type: code\n \
diff --git a/packages/emotion/src/__tests__/useTheme.test.tsx b/packages/emotion/src/__tests__/useTheme.test.tsx
index aa6c5d9f43..68985a4081 100644
--- a/packages/emotion/src/__tests__/useTheme.test.tsx
+++ b/packages/emotion/src/__tests__/useTheme.test.tsx
@@ -22,7 +22,11 @@
* SOFTWARE.
*/
import React from 'react'
-import { canvas, canvasHighContrast } from '@instructure/ui-themes'
+import {
+ canvas,
+ canvasHighContrast,
+ canvasThemeLocal
+} from '@instructure/ui-themes'
import { expect, mount, spy } from '@instructure/ui-test-utils'
import { ThemeRegistry } from '@instructure/theme-registry'
@@ -215,6 +219,37 @@ describe('useTheme hook', () => {
}
})
})
+ it('should use local themes correctly', async () => {
+ const callback = spy()
+ const theme = ThemeRegistry.registerTheme(canvas)
+ theme.use()
+ await mount(
+
+
+
+
+
+ )
+
+ expect(callback).to.have.been.calledWithMatch({
+ ...canvasThemeLocal,
+ colors: {
+ primitives: {
+ white: 'red'
+ }
+ }
+ })
+ })
})
describe('without using InstUISettingsProvider', () => {
it('should use theme from global ThemeRegistry', async () => {
@@ -352,6 +387,80 @@ describe('useTheme hook', () => {
}
})
})
+ it('local themes should work correctly', async () => {
+ const [cb1, cb2, cb3, cb4] = Array(6)
+ .fill(0)
+ .map(() => spy())
+
+ const theme = ThemeRegistry.registerTheme(canvasHighContrast)
+ theme.use({
+ overrides: {
+ colors: {
+ primitives: {
+ red12: 'red',
+ green12: 'yellow',
+ blue12: 'magenta'
+ }
+ }
+ }
+ })
+
+ await mount(
+ <>
+ {/* no provider -> canvasHighContrast theme */}
+
+
+ {/* theme provided -> canvas */}
+
+
+ {/* theme provided -> canvasThemeLocal theme */}
+
+
+ {/* theme provided -> canvas theme with overrides */}
+
+
+
+
+ >
+ )
+
+ expect(cb1).to.have.been.calledWithMatch({
+ ...theme,
+ colors: {
+ primitives: {
+ red12: 'red',
+ green12: 'yellow',
+ blue12: 'magenta'
+ }
+ }
+ })
+ expect(cb2).to.have.been.calledWith(canvas)
+ expect(cb3).to.have.been.calledWith(canvasThemeLocal)
+ expect(cb4).to.have.been.calledWithMatch({
+ ...canvasThemeLocal,
+ colors: {
+ primitives: {
+ red12: 'orange',
+ green12: 'olive'
+ }
+ }
+ })
+ })
})
it('should work correctly when multiple React trees is used', async () => {
const callback1 = spy()
diff --git a/packages/theme-registry/src/ThemeRegistry.ts b/packages/theme-registry/src/ThemeRegistry.ts
index 95ad43e475..5e628aa131 100644
--- a/packages/theme-registry/src/ThemeRegistry.ts
+++ b/packages/theme-registry/src/ThemeRegistry.ts
@@ -53,9 +53,14 @@ type Registry = {
}
type RegisteredTheme = T & {
- // DEPRECATED. Use InstUISettingsProvider instead
+ /**
+ * @deprecated since version 10
+ * @param arg the theme overrides
+ */
use(arg?: { overrides: DeepPartial }): void
- // DEPRECATED. Read its variables dirrectly from the theme object.
+ /**
+ * @deprecated since version 10
+ */
variables: BaseThemeVariables
}
@@ -118,7 +123,8 @@ function validateRegistry(registry: Registry>) {
/**
* Get the global theme registry.
- * @return {Registry} the theme registry
+ * @deprecated since version 10
+ * @return The theme registry
* @module getRegistry
*/
function getRegistry(): Registry {
@@ -127,6 +133,7 @@ function getRegistry(): Registry {
/**
* Set the global theme registry.
+ * @deprecated since version 10
* @param {Registry} registry - the registry to set/replace the current registry with.
* @returns {void}
* @module setRegistry
@@ -137,6 +144,7 @@ function setRegistry(registry: Registry): void {
/**
* Clear/reset the global theme registry.
+ * @deprecated since version 10
* @module clearRegistry
* @returns {void}
*/
@@ -146,6 +154,7 @@ function clearRegistry(): void {
/**
* Get the activated theme object.
+ * @deprecated since version 10
* @return {RegisteredTheme} the default theme object
* @module getCurrentTheme
*/
@@ -205,6 +214,11 @@ function makeTheme(theme: T): RegisteredTheme {
key,
description,
...rest,
+ /**
+ * Activate a global theme with the given overrides.
+ * @deprecated since version 10
+ * @param arg
+ */
use(arg?: { overrides: DeepPartial }): void {
activateTheme(key, arg?.overrides || {})
}
@@ -226,6 +240,7 @@ function makeTheme(theme: T): RegisteredTheme {
/**
* Registers the passed theme into the ThemeRegistry.
+ * @deprecated since version 10
* @param {BaseTheme} theme - the theme object to register into the ThemeRegistry
* @returns {RegisteredTheme} If the given theme is already in the ThemeRegistry then simply return that theme.
* Otherwise, returns the theme with a wrapper around it, so it can be `.use()`-ed to activate the given theme from the registry.
@@ -253,6 +268,9 @@ function registerTheme(theme: T): RegisteredTheme {
}
}
+/**
+ * @deprecated since version 10
+ */
const ThemeRegistry = {
getRegistry,
clearRegistry,
diff --git a/packages/theme-registry/src/__tests__/ThemeRegistry.test.ts b/packages/theme-registry/src/__tests__/ThemeRegistry.test.ts
index 52dfddba63..b26969de64 100644
--- a/packages/theme-registry/src/__tests__/ThemeRegistry.test.ts
+++ b/packages/theme-registry/src/__tests__/ThemeRegistry.test.ts
@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-import { BaseTheme } from '@instructure/shared-types'
+import type { BaseTheme } from '@instructure/shared-types'
import { expect } from '@instructure/ui-test-utils'
import { ThemeRegistry } from '../ThemeRegistry'
const defaultRegistry = ThemeRegistry.getRegistry()
diff --git a/packages/ui-themes/README.md b/packages/ui-themes/README.md
index 2aba588b16..e74224af30 100644
--- a/packages/ui-themes/README.md
+++ b/packages/ui-themes/README.md
@@ -18,14 +18,6 @@ npm install @instructure/ui-themes
##### Before mounting (rendering) your React application:
-- global theming:
-
- ```js
- import canvas from '@instructure/ui-themes'
-
- canvas.use()
- ```
-
- application level theming:
```jsx
@@ -39,9 +31,17 @@ npm install @instructure/ui-themes
)
```
+- (DEPRECATED) global theming:
+
+ ```js
+ import canvas from '@instructure/ui-themes'
+
+ canvas.use()
+ ```
+
##### To override the theme variables:
-- globally:
+- (DEPRECATED) globally:
```js
import canvas from '@instructure/ui-themes'
diff --git a/packages/ui-themes/src/__new-tests__/themes.test.tsx b/packages/ui-themes/src/__new-tests__/themes.test.tsx
index 8d5f1a1ef8..eb19dc86c2 100644
--- a/packages/ui-themes/src/__new-tests__/themes.test.tsx
+++ b/packages/ui-themes/src/__new-tests__/themes.test.tsx
@@ -21,12 +21,29 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-import { canvas, canvasHighContrast } from '..'
+import { canvas, canvasHighContrast, canvasThemeLocal } from '..'
import '@testing-library/jest-dom'
+import { ThemeRegistry } from '@instructure/theme-registry'
const themes = [canvas, canvasHighContrast]
describe('themes are backwards compatible', () => {
+ it('Local themes are not affected by ".use()"', async () => {
+ canvas.use({
+ overrides: {
+ colors: {
+ primitives: {
+ white: 'blue'
+ }
+ }
+ }
+ })
+ expect(ThemeRegistry.getCurrentTheme()?.colors?.primitives?.white).toEqual(
+ 'blue'
+ )
+ expect(canvasThemeLocal?.colors?.primitives?.white).toEqual('#FFFFFF')
+ })
+
describe("should be able to access theme variables with 'theme.variables.x'", () => {
for (const theme of themes) {
it(`${theme.key}`, () => {
diff --git a/packages/ui-themes/src/themes/canvas/index.ts b/packages/ui-themes/src/themes/canvas/index.ts
index b63fd3a44b..8007038e10 100644
--- a/packages/ui-themes/src/themes/canvas/index.ts
+++ b/packages/ui-themes/src/themes/canvas/index.ts
@@ -59,6 +59,11 @@ export type CanvasTheme = BaseTheme & {
key: 'canvas'
} & typeof sharedThemeTokens & { colors: Colors } & CanvasBrandVariables
+/**
+ * Canvas theme without the `use` function and `variables` prop.
+ * Not affected by global theme overrides (`.use()` function).
+ * Will be default in the next major version of InstUI
+ */
const __theme: CanvasTheme = {
key,
...sharedThemeTokens,
@@ -69,5 +74,4 @@ const __theme: CanvasTheme = {
const theme = ThemeRegistry.registerTheme(__theme)
export default theme
-// theme without the use() function and `variables` prop
export { __theme as canvasThemeLocal }
diff --git a/packages/ui-themes/src/themes/canvasHighContrast/index.ts b/packages/ui-themes/src/themes/canvasHighContrast/index.ts
index fe80e4bd18..a0c909cc19 100644
--- a/packages/ui-themes/src/themes/canvasHighContrast/index.ts
+++ b/packages/ui-themes/src/themes/canvasHighContrast/index.ts
@@ -33,6 +33,12 @@ export type CanvasHighContrastTheme = BaseTheme & {
key: 'canvas-high-contrast'
} & typeof sharedThemeTokens & { colors: Colors }
+/**
+ * Canvas high contrast theme without the `use` function and `variables` prop.
+ * Not affected by global theme overrides (`.use()` function).
+ *
+ * Will be default in the next major version of InstUI
+ */
const __theme: CanvasHighContrastTheme = {
key,
description: 'This theme meets WCAG 2.0 AA rules for color contrast.',