Skip to content

Commit

Permalink
feat(bottom-sheet): new component (PDS-228) (#645)
Browse files Browse the repository at this point in the history
* feat(bottom-sheet): add base of component

* feat(bottom-sheet): add base of swipe

* feat(bottom-sheet): add swiping

* fix(toast-plate): fix cross color (#642)

* chore(release): 16.1.2 [skip ci]

## [16.1.2](alfa-laboratory/core-components@v16.1.1...v16.1.2) (2021-05-05)

### Bug Fixes

* **toast-plate:** fix cross color ([#642](alfa-laboratory/core-components#642)) ([96a17fd](alfa-laboratory/core-components@96a17fd))

* chore: publish

 - @alfalab/core-components-notification-manager@2.0.2
 - @alfalab/core-components-notification@3.0.2
 - @alfalab/core-components-toast-plate@2.3.1
 - @alfalab/core-components-toast@2.0.1

* fix: update popover versions (#646)

* fix(calendar-input): update popover version

* fix(toast): update popover version

* fix(tooltip): update popover version

* chore(release): 16.1.3 [skip ci]

## [16.1.3](alfa-laboratory/core-components@v16.1.2...v16.1.3) (2021-05-06)

### Bug Fixes

* update popover versions ([#646](alfa-laboratory/core-components#646)) ([199cf80](alfa-laboratory/core-components@199cf80))

* chore: publish

 - @alfalab/core-components-calendar-input@3.0.1
 - @alfalab/core-components-calendar-range@1.3.27
 - @alfalab/core-components-toast@2.0.2
 - @alfalab/core-components-tooltip@3.0.1

* feat(button): add loader minimal display interval (#634)

* feat(button): add loader minimal display interval

* test(button): add some tests

* feat(icon-button): add negative view (#635)

* chore(release): 16.2.0 [skip ci]

# [16.2.0](alfa-laboratory/core-components@v16.1.3...v16.2.0) (2021-05-07)

### Features

* **button:** add loader minimal display interval ([#634](alfa-laboratory/core-components#634)) ([d2f7edc](alfa-laboratory/core-components@d2f7edc))
* **icon-button:** add negative view ([#635](alfa-laboratory/core-components#635)) ([7006116](alfa-laboratory/core-components@7006116))

* chore: publish

 - @alfalab/core-components-button@2.2.0-beta.4
 - @alfalab/core-components-file-upload-item@1.1.2
 - @alfalab/core-components-icon-button@1.3.0

* feat(button): fix version (#648)

* chore(deps-dev): bump json from 9.0.6 to 10.0.0 (#647)

Bumps [json](https://github.com/trentm/json) from 9.0.6 to 10.0.0.
- [Release notes](https://github.com/trentm/json/releases)
- [Changelog](https://github.com/trentm/json/blob/master/CHANGES.md)
- [Commits](trentm/json@9.0.6...10.0.0)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* feat(intl-phone-input): add autocomplete (#630)

* feat(intl-phone-input): draft intlphone input with autocomplete

* chore: pochinil

* feat(intl-phone-input): update country select styles

* feat(intl-phone-input): dont erase country code

* fix(intl-phone-input): fix registry

* fix(intl-phone-input): fix registry

* fix(intl-phone-input): fix build

* fix(intl-phone-input): ts error

* feat(intl-phone-input): return old deps

* feat(intl-phone-input): add new props

* fix(intl-phone-input): pasting starting with 8

* test(intl-phone-input): fix screenshot tests

* fix(intl-phone-input): fix ts error

Co-authored-by: Александр Серов <ARserov@alfabank.ru>
Co-authored-by: reme3d2y <AYatsenko@alfabank.ru>
Co-authored-by: dmitrsavk <dmitrsavk@yandex.ru>

* chore(release): 16.3.0 [skip ci]

# [16.3.0](alfa-laboratory/core-components@v16.2.0...v16.3.0) (2021-05-07)

### Features

* **button:** fix version ([#648](alfa-laboratory/core-components#648)) ([ec51599](alfa-laboratory/core-components@ec51599))
* **intl-phone-input:** add autocomplete ([#630](alfa-laboratory/core-components#630)) ([18b5714](alfa-laboratory/core-components@18b5714))

* chore: publish

 - @alfalab/core-components-alert@1.1.5
 - @alfalab/core-components-amount-input@4.0.15
 - @alfalab/core-components-attach@1.4.22
 - @alfalab/core-components-bank-card@3.4.2
 - @alfalab/core-components-button@2.3.0
 - @alfalab/core-components-calendar-input@3.0.2
 - @alfalab/core-components-calendar-range@1.3.28
 - @alfalab/core-components-calendar-with-skeleton@1.1.2
 - @alfalab/core-components-calendar@1.2.10
 - @alfalab/core-components-confirmation@5.0.0
 - @alfalab/core-components-file-upload-item@1.1.3
 - @alfalab/core-components-icon-button@1.3.1
 - @alfalab/core-components-input-autocomplete@6.1.0
 - @alfalab/core-components-input@6.0.14
 - @alfalab/core-components-intl-phone-input@4.1.0
 - @alfalab/core-components-masked-input@3.2.21
 - @alfalab/core-components-modal@1.4.2
 - @alfalab/core-components-notification-manager@2.0.3
 - @alfalab/core-components-notification@3.0.3
 - @alfalab/core-components-phone-input@4.0.14
 - @alfalab/core-components-picker-button@4.0.2
 - @alfalab/core-components-plate@1.7.2
 - @alfalab/core-components-select@8.0.2
 - @alfalab/core-components-slider-input@3.1.2
 - @alfalab/core-components-toast-plate@2.3.2
 - @alfalab/core-components-toast@2.0.3
 - @alfalab/core-components-with-suffix@2.4.14

* feat(base-modal): add utils export

* test: update snapshots

fix(backdrop): fix opacity

feat(bottom-sheet): updates

docs(bottom-sheet): updates

feat(bottom-sheet): updates

docs(bottom-sheet): updates

feat(bottom-sheet): try scroll

feat(bottom-sheet): try scroll

feat(bottom-sheet): some fixes

feat(bottom-sheet): add footer highlighted

feat(bottom-sheet): updates

feat(bottom-sheet): updates

feat(bottom-sheet): add base of tests

* test(bottom-sheet): fix

* test(bottom-sheet): add some tests

* test(bottom-sheet): add swipe test

* test(bottom-sheet): add some tests

* feat(bottom-sheet): add swipe velocity to sheet

* refactor(bottom-sheet): migrate to base modal (#669)

* refactor(bottom-sheet): migrate to base-modal

* feat(bottom-sheet): updates

Co-authored-by: dmitrsavk <dmitrsavk@yandex.ru>

* feat(bottom-sheet): some design-review fixes

* feat(bottom-sheet): updates

* feat(bottom-sheet): change animation

Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Aleksandr Serov <33555131+AleksandrSerov@users.noreply.github.com>
Co-authored-by: Александр Серов <ARserov@alfabank.ru>
Co-authored-by: reme3d2y <AYatsenko@alfabank.ru>
Co-authored-by: Alexander Yatsenko <reme3d2y@gmail.com>
  • Loading branch information
7 people committed Jun 28, 2021
1 parent 4738a25 commit 1f7391d
Show file tree
Hide file tree
Showing 18 changed files with 1,212 additions and 8 deletions.
28 changes: 22 additions & 6 deletions packages/base-modal/src/Component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import React, {
useEffect,
useMemo,
Ref,
FC,
MutableRefObject,
} from 'react';
import cn from 'classnames';
import mergeRefs from 'react-merge-refs';
Expand All @@ -19,7 +21,7 @@ import { TransitionProps } from 'react-transition-group/Transition';
import FocusLock from 'react-focus-lock';

import { Portal, PortalProps } from '@alfalab/core-components-portal';
import { Backdrop, BackdropProps } from '@alfalab/core-components-backdrop';
import { Backdrop as DefaultBackdrop, BackdropProps } from '@alfalab/core-components-backdrop';
import { Stack, stackingOrder } from '@alfalab/core-components-stack';

import { handleContainer, hasScrollbar, isScrolledToBottom, isScrolledToTop } from './utils';
Expand All @@ -32,6 +34,11 @@ export type BaseModalProps = {
*/
children?: ReactNode;

/**
* Компонент бэкдропа
*/
Backdrop?: FC<BackdropProps>;

/**
* Свойства для Бэкдропа
*/
Expand Down Expand Up @@ -100,7 +107,10 @@ export type BaseModalProps = {
*/
wrapperClassName?: string;

scrollHandler?: 'wrapper' | 'content';
/**
* Обработчик скролла контента
*/
scrollHandler?: 'wrapper' | 'content' | MutableRefObject<HTMLElement | null>;

/**
* Пропсы для анимации (CSSTransition)
Expand Down Expand Up @@ -179,6 +189,7 @@ export const BaseModal = forwardRef<HTMLDivElement, BaseModalProps>(
container,
children,
scrollHandler = 'wrapper',
Backdrop = DefaultBackdrop,
backdropProps = {},
transitionProps = {},
disableBackdropClick,
Expand Down Expand Up @@ -210,7 +221,7 @@ export const BaseModal = forwardRef<HTMLDivElement, BaseModalProps>(
const componentRef = useRef<HTMLDivElement>(null);
const contentRef = useRef<HTMLDivElement>(null);
const wrapperRef = useRef<HTMLDivElement>(null);
const scrollableNodeRef = useRef<HTMLDivElement | null>(null);
const scrollableNodeRef = useRef<HTMLElement | null>(null);
const restoreContainerStyles = useRef<null | Function>(null);

const shouldRender = keepMounted || open || !exited;
Expand Down Expand Up @@ -302,10 +313,15 @@ export const BaseModal = forwardRef<HTMLDivElement, BaseModalProps>(
[disableEscapeKeyDown, handleClose],
);

const getScrollHandler = useCallback(() => {
if (scrollHandler === 'wrapper') return wrapperRef.current;
if (scrollHandler === 'content') return componentRef.current;
return scrollHandler.current || wrapperRef.current;
}, [scrollHandler]);

const handleEntered: Required<TransitionProps>['onEntered'] = useCallback(
(node, isAppearing) => {
scrollableNodeRef.current =
scrollHandler === 'content' ? componentRef.current : wrapperRef.current;
scrollableNodeRef.current = getScrollHandler();

addResizeHandle();

Expand All @@ -320,7 +336,7 @@ export const BaseModal = forwardRef<HTMLDivElement, BaseModalProps>(

if (onMount) onMount();
},
[addResizeHandle, handleScroll, onMount, scrollHandler, transitionProps],
[addResizeHandle, getScrollHandler, handleScroll, onMount, transitionProps],
);

const handleExited: Required<TransitionProps>['onExited'] = useCallback(
Expand Down
1 change: 1 addition & 0 deletions packages/base-modal/src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './Component';
export * from './utils';
4 changes: 2 additions & 2 deletions packages/base-modal/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
export function isScrolledToTop(target: HTMLElement) {
return target.scrollTop === 0;
return target.scrollTop <= 0;
}

export function isScrolledToBottom(target: HTMLElement) {
return target.scrollHeight - target.offsetHeight === target.scrollTop;
return target.scrollHeight - target.offsetHeight <= target.scrollTop;
}

export function hasScrollbar(target: HTMLElement) {
Expand Down
30 changes: 30 additions & 0 deletions packages/bottom-sheet/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "@alfalab/core-components-bottom-sheet",
"version": "1.0.0",
"description": "Bottom sheet mobile component",
"keywords": [],
"license": "MIT",
"main": "dist/index.js",
"module": "./dist/esm/index.js",
"files": [
"dist"
],
"scripts": {
"postinstall": "node ./dist/send-stats.js > /dev/null 2>&1 || exit 0"
},
"publishConfig": {
"access": "public"
},
"peerDependencies": {
"react": "^16.9.0 || ^17.0.1",
"react-dom": "^16.9.0 || ^17.0.1"
},
"dependencies": {
"@alfalab/core-components-backdrop": "^1.1.2",
"@alfalab/core-components-base-modal": "^2.0.0",
"@alfalab/core-components-typography": "^1.4.7",
"classnames": "^2.2.6",
"react-swipeable": "^5.5.0",
"react-transition-group": "^4.3.0"
}
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
160 changes: 160 additions & 0 deletions packages/bottom-sheet/src/__snapshots__/component.test.tsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Bottom sheet Snapshots tests should match snapshot 1`] = `
<body
style="padding-right: 0px; overflow: hidden;"
>
<div />
<div
alfa-portal-container=""
>
<div
data-focus-guard="true"
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
tabindex="0"
/>
<div
data-focus-guard="true"
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
tabindex="1"
/>
<div
data-focus-lock-disabled="false"
>
<div
class="wrapper"
role="dialog"
style="z-index: 100;"
tabindex="-1"
>
<div
style="opacity: 1; transition: opacity 300ms ease-in-out;"
>
<div
aria-hidden="true"
class="backdrop appear appearActive"
/>
</div>
<div
class="component modal appear appearActive"
>
<div
class="content"
>
<div
class="component withTransition"
>
<div
class="marker"
/>
<div
class="scrollableContainer withPadding"
>
<h2
class="component title system-small bold primary"
>
Bottom sheet title
</h2>
<div
class="content"
>
<div>
Bottom sheet content
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div
data-focus-guard="true"
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
tabindex="0"
/>
</div>
</body>
`;

exports[`Bottom sheet Snapshots tests should match snapshot with action button 1`] = `
<body
style="padding-right: 0px; overflow: hidden;"
>
<div
alfa-portal-container=""
>
<div
data-focus-guard="true"
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
tabindex="0"
/>
<div
data-focus-guard="true"
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
tabindex="1"
/>
<div
data-focus-lock-disabled="false"
>
<div
class="wrapper"
role="dialog"
style="z-index: 100;"
tabindex="-1"
>
<div
style="opacity: 1; transition: opacity 300ms ease-in-out;"
>
<div
aria-hidden="true"
class="backdrop appear appearActive"
/>
</div>
<div
class="component modal appear appearActive"
>
<div
class="content"
>
<div
class="component withTransition"
>
<div
class="marker"
/>
<div
class="scrollableContainer"
>
<h2
class="component title system-small bold primary"
>
Bottom sheet title
</h2>
<div
class="content"
>
<div>
Bottom sheet content
</div>
</div>
<div
class="footer"
>
<div />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div
data-focus-guard="true"
style="width: 1px; height: 0px; padding: 0px; overflow: hidden; position: fixed; top: 1px; left: 1px;"
tabindex="0"
/>
</div>
<div />
</body>
`;
76 changes: 76 additions & 0 deletions packages/bottom-sheet/src/component.screenshots.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import {
setupScreenshotTesting,
createSpriteStorybookUrl,
createStorybookUrl,
openBrowserPage,
matchHtml,
closeBrowser,
} from '../../screenshot-utils';

const screenshotTesting = setupScreenshotTesting({
it,
beforeAll,
afterAll,
expect,
});

describe(
'BottomSheet',
screenshotTesting({
cases: [
[
'sprite',
createSpriteStorybookUrl({
componentName: 'BottomSheet',
size: { width: 350, height: 350 },
knobs: {
open: true,
title: 'Заголовок',
children: 'Контент',
},
}),
],
],
screenshotOpts: {
fullPage: true,
},
}),
);

describe('BottomSheet | interactions tests', () => {
test('Open sheet', async () => {
const pageUrl = createStorybookUrl({
componentName: 'BottomSheet',
testStory: false,
});

const { browser, context, page, css } = await openBrowserPage(pageUrl);

try {
await page.click('#button-1');

await matchHtml({
page,
expect,
css,
screenshotOpts: { fullPage: true },
});

await page.reload();

await page.click('#button-2');

await matchHtml({
page,
expect,
css,
screenshotOpts: { fullPage: true },
});
} catch (error) {
// eslint-disable-next-line no-console
console.error(error.message);
} finally {
await closeBrowser({ browser, context, page });
}
});
});

0 comments on commit 1f7391d

Please sign in to comment.