about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/Menu/context.tsx6
-rw-r--r--src/components/Menu/index.tsx34
-rw-r--r--src/components/Menu/index.web.tsx46
-rw-r--r--src/components/Menu/types.ts10
4 files changed, 71 insertions, 25 deletions
diff --git a/src/components/Menu/context.tsx b/src/components/Menu/context.tsx
index 9fc91f681..1ddcd583f 100644
--- a/src/components/Menu/context.tsx
+++ b/src/components/Menu/context.tsx
@@ -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,
+})
diff --git a/src/components/Menu/index.tsx b/src/components/Menu/index.tsx
index 3be69b348..a0a21a50f 100644
--- a/src/components/Menu/index.tsx
+++ b/src/components/Menu/index.tsx
@@ -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) {
diff --git a/src/components/Menu/index.web.tsx b/src/components/Menu/index.web.tsx
index 031250dde..6d2f5e941 100644
--- a/src/components/Menu/index.web.tsx
+++ b/src/components/Menu/index.web.tsx
@@ -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>
   )
 }
 
diff --git a/src/components/Menu/types.ts b/src/components/Menu/types.ts
index e710971ee..2f7aea5de 100644
--- a/src/components/Menu/types.ts
+++ b/src/components/Menu/types.ts
@@ -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'