From b2f9b911fafc832d5dd3fe189db832c29ecfe471 Mon Sep 17 00:00:00 2001 From: Mark Alexander <6917497+m15e@users.noreply.github.com> Date: Mon, 24 May 2021 16:43:47 +0800 Subject: [PATCH 1/6] feat: Button component + story --- src/components/Button/Button.stories.tsx | 54 ++++++++++++-- src/components/Button/Button.tsx | 94 +++++++++++++++++++++++- 2 files changed, 137 insertions(+), 11 deletions(-) diff --git a/src/components/Button/Button.stories.tsx b/src/components/Button/Button.stories.tsx index db6fddd..a15638d 100644 --- a/src/components/Button/Button.stories.tsx +++ b/src/components/Button/Button.stories.tsx @@ -1,20 +1,60 @@ import React from 'react' import {Story, Meta} from '@storybook/react' - +import {Icon} from '../Icons/Icon' import {Button} from './Button' export default { title: 'Components/Button', component: Button, argTypes: { - backgroundColor: {control: 'color'} + style: { + defaultValue: 'gray', + options: ['gray', 'primary', 'outline', 'ghost', 'link'], + control: {type: 'select'} + }, + size: { + defaultValue: 'md', + options: ['xs', 'sm', 'md', 'lg', 'responsive'], + control: {type: 'select'} + }, + status: { + defaultValue: 'normal', + options: ['normal', 'disabled'], + control: {type: 'radio'} + }, + outline: { + defaultValue: 'square', + options: ['square', 'round'], + control: {type: 'radio'} + } } } as Meta -const Template: Story = args => + + ) } + +export const Buttons = Template.bind({}) diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx index 2ccd0cb..98a6e65 100644 --- a/src/components/Button/Button.tsx +++ b/src/components/Button/Button.tsx @@ -1,8 +1,94 @@ import React from 'react' import cn from 'classnames' -import type {ComponentProps} from 'react' +import type {PropsWithChildren} from 'react' -// minor example -export function Button(props: ComponentProps<'button'>) { - return + ) } From 20b8299597b41bc17717c6fc30280f44e1cf3db0 Mon Sep 17 00:00:00 2001 From: Thiago Costa Porto Date: Mon, 24 May 2021 13:45:46 +0100 Subject: [PATCH 2/6] refactor: wip small changes during coscreen code review to buttons and button stories --- src/components/Button/Button.stories.tsx | 5 +- src/components/Button/Button.tsx | 71 ++++++++++-------------- 2 files changed, 31 insertions(+), 45 deletions(-) diff --git a/src/components/Button/Button.stories.tsx b/src/components/Button/Button.stories.tsx index a15638d..3896ed8 100644 --- a/src/components/Button/Button.stories.tsx +++ b/src/components/Button/Button.stories.tsx @@ -50,8 +50,9 @@ const Template: Story = args => { return ( <> ) diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx index 98a6e65..17c5b83 100644 --- a/src/components/Button/Button.tsx +++ b/src/components/Button/Button.tsx @@ -1,6 +1,5 @@ import React from 'react' import cn from 'classnames' -import type {PropsWithChildren} from 'react' type ButtonStyles = 'gray' | 'primary' | 'outline' | 'ghost' | 'link' type ButtonSizes = 'xs' | 'sm' | 'md' | 'lg' | 'responsive' @@ -19,76 +18,62 @@ export function Button({ size = 'md', status = 'normal', outline = 'square', + disabled, className, - children, ...props -}: PropsWithChildren<{ +}: { style: ButtonStyles size: ButtonSizes status: ButtonStatus outline: ButtonOutline - className: String -}>) { + className: string + disabled: boolean +}) { const buttonSize = buttonSizes[size] - const fonts = 'font-bold font-roboto' - const linkHover = style === 'link' ? 'hover:underline hover:cursor-pointer' : '' - const radius = outline == 'square' ? 'rounded' : 'rounded-full' - const opacity = status == 'disabled' ? 'opacity-40' : 'opacity-100' + const fontWeight = 'font-bold' + const linkHover = style === 'link' ? 'inline-block hover:underline cursor-pointer' : '' + const radius = outline === 'square' ? 'rounded' : 'rounded-full' - let hover = 'hover:bg-gradient-to-r hover:from-white hover:to-transparent' - let textColor = 'text-cyan-600' + let hover = 'hover:from-gradient-white' + let textColor = 'text-primary-600' let backgroundColor = 'bg-transparent' let borderColor = 'border-transparent' - if (style == 'primary' || style == 'outline') { - borderColor = 'border-cyan-600' - } - - if (style == 'gray') { - textColor = 'text-primary-200' - backgroundColor = 'bg-gray-800' - } + let buttonClasses = '' - if (style == 'primary') { + if (style === 'gray') { + buttonClasses = 'bg-gray-800 bg-gradient-to-r text-primary-200' + } else if (style === 'primary') { textColor = 'text-white' - backgroundColor = 'bg-cyan-500' - } - - if (style == 'outline') { - const border = size == 'md' || size == 'lg' ? 'border-2' : 'border' - borderColor = `border-cyan-500 ${border}` - hover = 'hover:bg-primary-500 hover:text-white' - } - - if (style == 'ghost') { + backgroundColor = 'bg-primary-500 bg-gradient-to-r' + borderColor = 'border-primary-600' + } else if (style === 'outline') { + const border = size === 'md' || size === 'lg' ? 'border-2' : 'border' + borderColor = `border-primary-500 ${border}` + backgroundColor = 'hover:bg-primary-500' + textColor = `${textColor} hover:text-white` + } else if (style == 'ghost') { hover = 'hover:bg-primary-100' } const classes = cn( - 'flex items-center text-center', - fonts, + 'flex items-center text-center space-x-2', + fontWeight, buttonSize, textColor, borderColor, backgroundColor, linkHover, radius, - opacity, hover, + buttonClasses, + disabled && 'opacity-40 cursor-not-allowed', className ) if (style === 'link') { - return ( - - {children} - - ) + return } - return ( - - ) + return + + )) + } + + return ( +
+ {heading &&
{heading}
} +
+
    {mapLinks(links)}
