Bluesky app fork with some witchin' additions 💫
0
fork

Configure Feed

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

Some button updates (#2889)

* Some button updates

* Better name

authored by

Eric Bailey and committed by
GitHub
ae9f8937 1b992d5d

+66 -34
+66 -34
src/components/Button.tsx
··· 27 27 | 'gradient_sunset' 28 28 | 'gradient_nordic' 29 29 | 'gradient_bonfire' 30 - export type ButtonSize = 'small' | 'large' 30 + export type ButtonSize = 'tiny' | 'small' | 'large' 31 31 export type ButtonShape = 'round' | 'square' | 'default' 32 32 export type VariantProps = { 33 33 /** ··· 48 48 shape?: ButtonShape 49 49 } 50 50 51 - export type ButtonProps = React.PropsWithChildren< 52 - Pick<PressableProps, 'disabled' | 'onPress'> & 53 - AccessibilityProps & 54 - VariantProps & { 55 - testID?: string 56 - label: string 57 - style?: StyleProp<ViewStyle> 58 - } 59 - > 60 - export type ButtonTextProps = TextProps & VariantProps & {disabled?: boolean} 51 + export type ButtonState = { 52 + hovered: boolean 53 + focused: boolean 54 + pressed: boolean 55 + disabled: boolean 56 + } 57 + 58 + export type ButtonContext = VariantProps & ButtonState 61 59 62 - const Context = React.createContext< 60 + export type ButtonProps = Pick< 61 + PressableProps, 62 + 'disabled' | 'onPress' | 'testID' 63 + > & 64 + AccessibilityProps & 63 65 VariantProps & { 64 - hovered: boolean 65 - focused: boolean 66 - pressed: boolean 67 - disabled: boolean 66 + testID?: string 67 + label: string 68 + style?: StyleProp<ViewStyle> 69 + children: 70 + | React.ReactNode 71 + | string 72 + | ((context: ButtonContext) => React.ReactNode | string) 68 73 } 69 - >({ 74 + export type ButtonTextProps = TextProps & VariantProps & {disabled?: boolean} 75 + 76 + const Context = React.createContext<VariantProps & ButtonState>({ 70 77 hovered: false, 71 78 focused: false, 72 79 pressed: false, ··· 277 284 baseStyles.push({paddingVertical: 15}, a.px_2xl, a.rounded_sm, a.gap_md) 278 285 } else if (size === 'small') { 279 286 baseStyles.push({paddingVertical: 9}, a.px_lg, a.rounded_sm, a.gap_sm) 287 + } else if (size === 'tiny') { 288 + baseStyles.push({paddingVertical: 4}, a.px_sm, a.rounded_xs, a.gap_xs) 280 289 } 281 290 } else if (shape === 'round' || shape === 'square') { 282 291 if (size === 'large') { ··· 287 296 } 288 297 } else if (size === 'small') { 289 298 baseStyles.push({height: 40, width: 40}) 299 + } else if (size === 'tiny') { 300 + baseStyles.push({height: 20, width: 20}) 290 301 } 291 302 292 303 if (shape === 'round') { 293 304 baseStyles.push(a.rounded_full) 294 305 } else if (shape === 'square') { 295 - baseStyles.push(a.rounded_sm) 306 + if (size === 'tiny') { 307 + baseStyles.push(a.rounded_xs) 308 + } else { 309 + baseStyles.push(a.rounded_sm) 310 + } 296 311 } 297 312 } 298 313 ··· 338 353 } 339 354 }, [variant, color]) 340 355 341 - const context = React.useMemo( 356 + const context = React.useMemo<ButtonContext>( 342 357 () => ({ 343 358 ...state, 344 359 variant, ··· 349 364 [state, variant, color, size, disabled], 350 365 ) 351 366 367 + const flattenedBaseStyles = flatten(baseStyles) 368 + 352 369 return ( 353 370 <Pressable 354 371 role="button" ··· 362 379 disabled: disabled || false, 363 380 }} 364 381 style={[ 365 - flatten(style), 366 382 a.flex_row, 367 383 a.align_center, 368 384 a.justify_center, 369 - a.overflow_hidden, 370 385 a.justify_center, 371 - ...baseStyles, 386 + flattenedBaseStyles, 372 387 ...(state.hovered || state.pressed ? hoverStyles : []), 373 388 ...(state.focused ? focusStyles : []), 389 + flatten(style), 374 390 ]} 375 391 onPressIn={onPressIn} 376 392 onPressOut={onPressOut} ··· 379 395 onFocus={onFocus} 380 396 onBlur={onBlur}> 381 397 {variant === 'gradient' && ( 382 - <LinearGradient 383 - colors={ 384 - state.hovered || state.pressed || state.focused 385 - ? gradientHoverColors 386 - : gradientColors 387 - } 388 - locations={gradientLocations} 389 - start={{x: 0, y: 0}} 390 - end={{x: 1, y: 1}} 391 - style={[a.absolute, a.inset_0]} 392 - /> 398 + <View 399 + style={[ 400 + a.absolute, 401 + a.inset_0, 402 + a.overflow_hidden, 403 + {borderRadius: flattenedBaseStyles.borderRadius}, 404 + ]}> 405 + <LinearGradient 406 + colors={ 407 + state.hovered || state.pressed || state.focused 408 + ? gradientHoverColors 409 + : gradientColors 410 + } 411 + locations={gradientLocations} 412 + start={{x: 0, y: 0}} 413 + end={{x: 1, y: 1}} 414 + style={[a.absolute, a.inset_0]} 415 + /> 416 + </View> 393 417 )} 394 418 <Context.Provider value={context}> 395 419 {typeof children === 'string' ? ( 396 420 <ButtonText>{children}</ButtonText> 421 + ) : typeof children === 'function' ? ( 422 + children(context) 397 423 ) : ( 398 424 children 399 425 )} ··· 493 519 494 520 if (size === 'large') { 495 521 baseStyles.push(a.text_md, android({paddingBottom: 1})) 522 + } else if (size === 'tiny') { 523 + baseStyles.push(a.text_xs, android({paddingBottom: 1})) 496 524 } else { 497 525 baseStyles.push(a.text_sm, android({paddingBottom: 1})) 498 526 } ··· 514 542 export function ButtonIcon({ 515 543 icon: Comp, 516 544 position, 545 + size: iconSize, 517 546 }: { 518 547 icon: React.ComponentType<SVGIconProps> 519 548 position?: 'left' | 'right' 549 + size?: SVGIconProps['size'] 520 550 }) { 521 551 const {size, disabled} = useButtonContext() 522 552 const textStyles = useSharedButtonTextStyles() ··· 532 562 }, 533 563 ]}> 534 564 <Comp 535 - size={size === 'large' ? 'md' : 'sm'} 565 + size={ 566 + iconSize ?? (size === 'large' ? 'md' : size === 'tiny' ? 'xs' : 'sm') 567 + } 536 568 style={[{color: textStyles.color, pointerEvents: 'none'}]} 537 569 /> 538 570 </View>