Fix sticker pack preview modal scrollbars and modal scroll dividers
This commit is contained in:
parent
c2ad69951f
commit
ce28993c78
5 changed files with 35 additions and 28 deletions
|
@ -125,10 +125,10 @@
|
||||||
&--has-header#{&}--header-divider {
|
&--has-header#{&}--header-divider {
|
||||||
.module-Modal__body {
|
.module-Modal__body {
|
||||||
@include light-theme() {
|
@include light-theme() {
|
||||||
border-top-color: $color-gray-15;
|
border-top-color: $color-gray-05;
|
||||||
}
|
}
|
||||||
@include dark-theme() {
|
@include dark-theme() {
|
||||||
border-top-color: $color-gray-60;
|
border-top-color: $color-gray-90;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,6 +137,7 @@
|
||||||
.module-Modal__body {
|
.module-Modal__body {
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
border-top: 1px solid transparent;
|
border-top: 1px solid transparent;
|
||||||
|
border-bottom: 1px solid transparent;
|
||||||
|
|
||||||
&--scrolled {
|
&--scrolled {
|
||||||
@include light-theme {
|
@include light-theme {
|
||||||
|
@ -144,7 +145,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@include dark-theme {
|
@include dark-theme {
|
||||||
border-top-color: $color-gray-80;
|
border-top-color: $color-gray-90;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,10 +154,10 @@
|
||||||
&--has-footer#{&}--footer-divider {
|
&--has-footer#{&}--footer-divider {
|
||||||
.module-Modal__body {
|
.module-Modal__body {
|
||||||
@include light-theme() {
|
@include light-theme() {
|
||||||
border-bottom-color: $color-gray-15;
|
border-bottom-color: $color-gray-05;
|
||||||
}
|
}
|
||||||
@include dark-theme() {
|
@include dark-theme() {
|
||||||
border-bottom-color: $color-gray-60;
|
border-bottom-color: $color-gray-90;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -164,6 +165,16 @@
|
||||||
&--has-footer {
|
&--has-footer {
|
||||||
.module-Modal__body {
|
.module-Modal__body {
|
||||||
border-bottom: 1px solid transparent;
|
border-bottom: 1px solid transparent;
|
||||||
|
|
||||||
|
&--overflow:not(&--scrolledToBottom) {
|
||||||
|
@include light-theme {
|
||||||
|
border-bottom-color: $color-gray-05;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include dark-theme {
|
||||||
|
border-bottom-color: $color-gray-90;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -217,8 +217,7 @@
|
||||||
|
|
||||||
.module-sticker-manager__preview-modal {
|
.module-sticker-manager__preview-modal {
|
||||||
&__modal.module-Modal {
|
&__modal.module-Modal {
|
||||||
max-width: 440px;
|
width: fit-content;
|
||||||
width: 440px;
|
|
||||||
}
|
}
|
||||||
&__error {
|
&__error {
|
||||||
color: $color-accent-red;
|
color: $color-accent-red;
|
||||||
|
@ -239,7 +238,6 @@
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-gap: 8px;
|
grid-gap: 8px;
|
||||||
grid-template-columns: repeat(4, 1fr);
|
grid-template-columns: repeat(4, 1fr);
|
||||||
overflow-y: auto;
|
|
||||||
|
|
||||||
&__cell {
|
&__cell {
|
||||||
width: 96px;
|
width: 96px;
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
// Copyright 2022 Signal Messenger, LLC
|
// Copyright 2022 Signal Messenger, LLC
|
||||||
// SPDX-License-Identifier: AGPL-3.0-only
|
// SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
import React, { useEffect } from 'react';
|
import React from 'react';
|
||||||
import { noop } from 'lodash';
|
import { noop } from 'lodash';
|
||||||
import { Button } from './Button';
|
import { Button } from './Button';
|
||||||
import { Modal } from './Modal';
|
import { Modal } from './Modal';
|
||||||
import type { LocalizerType, ThemeType } from '../types/Util';
|
import type { LocalizerType, ThemeType } from '../types/Util';
|
||||||
import type { SmartCompositionTextAreaProps } from '../state/smart/CompositionTextArea';
|
import type { SmartCompositionTextAreaProps } from '../state/smart/CompositionTextArea';
|
||||||
import type { HydratedBodyRangesType } from '../types/BodyRange';
|
import type { HydratedBodyRangesType } from '../types/BodyRange';
|
||||||
|
import { isScrolled, isScrolledToBottom } from '../hooks/useSizeObserver';
|
||||||
|
|
||||||
export type Props = {
|
export type Props = {
|
||||||
i18n: LocalizerType;
|
i18n: LocalizerType;
|
||||||
|
@ -38,8 +39,9 @@ export function AddCaptionModal({
|
||||||
HydratedBodyRangesType | undefined
|
HydratedBodyRangesType | undefined
|
||||||
>();
|
>();
|
||||||
|
|
||||||
const [isScrolledTop, setIsScrolledTop] = React.useState(true);
|
const [scrolled, setScrolled] = React.useState(false);
|
||||||
const [isScrolledBottom, setIsScrolledBottom] = React.useState(true);
|
// We don't know that this is true, but it most likely is
|
||||||
|
const [scrolledToBottom, setScrolledToBottom] = React.useState(true);
|
||||||
|
|
||||||
const scrollerRef = React.useRef<HTMLDivElement>(null);
|
const scrollerRef = React.useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
@ -47,17 +49,10 @@ export function AddCaptionModal({
|
||||||
const updateScrollState = React.useCallback(() => {
|
const updateScrollState = React.useCallback(() => {
|
||||||
const scrollerEl = scrollerRef.current;
|
const scrollerEl = scrollerRef.current;
|
||||||
if (scrollerEl) {
|
if (scrollerEl) {
|
||||||
setIsScrolledTop(scrollerEl.scrollTop === 0);
|
setScrolled(isScrolled(scrollerEl));
|
||||||
setIsScrolledBottom(
|
setScrolledToBottom(isScrolledToBottom(scrollerEl));
|
||||||
scrollerEl.scrollHeight - scrollerEl.scrollTop ===
|
|
||||||
scrollerEl.clientHeight
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}, [scrollerRef]);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
updateScrollState();
|
|
||||||
}, [updateScrollState]);
|
|
||||||
|
|
||||||
const handleSubmit = React.useCallback(() => {
|
const handleSubmit = React.useCallback(() => {
|
||||||
onSubmit(messageText, bodyRanges);
|
onSubmit(messageText, bodyRanges);
|
||||||
|
@ -68,8 +63,8 @@ export function AddCaptionModal({
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
modalName="AddCaptionModal"
|
modalName="AddCaptionModal"
|
||||||
hasXButton
|
hasXButton
|
||||||
hasHeaderDivider={!isScrolledTop}
|
hasHeaderDivider={scrolled}
|
||||||
hasFooterDivider={!isScrolledBottom}
|
hasFooterDivider={!scrolledToBottom}
|
||||||
moduleClassName="AddCaptionModal"
|
moduleClassName="AddCaptionModal"
|
||||||
padded={false}
|
padded={false}
|
||||||
title={i18n('icu:AddCaptionModal__title')}
|
title={i18n('icu:AddCaptionModal__title')}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import * as log from '../logging/log';
|
||||||
import {
|
import {
|
||||||
isOverflowing,
|
isOverflowing,
|
||||||
isScrolled,
|
isScrolled,
|
||||||
|
isScrolledToBottom,
|
||||||
useScrollObserver,
|
useScrollObserver,
|
||||||
} from '../hooks/useSizeObserver';
|
} from '../hooks/useSizeObserver';
|
||||||
|
|
||||||
|
@ -175,6 +176,7 @@ export function ModalPage({
|
||||||
const bodyInnerRef = useRef<HTMLDivElement>(null);
|
const bodyInnerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const [scrolled, setScrolled] = useState(false);
|
const [scrolled, setScrolled] = useState(false);
|
||||||
|
const [scrolledToBottom, setScrolledToBottom] = useState(false);
|
||||||
const [hasOverflow, setHasOverflow] = useState(false);
|
const [hasOverflow, setHasOverflow] = useState(false);
|
||||||
|
|
||||||
const hasHeader = Boolean(hasXButton || title || onBackButtonClick);
|
const hasHeader = Boolean(hasXButton || title || onBackButtonClick);
|
||||||
|
@ -182,6 +184,7 @@ export function ModalPage({
|
||||||
|
|
||||||
useScrollObserver(bodyRef, bodyInnerRef, scroll => {
|
useScrollObserver(bodyRef, bodyInnerRef, scroll => {
|
||||||
setScrolled(isScrolled(scroll));
|
setScrolled(isScrolled(scroll));
|
||||||
|
setScrolledToBottom(isScrolledToBottom(scroll));
|
||||||
setHasOverflow(isOverflowing(scroll));
|
setHasOverflow(isOverflowing(scroll));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -250,6 +253,7 @@ export function ModalPage({
|
||||||
className={classNames(
|
className={classNames(
|
||||||
getClassName('__body'),
|
getClassName('__body'),
|
||||||
scrolled ? getClassName('__body--scrolled') : null,
|
scrolled ? getClassName('__body--scrolled') : null,
|
||||||
|
scrolledToBottom ? getClassName('__body--scrolledToBottom') : null,
|
||||||
hasOverflow || scrolled ? getClassName('__body--overflow') : null
|
hasOverflow || scrolled ? getClassName('__body--overflow') : null
|
||||||
)}
|
)}
|
||||||
ref={bodyRef}
|
ref={bodyRef}
|
||||||
|
|
|
@ -93,11 +93,10 @@ export function SizeObserver({
|
||||||
return children(ref, size);
|
return children(ref, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Scroll = Readonly<{
|
// Note: You should just be able to pass an element into utils if you want.
|
||||||
scrollTop: number;
|
export type Scroll = Readonly<
|
||||||
scrollHeight: number;
|
Pick<Element, 'scrollTop' | 'scrollHeight' | 'clientHeight'>
|
||||||
clientHeight: number;
|
>;
|
||||||
}>;
|
|
||||||
|
|
||||||
export type ScrollChangeHandler = (scroll: Scroll) => void;
|
export type ScrollChangeHandler = (scroll: Scroll) => void;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue