Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
648 changes: 648 additions & 0 deletions docs/guides/new-theme-overrides.md

Large diffs are not rendered by default.

28 changes: 26 additions & 2 deletions docs/guides/using-theme-overrides.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,18 +122,42 @@ type: example
</Alert>

<InstUISettingsProvider
theme={{
componentOverrides: {
themeOverride={{
components:{
Alert: {
infoIconBackground: "darkblue",
infoBorderColor: "darkblue"
},
Pill:{

}
}
}}
>
<InstUISettingsProvider
themeOverride={{
components:{
Alert: {
infoIconBackground: "darkblue",
infoBorderColor: "darkblue"
},
Pill:{
infoTextColor:"red"
}
}
}}
>
<Alert variant="info" margin="small">
My icon background and border should be dark blue in any theme.
</Alert>
<Pill
statusLabel="Status"
color="info"
margin="x-small"
>
Draft
</Pill>
</InstUISettingsProvider>
</InstUISettingsProvider>

<InstUISettingsProvider
Expand Down
5 changes: 4 additions & 1 deletion dprint.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
"typescript": {
"semiColons": "asi"
},
"excludes": ["**/node_modules", "!packages/ui-themes/src/themes/newThemes/"],
"excludes": [
"**/node_modules",
"!packages/ui-themes/src/themes/newThemeTokens/"
],
"plugins": ["https://plugins.dprint.dev/typescript-0.95.11.wasm"]
}
2 changes: 1 addition & 1 deletion packages/__docs__/buildScripts/build-docs.mts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ const pathsToIgnore = [
// version export mapping files (e.g. src/exports/a.ts, b.ts)
'**/src/exports/**',
// shared theme token files
'**/src/sharedThemeTokens/**',
'**/src/legacySharedThemeTokens/**',

// packages to ignore:
'**/canvas-theme/**',
Expand Down
8 changes: 7 additions & 1 deletion packages/__docs__/buildScripts/utils/buildVersionMap.mts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ export async function buildVersionMap(
continue
}

// Skip packages that don't follow the src/exports/{letter}.ts convention
const exportFilePath = path.join(pkgDir, 'src', 'exports', `${exportLetter}.ts`)
if (!fs.existsSync(exportFilePath)) {
continue
}

// Resolve per-component-dir versions from the source export file
const componentDirVersions = resolveComponentVersions(
pkgDir,
Expand Down Expand Up @@ -194,7 +200,7 @@ function resolveComponentVersions(
if (!fs.existsSync(exportFilePath)) {
throw new Error(
`[buildVersionMap] Export file not found: ${exportFilePath} (${pkgShortName}). ` +
`The package.json exports field references a file that does not exist on disk.`
`The package.json exports field references a file that does not exist on disk.`
)
}

Expand Down
1 change: 0 additions & 1 deletion packages/__docs__/src/App/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,6 @@ class App extends Component<AppProps, AppState> {
? allThemeKeys
: ['canvas', 'canvas-high-contrast']
const smallScreen = this.state.layout === 'small'

const displayThemeName = (themeKey: string) => {
if (
showNewThemes &&
Expand Down
4 changes: 3 additions & 1 deletion packages/__docs__/src/Document/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,9 @@ class Document extends Component<DocumentProps, DocumentState> {
</code>
</View>
) : null}
<ComponentTheme componentTheme={componentTheme} />
<ComponentTheme
componentTheme={componentTheme as any /* TODO-theme-types check */}
/>

<View margin="x-large 0 0" display="block">
<Heading
Expand Down
14 changes: 4 additions & 10 deletions packages/__docs__/src/Playground/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ import Preview from '../Preview'
import { CodeSandboxButton } from '../CodeSandboxButton'
import type { PlaygroundProps, PlaygroundState } from './props'
import { allowedProps } from './props'
import type { MainDocsData } from '../../buildScripts/DataTypes.mjs'

const codeIconPath = (
<path d="M14,6c0-0.984-0.813-2-2-2c-0.531,0-0.994,0.193-1.38,0.58l-9.958,9.958C0.334,14.866,0,15.271,0,16s0.279,1.08,0.646,1.447 l9.974,9.973C11.006,27.807,11.469,28,12,28c1.188,0,2-1.016,2-2c0-0.516-0.186-0.986-0.58-1.38L4.8,16l8.62-8.62 C13.814,6.986,14,6.516,14,6z M31.338,14.538L21.38,4.58C20.994,4.193,20.531,4,20,4c-1.188,0-2,1.016-2,2 c0,0.516,0.186,0.986,0.58,1.38L27.2,16l-8.62,8.62C18.186,25.014,18,25.484,18,26c0,0.984,0.813,2,2,2 c0.531,0,0.994-0.193,1.38-0.58l9.974-9.973C31.721,17.08,32,16.729,32,16S31.666,14.866,31.338,14.538z" />
Expand Down Expand Up @@ -178,11 +177,7 @@ class Playground extends Component<PlaygroundProps, PlaygroundState> {
)
}

renderPreview = (
code: string,
themeKey: string,
themes: MainDocsData['themes']
) => {
renderPreview = (code: string, themeKey: string) => {
const { fullscreen, rtl } = this.state

return (
Expand All @@ -192,7 +187,6 @@ class Playground extends Component<PlaygroundProps, PlaygroundState> {
fullscreen={fullscreen}
rtl={rtl}
themeKey={themeKey}
themes={themes}
/>
)
}
Expand All @@ -202,7 +196,7 @@ class Playground extends Component<PlaygroundProps, PlaygroundState> {
const { fullscreen } = this.state
return (
<AppContext.Consumer>
{({ themeKey, themes }) => (
{({ themeKey }) => (
<div css={styles?.playground}>
{fullscreen ? (
<Modal
Expand All @@ -218,11 +212,11 @@ class Playground extends Component<PlaygroundProps, PlaygroundState> {
onClick={this.handleMinimize}
screenReaderLabel="Close"
/>
{this.renderPreview(this.state.code, themeKey, themes)}
{this.renderPreview(this.state.code, themeKey)}
</Modal.Body>
</Modal>
) : (
this.renderPreview(this.state.code, themeKey, themes)
this.renderPreview(this.state.code, themeKey)
)}

{this.state.showCode && this.renderEditor()}
Expand Down
11 changes: 7 additions & 4 deletions packages/__docs__/src/Preview/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ import generateComponentTheme from './theme'
import { compileAndRenderExample } from '../compileAndRenderExample'
import { allowedProps } from './props'
import type { PreviewProps, PreviewState } from './props'
import canvas from '@instructure/ui-themes'
import * as themes from '@instructure/ui-themes'
import { camelize } from '@instructure/ui-utils'

@withStyle(generateStyle, generateComponentTheme)
class Preview extends Component<PreviewProps, PreviewState> {
Expand Down Expand Up @@ -69,8 +70,8 @@ class Preview extends Component<PreviewProps, PreviewState> {
}

render() {
const { code, themeKey, themes, styles } = this.props
const theme = themes?.[themeKey!]?.resource || canvas
const { code, themeKey, styles } = this.props

const dir = (this.props.rtl ? DIRECTION.rtl : DIRECTION.ltr) as
| 'rtl'
| 'ltr'
Expand All @@ -87,7 +88,9 @@ class Preview extends Component<PreviewProps, PreviewState> {

return (
<div css={styles?.preview}>
<InstUISettingsProvider theme={theme}>
{/*TODO-theme-types: fix getTheme typing*/}
{/*@ts-expect-error types*/}
<InstUISettingsProvider theme={themes?.[camelize(themeKey)!]}>
<TextDirectionContext.Provider value={dir}>
<div dir={dir}>{compiledCode}</div>
</TextDirectionContext.Provider>
Expand Down
2 changes: 0 additions & 2 deletions packages/__docs__/src/Preview/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ type PreviewOwnProps = {
inverse?: boolean
rtl?: boolean
themeKey?: keyof MainDocsData['themes']
themes?: MainDocsData['themes']
error?: string
}

Expand Down Expand Up @@ -72,7 +71,6 @@ const allowedProps: AllowedPropKeys = [
'frameless',
'inverse',
'rtl',
'themes',
'themeKey'
]
export type { PreviewProps, PreviewTheme, PreviewState }
Expand Down
4 changes: 2 additions & 2 deletions packages/emotion/src/EmotionTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ type Overrides = {

type BaseThemeOrOverride = Theme | PartialTheme | Overrides

type ThemeOrOverride =
type ThemeOrLegacyOverride =
| BaseThemeOrOverride
| ((theme: BaseTheme) => BaseThemeOrOverride)

Expand Down Expand Up @@ -147,7 +147,7 @@ export interface StyleObject {

export type {
BaseThemeOrOverride,
ThemeOrOverride,
ThemeOrLegacyOverride,
Overrides,
ComponentOverride,
SpecificThemeOverride,
Expand Down
24 changes: 20 additions & 4 deletions packages/emotion/src/InstUISettingsProvider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { DeterministicIdContextProvider } from '@instructure/ui-react-utils'

import { getTheme } from '../getTheme'

import type { ThemeOrOverride } from '../EmotionTypes'
import type { ThemeOrLegacyOverride } from '../EmotionTypes'
import type { DeterministicIdProviderValue } from '@instructure/ui-react-utils'
declare const process: Record<string, any> | undefined

Expand All @@ -40,7 +40,14 @@ type InstUIProviderProps = {
/**
* A full theme or an override object
*/
theme?: ThemeOrOverride
theme?: ThemeOrLegacyOverride

// TODO-theme-types: fix override typing
// TODO explain the usage of this override object. It will be deep merged into theme.themeOverride and the shape has to be a partial of the "newTheme" object
/**
* An override object for the new theming system.
*/
themeOverride?: any

/**
* @deprecated the `instanceCounterMap` prop is deprecated. You don't need to supply the
Expand Down Expand Up @@ -70,7 +77,8 @@ function InstUISettingsProvider({
children,
theme = {},
dir,
instanceCounterMap
instanceCounterMap,
themeOverride
}: InstUIProviderProps) {
const finalDir = dir || useContext(TextDirectionContext)

Expand All @@ -85,9 +93,17 @@ function InstUISettingsProvider({
)
}

/**
* new pattern: if you want to replace a theme inside an InstUISettingsProvider, provide it via the theme prop. It'll
* override everything, replacing the otherwise used theme.
* if you want to apply an override, use the themeOverride prop.
* For backward compatibility reasons, the old way of passing a partial theme to the theme prop is still supported, however only for
* legacy (pre v11_7) components. Overriding the newTheme this way could break the system.
*/

let providers = (
<DeterministicIdContextProvider instanceCounterMap={instanceCounterMap}>
<ThemeProvider theme={getTheme(theme)}>
<ThemeProvider theme={getTheme(theme, themeOverride)}>
<TextDirectionContext.Provider value={finalDir}>
{children}
</TextDirectionContext.Provider>
Expand Down
4 changes: 2 additions & 2 deletions packages/emotion/src/__tests__/useTheme.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ import '@testing-library/jest-dom'

import { useTheme } from '../useTheme'
import { InstUISettingsProvider } from '../InstUISettingsProvider'
import type { ThemeOrOverride } from '../EmotionTypes'
import type { ThemeOrLegacyOverride } from '../EmotionTypes'

type Props = {
callback(theme: ThemeOrOverride): void
callback(theme: ThemeOrLegacyOverride): void
}

const ExampleComponent = (props: Props) => {
Expand Down
4 changes: 2 additions & 2 deletions packages/emotion/src/getComponentThemeOverride.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
*/

import type {
ThemeOrOverride,
ThemeOverride,
Overrides,
ComponentOverride
} from './EmotionTypes'
Expand All @@ -48,7 +48,7 @@ type ComponentName = keyof ComponentOverride | undefined
* @returns The calculated theme override object
*/
const getComponentThemeOverride = (
theme: ThemeOrOverride,
theme: ThemeOverride,
displayName: string,
componentId?: string,
// ThemeOverrideProp is the old type, ThemeOverrideValue is the new one
Expand Down
Loading
Loading