Pass through a11y props
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {View, Pressable} from 'react-native'
|
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 * as Dialog from '#/components/Dialog'
|
||||||
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
||||||
import {Text} from '#/components/Typography'
|
import {Text} from '#/components/Typography'
|
||||||
@@ -9,7 +10,7 @@ import {Text} from '#/components/Typography'
|
|||||||
import {Context} from '#/components/Menu/context'
|
import {Context} from '#/components/Menu/context'
|
||||||
import {
|
import {
|
||||||
ContextType,
|
ContextType,
|
||||||
TriggerChildProps,
|
TriggerProps,
|
||||||
ItemProps,
|
ItemProps,
|
||||||
GroupProps,
|
GroupProps,
|
||||||
ItemTextProps,
|
ItemTextProps,
|
||||||
@@ -39,11 +40,7 @@ export function Root({
|
|||||||
return <Context.Provider value={context}>{children}</Context.Provider>
|
return <Context.Provider value={context}>{children}</Context.Provider>
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Trigger({
|
export function Trigger({children, label}: TriggerProps) {
|
||||||
children,
|
|
||||||
}: ViewStyleProp & {
|
|
||||||
children(props: TriggerChildProps): React.ReactNode
|
|
||||||
}) {
|
|
||||||
const {control} = React.useContext(Context)
|
const {control} = React.useContext(Context)
|
||||||
const {state: focused, onIn: onFocus, onOut: onBlur} = useInteractionState()
|
const {state: focused, onIn: onFocus, onOut: onBlur} = useInteractionState()
|
||||||
const {
|
const {
|
||||||
@@ -52,11 +49,7 @@ export function Trigger({
|
|||||||
onOut: onPressOut,
|
onOut: onPressOut,
|
||||||
} = useInteractionState()
|
} = useInteractionState()
|
||||||
|
|
||||||
if (!control) {
|
const child = children({
|
||||||
throw new Error('Menu.Trigger must be used within a Menu.Root')
|
|
||||||
}
|
|
||||||
|
|
||||||
return children({
|
|
||||||
isNative: true,
|
isNative: true,
|
||||||
control,
|
control,
|
||||||
state: {
|
state: {
|
||||||
@@ -72,15 +65,23 @@ export function Trigger({
|
|||||||
onPressOut,
|
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<{}>) {
|
export function Outer({children}: React.PropsWithChildren<{}>) {
|
||||||
const {control} = React.useContext(Context)
|
const {control} = React.useContext(Context)
|
||||||
|
|
||||||
if (!control) {
|
|
||||||
throw new Error('Menu.Outer must be used within a Menu.Root')
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog.Outer control={control}>
|
<Dialog.Outer control={control}>
|
||||||
<Dialog.Handle />
|
<Dialog.Handle />
|
||||||
|
|||||||
@@ -4,12 +4,12 @@ import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
|||||||
|
|
||||||
import * as Dialog from '#/components/Dialog'
|
import * as Dialog from '#/components/Dialog'
|
||||||
import {useInteractionState} from '#/components/hooks/useInteractionState'
|
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 {Text} from '#/components/Typography'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ContextType,
|
ContextType,
|
||||||
TriggerChildProps,
|
TriggerProps,
|
||||||
ItemProps,
|
ItemProps,
|
||||||
GroupProps,
|
GroupProps,
|
||||||
ItemTextProps,
|
ItemTextProps,
|
||||||
@@ -76,12 +76,7 @@ export function Root({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Trigger({
|
export function Trigger({children, label, style}: TriggerProps) {
|
||||||
children,
|
|
||||||
style,
|
|
||||||
}: ViewStyleProp & {
|
|
||||||
children(props: TriggerChildProps): React.ReactNode
|
|
||||||
}) {
|
|
||||||
const {control} = React.useContext(Context)
|
const {control} = React.useContext(Context)
|
||||||
const {
|
const {
|
||||||
state: hovered,
|
state: hovered,
|
||||||
@@ -93,6 +88,8 @@ export function Trigger({
|
|||||||
return (
|
return (
|
||||||
<DropdownMenu.Trigger asChild>
|
<DropdownMenu.Trigger asChild>
|
||||||
<Pressable
|
<Pressable
|
||||||
|
accessibilityHint=""
|
||||||
|
accessibilityLabel={label}
|
||||||
onFocus={onFocus}
|
onFocus={onFocus}
|
||||||
onBlur={onBlur}
|
onBlur={onBlur}
|
||||||
style={flatten([style, web({outline: 0})])}
|
style={flatten([style, web({outline: 0})])}
|
||||||
@@ -123,7 +120,7 @@ export function Outer({children}: React.PropsWithChildren<{}>) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenu.Portal>
|
<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]}>
|
<View style={[a.rounded_sm, a.p_xs, t.atoms.bg_contrast_50]}>
|
||||||
{children}
|
{children}
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ export type ContextType = {
|
|||||||
control: Dialog.DialogOuterProps['control']
|
control: Dialog.DialogOuterProps['control']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type TriggerProps = ViewStyleProp & {
|
||||||
|
children(props: TriggerChildProps): React.ReactNode
|
||||||
|
label: string
|
||||||
|
}
|
||||||
export type TriggerChildProps =
|
export type TriggerChildProps =
|
||||||
| {
|
| {
|
||||||
isNative: true
|
isNative: true
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export function Menus() {
|
|||||||
<View style={[a.gap_md]}>
|
<View style={[a.gap_md]}>
|
||||||
<View style={[a.flex_row, a.align_start]}>
|
<View style={[a.flex_row, a.align_start]}>
|
||||||
<Menu.Root control={menuControl}>
|
<Menu.Root control={menuControl}>
|
||||||
<Menu.Trigger style={[a.flex_1]}>
|
<Menu.Trigger label="Open basic menu" style={[a.flex_1]}>
|
||||||
{({state, handlers}) => {
|
{({state, handlers}) => {
|
||||||
return (
|
return (
|
||||||
<Text
|
<Text
|
||||||
|
|||||||
Reference in New Issue
Block a user