From 2c0a7382a3c85b31645e7426287413f739a5de65 Mon Sep 17 00:00:00 2001 From: Andrew Coates <30809111+acoates-ms@users.noreply.github.com> Date: Fri, 17 May 2024 09:19:47 -0700 Subject: [PATCH 1/4] Move platform theming logic from button component into theme --- .../components/Button/src/Button.styling.ts | 39 +- packages/components/Button/src/Button.tsx | 21 +- .../components/Button/src/Button.types.ts | 10 + .../Button/src/ButtonColorTokens.android.ts | 81 --- .../Button/src/ButtonFontTokens.android.ts | 23 - .../Button/src/ButtonFontTokens.ios.ts | 23 - .../components/Button/src/ButtonFontTokens.ts | 21 - .../Button/src/ButtonFontTokens.win32.ts | 30 - .../Button/src/ButtonTokens.android.ts | 83 --- .../Button/src/ButtonTokens.win32.ts | 166 ----- .../CompoundButton/CompoundButton.styling.ts | 10 - .../src/CompoundButton/CompoundButton.tsx | 5 +- .../components/Button/src/FAB/FAB.styling.ts | 4 +- .../src/ToggleButton/ToggleButton.styling.ts | 6 +- .../Button/src/ToggleButton/ToggleButton.tsx | 5 +- packages/theming/android-theme/package.json | 1 + .../__snapshots__/android-theme.test.ts.snap | 675 ++++++++++++++++++ .../src/__tests__/android-theme.test.ts | 23 + .../components/Button/ButtonColorTokens.ts | 78 ++ .../src/components/Button/ButtonFontTokens.ts | 21 + .../src/components/Button/ButtonTheme.ts | 21 + .../src/components/Button/ButtonTokens.ts | 96 +++ .../src/components/Button}/FABColorTokens.ts | 5 +- .../src/components/Button}/FABTokens.ts | 9 +- .../Button}/ToggleButtonColorTokens.ts | 5 +- .../android-theme/src/createAndroidTheme.ts | 9 +- packages/theming/apple-theme/package.json | 1 + .../__snapshots__/apple-theme.test.ts.snap | 143 ++++ .../src/__tests__/apple-theme.test.ts | 23 + .../Button}/ButtonColorTokens.macos.ts | 7 +- .../components/Button/ButtonColorTokens.ts | 5 + .../components/Button/ButtonFontTokens.ios.ts | 20 + .../Button}/ButtonFontTokens.macos.ts | 7 +- .../src/components/Button/ButtonFontTokens.ts | 5 + .../src/components/Button/ButtonTheme.ts | 36 + .../components/Button}/ButtonTokens.ios.ts | 28 +- .../src/components/Button/ButtonTokens.ts | 101 +++ .../Button}/CompoundButtonColorTokens.ts | 5 +- .../Button}/CompoundButtonFontTokens.ts | 5 +- .../Button}/CompoundButtonTokens.ts | 5 +- .../src/components/Button/FABColorTokens.ts} | 5 +- .../src/components/Button/FABTokens.ts} | 9 +- .../Button/ToggleButtonColorTokens.ts | 21 + .../apple-theme/src/createAppleTheme.ios.ts | 7 +- .../apple-theme/src/createAppleTheme.macos.ts | 8 +- packages/theming/default-theme/package.json | 1 + .../src/__tests__/default-theme.test.ts | 30 + .../components/Button}/ButtonColorTokens.ts | 7 +- .../Button}/ButtonColorTokens.windows.ts | 7 +- .../src/components/Button/ButtonFontTokens.ts | 20 + .../src/components/Button/ButtonTheme.ts | 34 + .../src/components/Button}/ButtonTokens.ts | 27 +- .../Button/CompoundButtonColorTokens.ts | 38 + .../CompoundButtonColorTokens.windows.ts | 5 +- .../Button/CompoundButtonFontTokens.ts | 24 + .../components/Button/CompoundButtonTokens.ts | 80 +++ .../Button/ToggleButtonColorTokens.ts | 21 + .../ToggleButtonColorTokens.windows.ts | 5 +- .../default-theme/src/createDefaultTheme.ts | 7 +- packages/theming/theme-tokens/src/index.ts | 3 + packages/theming/win32-theme/package.json | 3 + .../__snapshots__/win32-theme.test.ts.snap | 259 +++++++ .../src/__tests__/win32-theme.test.ts | 30 + .../components/Button/ButtonColorTokens.ts} | 7 +- .../src/components/Button/ButtonFontTokens.ts | 28 + .../src/components/Button/ButtonTheme.ts | 34 + .../src/components/Button/ButtonTokens.ts | 183 +++++ .../Button/CompoundButtonColorTokens.ts} | 7 +- .../Button/CompoundButtonFontTokens.ts} | 7 +- .../Button/CompoundButtonTokens.ts} | 7 +- .../Button/ToggleButtonColorTokens.ts} | 5 +- .../win32-theme/src/createOfficeTheme.ts | 2 + yarn.lock | 6 + 73 files changed, 2192 insertions(+), 606 deletions(-) delete mode 100644 packages/components/Button/src/ButtonColorTokens.android.ts delete mode 100644 packages/components/Button/src/ButtonFontTokens.android.ts delete mode 100644 packages/components/Button/src/ButtonFontTokens.ios.ts delete mode 100644 packages/components/Button/src/ButtonFontTokens.ts delete mode 100644 packages/components/Button/src/ButtonFontTokens.win32.ts delete mode 100644 packages/components/Button/src/ButtonTokens.android.ts delete mode 100644 packages/components/Button/src/ButtonTokens.win32.ts create mode 100644 packages/theming/android-theme/src/components/Button/ButtonColorTokens.ts create mode 100644 packages/theming/android-theme/src/components/Button/ButtonFontTokens.ts create mode 100644 packages/theming/android-theme/src/components/Button/ButtonTheme.ts create mode 100644 packages/theming/android-theme/src/components/Button/ButtonTokens.ts rename packages/{components/Button/src/FAB => theming/android-theme/src/components/Button}/FABColorTokens.ts (88%) rename packages/{components/Button/src/FAB => theming/android-theme/src/components/Button}/FABTokens.ts (89%) rename packages/{components/Button/src/ToggleButton => theming/android-theme/src/components/Button}/ToggleButtonColorTokens.ts (71%) rename packages/{components/Button/src => theming/apple-theme/src/components/Button}/ButtonColorTokens.macos.ts (93%) create mode 100644 packages/theming/apple-theme/src/components/Button/ButtonColorTokens.ts create mode 100644 packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ios.ts rename packages/{components/Button/src => theming/apple-theme/src/components/Button}/ButtonFontTokens.macos.ts (55%) create mode 100644 packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ts create mode 100644 packages/theming/apple-theme/src/components/Button/ButtonTheme.ts rename packages/{components/Button/src => theming/apple-theme/src/components/Button}/ButtonTokens.ios.ts (70%) create mode 100644 packages/theming/apple-theme/src/components/Button/ButtonTokens.ts rename packages/{components/Button/src/CompoundButton => theming/apple-theme/src/components/Button}/CompoundButtonColorTokens.ts (79%) rename packages/{components/Button/src/CompoundButton => theming/apple-theme/src/components/Button}/CompoundButtonFontTokens.ts (63%) rename packages/{components/Button/src/CompoundButton => theming/apple-theme/src/components/Button}/CompoundButtonTokens.ts (89%) rename packages/{components/Button/src/FAB/FABColorTokens.ios.ts => theming/apple-theme/src/components/Button/FABColorTokens.ts} (87%) rename packages/{components/Button/src/FAB/FABTokens.ios.ts => theming/apple-theme/src/components/Button/FABTokens.ts} (89%) create mode 100644 packages/theming/apple-theme/src/components/Button/ToggleButtonColorTokens.ts rename packages/{components/Button/src => theming/default-theme/src/components/Button}/ButtonColorTokens.ts (92%) rename packages/{components/Button/src => theming/default-theme/src/components/Button}/ButtonColorTokens.windows.ts (95%) create mode 100644 packages/theming/default-theme/src/components/Button/ButtonFontTokens.ts create mode 100644 packages/theming/default-theme/src/components/Button/ButtonTheme.ts rename packages/{components/Button/src => theming/default-theme/src/components/Button}/ButtonTokens.ts (79%) create mode 100644 packages/theming/default-theme/src/components/Button/CompoundButtonColorTokens.ts rename packages/{components/Button/src/CompoundButton => theming/default-theme/src/components/Button}/CompoundButtonColorTokens.windows.ts (87%) create mode 100644 packages/theming/default-theme/src/components/Button/CompoundButtonFontTokens.ts create mode 100644 packages/theming/default-theme/src/components/Button/CompoundButtonTokens.ts create mode 100644 packages/theming/default-theme/src/components/Button/ToggleButtonColorTokens.ts rename packages/{components/Button/src/ToggleButton => theming/default-theme/src/components/Button}/ToggleButtonColorTokens.windows.ts (81%) rename packages/{components/Button/src/ButtonColorTokens.win32.ts => theming/win32-theme/src/components/Button/ButtonColorTokens.ts} (95%) create mode 100644 packages/theming/win32-theme/src/components/Button/ButtonFontTokens.ts create mode 100644 packages/theming/win32-theme/src/components/Button/ButtonTheme.ts create mode 100644 packages/theming/win32-theme/src/components/Button/ButtonTokens.ts rename packages/{components/Button/src/CompoundButton/CompoundButtonColorTokens.win32.ts => theming/win32-theme/src/components/Button/CompoundButtonColorTokens.ts} (86%) rename packages/{components/Button/src/CompoundButton/CompoundButtonFontTokens.win32.ts => theming/win32-theme/src/components/Button/CompoundButtonFontTokens.ts} (79%) rename packages/{components/Button/src/CompoundButton/CompoundButtonTokens.win32.ts => theming/win32-theme/src/components/Button/CompoundButtonTokens.ts} (93%) rename packages/{components/Button/src/ToggleButton/ToggleButtonColorTokens.win32.ts => theming/win32-theme/src/components/Button/ToggleButtonColorTokens.ts} (79%) diff --git a/packages/components/Button/src/Button.styling.ts b/packages/components/Button/src/Button.styling.ts index dc98c68ec9..48a8e5265b 100644 --- a/packages/components/Button/src/Button.styling.ts +++ b/packages/components/Button/src/Button.styling.ts @@ -8,10 +8,7 @@ import { borderStyles, layoutStyles, fontStyles } from '@fluentui-react-native/t import type { FontTokens } from '@fluentui-react-native/tokens'; import { buttonName } from './Button.types'; -import type { ButtonTokens, ButtonSlotProps, ButtonProps, ButtonSize, ButtonAppearance } from './Button.types'; -import { defaultButtonColorTokens } from './ButtonColorTokens'; -import { defaultButtonFontTokens } from './ButtonFontTokens'; -import { defaultButtonTokens } from './ButtonTokens'; +import type { ButtonTokens, ButtonSlotProps, ButtonProps } from './Button.types'; export const buttonStates: (keyof ButtonTokens)[] = [ 'block', @@ -34,7 +31,7 @@ export const buttonStates: (keyof ButtonTokens)[] = [ ]; export const stylingSettings: UseStylingOptions = { - tokens: [defaultButtonTokens, defaultButtonFontTokens, defaultButtonColorTokens, buttonName], + tokens: [buttonName], states: buttonStates, slotProps: { ...(Platform.OS === 'android' && { @@ -105,38 +102,6 @@ export const stylingSettings: UseStylingOptions { - if (Platform.OS === 'windows') { - return 'medium'; - } else if ((Platform.OS as any) === 'win32') { - return 'small'; - } - - return 'medium'; -}; - -export const getPlatformSpecificAppearance = (appearance: ButtonAppearance): ButtonAppearance => { - // Mobile platforms do not have seperate styling when no appearance is passed. - const hasDifferentDefaultAppearance = !(Platform.OS === 'android' || Platform.OS === 'ios'); - - switch (appearance) { - case 'accent': // Included to cover Mobile platform naming guidelines, maps to 'primary'. - return 'primary'; - - case 'primary': - case 'subtle': - case 'outline': // 'Outline' exists only for Mobile platforms, default picked on other platforms. - return appearance; - - default: - if (hasDifferentDefaultAppearance) { - return null; - } else { - return 'primary'; - } - } -}; - export const contentStyling = (tokens: ButtonTokens, theme: Theme, contentColor: ColorValue, fontStylesTokens: FontTokens) => { const textAdjustment = getTextMarginAdjustment(); const spacingIconContentBefore = tokens.spacingIconContentBefore diff --git a/packages/components/Button/src/Button.tsx b/packages/components/Button/src/Button.tsx index 7e498fbf9a..b4560d3127 100644 --- a/packages/components/Button/src/Button.tsx +++ b/packages/components/Button/src/Button.tsx @@ -6,13 +6,15 @@ import { Platform, Pressable, View } from 'react-native'; import { ActivityIndicator } from '@fluentui-react-native/experimental-activity-indicator'; import type { UseSlots } from '@fluentui-react-native/framework'; import { compose, memoize, mergeProps, withSlots } from '@fluentui-react-native/framework'; +import { useFluentTheme } from '@fluentui-react-native/framework'; import { Icon, createIconProps } from '@fluentui-react-native/icon'; import type { IPressableState } from '@fluentui-react-native/interactive-hooks'; import { TextV1 as Text } from '@fluentui-react-native/text'; +import type {Theme} from '@fluentui-react-native/theme-types'; -import { stylingSettings, getDefaultSize, getPlatformSpecificAppearance } from './Button.styling'; +import { stylingSettings } from './Button.styling'; import { buttonName } from './Button.types'; -import type { ButtonType, ButtonProps } from './Button.types'; +import type { ButtonType, ButtonProps, ButtonTokens } from './Button.types'; import { extractOuterStylePropsAndroid } from './ExtractStyle.android'; import { useButton } from './useButton'; @@ -22,15 +24,19 @@ import { useButton } from './useButton'; * @param layer The name of the state that is being checked for * @param state The current state of the button * @param userProps The props that were passed into the button + * @param theme The theme * @returns Whether the styles that are assigned to the layer should be applied to the button */ -export const buttonLookup = (layer: string, state: IPressableState, userProps: ButtonProps): boolean => { +export const buttonLookup = (layer: string, state: IPressableState, userProps: ButtonProps, theme: Theme): boolean => { + + const size = userProps['size'] ?? (theme?.components?.['Button'] as ButtonTokens)?.size ?? 'medium'; + const getPlatformSpecificAppearance = (theme?.components?.['Button'] as ButtonTokens)?.getPlatformSpecificAppearance; + const appearance = getPlatformSpecificAppearance ? getPlatformSpecificAppearance(userProps['appearance']) : null; return ( state[layer] || userProps[layer] || - layer === getPlatformSpecificAppearance(userProps['appearance']) || - layer === userProps['size'] || - (!userProps['size'] && layer === getDefaultSize()) || + layer === appearance || + layer === size || layer === userProps['shape'] || (!userProps['shape'] && layer === 'rounded') || (layer === 'hovered' && state[layer] && !userProps.loading) || @@ -52,10 +58,11 @@ export const Button = compose({ }, useRender: (userProps: ButtonProps, useSlots: UseSlots) => { const button = useButton(userProps); + const theme = useFluentTheme(); const iconProps = createIconProps(userProps.icon); // grab the styled slots - const Slots = useSlots(userProps, (layer) => buttonLookup(layer, button.state, userProps)); + const Slots = useSlots(userProps, (layer) => buttonLookup(layer, button.state, userProps, theme)); // now return the handler for finishing render return (final: ButtonProps, ...children: React.ReactNode[]) => { diff --git a/packages/components/Button/src/Button.types.ts b/packages/components/Button/src/Button.types.ts index 78ac37f033..ec2aacfb90 100644 --- a/packages/components/Button/src/Button.types.ts +++ b/packages/components/Button/src/Button.types.ts @@ -66,6 +66,11 @@ export interface ButtonCoreTokens extends LayoutTokens, FontTokens, IBorderToken borderInnerWidth?: number; borderInnerRadius?: number; borderInnerStyle?: ViewStyle['borderStyle']; + + /** + * The default size of the button + */ + size?: ButtonSize, } export interface ButtonTokens extends ButtonCoreTokens { @@ -89,6 +94,11 @@ export interface ButtonTokens extends ButtonCoreTokens { circular?: ButtonTokens; square?: ButtonTokens; hasIconAfter?: ButtonTokens; + + /** + * Returns the default appearance type, and can remap ButtonAppearances to other Appearances for this theme + */ + getPlatformSpecificAppearance?: (appearance: ButtonAppearance) => ButtonAppearance; } export interface ButtonCoreProps extends Omit { diff --git a/packages/components/Button/src/ButtonColorTokens.android.ts b/packages/components/Button/src/ButtonColorTokens.android.ts deleted file mode 100644 index 077f8f97bb..0000000000 --- a/packages/components/Button/src/ButtonColorTokens.android.ts +++ /dev/null @@ -1,81 +0,0 @@ -import type { Theme } from '@fluentui-react-native/framework'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; - -import type { ButtonTokens } from './Button.types'; - -export const defaultButtonColorTokens: TokenSettings = (t: Theme) => - ({ - /** Android does not have a different styles for 'default' button. - * 'primary', 'accent' and if no appearance is mentioned, picks this. - */ - backgroundColor: t.colors.brandBackground, - rippleColor: '#D4D4D4', - color: t.colors.neutralForegroundOnColor, - iconColor: t.colors.neutralForegroundOnColor, - disabled: { - backgroundColor: t.colors.neutralBackground5, - color: t.colors.neutralForegroundDisabled1, - iconColor: t.colors.neutralForegroundDisabled1, - }, - pressed: { - backgroundColor: t.colors.brandBackgroundPressed, - color: t.colors.neutralForegroundOnColor, - iconColor: t.colors.neutralForegroundOnColor, - }, - focused: { - backgroundColor: t.colors.brandBackground, - color: t.colors.neutralForegroundOnColor, - borderColor: t.colors.strokeFocus2, - borderInnerColor: t.colors.strokeFocus1, - iconColor: t.colors.neutralForegroundOnColor, - }, - subtle: { - backgroundColor: 'transparent', - rippleColor: '#D4D4D4', - color: t.colors.brandForeground1, - iconColor: t.colors.brandForeground1, - disabled: { - backgroundColor: 'transparent', - color: t.colors.neutralForegroundDisabled1, - iconColor: t.colors.neutralForegroundDisabled1, - }, - pressed: { - backgroundColor: 'transparent', - color: t.colors.brandForeground1Pressed, - iconColor: t.colors.brandForeground1Pressed, - }, - focused: { - backgroundColor: 'transparent', - borderColor: t.colors.strokeFocus2, - borderInnerColor: t.colors.strokeFocus1, - color: t.colors.brandForeground1, - iconColor: t.colors.brandForeground1, - }, - }, - outline: { - backgroundColor: 'transparent', - rippleColor: '#D4D4D4', - color: t.colors.brandForeground1, - iconColor: t.colors.brandForeground1, - borderColor: t.colors.brandStroke1, - disabled: { - backgroundColor: 'transparent', - color: t.colors.neutralForegroundDisabled1, - iconColor: t.colors.neutralForegroundDisabled1, - borderColor: t.colors.neutralStrokeDisabled, - }, - pressed: { - backgroundColor: 'transparent', - color: t.colors.brandForeground1Pressed, - iconColor: t.colors.brandForeground1Pressed, - borderColor: t.colors.brandStroke1Pressed, - }, - focused: { - backgroundColor: 'transparent', - borderColor: t.colors.strokeFocus2, - borderInnerColor: t.colors.strokeFocus1, - color: t.colors.brandForeground1, - iconColor: t.colors.brandForeground1, - }, - }, - } as ButtonTokens); diff --git a/packages/components/Button/src/ButtonFontTokens.android.ts b/packages/components/Button/src/ButtonFontTokens.android.ts deleted file mode 100644 index fa93871e5f..0000000000 --- a/packages/components/Button/src/ButtonFontTokens.android.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { Theme } from '@fluentui-react-native/framework'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; - -import type { ButtonTokens } from './Button.types'; - -export const defaultButtonFontTokens: TokenSettings = (t: Theme) => - ({ - medium: { - fontSize: t.typography.variants.body2Strong.size, - fontFamily: t.typography.variants.body2Strong.face, - fontWeight: t.typography.variants.body2Strong.weight, - }, - small: { - fontSize: t.typography.variants.body2Strong.size, - fontFamily: t.typography.variants.body2Strong.face, - fontWeight: t.typography.variants.body2Strong.weight, - }, - large: { - fontSize: t.typography.variants.body1Strong.size, - fontFamily: t.typography.variants.body1Strong.face, - fontWeight: t.typography.variants.body1Strong.weight, - }, - } as ButtonTokens); diff --git a/packages/components/Button/src/ButtonFontTokens.ios.ts b/packages/components/Button/src/ButtonFontTokens.ios.ts deleted file mode 100644 index 664da18b12..0000000000 --- a/packages/components/Button/src/ButtonFontTokens.ios.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { Theme } from '@fluentui-react-native/framework'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; - -import type { ButtonTokens } from './Button.types'; - -export const defaultButtonFontTokens: TokenSettings = (t: Theme) => - ({ - medium: { - fontSize: t.typography.variants.caption1Strong.size, - fontFamily: t.typography.variants.caption1Strong.face, - fontWeight: t.typography.variants.caption1Strong.weight, - }, - small: { - fontSize: t.typography.variants.caption1Strong.size, - fontFamily: t.typography.variants.caption1Strong.face, - fontWeight: t.typography.variants.caption1Strong.weight, - }, - large: { - fontSize: t.typography.variants.body1Strong.size, - fontFamily: t.typography.variants.body1Strong.face, - fontWeight: t.typography.variants.body1Strong.weight, - }, - } as ButtonTokens); diff --git a/packages/components/Button/src/ButtonFontTokens.ts b/packages/components/Button/src/ButtonFontTokens.ts deleted file mode 100644 index 2208b003ce..0000000000 --- a/packages/components/Button/src/ButtonFontTokens.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { Theme } from '@fluentui-react-native/framework'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; - -import type { ButtonTokens } from './Button.types'; - -export const defaultButtonFontTokens: TokenSettings = (_t: Theme) => - ({ - medium: { - hasContent: { - variant: 'bodySemibold', - }, - }, - small: { - hasContent: { - variant: 'secondaryStandard', - }, - }, - large: { - variant: 'subheaderSemibold', - }, - } as ButtonTokens); diff --git a/packages/components/Button/src/ButtonFontTokens.win32.ts b/packages/components/Button/src/ButtonFontTokens.win32.ts deleted file mode 100644 index 0d89579b40..0000000000 --- a/packages/components/Button/src/ButtonFontTokens.win32.ts +++ /dev/null @@ -1,30 +0,0 @@ -import type { Theme } from '@fluentui-react-native/framework'; -import { globalTokens } from '@fluentui-react-native/theme-tokens'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; - -import type { ButtonTokens } from './Button.types'; - -export const defaultButtonFontTokens: TokenSettings = (t: Theme) => - ({ - medium: { - hasContent: { - fontFamily: t.typography.families.secondary, - fontSize: globalTokens.font.size300, - fontWeight: globalTokens.font.weight.semibold, - }, - }, - small: { - hasContent: { - fontFamily: t.typography.families.primary, - fontSize: globalTokens.font.size200, - fontWeight: globalTokens.font.weight.regular, - }, - }, - large: { - hasContent: { - fontFamily: t.typography.families.secondary, - fontSize: globalTokens.font.size400, - fontWeight: globalTokens.font.weight.semibold, - }, - }, - } as ButtonTokens); diff --git a/packages/components/Button/src/ButtonTokens.android.ts b/packages/components/Button/src/ButtonTokens.android.ts deleted file mode 100644 index d8cc066604..0000000000 --- a/packages/components/Button/src/ButtonTokens.android.ts +++ /dev/null @@ -1,83 +0,0 @@ -import type { Theme } from '@fluentui-react-native/framework'; -import { globalTokens } from '@fluentui-react-native/theme-tokens'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; - -import type { ButtonTokens } from './Button.types'; - -export const defaultButtonTokens: TokenSettings = () => - ({ - focused: { - borderWidth: globalTokens.stroke.width20, - borderInnerWidth: globalTokens.stroke.width10, - }, - subtle: { - focused: { - borderWidth: globalTokens.stroke.width20, - borderInnerWidth: globalTokens.stroke.width10, - }, - }, - outline: { - borderWidth: globalTokens.stroke.width10, - disabled: { - borderWidth: globalTokens.stroke.width10, - }, - pressed: { - borderWidth: globalTokens.stroke.width10, - }, - focused: { - borderWidth: globalTokens.stroke.width20, - borderInnerWidth: globalTokens.stroke.width10, - }, - }, - block: { - width: '100%', - }, - large: { - paddingHorizontal: globalTokens.size200, - borderRadius: globalTokens.corner.radius80, - iconSize: 20, - outline: { - borderWidth: globalTokens.stroke.width10, - iconSize: 20, - }, - spacingIconContentBefore: globalTokens.size80, - spacingIconContentAfter: globalTokens.size80, - minHeight: 48, - minWidth: 36, - }, - medium: { - paddingHorizontal: globalTokens.size120, - borderRadius: globalTokens.corner.radius40, - iconSize: 20, - outline: { - borderWidth: globalTokens.stroke.width10, - iconSize: 20, - }, - spacingIconContentBefore: globalTokens.size80, - spacingIconContentAfter: globalTokens.size80, - minHeight: 36, - minWidth: 36, - }, - small: { - paddingHorizontal: globalTokens.size80, - borderRadius: globalTokens.corner.radius40, - iconSize: 16, - outline: { - borderWidth: globalTokens.stroke.width10, - iconSize: 16, - }, - spacingIconContentBefore: globalTokens.size40, - spacingIconContentAfter: globalTokens.size40, - minHeight: 28, - minWidth: 28, - }, - rounded: { - borderRadius: globalTokens.corner.radius40, - }, - circular: { - borderRadius: globalTokens.corner.radiusCircular, - }, - square: { - borderRadius: globalTokens.corner.radiusNone, - }, - } as ButtonTokens); diff --git a/packages/components/Button/src/ButtonTokens.win32.ts b/packages/components/Button/src/ButtonTokens.win32.ts deleted file mode 100644 index fcb96da30b..0000000000 --- a/packages/components/Button/src/ButtonTokens.win32.ts +++ /dev/null @@ -1,166 +0,0 @@ -import type { Theme } from '@fluentui-react-native/framework'; -import { globalTokens } from '@fluentui-react-native/theme-tokens'; -import { isHighContrast } from '@fluentui-react-native/theming-utils'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; - -import type { ButtonTokens } from './Button.types'; - -export const defaultButtonTokens: TokenSettings = (theme: Theme) => - ({ - borderWidth: globalTokens.stroke.width10, - borderInnerWidth: globalTokens.stroke.width10, - block: { - width: '100%', - }, - medium: { - padding: globalTokens.size80 - globalTokens.stroke.width10, - iconSize: 16, - focused: { - borderWidth: 0, - padding: globalTokens.size80, - }, - primary: !isHighContrast(theme) && { - focused: { - borderWidth: globalTokens.stroke.width20, - padding: globalTokens.size80 - globalTokens.stroke.width20, - }, - square: { - focused: { - borderWidth: globalTokens.stroke.width10, - padding: globalTokens.size80 - globalTokens.stroke.width10, - }, - }, - }, - hasContent: { - minWidth: 96, - padding: globalTokens.size60 - globalTokens.stroke.width10, - paddingHorizontal: globalTokens.size120 - globalTokens.stroke.width10, - hasIconAfter: { - spacingIconContentAfter: globalTokens.size80, - }, - hasIconBefore: { - spacingIconContentBefore: globalTokens.size80, - }, - focused: { - padding: globalTokens.size60, - paddingHorizontal: globalTokens.size120, - }, - primary: !isHighContrast(theme) && { - focused: { - padding: globalTokens.size60 - globalTokens.stroke.width20, - paddingHorizontal: globalTokens.size120 - globalTokens.stroke.width20, - }, - square: { - focused: { - padding: globalTokens.size60 - globalTokens.stroke.width10, - paddingHorizontal: globalTokens.size120 - globalTokens.stroke.width10, - }, - }, - }, - }, - }, - small: { - padding: globalTokens.size40 - globalTokens.stroke.width10, - iconSize: 16, - focused: { - borderWidth: 0, - padding: globalTokens.size40, - }, - primary: !isHighContrast(theme) && { - focused: { - borderWidth: globalTokens.stroke.width20, - padding: globalTokens.size40 - globalTokens.stroke.width20, - }, - square: { - focused: { - borderWidth: globalTokens.stroke.width10, - padding: globalTokens.size40 - globalTokens.stroke.width10, - }, - }, - }, - hasContent: { - minWidth: 64, - minHeight: 24, - paddingHorizontal: globalTokens.size80 - globalTokens.stroke.width10, - hasIconAfter: { - spacingIconContentAfter: globalTokens.size40, - }, - hasIconBefore: { - spacingIconContentBefore: globalTokens.size40, - }, - focused: { - paddingHorizontal: globalTokens.size80, - }, - primary: !isHighContrast(theme) && { - focused: { - paddingHorizontal: globalTokens.size80 - globalTokens.stroke.width20, - }, - square: { - focused: { - paddingHorizontal: globalTokens.size80 - globalTokens.stroke.width10, - }, - }, - }, - }, - }, - large: { - padding: globalTokens.size100 - globalTokens.stroke.width10, - iconSize: 20, - focused: { - borderWidth: 0, - padding: globalTokens.size100, - }, - primary: !isHighContrast(theme) && { - focused: { - borderWidth: globalTokens.stroke.width20, - padding: globalTokens.size100 - globalTokens.stroke.width20, - }, - square: { - focused: { - borderWidth: globalTokens.stroke.width10, - padding: globalTokens.size100 - globalTokens.stroke.width10, - }, - }, - }, - hasContent: { - minWidth: 96, - minHeight: 40, - padding: globalTokens.size80 - globalTokens.stroke.width10, - paddingHorizontal: globalTokens.size160 - globalTokens.stroke.width10, - hasIconAfter: { - spacingIconContentAfter: globalTokens.size60, - }, - hasIconBefore: { - spacingIconContentBefore: globalTokens.size60, - }, - focused: { - padding: globalTokens.size80, - paddingHorizontal: globalTokens.size160, - }, - primary: !isHighContrast(theme) && { - focused: { - padding: globalTokens.size80 - globalTokens.stroke.width20, - paddingHorizontal: globalTokens.size160 - globalTokens.stroke.width20, - }, - square: { - focused: { - padding: globalTokens.size80 - globalTokens.stroke.width10, - paddingHorizontal: globalTokens.size160 - globalTokens.stroke.width10, - }, - }, - }, - }, - }, - rounded: { - borderRadius: globalTokens.corner.radius40, - borderInnerRadius: globalTokens.corner.radius40 - 1, // reduce the rounding so that the curvature matches - }, - circular: { - borderRadius: globalTokens.corner.radiusCircular, - borderInnerRadius: globalTokens.corner.radiusCircular - 1, // reduce the rounding so that the curvature matches - }, - square: { - borderRadius: globalTokens.corner.radiusNone, - borderInnerRadius: globalTokens.corner.radiusNone, - }, - } as ButtonTokens); diff --git a/packages/components/Button/src/CompoundButton/CompoundButton.styling.ts b/packages/components/Button/src/CompoundButton/CompoundButton.styling.ts index 1b72d0d3e0..88387811f7 100644 --- a/packages/components/Button/src/CompoundButton/CompoundButton.styling.ts +++ b/packages/components/Button/src/CompoundButton/CompoundButton.styling.ts @@ -4,20 +4,10 @@ import { borderStyles, fontStyles, layoutStyles } from '@fluentui-react-native/t import { compoundButtonName } from './CompoundButton.types'; import type { CompoundButtonTokens, CompoundButtonSlotProps, CompoundButtonProps } from './CompoundButton.types'; -import { defaultCompoundButtonColorTokens } from './CompoundButtonColorTokens'; -import { defaultCompoundButtonFontTokens } from './CompoundButtonFontTokens'; -import { defaultCompoundButtonTokens } from './CompoundButtonTokens'; import { buttonStates, contentStyling } from '../Button.styling'; -import { defaultButtonColorTokens } from '../ButtonColorTokens'; -import { defaultButtonTokens } from '../ButtonTokens'; export const stylingSettings: UseStylingOptions = { tokens: [ - defaultButtonTokens, - defaultButtonColorTokens, - defaultCompoundButtonTokens, - defaultCompoundButtonFontTokens, - defaultCompoundButtonColorTokens, compoundButtonName, ], states: buttonStates, diff --git a/packages/components/Button/src/CompoundButton/CompoundButton.tsx b/packages/components/Button/src/CompoundButton/CompoundButton.tsx index c48c0e17f1..ccec491ea1 100644 --- a/packages/components/Button/src/CompoundButton/CompoundButton.tsx +++ b/packages/components/Button/src/CompoundButton/CompoundButton.tsx @@ -5,7 +5,7 @@ import { Platform, Pressable, View } from 'react-native'; import { ActivityIndicator } from '@fluentui-react-native/experimental-activity-indicator'; import type { UseSlots } from '@fluentui-react-native/framework'; -import { compose, mergeProps, withSlots } from '@fluentui-react-native/framework'; +import { compose, mergeProps, useFluentTheme, withSlots } from '@fluentui-react-native/framework'; import { Icon, createIconProps } from '@fluentui-react-native/icon'; import { TextV1 as Text } from '@fluentui-react-native/text'; @@ -29,9 +29,10 @@ export const CompoundButton = compose({ useRender: (userProps: CompoundButtonProps, useSlots: UseSlots) => { const button = useButton(userProps); const iconProps = createIconProps(userProps.icon); + const theme = useFluentTheme(); // grab the styled slots - const Slots = useSlots(userProps, (layer) => buttonLookup(layer, button.state, userProps)); + const Slots = useSlots(userProps, (layer) => buttonLookup(layer, button.state, userProps, theme)); // now return the handler for finishing render return (final: CompoundButtonProps, ...children: React.ReactNode[]) => { diff --git a/packages/components/Button/src/FAB/FAB.styling.ts b/packages/components/Button/src/FAB/FAB.styling.ts index 35b4209907..6f58f52554 100644 --- a/packages/components/Button/src/FAB/FAB.styling.ts +++ b/packages/components/Button/src/FAB/FAB.styling.ts @@ -7,13 +7,11 @@ import { borderStyles, layoutStyles, fontStyles, shadowStyles } from '@fluentui- import { fabName } from './FAB.types'; import type { FABProps, FABSlotProps, FABTokens } from './FAB.types'; -import { defaultFABColorTokens } from './FABColorTokens'; -import { defaultFABTokens } from './FABTokens'; export const FABStates: (keyof FABTokens)[] = ['focused', 'pressed', 'subtle', 'disabled', 'large', 'small', 'hasContent']; export const stylingSettings: UseStylingOptions = { - tokens: [defaultFABTokens, defaultFABColorTokens, fabName], + tokens: [fabName], states: FABStates, slotProps: { ...(Platform.OS === 'android' && { diff --git a/packages/components/Button/src/ToggleButton/ToggleButton.styling.ts b/packages/components/Button/src/ToggleButton/ToggleButton.styling.ts index fa6ef29c89..7ae4d8d993 100644 --- a/packages/components/Button/src/ToggleButton/ToggleButton.styling.ts +++ b/packages/components/Button/src/ToggleButton/ToggleButton.styling.ts @@ -4,14 +4,10 @@ import { borderStyles, layoutStyles, fontStyles } from '@fluentui-react-native/t import { toggleButtonName } from './ToggleButton.types'; import type { ToggleButtonTokens, ToggleButtonSlotProps, ToggleButtonProps } from './ToggleButton.types'; -import { defaultToggleButtonColorTokens } from './ToggleButtonColorTokens'; import { buttonStates, contentStyling } from '../Button.styling'; -import { defaultButtonColorTokens } from '../ButtonColorTokens'; -import { defaultButtonFontTokens } from '../ButtonFontTokens'; -import { defaultButtonTokens } from '../ButtonTokens'; export const stylingSettings: UseStylingOptions = { - tokens: [defaultButtonTokens, defaultButtonFontTokens, defaultButtonColorTokens, defaultToggleButtonColorTokens, toggleButtonName], + tokens: [toggleButtonName], states: ['checked', ...buttonStates], slotProps: { root: buildProps( diff --git a/packages/components/Button/src/ToggleButton/ToggleButton.tsx b/packages/components/Button/src/ToggleButton/ToggleButton.tsx index cae9858d0b..0d1662fdba 100644 --- a/packages/components/Button/src/ToggleButton/ToggleButton.tsx +++ b/packages/components/Button/src/ToggleButton/ToggleButton.tsx @@ -5,7 +5,7 @@ import { Platform, Pressable, View } from 'react-native'; import { ActivityIndicator } from '@fluentui-react-native/experimental-activity-indicator'; import type { UseSlots } from '@fluentui-react-native/framework'; -import { compose, mergeProps, withSlots } from '@fluentui-react-native/framework'; +import { compose, mergeProps, useFluentTheme, withSlots } from '@fluentui-react-native/framework'; import { Icon, createIconProps } from '@fluentui-react-native/icon'; import { TextV1 as Text } from '@fluentui-react-native/text'; @@ -27,9 +27,10 @@ export const ToggleButton = compose({ useRender: (userProps: ToggleButtonProps, useSlots: UseSlots) => { const iconProps = createIconProps(userProps.icon); const toggleButton = useToggleButton(userProps); + const theme = useFluentTheme(); // grab the styled slots - const Slots = useSlots(userProps, (layer) => buttonLookup(layer, toggleButton.state, userProps)); + const Slots = useSlots(userProps, (layer) => buttonLookup(layer, toggleButton.state, userProps, theme)); // now return the handler for finishing render return (final: ToggleButtonProps, ...children: React.ReactNode[]) => { diff --git a/packages/theming/android-theme/package.json b/packages/theming/android-theme/package.json index 92115981f3..9cfa8580f7 100644 --- a/packages/theming/android-theme/package.json +++ b/packages/theming/android-theme/package.json @@ -31,6 +31,7 @@ "author": "", "license": "MIT", "dependencies": { + "@fluentui-react-native/immutable-merge": "workspace:*", "@fluentui-react-native/memo-cache": "workspace:*", "@fluentui-react-native/theme": "workspace:*", "@fluentui-react-native/theme-tokens": "workspace:*", diff --git a/packages/theming/android-theme/src/__tests__/__snapshots__/android-theme.test.ts.snap b/packages/theming/android-theme/src/__tests__/__snapshots__/android-theme.test.ts.snap index 2eb72e88cf..acb432095a 100644 --- a/packages/theming/android-theme/src/__tests__/__snapshots__/android-theme.test.ts.snap +++ b/packages/theming/android-theme/src/__tests__/__snapshots__/android-theme.test.ts.snap @@ -224,6 +224,141 @@ exports[`createAndroidTheme test option { appearance: 'dark', defaultAppearance: "warningForeground2": "#feee66", }, "components": { + "Button": { + "backgroundColor": "#479ef5", + "block": { + "width": "100%", + }, + "circular": { + "borderRadius": 9999, + }, + "color": "#000000", + "disabled": { + "backgroundColor": "#3d3d3d", + "color": "#5c5c5c", + "iconColor": "#5c5c5c", + }, + "focused": { + "backgroundColor": "#479ef5", + "borderInnerWidth": 1, + "borderWidth": 2, + "color": "#000000", + "iconColor": "#000000", + }, + "iconColor": "#000000", + "large": { + "borderRadius": 8, + "fontFamily": "Roboto", + "fontSize": 16, + "fontWeight": "500", + "iconSize": 20, + "minHeight": 48, + "minWidth": 36, + "outline": { + "borderWidth": 1, + "iconSize": 20, + }, + "paddingHorizontal": 20, + "spacingIconContentAfter": 8, + "spacingIconContentBefore": 8, + }, + "medium": { + "borderRadius": 4, + "fontFamily": "Roboto", + "fontSize": 14, + "fontWeight": "500", + "iconSize": 20, + "minHeight": 36, + "minWidth": 36, + "outline": { + "borderWidth": 1, + "iconSize": 20, + }, + "paddingHorizontal": 12, + "spacingIconContentAfter": 8, + "spacingIconContentBefore": 8, + }, + "outline": { + "backgroundColor": "transparent", + "borderColor": "#479ef5", + "borderWidth": 1, + "color": "#479ef5", + "disabled": { + "backgroundColor": "transparent", + "borderColor": "#424242", + "borderWidth": 1, + "color": "#5c5c5c", + "iconColor": "#5c5c5c", + }, + "focused": { + "backgroundColor": "transparent", + "borderInnerWidth": 1, + "borderWidth": 2, + "color": "#479ef5", + "iconColor": "#479ef5", + }, + "iconColor": "#479ef5", + "pressed": { + "backgroundColor": "transparent", + "borderColor": "#96c6fa", + "borderWidth": 1, + "color": "#96c6fa", + "iconColor": "#96c6fa", + }, + "rippleColor": "#D4D4D4", + }, + "pressed": { + "backgroundColor": "#96c6fa", + "color": "#000000", + "iconColor": "#000000", + }, + "rippleColor": "#D4D4D4", + "rounded": { + "borderRadius": 4, + }, + "small": { + "borderRadius": 4, + "fontFamily": "Roboto", + "fontSize": 14, + "fontWeight": "500", + "iconSize": 16, + "minHeight": 28, + "minWidth": 28, + "outline": { + "borderWidth": 1, + "iconSize": 16, + }, + "paddingHorizontal": 8, + "spacingIconContentAfter": 4, + "spacingIconContentBefore": 4, + }, + "square": { + "borderRadius": 0, + }, + "subtle": { + "backgroundColor": "transparent", + "color": "#479ef5", + "disabled": { + "backgroundColor": "transparent", + "color": "#5c5c5c", + "iconColor": "#5c5c5c", + }, + "focused": { + "backgroundColor": "transparent", + "borderInnerWidth": 1, + "borderWidth": 2, + "color": "#479ef5", + "iconColor": "#479ef5", + }, + "iconColor": "#479ef5", + "pressed": { + "backgroundColor": "transparent", + "color": "#96c6fa", + "iconColor": "#96c6fa", + }, + "rippleColor": "#D4D4D4", + }, + }, "Checkbox": { "checkbox": { "style": { @@ -813,6 +948,141 @@ exports[`createAndroidTheme test option { appearance: 'darkElevated', defaultApp "warningForeground2": "#feee66", }, "components": { + "Button": { + "backgroundColor": "#479ef5", + "block": { + "width": "100%", + }, + "circular": { + "borderRadius": 9999, + }, + "color": "#000000", + "disabled": { + "backgroundColor": "#3d3d3d", + "color": "#5c5c5c", + "iconColor": "#5c5c5c", + }, + "focused": { + "backgroundColor": "#479ef5", + "borderInnerWidth": 1, + "borderWidth": 2, + "color": "#000000", + "iconColor": "#000000", + }, + "iconColor": "#000000", + "large": { + "borderRadius": 8, + "fontFamily": "Roboto", + "fontSize": 16, + "fontWeight": "500", + "iconSize": 20, + "minHeight": 48, + "minWidth": 36, + "outline": { + "borderWidth": 1, + "iconSize": 20, + }, + "paddingHorizontal": 20, + "spacingIconContentAfter": 8, + "spacingIconContentBefore": 8, + }, + "medium": { + "borderRadius": 4, + "fontFamily": "Roboto", + "fontSize": 14, + "fontWeight": "500", + "iconSize": 20, + "minHeight": 36, + "minWidth": 36, + "outline": { + "borderWidth": 1, + "iconSize": 20, + }, + "paddingHorizontal": 12, + "spacingIconContentAfter": 8, + "spacingIconContentBefore": 8, + }, + "outline": { + "backgroundColor": "transparent", + "borderColor": "#479ef5", + "borderWidth": 1, + "color": "#479ef5", + "disabled": { + "backgroundColor": "transparent", + "borderColor": "#424242", + "borderWidth": 1, + "color": "#5c5c5c", + "iconColor": "#5c5c5c", + }, + "focused": { + "backgroundColor": "transparent", + "borderInnerWidth": 1, + "borderWidth": 2, + "color": "#479ef5", + "iconColor": "#479ef5", + }, + "iconColor": "#479ef5", + "pressed": { + "backgroundColor": "transparent", + "borderColor": "#96c6fa", + "borderWidth": 1, + "color": "#96c6fa", + "iconColor": "#96c6fa", + }, + "rippleColor": "#D4D4D4", + }, + "pressed": { + "backgroundColor": "#96c6fa", + "color": "#000000", + "iconColor": "#000000", + }, + "rippleColor": "#D4D4D4", + "rounded": { + "borderRadius": 4, + }, + "small": { + "borderRadius": 4, + "fontFamily": "Roboto", + "fontSize": 14, + "fontWeight": "500", + "iconSize": 16, + "minHeight": 28, + "minWidth": 28, + "outline": { + "borderWidth": 1, + "iconSize": 16, + }, + "paddingHorizontal": 8, + "spacingIconContentAfter": 4, + "spacingIconContentBefore": 4, + }, + "square": { + "borderRadius": 0, + }, + "subtle": { + "backgroundColor": "transparent", + "color": "#479ef5", + "disabled": { + "backgroundColor": "transparent", + "color": "#5c5c5c", + "iconColor": "#5c5c5c", + }, + "focused": { + "backgroundColor": "transparent", + "borderInnerWidth": 1, + "borderWidth": 2, + "color": "#479ef5", + "iconColor": "#479ef5", + }, + "iconColor": "#479ef5", + "pressed": { + "backgroundColor": "transparent", + "color": "#96c6fa", + "iconColor": "#96c6fa", + }, + "rippleColor": "#D4D4D4", + }, + }, "Checkbox": { "checkbox": { "style": { @@ -1402,6 +1672,141 @@ exports[`createAndroidTheme test option { appearance: 'dynamic', defaultAppearan "warningForeground2": "#feee66", }, "components": { + "Button": { + "backgroundColor": "#479ef5", + "block": { + "width": "100%", + }, + "circular": { + "borderRadius": 9999, + }, + "color": "#000000", + "disabled": { + "backgroundColor": "#3d3d3d", + "color": "#5c5c5c", + "iconColor": "#5c5c5c", + }, + "focused": { + "backgroundColor": "#479ef5", + "borderInnerWidth": 1, + "borderWidth": 2, + "color": "#000000", + "iconColor": "#000000", + }, + "iconColor": "#000000", + "large": { + "borderRadius": 8, + "fontFamily": "Roboto", + "fontSize": 16, + "fontWeight": "500", + "iconSize": 20, + "minHeight": 48, + "minWidth": 36, + "outline": { + "borderWidth": 1, + "iconSize": 20, + }, + "paddingHorizontal": 20, + "spacingIconContentAfter": 8, + "spacingIconContentBefore": 8, + }, + "medium": { + "borderRadius": 4, + "fontFamily": "Roboto", + "fontSize": 14, + "fontWeight": "500", + "iconSize": 20, + "minHeight": 36, + "minWidth": 36, + "outline": { + "borderWidth": 1, + "iconSize": 20, + }, + "paddingHorizontal": 12, + "spacingIconContentAfter": 8, + "spacingIconContentBefore": 8, + }, + "outline": { + "backgroundColor": "transparent", + "borderColor": "#479ef5", + "borderWidth": 1, + "color": "#479ef5", + "disabled": { + "backgroundColor": "transparent", + "borderColor": "#424242", + "borderWidth": 1, + "color": "#5c5c5c", + "iconColor": "#5c5c5c", + }, + "focused": { + "backgroundColor": "transparent", + "borderInnerWidth": 1, + "borderWidth": 2, + "color": "#479ef5", + "iconColor": "#479ef5", + }, + "iconColor": "#479ef5", + "pressed": { + "backgroundColor": "transparent", + "borderColor": "#96c6fa", + "borderWidth": 1, + "color": "#96c6fa", + "iconColor": "#96c6fa", + }, + "rippleColor": "#D4D4D4", + }, + "pressed": { + "backgroundColor": "#96c6fa", + "color": "#000000", + "iconColor": "#000000", + }, + "rippleColor": "#D4D4D4", + "rounded": { + "borderRadius": 4, + }, + "small": { + "borderRadius": 4, + "fontFamily": "Roboto", + "fontSize": 14, + "fontWeight": "500", + "iconSize": 16, + "minHeight": 28, + "minWidth": 28, + "outline": { + "borderWidth": 1, + "iconSize": 16, + }, + "paddingHorizontal": 8, + "spacingIconContentAfter": 4, + "spacingIconContentBefore": 4, + }, + "square": { + "borderRadius": 0, + }, + "subtle": { + "backgroundColor": "transparent", + "color": "#479ef5", + "disabled": { + "backgroundColor": "transparent", + "color": "#5c5c5c", + "iconColor": "#5c5c5c", + }, + "focused": { + "backgroundColor": "transparent", + "borderInnerWidth": 1, + "borderWidth": 2, + "color": "#479ef5", + "iconColor": "#479ef5", + }, + "iconColor": "#479ef5", + "pressed": { + "backgroundColor": "transparent", + "color": "#96c6fa", + "iconColor": "#96c6fa", + }, + "rippleColor": "#D4D4D4", + }, + }, "Checkbox": { "checkbox": { "style": { @@ -1991,6 +2396,141 @@ exports[`createAndroidTheme test option { appearance: 'highContrast', defaultApp "warningForeground2": "#feee66", }, "components": { + "Button": { + "backgroundColor": "#479ef5", + "block": { + "width": "100%", + }, + "circular": { + "borderRadius": 9999, + }, + "color": "#000000", + "disabled": { + "backgroundColor": "#3d3d3d", + "color": "#5c5c5c", + "iconColor": "#5c5c5c", + }, + "focused": { + "backgroundColor": "#479ef5", + "borderInnerWidth": 1, + "borderWidth": 2, + "color": "#000000", + "iconColor": "#000000", + }, + "iconColor": "#000000", + "large": { + "borderRadius": 8, + "fontFamily": "Roboto", + "fontSize": 16, + "fontWeight": "500", + "iconSize": 20, + "minHeight": 48, + "minWidth": 36, + "outline": { + "borderWidth": 1, + "iconSize": 20, + }, + "paddingHorizontal": 20, + "spacingIconContentAfter": 8, + "spacingIconContentBefore": 8, + }, + "medium": { + "borderRadius": 4, + "fontFamily": "Roboto", + "fontSize": 14, + "fontWeight": "500", + "iconSize": 20, + "minHeight": 36, + "minWidth": 36, + "outline": { + "borderWidth": 1, + "iconSize": 20, + }, + "paddingHorizontal": 12, + "spacingIconContentAfter": 8, + "spacingIconContentBefore": 8, + }, + "outline": { + "backgroundColor": "transparent", + "borderColor": "#479ef5", + "borderWidth": 1, + "color": "#479ef5", + "disabled": { + "backgroundColor": "transparent", + "borderColor": "#424242", + "borderWidth": 1, + "color": "#5c5c5c", + "iconColor": "#5c5c5c", + }, + "focused": { + "backgroundColor": "transparent", + "borderInnerWidth": 1, + "borderWidth": 2, + "color": "#479ef5", + "iconColor": "#479ef5", + }, + "iconColor": "#479ef5", + "pressed": { + "backgroundColor": "transparent", + "borderColor": "#96c6fa", + "borderWidth": 1, + "color": "#96c6fa", + "iconColor": "#96c6fa", + }, + "rippleColor": "#D4D4D4", + }, + "pressed": { + "backgroundColor": "#96c6fa", + "color": "#000000", + "iconColor": "#000000", + }, + "rippleColor": "#D4D4D4", + "rounded": { + "borderRadius": 4, + }, + "small": { + "borderRadius": 4, + "fontFamily": "Roboto", + "fontSize": 14, + "fontWeight": "500", + "iconSize": 16, + "minHeight": 28, + "minWidth": 28, + "outline": { + "borderWidth": 1, + "iconSize": 16, + }, + "paddingHorizontal": 8, + "spacingIconContentAfter": 4, + "spacingIconContentBefore": 4, + }, + "square": { + "borderRadius": 0, + }, + "subtle": { + "backgroundColor": "transparent", + "color": "#479ef5", + "disabled": { + "backgroundColor": "transparent", + "color": "#5c5c5c", + "iconColor": "#5c5c5c", + }, + "focused": { + "backgroundColor": "transparent", + "borderInnerWidth": 1, + "borderWidth": 2, + "color": "#479ef5", + "iconColor": "#479ef5", + }, + "iconColor": "#479ef5", + "pressed": { + "backgroundColor": "transparent", + "color": "#96c6fa", + "iconColor": "#96c6fa", + }, + "rippleColor": "#D4D4D4", + }, + }, "Checkbox": { "checkbox": { "style": { @@ -2580,6 +3120,141 @@ exports[`createAndroidTheme test option { appearance: 'light', defaultAppearance "warningForeground2": "#817400", }, "components": { + "Button": { + "backgroundColor": "#0f6cbd", + "block": { + "width": "100%", + }, + "circular": { + "borderRadius": 9999, + }, + "color": "#ffffff", + "disabled": { + "backgroundColor": "#f0f0f0", + "color": "#bdbdbd", + "iconColor": "#bdbdbd", + }, + "focused": { + "backgroundColor": "#0f6cbd", + "borderInnerWidth": 1, + "borderWidth": 2, + "color": "#ffffff", + "iconColor": "#ffffff", + }, + "iconColor": "#ffffff", + "large": { + "borderRadius": 8, + "fontFamily": "Roboto", + "fontSize": 16, + "fontWeight": "500", + "iconSize": 20, + "minHeight": 48, + "minWidth": 36, + "outline": { + "borderWidth": 1, + "iconSize": 20, + }, + "paddingHorizontal": 20, + "spacingIconContentAfter": 8, + "spacingIconContentBefore": 8, + }, + "medium": { + "borderRadius": 4, + "fontFamily": "Roboto", + "fontSize": 14, + "fontWeight": "500", + "iconSize": 20, + "minHeight": 36, + "minWidth": 36, + "outline": { + "borderWidth": 1, + "iconSize": 20, + }, + "paddingHorizontal": 12, + "spacingIconContentAfter": 8, + "spacingIconContentBefore": 8, + }, + "outline": { + "backgroundColor": "transparent", + "borderColor": "#0f6cbd", + "borderWidth": 1, + "color": "#0f6cbd", + "disabled": { + "backgroundColor": "transparent", + "borderColor": "#e0e0e0", + "borderWidth": 1, + "color": "#bdbdbd", + "iconColor": "#bdbdbd", + }, + "focused": { + "backgroundColor": "transparent", + "borderInnerWidth": 1, + "borderWidth": 2, + "color": "#0f6cbd", + "iconColor": "#0f6cbd", + }, + "iconColor": "#0f6cbd", + "pressed": { + "backgroundColor": "transparent", + "borderColor": "#0e4775", + "borderWidth": 1, + "color": "#0e4775", + "iconColor": "#0e4775", + }, + "rippleColor": "#D4D4D4", + }, + "pressed": { + "backgroundColor": "#0e4775", + "color": "#ffffff", + "iconColor": "#ffffff", + }, + "rippleColor": "#D4D4D4", + "rounded": { + "borderRadius": 4, + }, + "small": { + "borderRadius": 4, + "fontFamily": "Roboto", + "fontSize": 14, + "fontWeight": "500", + "iconSize": 16, + "minHeight": 28, + "minWidth": 28, + "outline": { + "borderWidth": 1, + "iconSize": 16, + }, + "paddingHorizontal": 8, + "spacingIconContentAfter": 4, + "spacingIconContentBefore": 4, + }, + "square": { + "borderRadius": 0, + }, + "subtle": { + "backgroundColor": "transparent", + "color": "#0f6cbd", + "disabled": { + "backgroundColor": "transparent", + "color": "#bdbdbd", + "iconColor": "#bdbdbd", + }, + "focused": { + "backgroundColor": "transparent", + "borderInnerWidth": 1, + "borderWidth": 2, + "color": "#0f6cbd", + "iconColor": "#0f6cbd", + }, + "iconColor": "#0f6cbd", + "pressed": { + "backgroundColor": "transparent", + "color": "#0e4775", + "iconColor": "#0e4775", + }, + "rippleColor": "#D4D4D4", + }, + }, "Checkbox": { "checkbox": { "style": { diff --git a/packages/theming/android-theme/src/__tests__/android-theme.test.ts b/packages/theming/android-theme/src/__tests__/android-theme.test.ts index b340c5c3f0..d06b38f70d 100644 --- a/packages/theming/android-theme/src/__tests__/android-theme.test.ts +++ b/packages/theming/android-theme/src/__tests__/android-theme.test.ts @@ -1,6 +1,12 @@ +import type { ButtonTokens, FABTokens } from '@fluentui-react-native/button'; import type { ThemeOptions } from '@fluentui-react-native/theme-types'; import { getAndroidTheme } from '../androidTheme'; +import { defaultButtonColorTokens } from '../components/Button/ButtonColorTokens'; +import { defaultButtonFontTokens } from '../components/Button/ButtonFontTokens'; +import { defaultButtonTokens } from '../components/Button/ButtonTokens'; +import { defaultFABColorTokens } from '../components/Button/FABColorTokens'; +import { defaultFABTokens } from '../components/Button/FABTokens'; import { createAndroidTheme } from '../createAndroidTheme'; const defaultAppearance = 'light'; @@ -33,3 +39,20 @@ it.concurrent.each(themeOptions)('createAndroidTheme test option %o', (option: T const theme = createAndroidTheme(option).theme; expect(theme).toMatchSnapshot(); }); + +describe('verify types', () => { + it('Button types', () => { + const officeTheme = getAndroidTheme('light'); + const colorTokens: ButtonTokens = defaultButtonColorTokens(officeTheme); + expect(colorTokens).toBeTruthy(); + const fontTokens: ButtonTokens = defaultButtonFontTokens(officeTheme); + expect(fontTokens).toBeTruthy(); + const tokens: ButtonTokens = defaultButtonTokens(officeTheme); + expect(tokens).toBeTruthy(); + + const fabTokens: FABTokens = defaultFABTokens(officeTheme); + expect(fabTokens).toBeTruthy(); + const fabColorTokens: FABTokens = defaultFABColorTokens(officeTheme); + expect(fabColorTokens).toBeTruthy(); + }); +}) \ No newline at end of file diff --git a/packages/theming/android-theme/src/components/Button/ButtonColorTokens.ts b/packages/theming/android-theme/src/components/Button/ButtonColorTokens.ts new file mode 100644 index 0000000000..b84daeb177 --- /dev/null +++ b/packages/theming/android-theme/src/components/Button/ButtonColorTokens.ts @@ -0,0 +1,78 @@ +import type { Theme } from '@fluentui-react-native/framework'; + +export const defaultButtonColorTokens = (t: Theme) => +({ + /** Android does not have a different styles for 'default' button. + * 'primary', 'accent' and if no appearance is mentioned, picks this. + */ + backgroundColor: t.colors.brandBackground, + rippleColor: '#D4D4D4', + color: t.colors.neutralForegroundOnColor, + iconColor: t.colors.neutralForegroundOnColor, + disabled: { + backgroundColor: t.colors.neutralBackground5, + color: t.colors.neutralForegroundDisabled1, + iconColor: t.colors.neutralForegroundDisabled1, + }, + pressed: { + backgroundColor: t.colors.brandBackgroundPressed, + color: t.colors.neutralForegroundOnColor, + iconColor: t.colors.neutralForegroundOnColor, + }, + focused: { + backgroundColor: t.colors.brandBackground, + color: t.colors.neutralForegroundOnColor, + borderColor: t.colors.strokeFocus2, + borderInnerColor: t.colors.strokeFocus1, + iconColor: t.colors.neutralForegroundOnColor, + }, + subtle: { + backgroundColor: 'transparent', + rippleColor: '#D4D4D4', + color: t.colors.brandForeground1, + iconColor: t.colors.brandForeground1, + disabled: { + backgroundColor: 'transparent', + color: t.colors.neutralForegroundDisabled1, + iconColor: t.colors.neutralForegroundDisabled1, + }, + pressed: { + backgroundColor: 'transparent', + color: t.colors.brandForeground1Pressed, + iconColor: t.colors.brandForeground1Pressed, + }, + focused: { + backgroundColor: 'transparent', + borderColor: t.colors.strokeFocus2, + borderInnerColor: t.colors.strokeFocus1, + color: t.colors.brandForeground1, + iconColor: t.colors.brandForeground1, + }, + }, + outline: { + backgroundColor: 'transparent', + rippleColor: '#D4D4D4', + color: t.colors.brandForeground1, + iconColor: t.colors.brandForeground1, + borderColor: t.colors.brandStroke1, + disabled: { + backgroundColor: 'transparent', + color: t.colors.neutralForegroundDisabled1, + iconColor: t.colors.neutralForegroundDisabled1, + borderColor: t.colors.neutralStrokeDisabled, + }, + pressed: { + backgroundColor: 'transparent', + color: t.colors.brandForeground1Pressed, + iconColor: t.colors.brandForeground1Pressed, + borderColor: t.colors.brandStroke1Pressed, + }, + focused: { + backgroundColor: 'transparent', + borderColor: t.colors.strokeFocus2, + borderInnerColor: t.colors.strokeFocus1, + color: t.colors.brandForeground1, + iconColor: t.colors.brandForeground1, + }, + }, +}); diff --git a/packages/theming/android-theme/src/components/Button/ButtonFontTokens.ts b/packages/theming/android-theme/src/components/Button/ButtonFontTokens.ts new file mode 100644 index 0000000000..e4433a54e8 --- /dev/null +++ b/packages/theming/android-theme/src/components/Button/ButtonFontTokens.ts @@ -0,0 +1,21 @@ +import type { Theme } from '@fluentui-react-native/framework'; + + +export const defaultButtonFontTokens = (t: Theme) => +({ + medium: { + fontSize: t.typography.variants.body2Strong.size, + fontFamily: t.typography.variants.body2Strong.face, + fontWeight: t.typography.variants.body2Strong.weight, + }, + small: { + fontSize: t.typography.variants.body2Strong.size, + fontFamily: t.typography.variants.body2Strong.face, + fontWeight: t.typography.variants.body2Strong.weight, + }, + large: { + fontSize: t.typography.variants.body1Strong.size, + fontFamily: t.typography.variants.body1Strong.face, + fontWeight: t.typography.variants.body1Strong.weight, + }, +}); diff --git a/packages/theming/android-theme/src/components/Button/ButtonTheme.ts b/packages/theming/android-theme/src/components/Button/ButtonTheme.ts new file mode 100644 index 0000000000..91298cbc82 --- /dev/null +++ b/packages/theming/android-theme/src/components/Button/ButtonTheme.ts @@ -0,0 +1,21 @@ + +import type { Theme } from '@fluentui-react-native/framework'; +import { immutableMerge } from '@fluentui-react-native/immutable-merge'; + +import { defaultButtonColorTokens } from './ButtonColorTokens'; +import { defaultButtonFontTokens } from './ButtonFontTokens'; +import { defaultButtonTokens } from './ButtonTokens'; +import { defaultToggleButtonColorTokens } from './ToggleButtonColorTokens'; + +export const defaultButtonTheme = (theme: Theme) => +({ + components: { + Button: immutableMerge(defaultButtonColorTokens(theme), defaultButtonFontTokens(theme), defaultButtonTokens(theme)), + ToggleButton: + immutableMerge( + defaultButtonTokens(theme), + defaultButtonFontTokens(theme), + defaultButtonColorTokens(theme), + defaultToggleButtonColorTokens(theme)), + } +}); diff --git a/packages/theming/android-theme/src/components/Button/ButtonTokens.ts b/packages/theming/android-theme/src/components/Button/ButtonTokens.ts new file mode 100644 index 0000000000..3660988b6c --- /dev/null +++ b/packages/theming/android-theme/src/components/Button/ButtonTokens.ts @@ -0,0 +1,96 @@ +import type { DimensionValue } from 'react-native'; + +import type { Theme } from '@fluentui-react-native/framework'; +import { globalTokensAndroid as globalTokens } from '@fluentui-react-native/theme-tokens'; + +export const defaultButtonTokens = (_t: Theme) => +({ + focused: { + borderWidth: globalTokens.stroke.width20, + borderInnerWidth: globalTokens.stroke.width10, + }, + subtle: { + focused: { + borderWidth: globalTokens.stroke.width20, + borderInnerWidth: globalTokens.stroke.width10, + }, + }, + outline: { + borderWidth: globalTokens.stroke.width10, + disabled: { + borderWidth: globalTokens.stroke.width10, + }, + pressed: { + borderWidth: globalTokens.stroke.width10, + }, + focused: { + borderWidth: globalTokens.stroke.width20, + borderInnerWidth: globalTokens.stroke.width10, + }, + }, + block: { + width: '100%' as DimensionValue, + }, + large: { + paddingHorizontal: globalTokens.size200, + borderRadius: globalTokens.corner.radius80, + iconSize: 20, + outline: { + borderWidth: globalTokens.stroke.width10, + iconSize: 20, + }, + spacingIconContentBefore: globalTokens.size80, + spacingIconContentAfter: globalTokens.size80, + minHeight: 48, + minWidth: 36, + }, + medium: { + paddingHorizontal: globalTokens.size120, + borderRadius: globalTokens.corner.radius40, + iconSize: 20, + outline: { + borderWidth: globalTokens.stroke.width10, + iconSize: 20, + }, + spacingIconContentBefore: globalTokens.size80, + spacingIconContentAfter: globalTokens.size80, + minHeight: 36, + minWidth: 36, + }, + small: { + paddingHorizontal: globalTokens.size80, + borderRadius: globalTokens.corner.radius40, + iconSize: 16, + outline: { + borderWidth: globalTokens.stroke.width10, + iconSize: 16, + }, + spacingIconContentBefore: globalTokens.size40, + spacingIconContentAfter: globalTokens.size40, + minHeight: 28, + minWidth: 28, + }, + rounded: { + borderRadius: globalTokens.corner.radius40, + }, + circular: { + borderRadius: globalTokens.corner.radiusCircular, + }, + square: { + borderRadius: globalTokens.corner.radiusNone, + }, + getPlatformSpecificAppearance: (appearance): 'primary' | 'subtle' | 'outline' => { + switch (appearance) { + case 'accent': // Included to cover Mobile platform naming guidelines, maps to 'primary'. + return 'primary'; + + case 'primary': + case 'subtle': + case 'outline': // 'Outline' exists only for Mobile platforms, default picked on other platforms. + return appearance; + + default: + return 'primary'; + } + } +}); diff --git a/packages/components/Button/src/FAB/FABColorTokens.ts b/packages/theming/android-theme/src/components/Button/FABColorTokens.ts similarity index 88% rename from packages/components/Button/src/FAB/FABColorTokens.ts rename to packages/theming/android-theme/src/components/Button/FABColorTokens.ts index 158ed5788f..283de99805 100644 --- a/packages/components/Button/src/FAB/FABColorTokens.ts +++ b/packages/theming/android-theme/src/components/Button/FABColorTokens.ts @@ -1,9 +1,6 @@ import type { Theme } from '@fluentui-react-native/framework'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; -import type { FABTokens } from './FAB.types'; - -export const defaultFABColorTokens: TokenSettings = (t: Theme): FABTokens => ({ +export const defaultFABColorTokens = (t: Theme) => ({ // Default coloring same as 'primary' or 'accent' backgroundColor: t.colors.brandBackground, color: t.colors.neutralForegroundOnColor, diff --git a/packages/components/Button/src/FAB/FABTokens.ts b/packages/theming/android-theme/src/components/Button/FABTokens.ts similarity index 89% rename from packages/components/Button/src/FAB/FABTokens.ts rename to packages/theming/android-theme/src/components/Button/FABTokens.ts index 3a00dbd75c..a2e44f6b97 100644 --- a/packages/components/Button/src/FAB/FABTokens.ts +++ b/packages/theming/android-theme/src/components/Button/FABTokens.ts @@ -1,10 +1,7 @@ import type { Theme } from '@fluentui-react-native/framework'; -import { globalTokens } from '@fluentui-react-native/theme-tokens'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; +import {globalTokensAndroid as globalTokens} from '@fluentui-react-native/theme-tokens'; -import type { FABTokens } from './FAB.types'; - -export const defaultFABTokens: TokenSettings = (t: Theme) => +export const defaultFABTokens = (t: Theme) => ({ elevation: t.shadows.shadow8.key.blur, disabled: { @@ -76,4 +73,4 @@ export const defaultFABTokens: TokenSettings = (t: Theme) => spacingIconContentBefore: globalTokens.size80, }, }, - } as FABTokens); + }); diff --git a/packages/components/Button/src/ToggleButton/ToggleButtonColorTokens.ts b/packages/theming/android-theme/src/components/Button/ToggleButtonColorTokens.ts similarity index 71% rename from packages/components/Button/src/ToggleButton/ToggleButtonColorTokens.ts rename to packages/theming/android-theme/src/components/Button/ToggleButtonColorTokens.ts index a1a5670ae9..67585c56ba 100644 --- a/packages/components/Button/src/ToggleButton/ToggleButtonColorTokens.ts +++ b/packages/theming/android-theme/src/components/Button/ToggleButtonColorTokens.ts @@ -1,9 +1,6 @@ import type { Theme } from '@fluentui-react-native/framework'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; -import type { ToggleButtonTokens } from './ToggleButton.types'; - -export const defaultToggleButtonColorTokens: TokenSettings = (t: Theme): ToggleButtonTokens => ({ +export const defaultToggleButtonColorTokens = (t: Theme) => ({ checked: { color: t.colors.defaultCheckedContent, backgroundColor: t.colors.defaultCheckedBackground, diff --git a/packages/theming/android-theme/src/createAndroidTheme.ts b/packages/theming/android-theme/src/createAndroidTheme.ts index 7ca543861c..bbf09c6e7b 100644 --- a/packages/theming/android-theme/src/createAndroidTheme.ts +++ b/packages/theming/android-theme/src/createAndroidTheme.ts @@ -1,19 +1,22 @@ import { Appearance } from 'react-native'; import { ThemeReference } from '@fluentui-react-native/theme'; -import type { Theme, ThemeOptions } from '@fluentui-react-native/theme-types'; +import type { Theme, PartialTheme, ThemeOptions } from '@fluentui-react-native/theme-types'; import { getAndroidTheme } from './androidTheme'; +import { defaultButtonTheme } from './components/Button/ButtonTheme'; export function createAndroidTheme(options: ThemeOptions = {}): ThemeReference { - const themeRef = new ThemeReference({} as Theme, () => { + const themeRef = new ThemeReference({} as Theme, + () => { // Stub out HC and darkElevated on Android const current = options.appearance === 'dynamic' || options.appearance === 'highContrast' || options.appearance === 'darkElevated' ? (Appearance && Appearance.getColorScheme()) || 'light' : options.appearance; return getAndroidTheme(current); - }); + }, + defaultButtonTheme); if (Appearance && options.appearance === 'dynamic') { Appearance.addChangeListener(() => { diff --git a/packages/theming/apple-theme/package.json b/packages/theming/apple-theme/package.json index 124cc85c26..6f2eb95a20 100644 --- a/packages/theming/apple-theme/package.json +++ b/packages/theming/apple-theme/package.json @@ -35,6 +35,7 @@ "@fluentui-react-native/design-tokens-ios": "^0.53.0", "@fluentui-react-native/design-tokens-macos": "^0.53.0", "@fluentui-react-native/experimental-appearance-additions": "workspace:*", + "@fluentui-react-native/immutable-merge": "workspace:*", "@fluentui-react-native/memo-cache": "workspace:*", "@fluentui-react-native/theme": "workspace:*", "@fluentui-react-native/theme-tokens": "workspace:*", diff --git a/packages/theming/apple-theme/src/__tests__/__snapshots__/apple-theme.test.ts.snap b/packages/theming/apple-theme/src/__tests__/__snapshots__/apple-theme.test.ts.snap index e301af499d..f339f9b248 100644 --- a/packages/theming/apple-theme/src/__tests__/__snapshots__/apple-theme.test.ts.snap +++ b/packages/theming/apple-theme/src/__tests__/__snapshots__/apple-theme.test.ts.snap @@ -2,6 +2,9 @@ exports[`createAppleTheme test 1`] = ` { + "backgroundColor": "#ffffff", + "borderColor": "#d6d6d6", + "color": "#000000", "colors": { "accentButtonBackground": { "dynamic": { @@ -610,9 +613,72 @@ exports[`createAppleTheme test 1`] = ` }, }, }, + "disabled": { + "backgroundColor": "#ffffff", + "borderColor": "#d6d6d6", + "color": "#757575", + "iconColor": "#616161", + }, + "focused": { + "backgroundColor": "#ffffff", + "borderColor": "#d6d6d6", + "color": "#000000", + "icon": "#616161", + }, "host": { "appearance": "dynamic", }, + "hovered": { + "backgroundColor": "#ffffff", + "borderColor": "#d6d6d6", + "color": "#000000", + "iconColor": "#616161", + }, + "iconColor": "#000000", + "large": { + "variant": "subheaderSemibold", + }, + "medium": { + "hasContent": { + "variant": "bodyStandard", + }, + }, + "pressed": { + "backgroundColor": "#ebebeb", + "borderColor": "#d6d6d6", + "color": "#000000", + "iconColor": "#616161", + }, + "primary": { + "backgroundColor": "#0078d4", + "borderColor": "#0078d4", + "color": "#ffffff", + "disabled": { + "backgroundColor": "#f0f0f0", + "borderColor": "#e0e0e0", + "color": "#757575", + "iconColor": "#757575", + }, + "focused": { + "backgroundColor": "#106ebe", + "borderColor": "#000000", + "color": "#ffffff", + "iconColor": "#ffffff", + }, + "hovered": { + "backgroundColor": "#106ebe", + "borderColor": "#106ebe", + "color": "#ffffff", + "iconColor": "#ffffff", + }, + "iconColor": "#ffffff", + "pressed": { + "backgroundColor": "#106ebe", + "borderColor": "#106ebe", + "color": "#ffffff", + "iconColor": "#ffffff", + }, + }, "shadows": { "shadow16": { "ambient": { @@ -783,6 +849,11 @@ exports[`createAppleTheme test 1`] = ` }, }, }, + "small": { + "hasContent": { + "variant": "secondaryStandard", + }, + }, "spacing": { "l1": "20px", "l2": "24px", @@ -790,6 +861,78 @@ exports[`createAppleTheme test 1`] = ` "s1": "12px", "s2": "8px", }, + "subtle": { + "backgroundColor": "transparent", + "borderColor": "transparent", + "color": { + "dynamic": { + "dark": "#1890F1", + "highContrastDark": undefined, + "highContrastLight": undefined, + "light": "#0078D4", + }, + }, + "disabled": { + "backgroundColor": "transparent", + "borderColor": "transparent", + "color": "#757575", + "iconColor": "#757575", + }, + "focused": { + "backgroundColor": "transparent", + "borderColor": "transparent", + "color": { + "dynamic": { + "dark": "#1890F1", + "highContrastDark": undefined, + "highContrastLight": undefined, + "light": "#0078D4", + }, + }, + "icon": { + "dynamic": { + "dark": "#1890F1", + "highContrastDark": undefined, + "highContrastLight": undefined, + "light": "#0078D4", + }, + }, + }, + "hovered": { + "backgroundColor": "transparent", + "borderColor": "transparent", + "color": { + "dynamic": { + "dark": "#1890F1", + "highContrastDark": undefined, + "highContrastLight": undefined, + "light": "#0078D4", + }, + }, + "iconColor": { + "dynamic": { + "dark": "#1890F1", + "highContrastDark": undefined, + "highContrastLight": undefined, + "light": "#0078D4", + }, + }, + }, + "iconColor": { + "dynamic": { + "dark": "#1890F1", + "highContrastDark": undefined, + "highContrastLight": undefined, + "light": "#0078D4", + }, + }, + "pressed": { + "backgroundColor": "transparent", + "borderColor": "transparent", + "color": "#004578", + "icon": "#616161", + }, + }, "typography": { "families": { "cursive": "System", diff --git a/packages/theming/apple-theme/src/__tests__/apple-theme.test.ts b/packages/theming/apple-theme/src/__tests__/apple-theme.test.ts index 5fdb211ef7..1ec6df78f3 100644 --- a/packages/theming/apple-theme/src/__tests__/apple-theme.test.ts +++ b/packages/theming/apple-theme/src/__tests__/apple-theme.test.ts @@ -1,6 +1,12 @@ +import type { ButtonTokens, FABTokens } from '@fluentui-react-native/button'; import type { AppearanceOptions } from '@fluentui-react-native/theme-types'; import { getIsHighContrast, setIsHighContrast } from '../appleHighContrast.macos'; +import { defaultButtonColorTokens } from '../components/Button/ButtonColorTokens'; +import { defaultButtonFontTokens } from '../components/Button/ButtonFontTokens'; +import { defaultFABColorTokens } from '../components/Button/FABColorTokens'; +import { defaultFABTokens } from '../components/Button/FABTokens'; +import { defaultButtonTokens } from '../components/Button/ButtonTokens'; import { createAppleTheme } from '../createAppleTheme'; import { createMacOSColorAliasTokens, createMacOSShadowAliasTokens } from '../createMacOSAliasTokens'; @@ -65,3 +71,20 @@ it.concurrent.each(macOSAliasTokensTable)( } }, ); + +describe('verify types', () => { + it('Button types', () => { + const officeTheme = createAppleTheme().theme; + const colorTokens: ButtonTokens = defaultButtonColorTokens(officeTheme); + expect(colorTokens).toBeTruthy(); + const fontTokens: ButtonTokens = defaultButtonFontTokens(officeTheme); + expect(fontTokens).toBeTruthy(); + const tokens: ButtonTokens = defaultButtonTokens(officeTheme); + expect(tokens).toBeTruthy(); + + const fabColorTokens: FABTokens = defaultFABColorTokens(officeTheme); + expect(fabColorTokens).toBeTruthy(); + const fabTokens: FABTokens = defaultFABTokens(officeTheme); + expect(fabTokens).toBeTruthy(); + }); +}) \ No newline at end of file diff --git a/packages/components/Button/src/ButtonColorTokens.macos.ts b/packages/theming/apple-theme/src/components/Button/ButtonColorTokens.macos.ts similarity index 93% rename from packages/components/Button/src/ButtonColorTokens.macos.ts rename to packages/theming/apple-theme/src/components/Button/ButtonColorTokens.macos.ts index acb09755b9..64617b135f 100644 --- a/packages/components/Button/src/ButtonColorTokens.macos.ts +++ b/packages/theming/apple-theme/src/components/Button/ButtonColorTokens.macos.ts @@ -1,9 +1,6 @@ import type { Theme } from '@fluentui-react-native/framework'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; -import type { ButtonTokens } from './Button.types'; - -export const defaultButtonColorTokens: TokenSettings = (t: Theme) => +export const defaultButtonColorTokens = (t: Theme) => ({ backgroundColor: t.colors.defaultBackground, color: t.colors.defaultContent, @@ -93,4 +90,4 @@ export const defaultButtonColorTokens: TokenSettings = (t: icon: t.colors.ghostFocusedIcon, }, }, - } as ButtonTokens); + } ); diff --git a/packages/theming/apple-theme/src/components/Button/ButtonColorTokens.ts b/packages/theming/apple-theme/src/components/Button/ButtonColorTokens.ts new file mode 100644 index 0000000000..6049f66652 --- /dev/null +++ b/packages/theming/apple-theme/src/components/Button/ButtonColorTokens.ts @@ -0,0 +1,5 @@ +import type { Theme } from '@fluentui-react-native/framework'; + +export const defaultButtonColorTokens = (_t: Theme) => + ({ + }); diff --git a/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ios.ts b/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ios.ts new file mode 100644 index 0000000000..6fee75013b --- /dev/null +++ b/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ios.ts @@ -0,0 +1,20 @@ +import type { Theme } from '@fluentui-react-native/framework'; + +export const defaultButtonFontTokens = (t: Theme) => + ({ + medium: { + fontSize: t.typography.variants.caption1Strong!.size, + fontFamily: t.typography.variants.caption1Strong!.face, + fontWeight: t.typography.variants.caption1Strong!.weight, + }, + small: { + fontSize: t.typography.variants.caption1Strong!.size, + fontFamily: t.typography.variants.caption1Strong!.face, + fontWeight: t.typography.variants.caption1Strong!.weight, + }, + large: { + fontSize: t.typography.variants.body1Strong!.size, + fontFamily: t.typography.variants.body1Strong!.face, + fontWeight: t.typography.variants.body1Strong!.weight, + }, + }); diff --git a/packages/components/Button/src/ButtonFontTokens.macos.ts b/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.macos.ts similarity index 55% rename from packages/components/Button/src/ButtonFontTokens.macos.ts rename to packages/theming/apple-theme/src/components/Button/ButtonFontTokens.macos.ts index 47bcb99859..404bca85c3 100644 --- a/packages/components/Button/src/ButtonFontTokens.macos.ts +++ b/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.macos.ts @@ -1,9 +1,6 @@ import type { Theme } from '@fluentui-react-native/framework'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; -import type { ButtonTokens } from './Button.types'; - -export const defaultButtonFontTokens: TokenSettings = (_t: Theme) => +export const defaultButtonFontTokens = (_t: Theme) => ({ medium: { hasContent: { @@ -18,4 +15,4 @@ export const defaultButtonFontTokens: TokenSettings = (_t: large: { variant: 'subheaderSemibold', }, - } as ButtonTokens); + }); diff --git a/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ts b/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ts new file mode 100644 index 0000000000..be43d8df5d --- /dev/null +++ b/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ts @@ -0,0 +1,5 @@ +import type { Theme } from '@fluentui-react-native/framework'; + +export const defaultButtonFontTokens = (_t: Theme) => + ({ + }); diff --git a/packages/theming/apple-theme/src/components/Button/ButtonTheme.ts b/packages/theming/apple-theme/src/components/Button/ButtonTheme.ts new file mode 100644 index 0000000000..b8cfc3487d --- /dev/null +++ b/packages/theming/apple-theme/src/components/Button/ButtonTheme.ts @@ -0,0 +1,36 @@ + +import type { Theme } from '@fluentui-react-native/framework'; +import { immutableMerge } from '@fluentui-react-native/immutable-merge'; + +import { defaultButtonColorTokens } from './ButtonColorTokens'; +import { defaultButtonFontTokens } from './ButtonFontTokens'; +import { defaultButtonTokens } from './ButtonTokens'; +import { defaultCompoundButtonColorTokens } from './CompoundButtonColorTokens'; +import { defaultCompoundButtonFontTokens } from './CompoundButtonFontTokens'; +import { defaultCompoundButtonTokens } from './CompoundButtonTokens'; +import { defaultFABColorTokens } from './FABColorTokens'; +import { defaultFABTokens } from './FABTokens'; +import { defaultToggleButtonColorTokens } from './ToggleButtonColorTokens'; + +export const defaultButtonTheme = (theme: Theme) => +({ + components: { + Button: immutableMerge(defaultButtonColorTokens(theme), defaultButtonFontTokens(theme), defaultButtonTokens(theme)), + CompoundButton: + immutableMerge( + defaultButtonTokens(theme), + defaultButtonColorTokens(theme), + defaultCompoundButtonColorTokens(theme), + defaultCompoundButtonFontTokens(theme), + defaultCompoundButtonTokens(theme)), + + FAB: immutableMerge(defaultFABTokens(theme), defaultFABColorTokens(theme)), + + ToggleButton: + immutableMerge( + defaultButtonTokens(theme), + defaultButtonFontTokens(theme), + defaultButtonColorTokens(theme), + defaultToggleButtonColorTokens(theme)), + } +}); diff --git a/packages/components/Button/src/ButtonTokens.ios.ts b/packages/theming/apple-theme/src/components/Button/ButtonTokens.ios.ts similarity index 70% rename from packages/components/Button/src/ButtonTokens.ios.ts rename to packages/theming/apple-theme/src/components/Button/ButtonTokens.ios.ts index 60f50babd9..af370fea47 100644 --- a/packages/components/Button/src/ButtonTokens.ios.ts +++ b/packages/theming/apple-theme/src/components/Button/ButtonTokens.ios.ts @@ -1,13 +1,12 @@ -import type { Theme } from '@fluentui-react-native/framework'; -import { globalTokens } from '@fluentui-react-native/theme-tokens'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; +import type { DimensionValue } from 'react-native'; -import type { ButtonTokens } from './Button.types'; +import type { Theme } from '@fluentui-react-native/framework'; +import {default as globalTokens} from '@fluentui-react-native/theme-tokens/lib/tokens-global.ios'; -export const defaultButtonTokens: TokenSettings = () => +export const defaultButtonTokens = (_t: Theme) => ({ block: { - width: '100%', + width: '100%' as DimensionValue, }, medium: { paddingHorizontal: globalTokens.size120, @@ -73,4 +72,19 @@ export const defaultButtonTokens: TokenSettings = () => square: { borderRadius: globalTokens.corner.radiusNone, }, - } as ButtonTokens); + getPlatformSpecificAppearance: (appearance): 'accent' | 'primary' | 'subtle' | 'outline' => { + + switch (appearance) { + case 'accent': // Included to cover Mobile platform naming guidelines, maps to 'primary'. + return 'primary'; + + case 'primary': + case 'subtle': + case 'outline': // 'Outline' exists only for Mobile platforms, default picked on other platforms. + return appearance; + + default: + return 'primary'; + } + } + }); diff --git a/packages/theming/apple-theme/src/components/Button/ButtonTokens.ts b/packages/theming/apple-theme/src/components/Button/ButtonTokens.ts new file mode 100644 index 0000000000..fa6a4d72f2 --- /dev/null +++ b/packages/theming/apple-theme/src/components/Button/ButtonTokens.ts @@ -0,0 +1,101 @@ +import type { DimensionValue } from 'react-native'; + +import type { Theme } from '@fluentui-react-native/framework'; +import { globalTokens } from '@fluentui-react-native/theme-tokens'; + +export const defaultButtonTokens = (_t: Theme) => +({ + block: { + width: '100%' as DimensionValue, + }, + medium: { + padding: globalTokens.size60 - globalTokens.stroke.width10, + borderWidth: globalTokens.stroke.width10, + iconSize: 16, + focused: { + borderWidth: 0, + padding: globalTokens.size60, + }, + hasContent: { + minWidth: 96, + paddingHorizontal: globalTokens.size120 - globalTokens.stroke.width10, + hasIconAfter: { + spacingIconContentAfter: globalTokens.size60, + }, + hasIconBefore: { + spacingIconContentBefore: globalTokens.size60, + }, + focused: { + paddingHorizontal: globalTokens.size120, + }, + }, + }, + small: { + padding: globalTokens.size40 - globalTokens.stroke.width10, + borderWidth: globalTokens.stroke.width10, + iconSize: 16, + focused: { + borderWidth: 0, + padding: globalTokens.size40, + }, + hasContent: { + minWidth: 64, + minHeight: 24, + paddingHorizontal: globalTokens.size80 - globalTokens.stroke.width10, + hasIconAfter: { + spacingIconContentAfter: globalTokens.size40, + }, + hasIconBefore: { + spacingIconContentBefore: globalTokens.size40, + }, + focused: { + paddingHorizontal: globalTokens.size80, + }, + }, + }, + large: { + padding: globalTokens.size80 - globalTokens.stroke.width10, + borderWidth: globalTokens.stroke.width10, + iconSize: 20, + focused: { + borderWidth: 0, + padding: globalTokens.size80, + }, + hasContent: { + minWidth: 96, + paddingHorizontal: globalTokens.size160 - globalTokens.stroke.width10, + hasIconAfter: { + spacingIconContentAfter: globalTokens.size60, + }, + hasIconBefore: { + spacingIconContentBefore: globalTokens.size60, + }, + focused: { + paddingHorizontal: globalTokens.size160, + }, + }, + }, + rounded: { + borderRadius: globalTokens.corner.radius40, + }, + circular: { + borderRadius: globalTokens.corner.radiusCircular, + }, + square: { + borderRadius: globalTokens.corner.radiusNone, + }, + getPlatformSpecificAppearance: (appearance): 'primary' | 'subtle' | 'outline' | null => { + switch (appearance) { + case 'accent': // Included to cover Mobile platform naming guidelines, maps to 'primary'. + return 'primary'; + + case 'primary': + case 'subtle': + case 'outline': // 'Outline' exists only for Mobile platforms, default picked on other platforms. + return appearance; + + default: + return null; + } + } +}); diff --git a/packages/components/Button/src/CompoundButton/CompoundButtonColorTokens.ts b/packages/theming/apple-theme/src/components/Button/CompoundButtonColorTokens.ts similarity index 79% rename from packages/components/Button/src/CompoundButton/CompoundButtonColorTokens.ts rename to packages/theming/apple-theme/src/components/Button/CompoundButtonColorTokens.ts index 6e739edfee..1298af4e4a 100644 --- a/packages/components/Button/src/CompoundButton/CompoundButtonColorTokens.ts +++ b/packages/theming/apple-theme/src/components/Button/CompoundButtonColorTokens.ts @@ -1,9 +1,6 @@ import type { Theme } from '@fluentui-react-native/framework'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; -import type { CompoundButtonTokens } from './CompoundButton.types'; - -export const defaultCompoundButtonColorTokens: TokenSettings = (t: Theme): CompoundButtonTokens => ({ +export const defaultCompoundButtonColorTokens = (t: Theme) => ({ secondaryContentColor: t.colors.defaultSecondaryContent, hovered: { secondaryContentColor: t.colors.defaultHoveredSecondaryContent, diff --git a/packages/components/Button/src/CompoundButton/CompoundButtonFontTokens.ts b/packages/theming/apple-theme/src/components/Button/CompoundButtonFontTokens.ts similarity index 63% rename from packages/components/Button/src/CompoundButton/CompoundButtonFontTokens.ts rename to packages/theming/apple-theme/src/components/Button/CompoundButtonFontTokens.ts index d278051a82..1adab9492b 100644 --- a/packages/components/Button/src/CompoundButton/CompoundButtonFontTokens.ts +++ b/packages/theming/apple-theme/src/components/Button/CompoundButtonFontTokens.ts @@ -1,9 +1,6 @@ import type { Theme } from '@fluentui-react-native/framework'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; -import type { CompoundButtonTokens } from './CompoundButton.types'; - -export const defaultCompoundButtonFontTokens: TokenSettings = (_t: Theme): CompoundButtonTokens => ({ +export const defaultCompoundButtonFontTokens = (_t: Theme) => ({ medium: { hasContent: { variant: 'bodySemibold', diff --git a/packages/components/Button/src/CompoundButton/CompoundButtonTokens.ts b/packages/theming/apple-theme/src/components/Button/CompoundButtonTokens.ts similarity index 89% rename from packages/components/Button/src/CompoundButton/CompoundButtonTokens.ts rename to packages/theming/apple-theme/src/components/Button/CompoundButtonTokens.ts index 6fcb3af8d7..68f2669a46 100644 --- a/packages/components/Button/src/CompoundButton/CompoundButtonTokens.ts +++ b/packages/theming/apple-theme/src/components/Button/CompoundButtonTokens.ts @@ -1,10 +1,7 @@ import type { Theme } from '@fluentui-react-native/framework'; import { globalTokens } from '@fluentui-react-native/theme-tokens'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; -import type { CompoundButtonTokens } from './CompoundButton.types'; - -export const defaultCompoundButtonTokens: TokenSettings = (): CompoundButtonTokens => ({ +export const defaultCompoundButtonTokens = (_t: Theme) => ({ medium: { padding: globalTokens.size120 - globalTokens.stroke.width10, focused: { diff --git a/packages/components/Button/src/FAB/FABColorTokens.ios.ts b/packages/theming/apple-theme/src/components/Button/FABColorTokens.ts similarity index 87% rename from packages/components/Button/src/FAB/FABColorTokens.ios.ts rename to packages/theming/apple-theme/src/components/Button/FABColorTokens.ts index 35401ba006..4ac6a0c0dc 100644 --- a/packages/components/Button/src/FAB/FABColorTokens.ios.ts +++ b/packages/theming/apple-theme/src/components/Button/FABColorTokens.ts @@ -1,9 +1,6 @@ import type { Theme } from '@fluentui-react-native/framework'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; -import type { FABTokens } from './FAB.types'; - -export const defaultFABColorTokens: TokenSettings = (t: Theme): FABTokens => ({ +export const defaultFABColorTokens = (t: Theme) => ({ // Default coloring same as 'primary' or 'accent' backgroundColor: t.colors.brandBackground, color: t.colors.neutralForegroundOnColor, diff --git a/packages/components/Button/src/FAB/FABTokens.ios.ts b/packages/theming/apple-theme/src/components/Button/FABTokens.ts similarity index 89% rename from packages/components/Button/src/FAB/FABTokens.ios.ts rename to packages/theming/apple-theme/src/components/Button/FABTokens.ts index 20862dbcbe..2fd866693e 100644 --- a/packages/components/Button/src/FAB/FABTokens.ios.ts +++ b/packages/theming/apple-theme/src/components/Button/FABTokens.ts @@ -1,10 +1,7 @@ import type { Theme } from '@fluentui-react-native/framework'; -import { globalTokens } from '@fluentui-react-native/theme-tokens'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; +import {default as globalTokens} from '@fluentui-react-native/theme-tokens/lib/tokens-global.ios'; -import type { FABTokens } from './FAB.types'; - -export const defaultFABTokens: TokenSettings = (t: Theme) => +export const defaultFABTokens = (t: Theme) => ({ shadowToken: t.shadows.shadow8, disabled: { @@ -76,4 +73,4 @@ export const defaultFABTokens: TokenSettings = (t: Theme) => spacingIconContentBefore: globalTokens.size80, }, }, - } as FABTokens); + }); diff --git a/packages/theming/apple-theme/src/components/Button/ToggleButtonColorTokens.ts b/packages/theming/apple-theme/src/components/Button/ToggleButtonColorTokens.ts new file mode 100644 index 0000000000..67585c56ba --- /dev/null +++ b/packages/theming/apple-theme/src/components/Button/ToggleButtonColorTokens.ts @@ -0,0 +1,21 @@ +import type { Theme } from '@fluentui-react-native/framework'; + +export const defaultToggleButtonColorTokens = (t: Theme) => ({ + checked: { + color: t.colors.defaultCheckedContent, + backgroundColor: t.colors.defaultCheckedBackground, + hovered: { + color: t.colors.defaultCheckedHoveredContent, + backgroundColor: t.colors.defaultCheckedHoveredBackground, + }, + subtle: { + color: t.colors.ghostCheckedContent, + backgroundColor: t.colors.ghostCheckedBackground, + hovered: { + color: t.colors.ghostCheckedHoveredContent, + backgroundColor: t.colors.ghostCheckedHoveredBackground, + borderColor: t.colors.ghostCheckedHoveredBorder, + }, + }, + }, +}); diff --git a/packages/theming/apple-theme/src/createAppleTheme.ios.ts b/packages/theming/apple-theme/src/createAppleTheme.ios.ts index a165986345..c0527412d4 100644 --- a/packages/theming/apple-theme/src/createAppleTheme.ios.ts +++ b/packages/theming/apple-theme/src/createAppleTheme.ios.ts @@ -2,16 +2,17 @@ import { Appearance, NativeEventEmitter } from 'react-native'; import { NativeAppearanceAdditions } from '@fluentui-react-native/experimental-appearance-additions'; import { ThemeReference } from '@fluentui-react-native/theme'; -import type { Theme } from '@fluentui-react-native/theme-types'; +import type { PartialTheme, Theme } from '@fluentui-react-native/theme-types'; import { getBaseAppleThemeIOS } from './appleTheme.ios'; +import { defaultButtonTheme } from './components/Button/ButtonTheme'; export function createAppleTheme(): ThemeReference { - const appleThemeReference = new ThemeReference({} as Theme, () => { + const appleThemeReference = new ThemeReference({} as Theme, () => { const isLightMode = Appearance.getColorScheme() === 'light'; const isElevated = NativeAppearanceAdditions.userInterfaceLevel() === 'elevated'; return getBaseAppleThemeIOS(isLightMode, isElevated); - }); + }, defaultButtonTheme); Appearance.addChangeListener(() => { appleThemeReference.invalidate(); diff --git a/packages/theming/apple-theme/src/createAppleTheme.macos.ts b/packages/theming/apple-theme/src/createAppleTheme.macos.ts index 44a30f8ec5..2c9511e531 100644 --- a/packages/theming/apple-theme/src/createAppleTheme.macos.ts +++ b/packages/theming/apple-theme/src/createAppleTheme.macos.ts @@ -1,21 +1,23 @@ import { Appearance } from 'react-native'; import { ThemeReference } from '@fluentui-react-native/theme'; -import type { Theme } from '@fluentui-react-native/theme-types'; +import type { PartialTheme} from '@fluentui-react-native/theme-types'; +import { type Theme } from '@fluentui-react-native/theme-types'; import { getCurrentAppearance } from '@fluentui-react-native/theming-utils'; import { AccessibilityInfo } from 'react-native-macos'; import { setIsHighContrast } from './appleHighContrast.macos'; import { getBaseAppleThemeMacOS } from './appleTheme.macos'; +import { defaultButtonTheme } from './components/Button/ButtonTheme'; let appleThemeReference: ThemeReference; export function createAppleTheme(): ThemeReference { - appleThemeReference = new ThemeReference({} as Theme, () => { + appleThemeReference = new ThemeReference({} as Theme, () => { const appearance = Appearance.getColorScheme(); const mode = getCurrentAppearance(appearance, 'light'); return getBaseAppleThemeMacOS(mode); - }); + }, defaultButtonTheme); // Fetch initial system settings for high contrast mode highContrastHandler(); // Invalidate theme and set prop when high contrast setting changes diff --git a/packages/theming/default-theme/package.json b/packages/theming/default-theme/package.json index 32426b1120..c8dc238ad0 100644 --- a/packages/theming/default-theme/package.json +++ b/packages/theming/default-theme/package.json @@ -31,6 +31,7 @@ "author": "", "license": "MIT", "dependencies": { + "@fluentui-react-native/immutable-merge": "workspace:*", "@fluentui-react-native/memo-cache": "workspace:*", "@fluentui-react-native/theme": "workspace:*", "@fluentui-react-native/theme-tokens": "workspace:*", diff --git a/packages/theming/default-theme/src/__tests__/default-theme.test.ts b/packages/theming/default-theme/src/__tests__/default-theme.test.ts index db7d38b4e5..cdce962e4c 100644 --- a/packages/theming/default-theme/src/__tests__/default-theme.test.ts +++ b/packages/theming/default-theme/src/__tests__/default-theme.test.ts @@ -1,5 +1,13 @@ +import type { ButtonTokens, CompoundButtonTokens } from '@fluentui-react-native/button'; import type { ThemeOptions, AppearanceOptions } from '@fluentui-react-native/theme-types'; +import { defaultButtonColorTokens } from '../components/Button/ButtonColorTokens'; +import { defaultButtonFontTokens } from '../components/Button/ButtonFontTokens'; +import { defaultButtonTokens } from '../components/Button/ButtonTokens'; +import { defaultCompoundButtonColorTokens } from '../components/Button/CompoundButtonColorTokens'; +import { defaultCompoundButtonFontTokens } from '../components/Button/CompoundButtonFontTokens'; +import { defaultCompoundButtonTokens } from '../components/Button/CompoundButtonTokens'; + import { createColorAliasTokens, createShadowAliasTokens } from '../createAliasTokens'; import { createDefaultTheme } from '../createDefaultTheme'; import { defaultFluentTheme, defaultFluentDarkTheme } from '../defaultTheme'; @@ -47,3 +55,25 @@ describe('createShadowAliasTokens test', () => { expect(createShadowAliasTokens(appearanceOption)).toMatchSnapshot(); }); }); + +describe('verify types', () => { + it('Button types', () => { + const defaultTheme = createDefaultTheme().theme; + const colorTokens: ButtonTokens = defaultButtonColorTokens(defaultTheme); + expect(colorTokens).toBeTruthy(); + const fontTokens: ButtonTokens = defaultButtonFontTokens(defaultTheme); + expect(fontTokens).toBeTruthy(); + const tokens: ButtonTokens = defaultButtonTokens(defaultTheme); + expect(tokens).toBeTruthy(); + }); + + it('CompoundButton types', () => { + const defaultTheme = createDefaultTheme().theme; + const compoundColorTokens: CompoundButtonTokens = defaultCompoundButtonColorTokens(defaultTheme); + expect(compoundColorTokens).toBeTruthy(); + const compoundButtonFontTokens: CompoundButtonTokens = defaultCompoundButtonFontTokens(defaultTheme); + expect(compoundButtonFontTokens).toBeTruthy(); + const compoundButtonTokens: CompoundButtonTokens = defaultCompoundButtonTokens(defaultTheme); + expect(compoundButtonTokens).toBeTruthy(); + }); +}) \ No newline at end of file diff --git a/packages/components/Button/src/ButtonColorTokens.ts b/packages/theming/default-theme/src/components/Button/ButtonColorTokens.ts similarity index 92% rename from packages/components/Button/src/ButtonColorTokens.ts rename to packages/theming/default-theme/src/components/Button/ButtonColorTokens.ts index b2a6f4461a..943b01275b 100644 --- a/packages/components/Button/src/ButtonColorTokens.ts +++ b/packages/theming/default-theme/src/components/Button/ButtonColorTokens.ts @@ -1,9 +1,6 @@ import type { Theme } from '@fluentui-react-native/framework'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; -import type { ButtonTokens } from './Button.types'; - -export const defaultButtonColorTokens: TokenSettings = (t: Theme) => +export const defaultButtonColorTokens = (t: Theme) => ({ backgroundColor: t.colors.buttonBackground, color: t.colors.buttonText, @@ -85,4 +82,4 @@ export const defaultButtonColorTokens: TokenSettings = (t: icon: t.colors.ghostFocusedIcon, }, }, - } as ButtonTokens); + }); diff --git a/packages/components/Button/src/ButtonColorTokens.windows.ts b/packages/theming/default-theme/src/components/Button/ButtonColorTokens.windows.ts similarity index 95% rename from packages/components/Button/src/ButtonColorTokens.windows.ts rename to packages/theming/default-theme/src/components/Button/ButtonColorTokens.windows.ts index 17de26c304..2d7579726a 100644 --- a/packages/components/Button/src/ButtonColorTokens.windows.ts +++ b/packages/theming/default-theme/src/components/Button/ButtonColorTokens.windows.ts @@ -2,11 +2,8 @@ import { PlatformColor } from 'react-native'; import type { Theme } from '@fluentui-react-native/framework'; import { isHighContrast } from '@fluentui-react-native/theming-utils'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; -import type { ButtonTokens } from './Button.types'; - -export const defaultButtonColorTokens: TokenSettings = (t: Theme) => { +export const defaultButtonColorTokens = (t: Theme) => { if (isHighContrast(t)) { return highContrastColors; } @@ -100,7 +97,7 @@ export const defaultButtonColorTokens: TokenSettings = (t: iconColor: t.colors.neutralForeground1Hover, }, }, - } as ButtonTokens; + }; }; const highContrastColors = { diff --git a/packages/theming/default-theme/src/components/Button/ButtonFontTokens.ts b/packages/theming/default-theme/src/components/Button/ButtonFontTokens.ts new file mode 100644 index 0000000000..4315589584 --- /dev/null +++ b/packages/theming/default-theme/src/components/Button/ButtonFontTokens.ts @@ -0,0 +1,20 @@ +import type { Theme } from '@fluentui-react-native/framework'; + +type fontVariantType = 'secondaryStandard' | 'bodyStandard'; + +export const defaultButtonFontTokens = (_t: Theme) => + ({ + medium: { + hasContent: { + variant: 'bodySemibold' as fontVariantType, + }, + }, + small: { + hasContent: { + variant: 'secondaryStandard' as fontVariantType, + }, + }, + large: { + variant: 'subheaderSemibold' as fontVariantType, + }, + }); diff --git a/packages/theming/default-theme/src/components/Button/ButtonTheme.ts b/packages/theming/default-theme/src/components/Button/ButtonTheme.ts new file mode 100644 index 0000000000..34a8c5e669 --- /dev/null +++ b/packages/theming/default-theme/src/components/Button/ButtonTheme.ts @@ -0,0 +1,34 @@ + +import type { Theme } from '@fluentui-react-native/framework'; +import { immutableMerge } from '@fluentui-react-native/immutable-merge'; + +import { defaultButtonColorTokens } from './ButtonColorTokens'; +import { defaultButtonFontTokens } from './ButtonFontTokens'; +import { defaultButtonTokens } from './ButtonTokens'; +import { defaultCompoundButtonColorTokens } from './CompoundButtonColorTokens'; +import { defaultCompoundButtonFontTokens } from './CompoundButtonFontTokens'; +import { defaultCompoundButtonTokens } from './CompoundButtonTokens'; +import { defaultToggleButtonColorTokens } from './ToggleButtonColorTokens'; + +export const defaultButtonTheme = (theme: Theme) => +({ + components: { + Button: immutableMerge( + defaultButtonColorTokens(theme), + defaultButtonFontTokens(theme), + defaultButtonTokens(theme)), + CompoundButton: + immutableMerge( + defaultButtonTokens(theme), + defaultButtonColorTokens(theme), + defaultCompoundButtonColorTokens(theme), + defaultCompoundButtonFontTokens(theme), + defaultCompoundButtonTokens(theme)), + ToggleButton: + immutableMerge( + defaultButtonTokens(theme), + defaultButtonFontTokens(theme), + defaultButtonColorTokens(theme), + defaultToggleButtonColorTokens(theme)), + } +}); diff --git a/packages/components/Button/src/ButtonTokens.ts b/packages/theming/default-theme/src/components/Button/ButtonTokens.ts similarity index 79% rename from packages/components/Button/src/ButtonTokens.ts rename to packages/theming/default-theme/src/components/Button/ButtonTokens.ts index fe6b6e7d35..c5ae64a0dc 100644 --- a/packages/components/Button/src/ButtonTokens.ts +++ b/packages/theming/default-theme/src/components/Button/ButtonTokens.ts @@ -1,13 +1,12 @@ +import type { DimensionValue } from 'react-native'; + import type { Theme } from '@fluentui-react-native/framework'; import { globalTokens } from '@fluentui-react-native/theme-tokens'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; - -import type { ButtonTokens } from './Button.types'; -export const defaultButtonTokens: TokenSettings = () => +export const defaultButtonTokens = (_t: Theme) => ({ block: { - width: '100%', + width: '100%' as DimensionValue, }, medium: { padding: globalTokens.size60 - globalTokens.stroke.width10, @@ -85,4 +84,20 @@ export const defaultButtonTokens: TokenSettings = () => square: { borderRadius: globalTokens.corner.radiusNone, }, - } as ButtonTokens); + +getPlatformSpecificAppearance: (appearance): 'primary' | 'subtle' | 'outline' | null => { + switch (appearance) { + case 'accent': // Included to cover Mobile platform naming guidelines, maps to 'primary'. + return 'primary'; + + case 'primary': + case 'subtle': + case 'outline': // 'Outline' exists only for Mobile platforms, default picked on other platforms. + return appearance; + + default: + return null; + } +} + + }); diff --git a/packages/theming/default-theme/src/components/Button/CompoundButtonColorTokens.ts b/packages/theming/default-theme/src/components/Button/CompoundButtonColorTokens.ts new file mode 100644 index 0000000000..1298af4e4a --- /dev/null +++ b/packages/theming/default-theme/src/components/Button/CompoundButtonColorTokens.ts @@ -0,0 +1,38 @@ +import type { Theme } from '@fluentui-react-native/framework'; + +export const defaultCompoundButtonColorTokens = (t: Theme) => ({ + secondaryContentColor: t.colors.defaultSecondaryContent, + hovered: { + secondaryContentColor: t.colors.defaultHoveredSecondaryContent, + }, + focused: { + secondaryContentColor: t.colors.defaultFocusedSecondaryContent, + }, + pressed: { + secondaryContentColor: t.colors.defaultPressedSecondaryContent, + }, + primary: { + secondaryContentColor: t.colors.brandedSecondaryContent, + hovered: { + secondaryContentColor: t.colors.brandedHoveredSecondaryContent, + }, + focused: { + secondaryContentColor: t.colors.brandedFocusedSecondaryContent, + }, + pressed: { + secondaryContentColor: t.colors.brandedPressedSecondaryContent, + }, + }, + subtle: { + secondaryContentColor: t.colors.ghostSecondaryContent, + hovered: { + secondaryContentColor: t.colors.ghostHoveredSecondaryContent, + }, + focused: { + secondaryContentColor: t.colors.ghostFocusedSecondaryContent, + }, + pressed: { + secondaryContentColor: t.colors.ghostPressedSecondaryContent, + }, + }, +}); diff --git a/packages/components/Button/src/CompoundButton/CompoundButtonColorTokens.windows.ts b/packages/theming/default-theme/src/components/Button/CompoundButtonColorTokens.windows.ts similarity index 87% rename from packages/components/Button/src/CompoundButton/CompoundButtonColorTokens.windows.ts rename to packages/theming/default-theme/src/components/Button/CompoundButtonColorTokens.windows.ts index 9e9b64bde6..128ddcbff5 100644 --- a/packages/components/Button/src/CompoundButton/CompoundButtonColorTokens.windows.ts +++ b/packages/theming/default-theme/src/components/Button/CompoundButtonColorTokens.windows.ts @@ -2,11 +2,8 @@ import { PlatformColor } from 'react-native'; import type { Theme } from '@fluentui-react-native/framework'; import { isHighContrast } from '@fluentui-react-native/theming-utils'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; -import type { CompoundButtonTokens } from './CompoundButton.types'; - -export const defaultCompoundButtonColorTokens: TokenSettings = (t: Theme): CompoundButtonTokens => { +export const defaultCompoundButtonColorTokens = (t: Theme) => { if (isHighContrast(t)) { return highContrastColors; } diff --git a/packages/theming/default-theme/src/components/Button/CompoundButtonFontTokens.ts b/packages/theming/default-theme/src/components/Button/CompoundButtonFontTokens.ts new file mode 100644 index 0000000000..fe22f2657e --- /dev/null +++ b/packages/theming/default-theme/src/components/Button/CompoundButtonFontTokens.ts @@ -0,0 +1,24 @@ +import type { Theme } from '@fluentui-react-native/framework'; + +type fontVariantType = 'secondaryStandard' | 'bodyStandard'; + +export const defaultCompoundButtonFontTokens = (_t: Theme) => ({ + medium: { + hasContent: { + variant: 'bodySemibold' as fontVariantType, + secondaryContentFont: { variant: 'secondaryStandard' as fontVariantType }, + }, + }, + small: { + hasContent: { + variant: 'bodyStandard' as fontVariantType, + secondaryContentFont: { variant: 'secondaryStandard' as fontVariantType }, + }, + }, + large: { + hasContent: { + variant: 'subheaderSemibold' as fontVariantType, + secondaryContentFont: { variant: 'bodyStandard' as fontVariantType }, + }, + }, +}); diff --git a/packages/theming/default-theme/src/components/Button/CompoundButtonTokens.ts b/packages/theming/default-theme/src/components/Button/CompoundButtonTokens.ts new file mode 100644 index 0000000000..68f2669a46 --- /dev/null +++ b/packages/theming/default-theme/src/components/Button/CompoundButtonTokens.ts @@ -0,0 +1,80 @@ +import type { Theme } from '@fluentui-react-native/framework'; +import { globalTokens } from '@fluentui-react-native/theme-tokens'; + +export const defaultCompoundButtonTokens = (_t: Theme) => ({ + medium: { + padding: globalTokens.size120 - globalTokens.stroke.width10, + focused: { + padding: globalTokens.size120, + }, + hasContent: { + paddingHorizontal: globalTokens.size120 - globalTokens.stroke.width10, + minWidth: 96, + focused: { + paddingHorizontal: globalTokens.size120, + }, + hasIconAfter: { + spacingIconContentAfter: globalTokens.size120, + }, + hasIconBefore: { + spacingIconContentBefore: globalTokens.size120, + }, + circular: { + paddingHorizontal: globalTokens.size160 - globalTokens.stroke.width10, + focused: { + paddingHorizontal: globalTokens.size160, + }, + }, + }, + }, + small: { + padding: globalTokens.size80 - globalTokens.stroke.width10, + focused: { + padding: globalTokens.size80, + }, + hasContent: { + paddingHorizontal: globalTokens.size80 - globalTokens.stroke.width10, + minWidth: 64, + focused: { + paddingHorizontal: globalTokens.size80, + }, + hasIconAfter: { + spacingIconContentAfter: globalTokens.size80, + }, + hasIconBefore: { + spacingIconContentBefore: globalTokens.size80, + }, + circular: { + paddingHorizontal: globalTokens.size120 - globalTokens.stroke.width10, + focused: { + paddingHorizontal: globalTokens.size120, + }, + }, + }, + }, + large: { + padding: globalTokens.size160 - globalTokens.stroke.width10, + focused: { + padding: globalTokens.size160, + }, + hasContent: { + paddingHorizontal: globalTokens.size160 - globalTokens.stroke.width10, + minWidth: 96, + focused: { + paddingHorizontal: globalTokens.size160, + }, + hasIconAfter: { + spacingIconContentAfter: globalTokens.size160, + }, + hasIconBefore: { + spacingIconContentBefore: globalTokens.size160, + }, + circular: { + paddingHorizontal: globalTokens.size200 - globalTokens.stroke.width10, + focused: { + paddingHorizontal: globalTokens.size200, + }, + }, + }, + }, +}); diff --git a/packages/theming/default-theme/src/components/Button/ToggleButtonColorTokens.ts b/packages/theming/default-theme/src/components/Button/ToggleButtonColorTokens.ts new file mode 100644 index 0000000000..67585c56ba --- /dev/null +++ b/packages/theming/default-theme/src/components/Button/ToggleButtonColorTokens.ts @@ -0,0 +1,21 @@ +import type { Theme } from '@fluentui-react-native/framework'; + +export const defaultToggleButtonColorTokens = (t: Theme) => ({ + checked: { + color: t.colors.defaultCheckedContent, + backgroundColor: t.colors.defaultCheckedBackground, + hovered: { + color: t.colors.defaultCheckedHoveredContent, + backgroundColor: t.colors.defaultCheckedHoveredBackground, + }, + subtle: { + color: t.colors.ghostCheckedContent, + backgroundColor: t.colors.ghostCheckedBackground, + hovered: { + color: t.colors.ghostCheckedHoveredContent, + backgroundColor: t.colors.ghostCheckedHoveredBackground, + borderColor: t.colors.ghostCheckedHoveredBorder, + }, + }, + }, +}); diff --git a/packages/components/Button/src/ToggleButton/ToggleButtonColorTokens.windows.ts b/packages/theming/default-theme/src/components/Button/ToggleButtonColorTokens.windows.ts similarity index 81% rename from packages/components/Button/src/ToggleButton/ToggleButtonColorTokens.windows.ts rename to packages/theming/default-theme/src/components/Button/ToggleButtonColorTokens.windows.ts index cfcc4338fc..bb6940f9e5 100644 --- a/packages/components/Button/src/ToggleButton/ToggleButtonColorTokens.windows.ts +++ b/packages/theming/default-theme/src/components/Button/ToggleButtonColorTokens.windows.ts @@ -2,11 +2,8 @@ import { PlatformColor } from 'react-native'; import type { Theme } from '@fluentui-react-native/framework'; import { isHighContrast } from '@fluentui-react-native/theming-utils'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; -import type { ToggleButtonTokens } from './ToggleButton.types'; - -export const defaultToggleButtonColorTokens: TokenSettings = (t: Theme): ToggleButtonTokens => { +export const defaultToggleButtonColorTokens = (t: Theme) => { if (isHighContrast(t)) { return highContrastColors; } diff --git a/packages/theming/default-theme/src/createDefaultTheme.ts b/packages/theming/default-theme/src/createDefaultTheme.ts index ef5034d39f..57eae436c3 100644 --- a/packages/theming/default-theme/src/createDefaultTheme.ts +++ b/packages/theming/default-theme/src/createDefaultTheme.ts @@ -1,14 +1,15 @@ import { Appearance } from 'react-native'; import { ThemeReference } from '@fluentui-react-native/theme'; -import type { Theme, ThemeOptions } from '@fluentui-react-native/theme-types'; +import type { PartialTheme, Theme, ThemeOptions } from '@fluentui-react-native/theme-types'; import { getCurrentAppearance } from '@fluentui-react-native/theming-utils'; import assertNever from 'assert-never'; +import { defaultButtonTheme } from './components/Button/ButtonTheme'; import { defaultFluentDarkTheme, defaultFluentHighConstrastTheme, defaultFluentTheme } from './defaultTheme'; export function createDefaultTheme(options: ThemeOptions = {}): ThemeReference { - const themeRef = new ThemeReference({} as Theme, () => { + const themeRef = new ThemeReference({} as Theme, () => { const current = getCurrentAppearance(options.appearance, options.defaultAppearance || 'light'); switch (current) { case 'light': @@ -22,7 +23,7 @@ export function createDefaultTheme(options: ThemeOptions = {}): ThemeReference { default: assertNever(current); } - }); + }, defaultButtonTheme); if (Appearance && options.appearance === 'dynamic') { Appearance.addChangeListener(() => { diff --git a/packages/theming/theme-tokens/src/index.ts b/packages/theming/theme-tokens/src/index.ts index 2832ce3c03..8eff5a177c 100644 --- a/packages/theming/theme-tokens/src/index.ts +++ b/packages/theming/theme-tokens/src/index.ts @@ -1,2 +1,5 @@ export { default as globalTokens } from './tokens-global'; export { getAliasTokens, getShadowTokens } from './getTokens'; +export { default as globalTokensWin32 } from './tokens-global.win32'; +export { default as globalTokensIOS } from './tokens-global.ios'; +export { default as globalTokensAndroid } from './tokens-global.android'; \ No newline at end of file diff --git a/packages/theming/win32-theme/package.json b/packages/theming/win32-theme/package.json index 0a9d19e35c..e518439cd8 100644 --- a/packages/theming/win32-theme/package.json +++ b/packages/theming/win32-theme/package.json @@ -33,6 +33,7 @@ "dependencies": { "@fluentui-react-native/default-theme": "workspace:*", "@fluentui-react-native/design-tokens-win32": "^0.53.0", + "@fluentui-react-native/immutable-merge": "workspace:*", "@fluentui-react-native/memo-cache": "workspace:*", "@fluentui-react-native/theme": "workspace:*", "@fluentui-react-native/theme-tokens": "workspace:*", @@ -41,8 +42,10 @@ "tslib": "^2.3.1" }, "devDependencies": { + "@fluentui-react-native/button": "workspace:*", "@fluentui-react-native/eslint-config-rules": "workspace:*", "@fluentui-react-native/scripts": "workspace:*", + "@fluentui-react-native/use-styling": "workspace:*", "@office-iss/react-native-win32": "^0.73.0", "@react-native/babel-preset": "^0.73.0", "@react-native/metro-config": "^0.73.0", diff --git a/packages/theming/win32-theme/src/__tests__/__snapshots__/win32-theme.test.ts.snap b/packages/theming/win32-theme/src/__tests__/__snapshots__/win32-theme.test.ts.snap index be86785d83..6830c3c81f 100644 --- a/packages/theming/win32-theme/src/__tests__/__snapshots__/win32-theme.test.ts.snap +++ b/packages/theming/win32-theme/src/__tests__/__snapshots__/win32-theme.test.ts.snap @@ -2714,6 +2714,265 @@ exports[`createOfficeTheme test 1`] = ` "warningForeground3": "#fde300", "warningForegroundInverted": "#fef7b2", }, + "components": { + "Button": { + "backgroundColor": "antiquewhite", + "block": { + "width": "100%", + }, + "borderColor": "#969696", + "borderInnerWidth": 1, + "borderWidth": 1, + "circular": { + "borderInnerRadius": 9998, + "borderRadius": 9999, + }, + "color": "#262626", + "disabled": { + "backgroundColor": "#E6E6E6", + "borderColor": "#D2D2D2", + "color": "#B1B1B1", + "iconColor": "#B1B1B1", + }, + "focused": { + "backgroundColor": "#D2D2D2", + "borderColor": "#00000000", + "color": "#262626", + "iconColor": "#262626", + }, + "hovered": { + "backgroundColor": "#D2D2D2", + "borderColor": "#969696", + "color": "#262626", + "iconColor": "#262626", + }, + "iconColor": "#262626", + "large": { + "focused": { + "borderWidth": 0, + "padding": 10, + }, + "hasContent": { + "focused": { + "padding": 8, + "paddingHorizontal": 16, + }, + "fontFamily": "Segoe UI Semibold", + "fontSize": 16, + "fontWeight": "600", + "hasIconAfter": { + "spacingIconContentAfter": 6, + }, + "hasIconBefore": { + "spacingIconContentBefore": 6, + }, + "minHeight": 40, + "minWidth": 96, + "padding": 7, + "paddingHorizontal": 15, + "primary": { + "focused": { + "padding": 6, + "paddingHorizontal": 14, + }, + "square": { + "focused": { + "padding": 7, + "paddingHorizontal": 15, + }, + }, + }, + }, + "iconSize": 20, + "padding": 9, + "primary": { + "focused": { + "borderWidth": 2, + "padding": 8, + }, + "square": { + "focused": { + "borderWidth": 1, + "padding": 9, + }, + }, + }, + }, + "medium": { + "focused": { + "borderWidth": 0, + "padding": 8, + }, + "hasContent": { + "focused": { + "padding": 6, + "paddingHorizontal": 12, + }, + "fontFamily": "Segoe UI Semibold", + "fontSize": 14, + "fontWeight": "600", + "hasIconAfter": { + "spacingIconContentAfter": 8, + }, + "hasIconBefore": { + "spacingIconContentBefore": 8, + }, + "minWidth": 96, + "padding": 5, + "paddingHorizontal": 11, + "primary": { + "focused": { + "padding": 4, + "paddingHorizontal": 10, + }, + "square": { + "focused": { + "padding": 5, + "paddingHorizontal": 11, + }, + }, + }, + }, + "iconSize": 16, + "padding": 7, + "primary": { + "focused": { + "borderWidth": 2, + "padding": 6, + }, + "square": { + "focused": { + "borderWidth": 1, + "padding": 7, + }, + }, + }, + }, + "pressed": { + "backgroundColor": "#B1B1B1", + "borderColor": "#969696", + "color": "#262626", + "iconColor": "#262626", + }, + "primary": { + "backgroundColor": "#D83B01", + "borderColor": "#D83B01", + "color": "#FFFFFF", + "disabled": { + "backgroundColor": "#E6E6E6", + "borderColor": "#D2D2D2", + "color": "#B1B1B1", + "iconColor": "#B1B1B1", + }, + "focused": { + "backgroundColor": "#F29F71", + "borderColor": "#969696", + "borderInnerColor": "#ffffff", + "color": "#FFFFFF", + "iconColor": "#FFFFFF", + }, + "hovered": { + "backgroundColor": "#F29F71", + "borderColor": "#F29F71", + "color": "#FFFFFF", + "iconColor": "#FFFFFF", + }, + "iconColor": "#FFFFFF", + "pressed": { + "backgroundColor": "#A22C01", + "borderColor": "#A22C01", + "color": "#FFFFFF", + "iconColor": "#FFFFFF", + }, + }, + "rounded": { + "borderInnerRadius": 3, + "borderRadius": 4, + }, + "size": "small", + "small": { + "focused": { + "borderWidth": 0, + "padding": 4, + }, + "hasContent": { + "focused": { + "paddingHorizontal": 8, + }, + "fontFamily": "Segoe UI", + "fontSize": 12, + "fontWeight": "400", + "hasIconAfter": { + "spacingIconContentAfter": 4, + }, + "hasIconBefore": { + "spacingIconContentBefore": 4, + }, + "minHeight": 24, + "minWidth": 64, + "paddingHorizontal": 7, + "primary": { + "focused": { + "paddingHorizontal": 6, + }, + "square": { + "focused": { + "paddingHorizontal": 7, + }, + }, + }, + }, + "iconSize": 16, + "padding": 3, + "primary": { + "focused": { + "borderWidth": 2, + "padding": 2, + }, + "square": { + "focused": { + "borderWidth": 1, + "padding": 3, + }, + }, + }, + }, + "square": { + "borderInnerRadius": 0, + "borderRadius": 0, + }, + "subtle": { + "backgroundColor": "#00000000", + "borderColor": "#00000000", + "color": "#262626", + "disabled": { + "backgroundColor": "#00000000", + "borderColor": "#00000000", + "color": "#B1B1B1", + "iconColor": "#B1B1B1", + }, + "focused": { + "backgroundColor": "#f5f5f5", + "borderColor": "#00000000", + "color": "#262626", + "iconColor": "#262626", + }, + "hovered": { + "backgroundColor": "#f5f5f5", + "borderColor": "#f5f5f5", + "color": "#262626", + "iconColor": "#262626", + }, + "iconColor": "#262626", + "pressed": { + "backgroundColor": "#e0e0e0", + "borderColor": "#e0e0e0", + "color": "#262626", + "iconColor": "#262626", + }, + }, + }, + }, "host": { "appearance": "light", "colors": { diff --git a/packages/theming/win32-theme/src/__tests__/win32-theme.test.ts b/packages/theming/win32-theme/src/__tests__/win32-theme.test.ts index 1f4dc84c4e..c2899de65b 100644 --- a/packages/theming/win32-theme/src/__tests__/win32-theme.test.ts +++ b/packages/theming/win32-theme/src/__tests__/win32-theme.test.ts @@ -1,3 +1,11 @@ +import type { ButtonTokens, CompoundButtonTokens } from '@fluentui-react-native/button'; + +import { defaultButtonColorTokens } from '../components/Button/ButtonColorTokens'; +import { defaultButtonFontTokens } from '../components/Button/ButtonFontTokens'; +import { defaultButtonTokens } from '../components/Button/ButtonTokens'; +import { defaultCompoundButtonColorTokens } from '../components/Button/CompoundButtonColorTokens'; +import { defaultCompoundButtonFontTokens } from '../components/Button/CompoundButtonFontTokens'; +import { defaultCompoundButtonTokens } from '../components/Button/CompoundButtonTokens'; import { createBrandedThemeWithAlias, getCurrentBrandAliasTokens } from '../createBrandedThemeWithAlias'; import { createFontAliasTokens } from '../createFontAliasTokens'; import { createOfficeColorAliasTokens, createOfficeShadowAliasTokens } from '../createOfficeAliasTokens'; @@ -91,3 +99,25 @@ describe('getCurrentBrandAliasTokens test', () => { expect(brandAliasTokens).toMatchSnapshot(); }); }); + +describe('verify types', () => { + it('Button types', () => { + const officeTheme = createOfficeTheme({ paletteName: 'TaskPane', appearance: 'light' }).theme; + const colorTokens: ButtonTokens = defaultButtonColorTokens(officeTheme); + expect(colorTokens).toBeTruthy(); + const fontTokens: ButtonTokens = defaultButtonFontTokens(officeTheme); + expect(fontTokens).toBeTruthy(); + const tokens: ButtonTokens = defaultButtonTokens(officeTheme); + expect(tokens).toBeTruthy(); + }); + + it('CompoundButton types', () => { + const officeTheme = createOfficeTheme({ paletteName: 'TaskPane', appearance: 'light' }).theme; + const compoundColorTokens: CompoundButtonTokens = defaultCompoundButtonColorTokens(officeTheme); + expect(compoundColorTokens).toBeTruthy(); + const compoundButtonFontTokens: CompoundButtonTokens = defaultCompoundButtonFontTokens(officeTheme); + expect(compoundButtonFontTokens).toBeTruthy(); + const compoundButtonTokens: CompoundButtonTokens = defaultCompoundButtonTokens(officeTheme); + expect(compoundButtonTokens).toBeTruthy(); + }); +}) \ No newline at end of file diff --git a/packages/components/Button/src/ButtonColorTokens.win32.ts b/packages/theming/win32-theme/src/components/Button/ButtonColorTokens.ts similarity index 95% rename from packages/components/Button/src/ButtonColorTokens.win32.ts rename to packages/theming/win32-theme/src/components/Button/ButtonColorTokens.ts index 2a40e43d04..0e85f40b2f 100644 --- a/packages/components/Button/src/ButtonColorTokens.win32.ts +++ b/packages/theming/win32-theme/src/components/Button/ButtonColorTokens.ts @@ -2,11 +2,8 @@ import { PlatformColor } from 'react-native'; import type { Theme } from '@fluentui-react-native/framework'; import { isHighContrast } from '@fluentui-react-native/theming-utils'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; -import type { ButtonTokens } from './Button.types'; - -export const defaultButtonColorTokens: TokenSettings = (t: Theme) => { +export const defaultButtonColorTokens = (t: Theme) => { if (isHighContrast(t)) { return highContrastColors; } @@ -101,7 +98,7 @@ export const defaultButtonColorTokens: TokenSettings = (t: iconColor: t.colors.neutralForeground1Hover, }, }, - } as ButtonTokens; + }; }; const highContrastColors = { diff --git a/packages/theming/win32-theme/src/components/Button/ButtonFontTokens.ts b/packages/theming/win32-theme/src/components/Button/ButtonFontTokens.ts new file mode 100644 index 0000000000..f6432a215b --- /dev/null +++ b/packages/theming/win32-theme/src/components/Button/ButtonFontTokens.ts @@ -0,0 +1,28 @@ +import type { Theme } from '@fluentui-react-native/framework'; +import { globalTokensWin32 as globalTokens } from '@fluentui-react-native/theme-tokens'; +import type { FontWeight } from '@fluentui-react-native/theme-types' + +export const defaultButtonFontTokens = (t: Theme) => +({ + medium: { + hasContent: { + fontFamily: t.typography.families.secondary, + fontSize: globalTokens.font.size300, + fontWeight: globalTokens.font.weight.semibold as FontWeight, + }, + }, + small: { + hasContent: { + fontFamily: t.typography.families.primary, + fontSize: globalTokens.font.size200, + fontWeight: globalTokens.font.weight.regular as FontWeight, + }, + }, + large: { + hasContent: { + fontFamily: t.typography.families.secondary, + fontSize: globalTokens.font.size400, + fontWeight: globalTokens.font.weight.semibold as FontWeight, + }, + }, +}); diff --git a/packages/theming/win32-theme/src/components/Button/ButtonTheme.ts b/packages/theming/win32-theme/src/components/Button/ButtonTheme.ts new file mode 100644 index 0000000000..34a8c5e669 --- /dev/null +++ b/packages/theming/win32-theme/src/components/Button/ButtonTheme.ts @@ -0,0 +1,34 @@ + +import type { Theme } from '@fluentui-react-native/framework'; +import { immutableMerge } from '@fluentui-react-native/immutable-merge'; + +import { defaultButtonColorTokens } from './ButtonColorTokens'; +import { defaultButtonFontTokens } from './ButtonFontTokens'; +import { defaultButtonTokens } from './ButtonTokens'; +import { defaultCompoundButtonColorTokens } from './CompoundButtonColorTokens'; +import { defaultCompoundButtonFontTokens } from './CompoundButtonFontTokens'; +import { defaultCompoundButtonTokens } from './CompoundButtonTokens'; +import { defaultToggleButtonColorTokens } from './ToggleButtonColorTokens'; + +export const defaultButtonTheme = (theme: Theme) => +({ + components: { + Button: immutableMerge( + defaultButtonColorTokens(theme), + defaultButtonFontTokens(theme), + defaultButtonTokens(theme)), + CompoundButton: + immutableMerge( + defaultButtonTokens(theme), + defaultButtonColorTokens(theme), + defaultCompoundButtonColorTokens(theme), + defaultCompoundButtonFontTokens(theme), + defaultCompoundButtonTokens(theme)), + ToggleButton: + immutableMerge( + defaultButtonTokens(theme), + defaultButtonFontTokens(theme), + defaultButtonColorTokens(theme), + defaultToggleButtonColorTokens(theme)), + } +}); diff --git a/packages/theming/win32-theme/src/components/Button/ButtonTokens.ts b/packages/theming/win32-theme/src/components/Button/ButtonTokens.ts new file mode 100644 index 0000000000..80ae6197a0 --- /dev/null +++ b/packages/theming/win32-theme/src/components/Button/ButtonTokens.ts @@ -0,0 +1,183 @@ +import type { DimensionValue } from 'react-native'; + +import type { Theme } from '@fluentui-react-native/framework'; +import { globalTokensWin32 as globalTokens } from '@fluentui-react-native/theme-tokens'; +import { isHighContrast } from '@fluentui-react-native/theming-utils'; + +type ButtonSize = 'small'; + +export const defaultButtonTokens = (theme: Theme) => +({ + size: 'small' as ButtonSize, + borderWidth: globalTokens.stroke.width10, + borderInnerWidth: globalTokens.stroke.width10, + block: { + width: '100%' as DimensionValue, + }, + medium: { + padding: globalTokens.size80 - globalTokens.stroke.width10, + iconSize: 16, + focused: { + borderWidth: 0, + padding: globalTokens.size80, + }, + primary: !isHighContrast(theme) && { + focused: { + borderWidth: globalTokens.stroke.width20, + padding: globalTokens.size80 - globalTokens.stroke.width20, + }, + square: { + focused: { + borderWidth: globalTokens.stroke.width10, + padding: globalTokens.size80 - globalTokens.stroke.width10, + }, + }, + }, + hasContent: { + minWidth: 96, + padding: globalTokens.size60 - globalTokens.stroke.width10, + paddingHorizontal: globalTokens.size120 - globalTokens.stroke.width10, + hasIconAfter: { + spacingIconContentAfter: globalTokens.size80, + }, + hasIconBefore: { + spacingIconContentBefore: globalTokens.size80, + }, + focused: { + padding: globalTokens.size60, + paddingHorizontal: globalTokens.size120, + }, + primary: !isHighContrast(theme) && { + focused: { + padding: globalTokens.size60 - globalTokens.stroke.width20, + paddingHorizontal: globalTokens.size120 - globalTokens.stroke.width20, + }, + square: { + focused: { + padding: globalTokens.size60 - globalTokens.stroke.width10, + paddingHorizontal: globalTokens.size120 - globalTokens.stroke.width10, + }, + }, + }, + }, + }, + small: { + padding: globalTokens.size40 - globalTokens.stroke.width10, + iconSize: 16, + focused: { + borderWidth: 0, + padding: globalTokens.size40, + }, + primary: !isHighContrast(theme) && { + focused: { + borderWidth: globalTokens.stroke.width20, + padding: globalTokens.size40 - globalTokens.stroke.width20, + }, + square: { + focused: { + borderWidth: globalTokens.stroke.width10, + padding: globalTokens.size40 - globalTokens.stroke.width10, + }, + }, + }, + hasContent: { + minWidth: 64, + minHeight: 24, + paddingHorizontal: globalTokens.size80 - globalTokens.stroke.width10, + hasIconAfter: { + spacingIconContentAfter: globalTokens.size40, + }, + hasIconBefore: { + spacingIconContentBefore: globalTokens.size40, + }, + focused: { + paddingHorizontal: globalTokens.size80, + }, + primary: !isHighContrast(theme) && { + focused: { + paddingHorizontal: globalTokens.size80 - globalTokens.stroke.width20, + }, + square: { + focused: { + paddingHorizontal: globalTokens.size80 - globalTokens.stroke.width10, + }, + }, + }, + }, + }, + large: { + padding: globalTokens.size100 - globalTokens.stroke.width10, + iconSize: 20, + focused: { + borderWidth: 0, + padding: globalTokens.size100, + }, + primary: !isHighContrast(theme) && { + focused: { + borderWidth: globalTokens.stroke.width20, + padding: globalTokens.size100 - globalTokens.stroke.width20, + }, + square: { + focused: { + borderWidth: globalTokens.stroke.width10, + padding: globalTokens.size100 - globalTokens.stroke.width10, + }, + }, + }, + hasContent: { + minWidth: 96, + minHeight: 40, + padding: globalTokens.size80 - globalTokens.stroke.width10, + paddingHorizontal: globalTokens.size160 - globalTokens.stroke.width10, + hasIconAfter: { + spacingIconContentAfter: globalTokens.size60, + }, + hasIconBefore: { + spacingIconContentBefore: globalTokens.size60, + }, + focused: { + padding: globalTokens.size80, + paddingHorizontal: globalTokens.size160, + }, + primary: !isHighContrast(theme) && { + focused: { + padding: globalTokens.size80 - globalTokens.stroke.width20, + paddingHorizontal: globalTokens.size160 - globalTokens.stroke.width20, + }, + square: { + focused: { + padding: globalTokens.size80 - globalTokens.stroke.width10, + paddingHorizontal: globalTokens.size160 - globalTokens.stroke.width10, + }, + }, + }, + }, + }, + rounded: { + borderRadius: globalTokens.corner.radius40, + borderInnerRadius: globalTokens.corner.radius40 - 1, // reduce the rounding so that the curvature matches + }, + circular: { + borderRadius: globalTokens.corner.radiusCircular, + borderInnerRadius: globalTokens.corner.radiusCircular - 1, // reduce the rounding so that the curvature matches + }, + square: { + borderRadius: globalTokens.corner.radiusNone, + borderInnerRadius: globalTokens.corner.radiusNone, + }, + + getPlatformSpecificAppearance: (appearance): 'primary' | 'subtle' | 'outline' | null => { + switch (appearance) { + case 'accent': // Included to cover Mobile platform naming guidelines, maps to 'primary'. + return 'primary'; + + case 'primary': + case 'subtle': + case 'outline': // 'Outline' exists only for Mobile platforms, default picked on other platforms. + return appearance; + + default: + return null; + } + } +}); diff --git a/packages/components/Button/src/CompoundButton/CompoundButtonColorTokens.win32.ts b/packages/theming/win32-theme/src/components/Button/CompoundButtonColorTokens.ts similarity index 86% rename from packages/components/Button/src/CompoundButton/CompoundButtonColorTokens.win32.ts rename to packages/theming/win32-theme/src/components/Button/CompoundButtonColorTokens.ts index 2c7e801814..41a15d8769 100644 --- a/packages/components/Button/src/CompoundButton/CompoundButtonColorTokens.win32.ts +++ b/packages/theming/win32-theme/src/components/Button/CompoundButtonColorTokens.ts @@ -2,11 +2,8 @@ import { PlatformColor } from 'react-native'; import type { Theme } from '@fluentui-react-native/framework'; import { isHighContrast } from '@fluentui-react-native/theming-utils'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; -import type { CompoundButtonTokens } from './CompoundButton.types'; - -export const defaultCompoundButtonColorTokens: TokenSettings = (t: Theme): CompoundButtonTokens => { +export const defaultCompoundButtonColorTokens = (t: Theme) => { if (isHighContrast(t)) { return highContrastColors; } @@ -49,7 +46,7 @@ export const defaultCompoundButtonColorTokens: TokenSettings = (t: Theme): CompoundButtonTokens => ({ +export const defaultCompoundButtonFontTokens = (t: Theme) => ({ medium: { hasContent: { fontFamily: t.typography.families.secondary, diff --git a/packages/components/Button/src/CompoundButton/CompoundButtonTokens.win32.ts b/packages/theming/win32-theme/src/components/Button/CompoundButtonTokens.ts similarity index 93% rename from packages/components/Button/src/CompoundButton/CompoundButtonTokens.win32.ts rename to packages/theming/win32-theme/src/components/Button/CompoundButtonTokens.ts index d474eba9bb..906b784c70 100644 --- a/packages/components/Button/src/CompoundButton/CompoundButtonTokens.win32.ts +++ b/packages/theming/win32-theme/src/components/Button/CompoundButtonTokens.ts @@ -1,11 +1,8 @@ import type { Theme } from '@fluentui-react-native/framework'; -import { globalTokens } from '@fluentui-react-native/theme-tokens'; +import { globalTokensWin32 as globalTokens } from '@fluentui-react-native/theme-tokens'; import { isHighContrast } from '@fluentui-react-native/theming-utils'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; -import type { CompoundButtonTokens } from './CompoundButton.types'; - -export const defaultCompoundButtonTokens: TokenSettings = (theme: Theme): CompoundButtonTokens => ({ +export const defaultCompoundButtonTokens = (theme: Theme) => ({ medium: { padding: globalTokens.size120 - globalTokens.stroke.width10, focused: { diff --git a/packages/components/Button/src/ToggleButton/ToggleButtonColorTokens.win32.ts b/packages/theming/win32-theme/src/components/Button/ToggleButtonColorTokens.ts similarity index 79% rename from packages/components/Button/src/ToggleButton/ToggleButtonColorTokens.win32.ts rename to packages/theming/win32-theme/src/components/Button/ToggleButtonColorTokens.ts index e2bee988a4..9ea3f17cda 100644 --- a/packages/components/Button/src/ToggleButton/ToggleButtonColorTokens.win32.ts +++ b/packages/theming/win32-theme/src/components/Button/ToggleButtonColorTokens.ts @@ -2,11 +2,8 @@ import { PlatformColor } from 'react-native'; import type { Theme } from '@fluentui-react-native/framework'; import { isHighContrast } from '@fluentui-react-native/theming-utils'; -import type { TokenSettings } from '@fluentui-react-native/use-styling'; -import type { ToggleButtonTokens } from './ToggleButton.types'; - -export const defaultToggleButtonColorTokens: TokenSettings = (t: Theme): ToggleButtonTokens => { +export const defaultToggleButtonColorTokens = (t: Theme) => { if (isHighContrast(t)) { return highContrastColors; } diff --git a/packages/theming/win32-theme/src/createOfficeTheme.ts b/packages/theming/win32-theme/src/createOfficeTheme.ts index 46c903acae..154422dee6 100644 --- a/packages/theming/win32-theme/src/createOfficeTheme.ts +++ b/packages/theming/win32-theme/src/createOfficeTheme.ts @@ -2,6 +2,7 @@ import { createDefaultTheme } from '@fluentui-react-native/default-theme'; import { ThemeReference } from '@fluentui-react-native/theme'; import type { OfficePalette, Theme, ThemeOptions } from '@fluentui-react-native/theme-types'; +import {defaultButtonTheme} from './components/Button/ButtonTheme'; import { createAliasesFromPalette } from './createAliasesFromPalette'; import { createBrandedThemeWithAlias } from './createBrandedThemeWithAlias'; import { createOfficeColorAliasTokens, createOfficeShadowAliasTokens } from './createOfficeAliasTokens'; @@ -70,6 +71,7 @@ export function createOfficeTheme(options: ThemeOptions = {}): ThemeReference { typography: win32Typography(), }; }, + defaultButtonTheme, ); // set up the callback for theme changes on the native side diff --git a/yarn.lock b/yarn.lock index a867fd4284..c079da9792 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2642,6 +2642,7 @@ __metadata: resolution: "@fluentui-react-native/android-theme@workspace:packages/theming/android-theme" dependencies: "@fluentui-react-native/eslint-config-rules": "workspace:*" + "@fluentui-react-native/immutable-merge": "workspace:*" "@fluentui-react-native/memo-cache": "workspace:*" "@fluentui-react-native/scripts": "workspace:*" "@fluentui-react-native/theme": "workspace:*" @@ -2677,6 +2678,7 @@ __metadata: "@fluentui-react-native/design-tokens-macos": "npm:^0.53.0" "@fluentui-react-native/eslint-config-rules": "workspace:*" "@fluentui-react-native/experimental-appearance-additions": "workspace:*" + "@fluentui-react-native/immutable-merge": "workspace:*" "@fluentui-react-native/memo-cache": "workspace:*" "@fluentui-react-native/scripts": "workspace:*" "@fluentui-react-native/theme": "workspace:*" @@ -3027,6 +3029,7 @@ __metadata: resolution: "@fluentui-react-native/default-theme@workspace:packages/theming/default-theme" dependencies: "@fluentui-react-native/eslint-config-rules": "workspace:*" + "@fluentui-react-native/immutable-merge": "workspace:*" "@fluentui-react-native/memo-cache": "workspace:*" "@fluentui-react-native/scripts": "workspace:*" "@fluentui-react-native/theme": "workspace:*" @@ -4950,15 +4953,18 @@ __metadata: version: 0.0.0-use.local resolution: "@fluentui-react-native/win32-theme@workspace:packages/theming/win32-theme" dependencies: + "@fluentui-react-native/button": "workspace:*" "@fluentui-react-native/default-theme": "workspace:*" "@fluentui-react-native/design-tokens-win32": "npm:^0.53.0" "@fluentui-react-native/eslint-config-rules": "workspace:*" + "@fluentui-react-native/immutable-merge": "workspace:*" "@fluentui-react-native/memo-cache": "workspace:*" "@fluentui-react-native/scripts": "workspace:*" "@fluentui-react-native/theme": "workspace:*" "@fluentui-react-native/theme-tokens": "workspace:*" "@fluentui-react-native/theme-types": "workspace:*" "@fluentui-react-native/theming-utils": "workspace:*" + "@fluentui-react-native/use-styling": "workspace:*" "@office-iss/react-native-win32": "npm:^0.73.0" "@react-native/babel-preset": "npm:^0.73.0" "@react-native/metro-config": "npm:^0.73.0" From 9deac2d675a7d3510aee37afa3088179ca8a993d Mon Sep 17 00:00:00 2001 From: Andrew Coates <30809111+acoates-ms@users.noreply.github.com> Date: Fri, 17 May 2024 09:20:11 -0700 Subject: [PATCH 2/4] Change files --- ...android-theme-03453f4a-1c9c-4c5e-89bb-55fd61335f12.json | 7 +++++++ ...e-apple-theme-cff4f801-872c-4c62-928d-4d612fcfa8ca.json | 7 +++++++ ...native-button-ea7f7a18-e30a-44e1-acfc-119e1cbf4cc2.json | 7 +++++++ ...default-theme-7bbf18ff-9471-4960-9f7d-f10ac98fc092.json | 7 +++++++ ...-theme-tokens-f2d0f959-a06a-406c-93ee-f6936d7cfc9b.json | 7 +++++++ ...e-win32-theme-3c9bf79a-4eba-490d-b712-352ccc9888c0.json | 7 +++++++ 6 files changed, 42 insertions(+) create mode 100644 change/@fluentui-react-native-android-theme-03453f4a-1c9c-4c5e-89bb-55fd61335f12.json create mode 100644 change/@fluentui-react-native-apple-theme-cff4f801-872c-4c62-928d-4d612fcfa8ca.json create mode 100644 change/@fluentui-react-native-button-ea7f7a18-e30a-44e1-acfc-119e1cbf4cc2.json create mode 100644 change/@fluentui-react-native-default-theme-7bbf18ff-9471-4960-9f7d-f10ac98fc092.json create mode 100644 change/@fluentui-react-native-theme-tokens-f2d0f959-a06a-406c-93ee-f6936d7cfc9b.json create mode 100644 change/@fluentui-react-native-win32-theme-3c9bf79a-4eba-490d-b712-352ccc9888c0.json diff --git a/change/@fluentui-react-native-android-theme-03453f4a-1c9c-4c5e-89bb-55fd61335f12.json b/change/@fluentui-react-native-android-theme-03453f4a-1c9c-4c5e-89bb-55fd61335f12.json new file mode 100644 index 0000000000..c1a15f45bd --- /dev/null +++ b/change/@fluentui-react-native-android-theme-03453f4a-1c9c-4c5e-89bb-55fd61335f12.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Move platform theming logic from button component into theme", + "packageName": "@fluentui-react-native/android-theme", + "email": "30809111+acoates-ms@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-native-apple-theme-cff4f801-872c-4c62-928d-4d612fcfa8ca.json b/change/@fluentui-react-native-apple-theme-cff4f801-872c-4c62-928d-4d612fcfa8ca.json new file mode 100644 index 0000000000..7b3eb41006 --- /dev/null +++ b/change/@fluentui-react-native-apple-theme-cff4f801-872c-4c62-928d-4d612fcfa8ca.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Move platform theming logic from button component into theme", + "packageName": "@fluentui-react-native/apple-theme", + "email": "30809111+acoates-ms@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-native-button-ea7f7a18-e30a-44e1-acfc-119e1cbf4cc2.json b/change/@fluentui-react-native-button-ea7f7a18-e30a-44e1-acfc-119e1cbf4cc2.json new file mode 100644 index 0000000000..fbbc5a445e --- /dev/null +++ b/change/@fluentui-react-native-button-ea7f7a18-e30a-44e1-acfc-119e1cbf4cc2.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Move platform theming logic from button component into theme", + "packageName": "@fluentui-react-native/button", + "email": "30809111+acoates-ms@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-native-default-theme-7bbf18ff-9471-4960-9f7d-f10ac98fc092.json b/change/@fluentui-react-native-default-theme-7bbf18ff-9471-4960-9f7d-f10ac98fc092.json new file mode 100644 index 0000000000..ce56f13b6a --- /dev/null +++ b/change/@fluentui-react-native-default-theme-7bbf18ff-9471-4960-9f7d-f10ac98fc092.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Move platform theming logic from button component into theme", + "packageName": "@fluentui-react-native/default-theme", + "email": "30809111+acoates-ms@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-native-theme-tokens-f2d0f959-a06a-406c-93ee-f6936d7cfc9b.json b/change/@fluentui-react-native-theme-tokens-f2d0f959-a06a-406c-93ee-f6936d7cfc9b.json new file mode 100644 index 0000000000..47b59d6ad3 --- /dev/null +++ b/change/@fluentui-react-native-theme-tokens-f2d0f959-a06a-406c-93ee-f6936d7cfc9b.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Move platform theming logic from button component into theme", + "packageName": "@fluentui-react-native/theme-tokens", + "email": "30809111+acoates-ms@users.noreply.github.com", + "dependentChangeType": "patch" +} diff --git a/change/@fluentui-react-native-win32-theme-3c9bf79a-4eba-490d-b712-352ccc9888c0.json b/change/@fluentui-react-native-win32-theme-3c9bf79a-4eba-490d-b712-352ccc9888c0.json new file mode 100644 index 0000000000..b531bd135e --- /dev/null +++ b/change/@fluentui-react-native-win32-theme-3c9bf79a-4eba-490d-b712-352ccc9888c0.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Move platform theming logic from button component into theme", + "packageName": "@fluentui-react-native/win32-theme", + "email": "30809111+acoates-ms@users.noreply.github.com", + "dependentChangeType": "patch" +} From d88690f7c7a1ce5720b7cf86f1003e4303b21eab Mon Sep 17 00:00:00 2001 From: Andrew Coates <30809111+acoates-ms@users.noreply.github.com> Date: Mon, 3 Jun 2024 14:32:53 -0700 Subject: [PATCH 3/4] fix --- packages/theming/android-theme/package.json | 1 + .../components/Button/ButtonColorTokens.ts | 2 +- .../src/components/Button/ButtonFontTokens.ts | 2 +- .../src/components/Button/ButtonTheme.ts | 5 ++- .../src/components/Button/ButtonTokens.ts | 2 +- .../src/components/Button/FABColorTokens.ts | 2 +- .../src/components/Button/FABTokens.ts | 2 +- .../Button/ToggleButtonColorTokens.ts | 2 +- packages/theming/apple-theme/package.json | 1 + .../src/__tests__/apple-theme.test.ts | 4 +-- .../Button/ButtonColorTokens.macos.ts | 2 +- .../components/Button/ButtonColorTokens.ts | 2 +- .../components/Button/ButtonFontTokens.ios.ts | 2 +- .../Button/ButtonFontTokens.macos.ts | 2 +- .../src/components/Button/ButtonFontTokens.ts | 2 +- .../src/components/Button/ButtonTheme.ios.ts | 36 +++++++++++++++++++ .../src/components/Button/ButtonTheme.ts | 6 +--- .../src/components/Button/ButtonTokens.ios.ts | 4 +-- .../src/components/Button/ButtonTokens.ts | 2 +- .../Button/CompoundButtonColorTokens.ts | 2 +- .../Button/CompoundButtonFontTokens.ts | 2 +- .../components/Button/CompoundButtonTokens.ts | 2 +- ...ABColorTokens.ts => FABColorTokens.ios.ts} | 2 +- .../Button/{FABTokens.ts => FABTokens.ios.ts} | 4 +-- .../Button/ToggleButtonColorTokens.ts | 2 +- .../src/__tests__/default-theme.test.ts | 30 ---------------- .../components/Button/ButtonColorTokens.ts | 2 +- .../Button/ButtonColorTokens.windows.ts | 2 +- .../src/components/Button/ButtonFontTokens.ts | 2 +- .../src/components/Button/ButtonTheme.ts | 2 +- .../src/components/Button/ButtonTokens.ts | 2 +- .../Button/CompoundButtonColorTokens.ts | 2 +- .../CompoundButtonColorTokens.windows.ts | 2 +- .../Button/CompoundButtonFontTokens.ts | 2 +- .../components/Button/CompoundButtonTokens.ts | 2 +- .../Button/ToggleButtonColorTokens.ts | 2 +- .../Button/ToggleButtonColorTokens.windows.ts | 2 +- .../components/Button/ButtonColorTokens.ts | 2 +- .../src/components/Button/ButtonFontTokens.ts | 2 +- .../src/components/Button/ButtonTheme.ts | 2 +- .../src/components/Button/ButtonTokens.ts | 2 +- .../Button/CompoundButtonColorTokens.ts | 2 +- .../Button/CompoundButtonFontTokens.ts | 2 +- .../components/Button/CompoundButtonTokens.ts | 2 +- .../Button/ToggleButtonColorTokens.ts | 2 +- yarn.lock | 2 ++ 46 files changed, 87 insertions(+), 78 deletions(-) create mode 100644 packages/theming/apple-theme/src/components/Button/ButtonTheme.ios.ts rename packages/theming/apple-theme/src/components/Button/{FABColorTokens.ts => FABColorTokens.ios.ts} (96%) rename packages/theming/apple-theme/src/components/Button/{FABTokens.ts => FABTokens.ios.ts} (93%) diff --git a/packages/theming/android-theme/package.json b/packages/theming/android-theme/package.json index 9cfa8580f7..822876bccc 100644 --- a/packages/theming/android-theme/package.json +++ b/packages/theming/android-theme/package.json @@ -39,6 +39,7 @@ "@fluentui-react-native/theming-utils": "workspace:*" }, "devDependencies": { + "@fluentui-react-native/button": "workspace:*", "@fluentui-react-native/eslint-config-rules": "workspace:*", "@fluentui-react-native/scripts": "workspace:*", "@react-native/babel-preset": "^0.73.0", diff --git a/packages/theming/android-theme/src/components/Button/ButtonColorTokens.ts b/packages/theming/android-theme/src/components/Button/ButtonColorTokens.ts index b84daeb177..cf51494b2a 100644 --- a/packages/theming/android-theme/src/components/Button/ButtonColorTokens.ts +++ b/packages/theming/android-theme/src/components/Button/ButtonColorTokens.ts @@ -1,4 +1,4 @@ -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultButtonColorTokens = (t: Theme) => ({ diff --git a/packages/theming/android-theme/src/components/Button/ButtonFontTokens.ts b/packages/theming/android-theme/src/components/Button/ButtonFontTokens.ts index e4433a54e8..c58292e3ac 100644 --- a/packages/theming/android-theme/src/components/Button/ButtonFontTokens.ts +++ b/packages/theming/android-theme/src/components/Button/ButtonFontTokens.ts @@ -1,4 +1,4 @@ -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultButtonFontTokens = (t: Theme) => diff --git a/packages/theming/android-theme/src/components/Button/ButtonTheme.ts b/packages/theming/android-theme/src/components/Button/ButtonTheme.ts index 91298cbc82..1eb30016e3 100644 --- a/packages/theming/android-theme/src/components/Button/ButtonTheme.ts +++ b/packages/theming/android-theme/src/components/Button/ButtonTheme.ts @@ -1,16 +1,19 @@ -import type { Theme } from '@fluentui-react-native/framework'; import { immutableMerge } from '@fluentui-react-native/immutable-merge'; +import type { Theme } from '@fluentui-react-native/theme-types'; import { defaultButtonColorTokens } from './ButtonColorTokens'; import { defaultButtonFontTokens } from './ButtonFontTokens'; import { defaultButtonTokens } from './ButtonTokens'; +import { defaultFABColorTokens } from './FABColorTokens'; +import { defaultFABTokens } from './FABTokens'; import { defaultToggleButtonColorTokens } from './ToggleButtonColorTokens'; export const defaultButtonTheme = (theme: Theme) => ({ components: { Button: immutableMerge(defaultButtonColorTokens(theme), defaultButtonFontTokens(theme), defaultButtonTokens(theme)), + FAB: immutableMerge(defaultFABTokens(theme), defaultFABColorTokens(theme)), ToggleButton: immutableMerge( defaultButtonTokens(theme), diff --git a/packages/theming/android-theme/src/components/Button/ButtonTokens.ts b/packages/theming/android-theme/src/components/Button/ButtonTokens.ts index 3660988b6c..98898ac5c3 100644 --- a/packages/theming/android-theme/src/components/Button/ButtonTokens.ts +++ b/packages/theming/android-theme/src/components/Button/ButtonTokens.ts @@ -1,7 +1,7 @@ import type { DimensionValue } from 'react-native'; -import type { Theme } from '@fluentui-react-native/framework'; import { globalTokensAndroid as globalTokens } from '@fluentui-react-native/theme-tokens'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultButtonTokens = (_t: Theme) => ({ diff --git a/packages/theming/android-theme/src/components/Button/FABColorTokens.ts b/packages/theming/android-theme/src/components/Button/FABColorTokens.ts index 283de99805..c0c232fec6 100644 --- a/packages/theming/android-theme/src/components/Button/FABColorTokens.ts +++ b/packages/theming/android-theme/src/components/Button/FABColorTokens.ts @@ -1,4 +1,4 @@ -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultFABColorTokens = (t: Theme) => ({ // Default coloring same as 'primary' or 'accent' diff --git a/packages/theming/android-theme/src/components/Button/FABTokens.ts b/packages/theming/android-theme/src/components/Button/FABTokens.ts index a2e44f6b97..c3bce375a4 100644 --- a/packages/theming/android-theme/src/components/Button/FABTokens.ts +++ b/packages/theming/android-theme/src/components/Button/FABTokens.ts @@ -1,5 +1,5 @@ -import type { Theme } from '@fluentui-react-native/framework'; import {globalTokensAndroid as globalTokens} from '@fluentui-react-native/theme-tokens'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultFABTokens = (t: Theme) => ({ diff --git a/packages/theming/android-theme/src/components/Button/ToggleButtonColorTokens.ts b/packages/theming/android-theme/src/components/Button/ToggleButtonColorTokens.ts index 67585c56ba..8822ac0a4c 100644 --- a/packages/theming/android-theme/src/components/Button/ToggleButtonColorTokens.ts +++ b/packages/theming/android-theme/src/components/Button/ToggleButtonColorTokens.ts @@ -1,4 +1,4 @@ -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultToggleButtonColorTokens = (t: Theme) => ({ checked: { diff --git a/packages/theming/apple-theme/package.json b/packages/theming/apple-theme/package.json index 6f2eb95a20..01090fc2a4 100644 --- a/packages/theming/apple-theme/package.json +++ b/packages/theming/apple-theme/package.json @@ -44,6 +44,7 @@ "assert-never": "^1.2.1" }, "devDependencies": { + "@fluentui-react-native/button": "workspace:*", "@fluentui-react-native/eslint-config-rules": "workspace:*", "@fluentui-react-native/scripts": "workspace:*", "@react-native/babel-preset": "^0.73.0", diff --git a/packages/theming/apple-theme/src/__tests__/apple-theme.test.ts b/packages/theming/apple-theme/src/__tests__/apple-theme.test.ts index 1ec6df78f3..985e4bcdac 100644 --- a/packages/theming/apple-theme/src/__tests__/apple-theme.test.ts +++ b/packages/theming/apple-theme/src/__tests__/apple-theme.test.ts @@ -4,9 +4,9 @@ import type { AppearanceOptions } from '@fluentui-react-native/theme-types'; import { getIsHighContrast, setIsHighContrast } from '../appleHighContrast.macos'; import { defaultButtonColorTokens } from '../components/Button/ButtonColorTokens'; import { defaultButtonFontTokens } from '../components/Button/ButtonFontTokens'; -import { defaultFABColorTokens } from '../components/Button/FABColorTokens'; -import { defaultFABTokens } from '../components/Button/FABTokens'; import { defaultButtonTokens } from '../components/Button/ButtonTokens'; +import { defaultFABColorTokens } from '../components/Button/FABColorTokens.ios'; +import { defaultFABTokens } from '../components/Button/FABTokens.ios'; import { createAppleTheme } from '../createAppleTheme'; import { createMacOSColorAliasTokens, createMacOSShadowAliasTokens } from '../createMacOSAliasTokens'; diff --git a/packages/theming/apple-theme/src/components/Button/ButtonColorTokens.macos.ts b/packages/theming/apple-theme/src/components/Button/ButtonColorTokens.macos.ts index 64617b135f..9ce1eda30d 100644 --- a/packages/theming/apple-theme/src/components/Button/ButtonColorTokens.macos.ts +++ b/packages/theming/apple-theme/src/components/Button/ButtonColorTokens.macos.ts @@ -1,4 +1,4 @@ -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultButtonColorTokens = (t: Theme) => ({ diff --git a/packages/theming/apple-theme/src/components/Button/ButtonColorTokens.ts b/packages/theming/apple-theme/src/components/Button/ButtonColorTokens.ts index 6049f66652..c7afdd51f8 100644 --- a/packages/theming/apple-theme/src/components/Button/ButtonColorTokens.ts +++ b/packages/theming/apple-theme/src/components/Button/ButtonColorTokens.ts @@ -1,4 +1,4 @@ -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultButtonColorTokens = (_t: Theme) => ({ diff --git a/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ios.ts b/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ios.ts index 6fee75013b..b96a2c2a89 100644 --- a/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ios.ts +++ b/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ios.ts @@ -1,4 +1,4 @@ -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultButtonFontTokens = (t: Theme) => ({ diff --git a/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.macos.ts b/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.macos.ts index 404bca85c3..9aca1cda46 100644 --- a/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.macos.ts +++ b/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.macos.ts @@ -1,4 +1,4 @@ -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultButtonFontTokens = (_t: Theme) => ({ diff --git a/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ts b/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ts index be43d8df5d..933f7a2b54 100644 --- a/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ts +++ b/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ts @@ -1,4 +1,4 @@ -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultButtonFontTokens = (_t: Theme) => ({ diff --git a/packages/theming/apple-theme/src/components/Button/ButtonTheme.ios.ts b/packages/theming/apple-theme/src/components/Button/ButtonTheme.ios.ts new file mode 100644 index 0000000000..189621ff1e --- /dev/null +++ b/packages/theming/apple-theme/src/components/Button/ButtonTheme.ios.ts @@ -0,0 +1,36 @@ + +import { immutableMerge } from '@fluentui-react-native/immutable-merge'; +import type { Theme } from '@fluentui-react-native/theme-types'; + +import { defaultButtonColorTokens } from './ButtonColorTokens'; +import { defaultButtonFontTokens } from './ButtonFontTokens'; +import { defaultButtonTokens } from './ButtonTokens'; +import { defaultCompoundButtonColorTokens } from './CompoundButtonColorTokens'; +import { defaultCompoundButtonFontTokens } from './CompoundButtonFontTokens'; +import { defaultCompoundButtonTokens } from './CompoundButtonTokens'; +import { defaultFABColorTokens } from './FABColorTokens.ios'; +import { defaultFABTokens } from './FABTokens.ios'; +import { defaultToggleButtonColorTokens } from './ToggleButtonColorTokens'; + +export const defaultButtonTheme = (theme: Theme) => +({ + components: { + Button: immutableMerge(defaultButtonColorTokens(theme), defaultButtonFontTokens(theme), defaultButtonTokens(theme)), + CompoundButton: + immutableMerge( + defaultButtonTokens(theme), + defaultButtonColorTokens(theme), + defaultCompoundButtonColorTokens(theme), + defaultCompoundButtonFontTokens(theme), + defaultCompoundButtonTokens(theme)), + + FAB: immutableMerge(defaultFABTokens(theme), defaultFABColorTokens(theme)), + + ToggleButton: + immutableMerge( + defaultButtonTokens(theme), + defaultButtonFontTokens(theme), + defaultButtonColorTokens(theme), + defaultToggleButtonColorTokens(theme)), + } +}); diff --git a/packages/theming/apple-theme/src/components/Button/ButtonTheme.ts b/packages/theming/apple-theme/src/components/Button/ButtonTheme.ts index b8cfc3487d..1aa2d19253 100644 --- a/packages/theming/apple-theme/src/components/Button/ButtonTheme.ts +++ b/packages/theming/apple-theme/src/components/Button/ButtonTheme.ts @@ -1,6 +1,6 @@ -import type { Theme } from '@fluentui-react-native/framework'; import { immutableMerge } from '@fluentui-react-native/immutable-merge'; +import type { Theme } from '@fluentui-react-native/theme-types'; import { defaultButtonColorTokens } from './ButtonColorTokens'; import { defaultButtonFontTokens } from './ButtonFontTokens'; @@ -8,8 +8,6 @@ import { defaultButtonTokens } from './ButtonTokens'; import { defaultCompoundButtonColorTokens } from './CompoundButtonColorTokens'; import { defaultCompoundButtonFontTokens } from './CompoundButtonFontTokens'; import { defaultCompoundButtonTokens } from './CompoundButtonTokens'; -import { defaultFABColorTokens } from './FABColorTokens'; -import { defaultFABTokens } from './FABTokens'; import { defaultToggleButtonColorTokens } from './ToggleButtonColorTokens'; export const defaultButtonTheme = (theme: Theme) => @@ -24,8 +22,6 @@ export const defaultButtonTheme = (theme: Theme) => defaultCompoundButtonFontTokens(theme), defaultCompoundButtonTokens(theme)), - FAB: immutableMerge(defaultFABTokens(theme), defaultFABColorTokens(theme)), - ToggleButton: immutableMerge( defaultButtonTokens(theme), diff --git a/packages/theming/apple-theme/src/components/Button/ButtonTokens.ios.ts b/packages/theming/apple-theme/src/components/Button/ButtonTokens.ios.ts index af370fea47..2200d11757 100644 --- a/packages/theming/apple-theme/src/components/Button/ButtonTokens.ios.ts +++ b/packages/theming/apple-theme/src/components/Button/ButtonTokens.ios.ts @@ -1,7 +1,7 @@ import type { DimensionValue } from 'react-native'; -import type { Theme } from '@fluentui-react-native/framework'; -import {default as globalTokens} from '@fluentui-react-native/theme-tokens/lib/tokens-global.ios'; +import {globalTokensIOS as globalTokens} from '@fluentui-react-native/theme-tokens'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultButtonTokens = (_t: Theme) => ({ diff --git a/packages/theming/apple-theme/src/components/Button/ButtonTokens.ts b/packages/theming/apple-theme/src/components/Button/ButtonTokens.ts index fa6a4d72f2..9dd0a2c341 100644 --- a/packages/theming/apple-theme/src/components/Button/ButtonTokens.ts +++ b/packages/theming/apple-theme/src/components/Button/ButtonTokens.ts @@ -1,7 +1,7 @@ import type { DimensionValue } from 'react-native'; -import type { Theme } from '@fluentui-react-native/framework'; import { globalTokens } from '@fluentui-react-native/theme-tokens'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultButtonTokens = (_t: Theme) => ({ diff --git a/packages/theming/apple-theme/src/components/Button/CompoundButtonColorTokens.ts b/packages/theming/apple-theme/src/components/Button/CompoundButtonColorTokens.ts index 1298af4e4a..c87c62bc25 100644 --- a/packages/theming/apple-theme/src/components/Button/CompoundButtonColorTokens.ts +++ b/packages/theming/apple-theme/src/components/Button/CompoundButtonColorTokens.ts @@ -1,4 +1,4 @@ -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultCompoundButtonColorTokens = (t: Theme) => ({ secondaryContentColor: t.colors.defaultSecondaryContent, diff --git a/packages/theming/apple-theme/src/components/Button/CompoundButtonFontTokens.ts b/packages/theming/apple-theme/src/components/Button/CompoundButtonFontTokens.ts index 1adab9492b..f824ac4879 100644 --- a/packages/theming/apple-theme/src/components/Button/CompoundButtonFontTokens.ts +++ b/packages/theming/apple-theme/src/components/Button/CompoundButtonFontTokens.ts @@ -1,4 +1,4 @@ -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultCompoundButtonFontTokens = (_t: Theme) => ({ medium: { diff --git a/packages/theming/apple-theme/src/components/Button/CompoundButtonTokens.ts b/packages/theming/apple-theme/src/components/Button/CompoundButtonTokens.ts index 68f2669a46..04400e847d 100644 --- a/packages/theming/apple-theme/src/components/Button/CompoundButtonTokens.ts +++ b/packages/theming/apple-theme/src/components/Button/CompoundButtonTokens.ts @@ -1,5 +1,5 @@ -import type { Theme } from '@fluentui-react-native/framework'; import { globalTokens } from '@fluentui-react-native/theme-tokens'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultCompoundButtonTokens = (_t: Theme) => ({ medium: { diff --git a/packages/theming/apple-theme/src/components/Button/FABColorTokens.ts b/packages/theming/apple-theme/src/components/Button/FABColorTokens.ios.ts similarity index 96% rename from packages/theming/apple-theme/src/components/Button/FABColorTokens.ts rename to packages/theming/apple-theme/src/components/Button/FABColorTokens.ios.ts index 4ac6a0c0dc..bf320a50b1 100644 --- a/packages/theming/apple-theme/src/components/Button/FABColorTokens.ts +++ b/packages/theming/apple-theme/src/components/Button/FABColorTokens.ios.ts @@ -1,4 +1,4 @@ -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultFABColorTokens = (t: Theme) => ({ // Default coloring same as 'primary' or 'accent' diff --git a/packages/theming/apple-theme/src/components/Button/FABTokens.ts b/packages/theming/apple-theme/src/components/Button/FABTokens.ios.ts similarity index 93% rename from packages/theming/apple-theme/src/components/Button/FABTokens.ts rename to packages/theming/apple-theme/src/components/Button/FABTokens.ios.ts index 2fd866693e..b437990587 100644 --- a/packages/theming/apple-theme/src/components/Button/FABTokens.ts +++ b/packages/theming/apple-theme/src/components/Button/FABTokens.ios.ts @@ -1,5 +1,5 @@ -import type { Theme } from '@fluentui-react-native/framework'; -import {default as globalTokens} from '@fluentui-react-native/theme-tokens/lib/tokens-global.ios'; +import {globalTokensIOS as globalTokens} from '@fluentui-react-native/theme-tokens'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultFABTokens = (t: Theme) => ({ diff --git a/packages/theming/apple-theme/src/components/Button/ToggleButtonColorTokens.ts b/packages/theming/apple-theme/src/components/Button/ToggleButtonColorTokens.ts index 67585c56ba..8822ac0a4c 100644 --- a/packages/theming/apple-theme/src/components/Button/ToggleButtonColorTokens.ts +++ b/packages/theming/apple-theme/src/components/Button/ToggleButtonColorTokens.ts @@ -1,4 +1,4 @@ -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultToggleButtonColorTokens = (t: Theme) => ({ checked: { diff --git a/packages/theming/default-theme/src/__tests__/default-theme.test.ts b/packages/theming/default-theme/src/__tests__/default-theme.test.ts index cdce962e4c..db7d38b4e5 100644 --- a/packages/theming/default-theme/src/__tests__/default-theme.test.ts +++ b/packages/theming/default-theme/src/__tests__/default-theme.test.ts @@ -1,13 +1,5 @@ -import type { ButtonTokens, CompoundButtonTokens } from '@fluentui-react-native/button'; import type { ThemeOptions, AppearanceOptions } from '@fluentui-react-native/theme-types'; -import { defaultButtonColorTokens } from '../components/Button/ButtonColorTokens'; -import { defaultButtonFontTokens } from '../components/Button/ButtonFontTokens'; -import { defaultButtonTokens } from '../components/Button/ButtonTokens'; -import { defaultCompoundButtonColorTokens } from '../components/Button/CompoundButtonColorTokens'; -import { defaultCompoundButtonFontTokens } from '../components/Button/CompoundButtonFontTokens'; -import { defaultCompoundButtonTokens } from '../components/Button/CompoundButtonTokens'; - import { createColorAliasTokens, createShadowAliasTokens } from '../createAliasTokens'; import { createDefaultTheme } from '../createDefaultTheme'; import { defaultFluentTheme, defaultFluentDarkTheme } from '../defaultTheme'; @@ -55,25 +47,3 @@ describe('createShadowAliasTokens test', () => { expect(createShadowAliasTokens(appearanceOption)).toMatchSnapshot(); }); }); - -describe('verify types', () => { - it('Button types', () => { - const defaultTheme = createDefaultTheme().theme; - const colorTokens: ButtonTokens = defaultButtonColorTokens(defaultTheme); - expect(colorTokens).toBeTruthy(); - const fontTokens: ButtonTokens = defaultButtonFontTokens(defaultTheme); - expect(fontTokens).toBeTruthy(); - const tokens: ButtonTokens = defaultButtonTokens(defaultTheme); - expect(tokens).toBeTruthy(); - }); - - it('CompoundButton types', () => { - const defaultTheme = createDefaultTheme().theme; - const compoundColorTokens: CompoundButtonTokens = defaultCompoundButtonColorTokens(defaultTheme); - expect(compoundColorTokens).toBeTruthy(); - const compoundButtonFontTokens: CompoundButtonTokens = defaultCompoundButtonFontTokens(defaultTheme); - expect(compoundButtonFontTokens).toBeTruthy(); - const compoundButtonTokens: CompoundButtonTokens = defaultCompoundButtonTokens(defaultTheme); - expect(compoundButtonTokens).toBeTruthy(); - }); -}) \ No newline at end of file diff --git a/packages/theming/default-theme/src/components/Button/ButtonColorTokens.ts b/packages/theming/default-theme/src/components/Button/ButtonColorTokens.ts index 943b01275b..946eb052cc 100644 --- a/packages/theming/default-theme/src/components/Button/ButtonColorTokens.ts +++ b/packages/theming/default-theme/src/components/Button/ButtonColorTokens.ts @@ -1,4 +1,4 @@ -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultButtonColorTokens = (t: Theme) => ({ diff --git a/packages/theming/default-theme/src/components/Button/ButtonColorTokens.windows.ts b/packages/theming/default-theme/src/components/Button/ButtonColorTokens.windows.ts index 2d7579726a..08a2e8c5ad 100644 --- a/packages/theming/default-theme/src/components/Button/ButtonColorTokens.windows.ts +++ b/packages/theming/default-theme/src/components/Button/ButtonColorTokens.windows.ts @@ -1,6 +1,6 @@ import { PlatformColor } from 'react-native'; -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; import { isHighContrast } from '@fluentui-react-native/theming-utils'; export const defaultButtonColorTokens = (t: Theme) => { diff --git a/packages/theming/default-theme/src/components/Button/ButtonFontTokens.ts b/packages/theming/default-theme/src/components/Button/ButtonFontTokens.ts index 4315589584..d035e3ed68 100644 --- a/packages/theming/default-theme/src/components/Button/ButtonFontTokens.ts +++ b/packages/theming/default-theme/src/components/Button/ButtonFontTokens.ts @@ -1,4 +1,4 @@ -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; type fontVariantType = 'secondaryStandard' | 'bodyStandard'; diff --git a/packages/theming/default-theme/src/components/Button/ButtonTheme.ts b/packages/theming/default-theme/src/components/Button/ButtonTheme.ts index 34a8c5e669..917cffa828 100644 --- a/packages/theming/default-theme/src/components/Button/ButtonTheme.ts +++ b/packages/theming/default-theme/src/components/Button/ButtonTheme.ts @@ -1,6 +1,6 @@ -import type { Theme } from '@fluentui-react-native/framework'; import { immutableMerge } from '@fluentui-react-native/immutable-merge'; +import type { Theme } from '@fluentui-react-native/theme-types'; import { defaultButtonColorTokens } from './ButtonColorTokens'; import { defaultButtonFontTokens } from './ButtonFontTokens'; diff --git a/packages/theming/default-theme/src/components/Button/ButtonTokens.ts b/packages/theming/default-theme/src/components/Button/ButtonTokens.ts index c5ae64a0dc..5146018c03 100644 --- a/packages/theming/default-theme/src/components/Button/ButtonTokens.ts +++ b/packages/theming/default-theme/src/components/Button/ButtonTokens.ts @@ -1,7 +1,7 @@ import type { DimensionValue } from 'react-native'; -import type { Theme } from '@fluentui-react-native/framework'; import { globalTokens } from '@fluentui-react-native/theme-tokens'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultButtonTokens = (_t: Theme) => ({ diff --git a/packages/theming/default-theme/src/components/Button/CompoundButtonColorTokens.ts b/packages/theming/default-theme/src/components/Button/CompoundButtonColorTokens.ts index 1298af4e4a..c87c62bc25 100644 --- a/packages/theming/default-theme/src/components/Button/CompoundButtonColorTokens.ts +++ b/packages/theming/default-theme/src/components/Button/CompoundButtonColorTokens.ts @@ -1,4 +1,4 @@ -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultCompoundButtonColorTokens = (t: Theme) => ({ secondaryContentColor: t.colors.defaultSecondaryContent, diff --git a/packages/theming/default-theme/src/components/Button/CompoundButtonColorTokens.windows.ts b/packages/theming/default-theme/src/components/Button/CompoundButtonColorTokens.windows.ts index 128ddcbff5..c502a8474b 100644 --- a/packages/theming/default-theme/src/components/Button/CompoundButtonColorTokens.windows.ts +++ b/packages/theming/default-theme/src/components/Button/CompoundButtonColorTokens.windows.ts @@ -1,6 +1,6 @@ import { PlatformColor } from 'react-native'; -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; import { isHighContrast } from '@fluentui-react-native/theming-utils'; export const defaultCompoundButtonColorTokens = (t: Theme) => { diff --git a/packages/theming/default-theme/src/components/Button/CompoundButtonFontTokens.ts b/packages/theming/default-theme/src/components/Button/CompoundButtonFontTokens.ts index fe22f2657e..eeacb7e2d1 100644 --- a/packages/theming/default-theme/src/components/Button/CompoundButtonFontTokens.ts +++ b/packages/theming/default-theme/src/components/Button/CompoundButtonFontTokens.ts @@ -1,4 +1,4 @@ -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; type fontVariantType = 'secondaryStandard' | 'bodyStandard'; diff --git a/packages/theming/default-theme/src/components/Button/CompoundButtonTokens.ts b/packages/theming/default-theme/src/components/Button/CompoundButtonTokens.ts index 68f2669a46..04400e847d 100644 --- a/packages/theming/default-theme/src/components/Button/CompoundButtonTokens.ts +++ b/packages/theming/default-theme/src/components/Button/CompoundButtonTokens.ts @@ -1,5 +1,5 @@ -import type { Theme } from '@fluentui-react-native/framework'; import { globalTokens } from '@fluentui-react-native/theme-tokens'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultCompoundButtonTokens = (_t: Theme) => ({ medium: { diff --git a/packages/theming/default-theme/src/components/Button/ToggleButtonColorTokens.ts b/packages/theming/default-theme/src/components/Button/ToggleButtonColorTokens.ts index 67585c56ba..8822ac0a4c 100644 --- a/packages/theming/default-theme/src/components/Button/ToggleButtonColorTokens.ts +++ b/packages/theming/default-theme/src/components/Button/ToggleButtonColorTokens.ts @@ -1,4 +1,4 @@ -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; export const defaultToggleButtonColorTokens = (t: Theme) => ({ checked: { diff --git a/packages/theming/default-theme/src/components/Button/ToggleButtonColorTokens.windows.ts b/packages/theming/default-theme/src/components/Button/ToggleButtonColorTokens.windows.ts index bb6940f9e5..37d2996d02 100644 --- a/packages/theming/default-theme/src/components/Button/ToggleButtonColorTokens.windows.ts +++ b/packages/theming/default-theme/src/components/Button/ToggleButtonColorTokens.windows.ts @@ -1,6 +1,6 @@ import { PlatformColor } from 'react-native'; -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; import { isHighContrast } from '@fluentui-react-native/theming-utils'; export const defaultToggleButtonColorTokens = (t: Theme) => { diff --git a/packages/theming/win32-theme/src/components/Button/ButtonColorTokens.ts b/packages/theming/win32-theme/src/components/Button/ButtonColorTokens.ts index 0e85f40b2f..9df2cfda7e 100644 --- a/packages/theming/win32-theme/src/components/Button/ButtonColorTokens.ts +++ b/packages/theming/win32-theme/src/components/Button/ButtonColorTokens.ts @@ -1,6 +1,6 @@ import { PlatformColor } from 'react-native'; -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; import { isHighContrast } from '@fluentui-react-native/theming-utils'; export const defaultButtonColorTokens = (t: Theme) => { diff --git a/packages/theming/win32-theme/src/components/Button/ButtonFontTokens.ts b/packages/theming/win32-theme/src/components/Button/ButtonFontTokens.ts index f6432a215b..d8b31cf61a 100644 --- a/packages/theming/win32-theme/src/components/Button/ButtonFontTokens.ts +++ b/packages/theming/win32-theme/src/components/Button/ButtonFontTokens.ts @@ -1,5 +1,5 @@ -import type { Theme } from '@fluentui-react-native/framework'; import { globalTokensWin32 as globalTokens } from '@fluentui-react-native/theme-tokens'; +import type { Theme } from '@fluentui-react-native/theme-types'; import type { FontWeight } from '@fluentui-react-native/theme-types' export const defaultButtonFontTokens = (t: Theme) => diff --git a/packages/theming/win32-theme/src/components/Button/ButtonTheme.ts b/packages/theming/win32-theme/src/components/Button/ButtonTheme.ts index 34a8c5e669..917cffa828 100644 --- a/packages/theming/win32-theme/src/components/Button/ButtonTheme.ts +++ b/packages/theming/win32-theme/src/components/Button/ButtonTheme.ts @@ -1,6 +1,6 @@ -import type { Theme } from '@fluentui-react-native/framework'; import { immutableMerge } from '@fluentui-react-native/immutable-merge'; +import type { Theme } from '@fluentui-react-native/theme-types'; import { defaultButtonColorTokens } from './ButtonColorTokens'; import { defaultButtonFontTokens } from './ButtonFontTokens'; diff --git a/packages/theming/win32-theme/src/components/Button/ButtonTokens.ts b/packages/theming/win32-theme/src/components/Button/ButtonTokens.ts index 80ae6197a0..a21573e502 100644 --- a/packages/theming/win32-theme/src/components/Button/ButtonTokens.ts +++ b/packages/theming/win32-theme/src/components/Button/ButtonTokens.ts @@ -1,7 +1,7 @@ import type { DimensionValue } from 'react-native'; -import type { Theme } from '@fluentui-react-native/framework'; import { globalTokensWin32 as globalTokens } from '@fluentui-react-native/theme-tokens'; +import type { Theme } from '@fluentui-react-native/theme-types'; import { isHighContrast } from '@fluentui-react-native/theming-utils'; type ButtonSize = 'small'; diff --git a/packages/theming/win32-theme/src/components/Button/CompoundButtonColorTokens.ts b/packages/theming/win32-theme/src/components/Button/CompoundButtonColorTokens.ts index 41a15d8769..f4b463e097 100644 --- a/packages/theming/win32-theme/src/components/Button/CompoundButtonColorTokens.ts +++ b/packages/theming/win32-theme/src/components/Button/CompoundButtonColorTokens.ts @@ -1,6 +1,6 @@ import { PlatformColor } from 'react-native'; -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; import { isHighContrast } from '@fluentui-react-native/theming-utils'; export const defaultCompoundButtonColorTokens = (t: Theme) => { diff --git a/packages/theming/win32-theme/src/components/Button/CompoundButtonFontTokens.ts b/packages/theming/win32-theme/src/components/Button/CompoundButtonFontTokens.ts index b28b791fcc..c67b0a28cb 100644 --- a/packages/theming/win32-theme/src/components/Button/CompoundButtonFontTokens.ts +++ b/packages/theming/win32-theme/src/components/Button/CompoundButtonFontTokens.ts @@ -1,5 +1,5 @@ -import type { FontWeightValue, Theme } from '@fluentui-react-native/framework'; import { globalTokensWin32 as globalTokens } from '@fluentui-react-native/theme-tokens'; +import type { FontWeightValue, Theme } from '@fluentui-react-native/theme-types'; export const defaultCompoundButtonFontTokens = (t: Theme) => ({ medium: { diff --git a/packages/theming/win32-theme/src/components/Button/CompoundButtonTokens.ts b/packages/theming/win32-theme/src/components/Button/CompoundButtonTokens.ts index 906b784c70..9d42dbbf59 100644 --- a/packages/theming/win32-theme/src/components/Button/CompoundButtonTokens.ts +++ b/packages/theming/win32-theme/src/components/Button/CompoundButtonTokens.ts @@ -1,5 +1,5 @@ -import type { Theme } from '@fluentui-react-native/framework'; import { globalTokensWin32 as globalTokens } from '@fluentui-react-native/theme-tokens'; +import type { Theme } from '@fluentui-react-native/theme-types'; import { isHighContrast } from '@fluentui-react-native/theming-utils'; export const defaultCompoundButtonTokens = (theme: Theme) => ({ diff --git a/packages/theming/win32-theme/src/components/Button/ToggleButtonColorTokens.ts b/packages/theming/win32-theme/src/components/Button/ToggleButtonColorTokens.ts index 9ea3f17cda..e4ff217377 100644 --- a/packages/theming/win32-theme/src/components/Button/ToggleButtonColorTokens.ts +++ b/packages/theming/win32-theme/src/components/Button/ToggleButtonColorTokens.ts @@ -1,6 +1,6 @@ import { PlatformColor } from 'react-native'; -import type { Theme } from '@fluentui-react-native/framework'; +import type { Theme } from '@fluentui-react-native/theme-types'; import { isHighContrast } from '@fluentui-react-native/theming-utils'; export const defaultToggleButtonColorTokens = (t: Theme) => { diff --git a/yarn.lock b/yarn.lock index c079da9792..abe77ee04c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2641,6 +2641,7 @@ __metadata: version: 0.0.0-use.local resolution: "@fluentui-react-native/android-theme@workspace:packages/theming/android-theme" dependencies: + "@fluentui-react-native/button": "workspace:*" "@fluentui-react-native/eslint-config-rules": "workspace:*" "@fluentui-react-native/immutable-merge": "workspace:*" "@fluentui-react-native/memo-cache": "workspace:*" @@ -2673,6 +2674,7 @@ __metadata: version: 0.0.0-use.local resolution: "@fluentui-react-native/apple-theme@workspace:packages/theming/apple-theme" dependencies: + "@fluentui-react-native/button": "workspace:*" "@fluentui-react-native/default-theme": "workspace:*" "@fluentui-react-native/design-tokens-ios": "npm:^0.53.0" "@fluentui-react-native/design-tokens-macos": "npm:^0.53.0" From 40526c7ade58a9793b1ef194ba2e15f145e5513a Mon Sep 17 00:00:00 2001 From: Andrew Coates <30809111+acoates-ms@users.noreply.github.com> Date: Tue, 4 Jun 2024 08:47:48 -0700 Subject: [PATCH 4/4] prettier --- packages/components/Button/src/Button.tsx | 3 +- .../components/Button/src/Button.types.ts | 4 +- .../CompoundButton/CompoundButton.styling.ts | 4 +- .../src/__tests__/android-theme.test.ts | 2 +- .../components/Button/ButtonColorTokens.ts | 149 ++++++++-------- .../src/components/Button/ButtonFontTokens.ts | 34 ++-- .../src/components/Button/ButtonTheme.ts | 12 +- .../src/components/Button/ButtonTokens.ts | 5 +- .../src/components/Button/FABTokens.ts | 99 ++++++----- .../android-theme/src/createAndroidTheme.ts | 22 +-- .../src/__tests__/apple-theme.test.ts | 2 +- .../Button/ButtonColorTokens.macos.ts | 155 ++++++++--------- .../components/Button/ButtonColorTokens.ts | 4 +- .../components/Button/ButtonFontTokens.ios.ts | 35 ++-- .../Button/ButtonFontTokens.macos.ts | 27 ++- .../src/components/Button/ButtonFontTokens.ts | 4 +- .../src/components/Button/ButtonTheme.ios.ts | 18 +- .../src/components/Button/ButtonTheme.ts | 18 +- .../src/components/Button/ButtonTokens.ios.ts | 122 +++++++------ .../src/components/Button/ButtonTokens.ts | 5 +- .../src/components/Button/FABTokens.ios.ts | 103 ++++++----- .../apple-theme/src/createAppleTheme.ios.ts | 14 +- .../apple-theme/src/createAppleTheme.macos.ts | 16 +- .../components/Button/ButtonColorTokens.ts | 145 ++++++++-------- .../src/components/Button/ButtonFontTokens.ts | 27 ++- .../src/components/Button/ButtonTheme.ts | 33 ++-- .../src/components/Button/ButtonTokens.ts | 164 +++++++++--------- .../default-theme/src/createDefaultTheme.ts | 34 ++-- packages/theming/theme-tokens/src/index.ts | 2 +- .../src/__tests__/win32-theme.test.ts | 2 +- .../src/components/Button/ButtonFontTokens.ts | 5 +- .../src/components/Button/ButtonTheme.ts | 33 ++-- .../src/components/Button/ButtonTokens.ts | 5 +- .../Button/CompoundButtonColorTokens.ts | 2 +- .../win32-theme/src/createOfficeTheme.ts | 2 +- 35 files changed, 642 insertions(+), 669 deletions(-) diff --git a/packages/components/Button/src/Button.tsx b/packages/components/Button/src/Button.tsx index b4560d3127..34efbed4e4 100644 --- a/packages/components/Button/src/Button.tsx +++ b/packages/components/Button/src/Button.tsx @@ -10,7 +10,7 @@ import { useFluentTheme } from '@fluentui-react-native/framework'; import { Icon, createIconProps } from '@fluentui-react-native/icon'; import type { IPressableState } from '@fluentui-react-native/interactive-hooks'; import { TextV1 as Text } from '@fluentui-react-native/text'; -import type {Theme} from '@fluentui-react-native/theme-types'; +import type { Theme } from '@fluentui-react-native/theme-types'; import { stylingSettings } from './Button.styling'; import { buttonName } from './Button.types'; @@ -28,7 +28,6 @@ import { useButton } from './useButton'; * @returns Whether the styles that are assigned to the layer should be applied to the button */ export const buttonLookup = (layer: string, state: IPressableState, userProps: ButtonProps, theme: Theme): boolean => { - const size = userProps['size'] ?? (theme?.components?.['Button'] as ButtonTokens)?.size ?? 'medium'; const getPlatformSpecificAppearance = (theme?.components?.['Button'] as ButtonTokens)?.getPlatformSpecificAppearance; const appearance = getPlatformSpecificAppearance ? getPlatformSpecificAppearance(userProps['appearance']) : null; diff --git a/packages/components/Button/src/Button.types.ts b/packages/components/Button/src/Button.types.ts index ec2aacfb90..7bcb5398a2 100644 --- a/packages/components/Button/src/Button.types.ts +++ b/packages/components/Button/src/Button.types.ts @@ -70,7 +70,7 @@ export interface ButtonCoreTokens extends LayoutTokens, FontTokens, IBorderToken /** * The default size of the button */ - size?: ButtonSize, + size?: ButtonSize; } export interface ButtonTokens extends ButtonCoreTokens { @@ -95,7 +95,7 @@ export interface ButtonTokens extends ButtonCoreTokens { square?: ButtonTokens; hasIconAfter?: ButtonTokens; - /** + /** * Returns the default appearance type, and can remap ButtonAppearances to other Appearances for this theme */ getPlatformSpecificAppearance?: (appearance: ButtonAppearance) => ButtonAppearance; diff --git a/packages/components/Button/src/CompoundButton/CompoundButton.styling.ts b/packages/components/Button/src/CompoundButton/CompoundButton.styling.ts index 88387811f7..45f73566f3 100644 --- a/packages/components/Button/src/CompoundButton/CompoundButton.styling.ts +++ b/packages/components/Button/src/CompoundButton/CompoundButton.styling.ts @@ -7,9 +7,7 @@ import type { CompoundButtonTokens, CompoundButtonSlotProps, CompoundButtonProps import { buttonStates, contentStyling } from '../Button.styling'; export const stylingSettings: UseStylingOptions = { - tokens: [ - compoundButtonName, - ], + tokens: [compoundButtonName], states: buttonStates, slotProps: { root: buildProps( diff --git a/packages/theming/android-theme/src/__tests__/android-theme.test.ts b/packages/theming/android-theme/src/__tests__/android-theme.test.ts index d06b38f70d..efd3025977 100644 --- a/packages/theming/android-theme/src/__tests__/android-theme.test.ts +++ b/packages/theming/android-theme/src/__tests__/android-theme.test.ts @@ -55,4 +55,4 @@ describe('verify types', () => { const fabColorTokens: FABTokens = defaultFABColorTokens(officeTheme); expect(fabColorTokens).toBeTruthy(); }); -}) \ No newline at end of file +}); diff --git a/packages/theming/android-theme/src/components/Button/ButtonColorTokens.ts b/packages/theming/android-theme/src/components/Button/ButtonColorTokens.ts index cf51494b2a..8e737b7689 100644 --- a/packages/theming/android-theme/src/components/Button/ButtonColorTokens.ts +++ b/packages/theming/android-theme/src/components/Button/ButtonColorTokens.ts @@ -1,78 +1,77 @@ import type { Theme } from '@fluentui-react-native/theme-types'; -export const defaultButtonColorTokens = (t: Theme) => -({ - /** Android does not have a different styles for 'default' button. - * 'primary', 'accent' and if no appearance is mentioned, picks this. - */ - backgroundColor: t.colors.brandBackground, - rippleColor: '#D4D4D4', - color: t.colors.neutralForegroundOnColor, - iconColor: t.colors.neutralForegroundOnColor, - disabled: { - backgroundColor: t.colors.neutralBackground5, - color: t.colors.neutralForegroundDisabled1, - iconColor: t.colors.neutralForegroundDisabled1, - }, - pressed: { - backgroundColor: t.colors.brandBackgroundPressed, - color: t.colors.neutralForegroundOnColor, - iconColor: t.colors.neutralForegroundOnColor, - }, - focused: { - backgroundColor: t.colors.brandBackground, - color: t.colors.neutralForegroundOnColor, - borderColor: t.colors.strokeFocus2, - borderInnerColor: t.colors.strokeFocus1, - iconColor: t.colors.neutralForegroundOnColor, - }, - subtle: { - backgroundColor: 'transparent', - rippleColor: '#D4D4D4', - color: t.colors.brandForeground1, - iconColor: t.colors.brandForeground1, - disabled: { - backgroundColor: 'transparent', - color: t.colors.neutralForegroundDisabled1, - iconColor: t.colors.neutralForegroundDisabled1, - }, - pressed: { - backgroundColor: 'transparent', - color: t.colors.brandForeground1Pressed, - iconColor: t.colors.brandForeground1Pressed, - }, - focused: { - backgroundColor: 'transparent', - borderColor: t.colors.strokeFocus2, - borderInnerColor: t.colors.strokeFocus1, - color: t.colors.brandForeground1, - iconColor: t.colors.brandForeground1, - }, - }, - outline: { - backgroundColor: 'transparent', - rippleColor: '#D4D4D4', - color: t.colors.brandForeground1, - iconColor: t.colors.brandForeground1, - borderColor: t.colors.brandStroke1, - disabled: { - backgroundColor: 'transparent', - color: t.colors.neutralForegroundDisabled1, - iconColor: t.colors.neutralForegroundDisabled1, - borderColor: t.colors.neutralStrokeDisabled, - }, - pressed: { - backgroundColor: 'transparent', - color: t.colors.brandForeground1Pressed, - iconColor: t.colors.brandForeground1Pressed, - borderColor: t.colors.brandStroke1Pressed, - }, - focused: { - backgroundColor: 'transparent', - borderColor: t.colors.strokeFocus2, - borderInnerColor: t.colors.strokeFocus1, - color: t.colors.brandForeground1, - iconColor: t.colors.brandForeground1, - }, - }, +export const defaultButtonColorTokens = (t: Theme) => ({ + /** Android does not have a different styles for 'default' button. + * 'primary', 'accent' and if no appearance is mentioned, picks this. + */ + backgroundColor: t.colors.brandBackground, + rippleColor: '#D4D4D4', + color: t.colors.neutralForegroundOnColor, + iconColor: t.colors.neutralForegroundOnColor, + disabled: { + backgroundColor: t.colors.neutralBackground5, + color: t.colors.neutralForegroundDisabled1, + iconColor: t.colors.neutralForegroundDisabled1, + }, + pressed: { + backgroundColor: t.colors.brandBackgroundPressed, + color: t.colors.neutralForegroundOnColor, + iconColor: t.colors.neutralForegroundOnColor, + }, + focused: { + backgroundColor: t.colors.brandBackground, + color: t.colors.neutralForegroundOnColor, + borderColor: t.colors.strokeFocus2, + borderInnerColor: t.colors.strokeFocus1, + iconColor: t.colors.neutralForegroundOnColor, + }, + subtle: { + backgroundColor: 'transparent', + rippleColor: '#D4D4D4', + color: t.colors.brandForeground1, + iconColor: t.colors.brandForeground1, + disabled: { + backgroundColor: 'transparent', + color: t.colors.neutralForegroundDisabled1, + iconColor: t.colors.neutralForegroundDisabled1, + }, + pressed: { + backgroundColor: 'transparent', + color: t.colors.brandForeground1Pressed, + iconColor: t.colors.brandForeground1Pressed, + }, + focused: { + backgroundColor: 'transparent', + borderColor: t.colors.strokeFocus2, + borderInnerColor: t.colors.strokeFocus1, + color: t.colors.brandForeground1, + iconColor: t.colors.brandForeground1, + }, + }, + outline: { + backgroundColor: 'transparent', + rippleColor: '#D4D4D4', + color: t.colors.brandForeground1, + iconColor: t.colors.brandForeground1, + borderColor: t.colors.brandStroke1, + disabled: { + backgroundColor: 'transparent', + color: t.colors.neutralForegroundDisabled1, + iconColor: t.colors.neutralForegroundDisabled1, + borderColor: t.colors.neutralStrokeDisabled, + }, + pressed: { + backgroundColor: 'transparent', + color: t.colors.brandForeground1Pressed, + iconColor: t.colors.brandForeground1Pressed, + borderColor: t.colors.brandStroke1Pressed, + }, + focused: { + backgroundColor: 'transparent', + borderColor: t.colors.strokeFocus2, + borderInnerColor: t.colors.strokeFocus1, + color: t.colors.brandForeground1, + iconColor: t.colors.brandForeground1, + }, + }, }); diff --git a/packages/theming/android-theme/src/components/Button/ButtonFontTokens.ts b/packages/theming/android-theme/src/components/Button/ButtonFontTokens.ts index c58292e3ac..38cc1a16f7 100644 --- a/packages/theming/android-theme/src/components/Button/ButtonFontTokens.ts +++ b/packages/theming/android-theme/src/components/Button/ButtonFontTokens.ts @@ -1,21 +1,19 @@ import type { Theme } from '@fluentui-react-native/theme-types'; - -export const defaultButtonFontTokens = (t: Theme) => -({ - medium: { - fontSize: t.typography.variants.body2Strong.size, - fontFamily: t.typography.variants.body2Strong.face, - fontWeight: t.typography.variants.body2Strong.weight, - }, - small: { - fontSize: t.typography.variants.body2Strong.size, - fontFamily: t.typography.variants.body2Strong.face, - fontWeight: t.typography.variants.body2Strong.weight, - }, - large: { - fontSize: t.typography.variants.body1Strong.size, - fontFamily: t.typography.variants.body1Strong.face, - fontWeight: t.typography.variants.body1Strong.weight, - }, +export const defaultButtonFontTokens = (t: Theme) => ({ + medium: { + fontSize: t.typography.variants.body2Strong.size, + fontFamily: t.typography.variants.body2Strong.face, + fontWeight: t.typography.variants.body2Strong.weight, + }, + small: { + fontSize: t.typography.variants.body2Strong.size, + fontFamily: t.typography.variants.body2Strong.face, + fontWeight: t.typography.variants.body2Strong.weight, + }, + large: { + fontSize: t.typography.variants.body1Strong.size, + fontFamily: t.typography.variants.body1Strong.face, + fontWeight: t.typography.variants.body1Strong.weight, + }, }); diff --git a/packages/theming/android-theme/src/components/Button/ButtonTheme.ts b/packages/theming/android-theme/src/components/Button/ButtonTheme.ts index 1eb30016e3..b6c36878c0 100644 --- a/packages/theming/android-theme/src/components/Button/ButtonTheme.ts +++ b/packages/theming/android-theme/src/components/Button/ButtonTheme.ts @@ -1,4 +1,3 @@ - import { immutableMerge } from '@fluentui-react-native/immutable-merge'; import type { Theme } from '@fluentui-react-native/theme-types'; @@ -9,16 +8,15 @@ import { defaultFABColorTokens } from './FABColorTokens'; import { defaultFABTokens } from './FABTokens'; import { defaultToggleButtonColorTokens } from './ToggleButtonColorTokens'; -export const defaultButtonTheme = (theme: Theme) => -({ +export const defaultButtonTheme = (theme: Theme) => ({ components: { Button: immutableMerge(defaultButtonColorTokens(theme), defaultButtonFontTokens(theme), defaultButtonTokens(theme)), FAB: immutableMerge(defaultFABTokens(theme), defaultFABColorTokens(theme)), - ToggleButton: - immutableMerge( + ToggleButton: immutableMerge( defaultButtonTokens(theme), defaultButtonFontTokens(theme), defaultButtonColorTokens(theme), - defaultToggleButtonColorTokens(theme)), - } + defaultToggleButtonColorTokens(theme), + ), + }, }); diff --git a/packages/theming/android-theme/src/components/Button/ButtonTokens.ts b/packages/theming/android-theme/src/components/Button/ButtonTokens.ts index 98898ac5c3..42a9dbcd0f 100644 --- a/packages/theming/android-theme/src/components/Button/ButtonTokens.ts +++ b/packages/theming/android-theme/src/components/Button/ButtonTokens.ts @@ -3,8 +3,7 @@ import type { DimensionValue } from 'react-native'; import { globalTokensAndroid as globalTokens } from '@fluentui-react-native/theme-tokens'; import type { Theme } from '@fluentui-react-native/theme-types'; -export const defaultButtonTokens = (_t: Theme) => -({ +export const defaultButtonTokens = (_t: Theme) => ({ focused: { borderWidth: globalTokens.stroke.width20, borderInnerWidth: globalTokens.stroke.width10, @@ -92,5 +91,5 @@ export const defaultButtonTokens = (_t: Theme) => default: return 'primary'; } - } + }, }); diff --git a/packages/theming/android-theme/src/components/Button/FABTokens.ts b/packages/theming/android-theme/src/components/Button/FABTokens.ts index c3bce375a4..9f01c3de52 100644 --- a/packages/theming/android-theme/src/components/Button/FABTokens.ts +++ b/packages/theming/android-theme/src/components/Button/FABTokens.ts @@ -1,8 +1,20 @@ -import {globalTokensAndroid as globalTokens} from '@fluentui-react-native/theme-tokens'; +import { globalTokensAndroid as globalTokens } from '@fluentui-react-native/theme-tokens'; import type { Theme } from '@fluentui-react-native/theme-types'; -export const defaultFABTokens = (t: Theme) => - ({ +export const defaultFABTokens = (t: Theme) => ({ + elevation: t.shadows.shadow8.key.blur, + disabled: { + elevation: 0, + }, + pressed: { + elevation: t.shadows.shadow2.key.blur, + }, + focused: { + elevation: t.shadows.shadow2.key.blur, + borderWidth: globalTokens.stroke.width20, + borderInnerWidth: globalTokens.stroke.width10, + }, + subtle: { elevation: t.shadows.shadow8.key.blur, disabled: { elevation: 0, @@ -15,62 +27,49 @@ export const defaultFABTokens = (t: Theme) => borderWidth: globalTokens.stroke.width20, borderInnerWidth: globalTokens.stroke.width10, }, - subtle: { - elevation: t.shadows.shadow8.key.blur, - disabled: { - elevation: 0, - }, - pressed: { - elevation: t.shadows.shadow2.key.blur, - }, - focused: { - elevation: t.shadows.shadow2.key.blur, - borderWidth: globalTokens.stroke.width20, - borderInnerWidth: globalTokens.stroke.width10, - }, - }, - large: { + }, + large: { + borderRadius: globalTokens.corner.radiusCircular, + iconSize: 24, + minHeight: 56, + minWidth: 56, + paddingHorizontal: globalTokens.size160, + paddingVertical: globalTokens.size160, + spacingIconContentBefore: 0, + hasContent: { borderRadius: globalTokens.corner.radiusCircular, iconSize: 24, + fontSize: t.typography.variants.body1Strong.size, + fontFamily: t.typography.variants.body1Strong.face, + fontWeight: t.typography.variants.body1Strong.weight, minHeight: 56, minWidth: 56, - paddingHorizontal: globalTokens.size160, + paddingStart: globalTokens.size160, + paddingEnd: globalTokens.size200, paddingVertical: globalTokens.size160, - spacingIconContentBefore: 0, - hasContent: { - borderRadius: globalTokens.corner.radiusCircular, - iconSize: 24, - fontSize: t.typography.variants.body1Strong.size, - fontFamily: t.typography.variants.body1Strong.face, - fontWeight: t.typography.variants.body1Strong.weight, - minHeight: 56, - minWidth: 56, - paddingStart: globalTokens.size160, - paddingEnd: globalTokens.size200, - paddingVertical: globalTokens.size160, - spacingIconContentBefore: globalTokens.size80, - }, + spacingIconContentBefore: globalTokens.size80, }, - small: { + }, + small: { + borderRadius: globalTokens.corner.radiusCircular, + iconSize: 20, + minHeight: 44, + minWidth: 44, + paddingHorizontal: globalTokens.size120, + paddingVertical: globalTokens.size120, + spacingIconContentBefore: 0, + hasContent: { borderRadius: globalTokens.corner.radiusCircular, iconSize: 20, + fontSize: t.typography.variants.body2Strong.size, + fontFamily: t.typography.variants.body2Strong.face, + fontWeight: t.typography.variants.body2Strong.weight, minHeight: 44, minWidth: 44, paddingHorizontal: globalTokens.size120, - paddingVertical: globalTokens.size120, - spacingIconContentBefore: 0, - hasContent: { - borderRadius: globalTokens.corner.radiusCircular, - iconSize: 20, - fontSize: t.typography.variants.body2Strong.size, - fontFamily: t.typography.variants.body2Strong.face, - fontWeight: t.typography.variants.body2Strong.weight, - minHeight: 44, - minWidth: 44, - paddingHorizontal: globalTokens.size120, - paddingStart: globalTokens.size120, - paddingEnd: globalTokens.size160, - spacingIconContentBefore: globalTokens.size80, - }, + paddingStart: globalTokens.size120, + paddingEnd: globalTokens.size160, + spacingIconContentBefore: globalTokens.size80, }, - }); + }, +}); diff --git a/packages/theming/android-theme/src/createAndroidTheme.ts b/packages/theming/android-theme/src/createAndroidTheme.ts index bbf09c6e7b..45a61d6362 100644 --- a/packages/theming/android-theme/src/createAndroidTheme.ts +++ b/packages/theming/android-theme/src/createAndroidTheme.ts @@ -7,16 +7,18 @@ import { getAndroidTheme } from './androidTheme'; import { defaultButtonTheme } from './components/Button/ButtonTheme'; export function createAndroidTheme(options: ThemeOptions = {}): ThemeReference { - const themeRef = new ThemeReference({} as Theme, - () => { - // Stub out HC and darkElevated on Android - const current = - options.appearance === 'dynamic' || options.appearance === 'highContrast' || options.appearance === 'darkElevated' - ? (Appearance && Appearance.getColorScheme()) || 'light' - : options.appearance; - return getAndroidTheme(current); - }, - defaultButtonTheme); + const themeRef = new ThemeReference( + {} as Theme, + () => { + // Stub out HC and darkElevated on Android + const current = + options.appearance === 'dynamic' || options.appearance === 'highContrast' || options.appearance === 'darkElevated' + ? (Appearance && Appearance.getColorScheme()) || 'light' + : options.appearance; + return getAndroidTheme(current); + }, + defaultButtonTheme, + ); if (Appearance && options.appearance === 'dynamic') { Appearance.addChangeListener(() => { diff --git a/packages/theming/apple-theme/src/__tests__/apple-theme.test.ts b/packages/theming/apple-theme/src/__tests__/apple-theme.test.ts index 985e4bcdac..6b95a2dde6 100644 --- a/packages/theming/apple-theme/src/__tests__/apple-theme.test.ts +++ b/packages/theming/apple-theme/src/__tests__/apple-theme.test.ts @@ -87,4 +87,4 @@ describe('verify types', () => { const fabTokens: FABTokens = defaultFABTokens(officeTheme); expect(fabTokens).toBeTruthy(); }); -}) \ No newline at end of file +}); diff --git a/packages/theming/apple-theme/src/components/Button/ButtonColorTokens.macos.ts b/packages/theming/apple-theme/src/components/Button/ButtonColorTokens.macos.ts index 9ce1eda30d..05b0ae1349 100644 --- a/packages/theming/apple-theme/src/components/Button/ButtonColorTokens.macos.ts +++ b/packages/theming/apple-theme/src/components/Button/ButtonColorTokens.macos.ts @@ -1,93 +1,92 @@ import type { Theme } from '@fluentui-react-native/theme-types'; -export const defaultButtonColorTokens = (t: Theme) => - ({ +export const defaultButtonColorTokens = (t: Theme) => ({ + backgroundColor: t.colors.defaultBackground, + color: t.colors.defaultContent, + borderColor: t.colors.defaultBorder, + iconColor: t.colors.defaultContent, + disabled: { + backgroundColor: t.colors.defaultDisabledBackground, + color: t.colors.defaultDisabledContent, + borderColor: t.colors.defaultDisabledBorder, + iconColor: t.colors.defaultDisabledIcon, + }, + hovered: { backgroundColor: t.colors.defaultBackground, color: t.colors.defaultContent, borderColor: t.colors.defaultBorder, - iconColor: t.colors.defaultContent, + iconColor: t.colors.defaultHoveredIcon, + }, + pressed: { + backgroundColor: t.colors.defaultPressedBackground, + color: t.colors.defaultPressedContent, + borderColor: t.colors.defaultBorder, + iconColor: t.colors.defaultPressedIcon, + }, + focused: { + backgroundColor: t.colors.defaultFocusedBackground, + color: t.colors.defaultFocusedContent, + borderColor: t.colors.defaultFocusedBorder, + icon: t.colors.defaultFocusedIcon, + }, + primary: { + backgroundColor: t.colors.brandBackground, + color: t.colors.neutralForegroundOnBrand, + borderColor: t.colors.brandStroke1, + iconColor: t.colors.neutralForegroundOnBrand, disabled: { - backgroundColor: t.colors.defaultDisabledBackground, - color: t.colors.defaultDisabledContent, - borderColor: t.colors.defaultDisabledBorder, - iconColor: t.colors.defaultDisabledIcon, + backgroundColor: t.colors.neutralBackgroundDisabled, + color: t.colors.neutralForegroundDisabled, + borderColor: t.colors.neutralStrokeDisabled, + iconColor: t.colors.neutralForegroundDisabled, }, hovered: { - backgroundColor: t.colors.defaultBackground, - color: t.colors.defaultContent, - borderColor: t.colors.defaultBorder, - iconColor: t.colors.defaultHoveredIcon, + backgroundColor: t.colors.brandBackgroundHover, + color: t.colors.neutralForegroundOnBrandHover, + borderColor: t.colors.brandBackgroundHover, + iconColor: t.colors.neutralForegroundOnBrandHover, }, pressed: { - backgroundColor: t.colors.defaultPressedBackground, - color: t.colors.defaultPressedContent, - borderColor: t.colors.defaultBorder, - iconColor: t.colors.defaultPressedIcon, + backgroundColor: t.colors.brandBackgroundPressed, + color: t.colors.neutralForegroundOnBrandPressed, + borderColor: t.colors.brandBackgroundPressed, + iconColor: t.colors.neutralForegroundOnBrandPressed, }, focused: { - backgroundColor: t.colors.defaultFocusedBackground, - color: t.colors.defaultFocusedContent, - borderColor: t.colors.defaultFocusedBorder, - icon: t.colors.defaultFocusedIcon, + backgroundColor: t.colors.brandBackgroundHover, + color: t.colors.neutralForegroundOnBrandHover, + borderColor: t.colors.strokeFocus2, + iconColor: t.colors.neutralForegroundOnBrandHover, + }, + }, + subtle: { + backgroundColor: t.colors.ghostBackground, + color: t.colors.ghostContent, + borderColor: t.colors.ghostBorder, + iconColor: t.colors.ghostIcon, + disabled: { + color: t.colors.ghostDisabledContent, + borderColor: t.colors.ghostDisabledBorder, + backgroundColor: t.colors.ghostDisabledBackground, + iconColor: t.colors.ghostDisabledIcon, }, - primary: { - backgroundColor: t.colors.brandBackground, - color: t.colors.neutralForegroundOnBrand, - borderColor: t.colors.brandStroke1, - iconColor: t.colors.neutralForegroundOnBrand, - disabled: { - backgroundColor: t.colors.neutralBackgroundDisabled, - color: t.colors.neutralForegroundDisabled, - borderColor: t.colors.neutralStrokeDisabled, - iconColor: t.colors.neutralForegroundDisabled, - }, - hovered: { - backgroundColor: t.colors.brandBackgroundHover, - color: t.colors.neutralForegroundOnBrandHover, - borderColor: t.colors.brandBackgroundHover, - iconColor: t.colors.neutralForegroundOnBrandHover, - }, - pressed: { - backgroundColor: t.colors.brandBackgroundPressed, - color: t.colors.neutralForegroundOnBrandPressed, - borderColor: t.colors.brandBackgroundPressed, - iconColor: t.colors.neutralForegroundOnBrandPressed, - }, - focused: { - backgroundColor: t.colors.brandBackgroundHover, - color: t.colors.neutralForegroundOnBrandHover, - borderColor: t.colors.strokeFocus2, - iconColor: t.colors.neutralForegroundOnBrandHover, - }, + hovered: { + backgroundColor: t.colors.ghostHoveredBackground, + color: t.colors.ghostHoveredContent, + borderColor: t.colors.ghostHoveredBorder, + iconColor: t.colors.ghostHoveredIcon, }, - subtle: { - backgroundColor: t.colors.ghostBackground, - color: t.colors.ghostContent, - borderColor: t.colors.ghostBorder, - iconColor: t.colors.ghostIcon, - disabled: { - color: t.colors.ghostDisabledContent, - borderColor: t.colors.ghostDisabledBorder, - backgroundColor: t.colors.ghostDisabledBackground, - iconColor: t.colors.ghostDisabledIcon, - }, - hovered: { - backgroundColor: t.colors.ghostHoveredBackground, - color: t.colors.ghostHoveredContent, - borderColor: t.colors.ghostHoveredBorder, - iconColor: t.colors.ghostHoveredIcon, - }, - pressed: { - backgroundColor: t.colors.ghostPressedBackground, - borderColor: t.colors.ghostPressedBorder, - color: t.colors.ghostPressedContent, - icon: t.colors.ghostPressedIcon, - }, - focused: { - borderColor: t.colors.ghostFocusedBorder, - backgroundColor: t.colors.ghostFocusedBackground, - color: t.colors.ghostFocusedContent, - icon: t.colors.ghostFocusedIcon, - }, + pressed: { + backgroundColor: t.colors.ghostPressedBackground, + borderColor: t.colors.ghostPressedBorder, + color: t.colors.ghostPressedContent, + icon: t.colors.ghostPressedIcon, + }, + focused: { + borderColor: t.colors.ghostFocusedBorder, + backgroundColor: t.colors.ghostFocusedBackground, + color: t.colors.ghostFocusedContent, + icon: t.colors.ghostFocusedIcon, }, - } ); + }, +}); diff --git a/packages/theming/apple-theme/src/components/Button/ButtonColorTokens.ts b/packages/theming/apple-theme/src/components/Button/ButtonColorTokens.ts index c7afdd51f8..82404a847c 100644 --- a/packages/theming/apple-theme/src/components/Button/ButtonColorTokens.ts +++ b/packages/theming/apple-theme/src/components/Button/ButtonColorTokens.ts @@ -1,5 +1,3 @@ import type { Theme } from '@fluentui-react-native/theme-types'; -export const defaultButtonColorTokens = (_t: Theme) => - ({ - }); +export const defaultButtonColorTokens = (_t: Theme) => ({}); diff --git a/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ios.ts b/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ios.ts index b96a2c2a89..41f9991be3 100644 --- a/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ios.ts +++ b/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ios.ts @@ -1,20 +1,19 @@ import type { Theme } from '@fluentui-react-native/theme-types'; -export const defaultButtonFontTokens = (t: Theme) => - ({ - medium: { - fontSize: t.typography.variants.caption1Strong!.size, - fontFamily: t.typography.variants.caption1Strong!.face, - fontWeight: t.typography.variants.caption1Strong!.weight, - }, - small: { - fontSize: t.typography.variants.caption1Strong!.size, - fontFamily: t.typography.variants.caption1Strong!.face, - fontWeight: t.typography.variants.caption1Strong!.weight, - }, - large: { - fontSize: t.typography.variants.body1Strong!.size, - fontFamily: t.typography.variants.body1Strong!.face, - fontWeight: t.typography.variants.body1Strong!.weight, - }, - }); +export const defaultButtonFontTokens = (t: Theme) => ({ + medium: { + fontSize: t.typography.variants.caption1Strong!.size, + fontFamily: t.typography.variants.caption1Strong!.face, + fontWeight: t.typography.variants.caption1Strong!.weight, + }, + small: { + fontSize: t.typography.variants.caption1Strong!.size, + fontFamily: t.typography.variants.caption1Strong!.face, + fontWeight: t.typography.variants.caption1Strong!.weight, + }, + large: { + fontSize: t.typography.variants.body1Strong!.size, + fontFamily: t.typography.variants.body1Strong!.face, + fontWeight: t.typography.variants.body1Strong!.weight, + }, +}); diff --git a/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.macos.ts b/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.macos.ts index 9aca1cda46..2624ec74f8 100644 --- a/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.macos.ts +++ b/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.macos.ts @@ -1,18 +1,17 @@ import type { Theme } from '@fluentui-react-native/theme-types'; -export const defaultButtonFontTokens = (_t: Theme) => - ({ - medium: { - hasContent: { - variant: 'bodyStandard', - }, +export const defaultButtonFontTokens = (_t: Theme) => ({ + medium: { + hasContent: { + variant: 'bodyStandard', }, - small: { - hasContent: { - variant: 'secondaryStandard', - }, + }, + small: { + hasContent: { + variant: 'secondaryStandard', }, - large: { - variant: 'subheaderSemibold', - }, - }); + }, + large: { + variant: 'subheaderSemibold', + }, +}); diff --git a/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ts b/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ts index 933f7a2b54..8b2ea33d78 100644 --- a/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ts +++ b/packages/theming/apple-theme/src/components/Button/ButtonFontTokens.ts @@ -1,5 +1,3 @@ import type { Theme } from '@fluentui-react-native/theme-types'; -export const defaultButtonFontTokens = (_t: Theme) => - ({ - }); +export const defaultButtonFontTokens = (_t: Theme) => ({}); diff --git a/packages/theming/apple-theme/src/components/Button/ButtonTheme.ios.ts b/packages/theming/apple-theme/src/components/Button/ButtonTheme.ios.ts index 189621ff1e..b269bd0972 100644 --- a/packages/theming/apple-theme/src/components/Button/ButtonTheme.ios.ts +++ b/packages/theming/apple-theme/src/components/Button/ButtonTheme.ios.ts @@ -1,4 +1,3 @@ - import { immutableMerge } from '@fluentui-react-native/immutable-merge'; import type { Theme } from '@fluentui-react-native/theme-types'; @@ -12,25 +11,24 @@ import { defaultFABColorTokens } from './FABColorTokens.ios'; import { defaultFABTokens } from './FABTokens.ios'; import { defaultToggleButtonColorTokens } from './ToggleButtonColorTokens'; -export const defaultButtonTheme = (theme: Theme) => -({ +export const defaultButtonTheme = (theme: Theme) => ({ components: { Button: immutableMerge(defaultButtonColorTokens(theme), defaultButtonFontTokens(theme), defaultButtonTokens(theme)), - CompoundButton: - immutableMerge( + CompoundButton: immutableMerge( defaultButtonTokens(theme), defaultButtonColorTokens(theme), defaultCompoundButtonColorTokens(theme), defaultCompoundButtonFontTokens(theme), - defaultCompoundButtonTokens(theme)), + defaultCompoundButtonTokens(theme), + ), FAB: immutableMerge(defaultFABTokens(theme), defaultFABColorTokens(theme)), - ToggleButton: - immutableMerge( + ToggleButton: immutableMerge( defaultButtonTokens(theme), defaultButtonFontTokens(theme), defaultButtonColorTokens(theme), - defaultToggleButtonColorTokens(theme)), - } + defaultToggleButtonColorTokens(theme), + ), + }, }); diff --git a/packages/theming/apple-theme/src/components/Button/ButtonTheme.ts b/packages/theming/apple-theme/src/components/Button/ButtonTheme.ts index 1aa2d19253..ec13f389e6 100644 --- a/packages/theming/apple-theme/src/components/Button/ButtonTheme.ts +++ b/packages/theming/apple-theme/src/components/Button/ButtonTheme.ts @@ -1,4 +1,3 @@ - import { immutableMerge } from '@fluentui-react-native/immutable-merge'; import type { Theme } from '@fluentui-react-native/theme-types'; @@ -10,23 +9,22 @@ import { defaultCompoundButtonFontTokens } from './CompoundButtonFontTokens'; import { defaultCompoundButtonTokens } from './CompoundButtonTokens'; import { defaultToggleButtonColorTokens } from './ToggleButtonColorTokens'; -export const defaultButtonTheme = (theme: Theme) => -({ +export const defaultButtonTheme = (theme: Theme) => ({ components: { Button: immutableMerge(defaultButtonColorTokens(theme), defaultButtonFontTokens(theme), defaultButtonTokens(theme)), - CompoundButton: - immutableMerge( + CompoundButton: immutableMerge( defaultButtonTokens(theme), defaultButtonColorTokens(theme), defaultCompoundButtonColorTokens(theme), defaultCompoundButtonFontTokens(theme), - defaultCompoundButtonTokens(theme)), + defaultCompoundButtonTokens(theme), + ), - ToggleButton: - immutableMerge( + ToggleButton: immutableMerge( defaultButtonTokens(theme), defaultButtonFontTokens(theme), defaultButtonColorTokens(theme), - defaultToggleButtonColorTokens(theme)), - } + defaultToggleButtonColorTokens(theme), + ), + }, }); diff --git a/packages/theming/apple-theme/src/components/Button/ButtonTokens.ios.ts b/packages/theming/apple-theme/src/components/Button/ButtonTokens.ios.ts index 2200d11757..af417744a4 100644 --- a/packages/theming/apple-theme/src/components/Button/ButtonTokens.ios.ts +++ b/packages/theming/apple-theme/src/components/Button/ButtonTokens.ios.ts @@ -1,79 +1,77 @@ import type { DimensionValue } from 'react-native'; -import {globalTokensIOS as globalTokens} from '@fluentui-react-native/theme-tokens'; +import { globalTokensIOS as globalTokens } from '@fluentui-react-native/theme-tokens'; import type { Theme } from '@fluentui-react-native/theme-types'; -export const defaultButtonTokens = (_t: Theme) => - ({ - block: { - width: '100%' as DimensionValue, +export const defaultButtonTokens = (_t: Theme) => ({ + block: { + width: '100%' as DimensionValue, + }, + medium: { + paddingHorizontal: globalTokens.size120, + borderWidth: globalTokens.stroke.width10, + borderRadius: globalTokens.corner.radius80, + minHeight: 40, + iconSize: 20, + focused: { + borderWidth: 0, }, - medium: { - paddingHorizontal: globalTokens.size120, - borderWidth: globalTokens.stroke.width10, - borderRadius: globalTokens.corner.radius80, - minHeight: 40, - iconSize: 20, - focused: { - borderWidth: 0, + hasContent: { + minWidth: 96, + hasIconAfter: { + spacingIconContentAfter: globalTokens.size80, }, - hasContent: { - minWidth: 96, - hasIconAfter: { - spacingIconContentAfter: globalTokens.size80, - }, - hasIconBefore: { - spacingIconContentBefore: globalTokens.size80, - }, + hasIconBefore: { + spacingIconContentBefore: globalTokens.size80, }, }, - small: { - paddingHorizontal: globalTokens.size60, - borderWidth: globalTokens.stroke.width10, - borderRadius: globalTokens.corner.radius80, + }, + small: { + paddingHorizontal: globalTokens.size60, + borderWidth: globalTokens.stroke.width10, + borderRadius: globalTokens.corner.radius80, + minHeight: 28, + iconSize: 16, + focused: { + borderWidth: 0, + }, + hasContent: { + minWidth: 64, minHeight: 28, - iconSize: 16, - focused: { - borderWidth: 0, + hasIconAfter: { + spacingIconContentAfter: globalTokens.size40, }, - hasContent: { - minWidth: 64, - minHeight: 28, - hasIconAfter: { - spacingIconContentAfter: globalTokens.size40, - }, - hasIconBefore: { - spacingIconContentBefore: globalTokens.size40, - }, + hasIconBefore: { + spacingIconContentBefore: globalTokens.size40, }, }, - large: { - paddingHorizontal: globalTokens.size160, - borderWidth: globalTokens.stroke.width10, - iconSize: 20, - borderRadius: globalTokens.corner.radius120, - minHeight: 52, - focused: { - borderWidth: 0, + }, + large: { + paddingHorizontal: globalTokens.size160, + borderWidth: globalTokens.stroke.width10, + iconSize: 20, + borderRadius: globalTokens.corner.radius120, + minHeight: 52, + focused: { + borderWidth: 0, + }, + hasContent: { + minWidth: 96, + hasIconAfter: { + spacingIconContentAfter: globalTokens.size80, }, - hasContent: { - minWidth: 96, - hasIconAfter: { - spacingIconContentAfter: globalTokens.size80, - }, - hasIconBefore: { - spacingIconContentBefore: globalTokens.size80, - }, + hasIconBefore: { + spacingIconContentBefore: globalTokens.size80, }, }, - circular: { - borderRadius: globalTokens.corner.radiusCircular, - }, - square: { - borderRadius: globalTokens.corner.radiusNone, - }, + }, + circular: { + borderRadius: globalTokens.corner.radiusCircular, + }, + square: { + borderRadius: globalTokens.corner.radiusNone, + }, getPlatformSpecificAppearance: (appearance): 'accent' | 'primary' | 'subtle' | 'outline' => { - switch (appearance) { case 'accent': // Included to cover Mobile platform naming guidelines, maps to 'primary'. return 'primary'; @@ -86,5 +84,5 @@ export const defaultButtonTokens = (_t: Theme) => default: return 'primary'; } - } - }); + }, +}); diff --git a/packages/theming/apple-theme/src/components/Button/ButtonTokens.ts b/packages/theming/apple-theme/src/components/Button/ButtonTokens.ts index 9dd0a2c341..e4f0444f66 100644 --- a/packages/theming/apple-theme/src/components/Button/ButtonTokens.ts +++ b/packages/theming/apple-theme/src/components/Button/ButtonTokens.ts @@ -3,8 +3,7 @@ import type { DimensionValue } from 'react-native'; import { globalTokens } from '@fluentui-react-native/theme-tokens'; import type { Theme } from '@fluentui-react-native/theme-types'; -export const defaultButtonTokens = (_t: Theme) => -({ +export const defaultButtonTokens = (_t: Theme) => ({ block: { width: '100%' as DimensionValue, }, @@ -97,5 +96,5 @@ export const defaultButtonTokens = (_t: Theme) => default: return null; } - } + }, }); diff --git a/packages/theming/apple-theme/src/components/Button/FABTokens.ios.ts b/packages/theming/apple-theme/src/components/Button/FABTokens.ios.ts index b437990587..1553d6dbf8 100644 --- a/packages/theming/apple-theme/src/components/Button/FABTokens.ios.ts +++ b/packages/theming/apple-theme/src/components/Button/FABTokens.ios.ts @@ -1,8 +1,20 @@ -import {globalTokensIOS as globalTokens} from '@fluentui-react-native/theme-tokens'; +import { globalTokensIOS as globalTokens } from '@fluentui-react-native/theme-tokens'; import type { Theme } from '@fluentui-react-native/theme-types'; -export const defaultFABTokens = (t: Theme) => - ({ +export const defaultFABTokens = (t: Theme) => ({ + shadowToken: t.shadows.shadow8, + disabled: { + shadowToken: t.shadows.shadow2, + }, + pressed: { + shadowToken: t.shadows.shadow2, + }, + focused: { + shadowToken: t.shadows.shadow2, + borderWidth: globalTokens.stroke.width20, + borderInnerWidth: globalTokens.stroke.width10, + }, + subtle: { shadowToken: t.shadows.shadow8, disabled: { shadowToken: t.shadows.shadow2, @@ -15,62 +27,49 @@ export const defaultFABTokens = (t: Theme) => borderWidth: globalTokens.stroke.width20, borderInnerWidth: globalTokens.stroke.width10, }, - subtle: { - shadowToken: t.shadows.shadow8, - disabled: { - shadowToken: t.shadows.shadow2, - }, - pressed: { - shadowToken: t.shadows.shadow2, - }, - focused: { - shadowToken: t.shadows.shadow2, - borderWidth: globalTokens.stroke.width20, - borderInnerWidth: globalTokens.stroke.width10, - }, - }, - large: { + }, + large: { + borderRadius: globalTokens.corner.radiusCircular, + iconSize: 24, + minHeight: 56, + minWidth: 56, + paddingHorizontal: globalTokens.size160, + paddingVertical: globalTokens.size160, + spacingIconContentBefore: 0, + hasContent: { borderRadius: globalTokens.corner.radiusCircular, iconSize: 24, + fontSize: t.typography.variants.body1Strong.size, + fontFamily: t.typography.variants.body1Strong.face, + fontWeight: t.typography.variants.body1Strong.weight, minHeight: 56, minWidth: 56, - paddingHorizontal: globalTokens.size160, + paddingStart: globalTokens.size160, + paddingEnd: globalTokens.size200, paddingVertical: globalTokens.size160, - spacingIconContentBefore: 0, - hasContent: { - borderRadius: globalTokens.corner.radiusCircular, - iconSize: 24, - fontSize: t.typography.variants.body1Strong.size, - fontFamily: t.typography.variants.body1Strong.face, - fontWeight: t.typography.variants.body1Strong.weight, - minHeight: 56, - minWidth: 56, - paddingStart: globalTokens.size160, - paddingEnd: globalTokens.size200, - paddingVertical: globalTokens.size160, - spacingIconContentBefore: globalTokens.size80, - }, + spacingIconContentBefore: globalTokens.size80, }, - small: { + }, + small: { + borderRadius: globalTokens.corner.radiusCircular, + iconSize: 20, + minHeight: 44, + minWidth: 44, + paddingHorizontal: globalTokens.size120, + paddingVertical: globalTokens.size120, + spacingIconContentBefore: 0, + hasContent: { borderRadius: globalTokens.corner.radiusCircular, iconSize: 20, - minHeight: 44, - minWidth: 44, + fontSize: t.typography.variants.body2Strong.size, + fontFamily: t.typography.variants.body2Strong.face, + fontWeight: t.typography.variants.body2Strong.weight, + minHeight: 48, + minWidth: 48, paddingHorizontal: globalTokens.size120, - paddingVertical: globalTokens.size120, - spacingIconContentBefore: 0, - hasContent: { - borderRadius: globalTokens.corner.radiusCircular, - iconSize: 20, - fontSize: t.typography.variants.body2Strong.size, - fontFamily: t.typography.variants.body2Strong.face, - fontWeight: t.typography.variants.body2Strong.weight, - minHeight: 48, - minWidth: 48, - paddingHorizontal: globalTokens.size120, - paddingStart: globalTokens.size120, - paddingEnd: globalTokens.size160, - spacingIconContentBefore: globalTokens.size80, - }, + paddingStart: globalTokens.size120, + paddingEnd: globalTokens.size160, + spacingIconContentBefore: globalTokens.size80, }, - }); + }, +}); diff --git a/packages/theming/apple-theme/src/createAppleTheme.ios.ts b/packages/theming/apple-theme/src/createAppleTheme.ios.ts index c0527412d4..1215ee6d33 100644 --- a/packages/theming/apple-theme/src/createAppleTheme.ios.ts +++ b/packages/theming/apple-theme/src/createAppleTheme.ios.ts @@ -8,11 +8,15 @@ import { getBaseAppleThemeIOS } from './appleTheme.ios'; import { defaultButtonTheme } from './components/Button/ButtonTheme'; export function createAppleTheme(): ThemeReference { - const appleThemeReference = new ThemeReference({} as Theme, () => { - const isLightMode = Appearance.getColorScheme() === 'light'; - const isElevated = NativeAppearanceAdditions.userInterfaceLevel() === 'elevated'; - return getBaseAppleThemeIOS(isLightMode, isElevated); - }, defaultButtonTheme); + const appleThemeReference = new ThemeReference( + {} as Theme, + () => { + const isLightMode = Appearance.getColorScheme() === 'light'; + const isElevated = NativeAppearanceAdditions.userInterfaceLevel() === 'elevated'; + return getBaseAppleThemeIOS(isLightMode, isElevated); + }, + defaultButtonTheme, + ); Appearance.addChangeListener(() => { appleThemeReference.invalidate(); diff --git a/packages/theming/apple-theme/src/createAppleTheme.macos.ts b/packages/theming/apple-theme/src/createAppleTheme.macos.ts index 2c9511e531..0803d8bfc2 100644 --- a/packages/theming/apple-theme/src/createAppleTheme.macos.ts +++ b/packages/theming/apple-theme/src/createAppleTheme.macos.ts @@ -1,7 +1,7 @@ import { Appearance } from 'react-native'; import { ThemeReference } from '@fluentui-react-native/theme'; -import type { PartialTheme} from '@fluentui-react-native/theme-types'; +import type { PartialTheme } from '@fluentui-react-native/theme-types'; import { type Theme } from '@fluentui-react-native/theme-types'; import { getCurrentAppearance } from '@fluentui-react-native/theming-utils'; import { AccessibilityInfo } from 'react-native-macos'; @@ -13,11 +13,15 @@ import { defaultButtonTheme } from './components/Button/ButtonTheme'; let appleThemeReference: ThemeReference; export function createAppleTheme(): ThemeReference { - appleThemeReference = new ThemeReference({} as Theme, () => { - const appearance = Appearance.getColorScheme(); - const mode = getCurrentAppearance(appearance, 'light'); - return getBaseAppleThemeMacOS(mode); - }, defaultButtonTheme); + appleThemeReference = new ThemeReference( + {} as Theme, + () => { + const appearance = Appearance.getColorScheme(); + const mode = getCurrentAppearance(appearance, 'light'); + return getBaseAppleThemeMacOS(mode); + }, + defaultButtonTheme, + ); // Fetch initial system settings for high contrast mode highContrastHandler(); // Invalidate theme and set prop when high contrast setting changes diff --git a/packages/theming/default-theme/src/components/Button/ButtonColorTokens.ts b/packages/theming/default-theme/src/components/Button/ButtonColorTokens.ts index 946eb052cc..0ebca6c88d 100644 --- a/packages/theming/default-theme/src/components/Button/ButtonColorTokens.ts +++ b/packages/theming/default-theme/src/components/Button/ButtonColorTokens.ts @@ -1,85 +1,84 @@ import type { Theme } from '@fluentui-react-native/theme-types'; -export const defaultButtonColorTokens = (t: Theme) => - ({ - backgroundColor: t.colors.buttonBackground, - color: t.colors.buttonText, - borderColor: t.colors.buttonBorder, - iconColor: t.colors.buttonIcon, +export const defaultButtonColorTokens = (t: Theme) => ({ + backgroundColor: t.colors.buttonBackground, + color: t.colors.buttonText, + borderColor: t.colors.buttonBorder, + iconColor: t.colors.buttonIcon, + disabled: { + backgroundColor: t.colors.defaultDisabledBackground, + color: t.colors.defaultDisabledContent, + borderColor: t.colors.defaultDisabledBorder, + iconColor: t.colors.defaultDisabledIcon, + }, + hovered: { + backgroundColor: t.colors.defaultHoveredBackground, + color: t.colors.defaultHoveredContent, + borderColor: t.colors.defaultHoveredBorder, + iconColor: t.colors.defaultHoveredIcon, + }, + pressed: { + backgroundColor: t.colors.defaultPressedBackground, + color: t.colors.defaultPressedContent, + borderColor: t.colors.defaultPressedBorder, + iconColor: t.colors.defaultPressedIcon, + }, + focused: { + backgroundColor: t.colors.defaultFocusedBackground, + color: t.colors.defaultFocusedContent, + borderColor: t.colors.defaultFocusedBorder, + icon: t.colors.defaultFocusedIcon, + }, + primary: { + backgroundColor: t.colors.brandBackground, + color: t.colors.neutralForegroundOnColor, + borderColor: t.colors.brandStroke1, + iconColor: t.colors.neutralForegroundOnColor, disabled: { - backgroundColor: t.colors.defaultDisabledBackground, - color: t.colors.defaultDisabledContent, - borderColor: t.colors.defaultDisabledBorder, - iconColor: t.colors.defaultDisabledIcon, - }, - hovered: { - backgroundColor: t.colors.defaultHoveredBackground, - color: t.colors.defaultHoveredContent, - borderColor: t.colors.defaultHoveredBorder, - iconColor: t.colors.defaultHoveredIcon, + backgroundColor: t.colors.brandBackgroundDisabled, + color: t.colors.neutralForegroundDisabled1, + iconColor: t.colors.neutralForegroundDisabled1, }, pressed: { - backgroundColor: t.colors.defaultPressedBackground, - color: t.colors.defaultPressedContent, - borderColor: t.colors.defaultPressedBorder, - iconColor: t.colors.defaultPressedIcon, + backgroundColor: t.colors.brandBackgroundPressed, + color: t.colors.neutralForegroundOnColor, + iconColor: t.colors.neutralForegroundOnColor, }, focused: { - backgroundColor: t.colors.defaultFocusedBackground, - color: t.colors.defaultFocusedContent, - borderColor: t.colors.defaultFocusedBorder, - icon: t.colors.defaultFocusedIcon, - }, - primary: { backgroundColor: t.colors.brandBackground, color: t.colors.neutralForegroundOnColor, - borderColor: t.colors.brandStroke1, + borderColor: t.colors.strokeFocus2, iconColor: t.colors.neutralForegroundOnColor, - disabled: { - backgroundColor: t.colors.brandBackgroundDisabled, - color: t.colors.neutralForegroundDisabled1, - iconColor: t.colors.neutralForegroundDisabled1, - }, - pressed: { - backgroundColor: t.colors.brandBackgroundPressed, - color: t.colors.neutralForegroundOnColor, - iconColor: t.colors.neutralForegroundOnColor, - }, - focused: { - backgroundColor: t.colors.brandBackground, - color: t.colors.neutralForegroundOnColor, - borderColor: t.colors.strokeFocus2, - iconColor: t.colors.neutralForegroundOnColor, - }, }, - subtle: { - backgroundColor: t.colors.ghostBackground, - color: t.colors.ghostContent, - borderColor: t.colors.ghostBorder, - iconColor: t.colors.ghostIcon, - disabled: { - color: t.colors.ghostDisabledContent, - borderColor: t.colors.ghostDisabledBorder, - backgroundColor: t.colors.ghostDisabledBackground, - iconColor: t.colors.ghostDisabledIcon, - }, - hovered: { - backgroundColor: t.colors.ghostHoveredBackground, - color: t.colors.ghostHoveredContent, - borderColor: t.colors.ghostHoveredBorder, - iconColor: t.colors.ghostHoveredIcon, - }, - pressed: { - backgroundColor: t.colors.ghostPressedBackground, - borderColor: t.colors.ghostPressedBorder, - color: t.colors.ghostPressedContent, - icon: t.colors.ghostPressedIcon, - }, - focused: { - borderColor: t.colors.ghostFocusedBorder, - backgroundColor: t.colors.ghostFocusedBackground, - color: t.colors.ghostFocusedContent, - icon: t.colors.ghostFocusedIcon, - }, + }, + subtle: { + backgroundColor: t.colors.ghostBackground, + color: t.colors.ghostContent, + borderColor: t.colors.ghostBorder, + iconColor: t.colors.ghostIcon, + disabled: { + color: t.colors.ghostDisabledContent, + borderColor: t.colors.ghostDisabledBorder, + backgroundColor: t.colors.ghostDisabledBackground, + iconColor: t.colors.ghostDisabledIcon, + }, + hovered: { + backgroundColor: t.colors.ghostHoveredBackground, + color: t.colors.ghostHoveredContent, + borderColor: t.colors.ghostHoveredBorder, + iconColor: t.colors.ghostHoveredIcon, + }, + pressed: { + backgroundColor: t.colors.ghostPressedBackground, + borderColor: t.colors.ghostPressedBorder, + color: t.colors.ghostPressedContent, + icon: t.colors.ghostPressedIcon, + }, + focused: { + borderColor: t.colors.ghostFocusedBorder, + backgroundColor: t.colors.ghostFocusedBackground, + color: t.colors.ghostFocusedContent, + icon: t.colors.ghostFocusedIcon, }, - }); + }, +}); diff --git a/packages/theming/default-theme/src/components/Button/ButtonFontTokens.ts b/packages/theming/default-theme/src/components/Button/ButtonFontTokens.ts index d035e3ed68..1077077d91 100644 --- a/packages/theming/default-theme/src/components/Button/ButtonFontTokens.ts +++ b/packages/theming/default-theme/src/components/Button/ButtonFontTokens.ts @@ -2,19 +2,18 @@ import type { Theme } from '@fluentui-react-native/theme-types'; type fontVariantType = 'secondaryStandard' | 'bodyStandard'; -export const defaultButtonFontTokens = (_t: Theme) => - ({ - medium: { - hasContent: { - variant: 'bodySemibold' as fontVariantType, - }, +export const defaultButtonFontTokens = (_t: Theme) => ({ + medium: { + hasContent: { + variant: 'bodySemibold' as fontVariantType, }, - small: { - hasContent: { - variant: 'secondaryStandard' as fontVariantType, - }, + }, + small: { + hasContent: { + variant: 'secondaryStandard' as fontVariantType, }, - large: { - variant: 'subheaderSemibold' as fontVariantType, - }, - }); + }, + large: { + variant: 'subheaderSemibold' as fontVariantType, + }, +}); diff --git a/packages/theming/default-theme/src/components/Button/ButtonTheme.ts b/packages/theming/default-theme/src/components/Button/ButtonTheme.ts index 917cffa828..45835b5277 100644 --- a/packages/theming/default-theme/src/components/Button/ButtonTheme.ts +++ b/packages/theming/default-theme/src/components/Button/ButtonTheme.ts @@ -1,4 +1,3 @@ - import { immutableMerge } from '@fluentui-react-native/immutable-merge'; import type { Theme } from '@fluentui-react-native/theme-types'; @@ -10,25 +9,21 @@ import { defaultCompoundButtonFontTokens } from './CompoundButtonFontTokens'; import { defaultCompoundButtonTokens } from './CompoundButtonTokens'; import { defaultToggleButtonColorTokens } from './ToggleButtonColorTokens'; -export const defaultButtonTheme = (theme: Theme) => -({ +export const defaultButtonTheme = (theme: Theme) => ({ components: { - Button: immutableMerge( + Button: immutableMerge(defaultButtonColorTokens(theme), defaultButtonFontTokens(theme), defaultButtonTokens(theme)), + CompoundButton: immutableMerge( + defaultButtonTokens(theme), defaultButtonColorTokens(theme), + defaultCompoundButtonColorTokens(theme), + defaultCompoundButtonFontTokens(theme), + defaultCompoundButtonTokens(theme), + ), + ToggleButton: immutableMerge( + defaultButtonTokens(theme), defaultButtonFontTokens(theme), - defaultButtonTokens(theme)), - CompoundButton: - immutableMerge( - defaultButtonTokens(theme), - defaultButtonColorTokens(theme), - defaultCompoundButtonColorTokens(theme), - defaultCompoundButtonFontTokens(theme), - defaultCompoundButtonTokens(theme)), - ToggleButton: - immutableMerge( - defaultButtonTokens(theme), - defaultButtonFontTokens(theme), - defaultButtonColorTokens(theme), - defaultToggleButtonColorTokens(theme)), - } + defaultButtonColorTokens(theme), + defaultToggleButtonColorTokens(theme), + ), + }, }); diff --git a/packages/theming/default-theme/src/components/Button/ButtonTokens.ts b/packages/theming/default-theme/src/components/Button/ButtonTokens.ts index 5146018c03..5a044c9068 100644 --- a/packages/theming/default-theme/src/components/Button/ButtonTokens.ts +++ b/packages/theming/default-theme/src/components/Button/ButtonTokens.ts @@ -3,101 +3,99 @@ import type { DimensionValue } from 'react-native'; import { globalTokens } from '@fluentui-react-native/theme-tokens'; import type { Theme } from '@fluentui-react-native/theme-types'; -export const defaultButtonTokens = (_t: Theme) => - ({ - block: { - width: '100%' as DimensionValue, +export const defaultButtonTokens = (_t: Theme) => ({ + block: { + width: '100%' as DimensionValue, + }, + medium: { + padding: globalTokens.size60 - globalTokens.stroke.width10, + borderWidth: globalTokens.stroke.width10, + iconSize: 16, + focused: { + borderWidth: 0, + padding: globalTokens.size60, }, - medium: { - padding: globalTokens.size60 - globalTokens.stroke.width10, - borderWidth: globalTokens.stroke.width10, - iconSize: 16, - focused: { - borderWidth: 0, - padding: globalTokens.size60, + hasContent: { + minWidth: 96, + paddingHorizontal: globalTokens.size120 - globalTokens.stroke.width10, + hasIconAfter: { + spacingIconContentAfter: globalTokens.size60, }, - hasContent: { - minWidth: 96, - paddingHorizontal: globalTokens.size120 - globalTokens.stroke.width10, - hasIconAfter: { - spacingIconContentAfter: globalTokens.size60, - }, - hasIconBefore: { - spacingIconContentBefore: globalTokens.size60, - }, - focused: { - paddingHorizontal: globalTokens.size120, - }, + hasIconBefore: { + spacingIconContentBefore: globalTokens.size60, }, - }, - small: { - padding: globalTokens.size40 - globalTokens.stroke.width10, - borderWidth: globalTokens.stroke.width10, - iconSize: 16, focused: { - borderWidth: 0, - padding: globalTokens.size40, - }, - hasContent: { - minWidth: 64, - minHeight: 24, - paddingHorizontal: globalTokens.size80 - globalTokens.stroke.width10, - hasIconAfter: { - spacingIconContentAfter: globalTokens.size40, - }, - hasIconBefore: { - spacingIconContentBefore: globalTokens.size40, - }, - focused: { - paddingHorizontal: globalTokens.size80, - }, + paddingHorizontal: globalTokens.size120, }, }, - large: { - padding: globalTokens.size80 - globalTokens.stroke.width10, - borderWidth: globalTokens.stroke.width10, - iconSize: 20, - focused: { - borderWidth: 0, - padding: globalTokens.size80, + }, + small: { + padding: globalTokens.size40 - globalTokens.stroke.width10, + borderWidth: globalTokens.stroke.width10, + iconSize: 16, + focused: { + borderWidth: 0, + padding: globalTokens.size40, + }, + hasContent: { + minWidth: 64, + minHeight: 24, + paddingHorizontal: globalTokens.size80 - globalTokens.stroke.width10, + hasIconAfter: { + spacingIconContentAfter: globalTokens.size40, }, - hasContent: { - minWidth: 96, - paddingHorizontal: globalTokens.size160 - globalTokens.stroke.width10, - hasIconAfter: { - spacingIconContentAfter: globalTokens.size60, - }, - hasIconBefore: { - spacingIconContentBefore: globalTokens.size60, - }, - focused: { - paddingHorizontal: globalTokens.size160, - }, + hasIconBefore: { + spacingIconContentBefore: globalTokens.size40, + }, + focused: { + paddingHorizontal: globalTokens.size80, }, }, - rounded: { - borderRadius: globalTokens.corner.radius40, - }, - circular: { - borderRadius: globalTokens.corner.radiusCircular, + }, + large: { + padding: globalTokens.size80 - globalTokens.stroke.width10, + borderWidth: globalTokens.stroke.width10, + iconSize: 20, + focused: { + borderWidth: 0, + padding: globalTokens.size80, }, - square: { - borderRadius: globalTokens.corner.radiusNone, + hasContent: { + minWidth: 96, + paddingHorizontal: globalTokens.size160 - globalTokens.stroke.width10, + hasIconAfter: { + spacingIconContentAfter: globalTokens.size60, + }, + hasIconBefore: { + spacingIconContentBefore: globalTokens.size60, + }, + focused: { + paddingHorizontal: globalTokens.size160, + }, }, + }, + rounded: { + borderRadius: globalTokens.corner.radius40, + }, + circular: { + borderRadius: globalTokens.corner.radiusCircular, + }, + square: { + borderRadius: globalTokens.corner.radiusNone, + }, -getPlatformSpecificAppearance: (appearance): 'primary' | 'subtle' | 'outline' | null => { - switch (appearance) { - case 'accent': // Included to cover Mobile platform naming guidelines, maps to 'primary'. - return 'primary'; + getPlatformSpecificAppearance: (appearance): 'primary' | 'subtle' | 'outline' | null => { + switch (appearance) { + case 'accent': // Included to cover Mobile platform naming guidelines, maps to 'primary'. + return 'primary'; - case 'primary': - case 'subtle': - case 'outline': // 'Outline' exists only for Mobile platforms, default picked on other platforms. - return appearance; + case 'primary': + case 'subtle': + case 'outline': // 'Outline' exists only for Mobile platforms, default picked on other platforms. + return appearance; - default: + default: return null; - } -} - - }); + } + }, +}); diff --git a/packages/theming/default-theme/src/createDefaultTheme.ts b/packages/theming/default-theme/src/createDefaultTheme.ts index 57eae436c3..7feae70bf6 100644 --- a/packages/theming/default-theme/src/createDefaultTheme.ts +++ b/packages/theming/default-theme/src/createDefaultTheme.ts @@ -9,21 +9,25 @@ import { defaultButtonTheme } from './components/Button/ButtonTheme'; import { defaultFluentDarkTheme, defaultFluentHighConstrastTheme, defaultFluentTheme } from './defaultTheme'; export function createDefaultTheme(options: ThemeOptions = {}): ThemeReference { - const themeRef = new ThemeReference({} as Theme, () => { - const current = getCurrentAppearance(options.appearance, options.defaultAppearance || 'light'); - switch (current) { - case 'light': - return defaultFluentTheme; - case 'dark': - return defaultFluentDarkTheme; - case 'darkElevated': - return defaultFluentDarkTheme; - case 'highContrast': - return defaultFluentHighConstrastTheme; - default: - assertNever(current); - } - }, defaultButtonTheme); + const themeRef = new ThemeReference( + {} as Theme, + () => { + const current = getCurrentAppearance(options.appearance, options.defaultAppearance || 'light'); + switch (current) { + case 'light': + return defaultFluentTheme; + case 'dark': + return defaultFluentDarkTheme; + case 'darkElevated': + return defaultFluentDarkTheme; + case 'highContrast': + return defaultFluentHighConstrastTheme; + default: + assertNever(current); + } + }, + defaultButtonTheme, + ); if (Appearance && options.appearance === 'dynamic') { Appearance.addChangeListener(() => { diff --git a/packages/theming/theme-tokens/src/index.ts b/packages/theming/theme-tokens/src/index.ts index 8eff5a177c..89d2ae8439 100644 --- a/packages/theming/theme-tokens/src/index.ts +++ b/packages/theming/theme-tokens/src/index.ts @@ -2,4 +2,4 @@ export { default as globalTokens } from './tokens-global'; export { getAliasTokens, getShadowTokens } from './getTokens'; export { default as globalTokensWin32 } from './tokens-global.win32'; export { default as globalTokensIOS } from './tokens-global.ios'; -export { default as globalTokensAndroid } from './tokens-global.android'; \ No newline at end of file +export { default as globalTokensAndroid } from './tokens-global.android'; diff --git a/packages/theming/win32-theme/src/__tests__/win32-theme.test.ts b/packages/theming/win32-theme/src/__tests__/win32-theme.test.ts index c2899de65b..449520c0f5 100644 --- a/packages/theming/win32-theme/src/__tests__/win32-theme.test.ts +++ b/packages/theming/win32-theme/src/__tests__/win32-theme.test.ts @@ -120,4 +120,4 @@ describe('verify types', () => { const compoundButtonTokens: CompoundButtonTokens = defaultCompoundButtonTokens(officeTheme); expect(compoundButtonTokens).toBeTruthy(); }); -}) \ No newline at end of file +}); diff --git a/packages/theming/win32-theme/src/components/Button/ButtonFontTokens.ts b/packages/theming/win32-theme/src/components/Button/ButtonFontTokens.ts index d8b31cf61a..fbf6153875 100644 --- a/packages/theming/win32-theme/src/components/Button/ButtonFontTokens.ts +++ b/packages/theming/win32-theme/src/components/Button/ButtonFontTokens.ts @@ -1,9 +1,8 @@ import { globalTokensWin32 as globalTokens } from '@fluentui-react-native/theme-tokens'; import type { Theme } from '@fluentui-react-native/theme-types'; -import type { FontWeight } from '@fluentui-react-native/theme-types' +import type { FontWeight } from '@fluentui-react-native/theme-types'; -export const defaultButtonFontTokens = (t: Theme) => -({ +export const defaultButtonFontTokens = (t: Theme) => ({ medium: { hasContent: { fontFamily: t.typography.families.secondary, diff --git a/packages/theming/win32-theme/src/components/Button/ButtonTheme.ts b/packages/theming/win32-theme/src/components/Button/ButtonTheme.ts index 917cffa828..45835b5277 100644 --- a/packages/theming/win32-theme/src/components/Button/ButtonTheme.ts +++ b/packages/theming/win32-theme/src/components/Button/ButtonTheme.ts @@ -1,4 +1,3 @@ - import { immutableMerge } from '@fluentui-react-native/immutable-merge'; import type { Theme } from '@fluentui-react-native/theme-types'; @@ -10,25 +9,21 @@ import { defaultCompoundButtonFontTokens } from './CompoundButtonFontTokens'; import { defaultCompoundButtonTokens } from './CompoundButtonTokens'; import { defaultToggleButtonColorTokens } from './ToggleButtonColorTokens'; -export const defaultButtonTheme = (theme: Theme) => -({ +export const defaultButtonTheme = (theme: Theme) => ({ components: { - Button: immutableMerge( + Button: immutableMerge(defaultButtonColorTokens(theme), defaultButtonFontTokens(theme), defaultButtonTokens(theme)), + CompoundButton: immutableMerge( + defaultButtonTokens(theme), defaultButtonColorTokens(theme), + defaultCompoundButtonColorTokens(theme), + defaultCompoundButtonFontTokens(theme), + defaultCompoundButtonTokens(theme), + ), + ToggleButton: immutableMerge( + defaultButtonTokens(theme), defaultButtonFontTokens(theme), - defaultButtonTokens(theme)), - CompoundButton: - immutableMerge( - defaultButtonTokens(theme), - defaultButtonColorTokens(theme), - defaultCompoundButtonColorTokens(theme), - defaultCompoundButtonFontTokens(theme), - defaultCompoundButtonTokens(theme)), - ToggleButton: - immutableMerge( - defaultButtonTokens(theme), - defaultButtonFontTokens(theme), - defaultButtonColorTokens(theme), - defaultToggleButtonColorTokens(theme)), - } + defaultButtonColorTokens(theme), + defaultToggleButtonColorTokens(theme), + ), + }, }); diff --git a/packages/theming/win32-theme/src/components/Button/ButtonTokens.ts b/packages/theming/win32-theme/src/components/Button/ButtonTokens.ts index a21573e502..1bb9bb415c 100644 --- a/packages/theming/win32-theme/src/components/Button/ButtonTokens.ts +++ b/packages/theming/win32-theme/src/components/Button/ButtonTokens.ts @@ -6,8 +6,7 @@ import { isHighContrast } from '@fluentui-react-native/theming-utils'; type ButtonSize = 'small'; -export const defaultButtonTokens = (theme: Theme) => -({ +export const defaultButtonTokens = (theme: Theme) => ({ size: 'small' as ButtonSize, borderWidth: globalTokens.stroke.width10, borderInnerWidth: globalTokens.stroke.width10, @@ -179,5 +178,5 @@ export const defaultButtonTokens = (theme: Theme) => default: return null; } - } + }, }); diff --git a/packages/theming/win32-theme/src/components/Button/CompoundButtonColorTokens.ts b/packages/theming/win32-theme/src/components/Button/CompoundButtonColorTokens.ts index f4b463e097..98b0463337 100644 --- a/packages/theming/win32-theme/src/components/Button/CompoundButtonColorTokens.ts +++ b/packages/theming/win32-theme/src/components/Button/CompoundButtonColorTokens.ts @@ -46,7 +46,7 @@ export const defaultCompoundButtonColorTokens = (t: Theme) => { secondaryContentColor: t.colors.neutralForeground2Pressed, }, }, - } + }; }; const highContrastColors = { diff --git a/packages/theming/win32-theme/src/createOfficeTheme.ts b/packages/theming/win32-theme/src/createOfficeTheme.ts index 154422dee6..52e8489d73 100644 --- a/packages/theming/win32-theme/src/createOfficeTheme.ts +++ b/packages/theming/win32-theme/src/createOfficeTheme.ts @@ -2,7 +2,7 @@ import { createDefaultTheme } from '@fluentui-react-native/default-theme'; import { ThemeReference } from '@fluentui-react-native/theme'; import type { OfficePalette, Theme, ThemeOptions } from '@fluentui-react-native/theme-types'; -import {defaultButtonTheme} from './components/Button/ButtonTheme'; +import { defaultButtonTheme } from './components/Button/ButtonTheme'; import { createAliasesFromPalette } from './createAliasesFromPalette'; import { createBrandedThemeWithAlias } from './createBrandedThemeWithAlias'; import { createOfficeColorAliasTokens, createOfficeShadowAliasTokens } from './createOfficeAliasTokens';