Add nine agentic components and shared policies - #4308
Open
Jason Morse (JasonVMo) wants to merge 23 commits into
Open
Add nine agentic components and shared policies#4308Jason Morse (JasonVMo) wants to merge 23 commits into
Jason Morse (JasonVMo) wants to merge 23 commits into
Conversation
AvatarGroup lays a small set of Avatar children out as one cohort and optionally appends a trailing `+N` indicator for the members it does not show. It supports the spread and stack layouts and the eight Avatar sizes, and it resolves the spread gap, stack overlap, separation ring, item box, and indicator scale from its own declared size. React Native has no sibling-relative sizing and no mask compositing, so the contract records five accepted divergences: size is declared on the group for geometry only, the stack separation ring is a filled circular box rather than a mask, the indicator is its own view and text rather than an Avatar, the five-item maximum is advisory, and a labelled group uses the image role because React Native has no group role. Adds the reviewed contract and companions, the implementation, public exports, runtime and type tests, Storybook stories with a static desktop driver plan, and a changeset. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add DestructiveButton as a distinct component for irreversible and high-consequence actions rather than widening Button with a danger appearance. Keeping it separate lets the destructive surface drop the axes that do not apply to it: there is no selection model, no square shape, and no neutral emphasis level, so a destructive action can never be authored as a toggle or mistaken for a neutral square Button. The contract was authored and explicitly reviewed against the pinned Flex source (flex-1.5.0-206c4996) before any code, and records three divergences: the icon-only default shape, the mobile-only Secondary style, and FURN's single icon slot with iconPosition. Only icon sizing is reused from Button, since the source states it inherits; structural padding and radius are restated locally because Button's style factory is keyed by a square shape and a selection-bearing state shape that DestructiveButton does not have. The default token set maps no distinct hover or pressed value onto the loud danger background, so the primary appearance currently shows no background change on interaction. That gap is recorded in spec/tokens.yaml and spec/interaction.md rather than papered over. Resolves #4221 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add the InteractionTag component under packages/agentic/components with a reviewed, implemented contract for #4227. The component renders two independently pressable regions inside one non-interactive container: a primary action that names the tag and a dismiss action that removes it. Each region is its own button, its own tab stop, and its own focus visual, so nothing bubbles between them. Leading content is typed as an exclusive icon-or-avatar union, the divider is a private state slot, and dismissal stays caller owned. Includes the contract and companions with generated Flex provenance, runtime tests, compile-time type tests, stories with a static desktop driver plan, explicit package exports, and a changeset. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Label names an associated form control. It builds on the agentic Text component, offers regular and strong weights across three sizes, renders an optional decorative required indicator, and applies a disabled foreground that mirrors the control it names. Browser label activation forwarding has no React Native equivalent, so association is programmatic: a caller gives the label a nativeID and points the control at it with accessibilityLabelledBy. The root owns the accessible name so the label reports one text element on Windows UI Automation and macOS AX; the name is read from string content unless the caller supplies an explicit accessibilityLabel. The contract was authored from pinned Flex evidence and reviewed before implementation. Both divergences from the source are recorded as not-applicable in SPEC.md and spec/source.json. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add Link to @fluentui-react-native/components for #4229, contract first. SPEC.md and the spec/ companions were authored and reviewed before any code, and spec/source.json records the two sources that govern the requirements LNK-001 through LNK-012. The root is a native Text so the component participates in a surrounding text run and keeps React 19 ref-as-prop without forwardRef. The content slot is also a native Text rather than the agentic Text, which is what lets an inline link inherit the typography around it instead of imposing its own. Navigation is adapted to React Native Linking. onPress runs first on every activation and a supplied url is then opened, deliberately diverging from the V1 FURN Link where url supersedes onPress. When onNavigationError is supplied the rejection is routed to it; when it is not, no catch is attached at all, so the rejection is left untouched rather than silently absorbed. Nine divergences from the Flex source are recorded rather than faked. The most consequential are that CSS underline geometry and the dotted content underline have no React Native equivalent on Windows or macOS, that there is no hover state because core TextProps has no hover events, and that the focus visual is a single border on the root Text because FocusVisual composes Views that cannot nest inside a text run. Provenance caveat: report:spec-source-drift could not reach the origin repositories from this environment, so the origin digests in spec/source.json mirror the locally verified Marketplace digests and the report entry records candidateStatus "unchecked". Re-run --update-sources with credentials to confirm the origin lineage. This is also disclosed at the bottom of SPEC.md. Validated with package format, lint, build, check:spec-contracts, the package test suite (54 suites, 299 tests), and the root unified build. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add NavItem, a single pressable navigation row shared by a future Nav and Simple Nav. The contract is authored locally from the pinned Flex nav-item skill and reviewed before implementation. - Comfortable and compact density, top-level and sub-item nesting - Externally driven selection and category disclosure so a parent navigation can own which destination is current and which category is open - Item rows publish link semantics with selected state; category rows publish button semantics with expanded state and an optional controls id - Collapsed icon rail mode that requires an accessible name - Persistent selected indicator and focus visual so state never reflows - Trailing string content and always-visible trailing actions Fixes #4234 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Popover pairs a trigger with an anchored floating surface built on the native @fluentui-react-native/callout component. It owns controlled and uncontrolled open state, trigger accessibility and interaction, the anchor relationship, tokenized surface styling, and the mount lifetime of the surface content. The contract is authored from pinned Flex evidence plus the pinned Callout native sources, and it records the verified per-platform limits rather than assuming parity: macOS collapses every directional hint onto four screen edges, initial focus differs on each platform, focus return and anchor gap are not implemented anywhere, and viewport containment is native best effort. Eleven divergences capture those gaps explicitly. The visible surface boundary is drawn on the React Native content host inside the popup, which is the node both platforms render and size from. Also allows @fluentui-react-native/callout in the component source boundary and removes the now-obsolete knip ignore. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add SearchBox to the agentic components package for issue #4239. The component delegates all field chrome to the reviewed Input pipeline and owns only the search-specific surface: a leading search icon, a clear button that renders only while a query is present, and search semantics for submitting, clearing, and abandoning a query. Behavior owned by SearchBox: - controllable value with `value`, `defaultValue`, and `onChangeText` - `onSearch` on submit and `onClear` from the clear button or Escape - clear-button press returns focus to the text input - `disabled` and `readOnly` both suppress edits, clearing, and submit - a forwarded ref that resolves to the underlying text input - an accessible name required on the field and on the clear button Includes the reviewed contract and companions under `spec/`, runtime and type tests, stories with a static desktop-driver plan, and a changeset. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Tooltip pairs a trigger with a short descriptive label that appears on pointer entry after showDelay and immediately on keyboard focus. It is a specialization of the reviewed Popover pipeline rather than a second floating-surface implementation: Popover keeps the wrapper, anchor ref, surface mount lifetime, and native dismissal channel, and Tooltip drives it as a controlled surface while replacing the decisions a tooltip owns. Behavior: - Visibility is controllable (visible / defaultVisible / onVisibleChange) and driven independently by pointer and focus, so either interaction keeps the label up. Opposite interactions cancel pending timers, and pending timers are cleared on unmount. - The trigger describes itself with the label text and reports disabled state without reporting expanded state, because a tooltip is not a disclosure. Consumer trigger handlers run after Tooltip's own handling and the consumer ref composes with the anchor ref. - A disabled trigger never reveals the tooltip and never schedules a timer, but never blocks a hide. Close requests from trigger activation or native dismissal are always adopted, including while disabled; open requests from trigger activation are ignored. - The surface requests no initial focus and its label node carries the tooltip role; the surface and label mount only while visible. - Label styling comes from the pinned Flex tooltip tokens, with the consumer content style applied last. The reviewed contract, provenance, and companion specs are ratified to implemented against flex-1.5.0-206c4996. The component-scoped live source refresh confirmed the pinned tooltip source identities are unchanged; the only upstream edit is a refinement of the still-pending motion guidance, which does not affect the already-deferred tooltip-motion divergence. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The pointer reveal is gated on disabled when the pointer enters, but the trigger can be disabled while the showDelay timer is still pending. The timer then fired against the stale decision and revealed the tooltip from a disabled trigger, violating TIP-004. The delayed callback now re-checks the current disabled value before it reports a change. Only reveals are gated, so a pending hide still runs after the trigger is disabled and native dismissal is still adopted, matching the contract that disabled never blocks a hide. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Inline desktop-driver selectors in the new Popover and SearchBox stories, and constrain the representative-plan harness to the three stories it is designed to execute as the catalog grows. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
Bundle size reportTree-shaken production Metro bundles. Component costs are relative to their platform shell; shell costs are absolute.
The job is advisory: size changes are reported but do not fail the pull request. Bundle or analysis errors still fail. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Platforms Impacted
Description of changes
Adds the nine X3/Flex components that are ready now that Callout and FocusZone are available:
Each component includes its reviewed React Native contract, source provenance, token styling, runtime and type coverage, Storybook stories, and package exports.
This also:
accessibilityRoleto React Native's ARIA-alignedroleprop.Closes #4218
Closes #4221
Closes #4227
Closes #4228
Closes #4229
Closes #4234
Closes #4236
Closes #4239
Closes #4249
Verification
yarn workspace @fluentui-react-native/framework-base formatyarn workspace @fluentui-react-native/framework-base lintyarn workspace @fluentui-react-native/framework-base test(137 tests)yarn workspace @fluentui-react-native/design formatyarn workspace @fluentui-react-native/design lintyarn workspace @fluentui-react-native/design test(263 tests)yarn workspace @fluentui-react-native/components formatyarn workspace @fluentui-react-native/components lintyarn workspace @fluentui-react-native/components test(72 test files)yarn change:checkyarn buildPull request checklist
This PR has considered (when applicable):