Skip to content

Commit 0a17da2

Browse files
tnyleataylorotwell
andauthored
Tailwind V4 Upgrade 💾 (#93)
* new attempt at tw4 upgrade * Adding upgrade steps * Adding some final updates * Final touches for V4 upgrade * removing autoprefixer * replacing tailwind-animate with tw-animate-css * updating comments to latest version since last release * removing autoprefixer from dependencies * Delete composer.lock --------- Co-authored-by: Taylor Otwell <[email protected]>
1 parent ffcca06 commit 0a17da2

File tree

122 files changed

+2418
-2628
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

122 files changed

+2418
-2628
lines changed

‎package-lock.json

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

‎package.json

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,25 @@
1818
"eslint-plugin-vue": "^9.32.0",
1919
"prettier": "^3.4.2",
2020
"prettier-plugin-organize-imports": "^4.1.0",
21-
"prettier-plugin-tailwindcss": "^0.6.9",
21+
"prettier-plugin-tailwindcss": "^0.6.11",
22+
"tw-animate-css": "^1.2.5",
2223
"typescript-eslint": "^8.23.0",
2324
"vue-tsc": "^2.2.4"
2425
},
2526
"dependencies": {
2627
"@inertiajs/vue3": "^2.0.0-beta.3",
28+
"@tailwindcss/vite": "^4.1.1",
2729
"@vitejs/plugin-vue": "^5.2.1",
28-
"@vueuse/core": "^12.0.0",
29-
"autoprefixer": "^10.4.20",
30+
"@vueuse/core": "^12.8.2",
3031
"class-variance-authority": "^0.7.1",
3132
"clsx": "^2.1.1",
3233
"concurrently": "^9.0.1",
3334
"laravel-vite-plugin": "^1.0",
3435
"lucide": "^0.468.0",
3536
"lucide-vue-next": "^0.468.0",
36-
"reka-ui": "^2.0.0",
37+
"reka-ui": "^2.2.0",
3738
"tailwind-merge": "^2.5.5",
38-
"tailwindcss": "^3.4.1",
39+
"tailwindcss": "^4.1.1",
3940
"tailwindcss-animate": "^1.0.7",
4041
"typescript": "^5.2.2",
4142
"vite": "^6.2.0",

‎resources/css/app.css

Lines changed: 171 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,166 @@
1-
@tailwind base;
2-
@tailwind components;
3-
@tailwind utilities;
1+
@import 'tailwindcss';
42

5-
body,
6-
html {
7-
--font-sans:
8-
'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
3+
@import "tw-animate-css";
4+
5+
@source '../../vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php';
6+
@source '../../storage/framework/views/*.php';
7+
8+
@custom-variant dark (&:is(.dark *));
9+
10+
@theme inline {
11+
--font-sans:
12+
Instrument Sans, ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji',
13+
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
14+
15+
--radius-lg: var(--radius);
16+
--radius-md: calc(var(--radius) - 2px);
17+
--radius-sm: calc(var(--radius) - 4px);
18+
19+
--color-background: var(--background);
20+
--color-foreground: var(--foreground);
21+
22+
--color-card: var(--card);
23+
--color-card-foreground: var(--card-foreground);
24+
25+
--color-popover: var(--popover);
26+
--color-popover-foreground: var(--popover-foreground);
27+
28+
--color-primary: var(--primary);
29+
--color-primary-foreground: var(--primary-foreground);
30+
31+
--color-secondary: var(--secondary);
32+
--color-secondary-foreground: var(--secondary-foreground);
33+
34+
--color-muted: var(--muted);
35+
--color-muted-foreground: var(--muted-foreground);
36+
37+
--color-accent: var(--accent);
38+
--color-accent-foreground: var(--accent-foreground);
39+
40+
--color-destructive: var(--destructive);
41+
--color-destructive-foreground: var(--destructive-foreground);
42+
43+
--color-border: var(--border);
44+
--color-input: var(--input);
45+
--color-ring: var(--ring);
46+
47+
--color-chart-1: var(--chart-1);
48+
--color-chart-2: var(--chart-2);
49+
--color-chart-3: var(--chart-3);
50+
--color-chart-4: var(--chart-4);
51+
--color-chart-5: var(--chart-5);
52+
53+
--color-sidebar: var(--sidebar-background);
54+
--color-sidebar-foreground: var(--sidebar-foreground);
55+
--color-sidebar-primary: var(--sidebar-primary);
56+
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
57+
--color-sidebar-accent: var(--sidebar-accent);
58+
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
59+
--color-sidebar-border: var(--sidebar-border);
60+
--color-sidebar-ring: var(--sidebar-ring);
961
}
1062

63+
/*
64+
The default border color has changed to `currentColor` in Tailwind CSS v4,
65+
so we've added these compatibility styles to make sure everything still
66+
looks the same as it did with Tailwind CSS v3.
67+
68+
If we ever want to remove these styles, we need to add an explicit border
69+
color utility to any element that depends on these defaults.
70+
*/
1171
@layer base {
12-
:root {
13-
--background: 0 0% 100%;
14-
--foreground: 0 0% 3.9%;
15-
--card: 0 0% 100%;
16-
--card-foreground: 0 0% 3.9%;
17-
--popover: 0 0% 100%;
18-
--popover-foreground: 0 0% 3.9%;
19-
--primary: 0 0% 9%;
20-
--primary-foreground: 0 0% 98%;
21-
--secondary: 0 0% 92.1%;
22-
--secondary-foreground: 0 0% 9%;
23-
--muted: 0 0% 96.1%;
24-
--muted-foreground: 0 0% 45.1%;
25-
--accent: 0 0% 96.1%;
26-
--accent-foreground: 0 0% 9%;
27-
--destructive: 0 84.2% 60.2%;
28-
--destructive-foreground: 0 0% 98%;
29-
--border: 0 0% 92.8%;
30-
--input: 0 0% 89.8%;
31-
--ring: 0 0% 3.9%;
32-
--chart-1: 12 76% 61%;
33-
--chart-2: 173 58% 39%;
34-
--chart-3: 197 37% 24%;
35-
--chart-4: 43 74% 66%;
36-
--chart-5: 27 87% 67%;
37-
--radius: 0.5rem;
38-
--sidebar-background: 0 0% 98%;
39-
--sidebar-foreground: 240 5.3% 26.1%;
40-
--sidebar-primary: 0 0% 10%;
41-
--sidebar-primary-foreground: 0 0% 98%;
42-
--sidebar-accent: 0 0% 94%;
43-
--sidebar-accent-foreground: 0 0% 30%;
44-
--sidebar-border: 0 0% 91%;
45-
--sidebar-ring: 217.2 91.2% 59.8%;
46-
}
72+
*,
73+
::after,
74+
::before,
75+
::backdrop,
76+
::file-selector-button {
77+
border-color: var(--color-gray-200, currentColor);
78+
}
79+
}
4780

48-
.dark {
49-
--background: 0 0% 3.9%;
50-
--foreground: 0 0% 98%;
51-
--card: 0 0% 3.9%;
52-
--card-foreground: 0 0% 98%;
53-
--popover: 0 0% 3.9%;
54-
--popover-foreground: 0 0% 98%;
55-
--primary: 0 0% 98%;
56-
--primary-foreground: 0 0% 9%;
57-
--secondary: 0 0% 14.9%;
58-
--secondary-foreground: 0 0% 98%;
59-
--muted: 0 0% 6.9%;
60-
--muted-foreground: 0 0% 63.9%;
61-
--accent: 0 0% 14.9%;
62-
--accent-foreground: 0 0% 98%;
63-
--destructive: 0 84% 60%;
64-
--destructive-foreground: 0 0% 98%;
65-
--border: 0 0% 14.9%;
66-
--input: 0 0% 14.9%;
67-
--ring: 0 0% 83.1%;
68-
--chart-1: 220 70% 50%;
69-
--chart-2: 160 60% 45%;
70-
--chart-3: 30 80% 55%;
71-
--chart-4: 280 65% 60%;
72-
--chart-5: 340 75% 55%;
73-
--sidebar-background: 0 0% 7%;
74-
--sidebar-foreground: 0 0% 95.9%;
75-
--sidebar-primary: 360, 100%, 100%;
76-
--sidebar-primary-foreground: 0 0% 100%;
77-
--sidebar-accent: 0 0% 15.9%;
78-
--sidebar-accent-foreground: 240 4.8% 95.9%;
79-
--sidebar-border: 0 0% 15.9%;
80-
--sidebar-ring: 217.2 91.2% 59.8%;
81-
}
81+
@layer utilities {
82+
body,
83+
html {
84+
--font-sans:
85+
'Instrument Sans', ui-sans-serif, system-ui, sans-serif,
86+
'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol',
87+
'Noto Color Emoji';
88+
}
89+
}
90+
91+
:root {
92+
--background: hsl(0 0% 100%);
93+
--foreground: hsl(0 0% 3.9%);
94+
--card: hsl(0 0% 100%);
95+
--card-foreground: hsl(0 0% 3.9%);
96+
--popover: hsl(0 0% 100%);
97+
--popover-foreground: hsl(0 0% 3.9%);
98+
--primary: hsl(0 0% 9%);
99+
--primary-foreground: hsl(0 0% 98%);
100+
--secondary: hsl(0 0% 92.1%);
101+
--secondary-foreground: hsl(0 0% 9%);
102+
--muted: hsl(0 0% 96.1%);
103+
--muted-foreground: hsl(0 0% 45.1%);
104+
--accent: hsl(0 0% 96.1%);
105+
--accent-foreground: hsl(0 0% 9%);
106+
--destructive: hsl(0 84.2% 60.2%);
107+
--destructive-foreground: hsl(0 0% 98%);
108+
--border: hsl(0 0% 92.8%);
109+
--input: hsl(0 0% 89.8%);
110+
--ring: hsl(0 0% 3.9%);
111+
--chart-1: hsl(12 76% 61%);
112+
--chart-2: hsl(173 58% 39%);
113+
--chart-3: hsl(197 37% 24%);
114+
--chart-4: hsl(43 74% 66%);
115+
--chart-5: hsl(27 87% 67%);
116+
--radius: 0.5rem;
117+
--sidebar-background: hsl(0 0% 98%);
118+
--sidebar-foreground: hsl(240 5.3% 26.1%);
119+
--sidebar-primary: hsl(0 0% 10%);
120+
--sidebar-primary-foreground: hsl(0 0% 98%);
121+
--sidebar-accent: hsl(0 0% 94%);
122+
--sidebar-accent-foreground: hsl(0 0% 30%);
123+
--sidebar-border: hsl(0 0% 91%);
124+
--sidebar-ring: hsl(217.2 91.2% 59.8%);
125+
--sidebar:
126+
hsl(0 0% 98%);
127+
}
128+
129+
.dark {
130+
--background: hsl(0 0% 3.9%);
131+
--foreground: hsl(0 0% 98%);
132+
--card: hsl(0 0% 3.9%);
133+
--card-foreground: hsl(0 0% 98%);
134+
--popover: hsl(0 0% 3.9%);
135+
--popover-foreground: 0 0% 98%;
136+
--primary: hsl(0 0% 98%);
137+
--primary-foreground: hsl(0 0% 9%);
138+
--secondary: hsl(0 0% 14.9%);
139+
--secondary-foreground: hsl(0 0% 98%);
140+
--muted: hsl(0 0% 16.08%);
141+
--muted-foreground: hsl(0 0% 63.9%);
142+
--accent: hsl(0 0% 14.9%);
143+
--accent-foreground: hsl(0 0% 98%);
144+
--destructive: hsl(0 84% 60%);
145+
--destructive-foreground: hsl(0 0% 98%);
146+
--border: hsl(0 0% 14.9%);
147+
--input: hsl(0 0% 14.9%);
148+
--ring: hsl(0 0% 83.1%);
149+
--chart-1: hsl(220 70% 50%);
150+
--chart-2: hsl(160 60% 45%);
151+
--chart-3: hsl(30 80% 55%);
152+
--chart-4: hsl(280 65% 60%);
153+
--chart-5: hsl(340 75% 55%);
154+
--sidebar-background: hsl(0 0% 7%);
155+
--sidebar-foreground: hsl(0 0% 95.9%);
156+
--sidebar-primary: hsl(360, 100%, 100%);
157+
--sidebar-primary-foreground: hsl(0 0% 100%);
158+
--sidebar-accent: hsl(0 0% 15.9%);
159+
--sidebar-accent-foreground: hsl(240 4.8% 95.9%);
160+
--sidebar-border: hsl(0 0% 15.9%);
161+
--sidebar-ring: hsl(217.2 91.2% 59.8%);
162+
--sidebar:
163+
hsl(240 5.9% 10%);
82164
}
83165

84166
@layer base {
@@ -90,3 +172,16 @@ html {
90172
@apply bg-background text-foreground;
91173
}
92174
}
175+
176+
/*
177+
---break---
178+
*/
179+
180+
@layer base {
181+
* {
182+
@apply border-border outline-ring/50;
183+
}
184+
body {
185+
@apply bg-background text-foreground;
186+
}
187+
}

‎resources/js/components/AppSidebarHeader.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ defineProps<{
1010

1111
<template>
1212
<header
13-
class="flex h-16 shrink-0 items-center gap-2 border-b border-sidebar-border/70 px-6 transition-[width,height] ease-linear group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12 md:px-4"
13+
class="flex h-16 shrink-0 items-center gap-2 border-b border-sidebar-border/70 px-6 transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-12 md:px-4"
1414
>
1515
<div class="flex items-center gap-2">
1616
<SidebarTrigger class="-ml-1" />

‎resources/js/components/AppearanceTabs.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const tabs = [
2626
:class="[
2727
'flex items-center rounded-md px-3.5 py-1.5 transition-colors',
2828
appearance === value
29-
? 'bg-white shadow-sm dark:bg-neutral-700 dark:text-neutral-100'
29+
? 'bg-white shadow-xs dark:bg-neutral-700 dark:text-neutral-100'
3030
: 'text-neutral-500 hover:bg-neutral-200/60 hover:text-black dark:text-neutral-400 dark:hover:bg-neutral-700/60',
3131
]"
3232
>

‎resources/js/components/NavUser.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const { isMobile, state } = useSidebar();
2323
</SidebarMenuButton>
2424
</DropdownMenuTrigger>
2525
<DropdownMenuContent
26-
class="w-[--reka-dropdown-menu-trigger-width] min-w-56 rounded-lg"
26+
class="w-(--reka-dropdown-menu-trigger-width) min-w-56 rounded-lg"
2727
:side="isMobile ? 'bottom' : state === 'collapsed' ? 'left' : 'bottom'"
2828
align="end"
2929
:side-offset="4"

‎resources/js/components/TextLink.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ defineProps<Props>();
1717
:tabindex="tabindex"
1818
:method="method"
1919
:as="as"
20-
class="text-foreground underline decoration-neutral-300 underline-offset-4 transition-colors duration-300 ease-out hover:!decoration-current dark:decoration-neutral-500"
20+
class="text-foreground underline decoration-neutral-300 underline-offset-4 transition-colors duration-300 ease-out hover:decoration-current! dark:decoration-neutral-500"
2121
>
2222
<slot />
2323
</Link>
Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,18 @@
11
<script setup lang="ts">
2-
import { cn } from '@/lib/utils';
3-
import { AvatarRoot } from 'reka-ui';
4-
import type { HTMLAttributes } from 'vue';
5-
import { avatarVariant, type AvatarVariants } from '.';
2+
import type { HTMLAttributes } from 'vue'
3+
import { cn } from '@/lib/utils'
4+
import { AvatarRoot } from 'reka-ui'
65
7-
const props = withDefaults(
8-
defineProps<{
9-
class?: HTMLAttributes['class'];
10-
size?: AvatarVariants['size'];
11-
shape?: AvatarVariants['shape'];
12-
}>(),
13-
{
14-
size: 'sm',
15-
shape: 'circle',
16-
},
17-
);
6+
const props = defineProps<{
7+
class?: HTMLAttributes['class']
8+
}>()
189
</script>
1910

2011
<template>
21-
<AvatarRoot :class="cn(avatarVariant({ size, shape }), props.class)">
22-
<slot />
23-
</AvatarRoot>
12+
<AvatarRoot
13+
data-slot="avatar"
14+
:class="cn('relative flex size-8 shrink-0 overflow-hidden rounded-full', props.class)"
15+
>
16+
<slot />
17+
</AvatarRoot>
2418
</template>
Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
11
<script setup lang="ts">
2-
import { AvatarFallback, type AvatarFallbackProps } from 'reka-ui';
2+
import { cn } from '@/lib/utils'
3+
import { AvatarFallback, type AvatarFallbackProps } from 'reka-ui'
4+
import { computed, type HTMLAttributes } from 'vue'
35
4-
const props = defineProps<AvatarFallbackProps>();
6+
const props = defineProps<AvatarFallbackProps & { class?: HTMLAttributes['class'] }>()
7+
8+
const delegatedProps = computed(() => {
9+
const { class: _, ...delegated } = props
10+
11+
return delegated
12+
})
513
</script>
614

715
<template>
8-
<AvatarFallback v-bind="props">
9-
<slot />
10-
</AvatarFallback>
16+
<AvatarFallback
17+
data-slot="avatar-fallback"
18+
v-bind="delegatedProps"
19+
:class="cn('bg-muted flex size-full items-center justify-center rounded-full', props.class)"
20+
>
21+
<slot />
22+
</AvatarFallback>
1123
</template>

0 commit comments

Comments
 (0)