From 1b693b8bf405faa212e2d9a97a2d58fa25f58f9f Mon Sep 17 00:00:00 2001 From: Sarah Higley Date: Wed, 28 Dec 2022 04:43:03 -0800 Subject: [PATCH 1/4] fix: Field styles do not wrap SVG status icon in inline parent to avoid layout bugs --- .../src/components/Field/useFieldStyles.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/packages/react-components/react-field/src/components/Field/useFieldStyles.ts b/packages/react-components/react-field/src/components/Field/useFieldStyles.ts index bf37191fc707ae..80c37ca0dee4e9 100644 --- a/packages/react-components/react-field/src/components/Field/useFieldStyles.ts +++ b/packages/react-components/react-field/src/components/Field/useFieldStyles.ts @@ -59,12 +59,18 @@ const useSecondaryTextStyles = makeStyles({ }, }); -const useValidationMessageIconStyles = makeStyles({ +const useValidationMessageStyles = makeStyles({ base: { + display: 'flex', + }, + + icon: { + display: 'block', fontSize: '12px', lineHeight: '12px', verticalAlign: 'middle', marginRight: tokens.spacingHorizontalXS, + marginTop: tokens.spacingVerticalXXS, }, error: { @@ -112,12 +118,12 @@ export const useFieldStyles_unstable = (state: FieldStat ); } - const validationMessageIconStyles = useValidationMessageIconStyles(); + const validationMessageStyles = useValidationMessageStyles(); if (state.validationMessageIcon) { state.validationMessageIcon.className = mergeClasses( classNames.validationMessageIcon, - validationMessageIconStyles.base, - !!validationState && validationMessageIconStyles[validationState], + validationMessageStyles.icon, + !!validationState && validationMessageStyles[validationState], state.validationMessageIcon.className, ); } @@ -126,6 +132,7 @@ export const useFieldStyles_unstable = (state: FieldStat if (state.validationMessage) { state.validationMessage.className = mergeClasses( classNames.validationMessage, + validationMessageStyles.base, secondaryTextStyles.base, horizontal && rootStyles.secondColumn, validationState === 'error' && secondaryTextStyles.error, From 5dd8a3e2c397d85da0ce8ff14823b9db7fb21af9 Mon Sep 17 00:00:00 2001 From: Sarah Higley Date: Wed, 28 Dec 2022 04:43:59 -0800 Subject: [PATCH 2/4] change file --- ...i-react-field-b2bd417e-f8c8-4fba-ab72-7f3c6e0cdfe2.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/@fluentui-react-field-b2bd417e-f8c8-4fba-ab72-7f3c6e0cdfe2.json diff --git a/change/@fluentui-react-field-b2bd417e-f8c8-4fba-ab72-7f3c6e0cdfe2.json b/change/@fluentui-react-field-b2bd417e-f8c8-4fba-ab72-7f3c6e0cdfe2.json new file mode 100644 index 00000000000000..74f703d31a0165 --- /dev/null +++ b/change/@fluentui-react-field-b2bd417e-f8c8-4fba-ab72-7f3c6e0cdfe2.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "fix: Field styles do not wrap SVG status icon in inline parent to avoid layout bugs", + "packageName": "@fluentui/react-field", + "email": "sarah.higley@microsoft.com", + "dependentChangeType": "patch" +} From 3f90aa1684eaa941177be26c2d028ceda00746c9 Mon Sep 17 00:00:00 2001 From: Sarah Higley Date: Mon, 9 Jan 2023 01:06:05 -0800 Subject: [PATCH 3/4] update to grid layout to avoid extra wrapping node --- .../src/components/Field/renderField.tsx | 8 +++-- .../src/components/Field/useFieldStyles.ts | 35 ++++++++++++------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/packages/react-components/react-field/src/components/Field/renderField.tsx b/packages/react-components/react-field/src/components/Field/renderField.tsx index 4727909444e6f2..53a0aed506be24 100644 --- a/packages/react-components/react-field/src/components/Field/renderField.tsx +++ b/packages/react-components/react-field/src/components/Field/renderField.tsx @@ -14,10 +14,12 @@ export const renderField_unstable = (state: FieldState} {slots.validationMessage && ( - + <> {slots.validationMessageIcon && } - {slotProps.validationMessage.children} - + + {slotProps.validationMessage.children} + + )} {slots.hint && } diff --git a/packages/react-components/react-field/src/components/Field/useFieldStyles.ts b/packages/react-components/react-field/src/components/Field/useFieldStyles.ts index 80c37ca0dee4e9..283e9d552e5bd0 100644 --- a/packages/react-components/react-field/src/components/Field/useFieldStyles.ts +++ b/packages/react-components/react-field/src/components/Field/useFieldStyles.ts @@ -19,16 +19,23 @@ const useRootStyles = makeStyles({ base: { display: 'grid', gridAutoFlow: 'row', + gridTemplateColumns: 'auto 1fr', justifyItems: 'start', }, horizontal: { gridTemplateRows: 'auto auto auto auto', - gridTemplateColumns: '1fr 2fr', + gridTemplateColumns: '1fr auto 2fr', + }, + + fullWidth: { + gridColumnStart: '1', + gridColumnEnd: '-1', }, secondColumn: { gridColumnStart: '2', + gridColumnEnd: '-1', }, }); @@ -59,18 +66,18 @@ const useSecondaryTextStyles = makeStyles({ }, }); -const useValidationMessageStyles = makeStyles({ +const useValidationMessageIconStyles = makeStyles({ base: { - display: 'flex', - }, - - icon: { display: 'block', + alignSelf: 'start', fontSize: '12px', lineHeight: '12px', - verticalAlign: 'middle', marginRight: tokens.spacingHorizontalXS, - marginTop: tokens.spacingVerticalXXS, + marginTop: tokens.spacingVerticalXS, + }, + + horizontal: { + gridColumnStart: 2, }, error: { @@ -103,6 +110,7 @@ export const useFieldStyles_unstable = (state: FieldStat if (state.control) { state.control.className = mergeClasses( classNames.control, + !horizontal && rootStyles.fullWidth, horizontal && rootStyles.secondColumn, state.control.className, ); @@ -113,17 +121,19 @@ export const useFieldStyles_unstable = (state: FieldStat state.label.className = mergeClasses( classNames.label, labelStyles.base, + !horizontal && rootStyles.fullWidth, horizontal && labelStyles.horizontal, state.label.className, ); } - const validationMessageStyles = useValidationMessageStyles(); + const validationMessageIconStyles = useValidationMessageIconStyles(); if (state.validationMessageIcon) { state.validationMessageIcon.className = mergeClasses( classNames.validationMessageIcon, - validationMessageStyles.icon, - !!validationState && validationMessageStyles[validationState], + validationMessageIconStyles.base, + horizontal && validationMessageIconStyles.horizontal, + !!validationState && validationMessageIconStyles[validationState], state.validationMessageIcon.className, ); } @@ -132,9 +142,7 @@ export const useFieldStyles_unstable = (state: FieldStat if (state.validationMessage) { state.validationMessage.className = mergeClasses( classNames.validationMessage, - validationMessageStyles.base, secondaryTextStyles.base, - horizontal && rootStyles.secondColumn, validationState === 'error' && secondaryTextStyles.error, state.validationMessage.className, ); @@ -144,6 +152,7 @@ export const useFieldStyles_unstable = (state: FieldStat state.hint.className = mergeClasses( classNames.hint, secondaryTextStyles.base, + rootStyles.fullWidth, horizontal && rootStyles.secondColumn, state.hint.className, ); From 512db83cc8430a5350333fe20f85125645bf42d0 Mon Sep 17 00:00:00 2001 From: Sarah Higley Date: Tue, 10 Jan 2023 16:30:19 -0800 Subject: [PATCH 4/4] use named grid template areas for layout --- .../src/components/Field/renderField.tsx | 10 +-- .../src/components/Field/useFieldStyles.ts | 71 +++++++++++-------- 2 files changed, 44 insertions(+), 37 deletions(-) diff --git a/packages/react-components/react-field/src/components/Field/renderField.tsx b/packages/react-components/react-field/src/components/Field/renderField.tsx index 53a0aed506be24..2f8abff6607cbb 100644 --- a/packages/react-components/react-field/src/components/Field/renderField.tsx +++ b/packages/react-components/react-field/src/components/Field/renderField.tsx @@ -13,14 +13,10 @@ export const renderField_unstable = (state: FieldState} {/* eslint-disable-next-line @typescript-eslint/no-explicit-any */} {slots.control && } - {slots.validationMessage && ( - <> - {slots.validationMessageIcon && } - - {slotProps.validationMessage.children} - - + {slots.validationMessage && slots.validationMessageIcon && ( + )} + {slots.validationMessage && } {slots.hint && } ); diff --git a/packages/react-components/react-field/src/components/Field/useFieldStyles.ts b/packages/react-components/react-field/src/components/Field/useFieldStyles.ts index 283e9d552e5bd0..0a124acb848e22 100644 --- a/packages/react-components/react-field/src/components/Field/useFieldStyles.ts +++ b/packages/react-components/react-field/src/components/Field/useFieldStyles.ts @@ -20,22 +20,50 @@ const useRootStyles = makeStyles({ display: 'grid', gridAutoFlow: 'row', gridTemplateColumns: 'auto 1fr', + gridTemplateAreas: ` + "label label" + "control control" + "validationIcon validationMessage" + "hint hint" + `, justifyItems: 'start', }, horizontal: { - gridTemplateRows: 'auto auto auto auto', - gridTemplateColumns: '1fr auto 2fr', + gridTemplateColumns: '33% auto 1fr', + gridTemplateAreas: ` + "label control control" + "label validationIcon validationMessage" + "label hint hint" + "label . ." + `, }, - fullWidth: { - gridColumnStart: '1', - gridColumnEnd: '-1', + label: { + gridColumnStart: 'label', + gridColumnEnd: 'label', + gridRowStart: 'label', + gridRowEnd: 'label', }, - secondColumn: { - gridColumnStart: '2', - gridColumnEnd: '-1', + control: { + gridColumnStart: 'control', + gridColumnEnd: 'control', + }, + + validationIcon: { + gridColumnStart: 'validationIcon', + gridColumnEnd: 'validationIcon', + }, + + validationMessage: { + gridColumnStart: 'validationMessage', + gridColumnEnd: 'validationMessage', + }, + + hint: { + gridColumnStart: 'hint', + gridColumnEnd: 'hint', }, }); @@ -46,8 +74,6 @@ const useLabelStyles = makeStyles({ }, horizontal: { - gridRowStart: '1', - gridRowEnd: '-1', marginRight: tokens.spacingHorizontalM, alignSelf: 'start', justifySelf: 'stretch', @@ -76,10 +102,6 @@ const useValidationMessageIconStyles = makeStyles({ marginTop: tokens.spacingVerticalXS, }, - horizontal: { - gridColumnStart: 2, - }, - error: { color: tokens.colorPaletteRedForeground1, }, @@ -108,31 +130,20 @@ export const useFieldStyles_unstable = (state: FieldStat ); if (state.control) { - state.control.className = mergeClasses( - classNames.control, - !horizontal && rootStyles.fullWidth, - horizontal && rootStyles.secondColumn, - state.control.className, - ); + state.control.className = mergeClasses(classNames.control, rootStyles.control, state.control.className); } const labelStyles = useLabelStyles(); if (state.label) { - state.label.className = mergeClasses( - classNames.label, - labelStyles.base, - !horizontal && rootStyles.fullWidth, - horizontal && labelStyles.horizontal, - state.label.className, - ); + state.label.className = mergeClasses(classNames.label, rootStyles.label, labelStyles.base, state.label.className); } const validationMessageIconStyles = useValidationMessageIconStyles(); if (state.validationMessageIcon) { state.validationMessageIcon.className = mergeClasses( classNames.validationMessageIcon, + rootStyles.validationIcon, validationMessageIconStyles.base, - horizontal && validationMessageIconStyles.horizontal, !!validationState && validationMessageIconStyles[validationState], state.validationMessageIcon.className, ); @@ -142,6 +153,7 @@ export const useFieldStyles_unstable = (state: FieldStat if (state.validationMessage) { state.validationMessage.className = mergeClasses( classNames.validationMessage, + rootStyles.validationMessage, secondaryTextStyles.base, validationState === 'error' && secondaryTextStyles.error, state.validationMessage.className, @@ -152,8 +164,7 @@ export const useFieldStyles_unstable = (state: FieldStat state.hint.className = mergeClasses( classNames.hint, secondaryTextStyles.base, - rootStyles.fullWidth, - horizontal && rootStyles.secondColumn, + rootStyles.hint, state.hint.className, ); }