Skip to content

Commit

Permalink
feat: support Canban
Browse files Browse the repository at this point in the history
  • Loading branch information
asabotovich committed Jul 30, 2024
1 parent 7e6ddcc commit 4521799
Show file tree
Hide file tree
Showing 10 changed files with 293 additions and 0 deletions.
50 changes: 50 additions & 0 deletions src/harmony/Canban/Canban.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
.CanbanContainer {
display: flex;
}

.CanbanColumn {
width: 328px;
flex-grow: 0;
flex-shrink: 0;
padding: var(--gap-s) var(--gap-sm);
border-right: 1px solid var(--gray-900);
}

.CanbanColumn:last-child {
border-right: 0;
}

.CanbanCard {
background: var(--layer);
padding: var(--gap-s) var(--gap-sm);
border-radius: var(--radius-m);
border: 1px solid var(--gray-900);
}

.CanbanCard:not(:last-child) {
margin-bottom: var(--gap-s);
}

.CanbanCardInfo {
color: var(--text-ghost);
display: flex;
gap: var(--gap-s);
}

.CanbanCardInfo:not(:last-child) {
margin-bottom: var(--gap-xs);
}

.CanbanCardContent {
display: flex;
flex-wrap: nowrap;
gap: var(--gap-xs);
}

.CanbanCardContent:not(:last-child){
margin-bottom: var(--gap-xs);
}

.CanbanCardContentItem {
flex: 1;
}
153 changes: 153 additions & 0 deletions src/harmony/Canban/Canban.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import React, { FC, ReactNode } from 'react';
import type { Meta, StoryFn } from '@storybook/react';
import { IconMessageTextOutline } from '@taskany/icons';

import { Badge } from '../Badge/Badge';
import { State } from '../State/State';
import { Text } from '../Text/Text';
import { Dropdown as DropdownProvider, DropdownTrigger } from '../Dropdown/Dropdown';
import { FlatProgressBar } from '../FlatProgressBar/FlatProgressBar';

import { CanbanContainer } from './CanbanContainer';
import { CanbanColumn } from './CanbanColumn';
import { CanbanCard } from './CanbanCard';
import { CanbanCardTitle } from './CanbanCardTitle';
import { CanbanCardInfo } from './CanbanCardInfo';
import { CanbanCardContent } from './CanbanCardContent';
import { CanbanCardContentItem } from './CanbanCardContentItem';

const meta: Meta<typeof CanbanContainer> = {
title: '@harmony/Canban',
component: CanbanContainer,
};

export default meta;

const Dropdown = ({ children, label }: { children: ReactNode; label: string }) => {
return (
<DropdownProvider isOpen={false} arrow>
<DropdownTrigger view="outline" label={label} readOnly>
{children}
</DropdownTrigger>
</DropdownProvider>
);
};

const Card: FC<{
counter: number;
title: string;
subInfo?: string;
progress: number;
}> = ({ counter, title, subInfo, progress }) => {
return (
<CanbanCard>
<CanbanCardTitle>{title}</CanbanCardTitle>
<CanbanCardInfo>
<Badge size="s" weight="regular" text={counter} iconLeft={<IconMessageTextOutline size="s" />} />
<Text size="s">{subInfo}</Text>
</CanbanCardInfo>
<CanbanCardContent>
<CanbanCardContentItem>
<Dropdown label="Owner">
<Text size="s">Minulin Timur</Text>
</Dropdown>
</CanbanCardContentItem>
</CanbanCardContent>
<CanbanCardContent>
<CanbanCardContentItem>
<Dropdown label="Estimate">
<Text size="s">Q4/2023</Text>
</Dropdown>
</CanbanCardContentItem>
<CanbanCardContentItem>
<Dropdown label="Priority">
<Text size="s">Low</Text>
</Dropdown>
</CanbanCardContentItem>
</CanbanCardContent>
<FlatProgressBar value={progress} />
</CanbanCard>
);
};

const columns = [
{
state: {
color: 'var(--status-in-progress)',
title: 'In Progress',
},
data: [
{
title: '[news] Автоматизиция тестирования',
subInfo: 'updated 4 weeks ago',
counter: 6,
progress: 33,
},
{
title: 'Повысить экономию трайбов за счет роста автоматизации',
subInfo: 'updated 6 days ago',
counter: 12,
progress: 60,
},
],
},

{
state: {
color: 'var(--status-finished)',
title: 'Finished',
},
data: [
{
title: 'Принять окончательное решение по ключевым проектам',
subInfo: 'updated 1 day ago',
counter: 14,
progress: 100,
},
],
},

{
state: {
color: 'var(--status-failed)',
title: 'Failed',
},
data: [
{
title: 'Повысить экономию трайбов за счет роста автоматизации',
subInfo: 'updated last month',
counter: 10,
progress: 13,
},
{
title: 'Принять окончательное решение по ключевым проектам',
subInfo: 'updated 4 hours ago',
counter: 12,
progress: 63,
},
{
title: '[news] Автоматизиция тестирования',
subInfo: 'updated just now',
counter: 9,
progress: 80,
},
],
},
];

