react-native-windows 0.76.0-preview.2 → 0.76.0-preview.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/Libraries/Components/AccessibilityInfo/AccessibilityInfo.windows.js +15 -15
  2. package/Libraries/Components/Button.windows.js +18 -18
  3. package/Libraries/Components/Flyout/FlyoutNativeComponent.js +5 -1
  4. package/Libraries/Components/Keyboard/KeyboardExt.js +1 -1
  5. package/Libraries/Components/Keyboard/KeyboardExt.js.map +1 -1
  6. package/Libraries/Components/TextInput/TextInput.windows.js +16 -11
  7. package/Libraries/Components/Touchable/Touchable.windows.js +2 -2
  8. package/Libraries/Components/Touchable/TouchableWithoutFeedback.windows.js +5 -3
  9. package/Libraries/Components/View/View.windows.js +1 -3
  10. package/Libraries/Core/ReactNativeVersion.js +1 -1
  11. package/Libraries/Text/Text.windows.js +13 -9
  12. package/Libraries/Utilities/Platform.windows.js +4 -4
  13. package/Microsoft.ReactNative/Fabric/ComponentView.cpp +12 -0
  14. package/Microsoft.ReactNative/Fabric/ComponentView.h +3 -0
  15. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +66 -0
  16. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +8 -2
  17. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +24 -0
  18. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +2 -0
  19. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +8 -3
  20. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +1 -0
  21. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +11 -0
  22. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +2 -0
  23. package/Microsoft.ReactNative/Fabric/Composition/TextDrawing.cpp +1 -2
  24. package/Microsoft.ReactNative/Fabric/Composition/TextDrawing.h +1 -1
  25. package/Microsoft.ReactNative/Fabric/Composition/Theme.cpp +12 -4
  26. package/Microsoft.ReactNative/Fabric/Composition/TooltipService.cpp +338 -0
  27. package/Microsoft.ReactNative/Fabric/Composition/TooltipService.h +66 -0
  28. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +8 -0
  29. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +1 -0
  30. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +3 -0
  31. package/Microsoft.ReactNative/Fabric/ReactTaggedView.h +4 -0
  32. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.cpp +5 -0
  33. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.h +1 -1
  34. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewTraitsInitializer.h +1 -1
  35. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +1 -1
  36. package/Microsoft.ReactNative/ReactCoreInjection.h +0 -1
  37. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +15 -4
  38. package/Microsoft.ReactNative/ReactNativeAppBuilder.cpp +25 -129
  39. package/Microsoft.ReactNative/ReactNativeAppBuilder.h +5 -13
  40. package/Microsoft.ReactNative/ReactNativeAppBuilder.idl +13 -34
  41. package/Microsoft.ReactNative/ReactNativeWin32App.cpp +129 -18
  42. package/Microsoft.ReactNative/ReactNativeWin32App.h +14 -5
  43. package/PropertySheets/External/Microsoft.ReactNative.CppLib.props +17 -0
  44. package/PropertySheets/External/Microsoft.ReactNative.CppLib.targets +17 -0
  45. package/PropertySheets/Generated/PackageVersion.g.props +2 -2
  46. package/PropertySheets/WebView2.props +7 -0
  47. package/PropertySheets/WinUI.props +1 -1
  48. package/Shared/Shared.vcxitems +3 -10
  49. package/Shared/Shared.vcxitems.filters +1 -0
  50. package/just-task.js +1 -1
  51. package/package.json +15 -16
  52. package/templates/cpp-app/template.config.js +8 -3
  53. package/templates/cpp-app/windows/MyApp/MyApp.cpp +46 -131
  54. package/templates/cpp-lib/template.config.js +8 -3
  55. package/templates/cpp-lib/windows/MyLib/MyLib.vcxproj +4 -4
  56. package/templates/templateUtils.js +2 -3
  57. package/Microsoft.ReactNative/ReactInstanceSettingsBuilder.cpp +0 -59
  58. package/Microsoft.ReactNative/ReactInstanceSettingsBuilder.h +0 -23
@@ -55,21 +55,21 @@ const EventNames: Map<
55
55
  ['accessibilityServiceChanged', 'accessibilityServiceDidChange'],
56
56
  ])
57
57
  : Platform.OS === 'windows'
