diff --git a/packages/octuple/src/components/Button/BaseButton.tsx b/packages/octuple/src/components/Button/BaseButton.tsx index 1400e840c..dac04311a 100644 --- a/packages/octuple/src/components/Button/BaseButton.tsx +++ b/packages/octuple/src/components/Button/BaseButton.tsx @@ -1,5 +1,11 @@ import React, { FC, Ref } from 'react'; -import { ButtonSize, ButtonTheme, ButtonWidth, InternalButtonProps } from './'; +import { + ButtonShape, + ButtonSize, + ButtonTheme, + ButtonWidth, + InternalButtonProps, +} from './'; import { Icon, IconName, IconSize } from '../Icon'; import { Breakpoints, useMatchMedia } from '../../hooks/useMatchMedia'; import { classNames } from '../../shared/utilities'; @@ -14,11 +20,13 @@ export const BaseButton: FC = React.forwardRef( checked = false, className, disabled = false, + dropShadow = false, htmlType, icon, iconColor, id, onClick, + shape = ButtonShape.Rectangle, size = ButtonSize.Flex, style, text, @@ -59,6 +67,8 @@ export const BaseButton: FC = React.forwardRef( { [styles.buttonPadding2]: size === ButtonSize.Medium }, { [styles.buttonPadding3]: size === ButtonSize.Small }, { [styles.buttonStretch]: buttonWidth === ButtonWidth.fill }, + { [styles.pillShape]: shape === ButtonShape.Pill }, + { [styles.dropShadow]: dropShadow }, { [styles.dark]: theme === ButtonTheme.dark }, { [styles.disabled]: allowDisabledFocus || disabled }, ]); diff --git a/packages/octuple/src/components/Button/Button.stories.tsx b/packages/octuple/src/components/Button/Button.stories.tsx index 5bd33afb5..6778835be 100644 --- a/packages/octuple/src/components/Button/Button.stories.tsx +++ b/packages/octuple/src/components/Button/Button.stories.tsx @@ -1,7 +1,10 @@ import React, { FC } from 'react'; import { + ButtonShape, ButtonSize, + ButtonWidth, DefaultButton, + NeutralButton, PrimaryButton, SecondaryButton, } from './index'; @@ -30,6 +33,17 @@ export const Primary = () => ( />

+

Default Flex (Fill)

+
+ +
+

Text only

( />

+

Text only (Pill)

+ +
+

Icon only

( />

+

Text only (Pill)

+ +
+

Icon only

( />

+

Text only (Pill)

+ +
+

Icon only

( size={ButtonSize.Large} text="Default Button" /> +
+
+

Disruptive

+ + +); + +export const Neutral = () => ( + <> +

Neutral Button

+

Text only

+ +
+
+

Text only (Pill)

+ +
+
+

Icon only

+ +
+
+

Text + Icon

+ ); @@ -147,6 +245,7 @@ export const Toggle: FC = ({ checked }) => { const [skill1Added, { toggle: set1Added }] = useBoolean(false); const [skill2Added, { toggle: set2Added }] = useBoolean(false); const [skill3Added, { toggle: set3Added }] = useBoolean(false); + const [skill4Added, { toggle: set4Added }] = useBoolean(false); return ( <>

Toggle With Text + Icon

@@ -187,6 +286,17 @@ export const Toggle: FC = ({ checked }) => { toggle /> + + + ); }; diff --git a/packages/octuple/src/components/Button/Button.types.ts b/packages/octuple/src/components/Button/Button.types.ts index 8ca50a61d..d3a11a75c 100644 --- a/packages/octuple/src/components/Button/Button.types.ts +++ b/packages/octuple/src/components/Button/Button.types.ts @@ -14,6 +14,11 @@ export enum ButtonWidth { fill = 'fill', } +export enum ButtonShape { + Rectangle = 'rectangle', + Pill = 'pill', +} + export enum ButtonTheme { light = 'light', dark = 'dark', @@ -21,6 +26,7 @@ export enum ButtonTheme { export enum ButtonType { Default = 'default', + Neutral = 'neutral', Primary = 'primary', Secondary = 'secondary', } @@ -65,6 +71,11 @@ export interface ButtonProps extends NativeButtonProps { * @default false */ disruptive?: boolean; + /** + * The button drop shadow state. + * @default false + */ + dropShadow?: boolean; /** * The button html type. */ @@ -90,14 +101,10 @@ export interface ButtonProps extends NativeButtonProps { */ primaryColor?: string; /** - * The button text. + * Shape of the button. + * @default ButtonShape.Rectangle */ - text?: string; - /** - * The button theme. - * @default light - */ - theme?: ButtonTheme; + shape?: ButtonShape; /** * The button size. * @default ButtonSize.Medium @@ -120,6 +127,15 @@ export interface ButtonProps extends NativeButtonProps { * The button style. */ style?: React.CSSProperties; + /** + * The button text. + */ + text?: string; + /** + * The button theme. + * @default light + */ + theme?: ButtonTheme; /** * The button is a toggle button with distinct on and off states. */ diff --git a/packages/octuple/src/components/Button/DefaultButton/DefaultButton.tsx b/packages/octuple/src/components/Button/DefaultButton/DefaultButton.tsx index 2ce61e157..b78459604 100644 --- a/packages/octuple/src/components/Button/DefaultButton/DefaultButton.tsx +++ b/packages/octuple/src/components/Button/DefaultButton/DefaultButton.tsx @@ -1,5 +1,11 @@ import React, { FC, Ref } from 'react'; -import { BaseButton, ButtonProps, ButtonSize, ButtonType } from '../'; +import { + ButtonShape, + BaseButton, + ButtonProps, + ButtonSize, + ButtonType, +} from '../'; import { classNames } from '../../../shared/utilities'; import styles from '../button.module.scss'; @@ -12,12 +18,14 @@ export const DefaultButton: FC = React.forwardRef( checked = false, className, disabled = false, + dropShadow = false, htmlType, icon, iconColor, onClick, text, theme, + shape = ButtonShape.Rectangle, size = ButtonSize.Flex, style, toggle, @@ -43,10 +51,12 @@ export const DefaultButton: FC = React.forwardRef( checked={checked} className={buttonClassNames} disabled={disabled} + dropShadow={dropShadow} htmlType={htmlType} icon={icon} iconColor={iconColor} onClick={onClick} + shape={shape} size={size} style={style} text={text} diff --git a/packages/octuple/src/components/Button/NeutralButton/NeutralButton.tsx b/packages/octuple/src/components/Button/NeutralButton/NeutralButton.tsx new file mode 100644 index 000000000..359ae52c7 --- /dev/null +++ b/packages/octuple/src/components/Button/NeutralButton/NeutralButton.tsx @@ -0,0 +1,68 @@ +import React, { FC, Ref } from 'react'; +import { + ButtonShape, + BaseButton, + ButtonProps, + ButtonSize, + ButtonType, +} from '../'; +import { classNames } from '../../../shared/utilities'; + +import styles from '../button.module.scss'; + +export const NeutralButton: FC = React.forwardRef( + ( + { + allowDisabledFocus = false, + ariaLabel, + checked = false, + className, + disabled = false, + dropShadow = false, + htmlType, + icon, + iconColor, + onClick, + text, + theme, + shape = ButtonShape.Rectangle, + size = ButtonSize.Flex, + style, + toggle, + buttonWidth, + ...rest + }, + ref: Ref + ) => { + const buttonClassNames: string = classNames([ + className, + styles.button, + styles.buttonNeutral, + ]); + + return ( + + ); + } +); diff --git a/packages/octuple/src/components/Button/PrimaryButton/PrimaryButton.tsx b/packages/octuple/src/components/Button/PrimaryButton/PrimaryButton.tsx index 9d5c86b0b..8b22b2e87 100644 --- a/packages/octuple/src/components/Button/PrimaryButton/PrimaryButton.tsx +++ b/packages/octuple/src/components/Button/PrimaryButton/PrimaryButton.tsx @@ -1,5 +1,11 @@ import React, { FC, Ref } from 'react'; -import { BaseButton, ButtonProps, ButtonSize, ButtonType } from '../'; +import { + ButtonShape, + BaseButton, + ButtonProps, + ButtonSize, + ButtonType, +} from '../'; import { classNames } from '../../../shared/utilities'; import styles from '../button.module.scss'; @@ -13,10 +19,12 @@ export const PrimaryButton: FC = React.forwardRef( className, disabled = false, disruptive = false, + dropShadow = false, htmlType, icon, iconColor, onClick, + shape = ButtonShape.Rectangle, size = ButtonSize.Flex, style, text, @@ -42,10 +50,12 @@ export const PrimaryButton: FC = React.forwardRef( className={buttonClassNames} disabled={disabled} disruptive={disruptive} + dropShadow={dropShadow} htmlType={htmlType} icon={icon} iconColor={iconColor} onClick={onClick} + shape={shape} size={size} style={style} text={text} diff --git a/packages/octuple/src/components/Button/SecondaryButton/SecondaryButton.tsx b/packages/octuple/src/components/Button/SecondaryButton/SecondaryButton.tsx index f22e1580a..a381707cd 100644 --- a/packages/octuple/src/components/Button/SecondaryButton/SecondaryButton.tsx +++ b/packages/octuple/src/components/Button/SecondaryButton/SecondaryButton.tsx @@ -1,6 +1,12 @@ import React, { FC, Ref } from 'react'; import { classNames } from '../../../shared/utilities'; -import { BaseButton, ButtonProps, ButtonSize, ButtonType } from '../'; +import { + ButtonShape, + BaseButton, + ButtonProps, + ButtonSize, + ButtonType, +} from '../'; import styles from '../button.module.scss'; @@ -13,12 +19,14 @@ export const SecondaryButton: FC = React.forwardRef( className, disabled = false, disruptive = false, + dropShadow = false, htmlType, icon, iconColor, onClick, text, theme, + shape = ButtonShape.Rectangle, size = ButtonSize.Flex, style, toggle, @@ -42,10 +50,12 @@ export const SecondaryButton: FC = React.forwardRef( className={buttonClassNames} disabled={disabled} disruptive={disruptive} + dropShadow={dropShadow} htmlType={htmlType} icon={icon} iconColor={iconColor} onClick={onClick} + shape={shape} size={size} style={style} text={text} diff --git a/packages/octuple/src/components/Button/button.module.scss b/packages/octuple/src/components/Button/button.module.scss index 21cc99e76..6114cbbf2 100644 --- a/packages/octuple/src/components/Button/button.module.scss +++ b/packages/octuple/src/components/Button/button.module.scss @@ -25,6 +25,23 @@ margin-left: $button-spacer-small; } + &.pill-shape { + border-radius: $corner-radius-xl; + } + + &.drop-shadow { + box-shadow: 0 1px 2px rgba(15, 20, 31, 0.12), + 0 2px 8px rgba(15, 20, 31, 0.16); + } + + &.button-stretch { + width: 100%; + + span { + justify-content: center; + } + } + &:disabled, &.disabled { opacity: $disabled-alpha-value; @@ -37,10 +54,6 @@ } } -.button-stretch { - width: 100%; -} - .button-padding-1 { padding: $button-padding-vertical-large $button-padding-horizontal-large; } @@ -207,25 +220,31 @@ .button-neutral { color: var(--text-secondary-color); - border: rem(2px) solid var(--grey-color-70); + outline: transparent solid rem(2px); + outline-offset: rem(-2px); &:hover { background-color: var(--grey-color-20); - border-color: var(--grey-color-20); + outline-color: var(--grey-color-20); } &:active { background-color: var(--grey-color-10); - border-color: var(--grey-color-10); + outline-color: var(--grey-color-10); } &:focus-visible { - border-color: var(--primary-color-80); + outline-color: var(--grey-color-80); } } .dark { .button { background-color: inherit; + + &.drop-shadow { + box-shadow: 0 1px 2px rgba(15, 20, 31, 0.12), + 0 2px 8px rgba(15, 20, 31, 0.16); + } } } diff --git a/packages/octuple/src/components/Button/index.ts b/packages/octuple/src/components/Button/index.ts index df9ceb62f..3e865699e 100644 --- a/packages/octuple/src/components/Button/index.ts +++ b/packages/octuple/src/components/Button/index.ts @@ -1,5 +1,6 @@ export * from './Button.types'; export * from './BaseButton'; export * from './DefaultButton/DefaultButton'; +export * from './NeutralButton/NeutralButton'; export * from './PrimaryButton/PrimaryButton'; export * from './SecondaryButton/SecondaryButton'; diff --git a/packages/octuple/src/components/Inputs/Input.types.ts b/packages/octuple/src/components/Inputs/Input.types.ts index e4267f447..22a3c3606 100644 --- a/packages/octuple/src/components/Inputs/Input.types.ts +++ b/packages/octuple/src/components/Inputs/Input.types.ts @@ -8,7 +8,7 @@ export enum TextInputTheme { dark = 'dark', } -export enum InputWidth { +export enum TextInputWidth { fitContent = 'fitContent', fill = 'fill', } @@ -258,7 +258,7 @@ export interface InputProps { * Width of the tooltip * @default fitContent */ - inputWidth?: InputWidth; + inputWidth?: TextInputWidth; /** * The input icon img element source. */ diff --git a/packages/octuple/src/components/Inputs/SearchBox/SearchBox.stories.tsx b/packages/octuple/src/components/Inputs/SearchBox/SearchBox.stories.tsx index 322a59f1e..5fd0731cd 100644 --- a/packages/octuple/src/components/Inputs/SearchBox/SearchBox.stories.tsx +++ b/packages/octuple/src/components/Inputs/SearchBox/SearchBox.stories.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { IconName } from '../../Icon'; -import { InputWidth, SearchBox, TextInputShape } from '../index'; +import { SearchBox, TextInputShape, TextInputWidth } from '../index'; export default { title: 'Search Box', @@ -11,7 +11,7 @@ export const Search = () => ( <>

Search Boxes

Search Box Stretch (Rectangle)

- +

Search Box with Icon and Icon Button (Rectangle)

@@ -49,7 +49,7 @@ export const Search = () => ( _alertClicked(_event), diff --git a/packages/octuple/src/components/Inputs/SearchBox/SearchBox.tsx b/packages/octuple/src/components/Inputs/SearchBox/SearchBox.tsx index 156783354..559ce3ad1 100644 --- a/packages/octuple/src/components/Inputs/SearchBox/SearchBox.tsx +++ b/packages/octuple/src/components/Inputs/SearchBox/SearchBox.tsx @@ -1,7 +1,7 @@ import React, { FC } from 'react'; import { IconName } from '../../Icon'; import { - InputWidth, + TextInputWidth, SearchBoxProps, TextInput, TextInputShape, @@ -21,7 +21,7 @@ export const SearchBox: FC = ({ disabled: false, icon: IconName.mdiMagnify, }, - inputWidth = InputWidth.fitContent, + inputWidth = TextInputWidth.fitContent, label, labelIconButtonProps, maxlength, diff --git a/packages/octuple/src/components/Inputs/TextArea/TextArea.stories.tsx b/packages/octuple/src/components/Inputs/TextArea/TextArea.stories.tsx index 760250d8f..0fb143e24 100644 --- a/packages/octuple/src/components/Inputs/TextArea/TextArea.stories.tsx +++ b/packages/octuple/src/components/Inputs/TextArea/TextArea.stories.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { InputWidth, TextArea } from '../index'; +import { TextArea, TextInputWidth } from '../index'; export default { title: 'Text Area', @@ -10,7 +10,7 @@ export const Area = () => ( <>

Text Areas

Text Area No Expand Stretch (Rectangle)

-