diff --git a/desktop/package-lock.json b/desktop/package-lock.json index bfeb58ceec05..39b186beb022 100644 --- a/desktop/package-lock.json +++ b/desktop/package-lock.json @@ -9,7 +9,7 @@ "dependencies": { "electron-context-menu": "^2.3.0", "electron-log": "^4.4.7", - "electron-serve": "^1.0.0", + "electron-serve": "^1.2.0", "electron-updater": "^6.1.6", "node-machine-id": "^1.1.12" } @@ -145,9 +145,15 @@ "integrity": "sha512-uFZQdgevOp9Fn5lDOrJMU/bmmYxDLZitbIHJM7VXN+cpB59ZnPt1FQL4bOf/Dl2gaIMPYJEfXx38GvJma5iV6A==" }, "node_modules/electron-serve": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/electron-serve/-/electron-serve-1.1.0.tgz", - "integrity": "sha512-tQJBCbXKoKCfkBC143QCqnEtT1s8dNE2V+b/82NF6lxnGO/2Q3a3GSLHtKl3iEDQgdzTf9pH7p418xq2rXbz1Q==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/electron-serve/-/electron-serve-1.2.0.tgz", + "integrity": "sha512-zJG3wisMrDn2G/gnjrhyB074COvly1FnS0U7Edm8bfXLB8MYX7UtwR9/y2LkFreYjzQHm9nEbAfgCmF+9M9LHQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/electron-updater": { "version": "6.1.6", @@ -530,9 +536,9 @@ "integrity": "sha512-uFZQdgevOp9Fn5lDOrJMU/bmmYxDLZitbIHJM7VXN+cpB59ZnPt1FQL4bOf/Dl2gaIMPYJEfXx38GvJma5iV6A==" }, "electron-serve": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/electron-serve/-/electron-serve-1.1.0.tgz", - "integrity": "sha512-tQJBCbXKoKCfkBC143QCqnEtT1s8dNE2V+b/82NF6lxnGO/2Q3a3GSLHtKl3iEDQgdzTf9pH7p418xq2rXbz1Q==" + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/electron-serve/-/electron-serve-1.2.0.tgz", + "integrity": "sha512-zJG3wisMrDn2G/gnjrhyB074COvly1FnS0U7Edm8bfXLB8MYX7UtwR9/y2LkFreYjzQHm9nEbAfgCmF+9M9LHQ==" }, "electron-updater": { "version": "6.1.6", diff --git a/desktop/package.json b/desktop/package.json index a6b92bde81c4..7689c18f0dbd 100644 --- a/desktop/package.json +++ b/desktop/package.json @@ -6,7 +6,7 @@ "dependencies": { "electron-context-menu": "^2.3.0", "electron-log": "^4.4.7", - "electron-serve": "^1.0.0", + "electron-serve": "^1.2.0", "electron-updater": "^6.1.6", "node-machine-id": "^1.1.12" }, diff --git a/src/CONST.ts b/src/CONST.ts index 60a18538f87d..fa8e6d761185 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -255,6 +255,7 @@ const CONST = { BETA_COMMENT_LINKING: 'commentLinking', POLICY_ROOMS: 'policyRooms', VIOLATIONS: 'violations', + REPORT_FIELDS: 'reportFields', }, BUTTON_STATES: { DEFAULT: 'default', diff --git a/src/components/Composer/index.js b/src/components/Composer/index.js index bcd2fde11bce..3af22b63ed69 100755 --- a/src/components/Composer/index.js +++ b/src/components/Composer/index.js @@ -8,6 +8,7 @@ import RNTextInput from '@components/RNTextInput'; import Text from '@components/Text'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import withNavigation from '@components/withNavigation'; +import useIsScrollBarVisible from '@hooks/useIsScrollBarVisible'; import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -86,6 +87,9 @@ const propTypes = { /** Whether the sull composer is open */ isComposerFullSize: PropTypes.bool, + /** Should make the input only scroll inside the element avoid scroll out to parent */ + shouldContainScroll: PropTypes.bool, + ...withLocalizePropTypes, }; @@ -113,6 +117,7 @@ const defaultProps = { checkComposerVisibility: () => false, isReportActionCompose: false, isComposerFullSize: false, + shouldContainScroll: false, }; /** @@ -164,6 +169,7 @@ function Composer({ selection: selectionProp, isReportActionCompose, isComposerFullSize, + shouldContainScroll, ...props }) { const theme = useTheme(); @@ -180,6 +186,7 @@ function Composer({ const [caretContent, setCaretContent] = useState(''); const [valueBeforeCaret, setValueBeforeCaret] = useState(''); const [textInputWidth, setTextInputWidth] = useState(''); + const isScrollBarVisible = useIsScrollBarVisible(textInput, value); useEffect(() => { if (!shouldClear) { @@ -418,18 +425,26 @@ function Composer({ ); - const inputStyleMemo = useMemo( - () => [ + const scrollStyleMemo = useMemo(() => { + if (shouldContainScroll) { + return isScrollBarVisible ? [styles.overflowScroll, styles.overscrollBehaviorContain] : styles.overflowHidden; + } + return [ // We are hiding the scrollbar to prevent it from reducing the text input width, // so we can get the correct scroll height while calculating the number of lines. numberOfLines < maxLines ? styles.overflowHidden : {}, + ]; + }, [shouldContainScroll, isScrollBarVisible, maxLines, numberOfLines, styles.overflowHidden, styles.overflowScroll, styles.overscrollBehaviorContain]); + const inputStyleMemo = useMemo( + () => [ StyleSheet.flatten([style, {outline: 'none'}]), StyleUtils.getComposeTextAreaPadding(numberOfLines, isComposerFullSize), Browser.isMobileSafari() || Browser.isSafari() ? styles.rtlTextRenderForSafari : {}, + scrollStyleMemo, ], - [numberOfLines, maxLines, styles.overflowHidden, styles.rtlTextRenderForSafari, style, StyleUtils, isComposerFullSize], + [numberOfLines, scrollStyleMemo, styles.rtlTextRenderForSafari, style, StyleUtils, isComposerFullSize], ); return ( diff --git a/src/hooks/useIsScrollBarVisible/index.native.ts b/src/hooks/useIsScrollBarVisible/index.native.ts new file mode 100644 index 000000000000..a461e1b7b074 --- /dev/null +++ b/src/hooks/useIsScrollBarVisible/index.native.ts @@ -0,0 +1,7 @@ +/** + * Native doesn't have the DOM, so we just return null. + * + */ +const useIsScrollBarVisible = () => null; + +export default useIsScrollBarVisible; diff --git a/src/hooks/useIsScrollBarVisible/index.ts b/src/hooks/useIsScrollBarVisible/index.ts new file mode 100644 index 000000000000..4ab3a7bb24db --- /dev/null +++ b/src/hooks/useIsScrollBarVisible/index.ts @@ -0,0 +1,28 @@ +import {useCallback, useEffect, useState} from 'react'; + +const useIsScrollBarVisible = (ref: React.RefObject, value: string) => { + const [isScrollBarVisible, setIsScrollBarVisible] = useState(false); + + const handleResize = useCallback(() => { + if (!ref.current) { + return; + } + const {scrollHeight, clientHeight} = ref.current; + setIsScrollBarVisible(scrollHeight > clientHeight); + }, [ref]); + + useEffect(() => { + if (!ref.current || !('ResizeObserver' in (window || {}))) { + return; + } + + const resizeObserver = new ResizeObserver(handleResize); + resizeObserver.observe(ref.current); + return () => { + resizeObserver.disconnect(); + }; + }, [handleResize, ref, value]); + return isScrollBarVisible; +}; + +export default useIsScrollBarVisible; diff --git a/src/libs/Permissions.ts b/src/libs/Permissions.ts index 43e7ef9fbbc8..9cde613ebb5a 100644 --- a/src/libs/Permissions.ts +++ b/src/libs/Permissions.ts @@ -18,6 +18,10 @@ function canUseCommentLinking(betas: OnyxEntry): boolean { return !!betas?.includes(CONST.BETAS.BETA_COMMENT_LINKING) || canUseAllBetas(betas); } +function canUseReportFields(betas: OnyxEntry): boolean { + return !!betas?.includes(CONST.BETAS.REPORT_FIELDS) || canUseAllBetas(betas); +} + /** * We're requiring you to be added to the policy rooms beta on dev, * since contributors have been reporting a number of false issues related to the feature being under development. @@ -45,4 +49,5 @@ export default { canUsePolicyRooms, canUseLinkPreviews, canUseViolations, + canUseReportFields, }; diff --git a/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.js b/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.js index 381aef0a57b2..8def3a53ca0d 100644 --- a/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.js +++ b/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.js @@ -13,6 +13,7 @@ import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; +import * as Browser from '@libs/Browser'; import canFocusInputOnScreenFocus from '@libs/canFocusInputOnScreenFocus'; import compose from '@libs/compose'; import * as ComposerUtils from '@libs/ComposerUtils'; @@ -561,6 +562,7 @@ function ComposerWithSuggestions({ setComposerHeight(composerLayoutHeight); }} onScroll={hideSuggestionMenu} + shouldContainScroll={Browser.isMobileSafari()} />