58
- ? new Map([
59
- ['change', 'TOUCH_EXPLORATION_EVENT'],
60
- ['reduceMotionChanged', 'REDUCE_MOTION_EVENT'],
61
- ['screenReaderChanged', 'TOUCH_EXPLORATION_EVENT'],
62
- ])
63
- : new Map([
64
- ['announcementFinished', 'announcementFinished'],
65
- ['boldTextChanged', 'boldTextChanged'],
66
- ['change', 'screenReaderChanged'],
67
- ['grayscaleChanged', 'grayscaleChanged'],
68
- ['invertColorsChanged', 'invertColorsChanged'],
69
- ['reduceMotionChanged', 'reduceMotionChanged'],
70
- ['reduceTransparencyChanged', 'reduceTransparencyChanged'],
71
- ['screenReaderChanged', 'screenReaderChanged'],
72
- ]);
58
+ ? new Map([
59
+ ['change', 'TOUCH_EXPLORATION_EVENT'],
60
+ ['reduceMotionChanged', 'REDUCE_MOTION_EVENT'],
61
+ ['screenReaderChanged', 'TOUCH_EXPLORATION_EVENT'],
62
+ ])
63
+ : new Map([
64
+ ['announcementFinished', 'announcementFinished'],
65
+ ['boldTextChanged', 'boldTextChanged'],
66
+ ['change', 'screenReaderChanged'],
67
+ ['grayscaleChanged', 'grayscaleChanged'],
68
+ ['invertColorsChanged', 'invertColorsChanged'],
69
+ ['reduceMotionChanged', 'reduceMotionChanged'],
70
+ ['reduceTransparencyChanged', 'reduceTransparencyChanged'],
71
+ ['screenReaderChanged', 'screenReaderChanged'],
72
+ ]);
73
73
 
