diff --git a/change/@fluentui-react-2020-10-05-16-15-42-feat-react-swatchColorPicker.json b/change/@fluentui-react-2020-10-05-16-15-42-feat-react-swatchColorPicker.json new file mode 100644 index 0000000000000..cc81260ca7b67 --- /dev/null +++ b/change/@fluentui-react-2020-10-05-16-15-42-feat-react-swatchColorPicker.json @@ -0,0 +1,8 @@ +{ + "type": "minor", + "comment": "Adding SwatchColorPicker and ButtonGrid to @fluentui/react package and adding version imports to component .ts files.", + "packageName": "@fluentui/react", + "email": "czearing@outlook.com", + "dependentChangeType": "patch", + "date": "2020-10-05T23:15:42.316Z" +} diff --git a/change/@fluentui-react-internal-2020-10-05-16-15-42-feat-react-swatchColorPicker.json b/change/@fluentui-react-internal-2020-10-05-16-15-42-feat-react-swatchColorPicker.json new file mode 100644 index 0000000000000..74fea1422fcae --- /dev/null +++ b/change/@fluentui-react-internal-2020-10-05-16-15-42-feat-react-swatchColorPicker.json @@ -0,0 +1,8 @@ +{ + "type": "minor", + "comment": "Removing SwatchColorPicker and ButtonGrid exports.", + "packageName": "@fluentui/react-internal", + "email": "czearing@outlook.com", + "dependentChangeType": "patch", + "date": "2020-10-05T23:15:03.263Z" +} diff --git a/packages/react-internal/etc/react-internal.api.md b/packages/react-internal/etc/react-internal.api.md index 24b3de6f19e54..c4b36682f3933 100644 --- a/packages/react-internal/etc/react-internal.api.md +++ b/packages/react-internal/etc/react-internal.api.md @@ -456,19 +456,6 @@ export class Button extends React.Component { render(): JSX.Element; } -// @public (undocumented) -export const ButtonGrid: React.FunctionComponent; - -// @public (undocumented) -export class ButtonGridCell> extends React.Component { - // (undocumented) - static defaultProps: { - disabled: boolean; - }; - // (undocumented) - render(): JSX.Element; -} - // @public (undocumented) export enum ButtonType { // (undocumented) @@ -583,17 +570,6 @@ export class ColorPickerBase extends React.Component; - -// @public (undocumented) -export class ColorPickerGridCellBase extends React.PureComponent { - // (undocumented) - static defaultProps: Partial; - // (undocumented) - render(): JSX.Element; -} - // @public (undocumented) export const CommandBar: React.FunctionComponent; @@ -1054,12 +1030,6 @@ export const getSplitButtonClassNames: (styles: IButtonStyles, disabled: boolean // @public (undocumented) export function getSubmenuItems(item: IContextualMenuItem): IContextualMenuItem[] | undefined; -// @public @deprecated (undocumented) -export const Grid: React.FunctionComponent; - -// @public @deprecated (undocumented) -export const GridCell: typeof ButtonGridCell; - // @public export const HEX_REGEX: RegExp; @@ -1459,68 +1429,6 @@ export interface IButton { openMenu: (shouldFocusOnContainer?: boolean, shouldFocusOnMount?: boolean) => void; } -// @public (undocumented) -export interface IButtonGrid { -} - -// @public (undocumented) -export interface IButtonGridCellProps { - cellDisabledStyle?: string[]; - cellIsSelectedStyle?: string[]; - className?: string; - disabled?: boolean; - // Warning: (ae-forgotten-export) The symbol "IButtonClassNames" needs to be exported by the entry point index.d.ts - getClassNames?: (theme: ITheme, className: string, variantClassName: string, iconClassName: string | undefined, menuIconClassName: string | undefined, disabled: boolean, checked: boolean, expanded: boolean, isSplit: boolean | undefined) => IButtonClassNames; - id: string; - index?: number; - item: T; - label?: string; - onClick?: (item: T) => void; - onFocus?: (item: T) => void; - onHover?: (item?: T) => void; - onKeyDown?: (ev: React.KeyboardEvent) => void; - onMouseEnter?: (ev: React.MouseEvent) => boolean; - onMouseLeave?: (ev: React.MouseEvent) => void; - onMouseMove?: (ev: React.MouseEvent) => boolean; - onRenderItem: (item: T) => JSX.Element; - onWheel?: (ev: React.MouseEvent) => void; - role?: string; - selected?: boolean; -} - -// @public (undocumented) -export interface IButtonGridProps extends React.TableHTMLAttributes { - ariaPosInSet?: number; - ariaSetSize?: number; - columnCount: number; - componentRef?: IRefObject; - // @deprecated - containerClassName?: string; - doNotContainWithinFocusZone?: boolean; - items: any[]; - onBlur?: () => void; - onRenderItem: (item: any, index: number) => JSX.Element; - // @deprecated (undocumented) - positionInSet?: number; - // @deprecated (undocumented) - setSize?: number; - shouldFocusCircularNavigate?: boolean; - styles?: IStyleFunctionOrObject; - theme?: ITheme; -} - -// @public -export interface IButtonGridStyleProps { - theme: ITheme; -} - -// @public -export interface IButtonGridStyles { - focusedContainer?: IStyle; - root: IStyle; - tableCell: IStyle; -} - // @public (undocumented) export interface IButtonProps extends React.AllHTMLAttributes { allowDisabledFocus?: boolean; @@ -1539,6 +1447,7 @@ export interface IButtonProps extends React.AllHTMLAttributes; + // Warning: (ae-forgotten-export) The symbol "IButtonClassNames" needs to be exported by the entry point index.d.ts getClassNames?: (theme: ITheme, className: string, variantClassName: string, iconClassName: string | undefined, menuIconClassName: string | undefined, disabled: boolean, checked: boolean, expanded: boolean, hasMenu: boolean, isSplit: boolean | undefined, allowDisabledFocus: boolean) => IButtonClassNames; getSplitButtonClassNames?: (disabled: boolean, expanded: boolean, checked: boolean, allowDisabledFocus: boolean) => ISplitButtonClassNames; href?: string; @@ -2077,69 +1986,11 @@ export interface IColor extends IRGB, IHSV { t?: number; } -// @public (undocumented) -export interface IColorCellProps { - color?: string; - id: string; - index?: number; - label?: string; -} - // @public (undocumented) export interface IColorPicker { color: IColor; } -// @public (undocumented) -export interface IColorPickerGridCellProps { - borderWidth?: number; - circle?: boolean; - color?: string; - disabled?: boolean; - height?: number; - // @deprecated - id?: string; - idPrefix?: string; - index?: number; - item: IColorCellProps; - label?: string; - onClick?: (item: IColorCellProps) => void; - // (undocumented) - onFocus?: (item: IColorCellProps) => void; - // (undocumented) - onHover?: (item?: IColorCellProps) => void; - // (undocumented) - onKeyDown?: (ev: React.KeyboardEvent) => void; - onMouseEnter?: (ev: React.MouseEvent) => boolean; - // (undocumented) - onMouseLeave?: (ev: React.MouseEvent) => void; - onMouseMove?: (ev: React.MouseEvent) => boolean; - // (undocumented) - onWheel?: (ev: React.MouseEvent) => void; - selected: boolean; - styles?: IStyleFunctionOrObject; - theme?: ITheme; - width?: number; -} - -// @public (undocumented) -export interface IColorPickerGridCellStyleProps { - borderWidth?: number; - circle?: boolean; - disabled?: boolean; - height?: number; - isWhite?: boolean; - selected?: boolean; - theme: ITheme; - width?: number; -} - -// @public (undocumented) -export interface IColorPickerGridCellStyles { - colorCell: IStyle; - svg: IStyle; -} - // @public (undocumented) export interface IColorPickerProps { // @deprecated @@ -3245,26 +3096,6 @@ export interface IGenericItem { ValidationState: ValidationState; } -// @public @deprecated (undocumented) -export interface IGrid extends IButtonGrid { -} - -// @public @deprecated (undocumented) -export interface IGridCellProps extends IButtonGridCellProps { -} - -// @public @deprecated (undocumented) -export interface IGridProps extends IButtonGridProps { -} - -// @public @deprecated (undocumented) -export interface IGridStyleProps extends IButtonGridStyleProps { -} - -// @public @deprecated (undocumented) -export interface IGridStyles extends IButtonGridStyles { -} - // @public (undocumented) export interface IHoverCard { dismiss: (withTimeOut?: boolean) => void; @@ -5677,59 +5508,6 @@ export interface ISuggestionsSubComponentStyles { // @public export function isValidShade(shade?: Shade): boolean; -// @public (undocumented) -export interface ISwatchColorPickerProps { - ariaPosInSet?: number; - ariaSetSize?: number; - cellBorderWidth?: number; - cellHeight?: number; - cellMargin?: number; - cellShape?: 'circle' | 'square'; - cellWidth?: number; - className?: string; - colorCells: IColorCellProps[]; - columnCount: number; - disabled?: boolean; - doNotContainWithinFocusZone?: boolean; - focusOnHover?: boolean; - getColorGridCellStyles?: IStyleFunctionOrObject; - id?: string; - isControlled?: boolean; - mouseLeaveParentSelector?: string | undefined; - onCellFocused?: (id?: string, color?: string) => void; - onCellHovered?: (id?: string, color?: string) => void; - onColorChanged?: (id?: string, color?: string) => void; - onRenderColorCell?: IRenderFunction; - // @deprecated (undocumented) - positionInSet?: number; - selectedId?: string; - // @deprecated (undocumented) - setSize?: number; - shouldFocusCircularNavigate?: boolean; - styles?: IStyleFunctionOrObject; - theme?: ITheme; -} - -// @public (undocumented) -export interface ISwatchColorPickerState { - // (undocumented) - selectedIndex?: number; -} - -// @public -export interface ISwatchColorPickerStyleProps { - cellMargin?: number; - className?: string; - theme: ITheme; -} - -// @public -export interface ISwatchColorPickerStyles { - focusedContainer?: IStyle; - root: IStyle; - tableCell: IStyle; -} - // @public export interface ITag { key: string | number; @@ -7512,22 +7290,6 @@ export type SuggestionsStoreOptions = { getAriaLabel?: (item: T) => string; }; -// @public (undocumented) -export const SwatchColorPicker: React.FunctionComponent; - -// @public (undocumented) -export class SwatchColorPickerBase extends React.Component { - constructor(props: ISwatchColorPickerProps); - // (undocumented) - componentWillUnmount(): void; - // (undocumented) - static defaultProps: ISwatchColorPickerProps; - // (undocumented) - render(): JSX.Element | null; - // (undocumented) - UNSAFE_componentWillReceiveProps(newProps: ISwatchColorPickerProps): void; -} - // @public (undocumented) export const TagItem: React.FunctionComponent; diff --git a/packages/react-internal/src/Grid.ts b/packages/react-internal/src/Grid.ts deleted file mode 100644 index 6c8abf888ccf3..0000000000000 --- a/packages/react-internal/src/Grid.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './utilities/ButtonGrid/index'; diff --git a/packages/react-internal/src/SwatchColorPicker.ts b/packages/react-internal/src/SwatchColorPicker.ts deleted file mode 100644 index 5f24569fd03c2..0000000000000 --- a/packages/react-internal/src/SwatchColorPicker.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './components/SwatchColorPicker/index'; diff --git a/packages/react-internal/src/components/SwatchColorPicker/ColorPickerGridCell.base.tsx b/packages/react-internal/src/components/SwatchColorPicker/ColorPickerGridCell.base.tsx deleted file mode 100644 index be0409dd7d4b8..0000000000000 --- a/packages/react-internal/src/components/SwatchColorPicker/ColorPickerGridCell.base.tsx +++ /dev/null @@ -1,158 +0,0 @@ -import * as React from 'react'; -import { ITheme, mergeStyleSets } from '../../Styling'; -import { classNamesFunction, memoizeFunction } from '../../Utilities'; -import { getColorFromString } from '../../utilities/color/getColorFromString'; -import { ButtonGridCell } from '../../utilities/ButtonGrid/ButtonGridCell'; -import { IButtonGridCellProps } from '../../utilities/ButtonGrid/ButtonGridCell.types'; -import { getStyles as getActionButtonStyles } from '../Button/ActionButton/ActionButton.styles'; -import { IButtonClassNames } from '../Button/BaseButton.classNames'; -import { - IColorCellProps, - IColorPickerGridCellProps, - IColorPickerGridCellStyleProps, - IColorPickerGridCellStyles, -} from './ColorPickerGridCell.types'; - -const getColorPickerGridCellButtonClassNames = memoizeFunction( - ( - theme: ITheme, - className: string, - variantClassName: string, - iconClassName: string | undefined, - menuIconClassName: string | undefined, - disabled: boolean, - checked: boolean, - expanded: boolean, - isSplit: boolean | undefined, - ): IButtonClassNames => { - const styles = getActionButtonStyles(theme); - return mergeStyleSets({ - root: [ - 'ms-Button', - styles.root, - variantClassName, - className, - checked && ['is-checked', styles.rootChecked], - disabled && ['is-disabled', styles.rootDisabled], - !disabled && - !checked && { - selectors: { - ':hover': styles.rootHovered, - ':focus': styles.rootFocused, - ':active': styles.rootPressed, - }, - }, - disabled && checked && [styles.rootCheckedDisabled], - !disabled && - checked && { - selectors: { - ':hover': styles.rootCheckedHovered, - ':active': styles.rootCheckedPressed, - }, - }, - ], - flexContainer: ['ms-Button-flexContainer', styles.flexContainer], - }); - }, -); - -const getClassNames = classNamesFunction(); - -class ColorCell extends ButtonGridCell> {} - -export class ColorPickerGridCellBase extends React.PureComponent { - public static defaultProps: Partial = { - circle: true, - disabled: false, - selected: false, - }; - - private _classNames: { [key in keyof IColorPickerGridCellStyles]: string }; - - public render(): JSX.Element { - const { - item, - // eslint-disable-next-line deprecation/deprecation - idPrefix = this.props.id, - selected, - disabled, - styles, - theme, - circle, - color, - onClick, - onHover, - onFocus, - onMouseEnter, - onMouseMove, - onMouseLeave, - onWheel, - onKeyDown, - height, - width, - borderWidth, - } = this.props; - - this._classNames = getClassNames(styles!, { - theme: theme!, - disabled, - selected, - circle, - isWhite: this._isWhiteCell(color), - height, - width, - borderWidth, - }); - - return ( - - ); - } - - /** - * Render the core of a color cell - * @returns - Element representing the core of the item - */ - private _onRenderColorOption = (colorOption: IColorCellProps): JSX.Element => { - // Build an SVG for the cell with the given shape and color properties - return ( - - {this.props.circle ? : } - - ); - }; - - /** - * Validate if the cell's color is white or not to apply whiteCell style - * @param inputColor - The color of the current cell - * @returns - Whether the cell's color is white or not. - */ - private _isWhiteCell(inputColor: string | undefined): boolean { - const color = getColorFromString(inputColor!); - return color!.hex === 'ffffff'; - } -} diff --git a/packages/react-internal/src/components/SwatchColorPicker/SwatchColorPicker.base.tsx b/packages/react-internal/src/components/SwatchColorPicker/SwatchColorPicker.base.tsx deleted file mode 100644 index abf4776b2a869..0000000000000 --- a/packages/react-internal/src/components/SwatchColorPicker/SwatchColorPicker.base.tsx +++ /dev/null @@ -1,379 +0,0 @@ -import * as React from 'react'; -import { - Async, - classNamesFunction, - findIndex, - KeyCodes, - getId, - warnMutuallyExclusive, - warnConditionallyRequiredProps, -} from '../../Utilities'; -import { - ISwatchColorPickerProps, - ISwatchColorPickerStyleProps, - ISwatchColorPickerStyles, -} from './SwatchColorPicker.types'; -import { ButtonGrid } from '../../utilities/ButtonGrid/ButtonGrid'; -import { IColorCellProps } from './ColorPickerGridCell.types'; -import { ColorPickerGridCell } from './ColorPickerGridCell'; -import { memoizeFunction, warnDeprecations } from '@uifabric/utilities'; - -export interface ISwatchColorPickerState { - selectedIndex?: number; -} - -const getClassNames = classNamesFunction(); - -const COMPONENT_NAME = 'SwatchColorPicker'; - -export class SwatchColorPickerBase extends React.Component { - public static defaultProps = { - cellShape: 'circle', - disabled: false, - shouldFocusCircularNavigate: true, - cellMargin: 10, - } as ISwatchColorPickerProps; - - private _id: string; - private _cellFocused: boolean; - - private navigationIdleTimeoutId: number | undefined; - private isNavigationIdle: boolean; - private readonly navigationIdleDelay: number = 250 /* ms */; - private async: Async; - - // Add an index to each color cells. Memoizes this so that color cells do not re-render on every update. - private _getItemsWithIndex = memoizeFunction((items: IColorCellProps[]) => { - return items.map((item, index) => { - return { ...item, index: index }; - }); - }); - - constructor(props: ISwatchColorPickerProps) { - super(props); - - this._id = props.id || getId('swatchColorPicker'); - - if (process.env.NODE_ENV !== 'production') { - warnMutuallyExclusive(COMPONENT_NAME, props, { - focusOnHover: 'onHover', - }); - - warnConditionallyRequiredProps( - COMPONENT_NAME, - props, - ['focusOnHover'], - 'mouseLeaveParentSelector', - !!props.mouseLeaveParentSelector, - ); - - warnDeprecations(COMPONENT_NAME, props, { - positionInSet: 'ariaPosInSet', - setSize: 'ariaSetSize', - }); - } - - this.isNavigationIdle = true; - this.async = new Async(this); - - let selectedIndex: number | undefined; - if (props.selectedId) { - selectedIndex = this._getSelectedIndex(props.colorCells, props.selectedId); - } - - this.state = { - selectedIndex, - }; - } - - public UNSAFE_componentWillReceiveProps(newProps: ISwatchColorPickerProps): void { - if (newProps.selectedId !== undefined) { - this.setState({ - selectedIndex: this._getSelectedIndex(newProps.colorCells, newProps.selectedId), - }); - } - } - - public componentWillUnmount() { - if (this.props.onCellFocused && this._cellFocused) { - this._cellFocused = false; - this.props.onCellFocused(); - } - this.async.dispose(); - } - - public render(): JSX.Element | null { - const { - colorCells, - columnCount, - /* eslint-disable deprecation/deprecation */ - ariaPosInSet = this.props.positionInSet, - ariaSetSize = this.props.setSize, - /* eslint-enable deprecation/deprecation */ - shouldFocusCircularNavigate, - className, - doNotContainWithinFocusZone, - styles, - cellMargin, - } = this.props; - - const classNames = getClassNames(styles!, { - theme: this.props.theme!, - className, - cellMargin, - }); - - if (colorCells.length < 1 || columnCount < 1) { - return null; - } - return ( - - ); - } - - private _onRenderItem = (item: IColorCellProps, index: number): JSX.Element => { - const { onRenderColorCell = this._renderOption } = this.props; - return onRenderColorCell(item, this._renderOption) as JSX.Element; - }; - - /** - * When the whole swatchColorPicker is blurred, - * make sure to clear the pending focused stated - */ - private _onSwatchColorPickerBlur = (): void => { - if (this.props.onCellFocused) { - this._cellFocused = false; - this.props.onCellFocused(); - } - }; - - /** - * Get the selected item's index - * @param items - The items to search - * @param selectedId - The selected item's id to find - * @returns - The index of the selected item's id, -1 if there was no match - */ - private _getSelectedIndex(items: IColorCellProps[], selectedId: string): number | undefined { - const selectedIndex = findIndex(items, item => item.id === selectedId); - return selectedIndex >= 0 ? selectedIndex : undefined; - } - - /** - * Render a color cell - * @param item - The item to render - * @returns - Element representing the item - */ - private _renderOption = (item: IColorCellProps): JSX.Element => { - const props = this.props; - const id = this._id; - - return ( - - ); - }; - - /** - * Callback passed to the GridCell that will manage triggering the onCellHovered callback for mouseEnter - */ - private _onMouseEnter = (ev: React.MouseEvent): boolean => { - if (!this.props.focusOnHover) { - return !this.isNavigationIdle || !!this.props.disabled; - } - - if (this.isNavigationIdle && !this.props.disabled) { - ev.currentTarget.focus(); - } - - return true; - }; - - /** - * Callback passed to the GridCell that will manage Hover/Focus updates - */ - private _onMouseMove = (ev: React.MouseEvent): boolean => { - if (!this.props.focusOnHover) { - return !this.isNavigationIdle || !!this.props.disabled; - } - - const targetElement = ev.currentTarget as HTMLElement; - - // If navigation is idle and the targetElement is the focused element bail out - // if (!this.isNavigationIdle || (document && targetElement === (document.activeElement as HTMLElement))) { - if (this.isNavigationIdle && !(document && targetElement === (document.activeElement as HTMLElement))) { - targetElement.focus(); - } - - return true; - }; - - /** - * Callback passed to the GridCell that will manage Hover/Focus updates - */ - private _onMouseLeave = (ev: React.MouseEvent): void => { - const parentSelector = this.props.mouseLeaveParentSelector; - - if (!this.props.focusOnHover || !parentSelector || !this.isNavigationIdle || this.props.disabled) { - return; - } - - // Get the elements that math the given selector - const elements = document.querySelectorAll(parentSelector); - - // iterate over the elements return to make sure it is a parent of the target and focus it - for (let index = 0; index < elements.length; index += 1) { - if (elements[index].contains(ev.currentTarget)) { - /** - * IE11 focus() method forces parents to scroll to top of element. - * Edge and IE expose a setActive() function for focusable divs that - * sets the page focus but does not scroll the parent element. - */ - if ((elements[index] as any).setActive) { - try { - (elements[index] as any).setActive(); - } catch (e) { - /* no-op */ - } - } else { - (elements[index] as HTMLElement).focus(); - } - - break; - } - } - }; - - /** - * Callback to make sure we don't update the hovered element during mouse wheel - */ - private _onWheel = (): void => { - this._setNavigationTimeout(); - }; - - /** - * Callback that - */ - private _onKeyDown = (ev: React.KeyboardEvent): void => { - if ( - ev.which === KeyCodes.up || - ev.which === KeyCodes.down || - ev.which === KeyCodes.left || - ev.which === KeyCodes.right - ) { - this._setNavigationTimeout(); - } - }; - - /** - * Sets a timeout so we won't process any mouse "hover" events - * while navigating (via mouseWheel or arrowKeys) - */ - private _setNavigationTimeout = () => { - if (!this.isNavigationIdle && this.navigationIdleTimeoutId !== undefined) { - this.async.clearTimeout(this.navigationIdleTimeoutId); - this.navigationIdleTimeoutId = undefined; - } else { - this.isNavigationIdle = false; - } - - this.navigationIdleTimeoutId = this.async.setTimeout(() => { - this.isNavigationIdle = true; - }, this.navigationIdleDelay); - }; - - /** - * Callback passed to the GridCell class that will trigger the onCellHovered callback of the SwatchColorPicker - * NOTE: This will not be triggered if shouldFocusOnHover === true - */ - private _onGridCellHovered = (item?: IColorCellProps): void => { - const { onCellHovered } = this.props; - - if (onCellHovered) { - return item ? onCellHovered(item.id, item.color) : onCellHovered(); - } - }; - - /** - * Callback passed to the GridCell class that will trigger the onCellFocus callback of the SwatchColorPicker - */ - private _onGridCellFocused = (item?: IColorCellProps): void => { - const { onCellFocused } = this.props; - if (onCellFocused) { - if (item) { - this._cellFocused = true; - return onCellFocused(item.id, item.color); - } else { - this._cellFocused = false; - return onCellFocused(); - } - } - }; - - /** - * Handle the click on a cell - * @param item - The cell that the click was fired against - */ - private _onCellClick = (item: IColorCellProps): void => { - if (this.props.disabled) { - return; - } - - const index = item.index as number; - - // If we have a valid index and it is not already - // selected, select it - if (index >= 0 && index !== this.state.selectedIndex) { - if (this.props.onCellFocused && this._cellFocused) { - this._cellFocused = false; - this.props.onCellFocused(); - } - - if (this.props.onColorChanged) { - this.props.onColorChanged(item.id, item.color); - } - - // Update internal state only if the component is uncontrolled - if (this.props.isControlled !== true) { - this.setState({ - selectedIndex: index, - }); - } - } - }; -} diff --git a/packages/react-internal/src/index.ts b/packages/react-internal/src/index.ts index d38dc3b585708..7a5aa1c96ba5a 100644 --- a/packages/react-internal/src/index.ts +++ b/packages/react-internal/src/index.ts @@ -2,7 +2,6 @@ export * from './ActivityItem'; export * from './Autofill'; export * from './Announced'; export * from './Button'; -export * from './ButtonGrid'; export * from './Calendar'; export * from './Callout'; export * from './Check'; @@ -23,7 +22,6 @@ export * from './Facepile'; export * from './FloatingPicker'; export * from './FocusTrapZone'; export * from './FocusZone'; -export * from './Grid'; export * from './HoverCard'; export * from './Icon'; export * from './Icons'; @@ -64,7 +62,6 @@ export * from './Spinner'; export * from './Stack'; export * from './Sticky'; export * from './Styling'; -export * from './SwatchColorPicker'; export * from './TeachingBubble'; export * from './Text'; export * from './TextField'; diff --git a/packages/react-internal/src/utilities/ButtonGrid/ButtonGrid.base.tsx b/packages/react-internal/src/utilities/ButtonGrid/ButtonGrid.base.tsx deleted file mode 100644 index ed0ea7a96fc80..0000000000000 --- a/packages/react-internal/src/utilities/ButtonGrid/ButtonGrid.base.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import * as React from 'react'; -import { - getId, - toMatrix, - classNamesFunction, - getNativeProps, - htmlElementProperties, - initializeComponentRef, -} from '../../Utilities'; -import { FocusZone } from '../../FocusZone'; -import { IButtonGrid, IButtonGridProps, IButtonGridStyleProps, IButtonGridStyles } from './ButtonGrid.types'; - -const getClassNames = classNamesFunction(); - -export class ButtonGridBase extends React.Component implements IButtonGrid { - private _id: string; - - constructor(props: IButtonGridProps) { - super(props); - - initializeComponentRef(this); - this._id = props.id || getId(); - } - - public render(): JSX.Element { - const props = this.props; - const { - items, - columnCount, - onRenderItem, - - /* eslint-disable deprecation/deprecation */ - ariaPosInSet = props.positionInSet, - ariaSetSize = props.setSize, - /* eslint-enable deprecation/deprecation */ - - styles, - doNotContainWithinFocusZone, - } = props; - - const htmlProps = getNativeProps>( - this.props, - htmlElementProperties, - // avoid applying onBlur on the table if it's being used in the FocusZone - doNotContainWithinFocusZone ? [] : ['onBlur'], - ); - - const classNames = getClassNames(styles!, { theme: this.props.theme! }); - - // Array to store the cells in the correct row index - const rowsOfItems: any[][] = toMatrix(items, columnCount); - - const content = ( - - - {rowsOfItems.map((rows: any[], rowIndex: number) => { - return ( - - {rows.map((cell: any, cellIndex: number) => { - return ( - - ); - })} - - ); - })} - -
- {onRenderItem(cell, cellIndex)} -
- ); - - // Create the table/grid - return doNotContainWithinFocusZone ? ( - content - ) : ( - - {content} - - ); - } -} - -/** - * @deprecated - use ButtonGridBase instead - */ -export const GridBase = ButtonGridBase; diff --git a/packages/react-internal/src/utilities/ButtonGrid/ButtonGridCell.tsx b/packages/react-internal/src/utilities/ButtonGrid/ButtonGridCell.tsx deleted file mode 100644 index bf394755736b5..0000000000000 --- a/packages/react-internal/src/utilities/ButtonGrid/ButtonGridCell.tsx +++ /dev/null @@ -1,103 +0,0 @@ -import * as React from 'react'; -import { css } from '../../Utilities'; -import { IButtonGridCellProps } from './ButtonGridCell.types'; -import { CommandButton } from '../../Button'; - -export class ButtonGridCell> extends React.Component { - public static defaultProps = { - disabled: false, - }; - - public render(): JSX.Element { - const { - item, - id, - className, - role, - selected, - disabled, - onRenderItem, - cellDisabledStyle, - cellIsSelectedStyle, - index, - label, - getClassNames, - } = this.props; - - return ( - - {onRenderItem(item)} - - ); - } - - private _onClick = (): void => { - const { onClick, disabled, item } = this.props as P; - - if (onClick && !disabled) { - onClick(item); - } - }; - - private _onMouseEnter = (ev: React.MouseEvent): void => { - const { onHover, disabled, item, onMouseEnter } = this.props as P; - - const didUpdateOnEnter = onMouseEnter && onMouseEnter(ev); - - if (!didUpdateOnEnter && onHover && !disabled) { - onHover(item); - } - }; - - private _onMouseMove = (ev: React.MouseEvent): void => { - const { onHover, disabled, item, onMouseMove } = this.props as P; - - const didUpdateOnMove = onMouseMove && onMouseMove(ev); - - if (!didUpdateOnMove && onHover && !disabled) { - onHover(item); - } - }; - - private _onMouseLeave = (ev: React.MouseEvent): void => { - const { onHover, disabled, onMouseLeave } = this.props as P; - - const didUpdateOnLeave = onMouseLeave && onMouseLeave(ev); - - if (!didUpdateOnLeave && onHover && !disabled) { - onHover(); - } - }; - - private _onFocus = (): void => { - const { onFocus, disabled, item } = this.props as P; - - if (onFocus && !disabled) { - onFocus(item); - } - }; -} - -/** - * @deprecated - use ButtonGridCell instead - */ -export const GridCell = ButtonGridCell; diff --git a/packages/react/etc/react.api.md b/packages/react/etc/react.api.md index de0ea422a3791..8d797f43ba471 100644 --- a/packages/react/etc/react.api.md +++ b/packages/react/etc/react.api.md @@ -6,6 +6,7 @@ import { IAutofillProps } from '@fluentui/react-internal/lib/Autofill'; import { IBaseProps } from '@fluentui/react-internal/lib/Utilities'; +import { IButtonClassNames } from '@fluentui/react-internal/lib/components/Button/BaseButton.classNames'; import { IButtonProps } from '@fluentui/react-internal/lib/Button'; import { IButtonStyles } from '@fluentui/react-internal/lib/Button'; import { ICheckboxStyleProps } from '@fluentui/react-checkbox/lib/Checkbox'; @@ -65,6 +66,12 @@ export class BreadcrumbBase extends React.Component { // @public (undocumented) export function buildColumns(items: any[], canResizeColumns?: boolean, onColumnClick?: (ev: React.MouseEvent, column: IColumn) => void, sortedColumnKey?: string, isSortedDescending?: boolean, groupedColumnKey?: string, isMultiline?: boolean): IColumn[]; +// @public (undocumented) +export const ButtonGrid: React.FunctionComponent; + +// @public (undocumented) +export const ButtonGridCell: >(props: IButtonGridCellProps) => JSX.Element; + // @public (undocumented) export enum CheckboxVisibility { always = 1, @@ -80,6 +87,12 @@ export enum CollapseAllVisibility { visible = 1 } +// @public (undocumented) +export const ColorPickerGridCell: React.FunctionComponent; + +// @public (undocumented) +export const ColorPickerGridCellBase: React.FunctionComponent; + // @public export enum ColumnActionsMode { clickable = 1, @@ -459,6 +472,67 @@ export interface IBreadcrumbStyles { root: IStyle; } +// @public (undocumented) +export interface IButtonGrid { +} + +// @public (undocumented) +export interface IButtonGridCellProps { + cellDisabledStyle?: string[]; + cellIsSelectedStyle?: string[]; + className?: string; + disabled?: boolean; + getClassNames?: (theme: ITheme, className: string, variantClassName: string, iconClassName: string | undefined, menuIconClassName: string | undefined, disabled: boolean, checked: boolean, expanded: boolean, isSplit: boolean | undefined) => IButtonClassNames; + id: string; + index?: number; + item: T; + label?: string; + onClick?: (item: T) => void; + onFocus?: (item: T) => void; + onHover?: (item?: T) => void; + onKeyDown?: (ev: React.KeyboardEvent) => void; + onMouseEnter?: (ev: React.MouseEvent) => boolean; + onMouseLeave?: (ev: React.MouseEvent) => void; + onMouseMove?: (ev: React.MouseEvent) => boolean; + onRenderItem: (item: T) => JSX.Element; + onWheel?: (ev: React.MouseEvent) => void; + role?: string; + selected?: boolean; +} + +// @public (undocumented) +export interface IButtonGridProps extends React.TableHTMLAttributes, React.RefAttributes { + ariaPosInSet?: number; + ariaSetSize?: number; + columnCount: number; + componentRef?: IRefObject; + // @deprecated + containerClassName?: string; + doNotContainWithinFocusZone?: boolean; + items: any[]; + onBlur?: () => void; + onRenderItem: (item: any, index: number) => JSX.Element; + // @deprecated (undocumented) + positionInSet?: number; + // @deprecated (undocumented) + setSize?: number; + shouldFocusCircularNavigate?: boolean; + styles?: IStyleFunctionOrObject; + theme?: ITheme; +} + +// @public +export interface IButtonGridStyleProps { + theme: ITheme; +} + +// @public +export interface IButtonGridStyles { + focusedContainer?: IStyle; + root: IStyle; + tableCell: IStyle; +} + // @public (undocumented) export interface ICellStyleProps { // (undocumented) @@ -469,6 +543,64 @@ export interface ICellStyleProps { cellRightPadding: number; } +// @public (undocumented) +export interface IColorCellProps { + color: string; + id: string; + index?: number; + label?: string; +} + +// @public (undocumented) +export interface IColorPickerGridCellProps { + borderWidth?: number; + circle?: boolean; + color: string; + disabled?: boolean; + height?: number; + // @deprecated + id?: string; + idPrefix?: string; + index?: number; + item: IColorCellProps; + label?: string; + onClick?: (item: IColorCellProps) => void; + // (undocumented) + onFocus?: (item: IColorCellProps) => void; + // (undocumented) + onHover?: (item?: IColorCellProps) => void; + // (undocumented) + onKeyDown?: (ev: React.KeyboardEvent) => void; + onMouseEnter?: (ev: React.MouseEvent) => boolean; + // (undocumented) + onMouseLeave?: (ev: React.MouseEvent) => void; + onMouseMove?: (ev: React.MouseEvent) => boolean; + // (undocumented) + onWheel?: (ev: React.MouseEvent) => void; + selected: boolean; + styles?: IStyleFunctionOrObject; + theme?: ITheme; + width?: number; +} + +// @public (undocumented) +export interface IColorPickerGridCellStyleProps { + borderWidth?: number; + circle?: boolean; + disabled?: boolean; + height?: number; + isWhite?: boolean; + selected?: boolean; + theme: ITheme; + width?: number; +} + +// @public (undocumented) +export interface IColorPickerGridCellStyles { + colorCell: IStyle; + svg: IStyle; +} + // @public (undocumented) export interface IColumn { ariaLabel?: string; @@ -1931,6 +2063,53 @@ export interface IShimmeredDetailsListStyles { root: IStyle; } +// @public (undocumented) +export interface ISwatchColorPickerProps extends React.RefAttributes { + ariaPosInSet?: number; + ariaSetSize?: number; + cellBorderWidth?: number; + cellHeight?: number; + cellMargin?: number; + cellShape?: 'circle' | 'square'; + cellWidth?: number; + className?: string; + colorCells: IColorCellProps[]; + columnCount: number; + defaultSelectedId?: string | undefined; + disabled?: boolean; + doNotContainWithinFocusZone?: boolean; + focusOnHover?: boolean; + getColorGridCellStyles?: IStyleFunctionOrObject; + id?: string; + // @deprecated (undocumented) + isControlled?: boolean; + mouseLeaveParentSelector?: string | undefined; + onCellFocused?: (id?: string, color?: string) => void; + onCellHovered?: (id?: string, color?: string) => void; + onChange?: (event: React.FormEvent, id: string | undefined, color: string | undefined) => void; + // @deprecated (undocumented) + onColorChanged?: (id?: string, color?: string) => void; + onRenderColorCell?: IRenderFunction; + selectedId?: string; + shouldFocusCircularNavigate?: boolean; + styles?: IStyleFunctionOrObject; + theme?: ITheme; +} + +// @public +export interface ISwatchColorPickerStyleProps { + cellMargin?: number; + className?: string; + theme: ITheme; +} + +// @public +export interface ISwatchColorPickerStyles { + focusedContainer?: IStyle; + root: IStyle; + tableCell: IStyle; +} + export { IViewport } export { IWithViewportProps } @@ -1961,6 +2140,12 @@ export class ShimmeredDetailsListBase extends React.Component; + +// @public (undocumented) +export const SwatchColorPickerBase: React.FunctionComponent; + // @public (undocumented) export class VirtualizedComboBox extends React.Component implements IComboBox { constructor(props: IComboBoxProps); diff --git a/packages/react/src/ActivityItem.ts b/packages/react/src/ActivityItem.ts index 00f8003c7c274..9c4d062b6cc9c 100644 --- a/packages/react/src/ActivityItem.ts +++ b/packages/react/src/ActivityItem.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/ActivityItem'; diff --git a/packages/react/src/Announced.ts b/packages/react/src/Announced.ts index 2d17856c33fcb..734e8f4b212b4 100644 --- a/packages/react/src/Announced.ts +++ b/packages/react/src/Announced.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Announced'; diff --git a/packages/react/src/Autofill.ts b/packages/react/src/Autofill.ts index 5e3b515cbee64..d3262b53a96e7 100644 --- a/packages/react/src/Autofill.ts +++ b/packages/react/src/Autofill.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Autofill'; diff --git a/packages/react/src/Breadcrumb.ts b/packages/react/src/Breadcrumb.ts index 64b84fda7c791..22fddbb17759a 100644 --- a/packages/react/src/Breadcrumb.ts +++ b/packages/react/src/Breadcrumb.ts @@ -1 +1,2 @@ +import './version'; export * from './components/Breadcrumb/index'; diff --git a/packages/react/src/Button.ts b/packages/react/src/Button.ts index 1d67e4f94502e..8f455f1125577 100644 --- a/packages/react/src/Button.ts +++ b/packages/react/src/Button.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Button'; diff --git a/packages/react-internal/src/ButtonGrid.ts b/packages/react/src/ButtonGrid.ts similarity index 69% rename from packages/react-internal/src/ButtonGrid.ts rename to packages/react/src/ButtonGrid.ts index 6c8abf888ccf3..c9c7e02746b83 100644 --- a/packages/react-internal/src/ButtonGrid.ts +++ b/packages/react/src/ButtonGrid.ts @@ -1 +1,2 @@ +import './version'; export * from './utilities/ButtonGrid/index'; diff --git a/packages/react/src/Calendar.ts b/packages/react/src/Calendar.ts index c713fcb64cc5f..08c535bf6f164 100644 --- a/packages/react/src/Calendar.ts +++ b/packages/react/src/Calendar.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Calendar'; diff --git a/packages/react/src/Callout.ts b/packages/react/src/Callout.ts index 3a00b57548549..11f4c0bdc9bb4 100644 --- a/packages/react/src/Callout.ts +++ b/packages/react/src/Callout.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Callout'; diff --git a/packages/react/src/Check.ts b/packages/react/src/Check.ts index b2fdfe1a36828..d9971d2f50b3b 100644 --- a/packages/react/src/Check.ts +++ b/packages/react/src/Check.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Check'; diff --git a/packages/react/src/Checkbox.ts b/packages/react/src/Checkbox.ts index d9709f9c3a6f9..598f3cbdbf6be 100644 --- a/packages/react/src/Checkbox.ts +++ b/packages/react/src/Checkbox.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-checkbox/lib/Checkbox'; diff --git a/packages/react/src/ChoiceGroup.ts b/packages/react/src/ChoiceGroup.ts index 20dd319f03d7d..749388e1a3966 100644 --- a/packages/react/src/ChoiceGroup.ts +++ b/packages/react/src/ChoiceGroup.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/ChoiceGroup'; diff --git a/packages/react/src/ChoiceGroupOption.ts b/packages/react/src/ChoiceGroupOption.ts index 44e1870f975bb..58d8ca47eaa51 100644 --- a/packages/react/src/ChoiceGroupOption.ts +++ b/packages/react/src/ChoiceGroupOption.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/ChoiceGroupOption'; diff --git a/packages/react/src/Coachmark.ts b/packages/react/src/Coachmark.ts index 801e5191309ed..9d91e58d2a711 100644 --- a/packages/react/src/Coachmark.ts +++ b/packages/react/src/Coachmark.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Coachmark'; diff --git a/packages/react/src/Color.ts b/packages/react/src/Color.ts index 1d16fb3a4ea86..2c83418d82d52 100644 --- a/packages/react/src/Color.ts +++ b/packages/react/src/Color.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Color'; diff --git a/packages/react/src/ColorPicker.ts b/packages/react/src/ColorPicker.ts index ad960f69bf987..658202ca509da 100644 --- a/packages/react/src/ColorPicker.ts +++ b/packages/react/src/ColorPicker.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/ColorPicker'; diff --git a/packages/react/src/ComboBox.ts b/packages/react/src/ComboBox.ts index c9b81e057c5f2..885c82602b5e5 100644 --- a/packages/react/src/ComboBox.ts +++ b/packages/react/src/ComboBox.ts @@ -1 +1,2 @@ +import './version'; export * from './components/ComboBox/index'; diff --git a/packages/react/src/CommandBar.ts b/packages/react/src/CommandBar.ts index f82600c540a2c..a755f7b563472 100644 --- a/packages/react/src/CommandBar.ts +++ b/packages/react/src/CommandBar.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/CommandBar'; diff --git a/packages/react/src/ContextualMenu.ts b/packages/react/src/ContextualMenu.ts index 1acfa6a181fe0..25dec1fc056ec 100644 --- a/packages/react/src/ContextualMenu.ts +++ b/packages/react/src/ContextualMenu.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/ContextualMenu'; diff --git a/packages/react/src/DetailsList.ts b/packages/react/src/DetailsList.ts index dba9be9bb2a6d..a79d914f41618 100644 --- a/packages/react/src/DetailsList.ts +++ b/packages/react/src/DetailsList.ts @@ -1 +1,2 @@ +import './version'; export * from './components/DetailsList/index'; diff --git a/packages/react/src/Dialog.ts b/packages/react/src/Dialog.ts index 0607690042c94..92c5c748cdaaf 100644 --- a/packages/react/src/Dialog.ts +++ b/packages/react/src/Dialog.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Dialog'; diff --git a/packages/react/src/Divider.ts b/packages/react/src/Divider.ts index fc0d163b92306..dc7ef6ebdd76b 100644 --- a/packages/react/src/Divider.ts +++ b/packages/react/src/Divider.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Divider'; diff --git a/packages/react/src/DocumentCard.ts b/packages/react/src/DocumentCard.ts index e8a917d2c5049..dd6b4068a4dc0 100644 --- a/packages/react/src/DocumentCard.ts +++ b/packages/react/src/DocumentCard.ts @@ -1 +1,2 @@ +import './version'; export * from './components/DocumentCard/index'; diff --git a/packages/react/src/DragDrop.ts b/packages/react/src/DragDrop.ts index a9c57f3f402a5..52b5e7da7689c 100644 --- a/packages/react/src/DragDrop.ts +++ b/packages/react/src/DragDrop.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/DragDrop'; diff --git a/packages/react/src/Dropdown.ts b/packages/react/src/Dropdown.ts index 02d5745849f22..9bccd05429d0d 100644 --- a/packages/react/src/Dropdown.ts +++ b/packages/react/src/Dropdown.ts @@ -1 +1,2 @@ +import './version'; export * from './components/Dropdown/index'; diff --git a/packages/react/src/ExtendedPicker.ts b/packages/react/src/ExtendedPicker.ts index 820343199c865..35f36188c0c2e 100644 --- a/packages/react/src/ExtendedPicker.ts +++ b/packages/react/src/ExtendedPicker.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/ExtendedPicker'; diff --git a/packages/react/src/Fabric.ts b/packages/react/src/Fabric.ts index 736cd79937eca..718ed7d1310b7 100644 --- a/packages/react/src/Fabric.ts +++ b/packages/react/src/Fabric.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Fabric'; diff --git a/packages/react/src/Facepile.ts b/packages/react/src/Facepile.ts index 7e52f7b13058b..9477bc3c8c9b6 100644 --- a/packages/react/src/Facepile.ts +++ b/packages/react/src/Facepile.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Facepile'; diff --git a/packages/react/src/FloatingPicker.ts b/packages/react/src/FloatingPicker.ts index 370e826268488..cd0963d639c32 100644 --- a/packages/react/src/FloatingPicker.ts +++ b/packages/react/src/FloatingPicker.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/FloatingPicker'; diff --git a/packages/react/src/FocusTrapZone.ts b/packages/react/src/FocusTrapZone.ts index 9decb26b5956d..426848624a707 100644 --- a/packages/react/src/FocusTrapZone.ts +++ b/packages/react/src/FocusTrapZone.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/FocusTrapZone'; diff --git a/packages/react/src/FocusZone.ts b/packages/react/src/FocusZone.ts index 36ab3f6ce8cae..a496b7b2e897f 100644 --- a/packages/react/src/FocusZone.ts +++ b/packages/react/src/FocusZone.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/FocusZone'; diff --git a/packages/react/src/Foundation.ts b/packages/react/src/Foundation.ts index f40c5d9ca97ca..1eaa361147b08 100644 --- a/packages/react/src/Foundation.ts +++ b/packages/react/src/Foundation.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Foundation'; diff --git a/packages/react/src/Grid.ts b/packages/react/src/Grid.ts deleted file mode 100644 index bafff58454159..0000000000000 --- a/packages/react/src/Grid.ts +++ /dev/null @@ -1 +0,0 @@ -export * from '@fluentui/react-internal/lib/Grid'; diff --git a/packages/react/src/GroupedList.ts b/packages/react/src/GroupedList.ts index c55c281b2c37c..664d109889c67 100644 --- a/packages/react/src/GroupedList.ts +++ b/packages/react/src/GroupedList.ts @@ -1 +1,2 @@ +import './version'; export * from './components/GroupedList/index'; diff --git a/packages/react/src/HoverCard.ts b/packages/react/src/HoverCard.ts index 1842f30f4472e..0cd609b39ee33 100644 --- a/packages/react/src/HoverCard.ts +++ b/packages/react/src/HoverCard.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/HoverCard'; diff --git a/packages/react/src/Icon.ts b/packages/react/src/Icon.ts index 97c99fe3a7c66..0ddae9c7de26e 100644 --- a/packages/react/src/Icon.ts +++ b/packages/react/src/Icon.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Icon'; diff --git a/packages/react/src/Icons.ts b/packages/react/src/Icons.ts index 6b291959f067e..75c9e20c07970 100644 --- a/packages/react/src/Icons.ts +++ b/packages/react/src/Icons.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Icons'; diff --git a/packages/react/src/Image.ts b/packages/react/src/Image.ts index ca03dc49583f9..c605636a9ae15 100644 --- a/packages/react/src/Image.ts +++ b/packages/react/src/Image.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Image'; diff --git a/packages/react/src/Keytip.ts b/packages/react/src/Keytip.ts index 7b08af9429965..224d0a374a0ad 100644 --- a/packages/react/src/Keytip.ts +++ b/packages/react/src/Keytip.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Keytip'; diff --git a/packages/react/src/KeytipData.ts b/packages/react/src/KeytipData.ts index f0fc3bd43802c..9c2258e7dec4c 100644 --- a/packages/react/src/KeytipData.ts +++ b/packages/react/src/KeytipData.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/KeytipData'; diff --git a/packages/react/src/KeytipLayer.ts b/packages/react/src/KeytipLayer.ts index df7a03092323b..22d63c3d9f979 100644 --- a/packages/react/src/KeytipLayer.ts +++ b/packages/react/src/KeytipLayer.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/KeytipLayer'; diff --git a/packages/react/src/Keytips.ts b/packages/react/src/Keytips.ts index 34bd12fad5862..64bfae2a52319 100644 --- a/packages/react/src/Keytips.ts +++ b/packages/react/src/Keytips.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Keytips'; diff --git a/packages/react/src/Label.ts b/packages/react/src/Label.ts index 66c5e5ae5113f..f19682c131b55 100644 --- a/packages/react/src/Label.ts +++ b/packages/react/src/Label.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Label'; diff --git a/packages/react/src/Layer.ts b/packages/react/src/Layer.ts index 296e985f500c0..866342ae9c48f 100644 --- a/packages/react/src/Layer.ts +++ b/packages/react/src/Layer.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Layer'; diff --git a/packages/react/src/Link.ts b/packages/react/src/Link.ts index 04e11f2687e5e..b19f354ff65f6 100644 --- a/packages/react/src/Link.ts +++ b/packages/react/src/Link.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-link/lib/Link'; diff --git a/packages/react/src/List.ts b/packages/react/src/List.ts index 7d34c683f878c..6a7e6c23e0b12 100644 --- a/packages/react/src/List.ts +++ b/packages/react/src/List.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/List'; diff --git a/packages/react/src/MarqueeSelection.ts b/packages/react/src/MarqueeSelection.ts index b6e71c77d3597..d791f1ed4ab60 100644 --- a/packages/react/src/MarqueeSelection.ts +++ b/packages/react/src/MarqueeSelection.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/MarqueeSelection'; diff --git a/packages/react/src/MessageBar.ts b/packages/react/src/MessageBar.ts index 16292777cf57f..b9571a90f465f 100644 --- a/packages/react/src/MessageBar.ts +++ b/packages/react/src/MessageBar.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/MessageBar'; diff --git a/packages/react/src/Modal.ts b/packages/react/src/Modal.ts index e560f0f65d263..dc5ab387dc79d 100644 --- a/packages/react/src/Modal.ts +++ b/packages/react/src/Modal.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Modal'; diff --git a/packages/react/src/Nav.ts b/packages/react/src/Nav.ts index ba4405cd4808f..3c6c7dc026e29 100644 --- a/packages/react/src/Nav.ts +++ b/packages/react/src/Nav.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Nav'; diff --git a/packages/react/src/OverflowSet.ts b/packages/react/src/OverflowSet.ts index 936654a48de74..b603a0853afd9 100644 --- a/packages/react/src/OverflowSet.ts +++ b/packages/react/src/OverflowSet.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/OverflowSet'; diff --git a/packages/react/src/Overlay.ts b/packages/react/src/Overlay.ts index 83f08786dc04d..d7ca27cb46c28 100644 --- a/packages/react/src/Overlay.ts +++ b/packages/react/src/Overlay.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Overlay'; diff --git a/packages/react/src/Panel.ts b/packages/react/src/Panel.ts index 60a0ff225a792..f4dc71178132b 100644 --- a/packages/react/src/Panel.ts +++ b/packages/react/src/Panel.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Panel'; diff --git a/packages/react/src/Persona.ts b/packages/react/src/Persona.ts index 9d373887e2d40..032e16ccf3301 100644 --- a/packages/react/src/Persona.ts +++ b/packages/react/src/Persona.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Persona'; diff --git a/packages/react/src/PersonaCoin.ts b/packages/react/src/PersonaCoin.ts index 9d373887e2d40..032e16ccf3301 100644 --- a/packages/react/src/PersonaCoin.ts +++ b/packages/react/src/PersonaCoin.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Persona'; diff --git a/packages/react/src/PersonaPresence.ts b/packages/react/src/PersonaPresence.ts index 146c16352c7ff..ab48d66632044 100644 --- a/packages/react/src/PersonaPresence.ts +++ b/packages/react/src/PersonaPresence.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/PersonaPresence'; diff --git a/packages/react/src/Pickers.ts b/packages/react/src/Pickers.ts index d3c4b4f3b9df6..02c401bfb9f2c 100644 --- a/packages/react/src/Pickers.ts +++ b/packages/react/src/Pickers.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Pickers'; diff --git a/packages/react/src/Pivot.ts b/packages/react/src/Pivot.ts index f18d3405f74dc..c22ed26a5b6e4 100644 --- a/packages/react/src/Pivot.ts +++ b/packages/react/src/Pivot.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-tabs/lib/Pivot'; diff --git a/packages/react/src/Popup.ts b/packages/react/src/Popup.ts index 5f12c7e576e9c..fe94bce4906be 100644 --- a/packages/react/src/Popup.ts +++ b/packages/react/src/Popup.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Popup'; diff --git a/packages/react/src/Positioning.ts b/packages/react/src/Positioning.ts index 27b411d383422..d5c6ba189ec54 100644 --- a/packages/react/src/Positioning.ts +++ b/packages/react/src/Positioning.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Positioning'; diff --git a/packages/react/src/PositioningContainer.ts b/packages/react/src/PositioningContainer.ts index e4a31ff095d5f..ba0988eba59c0 100644 --- a/packages/react/src/PositioningContainer.ts +++ b/packages/react/src/PositioningContainer.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/PositioningContainer'; diff --git a/packages/react/src/ProgressIndicator.ts b/packages/react/src/ProgressIndicator.ts index 866fd856adc97..1326d69309757 100644 --- a/packages/react/src/ProgressIndicator.ts +++ b/packages/react/src/ProgressIndicator.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/ProgressIndicator'; diff --git a/packages/react/src/Rating.ts b/packages/react/src/Rating.ts index f20ed24aace23..f824a5d223d31 100644 --- a/packages/react/src/Rating.ts +++ b/packages/react/src/Rating.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Rating'; diff --git a/packages/react/src/ResizeGroup.ts b/packages/react/src/ResizeGroup.ts index cb560d7f81ed4..f8132f1a72000 100644 --- a/packages/react/src/ResizeGroup.ts +++ b/packages/react/src/ResizeGroup.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/ResizeGroup'; diff --git a/packages/react/src/ScrollablePane.ts b/packages/react/src/ScrollablePane.ts index ce3a2de3243b1..15dacf34144e1 100644 --- a/packages/react/src/ScrollablePane.ts +++ b/packages/react/src/ScrollablePane.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/ScrollablePane'; diff --git a/packages/react/src/SearchBox.ts b/packages/react/src/SearchBox.ts index 8bcd9d2d96846..05150c97e5f0a 100644 --- a/packages/react/src/SearchBox.ts +++ b/packages/react/src/SearchBox.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/SearchBox'; diff --git a/packages/react/src/SelectableOption.ts b/packages/react/src/SelectableOption.ts index 11b6bb7b2dd36..e88ca826bb977 100644 --- a/packages/react/src/SelectableOption.ts +++ b/packages/react/src/SelectableOption.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/SelectableOption'; diff --git a/packages/react/src/SelectedItemsList.ts b/packages/react/src/SelectedItemsList.ts index a5037c9ff8fe5..b793560c49f5f 100644 --- a/packages/react/src/SelectedItemsList.ts +++ b/packages/react/src/SelectedItemsList.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/SelectedItemsList'; diff --git a/packages/react/src/Selection.ts b/packages/react/src/Selection.ts index 485e9193be71e..7973bc3946db4 100644 --- a/packages/react/src/Selection.ts +++ b/packages/react/src/Selection.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Selection'; diff --git a/packages/react/src/Separator.ts b/packages/react/src/Separator.ts index e0998d641ac11..3ab6f43cc34f8 100644 --- a/packages/react/src/Separator.ts +++ b/packages/react/src/Separator.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Separator'; diff --git a/packages/react/src/Shimmer.ts b/packages/react/src/Shimmer.ts index 3073ab7a20b25..a797fb31e4c57 100644 --- a/packages/react/src/Shimmer.ts +++ b/packages/react/src/Shimmer.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Shimmer'; diff --git a/packages/react/src/ShimmeredDetailsList.ts b/packages/react/src/ShimmeredDetailsList.ts index 97cc1f76d4d8a..9010541a6afec 100644 --- a/packages/react/src/ShimmeredDetailsList.ts +++ b/packages/react/src/ShimmeredDetailsList.ts @@ -1,3 +1,4 @@ +import './version'; export * from './components/DetailsList/ShimmeredDetailsList'; export * from './components/DetailsList/ShimmeredDetailsList.base'; export * from './components/DetailsList/ShimmeredDetailsList.types'; diff --git a/packages/react/src/Slider.ts b/packages/react/src/Slider.ts index b17e5f15344a4..104254d6b6094 100644 --- a/packages/react/src/Slider.ts +++ b/packages/react/src/Slider.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-slider/lib/Slider'; diff --git a/packages/react/src/SpinButton.ts b/packages/react/src/SpinButton.ts index 5fe23c646a916..7b67027592e5e 100644 --- a/packages/react/src/SpinButton.ts +++ b/packages/react/src/SpinButton.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/SpinButton'; diff --git a/packages/react/src/Spinner.ts b/packages/react/src/Spinner.ts index 5bd5e99c7181d..b9e7f757f0114 100644 --- a/packages/react/src/Spinner.ts +++ b/packages/react/src/Spinner.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Spinner'; diff --git a/packages/react/src/Stack.ts b/packages/react/src/Stack.ts index 67810e882416f..be9eb72dd20ed 100644 --- a/packages/react/src/Stack.ts +++ b/packages/react/src/Stack.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Stack'; diff --git a/packages/react/src/Sticky.ts b/packages/react/src/Sticky.ts index 32de328be1d7e..53843371ae9c7 100644 --- a/packages/react/src/Sticky.ts +++ b/packages/react/src/Sticky.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Sticky'; diff --git a/packages/react/src/Styling.ts b/packages/react/src/Styling.ts index 3ffbc6ad7cdbc..4ae58dc55709a 100644 --- a/packages/react/src/Styling.ts +++ b/packages/react/src/Styling.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Styling'; diff --git a/packages/react/src/SwatchColorPicker.ts b/packages/react/src/SwatchColorPicker.ts index 0fa31f5953178..19f6b9c418ab6 100644 --- a/packages/react/src/SwatchColorPicker.ts +++ b/packages/react/src/SwatchColorPicker.ts @@ -1 +1,2 @@ -export * from '@fluentui/react-internal/lib/SwatchColorPicker'; +import './version'; +export * from './components/SwatchColorPicker/index'; diff --git a/packages/react/src/TeachingBubble.ts b/packages/react/src/TeachingBubble.ts index 276a8a791eb01..8174dddeb4414 100644 --- a/packages/react/src/TeachingBubble.ts +++ b/packages/react/src/TeachingBubble.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/TeachingBubble'; diff --git a/packages/react/src/Text.ts b/packages/react/src/Text.ts index 7195f93ea2180..0123ca42b1aaf 100644 --- a/packages/react/src/Text.ts +++ b/packages/react/src/Text.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Text'; diff --git a/packages/react/src/TextField.ts b/packages/react/src/TextField.ts index 3827a10aaf9d5..3f1539472e506 100644 --- a/packages/react/src/TextField.ts +++ b/packages/react/src/TextField.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/TextField'; diff --git a/packages/react/src/ThemeGenerator.ts b/packages/react/src/ThemeGenerator.ts index 06e9ae6d8f992..a7444d235549c 100644 --- a/packages/react/src/ThemeGenerator.ts +++ b/packages/react/src/ThemeGenerator.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/ThemeGenerator'; diff --git a/packages/react/src/Toggle.ts b/packages/react/src/Toggle.ts index 6354331acc612..7799a1e9f6719 100644 --- a/packages/react/src/Toggle.ts +++ b/packages/react/src/Toggle.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-toggle/lib/Toggle'; diff --git a/packages/react/src/Tooltip.ts b/packages/react/src/Tooltip.ts index d2b0cce72cbac..9c2be0ae64eca 100644 --- a/packages/react/src/Tooltip.ts +++ b/packages/react/src/Tooltip.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Tooltip'; diff --git a/packages/react/src/Utilities.ts b/packages/react/src/Utilities.ts index 17637cf245903..9ba3dddbe7746 100644 --- a/packages/react/src/Utilities.ts +++ b/packages/react/src/Utilities.ts @@ -1 +1,2 @@ +import './version'; export * from '@fluentui/react-internal/lib/Utilities'; diff --git a/packages/react/src/common/isConformant.ts b/packages/react/src/common/isConformant.ts index 6cd706619bdc8..b5f22ac880728 100644 --- a/packages/react/src/common/isConformant.ts +++ b/packages/react/src/common/isConformant.ts @@ -2,7 +2,7 @@ import { isConformant as baseIsConformant, IsConformantOptions } from '@fluentui export function isConformant(testInfo: Omit & { componentPath?: string }) { const defaultOptions = { - disabledTests: ['has-docblock', 'kebab-aria-attributes', 'is-static-property-of-parent'], + disabledTests: ['has-docblock', 'kebab-aria-attributes'], componentPath: module!.parent!.filename.replace('.test', ''), }; diff --git a/packages/react/src/components/ComponentConformance.test.tsx b/packages/react/src/components/ComponentConformance.test.tsx index b329873fab2c6..4b79e7162f308 100644 --- a/packages/react/src/components/ComponentConformance.test.tsx +++ b/packages/react/src/components/ComponentConformance.test.tsx @@ -179,7 +179,7 @@ describe('Top Level Component File Conformance', () => { jest.resetModules(); }); - // Top Level Compoennt File Compliance - + // Top Level Component File Compliance - // make sure that there is a corresponding top level component file for each component in the directory components.forEach(componentName => { it(`${componentName} has a corresponding top level component file`, () => { @@ -196,8 +196,9 @@ describe('Top Level Component File Conformance', () => { const packageName = componentPackageMap[componentName] || '@fluentui/react'; it(`${componentName} imports the ${packageName} version file`, () => { - (window as any).__packages__ = null; + delete require.cache[file]; require(file); + expect((window as any).__packages__[packageName]).not.toBeUndefined(); }); }); diff --git a/packages/react/src/components/SwatchColorPicker/ColorPickerGridCell.base.tsx b/packages/react/src/components/SwatchColorPicker/ColorPickerGridCell.base.tsx new file mode 100644 index 0000000000000..076dce54d0044 --- /dev/null +++ b/packages/react/src/components/SwatchColorPicker/ColorPickerGridCell.base.tsx @@ -0,0 +1,136 @@ +import * as React from 'react'; +import { ITheme, mergeStyleSets, IProcessedStyleSet } from '../../Styling'; +import { classNamesFunction, memoizeFunction } from '../../Utilities'; +import { getColorFromString } from '../../Color'; +import { ButtonGridCell } from '../../utilities/ButtonGrid/ButtonGridCell'; +import { getStyles as getActionButtonStyles } from '@fluentui/react-internal/lib/components/Button/ActionButton/ActionButton.styles'; +import { IButtonClassNames } from '@fluentui/react-internal/lib/components/Button/BaseButton.classNames'; +import { + IColorCellProps, + IColorPickerGridCellProps, + IColorPickerGridCellStyleProps, + IColorPickerGridCellStyles, +} from './ColorPickerGridCell.types'; + +const getClassNames = classNamesFunction(); + +/** Validate if the cell's color is white or not to apply whiteCell style */ +const isWhiteCell = (inputColor: string): boolean => { + const currentColor = getColorFromString(inputColor!); + return currentColor?.hex === 'ffffff'; +}; + +const getColorPickerGridCellButtonClassNames = memoizeFunction( + ( + theme: ITheme, + className: string, + variantClassName: string, + iconClassName: string | undefined, + menuIconClassName: string | undefined, + disabled: boolean, + checked: boolean, + expanded: boolean, + isSplit: boolean | undefined, + ): IButtonClassNames => { + const styles = getActionButtonStyles(theme); + return mergeStyleSets({ + root: [ + 'ms-Button', + styles.root, + variantClassName, + className, + checked && ['is-checked', styles.rootChecked], + disabled && ['is-disabled', styles.rootDisabled], + !disabled && + !checked && { + selectors: { + ':hover': styles.rootHovered, + ':focus': styles.rootFocused, + ':active': styles.rootPressed, + }, + }, + disabled && checked && [styles.rootCheckedDisabled], + !disabled && + checked && { + selectors: { + ':hover': styles.rootCheckedHovered, + ':active': styles.rootCheckedPressed, + }, + }, + ], + flexContainer: ['ms-Button-flexContainer', styles.flexContainer], + }); + }, +); + +export const ColorPickerGridCellBase: React.FunctionComponent = props => { + const { + item, + // eslint-disable-next-line deprecation/deprecation + idPrefix = props.id, + selected = false, + disabled = false, + styles, + circle = true, + color, + onClick, + onHover, + onFocus, + onMouseEnter, + onMouseMove, + onMouseLeave, + onWheel, + onKeyDown, + height, + width, + borderWidth, + } = props; + + const classNames: IProcessedStyleSet = getClassNames(styles!, { + theme: props.theme!, + disabled, + selected, + circle, + isWhite: isWhiteCell(color!), + height, + width, + borderWidth, + }); + + // Render the core of a color cell + const onRenderColorOption = (colorOption: IColorCellProps): JSX.Element => { + const svgClassName = classNames.svg; + + // Build an SVG for the cell with the given shape and color properties + return ( + + {circle ? : } + + ); + }; + + return ( + + ); +}; diff --git a/packages/react-internal/src/components/SwatchColorPicker/ColorPickerGridCell.styles.ts b/packages/react/src/components/SwatchColorPicker/ColorPickerGridCell.styles.ts similarity index 100% rename from packages/react-internal/src/components/SwatchColorPicker/ColorPickerGridCell.styles.ts rename to packages/react/src/components/SwatchColorPicker/ColorPickerGridCell.styles.ts diff --git a/packages/react-internal/src/components/SwatchColorPicker/ColorPickerGridCell.tsx b/packages/react/src/components/SwatchColorPicker/ColorPickerGridCell.tsx similarity index 100% rename from packages/react-internal/src/components/SwatchColorPicker/ColorPickerGridCell.tsx rename to packages/react/src/components/SwatchColorPicker/ColorPickerGridCell.tsx diff --git a/packages/react-internal/src/components/SwatchColorPicker/ColorPickerGridCell.types.ts b/packages/react/src/components/SwatchColorPicker/ColorPickerGridCell.types.ts similarity index 99% rename from packages/react-internal/src/components/SwatchColorPicker/ColorPickerGridCell.types.ts rename to packages/react/src/components/SwatchColorPicker/ColorPickerGridCell.types.ts index ea61cb4960b8a..d1a17626caa51 100644 --- a/packages/react-internal/src/components/SwatchColorPicker/ColorPickerGridCell.types.ts +++ b/packages/react/src/components/SwatchColorPicker/ColorPickerGridCell.types.ts @@ -30,7 +30,7 @@ export interface IColorPickerGridCellProps { /** * The CSS-compatible string to describe the color */ - color?: string; + color: string; /** * Index for this option @@ -125,7 +125,7 @@ export interface IColorCellProps { /** * The CSS-compatible string to describe the color */ - color?: string; + color: string; /** * Index for this option diff --git a/packages/react/src/components/SwatchColorPicker/SwatchColorPicker.base.tsx b/packages/react/src/components/SwatchColorPicker/SwatchColorPicker.base.tsx new file mode 100644 index 0000000000000..f147080f2bb04 --- /dev/null +++ b/packages/react/src/components/SwatchColorPicker/SwatchColorPicker.base.tsx @@ -0,0 +1,340 @@ +import * as React from 'react'; +import { classNamesFunction, KeyCodes } from '../../Utilities'; +import { + ISwatchColorPickerProps, + ISwatchColorPickerStyleProps, + ISwatchColorPickerStyles, +} from './SwatchColorPicker.types'; +import { ButtonGrid } from '../../utilities/ButtonGrid/ButtonGrid'; +import { IColorCellProps } from './ColorPickerGridCell.types'; +import { ColorPickerGridCell } from './ColorPickerGridCell'; +import { useId, useConst, useSetTimeout, useControllableValue, useWarnings } from '@uifabric/react-hooks'; +import { IButtonGridProps } from '../../utilities/ButtonGrid/ButtonGrid.types'; + +interface ISwatchColorPickerInternalState { + isNavigationIdle: boolean; + cellFocused: boolean; + navigationIdleTimeoutId: number | undefined; + navigationIdleDelay: number; +} + +const getClassNames = classNamesFunction(); + +const COMPONENT_NAME = 'SwatchColorPicker'; + +function useDebugWarnings(props: ISwatchColorPickerProps) { + if (process.env.NODE_ENV !== 'production') { + // eslint-disable-next-line react-hooks/rules-of-hooks -- build-time conditional + useWarnings({ + name: COMPONENT_NAME, + props, + mutuallyExclusive: { focusOnHover: 'onHover', selectedId: 'defaultSelectedId' }, + deprecations: { isControlled: "selectedId' or 'defaultSelectedId", onColorChanged: 'onChange' }, + }); + } +} + +export const SwatchColorPickerBase: React.FunctionComponent = React.forwardRef< + HTMLElement, + ISwatchColorPickerProps +>((props, ref) => { + const defaultId = useId('swatchColorPicker'); + const id = props.id || defaultId; + + const internalState = useConst({ + isNavigationIdle: true, + cellFocused: false, + navigationIdleTimeoutId: undefined, + navigationIdleDelay: 250, + }); + + const { setTimeout, clearTimeout } = useSetTimeout(); + + useDebugWarnings(props); + + const { + colorCells, + cellShape = 'circle', + columnCount, + shouldFocusCircularNavigate = true, + className, + disabled = false, + doNotContainWithinFocusZone, + styles, + cellMargin = 10, + defaultSelectedId, + focusOnHover, + mouseLeaveParentSelector, + onChange, + // eslint-disable-next-line deprecation/deprecation + onColorChanged, + onCellHovered, + onCellFocused, + getColorGridCellStyles, + cellHeight, + cellWidth, + cellBorderWidth, + } = props; + + /** + * Add an index to each color cells. Memoizes this so that color cells do not re-render on every update. + */ + const itemsWithIndex = React.useMemo(() => { + return colorCells.map((item, index) => { + return { ...item, index: index }; + }); + }, [colorCells]); + + const mergedOnChange = React.useCallback( + (ev: React.FormEvent, newSelectedId: string | undefined) => { + // Call both new and old change handlers, and add the extra `color` parameter + const newColor = colorCells.filter(c => c.id === newSelectedId)[0]?.color; + onChange?.(ev, newSelectedId, newColor); + onColorChanged?.(newSelectedId, newColor); + }, + [onChange, onColorChanged, colorCells], + ); + + const [selectedId, setSelectedId] = useControllableValue(props.selectedId, defaultSelectedId, mergedOnChange); + + const classNames = getClassNames(styles!, { + theme: props.theme!, + className, + cellMargin, + }); + + const gridStyles = { + root: classNames.root, + tableCell: classNames.tableCell, + focusedContainer: classNames.focusedContainer, + }; + + /** + * When the whole swatchColorPicker is blurred, + * make sure to clear the pending focused stated + */ + const onSwatchColorPickerBlur = React.useCallback((): void => { + if (onCellFocused) { + internalState.cellFocused = false; + onCellFocused(); + } + }, [internalState, onCellFocused]); + + /** + * Callback passed to the GridCell that will manage triggering the onCellHovered callback for mouseEnter + */ + const onMouseEnter = React.useCallback( + (ev: React.MouseEvent): boolean => { + if (!focusOnHover) { + return !internalState.isNavigationIdle || !!disabled; + } + if (internalState.isNavigationIdle && !disabled) { + ev.currentTarget.focus(); + } + return true; + }, + [focusOnHover, internalState, disabled], + ); + + /** + * Callback passed to the GridCell that will manage Hover/Focus updates + */ + const onMouseMove = React.useCallback( + (ev: React.MouseEvent): boolean => { + if (!focusOnHover) { + return !internalState.isNavigationIdle || !!disabled; + } + + const targetElement = ev.currentTarget as HTMLElement; + + // If navigation is idle and the targetElement is the focused element bail out + if (internalState.isNavigationIdle && !(document && targetElement === (document.activeElement as HTMLElement))) { + targetElement.focus(); + } + + return true; + }, + [focusOnHover, internalState, disabled], + ); + + /** + * Callback passed to the GridCell that will manage Hover/Focus updates + */ + const onMouseLeave = React.useCallback( + (ev: React.MouseEvent): void => { + const parentSelector = mouseLeaveParentSelector; + + if (!focusOnHover || !parentSelector || !internalState.isNavigationIdle || disabled) { + return; + } + + // Get the elements that math the given selector + const elements = document.querySelectorAll(parentSelector); + + // iterate over the elements return to make sure it is a parent of the target and focus it + for (let index = 0; index < elements.length; index += 1) { + if (elements[index].contains(ev.currentTarget)) { + /** + * IE11 focus() method forces parents to scroll to top of element. + * Edge and IE expose a setActive() function for focusable divs that + * sets the page focus but does not scroll the parent element. + */ + if ((elements[index] as any).setActive) { + try { + (elements[index] as any).setActive(); + } catch (e) { + /* no-op */ + } + } else { + (elements[index] as HTMLElement).focus(); + } + + break; + } + } + }, + [disabled, focusOnHover, internalState, mouseLeaveParentSelector], + ); + + /** + * Callback passed to the GridCell class that will trigger the onCellHovered callback of the SwatchColorPicker + * NOTE: This will not be triggered if shouldFocusOnHover === true + */ + const onGridCellHovered = React.useCallback( + (item?: IColorCellProps): void => { + if (onCellHovered) { + return item ? onCellHovered(item.id, item.color) : onCellHovered(); + } + }, + [onCellHovered], + ); + + /** + * Callback passed to the GridCell class that will trigger the onCellFocus callback of the SwatchColorPicker + */ + const onGridCellFocused = React.useCallback( + (item?: IColorCellProps): void => { + if (onCellFocused) { + if (item) { + internalState.cellFocused = true; + return onCellFocused(item.id, item.color); + } else { + internalState.cellFocused = false; + return onCellFocused(); + } + } + }, + [internalState, onCellFocused], + ); + + /** + * Handle the click on a cell + */ + const onCellClick = React.useCallback( + (item: IColorCellProps): void => { + if (disabled) { + return; + } + + if (item.id !== selectedId) { + if (onCellFocused && internalState.cellFocused) { + internalState.cellFocused = false; + onCellFocused(); + } + setSelectedId(item.id); + } + }, + [disabled, internalState, onCellFocused, selectedId, setSelectedId], + ); + + /** + * Sets a timeout so we won't process any mouse "hover" events + * while navigating (via mouseWheel or arrowKeys) + */ + const setNavigationTimeout = React.useCallback(() => { + if (!internalState.isNavigationIdle && internalState.navigationIdleTimeoutId !== undefined) { + clearTimeout(internalState.navigationIdleTimeoutId); + internalState.navigationIdleTimeoutId = undefined; + } else { + internalState.isNavigationIdle = false; + } + + internalState.navigationIdleTimeoutId = setTimeout(() => { + internalState.isNavigationIdle = true; + }, internalState.navigationIdleDelay); + }, [clearTimeout, internalState, setTimeout]); + + /** + * Callback used to handle KeyCode events + */ + const onKeyDown = React.useCallback( + (ev: React.KeyboardEvent): void => { + if ( + ev.which === KeyCodes.up || + ev.which === KeyCodes.down || + ev.which === KeyCodes.left || + ev.which === KeyCodes.right + ) { + setNavigationTimeout(); + } + }, + [setNavigationTimeout], + ); + + /** + * Render a color cell + * @param item - The item to render + * @returns - Element representing the item + */ + const renderOption = (item: IColorCellProps): JSX.Element => { + return ( + + ); + }; + + if (colorCells.length < 1 || columnCount < 1) { + return null; + } + const onRenderItem = (item: IColorCellProps, index: number): JSX.Element => { + const { onRenderColorCell = renderOption } = props; + return onRenderColorCell(item, renderOption) as JSX.Element; + }; + return ( + + ); +}); + +SwatchColorPickerBase.displayName = COMPONENT_NAME; diff --git a/packages/react-internal/src/components/SwatchColorPicker/SwatchColorPicker.styles.ts b/packages/react/src/components/SwatchColorPicker/SwatchColorPicker.styles.ts similarity index 100% rename from packages/react-internal/src/components/SwatchColorPicker/SwatchColorPicker.styles.ts rename to packages/react/src/components/SwatchColorPicker/SwatchColorPicker.styles.ts diff --git a/packages/react-internal/src/components/SwatchColorPicker/SwatchColorPicker.test.tsx b/packages/react/src/components/SwatchColorPicker/SwatchColorPicker.test.tsx similarity index 81% rename from packages/react-internal/src/components/SwatchColorPicker/SwatchColorPicker.test.tsx rename to packages/react/src/components/SwatchColorPicker/SwatchColorPicker.test.tsx index 8f3979002537a..b6dae1d981980 100644 --- a/packages/react-internal/src/components/SwatchColorPicker/SwatchColorPicker.test.tsx +++ b/packages/react/src/components/SwatchColorPicker/SwatchColorPicker.test.tsx @@ -1,9 +1,11 @@ import * as React from 'react'; -import * as renderer from 'react-test-renderer'; +import { create } from '@uifabric/utilities/lib/test'; import { mount } from 'enzyme'; import { SwatchColorPicker } from './SwatchColorPicker'; import { IColorCellProps } from './ColorPickerGridCell.types'; -import { expectNodes, findNodes } from '../../common/testUtilities'; +import { resetIds } from '@uifabric/utilities'; +import { isConformant } from '../../common/isConformant'; +import { expectNodes, findNodes } from '@fluentui/react-internal/lib/common/testUtilities'; const DEFAULT_OPTIONS: IColorCellProps[] = [ { id: 'a', label: 'green', color: '#00ff00' }, @@ -21,12 +23,22 @@ const DEFAULT_OPTIONS: IColorCellProps[] = [ ]; describe('SwatchColorPicker', () => { + beforeEach(() => { + resetIds(); + }); + it('renders SwatchColorPicker correctly', () => { - const component = renderer.create(); + const component = create(); const tree = component.toJSON(); expect(tree).toMatchSnapshot(); }); + isConformant({ + Component: SwatchColorPicker, + displayName: 'SwatchColorPicker', + requiredProps: { colorCells: DEFAULT_OPTIONS, columnCount: 4 }, + }); + it('Can render in full without being parented to a button', () => { const wrapper = mount(); @@ -52,9 +64,7 @@ describe('SwatchColorPicker', () => { it('Can execute a cell in non-collapsable swatch color picker ', () => { const onChange = jest.fn(); - const wrapper = mount( - , - ); + const wrapper = mount(); expectNodes(wrapper, '.ms-swatchColorPickerBodyContainer', 1); expectNodes(wrapper, '.ms-swatchColorPickerBodyContainer [role="gridcell"]', 1); @@ -66,7 +76,7 @@ describe('SwatchColorPicker', () => { expect(onChange).toHaveBeenCalledTimes(1); }); - it('Can fire the hover event on a cell in non-collapsable swatch color picker ', () => { + it('Can fire the hover event on a cell in non-collapsible swatch color picker ', () => { const onHover = jest.fn(); const wrapper = mount( , @@ -79,7 +89,7 @@ describe('SwatchColorPicker', () => { expect(onHover).toHaveBeenCalledTimes(1); }); - it('Can fire the focus event on a cell in non-collapsable swatch color picker ', () => { + it('Can fire the focus event on a cell in non-collapsible swatch color picker ', () => { const onFocus = jest.fn(); const wrapper = mount( , diff --git a/packages/react-internal/src/components/SwatchColorPicker/SwatchColorPicker.tsx b/packages/react/src/components/SwatchColorPicker/SwatchColorPicker.tsx similarity index 100% rename from packages/react-internal/src/components/SwatchColorPicker/SwatchColorPicker.tsx rename to packages/react/src/components/SwatchColorPicker/SwatchColorPicker.tsx diff --git a/packages/react-internal/src/components/SwatchColorPicker/SwatchColorPicker.types.ts b/packages/react/src/components/SwatchColorPicker/SwatchColorPicker.types.ts similarity index 84% rename from packages/react-internal/src/components/SwatchColorPicker/SwatchColorPicker.types.ts rename to packages/react/src/components/SwatchColorPicker/SwatchColorPicker.types.ts index ba0e711833932..2ad39afdb7e71 100644 --- a/packages/react-internal/src/components/SwatchColorPicker/SwatchColorPicker.types.ts +++ b/packages/react/src/components/SwatchColorPicker/SwatchColorPicker.types.ts @@ -1,3 +1,4 @@ +import * as React from 'react'; import { IStyle, ITheme } from '../../Styling'; import { IStyleFunctionOrObject, IRenderFunction } from '../../Utilities'; import { @@ -9,7 +10,7 @@ import { /** * {@docCategory SwatchColorPicker} */ -export interface ISwatchColorPickerProps { +export interface ISwatchColorPickerProps extends React.RefAttributes { /** * Number of columns for the swatch color picker */ @@ -32,7 +33,9 @@ export interface ISwatchColorPickerProps { cellShape?: 'circle' | 'square'; /** - * The ID of color cell that is currently selected + * ID of the current selected color swatch. Only provide this if the SwatchColorPicker is a + * controlled component where you are maintaining its current state; otherwise, use the + * `defaultSelectedId` property. */ selectedId?: string; @@ -46,22 +49,27 @@ export interface ISwatchColorPickerProps { colorCells: IColorCellProps[]; /** - * Indicates whether the SwatchColorPicker is fully controlled. - * When true, the component will not set its internal state to track the selected color. - * Instead, the parent component will be responsible for handling state in the callbacks like - * `onColorChanged`. - * - * NOTE: This property is a temporary workaround to force the component to be fully controllable - * without breaking existing behavior + * @deprecated No longer used. Provide `selectedId` if controlled or `defaultSelectedId` if uncontrolled. */ isControlled?: boolean; + /** + * ID of the default selected color swatch. Only provide this if the SwatchColorPicker is an + * uncontrolled component; otherwise, use the `selectedId` property. + */ + defaultSelectedId?: string | undefined; + + /** + * @deprecated Use `onChange` + */ + onColorChanged?: (id?: string, color?: string) => void; + /** * Callback for when the user changes the color. * If `id` and `color` are unspecified, there is no selected cell. * (e.g. the user executed the currently selected cell to unselect it) */ - onColorChanged?: (id?: string, color?: string) => void; + onChange?: (event: React.FormEvent, id: string | undefined, color: string | undefined) => void; /** * Callback for when the user hovers over a color cell. @@ -74,10 +82,12 @@ export interface ISwatchColorPickerProps { * If `id` and `color` are unspecified, cells are no longer being focused. */ onCellFocused?: (id?: string, color?: string) => void; + /** * Custom render function for the color cell */ onRenderColorCell?: IRenderFunction; + /** * Whether the control is disabled. */ @@ -88,21 +98,11 @@ export interface ISwatchColorPickerProps { */ ariaPosInSet?: number; - /** - * @deprecated Use `ariaPosInSet` - */ - positionInSet?: number; - /** * Size of the parent set (size of parent menu, for example) */ ariaSetSize?: number; - /** - * @deprecated Use `ariaSetSize` - */ - setSize?: number; - /** * Whether focus should cycle back to the beginning once the user navigates past the end (and vice versa). * Only relevant if `doNotContainWithinFocusZone` is not true. @@ -190,7 +190,7 @@ export interface ISwatchColorPickerStyleProps { } /** - * Styles for the Color Picker Component. + * Styles for the SwatchColorPicker. * {@docCategory SwatchColorPicker} */ export interface ISwatchColorPickerStyles { diff --git a/packages/react-internal/src/components/SwatchColorPicker/__snapshots__/SwatchColorPicker.test.tsx.snap b/packages/react/src/components/SwatchColorPicker/__snapshots__/SwatchColorPicker.test.tsx.snap similarity index 100% rename from packages/react-internal/src/components/SwatchColorPicker/__snapshots__/SwatchColorPicker.test.tsx.snap rename to packages/react/src/components/SwatchColorPicker/__snapshots__/SwatchColorPicker.test.tsx.snap diff --git a/packages/react-internal/src/components/SwatchColorPicker/index.ts b/packages/react/src/components/SwatchColorPicker/index.ts similarity index 100% rename from packages/react-internal/src/components/SwatchColorPicker/index.ts rename to packages/react/src/components/SwatchColorPicker/index.ts diff --git a/packages/react/src/index.bundle.ts b/packages/react/src/index.bundle.ts index 1db338758171a..3b7e009d2b82a 100644 --- a/packages/react/src/index.bundle.ts +++ b/packages/react/src/index.bundle.ts @@ -1,3 +1,4 @@ +import './version'; export * from './index'; // Using the default import, include all icon definitions. Products that care diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index 11aa3484a52b2..bc3c4529a8879 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -1,5 +1,7 @@ import './version'; + export * from '@fluentui/react-internal'; +export * from './ButtonGrid'; export * from './Breadcrumb'; export * from './Checkbox'; export * from './ComboBox'; @@ -11,4 +13,5 @@ export * from './Link'; export * from './Pivot'; export * from './ShimmeredDetailsList'; export * from './Slider'; +export * from './SwatchColorPicker'; export * from './Toggle'; diff --git a/packages/react/src/utilities/ButtonGrid/ButtonGrid.base.tsx b/packages/react/src/utilities/ButtonGrid/ButtonGrid.base.tsx new file mode 100644 index 0000000000000..8f3dba00329cd --- /dev/null +++ b/packages/react/src/utilities/ButtonGrid/ButtonGrid.base.tsx @@ -0,0 +1,78 @@ +import * as React from 'react'; +import { toMatrix, classNamesFunction, getNativeProps, htmlElementProperties } from '../../Utilities'; +import { FocusZone } from '../../FocusZone'; +import { IButtonGridProps, IButtonGridStyleProps, IButtonGridStyles } from './ButtonGrid.types'; +import { useId } from '@uifabric/react-hooks'; + +const getClassNames = classNamesFunction(); + +export const ButtonGridBase: React.FunctionComponent = React.forwardRef< + HTMLElement, + IButtonGridProps +>((props, forwardedRef) => { + const id = useId(undefined, props.id); + + const { + items, + columnCount, + onRenderItem, + // eslint-disable-next-line deprecation/deprecation + ariaPosInSet = props.positionInSet, + // eslint-disable-next-line deprecation/deprecation + ariaSetSize = props.setSize, + styles, + doNotContainWithinFocusZone, + } = props; + + const htmlProps = getNativeProps>( + props, + htmlElementProperties, + // avoid applying onBlur on the table if it's being used in the FocusZone + doNotContainWithinFocusZone ? [] : ['onBlur'], + ); + + const classNames = getClassNames(styles!, { theme: props.theme! }); + + // Array to store the cells in the correct row index + const rowsOfItems: any[][] = toMatrix(items, columnCount); + + const content = ( + + + {rowsOfItems.map((rows, rowIndex) => { + return ( + + {rows.map((cell, cellIndex: number) => { + return ( + + ); + })} + + ); + })} + +
+ {onRenderItem(cell, cellIndex)} +
+ ); + + return doNotContainWithinFocusZone ? ( + content + ) : ( + + {content} + + ); +}); diff --git a/packages/react-internal/src/utilities/ButtonGrid/ButtonGrid.styles.ts b/packages/react/src/utilities/ButtonGrid/ButtonGrid.styles.ts similarity index 100% rename from packages/react-internal/src/utilities/ButtonGrid/ButtonGrid.styles.ts rename to packages/react/src/utilities/ButtonGrid/ButtonGrid.styles.ts diff --git a/packages/react-internal/src/utilities/ButtonGrid/ButtonGrid.test.tsx b/packages/react/src/utilities/ButtonGrid/ButtonGrid.test.tsx similarity index 84% rename from packages/react-internal/src/utilities/ButtonGrid/ButtonGrid.test.tsx rename to packages/react/src/utilities/ButtonGrid/ButtonGrid.test.tsx index 961254d116505..ec851bf2068da 100644 --- a/packages/react-internal/src/utilities/ButtonGrid/ButtonGrid.test.tsx +++ b/packages/react/src/utilities/ButtonGrid/ButtonGrid.test.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import { ButtonGrid } from './ButtonGrid'; import { getStyles } from './ButtonGrid.styles'; +import { isConformant } from '../../common/isConformant'; import { safeMount } from '@uifabric/test-utilities'; const DEFAULT_ITEMS: any[] = [ @@ -15,13 +16,27 @@ const DEFAULT_ITEMS: any[] = [ ]; describe('ButtonGrid', () => { + isConformant({ + Component: ButtonGrid, + displayName: 'ButtonGrid', + requiredProps: { + items: DEFAULT_ITEMS, + columnCount: 4, + styles: getStyles, + onRenderItem: () => { + return; + }, + }, + disabledTests: ['has-top-level-file'], + }); + it('Can render a ButtonGrid with width of four', () => { safeMount( { + onRenderItem={(item, index: number) => { return ; }} />, @@ -40,7 +55,7 @@ describe('ButtonGrid', () => { items={DEFAULT_ITEMS} columnCount={2} styles={getStyles} - onRenderItem={(item: any, index: number) => { + onRenderItem={(item, index: number) => { return ; }} />, @@ -59,7 +74,7 @@ describe('ButtonGrid', () => { items={DEFAULT_ITEMS} columnCount={2} styles={getStyles} - onRenderItem={(item: any, index: number) => { + onRenderItem={(item, index: number) => { return ; }} positionInSet={1} diff --git a/packages/react-internal/src/utilities/ButtonGrid/ButtonGrid.tsx b/packages/react/src/utilities/ButtonGrid/ButtonGrid.tsx similarity index 80% rename from packages/react-internal/src/utilities/ButtonGrid/ButtonGrid.tsx rename to packages/react/src/utilities/ButtonGrid/ButtonGrid.tsx index d2827ca470c79..9553064d77dab 100644 --- a/packages/react-internal/src/utilities/ButtonGrid/ButtonGrid.tsx +++ b/packages/react/src/utilities/ButtonGrid/ButtonGrid.tsx @@ -7,10 +7,7 @@ import { getStyles } from './ButtonGrid.styles'; export const ButtonGrid: React.FunctionComponent = styled< IButtonGridProps, IButtonGridStyleProps, - IButtonGridStyles + IButtonGridStyles, + HTMLElement >(ButtonGridBase, getStyles); - -/** - * @deprecated - use ButtonGrid instead - */ -export const Grid = ButtonGrid; +ButtonGrid.displayName = 'ButtonGrid'; diff --git a/packages/react-internal/src/utilities/ButtonGrid/ButtonGrid.types.ts b/packages/react/src/utilities/ButtonGrid/ButtonGrid.types.ts similarity index 77% rename from packages/react-internal/src/utilities/ButtonGrid/ButtonGrid.types.ts rename to packages/react/src/utilities/ButtonGrid/ButtonGrid.types.ts index f86210002736d..7197076212845 100644 --- a/packages/react-internal/src/utilities/ButtonGrid/ButtonGrid.types.ts +++ b/packages/react/src/utilities/ButtonGrid/ButtonGrid.types.ts @@ -4,24 +4,26 @@ import { IRefObject, IStyleFunctionOrObject } from '../../Utilities'; export interface IButtonGrid {} -export interface IButtonGridProps extends React.TableHTMLAttributes { +export interface IButtonGridProps + extends React.TableHTMLAttributes, + React.RefAttributes { /** * Gets the component ref. */ componentRef?: IRefObject; /** - * Items to display in a ButtonGrid with the specified number of columns. + * Items to display in a ButtonGrid with the specified number of columns */ items: any[]; /** - * The number of columns. + * The number of columns */ columnCount: number; /** - * Custom renderer for the individual items. + * Custom renderer for the individual items */ onRenderItem: (item: any, index: number) => JSX.Element; @@ -85,7 +87,7 @@ export interface IButtonGridProps extends React.TableHTMLAttributes>(props: IButtonGridCellProps) => { + const defaultId = useId('gridCell'); + const { + item, + id = defaultId, + className, + role, + selected, + disabled = false, + onRenderItem, + cellDisabledStyle, + cellIsSelectedStyle, + index, + label, + getClassNames, + onClick, + onHover, + onMouseMove, + onMouseLeave, + onMouseEnter, + onFocus, + } = props; + + const handleClick = React.useCallback((): void => { + if (onClick && !disabled) { + onClick(item); + } + }, [disabled, item, onClick]); + + const handleMouseEnter = React.useCallback( + (ev: React.MouseEvent): void => { + const didUpdateOnEnter = onMouseEnter && onMouseEnter(ev); + + if (!didUpdateOnEnter && onHover && !disabled) { + onHover(item); + } + }, + [disabled, item, onHover, onMouseEnter], + ); + + const handleMouseMove = React.useCallback( + (ev: React.MouseEvent): void => { + const didUpdateOnMove = onMouseMove && onMouseMove(ev); + + if (!didUpdateOnMove && onHover && !disabled) { + onHover(item); + } + }, + [disabled, item, onHover, onMouseMove], + ); + + const handleMouseLeave = React.useCallback( + (ev: React.MouseEvent): void => { + const didUpdateOnLeave = onMouseLeave && onMouseLeave(ev); + + if (!didUpdateOnLeave && onHover && !disabled) { + onHover(); + } + }, + [disabled, onHover, onMouseLeave], + ); + + const handleFocus = React.useCallback((): void => { + if (onFocus && !disabled) { + onFocus(item); + } + }, [disabled, item, onFocus]); + + return ( + + {onRenderItem(item)} + + ); +}; diff --git a/packages/react-internal/src/utilities/ButtonGrid/ButtonGridCell.types.ts b/packages/react/src/utilities/ButtonGrid/ButtonGridCell.types.ts similarity index 90% rename from packages/react-internal/src/utilities/ButtonGrid/ButtonGridCell.types.ts rename to packages/react/src/utilities/ButtonGrid/ButtonGridCell.types.ts index 8db88f7a0bf5c..25d7d12121724 100644 --- a/packages/react-internal/src/utilities/ButtonGrid/ButtonGridCell.types.ts +++ b/packages/react/src/utilities/ButtonGrid/ButtonGridCell.types.ts @@ -1,5 +1,5 @@ import * as React from 'react'; -import { IButtonClassNames } from '../../components/Button/BaseButton.classNames'; +import { IButtonClassNames } from '@fluentui/react-internal/lib/components/Button/BaseButton.classNames'; import { ITheme } from '../../Styling'; export interface IButtonGridCellProps { @@ -14,7 +14,7 @@ export interface IButtonGridCellProps { id: string; /** - * Optional, if the this option should be diabled + * Optional, if the this option should be disabled */ disabled?: boolean; @@ -119,8 +119,3 @@ export interface IButtonGridCellProps { */ onKeyDown?: (ev: React.KeyboardEvent) => void; } - -/** - * @deprecated - use IButtonGridCellProps instead - */ -export interface IGridCellProps extends IButtonGridCellProps {} diff --git a/packages/react-internal/src/utilities/ButtonGrid/index.ts b/packages/react/src/utilities/ButtonGrid/index.ts similarity index 100% rename from packages/react-internal/src/utilities/ButtonGrid/index.ts rename to packages/react/src/utilities/ButtonGrid/index.ts