diff --git a/change/@fluentui-react-components-5b15aaa9-20f7-44b3-a369-8096b4cdf7eb.json b/change/@fluentui-react-components-5b15aaa9-20f7-44b3-a369-8096b4cdf7eb.json new file mode 100644 index 00000000000000..187195fcdf05c9 --- /dev/null +++ b/change/@fluentui-react-components-5b15aaa9-20f7-44b3-a369-8096b4cdf7eb.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "feat: Export useRestoreFocusTarget and useRestoreFocusSource", + "packageName": "@fluentui/react-components", + "email": "lingfan.gao@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-dialog-6ac1e0ff-b5c6-4471-836a-49470b24f8c3.json b/change/@fluentui-react-dialog-6ac1e0ff-b5c6-4471-836a-49470b24f8c3.json new file mode 100644 index 00000000000000..0c0bf453cac7b6 --- /dev/null +++ b/change/@fluentui-react-dialog-6ac1e0ff-b5c6-4471-836a-49470b24f8c3.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "fix: Focus should restore to a DialogTrigger outside of a Dialog", + "packageName": "@fluentui/react-dialog", + "email": "lingfan.gao@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-menu-fdccbc10-8c41-442c-bac0-f034e5e3c266.json b/change/@fluentui-react-menu-fdccbc10-8c41-442c-bac0-f034e5e3c266.json new file mode 100644 index 00000000000000..f58d41be215d65 --- /dev/null +++ b/change/@fluentui-react-menu-fdccbc10-8c41-442c-bac0-f034e5e3c266.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "refactor: Remove custom focus code in favour of useRestoreFocus hooks", + "packageName": "@fluentui/react-menu", + "email": "lingfan.gao@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-tabster-c0ff6814-1ae9-4231-a304-d985128bdc9b.json b/change/@fluentui-react-tabster-c0ff6814-1ae9-4231-a304-d985128bdc9b.json new file mode 100644 index 00000000000000..5571d5c3038b05 --- /dev/null +++ b/change/@fluentui-react-tabster-c0ff6814-1ae9-4231-a304-d985128bdc9b.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "feat: Implement useRestoreFocusSource and useRestoreFocusTarget based on the tabster restorer API", + "packageName": "@fluentui/react-tabster", + "email": "lingfan.gao@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/packages/react-components/react-components/etc/react-components.api.md b/packages/react-components/react-components/etc/react-components.api.md index c77d39d33ddb86..22b016bee11aea 100644 --- a/packages/react-components/react-components/etc/react-components.api.md +++ b/packages/react-components/react-components/etc/react-components.api.md @@ -1001,6 +1001,8 @@ import { useRadioGroupContextValue_unstable } from '@fluentui/react-radio'; import { useRadioGroupContextValues } from '@fluentui/react-radio'; import { useRadioGroupStyles_unstable } from '@fluentui/react-radio'; import { useRadioStyles_unstable } from '@fluentui/react-radio'; +import { useRestoreFocusSource } from '@fluentui/react-tabster'; +import { useRestoreFocusTarget } from '@fluentui/react-tabster'; import { useScrollbarWidth } from '@fluentui/react-utilities'; import { useSelect_unstable } from '@fluentui/react-select'; import { useSelectStyles_unstable } from '@fluentui/react-select'; @@ -3087,6 +3089,10 @@ export { useRadioGroupStyles_unstable } export { useRadioStyles_unstable } +export { useRestoreFocusSource } + +export { useRestoreFocusTarget } + export { useScrollbarWidth } export { useSelect_unstable } diff --git a/packages/react-components/react-components/src/index.ts b/packages/react-components/react-components/src/index.ts index 2fe634a7b09f6d..b1a7fdb853336d 100644 --- a/packages/react-components/react-components/src/index.ts +++ b/packages/react-components/react-components/src/index.ts @@ -40,6 +40,8 @@ export { useModalAttributes, useObservedElement, useFocusObserved, + useRestoreFocusTarget, + useRestoreFocusSource, } from '@fluentui/react-tabster'; export type { CreateCustomFocusIndicatorStyleOptions, diff --git a/packages/react-components/react-components/stories/Concepts/FocusManagement/useRestoreFocusSource/Default.stories.stories.tsx b/packages/react-components/react-components/stories/Concepts/FocusManagement/useRestoreFocusSource/Default.stories.stories.tsx new file mode 100644 index 00000000000000..77f4449c45436c --- /dev/null +++ b/packages/react-components/react-components/stories/Concepts/FocusManagement/useRestoreFocusSource/Default.stories.stories.tsx @@ -0,0 +1,54 @@ +import * as React from 'react'; +import { ThumbLikeRegular, ThumbDislikeRegular } from '@fluentui/react-icons'; +import { + useRestoreFocusSource, + useRestoreFocusTarget, + Button, + makeStyles, + Textarea, + Field, +} from '@fluentui/react-components'; + +const useStyles = makeStyles({ + feedback: { + display: 'flex', + alignItems: 'center', + }, + + field: { + width: '300px', + }, +}); + +export const Default = () => { + const styles = useStyles(); + const restoreFocusSourceAttribute = useRestoreFocusSource(); + const restoreFocusTargetAttribute = useRestoreFocusTarget(); + const [feedbackSent, setFeedbackSent] = React.useState(false); + + React.useEffect(() => { + if (feedbackSent) { + const timeout = setTimeout(() => setFeedbackSent(false), 5000); + return () => clearTimeout(timeout); + } + }, [feedbackSent]); + + return ( +
+ +