@react-aria/button
Version:
Spectrum UI components in React
98 lines (88 loc) • 4.46 kB
text/typescript
/*
* Copyright 2024 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
} from 'react';
import {AriaLabelingProps, DOMAttributes, Orientation, RefObject} from '@react-types/shared';
import {AriaToggleButtonGroupItemProps} from '@react-types/button';
import {ToggleButtonAria, useToggleButton} from './useToggleButton';
import {ToggleGroupProps, ToggleGroupState, ToggleState} from '@react-stately/toggle';
import {useToolbar} from '@react-aria/toolbar';
export interface AriaToggleButtonGroupProps extends ToggleGroupProps, AriaLabelingProps {
/**
* The orientation of the the toggle button group.
* @default 'horizontal'
*/
orientation?: Orientation
}
export interface ToggleButtonGroupAria {
/**
* Props for the toggle button group container.
*/
groupProps: DOMAttributes
}
export function useToggleButtonGroup(props: AriaToggleButtonGroupProps, state: ToggleGroupState, ref: RefObject<HTMLElement | null>): ToggleButtonGroupAria {
let {isDisabled} = props;
let {toolbarProps} = useToolbar(props, ref);
return {
groupProps: {
...toolbarProps,
role: state.selectionMode === 'single' ? 'radiogroup' : toolbarProps.role,
'aria-disabled': isDisabled
}
};
}
export type {AriaToggleButtonGroupItemProps};
export interface AriaToggleButtonGroupItemOptions<E extends ElementType> extends Omit<AriaToggleButtonGroupItemProps<E>, 'children'> {}
// Order with overrides is important: 'button' should be default
export function useToggleButtonGroupItem(props: AriaToggleButtonGroupItemOptions<'button'>, state: ToggleGroupState, ref: RefObject<HTMLButtonElement | null>): ToggleButtonAria<ButtonHTMLAttributes<HTMLButtonElement>>;
export function useToggleButtonGroupItem(props: AriaToggleButtonGroupItemOptions<'a'>, state: ToggleGroupState, ref: RefObject<HTMLAnchorElement | null>): ToggleButtonAria<AnchorHTMLAttributes<HTMLAnchorElement>>;
export function useToggleButtonGroupItem(props: AriaToggleButtonGroupItemOptions<'div'>, state: ToggleGroupState, ref: RefObject<HTMLDivElement | null>): ToggleButtonAria<HTMLAttributes<HTMLDivElement>>;
export function useToggleButtonGroupItem(props: AriaToggleButtonGroupItemOptions<'input'>, state: ToggleGroupState, ref: RefObject<HTMLInputElement | null>): ToggleButtonAria<InputHTMLAttributes<HTMLInputElement>>;
export function useToggleButtonGroupItem(props: AriaToggleButtonGroupItemOptions<'span'>, state: ToggleGroupState, ref: RefObject<HTMLSpanElement | null>): ToggleButtonAria<HTMLAttributes<HTMLSpanElement>>;
export function useToggleButtonGroupItem(props: AriaToggleButtonGroupItemOptions<ElementType>, state: ToggleGroupState, ref: RefObject<Element | null>): ToggleButtonAria<DOMAttributes>;
/**
* Provides the behavior and accessibility implementation for a toggle button component.
* ToggleButtons allow users to toggle a selection on or off, for example switching between two states or modes.
*/
export function useToggleButtonGroupItem(props: AriaToggleButtonGroupItemOptions<ElementType>, state: ToggleGroupState, ref: RefObject<any>): ToggleButtonAria<HTMLAttributes<any>> {
let toggleState: ToggleState = {
isSelected: state.selectedKeys.has(props.id),
defaultSelected: false,
setSelected(isSelected) {
state.setSelected(props.id, isSelected);
},
toggle() {
state.toggleKey(props.id);
}
};
let {isPressed, isSelected, isDisabled, buttonProps} = useToggleButton({
...props,
id: undefined,
isDisabled: props.isDisabled || state.isDisabled
}, toggleState, ref);
if (state.selectionMode === 'single') {
buttonProps.role = 'radio';
buttonProps['aria-checked'] = toggleState.isSelected;
delete buttonProps['aria-pressed'];
}
return {
isPressed,
isSelected,
isDisabled,
buttonProps
};
}