Fix sticker pack preview modal scrollbars and modal scroll dividers

This commit is contained in:
Jamie Kyle 2023-08-10 13:40:05 -07:00 committed by Jamie Kyle
parent c2ad69951f
commit ce28993c78
5 changed files with 35 additions and 28 deletions

View file

@ -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;
}
}
} }
} }

View file

@ -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;

View file

@ -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')}

View file

@ -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}

View file

@ -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;