diff --git a/apps/fluent-tester/src/FluentTesterApp.tsx b/apps/fluent-tester/src/FluentTesterApp.tsx index c6dd4a82667..37e2a084984 100644 --- a/apps/fluent-tester/src/FluentTesterApp.tsx +++ b/apps/fluent-tester/src/FluentTesterApp.tsx @@ -2,17 +2,50 @@ import { ThemeProvider } from '@fluentui-react-native/theme'; import * as React from 'react'; -import { Platform } from 'react-native'; +import { Platform, useWindowDimensions } from 'react-native'; import { FluentTester, FluentTesterProps } from './FluentTester'; import { tests } from './testPages'; import { testerTheme } from './theme/index'; -const isMobile = Platform.OS == 'android' || (Platform.OS === 'ios' && Platform.isPad === false); +type SizeClassIOS = 'regular' | 'compact' | undefined; + +/** + * Hook that "guesses" our Size Class on iOS based on our window width. + * Note: this is hacky and should not be used. + * + * For more information about Size Classes, see the following: + * https://developer.apple.com/documentation/uikit/uitraitcollection + * https://developer.apple.com/design/human-interface-guidelines/foundations/layout/#platform-considerations + * @returns SizeClassIOS: enum determining our size class + */ +const useSizeClassIOS_DO_NOT_USE: () => SizeClassIOS = () => { + if (Platform.OS === 'ios') { + /** + * Technically this violates the rules of hooks (calling hooks inside conditions) but Platform.OS checks are pretty non-conditional. + * This is necessary because useWindowDimensions() does not work in win32. + */ + // eslint-disable-next-line react-hooks/rules-of-hooks + const width = useWindowDimensions().width; + if (Platform.isPad && width > 375) { + return 'regular'; + } else { + return 'compact'; + } + } else { + return undefined; + } +}; export const FluentTesterApp: React.FunctionComponent = (props) => { + const sizeClass = useSizeClassIOS_DO_NOT_USE(); + const isMobile = Platform.OS == 'android' || (Platform.OS === 'ios' && Platform.isPad === false); + + // If on iPad we are presented in a Split View or Slide Over context, show the single pane view. + const shouldShowSinglePane = isMobile || (!isMobile && sizeClass === 'compact'); + return ( - + ); }; diff --git a/apps/fluent-tester/src/TestComponents/Notification/assets/play_button.svg b/apps/fluent-tester/src/TestComponents/Notification/assets/play_button.svg index e3c37a2f3ff..c6aeddb18c7 100644 --- a/apps/fluent-tester/src/TestComponents/Notification/assets/play_button.svg +++ b/apps/fluent-tester/src/TestComponents/Notification/assets/play_button.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/change/@fluentui-react-native-notification-27f44543-f5eb-46d8-a19f-96ccff3e986e.json b/change/@fluentui-react-native-notification-27f44543-f5eb-46d8-a19f-96ccff3e986e.json new file mode 100644 index 00000000000..732d75ebb3b --- /dev/null +++ b/change/@fluentui-react-native-notification-27f44543-f5eb-46d8-a19f-96ccff3e986e.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "add ipad width", + "packageName": "@fluentui-react-native/notification", + "email": "joannaquu@gmail.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-native-tester-0dab170f-4bbd-463c-b94a-48f2687663bf.json b/change/@fluentui-react-native-tester-0dab170f-4bbd-463c-b94a-48f2687663bf.json new file mode 100644 index 00000000000..b4f8cc6e40c --- /dev/null +++ b/change/@fluentui-react-native-tester-0dab170f-4bbd-463c-b94a-48f2687663bf.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "add support for compact mode", + "packageName": "@fluentui-react-native/tester", + "email": "joannaquu@gmail.com", + "dependentChangeType": "patch" +} diff --git a/packages/components/Notification/src/Notification.tsx b/packages/components/Notification/src/Notification.tsx index f2da20dec45..30e2d07c3d0 100644 --- a/packages/components/Notification/src/Notification.tsx +++ b/packages/components/Notification/src/Notification.tsx @@ -1,7 +1,7 @@ /** @jsx withSlots */ import { notification, NotificationType, NotificationProps } from './Notification.types'; import { Pressable } from '@fluentui-react-native/pressable'; -import { PressableProps, View, ViewStyle } from 'react-native'; +import { Platform, PressableProps, useWindowDimensions, View, ViewStyle } from 'react-native'; import { Icon } from '@fluentui-react-native/icon'; import { Text } from '@fluentui-react-native/experimental-text'; import { stylingSettings } from './Notification.styling'; @@ -11,6 +11,29 @@ import { createIconProps } from '@fluentui-react-native/interactive-hooks'; import { NotificationButton, createNotificationButtonProps } from './Notification.helper'; import { Shadow } from '@fluentui-react-native/experimental-shadow'; +type SizeClassIOS = 'regular' | 'compact' | undefined; + +/** + * Hook that "guesses" our Size Class on iOS based on our window width. + * Note: this is hacky and should not be used. + * + * For more information about Size Classes, see the following: + * https://developer.apple.com/documentation/uikit/uitraitcollection + * https://developer.apple.com/design/human-interface-guidelines/foundations/layout/#platform-considerations + * @returns SizeClassIOS: enum determining our size class + */ +const useSizeClassIOS_DO_NOT_USE: () => SizeClassIOS = () => { + const width = useWindowDimensions().width; + if (Platform.OS === 'ios') { + if (Platform.isPad && width > 375) { + return 'regular'; + } else { + return 'compact'; + } + } else { + return undefined; + } +}; /** * A function which determines if a set of styles should be applied to the component given the current state and props of the Notification. * @@ -41,15 +64,22 @@ export const Notification = compose({ useRender: (userProps: NotificationProps, useSlots: UseSlots) => { const Slots = useSlots(userProps, (layer) => notificationLookup(layer, userProps)); const isBar = ['primaryOutlineBar', 'primaryBar', 'neutralBar'].includes(userProps.variant); + const width = useWindowDimensions().width / 2; + const sizeClass = useSizeClassIOS_DO_NOT_USE(); + const onActionPress = userProps.onActionPress; + const rootStyle: ViewStyle = useMemo(() => { const marginHorizontal = isBar ? 0 : 16; - return { marginHorizontal: marginHorizontal }; - }, ['isBar']); + if (sizeClass === 'regular' && !isBar) { + return { alignSelf: 'center', marginHorizontal: marginHorizontal, width: width }; + } else { + return { marginHorizontal: marginHorizontal }; + } + }, [isBar, width]); const messageStyle: ViewStyle = useMemo(() => { - const onActionPress = userProps.onActionPress; const alignSelf = onActionPress ? 'flex-start' : 'center'; return { alignSelf: alignSelf }; - }, ['onActionPress']); + }, [onActionPress]); return (final: NotificationProps, ...children: React.ReactNode[]) => { const { variant, icon, title, action, onActionPress, ...rest } = mergeProps(userProps, final);