import * as PropTypes from 'prop-types'; import * as React from 'react'; import * as customPropTypes from '@fluentui/react-proptypes'; import * as _ from 'lodash'; import { Accessibility, tabBehavior } from '@fluentui/accessibility'; import { childrenExist, createShorthandFactory, UIComponentProps, commonPropTypes, rtlTextContainer, ContentComponentProps, ChildrenComponentProps, } from '../../utils'; import { ShorthandValue, ComponentEventHandler, FluentComponentStaticProps } from '../../types'; import { Box, BoxProps } from '../Box/Box'; import { ComponentWithAs, useTelemetry, getElementType, useFluentContext, useUnhandledProps, useAccessibility, useStyles, } from '@fluentui/react-bindings'; export interface CarouselNavigationItemSlotClassNames { indicator: string; content: string; } export interface CarouselNavigationItemProps extends UIComponentProps, ChildrenComponentProps, ContentComponentProps { /** * Accessibility behavior if overridden by the user. */ accessibility?: Accessibility; /** A menu item can be active. */ active?: boolean; /** Indicator for the Carousel Navigation Item. */ indicator?: ShorthandValue; /** A Carousel Navigation may have just icons. */ iconOnly?: boolean; /** CarouselNavigationIntem index inside CarouselNavigation. */ index?: number; /** * Called on click. * * @param {SyntheticEvent} event - React's original SyntheticEvent. * @param {object} data - All props. */ onClick?: ComponentEventHandler; /** The carousel navigation item can have primary type. */ primary?: boolean; /** The carousel navigation item can have secondary type. */ secondary?: boolean; /** A vertical carousel navigation displays elements vertically. */ vertical?: boolean; thumbnails?: boolean; } export type CarouselNavigationItemStylesProps = Required< Pick > & { hasContent: boolean; hasIndicator: boolean; }; export const carouselNavigationItemClassName = 'ui-carousel__navigationitem'; export const carouselNavigationItemSlotClassNames: CarouselNavigationItemSlotClassNames = { indicator: `${carouselNavigationItemClassName}__indicator`, content: `${carouselNavigationItemClassName}__content`, }; /** * A CarouselItem is an actionable item within a Carousel. */ export const CarouselNavigationItem: ComponentWithAs<'li', CarouselNavigationItemProps> & FluentComponentStaticProps = props => { const context = useFluentContext(); const { setStart, setEnd } = useTelemetry(CarouselNavigationItem.displayName, context.telemetry); setStart(); const { children, thumbnails, vertical, active, content, iconOnly, primary, indicator, className, design, styles, variables, } = props; const ElementType = getElementType(props); const unhandledProps = useUnhandledProps(CarouselNavigationItem.handledProps, props); const getA11yProps = useAccessibility(props.accessibility, { debugName: CarouselNavigationItem.displayName, actionHandlers: { performClick: event => !event.defaultPrevented && handleClick(event), }, }); const { classes, styles: resolvedStyles } = useStyles( CarouselNavigationItem.displayName, { className: carouselNavigationItemClassName, mapPropsToStyles: () => ({ thumbnails, vertical, active, hasContent: !!content, iconOnly, primary, hasIndicator: !!indicator, }), mapPropsToInlineStyles: () => ({ className, design, styles, variables, }), rtl: context.rtl, }, ); const renderContent = () => { return content ? Box.create(content, { defaultProps: () => ({ as: 'span', className: carouselNavigationItemSlotClassNames.content, styles: resolvedStyles.content, }), }) : Box.create(indicator, { defaultProps: () => ({ className: carouselNavigationItemSlotClassNames.indicator, styles: resolvedStyles.indicator, }), }); }; const handleClick = (e: Event | React.SyntheticEvent) => { _.invoke(props, 'onClick', e, props); }; const handleBlur = (e: React.SyntheticEvent) => { _.invoke(props, 'onBlur', e, props); }; const handleFocus = (e: React.SyntheticEvent) => { _.invoke(props, 'onFocus', e, props); }; const element = ( {childrenExist(children) ? children : renderContent()} ); setEnd(); return element; }; CarouselNavigationItem.displayName = 'CarouselNavigationItem'; CarouselNavigationItem.propTypes = { ...commonPropTypes.createCommon(), active: PropTypes.bool, indicator: customPropTypes.shorthandAllowingChildren, iconOnly: PropTypes.bool, index: PropTypes.number, onClick: PropTypes.func, primary: customPropTypes.every([customPropTypes.disallow(['secondary']), PropTypes.bool]), secondary: customPropTypes.every([customPropTypes.disallow(['primary']), PropTypes.bool]), vertical: PropTypes.bool, thumbnails: PropTypes.bool, }; CarouselNavigationItem.handledProps = Object.keys(CarouselNavigationItem.propTypes) as any; CarouselNavigationItem.defaultProps = { accessibility: tabBehavior as Accessibility, as: 'li', indicator: {}, }; CarouselNavigationItem.create = createShorthandFactory({ Component: CarouselNavigationItem, mappedArrayProp: 'content', });