Skip to content

Commit bf151e7

Browse files
authored
chore(react-aria): useARIAButton folder (#24444)
* chore: re-organize useARIAButton into its own folder * change file
1 parent c8244ad commit bf151e7

10 files changed

Lines changed: 123 additions & 100 deletions
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "none",
3+
"comment": "chore: re-organize useARIAButton into its own folder",
4+
"packageName": "@fluentui/react-aria",
5+
"email": "[email protected]",
6+
"dependentChangeType": "none"
7+
}

packages/react-components/react-aria/src/hooks/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from './useARIAButtonProps';
2+
export * from './useARIAButtonShorthand';
3+
export * from './types';
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import type { ExtractSlotProps, Slot } from '@fluentui/react-utilities';
2+
import * as React from 'react';
3+
4+
export type ARIAButtonType = 'button' | 'a' | 'div';
5+
6+
/**
7+
* Props expected by `useARIAButtonProps` hooks
8+
*/
9+
export type ARIAButtonProps<Type extends ARIAButtonType = ARIAButtonType> = React.PropsWithRef<
10+
JSX.IntrinsicElements[Type]
11+
> & {
12+
disabled?: boolean;
13+
/**
14+
* When set, allows the button to be focusable even when it has been disabled.
15+
* This is used in scenarios where it is important to keep a consistent tab order
16+
* for screen reader and keyboard users. The primary example of this
17+
* pattern is when the disabled button is in a menu or a commandbar and is seldom used for standalone buttons.
18+
*
19+
* @default false
20+
*/
21+
disabledFocusable?: boolean;
22+
};
23+
24+
export type ARIAButtonSlotProps<AlternateAs extends 'a' | 'div' = 'a' | 'div'> = ExtractSlotProps<
25+
Slot<'button', AlternateAs>
26+
> &
27+
Pick<ARIAButtonProps<ARIAButtonType>, 'disabled' | 'disabledFocusable'>;
28+
29+
/**
30+
* @internal
31+
* Props that will be modified internally by `useARIAButtonProps` by each case.
32+
* This typing is to ensure a well specified return value for `useARIAbButtonProps`
33+
*/
34+
export type ARIAButtonAlteredProps<Type extends ARIAButtonType> =
35+
| (Type extends 'button'
36+
? Pick<
37+
JSX.IntrinsicElements['button'],
38+
'onClick' | 'onKeyDown' | 'onKeyUp' | 'disabled' | 'aria-disabled' | 'tabIndex'
39+
>
40+
: never)
41+
| (Type extends 'a'
42+
? Pick<
43+
JSX.IntrinsicElements['a'],
44+
'onClick' | 'onKeyDown' | 'onKeyUp' | 'aria-disabled' | 'tabIndex' | 'role' | 'href'
45+
>
46+
: never)
47+
| (Type extends 'div'
48+
? Pick<JSX.IntrinsicElements['div'], 'onClick' | 'onKeyDown' | 'onKeyUp' | 'aria-disabled' | 'tabIndex' | 'role'>
49+
: never);
50+
51+
type UnionToIntersection<U> = (U extends unknown ? (x: U) => U : never) extends (x: infer I) => U ? I : never;
52+
53+
/**
54+
* Merge of props provided by the user and props provided internally.
55+
*/
56+
export type ARIAButtonResultProps<Type extends ARIAButtonType, Props> = Props &
57+
UnionToIntersection<ARIAButtonAlteredProps<Type>>;

packages/react-components/react-aria/src/hooks/useARIAButton.stories.tsx renamed to packages/react-components/react-aria/src/hooks/useARIAButton/useARIAButton.stories.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as React from 'react';
2-
import { useARIAButtonShorthand } from './useARIAButton';
3-
import type { ARIAButtonSlotProps } from './useARIAButton';
2+
import { useARIAButtonShorthand } from '../useARIAButton';
3+
import type { ARIAButtonSlotProps } from '../useARIAButton';
44
import { getSlots } from '@fluentui/react-components';
55
import type { ComponentState, Slot } from '@fluentui/react-components';
66

packages/react-components/react-aria/src/hooks/useARIAButton.test.tsx renamed to packages/react-components/react-aria/src/hooks/useARIAButton/useARIAButtonProps.test.tsx

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import * as React from 'react';
2-
import { useARIAButtonShorthand, useARIAButtonProps, ARIAButtonProps, ARIAButtonSlotProps } from './useARIAButton';
2+
import { useARIAButtonProps } from './useARIAButtonProps';
33
import { renderHook } from '@testing-library/react-hooks';
44
import { fireEvent, render } from '@testing-library/react';
55
import { getSlots, Slot, ComponentProps } from '@fluentui/react-utilities';
6+
import { ARIAButtonProps, ARIAButtonSlotProps } from './types';
7+
import { useARIAButtonShorthand } from './useARIAButtonShorthand';
68