+
+ {prereqs && ( + + Pre-Requisites + + )} +
    {prereqs && mapPrerequisites(prereqs)}
+ {hasMessage && userMessage()} +
+ ) +} From 0eea6e22061611c38fbb97964df9f4caaeb3abbf Mon Sep 17 00:00:00 2001 From: m15e <6917497+m15e@users.noreply.github.com> Date: Mon, 31 May 2021 18:13:57 +0800 Subject: [PATCH 5/6] feat: Sidebar story --- src/components/Sidebar/Sidebar.stories.tsx | 81 +++++++++- src/components/Sidebar/Sidebar.tsx | 165 ++++++--------------- src/components/Typography/Text.tsx | 2 +- 3 files changed, 124 insertions(+), 124 deletions(-) diff --git a/src/components/Sidebar/Sidebar.stories.tsx b/src/components/Sidebar/Sidebar.stories.tsx index d5dbba4..fb5729f 100644 --- a/src/components/Sidebar/Sidebar.stories.tsx +++ b/src/components/Sidebar/Sidebar.stories.tsx @@ -29,11 +29,86 @@ export default { } } as Meta +const smileyIcon = () => ( + + + +) + +const smileyIcon24 = () => ( + + + +) + +const simpleLinks = Array.from({length: 3}, () => ({ + title: 'Text Here', + target: 'https://openmined.org', + disabled: false +})) + +const iconLinks = Array.from({length: 3}, () => ({ + title: 'Text Here', + target: 'https://openmined.org', + icon: smileyIcon +})) + +const numberLinks = Array.from([1, 2, 3], n => ({ + title: 'Text Here', + target: 'https://openmined.org', + number: n +})) + +const iconLinks24 = Array.from({length: 3}, () => ({ + title: 'Text Here', + target: 'https://openmined.org', + icon: smileyIcon24 +})) + +const avatarLinks = Array.from({length: 3}, () => ({ + title: 'Text Here', + target: 'https://openmined.org', + avatar: + 'https://avataaars.io/?avatarStyle=Circle&topType=LongHairStraight&accessoriesType=Blank&hairColor=BrownDark&facialHairType=Blank&clotheType=BlazerShirt&eyeType=Default&eyebrowType=Default&mouthType=Default&skinColor=Light' +})) + +const prereqs = [ + { + title: 'Text Here', + target: 'https://openmined.org', + disabled: false + }, + { + title: 'Text Here', + target: 'https://openmined.org', + disabled: true + } +] + const Template: Story = args => { return ( - <> - - +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
) } diff --git a/src/components/Sidebar/Sidebar.tsx b/src/components/Sidebar/Sidebar.tsx index 126a812..0394a53 100644 --- a/src/components/Sidebar/Sidebar.tsx +++ b/src/components/Sidebar/Sidebar.tsx @@ -14,132 +14,51 @@ const messageIcon = () => ( ) -const smSmileyIcon = () => ( - - - -) - -const mdSmileyIcon = () => ( - - - -) - -const userMessage = () => { - return ( - <> -
-
- -
- - Not seeing an answer to your specific question? Go to our{' '} - - discussion boad - {' '} - to get extra assistance. - - - ) -} - -const links = [ - { - title: 'Text Here', - target: 'https://openmined.org', - disabled: false - }, - { - title: 'Text Here', - target: 'https://openmined.org', - disabled: true - }, - { - title: 'Text Here', - target: 'https://openmined.org', - disabled: false, - subtitle: 'Text Here' - }, - { - title: 'Text Here', - target: 'https://openmined.org', - disabled: true, - subtitle: 'Text Here' - }, - { - title: 'Text Here', - target: 'https://openmined.org', - disabled: false, - number: 1 - }, - { - title: 'Text Here', - target: 'https://openmined.org', - disabled: true, - number: 1 - }, - { - title: 'Text Here', - target: 'https://openmined.org', - icon: mdSmileyIcon, - subtitle: 'Text Here' - }, - { - title: 'Text Here', - target: 'https://openmined.org', - icon: smSmileyIcon - }, - { - title: 'Text Here', - target: 'https://openmined.org', - disabled: false, - avatar: - 'https://avataaars.io/?avatarStyle=Circle&topType=LongHairStraight&accessoriesType=Blank&hairColor=BrownDark&facialHairType=Blank&clotheType=BlazerShirt&eyeType=Default&eyebrowType=Default&mouthType=Default&skinColor=Light' - } -] - -const prereqs = [ - { - title: 'Text Here', - target: 'https://openmined.org', - disabled: false - }, - { - title: 'Text Here', - target: 'https://openmined.org', - disabled: true - } -] - export function Sidebar({ - heading = 'Heading 5', - hasMessage = true, + heading = '', + hasMessage = false, + borderLeft = false, + links, + prereqs, className, ...props }: { heading: string hasMessage: boolean + borderLeft: boolean icon: React.ReactType + links: [] + prereqs: [] className: string disabled: boolean }) { - const classes = cn('text-primary-600', className) - const numberClasses = 'rounded-full bg-gray-800 text-gray-50 text-sm w-5 h-5 leading-snug' + const containerClasses = `sm:w-1/3 lg:w-1/4 ${borderLeft ? 'border-l-2 pl-6' : ''}` + + const userMessage = () => { + return ( + <> +
+
+ +
+ + Not seeing an answer to your specific question? Go to our{' '} + + discussion boad + {' '} + to get extra assistance. + + + ) + } const mapPrerequisites = prereqs => { return prereqs.map(prereq => ( -
  • - +
  • + {prereq.title}
  • @@ -169,18 +88,24 @@ export function Sidebar({ } return ( -
    - {heading &&
    {heading}
    } -
    -
      {mapLinks(links)}
    -
    - {prereqs && ( - - Pre-Requisites - +
    + {heading && ( + <> +
    {heading}
    +
    + )} -
      {prereqs && mapPrerequisites(prereqs)}
    +
      {links && mapLinks(links)}
    {hasMessage && userMessage()} + {prereqs && ( +
    +
    + + Pre-Requisites + +
    + )} +
      {prereqs && mapPrerequisites(prereqs)}
    ) } diff --git a/src/components/Typography/Text.tsx b/src/components/Typography/Text.tsx index 06cd96c..facdaa2 100644 --- a/src/components/Typography/Text.tsx +++ b/src/components/Typography/Text.tsx @@ -2,7 +2,7 @@ import React from 'react' import cn from 'classnames' import type {PropsWithChildren} from 'react' -type TextComponent = 'p' | 'span' | 'div' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' +type TextComponent = 'p' | 'span' | 'div' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'a' type TextSizes = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '5xl' | '6xl' type FontWeight = 'font-medium' | 'font-normal' | 'font-black' | 'font-bold' From f26ef2fc369c20b7b27d1551a9978039baebb2ec Mon Sep 17 00:00:00 2001 From: m15e <6917497+m15e@users.noreply.github.com> Date: Tue, 1 Jun 2021 15:24:44 +0800 Subject: [PATCH 6/6] add: progress circle, sidebar components --- .../ProgressCircle/ProgressCircle.tsx | 65 +++++++++++++++++++ src/components/Sidebar/Sidebar.stories.tsx | 4 +- src/components/Sidebar/Sidebar.tsx | 9 +++ tailwind.config.js | 4 ++ 4 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 src/components/ProgressCircle/ProgressCircle.tsx diff --git a/src/components/ProgressCircle/ProgressCircle.tsx b/src/components/ProgressCircle/ProgressCircle.tsx new file mode 100644 index 0000000..9fc61be --- /dev/null +++ b/src/components/ProgressCircle/ProgressCircle.tsx @@ -0,0 +1,65 @@ +const cleanPercentage = percentage => { + const isNegativeOrNaN = !Number.isFinite(+percentage) || percentage < 0 // we can set non-numbers to 0 here + const isTooHigh = percentage > 100 + return isNegativeOrNaN ? 0 : isTooHigh ? 100 : +percentage +} + +const Circle = ({color, percentage, stroke}) => { + const r = 50 + const circ = 2 * Math.PI * r + const strokePct = ((100 - percentage) * circ) / 100 // where stroke will start, e.g. from 15% to 100%. + const circleColor = stroke ? stroke : color + return ( + + ) +} + +const Percent = ({percentage}) => { + return ( + + {percentage.toFixed(0)}% + + ) +} + +export const ProgressCircle = percentage => { + const pct = cleanPercentage(percentage) + return ( + <> +
    + + + + + + + + + + + + + + + ) +} diff --git a/src/components/Sidebar/Sidebar.stories.tsx b/src/components/Sidebar/Sidebar.stories.tsx index fb5729f..081e03b 100644 --- a/src/components/Sidebar/Sidebar.stories.tsx +++ b/src/components/Sidebar/Sidebar.stories.tsx @@ -96,14 +96,14 @@ const Template: Story = args => {
    - +

    - +

    diff --git a/src/components/Sidebar/Sidebar.tsx b/src/components/Sidebar/Sidebar.tsx index 0394a53..d021669 100644 --- a/src/components/Sidebar/Sidebar.tsx +++ b/src/components/Sidebar/Sidebar.tsx @@ -4,6 +4,7 @@ import {H5, Text} from '../Typography/Text' import {Button} from '../Button/Button' import {Icon} from '../Icons/Icon' import {Avatar} from '../Avatar/Avatar' +import {ProgressCircle} from '../ProgressCircle/ProgressCircle' const messageIcon = () => ( @@ -18,6 +19,7 @@ export function Sidebar({ heading = '', hasMessage = false, borderLeft = false, + progressPct, links, prereqs, className, @@ -27,6 +29,7 @@ export function Sidebar({ heading: string hasMessage: boolean borderLeft: boolean + progressPct: number icon: React.ReactType links: [] prereqs: [] @@ -106,6 +109,12 @@ export function Sidebar({
    )}
      {prereqs && mapPrerequisites(prereqs)}
    + {progressPct && ( + <> +
    + {ProgressCircle(progressPct)} + + )}
    ) } diff --git a/tailwind.config.js b/tailwind.config.js index 2849da3..cf297e9 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -48,6 +48,10 @@ module.exports = { }, dropShadow: { 'button-hover': '-4px 4px 8px --color-primary-500' + }, + strokeWidth: { + 5: '5', + 6: '6' } } },