Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .storybook/preview-head.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<style>
@import url('https://fonts.googleapis.com/css2?family=Ubuntu&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Ubuntu:wght@400;500&display=swap');
</style>
66 changes: 66 additions & 0 deletions src/components/alert/Alert.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React from "react";
import Alert from "./Alert";
import {Meta, StoryObj} from "@storybook/react";

const meta: Meta<typeof Alert> = {
title: "Alert",
component: Alert,
argTypes: {
dismissible: {
type: "boolean"
},
icon: {
type: "boolean"
},
onClose: {table:{disable: true}},
title: {table:{disable: true}},
variant: {table:{disable: true}}
},
}

export default meta
type Story = StoryObj<typeof Alert>;

export const WithBody: Story = {
render: (args) => {

const {dismissible, icon} = args

return <>
{
["primary", "secondary", "success", "warning", "error"].map(value => {
// @ts-ignore
return <Alert variant={value} onClose={event => window.alert("closed")} dismissible={dismissible} icon={icon} title={value}>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam
</Alert>
})
}
</>

},
args: {
dismissible: false,
icon: true
}
}

export const WithoutBody: Story = {
render: (args) => {

const {dismissible, icon} = args

return <>
{
["primary", "secondary", "success", "warning", "error"].map(value => {
// @ts-ignore
return <Alert variant={value} onClose={event => window.alert("closed")} dismissible={dismissible} icon={icon} title={value}/>
})
}
</>

},
args: {
dismissible: false,
icon: true
}
}
82 changes: 82 additions & 0 deletions src/components/alert/Alert.style.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
@import "../../styles/helpers";

.alert {
@include box(1);

padding: .5rem;
margin-bottom: 1rem;
min-height: 1.5rem;


&__heading {
font-weight: 500;
}

&__header {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
}

&__content {
margin: .5rem -.5rem -.5rem -.5rem;
padding: .5rem;
}

&__header-wrapper {
display: flex;
align-items: center;
}

&__icon {
@include box(2);
pointer-events: none;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
padding: .25rem;
margin-right: .5rem;

> * {
width: 1rem;
height: 1rem;
}
}

&__dismissible {
@include box(2);

display: flex;
width: 1rem;
height: 1rem;
padding: .25rem;
cursor: pointer;
margin-left: .5rem;

> * {
width: 1rem;
height: 1rem;
}
}

}

@each $name, $color in $variants {
.alert--#{$name} {
@include box(1, $color);

.alert__icon {
@include box(2, $color);
}

.alert__content {
border-top: 1px solid rgba($color, .1);
}

.alert__dismissible {
@include box(2, $color);
}
}
}
63 changes: 63 additions & 0 deletions src/components/alert/Alert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React, {ReactElement, ReactNode} from "react";
import {IconAlertCircle, IconCircleCheck, IconCircleX, IconInfoCircle, IconX} from "@tabler/icons-react";
import "./Alert.style.scss"

export interface AlertType {

children?: ReactNode | ReactNode[]
title: ReactNode
//defaults to info
variant?: "primary" | "secondary" | "success" | "warning" | "error"
//defaults to true
icon?: boolean
//defaults to false
dismissible?: boolean
onClose?: (event: React.MouseEvent<HTMLSpanElement, MouseEvent>) => void
}

const IconVariants = {
"primary": <IconInfoCircle/>,
"secondary": <IconInfoCircle/>,
"success": <IconCircleCheck/>,
"warning": <IconAlertCircle/>,
"error": <IconCircleX/>

}

const Alert: React.FC<AlertType> = (props) => {

const {variant = "primary", dismissible = false, icon = true, title, onClose = (event) => {}, children} = props

return <div className={`alert alert--${variant}`}>
<div className={"alert__header"}>
<div className={"alert__header-wrapper"}>
{icon ? <AlertIcon variant={variant}/> : null}
<span className={"alert__heading"}>{title}</span>
</div>
{dismissible ? <span className={"alert__dismissible"} onClick={onClose}><IconX/></span> : null}
</div>

{children ? <div className={"alert__content"}>
{children}
</div> : null}
</div>

}

export interface AlertHeadingType {
children: ReactNode
}

export interface AlertIconType {
variant: "primary" | "secondary" | "success" | "warning" | "error"
}

