(Canon)fix: Clicking Select label moves focus to trigger.

Signed-off-by: Johan Persson <johanopersson@gmail.com>
This commit is contained in:
Johan Persson
2025-04-28 10:04:21 +02:00
parent dce2bfad8c
commit 720033cd26
6 changed files with 44 additions and 2 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/canon': patch
---
For improved a11y, clicking a Select component label now focuses the Select trigger element.
+5
View File
@@ -836,6 +836,11 @@
font-weight: var(--canon-font-weight-regular);
color: var(--canon-fg-primary);
margin-bottom: var(--canon-space-1_5);
cursor: pointer;
}
.canon-SelectLabel[data-disabled] {
cursor: default;
}
.canon-SelectDescription {
+5
View File
@@ -10,6 +10,11 @@
font-weight: var(--canon-font-weight-regular);
color: var(--canon-fg-primary);
margin-bottom: var(--canon-space-1_5);
cursor: pointer;
}
.canon-SelectLabel[data-disabled] {
cursor: default;
}
.canon-SelectDescription {
+5
View File
@@ -10060,6 +10060,11 @@
font-weight: var(--canon-font-weight-regular);
color: var(--canon-fg-primary);
margin-bottom: var(--canon-space-1_5);
cursor: pointer;
}
.canon-SelectLabel[data-disabled] {
cursor: default;
}
.canon-SelectDescription {
@@ -26,6 +26,10 @@
font-weight: var(--canon-font-weight-regular);
color: var(--canon-fg-primary);
margin-bottom: var(--canon-space-1_5);
cursor: pointer;
}
.canon-SelectLabel[data-disabled] {
cursor: default;
}
.canon-SelectDescription {
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { forwardRef, useId } from 'react';
import { forwardRef, useCallback, useId, useRef, MouseEvent } from 'react';
import { Select as SelectPrimitive } from '@base-ui-components/react/select';
import { Icon } from '../Icon';
import clsx from 'clsx';
@@ -45,10 +45,27 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>((props, ref) => {
const descriptionId = useId();
const errorId = useId();
const triggerRef = useRef<HTMLButtonElement>(null);
const handleLabelClick = useCallback(
(e: MouseEvent<HTMLLabelElement>) => {
if (!props.disabled && triggerRef.current) {
e.preventDefault();
triggerRef.current.focus();
}
},
[props.disabled],
);
return (
<div className={clsx('canon-Select', className)} style={style} ref={ref}>
{label && (
<label className="canon-SelectLabel" htmlFor={selectId}>
<label
className="canon-SelectLabel"
htmlFor={selectId}
onClick={handleLabelClick}
data-disabled={props.disabled ? true : undefined}
>
{label}
{required && (
<span aria-hidden="true" className="canon-SelectRequired">
@@ -59,6 +76,7 @@ export const Select = forwardRef<HTMLDivElement, SelectProps>((props, ref) => {
)}
<SelectPrimitive.Root {...rest}>
<SelectPrimitive.Trigger
ref={triggerRef}
id={selectId}
className="canon-SelectTrigger"
data-size={responsiveSize}