Skip to content

Commit d4bcc64

Browse files
feat: add shadcn for components (#21)
* initialize shadcn * feat: create css variables and tw utilities based on figma variables * docs: create GUIDES.md to explain how to build UI starting from Figma * fix: biome wants every CSS rule to end with a semicolon * docs: add important note in the create component part
1 parent 2e87a08 commit d4bcc64

File tree

13 files changed

+345
-5
lines changed

13 files changed

+345
-5
lines changed

GUIDES.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Guides collection
2+
3+
## How to apply styles based on Figma design
4+
This guide is especially useful when customizing shadcn components to fit our design on Figma.
5+
6+
> [!important]
7+
> When reusing styled blocks of elements many times, consider creating a custom component.
8+
>
9+
> AVOID applying colors or typography by manually adding tailwind rules,
10+
> use instead our custom variables as shown below
11+
12+
### Background color
13+
Use `bg-` and append the color variable
14+
NB: do NOT include the variable class (e.g. `neutrals`) in the classname
15+
16+
e.g. `neutrals/background` => `bg-text-primary`
17+
e.g. `buttons/button-primary` => `bg-button-primary`
18+
19+
### Text color
20+
Use `text-` and append the color variable
21+
NB: do NOT include the variable class (e.g. `neutrals`) in the classname
22+
23+
e.g. `neutrals/text-primary` => `text-text-primary`
24+
e.g. `accents/blue-secondary` => `text-blue-secondary`
25+
26+
### Typography
27+
We created a custom [Tailwind utility class](https://tailwindcss.com/docs/adding-custom-styles#adding-custom-utilities)
28+
to apply the styles matching the typography library on Figma.
29+
Use `typo-`, adding the type and the weight separated by hyphen.
30+
31+
e.g. `polinet-type/baseline/display/extralarge` => `typo-display-extralarge`
32+
e.g. `polinet-type/baseline/label/small` => `typo-label-small`
33+
34+
35+
## How to create a new UI component
36+
We use shadcn components as base UI elements because they support variants and sizes, while usually following React reusable components guidelines.
37+
38+
> [!important]
39+
> shadcn components must be UI elements that are generally used across the website (like a Card or a Button).
40+
> If you need a component page-specific or section-specific, build upon shadcn components.
41+
> shadcn components must be the individual pieces that compose an end-user component.
42+
43+
Check if we already have that UI component in the `src/components/ui` folder.
44+
- If it does not exist:
45+
1. visit [shadcn's components list](https://ui.shadcn.com/docs/components) and follow the instructions to install
46+
2. change the default styling using our custom theme variables based on Figma design. See [this guide](#how-to-apply-styles-based-on-figma-design)
47+
> [!important]
48+
> We are using shadcn with `"cssVariables": false` to avoid their defautl `bg-background`, `text-accent-foreground` and others.
49+
> So, we highly recommend to wipe the most of the pre-generated classname string and building it on your own, using our custom CSS/Tailwind variables
50+
51+
- If the component already exists, but you need to add variants or sizes, follow the shadcn's button implementation:
52+
1. visit [shadcn's button page](https://ui.shadcn.com/docs/components/button#installation)
53+
2. click on "Manual"
54+
3. expand the code section and see how it is done

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@ First, it will be a rewrite of our homepage.
88
- [Next.js](https://nextjs.org)
99
- [Tailwind CSS](https://tailwindcss.com) (eventually with shadcn)
1010
- TRPC to connect to backend
11+
12+
## Contributing
13+
If you are contributing, you may check [GUIDES.md](./GUIDES.md)

components.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"$schema": "https://ui.shadcn.com/schema.json",
3+
"style": "new-york",
4+
"rsc": true,
5+
"tsx": true,
6+
"tailwind": {
7+
"config": "",
8+
"css": "src/styles/globals.css",
9+
"baseColor": "slate",
10+
"cssVariables": false,
11+
"prefix": ""
12+
},
13+
"iconLibrary": "lucide",
14+
"aliases": {
15+
"components": "@/components",
16+
"utils": "@/lib/utils",
17+
"ui": "@/components/ui",
18+
"lib": "@/lib",
19+
"hooks": "@/hooks"
20+
},
21+
"registries": {}
22+
}

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"@types/react-dom": "^19.2.1",
3939
"postcss": "^8.5.6",
4040
"tailwindcss": "^4.1.14",
41+
"tw-animate-css": "^1.4.0",
4142
"typescript": "^5.9.3"
4243
},
4344
"packageManager": "[email protected]",

pnpm-lock.yaml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/layout.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ export default function RootLayout({ children }: Readonly<{ children: React.Reac
5555
>
5656
<ThemeProvider
5757
attribute="class"
58-
defaultTheme="system"
59-
enableSystem
60-
storageKey="polinetwork_darkmode"
58+
defaultTheme="light"
59+
enableSystem={false} // TODO: enable when dark mode design is ready
60+
// storageKey="polinetwork_darkmode_temp" // TODO: enable when dark mode design is ready
6161
disableTransitionOnChange
6262
>
6363
<div className="flex min-h-screen w-full flex-col items-center justify-start">

src/app/page.tsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
11
export default function Home() {
22
return (
33
<main className="container mx-auto px-4 py-8">
4-
<h2 className="mb-4 text-3xl font-bold">Welcome to PoliNetwork</h2>
4+
<h2 className="mb-4 typo-headline-large font-bold bg">Welcome to PoliNetwork</h2>
55
<p className="mb-4">
66
PoliNetwork is a student association dedicated to connecting and supporting students at Politecnico.
77
</p>
8+
<div className="bg-red rounded-rectangles w-90 py-8 flex justify-center items-center flex-col gap-2">
9+
<p className="text-text-accent-darkbg typo-body-medium">Test with figma variables</p>
10+
<div className="bg-background-blur w-20 h-20 rounded-images" />
11+
<button
12+
className="bg-button-primary text-text-accent-lightbg typo-label-large px-6 py-2.5 rounded-buttonsM"
13+
type="button"
14+
>
15+
More groups
16+
</button>
17+
</div>
818
</main>
919
)
1020
}

src/components/theme-button.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import { useTheme } from "next-themes"
55
export function ThemeButton() {
66
const { resolvedTheme, setTheme } = useTheme()
77
return (
8-
<button type="button" onClick={() => setTheme(resolvedTheme === "light" ? "dark" : "light")}>
8+
// TODO: enable when dark mode design is ready
9+
<button type="button" disabled={true} onClick={() => setTheme(resolvedTheme === "light" ? "dark" : "light")}>
910
<SunIcon className="block h-6 w-6 dark:hidden" />
1011
<MoonIcon className="hidden h-6 w-6 dark:block" />
1112
</button>

src/styles/charts.css

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
In this file, we put the Shadcn default charts variables
3+
However, we probably won't use charts
4+
*/
5+
6+
:root {
7+
--chart-1: oklch(0.646 0.222 41.116);
8+
--chart-2: oklch(0.6 0.118 184.704);
9+
--chart-3: oklch(0.398 0.07 227.392);
10+
--chart-4: oklch(0.828 0.189 84.429);
11+
--chart-5: oklch(0.769 0.188 70.08);
12+
}
13+
14+
.dark {
15+
--chart-1: oklch(0.488 0.243 264.376);
16+
--chart-2: oklch(0.696 0.17 162.48);
17+
--chart-3: oklch(0.769 0.188 70.08);
18+
--chart-4: oklch(0.627 0.265 303.9);
19+
--chart-5: oklch(0.645 0.246 16.439);
20+
}

src/styles/figma.css

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
Figma Variables
3+
figma blur variables are equivalent to 40% opacity
4+
e.g. tw-slate/050-blur => color-slate-50 / 40
5+
to create a variable with defined opacity, follow the tailwind solution:
6+
--<var-name>: color-mix(in oklab, var(<base-color-var>) <opacity>, transparent);
7+
*/
8+
9+
:root {
10+
/* neutrals */
11+
--figma-background: var(--color-slate-100);
12+
--figma-background-blur: color-mix(in oklab, var(--color-slate-50) 40%, transparent);
13+
--figma-grey: var(--color-slate-300);
14+
--figma-text-primary: var(--color-slate-950);
15+
--figma-text-secondary: var(--color-slate-500);
16+
--figma-text-accent-darkbg: var(--color-slate-100);
17+
--figma-text-accent-lightbg: var(--color-slate-900);
18+
/* accents */
19+
--figma-red: var(--color-rose-600);
20+
--figma-green: var(--color-emerald-400);
21+
--figma-blue-primary: var(--color-blue-400);
22+
--figma-blue-primary-blur: color-mix(in oklab, var(--color-slate-400) 40%, transparent);
23+
--figma-blue-secondary: var(--color-sky-700);
24+
--figma-blue-tertiary: var(--color-sky-300);
25+
--figma-blue-tertiary-blur: color-mix(in oklab, var(--color-sky-300) 40%, transparent);
26+
/* buttons */
27+
--figma-button-primary: var(--figma-blue-primary);
28+
--figma-button-secondary: var(--figma-blue-secondary);
29+
--figma-button-tertiary: var(--figma-blue-tertiary);
30+
--figma-button-error: var(--figma-red);
31+
--figma-button-disabled: var(--figma-grey);
32+
/* radius */
33+
--figma-corner-images: 10px;
34+
--figma-corner-rectangles: 20px;
35+
--figma-corner-buttonsM: 60px;
36+
--figma-corner-buttonsL: 100px;
37+
}
38+
39+
.dark {
40+
/* Figma Variables */
41+
/* neutrals */
42+
--figma-background: oklch(35.13% 0.062 249.28);
43+
--figma-background-blur: oklch(39.07% 0.089 240.61 / 40%);
44+
--figma-grey: var(--color-slate-400);
45+
--figma-text-primary: var(--color-slate-50);
46+
--figma-text-secondary: var(--color-slate-400);
47+
--figma-text-accent-darkbg: var(--color-slate-100);
48+
--figma-text-accent-lightbg: var(--color-slate-900);
49+
/* accents */
50+
--figma-red: var(--color-rose-800);
51+
--figma-green: var(--color-emerald-600);
52+
--figma-blue-primary: var(--color-blue-800);
53+
--figma-blue-primary-blur: oklch(42.42% 0.198 265.5 / 40%);
54+
--figma-blue-secondary: var(--color-sky-900);
55+
--figma-blue-tertiary: var(--color-sky-700);
56+
--figma-blue-tertiary-blur: oklch(50.40% 0.128 245.46 / 40%);
57+
/* buttons and radius are the same as in the light theme */
58+
}
59+
60+
/*
61+
Use `inline` when referencing other css variables
62+
https://tailwindcss.com/docs/theme#referencing-other-variables
63+
*/
64+
@theme inline {
65+
--color-background: var(--figma-background);
66+
--color-text-primary: var(--figma-text-primary);
67+
68+
/* neutrals */
69+
--color-background: var(--figma-background);
70+
--color-background-blur: var(--figma-background-blur);
71+
--color-grey: var(--figma-grey);
72+
--color-text-primary: var(--figma-text-primary);
73+
--color-text-secondary: var(--figma-text-secondary);
74+
--color-text-accent-darkbg: var(--figma-text-accent-darkbg);
75+
--color-text-accent-lightbg: var(--figma-text-accent-lightbg);
76+
/* accents */
77+
--color-red: var(--figma-red);
78+
--color-green: var(--figma-green);
79+
--color-blue-primary: var(--figma-blue-primary);
80+
--color-blue-primary-blur: var(--figma-blue-primary-blur);
81+
--color-blue-secondary: var(--figma-blue-secondary);
82+
--color-blue-tertiary: var(--figma-blue-tertiary);
83+
--color-blue-tertiary-blur: var(--figma-blue-tertiary-blur);
84+
/* buttons */
85+
--color-button-primary: var(--figma-button-primary);
86+
--color-button-secondary: var(--figma-button-secondary);
87+
--color-button-tertiary: var(--figma-button-tertiary);
88+
--color-button-error: var(--figma-button-error);
89+
--color-button-disabled: var(--figma-button-disabled);
90+
/* radius */
91+
--radius-images: var(--figma-corner-images);
92+
--radius-rectangles: var(--figma-corner-rectangles);
93+
--radius-buttonsM: var(--figma-corner-buttonsM);
94+
--radius-buttonsL: var(--figma-corner-buttonsL);
95+
}

0 commit comments

Comments
 (0)