export const Default: StoryFn<typeof CanbanContainer> = () => {
return (
<CanbanContainer>
{columns.map((column, i) => (
<CanbanColumn key={i}>
<div style={{ marginBottom: 'var(--gap-s)' }}>
<State {...column.state} />
</div>
{column.data.map((item, j) => (
<Card key={j} {...item} />
))}
</CanbanColumn>
))}
</CanbanContainer>
);
};
12 changes: 12 additions & 0 deletions src/harmony/Canban/CanbanCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React, { FC, HTMLAttributes } from 'react';
import cn from 'classnames';

import s from './Canban.module.css';

export const CanbanCard: FC<HTMLAttributes<HTMLDivElement>> = ({ children, className, ...rest }) => {
return (
<div className={cn(s.CanbanCard, className)} {...rest}>
{children}
</div>
);
};
12 changes: 12 additions & 0 deletions src/harmony/Canban/CanbanCardContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React, { FC, HTMLAttributes } from 'react';
import cn from 'classnames';

import s from './Canban.module.css';

export const CanbanCardContent: FC<HTMLAttributes<HTMLDivElement>> = ({ children, className, ...rest }) => {
return (
<div className={cn(s.CanbanCardContent, className)} {...rest}>
{children}
</div>
);
};
12 changes: 12 additions & 0 deletions src/harmony/Canban/CanbanCardContentItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React, { FC, HTMLAttributes } from 'react';
import cn from 'classnames';

import s from './Canban.module.css';

export const CanbanCardContentItem: FC<HTMLAttributes<HTMLDivElement>> = ({ children, className, ...rest }) => {
return (
<div className={cn(s.CanbanCardContentItem, className)} {...rest}>
{children}
</div>
);
};
12 changes: 12 additions & 0 deletions src/harmony/Canban/CanbanCardInfo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React, { FC, HTMLAttributes } from 'react';
import cn from 'classnames';

import s from './Canban.module.css';

export const CanbanCardInfo: FC<HTMLAttributes<HTMLDivElement>> = ({ children, className, ...rest }) => {
return (
<div className={cn(s.CanbanCardInfo, className)} {...rest}>
{children}
</div>
);
};
11 changes: 11 additions & 0 deletions src/harmony/Canban/CanbanCardTitle.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React, { FC, ComponentProps } from 'react';

import { Text } from '../Text/Text';

export const CanbanCardTitle: FC<ComponentProps<typeof Text>> = ({ children, ...rest }) => {
return (
<Text as="h4" {...rest}>
{children}
</Text>
);
};
12 changes: 12 additions & 0 deletions src/harmony/Canban/CanbanColumn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React, { FC, HTMLAttributes } from 'react';
import cn from 'classnames';

import s from './Canban.module.css';

export const CanbanColumn: FC<HTMLAttributes<HTMLDivElement>> = ({ children, className, ...rest }) => {
return (
<div className={cn(s.CanbanColumn, className)} {...rest}>
{children}
</div>
);
};
12 changes: 12 additions & 0 deletions src/harmony/Canban/CanbanContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React, { FC, HTMLAttributes } from 'react';
import cn from 'classnames';

import s from './Canban.module.css';

export const CanbanContainer: FC<HTMLAttributes<HTMLDivElement>> = ({ children, className, ...rest }) => {
return (
<div className={cn(s.CanbanContainer, className)} {...rest}>
{children}
</div>
);
};
7 changes: 7 additions & 0 deletions src/harmony/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@ export * from './AutoComplete/AutoComplete';
export * from './Badge/Badge';
export * from './Breadcrumbs/Breadcrumbs';
export * from './Button/Button';
export * from './Canban/CanbanCard';
export * from './Canban/CanbanCardContent';
export * from './Canban/CanbanCardContentItem';
export * from './Canban/CanbanCardInfo';
export * from './Canban/CanbanCardTitle';
export * from './Canban/CanbanColumn';
export * from './Canban/CanbanContainer';
export * from './Card/Card';
export * from './Checkbox/Checkbox';
export * from './Circle/Circle';
Expand Down

0 comments on commit 4521799

Please sign in to comment.