components-test-pb 0.0.5 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Components/Button/Button.types.d.ts +2 -1
- package/dist/Components/Button/useButton.js +11 -3
- package/dist/Components/Button/useButtonStyles.styles.js +3 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/utilities/index.d.ts +2 -0
- package/dist/utilities/index.js +1 -0
- package/dist/utilities/useARIAButtonProps.d.ts +16 -0
- package/dist/utilities/useARIAButtonProps.js +75 -0
- package/package.json +1 -1
- package/src/Components/Button/Button.types.ts +2 -1
- package/src/Components/Button/useButton.ts +15 -4
- package/src/Components/Button/useButtonStyles.styles.ts +5 -3
- package/src/index.ts +5 -1
- package/src/utilities/index.ts +2 -0
- package/src/utilities/useARIAButtonProps.ts +106 -0
|
@@ -7,8 +7,9 @@ export type ButtonSize = 'small' | 'medium' | 'large';
|
|
|
7
7
|
export type ButtonProps = ComponentProps<ButtonSlots> & {
|
|
8
8
|
appearance?: 'secondary' | 'primary' | 'tertiary';
|
|
9
9
|
disabled?: boolean;
|
|
10
|
+
disabledFocusable?: boolean;
|
|
10
11
|
shape?: 'rounded' | 'circular' | 'square';
|
|
11
12
|
size?: ButtonSize;
|
|
12
13
|
};
|
|
13
14
|
export type ButtonBaseProps = DistributiveOmit<ButtonProps, 'appearance' | 'size' | 'shape'>;
|
|
14
|
-
export type ButtonState = ComponentState<ButtonSlots> & Required<Pick<ButtonProps, 'appearance' | 'disabled' | 'shape' | 'size'>>;
|
|
15
|
+
export type ButtonState = ComponentState<ButtonSlots> & Required<Pick<ButtonProps, 'appearance' | 'disabled' | 'disabledFocusable' | 'shape' | 'size'>>;
|
|
@@ -1,11 +1,19 @@
|
|
|
1
|
+
import { useARIAButtonProps } from '../../utilities/useARIAButtonProps.js';
|
|
1
2
|
export const useButton = (props) => {
|
|
2
|
-
const { appearance, shape, size, disabled, ...buttonProps } = props;
|
|
3
|
+
const { appearance, shape, size, disabled, disabledFocusable, ...buttonProps } = props;
|
|
4
|
+
const tag = (buttonProps.as ?? 'button');
|
|
5
|
+
const ariaButtonProps = useARIAButtonProps(tag, {
|
|
6
|
+
...buttonProps,
|
|
7
|
+
disabled,
|
|
8
|
+
disabledFocusable,
|
|
9
|
+
});
|
|
3
10
|
return {
|
|
4
11
|
appearance: appearance ?? 'secondary',
|
|
5
12
|
shape: shape ?? 'rounded',
|
|
6
13
|
size: size ?? 'medium',
|
|
7
14
|
disabled: disabled ?? false,
|
|
8
|
-
|
|
9
|
-
|
|
15
|
+
disabledFocusable: disabledFocusable ?? false,
|
|
16
|
+
components: { root: tag },
|
|
17
|
+
root: { as: tag, ...ariaButtonProps },
|
|
10
18
|
};
|
|
11
19
|
};
|
|
@@ -102,7 +102,8 @@ export const useButtonStyles = (state) => {
|
|
|
102
102
|
const rootBaseClassName = useRootBaseClassName();
|
|
103
103
|
const rootStyles = useRootStyles();
|
|
104
104
|
const rootDisabledStyles = useRootDisabledstyles();
|
|
105
|
-
const { appearance, disabled, shape, size } = state;
|
|
106
|
-
|
|
105
|
+
const { appearance, disabled, disabledFocusable, shape, size } = state;
|
|
106
|
+
const isDisabled = disabled || disabledFocusable;
|
|
107
|
+
state.root.className = mergeClasses(buttonClassNames.root, rootBaseClassName, appearance && rootStyles[appearance], rootStyles[size], rootStyles[shape], isDisabled && rootDisabledStyles.base, appearance && isDisabled && rootDisabledStyles[appearance], state.root.className);
|
|
107
108
|
return state;
|
|
108
109
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -4,3 +4,5 @@ export { Button, useButton, renderButton, useButtonStyles } from './Components/B
|
|
|
4
4
|
export type { ButtonSlots, ButtonProps, ButtonBaseProps, ButtonState } from './Components/Button/index.js';
|
|
5
5
|
export * from './Types/compose/index.js';
|
|
6
6
|
export * from './Types/utils/index.js';
|
|
7
|
+
export { useARIAButtonProps } from './utilities/index.js';
|
|
8
|
+
export type { ARIAButtonType, ARIAButtonProps, ARIAButtonResultProps } from './utilities/index.js';
|
package/dist/index.js
CHANGED
|
@@ -2,3 +2,4 @@ export { Text, useText, renderText, useTextStyles } from './Components/Text/inde
|
|
|
2
2
|
export { Button, useButton, renderButton, useButtonStyles } from './Components/Button/index.js';
|
|
3
3
|
export * from './Types/compose/index.js';
|
|
4
4
|
export * from './Types/utils/index.js';
|
|
5
|
+
export { useARIAButtonProps } from './utilities/index.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useARIAButtonProps } from './useARIAButtonProps.js';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { HTMLAttributes } from '../Types/utils/types.js';
|
|
2
|
+
export type ARIAButtonType = 'button' | 'a' | 'div';
|
|
3
|
+
export type ARIAButtonProps<Tag extends ARIAButtonType = 'button'> = HTMLAttributes<HTMLElement> & {
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
disabledFocusable?: boolean;
|
|
6
|
+
} & (Tag extends 'a' ? {
|
|
7
|
+
href?: string;
|
|
8
|
+
} : {});
|
|
9
|
+
export type ARIAButtonResultProps<Tag extends ARIAButtonType = 'button'> = HTMLAttributes<HTMLElement> & {
|
|
10
|
+
disabled?: Tag extends 'button' ? '' | undefined : never;
|
|
11
|
+
'aria-disabled'?: 'true';
|
|
12
|
+
role?: string;
|
|
13
|
+
tabIndex?: number;
|
|
14
|
+
href?: string;
|
|
15
|
+
};
|
|
16
|
+
export declare const useARIAButtonProps: <Tag extends ARIAButtonType>(tag: Tag, props?: ARIAButtonProps<Tag>) => ARIAButtonResultProps<Tag>;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const noop = () => { };
|
|
2
|
+
export const useARIAButtonProps = (tag, props = {}) => {
|
|
3
|
+
const { disabled, disabledFocusable, onClick, onKeyDown, onKeyUp, ...rest } = props;
|
|
4
|
+
const isDisabled = disabled || disabledFocusable;
|
|
5
|
+
const handleClick = (e) => {
|
|
6
|
+
if (isDisabled) {
|
|
7
|
+
e.preventDefault();
|
|
8
|
+
e.stopPropagation();
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
onClick?.(e);
|
|
12
|
+
};
|
|
13
|
+
if (tag === 'button') {
|
|
14
|
+
const result = {
|
|
15
|
+
...rest,
|
|
16
|
+
onClick: handleClick,
|
|
17
|
+
onKeyDown: isDisabled ? (e) => {
|
|
18
|
+
e.preventDefault();
|
|
19
|
+
e.stopPropagation();
|
|
20
|
+
} : onKeyDown,
|
|
21
|
+
onKeyUp: isDisabled ? (e) => {
|
|
22
|
+
e.preventDefault();
|
|
23
|
+
e.stopPropagation();
|
|
24
|
+
} : onKeyUp,
|
|
25
|
+
};
|
|
26
|
+
if (disabled && !disabledFocusable) {
|
|
27
|
+
result.disabled = '';
|
|
28
|
+
}
|
|
29
|
+
else if (disabledFocusable) {
|
|
30
|
+
result['aria-disabled'] = 'true';
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
const handleKeyDown = (e) => {
|
|
35
|
+
if (isDisabled) {
|
|
36
|
+
e.preventDefault();
|
|
37
|
+
e.stopPropagation();
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (e.key === 'Enter') {
|
|
41
|
+
e.preventDefault();
|
|
42
|
+
e.target?.click();
|
|
43
|
+
}
|
|
44
|
+
onKeyDown?.(e);
|
|
45
|
+
};
|
|
46
|
+
const handleKeyUp = (e) => {
|
|
47
|
+
if (isDisabled) {
|
|
48
|
+
e.preventDefault();
|
|
49
|
+
e.stopPropagation();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (e.key === ' ') {
|
|
53
|
+
e.preventDefault();
|
|
54
|
+
e.target?.click();
|
|
55
|
+
}
|
|
56
|
+
onKeyUp?.(e);
|
|
57
|
+
};
|
|
58
|
+
const result = {
|
|
59
|
+
...rest,
|
|
60
|
+
role: 'button',
|
|
61
|
+
onClick: handleClick,
|
|
62
|
+
onKeyDown: handleKeyDown,
|
|
63
|
+
onKeyUp: handleKeyUp,
|
|
64
|
+
};
|
|
65
|
+
if (isDisabled) {
|
|
66
|
+
result['aria-disabled'] = 'true';
|
|
67
|
+
if (tag === 'a') {
|
|
68
|
+
delete result.href;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (!disabled || disabledFocusable) {
|
|
72
|
+
result.tabIndex = rest.tabIndex ?? 0;
|
|
73
|
+
}
|
|
74
|
+
return result;
|
|
75
|
+
};
|
package/package.json
CHANGED
|
@@ -10,6 +10,7 @@ export type ButtonSize = 'small' | 'medium' | 'large';
|
|
|
10
10
|
export type ButtonProps = ComponentProps<ButtonSlots> & {
|
|
11
11
|
appearance?: 'secondary' | 'primary' | 'tertiary';
|
|
12
12
|
disabled?: boolean;
|
|
13
|
+
disabledFocusable?: boolean;
|
|
13
14
|
shape?: 'rounded' | 'circular' | 'square';
|
|
14
15
|
size?: ButtonSize;
|
|
15
16
|
};
|
|
@@ -20,6 +21,6 @@ export type ButtonState = ComponentState<ButtonSlots> &
|
|
|
20
21
|
Required<
|
|
21
22
|
Pick<
|
|
22
23
|
ButtonProps,
|
|
23
|
-
'appearance' | 'disabled' | 'shape' | 'size'
|
|
24
|
+
'appearance' | 'disabled' | 'disabledFocusable' | 'shape' | 'size'
|
|
24
25
|
>
|
|
25
26
|
>;
|
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
import type { ButtonProps, ButtonState } from './Button.types.js';
|
|
2
|
+
import { useARIAButtonProps } from '../../utilities/useARIAButtonProps.js';
|
|
3
|
+
import type { ARIAButtonType } from '../../utilities/useARIAButtonProps.js';
|
|
2
4
|
|
|
3
5
|
export const useButton = (props: ButtonProps): ButtonState => {
|
|
4
|
-
const { appearance, shape, size, disabled, ...buttonProps } = props;
|
|
6
|
+
const { appearance, shape, size, disabled, disabledFocusable, ...buttonProps } = props;
|
|
7
|
+
|
|
8
|
+
const tag = (buttonProps.as ?? 'button') as ARIAButtonType;
|
|
9
|
+
|
|
10
|
+
const ariaButtonProps = useARIAButtonProps(tag, {
|
|
11
|
+
...buttonProps,
|
|
12
|
+
disabled,
|
|
13
|
+
disabledFocusable,
|
|
14
|
+
});
|
|
5
15
|
|
|
6
16
|
return {
|
|
7
17
|
appearance: appearance ?? 'secondary',
|
|
8
18
|
shape: shape ?? 'rounded',
|
|
9
19
|
size: size ?? 'medium',
|
|
10
20
|
disabled: disabled ?? false,
|
|
21
|
+
disabledFocusable: disabledFocusable ?? false,
|
|
11
22
|
|
|
12
|
-
components: { root:
|
|
23
|
+
components: { root: tag },
|
|
13
24
|
|
|
14
|
-
root: { as:
|
|
25
|
+
root: { as: tag, ...ariaButtonProps } as ButtonState['root'],
|
|
15
26
|
};
|
|
16
|
-
};
|
|
27
|
+
};
|
|
@@ -130,7 +130,9 @@ export const useButtonStyles = (state: ButtonState): ButtonState => {
|
|
|
130
130
|
const rootStyles = useRootStyles();
|
|
131
131
|
const rootDisabledStyles = useRootDisabledstyles();
|
|
132
132
|
|
|
133
|
-
const { appearance, disabled, shape, size } = state;
|
|
133
|
+
const { appearance, disabled, disabledFocusable, shape, size } = state;
|
|
134
|
+
|
|
135
|
+
const isDisabled = disabled || disabledFocusable;
|
|
134
136
|
|
|
135
137
|
state.root.className = mergeClasses(
|
|
136
138
|
buttonClassNames.root,
|
|
@@ -141,8 +143,8 @@ export const useButtonStyles = (state: ButtonState): ButtonState => {
|
|
|
141
143
|
rootStyles[size],
|
|
142
144
|
rootStyles[shape],
|
|
143
145
|
|
|
144
|
-
|
|
145
|
-
appearance &&
|
|
146
|
+
isDisabled && rootDisabledStyles.base,
|
|
147
|
+
appearance && isDisabled && rootDisabledStyles[appearance],
|
|
146
148
|
|
|
147
149
|
state.root.className,
|
|
148
150
|
);
|
package/src/index.ts
CHANGED
|
@@ -17,6 +17,7 @@ export {
|
|
|
17
17
|
renderButton,
|
|
18
18
|
useButtonStyles
|
|
19
19
|
} from './Components/Button/index.js';
|
|
20
|
+
|
|
20
21
|
export type {
|
|
21
22
|
ButtonSlots,
|
|
22
23
|
ButtonProps,
|
|
@@ -25,4 +26,7 @@ export type {
|
|
|
25
26
|
} from './Components/Button/index.js';
|
|
26
27
|
|
|
27
28
|
export * from './Types/compose/index.js';
|
|
28
|
-
export * from './Types/utils/index.js';
|
|
29
|
+
export * from './Types/utils/index.js';
|
|
30
|
+
|
|
31
|
+
export { useARIAButtonProps } from './utilities/index.js';
|
|
32
|
+
export type { ARIAButtonType, ARIAButtonProps, ARIAButtonResultProps } from './utilities/index.js';
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { HTMLAttributes, IntrinsicElementKeys } from '../Types/utils/types.js';
|
|
2
|
+
|
|
3
|
+
export type ARIAButtonType = 'button' | 'a' | 'div';
|
|
4
|
+
|
|
5
|
+
export type ARIAButtonProps<Tag extends ARIAButtonType = 'button'> = HTMLAttributes<HTMLElement> & {
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
disabledFocusable?: boolean;
|
|
8
|
+
} & (Tag extends 'a' ? { href?: string } : {});
|
|
9
|
+
|
|
10
|
+
export type ARIAButtonResultProps<Tag extends ARIAButtonType = 'button'> = HTMLAttributes<HTMLElement> & {
|
|
11
|
+
disabled?: Tag extends 'button' ? '' | undefined : never;
|
|
12
|
+
'aria-disabled'?: 'true';
|
|
13
|
+
role?: string;
|
|
14
|
+
tabIndex?: number;
|
|
15
|
+
href?: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const noop = () => { };
|
|
19
|
+
|
|
20
|
+
export const useARIAButtonProps = <Tag extends ARIAButtonType>(
|
|
21
|
+
tag: Tag,
|
|
22
|
+
props: ARIAButtonProps<Tag> = {} as ARIAButtonProps<Tag>,
|
|
23
|
+
): ARIAButtonResultProps<Tag> => {
|
|
24
|
+
const { disabled, disabledFocusable, onClick, onKeyDown, onKeyUp, ...rest } = props as ARIAButtonProps & { href?: string };
|
|
25
|
+
|
|
26
|
+
const isDisabled = disabled || disabledFocusable;
|
|
27
|
+
|
|
28
|
+
const handleClick = (e: MouseEvent) => {
|
|
29
|
+
if (isDisabled) {
|
|
30
|
+
e.preventDefault();
|
|
31
|
+
e.stopPropagation();
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
onClick?.(e);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
if (tag === 'button') {
|
|
38
|
+
const result = {
|
|
39
|
+
...rest,
|
|
40
|
+
onClick: handleClick,
|
|
41
|
+
onKeyDown: isDisabled ? (e: KeyboardEvent) => {
|
|
42
|
+
e.preventDefault();
|
|
43
|
+
e.stopPropagation();
|
|
44
|
+
} : onKeyDown,
|
|
45
|
+
onKeyUp: isDisabled ? (e: KeyboardEvent) => {
|
|
46
|
+
e.preventDefault();
|
|
47
|
+
e.stopPropagation();
|
|
48
|
+
} : onKeyUp,
|
|
49
|
+
} as ARIAButtonResultProps<Tag>;
|
|
50
|
+
|
|
51
|
+
if (disabled && !disabledFocusable) {
|
|
52
|
+
(result as any).disabled = '';
|
|
53
|
+
} else if (disabledFocusable) {
|
|
54
|
+
result['aria-disabled'] = 'true';
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const handleKeyDown = (e: KeyboardEvent) => {
|
|
61
|
+
if (isDisabled) {
|
|
62
|
+
e.preventDefault();
|
|
63
|
+
e.stopPropagation();
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (e.key === 'Enter') {
|
|
67
|
+
e.preventDefault();
|
|
68
|
+
(e.target as HTMLElement)?.click();
|
|
69
|
+
}
|
|
70
|
+
onKeyDown?.(e);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const handleKeyUp = (e: KeyboardEvent) => {
|
|
74
|
+
if (isDisabled) {
|
|
75
|
+
e.preventDefault();
|
|
76
|
+
e.stopPropagation();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (e.key === ' ') {
|
|
80
|
+
e.preventDefault();
|
|
81
|
+
(e.target as HTMLElement)?.click();
|
|
82
|
+
}
|
|
83
|
+
onKeyUp?.(e);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const result: ARIAButtonResultProps<Tag> = {
|
|
87
|
+
...rest,
|
|
88
|
+
role: 'button',
|
|
89
|
+
onClick: handleClick,
|
|
90
|
+
onKeyDown: handleKeyDown,
|
|
91
|
+
onKeyUp: handleKeyUp,
|
|
92
|
+
} as ARIAButtonResultProps<Tag>;
|
|
93
|
+
|
|
94
|
+
if (isDisabled) {
|
|
95
|
+
result['aria-disabled'] = 'true';
|
|
96
|
+
if (tag === 'a') {
|
|
97
|
+
delete (result as any).href;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (!disabled || disabledFocusable) {
|
|
102
|
+
result.tabIndex = rest.tabIndex ?? 0;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return result;
|
|
106
|
+
};
|