From 8d224dfc8ef287a577385e34b606a83f91cb6ae8 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sat, 16 Dec 2023 16:31:45 +0100 Subject: [PATCH 1/5] implementation of button component --- src/components/button/Button.stories.tsx | 74 ++++++++++++++++++++++++ src/components/button/Button.style.scss | 47 +++++++++++++++ src/components/button/Button.tsx | 59 +++++++++++++++++++ 3 files changed, 180 insertions(+) create mode 100644 src/components/button/Button.stories.tsx create mode 100644 src/components/button/Button.style.scss create mode 100644 src/components/button/Button.tsx diff --git a/src/components/button/Button.stories.tsx b/src/components/button/Button.stories.tsx new file mode 100644 index 00000000..bdd8eb1a --- /dev/null +++ b/src/components/button/Button.stories.tsx @@ -0,0 +1,74 @@ +import Button from "./Button"; +import {StoryObj} from "@storybook/react"; +import React from "react"; +import ButtonGroup from "../button-group/ButtonGroup"; +import {IconAbc} from "@tabler/icons-react"; + +const meta = { + title: "Button", + component: Button, + argTypes: { + icon: { + type: "boolean", + default: true + }, + variant: {table: {disable: true}} + } +} + +type ButtonStory = StoryObj<{ icon: boolean }>; +type ButtonGroupStory = StoryObj; + +export default meta + +export const Buttons: ButtonStory = { + render: (args) => { + + const {icon} = args + + return <> + { + ["primary", "secondary", "info", "success", "warning", "error"].map(value => { + // @ts-ignore + return + }) + } + + }, + args: { + icon: true + } +} + +export const ButtonGroups: ButtonGroupStory = { + render: () => { + return <> + + { + ["primary", "secondary", "info", "success", "warning", "error"].map((value, index) => { + // @ts-ignore + return + }) + } + + + { + ["primary", "primary", "primary", "primary"].map((value, index) => { + // @ts-ignore + return + }) + } + + + + } +} \ No newline at end of file diff --git a/src/components/button/Button.style.scss b/src/components/button/Button.style.scss new file mode 100644 index 00000000..c1e52cd3 --- /dev/null +++ b/src/components/button/Button.style.scss @@ -0,0 +1,47 @@ +@import "../../styles/helpers"; + +.button { + @include box(true); + + padding: .5rem; + cursor: pointer; + display: flex; + align-items: center; + margin-bottom: 1rem; + width: fit-content; + + + &__icon + &__content { + margin-left: .5rem; + display: inline-block; + position: relative; + } + + &__icon { + @include box(false); + + display: inline-flex; + justify-content: center; + align-items: center; + width: 1rem; + height: 1rem; + padding: .25rem; + cursor: pointer; + + > * { + width: 1rem; + height: 1rem; + } + } +} + +@each $name, $color in $variants { + .button--#{$name} { + @include box(true, $color); + + .button__icon { + @include box(false, $color); + } + + } +} \ No newline at end of file diff --git a/src/components/button/Button.tsx b/src/components/button/Button.tsx new file mode 100644 index 00000000..ec6c6352 --- /dev/null +++ b/src/components/button/Button.tsx @@ -0,0 +1,59 @@ +import "./Button.style.scss" +import React, { + AnchorHTMLAttributes, + DetailedHTMLProps, + ReactNode +} from "react"; + +export interface ButtonType extends DetailedHTMLProps, HTMLAnchorElement> { + children: ReactNode | ReactNode[] + //defaults to primary + variant?: "primary" | "secondary" | "info" | "success" | "warning" | "error", + //defaults to false + active?: boolean +} + +export interface ButtonIconType { + children: ReactNode +} + +const Button: React.FC = (props) => { + + const {children, variant = "primary", active = false, ...args} = props + const icon = getChild(children, ButtonIcon) + const content = getContent(children, ButtonIcon) + + + return + {icon} + {content ? {content} : null} + +} + +const ButtonIcon: React.FC = ({children}) => { + return + {children} + +} + + +const getChild = (children: ReactNode | ReactNode[], child: React.FC): ReactNode | null => { + return React.Children.toArray(children).find((childT) => { + if (!React.isValidElement(childT)) return false; + return childT.type == child; + }) +} + +const getContent = (children: ReactNode | ReactNode[], ...child: React.FC[]): ReactNode[] | null => { + + const array = React.Children.toArray(children).filter((childT) => { + if (!React.isValidElement(childT)) return true; + return !child.find(value => value == childT.type); + }) + + return array.length == 0 ? null : array +} + +export default Object.assign(Button, { + Icon: ButtonIcon +}); \ No newline at end of file From 5e93e24129182bb19221f8b9152515cfcc7c38b3 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sat, 16 Dec 2023 16:31:53 +0100 Subject: [PATCH 2/5] implementation of button-group component --- .../button-group/ButtonGroup.style.scss | 25 +++++++++++++++++++ src/components/button-group/ButtonGroup.tsx | 18 +++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 src/components/button-group/ButtonGroup.style.scss create mode 100644 src/components/button-group/ButtonGroup.tsx diff --git a/src/components/button-group/ButtonGroup.style.scss b/src/components/button-group/ButtonGroup.style.scss new file mode 100644 index 00000000..0d6872f7 --- /dev/null +++ b/src/components/button-group/ButtonGroup.style.scss @@ -0,0 +1,25 @@ +@import "../../styles/helpers"; + +.button-group { + @include box(false, $primary); + + border: none; + width: fit-content; + margin-bottom: 1rem; + display: flex; + + > * { + margin-bottom: 0 !important; + border-radius: 0 !important; + + &:first-child { + border-bottom-left-radius: .5rem !important; + border-top-left-radius: .5rem !important; + } + + &:last-child { + border-bottom-right-radius: .5rem !important; + border-top-right-radius: .5rem !important; + } + } +} \ No newline at end of file diff --git a/src/components/button-group/ButtonGroup.tsx b/src/components/button-group/ButtonGroup.tsx new file mode 100644 index 00000000..e761fece --- /dev/null +++ b/src/components/button-group/ButtonGroup.tsx @@ -0,0 +1,18 @@ +import React, {ReactElement} from "react"; +import {ButtonType} from "../button/Button"; +import "./ButtonGroup.style.scss" + +export interface ButtonGroupType { + children: ReactElement[] +} + +const ButtonGroup: React.FC = (props) => { + + const {children} = props + + return
+ {children} +
+} + +export default ButtonGroup; \ No newline at end of file From 8c0a557500528d8c1d8f48db31f3f98eec82dbd6 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sat, 16 Dec 2023 17:04:37 +0100 Subject: [PATCH 3/5] fixing no border color bug, because of wrong param --- src/components/alert/Alert.style.scss | 2 +- src/styles/_helpers.scss | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/alert/Alert.style.scss b/src/components/alert/Alert.style.scss index b5fb1ea3..230df3fb 100644 --- a/src/components/alert/Alert.style.scss +++ b/src/components/alert/Alert.style.scss @@ -71,7 +71,7 @@ } .alert__content { - border-top: 1px solid borderColor($color); + border-top: 1px solid borderColor(); } .alert__dismissible { diff --git a/src/styles/_helpers.scss b/src/styles/_helpers.scss index ae69ec25..c106f7cf 100644 --- a/src/styles/_helpers.scss +++ b/src/styles/_helpers.scss @@ -8,12 +8,12 @@ color: rgba($white, .5); font-family: Ubuntu, sans-serif; font-size: $secondaryFontSize; - border: 1px solid borderColor($color); + border: 1px solid borderColor(); position: relative; @if ($active == true) { @include hoverAndActiveContent { - border: 1px solid borderColor($color, true); + border: 1px solid borderColor($white, true); } @include activeContent { From 33d60f2ed40ebdd5731ac1991954f7b99c12a500 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sat, 16 Dec 2023 17:09:22 +0100 Subject: [PATCH 4/5] adding disable functionality to buttons --- src/components/button/Button.stories.tsx | 25 ++++++++++++++++++++---- src/components/button/Button.style.scss | 4 ++++ src/components/button/Button.tsx | 6 ++++-- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/components/button/Button.stories.tsx b/src/components/button/Button.stories.tsx index bdd8eb1a..51f7c631 100644 --- a/src/components/button/Button.stories.tsx +++ b/src/components/button/Button.stories.tsx @@ -12,11 +12,15 @@ const meta = { type: "boolean", default: true }, + disabled: { + type: "boolean", + default: false + }, variant: {table: {disable: true}} } } -type ButtonStory = StoryObj<{ icon: boolean }>; +type ButtonStory = StoryObj<{ icon: boolean, disabled: boolean}>; type ButtonGroupStory = StoryObj; export default meta @@ -24,13 +28,13 @@ export default meta export const Buttons: ButtonStory = { render: (args) => { - const {icon} = args + const {icon, disabled} = args return <> { ["primary", "secondary", "info", "success", "warning", "error"].map(value => { // @ts-ignore - return @@ -39,7 +43,8 @@ export const Buttons: ButtonStory = { }, args: { - icon: true + icon: true, + disabled: false } } @@ -69,6 +74,18 @@ export const ButtonGroups: ButtonGroupStory = { } + + { + ["primary", "primary", "primary", "primary"].map((value, index) => { + // @ts-ignore + return + }) + } + + } } \ No newline at end of file diff --git a/src/components/button/Button.style.scss b/src/components/button/Button.style.scss index c1e52cd3..411bd9e3 100644 --- a/src/components/button/Button.style.scss +++ b/src/components/button/Button.style.scss @@ -10,6 +10,10 @@ margin-bottom: 1rem; width: fit-content; + &--disabled { + opacity: 50%; + pointer-events: none; + } &__icon + &__content { margin-left: .5rem; diff --git a/src/components/button/Button.tsx b/src/components/button/Button.tsx index ec6c6352..a57bb531 100644 --- a/src/components/button/Button.tsx +++ b/src/components/button/Button.tsx @@ -11,6 +11,8 @@ export interface ButtonType extends DetailedHTMLProps = (props) => { - const {children, variant = "primary", active = false, ...args} = props + const {children, variant = "primary", active = false, disabled = false, ...args} = props const icon = getChild(children, ButtonIcon) const content = getContent(children, ButtonIcon) - return + return {icon} {content ? {content} : null} From e6f92668e9a97041137bd7a48a829e5192b62f89 Mon Sep 17 00:00:00 2001 From: nicosammito Date: Sat, 16 Dec 2023 17:11:16 +0100 Subject: [PATCH 5/5] adding disable functionality to buttons --- src/components/button/Button.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/button/Button.stories.tsx b/src/components/button/Button.stories.tsx index 51f7c631..cf016af5 100644 --- a/src/components/button/Button.stories.tsx +++ b/src/components/button/Button.stories.tsx @@ -76,7 +76,7 @@ export const ButtonGroups: ButtonGroupStory = { { - ["primary", "primary", "primary", "primary"].map((value, index) => { + ["secondary", "secondary", "secondary", "secondary"].map((value, index) => { // @ts-ignore return