Skip to content

Commit

Permalink
feat(calendar-with-skeleton): add component
Browse files Browse the repository at this point in the history
  • Loading branch information
reme3d2y committed Apr 9, 2021
1 parent 2b87958 commit e940c88
Show file tree
Hide file tree
Showing 9 changed files with 905 additions and 1 deletion.
13 changes: 12 additions & 1 deletion packages/calendar-input/src/Component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ import React, {
MouseEvent,
KeyboardEvent,
useEffect,
ElementType,
} from 'react';
import cn from 'classnames';
import { MaskedInput, MaskedInputProps } from '@alfalab/core-components-masked-input';
import { Calendar, CalendarProps, dateInLimits } from '@alfalab/core-components-calendar';
import {
Calendar as DefaultCalendar,
CalendarProps,
dateInLimits,
} from '@alfalab/core-components-calendar';
import { Popover } from '@alfalab/core-components-popover';
import mergeRefs from 'react-merge-refs';
import {
Expand Down Expand Up @@ -96,6 +101,11 @@ export type CalendarInputProps = Omit<
*/
mobileMode?: 'native' | 'popover' | 'input';

/**
* Компонент календаря
*/
Calendar?: ElementType<CalendarProps>;

/**
* Обработчик изменения значения
*/
Expand Down Expand Up @@ -146,6 +156,7 @@ export const CalendarInput = forwardRef<HTMLInputElement, CalendarInputProps>(
onInputChange,
onCalendarChange,
readOnly,
Calendar = DefaultCalendar,
...restProps
},
ref,
Expand Down
25 changes: 25 additions & 0 deletions packages/calendar-with-skeleton/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "@alfalab/core-components-calendar-with-skeleton",
"version": "1.0.0",
"description": "CalendarWithSkeleton component",
"keywords": [],
"license": "MIT",
"main": "dist/index.js",
"module": "./dist/esm/index.js",
"files": [
"dist"
],
"publishConfig": {
"access": "public"
},
"peerDependencies": {
"react": "^16.9.0 || ^17.0.1",
"react-dom": "^16.9.0 || ^17.0.1"
},
"dependencies": {
"@alfalab/core-components-calendar": "^1.2.5",
"@alfalab/core-components-skeleton": "^1.3.4",
"classnames": "^2.2.6",
"react-transition-group": "^4.3.0"
}
}
91 changes: 91 additions & 0 deletions packages/calendar-with-skeleton/src/Component.stories.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { text, boolean } from '@storybook/addon-knobs';
import { Meta, Story, Preview, Props } from '@storybook/addon-docs/blocks';
import { Container, Row, Col } from 'storybook/blocks/grid';
import { ComponentHeader } from 'storybook/blocks/component-header';

import { CalendarWithSkeleton } from '.';
import { name, version } from '../package.json';

import { CalendarInput } from '../../calendar-input/src';
import { CalendarRange } from '../../calendar-range/src';
import { Button } from '../../button/src';


<Meta
title='Компоненты'
component={CalendarWithSkeleton}
parameters={{ 'theme-switcher': { themes: ['click'] } }}
/>


<!-- Canvas -->

<Story name='CalendarWithSkeleton'>
{React.createElement(() => {
const [visible, setVisible] = React.useState(false);
return (
<>
<CalendarWithSkeleton calendarVisible={ visible }/>
<Button size="xs" onClick={() => setVisible(!visible)}>toggle</Button>
</>
);
})}
</Story>


<!-- Docs -->

<ComponentHeader
name='CalendarWithSkeleton'
version={version}
package='@alfalab/core-components-calendar-with-skeleton'
stage={1}
design='https://www.figma.com/file/uGndMZufgvqxaNQTaNTEjG/B2B-Web-Components?node-id=3911%3A22929'
/>

```tsx
import { CalendarWithSkeleton } from '@alfalab/core-components-calendar-with-skeleton';
```

Календарь с возможностью скелетной загрузки

<Preview>
{React.createElement(() => {
const [visible, setVisible] = React.useState(false);
return (
<>
<CalendarWithSkeleton calendarVisible={ visible }/>
<Button size="xs" onClick={() => setVisible(!visible)}>toggle</Button>
</>
);
})}
</Preview>

<Props of={CalendarWithSkeleton} />

## Использование с другими компонентами

<Preview>
{React.createElement(() => {
return (
<CalendarInput
Calendar={CalendarWithSkeleton}
calendarProps={{ calendarVisible: false }}
/>
);
})}
</Preview>

<Preview>
{React.createElement(() => {
return (
<CalendarRange
inputFromProps={{
Calendar: CalendarWithSkeleton,
disabled: true,
calendarProps: {calendarVisible: false }
}}
/>
);
})}
</Preview>
36 changes: 36 additions & 0 deletions packages/calendar-with-skeleton/src/Component.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';
import { render } from '@testing-library/react';

import { CalendarWithSkeleton } from './Component';

jest.useFakeTimers();

describe('Calendar', () => {
const defaultValue = new Date('November 30, 2020 00:00:00').getTime();

describe('Render tests', () => {
test('should render skeleton when calendarVisible=`false`', () => {
const { container } = render(
<CalendarWithSkeleton value={defaultValue} calendarVisible={false} />,
);

jest.advanceTimersByTime(300);

expect(container).toMatchSnapshot();
});

test('should render calendar when calendarVisible=`true`', () => {
const { container } = render(
<CalendarWithSkeleton value={defaultValue} calendarVisible={true} />,
);

expect(container).toMatchSnapshot();
});

test('should unmount without errors', () => {
const { unmount } = render(<CalendarWithSkeleton value={defaultValue} />);

expect(unmount).not.toThrowError();
});
});
});
51 changes: 51 additions & 0 deletions packages/calendar-with-skeleton/src/Component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React, { forwardRef } from 'react';

import { CSSTransition } from 'react-transition-group';

import { Skeleton } from '@alfalab/core-components-skeleton';
import { Calendar, CalendarProps } from '@alfalab/core-components-calendar';

import styles from './index.module.css';

export type CalendarWithSkeletonProps = CalendarProps & {
/**
* Флаг включения анимации скелета
*/
animate?: boolean;

/**
* Флаг управлением видимостью календаря
*/
calendarVisible?: boolean;
};

export const CalendarWithSkeleton = forwardRef<HTMLDivElement, CalendarWithSkeletonProps>(
({ calendarVisible = true, animate = true, ...restProps }, ref) => {
const skeletonProps = { visible: true, animate };

return (
<div className={styles.component}>
{calendarVisible && <Calendar ref={ref} {...restProps} />}

<CSSTransition
in={!calendarVisible}
timeout={200}
unmountOnExit={true}
classNames={styles}
>
<div className={styles.skeleton} ref={ref}>
<Skeleton {...skeletonProps} className={styles.header} />

<Skeleton {...skeletonProps} className={styles.weekDays} />

<Skeleton {...skeletonProps} className={styles.row} />
<Skeleton {...skeletonProps} className={styles.row} />
<Skeleton {...skeletonProps} className={styles.row} />
<Skeleton {...skeletonProps} className={styles.row} />
<Skeleton {...skeletonProps} className={styles.row} />
</div>
</CSSTransition>
</div>
);
},
);

0 comments on commit e940c88

Please sign in to comment.