Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Expose more methods, support disabled items (#4954)

authored by

Eric Bailey and committed by
GitHub
e54298ec f235be98

+71 -25
+5 -1
src/components/Menu/context.tsx
··· 1 1 import React from 'react' 2 2 3 - import type {ContextType} from '#/components/Menu/types' 3 + import type {ContextType, ItemContextType} from '#/components/Menu/types' 4 4 5 5 export const Context = React.createContext<ContextType>({ 6 6 // @ts-ignore 7 7 control: null, 8 8 }) 9 + 10 + export const ItemContext = React.createContext<ItemContextType>({ 11 + disabled: false, 12 + })
+27 -7
src/components/Menu/index.tsx
··· 9 9 import {Button, ButtonText} from '#/components/Button' 10 10 import * as Dialog from '#/components/Dialog' 11 11 import {useInteractionState} from '#/components/hooks/useInteractionState' 12 - import {Context} from '#/components/Menu/context' 12 + import {Context, ItemContext} from '#/components/Menu/context' 13 13 import { 14 14 ContextType, 15 15 GroupProps, ··· 125 125 }} 126 126 onFocus={onFocus} 127 127 onBlur={onBlur} 128 - onPressIn={onPressIn} 129 - onPressOut={onPressOut} 128 + onPressIn={e => { 129 + onPressIn() 130 + rest.onPressIn?.(e) 131 + }} 132 + onPressOut={e => { 133 + onPressOut() 134 + rest.onPressOut?.(e) 135 + }} 130 136 style={[ 131 137 a.flex_row, 132 138 a.align_center, ··· 138 144 t.atoms.border_contrast_low, 139 145 {minHeight: 44, paddingVertical: 10}, 140 146 style, 141 - (focused || pressed) && [t.atoms.bg_contrast_50], 147 + (focused || pressed) && !rest.disabled && [t.atoms.bg_contrast_50], 142 148 ]}> 143 - {children} 149 + <ItemContext.Provider value={{disabled: Boolean(rest.disabled)}}> 150 + {children} 151 + </ItemContext.Provider> 144 152 </Pressable> 145 153 ) 146 154 } 147 155 148 156 export function ItemText({children, style}: ItemTextProps) { 149 157 const t = useTheme() 158 + const {disabled} = React.useContext(ItemContext) 150 159 return ( 151 160 <Text 152 161 numberOfLines={1} ··· 155 164 a.flex_1, 156 165 a.text_md, 157 166 a.font_bold, 158 - t.atoms.text_contrast_medium, 167 + t.atoms.text_contrast_high, 159 168 {paddingTop: 3}, 160 169 style, 170 + disabled && t.atoms.text_contrast_low, 161 171 ]}> 162 172 {children} 163 173 </Text> ··· 166 176 167 177 export function ItemIcon({icon: Comp}: ItemIconProps) { 168 178 const t = useTheme() 169 - return <Comp size="lg" fill={t.atoms.text_contrast_medium.color} /> 179 + const {disabled} = React.useContext(ItemContext) 180 + return ( 181 + <Comp 182 + size="lg" 183 + fill={ 184 + disabled 185 + ? t.atoms.text_contrast_low.color 186 + : t.atoms.text_contrast_medium.color 187 + } 188 + /> 189 + ) 170 190 } 171 191 172 192 export function Group({children, style}: GroupProps) {
+32 -14
src/components/Menu/index.web.tsx
··· 9 9 import {atoms as a, flatten, useTheme, web} from '#/alf' 10 10 import * as Dialog from '#/components/Dialog' 11 11 import {useInteractionState} from '#/components/hooks/useInteractionState' 12 - import {Context} from '#/components/Menu/context' 12 + import {Context, ItemContext} from '#/components/Menu/context' 13 13 import { 14 14 ContextType, 15 15 GroupProps, ··· 239 239 a.rounded_xs, 240 240 {minHeight: 32, paddingHorizontal: 10}, 241 241 web({outline: 0}), 242 - (hovered || focused) && [ 243 - web({outline: '0 !important'}), 244 - t.name === 'light' 245 - ? t.atoms.bg_contrast_25 246 - : t.atoms.bg_contrast_50, 247 - ], 242 + (hovered || focused) && 243 + !rest.disabled && [ 244 + web({outline: '0 !important'}), 245 + t.name === 'light' 246 + ? t.atoms.bg_contrast_25 247 + : t.atoms.bg_contrast_50, 248 + ], 248 249 ])} 249 250 {...web({ 250 251 onMouseEnter, 251 252 onMouseLeave, 252 253 })}> 253 - {children} 254 + <ItemContext.Provider value={{disabled: Boolean(rest.disabled)}}> 255 + {children} 256 + </ItemContext.Provider> 254 257 </Pressable> 255 258 </DropdownMenu.Item> 256 259 ) ··· 258 261 259 262 export function ItemText({children, style}: ItemTextProps) { 260 263 const t = useTheme() 264 + const {disabled} = React.useContext(ItemContext) 261 265 return ( 262 - <Text style={[a.flex_1, a.font_bold, t.atoms.text_contrast_high, style]}> 266 + <Text 267 + style={[ 268 + a.flex_1, 269 + a.font_bold, 270 + t.atoms.text_contrast_high, 271 + style, 272 + disabled && t.atoms.text_contrast_low, 273 + ]}> 263 274 {children} 264 275 </Text> 265 276 ) ··· 267 278 268 279 export function ItemIcon({icon: Comp, position = 'left'}: ItemIconProps) { 269 280 const t = useTheme() 281 + const {disabled} = React.useContext(ItemContext) 270 282 return ( 271 - <Comp 272 - size="md" 273 - fill={t.atoms.text_contrast_medium.color} 283 + <View 274 284 style={[ 275 285 position === 'left' && { 276 286 marginLeft: -2, ··· 279 289 marginRight: -2, 280 290 marginLeft: 12, 281 291 }, 282 - ]} 283 - /> 292 + ]}> 293 + <Comp 294 + size="md" 295 + fill={ 296 + disabled 297 + ? t.atoms.text_contrast_low.color 298 + : t.atoms.text_contrast_medium.color 299 + } 300 + /> 301 + </View> 284 302 ) 285 303 } 286 304
+7 -3
src/components/Menu/types.ts
··· 1 1 import React from 'react' 2 2 import { 3 + AccessibilityProps, 3 4 GestureResponderEvent, 4 5 PressableProps, 5 - AccessibilityProps, 6 6 } from 'react-native' 7 7 8 - import {Props as SVGIconProps} from '#/components/icons/common' 8 + import {TextStyleProp, ViewStyleProp} from '#/alf' 9 9 import * as Dialog from '#/components/Dialog' 10 - import {TextStyleProp, ViewStyleProp} from '#/alf' 10 + import {Props as SVGIconProps} from '#/components/icons/common' 11 11 12 12 export type ContextType = { 13 13 control: Dialog.DialogOuterProps['control'] 14 + } 15 + 16 + export type ItemContextType = { 17 + disabled: boolean 14 18 } 15 19 16 20 export type RadixPassThroughTriggerProps = {