Skip to content

Commit

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

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

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

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

.KanbanCard:not(:last-child) {
margin-bottom: var(--gap-sm);
}

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

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

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

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

.KanbanCardContentItem {
flex: 1;
}
153 changes: 153 additions & 0 deletions src/harmony/Kanban/Kanban.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 { KanbanContainer } from './KanbanContainer';
import { KanbanColumn } from './KanbanColumn';
import { KanbanCard } from './KanbanCard';
import { KanbanCardTitle } from './KanbanCardTitle';
import { KanbanCardInfo } from './KanbanCardInfo';
import { KanbanCardContent } from './KanbanCardContent';
import { KanbanCardContentItem } from './KanbanCardContentItem';

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

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 (
<KanbanCard>
<KanbanCardTitle>{title}</KanbanCardTitle>
<KanbanCardInfo>
<Badge size="s" weight="regular" text={counter} iconLeft={<IconMessageTextOutline size="s" />} />
<Text size="s">{subInfo}</Text>
</KanbanCardInfo>
<KanbanCardContent>
<KanbanCardContentItem>
<Dropdown label="Owner">
<Text size="s">Minulin Timur</Text>
</Dropdown>
</KanbanCardContentItem>
</KanbanCardContent>
<KanbanCardContent>
<KanbanCardContentItem>
<Dropdown label="Estimate">
<Text size="s">Q4/2023</Text>
</Dropdown>
</KanbanCardContentItem>
<KanbanCardContentItem>
<Dropdown label="Priority">
<Text size="s">Low</Text>
</Dropdown>
</KanbanCardContentItem>
</KanbanCardContent>
<FlatProgressBar value={progress} />
</KanbanCard>
);
};

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 KanbanContainer> = () => {
return (
<KanbanContainer>
{columns.map((column, i) => (
<KanbanColumn key={i}>
<div style={{ marginBottom: 'var(--gap-s)' }}>
<State {...column.state} />
</div>
{column.data.map((item, j) => (
<Card key={j} {...item} />
))}
</KanbanColumn>
))}
</KanbanContainer>
);
};
12 changes: 12 additions & 0 deletions src/harmony/Kanban/KanbanCard.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 './Kanban.module.css';

export const KanbanCard: FC<HTMLAttributes<HTMLDivElement>> = ({ children, className, ...rest }) => {
return (
<div className={cn(s.KanbanCard, className)} {...rest}>
{children}
</div>
);
};
12 changes: 12 additions & 0 deletions src/harmony/Kanban/KanbanCardContent.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 './Kanban.module.css';

export const KanbanCardContent: FC<HTMLAttributes<HTMLDivElement>> = ({ children, className, ...rest }) => {
return (
<div className={cn(s.KanbanCardContent, className)} {...rest}>
{children}
</div>
);
};
12 changes: 12 additions & 0 deletions src/harmony/Kanban/KanbanCardContentItem.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 './Kanban.module.css';

export const KanbanCardContentItem: FC<HTMLAttributes<HTMLDivElement>> = ({ children, className, ...rest }) => {
return (
<div className={cn(s.KanbanCardContentItem, className)} {...rest}>
{children}
</div>
);
};
12 changes: 12 additions & 0 deletions src/harmony/Kanban/KanbanCardInfo.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 './Kanban.module.css';

export const KanbanCardInfo: FC<HTMLAttributes<HTMLDivElement>> = ({ children, className, ...rest }) => {
return (
<div className={cn(s.KanbanCardInfo, className)} {...rest}>
{children}
</div>
);
};
11 changes: 11 additions & 0 deletions src/harmony/Kanban/KanbanCardTitle.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 KanbanCardTitle: FC<ComponentProps<typeof Text>> = ({ children, ...rest }) => {
return (
<Text as="h4" {...rest}>
{children}
</Text>
);
};
12 changes: 12 additions & 0 deletions src/harmony/Kanban/KanbanColumn.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 './Kanban.module.css';

export const KanbanColumn: FC<HTMLAttributes<HTMLDivElement>> = ({ children, className, ...rest }) => {
return (
<div className={cn(s.KanbanColumn, className)} {...rest}>
{children}
</div>
);
};
12 changes: 12 additions & 0 deletions src/harmony/Kanban/KanbanContainer.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 './Kanban.module.css';

export const KanbanContainer: FC<HTMLAttributes<HTMLDivElement>> = ({ children, className, ...rest }) => {
return (
<div className={cn(s.KanbanContainer, 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 72050dd

Please sign in to comment.