-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(ui): Add the SectionCard Component (#2697)
- Loading branch information
1 parent
5c5c747
commit 4c684a2
Showing
14 changed files
with
1,099 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@kadena/kode-ui': minor | ||
--- | ||
|
||
add the SectionCard Component |
24 changes: 24 additions & 0 deletions
24
packages/libs/kode-ui/src/patterns/SectionCard/IconWrapper.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import type { FC } from 'react'; | ||
import React from 'react'; | ||
import { Stack } from './../../components'; | ||
import { LoaderIcon } from './LoaderIcon'; | ||
import type { ISectionCardProps } from './SectionCard'; | ||
import { iconWrapperClass, loadingIconClass } from './style.css'; | ||
|
||
interface IIconsProps { | ||
icon: ISectionCardProps['icon']; | ||
intent: ISectionCardProps['intent']; | ||
variant: ISectionCardProps['variant']; | ||
isLoading: boolean; | ||
} | ||
|
||
export const IconWrapper: FC<IIconsProps> = ({ icon, intent, isLoading }) => { | ||
if (!icon) return null; | ||
|
||
return ( | ||
<Stack className={iconWrapperClass({ intent, isLoading })}> | ||
{icon} | ||
{isLoading && <LoaderIcon className={loadingIconClass({ intent })} />} | ||
</Stack> | ||
); | ||
}; |
34 changes: 34 additions & 0 deletions
34
packages/libs/kode-ui/src/patterns/SectionCard/LoaderIcon.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import React from 'react'; | ||
export const LoaderIcon = ({ ...props }) => { | ||
return ( | ||
<svg | ||
data-style="animated" | ||
xmlns="http://www.w3.org/2000/svg" | ||
width={40} | ||
height={40} | ||
fill="none" | ||
viewBox="20 20 40 40" | ||
style={{ | ||
animation: 'rotate 2s linear infinite', | ||
transformOrigin: 'center center', | ||
}} | ||
{...props} | ||
> | ||
<defs> | ||
<style> | ||
{ | ||
'\n .loader-path {\n stroke-dasharray: 150,200;\n stroke-dashoffset: -10;\n animation: dash 1.5s ease-in-out infinite, color 6s ease-in-out infinite;\n stroke-linecap: round;\n }\n\n @-webkit-keyframes rotate { 100% { transform: rotate(360deg); } }\n @keyframes rotate { 100% { transform: rotate(360deg); } }\n @-webkit-keyframes dash { 0% { stroke-dasharray: 1,200; stroke-dashoffset: 0; } 50% { stroke-dasharray: 89,200; stroke-dashoffset: -35; } 100% { stroke-dasharray: 89,200; stroke-dashoffset: -124; } }\n @keyframes dash { 0% { stroke-dasharray: 1,200; stroke-dashoffset: 0; } 50% { stroke-dasharray: 89,200; stroke-dashoffset: -35; } 100% { stroke-dasharray: 89,200; stroke-dashoffset: -124; } }\n @-webkit-keyframes color { 0% { stroke: currentColor; } 40% { stroke: currentColor; } 66% { stroke: currentColor; } 80%, 90% { stroke: currentColor; } }\n @keyframes color { 0% { stroke: currentColor; } 40% { stroke: currentColor; } 66% { stroke: currentColor; } 80%, 90% { stroke: currentColor; } }\n\n ' | ||
} | ||
</style> | ||
</defs> | ||
<circle | ||
className="loader-path" | ||
cx={40} | ||
cy={40} | ||
r={19} | ||
fill="none" | ||
strokeWidth={2} | ||
/> | ||
</svg> | ||
); | ||
}; |
298 changes: 298 additions & 0 deletions
298
packages/libs/kode-ui/src/patterns/SectionCard/SectionCard.stories.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,298 @@ | ||
import { MonoAccessAlarm, MonoAdd } from '@kadena/kode-icons/system'; | ||
import type { Meta, StoryObj } from '@storybook/react'; | ||
import React from 'react'; | ||
import { Button, Stack, Text } from './../../components'; | ||
import { getVariants } from './../../storyDecorators'; | ||
import type { ISectionCardProps } from './SectionCard'; | ||
import { SectionCard } from './SectionCard'; | ||
import type { ISectionCardBodyProps } from './SectionCardBody'; | ||
import { SectionCardBody } from './SectionCardBody'; | ||
import { SectionCardContentBlock } from './SectionCardContentBlock'; | ||
import type { ISectionCardHeaderProps } from './SectionCardHeader'; | ||
import { SectionCardHeader } from './SectionCardHeader'; | ||
import { iconWrapperClass } from './style.css'; | ||
|
||
const intentVariants = getVariants(iconWrapperClass); | ||
|
||
interface IProps | ||
extends ISectionCardHeaderProps, | ||
ISectionCardProps, | ||
ISectionCardBodyProps {} | ||
|
||
const meta: Meta<IProps> = { | ||
title: 'Patterns/SectionCard', | ||
parameters: { | ||
status: { type: 'stable' }, | ||
docs: { | ||
description: { | ||
component: | ||
'The card can have multiple sections, a title and content section. `Buttons` in the actions prop have to be compact variants', | ||
}, | ||
}, | ||
}, | ||
argTypes: { | ||
intent: { | ||
options: intentVariants.intent, | ||
control: { | ||
type: 'select', | ||
}, | ||
description: 'intent color', | ||
table: { | ||
type: { summary: intentVariants.intent.join(' | ') }, | ||
defaultValue: { summary: 'default' }, | ||
}, | ||
}, | ||
title: { | ||
control: { | ||
type: 'text', | ||
}, | ||
description: 'Card Title', | ||
}, | ||
description: { | ||
description: 'Card description', | ||
control: { | ||
type: 'text', | ||
}, | ||
}, | ||
stack: { | ||
options: ['horizontal', 'vertical'], | ||
control: { | ||
type: 'select', | ||
}, | ||
}, | ||
children: { | ||
control: { | ||
type: 'text', | ||
}, | ||
description: 'The main content for the card', | ||
}, | ||
}, | ||
}; | ||
|
||
export default meta; | ||
type Story = StoryObj<IProps>; | ||
|
||
const Actions = () => { | ||
return ( | ||
<Button variant="outlined" isCompact endVisual={<MonoAdd />}> | ||
add | ||
</Button> | ||
); | ||
}; | ||
|
||
export const Primary: Story = { | ||
name: 'SectionCard basecard', | ||
args: { | ||
title: 'Our section', | ||
description: <>Our section is awesome</>, | ||
actions: <Actions />, | ||
children: 'This is the content for our section', | ||
}, | ||
render: ({ stack, title, description, children, actions, intent }) => { | ||
return ( | ||
<Stack width="100%" padding="lg"> | ||
<SectionCard stack={stack} intent={intent}> | ||
<SectionCardContentBlock> | ||
<SectionCardBody | ||
title="Content title" | ||
description="small description" | ||
> | ||
{children} | ||
</SectionCardBody> | ||
<SectionCardHeader | ||
title={title} | ||
description={description} | ||
actions={actions} | ||
/> | ||
<div>sdfsdf</div> | ||
</SectionCardContentBlock> | ||
</SectionCard> | ||
</Stack> | ||
); | ||
}, | ||
}; | ||
|
||
export const main: Story = { | ||
name: 'SectionCard mainCard', | ||
args: { | ||
title: 'Our section', | ||
description: <>Our section is awesome</>, | ||
actions: <Actions />, | ||
children: 'This is the content for our section', | ||
}, | ||
render: ({ stack, title, description, children, actions, intent }) => { | ||
return ( | ||
<Stack width="100%" padding="lg"> | ||
<SectionCard stack={stack} variant="main" intent={intent}> | ||
<SectionCardContentBlock> | ||
<SectionCardBody | ||
title="Content title" | ||
description="small description" | ||
> | ||
{children} | ||
<Text>this is content</Text> | ||
<Text>this is content</Text> | ||
<Text>this is content</Text> | ||
<Text>this is content</Text> | ||
<Text>this is content</Text> | ||
</SectionCardBody> | ||
<SectionCardHeader | ||
title={title} | ||
description={description} | ||
actions={actions} | ||
/> | ||
</SectionCardContentBlock> | ||
</SectionCard> | ||
</Stack> | ||
); | ||
}, | ||
}; | ||
|
||
export const withIcon: Story = { | ||
name: 'SectionCard card with Icon', | ||
args: { | ||
title: 'Our section', | ||
description: <>Our section is awesome</>, | ||
actions: <Actions />, | ||
children: 'This is the content for our section', | ||
}, | ||
render: ({ stack, title, description, children, actions, intent }) => { | ||
return ( | ||
<Stack width="100%" padding="lg"> | ||
<SectionCard stack={stack} icon={<MonoAccessAlarm />} intent={intent}> | ||
<SectionCardContentBlock> | ||
<SectionCardBody | ||
title="Content title" | ||
description="small description" | ||
> | ||
{children} | ||
<Text>this is content</Text> | ||
<Text>this is content</Text> | ||
<Text>this is content</Text> | ||
<Text>this is content</Text> | ||
<Text>this is content</Text> | ||
</SectionCardBody> | ||
<SectionCardHeader | ||
title={title} | ||
description={description} | ||
actions={actions} | ||
/> | ||
</SectionCardContentBlock> | ||
</SectionCard> | ||
</Stack> | ||
); | ||
}, | ||
}; | ||
|
||
export const withIconIsLoading: Story = { | ||
name: 'SectionCard loading state', | ||
args: { | ||
title: 'Our section', | ||
description: <>Our section is awesome</>, | ||
actions: <Actions />, | ||
children: 'This is the content for our section', | ||
intent: 'info', | ||
}, | ||
render: ({ stack, title, description, children, actions, intent }) => { | ||
return ( | ||
<Stack width="100%" padding="lg"> | ||
<SectionCard | ||
stack={stack} | ||
icon={<MonoAccessAlarm />} | ||
intent={intent} | ||
isLoading | ||
> | ||
<SectionCardContentBlock> | ||
<SectionCardBody | ||
title="Content title" | ||
description="small description" | ||
> | ||
{children} | ||
<Text>this is content</Text> | ||
<Text>this is content</Text> | ||
<Text>this is content</Text> | ||
<Text>this is content</Text> | ||
<Text>this is content</Text> | ||
</SectionCardBody> | ||
<SectionCardHeader | ||
title={title} | ||
description={description} | ||
actions={actions} | ||
/> | ||
</SectionCardContentBlock> | ||
</SectionCard> | ||
</Stack> | ||
); | ||
}, | ||
}; | ||
|
||
export const reverseBackground: Story = { | ||
name: 'SectionCard Reversed background', | ||
args: { | ||
title: 'Our section', | ||
description: <>Our section is awesome</>, | ||
actions: <Actions />, | ||
children: 'This is the content for our section', | ||
}, | ||
render: ({ stack, title, description, children, actions, intent }) => { | ||
return ( | ||
<Stack width="100%" padding="lg"> | ||
<SectionCard background="reversed" stack={stack}> | ||
<SectionCardContentBlock> | ||
<SectionCardBody | ||
title="Content title" | ||
description="small description" | ||
> | ||
{children} | ||
<Text>this is content</Text> | ||
<Text>this is content</Text> | ||
<Text>this is content</Text> | ||
<Text>this is content</Text> | ||
<Text>this is content</Text> | ||
</SectionCardBody> | ||
<SectionCardHeader | ||
title={title} | ||
description={description} | ||
actions={actions} | ||
/> | ||
</SectionCardContentBlock> | ||
</SectionCard> | ||
</Stack> | ||
); | ||
}, | ||
}; | ||
export const noBackground: Story = { | ||
name: 'SectionCard No background', | ||
args: { | ||
title: 'Our section', | ||
description: <>Our section is awesome</>, | ||
actions: <Actions />, | ||
children: 'This is the content for our section', | ||
}, | ||
render: ({ stack, title, description, children, actions, intent }) => { | ||
return ( | ||
<Stack width="100%" padding="lg"> | ||
<SectionCard background="none" stack={stack}> | ||
<SectionCardContentBlock> | ||
<SectionCardBody | ||
title="Content title" | ||
description="small description" | ||
> | ||
{children} | ||
<Text>this is content</Text> | ||
<Text>this is content</Text> | ||
<Text>this is content</Text> | ||
<Text>this is content</Text> | ||
<Text>this is content</Text> | ||
</SectionCardBody> | ||
<SectionCardHeader | ||
title={title} | ||
description={description} | ||
actions={actions} | ||
/> | ||
</SectionCardContentBlock> | ||
</SectionCard> | ||
</Stack> | ||
); | ||
}, | ||
}; |
Oops, something went wrong.