From 564cf38ea800d532f56d46ce50dd0f2e59161218 Mon Sep 17 00:00:00 2001 From: Lawrence Win Date: Fri, 24 Mar 2023 13:35:06 -0500 Subject: [PATCH 1/6] On/off text renders with labelPosition=before --- .../components/Switch/src/Switch.styling.ts | 25 +++++++++++++++++-- packages/components/Switch/src/Switch.tsx | 12 ++++++--- .../components/Switch/src/Switch.types.ts | 7 +++++- .../Switch/src/SwitchTokens.mobile.ts | 2 ++ .../components/Switch/src/SwitchTokens.ts | 4 +++ .../Switch/src/SwitchTokens.win32.ts | 2 ++ packages/components/Switch/src/useSwitch.ts | 10 -------- 7 files changed, 46 insertions(+), 16 deletions(-) diff --git a/packages/components/Switch/src/Switch.styling.ts b/packages/components/Switch/src/Switch.styling.ts index 7bae5dec0b..3acb07ee3e 100644 --- a/packages/components/Switch/src/Switch.styling.ts +++ b/packages/components/Switch/src/Switch.styling.ts @@ -102,14 +102,35 @@ export const stylingSettings: UseStylingOptions ({ + style: { + flexDirection: 'column', + alignItems: 'flex-start', + justifyContent: 'center', + }, + }), + [], + ), + onText: buildProps( (tokens: SwitchTokens, theme: Theme) => ({ style: { color: tokens.color, + height: tokens.onTextHeight, ...fontStyles.from(tokens, theme), }, }), - ['color', ...fontStyles.keys], + ['color', 'onTextHeight', ...fontStyles.keys], + ), + offText: buildProps( + (tokens: SwitchTokens, theme: Theme) => ({ + style: { + color: tokens.color, + height: tokens.offTextHeight, + ...fontStyles.from(tokens, theme), + }, + }), + ['color', 'offTextHeight', ...fontStyles.keys], ), }, }; diff --git a/packages/components/Switch/src/Switch.tsx b/packages/components/Switch/src/Switch.tsx index 8a701ac09c..ac71b780a2 100644 --- a/packages/components/Switch/src/Switch.tsx +++ b/packages/components/Switch/src/Switch.tsx @@ -44,7 +44,9 @@ export const Switch = compose({ track: Animated.View, // Conversion from View to Animated.View for Animated API to work thumb: Animated.View, toggleContainer: View, - onOffText: Text, + onOffTextContainer: View, + onText: Text, + offText: Text, }, useRender: (userProps: SwitchProps, useSlots: UseSlots) => { const switchOnSlot = useSlots(userProps, (layer) => switchLookup(layer, { toggled: true, disabled: userProps.disabled }, {})); @@ -68,7 +70,6 @@ export const Switch = compose({ // now return the handler for finishing render return (final: SwitchProps) => { const { label, offText, onText, labelPosition, ...mergedProps } = mergeProps(switchInfo.props, final); - const onOffText = switchInfo.state.toggled ? onText : offText; const displayOnOffText = !!offText || !!onText; const isReduceMotionEnabled = AccessibilityInfo.isReduceMotionEnabled; const thumbAnimation = isReduceMotionEnabled ? { animationClass: 'Ribbon_SwitchThumb' } : null; @@ -80,7 +81,12 @@ export const Switch = compose({ - {displayOnOffText && {onOffText}} + {displayOnOffText && ( + + {onText} + {offText} + + )} ); diff --git a/packages/components/Switch/src/Switch.types.ts b/packages/components/Switch/src/Switch.types.ts index 25f17db8b3..9f046f52f9 100644 --- a/packages/components/Switch/src/Switch.types.ts +++ b/packages/components/Switch/src/Switch.types.ts @@ -109,6 +109,9 @@ export interface SwitchTokens extends LayoutTokens, FontTokens, IBorderTokens, I */ toggleContainerFlexDirection?: ViewStyle['flexDirection']; + onTextHeight?: number; + offTextHeight?: number; + /** * States that can be applied to a switch * Note: 'hovered','focused','before','beforeContent','above' are not supported for Android @@ -202,7 +205,9 @@ export interface SwitchSlotProps { track: IViewProps; thumb: IViewProps; toggleContainer: IViewProps; - onOffText: TextProps; + onOffTextContainer: IViewProps; + onText: TextProps; + offText: TextProps; } export interface SwitchType { diff --git a/packages/components/Switch/src/SwitchTokens.mobile.ts b/packages/components/Switch/src/SwitchTokens.mobile.ts index 43ea59b962..8ef30ed55f 100644 --- a/packages/components/Switch/src/SwitchTokens.mobile.ts +++ b/packages/components/Switch/src/SwitchTokens.mobile.ts @@ -35,6 +35,7 @@ export const defaultSwitchTokens: TokenSettings = (t: Theme toggleOn: { trackColor: t.colors.brandBackground, thumbColor: t.colors.neutralBackgroundLightStatic, + offTextHeight: 0, pressed: { thumbSize: 24, thumbMargin: 4, @@ -49,6 +50,7 @@ export const defaultSwitchTokens: TokenSettings = (t: Theme toggleOff: { trackColor: t.colors.neutralBackground5, thumbColor: t.colors.neutralBackgroundLightStatic, + onTextHeight: 0, pressed: { thumbSize: 24, thumbMargin: 4, diff --git a/packages/components/Switch/src/SwitchTokens.ts b/packages/components/Switch/src/SwitchTokens.ts index 9dd28ddc13..f2c249ec52 100644 --- a/packages/components/Switch/src/SwitchTokens.ts +++ b/packages/components/Switch/src/SwitchTokens.ts @@ -22,6 +22,8 @@ export const defaultSwitchTokens: TokenSettings = (t: Theme trackMarginLeft: 2, trackMarginRight: 2, thumbMargin: 2, + onOpacity: 0, + offOpacity: 0, beforeContent: { trackMarginLeft: 8, @@ -51,6 +53,7 @@ export const defaultSwitchTokens: TokenSettings = (t: Theme thumbColor: t.colors.neutralForegroundInverted, borderColor: t.colors.compoundBrandBackground1, justifyContent: 'flex-end', + offTextHeight: 0, hovered: { trackColor: t.colors.compoundBrandBackground1Hover, thumbColor: t.colors.neutralForegroundInvertedLink, @@ -73,6 +76,7 @@ export const defaultSwitchTokens: TokenSettings = (t: Theme thumbColor: t.colors.neutralStrokeAccessible, borderColor: t.colors.neutralStrokeAccessible, justifyContent: 'flex-start', + onTextHeight: 0, hovered: { trackColor: t.colors.neutralForegroundInvertedLinkHover, thumbColor: t.colors.neutralStrokeAccessibleHover, diff --git a/packages/components/Switch/src/SwitchTokens.win32.ts b/packages/components/Switch/src/SwitchTokens.win32.ts index fce920148d..9834e4a362 100644 --- a/packages/components/Switch/src/SwitchTokens.win32.ts +++ b/packages/components/Switch/src/SwitchTokens.win32.ts @@ -52,6 +52,7 @@ export const defaultSwitchTokens: TokenSettings = (t: Theme thumbColor: isHighContrast(t) ? t.colors.neutralForegroundOnBrandHover : t.colors.neutralForegroundInverted, borderColor: t.colors.compoundBrandBackground1, justifyContent: 'flex-end', + offTextHeight: 0, hovered: { trackColor: isHighContrast(t) ? t.colors.neutralForegroundOnBrandHover : t.colors.compoundBrandBackground1Hover, thumbColor: isHighContrast(t) ? t.colors.compoundBrandBackground1Hover : t.colors.neutralForegroundInvertedLink, @@ -74,6 +75,7 @@ export const defaultSwitchTokens: TokenSettings = (t: Theme thumbColor: isHighContrast(t) ? t.colors.neutralForegroundOnBrand : t.colors.neutralStrokeAccessible, borderColor: isHighContrast(t) ? t.colors.neutralForegroundOnBrand : t.colors.neutralStrokeAccessible, justifyContent: 'flex-start', + onTextHeight: 0, hovered: { trackColor: isHighContrast(t) ? t.colors.brandBackgroundHover : t.colors.neutralForegroundInvertedLinkHover, thumbColor: isHighContrast(t) ? t.colors.neutralForegroundOnBrandHover : t.colors.neutralStrokeAccessibleHover, diff --git a/packages/components/Switch/src/useSwitch.ts b/packages/components/Switch/src/useSwitch.ts index faa6e12539..a06eac16bf 100644 --- a/packages/components/Switch/src/useSwitch.ts +++ b/packages/components/Switch/src/useSwitch.ts @@ -97,16 +97,6 @@ export const useSwitch = (props: SwitchProps, animationConfig?: AnimationConfig) console.warn("The props 'defaultChecked' and 'checked' are mutually exclusive. Use only one of the props, do not use both."); } - if (labelPosition === 'after' || labelPosition === undefined) { - if (__DEV__ && (!!props.onText || !!props.offText)) { - console.warn( - "The prop labelPosition's value of \"after\" and the props 'onText' or 'offText' are mutually exclusive. Try setting 'labelPosition' value to \"before\" or \"above\" instead.", - ); - } - props.onText = null; - props.offText = null; - } - const onClickWithFocus = useOnPressWithFocus(focusRef, toggleCallback); const pressable = usePressableState({ ...rest, onPress: onClickWithFocus }); const onKeyUpProps = useKeyProps(toggleCallback, ' ', 'Enter'); From c767e921ec1e048f332e3feff5cbe97a52fafa5f Mon Sep 17 00:00:00 2001 From: Lawrence Win Date: Fri, 24 Mar 2023 13:36:08 -0500 Subject: [PATCH 2/6] Change files --- ...native-switch-407aa2c6-eb30-4bca-9b93-dc14436e8786.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/@fluentui-react-native-switch-407aa2c6-eb30-4bca-9b93-dc14436e8786.json diff --git a/change/@fluentui-react-native-switch-407aa2c6-eb30-4bca-9b93-dc14436e8786.json b/change/@fluentui-react-native-switch-407aa2c6-eb30-4bca-9b93-dc14436e8786.json new file mode 100644 index 0000000000..436156816f --- /dev/null +++ b/change/@fluentui-react-native-switch-407aa2c6-eb30-4bca-9b93-dc14436e8786.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "On/off text renders with labelPosition=before", + "packageName": "@fluentui-react-native/switch", + "email": "winlarry@microsoft.com", + "dependentChangeType": "patch" +} From d1ee88eb04552b3e74e6264192dadd118e37c475 Mon Sep 17 00:00:00 2001 From: Lawrence Win Date: Wed, 29 Mar 2023 12:56:57 -0700 Subject: [PATCH 3/6] Various changes to switch and test app Remove stray opacity tokens, add comment on height tokens, add extra on/off example in test app. --- apps/fluent-tester/src/TestComponents/Switch/SwitchTest.tsx | 1 + packages/components/Switch/src/Switch.types.ts | 3 +++ packages/components/Switch/src/SwitchTokens.ts | 2 -- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/fluent-tester/src/TestComponents/Switch/SwitchTest.tsx b/apps/fluent-tester/src/TestComponents/Switch/SwitchTest.tsx index d52285588a..84f3be88d0 100644 --- a/apps/fluent-tester/src/TestComponents/Switch/SwitchTest.tsx +++ b/apps/fluent-tester/src/TestComponents/Switch/SwitchTest.tsx @@ -96,6 +96,7 @@ const OnOffText: React.FunctionComponent = () => { + ); }; diff --git a/packages/components/Switch/src/Switch.types.ts b/packages/components/Switch/src/Switch.types.ts index 9f046f52f9..50e572d841 100644 --- a/packages/components/Switch/src/Switch.types.ts +++ b/packages/components/Switch/src/Switch.types.ts @@ -109,6 +109,9 @@ export interface SwitchTokens extends LayoutTokens, FontTokens, IBorderTokens, I */ toggleContainerFlexDirection?: ViewStyle['flexDirection']; + /** + * Height of the on / off texts respectively + */ onTextHeight?: number; offTextHeight?: number; diff --git a/packages/components/Switch/src/SwitchTokens.ts b/packages/components/Switch/src/SwitchTokens.ts index f2c249ec52..15aba6fc0f 100644 --- a/packages/components/Switch/src/SwitchTokens.ts +++ b/packages/components/Switch/src/SwitchTokens.ts @@ -22,8 +22,6 @@ export const defaultSwitchTokens: TokenSettings = (t: Theme trackMarginLeft: 2, trackMarginRight: 2, thumbMargin: 2, - onOpacity: 0, - offOpacity: 0, beforeContent: { trackMarginLeft: 8, From b9ddc13926526acd8e0e7286ab4ebee66399e4fd Mon Sep 17 00:00:00 2001 From: Lawrence Win Date: Wed, 29 Mar 2023 13:26:23 -0700 Subject: [PATCH 4/6] Change files --- ...native-tester-3b07212a-3b7c-48bd-a9ba-516497167dc8.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/@fluentui-react-native-tester-3b07212a-3b7c-48bd-a9ba-516497167dc8.json diff --git a/change/@fluentui-react-native-tester-3b07212a-3b7c-48bd-a9ba-516497167dc8.json b/change/@fluentui-react-native-tester-3b07212a-3b7c-48bd-a9ba-516497167dc8.json new file mode 100644 index 0000000000..bd4600bc4d --- /dev/null +++ b/change/@fluentui-react-native-tester-3b07212a-3b7c-48bd-a9ba-516497167dc8.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Add new example for Switch on/off text section", + "packageName": "@fluentui-react-native/tester", + "email": "winlarry@microsoft.com", + "dependentChangeType": "patch" +} From 8f2f42258515e89186b13d7d97f4313cab7d4e62 Mon Sep 17 00:00:00 2001 From: Lawrence Win Date: Wed, 29 Mar 2023 16:21:53 -0700 Subject: [PATCH 5/6] Remove on/off text height tokens Also removed shifting of label when labelPosition=above with on/off text --- .../components/Switch/src/Switch.styling.ts | 15 +------ packages/components/Switch/src/Switch.tsx | 43 ++++++++++++++----- .../components/Switch/src/Switch.types.ts | 9 +--- .../Switch/src/SwitchTokens.mobile.ts | 2 - .../components/Switch/src/SwitchTokens.ts | 2 - .../Switch/src/SwitchTokens.win32.ts | 2 - 6 files changed, 36 insertions(+), 37 deletions(-) diff --git a/packages/components/Switch/src/Switch.styling.ts b/packages/components/Switch/src/Switch.styling.ts index 3acb07ee3e..364bd4d797 100644 --- a/packages/components/Switch/src/Switch.styling.ts +++ b/packages/components/Switch/src/Switch.styling.ts @@ -112,25 +112,14 @@ export const stylingSettings: UseStylingOptions ({ style: { color: tokens.color, - height: tokens.onTextHeight, ...fontStyles.from(tokens, theme), }, }), - ['color', 'onTextHeight', ...fontStyles.keys], - ), - offText: buildProps( - (tokens: SwitchTokens, theme: Theme) => ({ - style: { - color: tokens.color, - height: tokens.offTextHeight, - ...fontStyles.from(tokens, theme), - }, - }), - ['color', 'offTextHeight', ...fontStyles.keys], + ['color', ...fontStyles.keys], ), }, }; diff --git a/packages/components/Switch/src/Switch.tsx b/packages/components/Switch/src/Switch.tsx index ac71b780a2..440a30176d 100644 --- a/packages/components/Switch/src/Switch.tsx +++ b/packages/components/Switch/src/Switch.tsx @@ -1,9 +1,11 @@ /** @jsx withSlots */ +import type { StyleProp } from 'react-native'; import { View, AccessibilityInfo, Pressable, Animated, Platform } from 'react-native'; import type { UseSlots } from '@fluentui-react-native/framework'; -import { compose, mergeProps, withSlots } from '@fluentui-react-native/framework'; +import { compose, memoize, mergeProps, withSlots } from '@fluentui-react-native/framework'; import { Text } from '@fluentui-react-native/text'; +import type { TextStyle } from '@office-iss/react-native-win32'; import { stylingSettings } from './Switch.styling'; import type { SwitchType, SwitchState, SwitchProps } from './Switch.types'; @@ -45,8 +47,7 @@ export const Switch = compose({ thumb: Animated.View, toggleContainer: View, onOffTextContainer: View, - onText: Text, - offText: Text, + onOffText: Text, }, useRender: (userProps: SwitchProps, useSlots: UseSlots) => { const switchOnSlot = useSlots(userProps, (layer) => switchLookup(layer, { toggled: true, disabled: userProps.disabled }, {})); @@ -70,9 +71,31 @@ export const Switch = compose({ // now return the handler for finishing render return (final: SwitchProps) => { const { label, offText, onText, labelPosition, ...mergedProps } = mergeProps(switchInfo.props, final); - const displayOnOffText = !!offText || !!onText; + const isToggled = switchInfo.state.toggled; const isReduceMotionEnabled = AccessibilityInfo.isReduceMotionEnabled; const thumbAnimation = isReduceMotionEnabled ? { animationClass: 'Ribbon_SwitchThumb' } : null; + + /** + * We render on/off text two ways. If the onText and offText are different lengths, this can cause unwanted shifting of the + * track, if labelPosition = "after", or the label, if labelPosition = "above". In this case, we prevent shifting by rendering + * both texts and setting the correct text height to zero depending on the switch's toggled state. + * + * If labelPosition = "before", none of the other slots will shift, so we can just render one onOffText slot and toggle the displayed + * text. + */ + const displayOnOffText = !!offText || !!onText; + let onOffTextJsx = null; + if (displayOnOffText && labelPosition !== 'before') { + onOffTextJsx = ( + + {onText} + {offText} + + ); + } else if (displayOnOffText) { + onOffTextJsx = {isToggled ? onText : offText}; + } + return ( {label} @@ -81,15 +104,15 @@ export const Switch = compose({ - {displayOnOffText && ( - - {onText} - {offText} - - )} + {onOffTextJsx} ); }; }, }); + +const onOffTextStyleWorker = (text: 'on' | 'off', isOn: boolean): StyleProp => ({ + height: (text === 'on' && isOn) || (text === 'off' && !isOn) ? undefined : 0, +}); +const getOnOffTextStyle = memoize(onOffTextStyleWorker); diff --git a/packages/components/Switch/src/Switch.types.ts b/packages/components/Switch/src/Switch.types.ts index 50e572d841..049251505c 100644 --- a/packages/components/Switch/src/Switch.types.ts +++ b/packages/components/Switch/src/Switch.types.ts @@ -109,12 +109,6 @@ export interface SwitchTokens extends LayoutTokens, FontTokens, IBorderTokens, I */ toggleContainerFlexDirection?: ViewStyle['flexDirection']; - /** - * Height of the on / off texts respectively - */ - onTextHeight?: number; - offTextHeight?: number; - /** * States that can be applied to a switch * Note: 'hovered','focused','before','beforeContent','above' are not supported for Android @@ -209,8 +203,7 @@ export interface SwitchSlotProps { thumb: IViewProps; toggleContainer: IViewProps; onOffTextContainer: IViewProps; - onText: TextProps; - offText: TextProps; + onOffText: TextProps; } export interface SwitchType { diff --git a/packages/components/Switch/src/SwitchTokens.mobile.ts b/packages/components/Switch/src/SwitchTokens.mobile.ts index 8ef30ed55f..43ea59b962 100644 --- a/packages/components/Switch/src/SwitchTokens.mobile.ts +++ b/packages/components/Switch/src/SwitchTokens.mobile.ts @@ -35,7 +35,6 @@ export const defaultSwitchTokens: TokenSettings = (t: Theme toggleOn: { trackColor: t.colors.brandBackground, thumbColor: t.colors.neutralBackgroundLightStatic, - offTextHeight: 0, pressed: { thumbSize: 24, thumbMargin: 4, @@ -50,7 +49,6 @@ export const defaultSwitchTokens: TokenSettings = (t: Theme toggleOff: { trackColor: t.colors.neutralBackground5, thumbColor: t.colors.neutralBackgroundLightStatic, - onTextHeight: 0, pressed: { thumbSize: 24, thumbMargin: 4, diff --git a/packages/components/Switch/src/SwitchTokens.ts b/packages/components/Switch/src/SwitchTokens.ts index 15aba6fc0f..9dd28ddc13 100644 --- a/packages/components/Switch/src/SwitchTokens.ts +++ b/packages/components/Switch/src/SwitchTokens.ts @@ -51,7 +51,6 @@ export const defaultSwitchTokens: TokenSettings = (t: Theme thumbColor: t.colors.neutralForegroundInverted, borderColor: t.colors.compoundBrandBackground1, justifyContent: 'flex-end', - offTextHeight: 0, hovered: { trackColor: t.colors.compoundBrandBackground1Hover, thumbColor: t.colors.neutralForegroundInvertedLink, @@ -74,7 +73,6 @@ export const defaultSwitchTokens: TokenSettings = (t: Theme thumbColor: t.colors.neutralStrokeAccessible, borderColor: t.colors.neutralStrokeAccessible, justifyContent: 'flex-start', - onTextHeight: 0, hovered: { trackColor: t.colors.neutralForegroundInvertedLinkHover, thumbColor: t.colors.neutralStrokeAccessibleHover, diff --git a/packages/components/Switch/src/SwitchTokens.win32.ts b/packages/components/Switch/src/SwitchTokens.win32.ts index 9834e4a362..fce920148d 100644 --- a/packages/components/Switch/src/SwitchTokens.win32.ts +++ b/packages/components/Switch/src/SwitchTokens.win32.ts @@ -52,7 +52,6 @@ export const defaultSwitchTokens: TokenSettings = (t: Theme thumbColor: isHighContrast(t) ? t.colors.neutralForegroundOnBrandHover : t.colors.neutralForegroundInverted, borderColor: t.colors.compoundBrandBackground1, justifyContent: 'flex-end', - offTextHeight: 0, hovered: { trackColor: isHighContrast(t) ? t.colors.neutralForegroundOnBrandHover : t.colors.compoundBrandBackground1Hover, thumbColor: isHighContrast(t) ? t.colors.compoundBrandBackground1Hover : t.colors.neutralForegroundInvertedLink, @@ -75,7 +74,6 @@ export const defaultSwitchTokens: TokenSettings = (t: Theme thumbColor: isHighContrast(t) ? t.colors.neutralForegroundOnBrand : t.colors.neutralStrokeAccessible, borderColor: isHighContrast(t) ? t.colors.neutralForegroundOnBrand : t.colors.neutralStrokeAccessible, justifyContent: 'flex-start', - onTextHeight: 0, hovered: { trackColor: isHighContrast(t) ? t.colors.brandBackgroundHover : t.colors.neutralForegroundInvertedLinkHover, thumbColor: isHighContrast(t) ? t.colors.neutralForegroundOnBrandHover : t.colors.neutralStrokeAccessibleHover, From 02a79161e06af970e0ea202f5e9c285060fc9377 Mon Sep 17 00:00:00 2001 From: Lawrence Win Date: Thu, 30 Mar 2023 14:42:38 -0700 Subject: [PATCH 6/6] Render two texts always --- packages/components/Switch/src/Switch.tsx | 35 ++++++++--------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/packages/components/Switch/src/Switch.tsx b/packages/components/Switch/src/Switch.tsx index 440a30176d..17ccf5eb80 100644 --- a/packages/components/Switch/src/Switch.tsx +++ b/packages/components/Switch/src/Switch.tsx @@ -71,31 +71,10 @@ export const Switch = compose({ // now return the handler for finishing render return (final: SwitchProps) => { const { label, offText, onText, labelPosition, ...mergedProps } = mergeProps(switchInfo.props, final); - const isToggled = switchInfo.state.toggled; + const displayOnOffText = !!offText || !!onText; const isReduceMotionEnabled = AccessibilityInfo.isReduceMotionEnabled; const thumbAnimation = isReduceMotionEnabled ? { animationClass: 'Ribbon_SwitchThumb' } : null; - /** - * We render on/off text two ways. If the onText and offText are different lengths, this can cause unwanted shifting of the - * track, if labelPosition = "after", or the label, if labelPosition = "above". In this case, we prevent shifting by rendering - * both texts and setting the correct text height to zero depending on the switch's toggled state. - * - * If labelPosition = "before", none of the other slots will shift, so we can just render one onOffText slot and toggle the displayed - * text. - */ - const displayOnOffText = !!offText || !!onText; - let onOffTextJsx = null; - if (displayOnOffText && labelPosition !== 'before') { - onOffTextJsx = ( - - {onText} - {offText} - - ); - } else if (displayOnOffText) { - onOffTextJsx = {isToggled ? onText : offText}; - } - return ( {label} @@ -104,7 +83,17 @@ export const Switch = compose({ - {onOffTextJsx} + {displayOnOffText && ( + /** + * If the onText and offText are different lengths, this can cause unwanted shifting of the track, if labelPosition = "after", + * or the label, if labelPosition = "above". We fix this by rendering both texts and setting the height of the text to hide to + * zero. This way, even when not visible, the hidden text still takes up its width to prevent shifting. + */ + + {onText} + {offText} + + )} );