Skip to content

Commit

Permalink
feat: move components from uikit (#63)
Browse files Browse the repository at this point in the history
  • Loading branch information
amje authored Jun 19, 2023
1 parent fd1f7e8 commit 98f7936
Show file tree
Hide file tree
Showing 40 changed files with 1,845 additions and 0 deletions.
33 changes: 33 additions & 0 deletions src/components/ChangelogDialog/ChangelogDialog.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
@use '../variables';

$block: '.#{variables.$ns}changelog-dialog';
$width: 732px;
$maxItemsHeight: 70vh;

#{$block} {
width: $width;

&__full-list-link-icon {
margin-left: 4px;
vertical-align: middle;
}

&__items-container {
max-height: $maxItemsHeight;
overflow-y: auto;
margin-bottom: 20px;

#{$block}__item:last-child {
margin-bottom: 0;
}
}

&__item {
margin-bottom: 32px;
}

&__empty-placeholder {
color: var(--yc-color-text-secondary);
text-align: center;
}
}
82 changes: 82 additions & 0 deletions src/components/ChangelogDialog/ChangelogDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import React from 'react';
import {ArrowUpRightFromSquare} from '@gravity-ui/icons';
import {Dialog, Icon, Link} from '@gravity-ui/uikit';
import type {DialogProps} from '@gravity-ui/uikit';

import {block} from '../utils/cn';

import {Item} from './components/Item/Item';
import i18n from './i18n';
import type {ChangelogItem} from './types';

import './ChangelogDialog.scss';

const b = block('changelog-dialog');

export interface ChangelogDialogProps {
open: boolean;
title?: string;
fullListLink?: string;
items: ChangelogItem[];
disableBodyScrollLock?: boolean;
disableOutsideClick?: boolean;
onClose: DialogProps['onClose'];
onStoryClick?: (storyId: string) => void;
}

let nextId = 1;
function getNextId() {
return nextId++;
}

export function ChangelogDialog({
open,
title = i18n('title'),
fullListLink,
items,
disableBodyScrollLock = true,
disableOutsideClick,
onClose,
onStoryClick,
}: ChangelogDialogProps) {
const idRef = React.useRef<number>();
idRef.current = idRef.current || getNextId();
const dialogCaptionId = `changelog-dialog-title-${idRef.current}`;

return (
<Dialog
className={b()}
open={open}
onClose={onClose}
disableBodyScrollLock={disableBodyScrollLock}
disableOutsideClick={disableOutsideClick}
aria-labelledby={dialogCaptionId}
>
<Dialog.Header caption={title} id={dialogCaptionId} />
{fullListLink ? (
<Dialog.Body key="full-list-link">
<Link href={fullListLink} target="_blank">
<span>{i18n('link_full_list')}</span>
<span className={b('full-list-link-icon')}>
<Icon data={ArrowUpRightFromSquare} size={14} />
</span>
</Link>
</Dialog.Body>
) : null}
<Dialog.Body key="items" className={b('items-container')}>
{items.length > 0 ? (
items.map((item, index) => (
<Item
key={index}
className={b('item')}
data={item}
onStoryClick={onStoryClick}
/>
))
) : (
<div className={b('empty-placeholder')}>{i18n('label_empty')}</div>
)}
</Dialog.Body>
</Dialog>
);
}
68 changes: 68 additions & 0 deletions src/components/ChangelogDialog/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
## ChangelogDialog

Component for displaying the changelog. It looks like a list of versions in a modal. It can display regular versions and versions associated with stories.

### PropTypes

| Property | Type | Required | Default | Description |
| :-------------------- | :--------------------------- | :------- | :---------- | :-------------------------------------------------------------- |
| open | `Boolean` || | Visibility flag |
| title | `String` | | `Changelog` | Dialog title |
| fullListLink | `String` | | | Link to documentation with full changelog |
| items | `ChangelogItem[]` || | List of versions to display |
| disableBodyScrollLock | `Boolean` | | true | If `true`, window scrolling is disabled when the dialog is open |
| disableOutsideClick | `Boolean` | | | If `true`, do not close dialog on click outside |
| onClose | `Function` || | Action on close |
| onStoryClick | `ChangelogStoryClickHandler` | | | Action on click to "View story" |

### ChangelogItem object

| Field | Type | Required | Default | Description |
| ----------- | ----------- | -------- | ------- | --------------------------- |
| date | `String` || | Version release date |
| isNew | `Boolean` | | | If `true`, show "New" label |
| title | `String` || | Version title |
| image | `ImageData` | | | Version image info |
| description | `String` || | Version description |
| storyId | `String` | | | Version related story |

### ImageData object

| Field | Type | Required | Default | Description |
| ----- | -------- | -------- | ------- | ---------------------------------------------------------------------------- |
| src | `String` || | Image link |
| alt | `String` | | | Image alt text |
| ratio | `Number` | | | Image aspect ratio = [height / width]. Used to draw placeholder with loader. |

### ChangelogStoryClickHandler function

`(storyId: string) => void`

