import * as React from 'react'; import { Stack, IStackTokens } from 'office-ui-fabric-react/lib/Stack'; import { Text } from 'office-ui-fabric-react/lib/Text'; import { IMenuButtonProps, IMenuButtonStyles, IMenuButtonTokens, MenuButton, } from '@uifabric/experiments/lib/MenuButton'; import { ISplitButtonProps, ISplitButtonTokens, SplitButton } from '@uifabric/experiments/lib/SplitButton'; interface IRibbonMenuButtonProps extends IMenuButtonProps { vertical?: boolean; } interface ISplitRibbonMenuButtonProps extends ISplitButtonProps { vertical?: boolean; } const menuProps: ISplitButtonProps['menu'] = { items: [ { key: 'a', name: 'Item a', }, { key: 'b', name: 'Item b', }, ], }; const RibbonMenuButtonTokens: IMenuButtonTokens = { backgroundColorExpanded: '#C8C6C4', backgroundColorHovered: '#C8C6C4', backgroundColorExpandedHovered: '#C8C6C4', backgroundColorPressed: '#C8C6C4', backgroundColorExpandedPressed: '#C8C6C4', childrenGap: 0, height: '100%', }; const RibbonMenuButtonVerticalTokens: IMenuButtonTokens = { ...RibbonMenuButtonTokens, contentPadding: '2px 4px 0px', iconSize: '32px', textSize: '12px', minHeight: 0, }; const RibbonMenuButtonVerticalStyles: IMenuButtonStyles = { root: { flexDirection: 'column', }, icon: { marginBottom: 4, padding: 4, }, content: { marginBottom: '-4px', }, menuIcon: { fontSize: '6px', }, }; const RibbonMenuButton: React.FunctionComponent = props => { const mergedProps: IMenuButtonProps = props.vertical ? { ...props, menuIcon: 'ChevronDownSmall', styles: RibbonMenuButtonVerticalStyles, tokens: RibbonMenuButtonVerticalTokens, } : { ...props, tokens: RibbonMenuButtonTokens }; return ; }; const SplitMenuButtonVerticalTokens: ISplitButtonTokens = { ...RibbonMenuButtonTokens, contentPadding: 4, secondaryPadding: '0px 4px', iconSize: '32px', textSize: '12px', }; const SplitMenuButtonVerticalStyles: ISplitRibbonMenuButtonProps['styles'] = (props, theme, tokens) => { return { button: { borderBottomLeftRadius: 0, borderBottomRightRadius: 0, borderTopLeftRadius: tokens.borderRadius, borderTopRightRadius: tokens.borderRadius, borderBottomWidth: tokens.borderWidth, borderLeftWidth: tokens.borderWidth, borderRightWidth: tokens.borderWidth, borderTopWidth: tokens.borderWidth, width: '100%', }, menuButton: { borderBottomLeftRadius: tokens.borderRadius, borderBottomRightRadius: tokens.borderRadius, borderTopLeftRadius: 0, borderTopRightRadius: 0, borderBottomWidth: tokens.borderWidth, borderLeftWidth: tokens.borderWidth, borderRightWidth: tokens.borderWidth, borderTopWidth: 0, }, splitDividerContainer: { borderWidth: 0, }, }; }; const SplitMenuButtonVerticalSlots: ISplitRibbonMenuButtonProps['slots'] = { menuButton: { component: RibbonMenuButton, }, splitDivider: { render: () => null }, }; const RibbonSplitMenuButton: React.FunctionComponent = props => { const { content, vertical, ...rest } = props; const rootProps: React.DetailedHTMLProps, any> = { style: { alignItems: 'center', flexDirection: 'column', }, }; // TODO: This cast is required because menu is required in IMenuButtonSlots. However, it's provided by the top level // props of ISplitRibbonMenuButton props, so it shouldn't be required in multiple places. // Should menu be made optional in IMenuButtonSlots? const verticalMenuButtonProps: IRibbonMenuButtonProps = { content: props.content, vertical: true, } as IRibbonMenuButtonProps; // Move content to menu button when vertical. const mergedProps: ISplitRibbonMenuButtonProps = vertical ? { ...rest, root: rootProps, menuButton: verticalMenuButtonProps, styles: SplitMenuButtonVerticalStyles, tokens: SplitMenuButtonVerticalTokens, slots: SplitMenuButtonVerticalSlots, } : { ...rest, content, tokens: RibbonMenuButtonTokens }; return ; }; export class ButtonSlotsExample extends React.Component<{}, {}> { public render(): JSX.Element { const stackTokens: IStackTokens = { childrenGap: 10 }; return ( Horizontal Buttons Vertical Buttons ); } }