79
const TestButton = (props: ComponentProps<{ root: Slot<ARIAButtonSlotProps> }>) => {
810
const { slots, slotProps } = getSlots<{ root: Slot<ARIAButtonSlotProps> }>({
@@ -158,24 +160,3 @@ describe('useARIAButton', () => {
158160
expect(handleClick).toBeCalledTimes(0);
159161
});
160162
});
161-
162-
describe('useARIAButtonShorthands', () => {
163-
it('should return shorthands', () => {
164-
const {
165-
result: { current: buttonShorthand },
166-
} = renderHook(() => useARIAButtonShorthand({ as: 'button' }));
167-
expect(buttonShorthand.as).toBe('button');
168-
const {
169-
result: { current: buttonShorthand2 },
170-
} = renderHook(() => useARIAButtonShorthand({ as: undefined }));
171-
expect(buttonShorthand2.as).toBe(undefined);
172-
const {
173-
result: { current: acnhorShorthand },
174-
} = renderHook(() => useARIAButtonShorthand({ as: 'a' }));
175-
expect(acnhorShorthand.as).toBe('a');
176-
const {
177-
result: { current: divShorthand },
178-
} = renderHook(() => useARIAButtonShorthand({ as: 'div' }));
179-
expect(divShorthand.as).toBe('div');
180-
});
181-
});

packages/react-components/react-aria/src/hooks/useARIAButton.ts renamed to packages/react-components/react-aria/src/hooks/useARIAButton/useARIAButtonProps.ts

Lines changed: 2 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,6 @@
11
import { Enter, Space } from '@fluentui/keyboard-keys';
2-
import { resolveShorthand, useEventCallback } from '@fluentui/react-utilities';
3-
import type { ExtractSlotProps, ResolveShorthandFunction, Slot } from '@fluentui/react-utilities';
4-
import * as React from 'react';
5-
6-
export type ARIAButtonType = 'button' | 'a' | 'div';
7-
8-
/**
9-
* Props expected by `useARIAButtonProps` hooks
10-
*/
11-
export type ARIAButtonProps<Type extends ARIAButtonType = ARIAButtonType> = React.PropsWithRef<
12-
JSX.IntrinsicElements[Type]
13-
> & {
14-
disabled?: boolean;
15-
/**
16-
* When set, allows the button to be focusable even when it has been disabled.
17-
* This is used in scenarios where it is important to keep a consistent tab order
18-
* for screen reader and keyboard users. The primary example of this
19-
* pattern is when the disabled button is in a menu or a commandbar and is seldom used for standalone buttons.
20-
*
21-
* @default false
22-
*/
23-
disabledFocusable?: boolean;
24-
};
25-
26-
export type ARIAButtonSlotProps<AlternateAs extends 'a' | 'div' = 'a' | 'div'> = ExtractSlotProps<
27-
Slot<'button', AlternateAs>
28-
> &
29-
Pick<ARIAButtonProps<ARIAButtonType>, 'disabled' | 'disabledFocusable'>;
30-
31-
/**
32-
* @internal
33-
* Props that will be modified internally by `useARIAButtonProps` by each case.
34-
* This typing is to ensure a well specified return value for `useARIAbButtonProps`
35-
*/
36-
type ARIAButtonAlteredProps<Type extends ARIAButtonType> =
37-
| (Type extends 'button'
38-
? Pick<
39-
JSX.IntrinsicElements['button'],
40-
'onClick' | 'onKeyDown' | 'onKeyUp' | 'disabled' | 'aria-disabled' | 'tabIndex'
41-
>
42-
: never)
43-
| (Type extends 'a'
44-
? Pick<
45-
JSX.IntrinsicElements['a'],
46-
'onClick' | 'onKeyDown' | 'onKeyUp' | 'aria-disabled' | 'tabIndex' | 'role' | 'href'
47-
>
48-
: never)
49-
| (Type extends 'div'
50-
? Pick<JSX.IntrinsicElements['div'], 'onClick' | 'onKeyDown' | 'onKeyUp' | 'aria-disabled' | 'tabIndex' | 'role'>
51-
: never);
52-
53-
type UnionToIntersection<U> = (U extends unknown ? (x: U) => U : never) extends (x: infer I) => U ? I : never;
54-
55-
/**
56-
* Merge of props provided by the user and props provided internally.
57-
*/
58-
export type ARIAButtonResultProps<Type extends ARIAButtonType, Props> = Props &
59-
UnionToIntersection<ARIAButtonAlteredProps<Type>>;
2+
import { useEventCallback } from '@fluentui/react-utilities';
3+
import type { ARIAButtonProps, ARIAButtonResultProps, ARIAButtonType } from './types';
604

615
/**
626
* @internal
@@ -199,18 +143,3 @@ export function useARIAButtonProps<Type extends ARIAButtonType, Props extends AR
199143
return resultProps;
200144
}
201145
}
202-
203-
/**
204-
* @internal
205-
*
206-
* This function expects to receive a slot, if `as` property is not desired use `useARIAButtonProps` instead
207-
*
208-
* Button keyboard handling, role, disabled and tabIndex implementation that ensures ARIA spec
209-
* for multiple scenarios of shorthand properties. Ensuring 1st rule of ARIA for cases
210-
* where no attribute addition is required.
211-
*/
212-
export const useARIAButtonShorthand: ResolveShorthandFunction<ARIAButtonSlotProps> = (slot, options) => {
213-
const shorthand = resolveShorthand(slot, options);
214-
const shorthandARIAButton = useARIAButtonProps<ARIAButtonType, ARIAButtonProps>(shorthand?.as ?? 'button', shorthand);
215-
return shorthand && shorthandARIAButton;
216-
};
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { useARIAButtonShorthand } from './useARIAButtonShorthand';
2+
import { renderHook } from '@testing-library/react-hooks';
3+
4+
describe('useARIAButtonShorthands', () => {
5+
it('should return shorthands', () => {
6+
const {
7+
result: { current: buttonShorthand },
8+
} = renderHook(() => useARIAButtonShorthand({ as: 'button' }));
9+
expect(buttonShorthand.as).toBe('button');
10+
const {
11+
result: { current: buttonShorthand2 },
12+
} = renderHook(() => useARIAButtonShorthand({ as: undefined }));
13+
expect(buttonShorthand2.as).toBe(undefined);
14+
const {
15+
result: { current: anchorShorthand },
16+
} = renderHook(() => useARIAButtonShorthand({ as: 'a' }));
17+
expect(anchorShorthand.as).toBe('a');
18+
const {
19+
result: { current: divShorthand },
20+
} = renderHook(() => useARIAButtonShorthand({ as: 'div' }));
21+
expect(divShorthand.as).toBe('div');
22+
});
23+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { resolveShorthand } from '@fluentui/react-utilities';
2+
import { useARIAButtonProps } from './useARIAButtonProps';
3+
import type { ResolveShorthandFunction } from '@fluentui/react-utilities';
4+
import type { ARIAButtonProps, ARIAButtonSlotProps, ARIAButtonType } from './types';
5+
6+
/**
7+
* @internal
8+
*
9+
* This function expects to receive a slot, if `as` property is not desired use `useARIAButtonProps` instead
10+
*
11+
* Button keyboard handling, role, disabled and tabIndex implementation that ensures ARIA spec
12+
* for multiple scenarios of shorthand properties. Ensuring 1st rule of ARIA for cases
13+
* where no attribute addition is required.
14+
*/
15+
export const useARIAButtonShorthand: ResolveShorthandFunction<ARIAButtonSlotProps> = (slot, options) => {
16+
const shorthand = resolveShorthand(slot, options);
17+
const shorthandARIAButton = useARIAButtonProps<ARIAButtonType, ARIAButtonProps>(shorthand?.as ?? 'button', shorthand);
18+
return shorthand && shorthandARIAButton;
19+
};
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
1-
export { useARIAButtonShorthand, useARIAButtonProps } from './hooks/index';
2-
export type { ARIAButtonSlotProps, ARIAButtonProps, ARIAButtonResultProps, ARIAButtonType } from './hooks/index';
1+
export { useARIAButtonShorthand, useARIAButtonProps } from './hooks/useARIAButton/index';
2+
export type {
3+
ARIAButtonSlotProps,
4+
ARIAButtonProps,
5+
ARIAButtonResultProps,
6+
ARIAButtonType,
7+
} from './hooks/useARIAButton/index';

0 commit comments

Comments
 (0)