74
74
  /**
75
75
  * Sometimes it's useful to know whether or not the device has a screen reader
@@ -407,10 +407,10 @@ const Button: React.AbstractComponent<
407
407
  color
408
408
  ? {borderRadius: 3}
409
409
  : pressed
410
- ? [buttonStyles, styles.buttonPressed]
411
- : hover
412
- ? [buttonStyles, styles.buttonHover]
413
- : buttonStyles
410
+ ? [buttonStyles, styles.buttonPressed]
411
+ : hover
412
+ ? [buttonStyles, styles.buttonHover]
413
+ : buttonStyles
414
414
  }
415
415
  onMouseEnter={() => {
416
416
  if (!disabled) setHover(true);
@@ -445,20 +445,20 @@ const Button: React.AbstractComponent<
445
445
  color
446
446
  ? textStyles
447
447
  : pressed
448
- ? [
449
- textStyles,
450
- {
451
- color: PlatformColor('ButtonForegroundPressed'),
452
- },
453
- ]
454
- : hover
455
- ? [
456
- textStyles,
457
- {
458
- color: PlatformColor('ButtonForegroundPointerOver'),
459
- },
460
- ]
461
- : textStyles
448
+ ? [
449
+ textStyles,
450
+ {
451
+ color: PlatformColor('ButtonForegroundPressed'),
452
+ },
453
+ ]
454
+ : hover
455
+ ? [
456
+ textStyles,
457
+ {
458
+ color: PlatformColor('ButtonForegroundPointerOver'),
459
+ },
460
+ ]
461
+ : textStyles
462
462
  }
463
463
  disabled={disabled}>
464
464
  {formattedTitle}
@@ -7,7 +7,11 @@
7
7
 
8
8
  import type {ViewProps} from 'react-native/Libraries/Components/View/ViewPropTypes';
9
9
  import type {HostComponent} from 'react-native/Libraries/Renderer/shims/ReactNativeTypes';
10
- import type {DirectEventHandler, Double, Int32} from 'react-native/Libraries/Types/CodegenTypes';
10
+ import type {
11
+ DirectEventHandler,
12
+ Double,
13
+ Int32,
14
+ } from 'react-native/Libraries/Types/CodegenTypes';
11
15
 
12
16
  import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
13
17
 
@@ -17,7 +17,7 @@ const supportKeyboard = (WrappedComponent) => {
17
17
  class SupportKeyboard extends react_1.default.Component {
18
18
  render() {
19
19
  const { forwardedRef, ...rest } = this.props;
20
- return react_1.default.createElement(WrappedComponent, { ref: forwardedRef, ...rest });
20
+ return (react_1.default.createElement(WrappedComponent, { ref: forwardedRef, ...rest }));
21
21
  }
22
22
  }
23
23
  return react_1.default.forwardRef((props, ref) => {
@@ -1 +1 @@
1
- {"version":3,"file":"KeyboardExt.js","sourceRoot":"","sources":["../../../src-win/Libraries/Components/Keyboard/KeyboardExt.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,YAAY,CAAC;;;;;;AAEb,kDAA0B;AAG1B;;GAEG;AACI,MAAM,eAAe,GAAG,CAC7B,gBAAwC,EACxC,EAAE;IAUF,MAAM,eAAgB,SAAQ,eAAK,CAAC,SAAgC;QAC3D,MAAM;YACX,MAAM,EAAC,YAAY,EAAE,GAAG,IAAI,EAAC,GAAG,IAAI,CAAC,KAAK,CAAC;YAC3C,OAAO,8BAAC,gBAAgB,IAAC,GAAG,EAAE,YAAY,KAAO,IAAqB,GAAI,CAAC;QAC7E,CAAC;KACF;IAED,OAAO,eAAK,CAAC,UAAU,CACrB,CAAC,KAAsD,EAAE,GAAmB,EAAE,EAAE;QAC9E,OAAO,8BAAC,eAAe,OAAK,KAAK,EAAE,YAAY,EAAE,GAAG,GAAI,CAAC;IAC3D,CAAC,CACF,CAAC;AACJ,CAAC,CAAC;AAxBW,QAAA,eAAe,mBAwB1B","sourcesContent":["/**\n * Copyright (c) Microsoft Corporation.\n * Licensed under the MIT License.\n * @format\n */\n'use strict';\n\nimport React from 'react';\nimport {IKeyboardProps} from './KeyboardExtProps';\n\n/**\n * @deprecated - Exported types should already have the keyboarding properties on them\n */\nexport const supportKeyboard = <P extends Record<string, any>>(\n WrappedComponent: React.ComponentType<P>,\n) => {\n interface IForwardRefProps {\n forwardedRef: React.Ref<any>;\n }\n\n // children is used to avoid error: Property 'children' does not exist on type 'IntrinsicAttributes & ViewProps &\n // IKeyboardProps & RefAttributes<any>\n type PropsWithoutForwardedRef = P & React.PropsWithChildren<IKeyboardProps>;\n type PropsWithForwardedRef = React.PropsWithoutRef<PropsWithoutForwardedRef> & IForwardRefProps;\n\n class SupportKeyboard extends React.Component<PropsWithForwardedRef> {\n public render(): JSX.Element {\n const {forwardedRef, ...rest} = this.props;\n return <WrappedComponent ref={forwardedRef} {...(rest as unknown as P)} />;\n }\n }\n\n return React.forwardRef(\n (props: React.PropsWithoutRef<PropsWithoutForwardedRef>, ref: React.Ref<any>) => {\n return <SupportKeyboard {...props} forwardedRef={ref} />;\n },\n );\n};\n"]}
1
+ {"version":3,"file":"KeyboardExt.js","sourceRoot":"","sources":["../../../src-win/Libraries/Components/Keyboard/KeyboardExt.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,YAAY,CAAC;;;;;;AAEb,kDAA0B;AAG1B;;GAEG;AACI,MAAM,eAAe,GAAG,CAC7B,gBAAwC,EACxC,EAAE;IAWF,MAAM,eAAgB,SAAQ,eAAK,CAAC,SAAgC;QAC3D,MAAM;YACX,MAAM,EAAC,YAAY,EAAE,GAAG,IAAI,EAAC,GAAG,IAAI,CAAC,KAAK,CAAC;YAC3C,OAAO,CACL,8BAAC,gBAAgB,IAAC,GAAG,EAAE,YAAY,KAAO,IAAqB,GAAI,CACpE,CAAC;QACJ,CAAC;KACF;IAED,OAAO,eAAK,CAAC,UAAU,CACrB,CACE,KAAsD,EACtD,GAAmB,EACnB,EAAE;QACF,OAAO,8BAAC,eAAe,OAAK,KAAK,EAAE,YAAY,EAAE,GAAG,GAAI,CAAC;IAC3D,CAAC,CACF,CAAC;AACJ,CAAC,CAAC;AA9BW,QAAA,eAAe,mBA8B1B","sourcesContent":["/**\n * Copyright (c) Microsoft Corporation.\n * Licensed under the MIT License.\n * @format\n */\n'use strict';\n\nimport React from 'react';\nimport {IKeyboardProps} from './KeyboardExtProps';\n\n/**\n * @deprecated - Exported types should already have the keyboarding properties on them\n */\nexport const supportKeyboard = <P extends Record<string, any>>(\n WrappedComponent: React.ComponentType<P>,\n) => {\n interface IForwardRefProps {\n forwardedRef: React.Ref<any>;\n }\n\n // children is used to avoid error: Property 'children' does not exist on type 'IntrinsicAttributes & ViewProps &\n // IKeyboardProps & RefAttributes<any>\n type PropsWithoutForwardedRef = P & React.PropsWithChildren<IKeyboardProps>;\n type PropsWithForwardedRef = React.PropsWithoutRef<PropsWithoutForwardedRef> &\n IForwardRefProps;\n\n class SupportKeyboard extends React.Component<PropsWithForwardedRef> {\n public render(): JSX.Element {\n const {forwardedRef, ...rest} = this.props;\n return (\n <WrappedComponent ref={forwardedRef} {...(rest as unknown as P)} />\n );\n }\n }\n\n return React.forwardRef(\n (\n props: React.PropsWithoutRef<PropsWithoutForwardedRef>,\n ref: React.Ref<any>,\n ) => {\n return <SupportKeyboard {...props} forwardedRef={ref} />;\n },\n );\n};\n"]}
@@ -1360,11 +1360,12 @@ function InternalTextInput(props: Props): React.Node {
1360
1360
  typeof props.value === 'string'
1361
1361
  ? props.value
1362
1362
  : typeof props.defaultValue === 'string'
1363
- ? props.defaultValue
1364
- : '';
1363
+ ? props.defaultValue
1364
+ : '';
1365
1365
 
1366
1366
  const viewCommands =
1367
- WindowsTextInputCommands || AndroidTextInputCommands || // [Windows]
1367
+ WindowsTextInputCommands ||
1368
+ AndroidTextInputCommands || // [Windows]
1368
1369
  (props.multiline === true
1369
1370
  ? RCTMultilineTextInputNativeCommands
1370
1371
  : RCTSinglelineTextInputNativeCommands);
@@ -1442,8 +1443,12 @@ function InternalTextInput(props: Props): React.Node {
1442
1443
  }
1443
1444
  },
1444
1445
  isFocused(): boolean {
1445
- const currentlyFocusedInput = TextInputState.currentlyFocusedInput();
1446
- return currentlyFocusedInput !== null && currentlyFocusedInput === inputRef.current;
1446
+ const currentlyFocusedInput =
1447
+ TextInputState.currentlyFocusedInput();
1448
+ return (
1449
+ currentlyFocusedInput !== null &&
1450
+ currentlyFocusedInput === inputRef.current
1451
+ );
1447
1452
  },
1448
1453
  getNativeRef(): ?React.ElementRef<HostComponent<mixed>> {
1449
1454
  return inputRef.current;
@@ -1998,12 +2003,12 @@ const ExportedForwardRef: React.AbstractComponent<
1998
2003
  textContentType != null
1999
2004
  ? textContentType
2000
2005
  : Platform.OS === 'ios' &&
2001
- autoComplete &&
2002
- autoComplete in autoCompleteWebToTextContentTypeMap
2003
- ? // $FlowFixMe[invalid-computed-prop]
2004
- // $FlowFixMe[prop-missing]
2005
- autoCompleteWebToTextContentTypeMap[autoComplete]
2006
- : textContentType
2006
+ autoComplete &&
2007
+ autoComplete in autoCompleteWebToTextContentTypeMap
2008
+ ? // $FlowFixMe[invalid-computed-prop]
2009
+ // $FlowFixMe[prop-missing]
2010
+ autoCompleteWebToTextContentTypeMap[autoComplete]
2011
+ : textContentType
2007
2012
  }
2008
2013
  {...restProps}
2009
2014
  forwardedRef={forwardedRef}
@@ -45,8 +45,8 @@ const extractSingleTouch = (nativeEvent: {
45
45
  return !hasTouches && hasChangedTouches
46
46
  ? changedTouches[0]
47
47
  : hasTouches
48
- ? touches[0]
49
- : nativeEvent;
48
+ ? touches[0]
49
+ : nativeEvent;
50
50
  };
51
51
 
52
52
  /**
@@ -131,7 +131,10 @@ const PASSTHROUGH_PROPS = [
131
131
  const TouchableWithoutFeedback: React.AbstractComponent<
132
132
  Props,
133
133
  React.ElementRef<typeof Animated.View>,
134
- > = React.forwardRef(function TouchableWithoutFeedback(props: Props, ref): React.Node {
134
+ > = React.forwardRef(function TouchableWithoutFeedback(
135
+ props: Props,
136
+ ref,
137
+ ): React.Node {
135
138
  const {
136
139
  disabled,
137
140
  rejectResponderTermination,
@@ -153,7 +156,6 @@ const TouchableWithoutFeedback: React.AbstractComponent<
153
156
  onMouseLeave, // [Windows]
154
157
  } = props;
155
158
 
156
-
157
159
  const pressabilityConfig = useMemo(
158
160
  () => ({
159
161
  cancelable: !rejectResponderTermination,
@@ -262,4 +264,4 @@ const TouchableWithoutFeedback: React.AbstractComponent<
262
264
  return React.cloneElement(element, {...elementProps, ref}, ...children);
263
265
  });
264
266
 
265
- module.exports = TouchableWithoutFeedback;
267
+ module.exports = TouchableWithoutFeedback;
@@ -33,9 +33,7 @@ const childrenWithImportantForAccessibility = children => {
33
33
  // $FlowFixMe[incompatible-call]
34
34
  return React.cloneElement(child, {
35
35
  accessible: false,
36
- children: childrenWithImportantForAccessibility(
37
- child.props.children,
38
- ),
36
+ children: childrenWithImportantForAccessibility(child.props.children),
39
37
  });
40
38
  } else {
41
39
  // $FlowFixMe[incompatible-call]
@@ -17,7 +17,7 @@ const version: $ReadOnly<{
17
17
  major: 0,
18
18
  minor: 76,
19
19
  patch: 0,
20
- prerelease: 'rc.4',
20
+ prerelease: 'rc.6',
21
21
  };
22
22
 
23
23
  module.exports = {version};
@@ -329,9 +329,9 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
329
329
  styleProps.borderTopWidth != null)
330
330
  ) {
331
331
  let textStyleProps = Array.isArray(styleProps)
332
- ? // $FlowFixMe[underconstrained-implicit-instantiation]
333
- flattenStyle(styleProps)
334
- : styleProps;
332
+ ? // $FlowFixMe[underconstrained-implicit-instantiation]
333
+ flattenStyle(styleProps)
334
+ : styleProps;
335
335
  let {
336
336
  // $FlowFixMe[prop-missing]
337
337
  margin,
@@ -371,11 +371,15 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
371
371
  paddingVertical,
372
372
  // $FlowFixMe[not-an-object]
373
373
  ...rest
374
- } = textStyleProps != null ? textStyleProps : {}
375
- return (
376
- <View style={styleProps}><TextAncestor.Provider value={true}>{nativeText}</TextAncestor.Provider></View>
377
- );
378
- };
374
+ } = textStyleProps != null ? textStyleProps : {};
375
+ return (
376
+ <View style={styleProps}>
377
+ <TextAncestor.Provider value={true}>
378
+ {nativeText}
379
+ </TextAncestor.Provider>
380
+ </View>
381
+ );
382
+ }
379
383
  // Windows]
380
384
 
381
385
  if (children == null) {
@@ -617,4 +621,4 @@ const verticalAlignToTextAlignVerticalMap = {
617
621
  middle: 'center',
618
622
  };
619
623
 
620
- module.exports = Text;
624
+ module.exports = Text;
@@ -70,10 +70,10 @@ const Platform: PlatformType = {
70
70
  ? // $FlowFixMe[incompatible-return]
71
71
  spec.windows
72
72
  : 'native' in spec
73
- ? // $FlowFixMe[incompatible-return]
74
- spec.native
75
- : // $FlowFixMe[incompatible-return]
76
- spec.default,
73
+ ? // $FlowFixMe[incompatible-return]
74
+ spec.native
75
+ : // $FlowFixMe[incompatible-return]
76
+ spec.default,
77
77
  };
78
78
 
79
79
  module.exports = Platform;
@@ -14,6 +14,7 @@
14
14
  #include <Fabric/Composition/RootComponentView.h>
15
15
  #include "AbiEventEmitter.h"
16
16
  #include "AbiShadowNode.h"
17
+ #include "ReactCoreInjection.h"
17
18
 
18
19
  namespace winrt::Microsoft::ReactNative::Composition::implementation {
19
20
  struct RootComponentView;
@@ -262,6 +263,17 @@ void ComponentView::HandleCommand(const winrt::Microsoft::ReactNative::HandleCom
262
263
  }
263
264
  }
264
265
 
266
+ HWND ComponentView::GetHwndForParenting() noexcept {
267
+ if (m_parent) {
268
+ return winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(m_parent)
269
+ ->GetHwndForParenting();
270
+ }
271
+
272
+ // Fallback if we do not know any more specific HWND
273
+ return reinterpret_cast<HWND>(winrt::Microsoft::ReactNative::implementation::ReactCoreInjection::GetTopLevelWindowId(
274
+ m_reactContext.Properties().Handle()));
275
+ }
276
+
265
277
  winrt::Microsoft::ReactNative::Composition::implementation::RootComponentView *ComponentView::rootComponentView()
266
278
  const noexcept {
267
279
  if (m_rootView)
@@ -209,6 +209,9 @@ struct ComponentView : public ComponentViewT<ComponentView> {
209
209
  // Notify up the tree to bring the rect into view by scrolling as needed
210
210
  virtual void StartBringIntoView(BringIntoViewOptions &&args) noexcept;
211
211
 
212
+ // Eventually PopupContentLink and similar APIs will remove the need for this.
213
+ virtual HWND GetHwndForParenting() noexcept;
214
+
212
215
  virtual const winrt::Microsoft::ReactNative::IComponentProps userProps(
213
216
  facebook::react::Props::Shared const &props) noexcept;
214
217
 
@@ -129,6 +129,18 @@ bool accessibilityValueHasValue(const facebook::react::AccessibilityValue &value
129
129
  return (value.min.has_value() && value.max.has_value()) || value.now.has_value() || value.text.has_value();
130
130
  }
131
131
 
132
+ bool expandableControl(const facebook::react::SharedViewProps props) {
133
+ if (props->accessibilityState.has_value() && props->accessibilityState->expanded.has_value())
134
+ return true;
135
+ auto accessibilityActions = props->accessibilityActions;
136
+ for (size_t i = 0; i < accessibilityActions.size(); i++) {
137
+ if (accessibilityActions[i].name == "expand" || accessibilityActions[i].name == "collapse") {
138
+ return true;
139
+ }
140
+ }
141
+ return false;
142
+ }
143
+
132
144
  HRESULT __stdcall CompositionDynamicAutomationProvider::GetPatternProvider(PATTERNID patternId, IUnknown **pRetVal) {
133
145
  if (pRetVal == nullptr)
134
146
  return E_POINTER;
@@ -181,6 +193,15 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPatternProvider(PATTE
181
193
  AddRef();
182
194
  }
183
195
 
196
+ if (patternId == UIA_ExpandCollapsePatternId &&
197
+ (accessibilityRole == "combobox" || accessibilityRole == "splitbutton" || accessibilityRole == "treeitem" ||
198
+ (expandableControl(props) &&
199
+ (accessibilityRole == "toolbar" || accessibilityRole == "menuitem" || accessibilityRole == "menubar" ||
200
+ accessibilityRole == "listitem" || accessibilityRole == "group" || accessibilityRole == "button")))) {
201
+ *pRetVal = static_cast<IExpandCollapseProvider *>(this);
202
+ AddRef();
203
+ }
204
+
184
205
  return S_OK;
185
206
  }
186
207
 
@@ -349,6 +370,13 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPropertyValue(PROPERT
349
370
  pRetVal->lVal = GetLiveSetting(props->accessibilityLiveRegion);
350
371
  break;
351
372
  }
373
+ case UIA_ItemStatusPropertyId: {
374
+ pRetVal->vt = VT_BSTR;
375
+ pRetVal->bstrVal = (props->accessibilityState.has_value() && props->accessibilityState->busy)
376
+ ? SysAllocString(L"Busy")
377
+ : SysAllocString(L"");
378
+ break;
379
+ }
352
380
  }
353
381
 
354
382
  return hr;
@@ -496,4 +524,42 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::Toggle() {
496
524
  return S_OK;
497
525
  }
498
526
 
527
+ HRESULT __stdcall CompositionDynamicAutomationProvider::get_ExpandCollapseState(ExpandCollapseState *pRetVal) {
528
+ if (pRetVal == nullptr)
529
+ return E_POINTER;
530
+ auto strongView = m_view.view();
531
+
532
+ if (!strongView)
533
+ return UIA_E_ELEMENTNOTAVAILABLE;
534
+
535
+ auto props = std::static_pointer_cast<const facebook::react::ViewProps>(
536
+ winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(strongView)->props());
537
+
538
+ if (props == nullptr)
539
+ return UIA_E_ELEMENTNOTAVAILABLE;
540
+
541
+ *pRetVal = props->accessibilityState->expanded.has_value()
542
+ ? GetExpandCollapseState(props->accessibilityState->expanded.value())
543
+ : ExpandCollapseState_Collapsed;
544
+ return S_OK;
545
+ }
546
+
547
+ HRESULT __stdcall CompositionDynamicAutomationProvider::Expand() {
548
+ auto strongView = m_view.view();
549
+
550
+ if (!strongView)
551
+ return UIA_E_ELEMENTNOTAVAILABLE;
552
+ DispatchAccessibilityAction(m_view, "expand");
553
+ return S_OK;
554
+ }
555
+
556
+ HRESULT __stdcall CompositionDynamicAutomationProvider::Collapse() {
557
+ auto strongView = m_view.view();
558
+
559
+ if (!strongView)
560
+ return UIA_E_ELEMENTNOTAVAILABLE;
561
+ DispatchAccessibilityAction(m_view, "collapse");
562
+ return S_OK;
563
+ }
564
+
499
565
  } // namespace winrt::Microsoft::ReactNative::implementation
@@ -16,7 +16,8 @@ class CompositionDynamicAutomationProvider : public winrt::implements<
16
16
  IInvokeProvider,
17
17
  IScrollItemProvider,
18
18
  IValueProvider,
19
- IToggleProvider> {
19
+ IToggleProvider,
20
+ IExpandCollapseProvider> {
20
21
  public:
21
22
  CompositionDynamicAutomationProvider(
22
23
  const winrt::Microsoft::ReactNative::Composition::ComponentView &componentView) noexcept;
@@ -47,10 +48,15 @@ class CompositionDynamicAutomationProvider : public winrt::implements<
47
48
  virtual HRESULT __stdcall get_Value(BSTR *pRetVal) override;
48
49
  virtual HRESULT __stdcall get_IsReadOnly(BOOL *pRetVal) override;
49
50
 
50
- // inherited via IToggleProivder
51
+ // inherited via IToggleProvider
51
52
  virtual HRESULT __stdcall get_ToggleState(ToggleState *pRetVal) override;
52
53
  virtual HRESULT __stdcall Toggle() override;
53
54
 
55
+ // inherited via IExpandCollapseProvider
56
+ virtual HRESULT __stdcall get_ExpandCollapseState(ExpandCollapseState *pRetVal) override;
57
+ virtual HRESULT __stdcall Expand() override;
58
+ virtual HRESULT __stdcall Collapse() override;
59
+
54
60
  private:
55
61
  ::Microsoft::ReactNative::ReactTaggedView m_view;
56
62
  };
@@ -23,6 +23,7 @@
23
23
  #include "CompositionHelpers.h"
24
24
  #include "RootComponentView.h"
25
25
  #include "Theme.h"
26
+ #include "TooltipService.h"
26
27
  #include "UiaHelpers.h"
27
28
  #include "d2d1helper.h"
28
29
 
@@ -43,6 +44,13 @@ ComponentView::ComponentView(
43
44
  m_outerVisual.InsertAt(m_focusVisual.InnerVisual(), 0);
44
45
  }
45
46
 
47
+ ComponentView::~ComponentView() {
48
+ if (m_tooltipTracked) {
49
+ TooltipService::GetCurrent(m_reactContext.Properties())->StopTracking(*this);
50
+ m_tooltipTracked = false;
51
+ }
52
+ }
53
+
46
54
  facebook::react::Tag ComponentView::Tag() const noexcept {
47
55
  return m_tag;
48
56
  }
@@ -130,6 +138,16 @@ void ComponentView::updateProps(
130
138
  updateShadowProps(oldViewProps, newViewProps);
131
139
  }
132
140
 
141
+ if (oldViewProps.tooltip != newViewProps.tooltip) {
142
+ if (!m_tooltipTracked && newViewProps.tooltip) {
143
+ TooltipService::GetCurrent(m_reactContext.Properties())->StartTracking(*this);
144
+ m_tooltipTracked = true;
145
+ } else if (m_tooltipTracked && !newViewProps.tooltip) {
146
+ TooltipService::GetCurrent(m_reactContext.Properties())->StopTracking(*this);
147
+ m_tooltipTracked = false;
148
+ }
149
+ }
150
+
133
151
  base_type::updateProps(props, oldProps);
134
152
  }
135
153
 
@@ -1303,6 +1321,12 @@ void ComponentView::updateAccessibilityProps(
1303
1321
  !(oldViewProps.accessibilityState && oldViewProps.accessibilityState->disabled),
1304
1322
  !(newViewProps.accessibilityState && newViewProps.accessibilityState->disabled));
1305
1323
 
1324
+ winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
1325
+ m_uiaProvider,
1326
+ UIA_IsEnabledPropertyId,
1327
+ !(oldViewProps.accessibilityState && oldViewProps.accessibilityState->busy),
1328
+ !(newViewProps.accessibilityState && newViewProps.accessibilityState->busy));
1329
+
1306
1330
  winrt::Microsoft::ReactNative::implementation::UpdateUiaProperty(
1307
1331
  m_uiaProvider, UIA_ControlTypePropertyId, oldViewProps.accessibilityRole, newViewProps.accessibilityRole);
1308
1332
 
@@ -30,6 +30,7 @@ struct ComponentView : public ComponentViewT<
30
30
  facebook::react::Tag tag,
31
31
  winrt::Microsoft::ReactNative::ReactContext const &reactContext,
32
32
  ComponentViewFeatures flags);
33
+ virtual ~ComponentView();
33
34
 
34
35
  virtual winrt::Microsoft::ReactNative::Composition::Experimental::IVisual Visual() const noexcept {
35
36
  return nullptr;
@@ -151,6 +152,7 @@ struct ComponentView : public ComponentViewT<
151
152
  const facebook::react::ViewProps &viewProps) noexcept;
152
153
 
153
154
  bool m_FinalizeTransform{false};
155
+ bool m_tooltipTracked{false};
154
156
  ComponentViewFeatures m_flags;
155
157
  void showFocusVisual(bool show) noexcept;
156
158
  winrt::Microsoft::ReactNative::Composition::Experimental::IFocusVisual m_focusVisual{nullptr};
@@ -157,6 +157,7 @@ void ReactNativeIsland::ReactViewHost(winrt::Microsoft::ReactNative::IReactViewH
157
157
  }
158
158
 
159
159
  if (m_reactViewHost) {
160
+ UninitRootView();
160
161
  m_reactViewHost.DetachViewInstance();
161
162
  }
162
163
 
@@ -332,7 +333,7 @@ winrt::IInspectable ReactNativeIsland::GetUiaProvider() noexcept {
332
333
  if (m_uiaProvider == nullptr) {
333
334
  m_uiaProvider =
334
335
  winrt::make<winrt::Microsoft::ReactNative::implementation::CompositionRootAutomationProvider>(*this);
335
- if (m_hwnd) {
336
+ if (m_hwnd && !m_island) {
336
337
  auto pRootProvider =
337
338
  static_cast<winrt::Microsoft::ReactNative::implementation::CompositionRootAutomationProvider *>(
338
339
  m_uiaProvider.as<IRawElementProviderSimple>().get());
@@ -348,6 +349,10 @@ void ReactNativeIsland::SetWindow(uint64_t hwnd) noexcept {
348
349
  m_hwnd = reinterpret_cast<HWND>(hwnd);
349
350
  }
350
351
 
352
+ HWND ReactNativeIsland::GetHwndForParenting() noexcept {
353
+ return m_hwnd;
354
+ }
355
+
351
356
  int64_t ReactNativeIsland::SendMessage(uint32_t msg, uint64_t wParam, int64_t lParam) noexcept {
352
357
  if (m_rootTag == -1)
353
358
  return 0;
@@ -367,7 +372,7 @@ int64_t ReactNativeIsland::SendMessage(uint32_t msg, uint64_t wParam, int64_t lP
367
372
  bool ReactNativeIsland::CapturePointer(
368
373
  const winrt::Microsoft::ReactNative::Composition::Input::Pointer &pointer,
369
374
  facebook::react::Tag tag) noexcept {
370
- if (m_hwnd) {
375
+ if (m_hwnd && !m_island) {
371
376
  SetCapture(m_hwnd);
372
377
  }
373
378
  return m_CompositionEventHandler->CapturePointer(pointer, tag);
@@ -377,7 +382,7 @@ void ReactNativeIsland::ReleasePointerCapture(
377
382
  const winrt::Microsoft::ReactNative::Composition::Input::Pointer &pointer,
378
383
  facebook::react::Tag tag) noexcept {
379
384
  if (m_CompositionEventHandler->ReleasePointerCapture(pointer, tag)) {
380
- if (m_hwnd) {
385
+ if (m_hwnd && !m_island) {
381
386
  if (m_hwnd == GetCapture()) {
382
387
  ReleaseCapture();
383
388
  }
@@ -82,6 +82,7 @@ struct ReactNativeIsland
82
82
  void AddRenderedVisual(const winrt::Microsoft::ReactNative::Composition::Experimental::IVisual &visual) noexcept;
83
83
  void RemoveRenderedVisual(const winrt::Microsoft::ReactNative::Composition::Experimental::IVisual &visual) noexcept;
84
84
  bool TrySetFocus() noexcept;
85
+ HWND GetHwndForParenting() noexcept;
85
86
 
86
87
  winrt::Microsoft::ReactNative::Composition::ICustomResourceLoader Resources() noexcept;
87
88
  void Resources(const winrt::Microsoft::ReactNative::Composition::ICustomResourceLoader &resources) noexcept;
@@ -231,4 +231,15 @@ winrt::Microsoft::ReactNative::implementation::ClipState RootComponentView::getC
231
231
  return winrt::Microsoft::ReactNative::implementation::ClipState::NoClip;
232
232
  }
233
233
 
234
+ HWND RootComponentView::GetHwndForParenting() noexcept {
235
+ if (auto rootView = m_wkRootView.get()) {
236
+ auto hwnd = winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>(rootView)
237
+ ->GetHwndForParenting();
238
+ if (hwnd)
239
+ return hwnd;
240
+ }
241
+
242
+ return base_type::GetHwndForParenting();
243
+ }
244
+
234
245
  } // namespace winrt::Microsoft::ReactNative::Composition::implementation
@@ -64,6 +64,8 @@ struct RootComponentView : RootComponentViewT<RootComponentView, ViewComponentVi
64
64
  winrt::Microsoft::ReactNative::ComponentView FindFirstFocusableElement() noexcept;
65
65
  winrt::Microsoft::ReactNative::ComponentView FindLastFocusableElement() noexcept;
66
66
 
67
+ HWND GetHwndForParenting() noexcept override;
68
+
67
69
  private:
68
70
  // should this be a ReactTaggedView? - It shouldn't actually matter since if the view is going away it should always
69
71
  // be clearing its focus But being a reactTaggedView might make it easier to identify cases where that isn't
@@ -16,7 +16,7 @@
16
16
  namespace winrt::Microsoft::ReactNative::Composition {
17
17
 
18
18
  void RenderText(
19
- ID2D1DeviceContext &deviceContext,
19
+ ID2D1RenderTarget &deviceContext,
20
20
  ::IDWriteTextLayout &textLayout,
21
21
  const facebook::react::AttributedString &attributedString,
22
22
  const facebook::react::TextAttributes &textAttributes,
@@ -26,7 +26,6 @@ void RenderText(
26
26
  float offsetX = offset.x / pointScaleFactor;
27
27
  float offsetY = offset.y / pointScaleFactor;
28
28
 
29
- assert(deviceContext.GetUnitMode() == D2D1_UNIT_MODE_DIPS);
30
29
  const auto dpi = pointScaleFactor * 96.0f;
31
30
  float oldDpiX, oldDpiY;
32
31
  deviceContext.GetDpi(&oldDpiX, &oldDpiY);
@@ -14,7 +14,7 @@
14
14
  namespace winrt::Microsoft::ReactNative::Composition {
15
15
 
16
16
  void RenderText(
17
- ID2D1DeviceContext &deviceContext,
17
+ ID2D1RenderTarget &deviceContext,
18
18
  ::IDWriteTextLayout &textLayout,
19
19
  const facebook::react::AttributedString &attributedString,
20
20
  const facebook::react::TextAttributes &textAttributes,