diff --git a/packages/eui/changelogs/upcoming/7776.md b/packages/eui/changelogs/upcoming/7776.md new file mode 100644 index 00000000000..ceaeea60bd3 --- /dev/null +++ b/packages/eui/changelogs/upcoming/7776.md @@ -0,0 +1,3 @@ +**CSS-in-JS conversions** + +- Updated the autofill colors of Chrome (and other webkit browsers) to better match EUI's light and dark mode diff --git a/packages/eui/src/components/form/field_text/field_text.stories.tsx b/packages/eui/src/components/form/field_text/field_text.stories.tsx index 4484f691814..1c4276c974d 100644 --- a/packages/eui/src/components/form/field_text/field_text.stories.tsx +++ b/packages/eui/src/components/form/field_text/field_text.stories.tsx @@ -6,6 +6,7 @@ * Side Public License, v 1. */ +import React from 'react'; import type { Meta, StoryObj } from '@storybook/react'; import { disableStorybookControls, @@ -62,3 +63,24 @@ moveStorybookControlsToCategory(IconShape, [ ]); // Hide props that remove or won't affect the icon or its positioning hideStorybookControls(IconShape, ['controlOnly', 'inputRef']); + +export const AutoFill: Story = { + parameters: { + controls: { include: ['name', 'isInvalid'] }, + loki: { skip: true }, + }, + decorators: [ + (Story) => ( +
+ In Chrome: Type any text, press Enter, then go back and select the + autofill suggestion. Test light+dark mode as well as invalid state +
+
+ + + ), + ], + args: { + name: 'autofill-test', + }, +}; diff --git a/packages/eui/src/components/form/field_text/field_text.styles.ts b/packages/eui/src/components/form/field_text/field_text.styles.ts index 08a6d0a5894..dd1b194e8ca 100644 --- a/packages/eui/src/components/form/field_text/field_text.styles.ts +++ b/packages/eui/src/components/form/field_text/field_text.styles.ts @@ -34,7 +34,9 @@ export const euiFieldTextStyles = (euiThemeContext: UseEuiTheme) => { ${formStyles.readOnly} } - ${formStyles.autoFill} + &:autofill { + ${formStyles.autoFill} + } `, // Skip the css() on the default height to avoid generating a className diff --git a/packages/eui/src/components/form/form.styles.test.tsx b/packages/eui/src/components/form/form.styles.test.tsx index d65acf01cfe..80ff5357c83 100644 --- a/packages/eui/src/components/form/form.styles.test.tsx +++ b/packages/eui/src/components/form/form.styles.test.tsx @@ -31,7 +31,6 @@ describe('euiFormVariables', () => { "backgroundDisabledColor": "#eef1f7", "backgroundReadOnlyColor": "#FFF", "borderColor": "rgba(32,38,47,0.1)", - "controlAutoFillColor": "#343741", "controlBorderRadius": "6px", "controlBoxShadow": "0 0 transparent", "controlCompressedBorderRadius": "4px", @@ -82,13 +81,15 @@ describe('euiFormControlStyles', () => { expect(result.current).toMatchInlineSnapshot(` Object { "autoFill": " - &:-webkit-autofill { - -webkit-text-fill-color: #343741; + &:-webkit-autofill { + -webkit-text-fill-color: #343741; + -webkit-box-shadow: inset 0 0 0 1px rgba(0,107,184,0.2), inset 0 0 0 100vw #f0f7fc; - ~ .euiFormControlLayoutIcons { - color: #343741; - } - }", + &:invalid { + -webkit-box-shadow: inset 0 0 0 1px #BD271E, inset 0 0 0 100vw #f0f7fc; + } + } + ", "compressed": " block-size: 32px; padding-block: 8px; diff --git a/packages/eui/src/components/form/form.styles.ts b/packages/eui/src/components/form/form.styles.ts index 3932e2ebfa0..d47b4940fcc 100644 --- a/packages/eui/src/components/form/form.styles.ts +++ b/packages/eui/src/components/form/form.styles.ts @@ -20,6 +20,7 @@ import { euiCanAnimate, euiFontSize, } from '../../global_styling'; +import { euiButtonColor } from '../../themes/amsterdam/global_styling/mixins'; export const euiFormVariables = (euiThemeContext: UseEuiTheme) => { const { euiTheme, colorMode } = euiThemeContext; @@ -59,10 +60,6 @@ export const euiFormVariables = (euiThemeContext: UseEuiTheme) => { controlPlaceholderText: makeHighContrastColor(euiTheme.colors.subduedText)( backgroundColor ), - controlAutoFillColor: - colorMode === 'LIGHT' - ? euiTheme.colors.darkestShade - : euiTheme.colors.lightShade, inputGroupLabelBackground: isColorDark ? shade(euiTheme.colors.lightShade, 0.15) : tint(euiTheme.colors.lightShade, 0.5), @@ -167,14 +164,7 @@ export const euiFormControlStyles = (euiThemeContext: UseEuiTheme) => { focus: euiFormControlFocusStyles(euiThemeContext), disabled: euiFormControlDisabledStyles(euiThemeContext), readOnly: euiFormControlReadOnlyStyles(euiThemeContext), - autoFill: ` - &:-webkit-autofill { - -webkit-text-fill-color: ${form.controlAutoFillColor}; - - ~ .euiFormControlLayoutIcons { - color: ${form.controlAutoFillColor}; - } - }`, + autoFill: euiFormControlAutoFillStyles(euiThemeContext), }; }; @@ -312,6 +302,41 @@ export const euiFormControlReadOnlyStyles = (euiThemeContext: UseEuiTheme) => { `; }; +export const euiFormControlAutoFillStyles = (euiThemeContext: UseEuiTheme) => { + const { euiTheme, colorMode } = euiThemeContext; + + // Make the text color slightly less prominent than the default colors.text + const textColor = euiTheme.colors.darkestShade; + + const { backgroundColor } = euiButtonColor(euiThemeContext, 'primary'); + const tintedBackgroundColor = + colorMode === 'DARK' + ? shade(backgroundColor, 0.5) + : tint(backgroundColor, 0.7); + // Hacky workaround to background-color, since Chrome doesn't normally allow overriding its styles + // @see https://developer.mozilla.org/en-US/docs/Web/CSS/:autofill#sect1 + const backgroundShadow = `inset 0 0 0 100vw ${tintedBackgroundColor}`; + + // Re-create the border, since the above webkit box shadow overrides the default border box-shadow + // + change the border color to match states, since the underline background gradient no longer works + const borderColor = transparentize(euiTheme.colors.primaryText, 0.2); + const invalidBorder = euiTheme.colors.danger; + const borderShadow = (color: string) => + `inset 0 0 0 ${euiTheme.border.width.thin} ${color}`; + + // These styles only apply/override Chrome/webkit browsers - Firefox does not set autofill styles + return ` + &:-webkit-autofill { + -webkit-text-fill-color: ${textColor}; + -webkit-box-shadow: ${borderShadow(borderColor)}, ${backgroundShadow}; + + &:invalid { + -webkit-box-shadow: ${borderShadow(invalidBorder)}, ${backgroundShadow}; + } + } + `; +}; + const euiPlaceholderPerBrowser = (content: string) => ` &::-webkit-input-placeholder { ${content} } &::-moz-placeholder { ${content} }