Private
Public Access
1
0
Files

104 lines
4.5 KiB
JavaScript

'use client';
import { useRenderer_unstable } from '@griffel/react';
import { useFocusVisible } from '@fluentui/react-tabster';
import { ThemeContext_unstable as ThemeContext, useFluent_unstable as useFluent, useOverrides_unstable as useOverrides, CustomStyleHooksContext_unstable as CustomStyleHooksContext } from '@fluentui/react-shared-contexts';
import { getIntrinsicElementProps, useMergedRefs, slot } from '@fluentui/react-utilities';
import * as React from 'react';
import { useFluentProviderThemeStyleTag } from './useFluentProviderThemeStyleTag';
// Meomizing empty objects to avoid unnecessary rerenders.
const DEFAULT_STYLE_HOOKS = {};
const DEFAULT_RENDERER_ATTRIBUTES = {};
/**
* Create the state required to render FluentProvider.
*
* The returned state can be modified with hooks such as useFluentProviderStyles_unstable,
* before being passed to renderFluentProvider_unstable.
*
* @param props - props from this instance of FluentProvider
* @param ref - reference to root HTMLElement of FluentProvider
*/ export const useFluentProvider_unstable = (props, ref)=>{
'use no memo';
const parentContext = useFluent();
const parentTheme = useTheme();
const parentOverrides = useOverrides();
const parentCustomStyleHooks = React.useContext(CustomStyleHooksContext) || DEFAULT_STYLE_HOOKS;
/**
* TODO: add merge functions to "dir" merge,
* nesting providers with the same "dir" should not add additional attributes to DOM
* see https://github.com/microsoft/fluentui/blob/0dc74a19f3aa5a058224c20505016fbdb84db172/packages/fluentui/react-northstar/src/utils/mergeProviderContexts.ts#L89-L93
*/ const { applyStylesToPortals = true, // eslint-disable-next-line @typescript-eslint/naming-convention
customStyleHooks_unstable, dir = parentContext.dir, targetDocument = parentContext.targetDocument, theme, overrides_unstable: overrides = {} } = props;
const mergedTheme = shallowMerge(parentTheme, theme);
const mergedOverrides = shallowMerge(parentOverrides, overrides);
const mergedCustomStyleHooks = shallowMerge(parentCustomStyleHooks, customStyleHooks_unstable);
const renderer = useRenderer_unstable();
var _renderer_styleElementAttributes;
const { styleTagId, rule } = useFluentProviderThemeStyleTag({
theme: mergedTheme,
targetDocument,
rendererAttributes: (_renderer_styleElementAttributes = renderer.styleElementAttributes) !== null && _renderer_styleElementAttributes !== void 0 ? _renderer_styleElementAttributes : DEFAULT_RENDERER_ATTRIBUTES
});
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line react-hooks/rules-of-hooks
React.useEffect(()=>{
if (mergedTheme === undefined) {
// eslint-disable-next-line no-console
console.warn([
'@fluentui/react-provider: FluentProvider does not have your "theme" defined.',
"Make sure that your top-level FluentProvider has set a `theme` prop or you're setting the theme in your child FluentProvider."
].join(' '));
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
}
return {
applyStylesToPortals,
// eslint-disable-next-line @typescript-eslint/naming-convention
customStyleHooks_unstable: mergedCustomStyleHooks,
dir,
targetDocument,
theme: mergedTheme,
// eslint-disable-next-line @typescript-eslint/naming-convention
overrides_unstable: mergedOverrides,
themeClassName: styleTagId,
components: {
root: 'div'
},
root: slot.always(getIntrinsicElementProps('div', {
...props,
dir,
// FIXME:
// `ref` is wrongly assigned to be `HTMLElement` instead of `HTMLDivElement`
// but since it would be a breaking change to fix it, we are casting ref to it's proper type
ref: useMergedRefs(ref, useFocusVisible({
targetDocument
}))
}), {
elementType: 'div'
}),
serverStyleProps: {
cssRule: rule,
attributes: {
...renderer.styleElementAttributes,
id: styleTagId
}
}
};
};
function shallowMerge(a, b) {
// Merge impacts perf: we should like to avoid it if it's possible
if (a && b) {
return {
...a,
...b
};
}
if (a) {
return a;
}
return b;
}
function useTheme() {
return React.useContext(ThemeContext);
}