import { compose, ProviderContextPrepared, useStyles, useUnhandledProps, Unstable_FluentContextProvider, } from '@fluentui/react-bindings'; import { noopRenderer } from '@fluentui/react-northstar-styles-renderer'; import { ComponentSlotStylesPrepared, emptyTheme, ThemeInput } from '@fluentui/styles'; import cx from 'classnames'; import { mount, shallow } from 'enzyme'; import * as React from 'react'; const TestProvider: React.FC<{ theme: ThemeInput }> = props => { const value: ProviderContextPrepared = { disableAnimations: false, renderer: { ...noopRenderer, renderRule: props => { return cx( props.color && `color-${props.color}`, props.hidden && `hidden-${props.hidden}`, props.visible && `visible-${props.visible}`, ); }, }, performance: { enableStylesCaching: false, enableVariablesCaching: false, enableSanitizeCssPlugin: false, enableBooleanVariablesCaching: false, }, rtl: false, telemetry: undefined, target: undefined, theme: { ...emptyTheme, // Noop to pass all props as styles to `renderRule()` componentStyles: new Proxy({}, { get: (): ComponentSlotStylesPrepared => ({ root: ({ props }) => props }) }), }, }; return {props.children}; }; type BaseComponentProps = { color?: string } & React.HTMLAttributes; type BaseComponentStylesProps = { color: string | undefined; open: boolean }; const BaseComponent: React.FC = compose< 'button', BaseComponentProps, BaseComponentStylesProps, {}, {} >( (props, ref, composeOptions) => { const { color } = props; const [open, setOpen] = React.useState(false); const { classes } = useStyles(composeOptions.displayName, { className: composeOptions.className, composeOptions, mapPropsToStyles: () => ({ color, open }), unstable_props: props, }); const unhandledProps = useUnhandledProps(composeOptions.handledProps, props); return ( ); }, { className: 'ui-base-with-slots', displayName: 'BaseComponentWithSlots', handledProps: ['className', 'data-start', 'data-end', 'data-main'], slots: { start: 'span', main: 'b', end: 'i', }, slotProps: props => ({ start: { 'data-attr': props['data-start'], }, main: { 'data-attr': props['data-main'], }, end: { 'data-attr': props['data-end'], }, }), }, ); describe('useCompose', () => { it('applies props on base component', () => { const wrapper = mount(, { wrappingComponent: TestProvider }); expect(wrapper.find('button').prop('className')).toContain('ui-base'); expect(wrapper.find('button').prop('className')).toContain('color-red'); }); it('applies props on composed component', () => { const wrapper = mount(