Expose more methods, support disabled items (#4954)

zio/stable
Eric Bailey 2024-08-19 14:21:29 -05:00 committed by GitHub
parent f235be9819
commit e54298ec2c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 71 additions and 25 deletions

View File

@ -1,8 +1,12 @@
import React from 'react'
import type {ContextType} from '#/components/Menu/types'
import type {ContextType, ItemContextType} from '#/components/Menu/types'
export const Context = React.createContext<ContextType>({
// @ts-ignore
control: null,
})
export const ItemContext = React.createContext<ItemContextType>({
disabled: false,
})

View File

@ -9,7 +9,7 @@ import {atoms as a, useTheme} from '#/alf'
import {Button, ButtonText} from '#/components/Button'
import * as Dialog from '#/components/Dialog'
import {useInteractionState} from '#/components/hooks/useInteractionState'
import {Context} from '#/components/Menu/context'
import {Context, ItemContext} from '#/components/Menu/context'
import {
ContextType,
GroupProps,
@ -125,8 +125,14 @@ export function Item({children, label, style, onPress, ...rest}: ItemProps) {
}}
onFocus={onFocus}
onBlur={onBlur}
onPressIn={onPressIn}
onPressOut={onPressOut}
onPressIn={e => {
onPressIn()
rest.onPressIn?.(e)
}}
onPressOut={e => {
onPressOut()
rest.onPressOut?.(e)
}}
style={[
a.flex_row,
a.align_center,
@ -138,15 +144,18 @@ export function Item({children, label, style, onPress, ...rest}: ItemProps) {
t.atoms.border_contrast_low,
{minHeight: 44, paddingVertical: 10},
style,
(focused || pressed) && [t.atoms.bg_contrast_50],
(focused || pressed) && !rest.disabled && [t.atoms.bg_contrast_50],
]}>
{children}
<ItemContext.Provider value={{disabled: Boolean(rest.disabled)}}>
{children}
</ItemContext.Provider>
</Pressable>
)
}
export function ItemText({children, style}: ItemTextProps) {
const t = useTheme()
const {disabled} = React.useContext(ItemContext)
return (
<Text
numberOfLines={1}
@ -155,9 +164,10 @@ export function ItemText({children, style}: ItemTextProps) {
a.flex_1,
a.text_md,
a.font_bold,
t.atoms.text_contrast_medium,
t.atoms.text_contrast_high,
{paddingTop: 3},
style,
disabled && t.atoms.text_contrast_low,
]}>
{children}
</Text>
@ -166,7 +176,17 @@ export function ItemText({children, style}: ItemTextProps) {
export function ItemIcon({icon: Comp}: ItemIconProps) {
const t = useTheme()
return <Comp size="lg" fill={t.atoms.text_contrast_medium.color} />
const {disabled} = React.useContext(ItemContext)
return (
<Comp
size="lg"
fill={
disabled
? t.atoms.text_contrast_low.color
: t.atoms.text_contrast_medium.color
}
/>
)
}
export function Group({children, style}: GroupProps) {

View File

@ -9,7 +9,7 @@ import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
import {atoms as a, flatten, useTheme, web} from '#/alf'
import * as Dialog from '#/components/Dialog'
import {useInteractionState} from '#/components/hooks/useInteractionState'
import {Context} from '#/components/Menu/context'
import {Context, ItemContext} from '#/components/Menu/context'
import {
ContextType,
GroupProps,
@ -239,18 +239,21 @@ export function Item({children, label, onPress, ...rest}: ItemProps) {
a.rounded_xs,
{minHeight: 32, paddingHorizontal: 10},
web({outline: 0}),
(hovered || focused) && [
web({outline: '0 !important'}),
t.name === 'light'
? t.atoms.bg_contrast_25
: t.atoms.bg_contrast_50,
],
(hovered || focused) &&
!rest.disabled && [
web({outline: '0 !important'}),
t.name === 'light'
? t.atoms.bg_contrast_25
: t.atoms.bg_contrast_50,
],
])}
{...web({
onMouseEnter,
onMouseLeave,
})}>
{children}
<ItemContext.Provider value={{disabled: Boolean(rest.disabled)}}>
{children}
</ItemContext.Provider>
</Pressable>
</DropdownMenu.Item>
)
@ -258,8 +261,16 @@ export function Item({children, label, onPress, ...rest}: ItemProps) {
export function ItemText({children, style}: ItemTextProps) {
const t = useTheme()
const {disabled} = React.useContext(ItemContext)
return (
<Text style={[a.flex_1, a.font_bold, t.atoms.text_contrast_high, style]}>
<Text
style={[
a.flex_1,
a.font_bold,
t.atoms.text_contrast_high,
style,
disabled && t.atoms.text_contrast_low,
]}>
{children}
</Text>
)
@ -267,10 +278,9 @@ export function ItemText({children, style}: ItemTextProps) {
export function ItemIcon({icon: Comp, position = 'left'}: ItemIconProps) {
const t = useTheme()
const {disabled} = React.useContext(ItemContext)
return (
<Comp
size="md"
fill={t.atoms.text_contrast_medium.color}
<View
style={[
position === 'left' && {
marginLeft: -2,
@ -279,8 +289,16 @@ export function ItemIcon({icon: Comp, position = 'left'}: ItemIconProps) {
marginRight: -2,
marginLeft: 12,
},
]}
/>
]}>
<Comp
size="md"
fill={
disabled
? t.atoms.text_contrast_low.color
: t.atoms.text_contrast_medium.color
}
/>
</View>
)
}

View File

@ -1,18 +1,22 @@
import React from 'react'
import {
AccessibilityProps,
GestureResponderEvent,
PressableProps,
AccessibilityProps,
} from 'react-native'
import {Props as SVGIconProps} from '#/components/icons/common'
import * as Dialog from '#/components/Dialog'
import {TextStyleProp, ViewStyleProp} from '#/alf'
import * as Dialog from '#/components/Dialog'
import {Props as SVGIconProps} from '#/components/icons/common'
export type ContextType = {
control: Dialog.DialogOuterProps['control']
}
export type ItemContextType = {
disabled: boolean
}
export type RadixPassThroughTriggerProps = {
id: string
type: 'button'