Expose more methods, support disabled items (#4954)
parent
f235be9819
commit
e54298ec2c
|
@ -1,8 +1,12 @@
|
||||||
import React from 'react'
|
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>({
|
export const Context = React.createContext<ContextType>({
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
control: null,
|
control: null,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const ItemContext = React.createContext<ItemContextType>({
|
||||||
|
disabled: false,
|
||||||
|
})
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {atoms as a, useTheme} from '#/alf'
|
||||||
import {Button, ButtonText} from '#/components/Button'
|
import {Button, ButtonText} from '#/components/Button'
|
||||||
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 {Context} from '#/components/Menu/context'
|
import {Context, ItemContext} from '#/components/Menu/context'
|
||||||
import {
|
import {
|
||||||
ContextType,
|
ContextType,
|
||||||
GroupProps,
|
GroupProps,
|
||||||
|
@ -125,8 +125,14 @@ export function Item({children, label, style, onPress, ...rest}: ItemProps) {
|
||||||
}}
|
}}
|
||||||
onFocus={onFocus}
|
onFocus={onFocus}
|
||||||
onBlur={onBlur}
|
onBlur={onBlur}
|
||||||
onPressIn={onPressIn}
|
onPressIn={e => {
|
||||||
onPressOut={onPressOut}
|
onPressIn()
|
||||||
|
rest.onPressIn?.(e)
|
||||||
|
}}
|
||||||
|
onPressOut={e => {
|
||||||
|
onPressOut()
|
||||||
|
rest.onPressOut?.(e)
|
||||||
|
}}
|
||||||
style={[
|
style={[
|
||||||
a.flex_row,
|
a.flex_row,
|
||||||
a.align_center,
|
a.align_center,
|
||||||
|
@ -138,15 +144,18 @@ export function Item({children, label, style, onPress, ...rest}: ItemProps) {
|
||||||
t.atoms.border_contrast_low,
|
t.atoms.border_contrast_low,
|
||||||
{minHeight: 44, paddingVertical: 10},
|
{minHeight: 44, paddingVertical: 10},
|
||||||
style,
|
style,
|
||||||
(focused || pressed) && [t.atoms.bg_contrast_50],
|
(focused || pressed) && !rest.disabled && [t.atoms.bg_contrast_50],
|
||||||
]}>
|
]}>
|
||||||
|
<ItemContext.Provider value={{disabled: Boolean(rest.disabled)}}>
|
||||||
{children}
|
{children}
|
||||||
|
</ItemContext.Provider>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ItemText({children, style}: ItemTextProps) {
|
export function ItemText({children, style}: ItemTextProps) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
|
const {disabled} = React.useContext(ItemContext)
|
||||||
return (
|
return (
|
||||||
<Text
|
<Text
|
||||||
numberOfLines={1}
|
numberOfLines={1}
|
||||||
|
@ -155,9 +164,10 @@ export function ItemText({children, style}: ItemTextProps) {
|
||||||
a.flex_1,
|
a.flex_1,
|
||||||
a.text_md,
|
a.text_md,
|
||||||
a.font_bold,
|
a.font_bold,
|
||||||
t.atoms.text_contrast_medium,
|
t.atoms.text_contrast_high,
|
||||||
{paddingTop: 3},
|
{paddingTop: 3},
|
||||||
style,
|
style,
|
||||||
|
disabled && t.atoms.text_contrast_low,
|
||||||
]}>
|
]}>
|
||||||
{children}
|
{children}
|
||||||
</Text>
|
</Text>
|
||||||
|
@ -166,7 +176,17 @@ export function ItemText({children, style}: ItemTextProps) {
|
||||||
|
|
||||||
export function ItemIcon({icon: Comp}: ItemIconProps) {
|
export function ItemIcon({icon: Comp}: ItemIconProps) {
|
||||||
const t = useTheme()
|
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) {
|
export function Group({children, style}: GroupProps) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import * as DropdownMenu from '@radix-ui/react-dropdown-menu'
|
||||||
import {atoms as a, flatten, useTheme, web} from '#/alf'
|
import {atoms as a, flatten, useTheme, web} 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 {Context} from '#/components/Menu/context'
|
import {Context, ItemContext} from '#/components/Menu/context'
|
||||||
import {
|
import {
|
||||||
ContextType,
|
ContextType,
|
||||||
GroupProps,
|
GroupProps,
|
||||||
|
@ -239,7 +239,8 @@ export function Item({children, label, onPress, ...rest}: ItemProps) {
|
||||||
a.rounded_xs,
|
a.rounded_xs,
|
||||||
{minHeight: 32, paddingHorizontal: 10},
|
{minHeight: 32, paddingHorizontal: 10},
|
||||||
web({outline: 0}),
|
web({outline: 0}),
|
||||||
(hovered || focused) && [
|
(hovered || focused) &&
|
||||||
|
!rest.disabled && [
|
||||||
web({outline: '0 !important'}),
|
web({outline: '0 !important'}),
|
||||||
t.name === 'light'
|
t.name === 'light'
|
||||||
? t.atoms.bg_contrast_25
|
? t.atoms.bg_contrast_25
|
||||||
|
@ -250,7 +251,9 @@ export function Item({children, label, onPress, ...rest}: ItemProps) {
|
||||||
onMouseEnter,
|
onMouseEnter,
|
||||||
onMouseLeave,
|
onMouseLeave,
|
||||||
})}>
|
})}>
|
||||||
|
<ItemContext.Provider value={{disabled: Boolean(rest.disabled)}}>
|
||||||
{children}
|
{children}
|
||||||
|
</ItemContext.Provider>
|
||||||
</Pressable>
|
</Pressable>
|
||||||
</DropdownMenu.Item>
|
</DropdownMenu.Item>
|
||||||
)
|
)
|
||||||
|
@ -258,8 +261,16 @@ export function Item({children, label, onPress, ...rest}: ItemProps) {
|
||||||
|
|
||||||
export function ItemText({children, style}: ItemTextProps) {
|
export function ItemText({children, style}: ItemTextProps) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
|
const {disabled} = React.useContext(ItemContext)
|
||||||
return (
|
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}
|
{children}
|
||||||
</Text>
|
</Text>
|
||||||
)
|
)
|
||||||
|
@ -267,10 +278,9 @@ export function ItemText({children, style}: ItemTextProps) {
|
||||||
|
|
||||||
export function ItemIcon({icon: Comp, position = 'left'}: ItemIconProps) {
|
export function ItemIcon({icon: Comp, position = 'left'}: ItemIconProps) {
|
||||||
const t = useTheme()
|
const t = useTheme()
|
||||||
|
const {disabled} = React.useContext(ItemContext)
|
||||||
return (
|
return (
|
||||||
<Comp
|
<View
|
||||||
size="md"
|
|
||||||
fill={t.atoms.text_contrast_medium.color}
|
|
||||||
style={[
|
style={[
|
||||||
position === 'left' && {
|
position === 'left' && {
|
||||||
marginLeft: -2,
|
marginLeft: -2,
|
||||||
|
@ -279,8 +289,16 @@ export function ItemIcon({icon: Comp, position = 'left'}: ItemIconProps) {
|
||||||
marginRight: -2,
|
marginRight: -2,
|
||||||
marginLeft: 12,
|
marginLeft: 12,
|
||||||
},
|
},
|
||||||
]}
|
]}>
|
||||||
|
<Comp
|
||||||
|
size="md"
|
||||||
|
fill={
|
||||||
|
disabled
|
||||||
|
? t.atoms.text_contrast_low.color
|
||||||
|
: t.atoms.text_contrast_medium.color
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,22 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {
|
import {
|
||||||
|
AccessibilityProps,
|
||||||
GestureResponderEvent,
|
GestureResponderEvent,
|
||||||
PressableProps,
|
PressableProps,
|
||||||
AccessibilityProps,
|
|
||||||
} from 'react-native'
|
} from 'react-native'
|
||||||
|
|
||||||
import {Props as SVGIconProps} from '#/components/icons/common'
|
|
||||||
import * as Dialog from '#/components/Dialog'
|
|
||||||
import {TextStyleProp, ViewStyleProp} from '#/alf'
|
import {TextStyleProp, ViewStyleProp} from '#/alf'
|
||||||
|
import * as Dialog from '#/components/Dialog'
|
||||||
|
import {Props as SVGIconProps} from '#/components/icons/common'
|
||||||
|
|
||||||
export type ContextType = {
|
export type ContextType = {
|
||||||
control: Dialog.DialogOuterProps['control']
|
control: Dialog.DialogOuterProps['control']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ItemContextType = {
|
||||||
|
disabled: boolean
|
||||||
|
}
|
||||||
|
|
||||||
export type RadixPassThroughTriggerProps = {
|
export type RadixPassThroughTriggerProps = {
|
||||||
id: string
|
id: string
|
||||||
type: 'button'
|
type: 'button'
|
||||||
|
|
Loading…
Reference in New Issue