diff --git a/packages/__docs__/src/App/index.tsx b/packages/__docs__/src/App/index.tsx index f5e189d1b8..bdfd5c6782 100644 --- a/packages/__docs__/src/App/index.tsx +++ b/packages/__docs__/src/App/index.tsx @@ -22,9 +22,8 @@ * SOFTWARE. */ -import { +import React, { Component, - createContext, LegacyRef, ReactElement, SyntheticEvent, @@ -82,34 +81,18 @@ import { getComponentsForVersion } from '../../versioned-components' import { updateGlobalsForVersion } from '../../globals' import type { AppProps, AppState, DocData, LayoutSize } from './props' import { allowedProps } from './props' -import type { - LibraryOptions, - MainDocsData, - ParsedDocSummary -} from '../../buildScripts/DataTypes.mjs' +import type { ParsedDocSummary } from '../../buildScripts/DataTypes.mjs' import { logError } from '@instructure/console' import type { Spacing } from '@instructure/emotion' import type { NewComponentTypes } from '@instructure/ui-themes' import { FocusRegion } from '@instructure/ui-a11y-utils' - -type AppContextType = { - /** - * The ID of the currently selected theme. - */ - themeKey: keyof MainDocsData['themes'] - themes: MainDocsData['themes'] - library?: LibraryOptions -} - -export const AppContext = createContext({ - themes: {}, - themeKey: '', - library: undefined -}) +import { AppContext } from '../appContext' @withStyle(generateStyle, generateComponentTheme) class App extends Component { static allowedProps = allowedProps + static contextType = AppContext + declare context: React.ContextType private navRef = createRef() private navFocusRegion: FocusRegion | null = null @@ -1068,7 +1051,8 @@ class App extends Component { value={{ library: docsData.library, themeKey: this.state.themeKey!, - themes: docsData.themes + themes: docsData.themes, + componentVersion: this.state.selectedMinorVersion }} >
@@ -1111,5 +1095,4 @@ class App extends Component { } export default App -export type { AppContextType } export { App } diff --git a/packages/__docs__/src/Document/index.tsx b/packages/__docs__/src/Document/index.tsx index fec052774c..d0ed92565e 100644 --- a/packages/__docs__/src/Document/index.tsx +++ b/packages/__docs__/src/Document/index.tsx @@ -22,12 +22,13 @@ * SOFTWARE. */ -import { Component } from 'react' +import React, { Component } from 'react' import { Link } from '@instructure/ui-link' import { View } from '@instructure/ui-view' import { Tabs } from '@instructure/ui-tabs' import type { TabsProps } from '@instructure/ui-tabs' +import type { NewBaseTheme } from '@instructure/ui-themes' import { SourceCodeEditor } from '@instructure/ui-source-code-editor' import { withStyleForDocs as withStyle } from '../withStyleForDocs' @@ -41,12 +42,16 @@ import { ComponentTheme } from '../ComponentTheme' import { TableOfContents } from '../TableOfContents' import { Heading } from '../Heading' +import { AppContext } from '../appContext' + import { allowedProps } from './props' import type { DocumentProps, DocumentState, DocDataType } from './props' @withStyle(generateStyle) class Document extends Component { static allowedProps = allowedProps + static contextType = AppContext + declare context: React.ContextType static defaultProps = { description: undefined, @@ -78,34 +83,39 @@ class Document extends Component { // use PascalCase without dots (e.g. "MenuItem"). // New-theme entries are in themeVariables.newTheme.components. const selectedId = this.state.selectedDetailsTabId + type ComponentKey = keyof NewBaseTheme['components'] const childDoc = selectedId !== doc.id ? doc?.children?.find((value) => value.id === selectedId) : null // in case of some components, we need to display the theme variables of other components based on themeId (like displaying the theme variables of Options in Drillsdown.Group) - const themeKey = childDoc?.themeId || selectedId?.replace(/\./g, '') - // @ts-ignore todo type - const newThemeEntry = themeVariables?.newTheme?.components?.[themeKey] - const componentInstance = - selectedId === doc.id - ? doc?.componentInstance - : childDoc?.componentInstance - if ( - newThemeEntry && - typeof componentInstance?.generateComponentTheme !== 'function' - ) { - // new theme - use pre-computed theme object directly - this.setState({ componentTheme: newThemeEntry }) - return + const themeKey: ComponentKey = (childDoc?.themeId || + selectedId?.replace(/\./g, '')) as ComponentKey + const isLegacyTheme = this.context?.componentVersion == 'v11_6' + // new theme + if (!isLegacyTheme) { + const newThemeEntry = themeVariables?.newTheme?.components?.[themeKey] + const componentInstance = + selectedId === doc.id + ? doc?.componentInstance + : childDoc?.componentInstance + if ( + newThemeEntry && + typeof componentInstance?.generateComponentTheme !== 'function' + ) { + // new theme - use pre-computed theme object directly + this.setState({ componentTheme: newThemeEntry }) + return + } } // old theme - use generateComponentTheme function if (selectedId === doc.id) { generateTheme = doc?.componentInstance?.generateComponentTheme + // TODO functional components do not work, e.g. Avatar } else { generateTheme = childDoc?.componentInstance?.generateComponentTheme } if (typeof generateTheme === 'function' && themeVariables) { - // @ts-ignore todo type this.setState({ componentTheme: generateTheme(themeVariables) }) } else { this.setState({ componentTheme: undefined }) @@ -115,7 +125,6 @@ class Document extends Component { componentDidUpdate(prevProps: typeof this.props, prevState: DocumentState) { this.props.makeStyles?.() if ( - // @ts-ignore todo check this.props.themeVariables?.key !== prevProps.themeVariables?.key || this.state.selectedDetailsTabId != prevState.selectedDetailsTabId ) { diff --git a/packages/__docs__/src/Document/props.ts b/packages/__docs__/src/Document/props.ts index 4ff134a75e..d3f0dc4046 100644 --- a/packages/__docs__/src/Document/props.ts +++ b/packages/__docs__/src/Document/props.ts @@ -23,16 +23,16 @@ */ import { ComponentStyle, WithStyleProps } from '@instructure/emotion' -import type { BaseTheme, ThemeVariables } from '@instructure/shared-types' +import type { ThemeVariables } from '@instructure/shared-types' import { DocData } from '../App/props' -import { NewBaseTheme } from '@instructure/ui-themes' +import type { Theme, NewBaseTheme } from '@instructure/ui-themes' type DocDataType = DocData & { legacyGitBranch?: string } type DocumentOwnProps = { doc: DocDataType description: string - themeVariables?: BaseTheme | NewBaseTheme + themeVariables?: Theme repository?: string layout?: 'small' | 'medium' | 'large' | 'x-large' selectedMinorVersion?: string @@ -49,7 +49,10 @@ type DocumentStyle = ComponentStyle<'githubCornerOctoArm' | 'githubCorner'> type DocumentState = { selectedDetailsTabId: string | undefined pageRef: HTMLDivElement | null - componentTheme: Partial | undefined + componentTheme: + | ThemeVariables[keyof ThemeVariables] + | NewBaseTheme['components'][keyof NewBaseTheme['components']] + | undefined } const allowedProps: AllowedPropKeys = [ diff --git a/packages/__docs__/src/Playground/index.tsx b/packages/__docs__/src/Playground/index.tsx index afeceaba30..9d2d61d7fb 100644 --- a/packages/__docs__/src/Playground/index.tsx +++ b/packages/__docs__/src/Playground/index.tsx @@ -39,7 +39,7 @@ import { withStyleForDocs as withStyle } from '../withStyleForDocs' import generateStyle from './styles' import generateComponentTheme from './theme' -import { AppContext } from '../App' +import { AppContext } from '../appContext' import Preview from '../Preview' import { CodeSandboxButton } from '../CodeSandboxButton' import type { PlaygroundProps, PlaygroundState } from './props' diff --git a/packages/__docs__/src/appContext.ts b/packages/__docs__/src/appContext.ts new file mode 100644 index 0000000000..bf3d556b11 --- /dev/null +++ b/packages/__docs__/src/appContext.ts @@ -0,0 +1,49 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2015 - present Instructure, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import type { + LibraryOptions, + MainDocsData +} from '../buildScripts/DataTypes.mjs' +import { createContext } from 'react' + +type AppContextType = { + /** + * The ID of the currently selected theme. + */ + themeKey: keyof MainDocsData['themes'] + themes: MainDocsData['themes'] + library?: LibraryOptions + /** + * Currently selected component version, e.g. "v11_7" + */ + componentVersion?: string +} + +export const AppContext = createContext({ + themes: {}, + themeKey: '', + library: undefined, + componentVersion: undefined +}) diff --git a/packages/ui-babel-preset/package.json b/packages/ui-babel-preset/package.json index 696ab42f7b..d5d2db8cf2 100644 --- a/packages/ui-babel-preset/package.json +++ b/packages/ui-babel-preset/package.json @@ -34,7 +34,7 @@ "@babel/runtime": "^7.27.6", "@instructure/babel-plugin-transform-imports": "workspace:*", "@instructure/browserslist-config-instui": "workspace:*", - "babel-loader": "^9.2.1", + "babel-loader": "^10.0.0", "babel-plugin-dynamic-import-node": "^2.3.3", "babel-plugin-istanbul": "^7.0.0", "babel-plugin-macros": "^3.1.0", diff --git a/packages/ui-webpack-config/config/index.js b/packages/ui-webpack-config/config/index.js index 68f1aab6be..cdee8a371d 100644 --- a/packages/ui-webpack-config/config/index.js +++ b/packages/ui-webpack-config/config/index.js @@ -36,7 +36,7 @@ const config = { mode: ENV === 'production' ? 'production' : 'development', cache: ENV !== 'production', bail: !DEBUG, - devtool: ENV === 'production' ? false : 'cheap-module-source-map', + devtool: ENV === 'production' ? false : 'eval-source-map', module: { rules }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4180ce7132..dacca56e6c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1113,8 +1113,8 @@ importers: specifier: workspace:* version: link:../browserslist-config-instui babel-loader: - specifier: ^9.2.1 - version: 9.2.1(@babel/core@7.28.4)(webpack@5.102.1(esbuild@0.25.10)) + specifier: ^10.0.0 + version: 10.0.0(@babel/core@7.28.4)(webpack@5.102.1(esbuild@0.25.10)) babel-plugin-dynamic-import-node: specifier: ^2.3.3 version: 2.3.3 @@ -7258,7 +7258,7 @@ packages: '@xmldom/xmldom@0.7.13': resolution: {integrity: sha512-lm2GW5PkosIzccsaZIz7tp8cPADSIlIHWDFTR1N0SzfinhhYgeIQjFMz4rYzanCScr3DqQLeomUDArp6MWKm+g==} engines: {node: '>=10.0.0'} - deprecated: this version is no longer supported, please update to at least 0.8.* + deprecated: this version has critical issues, please update to the latest version '@xtuc/ieee754@1.2.0': resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} @@ -7584,13 +7584,6 @@ packages: '@babel/core': ^7.12.0 webpack: '>=5.61.0' - babel-loader@9.2.1: - resolution: {integrity: sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==} - engines: {node: '>= 14.15.0'} - peerDependencies: - '@babel/core': ^7.12.0 - webpack: '>=5' - babel-plugin-add-import-extension@1.6.0: resolution: {integrity: sha512-JVSQPMzNzN/S4wPRoKQ7+u8PlkV//BPUMnfWVbr63zcE+6yHdU2Mblz10Vf7qe+6Rmu4svF5jG7JxdcPi9VvKg==} peerDependencies: @@ -8060,9 +8053,6 @@ packages: common-ancestor-path@1.0.1: resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==} - common-path-prefix@3.0.0: - resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} - common-tags@1.8.2: resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} engines: {node: '>=4.0.0'} @@ -9078,10 +9068,6 @@ packages: resolution: {integrity: sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==} engines: {node: '>=6'} - find-cache-dir@4.0.0: - resolution: {integrity: sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==} - engines: {node: '>=14.16'} - find-file-up@0.1.3: resolution: {integrity: sha512-mBxmNbVyjg1LQIIpgO8hN+ybWBgDQK8qjht+EbrTCGmmPV/sc7RF1i9stPTD6bpvXZywBdrwRYxhSdJv867L6A==} engines: {node: '>=0.10.0'} @@ -9112,10 +9098,6 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - find-up@6.3.0: - resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - find-up@7.0.0: resolution: {integrity: sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==} engines: {node: '>=18'} @@ -9327,11 +9309,13 @@ packages: git-raw-commits@3.0.0: resolution: {integrity: sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==} engines: {node: '>=14'} + deprecated: This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead. hasBin: true git-raw-commits@4.0.0: resolution: {integrity: sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==} engines: {node: '>=16'} + deprecated: This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead. hasBin: true git-remote-origin-url@2.0.0: @@ -9345,6 +9329,7 @@ packages: git-semver-tags@5.0.1: resolution: {integrity: sha512-hIvOeZwRbQ+7YEUmCkHqo8FOLQZCEn18yevLHADlFPZY02KJGsu5FZt9YW/lybfK2uhWFI7Qg/07LekJiTv7iA==} engines: {node: '>=14'} + deprecated: This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead. hasBin: true git-up@7.0.0: @@ -9384,12 +9369,12 @@ packages: glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} engines: {node: '>=12'} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me glob@9.3.5: resolution: {integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==} @@ -11400,10 +11385,6 @@ packages: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} - pkg-dir@7.0.0: - resolution: {integrity: sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==} - engines: {node: '>=14.16'} - portfinder@1.0.38: resolution: {integrity: sha512-rEwq/ZHlJIKw++XtLAO8PPuOQA/zaPJOZJ37BVuN97nLpMJeuDVLVGRwbFoBgLudgdTMP2hdRJP++H+8QOA3vg==} engines: {node: '>= 10.12'} @@ -16158,13 +16139,6 @@ snapshots: find-up: 5.0.0 webpack: 5.102.1(esbuild@0.25.10) - babel-loader@9.2.1(@babel/core@7.28.4)(webpack@5.102.1(esbuild@0.25.10)): - dependencies: - '@babel/core': 7.28.4 - find-cache-dir: 4.0.0 - schema-utils: 4.3.3 - webpack: 5.102.1(esbuild@0.25.10) - babel-plugin-add-import-extension@1.6.0(@babel/core@7.28.4): dependencies: '@babel/core': 7.28.4 @@ -16733,8 +16707,6 @@ snapshots: common-ancestor-path@1.0.1: {} - common-path-prefix@3.0.0: {} - common-tags@1.8.2: {} commondir@1.0.1: {} @@ -18022,11 +17994,6 @@ snapshots: make-dir: 2.1.0 pkg-dir: 3.0.0 - find-cache-dir@4.0.0: - dependencies: - common-path-prefix: 3.0.0 - pkg-dir: 7.0.0 - find-file-up@0.1.3: dependencies: fs-exists-sync: 0.1.0 @@ -18061,11 +18028,6 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - find-up@6.3.0: - dependencies: - locate-path: 7.2.0 - path-exists: 5.0.0 - find-up@7.0.0: dependencies: locate-path: 7.2.0 @@ -20764,10 +20726,6 @@ snapshots: dependencies: find-up: 4.1.0 - pkg-dir@7.0.0: - dependencies: - find-up: 6.3.0 - portfinder@1.0.38: dependencies: async: 3.2.6