/* * Copyright 2020 Adobe. All rights reserved. * This file is licensed to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy * of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ import clsx from 'clsx'; import {mergeProps} from '@react-aria/utils'; import React, {ReactElement} from 'react'; import {useFocusRing} from './useFocusRing'; export interface FocusRingProps { /** Child element to apply CSS classes to. */ children: ReactElement, /** CSS class to apply when the element is focused. */ focusClass?: string, /** CSS class to apply when the element has keyboard focus. */ focusRingClass?: string, /** * Whether to show the focus ring when something * inside the container element has focus (true), or * only if the container itself has focus (false). * @default false */ within?: boolean, /** Whether the element is a text input. */ isTextInput?: boolean, /** Whether the element will be auto focused. */ autoFocus?: boolean } /** * A utility component that applies a CSS class when an element has keyboard focus. * Focus rings are visible only when the user is interacting with a keyboard, * not with a mouse, touch, or other input methods. */ export function FocusRing(props: FocusRingProps) { let {children, focusClass, focusRingClass} = props; let {isFocused, isFocusVisible, focusProps} = useFocusRing(props); let child = React.Children.only(children); return React.cloneElement(child, mergeProps(child.props as any, { ...focusProps, className: clsx({ [focusClass || '']: isFocused, [focusRingClass || '']: isFocusVisible }) })); }