Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Docs: Add 'Change Event Callback' pattern doc #33216

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions docs/react-v9/contributing/patterns/change-event-callbacks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
## Change Event Callbacks

Fluent UI React V9 implements event callbacks to expose internal state changes to consumers. These callbacks pass both the event data and the underlying React or DOM event for consumption.
mltejera marked this conversation as resolved.
Show resolved Hide resolved

An example of this is the boolean change on Dialog to open or close via internal interactions, surfacing these events ensures that controlled implementations can update based on internal state.

```
// Dialog.types..ts
export type DialogOpenChangeEvent = DialogOpenChangeData['event'];

export type DialogOpenChangeData =
| {
type: 'escapeKeyDown';
open: boolean;
event: React.KeyboardEvent<DialogSurfaceElement>;
}
| {
type: 'backdropClick';
open: boolean;
event: React.MouseEvent<DialogSurfaceElement>;
}
| {
type: 'triggerClick';
open: boolean;
event: React.MouseEvent<DialogSurfaceElement>;
};
/**
* Callback fired when the component changes value from open state.
Mitch-At-Work marked this conversation as resolved.
Show resolved Hide resolved
*
* @param event - a React's Synthetic event or a KeyboardEvent in case of `documentEscapeKeyDown`
* @param data - A data object with relevant information,
* such as open value and type of interaction that created the event
*/
export type DialogOpenChangeEventHandler = (event: DialogOpenChangeEvent, data: DialogOpenChangeData) => void;

/**
* Callback fired when the component changes value from open state.
*
* @param event - a React's Synthetic event or a KeyboardEvent in case of `documentEscapeKeyDown`
* @param data - A data object with relevant information,
* such as open value and type of interaction that created the event
*/
// eslint-disable-next-line @nx/workspace-consistent-callback-type -- can't change type of existing callback
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a deprecated callback type. What about use an example that uses the new callback type? For example TagPicker onOpenChange?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the first example is all taken from dialog. So maybe just add a comment somewhere here pointing to a component that uses the new type like TagPicker

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch thank you! I'll replace this with the latest

onOpenChange?: DialogOpenChangeEventHandler;
```

When implementing callback events be mindful of:

1.) All events for a state change must be supported, take care to leave flexibility in data and event types to prevent breaking changes if new functionality is added
Mitch-At-Work marked this conversation as resolved.
Show resolved Hide resolved

2.) Some callbacks may not have an underlying DOM or React event to bubble if not driven by user interaction, such as a timer based interactions. If non-event callbacks may be required in the future, it is important to set event types as optional to prevent breaking changes when not present.
Loading