diff --git a/packages/fluentui/CHANGELOG.md b/packages/fluentui/CHANGELOG.md index 1c54a0f2623101..f105394c773cb0 100644 --- a/packages/fluentui/CHANGELOG.md +++ b/packages/fluentui/CHANGELOG.md @@ -100,6 +100,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Add `show` and `hide` animations in the `Popup` component @mnajdova ([#13439](https://github.com/microsoft/fluentui/pull/13439)) - Added icons: `MeetingTimeIcon`, `VideomailIcon`, `ScreenshareIcon`, `Shift24hIcon`, `ShiftActivity` @TanelVari ([#13513](https://github.com/microsoft/fluentui/pull/13513)) - Extract `Renderer` related types to a separate package @layershifter ([#13616](https://github.com/microsoft/fluentui/pull/13616)) +- Add Emotion as an optional CSS-in-JS renderer @layershifter ([#13547](https://github.com/microsoft/fluentui/pull/13547)) ### Performance - Omit `_.findKey()` usage in `focusVisibleEnhancer()` @layershifter ([#13343](https://github.com/microsoft/fluentui/pull/13343)) diff --git a/packages/fluentui/docs/package.json b/packages/fluentui/docs/package.json index f7e0755eec338a..87374bbe6bc432 100644 --- a/packages/fluentui/docs/package.json +++ b/packages/fluentui/docs/package.json @@ -15,6 +15,8 @@ "@fluentui/react-component-ref": "^0.50.0", "@fluentui/react-icons-northstar": "^0.50.0", "@fluentui/react-northstar": "^0.50.0", + "@fluentui/react-northstar-fela-renderer": "^0.49.0", + "@fluentui/react-northstar-emotion-renderer": "^0.49.0", "@fluentui/react-northstar-styles-renderer": "^0.50.0", "@fluentui/react-telemetry": "^0.50.0", "@fluentui/styles": "^0.50.0", diff --git a/packages/fluentui/docs/src/app.tsx b/packages/fluentui/docs/src/app.tsx index 5df2464e9fb171..8c1bb24a6ee0de 100644 --- a/packages/fluentui/docs/src/app.tsx +++ b/packages/fluentui/docs/src/app.tsx @@ -1,14 +1,24 @@ import * as React from 'react'; import { hot } from 'react-hot-loader/root'; -import { Provider, Debug, teamsTheme, teamsDarkTheme, teamsHighContrastTheme } from '@fluentui/react-northstar'; +import { + Provider, + Debug, + teamsTheme, + teamsDarkTheme, + teamsHighContrastTheme, + RendererContext, +} from '@fluentui/react-northstar'; +import { createEmotionRenderer } from '@fluentui/react-northstar-emotion-renderer'; +import { createFelaRenderer } from '@fluentui/react-northstar-fela-renderer'; import { TelemetryPopover } from '@fluentui/react-telemetry'; import { mergeThemes } from '@fluentui/styles'; -import { ThemeContext, ThemeContextData, themeContextDefaults } from './context/ThemeContext'; +import { ThemeName, ThemeContext, ThemeContextData, themeContextDefaults } from './context/ThemeContext'; import Routes from './routes'; // Experimental dev-time accessibility attributes integrity validation. import { setup } from '@fluentui/ability-attributes'; +import { CreateRenderer } from '../../react-northstar-styles-renderer/src'; // Temporarily disabling the validation for Screener. if (process.env.NODE_ENV !== 'production' && !process.env.SCREENER) { @@ -21,18 +31,41 @@ const themes = { teamsHighContrastTheme, }; -class App extends React.Component { +function useRendererFactory(): CreateRenderer { + const rendererFactory = localStorage.fluentRenderer === 'emotion' ? createEmotionRenderer : createFelaRenderer; + + React.useEffect(() => { + (window as any).setFluentRenderer = (rendererName: 'fela' | 'emotion') => { + if (rendererName === 'fela' || rendererName === 'emotion') { + localStorage.fluentRenderer = rendererName; + location.reload(); + } else { + throw new Error('Only "emotion" & "fela" are supported!'); + } + }; + }, []); + + return rendererFactory; +} + +const App: React.FC = () => { + const [themeName, setThemeName] = React.useState(themeContextDefaults.themeName); // State also contains the updater function so it will // be passed down into the context provider - state: ThemeContextData = { - ...themeContextDefaults, - changeTheme: (e, { value: item }) => this.setState({ themeName: item.value }), - }; - - render() { - const { themeName } = this.state; - return ( - + const themeContext = React.useMemo( + () => ({ + ...themeContextDefaults, + changeTheme: (e, data) => setThemeName(data.value.value), + themeName, + }), + [themeName], + ); + + const rendererFactory = useRendererFactory(); + + return ( + + { - - ); - } -} + + + ); +}; export default hot(App); diff --git a/packages/fluentui/docs/src/context/ThemeContext.tsx b/packages/fluentui/docs/src/context/ThemeContext.tsx index c34ac804b30104..778183f0ce035e 100644 --- a/packages/fluentui/docs/src/context/ThemeContext.tsx +++ b/packages/fluentui/docs/src/context/ThemeContext.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -type ThemeName = 'teamsTheme' | 'teamsDarkTheme' | 'teamsHighContrastTheme'; +export type ThemeName = 'teamsTheme' | 'teamsDarkTheme' | 'teamsHighContrastTheme'; type ThemeOption = { text: string; value: ThemeName }; export type ThemeContextData = { diff --git a/packages/fluentui/react-northstar-emotion-renderer/.eslintignore b/packages/fluentui/react-northstar-emotion-renderer/.eslintignore new file mode 100644 index 00000000000000..b08f6bfbd8d7fc --- /dev/null +++ b/packages/fluentui/react-northstar-emotion-renderer/.eslintignore @@ -0,0 +1,4 @@ +coverage/ +dist/ +lib/ +node_modules/ diff --git a/packages/fluentui/react-northstar-emotion-renderer/.eslintrc.json b/packages/fluentui/react-northstar-emotion-renderer/.eslintrc.json new file mode 100644 index 00000000000000..853e09ad6c3f2b --- /dev/null +++ b/packages/fluentui/react-northstar-emotion-renderer/.eslintrc.json @@ -0,0 +1,4 @@ +{ + "extends": ["../../../scripts/eslint/index"], + "root": true +} diff --git a/packages/fluentui/react-northstar-emotion-renderer/.gulp.js b/packages/fluentui/react-northstar-emotion-renderer/.gulp.js new file mode 100644 index 00000000000000..fc15ae19f15311 --- /dev/null +++ b/packages/fluentui/react-northstar-emotion-renderer/.gulp.js @@ -0,0 +1 @@ +module.exports = require('@uifabric/build/gulp/.gulp'); diff --git a/packages/fluentui/react-northstar-emotion-renderer/babel.config.js b/packages/fluentui/react-northstar-emotion-renderer/babel.config.js new file mode 100644 index 00000000000000..12a35d5c90c44e --- /dev/null +++ b/packages/fluentui/react-northstar-emotion-renderer/babel.config.js @@ -0,0 +1 @@ +module.exports = api => require('@uifabric/build/babel')(api); diff --git a/packages/fluentui/react-northstar-emotion-renderer/gulpfile.ts b/packages/fluentui/react-northstar-emotion-renderer/gulpfile.ts new file mode 100644 index 00000000000000..1494ed38c24558 --- /dev/null +++ b/packages/fluentui/react-northstar-emotion-renderer/gulpfile.ts @@ -0,0 +1 @@ +import '../../../gulpfile'; diff --git a/packages/fluentui/react-northstar-emotion-renderer/package.json b/packages/fluentui/react-northstar-emotion-renderer/package.json new file mode 100644 index 00000000000000..5d5e7e294ab757 --- /dev/null +++ b/packages/fluentui/react-northstar-emotion-renderer/package.json @@ -0,0 +1,47 @@ +{ + "name": "@fluentui/react-northstar-emotion-renderer", + "description": "A CSS-in-JS renderer based on Emotion for FluentUI React Northstar.", + "version": "0.49.0", + "bugs": "https://github.com/microsoft/fluentui/issues", + "dependencies": { + "@babel/runtime": "^7.7.6", + "@emotion/cache": "^10.0.29", + "@emotion/serialize": "^0.11.16", + "@emotion/sheet": "^0.9.4", + "@emotion/utils": "^0.11.3", + "@fluentui/react-northstar-styles-renderer": "^0.49.0", + "@fluentui/styles": "^0.49.0", + "@quid/stylis-plugin-focus-visible": "^4.0.0", + "stylis-plugin-rtl": "^1.0.0" + }, + "devDependencies": { + "@types/react": "16.8.25", + "@uifabric/build": "^7.0.0", + "lerna-alias": "^3.0.3-0", + "react": "16.8.6" + }, + "files": [ + "dist" + ], + "homepage": "https://github.com/microsoft/fluentui/tree/master/packages/fluentui/react-northstar-emotion-renderer", + "jsnext:main": "dist/es/index.js", + "license": "MIT", + "main": "dist/commonjs/index.js", + "module": "dist/es/index.js", + "peerDependencies": { + "react": "^16.8.0", + "react-dom": "^16.8.0" + }, + "publishConfig": { + "access": "public" + }, + "repository": "microsoft/fluentui.git", + "scripts": { + "build": "gulp bundle:package:no-umd", + "clean": "gulp bundle:package:clean", + "lint": "eslint --ext .js,.ts,.tsx .", + "lint:fix": "yarn lint --fix" + }, + "sideEffects": false, + "types": "dist/es/index.d.ts" +} diff --git a/packages/fluentui/react-northstar-emotion-renderer/src/createEmotionRenderer.ts b/packages/fluentui/react-northstar-emotion-renderer/src/createEmotionRenderer.ts new file mode 100644 index 00000000000000..57ba0efd677ce8 --- /dev/null +++ b/packages/fluentui/react-northstar-emotion-renderer/src/createEmotionRenderer.ts @@ -0,0 +1,121 @@ +import createCache from '@emotion/cache'; +import { ObjectInterpolation, serializeStyles } from '@emotion/serialize'; +import { StyleSheet } from '@emotion/sheet'; +import { EmotionCache, insertStyles } from '@emotion/utils'; +import { + Renderer, + RendererRenderGlobal, + RendererRenderFont, + RendererRenderRule, +} from '@fluentui/react-northstar-styles-renderer'; +// @ts-ignore No typings :( +import focusVisiblePlugin from '@quid/stylis-plugin-focus-visible'; +// @ts-ignore No typings :( +import rtlPlugin from 'stylis-plugin-rtl'; +import * as React from 'react'; + +import { disableAnimations } from './disableAnimations'; +import { generateFontSource, getFontLocals, toCSSString } from './fontUtils'; +import { invokeKeyframes } from './invokeKeyframes'; + +export function createEmotionRenderer(target?: Document): Renderer { + const cacheLtr = createCache({ + container: target?.head, + key: 'fui', + stylisPlugins: [focusVisiblePlugin], + + // TODO: make this configurable via perf flags + speedy: true, + }) as EmotionCache & { insert: Function }; + const cacheRtl = createCache({ + container: target?.head, + key: 'rfui', + stylisPlugins: [focusVisiblePlugin, rtlPlugin], + + // TODO: make this configurable via perf flags + speedy: true, + }); + + const sheet = new StyleSheet({ + key: `${cacheLtr.key}-global`, + nonce: cacheLtr.sheet.nonce, + container: cacheLtr.sheet.container, + }); + + const Provider: React.FC = props => { + // TODO: Find a way to cleanup global styles + // React.useEffect(() => { + // return () => sheet.flush(); + // }); + + return React.createElement(React.Fragment, null, props.children); + }; + + const renderRule: RendererRenderRule = (styles, param) => { + // Emotion has a bug with passing empty objects, should be fixed in upstream + if (Object.keys(styles).length === 0) { + return ''; + } + + const cache = param.direction === 'ltr' ? cacheLtr : cacheRtl; + const style = param.disableAnimations ? disableAnimations(styles) : styles; + const serialized = serializeStyles([invokeKeyframes(cache, style) as any], cache.registered, undefined); + + insertStyles(cache, serialized, true); + + return `${cache.key}-${serialized.name}`; + }; + + const renderGlobal: RendererRenderGlobal = (styles, selector) => { + if (typeof styles === 'string') { + const serializedStyles = serializeStyles( + [styles], + // This looks as a bug in typings as in Emotion code this function can be used with a single param. + // https://github.com/emotion-js/emotion/blob/a076e7fa5f78fec6515671b78801cfc9d6cf1316/packages/core/src/global.js#L45 + // @ts-ignore + undefined, + ); + + cacheLtr.insert(``, serializedStyles, sheet, false); + } + + if (typeof styles === 'object') { + if (typeof selector !== 'string') { + throw new Error('A valid "selector" is required when an object is passed to "renderGlobal"'); + } + + const serializedStyles = serializeStyles( + [{ [selector]: (styles as unknown) as ObjectInterpolation<{}> }], + // This looks as a bug in typings as in Emotion code this function can be used with a single param. + // https://github.com/emotion-js/emotion/blob/a076e7fa5f78fec6515671b78801cfc9d6cf1316/packages/core/src/global.js#L45 + // @ts-ignore + null, + ); + + cacheLtr.insert(``, serializedStyles, sheet, false); + } + }; + const renderFont: RendererRenderFont = font => { + const { localAlias, ...otherProperties } = font.props; + + const fontLocals = getFontLocals(localAlias); + const fontFamily = toCSSString(font.name); + + renderGlobal( + { + ...otherProperties, + src: generateFontSource(font.paths, fontLocals), + fontFamily, + }, + '@font-face', + ); + }; + + return { + renderGlobal, + renderFont, + renderRule, + + Provider, + }; +} diff --git a/packages/fluentui/react-northstar-emotion-renderer/src/disableAnimations.ts b/packages/fluentui/react-northstar-emotion-renderer/src/disableAnimations.ts new file mode 100644 index 00000000000000..a2515ff8cba55a --- /dev/null +++ b/packages/fluentui/react-northstar-emotion-renderer/src/disableAnimations.ts @@ -0,0 +1,26 @@ +import { ICSSInJSStyle } from '@fluentui/styles'; +import { isStyleObject } from './utils'; + +const animationProps: (keyof ICSSInJSStyle)[] = [ + 'animation', + 'animationName', + 'animationDuration', + 'animationTimingFunction', + 'animationDelay', + 'animationIterationCount', + 'animationDirection', + 'animationFillMode', + 'animationPlayState', +]; + +export function disableAnimations(styles: ICSSInJSStyle): ICSSInJSStyle { + for (const property in styles) { + if (animationProps.indexOf(property) !== -1) { + styles[property] = undefined; + } else if (isStyleObject(property)) { + styles[property] = disableAnimations(styles[property]); + } + } + + return styles; +} diff --git a/packages/fluentui/react-northstar-emotion-renderer/src/fontUtils.ts b/packages/fluentui/react-northstar-emotion-renderer/src/fontUtils.ts new file mode 100644 index 00000000000000..fec15f2bd1dfda --- /dev/null +++ b/packages/fluentui/react-northstar-emotion-renderer/src/fontUtils.ts @@ -0,0 +1,126 @@ +// +// Code here is taken mainly from fela-utils to implement to same FontFace interface. +// + +export function getFontLocals(localAlias?: string | string[]): string[] { + if (typeof localAlias === 'string') { + return [localAlias]; + } + + if (Array.isArray(localAlias)) { + return localAlias.slice(); + } + + return []; +} + +export function toCSSString(value: string): string { + if (value.charAt(0) === '"') { + return value; + } + + return `"${value}"`; +} + +function isBase64(property: string): boolean { + return property.substr(0, 5) === 'data:'; +} + +function getFontUrl(src: string): string { + if (isBase64(src)) { + return src; + } + + return `'${src}'`; +} + +const formats: Record = { + '.woff': 'woff', + '.woff2': 'woff2', + '.eot': 'embedded-opentype', + '.ttf': 'truetype', + '.otf': 'opentype', + '.svg': 'svg', + '.svgz': 'svg', +}; + +const base64Formats: Record = { + 'image/svg+xml': 'svg', + 'application/x-font-woff': 'woff', + 'application/font-woff': 'woff', + 'application/x-font-woff2': 'woff2', + 'application/font-woff2': 'woff2', + 'font/woff2': 'woff2', + 'application/octet-stream': 'truetype', + 'application/x-font-ttf': 'truetype', + 'application/x-font-truetype': 'truetype', + 'application/x-font-opentype': 'opentype', + 'application/vnd.ms-fontobject': 'embedded-opentype', + 'application/font-sfnt': 'sfnt', +}; + +function getFontFormat(src: string): string { + if (isBase64(src)) { + let mime = ''; + for (let i = 5; ; i++) { + // 'data:'.length === 5 + const c = src.charAt(i); + + if (c === ';' || c === ',') { + break; + } + + mime += c; + } + + const fmt = base64Formats[mime]; + if (fmt) { + return fmt; + } + + console.warn( + `A invalid base64 font was used. Please use one of the following mime type: ${Object.keys(base64Formats).join( + ', ', + )}.`, + ); + } else { + let extension = ''; + for (let i = src.length - 1; ; i--) { + const c = src.charAt(i); + + if (c === '.') { + extension = c + extension; + break; + } + + extension = c + extension; + } + + const fmt = formats[extension]; + if (fmt) { + return fmt; + } + + console.warn(`A invalid font-format was used in "${src}". Use one of these: ${Object.keys(formats).join(', ')}.`); + } + return ''; +} + +export function generateFontSource(files: string[] = [], fontLocals: string[] = []): string { + const localSource = fontLocals.reduce((src, local, index) => { + const prefix = index > 0 ? ',' : ''; + const localUrl = getFontUrl(local); + + return `${src}${prefix}local(${localUrl})`; + }, ''); + const urlSource = files.reduce((src, fileSource, index) => { + const prefix = index > 0 ? ',' : ''; + const fileFormat = getFontFormat(fileSource); + const fileUrl = getFontUrl(fileSource); + + return `${src}${prefix}url(${fileUrl}) format('${fileFormat}')`; + }, ''); + const delimiter = localSource.length > 0 && urlSource.length > 0 ? ',' : ''; + + return `${localSource}${delimiter}${urlSource}`; +} diff --git a/packages/fluentui/react-northstar-emotion-renderer/src/index.ts b/packages/fluentui/react-northstar-emotion-renderer/src/index.ts new file mode 100644 index 00000000000000..66a235c66a06bd --- /dev/null +++ b/packages/fluentui/react-northstar-emotion-renderer/src/index.ts @@ -0,0 +1 @@ +export { createEmotionRenderer } from './createEmotionRenderer'; diff --git a/packages/fluentui/react-northstar-emotion-renderer/src/invokeKeyframes.ts b/packages/fluentui/react-northstar-emotion-renderer/src/invokeKeyframes.ts new file mode 100644 index 00000000000000..10b80efe4c90c1 --- /dev/null +++ b/packages/fluentui/react-northstar-emotion-renderer/src/invokeKeyframes.ts @@ -0,0 +1,51 @@ +import { serializeStyles } from '@emotion/serialize'; +import { EmotionCache } from '@emotion/utils'; +import { AnimationName, ICSSInJSStyle } from '@fluentui/styles'; + +import { isStyleObject } from './utils'; + +// This code is taken from @emotion/core: +// https://github.com/emotion-js/emotion/blob/a076e7fa5f78fec6515671b78801cfc9d6cf1316/packages/core/src/keyframes.js#L11 +export const keyframes = ( + cache: EmotionCache, + keyframe: AnimationName['keyframe'], + params: AnimationName['params'] = {}, +): object => { + const style = typeof keyframe === 'function' ? keyframe(params) : keyframe; + const insertable = serializeStyles([style as any], cache.registered, undefined); + + const name = `animation-${insertable.name}`; + const styles = `@keyframes ${name}{${insertable.styles}}`; + + return { + name, + styles, + anim: 1, + toString() { + return `_EMO_${name}_${styles}_EMO_`; + }, + }; +}; + +/** + * Allows to transform animations that are defined under "animationName" to keyframes. + */ +export function invokeKeyframes(cache: EmotionCache, styles: ICSSInJSStyle) { + for (const property in styles) { + if (isStyleObject(styles[property])) { + if (property === 'animationName') { + const style = styles[property] as AnimationName; + + if (style.keyframe) { + styles[property] = keyframes(cache, style.keyframe, style.params); + } + + continue; + } + + styles[property] = invokeKeyframes(cache, styles[property]); + } + } + + return styles; +} diff --git a/packages/fluentui/react-northstar-emotion-renderer/src/utils.ts b/packages/fluentui/react-northstar-emotion-renderer/src/utils.ts new file mode 100644 index 00000000000000..677f08d3002c1f --- /dev/null +++ b/packages/fluentui/react-northstar-emotion-renderer/src/utils.ts @@ -0,0 +1,5 @@ +import { ICSSInJSStyle } from '@fluentui/styles'; + +export function isStyleObject(val: any): val is ICSSInJSStyle { + return val != null && typeof val === 'object' && Array.isArray(val) === false; +} diff --git a/packages/fluentui/react-northstar-emotion-renderer/tsconfig.json b/packages/fluentui/react-northstar-emotion-renderer/tsconfig.json new file mode 100644 index 00000000000000..50d1e6a45ec130 --- /dev/null +++ b/packages/fluentui/react-northstar-emotion-renderer/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "../../../scripts/typescript/tsconfig.fluentui", + "compilerOptions": { + "composite": true, + "outDir": "dist/dts", + "noImplicitReturns": true, + "noImplicitThis": true, + "noImplicitAny": true, + "noUnusedParameters": true, + "strictNullChecks": true + }, + "include": ["src", "test"], + "references": [ + { + "path": "../styles" + }, + { + "path": "../react-northstar-styles-renderer" + } + ] +} diff --git a/packages/fluentui/react-northstar/src/themes/teams/components/Accordion/accordionTitleStyles.ts b/packages/fluentui/react-northstar/src/themes/teams/components/Accordion/accordionTitleStyles.ts index 097507ef5bc887..8d12197f7c9dde 100644 --- a/packages/fluentui/react-northstar/src/themes/teams/components/Accordion/accordionTitleStyles.ts +++ b/packages/fluentui/react-northstar/src/themes/teams/components/Accordion/accordionTitleStyles.ts @@ -33,12 +33,12 @@ const accordionTitleStyles: ComponentSlotStylesPrepared ({ alignItems: 'center', display: 'grid', - '-ms-grid-column': '2', + msGridColumn: '2', }), }; diff --git a/packages/fluentui/react-northstar/src/themes/teams/components/Alert/alertDismissActionStyles.ts b/packages/fluentui/react-northstar/src/themes/teams/components/Alert/alertDismissActionStyles.ts index 29fd1c510511ac..9af19a87f21a8f 100644 --- a/packages/fluentui/react-northstar/src/themes/teams/components/Alert/alertDismissActionStyles.ts +++ b/packages/fluentui/react-northstar/src/themes/teams/components/Alert/alertDismissActionStyles.ts @@ -42,7 +42,7 @@ const alertDismissActionStyles: ComponentSlotStylesPrepared = { .join(' '), ...(vertical && { gridAutoFlow: 'row', - '-ms-grid-columns': '1fr', + msGridColumns: '1fr', }), }; }, @@ -51,21 +51,21 @@ const layoutStyles: ComponentSlotStylesPrepared = { ...(p.debug && debugArea()), alignItems: 'center', display: 'inline-flex', - [p.vertical ? '-ms-grid-row' : '-ms-grid-column']: '1', + [p.vertical ? 'msGridRow' : 'msGridColumn']: '1', }), main: ({ props: p }): ICSSInJSStyle => ({ ...(p.debug && debugArea()), alignItems: 'center', display: ['grid', '-ms-grid'], - [p.vertical ? '-ms-grid-row' : '-ms-grid-column']: countTrue([p.hasStart, p.hasStart && p.gap, p.hasMain]), + [p.vertical ? 'msGridRow' : 'msGridColumn']: countTrue([p.hasStart, p.hasStart && p.gap, p.hasMain]), }), end: ({ props: p }): ICSSInJSStyle => ({ ...(p.debug && debugArea()), alignItems: 'center', display: 'inline-flex', - [p.vertical ? '-ms-grid-row' : '-ms-grid-column']: countTrue([p.hasStart, p.hasStart && p.gap, p.hasMain && p.gap]), + [p.vertical ? 'msGridRow' : 'msGridColumn']: countTrue([p.hasStart, p.hasStart && p.gap, p.hasMain && p.gap]), }), }; diff --git a/packages/fluentui/react-northstar/src/themes/teams/components/SvgIcon/svgIconStyles.ts b/packages/fluentui/react-northstar/src/themes/teams/components/SvgIcon/svgIconStyles.ts index 4cd848e0caddf4..691ed384e0ed38 100644 --- a/packages/fluentui/react-northstar/src/themes/teams/components/SvgIcon/svgIconStyles.ts +++ b/packages/fluentui/react-northstar/src/themes/teams/components/SvgIcon/svgIconStyles.ts @@ -83,7 +83,7 @@ const svgIconStyles: ComponentSlotStylesPrepared { + svg: ({ props: { size, disabled, rotate }, variables: v, rtl }): ICSSInJSStyle => { const iconSizeInRems = getIconSize(size, v); return { @@ -97,6 +97,10 @@ const svgIconStyles: ComponentSlotStylesPrepared