From 03711e42409ac764b0de6884123657a47728ee70 Mon Sep 17 00:00:00 2001 From: Yash Raj Chhabra Date: Thu, 31 Mar 2022 18:22:49 +0530 Subject: [PATCH 1/5] Adds octuples pills component --- src/components/Icon/icon.module.scss | 9 +- src/components/Pills/Pill.tsx | 48 +++++++ src/components/Pills/Pills.stories.tsx | 78 +++++++++++ src/components/Pills/Pills.types.ts | 11 ++ src/components/Pills/index.ts | 2 + src/components/Pills/pills.module.scss | 187 +++++++++++++++++++++++++ 6 files changed, 329 insertions(+), 6 deletions(-) create mode 100644 src/components/Pills/Pill.tsx create mode 100644 src/components/Pills/Pills.stories.tsx create mode 100644 src/components/Pills/Pills.types.ts create mode 100644 src/components/Pills/index.ts create mode 100644 src/components/Pills/pills.module.scss diff --git a/src/components/Icon/icon.module.scss b/src/components/Icon/icon.module.scss index 61dd8f2fe..f09b3cbf6 100644 --- a/src/components/Icon/icon.module.scss +++ b/src/components/Icon/icon.module.scss @@ -1,9 +1,6 @@ -.iconWrapper { - display: inline-block; +.icon-wrapper { + display: flex; + align-items: center; margin: 0; padding: 0; - - svg { - vertical-align: middle; - } } diff --git a/src/components/Pills/Pill.tsx b/src/components/Pills/Pill.tsx new file mode 100644 index 000000000..7a475a856 --- /dev/null +++ b/src/components/Pills/Pill.tsx @@ -0,0 +1,48 @@ +import React, { FC } from 'react'; +import { PillProps } from './Pills.types'; + +import styles from './pills.module.scss'; +import { classNames } from '../../shared/utilities'; +import { Icon, IconName, IconSize } from '../Icon'; + +export const Pill: FC = ({ + color, + children, + icon, + onClose, + theme = 'blue', + closable, +}) => { + const tagClassName = classNames([ + styles.tagPills, + { [styles.red]: theme === 'red' }, + { [styles.orange]: theme === 'orange' }, + { [styles.yellow]: theme === 'yellow' }, + { [styles.green]: theme === 'green' }, + { [styles.bluegreen]: theme === 'bluegreen' }, + { [styles.blue]: theme === 'blue' }, + { [styles.violet]: theme === 'violet' }, + { [styles.grey]: theme === 'grey' }, + ]); + return ( +
+ {icon && ( + + )} + {children} + {closable && ( + + )} +
+ ); +}; diff --git a/src/components/Pills/Pills.stories.tsx b/src/components/Pills/Pills.stories.tsx new file mode 100644 index 000000000..3c463d4ef --- /dev/null +++ b/src/components/Pills/Pills.stories.tsx @@ -0,0 +1,78 @@ +import React from 'react'; +import { Pill } from './'; +import { OcThemeNames } from '../ConfigProvider'; +import { IconName } from '../Icon'; + +export default { + title: 'Pill', + component: Pill, +}; + +const themes: OcThemeNames[] = [ + 'red', + 'orange', + 'yellow', + 'green', + 'bluegreen', + 'blue', + 'violet', + 'grey', +]; + +export const Pills = () => ( + <> +

Pills

+
+
+ {themes.map((theme) => ( + + + {theme} + + + ))} +
+ +
+ {themes.map((theme) => ( + + + {theme} + + + ))} +
+
+ {themes.map((theme) => ( + + + {theme} + + + ))} +
+
+ +); diff --git a/src/components/Pills/Pills.types.ts b/src/components/Pills/Pills.types.ts new file mode 100644 index 000000000..50a73569f --- /dev/null +++ b/src/components/Pills/Pills.types.ts @@ -0,0 +1,11 @@ +import * as React from 'react'; +import { IconName } from '../Icon'; +import { OcThemeNames } from '../ConfigProvider'; + +export interface PillProps { + theme?: OcThemeNames; + color?: string; + icon?: IconName; + closable?: boolean; + onClose?: React.MouseEventHandler; +} diff --git a/src/components/Pills/index.ts b/src/components/Pills/index.ts new file mode 100644 index 000000000..8f2cde77d --- /dev/null +++ b/src/components/Pills/index.ts @@ -0,0 +1,2 @@ +export * from './Pill'; +export * from './Pills.types'; diff --git a/src/components/Pills/pills.module.scss b/src/components/Pills/pills.module.scss new file mode 100644 index 000000000..6003b61c1 --- /dev/null +++ b/src/components/Pills/pills.module.scss @@ -0,0 +1,187 @@ +@import '../../styles/abstracts/functions'; +@import '../../styles/base/colors'; +@import '../../styles/themes/definitions-light'; +@import '../../styles/themes/default-theme'; + +.tag-pills { + --bg: var(--blue-color-20); + --label: var(--blue-color); + --hover-bg: var(--blue-color-30); + --hover-label: var(--text-primary-color); + padding: $space-xxs $space-s; + border-radius: $corner-radius-l; + transition: all $motion-duration-extra-fast $motion-easing-easeinout 0s; + background: var(--bg); + color: var(--label); + width: fit-content; + display: flex; + align-items: center; + font-weight: $text-font-weight-semibold; + + &:hover { + --bg: var(--hover-bg); + --label: var(--hover-label); + } + + &.red { + --bg: var(--red-color-20); + --label: var(--red-color); + --hover-bg: var(--red-color-30); + } + + &.orange { + --bg: var(--orange-color-20); + --label: var(--orange-color); + --hover-bg: var(--orange-color-30); + } + + &.yellow { + --bg: var(--yellow-color-20); + --label: var(--yellow-color); + --hover-bg: var(--yellow-color-30); + } + + &.green { + --bg: var(--green-color-20); + --label: var(--green-color); + --hover-bg: var(--green-color-30); + } + + &.bluegreen { + --bg: var(--bluegreen-color-20); + --label: var(--bluegreen-color); + --hover-bg: var(--bluegreen-color-30); + } + + &.blue { + --bg: var(--blue-color-20); + --label: var(--blue-color); + } + + &.violet { + --bg: var(--violet-color-20); + --label: var(--violet-color); + --hover-bg: var(--violet-color-30); + } + + &.grey { + --bg: var(--grey-color-20); + --label: var(--grey-color); + --hover-bg: var(--grey-color-30); + } + + .close-icon-wrapper { + border: none; + background: inherit; + color: inherit; + padding: 0; + cursor: pointer; + margin: 0 0 0 $space-xxs; + } + + .icon { + margin-right: $space-xxs; + } +} + +//.tag-pills-xs { +// transition: all $motion-duration-extra-fast $motion-easing-easeinout 0s; +// +// &.secondary-red { +// +// .text-color { +// color: $color-secondary-red; +// } +// +// .icon-color { +// color: $color-tertiary-red; +// } +// +// } +// +// &.secondary-orange { +// +// .text-color { +// color: $color-secondary-orange; +// } +// +// .icon-color { +// color: $color-tertiary-orange; +// } +// +// } +// +// &.secondary-yellow { +// +// .text-color { +// color: $color-secondary-yellow; +// } +// +// .icon-color { +// color: $color-tertiary-yellow; +// } +// +// } +// +// &.secondary-green { +// +// .text-color { +// color: $color-secondary-green; +// } +// +// .icon-color { +// color: $color-tertiary-green; +// } +// +// } +// +// &.secondary-blue-green { +// +// .text-color { +// color: $color-secondary-blue-green; +// } +// +// .icon-color { +// color: $color-tertiary-blue-green; +// } +// +// } +// +// &.secondary-blue { +// +// .text-color { +// color: $color-secondary-blue; +// } +// +// .icon-color { +// color: $color-tertiary-blue; +// } +// +// } +// +// &.secondary-violet { +// +// .text-color { +// color: $color-secondary-violet; +// } +// +// .icon-color { +// color: $color-tertiary-violet; +// } +// +// } +// +// &.secondary-grey { +// +// .text-color { +// color: $color-secondary-grey; +// } +// +// .icon-color { +// color: $color-tertiary-grey; +// } +// +// } +// +//} +// From e3291b91e81703d6592dfd442c48a2ab7c2b5ab7 Mon Sep 17 00:00:00 2001 From: Yash Raj Chhabra Date: Thu, 31 Mar 2022 18:53:27 +0530 Subject: [PATCH 2/5] remove unused class --- src/components/Pills/Pill.tsx | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/components/Pills/Pill.tsx b/src/components/Pills/Pill.tsx index 7a475a856..b11f3725a 100644 --- a/src/components/Pills/Pill.tsx +++ b/src/components/Pills/Pill.tsx @@ -1,10 +1,10 @@ import React, { FC } from 'react'; import { PillProps } from './Pills.types'; - -import styles from './pills.module.scss'; import { classNames } from '../../shared/utilities'; import { Icon, IconName, IconSize } from '../Icon'; +import styles from './pills.module.scss'; + export const Pill: FC = ({ color, children, @@ -13,7 +13,7 @@ export const Pill: FC = ({ theme = 'blue', closable, }) => { - const tagClassName = classNames([ + const tagClassName: string = classNames([ styles.tagPills, { [styles.red]: theme === 'red' }, { [styles.orange]: theme === 'orange' }, @@ -36,11 +36,7 @@ export const Pill: FC = ({ {children} {closable && ( )} From b58873b9e45aedd0d23c8e1be03dd13438bca8d7 Mon Sep 17 00:00:00 2001 From: Yash Raj Chhabra Date: Fri, 1 Apr 2022 13:57:43 +0530 Subject: [PATCH 3/5] remove unused scss --- src/components/Pills/pills.module.scss | 102 ------------------------- 1 file changed, 102 deletions(-) diff --git a/src/components/Pills/pills.module.scss b/src/components/Pills/pills.module.scss index 6003b61c1..bb429fe31 100644 --- a/src/components/Pills/pills.module.scss +++ b/src/components/Pills/pills.module.scss @@ -83,105 +83,3 @@ margin-right: $space-xxs; } } - -//.tag-pills-xs { -// transition: all $motion-duration-extra-fast $motion-easing-easeinout 0s; -// -// &.secondary-red { -// -// .text-color { -// color: $color-secondary-red; -// } -// -// .icon-color { -// color: $color-tertiary-red; -// } -// -// } -// -// &.secondary-orange { -// -// .text-color { -// color: $color-secondary-orange; -// } -// -// .icon-color { -// color: $color-tertiary-orange; -// } -// -// } -// -// &.secondary-yellow { -// -// .text-color { -// color: $color-secondary-yellow; -// } -// -// .icon-color { -// color: $color-tertiary-yellow; -// } -// -// } -// -// &.secondary-green { -// -// .text-color { -// color: $color-secondary-green; -// } -// -// .icon-color { -// color: $color-tertiary-green; -// } -// -// } -// -// &.secondary-blue-green { -// -// .text-color { -// color: $color-secondary-blue-green; -// } -// -// .icon-color { -// color: $color-tertiary-blue-green; -// } -// -// } -// -// &.secondary-blue { -// -// .text-color { -// color: $color-secondary-blue; -// } -// -// .icon-color { -// color: $color-tertiary-blue; -// } -// -// } -// -// &.secondary-violet { -// -// .text-color { -// color: $color-secondary-violet; -// } -// -// .icon-color { -// color: $color-tertiary-violet; -// } -// -// } -// -// &.secondary-grey { -// -// .text-color { -// color: $color-secondary-grey; -// } -// -// .icon-color { -// color: $color-tertiary-grey; -// } -// -// } -// -//} -// From a3eca7e47c62fbc7c6015be4363eab9f10d803a0 Mon Sep 17 00:00:00 2001 From: Yash Raj Chhabra Date: Fri, 1 Apr 2022 18:10:48 +0530 Subject: [PATCH 4/5] add all pill types and sizes --- src/components/Pills/Pill.tsx | 24 ++- src/components/Pills/Pills.stories.tsx | 220 +++++++++++++++++++++++-- src/components/Pills/Pills.types.ts | 18 +- src/components/Pills/pills.module.scss | 28 +++- 4 files changed, 262 insertions(+), 28 deletions(-) diff --git a/src/components/Pills/Pill.tsx b/src/components/Pills/Pill.tsx index b11f3725a..5dbd1d26f 100644 --- a/src/components/Pills/Pill.tsx +++ b/src/components/Pills/Pill.tsx @@ -1,5 +1,5 @@ import React, { FC } from 'react'; -import { PillProps } from './Pills.types'; +import { PillProps, PillSize, PillType } from './Pills.types'; import { classNames } from '../../shared/utilities'; import { Icon, IconName, IconSize } from '../Icon'; @@ -7,11 +7,14 @@ import styles from './pills.module.scss'; export const Pill: FC = ({ color, - children, + label, icon, - onClose, theme = 'blue', - closable, + onClose, + onClick, + buttonContent, + type = PillType.default, + size = PillSize.Large, }) => { const tagClassName: string = classNames([ styles.tagPills, @@ -23,6 +26,8 @@ export const Pill: FC = ({ { [styles.blue]: theme === 'blue' }, { [styles.violet]: theme === 'violet' }, { [styles.grey]: theme === 'grey' }, + { [styles.medium]: size === PillSize.Medium }, + { [styles.small]: size === PillSize.Small }, ]); return (
@@ -33,9 +38,14 @@ export const Pill: FC = ({ className={styles.icon} /> )} - {children} - {closable && ( - + )} + {type === PillType.closable && ( + )} diff --git a/src/components/Pills/Pills.stories.tsx b/src/components/Pills/Pills.stories.tsx index 3c463d4ef..cc9874d92 100644 --- a/src/components/Pills/Pills.stories.tsx +++ b/src/components/Pills/Pills.stories.tsx @@ -1,7 +1,7 @@ import React from 'react'; -import { Pill } from './'; +import { Pill, PillSize, PillType } from './'; import { OcThemeNames } from '../ConfigProvider'; -import { IconName } from '../Icon'; +import { Icon, IconName, IconSize } from '../Icon'; export default { title: 'Pill', @@ -21,7 +21,7 @@ const themes: OcThemeNames[] = [ export const Pills = () => ( <> -

Pills

+

Pills ({PillSize.Large})

( }} > {themes.map((theme) => ( - - - {theme} - - + ))}
@@ -47,11 +43,93 @@ export const Pills = () => ( }} > {themes.map((theme) => ( - - - {theme} - - + + ))} +
+
+ {themes.map((theme) => ( + + ))} +
+
+ {themes.map((theme) => ( + + + 2 + + } + /> + ))} +
+
+
+
+
+

Pills ({PillSize.Medium})

+
+
+ {themes.map((theme) => ( + + ))} +
+ +
+ {themes.map((theme) => ( + ))}
( > {themes.map((theme) => ( - - {theme} - - + size={PillSize.Medium} + /> + ))} +
+
+ {themes.map((theme) => ( + + + 2 + + } + /> + ))} +
+
+
+
+
+

Pills ({PillSize.Small})

+
+
+ {themes.map((theme) => ( + + ))} +
+
+ {themes.map((theme) => ( + + ))} +
+
+ {themes.map((theme) => ( + + ))} +
+
+ {themes.map((theme) => ( + + + 2 + + } + /> ))}
diff --git a/src/components/Pills/Pills.types.ts b/src/components/Pills/Pills.types.ts index 50a73569f..ffe1edd87 100644 --- a/src/components/Pills/Pills.types.ts +++ b/src/components/Pills/Pills.types.ts @@ -2,10 +2,26 @@ import * as React from 'react'; import { IconName } from '../Icon'; import { OcThemeNames } from '../ConfigProvider'; +export enum PillType { + default = 'default', + closable = 'closable', + withButton = 'withButton', +} + +export enum PillSize { + Large = 'large', + Medium = 'medium', + Small = 'small', +} + export interface PillProps { + label: string; theme?: OcThemeNames; color?: string; icon?: IconName; - closable?: boolean; + type?: PillType; + size?: PillSize; + buttonContent?: React.ReactNode; onClose?: React.MouseEventHandler; + onClick?: React.MouseEventHandler; } diff --git a/src/components/Pills/pills.module.scss b/src/components/Pills/pills.module.scss index bb429fe31..e3d0a643a 100644 --- a/src/components/Pills/pills.module.scss +++ b/src/components/Pills/pills.module.scss @@ -16,7 +16,23 @@ width: fit-content; display: flex; align-items: center; - font-weight: $text-font-weight-semibold; + + .label { + font-weight: $text-font-weight-semibold; + font-size: $text-font-size-5; + } + + &.medium { + .label { + font-size: $text-font-size-3; + } + } + + &.small { + .label { + font-size: $text-font-size-2; + } + } &:hover { --bg: var(--hover-bg); @@ -70,13 +86,21 @@ --hover-bg: var(--grey-color-30); } - .close-icon-wrapper { + .button, + .close-button { border: none; background: inherit; color: inherit; padding: 0; cursor: pointer; margin: 0 0 0 $space-xxs; + display: flex; + align-items: center; + } + + .label + .button:not(:empty) { + border-left: 1px solid var(--label); + padding-left: $space-xxs; } .icon { From ab851a3226c2528f32872838474b54982a787db2 Mon Sep 17 00:00:00 2001 From: Yash Raj Chhabra Date: Sat, 2 Apr 2022 00:31:14 +0530 Subject: [PATCH 5/5] chore: use default button for pill buttons --- src/components/Pills/Pill.tsx | 23 +++++++---- src/components/Pills/Pills.stories.tsx | 51 +++++++++++------------- src/components/Pills/Pills.types.ts | 55 +++++++++++++++++++++++++- src/components/Pills/pills.module.scss | 4 +- 4 files changed, 95 insertions(+), 38 deletions(-) diff --git a/src/components/Pills/Pill.tsx b/src/components/Pills/Pill.tsx index 5dbd1d26f..35c8cd028 100644 --- a/src/components/Pills/Pill.tsx +++ b/src/components/Pills/Pill.tsx @@ -4,6 +4,7 @@ import { classNames } from '../../shared/utilities'; import { Icon, IconName, IconSize } from '../Icon'; import styles from './pills.module.scss'; +import { ButtonSize, DefaultButton } from '../Button'; export const Pill: FC = ({ color, @@ -12,7 +13,8 @@ export const Pill: FC = ({ theme = 'blue', onClose, onClick, - buttonContent, + closeButtonProps, + pillButtonProps, type = PillType.default, size = PillSize.Large, }) => { @@ -40,14 +42,21 @@ export const Pill: FC = ({ )} {label} {type === PillType.withButton && ( - + )} {type === PillType.closable && ( - + )} ); diff --git a/src/components/Pills/Pills.stories.tsx b/src/components/Pills/Pills.stories.tsx index cc9874d92..d903c8ac4 100644 --- a/src/components/Pills/Pills.stories.tsx +++ b/src/components/Pills/Pills.stories.tsx @@ -48,6 +48,9 @@ export const Pills = () => ( theme={theme} key={theme} type={PillType.closable} + closeButtonProps={{ + ariaLabel: 'Close', + }} /> ))} @@ -80,15 +83,11 @@ export const Pills = () => ( theme={theme} key={theme} type={PillType.withButton} - buttonContent={ - <> - - 2 - - } + pillButtonProps={{ + icon: IconName.mdiThumbUpOutline, + text: '2', + ariaLabel: 'Thumbs up', + }} /> ))} @@ -129,6 +128,9 @@ export const Pills = () => ( key={theme} size={PillSize.Medium} type={PillType.closable} + closeButtonProps={{ + ariaLabel: 'Close', + }} /> ))} @@ -163,15 +165,11 @@ export const Pills = () => ( key={theme} type={PillType.withButton} size={PillSize.Medium} - buttonContent={ - <> - - 2 - - } + pillButtonProps={{ + icon: IconName.mdiThumbUpOutline, + text: '2', + ariaLabel: 'Thumbs up', + }} /> ))} @@ -211,6 +209,9 @@ export const Pills = () => ( key={theme} size={PillSize.Small} type={PillType.closable} + closeButtonProps={{ + ariaLabel: 'Close', + }} /> ))} @@ -245,15 +246,11 @@ export const Pills = () => ( key={theme} type={PillType.withButton} size={PillSize.Small} - buttonContent={ - <> - - 2 - - } + pillButtonProps={{ + icon: IconName.mdiThumbUpOutline, + text: '2', + ariaLabel: 'Thumbs up', + }} /> ))} diff --git a/src/components/Pills/Pills.types.ts b/src/components/Pills/Pills.types.ts index ffe1edd87..c200813dc 100644 --- a/src/components/Pills/Pills.types.ts +++ b/src/components/Pills/Pills.types.ts @@ -1,6 +1,7 @@ import * as React from 'react'; import { IconName } from '../Icon'; import { OcThemeNames } from '../ConfigProvider'; +import { ButtonProps } from '../Button'; export enum PillType { default = 'default', @@ -14,14 +15,66 @@ export enum PillSize { Small = 'small', } +/** + * Props for the close button + */ +export type closeButtonProps = Omit< + ButtonProps, + 'icon' | 'onClick' | 'size' | 'className' +>; + +/** + * Props for the pill button shown on right of the label + */ +export type pillButtonProps = Omit< + ButtonProps, + 'onClick' | 'size' | 'className' +>; + export interface PillProps { + /** + * Label of the pill + */ label: string; + /** + * Theme of the pill + * @default blue + */ theme?: OcThemeNames; + /** + * Custom color for the pill + */ color?: string; + /** + * Icon shown before the label + */ icon?: IconName; + /** + * Type of the pill + * @default PillType.default + */ type?: PillType; + /** + * Size of the pill + * @default PillType.Large + */ size?: PillSize; - buttonContent?: React.ReactNode; + /** + * Props for the close button, + * if type is set to PillType.closable + */ + closeButtonProps?: closeButtonProps; + /** + * Props for the button on the right side of the pill + * if type is set to PillType.withButton + */ + pillButtonProps?: pillButtonProps; + /** + * Callback called on click of the close button + */ onClose?: React.MouseEventHandler; + /** + * Callback called on click of the button right of the pill + */ onClick?: React.MouseEventHandler; } diff --git a/src/components/Pills/pills.module.scss b/src/components/Pills/pills.module.scss index e3d0a643a..ac16e0258 100644 --- a/src/components/Pills/pills.module.scss +++ b/src/components/Pills/pills.module.scss @@ -89,13 +89,11 @@ .button, .close-button { border: none; + border-radius: 0; background: inherit; color: inherit; padding: 0; - cursor: pointer; margin: 0 0 0 $space-xxs; - display: flex; - align-items: center; } .label + .button:not(:empty) {