02 Waffles (Toasts) | Building 🚧 Dock-UI: Custom Tailwind CSS components for H010SPACE
Tags: tailwindcss, css
Published: 2021-11-30 16:06:50

> Every since I was introduced to Tailwind CSS - A utility-first CSS framework - I have wanted to build my own flavor of custom UI components with it. Even with so many wonderful UI component frameworks and libraries out there, some may have a few component styles I like, but none have all and only the components I like / find useful.

> So, I have decided to document building a complete set of my own custom components called Dock-UI.

Last time, we used Tailwind CSS to style the `<input />` element to look like the [Material Design filled text field](https://dev.to/shecodez/building-dock-ui-custom-tailwind-css-components-for-h010space-1-text-fields-28dj).  

*This is gon' be fun. We can stay up in the comment section, swapping dev stories, 'cause in this mornings post we're making waffles!* 🧇 

{% youtube bHIa5IFfKZI %}

**Question**: so what the duck 🦆 are *waffles*? **Answer**: waffles are fancy toast. 

I hope with this post you'll see that we're building more than just plain old toasts so I dub thee fancy toast sir `d-waffles`.

So starting off the inspiration for style of this UI component comes from this [codepen](https://codepen.io/juliepark/pen/vjMOKQ) by [Julie Park](https://codepen.io/juliepark).

**HTML**
```
<div class="d-waffle overflow-hidden w-64 py-2 border border-gray-600 m-1 rounded-lg shadow-md">
  <div class="actions flex justify-end space-x-1 p-1 mr-2">
    <div class="w-2 h-2 rounded-full bg-white bg-opacity-50 hover:bg-green-500 cursor-pointer">
      <span class="sr-only">ok</span>
    </div>
    <div class="w-2 h-2 rounded-full bg-white hover:bg-red-500 cursor-pointer">
      <span class="sr-only">close</span>
    </div>
  </div>

  <div class="relative success-face">
    <div class="exclamation absolute left-7 -top-6 z-20 text-red-400 font-bold hidden">-!-</div>
    <div class="face absolute w-11 h-11 bg-white rounded-full border border-gray-800 top-0 left-4 z-10">
      <span class="eye absolute w-1 h-1 bg-gray-900 rounded-full"></span>
      <span class="eye absolute w-1 h-1 bg-gray-900 rounded-full"></span>
      <span class="mouth absolute w-2 h-2 rounded-full"></span>
    </div>
    <div class="shadow absolute w-10 h-1 bg-gray-900 bg-opacity-30 left-5 top-11 z-10"></div>
  </div>
  <div class="message ml-16 text-white">
    <h4 class="mx-2 text-sm font-bold uppercase">Success</h4>
    <p class="mx-2 text-xs text-gray-800">We made a waffle! 🧇</p>
  </div>
</div>
```

**SCSS**
```
.d-waffle {
  min-height: 5rem;
}

.d-waffle .message h4 {
  text-shadow: 1px 1px #222;
  letter-spacing: 2px;
}

.d-waffle .eye {
  top: 40%;
  left: 21%;
}
.d-waffle .eye:nth-of-type(2) {
  left: 68%;
}

.d-waffle .shadow {
  border-radius: 50%;
}

.d-waffle .mouth {
  top: 43%;
  left: 41%;
}

.d-waffle .success-face .mouth {
  border: 1px solid;
  border-color: transparent #777 #777 transparent;
  transform: rotate(45deg);
}

$white: #fcfcfc;
$grey: #ccc;
$dark: #777;
$error: #ef8d9c;
$orange: #ffc39e;
$success: #b0db7d;
$lime: #99dbb4;
$blue: #7db0db;
$purple: #7d81db;
$yellow: #efe08d;
$peach: #efaf8d;

.d-waffle {
  //@apply bg-gradient-to-br from-green-500 to-indigo-300;
  background: linear-gradient(to bottom right, $success 40%, $lime 100%);
}
```

That gives us this cute little guy.

{% codepen https://codepen.io/shecodez/pen/QWMXVMQ %}

Lets add the CSS for the error, info, and warning waffle background.

**SCSS**
```
$white: #fcfcfc;
$grey: #ccc;
$dark: #777;
$error: #ef8d9c;
$orange: #ffc39e;
$success: #b0db7d;
$lime: #99dbb4;
$blue: #7db0db;
$purple: #7d81db;
$yellow: #efe08d;
$peach: #efaf8d;

.d-waffle.error-waffle {
  /*@apply bg-gradient-to-bl from-error-500 to-yellow-500;*/
  background: linear-gradient(to bottom left, $error 40%, $orange 100%);
}

.d-waffle.info-waffle {
  /*@apply bg-gradient-to-br from-info-500 to-purple-500;*/ 
  background: linear-gradient(to bottom right, $blue 40%, $purple 100%);
}

.d-waffle.warning-waffle {
  /*@apply bg-gradient-to-bl from-warning-500 to-red-300;*/
  background: linear-gradient(to bottom left, $yellow 40%, $peach 100%); 
}
```

Success is the default `.d-waffle` background so we can add `.error-waffle`, `.info-waffle`, or `.warning-waffle` to change the background colors.

Now all we have to do is add the styles for the different faces and animate them.

**SCSS**
```
.d-waffle .success-face .mouth {
  border: 1px solid;
  border-color: transparent #777 #777 transparent;
  transform: rotate(45deg);
}

.d-waffle .error-face .mouth {
  border: 1px solid;
  border-color: #777 transparent transparent #777;
  transform: rotate(45deg);
}

.d-waffle .info-face .mouth {
  border: 1px solid #777;
  border-radius: 0;
}

.d-waffle .warning-face .mouth {
  top: 50%;
  height: 1px;
  border-bottom: 1px solid #777;
  border-radius: 0;
}
``` 

And the finally the animations!
 
**SCSS**
```
.d-waffle .success-face .face {
  animation: bounce 1s ease-in infinite;
}
.d-waffle .success-face .shadow {
  animation: scale 1s ease-in infinite;
}

.d-waffle .error-face .face {
  left: initial;
  right: 5%;
  animation: roll 3s ease-in-out infinite;
}
.d-waffle .error-face .shadow {
  left: initial;
  right: 5%;
  animation: move 3s ease-in-out infinite;
}

.d-waffle .info-face .mouth {
  animation: talk 2s ease-in-out infinite;
}

.d-waffle .warning-face .eye {
  animation: blink 2s steps(5, start) infinite;
}

.d-waffle.warning-waffle .exclamation {
  text-shadow: 1px 1px #777;
  animation: scale 1s ease-in-out infinite;
}

@keyframes bounce {
  50% {
    transform: translateY(-10px);
  }
}

@keyframes scale {
  50% {
    transform: scale(0.85);
  }
}

@keyframes roll {
  0% {
    transform: rotate(0deg);
    right: 5%;
  }
  50% {
    right: 45%;
    transform: rotate(-175deg);
  }
  100% {
    transform: rotate(0deg);
    right: 5%;
  }
}

@keyframes move {
  0% {
    right: 5%;
  }
  50% {
    right: 45%;
  }
  100% {
    right: 5%;
  }
}

@keyframes talk {
  0% {
    height: 8px;
  }
  45% {
    height: 2px;
  }
  75% {
    height: 6px;
  }
  85% {
    height: 4px;
  }
  100% {
    height: 6px;
  }
}

@keyframes blink {
  0% {
    height: 4px;
  }
  85% {
    height: 4px;
  }
  95% {
    height: 2px;
  }
  100% {
    height: 1px;
  }
}
```

{% codepen https://codepen.io/shecodez/pen/ExwxrxO %}

And with that we've completed the `d-waffle` dock-ui component. Of course it's very basic right now, but I leave the upgrades for you and future me. Thanks for reading! 😊