Skip to content

Commit 6583cc1

Browse files
feat: ui 2025 layer (#52)
1 parent 131e42a commit 6583cc1

File tree

12 files changed

+118
-12
lines changed

12 files changed

+118
-12
lines changed

.prettierrc

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@
66
"bracketSameLine": true,
77
"arrowParens": "avoid",
88
"vueIndentScriptAndStyle": false,
9-
"htmlWhitespaceSensitivity": "ignore"
9+
"htmlWhitespaceSensitivity": "ignore",
10+
"plugins": ["prettier-plugin-tailwindcss"]
1011
}

.vscode/settings.json

+5-1
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,9 @@
1818
"editor.defaultFormatter": "esbenp.prettier-vscode",
1919
"files.associations": {
2020
"*.css":"tailwindcss"
21-
}
21+
},
22+
"tailwindCSS.experimental.classRegex": [
23+
["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"],
24+
["cx\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]
25+
]
2226
}

bun.lockb

2.16 KB
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
---
2+
created: 2024-12-03
3+
authors:
4+
- Nishant
5+
---
6+
This layer contains the the components and styles used for IC Hack 25. At this point, [Class Variance Authority (CVA)](https://cva.style/docs) is unstable and experimental but it seems we don't need alot of functionality from them. You may need **tailwind-merge**. In case of failure, here's how you would convert the following CVA code to use custom props (untested).
7+
8+
```html
9+
<script setup lang="ts">
10+
import { cva, type VariantProps } from 'cva';
11+
12+
const button = cva('px-1 py-2', {
13+
variants: {
14+
intent: {
15+
primary: 'bg-blue-500 text-white',
16+
secondary: 'bg-gray-500 text-white',
17+
success: 'bg-green-500 text-white',
18+
danger: 'bg-red-500 text-white'
19+
},
20+
size: {
21+
sm: 'text-sm',
22+
md: 'text-md',
23+
lg: 'text-lg'
24+
}
25+
}
26+
});
27+
type ButtonVariant = VariantProps<typeof button>;
28+
29+
const { intent = 'primary', size = 'sm' } = defineProps<ButtonVariant>();
30+
</script>
31+
32+
<template>
33+
<button :class="button({ intent, size })"><slot></slot></button>
34+
</template>
35+
```
36+
37+
This code becomes:
38+
39+
```html
40+
<script setup lang="ts">
41+
import { twMerge } from 'tailwind-merge'; // Something like this
42+
43+
type Variant = {
44+
intent: 'primary' | 'secondary' | 'success' | 'danger'
45+
size: 'sm' | 'md' | 'lg'
46+
}
47+
48+
const button = (variant: Variant) => {
49+
const base = 'px-1 py-2';
50+
const intentClasses = {
51+
primary: 'bg-blue-500 text-white',
52+
secondary: 'bg-gray-500 text-white',
53+
success: 'bg-green-500 text-white',
54+
danger: 'bg-red-500 text-white'
55+
};
56+
const sizeClasses = {
57+
sm: 'text-sm',
58+
md: 'text-md',
59+
lg: 'text-lg'
60+
};
61+
62+
return twMerge(`${base} ${intentClasses[variant.intent]} ${sizeClasses[variant.size]}`)
63+
}
64+
65+
const { intent = 'primary', size = 'sm' } = defineProps<Variant>();
66+
</script>
67+
68+
<template>
69+
<button :class="button({ intent, size })"><slot></slot></button>
70+
</template>
71+
```

layers/admin/layouts/toolbar.vue

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ const name = computed(() => profile?.name.split(' ')[0]);
55
</script>
66

77
<template>
8-
<div class="w-screen h-screen flex">
9-
<div class="h-full px-6 py-4 border-r border-gray-200 dark:border-gray-800">
8+
<div class="flex h-screen w-screen">
9+
<div class="h-full border-r border-gray-200 px-6 py-4 dark:border-gray-800">
1010
<h1>Welcome, {{ name ?? 'null' }}</h1>
1111
<Toolbar class="mt-5" />
1212
</div>
13-
<div class="flex-1 h-full">
13+
<div class="h-full flex-1">
1414
<slot></slot>
1515
</div>
1616
</div>

layers/admin/pages/$admin/login.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ const handleLogin = async () => {
2222
</script>
2323

2424
<template>
25-
<h2 class="font-semibold text-5xl text-center">Admin's Login Screen</h2>
26-
<UContainer class="flex flex-col justify-center items-center">
25+
<h2 class="text-center text-5xl font-semibold">Admin's Login Screen</h2>
26+
<UContainer class="flex flex-col items-center justify-center">
2727
<UForm
2828
:schema="postLoginBody"
2929
:state="userCredentials"

layers/admin/pages/$admin/users.vue

+3-3
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ definePageMeta({
9999

100100
<template>
101101
<NuxtLayout name="toolbar">
102-
<UContainer class="relative overflow-y-scroll max-h-full">
103-
<h2 class="font-semibold text-5xl text-center">Manage Users</h2>
102+
<UContainer class="relative max-h-full overflow-y-scroll">
103+
<h2 class="text-center text-5xl font-semibold">Manage Users</h2>
104104
<UButton
105105
label="Add User"
106106
@click="isAddUserPopupOpen = true"
@@ -131,7 +131,7 @@ definePageMeta({
131131
</template>
132132
</UTable>
133133
<UModal v-model="isAddUserPopupOpen">
134-
<UContainer class="mb-4 p-10 justify-center grid grid-flow-row">
134+
<UContainer class="mb-4 grid grid-flow-row justify-center p-10">
135135
<UForm
136136
data-testid="form"
137137
:schema="schema"

layers/ui25/components/IC/Button.vue

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<script setup lang="ts">
2+
import { cva, type VariantProps } from 'cva';
3+
4+
const button = cva('px-1 py-2', {
5+
variants: {
6+
intent: {
7+
primary: 'bg-blue-500 text-white',
8+
secondary: 'bg-gray-500 text-white',
9+
success: 'bg-green-500 text-white',
10+
danger: 'bg-red-500 text-white'
11+
},
12+
size: {
13+
sm: 'text-sm',
14+
md: 'text-md',
15+
lg: 'text-lg'
16+
}
17+
}
18+
});
19+
type ButtonVariant = VariantProps<typeof button>;
20+
21+
const { intent = 'primary', size = 'sm' } = defineProps<ButtonVariant>();
22+
</script>
23+
24+
<template>
25+
<button :class="button({ intent, size })"><slot></slot></button>
26+
</template>

layers/ui25/nuxt.config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default defineNuxtConfig({});

package.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,11 @@
1717
},
1818
"devDependencies": {
1919
"@types/bun": "^1.1.6",
20+
"@types/pg": "^8.11.6",
2021
"bun-types": "^1.1.20",
22+
"drizzle-kit": "^0.24.0",
2123
"prettier": "^3.3.2",
22-
"@types/pg": "^8.11.6",
23-
"drizzle-kit": "^0.24.0"
24+
"prettier-plugin-tailwindcss": "^0.6.9"
2425
},
2526
"peerDependencies": {
2627
"typescript": "^5.0.0"
@@ -40,6 +41,7 @@
4041
"@pinia/nuxt": "^0.5.3",
4142
"argon2": "^0.40.3",
4243
"build-url-ts": "^6.1.7",
44+
"cva": "npm:class-variance-authority",
4345
"drizzle-orm": "^0.33.0",
4446
"drizzle-zod": "^0.5.1",
4547
"hono": "^4.5.5",
@@ -49,6 +51,7 @@
4951
"pg": "^8.12.0",
5052
"picocolors": "^1.0.1",
5153
"pinia": "^2.2.1",
54+
"tailwind-merge": "^2.5.5",
5255
"typescript-result": "^2.1.0",
5356
"vue": "latest",
5457
"zod": "^3.23.8"

0 commit comments

Comments
 (0)