From 9aa4dc8b27b4e3d7b2aad48365bf933e73e9f4e3 Mon Sep 17 00:00:00 2001 From: Max S Date: Thu, 18 Jul 2024 19:18:55 +0200 Subject: [PATCH] :sparkles: icon button --- .../IconButton/classes.module.scss | 98 +++++++++++++++++++ .../DesignSystem/IconButton/index.tsx | 32 ++++++ .../Components/DesignSystem/Modal/index.tsx | 3 +- .../Components/Layouts/DesignSystem/index.tsx | 14 ++- src/front/Themes/variables.scss | 2 +- 5 files changed, 145 insertions(+), 4 deletions(-) create mode 100644 src/front/Components/DesignSystem/IconButton/classes.module.scss create mode 100644 src/front/Components/DesignSystem/IconButton/index.tsx diff --git a/src/front/Components/DesignSystem/IconButton/classes.module.scss b/src/front/Components/DesignSystem/IconButton/classes.module.scss new file mode 100644 index 00000000..0a0b751c --- /dev/null +++ b/src/front/Components/DesignSystem/IconButton/classes.module.scss @@ -0,0 +1,98 @@ +@import "@Themes/constants.scss"; + +.root { + cursor: pointer; + border-radius: var(--button-icon-button-radius, 8px); + + svg { + width: 24px; + min-width: 24px; + stroke: var(--button-icon-button-default-default); + } + + &:hover { + svg { + stroke: var(--button-icon-button-default-hovered); + } + } + + &.neutral { + background: var(--button-icon-button-neutral-default); + + svg { + stroke: var(--button-icon-button-default-default); + } + + &:hover { + background: var(--button-icon-button-neutral-hovered); + + svg { + stroke: var(--button-icon-button-default-hovered); + } + } + } + + &.primary { + background: var(--button-icon-button-primary-default); + + svg { + stroke: var(--button-icon-button-primary-contrast); + } + + &:hover { + background: var(--button-icon-button-primary-hovered); + } + } + + &.error { + background: var(--button-icon-button-error-default); + + svg { + stroke: var(--button-icon-button-error-contrast); + } + + &:hover { + background: var(--button-icon-button-error-hovered); + } + } + &.success { + background: var(--button-icon-button-success-default); + + svg { + stroke: var(--button-icon-button-success-contrast); + } + + &:hover { + background: var(--button-icon-button-success-hovered); + } + } + + &.warning { + background: var(--button-icon-button-warning-default); + + svg { + stroke: var(--button-icon-button-warning-contrast); + } + + &:hover { + background: var(--button-icon-button-warning-hovered); + } + } + + &.info { + background: var(--button-icon-button-info-default); + + svg { + stroke: var(--button-icon-button-info-contrast); + } + + &:hover { + background: var(--button-icon-button-info-hovered); + } + } + + &.disabled { + cursor: default; + opacity: var(--opacity-disabled, 0.3); + } +} diff --git a/src/front/Components/DesignSystem/IconButton/index.tsx b/src/front/Components/DesignSystem/IconButton/index.tsx new file mode 100644 index 00000000..817cee68 --- /dev/null +++ b/src/front/Components/DesignSystem/IconButton/index.tsx @@ -0,0 +1,32 @@ +import classNames from "classnames"; +import React from "react"; + +import classes from "./classes.module.scss"; + +export enum EIconButtonVariant { + DEFAULT = "default", + NEUTRAL = "neutral", + PRIMARY = "primary", + ERROR = "error", + SUCCESS = "success", + WARNING = "warning", + INFO = "info", +} + +type IProps = { + icon: React.ReactNode; + onClick?: React.MouseEventHandler | undefined; + variant?: EIconButtonVariant; + disabled?: boolean; + className?: string; +}; + +export default function IconButton(props: IProps) { + const { icon, onClick, className, variant = EIconButtonVariant.DEFAULT, disabled = false } = props; + + return ( + + {icon} + + ); +} diff --git a/src/front/Components/DesignSystem/Modal/index.tsx b/src/front/Components/DesignSystem/Modal/index.tsx index 1acfbab7..61022860 100644 --- a/src/front/Components/DesignSystem/Modal/index.tsx +++ b/src/front/Components/DesignSystem/Modal/index.tsx @@ -5,6 +5,7 @@ import React from "react"; import Typography, { ETypo } from "../Typography"; import { XMarkIcon } from "@heroicons/react/24/outline"; +import IconButton, { EIconButtonVariant } from "../IconButton"; type IProps = { className?: string; @@ -45,7 +46,7 @@ export default function Modal(props: IProps) { )}>
{title && {title}} - + }/>
{children}
diff --git a/src/front/Components/Layouts/DesignSystem/index.tsx b/src/front/Components/Layouts/DesignSystem/index.tsx index 8a2a6a0a..7a60cacd 100644 --- a/src/front/Components/Layouts/DesignSystem/index.tsx +++ b/src/front/Components/Layouts/DesignSystem/index.tsx @@ -6,13 +6,13 @@ import Tag, { ETagColor, ETagVariant } from "@Front/Components/DesignSystem/Tag" import Typography, { ETypo } from "@Front/Components/DesignSystem/Typography"; import Tabs from "@Front/Components/Elements/Tabs"; import DefaultTemplate from "@Front/Components/LayoutTemplates/DefaultTemplate"; -import { ArrowLongLeftIcon, ArrowLongRightIcon } from "@heroicons/react/24/outline"; +import { ArrowLongLeftIcon, ArrowLongRightIcon, XMarkIcon } from "@heroicons/react/24/outline"; import { useCallback, useMemo, useState } from "react"; import classes from "./classes.module.scss"; import useOpenable from "@Front/Hooks/useOpenable"; import Modal from "@Front/Components/DesignSystem/Modal"; -import Confirm from "@Front/Components/DesignSystem/OldModal/Confirm"; +import IconButton, { EIconButtonVariant } from "@Front/Components/DesignSystem/IconButton"; export default function DesignSystem() { const { isOpen, open, close } = useOpenable(); @@ -281,6 +281,16 @@ export default function DesignSystem() { Info +
+ } variant={EIconButtonVariant.DEFAULT} /> + } variant={EIconButtonVariant.NEUTRAL} /> + } variant={EIconButtonVariant.PRIMARY} /> + } variant={EIconButtonVariant.ERROR} /> + } variant={EIconButtonVariant.SUCCESS} /> + } variant={EIconButtonVariant.WARNING} /> + } variant={EIconButtonVariant.INFO} /> + } variant={EIconButtonVariant.INFO} disabled /> +
diff --git a/src/front/Themes/variables.scss b/src/front/Themes/variables.scss index ef4cc7da..6661f268 100644 --- a/src/front/Themes/variables.scss +++ b/src/front/Themes/variables.scss @@ -565,7 +565,7 @@ --modal-spacing: var(--spacing-md); --navigation-radius: var(--radius-none); --notification-radius: var(--radius-minimal); - --opacity-disabled: 1.875rem; + --opacity-disabled: 0.3; --radius-none: 0px; --radius-minimal: var(--radius-md); --radius-rounded: var(--radius-lg);