const AlertIcon: React.FC<AlertIconType> = ({variant}) => {
return <span className={"alert__icon"}>
{IconVariants[variant]}
</span>
}



export default Alert
9 changes: 4 additions & 5 deletions src/components/input/Input.style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

.input {
margin-bottom: 1rem;
max-width: 300px;

&:last-child, &:last-of-type {
margin-bottom: 0;
Expand All @@ -17,7 +16,7 @@
display: flex;
align-items: center;

@include box();
@include box(1);
}

&__label {
Expand Down Expand Up @@ -62,7 +61,7 @@
//second parameter describes weither the this box is inside another box
@include box(2);

> svg {
> * {
width: 1rem;
height: 1rem;
}
Expand Down Expand Up @@ -135,7 +134,7 @@
&--not-valid {
.input__message {

$color: mixinColor(#D90429, 2.5);
$color: mixinColor(#D90429, 1);

display: block;
background: $color;
Expand All @@ -155,7 +154,7 @@
&--valid {
.input__message {

$color: mixinColor(#29BF12, 2.5);
$color: mixinColor(#29BF12, 1);

display: block;
background: $color;
Expand Down
57 changes: 23 additions & 34 deletions src/styles/_helpers.scss
Original file line number Diff line number Diff line change
@@ -1,42 +1,33 @@
@use "sass:math";
@import "variables";

@mixin box($level: 0, $color: $primary) {

@mixin gradientBorder($isPrimary: true) {

$color: if($isPrimary, $primary, $secondary);

&:after {
content: "";
position: absolute;
inset: 0;
border-radius: inherit;
padding: 1px; /* control the border thickness */
background: linear-gradient(0deg, rgba($color, 0), rgba($color, .1));
-webkit-mask: linear-gradient($color 0 0) content-box, linear-gradient($color 0 0);
-webkit-mask-composite: xor;
mask-composite: exclude;
pointer-events: none;
@if ($level <= 0) {
background: mixinColor($primary, .5);
} @else {
background: linear-gradient(135deg, mixinColor($color, $level) 0%, mixinColor($color, math.div($level, 2)) 100%);
}

&:hover, &:active, &--active {
&:after {
background: linear-gradient(0deg, rgba($color, 0), rgba($color, .25));
}
}
}

@mixin box($level: 1) {

background: mixinColor($primary, $level);
border-radius: $borderRadius;
color: rgba($primary, .5);
font-family: Ubuntu, sans-serif;
font-size: 1rem;
box-shadow: 0 .1rem .1rem rgba($black, .1);
border: none;
font-size: $secondaryFontSize;
@if ($level >= 2) {
box-shadow: 0 .25rem .25rem rgba($black, .2), inset 0 0 0 1px rgba($color, .1);
} @else {
box-shadow: inset 0 0 0 1px rgba($color, .1);
}
position: relative;

@include gradientBorder(true)

&:hover, &:active, &--active {

@if ($level >= 2) {
box-shadow: 0 .25rem .25rem rgba($black, .2), inset 0 0 0 1px rgba($color, .2);
} @else {
box-shadow: inset 0 0 0 1px rgba($color, .2);
}
}
}

@mixin boxSecondary($level: 1) {
Expand All @@ -45,15 +36,13 @@
border-radius: $borderRadius;
color: rgba($secondary, .5);
box-shadow: 0 .1rem .1rem rgba($black, .1);
border: none;
border: 1px solid rgba($primary, .1);
position: relative;

@include gradientBorder(false)
}


@function mixinColor($color, $level) {
@return mix($color, $bodyBg, 10% * $level);
@return mix($color, $bodyBg, 15% * $level);
}

@function lighten($level) {
Expand Down
11 changes: 11 additions & 0 deletions src/styles/_variables.scss
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
$bodyBg: #030014;
$primary: #ffffff;
$secondary: #70ffb2;
$success: #29BF12;
$warning: #FFBE0B;
$error: #D90429;
$black: #000000;

//component styling
$borderRadius: .5rem;
$primaryFontSize: 1.25rem;
$secondaryFontSize: 1rem;
$tertiaryFontSize: .75rem;

$variants: (
"primary": $primary,
"secondary": $secondary,
"success": $success,
"warning": $warning,
"error": $error
)