Skip to content

Commit

Permalink
refactor(BottomSheetController): mv initialSnapPoint to snapPoint
Browse files Browse the repository at this point in the history
  • Loading branch information
inomdzhon committed Nov 29, 2024
1 parent 3408fc9 commit 8275749
Show file tree
Hide file tree
Showing 7 changed files with 422 additions and 455 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export const ModalCardInternal = ({
bottomSheetEnabled,
{
blocked: keyboardOpened,
initialSnapPoint: 'auto',
snapPoint: 'auto',
sheetCSSProperty: '--vkui_internal_ModalCard--translateY',
backdropCSSProperty: '--vkui_internal--modal-overlay--opacity',
onDismiss() {
Expand Down
25 changes: 23 additions & 2 deletions packages/vkui/src/components/ModalPage/ModalPage.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
'use client';

import { useId } from 'react';
import { useId, useMemo } from 'react';
import { ModalContext } from '../../context/ModalContext';
import { inRange } from '../../helpers/range';
import { getNavId } from '../../lib/getNavId';
import { SNAP_POINT_DETENTS, SNAP_POINT_SAFE_RANGE, type SnapPoint } from '../../lib/sheet';
import { warnOnce } from '../../lib/warnOnce';
import { useModalManager } from '../ModalRoot/useModalManager';
import { ModalPageInternal } from './ModalPageInternal';
Expand All @@ -25,12 +27,31 @@ export const ModalPage = ({
onClosed,
size = 's',
settlingHeight = 50,
dynamicContentHeight,
keepMounted = false,
...restProps
}: ModalPageProps) => {
const generatingId = useId();
const id = getNavId({ nav, id: idProp }, warn) || generatingId;

const snapPoint = useMemo((): SnapPoint => {
if (dynamicContentHeight) {
return 'auto';
}

const currentSnapPoint = Math.min(
Math.max(settlingHeight, SNAP_POINT_SAFE_RANGE.LOWER),
SNAP_POINT_DETENTS.LARGE,
);

return {
initial: currentSnapPoint,
detents: inRange(currentSnapPoint, SNAP_POINT_SAFE_RANGE.LOWER, SNAP_POINT_SAFE_RANGE.HIGHEST)
? [SNAP_POINT_DETENTS.MIN, currentSnapPoint, SNAP_POINT_DETENTS.LARGE]
: [SNAP_POINT_DETENTS.MIN, currentSnapPoint],
};
}, [settlingHeight, dynamicContentHeight]);

const { mounted, ...resolvedProps } = useModalManager({
id,
open,
Expand All @@ -53,7 +74,7 @@ export const ModalPage = ({
id={id}
size={size}
aria-labelledby={`${id}-label`}
settlingHeight={settlingHeight}
snapPoint={snapPoint}
{...resolvedProps}
{...restProps}
/>
Expand Down
15 changes: 10 additions & 5 deletions packages/vkui/src/components/ModalPage/ModalPageInternal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import { useExternRef } from '../../hooks/useExternRef';
import { useVirtualKeyboardState } from '../../hooks/useVirtualKeyboardState';
import { Keys, pressedKey } from '../../lib/accessibility';
import { useCSSTransition, type UseCSSTransitionState } from '../../lib/animation';
import { BLOCK_SHEET_BEHAVIOR_DATA_ATTRIBUTE, useBottomSheet } from '../../lib/sheet';
import {
BLOCK_SHEET_BEHAVIOR_DATA_ATTRIBUTE,
type SnapPoint,
useBottomSheet,
} from '../../lib/sheet';
import type { CSSCustomProperties } from '../../types';
import { useScrollLock } from '../AppRoot/ScrollContext';
import { useConfigProvider } from '../ConfigProvider/ConfigProviderContext';
Expand All @@ -33,7 +37,9 @@ const transitionStateClassNames: Partial<Record<UseCSSTransitionState, string>>
exited: styles['documentStateExited'],
};

export interface ModalPageInternalProps extends Omit<ModalPageProps, 'nav' | 'keepMounted'> {
export interface ModalPageInternalProps
extends Omit<ModalPageProps, 'nav' | 'keepMounted' | 'settlingHeight' | 'dynamicContentHeight'> {
snapPoint: SnapPoint;
ModalOverlay?: ComponentType<ModalOverlayProps>;
}

Expand All @@ -51,8 +57,7 @@ export const ModalPageInternal = ({
children,
className,
style,
dynamicContentHeight,
settlingHeight,
snapPoint,
getModalContentRef,
ModalOverlay = ModalOverlayDefault,
modalOverlayTestId,
Expand Down Expand Up @@ -92,7 +97,7 @@ export const ModalPageInternal = ({
const [{ initialStyle, setSheetEl, setSheetScrollEl, setBackdropEl }, bottomSheetEventHandlers] =
useBottomSheet(bottomSheetEnabled, {
blocked: keyboardOpened,
initialSnapPoint: dynamicContentHeight ? 'auto' : settlingHeight,
snapPoint,
sheetCSSProperty: '--vkui_internal_ModalPageDocument--snapPoint',
backdropCSSProperty: '--vkui_internal--modal-overlay--opacity',
onDismiss() {
Expand Down
56 changes: 11 additions & 45 deletions packages/vkui/src/lib/sheet/controllers/BottomSheetController.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { noop } from '@vkontakte/vkjs';
import { clamp } from '../../../helpers/math';
import { inRange } from '../../../helpers/range';
import { rubberbandIfOutOfBounds } from '../../animation';
import { getNearestOverflowAncestor, hasSelectionWithRangeType } from '../../dom';
import { UIPanGestureRecognizer } from '../../touch/UIPanGestureRecognizer';
Expand All @@ -9,19 +8,12 @@ import {
DRAG_THRESHOLDS,
DYNAMIC_SNAP_POINT_DATA,
SNAP_POINT_DETENTS,
SNAP_POINT_SAFE_RANGE,
} from '../constants';
import type { CSSTransitionController } from './CSSTransitionController';

export type InitialSnapPoint = 'auto' | number;

export type SnapPointDetents = [number, number] | [number, number, number];

export type BottomSheetControllerSnapPointData = {
unit: '%' | 'px';
currentSnapPoint: number;
snapPointDetents: SnapPointDetents;
};
export type SnapPoint = 'auto' | { initial: number; detents: SnapPointDetents };

export type BottomSheetControllerOptions = {
sheetScrollEl: HTMLElement | null;
Expand All @@ -31,35 +23,6 @@ export type BottomSheetControllerOptions = {
};

export class BottomSheetController {
static parseInitialSnapPoint(
initialSnapPoint: InitialSnapPoint = SNAP_POINT_DETENTS.MEDIUM,
): BottomSheetControllerSnapPointData {
if (initialSnapPoint === 'auto') {
return {
unit: 'px',
currentSnapPoint: DYNAMIC_SNAP_POINT_DATA.IDLE_POINT_VALUE,
snapPointDetents: [SNAP_POINT_DETENTS.MIN, DYNAMIC_SNAP_POINT_DATA.IDLE_POINT_VALUE],
};
}

const currentSnapPoint = Math.min(
Math.max(initialSnapPoint, SNAP_POINT_SAFE_RANGE.LOWER),
SNAP_POINT_DETENTS.LARGE,
);

return {
unit: '%',
currentSnapPoint,
snapPointDetents: inRange(
currentSnapPoint,
SNAP_POINT_SAFE_RANGE.LOWER,
SNAP_POINT_SAFE_RANGE.HIGHEST,
)
? [SNAP_POINT_DETENTS.MIN, currentSnapPoint, SNAP_POINT_DETENTS.LARGE]
: [SNAP_POINT_DETENTS.MIN, currentSnapPoint],
};
}

constructor(
private readonly sheetEl: HTMLElement,
{
Expand All @@ -76,15 +39,18 @@ export class BottomSheetController {
this.backdropTransitionController = backdropTransitionController;
}

init(initialSnapPoint?: InitialSnapPoint) {
init(snapPoint: SnapPoint) {
this.isInitialized = true;

const { unit, currentSnapPoint, snapPointDetents } =
BottomSheetController.parseInitialSnapPoint(initialSnapPoint);

this.unit = unit;
this.currentSnapPoint = currentSnapPoint;
this.snapPointDetents = snapPointDetents;
if (snapPoint === 'auto') {
this.unit = 'px';
this.currentSnapPoint = DYNAMIC_SNAP_POINT_DATA.IDLE_POINT_VALUE;
this.snapPointDetents = [SNAP_POINT_DETENTS.MIN, DYNAMIC_SNAP_POINT_DATA.IDLE_POINT_VALUE];
} else {
this.unit = '%';
this.currentSnapPoint = snapPoint.initial;
this.snapPointDetents = snapPoint.detents;
}
}

destroy() {
Expand Down
3 changes: 3 additions & 0 deletions packages/vkui/src/lib/sheet/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
export {
BLOCK_SHEET_BEHAVIOR_DATA_ATTRIBUTE_KEY,
BLOCK_SHEET_BEHAVIOR_DATA_ATTRIBUTE,
SNAP_POINT_DETENTS,
SNAP_POINT_SAFE_RANGE,
} from './constants';
export {
type UseBottomSheetOptions,
type UseBottomSheetHandlers,
type UseBottomSheetResult,
useBottomSheet,
} from './useBottomSheet';
export type { SnapPoint } from './controllers/BottomSheetController';
Loading

0 comments on commit 8275749

Please sign in to comment.