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/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 diff --git a/src/components/button/Button.stories.tsx b/src/components/button/Button.stories.tsx new file mode 100644 index 00000000..cf016af5 --- /dev/null +++ b/src/components/button/Button.stories.tsx @@ -0,0 +1,91 @@ +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 + }, + disabled: { + type: "boolean", + default: false + }, + variant: {table: {disable: true}} + } +} + +type ButtonStory = StoryObj<{ icon: boolean, disabled: boolean}>; +type ButtonGroupStory = StoryObj; + +export default meta + +export const Buttons: ButtonStory = { + render: (args) => { + + const {icon, disabled} = args + + return <> + { + ["primary", "secondary", "info", "success", "warning", "error"].map(value => { + // @ts-ignore + return + }) + } + + }, + args: { + icon: true, + disabled: false + } +} + +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 + }) + } + + + + { + ["secondary", "secondary", "secondary", "secondary"].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..411bd9e3 --- /dev/null +++ b/src/components/button/Button.style.scss @@ -0,0 +1,51 @@ +@import "../../styles/helpers"; + +.button { + @include box(true); + + padding: .5rem; + cursor: pointer; + display: flex; + align-items: center; + margin-bottom: 1rem; + width: fit-content; + + &--disabled { + opacity: 50%; + pointer-events: none; + } + + &__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..a57bb531 --- /dev/null +++ b/src/components/button/Button.tsx @@ -0,0 +1,61 @@ +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 + //defaults to false + disabled?: boolean +} + +export interface ButtonIconType { + children: ReactNode +} + +const Button: React.FC = (props) => { + + const {children, variant = "primary", active = false, disabled = 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 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 {