Pass through a11y props

This commit is contained in:
Eric Bailey
2024-03-05 12:14:40 -06:00
parent 4cdb72f944
commit 076fa9dddd
4 changed files with 28 additions and 26 deletions
+17 -16
View File
@@ -1,7 +1,8 @@
import React from 'react'
import {View, Pressable} from 'react-native'
import {atoms as a, useTheme, ViewStyleProp} from '#/alf'
import {logger} from '#/logger'
import {atoms as a, useTheme} from '#/alf'
import * as Dialog from '#/components/Dialog'
import {useInteractionState} from '#/components/hooks/useInteractionState'
import {Text} from '#/components/Typography'
@@ -9,7 +10,7 @@ import {Text} from '#/components/Typography'
import {Context} from '#/components/Menu/context'
import {
ContextType,
TriggerChildProps,
TriggerProps,
ItemProps,
GroupProps,
ItemTextProps,
@@ -39,11 +40,7 @@ export function Root({
return <Context.Provider value={context}>{children}</Context.Provider>
}
export function Trigger({
children,
}: ViewStyleProp & {
children(props: TriggerChildProps): React.ReactNode
}) {
export function Trigger({children, label}: TriggerProps) {
const {control} = React.useContext(Context)
const {state: focused, onIn: onFocus, onOut: onBlur} = useInteractionState()
const {
@@ -52,11 +49,7 @@ export function Trigger({
onOut: onPressOut,
} = useInteractionState()
if (!control) {
throw new Error('Menu.Trigger must be used within a Menu.Root')
}
return children({
const child = children({
isNative: true,
control,
state: {
@@ -72,15 +65,23 @@ export function Trigger({
onPressOut,
},
})
if (!React.isValidElement(child)) {
logger.error(
'Menu.Trigger children must be a function that returns a valid element',
)
return null
}
return React.cloneElement(child, {
...child.props,
accessibilityLabel: label,
})
}
export function Outer({children}: React.PropsWithChildren<{}>) {
const {control} = React.useContext(Context)
if (!control) {
throw new Error('Menu.Outer must be used within a Menu.Root')
}
return (
<Dialog.Outer control={control}>
<Dialog.Handle />
+6 -9
View File
@@ -4,12 +4,12 @@ import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
import * as Dialog from '#/components/Dialog'
import {useInteractionState} from '#/components/hooks/useInteractionState'
import {atoms as a, useTheme, flatten, web, ViewStyleProp} from '#/alf'
import {atoms as a, useTheme, flatten, web} from '#/alf'
import {Text} from '#/components/Typography'
import {
ContextType,
TriggerChildProps,
TriggerProps,
ItemProps,
GroupProps,
ItemTextProps,
@@ -76,12 +76,7 @@ export function Root({
)
}
export function Trigger({
children,
style,
}: ViewStyleProp & {
children(props: TriggerChildProps): React.ReactNode
}) {
export function Trigger({children, label, style}: TriggerProps) {
const {control} = React.useContext(Context)
const {
state: hovered,
@@ -93,6 +88,8 @@ export function Trigger({
return (
<DropdownMenu.Trigger asChild>
<Pressable
accessibilityHint=""
accessibilityLabel={label}
onFocus={onFocus}
onBlur={onBlur}
style={flatten([style, web({outline: 0})])}
@@ -123,7 +120,7 @@ export function Outer({children}: React.PropsWithChildren<{}>) {
return (
<DropdownMenu.Portal>
<DropdownMenu.Content sideOffset={5} loop>
<DropdownMenu.Content sideOffset={5} loop aria-label="Test">
<View style={[a.rounded_sm, a.p_xs, t.atoms.bg_contrast_50]}>
{children}
</View>
+4
View File
@@ -8,6 +8,10 @@ export type ContextType = {
control: Dialog.DialogOuterProps['control']
}
export type TriggerProps = ViewStyleProp & {
children(props: TriggerChildProps): React.ReactNode
label: string
}
export type TriggerChildProps =
| {
isNative: true
+1 -1
View File
@@ -16,7 +16,7 @@ export function Menus() {
<View style={[a.gap_md]}>
<View style={[a.flex_row, a.align_start]}>
<Menu.Root control={menuControl}>
<Menu.Trigger style={[a.flex_1]}>
<Menu.Trigger label="Open basic menu" style={[a.flex_1]}>
{({state, handlers}) => {
return (
<Text