fix: editor content being hidden under keyboard on mobile (#1410)
This commit is contained in:
@@ -33,7 +33,7 @@ const VisibilityChangeKey = 'visibilitychange'
|
||||
const MSToWaitAfterIframeLoadToAvoidFlicker = 35
|
||||
|
||||
const ComponentView: FunctionComponent<IProps> = ({ application, onLoad, componentViewer, requestReload }) => {
|
||||
const iframeRef = useRef<HTMLIFrameElement>(null)
|
||||
const iframeRef = useRef<HTMLIFrameElement | null>(null)
|
||||
const [loadTimeout, setLoadTimeout] = useState<ReturnType<typeof setTimeout> | undefined>(undefined)
|
||||
|
||||
const [hasIssueLoading, setHasIssueLoading] = useState(false)
|
||||
@@ -200,6 +200,7 @@ const ComponentView: FunctionComponent<IProps> = ({ application, onLoad, compone
|
||||
{error === ComponentViewerError.MissingUrl && <UrlMissing componentName={component.displayName} />}
|
||||
{component.uuid && isComponentValid && (
|
||||
<iframe
|
||||
className="min-h-[40rem]"
|
||||
ref={iframeRef}
|
||||
onLoad={onIframeLoad}
|
||||
data-component-viewer-id={componentViewer.identifier}
|
||||
|
||||
@@ -68,8 +68,8 @@ const ContentList: FunctionComponent<Props> = ({
|
||||
return (
|
||||
<div
|
||||
className={classNames(
|
||||
'infinite-scroll overflow-y-auto overflow-x-hidden focus:shadow-none focus:outline-none',
|
||||
'md:overflow-y-hidden md:hover:overflow-y-auto',
|
||||
'infinite-scroll max-h-[75vh] overflow-y-auto overflow-x-hidden focus:shadow-none focus:outline-none',
|
||||
'md:max-h-full md:overflow-y-hidden md:hover:overflow-y-auto',
|
||||
'md:hover:[overflow-y:_overlay]',
|
||||
)}
|
||||
id={ElementIds.ContentList}
|
||||
|
||||
@@ -191,7 +191,7 @@ const ContentListView: FunctionComponent<Props> = ({
|
||||
aria-label={'Notes & Files'}
|
||||
ref={itemsViewPanelRef}
|
||||
>
|
||||
<ResponsivePaneContent paneId={AppPaneId.Items}>
|
||||
<ResponsivePaneContent paneId={AppPaneId.Items} contentClassName="min-h-[85vh]">
|
||||
<div id="items-title-bar" className="section-title-bar border-b border-solid border-border">
|
||||
<div id="items-title-bar-container">
|
||||
<input
|
||||
|
||||
@@ -51,7 +51,11 @@ const Navigation: FunctionComponent<Props> = ({ application }) => {
|
||||
className={'sn-component section app-column w-[220px] xsm-only:!w-full sm-only:!w-full'}
|
||||
ref={ref}
|
||||
>
|
||||
<ResponsivePaneContent paneId={AppPaneId.Navigation} contentElementId="navigation-content">
|
||||
<ResponsivePaneContent
|
||||
paneId={AppPaneId.Navigation}
|
||||
contentElementId="navigation-content"
|
||||
contentClassName="min-h-[85vh]"
|
||||
>
|
||||
<div className={'section-title-bar'}>
|
||||
<div className="section-title-bar-header">
|
||||
<div className="title text-sm">
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { classNames } from '@/Utils/ConcatenateClassNames'
|
||||
import { ComponentPropsWithoutRef, ForwardedRef, forwardRef } from 'react'
|
||||
|
||||
// Based on: https://css-tricks.com/auto-growing-inputs-textareas/#aa-other-ideas
|
||||
const AutoresizingNoteViewTextarea = forwardRef(
|
||||
({ value, ...textareaProps }: ComponentPropsWithoutRef<'textarea'>, ref: ForwardedRef<HTMLTextAreaElement>) => {
|
||||
return (
|
||||
<div className="relative inline-grid min-h-[75vh] w-full grid-rows-1 items-stretch md:block md:flex-grow">
|
||||
<pre
|
||||
id="textarea-mobile-resizer"
|
||||
className={classNames(
|
||||
'editable font-editor break-word whitespace-pre-wrap',
|
||||
'invisible [grid-area:1_/_1] md:hidden',
|
||||
)}
|
||||
aria-hidden
|
||||
>
|
||||
{value}{' '}
|
||||
</pre>
|
||||
<textarea
|
||||
value={value}
|
||||
className="editable font-editor [grid-area:1_/_1] md:h-full md:min-h-0"
|
||||
{...textareaProps}
|
||||
ref={ref}
|
||||
></textarea>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
export default AutoresizingNoteViewTextarea
|
||||
@@ -37,6 +37,7 @@ import { reloadFont } from './FontFunctions'
|
||||
import { NoteViewProps } from './NoteViewProps'
|
||||
import IndicatorCircle from '../IndicatorCircle/IndicatorCircle'
|
||||
import { classNames } from '@/Utils/ConcatenateClassNames'
|
||||
import AutoresizingNoteViewTextarea from './AutoresizingTextarea'
|
||||
|
||||
const MINIMUM_STATUS_DURATION = 400
|
||||
const TEXTAREA_DEBOUNCE = 100
|
||||
@@ -889,7 +890,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
|
||||
|
||||
return (
|
||||
<div aria-label="Note" className="section editor sn-component">
|
||||
<div className="flex flex-grow flex-col">
|
||||
<div className="flex-grow flex-col md:flex">
|
||||
{this.state.noteLocked && (
|
||||
<EditingDisabledBanner
|
||||
onMouseLeave={() => {
|
||||
@@ -1021,9 +1022,8 @@ class NoteView extends PureComponent<NoteViewProps, State> {
|
||||
)}
|
||||
|
||||
{this.state.editorStateDidLoad && !this.state.editorComponentViewer && !this.state.textareaUnloading && (
|
||||
<textarea
|
||||
<AutoresizingNoteViewTextarea
|
||||
autoComplete="off"
|
||||
className="editable font-editor"
|
||||
dir="auto"
|
||||
id={ElementIds.NoteTextEditor}
|
||||
onChange={this.onTextAreaChange}
|
||||
@@ -1032,7 +1032,7 @@ class NoteView extends PureComponent<NoteViewProps, State> {
|
||||
onFocus={this.onContentFocus}
|
||||
spellCheck={this.state.spellcheck}
|
||||
ref={(ref) => ref && this.onSystemEditorLoad(ref)}
|
||||
></textarea>
|
||||
/>
|
||||
)}
|
||||
|
||||
{this.state.marginResizersEnabled && this.editorContentRef.current ? (
|
||||
|
||||
@@ -9,6 +9,8 @@ import { getPositionedPopoverStyles } from './GetPositionedPopoverStyles'
|
||||
import { PopoverContentProps } from './Types'
|
||||
import { getPopoverMaxHeight, getAppRect } from './Utils/Rect'
|
||||
import { usePopoverCloseOnClickOutside } from './Utils/usePopoverCloseOnClickOutside'
|
||||
import { fitNodeToMobileScreen } from '@/Utils'
|
||||
import { useDisableBodyScrollOnMobile } from '@/Hooks/useDisableBodyScrollOnMobile'
|
||||
|
||||
const PositionedPopoverContent = ({
|
||||
align = 'end',
|
||||
@@ -49,6 +51,8 @@ const PositionedPopoverContent = ({
|
||||
childPopovers,
|
||||
})
|
||||
|
||||
useDisableBodyScrollOnMobile()
|
||||
|
||||
return (
|
||||
<Portal>
|
||||
<div
|
||||
@@ -63,6 +67,7 @@ const PositionedPopoverContent = ({
|
||||
}}
|
||||
ref={(node) => {
|
||||
setPopoverElement(node)
|
||||
fitNodeToMobileScreen(node)
|
||||
}}
|
||||
data-popover={id}
|
||||
>
|
||||
|
||||
@@ -4,6 +4,8 @@ import { observer } from 'mobx-react-lite'
|
||||
import { PreferencesMenu } from './PreferencesMenu'
|
||||
import PreferencesCanvas from './PreferencesCanvas'
|
||||
import { PreferencesProps } from './PreferencesProps'
|
||||
import { fitNodeToMobileScreen } from '@/Utils'
|
||||
import { useDisableBodyScrollOnMobile } from '@/Hooks/useDisableBodyScrollOnMobile'
|
||||
|
||||
const PreferencesView: FunctionComponent<PreferencesProps> = (props) => {
|
||||
const menu = useMemo(
|
||||
@@ -25,8 +27,13 @@ const PreferencesView: FunctionComponent<PreferencesProps> = (props) => {
|
||||
}
|
||||
}, [props, menu])
|
||||
|
||||
useDisableBodyScrollOnMobile()
|
||||
|
||||
return (
|
||||
<div className="absolute top-0 left-0 z-preferences flex h-full w-full flex-col bg-contrast">
|
||||
<div
|
||||
className="absolute top-0 left-0 z-preferences flex h-full max-h-screen w-full flex-col bg-contrast"
|
||||
ref={fitNodeToMobileScreen}
|
||||
>
|
||||
<div className="flex w-full flex-row items-center justify-between border-b border-solid border-border bg-default px-3 py-2 md:p-3">
|
||||
<div className="hidden h-8 w-8 md:block" />
|
||||
<h1 className="text-base font-bold md:text-lg">Your preferences for Standard Notes</h1>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { classNames } from '@/Utils/ConcatenateClassNames'
|
||||
import { FunctionComponent } from 'react'
|
||||
import { Fragment, FunctionComponent } from 'react'
|
||||
|
||||
type Props = {
|
||||
className?: string
|
||||
@@ -11,10 +11,10 @@ const ModalDialogButtons: FunctionComponent<Props> = ({ children, className }) =
|
||||
<div className={classNames('flex items-center justify-end px-4 py-4', className)}>
|
||||
{children != undefined && Array.isArray(children)
|
||||
? children.map((child, idx, arr) => (
|
||||
<>
|
||||
<Fragment key={idx}>
|
||||
{child}
|
||||
{idx < arr.length - 1 ? <div className="min-w-3" /> : undefined}
|
||||
</>
|
||||
</Fragment>
|
||||
))
|
||||
: children}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user