#### Usage example

```jsx harmony
<ChangelogDialog
open
items={[
{
date: '03 Jul 2022',
isNew: true,
title: 'New navigation',
image: {
src: 'https://storage.yandexcloud.net/uikit-storybook-assets/changelog-dialog-picture-1.png',
alt: 'New navigation',
ratio: 240 / 516,
},
description:
'At the top of the panel is the service navigation for each service. Below are common navigation elements: a component for switching between accounts and organizations, settings, help center, search, notifications, favorites.',
storyId: 'someStoryId1',
},
{
date: '15 Jun 2022',
title: 'Minor fixes',
description:
'At the top of the panel is the service navigation for each service. Below are common navigation elements: a component for switching between accounts and organizations, settings, help center, search, notifications, favorites.',
},
]}
/>
```
115 changes: 115 additions & 0 deletions src/components/ChangelogDialog/__stories__/ChangelogDialog.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import React from 'react';

import type {Meta, StoryFn} from '@storybook/react';
import {Button} from '@gravity-ui/uikit';

import {ChangelogDialog} from '../ChangelogDialog';
import type {ChangelogDialogProps} from '../ChangelogDialog';
import type {ChangelogItem} from '../types';

export default {
title: 'Components/ChangelogDialog',
component: ChangelogDialog,
argTypes: {
onStoryClick: {
action: 'onStoryClick',
},
},
} as Meta;

const items: ChangelogItem[] = [
{
date: '03 Jul 2022',
isNew: true,
title: 'New navigation',
image: {
src: 'https://storage.yandexcloud.net/uikit-storybook-assets/changelog-dialog-picture-1.png',
alt: 'New navigation',
ratio: 240 / 516,
},
description:
'At the top of the panel is the service navigation for each service. Below are common navigation elements: a component for switching between accounts and organizations, settings, help center, search, notifications, favorites.',
storyId: 'someStoryId1',
},
{
date: '23 Jun 2022',
isNew: true,
title: 'New components',
description:
'At the top of the panel is the service navigation for each service. Below are common navigation elements: a component for switching between accounts and organizations, settings, help center, search, notifications, favorites.',
},
{
date: '15 Jun 2022',
title: 'Dark theme is now available',
description:
'At the top of the panel is the service navigation for each service. Below are common navigation elements: a component for switching between accounts and organizations, settings, help center, search, notifications, favorites.',
},
{
date: '12 Jun 2022',
title: 'Minor fixes',
image: {
src: 'https://storage.yandexcloud.net/uikit-storybook-assets/changelog-dialog-picture-2.png',
ratio: 240 / 516,
},
description:
'At the top of the panel is the service navigation for each service. Below are common navigation elements: a component for switching between accounts and organizations, settings, help center, search, notifications, favorites.',
storyId: 'someStoryId2',
},
{
date: '10 Jun 2022',
title: 'New features',
image: {
src: 'broken-url',
ratio: 240 / 516,
},
description:
'At the top of the panel is the service navigation for each service. Below are common navigation elements: a component for switching between accounts and organizations, settings, help center, search, notifications, favorites.',
storyId: 'someStoryId3',
},
{
date: '10 May 2022',
title: 'Fix basis components behavior',
description:
'At the top of the panel is the service navigation for each service. Below are common navigation elements: a component for switching between accounts and organizations, settings, help center, search, notifications, favorites.',
},
];

const DefaultTemplate: StoryFn<ChangelogDialogProps> = (props: ChangelogDialogProps) => {
const [visible, setVisible] = React.useState(props.open);

React.useEffect(() => {
setVisible(props.open);
}, [props.open]);

return (
<React.Fragment>
<div>
<Button
onClick={() => {
setVisible(true);
}}
>
Open
</Button>
</div>
<ChangelogDialog
{...props}
open={visible}
onClose={() => {
setVisible(false);
}}
/>
</React.Fragment>
);
};

export const Default = DefaultTemplate.bind({});

Default.args = {
open: false,
items,
fullListLink: 'https://github.com/gravity-ui/uikit',
onStoryClick: (storyId) => {
console.log(storyId);
},
};
46 changes: 46 additions & 0 deletions src/components/ChangelogDialog/components/Item/Item.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
@use '@gravity-ui/uikit/styles/mixins';
@use '../../../variables';

$block: '.#{variables.$ns}changelog-dialog-item';
$metaWidth: 124px;

#{$block} {
display: flex;

&__meta {
width: $metaWidth;
}

&__date {
line-height: var(--yc-text-subheader-3-line-height);
color: var(--yc-color-text-secondary);
}

&__label-new {
margin-top: 4px;
}

&__content {
flex: 1;
margin-left: 16px;
}

&__title {
margin: 0;
@include mixins.text-subheader-3();
}

&__image {
margin-top: 12px;
border-radius: 16px;
overflow: hidden;
}

&__description {
margin-top: 12px;
}

&__story-button {
margin-top: 16px;
}
}
Loading

0 comments on commit 98f7936

Please sign in to comment.