Skip to content

Commit

Permalink
fix: refactor visionos_hoverStyle to take a string and new arch support
Browse files Browse the repository at this point in the history
  • Loading branch information
okwasniewski committed Oct 15, 2023
1 parent 9fd0e8a commit de9662a
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ import useAndroidRippleForView, {
import * as React from 'react';
import {useImperativeHandle, useMemo, useRef, useState} from 'react';

const defaultHoverStyle: HoverStyle = {
effectType: 'automatic',
};
const defaultHoverStyle: HoverStyle = 'highlight';

type ViewStyleProp = $ElementType<React.ElementConfig<typeof View>, 'style'>;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ import flattenStyle from '../../StyleSheet/flattenStyle';
import Platform from '../../Utilities/Platform';
import * as React from 'react';

const defaultHoverStyle: HoverStyle = {
effectType: 'automatic',
};
const defaultHoverStyle: HoverStyle = 'highlight';

type TVProps = $ReadOnly<{|
hasTVPreferredFocus?: ?boolean,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,7 @@ import {LayoutChangeEvent, PointerEvents} from '../../Types/CoreEventTypes';
import {Touchable} from '../Touchable/Touchable';
import {AccessibilityProps} from './ViewAccessibility';

export type HoverStyle = {
/**
* If true the hover effect is enabled. Defaults to true.
*/
enabled: boolean;
/**
* Hover effect type to apply to the view.
*/
effectType: 'automatic' | 'lift' | 'highlight';
/**
* Corner radius of the hover effect.
*/
cornerRadius?: number | undefined;
};
export type HoverStyle = 'lift' | 'highlight';

export type TVParallaxProperties = {
/**
Expand Down
15 changes: 1 addition & 14 deletions packages/react-native/Libraries/Components/View/ViewPropTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -263,20 +263,7 @@ type AndroidDrawableRipple = $ReadOnly<{|
rippleRadius?: ?number,
|}>;

export type HoverStyle = $ReadOnly<{|
/**
* If true the hover effect is enabled. Defaults to true.
*/
enabled?: ?boolean,
/**
* Hover effect type to apply to the view.
*/
effectType: 'automatic' | 'lift' | 'highlight',
/**
* Corner radius of the hover effect.
*/
cornerRadius?: ?number,
|}>;
export type HoverStyle = 'lift' | 'highlight';

type AndroidDrawable = AndroidDrawableThemeAttr | AndroidDrawableRipple;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,12 @@ - (void)updateProps:(const Props::Shared &)props oldProps:(const Props::Shared &
oldViewProps.borderColors != newViewProps.borderColors) {
needsInvalidateLayer = YES;
}

#if TARGET_OS_VISION
if (oldViewProps.visionos_hoverStyle != newViewProps.visionos_hoverStyle) {
[self updateHoverStyleProp:[NSString stringWithUTF8String:newViewProps.visionos_hoverStyle.c_str()]];
}
#endif

// `nativeId`
if (oldViewProps.nativeId != newViewProps.nativeId) {
Expand Down Expand Up @@ -513,6 +519,28 @@ - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
}
}

#if TARGET_OS_VISION
- (void) updateHoverStyleProp:(NSString*)hoverStyle {
if (hoverStyle == nil || [hoverStyle isEqualToString:@""]) {
self.hoverStyle = nil;
return;
}

UIShape *shape = [UIShape rectShapeWithCornerRadius:self.layer.cornerRadius];
id<UIHoverEffect> hoverEffect;

if ([hoverStyle isEqualToString:@"lift"]) {
hoverEffect = [UIHoverLiftEffect effect];
} else if ([hoverStyle isEqualToString:@"highlight"]) {
hoverEffect = [UIHoverHighlightEffect effect];
}

if (hoverEffect != nil) {
self.hoverStyle = [UIHoverStyle styleWithEffect:hoverEffect shape:shape];
}
}
#endif

static RCTCornerRadii RCTCornerRadiiFromBorderRadii(BorderRadii borderRadii)
{
return RCTCornerRadii{
Expand Down
2 changes: 1 addition & 1 deletion packages/react-native/React/Views/RCTView.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ extern const UIAccessibilityTraits SwitchAccessibilityTrait;
/**
* The hover style to apply to a view, including an effect and a shape to use for displaying that effect.
*/
@property (nonatomic, copy) NSDictionary *hoverStyleProperties;
@property (nonatomic, copy) NSString *hoverStyleEffect;
#endif

/**
Expand Down
25 changes: 9 additions & 16 deletions packages/react-native/React/Views/RCTView.m
Original file line number Diff line number Diff line change
Expand Up @@ -668,33 +668,26 @@ - (UIEdgeInsets)bordersAsInsets


#if TARGET_OS_VISION
- (void)setHoverStyleProperties:(NSDictionary *)hoverStyleProperties {
_hoverStyleProperties = hoverStyleProperties;
- (void)setHoverStyleEffect:(NSString *)hoverStyleEffect {
_hoverStyleEffect = hoverStyleEffect;

BOOL enabled = _hoverStyleProperties[@"enabled"] != nil ? [_hoverStyleProperties[@"enabled"] boolValue] : YES;

if (!enabled || hoverStyleProperties == nil) {
if (hoverStyleEffect == nil) {
self.hoverStyle = nil;
return;
}

NSString *effectType = (NSString *)[_hoverStyleProperties objectForKey:@"effectType"];
NSNumber *cornerRadius = (NSNumber *)[_hoverStyleProperties objectForKey:@"cornerRadius"];

float cornerRadiusFloat = [cornerRadius floatValue];

UIShape *shape = [UIShape rectShapeWithCornerRadius:cornerRadiusFloat];
UIShape *shape = [UIShape rectShapeWithCornerRadius:_borderRadius];
id<UIHoverEffect> hoverEffect;

if ([effectType isEqualToString:@"lift"]) {
if ([hoverStyleEffect isEqualToString:@"lift"]) {
hoverEffect = [UIHoverLiftEffect effect];
} else if ([effectType isEqualToString:@"highlight"]) {
} else if ([hoverStyleEffect isEqualToString:@"highlight"]) {
hoverEffect = [UIHoverHighlightEffect effect];
} else if ([effectType isEqualToString:@"automatic"]) {
hoverEffect = [UIHoverAutomaticEffect effect];
}

self.hoverStyle = [UIHoverStyle styleWithEffect:hoverEffect shape:shape];
if (hoverEffect != nil) {
self.hoverStyle = [UIHoverStyle styleWithEffect:hoverEffect shape:shape];
}
}
#endif

Expand Down
2 changes: 1 addition & 1 deletion packages/react-native/React/Views/RCTViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ - (RCTShadowView *)shadowView
RCT_REMAP_VIEW_PROPERTY(testID, reactAccessibilityElement.accessibilityIdentifier, NSString)

RCT_EXPORT_VIEW_PROPERTY(backgroundColor, UIColor)
RCT_REMAP_VISIONOS_VIEW_PROPERTY(visionos_hoverStyle, hoverStyleProperties, NSDictionary)
RCT_REMAP_VISIONOS_VIEW_PROPERTY(visionos_hoverStyle, hoverStyleEffect, NSString)
RCT_REMAP_VIEW_PROPERTY(backfaceVisibility, layer.doubleSided, css_backface_visibility_t)
RCT_REMAP_VIEW_PROPERTY(opacity, alpha, CGFloat)
RCT_REMAP_VIEW_PROPERTY(shadowColor, layer.shadowColor, CGColor)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,17 @@ BaseViewProps::BaseViewProps(
"backgroundColor",
sourceProps.backgroundColor,
{})),
#if TARGET_OS_VISION
visionos_hoverStyle(
CoreFeatures::enablePropIteratorSetter
? sourceProps.visionos_hoverStyle
: convertRawProp(
context,
rawProps,
"visionos_hoverStyle",
sourceProps.visionos_hoverStyle,
{})),
#endif
borderRadii(
CoreFeatures::enablePropIteratorSetter ? sourceProps.borderRadii
: convertRawProp(
Expand Down Expand Up @@ -281,6 +292,9 @@ void BaseViewProps::setProp(
RAW_SET_PROP_SWITCH_CASE_BASIC(collapsable);
RAW_SET_PROP_SWITCH_CASE_BASIC(removeClippedSubviews);
RAW_SET_PROP_SWITCH_CASE_BASIC(experimental_layoutConformance);
#if TARGET_OS_VISION
RAW_SET_PROP_SWITCH_CASE_BASIC(visionos_hoverStyle);
#endif
// events field
VIEW_EVENT_CASE(PointerEnter);
VIEW_EVENT_CASE(PointerEnterCapture);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ class BaseViewProps : public YogaStylableProps, public AccessibilityProps {
PointerEventsMode pointerEvents{};
EdgeInsets hitSlop{};
bool onLayout{};

#if TARGET_OS_VISION
std::string visionos_hoverStyle{};
#endif

ViewEvents events{};

Expand Down

0 comments on commit de9662a

Please sign in to comment.