Build NapCat Artifacts / Windows Loader Test (push) Canceled after 0s
Build NapCat Artifacts / Type Check & Test (push) Canceled after 0s
Build NapCat Artifacts / Build NapCat.Framework (push) Canceled after 0s
Build NapCat Artifacts / Build NapCat.Shell (push) Canceled after 0s
122 lines
4.6 KiB
Plaintext
122 lines
4.6 KiB
Plaintext
/*
|
|
* 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 {
|
|
AnchorHTMLAttributes,
|
|
ButtonHTMLAttributes,
|
|
ElementType,
|
|
HTMLAttributes,
|
|
InputHTMLAttributes,
|
|
RefObject
|
|
} from 'react';
|
|
import {AriaButtonProps} from '@react-types/button';
|
|
import {DOMAttributes} from '@react-types/shared';
|
|
import {filterDOMProps, mergeProps} from '@react-aria/utils';
|
|
import {useFocusable, usePress} from '@react-aria/interactions';
|
|
|
|
export interface AriaButtonOptions<E extends ElementType> extends Omit<AriaButtonProps<E>, 'children'> {}
|
|
|
|
export interface ButtonAria<T> {
|
|
/** Props for the button element. */
|
|
buttonProps: T,
|
|
/** Whether the button is currently pressed. */
|
|
isPressed: boolean
|
|
}
|
|
|
|
// Order with overrides is important: 'button' should be default
|
|
export function useButton(props: AriaButtonOptions<'button'>, ref: RefObject<HTMLButtonElement | null>): ButtonAria<ButtonHTMLAttributes<HTMLButtonElement>>;
|
|
export function useButton(props: AriaButtonOptions<'a'>, ref: RefObject<HTMLAnchorElement | null>): ButtonAria<AnchorHTMLAttributes<HTMLAnchorElement>>;
|
|
export function useButton(props: AriaButtonOptions<'div'>, ref: RefObject<HTMLDivElement | null>): ButtonAria<HTMLAttributes<HTMLDivElement>>;
|
|
export function useButton(props: AriaButtonOptions<'input'>, ref: RefObject<HTMLInputElement | null>): ButtonAria<InputHTMLAttributes<HTMLInputElement>>;
|
|
export function useButton(props: AriaButtonOptions<'span'>, ref: RefObject<HTMLSpanElement | null>): ButtonAria<HTMLAttributes<HTMLSpanElement>>;
|
|
export function useButton(props: AriaButtonOptions<ElementType>, ref: RefObject<Element | null>): ButtonAria<DOMAttributes>;
|
|
/**
|
|
* Provides the behavior and accessibility implementation for a button component. Handles mouse, keyboard, and touch interactions,
|
|
* focus behavior, and ARIA props for both native button elements and custom element types.
|
|
* @param props - Props to be applied to the button.
|
|
* @param ref - A ref to a DOM element for the button.
|
|
*/
|
|
export function useButton(props: AriaButtonOptions<ElementType>, ref: RefObject<any>): ButtonAria<HTMLAttributes<any>> {
|
|
let {
|
|
elementType = 'button',
|
|
isDisabled,
|
|
onPress,
|
|
onPressStart,
|
|
onPressEnd,
|
|
onPressUp,
|
|
onPressChange,
|
|
preventFocusOnPress,
|
|
// @ts-ignore - undocumented
|
|
allowFocusWhenDisabled,
|
|
onClick,
|
|
href,
|
|
target,
|
|
rel,
|
|
type = 'button'
|
|
} = props;
|
|
let additionalProps;
|
|
if (elementType === 'button') {
|
|
additionalProps = {
|
|
type,
|
|
disabled: isDisabled,
|
|
form: props.form,
|
|
formAction: props.formAction,
|
|
formEncType: props.formEncType,
|
|
formMethod: props.formMethod,
|
|
formNoValidate: props.formNoValidate,
|
|
formTarget: props.formTarget,
|
|
name: props.name,
|
|
value: props.value
|
|
};
|
|
} else {
|
|
additionalProps = {
|
|
role: 'button',
|
|
href: elementType === 'a' && !isDisabled ? href : undefined,
|
|
target: elementType === 'a' ? target : undefined,
|
|
type: elementType === 'input' ? type : undefined,
|
|
disabled: elementType === 'input' ? isDisabled : undefined,
|
|
'aria-disabled': !isDisabled || elementType === 'input' ? undefined : isDisabled,
|
|
rel: elementType === 'a' ? rel : undefined
|
|
};
|
|
}
|
|
|
|
let {pressProps, isPressed} = usePress({
|
|
onPressStart,
|
|
onPressEnd,
|
|
onPressChange,
|
|
onPress,
|
|
onPressUp,
|
|
onClick,
|
|
isDisabled,
|
|
preventFocusOnPress,
|
|
ref
|
|
});
|
|
|
|
let {focusableProps} = useFocusable(props, ref);
|
|
if (allowFocusWhenDisabled) {
|
|
focusableProps.tabIndex = isDisabled ? -1 : focusableProps.tabIndex;
|
|
}
|
|
let buttonProps = mergeProps(focusableProps, pressProps, filterDOMProps(props, {labelable: true}));
|
|
|
|
return {
|
|
isPressed, // Used to indicate press state for visual
|
|
buttonProps: mergeProps(additionalProps, buttonProps, {
|
|
'aria-haspopup': props['aria-haspopup'],
|
|
'aria-expanded': props['aria-expanded'],
|
|
'aria-controls': props['aria-controls'],
|
|
'aria-pressed': props['aria-pressed'],
|
|
'aria-current': props['aria-current'],
|
|
'aria-disabled': props['aria-disabled']
|
|
})
|
|
};
|
|
}
|