# Tailwind
## Introduction
[Tailwind CSS](https://tailwindcss.com/docs/installation) is a "utility-first CSS framework".Tailwind provides hundreds of built-in classes that eliminate the need to start from scratch when creating designs.
Tailwind also uses [PurgeCSS](https://v2.tailwindcss.com/docs/optimizing-for-production) to remove unused classes in production, resulting in a smaller bundle size.
If you've used Bootstrap before, you'll find Tailwind easy to pick up since a lot of the classes used are similiar.
## Basic Example
CSS
```typescript
<div style={{ width: '12px', height: '12px', backgroundColor: '#fe1b1b' }}></div>
```
Tailwind
```typescript
<div className='w-3 h-3 bg-red-500'>...</div>
```
## Breakpoints
Tailwind is utilizes a [mobile-first design](https://tailwindcss.com/docs/responsive-design).
```typescript
<p className="pt-3 text-sm md:text-base xl:text-lg">...</p>
```
## Hover, Focus, and Other States
Every utility class in Tailwind can be applied conditionally by adding a [modifier](https://tailwindcss.com/docs/hover-focus-and-other-states).
```typescript
<p className="bg-sky-500 hover:bg-sky-700 ">...</p>
```
These modifiers can even be stacked to target more specific situations.
```typescript
<p className="bg-sky-500 md:hover:bg-sky-700 ">...</p>
```
## Arbitrary Values
What if you want to use a style that's not in the default Tailwind classes? And it's only seldom used, so you don't want to add it to our custom Tailwind config?
This is where Tailwind's [arbitrary values](https://tailwindcss.com/docs/adding-custom-styles#using-arbitrary-values) come into play.
```typescript
<p className="text-[28px] bg-[#6aa700]">...</p>
```
**Note:**
- Before you use an arbitray value, **please make sure that the value you need isn't in the Tailwind default classes or our custom Tailwind Config first**.
- If you find that the arbitrary values **will need to be used a lot** in the future, **please add it in our custom Tailwind Config**.
## Important Modifier
You can make any utility **important** by adding a `!` character to the beginning:
```typescript
<p className="font-bold !font-medium">...</p>
```
This is useful when we need to override old Bootstrap classes.
## Grid Example

```typescript
<div className="h-[800px] flex items-center justify-center">
<div className="grid grid-cols-3 gap-4 p-4 bg-green-500 w-[300px] h-[500px]">
<div className="row-span-2 bg-green-300">1</div>
<div className="bg-green-300">2</div>
<div className="row-span-2 bg-green-300">3</div>
<div className="bg-green-300">4</div>
<div className="col-span-3 bg-green-300">5</div>
</div>
</div>
```
## Grid example with Breakpoints

```typescript
<div className="h-[800px] flex items-center justify-center">
<div className="md:grid grid-cols-3 gap-4 p-4 bg-green-500 w-[300px] h-[500px]">
<div className="row-span-2 bg-green-300">1</div>
<div className="bg-green-300">2</div>
<div className="row-span-2 bg-green-300">3</div>
<div className="bg-green-300">4</div>
<div className="col-span-3 bg-green-300">5</div>
</div>
</div>
```
## Config
By default, Tailwind will look for an optional [tailwind.config.js](https://tailwindcss.com/docs/configuration) file at the root of your project where you can define any customizations.
### Content
Because we currently use Bootstrap as well as Tailwind in our USA project (we are planning to phase-out Bootstrap but it takes time), if we enable Tailwind globally it will mess up the formatting in some places.
Thus, if we add a new new page/component that needs Tailwind, we have to add it to the **Content** section:

**Glob Basic Syntax**
Tailwind uses [fast-glob](https://github.com/mrmlnc/fast-glob) for pattern matching.
- An asterisk (`*`) — matches everything except slashes (path separators), hidden files (names starting with `.`).
- A double star or globstar (`**`) — matches zero or more directories.
**Examples**
Say your file structure looks like this:
```
🗀 components
🗀 blog
🗀 categories
🞍 categories-list.tsx
🞍 categories-link.tsx
🞍 container.tsx
🞍 metadata.tsx
🗀 faq
🞍 search-result.tsx
🞍 search.tsx
🞍 footer.tsx
🞍 modal.tsx
🗀 pages
🞍 tailwind.config.js
```
- `./components/blog/**/*.{tsx,jsx,js}` — matches all files in the **components/blog** directory (any level of nesting) that have the extension **tsx**, **jsx**, or **js**.
- If you want to specify just one file for example, you can write `./components/blog/categories/categories-link.tsx`
### Screens
In **theme** > **screens**, we can customize our breakpoints:

### Colors
In **theme** > **extend** > **colors**, we can customize our colors:

### Important Note
- Notice how **colors** is placed within **extend**. Any config that is under **extend** means that **it is extended from the default config**.
- If it's not under **extend**, it will **override the default config** and we usually don't want that.
- So please make sure to add **any new config options under extend**.

## Homework
In our **iBuypower.NextJS** project, go to branch **playground**.
Write the code for Homework 1 and 2 here:
- pages\playground\hw-1.tsx
- pages\playground\hw-2.tsx
Work task: IUW-369
### Homework 1 - Tailwind Grid Layout (no RWD required)

### Homework 2 - Tailwind Grid Layout (with RWD)
Mobile view

Tablet view

Desktop view

## Official Docs
- https://tailwindcss.com/docs/installation
---
# Classnames
## Introduction
[Classnames](https://www.npmjs.com/package/classnames) is a simple JavaScript utility for conditionally joining classNames together.
## Usage
Basic examples of different usage:
```typescript!
classNames('foo', 'bar'); // => 'foo bar'
classNames('foo', { bar: true }); // => 'foo bar'
classNames({ 'foo-bar': true }); // => 'foo-bar'
classNames({ 'foo-bar': false }); // => ''
classNames({ foo: true }, { bar: true }); // => 'foo bar'
classNames({ foo: true, bar: true }); // => 'foo bar'
// lots of arguments of various types
classNames('foo', { bar: true, duck: false }, 'baz', { quux: true });
// => 'foo bar baz quux'
// other falsy values are just ignored
classNames(null, false, 'bar', undefined, 0, 1, { baz: null }, ''); // => 'bar 1
```
Usage with React, Tailwind, and TypeScript:
```typescript!
import cn from 'classnames';
export default function ItemCard({ text, isShown = true, variant = Variant.THIN }: IItemCardProps) {
return (
<div
className={cn('mx-auto bg-lime-400', {
'w-80 text-sm': variant === Variant.THIN,
'text-md w-96 font-bold': variant === Variant.FAT,
'hidden': isShown === false,
})}
>
<p>{text}</p>
</div>
);
}
export enum Variant {
THIN = 'THIN',
FAT = 'FAT',
}
interface IItemCardProps {
text: string;
isShown?: boolean;
variant?: Variant;
}
```
# Other
- $projects and config
- eslint and prettierr
- file naming
- const
- API proxy, endpoints, services
- redis
- preventXSS
- assgined jira work tasks
=> explain work task specs, create new branch, git commit message, how to mark progress, QA, deploying,
- answer questions