diff --git a/.changeset/modern-native-core.md b/.changeset/modern-native-core.md new file mode 100644 index 00000000000..e3bb7476d2c --- /dev/null +++ b/.changeset/modern-native-core.md @@ -0,0 +1,7 @@ +--- +"@fluentui-react-native/native-core": minor +--- + +Initialize the native-core package with cross-platform, macOS, Windows, shared Windows/Win32, and Win32 entrypoints and a native component and TurboModule organization plan. + +Own the Callout and FocusZone JS wrappers, codegen specifications, macOS Paper/Fabric adapters, and Windows Fabric implementations in this shared package. diff --git a/.changeset/native-core-component-migration.md b/.changeset/native-core-component-migration.md new file mode 100644 index 00000000000..a4a72c2b512 --- /dev/null +++ b/.changeset/native-core-component-migration.md @@ -0,0 +1,9 @@ +--- +"@fluentui-react-native/callout": patch +"@fluentui-react-native/focus-zone": patch +"@fluentui-react-native/components": patch +"@fluentui-react-native/storybook-desktop-runtime": patch +"@fluentui-react-native/tester": patch +--- + +Move Callout and FocusZone implementations into native-core and retain the existing packages as JS-only compatibility shims under packages/shim. Native applications must directly depend on native-core and regenerate native autolinking/Pods; macOS now uses the shared FRNNativeCore pod and Windows uses one Fabric library for both components. Public APIs and native registration names are unchanged. diff --git a/.changeset/native-core-legacy-entrypoint.md b/.changeset/native-core-legacy-entrypoint.md new file mode 100644 index 00000000000..72f599131c5 --- /dev/null +++ b/.changeset/native-core-legacy-entrypoint.md @@ -0,0 +1,9 @@ +--- +"@fluentui-react-native/native-core": minor +"@fluentui-react-native/callout": patch +"@fluentui-react-native/focus-zone": patch +"@fluentui-react-native/components": patch +"@fluentui-react-native/storybook-desktop-runtime": patch +--- + +Isolate the existing Callout and FocusZone JavaScript wrappers under native-core/legacy instead of the package root. Compatibility shims retain their exports through this submodule; native implementations and codegen specifications are unchanged. diff --git a/.changeset/native-core-macos-interop.md b/.changeset/native-core-macos-interop.md new file mode 100644 index 00000000000..1395eefc1fe --- /dev/null +++ b/.changeset/native-core-macos-interop.md @@ -0,0 +1,5 @@ +--- +'@fluentui-react-native/native-core': patch +--- + +Fix the macOS Swift interoperability header name for the consolidated native-core pod. diff --git a/.github/skills/agentic-component-authoring/references/focus-macos.md b/.github/skills/agentic-component-authoring/references/focus-macos.md index 1e9cf6184c1..990010bb1af 100644 --- a/.github/skills/agentic-component-authoring/references/focus-macos.md +++ b/.github/skills/agentic-component-authoring/references/focus-macos.md @@ -31,8 +31,8 @@ focus visual should be presented as active. exposure or global numeric-tag lookup. Local references: -`packages\components\FocusZone\macos\RCTFocusZone.m:24-35,122-129`; -`packages\components\FocusZone\macos\RCTFocusZoneComponentView.mm:118-179`. +`packages\agentic\native-core\macos\components\FocusZone\shared\RCTFocusZone.m:24-35,122-129`; +`packages\agentic\native-core\macos\components\FocusZone\fabric\RCTFocusZoneComponentView.mm:118-179`. Installed RNmacOS `React\Fabric\Mounting\ComponentViews\View\RCTViewComponentView.mm:1719-1804` implements focus/blur commands and responder event emission. @@ -105,8 +105,8 @@ same keys. Recompute eligibility when children mount/unmount and when props change, and clear the default responder on recycle. Retain direction, wrap/stop, RTL, nested zones, scrolling, and editable-child semantics. -Evidence: `packages\components\FocusZone\macos\RCTFocusZone.m:584-675`; -`packages\components\FocusZone\macos\RCTFocusZoneComponentView.mm:118-195`. +Evidence: `packages\agentic\native-core\macos\components\FocusZone\shared\RCTFocusZone.m:584-675`; +`packages\agentic\native-core\macos\components\FocusZone\fabric\RCTFocusZoneComponentView.mm:118-195`. ## Popup windows and lifecycle @@ -131,10 +131,10 @@ Do not install OS-global keyboard hooks or require desktop-driver permissions for ordinary production focus behavior. Evidence: -`packages\native\Callout\macos\CalloutWindow.swift:9-38`; -`packages\native\Callout\macos\CalloutView.swift:33-45,142-216`; -`packages\native\Callout\macos\RCTCalloutComponentView.mm:96-132`; -`packages\native\Callout\macos\GuardedEventMonitor.swift:1-29`; +`packages\agentic\native-core\macos\components\Callout\shared\CalloutWindow.swift:9-38`; +`packages\agentic\native-core\macos\components\Callout\shared\CalloutView.swift:33-45,142-216`; +`packages\agentic\native-core\macos\components\Callout\fabric\RCTCalloutComponentView.mm:96-132`; +`packages\agentic\native-core\macos\components\Callout\shared\GuardedEventMonitor.swift:1-29`; `packages\components\ContextualMenu\src\ContextualMenu.tsx:39-55`. ## Native versus custom ring drawing diff --git a/.github/skills/agentic-component-authoring/references/focus-windows.md b/.github/skills/agentic-component-authoring/references/focus-windows.md index bcf96e33111..bd677f65cc0 100644 --- a/.github/skills/agentic-component-authoring/references/focus-windows.md +++ b/.github/skills/agentic-component-authoring/references/focus-windows.md @@ -53,7 +53,7 @@ assume a React ref can be serialized into a TurboModule argument. The existing Fabric FocusZone uses `TryFocus(FocusState::Keyboard)` and checks the root's focused component after the request -(`packages\components\FocusZone\windows\FRNFocusZone\FocusZoneComponentView.cpp:175-224`). +(`packages\agentic\native-core\windows\NativeCore\components\FocusZone\FocusZoneComponentView.cpp:175-224`). Reuse this request-versus-observation pattern. Do not report success merely because JavaScript called an optional `.focus()` method. @@ -94,7 +94,7 @@ This native implementation detail is not a promised public JavaScript API. consume every key. Sources: `packages\utils\interactive-hooks\src\useKeyProps.ts:8-95,114-126`; -`packages\components\FocusZone\windows\FRNFocusZone\FocusZoneComponentView.cpp:71-133`. +`packages\agentic\native-core\windows\NativeCore\components\FocusZone\FocusZoneComponentView.cpp:71-133`. ## Native and custom focus visuals diff --git a/.gitignore b/.gitignore index c89077c9ea0..d0ff6b78de4 100644 --- a/.gitignore +++ b/.gitignore @@ -104,6 +104,12 @@ apps/*/.vscode/.react/ # Visual Studio .vs/ +# Native library outputs, including caches left behind by workspace relocations +packages/**/windows/**/[Oo]bj/ +packages/**/windows/**/Generated Files/ +packages/**/windows/**/x64/[Dd]ebug*/ +packages/**/windows/**/x64/[Rr]elease*/ + # Ignore Gradle build output directory **/android/**/build diff --git a/.oxfmtrc.json b/.oxfmtrc.json index 78d5f13b9a9..4750ea7dacb 100644 --- a/.oxfmtrc.json +++ b/.oxfmtrc.json @@ -10,7 +10,7 @@ "**/*.generated.*", "**/lib-commonjs/**", "**/dist/**", - "packages/native/Callout/windows/Callout/codegen/**", + "packages/agentic/native-core/windows/NativeCore/codegen/**", "**/CHANGELOG.*", "**/CODE_OF_CONDUCT.md", "**/SECURITY.md", diff --git a/AGENTS.md b/AGENTS.md index 7d8f9225862..fe2e40686aa 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -86,8 +86,9 @@ This is the **FluentUI React Native** repository, a monorepo containing React Na /win32/ - Win32-specific test app /component-generator/ - Tool to generate new components /packages/ - Core library packages + /agentic/native-core/ - Shared modern native components and TurboModules /components/ - UI component implementations (Button, Checkbox, Avatar, etc.) - /native/ - Standalone native-backed component packages (Callout, etc.) + /shim/ - Compatibility entrypoints (Callout, FocusZone, theming, etc.) /framework/ - Core theming and composition framework /composition/ - Component composition factory (current approach) /theme/ - Theme system @@ -237,8 +238,9 @@ The composition framework uses precise types for better type safety: ### Component Development -**Component Location**: Stable JavaScript components are in `/packages/components/`, standalone native-backed components are in -`/packages/native/`, and components under development are in `/packages/experimental/`. +**Component Location**: Stable JavaScript components are in `/packages/components/`, components under development are in +`/packages/experimental/`, and compatibility packages are in `/packages/shim/`. Modern native components and modules share +`/packages/agentic/native-core/`; follow its [organization plan](packages/agentic/native-core/README.md). **Component Structure**: Each component typically has: @@ -272,19 +274,25 @@ The composition framework uses precise types for better type safety: - **Do not use barrel exports (`export * from '...'`)** - wildcard re-exports break tree-shaking because bundlers cannot statically determine which symbols are used, so unused code is retained in consumers' bundles. Always use explicit named re-exports instead, e.g. `export { Foo, Bar } from './module'` and `export type { Baz } from './module'`. -**Native Modules**: Standalone native-backed component packages, such as Callout, live in `/packages/native/`. Components with -native code (iOS/Android/Windows): +**Native Modules**: Callout and FocusZone implementations live in `@fluentui-react-native/native-core`; their former packages +are JS-only compatibility shims under `/packages/shim/`. Their JavaScript wrappers live in `src/legacy` and are exported +only from `@fluentui-react-native/native-core/legacy`, not native-core's root entrypoint. Components with native code: - Typically have one root slot wrapping the native component - Use `codegenNativeComponent` for new architecture compatibility - May use `constantsToExport` for default values from native side - iOS/macOS: Include `.podspec` files -- Must be added to FluentTester's Podfile (transitive dependencies aren't autolinked) +- Native applications must directly depend on native-core for native project discovery and autolinking + +For new modern native components and modules, use `@fluentui-react-native/native-core` rather than creating another standalone +package. Its Windows components are Fabric-only; macOS components support Paper and Fabric initially. Export shared APIs +from the root and scope platform APIs to `macos`, `windows` (React Native Windows), `win` (Windows/Win32), or `win32`. +Callout and FocusZone retain their existing public APIs and native registration names after migration. ### Creating a New Component -1. Create the package under `/packages/components/`, `/packages/native/` for a standalone - native-backed component, or `/packages/experimental/` while it is under development +1. Create the package under `/packages/components/` or `/packages/experimental/` while it is + under development. Add modern native components/modules to the existing `/packages/agentic/native-core/` package instead. 2. Copy structure from existing component (e.g., Shimmer, Button) 3. Update `package.json` with correct name and dependencies (use `workspace:*` for internal packages) 4. Add the new package's `tsconfig.json` to the root `tsconfig.json` `references` so it joins the unified build diff --git a/apps/E2E/tsconfig.json b/apps/E2E/tsconfig.json index 97bea26d4a5..55864b6fdef 100644 --- a/apps/E2E/tsconfig.json +++ b/apps/E2E/tsconfig.json @@ -10,7 +10,7 @@ "include": ["src"], "references": [ { - "path": "../../packages/components/FocusZone/tsconfig.json" + "path": "../../packages/shim/focus-zone/tsconfig.json" }, { "path": "../../scripts/tsconfig.json" diff --git a/apps/fluent-tester/package.json b/apps/fluent-tester/package.json index 71f307224ce..dad808e8dcf 100644 --- a/apps/fluent-tester/package.json +++ b/apps/fluent-tester/package.json @@ -38,6 +38,7 @@ "windows": "react-native run-windows --arch x64 --sln windows/FluentTester.sln" }, "dependencies": { + "@fluentui-react-native/native-core": "workspace:*", "@types/node": "catalog:", "@types/react": "~19.1.4", "react": "19.1.4", diff --git a/apps/fluent-tester/tsconfig.json b/apps/fluent-tester/tsconfig.json index 23bace6b871..ae103d04278 100644 --- a/apps/fluent-tester/tsconfig.json +++ b/apps/fluent-tester/tsconfig.json @@ -11,7 +11,7 @@ "include": ["src"], "references": [ { - "path": "../../packages/native/Callout/tsconfig.json" + "path": "../../packages/shim/callout/tsconfig.json" }, { "path": "../../packages/experimental/AppearanceAdditions/tsconfig.json" @@ -32,11 +32,14 @@ "path": "../../packages/experimental/Shimmer/tsconfig.json" }, { - "path": "../../packages/components/FocusZone/tsconfig.json" + "path": "../../packages/shim/focus-zone/tsconfig.json" }, { "path": "../../packages/components/MenuButton/tsconfig.json" }, + { + "path": "../../packages/agentic/native-core/tsconfig.json" + }, { "path": "../../packages/components/RadioGroup/tsconfig.json" }, diff --git a/apps/storybook/README.md b/apps/storybook/README.md index b24ae090605..b34184c2513 100644 --- a/apps/storybook/README.md +++ b/apps/storybook/README.md @@ -1,10 +1,11 @@ # Agentic Components Storybook On-device [Storybook](https://storybook.js.org/) test app (Storybook for React Native v10) for -`@fluentui-react-native/components` and linked standalone native packages. It loads every -`*.stories.(ts|tsx)` file from the agentic components package plus the standalone Callout -package. FocusZone stories are agentic primitive stories, while its standalone native package -remains linked so they run in the Fabric and Paper hosts. +`@fluentui-react-native/components` and `@fluentui-react-native/native-core`. It loads every +`*.stories.(ts|tsx)` file from the agentic components package plus native-core's Callout +stories. FocusZone stories remain agentic primitive stories and use native-core's +`legacy` entrypoint, as does the Win32 Callout portal. +Native-core owns the shared macOS pod and Windows Fabric library for both components. The reusable desktop CLI and configuration live in `packages/agentic/storybook-desktop`, with peer-dependent React Native @@ -129,9 +130,9 @@ by smoke so its bundle identity does not fall back to the generated app default. ## Running on Windows The Windows app also uses `react-native-test-app`. Its generated Win32 project uses React Native -Windows 0.81's New Architecture and Fabric renderer. The Callout and FocusZone packages are -autolinked as Windows Fabric native libraries; their Paper implementations remain available on -their supported legacy endpoints. +Windows 0.81's New Architecture and Fabric renderer. Native-core is autolinked as one Windows +Fabric native library that registers Callout and FocusZone. macOS retains both Paper and Fabric +adapters; Win32 continues using its host-provided native implementations. ```powershell # from this directory diff --git a/apps/storybook/agent-map.yaml b/apps/storybook/agent-map.yaml index df305c7a802..8039f0170ec 100644 --- a/apps/storybook/agent-map.yaml +++ b/apps/storybook/agent-map.yaml @@ -15,7 +15,7 @@ sources: policy: generated-do-not-edit story_packages: - '@fluentui-react-native/components' - - '@fluentui-react-native/callout' + - '@fluentui-react-native/native-core' services: supervisor: diff --git a/apps/storybook/package.json b/apps/storybook/package.json index 4903ff03a73..13f134e41ce 100644 --- a/apps/storybook/package.json +++ b/apps/storybook/package.json @@ -20,9 +20,8 @@ "format": "fluentui-scripts format" }, "dependencies": { - "@fluentui-react-native/callout": "workspace:*", "@fluentui-react-native/components": "workspace:*", - "@fluentui-react-native/focus-zone": "workspace:*", + "@fluentui-react-native/native-core": "workspace:*", "@fluentui-react-native/storybook-desktop": "workspace:*", "@fluentui-react-native/storybook-desktop-runtime": "workspace:*", "@office-iss/react-native-win32": "^0.81.0", @@ -57,9 +56,8 @@ "furn": { "knip": { "ignoreDependencies": [ - "@fluentui-react-native/callout", "@fluentui-react-native/components", - "@fluentui-react-native/focus-zone", + "@fluentui-react-native/native-core", "react-native-svg" ] } diff --git a/apps/storybook/storybook.config.mts b/apps/storybook/storybook.config.mts index a2c85410840..62844258996 100644 --- a/apps/storybook/storybook.config.mts +++ b/apps/storybook/storybook.config.mts @@ -29,7 +29,7 @@ export default makeDesktopStorybookConfig({ }, ], [ - '@fluentui-react-native/callout', + '@fluentui-react-native/native-core', { platformSettings: { windows: { diff --git a/apps/storybook/tsconfig.json b/apps/storybook/tsconfig.json index 2e379f55aa6..3ce850c19e3 100644 --- a/apps/storybook/tsconfig.json +++ b/apps/storybook/tsconfig.json @@ -16,16 +16,13 @@ "exclude": ["node_modules", "dist", ".cache"], "references": [ { - "path": "../../packages/agentic/storybook-desktop/tsconfig.json" - }, - { - "path": "../../packages/native/Callout/tsconfig.json" + "path": "../../packages/agentic/components/tsconfig.json" }, { - "path": "../../packages/agentic/components/tsconfig.json" + "path": "../../packages/agentic/desktop-driver/tsconfig.json" }, { - "path": "../../packages/components/FocusZone/tsconfig.json" + "path": "../../packages/agentic/native-core/tsconfig.json" }, { "path": "../../scripts/tsconfig.json" @@ -34,7 +31,7 @@ "path": "../../packages/agentic/storybook-desktop-runtime/tsconfig.json" }, { - "path": "../../packages/agentic/desktop-driver/tsconfig.json" + "path": "../../packages/agentic/storybook-desktop/tsconfig.json" } ] } diff --git a/apps/tester-core/tsconfig.json b/apps/tester-core/tsconfig.json index 77573102892..ee6c375fcf5 100644 --- a/apps/tester-core/tsconfig.json +++ b/apps/tester-core/tsconfig.json @@ -29,7 +29,7 @@ "path": "../../packages/components/Button/tsconfig.json" }, { - "path": "../../packages/native/Callout/tsconfig.json" + "path": "../../packages/shim/callout/tsconfig.json" }, { "path": "../../packages/components/Chip/tsconfig.json" @@ -83,7 +83,7 @@ "path": "../../packages/experimental/Shimmer/tsconfig.json" }, { - "path": "../../packages/components/FocusZone/tsconfig.json" + "path": "../../packages/shim/focus-zone/tsconfig.json" }, { "path": "../../packages/framework-base/tsconfig.json" diff --git a/packages/agentic/components/WIN32-FOCUS-PLAN.md b/packages/agentic/components/WIN32-FOCUS-PLAN.md index ce765d75f63..93dc5b71239 100644 --- a/packages/agentic/components/WIN32-FOCUS-PLAN.md +++ b/packages/agentic/components/WIN32-FOCUS-PLAN.md @@ -246,7 +246,7 @@ paths. The installed Win32 JavaScript inspected was `packages\components\Menu\src\MenuPopover\useMenuPopover.ts:42-84,100-118`. - **V6:** `packages\components\TabList\src\Tab\useTab.win32.ts:64-110,142-152`; `packages\components\TabList\src\TabList\useTabList.ts:142-176,183-200`. -- **V7:** `packages\components\FocusZone\src\FocusZone.tsx:15-45`; +- **V7:** `packages\agentic\native-core\src\legacy\focus-zone\FocusZone.tsx:15-45`; `packages\components\FocusTrapZone\src\FocusTrapZone.ts:15-31`. These wrappers do not by themselves prove native trap/restoration semantics. - **V8:** `apps\tester-core\src\TestComponents\FocusZone\FocusZoneE2ETest.tsx:1-120`; @@ -297,7 +297,7 @@ paths. The installed Win32 JavaScript inspected was ### Added Fabric, macOS, and modern-ref evidence -- **W1:** `packages\components\FocusZone\windows\FRNFocusZone\FocusZoneComponentView.cpp:33-65,71-133,175-224` +- **W1:** `packages\agentic\native-core\windows\NativeCore\components\FocusZone\FocusZoneComponentView.cpp:33-65,71-133,175-224` subscribes to native focus/key events, requests `TryFocus(FocusState::Keyboard)`, and checks actual focused identity. This is a Fabric implementation model for V1 outcomes, not a reason to copy its transport to Win32. @@ -316,18 +316,18 @@ paths. The installed Win32 JavaScript inspected was implements AppKit focus/blur, ring-mask drawing, responder events, and pointer focus behavior. Lines 1807-1861 emit key events and use native handled-key entries to decide whether AppKit receives `super` handling. -- **M3:** `packages\components\FocusZone\macos\RCTFocusZone.m:24-35,122-129,584-675` +- **M3:** `packages\agentic\native-core\macos\components\FocusZone\shared\RCTFocusZone.m:24-35,122-129,584-675` resolves editable focus targets and key-view navigation, including a hierarchy fallback for Fabric-backed zones. - `packages\components\FocusZone\macos\RCTFocusZoneComponentView.mm:118-195` + `packages\agentic\native-core\macos\components\FocusZone\fabric\RCTFocusZoneComponentView.mm:118-195` forwards focus to its content rather than becoming a duplicate tab stop and clears default-responder state on recycle. -- **M4:** `packages\native\Callout\macos\CalloutWindow.swift:9-38`; - `packages\native\Callout\macos\CalloutView.swift:33-45,142-216`; - `packages\native\Callout\macos\RCTCalloutComponentView.mm:96-132`. +- **M4:** `packages\agentic\native-core\macos\components\Callout\shared\CalloutWindow.swift:9-38`; + `packages\agentic\native-core\macos\components\Callout\shared\CalloutView.swift:33-45,142-216`; + `packages\agentic\native-core\macos\components\Callout\fabric\RCTCalloutComponentView.mm:96-132`. Popup key-window activation, initial child focus, and a separate Fabric touch attachment are distinct concerns. - `packages\native\Callout\macos\GuardedEventMonitor.swift:1-29` owns monitor cleanup. + `packages\agentic\native-core\macos\components\Callout\shared\GuardedEventMonitor.swift:1-29` owns monitor cleanup. - **M5:** `packages\components\ContextualMenu\src\ContextualMenu.tsx:39-55` contains a macOS layout-effect/timer workaround: a readiness problem to solve, not a general timer recipe. @@ -341,7 +341,7 @@ paths. The installed Win32 JavaScript inspected was covers stable native refs and compatible replacements. - **R2:** `packages\agentic\components\src\refs.types.test.tsx:30-84` distinguishes structural and pressable root refs. - `packages\native\Callout\src\CalloutNativeComponent.ts:63-70` demonstrates + `packages\agentic\native-core\src\specs\components\CalloutNativeComponent.ts:63-70` demonstrates typed native commands with host refs rather than global tag arguments. ### macOS adaptation decisions diff --git a/packages/agentic/components/package.json b/packages/agentic/components/package.json index 5a5783aa184..846c5c4527c 100644 --- a/packages/agentic/components/package.json +++ b/packages/agentic/components/package.json @@ -40,14 +40,13 @@ "update-snapshots": "fluentui-scripts jest -u" }, "dependencies": { - "@fluentui-react-native/callout": "workspace:*", "@fluentui-react-native/design": "workspace:*", - "@fluentui-react-native/framework-base": "workspace:*" + "@fluentui-react-native/framework-base": "workspace:*", + "@fluentui-react-native/native-core": "workspace:*" }, "devDependencies": { "@babel/core": "catalog:", "@fluentui-react-native/desktop-driver": "workspace:*", - "@fluentui-react-native/focus-zone": "workspace:*", "@fluentui-react-native/scripts": "workspace:*", "@fluentui-react-native/storybook-desktop": "workspace:*", "@office-iss/react-native-win32": "^0.81.0", @@ -94,7 +93,7 @@ "jestPlatform": "macos", "knip": { "ignoreDependencies": [ - "@fluentui-react-native/callout" + "@fluentui-react-native/native-core" ] } }, diff --git a/packages/agentic/components/src/primitives/focus-zone/focus-zone.stories.tsx b/packages/agentic/components/src/primitives/focus-zone/focus-zone.stories.tsx index bb86787ff35..15af215ab21 100644 --- a/packages/agentic/components/src/primitives/focus-zone/focus-zone.stories.tsx +++ b/packages/agentic/components/src/primitives/focus-zone/focus-zone.stories.tsx @@ -4,8 +4,8 @@ import { Platform, Pressable, StyleSheet, Text, View } from 'react-native'; import type { StyleProp, ViewStyle } from 'react-native'; import type { WdioStory } from '@fluentui-react-native/storybook-desktop/testing'; -import { FocusZone } from '@fluentui-react-native/focus-zone'; -import type { FocusZoneDirection, FocusZoneProps, FocusZoneTabNavigation } from '@fluentui-react-native/focus-zone'; +import { FocusZone } from '@fluentui-react-native/native-core/legacy'; +import type { FocusZoneDirection, FocusZoneProps, FocusZoneTabNavigation } from '@fluentui-react-native/native-core/legacy'; import type { Meta, StoryObj } from '@storybook/react-native'; import { Button } from '../../components/button/button'; diff --git a/packages/agentic/components/tsconfig.json b/packages/agentic/components/tsconfig.json index 1b9942a25ad..965178a7ed8 100644 --- a/packages/agentic/components/tsconfig.json +++ b/packages/agentic/components/tsconfig.json @@ -9,9 +9,6 @@ "include": ["src"], "exclude": ["**/*.stories.ts", "**/*.stories.tsx", "**/*.story-helpers.tsx", "**/*.wdio.ts"], "references": [ - { - "path": "../../native/Callout/tsconfig.json" - }, { "path": "../design/tsconfig.json" }, @@ -19,16 +16,16 @@ "path": "../desktop-driver/tsconfig.json" }, { - "path": "../storybook-desktop/tsconfig.json" + "path": "../../framework-base/tsconfig.json" }, { - "path": "../../components/FocusZone/tsconfig.json" + "path": "../native-core/tsconfig.json" }, { - "path": "../../framework-base/tsconfig.json" + "path": "../../../scripts/tsconfig.json" }, { - "path": "../../../scripts/tsconfig.json" + "path": "../storybook-desktop/tsconfig.json" } ] } diff --git a/packages/native/Callout/FRNCallout.podspec b/packages/agentic/native-core/FRNNativeCore.podspec similarity index 82% rename from packages/native/Callout/FRNCallout.podspec rename to packages/agentic/native-core/FRNNativeCore.podspec index 5a46aedb2aa..3165e1234c2 100644 --- a/packages/native/Callout/FRNCallout.podspec +++ b/packages/agentic/native-core/FRNNativeCore.podspec @@ -3,8 +3,8 @@ require 'json' package = JSON.parse(File.read(File.join(__dir__, 'package.json'))) Pod::Spec.new do |s| - s.name = 'FRNCallout' - s.module_name = 'FRNCallout' + s.name = 'FRNNativeCore' + s.module_name = 'FRNNativeCore' s.version = package['version'] s.summary = package['description'] s.license = package['license'] @@ -16,7 +16,7 @@ Pod::Spec.new do |s| s.swift_version = "5" s.osx.deployment_target = "10.15" - s.osx.source_files = "macos/*.{swift,h,m,mm}" + s.osx.source_files = "macos/**/*.{swift,h,m,mm}" s.dependency 'React' diff --git a/packages/native/Callout/NuGet.config b/packages/agentic/native-core/NuGet.config similarity index 100% rename from packages/native/Callout/NuGet.config rename to packages/agentic/native-core/NuGet.config diff --git a/packages/agentic/native-core/README.md b/packages/agentic/native-core/README.md new file mode 100644 index 00000000000..94f76086e5f --- /dev/null +++ b/packages/agentic/native-core/README.md @@ -0,0 +1,251 @@ +# Native Core + +`@fluentui-react-native/native-core` is the shared home for new native-backed +components and non-UI native modules. JavaScript should generally be a thin, +typed wrapper around native behavior, not a second implementation of it. +Higher-order Fluent components, theming, and composition remain in their +existing packages and can consume this package without introducing a reverse +dependency. + +## Current contents + +The existing unstyled `Callout` and `FocusZone` JavaScript wrappers, public +types, tests, stories, and specifications live under `src/legacy` and are +exported only from `@fluentui-react-native/native-core/legacy`. They are not +exported by the root entrypoint, which is reserved for modern cross-platform +APIs. The `macos`, `windows`, `win`, and `win32` entrypoints are reserved for +future host-specific APIs and remain empty. + +`@fluentui-react-native/callout` and `@fluentui-react-native/focus-zone` are +JS-only compatibility shims under `packages/shim`. Deprecated type aliases and +native registration names are preserved. The legacy entrypoint uses the +component-qualified `FocusZoneNativeProps`; the FocusZone shim retains its old +`NativeProps` name. + +```ts +import { Callout, FocusZone } from '@fluentui-react-native/native-core/legacy'; +import type { CalloutProps, FocusZoneProps } from '@fluentui-react-native/native-core/legacy'; +``` + +Native implementations and shared codegen inputs remain outside `src/legacy`; +the legacy boundary applies to the JavaScript component API, not native +ownership or renderer support. + +Native applications must directly depend on this package for autolinking. +macOS now uses one `FRNNativeCore` pod, and Windows uses one +`FRNNativeCore.ReactPackageProvider` library for both components. Remove +explicit old `FRNCallout`/`RCTFocusZone` pod or standalone Windows project +references and regenerate the consuming native project/Pods. Win32 continues +to use its host-provided `RCTCallout` and `RCTFocusZone`. + +The macOS module-named header at `macos/shared/FRNNativeCore.h` is required by +the generated `FRNNativeCore-Swift.h`; keep it aligned with the pod's +`module_name` when changing native ownership. + +## Public entrypoints + +| Import | Scope | Source entrypoint | +| -------------------------------------------- | ------------------------------------------- | ---------------------- | +| `@fluentui-react-native/native-core` | Cross-platform APIs | `src/index.ts` | +| `@fluentui-react-native/native-core/legacy` | Legacy Callout/FocusZone wrappers and types | `src/legacy/index.ts` | +| `@fluentui-react-native/native-core/macos` | macOS-specific APIs | `src/macos/index.ts` | +| `@fluentui-react-native/native-core/windows` | React Native Windows-specific APIs | `src/windows/index.ts` | +| `@fluentui-react-native/native-core/win` | APIs shared by Windows and Win32 | `src/win/index.ts` | +| `@fluentui-react-native/native-core/win32` | Office React Native Win32-specific APIs | `src/win32/index.ts` | + +Each entrypoint explicitly exports components, module facades, and their +public types. The root does not re-export legacy or platform submodules; +`win` is not an umbrella export of `windows` and `win32`. Give an API its +narrowest applicable public home. Shared implementation does not itself make +an API cross-platform. + +Root exports require equivalent implementations on all supported desktop +hosts: macOS, React Native Windows, and Win32. Additional platform support +must be stated and verified per API; this initialization does not promise +iOS or Android support. A `win` export must work on both Windows hosts, +despite their potentially different native implementations. + +Keep platform imports behind the corresponding entrypoint and implementation +file. Importing one entrypoint must not initialize another platform's native +components or module registry. Keep schemas, generated bindings, registration, +and internal helpers private; the export map deliberately disallows deep +imports. Never use wildcard re-exports. + +## JavaScript and specification layout + +Legacy wrappers live in `src/legacy/callout` and `src/legacy/focus-zone`, with +shared codegen inputs in `src/specs/components`. Reserve `src/components` for +modern wrappers and add module/internal directories as real features arrive: + +```text +src/ + index.ts + macos/index.ts + windows/index.ts + win/index.ts + win32/index.ts + legacy/ + index.ts Explicit legacy-only public exports + callout/ Existing Callout wrapper, types, tests, and stories + focus-zone/ Existing FocusZone wrapper, types, and tests + components/ + / + .tsx Thin public wrapper, when shared + .types.ts Public props, events, commands, and refs + ..tsx Platform binding when needed + .test.tsx Wrapper behavior tests + .types.test.ts Public type contract + SPEC.md Supported platforms and renderer behavior + modules/ + / + .ts Typed public facade over a native module + ..ts Platform binding when needed + .test.ts Facade and error propagation tests + SPEC.md Availability, threading, events, and lifetime + specs/ + components/ + NativeComponent.ts Fabric props, events, and native commands + modules/ + Native.ts TurboModule interface + internal/ Private shared boundary utilities, as needed +``` + +Use React Native codegen-compatible schemas as the JS/native source of truth. +Keep public ergonomic props separate from the lower-level native schema only +when translation is necessary. Native component wrappers forward props, +events, commands, children, and native refs; module facades normalize only +the behavior needed for the public contract. + +Use `.macos`, `.windows`, and `.win32` implementation files for real host +differences. `win` is a package scope, not a Metro platform extension. Keep +React Native fork imports out of the shared TypeScript type graph; use +platform-specific files or platform-neutral shapes. Missing required native +registrations must surface a descriptive error, not a no-op component or a +success-shaped module fallback. + +## Native layout and architecture + +The planned native layout separates UI components from non-UI modules and +shares platform behavior below the renderer adapters: + +```text +macos/ + components// + shared/ AppKit view and behavior + fabric/ Fabric component-view adapter + paper/ Temporary Paper view-manager adapter + modules// TurboModule implementation and required glue + shared/ Platform utilities used by multiple features + registration/ Component and module provider wiring +windows/ + NativeCore/ + components// Fabric component views + modules// TurboModule implementations + shared/ C++/WinRT platform utilities + registration/ ReactPackageProvider wiring + codegen/ Generated Windows bindings, never hand-edited +win32/ Host-specific integration, only when needed +FRNNativeCore.podspec macOS sources and native dependencies +react-native.config.cjs Native project discovery/autolinking +``` + +| Host | Native component policy | Non-UI module policy | +| -------------------------------- | --------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | +| React Native Windows (`windows`) | Fabric only; no new Paper view managers or fallback path | TurboModules, with host support verified per module | +| macOS (`macos`) | Both Paper and Fabric initially; Fabric-only long term | TurboModules; add narrowly scoped legacy-host glue only when required and verified | +| Office Win32 (`win32`) | Explicit host contract per feature; do not assume the RNW Fabric implementation is compatible | Explicit host registration and module availability per feature | + +On macOS, Paper and Fabric adapters must expose the same props, events, +commands, refs, and behavior while delegating to shared AppKit logic. +Keep Paper-specific code in `paper/` and guard native compilation with the +host's architecture configuration. Retire that adapter after supported macOS +hosts become Fabric-only, without changing the public JS API. + +The Windows component project must require the New Architecture and fail +clearly for a Paper build. Use the repository's +[Windows Fabric native component reference](../../../.github/skills/agentic-component-authoring/references/windows-fabric-native-components.md) +and verify APIs against the installed RNW version. +Win32 integration is separate from React Native Windows Paper support; adding +a Win32 export does not authorize a second RNW view-manager implementation. + +Component renderer support and TurboModule availability are separate +capabilities. Do not infer module availability solely from Fabric being +enabled. Modules own their native threading, resource cleanup, event +subscriptions, and cancellation contracts; wrappers preserve those contracts +and expose native failures. + +## Codegen, registration, and publishing plan + +The shared native build metadata follows this organization: + +1. Use one package-level codegen identity, `FRNNativeCoreSpec`, with + `type: "all"` and `jsSrcsDir: "src/specs"` so components and modules remain + distinct in source but share a generation boundary. +2. Name component schemas `NativeComponent.ts` and module schemas + `Native.ts`. Prefix native registration names with `FRNNativeCore` + for new APIs to avoid collisions. Migrated Callout and FocusZone retain + their existing Fabric and Paper names for compatibility. Keep names + identical in the schema, generated interface, registration, and JS binding. +3. Configure Windows with both `componentsWindows` and `modulesWindows` + generators and `windows/NativeCore/codegen` output. Apple codegen should + run through the consuming macOS app's Pod integration. Inspect each + platform's generated schema and provider list so platform-only APIs do + not require registration on unrelated hosts. +4. Leave `includesGeneratedCode` unset unless generated artifacts for every + supported native platform are deliberately shipped and verified. It is + not a Windows-only switch and can prevent Apple code generation. +5. The macOS podspec includes both components' shared and Paper sources. + Fabric component views retain their `RCT_NEW_ARCH_ENABLED` guards. Paper + managers remain available for existing bridge interoperability until the + supported macOS hosts are Fabric-only. Windows declares `RnwNewArchOnly` + and registers both components through one package provider. +6. Keep native targets and required generated outputs in the published + archive. The `files` allowlist includes `src`, `lib`, `macos`, + `windows`, `win32`, podspecs, and `react-native.config.cjs`. Intermediate + native build artifacts, tests, and machine-local project output must not + leak into it. +7. Verify the packed package in consuming hosts before replacing an existing + package. Migrations are separate changes with compatibility evidence, not + implicit effects of adding this workspace. + +## Delivery and validation + +Add each feature as one reviewed contract, thin wrapper/schema, native +implementation, explicit export, and tests. The component codegen path is +exercised by Callout and FocusZone; add a representative TurboModule before +claiming module readiness. +macOS component admission requires both Paper and Fabric evidence; Windows +component admission requires Fabric evidence. A `win` or root API also +requires Win32 evidence before it is exported there. + +Run the owning workspace's scripts from the repository root: + +```sh +yarn workspace @fluentui-react-native/native-core format --check +yarn workspace @fluentui-react-native/native-core lint +yarn workspace @fluentui-react-native/native-core build +yarn workspace @fluentui-react-native/native-core test +yarn workspace @fluentui-react-native/native-core codegen:windows --check +yarn build +``` + +Node tests validate the six export maps, emitted JS/declaration files, +conditional resolution, shared native ownership, and JS-only shims. Colocated +Jest tests retain wrapper behavior, imperative refs/commands, slot acceptance, +and public type contracts; shim tests verify exact component identity. +Runtime and compile-time checks reject legacy component/type exports at root. +The package prebuild regenerates Windows bindings from the shared spec. +Native +verification must cover registration, events/commands, refs, unmount cleanup, +error propagation, and architecture/platform parity, not only JS mocks. +Callout's executable macOS Fabric story verifies native popup creation, `onShow` and +`onDismiss`, outside-click dismissal, and reopening. Run it together +with FocusZone's keyboard cases from `apps/storybook` using the owned lifecycle: + +```sh +STORYBOOK_SMOKE_STORY='native-*' yarn storybook smoke --macos --mode stories-and-tests +``` + +This traverses the full catalog before running the selected native tests. +The macOS Desktop Driver currently targets Fabric; a successful Paper build +does not establish Paper runtime or input parity. diff --git a/packages/components/FocusZone/jest.config.cjs b/packages/agentic/native-core/jest.config.cjs similarity index 100% rename from packages/components/FocusZone/jest.config.cjs rename to packages/agentic/native-core/jest.config.cjs diff --git a/packages/native/Callout/macos/RCTCalloutComponentView.h b/packages/agentic/native-core/macos/components/Callout/fabric/RCTCalloutComponentView.h similarity index 100% rename from packages/native/Callout/macos/RCTCalloutComponentView.h rename to packages/agentic/native-core/macos/components/Callout/fabric/RCTCalloutComponentView.h diff --git a/packages/native/Callout/macos/RCTCalloutComponentView.mm b/packages/agentic/native-core/macos/components/Callout/fabric/RCTCalloutComponentView.mm similarity index 95% rename from packages/native/Callout/macos/RCTCalloutComponentView.mm rename to packages/agentic/native-core/macos/components/Callout/fabric/RCTCalloutComponentView.mm index 86a6d5a259e..2dee187651e 100644 --- a/packages/native/Callout/macos/RCTCalloutComponentView.mm +++ b/packages/agentic/native-core/macos/components/Callout/fabric/RCTCalloutComponentView.mm @@ -2,10 +2,10 @@ #import "RCTCalloutComponentView.h" -#import -#import -#import -#import +#import +#import +#import +#import #import #import @@ -13,7 +13,7 @@ #import #import -#import "FRNCallout-Swift.h" +#import "FRNNativeCore-Swift.h" using namespace facebook::react; diff --git a/packages/native/Callout/macos/CalloutManager.swift b/packages/agentic/native-core/macos/components/Callout/paper/CalloutManager.swift similarity index 100% rename from packages/native/Callout/macos/CalloutManager.swift rename to packages/agentic/native-core/macos/components/Callout/paper/CalloutManager.swift diff --git a/packages/native/Callout/macos/FRNCalloutManager.h b/packages/agentic/native-core/macos/components/Callout/paper/FRNCalloutManager.h similarity index 100% rename from packages/native/Callout/macos/FRNCalloutManager.h rename to packages/agentic/native-core/macos/components/Callout/paper/FRNCalloutManager.h diff --git a/packages/native/Callout/macos/FRNCalloutManager.m b/packages/agentic/native-core/macos/components/Callout/paper/FRNCalloutManager.m similarity index 98% rename from packages/native/Callout/macos/FRNCalloutManager.m rename to packages/agentic/native-core/macos/components/Callout/paper/FRNCalloutManager.m index ca5ebd4b58f..f162f6cc3b3 100644 --- a/packages/native/Callout/macos/FRNCalloutManager.m +++ b/packages/agentic/native-core/macos/components/Callout/paper/FRNCalloutManager.m @@ -1,6 +1,6 @@ #import "FRNCalloutManager.h" -#import "FRNCallout-Swift.h" +#import "FRNNativeCore-Swift.h" @implementation RCTConvert (FRNCalloutAdditions) diff --git a/packages/native/Callout/macos/CalloutView.swift b/packages/agentic/native-core/macos/components/Callout/shared/CalloutView.swift similarity index 100% rename from packages/native/Callout/macos/CalloutView.swift rename to packages/agentic/native-core/macos/components/Callout/shared/CalloutView.swift diff --git a/packages/native/Callout/macos/CalloutWindow.swift b/packages/agentic/native-core/macos/components/Callout/shared/CalloutWindow.swift similarity index 100% rename from packages/native/Callout/macos/CalloutWindow.swift rename to packages/agentic/native-core/macos/components/Callout/shared/CalloutWindow.swift diff --git a/packages/native/Callout/macos/FlippedVisualEffectView.swift b/packages/agentic/native-core/macos/components/Callout/shared/FlippedVisualEffectView.swift similarity index 100% rename from packages/native/Callout/macos/FlippedVisualEffectView.swift rename to packages/agentic/native-core/macos/components/Callout/shared/FlippedVisualEffectView.swift diff --git a/packages/native/Callout/macos/GuardedEventMonitor.swift b/packages/agentic/native-core/macos/components/Callout/shared/GuardedEventMonitor.swift similarity index 100% rename from packages/native/Callout/macos/GuardedEventMonitor.swift rename to packages/agentic/native-core/macos/components/Callout/shared/GuardedEventMonitor.swift diff --git a/packages/components/FocusZone/macos/RCTFocusZoneComponentView.h b/packages/agentic/native-core/macos/components/FocusZone/fabric/RCTFocusZoneComponentView.h similarity index 100% rename from packages/components/FocusZone/macos/RCTFocusZoneComponentView.h rename to packages/agentic/native-core/macos/components/FocusZone/fabric/RCTFocusZoneComponentView.h diff --git a/packages/components/FocusZone/macos/RCTFocusZoneComponentView.mm b/packages/agentic/native-core/macos/components/FocusZone/fabric/RCTFocusZoneComponentView.mm similarity index 94% rename from packages/components/FocusZone/macos/RCTFocusZoneComponentView.mm rename to packages/agentic/native-core/macos/components/FocusZone/fabric/RCTFocusZoneComponentView.mm index 2905eb6fbb7..8326d4d086c 100644 --- a/packages/components/FocusZone/macos/RCTFocusZoneComponentView.mm +++ b/packages/agentic/native-core/macos/components/FocusZone/fabric/RCTFocusZoneComponentView.mm @@ -2,14 +2,14 @@ #import "RCTFocusZoneComponentView.h" -#import -#import -#import -#import +#import +#import +#import +#import #import -#import "RCTFocusZone.h" +#import "../shared/RCTFocusZone.h" using namespace facebook::react; diff --git a/packages/components/FocusZone/macos/RCTFocusZoneManager.h b/packages/agentic/native-core/macos/components/FocusZone/paper/RCTFocusZoneManager.h similarity index 100% rename from packages/components/FocusZone/macos/RCTFocusZoneManager.h rename to packages/agentic/native-core/macos/components/FocusZone/paper/RCTFocusZoneManager.h diff --git a/packages/components/FocusZone/macos/RCTFocusZoneManager.m b/packages/agentic/native-core/macos/components/FocusZone/paper/RCTFocusZoneManager.m similarity index 97% rename from packages/components/FocusZone/macos/RCTFocusZoneManager.m rename to packages/agentic/native-core/macos/components/FocusZone/paper/RCTFocusZoneManager.m index 68b93f136be..7d4eddaa480 100644 --- a/packages/components/FocusZone/macos/RCTFocusZoneManager.m +++ b/packages/agentic/native-core/macos/components/FocusZone/paper/RCTFocusZoneManager.m @@ -1,4 +1,4 @@ -#import "RCTFocusZone.h" +#import "../shared/RCTFocusZone.h" #import "RCTFocusZoneManager.h" #import #import diff --git a/packages/components/FocusZone/macos/KeyCodes.h b/packages/agentic/native-core/macos/components/FocusZone/shared/KeyCodes.h similarity index 100% rename from packages/components/FocusZone/macos/KeyCodes.h rename to packages/agentic/native-core/macos/components/FocusZone/shared/KeyCodes.h diff --git a/packages/components/FocusZone/macos/RCTFocusZone.h b/packages/agentic/native-core/macos/components/FocusZone/shared/RCTFocusZone.h similarity index 100% rename from packages/components/FocusZone/macos/RCTFocusZone.h rename to packages/agentic/native-core/macos/components/FocusZone/shared/RCTFocusZone.h diff --git a/packages/components/FocusZone/macos/RCTFocusZone.m b/packages/agentic/native-core/macos/components/FocusZone/shared/RCTFocusZone.m similarity index 100% rename from packages/components/FocusZone/macos/RCTFocusZone.m rename to packages/agentic/native-core/macos/components/FocusZone/shared/RCTFocusZone.m diff --git a/packages/agentic/native-core/macos/shared/FRNNativeCore.h b/packages/agentic/native-core/macos/shared/FRNNativeCore.h new file mode 100644 index 00000000000..8c039ee640e --- /dev/null +++ b/packages/agentic/native-core/macos/shared/FRNNativeCore.h @@ -0,0 +1,2 @@ +// The generated FRNNativeCore-Swift.h imports this module-named interoperability header. +#pragma once diff --git a/packages/agentic/native-core/package.json b/packages/agentic/native-core/package.json new file mode 100644 index 00000000000..f73334bcbc0 --- /dev/null +++ b/packages/agentic/native-core/package.json @@ -0,0 +1,182 @@ +{ + "name": "@fluentui-react-native/native-core", + "version": "0.0.1", + "description": "Modern native components and modules for Fluent UI React Native.", + "license": "MIT", + "author": "", + "repository": { + "type": "git", + "url": "https://github.com/microsoft/fluentui-react-native.git", + "directory": "packages/agentic/native-core" + }, + "files": [ + "lib", + "src", + "macos", + "windows", + "win32", + "NuGet.config", + "*.podspec", + "react-native.config.cjs", + "!src/**/__tests__/**", + "!src/**/*.test.*", + "!lib/**/__tests__/**", + "!lib/**/*.test.*", + "!windows/**/obj/**", + "!windows/**/x64/**", + "!windows/**/ARM64/**", + "!windows/**/Win32/**", + "!windows/**/Generated Files/**", + "!windows/**/packages/**" + ], + "type": "module", + "sideEffects": false, + "main": "lib/index.js", + "module": "lib/index.js", + "types": "lib/index.d.ts", + "exports": { + ".": { + "types": "./lib/index.d.ts", + "react-native": "./src/index.ts", + "import": "./lib/index.js", + "default": "./src/index.ts" + }, + "./legacy": { + "types": "./lib/legacy/index.d.ts", + "react-native": "./src/legacy/index.ts", + "import": "./lib/legacy/index.js", + "default": "./src/legacy/index.ts" + }, + "./macos": { + "types": "./lib/macos/index.d.ts", + "react-native": "./src/macos/index.ts", + "import": "./lib/macos/index.js", + "default": "./src/macos/index.ts" + }, + "./windows": { + "types": "./lib/windows/index.d.ts", + "react-native": "./src/windows/index.ts", + "import": "./lib/windows/index.js", + "default": "./src/windows/index.ts" + }, + "./win": { + "types": "./lib/win/index.d.ts", + "react-native": "./src/win/index.ts", + "import": "./lib/win/index.js", + "default": "./src/win/index.ts" + }, + "./win32": { + "types": "./lib/win32/index.d.ts", + "react-native": "./src/win32/index.ts", + "import": "./lib/win32/index.js", + "default": "./src/win32/index.ts" + }, + "./package.json": "./package.json" + }, + "scripts": { + "build": "tsc -b", + "clean": "fluentui-scripts clean", + "codegen:windows": "react-native codegen-windows --no-telemetry", + "format": "fluentui-scripts format", + "lint": "fluentui-scripts lint", + "prebuild": "yarn codegen:windows", + "test": "yarn build && yarn test:stories && node --test tests/entrypoints.test.mjs tests/native-ownership.test.mjs && fluentui-scripts jest", + "test:stories": "tsc -p tsconfig.stories.json", + "update-snapshots": "fluentui-scripts jest -u" + }, + "dependencies": { + "@fluentui-react-native/framework-base": "workspace:*", + "@fluentui-react-native/interactive-hooks": "workspace:*" + }, + "devDependencies": { + "@babel/core": "catalog:", + "@fluentui-react-native/scripts": "workspace:*", + "@fluentui-react-native/storybook-desktop": "workspace:*", + "@office-iss/react-native-win32": "^0.81.8", + "@react-native-community/cli": "^20.0.0", + "@react-native-community/cli-platform-android": "^20.0.0", + "@react-native-community/cli-platform-ios": "^20.0.0", + "@react-native-windows/cli": "^0.81.0", + "@react-native/babel-preset": "^0.81.0", + "@react-native/metro-config": "^0.81.0", + "@storybook/react-native": "^10.4.7", + "@testing-library/react-native": "catalog:", + "@types/react": "~19.1.4", + "@types/react-test-renderer": "^19.1.0", + "react": "19.1.4", + "react-native": "^0.81.6", + "react-native-macos": "^0.81.0", + "react-native-windows": "^0.81.0", + "react-test-renderer": "19.1.4", + "storybook": "^10.4.0", + "test-renderer": "catalog:" + }, + "peerDependencies": { + "@office-iss/react-native-win32": "^0.74.0 || ^0.81.0", + "@types/react": "~18.2.0 || ~19.0.0 || ~19.1.4", + "react": "18.2.0 || 19.0.0 || 19.1.4", + "react-native": "^0.73.0 || ^0.74.0 || ^0.78.0 || ^0.81.6", + "react-native-macos": "^0.73.0 || ^0.74.0 || ^0.78.0 || ^0.81.0", + "react-native-windows": "^0.73.0 || ^0.74.0 || ^0.78.0 || ^0.81.0" + }, + "peerDependenciesMeta": { + "@office-iss/react-native-win32": { + "optional": true + }, + "@types/react": { + "optional": true + }, + "react-native-macos": { + "optional": true + }, + "react-native-windows": { + "optional": true + } + }, + "codegenConfig": { + "name": "FRNNativeCoreSpec", + "type": "all", + "jsSrcsDir": "src/specs", + "ios": { + "componentProvider": { + "Callout": "RCTCalloutComponentView", + "FocusZone": "RCTFocusZoneComponentView" + } + }, + "windows": { + "generators": [ + "componentsWindows", + "modulesWindows" + ], + "namespace": "FRNNativeCoreCodegen", + "outputDirectory": "windows/NativeCore/codegen", + "separateDataTypes": true + } + }, + "furn": { + "jestPlatform": "win32" + }, + "react-native-windows": { + "init-windows": { + "name": "FRNNativeCore", + "namespace": "FRNNativeCore", + "template": "cpp-lib" + } + }, + "rnx-kit": { + "kitType": "library", + "alignDeps": { + "capabilities": [ + "babel-preset-react-native", + "core", + "core-android", + "core-ios", + "core-macos", + "core-windows", + "react", + "react-test-renderer" + ] + }, + "extends": "@fluentui-react-native/scripts/kit-config" + } +} diff --git a/packages/native/Callout/react-native.config.cjs b/packages/agentic/native-core/react-native.config.cjs similarity index 78% rename from packages/native/Callout/react-native.config.cjs rename to packages/agentic/native-core/react-native.config.cjs index 5046885ab4d..d495c666a0b 100644 --- a/packages/native/Callout/react-native.config.cjs +++ b/packages/agentic/native-core/react-native.config.cjs @@ -5,7 +5,7 @@ module.exports = { sourceDir: 'windows', projects: [ { - projectFile: 'Callout/Callout.vcxproj', + projectFile: 'NativeCore/NativeCore.vcxproj', directDependency: true, }, ], diff --git a/packages/agentic/native-core/src/index.ts b/packages/agentic/native-core/src/index.ts new file mode 100644 index 00000000000..cb0ff5c3b54 --- /dev/null +++ b/packages/agentic/native-core/src/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/native/Callout/src/Callout.stories.tsx b/packages/agentic/native-core/src/legacy/callout/Callout.stories.tsx similarity index 82% rename from packages/native/Callout/src/Callout.stories.tsx rename to packages/agentic/native-core/src/legacy/callout/Callout.stories.tsx index 6ae0691aafc..c139f7a9fb6 100644 --- a/packages/native/Callout/src/Callout.stories.tsx +++ b/packages/agentic/native-core/src/legacy/callout/Callout.stories.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import { Pressable, StyleSheet, Text, View } from 'react-native'; +import type { WdioStory } from '@fluentui-react-native/storybook-desktop/testing'; import type { Meta, StoryObj } from '@storybook/react-native'; import { Callout } from './Callout'; @@ -48,6 +49,11 @@ const CalloutExample = ({ defaultVisible = false, onDismiss, onShow, showWindowC return ( + + + Native window: {status} + + {visible ? 'Close callout' : 'Open callout'} - - Native window: {status} - {visible && ( @@ -177,10 +180,37 @@ const meta: Meta = { export default meta; -type Story = StoryObj; +type Story = WdioStory>; export const Default: Story = { + tags: ['desktop-e2e'], render: (args) => , + wdio: { + 'macOS opens, dismisses, and recreates a native popup window': async ({ browser, expect, platform, skip }) => { + if (platform !== 'macos') { + skip('This case verifies the AppKit popup-window lifecycle.'); + return; + } + const features = browser.capabilities['furn:features']; + if (!features?.physicalClick) { + skip('Popup lifecycle qualification requires physical pointer input.'); + return; + } + for (let attempt = 0; attempt < 2; attempt++) { + await expect(await browser.$('~agentic-storybook-callout-status')).toHaveText('Native window: Shown'); + expect(await browser.getWindowHandles()).toHaveLength(2); + await (await browser.$('~agentic-storybook-callout-status')).click(); + await browser.waitUntil(async () => (await browser.getWindowHandles()).length === 1, { + timeout: 5000, + timeoutMsg: 'Expected dismissal to remove the native Callout window.', + }); + await expect(await browser.$('~agentic-storybook-callout-status')).toHaveText('Native window: Dismissed'); + if (attempt === 0) { + await (await browser.$('~agentic-storybook-callout-trigger')).click(); + } + } + }, + }, }; export const Placement: Story = { @@ -252,7 +282,7 @@ const styles = StyleSheet.create({ }, status: { color: '#616161', - marginTop: 12, + marginBottom: 12, }, story: { alignItems: 'center', diff --git a/packages/native/Callout/src/Callout.tsx b/packages/agentic/native-core/src/legacy/callout/Callout.tsx similarity index 97% rename from packages/native/Callout/src/Callout.tsx rename to packages/agentic/native-core/src/legacy/callout/Callout.tsx index 6d0a9e33e39..b9fdd5da92b 100644 --- a/packages/native/Callout/src/Callout.tsx +++ b/packages/agentic/native-core/src/legacy/callout/Callout.tsx @@ -6,7 +6,7 @@ import { directComponent, mergeProps, phasedComponent } from '@fluentui-react-na import type { CalloutProps } from './Callout.types'; import { calloutName } from './Callout.types'; -import NativeCalloutView, { Commands } from './CalloutNativeComponent'; +import NativeCalloutView, { Commands } from '../../specs/components/CalloutNativeComponent'; const colorTransparent = '#00000000'; diff --git a/packages/native/Callout/src/Callout.types.ts b/packages/agentic/native-core/src/legacy/callout/Callout.types.ts similarity index 100% rename from packages/native/Callout/src/Callout.types.ts rename to packages/agentic/native-core/src/legacy/callout/Callout.types.ts diff --git a/packages/native/Callout/SPEC.md b/packages/agentic/native-core/src/legacy/callout/SPEC.md similarity index 70% rename from packages/native/Callout/SPEC.md rename to packages/agentic/native-core/src/legacy/callout/SPEC.md index 92fd3b3497c..1e48b41be8b 100644 --- a/packages/native/Callout/SPEC.md +++ b/packages/agentic/native-core/src/legacy/callout/SPEC.md @@ -4,8 +4,11 @@ Callout is an unstyled native primitive that presents children in transient UI positioned relative to a target ref, registered native anchor, or anchor -rectangle. It remains a standalone package because it owns native code and -CocoaPods integration. +rectangle. Its JS wrapper, native adapters, and codegen schema are owned by +`@fluentui-react-native/native-core`; the old Callout package is a JS-only shim. + +The JavaScript component and its public types are exported only from +`@fluentui-react-native/native-core/legacy`, not the package root. ## Contract @@ -27,8 +30,8 @@ CocoaPods integration. - macOS presents children in a native popup window and supports window focus commands through both Paper and Fabric component registrations. -- Windows uses the platform's built-in Paper `RCTCallout` and supplies a - package-owned Fabric registration for React Native Windows 0.81 and newer. +- Windows uses native-core's Fabric registration for React Native Windows + 0.81 and newer. Native-core supplies no Windows Paper implementation. - Win32 supplies the platform `RCTCallout` implementation and supports native dismissal, pointer capture, beak, and focus-restoration behavior. - Unsupported native behavior remains platform-defined rather than being @@ -37,7 +40,11 @@ CocoaPods integration. ## Compatibility `ICalloutProps`, `ICalloutTokens`, and `CalloutNativeCommands` remain as -deprecated aliases for the modern public types. +deprecated aliases for the public types in the legacy entrypoint. + +Existing `Callout`/`RCTCallout` native registration names remain unchanged. +Native applications must directly depend on `@fluentui-react-native/native-core` +so native tooling discovers the shared pod and Windows project. ## Demonstration diff --git a/packages/native/Callout/src/__tests__/Callout.test.tsx b/packages/agentic/native-core/src/legacy/callout/__tests__/Callout.test.tsx similarity index 98% rename from packages/native/Callout/src/__tests__/Callout.test.tsx rename to packages/agentic/native-core/src/legacy/callout/__tests__/Callout.test.tsx index 959a94e4fcf..bd10a9a60f3 100644 --- a/packages/native/Callout/src/__tests__/Callout.test.tsx +++ b/packages/agentic/native-core/src/legacy/callout/__tests__/Callout.test.tsx @@ -8,7 +8,7 @@ import type { SlotProp } from '@fluentui-react-native/framework-base'; import { Callout } from '../Callout'; import type { CalloutHandle } from '../Callout.types'; -import { Commands } from '../CalloutNativeComponent'; +import { Commands } from '../../../specs/components/CalloutNativeComponent'; jest.mock('react-native/Libraries/ReactNative/RendererProxy', () => ({ ...jest.requireActual('react-native/Libraries/ReactNative/RendererProxy'), diff --git a/packages/native/Callout/src/__tests__/Callout.types.test.ts b/packages/agentic/native-core/src/legacy/callout/__tests__/Callout.types.test.ts similarity index 100% rename from packages/native/Callout/src/__tests__/Callout.types.test.ts rename to packages/agentic/native-core/src/legacy/callout/__tests__/Callout.types.test.ts diff --git a/packages/native/Callout/src/__tests__/__snapshots__/Callout.test.tsx.snap b/packages/agentic/native-core/src/legacy/callout/__tests__/__snapshots__/Callout.test.tsx.snap similarity index 100% rename from packages/native/Callout/src/__tests__/__snapshots__/Callout.test.tsx.snap rename to packages/agentic/native-core/src/legacy/callout/__tests__/__snapshots__/Callout.test.tsx.snap diff --git a/packages/components/FocusZone/src/FocusZone.tsx b/packages/agentic/native-core/src/legacy/focus-zone/FocusZone.tsx similarity index 96% rename from packages/components/FocusZone/src/FocusZone.tsx rename to packages/agentic/native-core/src/legacy/focus-zone/FocusZone.tsx index 7624ee2f2bb..0430f6c1123 100644 --- a/packages/components/FocusZone/src/FocusZone.tsx +++ b/packages/agentic/native-core/src/legacy/focus-zone/FocusZone.tsx @@ -7,7 +7,7 @@ import { useViewCommandFocus } from '@fluentui-react-native/interactive-hooks'; import type { FocusZoneProps } from './FocusZone.types'; import { focusZoneName } from './FocusZone.types'; -import NativeFocusZone from './FocusZoneNativeComponent'; +import NativeFocusZone from '../../specs/components/FocusZoneNativeComponent'; /** * Renders the native FocusZone without applying theme or appearance defaults. diff --git a/packages/components/FocusZone/src/FocusZone.types.ts b/packages/agentic/native-core/src/legacy/focus-zone/FocusZone.types.ts similarity index 100% rename from packages/components/FocusZone/src/FocusZone.types.ts rename to packages/agentic/native-core/src/legacy/focus-zone/FocusZone.types.ts diff --git a/packages/components/FocusZone/SPEC.md b/packages/agentic/native-core/src/legacy/focus-zone/SPEC.md similarity index 79% rename from packages/components/FocusZone/SPEC.md rename to packages/agentic/native-core/src/legacy/focus-zone/SPEC.md index 54ce2640a9b..2abe6129059 100644 --- a/packages/components/FocusZone/SPEC.md +++ b/packages/agentic/native-core/src/legacy/focus-zone/SPEC.md @@ -3,8 +3,12 @@ ## Purpose FocusZone is an unstyled native primitive that coordinates directional and Tab -keyboard navigation among focusable descendants. It remains a standalone package -because it owns native macOS code and CocoaPods integration. +keyboard navigation among focusable descendants. Its JS wrapper, native +adapters, and codegen schema are owned by `@fluentui-react-native/native-core`; +the old FocusZone package is a JS-only shim. + +The JavaScript component and its public types are exported only from +`@fluentui-react-native/native-core/legacy`, not the package root. ## Contract @@ -45,6 +49,12 @@ because it owns native macOS code and CocoaPods integration. `FocusZoneRenderData`, and `FocusZoneType` remain as deprecated compatibility types. +Existing `FocusZone`/`RCTFocusZone` native registration names remain unchanged. +The old package's `NativeProps` export aliases native-core's +`FocusZoneNativeProps`. Native applications must directly depend on +`@fluentui-react-native/native-core` so native tooling discovers the shared pod +and Windows project. + ## Demonstration Interactive directional, circular, Tab, disabled, and default-focus scenarios diff --git a/packages/components/FocusZone/src/__tests__/FocusZone.test.tsx b/packages/agentic/native-core/src/legacy/focus-zone/__tests__/FocusZone.test.tsx similarity index 100% rename from packages/components/FocusZone/src/__tests__/FocusZone.test.tsx rename to packages/agentic/native-core/src/legacy/focus-zone/__tests__/FocusZone.test.tsx diff --git a/packages/components/FocusZone/src/__tests__/FocusZone.types.test.ts b/packages/agentic/native-core/src/legacy/focus-zone/__tests__/FocusZone.types.test.ts similarity index 100% rename from packages/components/FocusZone/src/__tests__/FocusZone.types.test.ts rename to packages/agentic/native-core/src/legacy/focus-zone/__tests__/FocusZone.types.test.ts diff --git a/packages/agentic/native-core/src/legacy/index.ts b/packages/agentic/native-core/src/legacy/index.ts new file mode 100644 index 00000000000..5ac07b734ed --- /dev/null +++ b/packages/agentic/native-core/src/legacy/index.ts @@ -0,0 +1,27 @@ +export { Callout } from './callout/Callout'; +export { calloutName } from './callout/Callout.types'; +export type { + CalloutHandle, + CalloutNativeCommands, + CalloutProps, + CalloutTokens, + DirectionalHint, + DismissBehaviors, + ICalloutProps, + ICalloutTokens, + RestoreFocusEvent, +} from './callout/Callout.types'; +export { FocusZone } from './focus-zone/FocusZone'; +export { focusZoneName } from './focus-zone/FocusZone.types'; +export type { + FocusZoneDirection, + FocusZoneProps, + FocusZoneRenderData, + FocusZoneSlotProps, + FocusZoneState, + FocusZoneTabNavigation, + FocusZoneTokens, + FocusZoneType, + NativeProps as FocusZoneNativeProps, + NavigateAtEnd, +} from './focus-zone/FocusZone.types'; diff --git a/packages/agentic/native-core/src/legacy/legacy.types.test.ts b/packages/agentic/native-core/src/legacy/legacy.types.test.ts new file mode 100644 index 00000000000..2e516f89774 --- /dev/null +++ b/packages/agentic/native-core/src/legacy/legacy.types.test.ts @@ -0,0 +1,30 @@ +import * as root from '../index'; +import { Callout, FocusZone } from './index'; +import type { CalloutProps, FocusZoneProps } from './index'; + +const calloutProps: CalloutProps = { target: 'anchor' }; +const focusZoneProps: FocusZoneProps = { focusZoneDirection: 'horizontal' }; + +// @ts-expect-error CalloutProps is available only from the legacy entrypoint. +const rootCalloutProps: root.CalloutProps = calloutProps; +// @ts-expect-error FocusZoneProps is available only from the legacy entrypoint. +const rootFocusZoneProps: root.FocusZoneProps = focusZoneProps; + +// @ts-expect-error Callout is not exported from the root entrypoint. +const rootCalloutKey: keyof typeof root = 'Callout'; +// @ts-expect-error FocusZone is not exported from the root entrypoint. +const rootFocusZoneKey: keyof typeof root = 'FocusZone'; + +describe('Legacy entrypoint types', () => { + it('exposes the wrappers only from legacy', () => { + expect(Callout).toBeDefined(); + expect(FocusZone).toBeDefined(); + expect(root).not.toHaveProperty(rootCalloutKey); + expect(root).not.toHaveProperty(rootFocusZoneKey); + }); + + it('retains the legacy public prop contracts', () => { + expect(rootCalloutProps).toBe(calloutProps); + expect(rootFocusZoneProps).toBe(focusZoneProps); + }); +}); diff --git a/packages/agentic/native-core/src/macos/index.ts b/packages/agentic/native-core/src/macos/index.ts new file mode 100644 index 00000000000..cb0ff5c3b54 --- /dev/null +++ b/packages/agentic/native-core/src/macos/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/native/Callout/src/CalloutNativeComponent.ts b/packages/agentic/native-core/src/specs/components/CalloutNativeComponent.ts similarity index 100% rename from packages/native/Callout/src/CalloutNativeComponent.ts rename to packages/agentic/native-core/src/specs/components/CalloutNativeComponent.ts diff --git a/packages/components/FocusZone/src/FocusZoneNativeComponent.ts b/packages/agentic/native-core/src/specs/components/FocusZoneNativeComponent.ts similarity index 100% rename from packages/components/FocusZone/src/FocusZoneNativeComponent.ts rename to packages/agentic/native-core/src/specs/components/FocusZoneNativeComponent.ts diff --git a/packages/components/FocusZone/src/FocusZoneNativeComponent.win32.ts b/packages/agentic/native-core/src/specs/components/FocusZoneNativeComponent.win32.ts similarity index 100% rename from packages/components/FocusZone/src/FocusZoneNativeComponent.win32.ts rename to packages/agentic/native-core/src/specs/components/FocusZoneNativeComponent.win32.ts diff --git a/packages/agentic/native-core/src/win/index.ts b/packages/agentic/native-core/src/win/index.ts new file mode 100644 index 00000000000..cb0ff5c3b54 --- /dev/null +++ b/packages/agentic/native-core/src/win/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/agentic/native-core/src/win32/index.ts b/packages/agentic/native-core/src/win32/index.ts new file mode 100644 index 00000000000..cb0ff5c3b54 --- /dev/null +++ b/packages/agentic/native-core/src/win32/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/agentic/native-core/src/windows/index.ts b/packages/agentic/native-core/src/windows/index.ts new file mode 100644 index 00000000000..cb0ff5c3b54 --- /dev/null +++ b/packages/agentic/native-core/src/windows/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/agentic/native-core/tests/entrypoints.test.mjs b/packages/agentic/native-core/tests/entrypoints.test.mjs new file mode 100644 index 00000000000..6eb5357d994 --- /dev/null +++ b/packages/agentic/native-core/tests/entrypoints.test.mjs @@ -0,0 +1,66 @@ +import assert from 'node:assert/strict'; +import { spawnSync } from 'node:child_process'; +import { access, readFile } from 'node:fs/promises'; +import test from 'node:test'; +import { fileURLToPath } from 'node:url'; + +const packageRoot = new URL('../', import.meta.url); +const manifest = JSON.parse(await readFile(new URL('package.json', packageRoot), 'utf8')); +const entrypoints = [ + ['.', 'index'], + ['./legacy', 'legacy/index'], + ['./macos', 'macos/index'], + ['./windows', 'windows/index'], + ['./win', 'win/index'], + ['./win32', 'win32/index'], +]; + +test('declares exactly the six public entrypoints and package metadata', () => { + assert.equal(manifest.name, '@fluentui-react-native/native-core'); + assert.deepEqual(Object.keys(manifest.exports), [...entrypoints.map(([entrypoint]) => entrypoint), './package.json']); + assert.equal(manifest.exports['./package.json'], './package.json'); + assert.equal(manifest.main, 'lib/index.js'); + assert.equal(manifest.module, 'lib/index.js'); + assert.equal(manifest.types, 'lib/index.d.ts'); +}); + +test('the root entrypoint does not expose or initialize legacy components', async () => { + const root = await import('@fluentui-react-native/native-core'); + assert.ok(!('Callout' in root)); + assert.ok(!('FocusZone' in root)); + assert.ok(!('calloutName' in root)); + assert.ok(!('focusZoneName' in root)); +}); + +for (const [entrypoint, path] of entrypoints) { + test(`${entrypoint} has distinct source, JavaScript, and declaration targets`, async () => { + const expected = { + types: `./lib/${path}.d.ts`, + 'react-native': `./src/${path}.ts`, + import: `./lib/${path}.js`, + default: `./src/${path}.ts`, + }; + assert.deepEqual(manifest.exports[entrypoint], expected); + assert.deepEqual(Object.keys(manifest.exports[entrypoint]), Object.keys(expected)); + await Promise.all(Object.values(expected).map((target) => access(new URL(target, packageRoot)))); + }); +} + +for (const condition of ['import', 'react-native', 'types']) { + test(`${condition} resolution selects the correct public entrypoints`, () => { + const specifiers = entrypoints.map(([entrypoint]) => manifest.name + (entrypoint === '.' ? '' : entrypoint.slice(1))); + const script = `console.log(JSON.stringify(${JSON.stringify(specifiers)}.map((specifier) => import.meta.resolve(specifier))))`; + const args = condition === 'import' ? [] : [`--conditions=${condition}`]; + const result = spawnSync(process.execPath, [...args, '--input-type=module', '--eval', script], { + cwd: fileURLToPath(packageRoot), + encoding: 'utf8', + }); + + assert.ifError(result.error); + assert.equal(result.status, 0, result.stderr); + assert.deepEqual( + JSON.parse(result.stdout), + entrypoints.map(([entrypoint]) => new URL(manifest.exports[entrypoint][condition], packageRoot).href), + ); + }); +} diff --git a/packages/agentic/native-core/tests/native-ownership.test.mjs b/packages/agentic/native-core/tests/native-ownership.test.mjs new file mode 100644 index 00000000000..ceb5ab99cea --- /dev/null +++ b/packages/agentic/native-core/tests/native-ownership.test.mjs @@ -0,0 +1,76 @@ +import assert from 'node:assert/strict'; +import { readFile, readdir } from 'node:fs/promises'; +import { createRequire } from 'node:module'; +import test from 'node:test'; + +const packageRoot = new URL('../', import.meta.url); +const manifest = JSON.parse(await readFile(new URL('package.json', packageRoot), 'utf8')); +const require = createRequire(import.meta.url); + +test('owns one codegen boundary for both native components and future modules', () => { + assert.equal(manifest.codegenConfig.name, 'FRNNativeCoreSpec'); + assert.equal(manifest.codegenConfig.type, 'all'); + assert.equal(manifest.codegenConfig.jsSrcsDir, 'src/specs'); + assert.notEqual(manifest.codegenConfig.includesGeneratedCode, true); + assert.deepEqual(manifest.codegenConfig.ios.componentProvider, { + Callout: 'RCTCalloutComponentView', + FocusZone: 'RCTFocusZoneComponentView', + }); + assert.deepEqual(manifest.codegenConfig.windows.generators, ['componentsWindows', 'modulesWindows']); +}); + +test('autolinks one Fabric-only Windows library registering both components', async () => { + const config = require('../react-native.config.cjs'); + assert.deepEqual(config.dependency.platforms.windows.projects, [ + { projectFile: 'NativeCore/NativeCore.vcxproj', directDependency: true }, + ]); + + const project = await readFile(new URL('windows/NativeCore/NativeCore.vcxproj', packageRoot), 'utf8'); + assert.match(project, /true<\/RnwNewArchOnly>/); + assert.match(project, /components\\Callout\\Callout\.cpp/); + assert.match(project, /components\\FocusZone\\FocusZoneComponentView\.cpp/); + const provider = await readFile(new URL('windows/NativeCore/ReactPackageProvider.cpp', packageRoot), 'utf8'); + assert.match(provider, /RegisterCalloutComponentView\(packageBuilder\)/); + assert.match(provider, /RegisterFocusZoneComponentView\(packageBuilder\)/); +}); + +test('the shared macOS pod includes both components and retains both renderer adapters', async () => { + const podspec = await readFile(new URL('FRNNativeCore.podspec', packageRoot), 'utf8'); + assert.match(podspec, /s\.name\s*=\s*'FRNNativeCore'/); + assert.match(podspec, /macos\/\*\*\/\*\.\{swift,h,m,mm\}/); + + for (const component of ['Callout', 'FocusZone']) { + const fabric = await readFile(new URL(`macos/components/${component}/fabric/RCT${component}ComponentView.mm`, packageRoot), 'utf8'); + assert.match(fabric, /react\/renderer\/components\/FRNNativeCoreSpec\/Props\.h/); + assert.ok((await readdir(new URL(`macos/components/${component}/paper/`, packageRoot))).length > 0); + assert.ok((await readdir(new URL(`macos/components/${component}/shared/`, packageRoot))).length > 0); + } +}); + +test('macOS Swift interoperability uses the consolidated pod module name', async () => { + const podspec = await readFile(new URL('FRNNativeCore.podspec', packageRoot), 'utf8'); + const moduleName = podspec.match(/s\.module_name\s*=\s*'([^']+)'/)?.[1]; + assert.equal(moduleName, 'FRNNativeCore'); + await readFile(new URL(`macos/shared/${moduleName}.h`, packageRoot), 'utf8'); + + for (const adapter of ['fabric/RCTCalloutComponentView.mm', 'paper/FRNCalloutManager.m']) { + const source = await readFile(new URL(`macos/components/Callout/${adapter}`, packageRoot), 'utf8'); + assert.ok(source.includes(`#import "${moduleName}-Swift.h"`)); + assert.doesNotMatch(source, /FRNCallout-Swift\.h/); + } +}); + +for (const shim of ['callout', 'focus-zone']) { + test(`${shim} is a JS-only compatibility shim with no duplicate native ownership`, async () => { + const root = new URL(`../../shim/${shim}/`, packageRoot); + const shimManifest = JSON.parse(await readFile(new URL('package.json', root), 'utf8')); + assert.equal(shimManifest.dependencies[manifest.name], 'workspace:*'); + assert.equal(shimManifest.codegenConfig, undefined); + assert.equal(shimManifest['react-native-windows'], undefined); + const files = await readdir(root); + assert.ok(!files.some((file) => file.endsWith('.podspec') || ['macos', 'windows', 'react-native.config.cjs'].includes(file))); + const entrypoint = await readFile(new URL('src/index.ts', root), 'utf8'); + assert.match(entrypoint, /from '@fluentui-react-native\/native-core\/legacy'/); + assert.doesNotMatch(entrypoint, /export \*/); + }); +} diff --git a/packages/components/FocusZone/tsconfig.json b/packages/agentic/native-core/tsconfig.json similarity index 79% rename from packages/components/FocusZone/tsconfig.json rename to packages/agentic/native-core/tsconfig.json index 243ef12c404..b8fd9ae534e 100644 --- a/packages/components/FocusZone/tsconfig.json +++ b/packages/agentic/native-core/tsconfig.json @@ -7,11 +7,8 @@ "tsBuildInfoFile": ".cache/tsconfig.tsbuildinfo" }, "include": ["src"], - "exclude": ["**/*.stories.ts", "**/*.stories.tsx"], + "exclude": ["**/*.stories.ts", "**/*.stories.tsx", "**/*.wdio.ts"], "references": [ - { - "path": "../../agentic/desktop-driver/tsconfig.json" - }, { "path": "../../framework-base/tsconfig.json" }, @@ -20,6 +17,9 @@ }, { "path": "../../../scripts/tsconfig.json" + }, + { + "path": "../storybook-desktop/tsconfig.json" } ] } diff --git a/packages/agentic/native-core/tsconfig.stories.json b/packages/agentic/native-core/tsconfig.stories.json new file mode 100644 index 00000000000..40b8e99540d --- /dev/null +++ b/packages/agentic/native-core/tsconfig.stories.json @@ -0,0 +1,19 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "composite": false, + "noImplicitAny": true, + "noEmit": true, + "tsBuildInfoFile": ".cache/tsconfig.stories.tsbuildinfo" + }, + "include": ["src/legacy/callout/Callout.stories.tsx"], + "exclude": [], + "references": [ + { + "path": "./tsconfig.json" + }, + { + "path": "../storybook-desktop/tsconfig.json" + } + ] +} diff --git a/packages/components/FocusZone/windows/.gitignore b/packages/agentic/native-core/windows/.gitignore similarity index 100% rename from packages/components/FocusZone/windows/.gitignore rename to packages/agentic/native-core/windows/.gitignore diff --git a/packages/components/FocusZone/windows/ExperimentalFeatures.props b/packages/agentic/native-core/windows/ExperimentalFeatures.props similarity index 100% rename from packages/components/FocusZone/windows/ExperimentalFeatures.props rename to packages/agentic/native-core/windows/ExperimentalFeatures.props diff --git a/packages/components/FocusZone/windows/FRNFocusZone/FRNFocusZone.def b/packages/agentic/native-core/windows/NativeCore/NativeCore.def similarity index 100% rename from packages/components/FocusZone/windows/FRNFocusZone/FRNFocusZone.def rename to packages/agentic/native-core/windows/NativeCore/NativeCore.def diff --git a/packages/components/FocusZone/windows/FRNFocusZone/FRNFocusZone.vcxproj b/packages/agentic/native-core/windows/NativeCore/NativeCore.vcxproj similarity index 94% rename from packages/components/FocusZone/windows/FRNFocusZone/FRNFocusZone.vcxproj rename to packages/agentic/native-core/windows/NativeCore/NativeCore.vcxproj index 3d23cae5051..ac701265e98 100644 --- a/packages/components/FocusZone/windows/FRNFocusZone/FRNFocusZone.vcxproj +++ b/packages/agentic/native-core/windows/NativeCore/NativeCore.vcxproj @@ -6,9 +6,9 @@ true true {85648B33-7A31-434B-ACE5-6E4F6E52EBAD} - FRNFocusZone + FRNNativeCore Win32Proj - FRNFocusZone + FRNNativeCore 10.0.22621.0 en-US @@ -92,7 +92,7 @@ user32.lib;windowsapp.lib;%(AdditionalDependencies) Console true - FRNFocusZone.def + NativeCore.def @@ -107,16 +107,17 @@ - + + ReactPackageProvider.idl - - + + Create @@ -128,9 +129,6 @@ - - - diff --git a/packages/components/FocusZone/windows/FRNFocusZone/ReactPackageProvider.cpp b/packages/agentic/native-core/windows/NativeCore/ReactPackageProvider.cpp similarity index 59% rename from packages/components/FocusZone/windows/FRNFocusZone/ReactPackageProvider.cpp rename to packages/agentic/native-core/windows/NativeCore/ReactPackageProvider.cpp index ce6933d5689..c215bf44f29 100644 --- a/packages/components/FocusZone/windows/FRNFocusZone/ReactPackageProvider.cpp +++ b/packages/agentic/native-core/windows/NativeCore/ReactPackageProvider.cpp @@ -5,20 +5,23 @@ #include "ReactPackageProvider.g.cpp" #endif -#include "FocusZoneComponentView.h" +#include "components/Callout/Callout.h" +#include "components/FocusZone/FocusZoneComponentView.h" using namespace winrt::Microsoft::ReactNative; -namespace winrt::FRNFocusZone::implementation +namespace winrt::FRNNativeCore::implementation { void ReactPackageProvider::CreatePackage(IReactPackageBuilder const &packageBuilder) noexcept { #ifdef RNW_NEW_ARCH + AddAttributedModules(packageBuilder, true); + RegisterCalloutComponentView(packageBuilder); RegisterFocusZoneComponentView(packageBuilder); #else UNREFERENCED_PARAMETER(packageBuilder); #endif } -} // namespace winrt::FRNFocusZone::implementation +} // namespace winrt::FRNNativeCore::implementation diff --git a/packages/components/FocusZone/windows/FRNFocusZone/ReactPackageProvider.h b/packages/agentic/native-core/windows/NativeCore/ReactPackageProvider.h similarity index 65% rename from packages/components/FocusZone/windows/FRNFocusZone/ReactPackageProvider.h rename to packages/agentic/native-core/windows/NativeCore/ReactPackageProvider.h index 1912fd12d3e..5d81282ff70 100644 --- a/packages/components/FocusZone/windows/FRNFocusZone/ReactPackageProvider.h +++ b/packages/agentic/native-core/windows/NativeCore/ReactPackageProvider.h @@ -4,7 +4,7 @@ using namespace winrt::Microsoft::ReactNative; -namespace winrt::FRNFocusZone::implementation +namespace winrt::FRNNativeCore::implementation { struct ReactPackageProvider : ReactPackageProviderT @@ -14,11 +14,11 @@ struct ReactPackageProvider : ReactPackageProviderT void CreatePackage(IReactPackageBuilder const &packageBuilder) noexcept; }; -} // namespace winrt::FRNFocusZone::implementation +} // namespace winrt::FRNNativeCore::implementation -namespace winrt::FRNFocusZone::factory_implementation +namespace winrt::FRNNativeCore::factory_implementation { struct ReactPackageProvider : ReactPackageProviderT {}; -} // namespace winrt::FRNFocusZone::factory_implementation +} // namespace winrt::FRNNativeCore::factory_implementation diff --git a/packages/components/FocusZone/windows/FRNFocusZone/ReactPackageProvider.idl b/packages/agentic/native-core/windows/NativeCore/ReactPackageProvider.idl similarity index 87% rename from packages/components/FocusZone/windows/FRNFocusZone/ReactPackageProvider.idl rename to packages/agentic/native-core/windows/NativeCore/ReactPackageProvider.idl index f8a01091d52..7850c2224ce 100644 --- a/packages/components/FocusZone/windows/FRNFocusZone/ReactPackageProvider.idl +++ b/packages/agentic/native-core/windows/NativeCore/ReactPackageProvider.idl @@ -1,4 +1,4 @@ -namespace FRNFocusZone +namespace FRNNativeCore { [webhosthidden] [default_interface] diff --git a/packages/components/FocusZone/windows/FRNFocusZone/codegen/.clang-format b/packages/agentic/native-core/windows/NativeCore/codegen/.clang-format similarity index 50% rename from packages/components/FocusZone/windows/FRNFocusZone/codegen/.clang-format rename to packages/agentic/native-core/windows/NativeCore/codegen/.clang-format index 9d159247d51..a43d914ec38 100644 --- a/packages/components/FocusZone/windows/FRNFocusZone/codegen/.clang-format +++ b/packages/agentic/native-core/windows/NativeCore/codegen/.clang-format @@ -1,2 +1,2 @@ DisableFormat: true -SortIncludes: false +SortIncludes: false \ No newline at end of file diff --git a/packages/native/Callout/windows/Callout/codegen/react/components/FRNCalloutSpec/Callout.g.h b/packages/agentic/native-core/windows/NativeCore/codegen/react/components/FRNNativeCoreSpec/Callout.g.h similarity index 99% rename from packages/native/Callout/windows/Callout/codegen/react/components/FRNCalloutSpec/Callout.g.h rename to packages/agentic/native-core/windows/NativeCore/codegen/react/components/FRNNativeCoreSpec/Callout.g.h index ef6731db348..072434e2c08 100644 --- a/packages/native/Callout/windows/Callout/codegen/react/components/FRNCalloutSpec/Callout.g.h +++ b/packages/agentic/native-core/windows/NativeCore/codegen/react/components/FRNNativeCoreSpec/Callout.g.h @@ -16,7 +16,7 @@ #ifdef RNW_NEW_ARCH -namespace winrt::FluentUI::Callout::Codegen { +namespace FRNNativeCoreCodegen { REACT_STRUCT(CalloutSpec_CalloutProps_anchorRect) struct CalloutSpec_CalloutProps_anchorRect { @@ -370,6 +370,6 @@ void RegisterCalloutNativeComponent( }); } -} // namespace winrt::FluentUI::Callout::Codegen +} // namespace FRNNativeCoreCodegen #endif // #ifdef RNW_NEW_ARCH diff --git a/packages/components/FocusZone/windows/FRNFocusZone/codegen/react/components/FRNFocusZoneSpec/FocusZone.g.h b/packages/agentic/native-core/windows/NativeCore/codegen/react/components/FRNNativeCoreSpec/FocusZone.g.h similarity index 99% rename from packages/components/FocusZone/windows/FRNFocusZone/codegen/react/components/FRNFocusZoneSpec/FocusZone.g.h rename to packages/agentic/native-core/windows/NativeCore/codegen/react/components/FRNNativeCoreSpec/FocusZone.g.h index da24d5e0cd3..e6e20806144 100644 --- a/packages/components/FocusZone/windows/FRNFocusZone/codegen/react/components/FRNFocusZoneSpec/FocusZone.g.h +++ b/packages/agentic/native-core/windows/NativeCore/codegen/react/components/FRNNativeCoreSpec/FocusZone.g.h @@ -16,7 +16,7 @@ #ifdef RNW_NEW_ARCH -namespace FRNFocusZoneCodegen { +namespace FRNNativeCoreCodegen { REACT_STRUCT(FocusZoneProps) struct FocusZoneProps : winrt::implements { @@ -238,6 +238,6 @@ void RegisterFocusZoneNativeComponent( }); } -} // namespace FRNFocusZoneCodegen +} // namespace FRNNativeCoreCodegen #endif // #ifdef RNW_NEW_ARCH diff --git a/packages/native/Callout/windows/Callout/Callout.cpp b/packages/agentic/native-core/windows/NativeCore/components/Callout/Callout.cpp similarity index 100% rename from packages/native/Callout/windows/Callout/Callout.cpp rename to packages/agentic/native-core/windows/NativeCore/components/Callout/Callout.cpp diff --git a/packages/native/Callout/windows/Callout/Callout.h b/packages/agentic/native-core/windows/NativeCore/components/Callout/Callout.h similarity index 86% rename from packages/native/Callout/windows/Callout/Callout.h rename to packages/agentic/native-core/windows/NativeCore/components/Callout/Callout.h index 4a434fbfa91..41b5ffb6231 100644 --- a/packages/native/Callout/windows/Callout/Callout.h +++ b/packages/agentic/native-core/windows/NativeCore/components/Callout/Callout.h @@ -6,7 +6,7 @@ #include "NativeModules.h" -#include "codegen/react/components/FRNCalloutSpec/Callout.g.h" +#include "codegen/react/components/FRNNativeCoreSpec/Callout.g.h" #include #include @@ -19,6 +19,8 @@ namespace winrt::FluentUI::Callout { +namespace Codegen = ::FRNNativeCoreCodegen; + } // namespace winrt::FluentUI::Callout void RegisterCalloutComponentView( diff --git a/packages/components/FocusZone/windows/FRNFocusZone/FocusZoneComponentView.cpp b/packages/agentic/native-core/windows/NativeCore/components/FocusZone/FocusZoneComponentView.cpp similarity index 98% rename from packages/components/FocusZone/windows/FRNFocusZone/FocusZoneComponentView.cpp rename to packages/agentic/native-core/windows/NativeCore/components/FocusZone/FocusZoneComponentView.cpp index f75854d11e9..b373546a62a 100644 --- a/packages/components/FocusZone/windows/FRNFocusZone/FocusZoneComponentView.cpp +++ b/packages/agentic/native-core/windows/NativeCore/components/FocusZone/FocusZoneComponentView.cpp @@ -4,7 +4,7 @@ #ifdef RNW_NEW_ARCH -#include "codegen/react/components/FRNFocusZoneSpec/FocusZone.g.h" +#include "codegen/react/components/FRNNativeCoreSpec/FocusZone.g.h" namespace winrt::FRNFocusZone { @@ -29,7 +29,7 @@ void CollectFocusableDescendants( struct FocusZoneComponentView : winrt::implements, - FRNFocusZoneCodegen::BaseFocusZone { + FRNNativeCoreCodegen::BaseFocusZone { void Initialize(const winrtRN::ComponentView &view) noexcept override { m_containerTag = view.Tag(); @@ -586,7 +586,7 @@ struct FocusZoneComponentView void RegisterFocusZoneComponentView(const winrt::Microsoft::ReactNative::IReactPackageBuilder &packageBuilder) noexcept { using ComponentView = winrt::FRNFocusZone::FocusZoneComponentView; - FRNFocusZoneCodegen::RegisterFocusZoneNativeComponent(packageBuilder, {}); + FRNNativeCoreCodegen::RegisterFocusZoneNativeComponent(packageBuilder, {}); } #endif diff --git a/packages/components/FocusZone/windows/FRNFocusZone/FocusZoneComponentView.h b/packages/agentic/native-core/windows/NativeCore/components/FocusZone/FocusZoneComponentView.h similarity index 100% rename from packages/components/FocusZone/windows/FRNFocusZone/FocusZoneComponentView.h rename to packages/agentic/native-core/windows/NativeCore/components/FocusZone/FocusZoneComponentView.h diff --git a/packages/components/FocusZone/windows/FRNFocusZone/packages.lock.json b/packages/agentic/native-core/windows/NativeCore/packages.lock.json similarity index 100% rename from packages/components/FocusZone/windows/FRNFocusZone/packages.lock.json rename to packages/agentic/native-core/windows/NativeCore/packages.lock.json diff --git a/packages/components/FocusZone/windows/FRNFocusZone/pch.cpp b/packages/agentic/native-core/windows/NativeCore/pch.cpp similarity index 100% rename from packages/components/FocusZone/windows/FRNFocusZone/pch.cpp rename to packages/agentic/native-core/windows/NativeCore/pch.cpp diff --git a/packages/components/FocusZone/windows/FRNFocusZone/pch.h b/packages/agentic/native-core/windows/NativeCore/pch.h similarity index 100% rename from packages/components/FocusZone/windows/FRNFocusZone/pch.h rename to packages/agentic/native-core/windows/NativeCore/pch.h diff --git a/packages/components/FocusZone/windows/FRNFocusZone/targetver.h b/packages/agentic/native-core/windows/NativeCore/targetver.h similarity index 100% rename from packages/components/FocusZone/windows/FRNFocusZone/targetver.h rename to packages/agentic/native-core/windows/NativeCore/targetver.h diff --git a/packages/components/FocusZone/windows/NuGet.Config b/packages/agentic/native-core/windows/NuGet.Config similarity index 100% rename from packages/components/FocusZone/windows/NuGet.Config rename to packages/agentic/native-core/windows/NuGet.Config diff --git a/packages/agentic/storybook-desktop-runtime/package.json b/packages/agentic/storybook-desktop-runtime/package.json index 51388d9ae66..0272613670d 100644 --- a/packages/agentic/storybook-desktop-runtime/package.json +++ b/packages/agentic/storybook-desktop-runtime/package.json @@ -31,9 +31,9 @@ "test": "fluentui-scripts jest" }, "dependencies": { - "@fluentui-react-native/callout": "workspace:*", "@fluentui-react-native/default-theme": "workspace:*", "@fluentui-react-native/design": "workspace:*", + "@fluentui-react-native/native-core": "workspace:*", "@rnx-kit/metro-config": "catalog:", "@rnx-kit/metro-resolver-symlinks": "catalog:", "@storybook/react-native": "^10.4.7", @@ -85,7 +85,7 @@ "jestPlatform": "macos", "knip": { "ignoreDependencies": [ - "@fluentui-react-native/callout" + "@fluentui-react-native/native-core" ] } }, diff --git a/packages/agentic/storybook-desktop-runtime/src/Win32CalloutPortal.tsx b/packages/agentic/storybook-desktop-runtime/src/Win32CalloutPortal.tsx index 1d1e36b211c..ee5b587a232 100644 --- a/packages/agentic/storybook-desktop-runtime/src/Win32CalloutPortal.tsx +++ b/packages/agentic/storybook-desktop-runtime/src/Win32CalloutPortal.tsx @@ -1,8 +1,8 @@ import * as React from 'react'; import { StyleSheet } from 'react-native'; -import { Callout } from '@fluentui-react-native/callout'; -import type { CalloutProps, DirectionalHint } from '@fluentui-react-native/callout'; +import { Callout } from '@fluentui-react-native/native-core/legacy'; +import type { CalloutProps, DirectionalHint } from '@fluentui-react-native/native-core/legacy'; import { RootInputBoundary } from '@fluentui-react-native/design'; import { useTheme } from '@storybook/react-native-theming'; diff --git a/packages/agentic/storybook-desktop-runtime/tsconfig.json b/packages/agentic/storybook-desktop-runtime/tsconfig.json index d7156beca43..2fe2c0c71ff 100644 --- a/packages/agentic/storybook-desktop-runtime/tsconfig.json +++ b/packages/agentic/storybook-desktop-runtime/tsconfig.json @@ -8,15 +8,15 @@ }, "include": ["src"], "references": [ - { - "path": "../../native/Callout/tsconfig.json" - }, { "path": "../../theming/default-theme/tsconfig.json" }, { "path": "../design/tsconfig.json" }, + { + "path": "../native-core/tsconfig.json" + }, { "path": "../../../scripts/tsconfig.json" } diff --git a/packages/agentic/storybook-desktop/src/config/makeDesktopStorybookConfig.test.ts b/packages/agentic/storybook-desktop/src/config/makeDesktopStorybookConfig.test.ts index dcf4c56e28b..49cead7354e 100644 --- a/packages/agentic/storybook-desktop/src/config/makeDesktopStorybookConfig.test.ts +++ b/packages/agentic/storybook-desktop/src/config/makeDesktopStorybookConfig.test.ts @@ -20,7 +20,7 @@ function makeAgenticConfig() { }, }, ], - '@fluentui-react-native/callout', + '@fluentui-react-native/native-core', ], }); } @@ -40,7 +40,7 @@ describe('DesktopStorybookConfig', () => { const config = makeAgenticConfig(); const packages = config.getStoryPackages('macos'); - expect(packages.map(({ name }) => name)).toEqual(['@fluentui-react-native/components', '@fluentui-react-native/callout']); + expect(packages.map(({ name }) => name)).toEqual(['@fluentui-react-native/components', '@fluentui-react-native/native-core']); expect(packages[0].root).toBe(path.resolve(storybookRoot, '../../packages/agentic/components')); expect(packages[0].storyPatterns).toEqual(['src/**/*.stories.?(ts|tsx)']); }); @@ -50,19 +50,19 @@ describe('DesktopStorybookConfig', () => { expect(config.getStoryGlobs('macos')).toEqual([ '../../../packages/agentic/components/src/**/*.stories.?(ts|tsx)', - '../../../packages/native/Callout/src/**/*.stories.?(ts|tsx)', + '../../../packages/agentic/native-core/src/**/*.stories.?(ts|tsx)', ]); expect(config.getStoryGlobs('win32')).toEqual([ '../../../packages/agentic/components/src/primitives/**/*.stories.?(ts|tsx)', '../../../packages/agentic/components/src/components/!(accordion|list-item)/**/*.stories.?(ts|tsx)', - '../../../packages/native/Callout/src/**/*.stories.?(ts|tsx)', + '../../../packages/agentic/native-core/src/**/*.stories.?(ts|tsx)', ]); }); test('filters packages by platform and applies addon defaults', () => { const config = makeDesktopStorybookConfig({ projectRoot: storybookRoot, - storyPackages: [['@fluentui-react-native/callout', { platforms: ['macos'] }]], + storyPackages: [['@fluentui-react-native/native-core', { platforms: ['macos'] }]], }); expect(config.getStorybookConfig('windows')).toMatchObject({ diff --git a/packages/components/ContextualMenu/tsconfig.json b/packages/components/ContextualMenu/tsconfig.json index 2ab212fd858..753669edfce 100644 --- a/packages/components/ContextualMenu/tsconfig.json +++ b/packages/components/ContextualMenu/tsconfig.json @@ -12,13 +12,13 @@ "path": "../../utils/adapters/tsconfig.json" }, { - "path": "../../native/Callout/tsconfig.json" + "path": "../../shim/callout/tsconfig.json" }, { "path": "../../agentic/design/tsconfig.json" }, { - "path": "../FocusZone/tsconfig.json" + "path": "../../shim/focus-zone/tsconfig.json" }, { "path": "../../framework-base/tsconfig.json" diff --git a/packages/components/FocusZone/RCTFocusZone.podspec b/packages/components/FocusZone/RCTFocusZone.podspec deleted file mode 100644 index 13ae57174eb..00000000000 --- a/packages/components/FocusZone/RCTFocusZone.podspec +++ /dev/null @@ -1,21 +0,0 @@ -require 'json' - -package = JSON.parse(File.read(File.join(__dir__, 'package.json'))) - -Pod::Spec.new do |s| - s.name = 'RCTFocusZone' - s.version = package['version'] - s.summary = package['description'] - s.license = package['license'] - - s.authors = package['author'] - s.homepage = "https://github.com/microsoft/fluentui-react-native" - - s.source = { :git => "https://github.com/microsoft/fluentui-react-native.git", :tag => "#{s.version}" } - s.swift_version = "5" - - s.osx.deployment_target = "10.15" - s.osx.source_files = "macos/*.{swift,h,m,mm}" - - install_modules_dependencies(s) -end diff --git a/packages/components/FocusZone/react-native.config.cjs b/packages/components/FocusZone/react-native.config.cjs deleted file mode 100644 index e6858db4296..00000000000 --- a/packages/components/FocusZone/react-native.config.cjs +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = { - dependency: { - platforms: { - windows: { - sourceDir: 'windows', - projects: [ - { - projectFile: 'FRNFocusZone/FRNFocusZone.vcxproj', - directDependency: true, - }, - ], - }, - }, - }, -}; diff --git a/packages/components/FocusZone/windows/FRNFocusZone.sln b/packages/components/FocusZone/windows/FRNFocusZone.sln deleted file mode 100644 index 08d4bc6912e..00000000000 --- a/packages/components/FocusZone/windows/FRNFocusZone.sln +++ /dev/null @@ -1,43 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.3.32929.385 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FRNFocusZone", "FRNFocusZone\FRNFocusZone.vcxproj", "{85648B33-7A31-434B-ACE5-6E4F6E52EBAD}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Debug|ARM64 = Debug|ARM64 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - Release|ARM64 = Release|ARM64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {85648B33-7A31-434B-ACE5-6E4F6E52EBAD}.Debug|x64.ActiveCfg = Debug|x64 - {85648B33-7A31-434B-ACE5-6E4F6E52EBAD}.Debug|x64.Build.0 = Debug|x64 - {85648B33-7A31-434B-ACE5-6E4F6E52EBAD}.Debug|x64.Deploy.0 = Debug|x64 - {85648B33-7A31-434B-ACE5-6E4F6E52EBAD}.Debug|x86.ActiveCfg = Debug|Win32 - {85648B33-7A31-434B-ACE5-6E4F6E52EBAD}.Debug|x86.Build.0 = Debug|Win32 - {85648B33-7A31-434B-ACE5-6E4F6E52EBAD}.Debug|x86.Deploy.0 = Debug|Win32 - {85648B33-7A31-434B-ACE5-6E4F6E52EBAD}.Debug|ARM64.ActiveCfg = Debug|ARM64 - {85648B33-7A31-434B-ACE5-6E4F6E52EBAD}.Debug|ARM64.Build.0 = Debug|ARM64 - {85648B33-7A31-434B-ACE5-6E4F6E52EBAD}.Debug|ARM64.Deploy.0 = Debug|ARM64 - {85648B33-7A31-434B-ACE5-6E4F6E52EBAD}.Release|x64.ActiveCfg = Release|x64 - {85648B33-7A31-434B-ACE5-6E4F6E52EBAD}.Release|x64.Build.0 = Release|x64 - {85648B33-7A31-434B-ACE5-6E4F6E52EBAD}.Release|x64.Deploy.0 = Release|x64 - {85648B33-7A31-434B-ACE5-6E4F6E52EBAD}.Release|x86.ActiveCfg = Release|Win32 - {85648B33-7A31-434B-ACE5-6E4F6E52EBAD}.Release|x86.Build.0 = Release|Win32 - {85648B33-7A31-434B-ACE5-6E4F6E52EBAD}.Release|x86.Deploy.0 = Release|Win32 - {85648B33-7A31-434B-ACE5-6E4F6E52EBAD}.Release|ARM64.ActiveCfg = Release|ARM64 - {85648B33-7A31-434B-ACE5-6E4F6E52EBAD}.Release|ARM64.Build.0 = Release|ARM64 - {85648B33-7A31-434B-ACE5-6E4F6E52EBAD}.Release|ARM64.Deploy.0 = Release|ARM64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {CA064327-BA5B-4132-B77B-23C9DDDF9E92} - EndGlobalSection -EndGlobal diff --git a/packages/components/FocusZone/windows/FRNFocusZone/FRNFocusZone.rc b/packages/components/FocusZone/windows/FRNFocusZone/FRNFocusZone.rc deleted file mode 100644 index 3212c105fce..00000000000 Binary files a/packages/components/FocusZone/windows/FRNFocusZone/FRNFocusZone.rc and /dev/null differ diff --git a/packages/components/FocusZone/windows/FRNFocusZone/FRNFocusZone.vcxproj.filters b/packages/components/FocusZone/windows/FRNFocusZone/FRNFocusZone.vcxproj.filters deleted file mode 100644 index b4602ae41c6..00000000000 --- a/packages/components/FocusZone/windows/FRNFocusZone/FRNFocusZone.vcxproj.filters +++ /dev/null @@ -1,44 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - - - Resource Files - - - \ No newline at end of file diff --git a/packages/components/FocusZone/windows/FRNFocusZone/resource.h b/packages/components/FocusZone/windows/FRNFocusZone/resource.h deleted file mode 100644 index fe63e7c1ad6..00000000000 --- a/packages/components/FocusZone/windows/FRNFocusZone/resource.h +++ /dev/null @@ -1,5 +0,0 @@ -// -// Microsoft Visual C++ generated include file. -// Used by FRNFocusZone.rc - -#pragma once diff --git a/packages/components/Menu/tsconfig.json b/packages/components/Menu/tsconfig.json index 72d42549d53..36b2d5eb8f6 100644 --- a/packages/components/Menu/tsconfig.json +++ b/packages/components/Menu/tsconfig.json @@ -15,13 +15,13 @@ "path": "../Button/tsconfig.json" }, { - "path": "../../native/Callout/tsconfig.json" + "path": "../../shim/callout/tsconfig.json" }, { "path": "../../agentic/design/tsconfig.json" }, { - "path": "../FocusZone/tsconfig.json" + "path": "../../shim/focus-zone/tsconfig.json" }, { "path": "../../framework-base/tsconfig.json" diff --git a/packages/components/RadioGroup/tsconfig.json b/packages/components/RadioGroup/tsconfig.json index 82457146a4d..dbcd3d438c6 100644 --- a/packages/components/RadioGroup/tsconfig.json +++ b/packages/components/RadioGroup/tsconfig.json @@ -15,7 +15,7 @@ "path": "../../agentic/design/tsconfig.json" }, { - "path": "../FocusZone/tsconfig.json" + "path": "../../shim/focus-zone/tsconfig.json" }, { "path": "../../framework-base/tsconfig.json" diff --git a/packages/components/TabList/tsconfig.json b/packages/components/TabList/tsconfig.json index 1644446a075..137360d774d 100644 --- a/packages/components/TabList/tsconfig.json +++ b/packages/components/TabList/tsconfig.json @@ -15,7 +15,7 @@ "path": "../../agentic/design/tsconfig.json" }, { - "path": "../FocusZone/tsconfig.json" + "path": "../../shim/focus-zone/tsconfig.json" }, { "path": "../../framework-base/tsconfig.json" diff --git a/packages/deprecated/foundation-compose/AGENTS.md b/packages/deprecated/foundation-compose/AGENTS.md index 0ef61601ae5..218573b309d 100644 --- a/packages/deprecated/foundation-compose/AGENTS.md +++ b/packages/deprecated/foundation-compose/AGENTS.md @@ -147,7 +147,7 @@ automatically. `ref` during preparation, commonly with `useViewCommandFocus`; type ref-bearing roots with `React.PropsWithRef<...>`. For imperative native APIs, use an internal native ref plus `useImperativeHandle`, as in - `packages/native/Callout/src/Callout.tsx`. + `packages/agentic/native-core/src/legacy/callout/Callout.tsx`. - Do not introduce `forwardRef` or a new public `ref` convention into an established v0 API without an explicit migration requirement. diff --git a/packages/experimental/Dropdown/tsconfig.json b/packages/experimental/Dropdown/tsconfig.json index d7fb6048b8d..a6dbd1a0307 100644 --- a/packages/experimental/Dropdown/tsconfig.json +++ b/packages/experimental/Dropdown/tsconfig.json @@ -15,7 +15,7 @@ "path": "../../components/Button/tsconfig.json" }, { - "path": "../../native/Callout/tsconfig.json" + "path": "../../shim/callout/tsconfig.json" }, { "path": "../../agentic/design/tsconfig.json" diff --git a/packages/experimental/Tooltip/tsconfig.json b/packages/experimental/Tooltip/tsconfig.json index 011332a5de8..db3204acba4 100644 --- a/packages/experimental/Tooltip/tsconfig.json +++ b/packages/experimental/Tooltip/tsconfig.json @@ -12,7 +12,7 @@ "path": "../../components/Button/tsconfig.json" }, { - "path": "../../native/Callout/tsconfig.json" + "path": "../../shim/callout/tsconfig.json" }, { "path": "../../framework-base/tsconfig.json" diff --git a/packages/libraries/core/tsconfig.json b/packages/libraries/core/tsconfig.json index 5bd6e0487c2..b675c0d1e47 100644 --- a/packages/libraries/core/tsconfig.json +++ b/packages/libraries/core/tsconfig.json @@ -21,7 +21,7 @@ "path": "../../components/Button/tsconfig.json" }, { - "path": "../../native/Callout/tsconfig.json" + "path": "../../shim/callout/tsconfig.json" }, { "path": "../../components/Checkbox/tsconfig.json" @@ -33,7 +33,7 @@ "path": "../../components/FocusTrapZone/tsconfig.json" }, { - "path": "../../components/FocusZone/tsconfig.json" + "path": "../../shim/focus-zone/tsconfig.json" }, { "path": "../../utils/interactive-hooks/tsconfig.json" diff --git a/packages/native/Callout/macos/FRNCallout.h b/packages/native/Callout/macos/FRNCallout.h deleted file mode 100644 index a938f891a54..00000000000 --- a/packages/native/Callout/macos/FRNCallout.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// FRNCallout.h -// Pods -// -// Created by Patrick Boyd on 9/24/24. -// -// Created as a dummy file to enable importing FRNCallout-Swift.h and invoking Swift functions from Obj-C -// - -#ifndef FRNCallout_h -#define FRNCallout_h - - -#endif /* FRNCallout_h */ diff --git a/packages/native/Callout/windows/.gitignore b/packages/native/Callout/windows/.gitignore deleted file mode 100644 index 0fd0acfc6d4..00000000000 --- a/packages/native/Callout/windows/.gitignore +++ /dev/null @@ -1,46 +0,0 @@ -*AppPackages* -*BundleArtifacts* - -#OS junk files -[Tt]humbs.db -*.DS_Store - -#Visual Studio files -*.[Oo]bj -*.user -*.aps -*.pch -*.vspscc -*.vssscc -*_i.c -*_p.c -*.ncb -*.suo -*.tlb -*.tlh -*.bak -*.[Cc]ache -*.ilk -*.log -*.lib -*.sbr -*.sdf -*.opensdf -*.opendb -*.unsuccessfulbuild -ipch/ -[Oo]bj/ -[Bb]in -[Dd]ebug*/ -[Rr]elease*/ -Ankh.NoLoad -.vs/ -# Visual C++ cache files - -#Files generated by the VS build -**/Generated Files/** - -#Files generated by MS build -*.binlog -*.err -*.wrn diff --git a/packages/native/Callout/windows/Callout/Callout.def b/packages/native/Callout/windows/Callout/Callout.def deleted file mode 100644 index 24e7c1235c3..00000000000 --- a/packages/native/Callout/windows/Callout/Callout.def +++ /dev/null @@ -1,3 +0,0 @@ -EXPORTS -DllCanUnloadNow = WINRT_CanUnloadNow PRIVATE -DllGetActivationFactory = WINRT_GetActivationFactory PRIVATE diff --git a/packages/native/Callout/windows/Callout/Callout.vcxproj b/packages/native/Callout/windows/Callout/Callout.vcxproj deleted file mode 100644 index 88efc1ff9b8..00000000000 --- a/packages/native/Callout/windows/Callout/Callout.vcxproj +++ /dev/null @@ -1,152 +0,0 @@ - - - - - - true - true - true - {FE36524A-FE8C-456A-9368-08FB1EB16CF8} - FluentUICallout - FluentUI.Callout - en-US - 16.0 - false - Windows Store - 10.0 - 10.0.19041.0 - 10.0.17763.0 - - - $([MSBuild]::GetDirectoryNameOfFileAbove($(SolutionDir), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\ - true - - - - - - Debug - ARM - - - Debug - ARM64 - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - ARM64 - - - Release - Win32 - - - Release - x64 - - - - DynamicLibrary - Unicode - false - - - true - true - - - false - true - false - - - - - - - - - - - - - - Use - pch.h - $(IntDir)pch.pch - Level4 - %(AdditionalOptions) /bigobj - 4453;28204 - _WINRT_DLL;%(PreprocessorDefinitions) - $(WindowsSDK_WindowsMetadata);$(AdditionalUsingDirectories) - - - User32.lib;%(AdditionalDependencies) - Console - true - Callout.def - - - - - _DEBUG;%(PreprocessorDefinitions) - - - - - NDEBUG;%(PreprocessorDefinitions) - - - - - false - - - - - - ReactPackageProvider.idl - - - - - - - Create - - - ReactPackageProvider.idl - - - - - - - - - - - - - - - - - This project references targets in your node_modules\react-native-windows folder that are missing. The missing file is {0}. - - - - - diff --git a/packages/native/Callout/windows/Callout/ReactPackageProvider.cpp b/packages/native/Callout/windows/Callout/ReactPackageProvider.cpp deleted file mode 100644 index bac18811408..00000000000 --- a/packages/native/Callout/windows/Callout/ReactPackageProvider.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#include "pch.h" - -#include "ReactPackageProvider.h" -#if __has_include("ReactPackageProvider.g.cpp") -#include "ReactPackageProvider.g.cpp" -#endif - -#include "Callout.h" - -using namespace winrt::Microsoft::ReactNative; - -namespace winrt::FluentUI::Callout::implementation { - -void ReactPackageProvider::CreatePackage( - IReactPackageBuilder const &packageBuilder) noexcept { - AddAttributedModules(packageBuilder, true); - -#ifdef RNW_NEW_ARCH - RegisterCalloutComponentView(packageBuilder); -#endif // #ifdef RNW_NEW_ARCH -} - -} // namespace winrt::FluentUI::Callout::implementation diff --git a/packages/native/Callout/windows/Callout/ReactPackageProvider.h b/packages/native/Callout/windows/Callout/ReactPackageProvider.h deleted file mode 100644 index ee4a6091036..00000000000 --- a/packages/native/Callout/windows/Callout/ReactPackageProvider.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. -#pragma once - -#include "ReactPackageProvider.g.h" - -using namespace winrt::Microsoft::ReactNative; - -namespace winrt::FluentUI::Callout::implementation { - -struct ReactPackageProvider : ReactPackageProviderT { - ReactPackageProvider() = default; - - void CreatePackage(IReactPackageBuilder const &packageBuilder) noexcept; -}; - -} // namespace winrt::FluentUI::Callout::implementation - -namespace winrt::FluentUI::Callout::factory_implementation { - -struct ReactPackageProvider - : ReactPackageProviderT {}; - -} // namespace winrt::FluentUI::Callout::factory_implementation diff --git a/packages/native/Callout/windows/Callout/ReactPackageProvider.idl b/packages/native/Callout/windows/Callout/ReactPackageProvider.idl deleted file mode 100644 index cd726b6e617..00000000000 --- a/packages/native/Callout/windows/Callout/ReactPackageProvider.idl +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -namespace FluentUI.Callout -{ - [webhosthidden] - [default_interface] - runtimeclass ReactPackageProvider : Microsoft.ReactNative.IReactPackageProvider - { - ReactPackageProvider(); - }; -} diff --git a/packages/native/Callout/windows/Callout/codegen/.clang-format b/packages/native/Callout/windows/Callout/codegen/.clang-format deleted file mode 100644 index 9d159247d51..00000000000 --- a/packages/native/Callout/windows/Callout/codegen/.clang-format +++ /dev/null @@ -1,2 +0,0 @@ -DisableFormat: true -SortIncludes: false diff --git a/packages/native/Callout/windows/Callout/packages.lock.json b/packages/native/Callout/windows/Callout/packages.lock.json deleted file mode 100644 index 396b4e4c7a1..00000000000 --- a/packages/native/Callout/windows/Callout/packages.lock.json +++ /dev/null @@ -1,151 +0,0 @@ -{ - "version": 1, - "dependencies": { - "native,Version=v0.0": { - "boost": { - "type": "Direct", - "requested": "[1.84.0, )", - "resolved": "1.84.0", - "contentHash": "4el2YP3cNJDVFPdzOso+LxGvdWP2rHxML4siq8VdonNypW2m4q503tHfCj6vK0L1UfxioE2hpFGb4ITEua73tg==" - }, - "Microsoft.ReactNative": { - "type": "Direct", - "requested": "[0.81.35, )", - "resolved": "0.81.35", - "contentHash": "WjsJFALaLLUvJHUBw8k8G8/PB3p5qvqqXG7NYJefHOgqB7MbCSOnD/bckIqKcp53J+MkPxqaeg5tnYLVTVhqwQ==" - }, - "Microsoft.ReactNative.Cxx": { - "type": "Direct", - "requested": "[0.81.35, )", - "resolved": "0.81.35", - "contentHash": "oadpIMSLN11M9W/hyZKyiCKE2wMvjb80Bl5jInVUmqDJWNswxnu7W5Kt/NA9ciy+BN0ru62ucO0E2PJDrnP/Jg==", - "dependencies": { - "Microsoft.ReactNative": "0.81.35" - } - }, - "Microsoft.VCRTForwarders.140": { - "type": "Direct", - "requested": "[1.0.2-rc, )", - "resolved": "1.0.2-rc", - "contentHash": "/r+sjtEeCIGyDhobIZ5hSmYhC/dSyGZxf1SxYJpElUhB0LMCktOMFs9gXrauXypIFECpVynNyVjAmJt6hjJ5oQ==" - }, - "Microsoft.Windows.CppWinRT": { - "type": "Direct", - "requested": "[2.0.230706.1, )", - "resolved": "2.0.230706.1", - "contentHash": "l0D7oCw/5X+xIKHqZTi62TtV+1qeSz7KVluNFdrJ9hXsst4ghvqQ/Yhura7JqRdZWBXAuDS0G0KwALptdoxweQ==" - }, - "Microsoft.WindowsAppSDK": { - "type": "Direct", - "requested": "[1.8.260508005, )", - "resolved": "1.8.260508005", - "contentHash": "+aA+zrvqJKgsn/1TPOSR0Uy7dkMO5jI/+cDWPu2pWmXe4KQxYkR8gQFY9IrfbgCxxSd/yl1zMcAKD/4HBbNqaw==", - "dependencies": { - "Microsoft.WindowsAppSDK.AI": "[1.8.76]", - "Microsoft.WindowsAppSDK.Base": "[1.8.251216001]", - "Microsoft.WindowsAppSDK.DWrite": "[1.8.25122902]", - "Microsoft.WindowsAppSDK.Foundation": "[1.8.260505001]", - "Microsoft.WindowsAppSDK.InteractiveExperiences": "[1.8.260430001]", - "Microsoft.WindowsAppSDK.ML": "[1.8.2197]", - "Microsoft.WindowsAppSDK.Runtime": "[1.8.260508005]", - "Microsoft.WindowsAppSDK.Widgets": "[1.8.251231004]", - "Microsoft.WindowsAppSDK.WinUI": "[1.8.260505002]" - } - }, - "Microsoft.Web.WebView2": { - "type": "Transitive", - "resolved": "1.0.3179.45", - "contentHash": "3pokSH5CnN0G6rGhGFo1y87inxYhNxBQ2Vdf0wlvBj99KHxQJormjDACmqRnFeUsmuNFIhWwfAL1ztq7wD5qRA==" - }, - "Microsoft.Windows.SDK.BuildTools": { - "type": "Transitive", - "resolved": "10.0.26100.4654", - "contentHash": "2mgcOlj/t2RfSyyw+pVESfO+Tk1RkfQzto9Vrq42M1lUQIfQEwbi8QLha9GXWIOj+TFzeHIEJckIoF25mgiM8A==" - }, - "Microsoft.Windows.SDK.BuildTools.MSIX": { - "type": "Transitive", - "resolved": "1.7.20250829.1", - "contentHash": "IMdvRmCIZnBS5GkYnv0po1bcx6U1OF39pqA4TphQ9evDzpCRoSE19/PkDvlUNNrBavTsLIEJgd/TAIFner75ow==" - }, - "Microsoft.WindowsAppSDK.AI": { - "type": "Transitive", - "resolved": "1.8.76", - "contentHash": "Ayn9QybcwzH+c8eQlE7dm2oO3Jrcn2uohLcsHJpCbLOAfcisjzwtSBe0oyulbaJ86R4eDSX3RDS25tsjGpIqyQ==", - "dependencies": { - "Microsoft.WindowsAppSDK.Base": "1.8.251216001", - "Microsoft.WindowsAppSDK.Foundation": "1.8.260501000" - } - }, - "Microsoft.WindowsAppSDK.Base": { - "type": "Transitive", - "resolved": "1.8.251216001", - "contentHash": "PS1wriuFknz3W2F2P/e6RvOTM35w89Lsj/f0QmUEPrJjKnc+jM0JLX1vfdytI14y1gNRUTm9uclwP0aH/SVU5w==", - "dependencies": { - "Microsoft.Windows.SDK.BuildTools": "10.0.26100.4654", - "Microsoft.Windows.SDK.BuildTools.MSIX": "1.7.20250829.1" - } - }, - "Microsoft.WindowsAppSDK.DWrite": { - "type": "Transitive", - "resolved": "1.8.25122902", - "contentHash": "zFNn07i7Cyz62Y8FnPQAyzeZK7ww3m9t42i9pzy4C04pNbyUDQ4fG7pB6VSh6n4EyFuYtuFQuDzt4mKmXFrkrg==", - "dependencies": { - "Microsoft.WindowsAppSDK.Base": "1.8.251216001" - } - }, - "Microsoft.WindowsAppSDK.Foundation": { - "type": "Transitive", - "resolved": "1.8.260505001", - "contentHash": "41SSoEn3sKKCAVPA/w18zVJwV1C7aDEkPS2f6Zyp19m27tDEmteEp0XS3Ln3b0ElYR4FfPEPvIDbJPSA9vePGw==", - "dependencies": { - "Microsoft.WindowsAppSDK.Base": "1.8.251216001", - "Microsoft.WindowsAppSDK.InteractiveExperiences": "1.8.260430001" - } - }, - "Microsoft.WindowsAppSDK.InteractiveExperiences": { - "type": "Transitive", - "resolved": "1.8.260430001", - "contentHash": "fTPCnQb3ZarMh9khlEfbLDllcZzK0tSP+2S6W/T4cPyLLSAmARm8Gd3AC5kqubnDjzTvG+1lNZ1bZGFsIHplJQ==", - "dependencies": { - "Microsoft.WindowsAppSDK.Base": "1.8.251216001" - } - }, - "Microsoft.WindowsAppSDK.ML": { - "type": "Transitive", - "resolved": "1.8.2197", - "contentHash": "6Bc1SOLd5HicY3GbF+zr76YBfH4iZOKeEGxTK/lHKAK2ExZTWavOADxB2CKSi/irF4dWSngUdRFopWPmckJ6fA==", - "dependencies": { - "Microsoft.WindowsAppSDK.Base": "1.8.251216001", - "Microsoft.WindowsAppSDK.Foundation": "1.8.260505001" - } - }, - "Microsoft.WindowsAppSDK.Runtime": { - "type": "Transitive", - "resolved": "1.8.260508005", - "contentHash": "2JqXzA4heHSkkaXJNyEvYtpv2wsEUMhwQzgXmZsFmYSkUXSdeVc6hdHcWoBK1SY9l1Sjd1brLt7h16kIpgh2kA==", - "dependencies": { - "Microsoft.WindowsAppSDK.Base": "1.8.251216001" - } - }, - "Microsoft.WindowsAppSDK.Widgets": { - "type": "Transitive", - "resolved": "1.8.251231004", - "contentHash": "bIWqQYR8DCoB1SoPOMil5AtgtkTn438wJTdpsHgyO/6o7Eh7PMP5BzrR0KbDsFqy+4LhPWQ4vtwko5k93fECcA==", - "dependencies": { - "Microsoft.WindowsAppSDK.Base": "1.8.251216001" - } - }, - "Microsoft.WindowsAppSDK.WinUI": { - "type": "Transitive", - "resolved": "1.8.260505002", - "contentHash": "/hGl6EOmo8aeJR2bYbOmGhOicnJK4EY+u+cQI+jm8H1uXThfMX32DsfKOt9LkOcu8AKX3j5FpiBay8ObUSytIw==", - "dependencies": { - "Microsoft.Web.WebView2": "1.0.3179.45", - "Microsoft.WindowsAppSDK.Base": "1.8.251216001", - "Microsoft.WindowsAppSDK.Foundation": "1.8.260505001", - "Microsoft.WindowsAppSDK.InteractiveExperiences": "1.8.260430001" - } - } - } - } -} diff --git a/packages/native/Callout/windows/Callout/pch.cpp b/packages/native/Callout/windows/Callout/pch.cpp deleted file mode 100644 index bcb5590be1b..00000000000 --- a/packages/native/Callout/windows/Callout/pch.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "pch.h" diff --git a/packages/native/Callout/windows/Callout/pch.h b/packages/native/Callout/windows/Callout/pch.h deleted file mode 100644 index 4eac9041ed7..00000000000 --- a/packages/native/Callout/windows/Callout/pch.h +++ /dev/null @@ -1,28 +0,0 @@ -// pch.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#pragma once - -#define NOMINMAX 1 -//#define WIN32_LEAN_AND_MEAN 1 -//#define WINRT_LEAN_AND_MEAN 1 - -// Windows Header Files -#include -#undef GetCurrentTime -#include - -// WinRT Header Files -#include -#include -#include - -// C RunTime Header Files -#include -#include -#include -#include - -// Reference additional headers your project requires here diff --git a/packages/native/Callout/windows/ExperimentalFeatures.props b/packages/native/Callout/windows/ExperimentalFeatures.props deleted file mode 100644 index db10c59f9ad..00000000000 --- a/packages/native/Callout/windows/ExperimentalFeatures.props +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - true - - - true - - true - - - diff --git a/packages/native/Callout/windows/NuGet.Config b/packages/native/Callout/windows/NuGet.Config deleted file mode 100644 index aee3137fd74..00000000000 --- a/packages/native/Callout/windows/NuGet.Config +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/packages/native/Callout/CHANGELOG.json b/packages/shim/callout/CHANGELOG.json similarity index 100% rename from packages/native/Callout/CHANGELOG.json rename to packages/shim/callout/CHANGELOG.json diff --git a/packages/native/Callout/CHANGELOG.md b/packages/shim/callout/CHANGELOG.md similarity index 100% rename from packages/native/Callout/CHANGELOG.md rename to packages/shim/callout/CHANGELOG.md diff --git a/packages/shim/callout/README.md b/packages/shim/callout/README.md new file mode 100644 index 00000000000..cb7c14ee157 --- /dev/null +++ b/packages/shim/callout/README.md @@ -0,0 +1,18 @@ +# Callout compatibility shim + +`@fluentui-react-native/callout` preserves its existing named exports by +re-exporting the implementation and public types from +`@fluentui-react-native/native-core/legacy`. + +New consumers should import `Callout`, `CalloutProps`, and `CalloutHandle` +from `@fluentui-react-native/native-core/legacy`. Deprecated compatibility aliases +remain available through this shim. + +This package owns no native code, codegen specification, pod, or Windows +project. Native applications must list `@fluentui-react-native/native-core` +as a direct dependency so native tooling discovers its pod and Windows +Fabric library. Remove explicit `FRNCallout` pod declarations and regenerate +autolinking/Pods after updating. + +See the [Callout contract](../../agentic/native-core/src/legacy/callout/SPEC.md) +and [native-core organization](../../agentic/native-core/README.md). diff --git a/packages/native/Callout/jest.config.cjs b/packages/shim/callout/jest.config.cjs similarity index 100% rename from packages/native/Callout/jest.config.cjs rename to packages/shim/callout/jest.config.cjs diff --git a/packages/native/Callout/package.json b/packages/shim/callout/package.json similarity index 77% rename from packages/native/Callout/package.json rename to packages/shim/callout/package.json index 62402c199fc..5a99dda3129 100644 --- a/packages/native/Callout/package.json +++ b/packages/shim/callout/package.json @@ -1,16 +1,24 @@ { "name": "@fluentui-react-native/callout", "version": "0.29.6", - "description": "A cross-platform Callout component using the Fluent Design System", + "description": "Compatibility shim for the native-core Callout component.", "homepage": "https://github.com/microsoft/fluentui-react-native", "license": "MIT", "author": "", "repository": { "type": "git", "url": "https://github.com/microsoft/fluentui-react-native.git", - "directory": "packages/native/Callout" + "directory": "packages/shim/callout" }, + "files": [ + "lib/index.js", + "lib/index.js.map", + "lib/index.d.ts", + "lib/index.d.ts.map", + "src/index.ts" + ], "type": "module", + "sideEffects": false, "main": "lib/index.js", "module": "lib/index.js", "types": "lib/index.d.ts", @@ -31,7 +39,7 @@ "update-snapshots": "fluentui-scripts jest -u" }, "dependencies": { - "@fluentui-react-native/framework-base": "workspace:*" + "@fluentui-react-native/native-core": "workspace:*" }, "devDependencies": { "@babel/core": "catalog:", @@ -74,32 +82,9 @@ "optional": true } }, - "codegenConfig": { - "name": "FRNCalloutSpec", - "type": "all", - "jsSrcsDir": "src", - "ios": { - "componentProvider": { - "Callout": "RCTCalloutComponentView" - } - }, - "windows": { - "generators": "componentsWindows", - "namespace": "winrt::FluentUI::Callout::Codegen", - "outputDirectory": "windows/Callout/codegen", - "separateDataTypes": true - } - }, "furn": { "jestPlatform": "win32" }, - "react-native-windows": { - "init-windows": { - "name": "Callout", - "namespace": "FluentUI.Callout", - "template": "cpp-lib" - } - }, "rnx-kit": { "kitType": "library", "alignDeps": { diff --git a/packages/shim/callout/src/index.test.ts b/packages/shim/callout/src/index.test.ts new file mode 100644 index 00000000000..15a107f5bee --- /dev/null +++ b/packages/shim/callout/src/index.test.ts @@ -0,0 +1,22 @@ +import { Callout, calloutName } from './index'; +import { Callout as NativeCallout, calloutName as nativeCalloutName } from '@fluentui-react-native/native-core/legacy'; +import type { CalloutHandle, CalloutProps, ICalloutProps, ICalloutTokens } from './index'; +import type { CalloutHandle as NativeCalloutHandle, CalloutProps as NativeCalloutProps } from '@fluentui-react-native/native-core/legacy'; + +const props: ICalloutProps & ICalloutTokens = { directionalHint: 'bottomCenter' }; +const nativeProps: NativeCalloutProps = props; +const legacyProps: CalloutProps = nativeProps; +const handle: NativeCalloutHandle = { blurWindow() {}, focusWindow() {} }; +const legacyHandle: CalloutHandle = handle; + +describe('Callout compatibility shim', () => { + it('re-exports the exact native-core component and name', () => { + expect(Callout).toBe(NativeCallout); + expect(calloutName).toBe(nativeCalloutName); + }); + + it('preserves public and deprecated type contracts', () => { + expect(legacyProps).toBe(props); + expect(legacyHandle).toBe(handle); + }); +}); diff --git a/packages/native/Callout/src/index.ts b/packages/shim/callout/src/index.ts similarity index 57% rename from packages/native/Callout/src/index.ts rename to packages/shim/callout/src/index.ts index 9925f9225ed..0b952380002 100644 --- a/packages/native/Callout/src/index.ts +++ b/packages/shim/callout/src/index.ts @@ -1,4 +1,4 @@ -export { calloutName } from './Callout.types'; +export { Callout, calloutName } from '@fluentui-react-native/native-core/legacy'; export type { CalloutHandle, CalloutNativeCommands, @@ -9,5 +9,4 @@ export type { ICalloutProps, ICalloutTokens, RestoreFocusEvent, -} from './Callout.types'; -export { Callout } from './Callout'; +} from '@fluentui-react-native/native-core/legacy'; diff --git a/packages/native/Callout/tsconfig.json b/packages/shim/callout/tsconfig.json similarity index 87% rename from packages/native/Callout/tsconfig.json rename to packages/shim/callout/tsconfig.json index d13fbc90df7..a1c5ec1e711 100644 --- a/packages/native/Callout/tsconfig.json +++ b/packages/shim/callout/tsconfig.json @@ -10,7 +10,7 @@ "exclude": ["**/*.stories.ts", "**/*.stories.tsx"], "references": [ { - "path": "../../framework-base/tsconfig.json" + "path": "../../agentic/native-core/tsconfig.json" }, { "path": "../../../scripts/tsconfig.json" diff --git a/packages/components/FocusZone/CHANGELOG.json b/packages/shim/focus-zone/CHANGELOG.json similarity index 100% rename from packages/components/FocusZone/CHANGELOG.json rename to packages/shim/focus-zone/CHANGELOG.json diff --git a/packages/components/FocusZone/CHANGELOG.md b/packages/shim/focus-zone/CHANGELOG.md similarity index 100% rename from packages/components/FocusZone/CHANGELOG.md rename to packages/shim/focus-zone/CHANGELOG.md diff --git a/packages/shim/focus-zone/README.md b/packages/shim/focus-zone/README.md new file mode 100644 index 00000000000..83130a9cd7f --- /dev/null +++ b/packages/shim/focus-zone/README.md @@ -0,0 +1,19 @@ +# FocusZone compatibility shim + +`@fluentui-react-native/focus-zone` preserves its existing named exports by +re-exporting the implementation and public types from +`@fluentui-react-native/native-core/legacy`. Its legacy `NativeProps` export aliases +the component-qualified `FocusZoneNativeProps` export. + +New consumers should import `FocusZone` and `FocusZoneProps` from +`@fluentui-react-native/native-core/legacy`. Deprecated compatibility types remain +available through this shim. + +This package owns no native code, codegen specification, pod, or Windows +project. Native applications must list `@fluentui-react-native/native-core` +as a direct dependency so native tooling discovers its pod and Windows +Fabric library. Remove explicit `RCTFocusZone` pod declarations and regenerate +autolinking/Pods after updating. Win32 keeps its host-provided native component. + +See the [FocusZone contract](../../agentic/native-core/src/legacy/focus-zone/SPEC.md) +and [native-core organization](../../agentic/native-core/README.md). diff --git a/packages/shim/focus-zone/jest.config.cjs b/packages/shim/focus-zone/jest.config.cjs new file mode 100644 index 00000000000..b391f5b6623 --- /dev/null +++ b/packages/shim/focus-zone/jest.config.cjs @@ -0,0 +1 @@ +module.exports = require('@fluentui-react-native/scripts/jest-config'); diff --git a/packages/components/FocusZone/package.json b/packages/shim/focus-zone/package.json similarity index 74% rename from packages/components/FocusZone/package.json rename to packages/shim/focus-zone/package.json index 1adc1d604cc..bb222eb5c90 100644 --- a/packages/components/FocusZone/package.json +++ b/packages/shim/focus-zone/package.json @@ -1,15 +1,23 @@ { "name": "@fluentui-react-native/focus-zone", "version": "0.23.6", - "description": "A cross-platform FocusZone component using the Fluent Design System", + "description": "Compatibility shim for the native-core FocusZone component.", "license": "MIT", "author": "", "repository": { "type": "git", "url": "https://github.com/microsoft/fluentui-react-native.git", - "directory": "packages/components/FocusZone" + "directory": "packages/shim/focus-zone" }, + "files": [ + "lib/index.js", + "lib/index.js.map", + "lib/index.d.ts", + "lib/index.d.ts.map", + "src/index.ts" + ], "type": "module", + "sideEffects": false, "main": "lib/index.js", "module": "lib/index.js", "types": "lib/index.d.ts", @@ -30,12 +38,10 @@ "update-snapshots": "fluentui-scripts jest -u" }, "dependencies": { - "@fluentui-react-native/framework-base": "workspace:*", - "@fluentui-react-native/interactive-hooks": "workspace:*" + "@fluentui-react-native/native-core": "workspace:*" }, "devDependencies": { "@babel/core": "catalog:", - "@fluentui-react-native/desktop-driver": "workspace:*", "@fluentui-react-native/scripts": "workspace:*", "@office-iss/react-native-win32": "^0.81.8", "@react-native-community/cli": "^20.0.0", @@ -75,32 +81,9 @@ "optional": true } }, - "codegenConfig": { - "name": "FRNFocusZoneSpec", - "type": "all", - "jsSrcsDir": "src", - "ios": { - "componentProvider": { - "FocusZone": "RCTFocusZoneComponentView" - } - }, - "windows": { - "generators": "componentsWindows", - "namespace": "FRNFocusZoneCodegen", - "outputDirectory": "windows/FRNFocusZone/codegen", - "separateDataTypes": true - } - }, "furn": { "jestPlatform": "win32" }, - "react-native-windows": { - "init-windows": { - "name": "FRNFocusZone", - "namespace": "FRNFocusZone", - "template": "cpp-lib" - } - }, "rnx-kit": { "kitType": "library", "alignDeps": { diff --git a/packages/shim/focus-zone/src/index.test.ts b/packages/shim/focus-zone/src/index.test.ts new file mode 100644 index 00000000000..00c6905dd35 --- /dev/null +++ b/packages/shim/focus-zone/src/index.test.ts @@ -0,0 +1,26 @@ +import { FocusZone, focusZoneName } from './index'; +import { FocusZone as NativeFocusZone, focusZoneName as nativeFocusZoneName } from '@fluentui-react-native/native-core/legacy'; +import type { FocusZoneProps, FocusZoneRenderData, FocusZoneState, FocusZoneTokens, FocusZoneType, NativeProps } from './index'; +import type { FocusZoneNativeProps, FocusZoneProps as NativeFocusZoneProps } from '@fluentui-react-native/native-core/legacy'; + +const props: FocusZoneProps = { focusZoneDirection: 'horizontal', isCircularNavigation: true }; +const nativeProps: NativeFocusZoneProps = props; +const nativeRootProps: FocusZoneNativeProps = { navigateAtEnd: 'NavigateWrap' }; +const legacyRootProps: NativeProps = nativeRootProps; +const state: FocusZoneState = {}; +const tokens: FocusZoneTokens = {}; +const renderData: FocusZoneRenderData = { slotProps: { root: legacyRootProps }, state }; +const legacyType: FocusZoneType = { props, tokens, slotProps: renderData.slotProps, state }; + +describe('FocusZone compatibility shim', () => { + it('re-exports the exact native-core component and name', () => { + expect(FocusZone).toBe(NativeFocusZone); + expect(focusZoneName).toBe(nativeFocusZoneName); + }); + + it('preserves public, native, and deprecated type contracts', () => { + expect(nativeProps).toBe(props); + expect(legacyRootProps).toBe(nativeRootProps); + expect(legacyType.state).toBe(state); + }); +}); diff --git a/packages/components/FocusZone/src/index.ts b/packages/shim/focus-zone/src/index.ts similarity index 52% rename from packages/components/FocusZone/src/index.ts rename to packages/shim/focus-zone/src/index.ts index f84aa915751..53614aef8d1 100644 --- a/packages/components/FocusZone/src/index.ts +++ b/packages/shim/focus-zone/src/index.ts @@ -1,4 +1,4 @@ -export { focusZoneName } from './FocusZone.types'; +export { FocusZone, focusZoneName } from '@fluentui-react-native/native-core/legacy'; export type { FocusZoneDirection, FocusZoneProps, @@ -8,7 +8,6 @@ export type { FocusZoneTabNavigation, FocusZoneTokens, FocusZoneType, - NativeProps, + FocusZoneNativeProps as NativeProps, NavigateAtEnd, -} from './FocusZone.types'; -export { FocusZone } from './FocusZone'; +} from '@fluentui-react-native/native-core/legacy'; diff --git a/packages/shim/focus-zone/tsconfig.json b/packages/shim/focus-zone/tsconfig.json new file mode 100644 index 00000000000..a1c5ec1e711 --- /dev/null +++ b/packages/shim/focus-zone/tsconfig.json @@ -0,0 +1,19 @@ +{ + "extends": "@fluentui-react-native/scripts/tsconfig", + "compilerOptions": { + "outDir": "lib", + "rootDir": "src", + "composite": true, + "tsBuildInfoFile": ".cache/tsconfig.tsbuildinfo" + }, + "include": ["src"], + "exclude": ["**/*.stories.ts", "**/*.stories.tsx"], + "references": [ + { + "path": "../../agentic/native-core/tsconfig.json" + }, + { + "path": "../../../scripts/tsconfig.json" + } + ] +} diff --git a/tsconfig.json b/tsconfig.json index d2f500b8512..1bb404723f6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -28,6 +28,9 @@ { "path": "packages/agentic/desktop-driver/tsconfig.json" }, + { + "path": "packages/agentic/native-core/tsconfig.json" + }, { "path": "packages/agentic/storybook-desktop/tsconfig.json" }, @@ -61,9 +64,6 @@ { "path": "packages/components/FocusTrapZone/tsconfig.json" }, - { - "path": "packages/components/FocusZone/tsconfig.json" - }, { "path": "packages/components/Icon/tsconfig.json" }, @@ -206,7 +206,10 @@ "path": "packages/libraries/core/tsconfig.json" }, { - "path": "packages/native/Callout/tsconfig.json" + "path": "packages/shim/callout/tsconfig.json" + }, + { + "path": "packages/shim/focus-zone/tsconfig.json" }, { "path": "packages/shim/theme/tsconfig.json" diff --git a/yarn.lock b/yarn.lock index 3fa2fa59ba8..3f731438817 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2565,10 +2565,9 @@ __metadata: resolution: "@fluentui-react-native/agentic-components-storybook@workspace:apps/storybook" dependencies: "@babel/core": "catalog:" - "@fluentui-react-native/callout": "workspace:*" "@fluentui-react-native/components": "workspace:*" "@fluentui-react-native/desktop-driver": "workspace:*" - "@fluentui-react-native/focus-zone": "workspace:*" + "@fluentui-react-native/native-core": "workspace:*" "@fluentui-react-native/scripts": "workspace:*" "@fluentui-react-native/storybook-desktop": "workspace:*" "@fluentui-react-native/storybook-desktop-runtime": "workspace:*" @@ -2852,12 +2851,12 @@ __metadata: languageName: unknown linkType: soft -"@fluentui-react-native/callout@workspace:*, @fluentui-react-native/callout@workspace:packages/native/Callout": +"@fluentui-react-native/callout@workspace:*, @fluentui-react-native/callout@workspace:packages/shim/callout": version: 0.0.0-use.local - resolution: "@fluentui-react-native/callout@workspace:packages/native/Callout" + resolution: "@fluentui-react-native/callout@workspace:packages/shim/callout" dependencies: "@babel/core": "catalog:" - "@fluentui-react-native/framework-base": "workspace:*" + "@fluentui-react-native/native-core": "workspace:*" "@fluentui-react-native/scripts": "workspace:*" "@office-iss/react-native-win32": "npm:^0.81.8" "@react-native-community/cli": "npm:^20.0.0" @@ -3017,11 +3016,10 @@ __metadata: resolution: "@fluentui-react-native/components@workspace:packages/agentic/components" dependencies: "@babel/core": "catalog:" - "@fluentui-react-native/callout": "workspace:*" "@fluentui-react-native/design": "workspace:*" "@fluentui-react-native/desktop-driver": "workspace:*" - "@fluentui-react-native/focus-zone": "workspace:*" "@fluentui-react-native/framework-base": "workspace:*" + "@fluentui-react-native/native-core": "workspace:*" "@fluentui-react-native/scripts": "workspace:*" "@fluentui-react-native/storybook-desktop": "workspace:*" "@office-iss/react-native-win32": "npm:^0.81.0" @@ -4112,14 +4110,12 @@ __metadata: languageName: unknown linkType: soft -"@fluentui-react-native/focus-zone@workspace:*, @fluentui-react-native/focus-zone@workspace:packages/components/FocusZone": +"@fluentui-react-native/focus-zone@workspace:*, @fluentui-react-native/focus-zone@workspace:packages/shim/focus-zone": version: 0.0.0-use.local - resolution: "@fluentui-react-native/focus-zone@workspace:packages/components/FocusZone" + resolution: "@fluentui-react-native/focus-zone@workspace:packages/shim/focus-zone" dependencies: "@babel/core": "catalog:" - "@fluentui-react-native/desktop-driver": "workspace:*" - "@fluentui-react-native/framework-base": "workspace:*" - "@fluentui-react-native/interactive-hooks": "workspace:*" + "@fluentui-react-native/native-core": "workspace:*" "@fluentui-react-native/scripts": "workspace:*" "@office-iss/react-native-win32": "npm:^0.81.8" "@react-native-community/cli": "npm:^20.0.0" @@ -4515,6 +4511,52 @@ __metadata: languageName: unknown linkType: soft +"@fluentui-react-native/native-core@workspace:*, @fluentui-react-native/native-core@workspace:packages/agentic/native-core": + version: 0.0.0-use.local + resolution: "@fluentui-react-native/native-core@workspace:packages/agentic/native-core" + dependencies: + "@babel/core": "catalog:" + "@fluentui-react-native/framework-base": "workspace:*" + "@fluentui-react-native/interactive-hooks": "workspace:*" + "@fluentui-react-native/scripts": "workspace:*" + "@fluentui-react-native/storybook-desktop": "workspace:*" + "@office-iss/react-native-win32": "npm:^0.81.8" + "@react-native-community/cli": "npm:^20.0.0" + "@react-native-community/cli-platform-android": "npm:^20.0.0" + "@react-native-community/cli-platform-ios": "npm:^20.0.0" + "@react-native-windows/cli": "npm:^0.81.0" + "@react-native/babel-preset": "npm:^0.81.0" + "@react-native/metro-config": "npm:^0.81.0" + "@storybook/react-native": "npm:^10.4.7" + "@testing-library/react-native": "catalog:" + "@types/react": "npm:~19.1.4" + "@types/react-test-renderer": "npm:^19.1.0" + react: "npm:19.1.4" + react-native: "npm:^0.81.6" + react-native-macos: "npm:^0.81.0" + react-native-windows: "npm:^0.81.0" + react-test-renderer: "npm:19.1.4" + storybook: "npm:^10.4.0" + test-renderer: "catalog:" + peerDependencies: + "@office-iss/react-native-win32": ^0.74.0 || ^0.81.0 + "@types/react": ~18.2.0 || ~19.0.0 || ~19.1.4 + react: 18.2.0 || 19.0.0 || 19.1.4 + react-native: ^0.73.0 || ^0.74.0 || ^0.78.0 || ^0.81.6 + react-native-macos: ^0.73.0 || ^0.74.0 || ^0.78.0 || ^0.81.0 + react-native-windows: ^0.73.0 || ^0.74.0 || ^0.78.0 || ^0.81.0 + peerDependenciesMeta: + "@office-iss/react-native-win32": + optional: true + "@types/react": + optional: true + react-native-macos: + optional: true + react-native-windows: + optional: true + languageName: unknown + linkType: soft + "@fluentui-react-native/notification@workspace:*, @fluentui-react-native/notification@workspace:packages/components/Notification": version: 0.0.0-use.local resolution: "@fluentui-react-native/notification@workspace:packages/components/Notification" @@ -5052,9 +5094,9 @@ __metadata: resolution: "@fluentui-react-native/storybook-desktop-runtime@workspace:packages/agentic/storybook-desktop-runtime" dependencies: "@babel/core": "catalog:" - "@fluentui-react-native/callout": "workspace:*" "@fluentui-react-native/default-theme": "workspace:*" "@fluentui-react-native/design": "workspace:*" + "@fluentui-react-native/native-core": "workspace:*" "@fluentui-react-native/scripts": "workspace:*" "@office-iss/react-native-win32": "npm:^0.81.0" "@react-native-community/cli": "npm:^20.0.0" @@ -5477,6 +5519,7 @@ __metadata: "@fluentui-react-native/experimental-shimmer": "workspace:*" "@fluentui-react-native/focus-zone": "workspace:*" "@fluentui-react-native/menu-button": "workspace:*" + "@fluentui-react-native/native-core": "workspace:*" "@fluentui-react-native/radio-group": "workspace:*" "@fluentui-react-native/scripts": "workspace:*" "@fluentui-react-native/tester-core": "workspace:*"