fix(Provider): render portals inside styled elements (#2192)
* fix(Dialog): apply Provider styles in Dialog * add changelog entry * wip! * wip! * fix RTL props * more fixes * fix tests * fix SSR * fix merge issue * update changelog * fix inline styles & screener test * Update CHANGELOG.md * fix class issue and spreading props
This commit is contained in:
Родитель
9cd7d546d2
Коммит
dcb43c58d7
|
@ -23,6 +23,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|||
- Styles for the `Animation` component are removed from Teams theme @layershifter ([#2258](https://github.com/microsoft/fluent-ui-react/pull/2258))
|
||||
- Styles from `Popup` were moved `PopupContent` component @layershifter ([#2333](https://github.com/microsoft/fluent-ui-react/pull/2333))
|
||||
- Styles from `Tooltip` were moved `TooltipContent` component @layershifter ([#2333](https://github.com/microsoft/fluent-ui-react/pull/2333))
|
||||
- `ProviderBox` component was removed @layershifter ([#2192](https://github.com/microsoft/fluent-ui-react/pull/2192))
|
||||
- Styles and variables from `ProviderBox` are moved to `Provider` @layershifter ([#2192](https://github.com/microsoft/fluent-ui-react/pull/2192))
|
||||
|
||||
### Fixes
|
||||
- Remove dependency on Lodash in TypeScript typings @layershifter ([#2323](https://github.com/microsoft/fluent-ui-react/pull/2323))
|
||||
|
@ -33,6 +35,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|||
- Use referentially equal objects for `actions` in `useStateManager` @layershifter ([#2347](https://github.com/microsoft/fluent-ui-react/pull/2347))
|
||||
- Fix `Animation` component not to throw when `children` is not provided @mnajdova ([#2345](https://github.com/microsoft/fluent-ui-react/pull/2345))
|
||||
- Fix `loader` - adding labeling when loader get focus @kolaps33 ([#2352](https://github.com/microsoft/fluent-ui-react/pull/2352))
|
||||
- Styles from `Provider` are applied to components that rendered out of it in DOM @layershifter ([#2192](https://github.com/microsoft/fluent-ui-react/pull/2192))
|
||||
|
||||
### Features
|
||||
- Added sourcemaps to the dist output to simplify debugging @miroslavstastny ([#2329](https://github.com/microsoft/fluent-ui-react/pull/2329))
|
||||
|
|
|
@ -461,7 +461,7 @@ class ComponentExample extends React.Component<ComponentExampleProps, ComponentE
|
|||
const newTheme: ThemeInput = {
|
||||
componentVariables: {
|
||||
...componentVariables,
|
||||
ProviderBox: { background: showTransparent ? 'initial' : undefined },
|
||||
Provider: { background: showTransparent ? 'initial' : undefined },
|
||||
},
|
||||
}
|
||||
const exampleStyles = {
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
import getScreenerSteps from '../commonScreenerSteps'
|
||||
|
||||
const config: ScreenerTestsConfig = {
|
||||
themes: ['teams', 'teamsDark', 'teamsHighContrast'],
|
||||
steps: getScreenerSteps(),
|
||||
}
|
||||
|
||||
export default config
|
|
@ -0,0 +1,32 @@
|
|||
import { Button, Dialog } from '@fluentui/react'
|
||||
import * as React from 'react'
|
||||
import * as _ from 'lodash'
|
||||
|
||||
const DialogExampleScroll = () => (
|
||||
<Dialog
|
||||
content={{
|
||||
content: (
|
||||
<>
|
||||
{_.times(10, i => (
|
||||
<p key={i}>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent ornare, neque eget
|
||||
egestas fermentum, massa risus mollis orci, et ullamcorper purus turpis at risus.
|
||||
Fusce pharetra mollis sapien nec commodo. Quisque ut congue sem, vel aliquam augue.
|
||||
Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia
|
||||
Curae; Duis porttitor, nunc quis dapibus imperdiet, ligula sem egestas orci, sed
|
||||
volutpat ipsum felis vitae velit. Sed maximus egestas dui elementum aliquam. In hac
|
||||
habitasse platea dictumst. Proin maximus nibh velit, ut ornare dui mollis viverra.
|
||||
</p>
|
||||
))}
|
||||
</>
|
||||
),
|
||||
styles: {
|
||||
height: '500px',
|
||||
overflow: 'scroll',
|
||||
},
|
||||
}}
|
||||
trigger={<Button content="Open a dialog" />}
|
||||
/>
|
||||
)
|
||||
|
||||
export default DialogExampleScroll
|
|
@ -6,6 +6,9 @@ import Rtl from './Rtl'
|
|||
import Variations from './Variations'
|
||||
import Usage from './Usage'
|
||||
|
||||
import NonPublicSection from 'docs/src/components/ComponentDoc/NonPublicSection'
|
||||
import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample/ComponentExample'
|
||||
|
||||
const DialogExamples = () => (
|
||||
<>
|
||||
<Types />
|
||||
|
@ -13,6 +16,9 @@ const DialogExamples = () => (
|
|||
<Content />
|
||||
<Usage />
|
||||
<Rtl />
|
||||
<NonPublicSection title="Visual tests">
|
||||
<ComponentExample examplePath="components/Dialog/Variations/DialogExampleScroll" />
|
||||
</NonPublicSection>
|
||||
</>
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
import * as React from 'react'
|
||||
import { mergeThemes, Provider, themes } from '@fluentui/react'
|
||||
|
||||
const ProviderExampleShorthand = () => (
|
||||
<Provider
|
||||
variables={{ background: 'red' }}
|
||||
design={{ padding: '20px' }}
|
||||
styles={{ borderBottom: '3px solid blue' }}
|
||||
theme={mergeThemes(themes.teamsDark, {
|
||||
siteVariables: {
|
||||
bodyBackground: 'salmon',
|
||||
},
|
||||
componentVariables: {
|
||||
Provider: {
|
||||
color: 'yellow',
|
||||
},
|
||||
},
|
||||
componentStyles: {
|
||||
Provider: {
|
||||
root: {
|
||||
borderTop: '3px solid green',
|
||||
},
|
||||
},
|
||||
},
|
||||
})}
|
||||
>
|
||||
<p>with custom overrides</p>
|
||||
</Provider>
|
||||
)
|
||||
|
||||
export default ProviderExampleShorthand
|
|
@ -25,8 +25,7 @@ const Types = () => (
|
|||
</ExampleSection>
|
||||
<NonPublicSection title="Types for visual tests">
|
||||
<ComponentExample examplePath="components/Provider/Types/ProviderExampleScrollbar" />
|
||||
</NonPublicSection>
|
||||
<NonPublicSection title="Types for visual tests">
|
||||
<ComponentExample examplePath="components/Provider/Types/ProviderExampleStyles" />
|
||||
<ComponentExample examplePath="components/Provider/Types/ProviderExampleRendererFelaPluginFallbackValue" />
|
||||
</NonPublicSection>
|
||||
</>
|
||||
|
|
|
@ -11,10 +11,10 @@ export * from './FocusZone/focusUtilities'
|
|||
|
||||
export { default as useAccessibility } from './hooks/useAccessibility'
|
||||
export { default as useAutoControlled } from './hooks/useAutoControlled'
|
||||
export { default as useStyles } from './hooks/useStyles'
|
||||
export { default as unstable_useDispatchEffect } from './hooks/useDispatchEffect'
|
||||
export { default as useIsomorphicLayoutEffect } from './hooks/useIsomorphicLayoutEffect'
|
||||
export { default as useStateManager } from './hooks/useStateManager'
|
||||
export { default as useStyles } from './hooks/useStyles'
|
||||
|
||||
export { default as unstable_createAnimationStyles } from './styles/createAnimationStyles'
|
||||
export { default as unstable_getStyles } from './styles/getStyles'
|
||||
|
|
|
@ -287,8 +287,6 @@ class Dialog extends AutoControlledComponent<WithAsProp<DialogProps>, DialogStat
|
|||
<Ref innerRef={this.contentRef}>
|
||||
<ElementType
|
||||
className={classes.root}
|
||||
// it's required to have an `rtl` attribute there as Dialog is rendered outside the main DOM tree
|
||||
dir={rtl ? 'rtl' : undefined}
|
||||
{...accessibility.attributes.popup}
|
||||
{...unhandledProps}
|
||||
{...applyAccessibilityKeyHandlers(accessibility.keyHandlers.popup, unhandledProps)}
|
||||
|
|
|
@ -470,12 +470,12 @@ export default class Popup extends AutoControlledComponent<PopupProps, PopupStat
|
|||
rtl={rtl}
|
||||
unstable_pinned={unstable_pinned}
|
||||
targetRef={this.rightClickReferenceObject || target || this.triggerRef}
|
||||
children={this.renderPopperChildren(rtl, accessibility)}
|
||||
children={this.renderPopperChildren(accessibility)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
renderPopperChildren = (rtl: boolean, accessibility: ReactAccessibilityBehavior) => ({
|
||||
renderPopperChildren = (accessibility: ReactAccessibilityBehavior) => ({
|
||||
placement,
|
||||
scheduleUpdate,
|
||||
}: PopperChildrenProps) => {
|
||||
|
@ -491,7 +491,6 @@ export default class Popup extends AutoControlledComponent<PopupProps, PopupStat
|
|||
const content = renderContent ? renderContent(scheduleUpdate) : propsContent
|
||||
const popupContent = Popup.Content.create(content || {}, {
|
||||
defaultProps: () => ({
|
||||
...(rtl && { dir: 'rtl' }),
|
||||
...accessibility.attributes.popup,
|
||||
...accessibility.keyHandlers.popup,
|
||||
...this.getContentProps(),
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import * as PropTypes from 'prop-types'
|
||||
import * as _ from 'lodash'
|
||||
import * as PropTypes from 'prop-types'
|
||||
import * as React from 'react'
|
||||
import * as ReactDOM from 'react-dom'
|
||||
// @ts-ignore
|
||||
import { ThemeContext } from 'react-fela'
|
||||
|
||||
import { isBrowser, ChildrenComponentProps, commonPropTypes } from '../../utils'
|
||||
import { PortalBoxContext } from '../Provider/usePortalBox'
|
||||
|
||||
export interface PortalInnerProps extends ChildrenComponentProps {
|
||||
/** Existing element the portal should be bound to. */
|
||||
|
@ -30,7 +29,7 @@ export interface PortalInnerProps extends ChildrenComponentProps {
|
|||
* A PortalInner is a container for Portal's content.
|
||||
*/
|
||||
class PortalInner extends React.Component<PortalInnerProps> {
|
||||
static contextType = ThemeContext
|
||||
static contextType = PortalBoxContext
|
||||
|
||||
static propTypes = {
|
||||
...commonPropTypes.createCommon({
|
||||
|
@ -56,7 +55,9 @@ class PortalInner extends React.Component<PortalInnerProps> {
|
|||
render() {
|
||||
const { children, mountNode } = this.props
|
||||
|
||||
const target: HTMLElement | null = isBrowser() ? this.context.target.body : null
|
||||
// PortalInner should render elements even without a context
|
||||
// eslint-disable-next-line
|
||||
const target: HTMLDivElement | null = isBrowser() ? this.context || document.body : null
|
||||
const container: HTMLElement | null = mountNode || target
|
||||
|
||||
return container && ReactDOM.createPortal(children, container)
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import { IStyle } from 'fela'
|
||||
import * as _ from 'lodash'
|
||||
import {
|
||||
getElementType,
|
||||
getUnhandledProps,
|
||||
Renderer,
|
||||
StylesContextPerformance,
|
||||
Telemetry,
|
||||
unstable_getStyles,
|
||||
useIsomorphicLayoutEffect,
|
||||
} from '@fluentui/react-bindings'
|
||||
import {
|
||||
|
@ -13,7 +15,6 @@ import {
|
|||
StaticStyle,
|
||||
StaticStyleFunction,
|
||||
FontFace,
|
||||
ComponentVariablesInput,
|
||||
ThemeInput,
|
||||
SiteVariablesPrepared,
|
||||
} from '@fluentui/styles'
|
||||
|
@ -22,10 +23,13 @@ import * as React from 'react'
|
|||
// @ts-ignore
|
||||
import { RendererProvider, ThemeProvider, ThemeContext } from 'react-fela'
|
||||
|
||||
import { ChildrenComponentProps, setUpWhatInput, tryCleanupWhatInput } from '../../utils'
|
||||
import {
|
||||
ChildrenComponentProps,
|
||||
setUpWhatInput,
|
||||
tryCleanupWhatInput,
|
||||
UIComponentProps,
|
||||
} from '../../utils'
|
||||
|
||||
import ProviderConsumer from './ProviderConsumer'
|
||||
import ProviderBox, { ProviderBoxProps } from './ProviderBox'
|
||||
import {
|
||||
WithAsProp,
|
||||
ProviderContextInput,
|
||||
|
@ -33,8 +37,10 @@ import {
|
|||
withSafeTypeForAs,
|
||||
} from '../../types'
|
||||
import mergeContexts from '../../utils/mergeProviderContexts'
|
||||
import ProviderConsumer from './ProviderConsumer'
|
||||
import usePortalBox, { PortalBoxContext } from './usePortalBox'
|
||||
|
||||
export interface ProviderProps extends ChildrenComponentProps {
|
||||
export interface ProviderProps extends ChildrenComponentProps, UIComponentProps {
|
||||
renderer?: Renderer
|
||||
rtl?: boolean
|
||||
disableAnimations?: boolean
|
||||
|
@ -42,7 +48,6 @@ export interface ProviderProps extends ChildrenComponentProps {
|
|||
overwrite?: boolean
|
||||
target?: Document
|
||||
theme?: ThemeInput
|
||||
variables?: ComponentVariablesInput
|
||||
telemetryRef?: React.MutableRefObject<Telemetry>
|
||||
}
|
||||
|
||||
|
@ -99,11 +104,13 @@ const renderStaticStyles = (
|
|||
* The Provider passes the CSS-in-JS renderer, theme styles and other settings to Fluent UI components.
|
||||
*/
|
||||
const Provider: React.FC<WithAsProp<ProviderProps>> & {
|
||||
Box: typeof ProviderBox
|
||||
className: string
|
||||
Consumer: typeof ProviderConsumer
|
||||
handledProps: (keyof ProviderProps)[]
|
||||
} = props => {
|
||||
const { as, children, overwrite, variables, telemetryRef } = props
|
||||
const { children, className, design, overwrite, styles, variables, telemetryRef } = props
|
||||
|
||||
const ElementType = getElementType(props)
|
||||
const unhandledProps = getUnhandledProps(Provider.handledProps, props)
|
||||
|
||||
const telemetry = React.useMemo<Telemetry | undefined>(() => {
|
||||
|
@ -143,6 +150,30 @@ const Provider: React.FC<WithAsProp<ProviderProps>> & {
|
|||
rtlProps.dir = outgoingContext.rtl ? 'rtl' : 'ltr'
|
||||
}
|
||||
|
||||
const { classes } = unstable_getStyles({
|
||||
className: Provider.className,
|
||||
displayName: Provider.displayName,
|
||||
props: {
|
||||
className,
|
||||
design,
|
||||
styles,
|
||||
variables,
|
||||
},
|
||||
|
||||
disableAnimations: outgoingContext.disableAnimations,
|
||||
performance: outgoingContext.performance,
|
||||
renderer: outgoingContext.renderer,
|
||||
rtl: outgoingContext.rtl,
|
||||
theme: outgoingContext.theme,
|
||||
saveDebug: _.noop,
|
||||
})
|
||||
|
||||
const element = usePortalBox({
|
||||
className: classes.root,
|
||||
target: outgoingContext.target,
|
||||
rtl: outgoingContext.rtl,
|
||||
})
|
||||
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
renderFontFaces(outgoingContext.renderer, props.theme)
|
||||
renderStaticStyles(outgoingContext.renderer, props.theme, outgoingContext.theme.siteVariables)
|
||||
|
@ -158,20 +189,31 @@ const Provider: React.FC<WithAsProp<ProviderProps>> & {
|
|||
}
|
||||
}, [])
|
||||
|
||||
// do not spread anything - React.Fragment can only have `key` and `children` props
|
||||
const elementProps =
|
||||
ElementType === React.Fragment
|
||||
? {}
|
||||
: {
|
||||
className: classes.root,
|
||||
...rtlProps,
|
||||
...unhandledProps,
|
||||
}
|
||||
|
||||
return (
|
||||
<RendererProvider
|
||||
renderer={outgoingContext.renderer}
|
||||
{...{ rehydrate: false, targetDocument: outgoingContext.target }}
|
||||
>
|
||||
<ThemeProvider theme={outgoingContext} overwrite>
|
||||
<ProviderBox as={as} variables={variables} {...unhandledProps} {...rtlProps}>
|
||||
{children}
|
||||
</ProviderBox>
|
||||
<PortalBoxContext.Provider value={element}>
|
||||
<ElementType {...elementProps}>{children}</ElementType>
|
||||
</PortalBoxContext.Provider>
|
||||
</ThemeProvider>
|
||||
</RendererProvider>
|
||||
)
|
||||
}
|
||||
|
||||
Provider.className = 'ui-provider'
|
||||
Provider.displayName = 'Provider'
|
||||
|
||||
Provider.defaultProps = {
|
||||
|
@ -179,7 +221,9 @@ Provider.defaultProps = {
|
|||
}
|
||||
Provider.propTypes = {
|
||||
as: PropTypes.elementType,
|
||||
design: PropTypes.object,
|
||||
variables: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
|
||||
styles: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
|
||||
theme: PropTypes.shape({
|
||||
siteVariables: PropTypes.object,
|
||||
componentVariables: PropTypes.object,
|
||||
|
@ -220,6 +264,5 @@ Provider.propTypes = {
|
|||
Provider.handledProps = Object.keys(Provider.propTypes) as any
|
||||
|
||||
Provider.Consumer = ProviderConsumer
|
||||
Provider.Box = ProviderBox
|
||||
|
||||
export default withSafeTypeForAs<typeof Provider, ProviderProps & ProviderBoxProps>(Provider)
|
||||
export default withSafeTypeForAs<typeof Provider, ProviderProps>(Provider)
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
import * as React from 'react'
|
||||
import {
|
||||
commonPropTypes,
|
||||
ContentComponentProps,
|
||||
ChildrenComponentProps,
|
||||
UIComponentProps,
|
||||
} from '../../utils'
|
||||
import createComponentInternal from '../../utils/createComponentInternal'
|
||||
import { WithAsProp, withSafeTypeForAs } from '../../types'
|
||||
|
||||
export interface ProviderBoxProps
|
||||
extends UIComponentProps<ProviderBoxProps>,
|
||||
ContentComponentProps,
|
||||
ChildrenComponentProps {}
|
||||
|
||||
const ProviderBox = createComponentInternal<WithAsProp<ProviderBoxProps>>({
|
||||
displayName: 'ProviderBox',
|
||||
|
||||
className: 'ui-provider__box',
|
||||
|
||||
propTypes: {
|
||||
...commonPropTypes.createCommon(),
|
||||
},
|
||||
|
||||
render(config, props) {
|
||||
const { ElementType, classes, unhandledProps } = config
|
||||
const { children } = props
|
||||
if (ElementType === React.Fragment) {
|
||||
// do not spread anything - React.Fragment can only have `key` and `children` props.
|
||||
return <>{children}</>
|
||||
}
|
||||
|
||||
return (
|
||||
<ElementType className={classes.root} {...unhandledProps}>
|
||||
{children}
|
||||
</ElementType>
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
/**
|
||||
* The ProviderBox passes the CSS-in-JS renderer, theme styles and other settings to Fluent UI components.
|
||||
* Also, being comapred to Provider, it additionally renders an element to the DOM (`div` by default).
|
||||
*/
|
||||
export default withSafeTypeForAs<typeof ProviderBox, ProviderBoxProps>(ProviderBox)
|
|
@ -0,0 +1,48 @@
|
|||
import { useIsomorphicLayoutEffect } from '@fluentui/react-bindings'
|
||||
import * as React from 'react'
|
||||
|
||||
import isBrowser from '../../utils/isBrowser'
|
||||
|
||||
type UsePortalBoxOptions = {
|
||||
className: string
|
||||
rtl: boolean
|
||||
target: Document
|
||||
}
|
||||
|
||||
export const PortalBoxContext = React.createContext<HTMLDivElement>(null)
|
||||
|
||||
const usePortalBox = (options: UsePortalBoxOptions): HTMLDivElement => {
|
||||
const { className, rtl, target } = options
|
||||
|
||||
const element: HTMLDivElement | null = React.useMemo(
|
||||
() => (isBrowser() ? target.createElement('div') : null),
|
||||
[target],
|
||||
)
|
||||
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
if (element) {
|
||||
target.body.appendChild(element)
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (element) {
|
||||
target.body.removeChild(element)
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
if (element) {
|
||||
element.setAttribute('class', className)
|
||||
|
||||
if (rtl) {
|
||||
element.setAttribute('dir', 'rtl')
|
||||
} else {
|
||||
element.removeAttribute('dir')
|
||||
}
|
||||
}
|
||||
}, [className, rtl])
|
||||
|
||||
return element
|
||||
}
|
||||
|
||||
export default usePortalBox
|
|
@ -252,18 +252,17 @@ export default class Tooltip extends AutoControlledComponent<TooltipProps, Toolt
|
|||
enabled={open}
|
||||
rtl={rtl}
|
||||
targetRef={target || this.triggerRef}
|
||||
children={this.renderPopperChildren(rtl, accessibility)}
|
||||
children={this.renderPopperChildren(accessibility)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
renderPopperChildren = (rtl: boolean, accessibility: ReactAccessibilityBehavior) => ({
|
||||
renderPopperChildren = (accessibility: ReactAccessibilityBehavior) => ({
|
||||
placement,
|
||||
}: PopperChildrenProps) => {
|
||||
const { content, pointing } = this.props
|
||||
|
||||
const tooltipContentAttributes = {
|
||||
...(rtl && { dir: 'rtl' }),
|
||||
...accessibility.attributes.tooltip,
|
||||
...accessibility.keyHandlers.tooltip,
|
||||
...this.getContentProps(),
|
||||
|
|
|
@ -14,6 +14,6 @@ export { default as Menu } from './components/Menu/menuVariables'
|
|||
export { default as Icon } from './components/Icon/iconVariables'
|
||||
export { default as Reaction } from './components/Reaction/reactionVariables'
|
||||
export { default as Alert } from './components/Alert/alertVariables'
|
||||
export { default as ProviderBox } from './components/Provider/providerBoxVariables'
|
||||
export { default as Provider } from './components/Provider/providerVariables'
|
||||
export { default as Dropdown } from './components/Dropdown/dropdownVariables'
|
||||
export { default as Label } from './components/Label/labelVariables'
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
import { ProviderBoxVariables } from '../../../teams/components/Provider/providerBoxVariables'
|
||||
|
||||
export default (siteVariables): Partial<ProviderBoxVariables> => ({
|
||||
scrollbarThumbBackgroundColor: siteVariables.colors.grey[450],
|
||||
scrollbarThumbHoverBackgroundColor: siteVariables.colors.grey[400],
|
||||
})
|
|
@ -0,0 +1,6 @@
|
|||
import { ProviderVariables } from '../../../teams/components/Provider/providerVariables'
|
||||
|
||||
export default (siteVariables): Partial<ProviderVariables> => ({
|
||||
scrollbarThumbBackgroundColor: siteVariables.colors.grey[450],
|
||||
scrollbarThumbHoverBackgroundColor: siteVariables.colors.grey[400],
|
||||
})
|
|
@ -19,7 +19,7 @@ export { default as HierarchicalTreeTitle } from './components/HierarchicalTree/
|
|||
export { default as Status } from './components/Status/statusVariables'
|
||||
export { default as Reaction } from './components/Reaction/reactionVariables'
|
||||
export { default as Alert } from './components/Alert/alertVariables'
|
||||
export { default as ProviderBox } from './components/Provider/providerBoxVariables'
|
||||
export { default as Provider } from './components/Provider/providerVariables'
|
||||
export { default as Dropdown } from './components/Dropdown/dropdownVariables'
|
||||
export { default as Label } from './components/Label/labelVariables'
|
||||
export { default as TooltipContent } from './components/Tooltip/tooltipContentVariables'
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
import { ProviderBoxVariables } from '../../../teams/components/Provider/providerBoxVariables'
|
||||
|
||||
export default (siteVariables): Partial<ProviderBoxVariables> => ({
|
||||
scrollbarThumbBackgroundColor: siteVariables.colors.white,
|
||||
scrollbarThumbHoverBackgroundColor: siteVariables.colors.white,
|
||||
})
|
|
@ -0,0 +1,6 @@
|
|||
import { ProviderVariables } from '../../../teams/components/Provider/providerVariables'
|
||||
|
||||
export default (siteVariables): Partial<ProviderVariables> => ({
|
||||
scrollbarThumbBackgroundColor: siteVariables.colors.white,
|
||||
scrollbarThumbHoverBackgroundColor: siteVariables.colors.white,
|
||||
})
|
|
@ -69,7 +69,7 @@ export { default as MenuButton } from './components/MenuButton/menuButtonStyles'
|
|||
|
||||
export { default as PopupContent } from './components/Popup/popupContentStyles'
|
||||
|
||||
export { default as ProviderBox } from './components/Provider/providerBoxStyles'
|
||||
export { default as Provider } from './components/Provider/providerStyles'
|
||||
|
||||
export { default as RadioGroupItem } from './components/RadioGroup/radioGroupItemStyles'
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ export { default as MenuDivider } from './components/Menu/menuDividerVariables'
|
|||
|
||||
export { default as PopupContent } from './components/Popup/popupContentVariables'
|
||||
|
||||
export { default as ProviderBox } from './components/Provider/providerBoxVariables'
|
||||
export { default as Provider } from './components/Provider/providerVariables'
|
||||
|
||||
export { default as RadioGroupItem } from './components/RadioGroup/radioGroupItemVariables'
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { ComponentStyleFunctionParam, ICSSInJSStyle } from '@fluentui/styles'
|
||||
import { ProviderBoxVariables } from './providerBoxVariables'
|
||||
import { ProviderVariables } from './providerVariables'
|
||||
|
||||
export default {
|
||||
root: ({
|
||||
variables: v,
|
||||
}: ComponentStyleFunctionParam<never, ProviderBoxVariables>): ICSSInJSStyle => ({
|
||||
}: ComponentStyleFunctionParam<never, ProviderVariables>): ICSSInJSStyle => ({
|
||||
background: v.background,
|
||||
color: v.color,
|
||||
textAlign: 'left',
|
|
@ -1,6 +1,6 @@
|
|||
import { pxToRem } from '../../../../utils'
|
||||
|
||||
export interface ProviderBoxVariables {
|
||||
export interface ProviderVariables {
|
||||
background: string
|
||||
color: string
|
||||
|
||||
|
@ -15,7 +15,7 @@ export interface ProviderBoxVariables {
|
|||
scrollbarThumbHoverBorderSize: string
|
||||
}
|
||||
|
||||
export default (siteVariables): Partial<ProviderBoxVariables> => ({
|
||||
export default (siteVariables): Partial<ProviderVariables> => ({
|
||||
background: siteVariables.bodyBackground,
|
||||
color: siteVariables.bodyColor,
|
||||
|
|
@ -6,6 +6,27 @@ import * as React from 'react'
|
|||
import Provider from 'src/components/Provider/Provider'
|
||||
import ProviderConsumer from 'src/components/Provider/ProviderConsumer'
|
||||
|
||||
const createDocumentMock = (): Document => {
|
||||
const externalDocument = document.implementation.createDocument(
|
||||
'http://www.w3.org/1999/xhtml',
|
||||
'html',
|
||||
null,
|
||||
)
|
||||
const externalWindow: Partial<Window> = {
|
||||
ontouchstart: () => {}, // whatInput asserts for this method
|
||||
|
||||
addEventListener: () => {},
|
||||
removeEventListener: () => {},
|
||||
}
|
||||
|
||||
externalDocument.documentElement.appendChild(externalDocument.createElement('body'))
|
||||
// `defaultView` is read-only by spec, getter is used as workaround
|
||||
// https://github.com/facebook/jest/issues/2227#issuecomment-430435133
|
||||
jest.spyOn(externalDocument, 'defaultView', 'get').mockReturnValue(externalWindow as any)
|
||||
|
||||
return externalDocument
|
||||
}
|
||||
|
||||
describe('Provider', () => {
|
||||
test('is exported', () => {
|
||||
expect(require('src/index.ts').Provider).toEqual(Provider)
|
||||
|
@ -235,18 +256,10 @@ describe('Provider', () => {
|
|||
|
||||
describe('target', () => {
|
||||
test('performs whatinput init on first Provider mount', () => {
|
||||
const addEventListener = jest.fn()
|
||||
const setAttribute = jest.fn()
|
||||
const externalDocument: any = {
|
||||
defaultView: {
|
||||
addEventListener,
|
||||
removeEventListener: jest.fn(),
|
||||
ontouchstart: jest.fn(),
|
||||
},
|
||||
documentElement: {
|
||||
setAttribute,
|
||||
},
|
||||
}
|
||||
const externalDocument = createDocumentMock()
|
||||
|
||||
const addEventListener = jest.spyOn(externalDocument.defaultView, 'addEventListener')
|
||||
const setAttribute = jest.spyOn(externalDocument.documentElement, 'setAttribute')
|
||||
|
||||
mount(
|
||||
<Provider id="first-provider" target={externalDocument}>
|
||||
|
@ -262,18 +275,8 @@ describe('Provider', () => {
|
|||
})
|
||||
|
||||
test('performs whatinput cleanup on last Provider unmount', () => {
|
||||
const removeEventListener = jest.fn()
|
||||
const setAttribute = jest.fn()
|
||||
const externalDocument: any = {
|
||||
defaultView: {
|
||||
addEventListener: jest.fn(),
|
||||
removeEventListener,
|
||||
ontouchstart: jest.fn(),
|
||||
},
|
||||
documentElement: {
|
||||
setAttribute,
|
||||
},
|
||||
}
|
||||
const externalDocument = createDocumentMock()
|
||||
const removeEventListener = jest.spyOn(externalDocument.defaultView, 'removeEventListener')
|
||||
|
||||
const wrapper = mount(
|
||||
<Provider id="first-provider" target={externalDocument}>
|
||||
|
|
|
@ -14,7 +14,7 @@ exports[`felaRenderer CSS fallback values are rendered 1`] = `
|
|||
exports[`felaRenderer animations are not applied if animations are disabled 1`] = `
|
||||
"
|
||||
|
||||
<div className=ui-provider__box dir=ltr>
|
||||
<div className=ui-provider dir=ltr>
|
||||
<div className=ui-box ui-animation />
|
||||
</div>;
|
||||
"
|
||||
|
@ -62,7 +62,7 @@ exports[`felaRenderer array returned by keyframe results in CSS fallback values
|
|||
}
|
||||
|
||||
|
||||
<div className=ui-provider__box dir=ltr>
|
||||
<div className=ui-provider dir=ltr>
|
||||
<div className=ui-box ui-animation a />
|
||||
</div>;
|
||||
"
|
||||
|
@ -111,7 +111,7 @@ exports[`felaRenderer keyframe colors are rendered 1`] = `
|
|||
}
|
||||
|
||||
|
||||
<div className=ui-provider__box dir=ltr>
|
||||
<div className=ui-provider dir=ltr>
|
||||
<div className=ui-box ui-animation a b />
|
||||
</div>;
|
||||
"
|
||||
|
@ -123,7 +123,7 @@ exports[`felaRenderer marginLeft is rendered into marginLeft due to RTL with \`n
|
|||
}
|
||||
|
||||
|
||||
<div className=ui-provider__box dir=rtl>
|
||||
<div className=ui-provider dir=rtl>
|
||||
<span className=ui-text a dir=auto>
|
||||
Hello
|
||||
</span>
|
||||
|
@ -137,7 +137,7 @@ exports[`felaRenderer marginLeft is rendered into marginRight due to RTL 1`] = `
|
|||
}
|
||||
|
||||
|
||||
<div className=ui-provider__box dir=rtl>
|
||||
<div className=ui-provider dir=rtl>
|
||||
<span className=ui-text a dir=auto>
|
||||
Hello
|
||||
</span>
|
||||
|
|
Загрузка…
Ссылка в новой задаче