From 9d22a45679e58d5e1638beb5a0e367dce05f6909 Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 20 Dec 2023 14:27:29 +0700 Subject: [PATCH 1/4] fix: 33318 --- src/components/ThemeProvider.tsx | 7 +++- src/libs/DomUtils/index.native.ts | 6 ++++ src/libs/DomUtils/index.ts | 57 +++++++++++++++++++++++++++++++ web/index.html | 26 -------------- 4 files changed, 69 insertions(+), 27 deletions(-) diff --git a/src/components/ThemeProvider.tsx b/src/components/ThemeProvider.tsx index 34bc32be9c99..41423991f051 100644 --- a/src/components/ThemeProvider.tsx +++ b/src/components/ThemeProvider.tsx @@ -1,10 +1,11 @@ /* eslint-disable react/jsx-props-no-spreading */ import PropTypes from 'prop-types'; -import React, {useMemo} from 'react'; +import React, {useEffect, useMemo} from 'react'; import useThemePreferenceWithStaticOverride from '@hooks/useThemePreferenceWithStaticOverride'; import themes from '@styles/theme'; import ThemeContext from '@styles/theme/context/ThemeContext'; import {ThemePreferenceWithoutSystem} from '@styles/theme/types'; +import DomUtils from '@libs/DomUtils'; const propTypes = { /** Rendered child component */ @@ -20,6 +21,10 @@ function ThemeProvider({children, theme: staticThemePreference}: ThemeProviderPr const theme = useMemo(() => themes[themePreference], [themePreference]); + useEffect(() => { + DomUtils.addCSS(DomUtils.getAutofilledInputStyle(theme.text), 'autofill-input') + }, [theme.text]); + return {children}; } diff --git a/src/libs/DomUtils/index.native.ts b/src/libs/DomUtils/index.native.ts index 0864f1a16ac0..f161e0eeeeb2 100644 --- a/src/libs/DomUtils/index.native.ts +++ b/src/libs/DomUtils/index.native.ts @@ -2,6 +2,10 @@ import GetActiveElement from './types'; const getActiveElement: GetActiveElement = () => null; +const addCSS = () => null; + +const getAutofilledInputStyle = () => null; + const requestAnimationFrame = (callback: () => void) => { if (!callback) { return; @@ -11,6 +15,8 @@ const requestAnimationFrame = (callback: () => void) => { }; export default { + addCSS, + getAutofilledInputStyle, getActiveElement, requestAnimationFrame, }; diff --git a/src/libs/DomUtils/index.ts b/src/libs/DomUtils/index.ts index 6a2eed57fbe6..001d57745f53 100644 --- a/src/libs/DomUtils/index.ts +++ b/src/libs/DomUtils/index.ts @@ -2,7 +2,64 @@ import GetActiveElement from './types'; const getActiveElement: GetActiveElement = () => document.activeElement; +const addCSS = (css: string, styleId: string) => { + var head = document.getElementsByTagName('head')[0]; + var existingStyle = document.getElementById(styleId); + + if (existingStyle) { + // If style tag with the specified ID exists, update its content + if (existingStyle.styleSheet) { // IE + existingStyle.styleSheet.cssText = css; + } else { // the world + existingStyle.innerHTML = css; + } + } else { + // If style tag doesn't exist, create a new one + var s = document.createElement('style'); + s.setAttribute("id", styleId); + s.setAttribute('type', 'text/css'); + + if (s.styleSheet) { // IE + s.styleSheet.cssText = css; + } else { // the world + s.appendChild(document.createTextNode(css)); + } + + head.appendChild(s); + } +} + +/* Customizes the background and text colors for autofill inputs in Chrome */ +/* Chrome on iOS does not support the autofill pseudo class because it is a non-standard webkit feature. +We should rely on the chrome-autofilled property being added to the input when users use auto-fill */ +const getAutofilledInputStyle = (inputTextColor: string) => ` + input[chrome-autofilled], + input[chrome-autofilled]:hover, + input[chrome-autofilled]:focus, + textarea[chrome-autofilled], + textarea[chrome-autofilled]:hover, + textarea[chrome-autofilled]:focus, + select[chrome-autofilled], + select[chrome-autofilled]:hover, + select[chrome-autofilled]:focus, + input:-webkit-autofill, + input:-webkit-autofill:hover, + input:-webkit-autofill:focus, + textarea:-webkit-autofill, + textarea:-webkit-autofill:hover, + textarea:-webkit-autofill:focus, + select:-webkit-autofill, + select:-webkit-autofill:hover, + select:-webkit-autofill:focus { + -webkit-background-clip: text; + -webkit-text-fill-color: ${inputTextColor}; + caret-color: ${inputTextColor}; + } +`; + export default { + addCSS, + getAutofilledInputStyle, getActiveElement, requestAnimationFrame: window.requestAnimationFrame.bind(window), }; diff --git a/web/index.html b/web/index.html index 967873fe586c..e83f4527a1a3 100644 --- a/web/index.html +++ b/web/index.html @@ -70,32 +70,6 @@ display: none; } - /* Customizes the background and text colors for autofill inputs in Chrome */ - /* Chrome on iOS does not support the autofill pseudo class because it is a non-standard webkit feature. - We should rely on the chrome-autofilled property being added to the input when users use auto-fill */ - input[chrome-autofilled], - input[chrome-autofilled]:hover, - input[chrome-autofilled]:focus, - textarea[chrome-autofilled], - textarea[chrome-autofilled]:hover, - textarea[chrome-autofilled]:focus, - select[chrome-autofilled], - select[chrome-autofilled]:hover, - select[chrome-autofilled]:focus, - input:-webkit-autofill, - input:-webkit-autofill:hover, - input:-webkit-autofill:focus, - textarea:-webkit-autofill, - textarea:-webkit-autofill:hover, - textarea:-webkit-autofill:focus, - select:-webkit-autofill, - select:-webkit-autofill:hover, - select:-webkit-autofill:focus { - -webkit-background-clip: text; - -webkit-text-fill-color: #ffffff; - caret-color: #ffffff; - } - /* Prevent autofill from overlapping with the input label in Chrome */ div:has(input:-webkit-autofill, input[chrome-autofilled]) > label { transform: translateY(var(--active-label-translate-y)) scale(var(--active-label-scale)) !important; From 81142e7cf9191e19c461e8704c27f2fcbe54117a Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 22 Dec 2023 15:54:36 +0700 Subject: [PATCH 2/4] fix ts error --- src/components/ThemeProvider.tsx | 4 ++-- src/libs/DomUtils/index.ts | 40 +++++++++++++++++--------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/components/ThemeProvider.tsx b/src/components/ThemeProvider.tsx index 41423991f051..5fe9bfec1e4a 100644 --- a/src/components/ThemeProvider.tsx +++ b/src/components/ThemeProvider.tsx @@ -2,10 +2,10 @@ import PropTypes from 'prop-types'; import React, {useEffect, useMemo} from 'react'; import useThemePreferenceWithStaticOverride from '@hooks/useThemePreferenceWithStaticOverride'; +import DomUtils from '@libs/DomUtils'; import themes from '@styles/theme'; import ThemeContext from '@styles/theme/context/ThemeContext'; import {ThemePreferenceWithoutSystem} from '@styles/theme/types'; -import DomUtils from '@libs/DomUtils'; const propTypes = { /** Rendered child component */ @@ -22,7 +22,7 @@ function ThemeProvider({children, theme: staticThemePreference}: ThemeProviderPr const theme = useMemo(() => themes[themePreference], [themePreference]); useEffect(() => { - DomUtils.addCSS(DomUtils.getAutofilledInputStyle(theme.text), 'autofill-input') + DomUtils.addCSS(DomUtils.getAutofilledInputStyle(theme.text), 'autofill-input'); }, [theme.text]); return {children}; diff --git a/src/libs/DomUtils/index.ts b/src/libs/DomUtils/index.ts index 001d57745f53..17dce79cf503 100644 --- a/src/libs/DomUtils/index.ts +++ b/src/libs/DomUtils/index.ts @@ -3,35 +3,37 @@ import GetActiveElement from './types'; const getActiveElement: GetActiveElement = () => document.activeElement; const addCSS = (css: string, styleId: string) => { - var head = document.getElementsByTagName('head')[0]; - var existingStyle = document.getElementById(styleId); + const existingStyle = document.getElementById(styleId); if (existingStyle) { - // If style tag with the specified ID exists, update its content - if (existingStyle.styleSheet) { // IE - existingStyle.styleSheet.cssText = css; - } else { // the world + if ('styleSheet' in existingStyle) { + // Supports IE8 and below + (existingStyle.styleSheet as any).cssText = css; + } else { existingStyle.innerHTML = css; } } else { - // If style tag doesn't exist, create a new one - var s = document.createElement('style'); - s.setAttribute("id", styleId); - s.setAttribute('type', 'text/css'); + const styleElement = document.createElement('style'); + styleElement.setAttribute('id', styleId); + styleElement.setAttribute('type', 'text/css'); - if (s.styleSheet) { // IE - s.styleSheet.cssText = css; - } else { // the world - s.appendChild(document.createTextNode(css)); + if ('styleSheet' in styleElement) { + // Supports IE8 and below + (styleElement.styleSheet as any).cssText = css; + } else { + styleElement.appendChild(document.createTextNode(css)); } - head.appendChild(s); + const head = document.getElementsByTagName('head')[0]; + head.appendChild(styleElement); } -} +}; -/* Customizes the background and text colors for autofill inputs in Chrome */ -/* Chrome on iOS does not support the autofill pseudo class because it is a non-standard webkit feature. -We should rely on the chrome-autofilled property being added to the input when users use auto-fill */ +/** + * Customizes the background and text colors for autofill inputs in Chrome + * Chrome on iOS does not support the autofill pseudo class because it is a non-standard webkit feature. + * We should rely on the chrome-autofilled property being added to the input when users use auto-fill + */ const getAutofilledInputStyle = (inputTextColor: string) => ` input[chrome-autofilled], input[chrome-autofilled]:hover, From d5ba5b5f9d82cb2fa7027466de5ac7864dad41c9 Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 22 Dec 2023 16:17:26 +0700 Subject: [PATCH 3/4] fix lint --- src/libs/DomUtils/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/DomUtils/index.ts b/src/libs/DomUtils/index.ts index 17dce79cf503..25700ca015bb 100644 --- a/src/libs/DomUtils/index.ts +++ b/src/libs/DomUtils/index.ts @@ -8,6 +8,7 @@ const addCSS = (css: string, styleId: string) => { if (existingStyle) { if ('styleSheet' in existingStyle) { // Supports IE8 and below + // eslint-disable-next-line @typescript-eslint/no-explicit-any (existingStyle.styleSheet as any).cssText = css; } else { existingStyle.innerHTML = css; @@ -19,6 +20,7 @@ const addCSS = (css: string, styleId: string) => { if ('styleSheet' in styleElement) { // Supports IE8 and below + // eslint-disable-next-line @typescript-eslint/no-explicit-any (styleElement.styleSheet as any).cssText = css; } else { styleElement.appendChild(document.createTextNode(css)); From 4f170a18ff3ef16a4b7b47247f8d2154a1468f36 Mon Sep 17 00:00:00 2001 From: Tienifr <113963320+tienifr@users.noreply.github.com> Date: Mon, 15 Jan 2024 14:13:35 +0700 Subject: [PATCH 4/4] Noop function Co-authored-by: Aimane Chnaif <96077027+aimane-chnaif@users.noreply.github.com> --- src/libs/DomUtils/index.native.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/DomUtils/index.native.ts b/src/libs/DomUtils/index.native.ts index 42b19c1cad20..eac988e55f1b 100644 --- a/src/libs/DomUtils/index.native.ts +++ b/src/libs/DomUtils/index.native.ts @@ -2,7 +2,7 @@ import type GetActiveElement from './types'; const getActiveElement: GetActiveElement = () => null; -const addCSS = () => null; +const addCSS = () => {}; const getAutofilledInputStyle = () => null;