diff --git a/packages/emotion/src/EmotionTypes.ts b/packages/emotion/src/EmotionTypes.ts index b120ab83dc..c77a8a810a 100644 --- a/packages/emotion/src/EmotionTypes.ts +++ b/packages/emotion/src/EmotionTypes.ts @@ -28,7 +28,7 @@ import type { ComponentThemeMap, DeepPartial } from '@instructure/shared-types' -import type { Theme } from '@instructure/ui-themes' +import type { Theme, SharedTokens } from '@instructure/ui-themes' /** * A theme object where every prop is optional @@ -121,6 +121,13 @@ type GenerateStyle = ( state?: State ) => StyleObject +type GenerateStyleRework = ( + componentTheme: ComponentTheme, + props: Props, + sharedTokens: SharedTokens, + state?: State +) => StyleObject + type GenerateStyleFunctional = ( componentTheme: ComponentTheme, params: Record @@ -150,6 +157,7 @@ export type { State, GenerateComponentTheme, GenerateStyle, + GenerateStyleRework, GenerateStyleFunctional, ComponentStyle } diff --git a/packages/emotion/src/index.ts b/packages/emotion/src/index.ts index e0de1a4c71..e827d89c17 100644 --- a/packages/emotion/src/index.ts +++ b/packages/emotion/src/index.ts @@ -27,6 +27,7 @@ export * from '@emotion/react' export { InstUISettingsProvider } from './InstUISettingsProvider' export { withStyle } from './withStyle' +export { withStyleRework } from './withStyleRework' export { ThemeablePropValues, makeThemeVars, diff --git a/packages/emotion/src/withStyle.tsx b/packages/emotion/src/withStyle.tsx index f76fbb127b..afc72e9892 100644 --- a/packages/emotion/src/withStyle.tsx +++ b/packages/emotion/src/withStyle.tsx @@ -202,20 +202,10 @@ const withStyle = decorator( ...defaultValues } - let baseComponentTheme = + const baseComponentTheme = typeof generateComponentTheme === 'function' ? generateComponentTheme(theme as BaseTheme) : {} - if ( - //@ts-expect-error TODO fix these later - theme.newTheme && - //@ts-expect-error TODO fix these later - theme.newTheme.components[ComposedComponent.componentId] - ) { - baseComponentTheme = - //@ts-expect-error TODO fix these later - theme.newTheme.components[ComposedComponent.componentId] - } const themeOverride = getComponentThemeOverride( theme, diff --git a/packages/emotion/src/withStyleRework.tsx b/packages/emotion/src/withStyleRework.tsx new file mode 100644 index 0000000000..ca4f68a696 --- /dev/null +++ b/packages/emotion/src/withStyleRework.tsx @@ -0,0 +1,288 @@ +/* + * 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 { forwardRef, useState } from 'react' +import type { + ForwardRefExoticComponent, + PropsWithoutRef, + RefAttributes +} from 'react' + +import hoistNonReactStatics from 'hoist-non-react-statics' + +import { deepEqual as isEqual } from '@instructure/ui-utils' +import { warn } from '@instructure/console' +import { decorator } from '@instructure/ui-decorator' + +import { getComponentThemeOverride } from './getComponentThemeOverride' +import { useTheme } from './useTheme' + +import type { + BaseTheme, + ComponentTheme, + InstUIComponent +} from '@instructure/shared-types' +import type { + ComponentStyle, + ComponentOverride, + GenerateComponentTheme, + GenerateStyleRework, + Props +} from './EmotionTypes' + +import type { NewComponentTypes, Theme } from '@instructure/ui-themes' + +// Extract is needed because it would allow number otherwise +// https://stackoverflow.com/a/51808262/319473 + +// Unique name of an InstUI component +type ComponentName = Extract + +interface WithStyleComponent extends InstUIComponent { + componentId?: ComponentName +} + +type WithStylePrivateProps< + Style extends ComponentStyle | null = ComponentStyle +> = Style extends null + ? object + : { + styles?: Style + makeStyles?: (extraArgs?: Record) => void + } + +type ThemeOverrideProp = { + themeOverride?: + | Partial + | ((componentTheme: Theme, currentTheme: BaseTheme) => Partial) +} + +type WithStyleProps< + Theme extends ComponentTheme | null = ComponentTheme, + Style extends ComponentStyle | null = ComponentStyle +> = Theme extends null + ? WithStylePrivateProps