chore: update Tailwind CSS from 3.4.15, to 4.1.11
- Changed the PostCSS configuration to use '@tailwindcss/postcss' instead of 'tailwindcss'. - Deleted the Tailwind configuration file as it is no longer needed.
This commit is contained in:
@@ -1 +1 @@
|
||||
NEXT_PUBLIC_COMMIT_SHA=a00bf3e
|
||||
NEXT_PUBLIC_COMMIT_SHA=95e3682
|
||||
|
||||
@@ -94,7 +94,7 @@ export default function BrowsePage() {
|
||||
<div className="h-full px-4 py-6 lg:px-8">
|
||||
<>
|
||||
<Tabs defaultValue="music" className="h-full flex flex-col space-y-6">
|
||||
<TabsContent value="music" className="border-none p-0 outline-none flex flex-col flex-grow">
|
||||
<TabsContent value="music" className="border-none p-0 outline-hidden flex flex-col grow">
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="space-y-1">
|
||||
@@ -111,7 +111,7 @@ export default function BrowsePage() {
|
||||
</Button>
|
||||
</div>
|
||||
<Separator className="my-4" />
|
||||
<div className="relative flex-grow">
|
||||
<div className="relative grow">
|
||||
<div className="relative">
|
||||
<ScrollArea>
|
||||
<div className="flex space-x-4 pb-4">
|
||||
@@ -119,7 +119,7 @@ export default function BrowsePage() {
|
||||
<ArtistIcon
|
||||
key={artist.id}
|
||||
artist={artist}
|
||||
className="flex-shrink-0 overflow-hidden"
|
||||
className="shrink-0 overflow-hidden"
|
||||
size={190}
|
||||
/>
|
||||
))}
|
||||
@@ -139,7 +139,7 @@ export default function BrowsePage() {
|
||||
</div>
|
||||
</div>
|
||||
<Separator className="my-4" />
|
||||
<div className="relative flex-grow">
|
||||
<div className="relative grow">
|
||||
<ScrollArea className="h-full">
|
||||
<div className="h-full overflow-y-auto">
|
||||
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 2xl:grid-cols-7 gap-4 p-4 pb-8">
|
||||
|
||||
@@ -359,7 +359,7 @@ export const AudioPlayer: React.FC = () => {
|
||||
return (
|
||||
<div className="fixed bottom-4 left-4 z-50">
|
||||
<div
|
||||
className="bg-background/95 backdrop-blur-sm border rounded-lg shadow-lg cursor-pointer hover:scale-[1.02] transition-transform w-80"
|
||||
className="bg-background/95 backdrop-blur-xs border rounded-lg shadow-lg cursor-pointer hover:scale-[1.02] transition-transform w-80"
|
||||
onClick={() => setIsMinimized(false)}
|
||||
>
|
||||
<div className="flex items-center p-3">
|
||||
@@ -368,7 +368,7 @@ export const AudioPlayer: React.FC = () => {
|
||||
alt={currentTrack.name}
|
||||
width={40}
|
||||
height={40}
|
||||
className="w-10 h-10 rounded-md flex-shrink-0"
|
||||
className="w-10 h-10 rounded-md shrink-0"
|
||||
/>
|
||||
<div className="flex-1 min-w-0 mx-3">
|
||||
<div className="overflow-hidden">
|
||||
@@ -413,7 +413,7 @@ export const AudioPlayer: React.FC = () => {
|
||||
// Compact floating player (default state)
|
||||
return (
|
||||
<div className="fixed bottom-4 left-4 right-4 z-50">
|
||||
<div className="bg-background/95 backdrop-blur-sm border rounded-lg shadow-lg p-3 cursor-pointer hover:scale-[1.01] transition-transform">
|
||||
<div className="bg-background/95 backdrop-blur-xs border rounded-lg shadow-lg p-3 cursor-pointer hover:scale-[1.01] transition-transform">
|
||||
<div className="flex items-center">
|
||||
{/* Track info */}
|
||||
<div className="flex items-center flex-1 min-w-0">
|
||||
@@ -422,7 +422,7 @@ export const AudioPlayer: React.FC = () => {
|
||||
alt={currentTrack.name}
|
||||
width={48}
|
||||
height={48}
|
||||
className="w-12 h-12 rounded-md mr-4 flex-shrink-0"
|
||||
className="w-12 h-12 rounded-md mr-4 shrink-0"
|
||||
/>
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="font-semibold truncate text-base">{currentTrack.name}</p>
|
||||
|
||||
@@ -296,7 +296,7 @@ export const FullScreenPlayer: React.FC<FullScreenPlayerProps> = ({ isOpen, onCl
|
||||
<div className="absolute inset-0 bg-black/50" />
|
||||
<div className="relative h-full w-full flex flex-col">
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between p-4 lg:p-6 flex-shrink-0">
|
||||
<div className="flex items-center justify-between p-4 lg:p-6 shrink-0">
|
||||
<h2 className="text-lg lg:text-xl font-semibold text-white"></h2>
|
||||
<div className="flex items-center gap-2">
|
||||
{onOpenQueue && (
|
||||
@@ -323,7 +323,7 @@ export const FullScreenPlayer: React.FC<FullScreenPlayerProps> = ({ isOpen, onCl
|
||||
{/* Left Side - Album Art and Controls */}
|
||||
<div className="flex flex-col items-center justify-center min-h-0 flex-1 min-w-0">
|
||||
{/* Album Art */}
|
||||
<div className="relative mb-4 lg:mb-6 flex-shrink-0">
|
||||
<div className="relative mb-4 lg:mb-6 shrink-0">
|
||||
<Image
|
||||
src={currentTrack.coverArt || '/default-album.png'}
|
||||
alt={currentTrack.album}
|
||||
@@ -335,7 +335,7 @@ export const FullScreenPlayer: React.FC<FullScreenPlayerProps> = ({ isOpen, onCl
|
||||
</div>
|
||||
|
||||
{/* Track Info */}
|
||||
<div className="text-center mb-4 lg:mb-6 px-4 flex-shrink-0 max-w-full">
|
||||
<div className="text-center mb-4 lg:mb-6 px-4 shrink-0 max-w-full">
|
||||
<h1 className="text-lg sm:text-xl lg:text-3xl font-bold text-foreground mb-2 line-clamp-2 leading-tight">
|
||||
{currentTrack.name}
|
||||
</h1>
|
||||
@@ -348,7 +348,7 @@ export const FullScreenPlayer: React.FC<FullScreenPlayerProps> = ({ isOpen, onCl
|
||||
</div>
|
||||
|
||||
{/* Progress */}
|
||||
<div className="w-full max-w-sm lg:max-w-md mb-4 lg:mb-6 px-4 flex-shrink-0">
|
||||
<div className="w-full max-w-sm lg:max-w-md mb-4 lg:mb-6 px-4 shrink-0">
|
||||
<div className="w-full" onClick={handleSeek}>
|
||||
<Progress value={progress} className="h-2 cursor-pointer" />
|
||||
</div>
|
||||
@@ -359,7 +359,7 @@ export const FullScreenPlayer: React.FC<FullScreenPlayerProps> = ({ isOpen, onCl
|
||||
</div>
|
||||
|
||||
{/* Controls */}
|
||||
<div className="flex items-center gap-3 sm:gap-4 lg:gap-6 mb-4 lg:mb-6 flex-shrink-0">
|
||||
<div className="flex items-center gap-3 sm:gap-4 lg:gap-6 mb-4 lg:mb-6 shrink-0">
|
||||
<button
|
||||
onClick={toggleShuffle}
|
||||
className={`p-2 hover:bg-gray-700/50 rounded-full transition-colors ${
|
||||
@@ -407,7 +407,7 @@ export const FullScreenPlayer: React.FC<FullScreenPlayerProps> = ({ isOpen, onCl
|
||||
</div>
|
||||
|
||||
{/* Volume and Lyrics Toggle */}
|
||||
<div className="flex items-center gap-3 flex-shrink-0 justify-center">
|
||||
<div className="flex items-center gap-3 shrink-0 justify-center">
|
||||
<button
|
||||
onMouseEnter={() => setShowVolumeSlider(true)}
|
||||
className="p-2 hover:bg-gray-700/50 rounded-full transition-colors">
|
||||
|
||||
@@ -92,7 +92,7 @@ export function PopularSongs({ songs, artistName }: PopularSongsProps) {
|
||||
</div>
|
||||
|
||||
{/* Album Art */}
|
||||
<div className="relative w-12 h-12 bg-muted rounded-md overflow-hidden flex-shrink-0">
|
||||
<div className="relative w-12 h-12 bg-muted rounded-md overflow-hidden shrink-0">
|
||||
{song.coverArt && api && (
|
||||
<Image
|
||||
src={api.getCoverArtUrl(song.coverArt, 96)}
|
||||
|
||||
@@ -68,7 +68,7 @@ export function SimilarArtists({ artistName }: SimilarArtistsProps) {
|
||||
<Link
|
||||
key={artist.name}
|
||||
href={`/artist/${encodeURIComponent(artist.name)}`}
|
||||
className="flex-shrink-0"
|
||||
className="shrink-0"
|
||||
>
|
||||
<div className="w-32 space-y-2 group cursor-pointer">
|
||||
<div className="relative w-32 h-32 bg-muted rounded-full overflow-hidden">
|
||||
|
||||
@@ -170,14 +170,14 @@ export function WhatsNewPopup() {
|
||||
<>
|
||||
<div className="flex gap-2 mb-4">
|
||||
<Button
|
||||
variant={tab === 'latest' ? 'default' : 'outline'}
|
||||
variant={tab === 'latest' ? 'default' : 'outline-solid'}
|
||||
size="sm"
|
||||
onClick={() => setTab('latest')}
|
||||
>
|
||||
Latest
|
||||
</Button>
|
||||
<Button
|
||||
variant={tab === 'archive' ? 'default' : 'outline'}
|
||||
variant={tab === 'archive' ? 'default' : 'outline-solid'}
|
||||
size="sm"
|
||||
onClick={() => setTab('archive')}
|
||||
disabled={archiveChangelogs.length === 0}
|
||||
|
||||
@@ -148,7 +148,7 @@ export function AlbumArtwork({
|
||||
|
||||
className={cn(
|
||||
"w-full h-full object-cover transition-all hover:scale-105",
|
||||
aspectRatio === "portrait" ? "aspect-[3/4]" : "aspect-square"
|
||||
aspectRatio === "portrait" ? "aspect-3/4" : "aspect-square"
|
||||
)}
|
||||
/>
|
||||
</div> */}
|
||||
|
||||
@@ -63,7 +63,7 @@ export function ArtistIcon({
|
||||
if (imageOnly) {
|
||||
return (
|
||||
<div
|
||||
className={cn("overflow-hidden rounded-full cursor-pointer flex-shrink-0", className)}
|
||||
className={cn("overflow-hidden rounded-full cursor-pointer shrink-0", className)}
|
||||
onClick={handleClick}
|
||||
style={{ width: size, height: size }}
|
||||
{...props}
|
||||
@@ -106,7 +106,7 @@ export function ArtistIcon({
|
||||
</CardContent>
|
||||
</Card>
|
||||
{/* <div
|
||||
className="overflow-hidden rounded-full cursor-pointer flex-shrink-0"
|
||||
className="overflow-hidden rounded-full cursor-pointer shrink-0"
|
||||
onClick={handleClick}
|
||||
style={{ width: size, height: size }}
|
||||
>
|
||||
|
||||
@@ -62,7 +62,7 @@ const Ihateserverside: React.FC<IhateserversideProps> = ({ children }) => {
|
||||
|
||||
{/* Main Content Area */}
|
||||
<div className="flex-1 flex overflow-hidden">
|
||||
<div className="w-64 flex-shrink-0 border-r transition-all duration-200">
|
||||
<div className="w-64 shrink-0 border-r transition-all duration-200">
|
||||
<Sidebar
|
||||
playlists={playlists}
|
||||
className="h-full overflow-y-auto"
|
||||
@@ -103,7 +103,7 @@ const Ihateserverside: React.FC<IhateserversideProps> = ({ children }) => {
|
||||
{/* Main Content Area */}
|
||||
<div className="flex-1 flex overflow-hidden">
|
||||
{isSidebarVisible && (
|
||||
<div className={`${isSidebarCollapsed ? 'w-16' : 'w-64'} flex-shrink-0 border-r transition-all duration-200`}>
|
||||
<div className={`${isSidebarCollapsed ? 'w-16' : 'w-64'} shrink-0 border-r transition-all duration-200`}>
|
||||
<Sidebar
|
||||
playlists={playlists}
|
||||
className="h-full overflow-y-auto"
|
||||
|
||||
@@ -217,7 +217,7 @@ const FavoritesPage = () => {
|
||||
<div className="w-8 text-sm text-muted-foreground text-center">
|
||||
{index + 1}
|
||||
</div>
|
||||
<div className="w-12 h-12 relative flex-shrink-0">
|
||||
<div className="w-12 h-12 relative shrink-0">
|
||||
{song.coverArt && api ? (
|
||||
<Image
|
||||
src={api.getCoverArtUrl(song.coverArt)}
|
||||
|
||||
104
app/globals.css
104
app/globals.css
@@ -1,31 +1,92 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@import 'tailwindcss';
|
||||
|
||||
@custom-variant dark (@media (prefers-color-scheme: dark));
|
||||
|
||||
body {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
@theme {
|
||||
--color-background: hsl(var(--background));
|
||||
--color-foreground: hsl(var(--foreground));
|
||||
|
||||
--color-card: hsl(var(--card));
|
||||
--color-card-foreground: hsl(var(--card-foreground));
|
||||
|
||||
--color-popover: hsl(var(--popover));
|
||||
--color-popover-foreground: hsl(var(--popover-foreground));
|
||||
|
||||
--color-primary: hsl(var(--primary));
|
||||
--color-primary-foreground: hsl(var(--primary-foreground));
|
||||
|
||||
--color-secondary: hsl(var(--secondary));
|
||||
--color-secondary-foreground: hsl(var(--secondary-foreground));
|
||||
|
||||
--color-muted: hsl(var(--muted));
|
||||
--color-muted-foreground: hsl(var(--muted-foreground));
|
||||
|
||||
--color-accent: hsl(var(--accent));
|
||||
--color-accent-foreground: hsl(var(--accent-foreground));
|
||||
|
||||
--color-destructive: hsl(var(--destructive));
|
||||
--color-destructive-foreground: hsl(var(--destructive-foreground));
|
||||
|
||||
--color-border: hsl(var(--border));
|
||||
--color-input: hsl(var(--input));
|
||||
--color-ring: hsl(var(--ring));
|
||||
--color-hover: hsl(var(--hover));
|
||||
|
||||
--color-chart-1: hsl(var(--chart-1));
|
||||
--color-chart-2: hsl(var(--chart-2));
|
||||
--color-chart-3: hsl(var(--chart-3));
|
||||
--color-chart-4: hsl(var(--chart-4));
|
||||
--color-chart-5: hsl(var(--chart-5));
|
||||
|
||||
--radius-lg: var(--radius);
|
||||
--radius-md: calc(var(--radius) - 2px);
|
||||
--radius-sm: calc(var(--radius) - 4px);
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
.text-balance {
|
||||
/*
|
||||
The default border color has changed to `currentcolor` in Tailwind CSS v4,
|
||||
so we've added these compatibility styles to make sure everything still
|
||||
looks the same as it did with Tailwind CSS v3.
|
||||
|
||||
If we ever want to remove these styles, we need to add an explicit border
|
||||
color utility to any element that depends on these defaults.
|
||||
*/
|
||||
@layer base {
|
||||
*,
|
||||
::after,
|
||||
::before,
|
||||
::backdrop,
|
||||
::file-selector-button {
|
||||
border-color: var(--color-gray-200, currentcolor);
|
||||
}
|
||||
}
|
||||
|
||||
@utility text-balance {
|
||||
text-wrap: balance;
|
||||
}
|
||||
|
||||
.animate-scroll {
|
||||
@utility animate-scroll {
|
||||
animation: scroll 8s linear infinite;
|
||||
}
|
||||
|
||||
.animate-infinite-scroll {
|
||||
@utility animate-infinite-scroll {
|
||||
animation: infiniteScroll 10s linear infinite;
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
body {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
@keyframes scroll {
|
||||
0%, 20% {
|
||||
0%,
|
||||
20% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
80%, 100% {
|
||||
80%,
|
||||
100% {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
}
|
||||
@@ -38,6 +99,7 @@ body {
|
||||
transform: translateX(-215%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
@@ -263,6 +325,7 @@ body {
|
||||
|
||||
|
||||
|
||||
@layer utilities {
|
||||
/* BackUp */
|
||||
.dark {
|
||||
--background: 240 10% 3.9%;
|
||||
@@ -293,19 +356,20 @@ body {
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
:focus-visible { outline-color: rgb(59, 130, 246); }
|
||||
::selection { background-color: rgb(59, 130, 246); }
|
||||
::marker { color: rgb(59, 130, 246); }
|
||||
|
||||
|
||||
:focus-visible {
|
||||
outline-color: rgb(59, 130, 246);
|
||||
}
|
||||
::selection {
|
||||
background-color: rgb(59, 130, 246);
|
||||
}
|
||||
::marker {
|
||||
color: rgb(59, 130, 246);
|
||||
}
|
||||
|
||||
::selection {
|
||||
background: var(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
|
||||
@@ -79,7 +79,7 @@ export default function HistoryPage() {
|
||||
return (
|
||||
<div className="h-full px-4 py-6 lg:px-8">
|
||||
<Tabs defaultValue="music" className="h-full space-y-6">
|
||||
<TabsContent value="music" className="border-none p-0 outline-none">
|
||||
<TabsContent value="music" className="border-none p-0 outline-hidden">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="space-y-1">
|
||||
<div className="flex items-center gap-2">
|
||||
@@ -155,7 +155,7 @@ export default function HistoryPage() {
|
||||
</div>
|
||||
|
||||
{/* Album Art */}
|
||||
<div className="w-12 h-12 mr-4 flex-shrink-0">
|
||||
<div className="w-12 h-12 mr-4 shrink-0">
|
||||
<Image
|
||||
src={track.coverArt || '/default-user.jpg'}
|
||||
alt={track.album}
|
||||
|
||||
@@ -109,7 +109,7 @@ export default function AlbumsPage() {
|
||||
return (
|
||||
<div className="h-full px-4 py-6 lg:px-8">
|
||||
<Tabs defaultValue="music" className="h-full flex flex-col space-y-6">
|
||||
<TabsContent value="music" className="border-none p-0 outline-none flex flex-col flex-grow">
|
||||
<TabsContent value="music" className="border-none p-0 outline-hidden flex flex-col grow">
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="space-y-1">
|
||||
<p className="text-2xl font-semibold tracking-tight">
|
||||
@@ -150,7 +150,7 @@ export default function AlbumsPage() {
|
||||
|
||||
<Separator className="my-4" />
|
||||
|
||||
<div className="relative flex-grow">
|
||||
<div className="relative grow">
|
||||
<ScrollArea className="h-full">
|
||||
<div className="h-full overflow-y-auto">
|
||||
<div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 2xl:grid-cols-7 gap-4 p-4 pb-8">
|
||||
|
||||
@@ -67,7 +67,7 @@ export default function ArtistPage() {
|
||||
return (
|
||||
<div className="h-full px-4 py-6 lg:px-8 mb-24">
|
||||
<Tabs defaultValue="music" className="h-full space-y-6">
|
||||
<TabsContent value="music" className="border-none p-0 outline-none">
|
||||
<TabsContent value="music" className="border-none p-0 outline-hidden">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="space-y-1">
|
||||
<p className="text-2xl font-semibold tracking-tight">
|
||||
|
||||
@@ -33,7 +33,7 @@ const PlaylistsPage: React.FC = () => {
|
||||
return (
|
||||
<div className="h-full px-4 py-6 lg:px-8">
|
||||
<Tabs defaultValue="music" className="h-full space-y-6">
|
||||
<TabsContent value="music" className="border-none p-0 outline-none">
|
||||
<TabsContent value="music" className="border-none p-0 outline-hidden">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="space-y-1">
|
||||
<p className="text-2xl font-semibold tracking-tight">
|
||||
@@ -60,7 +60,7 @@ const PlaylistsPage: React.FC = () => {
|
||||
<Link key={playlist.id} href={`/playlist/${playlist.id}`}>
|
||||
<div className="p-4 rounded-lg border border-border hover:bg-accent hover:text-accent-foreground transition-colors cursor-pointer h-32">
|
||||
<div className="flex items-center space-x-4 h-full">
|
||||
<div className="w-12 h-12 bg-muted rounded-md overflow-hidden flex-shrink-0">
|
||||
<div className="w-12 h-12 bg-muted rounded-md overflow-hidden shrink-0">
|
||||
<Image
|
||||
src={playlistCoverUrl}
|
||||
alt={playlist.name}
|
||||
|
||||
@@ -239,7 +239,7 @@ export default function SongsPage() {
|
||||
</div>
|
||||
|
||||
{/* Album Art */}
|
||||
<div className="w-12 h-12 mr-4 flex-shrink-0"> <Image
|
||||
<div className="w-12 h-12 mr-4 shrink-0"> <Image
|
||||
src={song.coverArt && api ? api.getCoverArtUrl(song.coverArt, 100) : '/default-user.jpg'}
|
||||
alt={song.album}
|
||||
width={48}
|
||||
|
||||
16
app/page.tsx
16
app/page.tsx
@@ -185,7 +185,7 @@ export default function MusicPage() {
|
||||
<div className="relative rounded-lg p-8">
|
||||
<div className="relative rounded-sm p-10">
|
||||
<div
|
||||
className="absolute inset-0 bg-center bg-cover bg-no-repeat blur-xl bg-gradient-to-r from-primary to-secondary"
|
||||
className="absolute inset-0 bg-center bg-cover bg-no-repeat blur-xl bg-linear-to-r from-primary to-secondary"
|
||||
style={{
|
||||
backgroundImage:
|
||||
timeOfDay === 'morning'
|
||||
@@ -203,7 +203,7 @@ export default function MusicPage() {
|
||||
</div>
|
||||
<>
|
||||
<Tabs defaultValue="music" className="h-full space-y-6">
|
||||
<TabsContent value="music" className="border-none p-0 outline-none">
|
||||
<TabsContent value="music" className="border-none p-0 outline-hidden">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="space-y-1">
|
||||
<p className="text-2xl font-semibold tracking-tight">
|
||||
@@ -221,14 +221,14 @@ export default function MusicPage() {
|
||||
{isLoading ? (
|
||||
// Loading skeletons
|
||||
Array.from({ length: 10 }).map((_, i) => (
|
||||
<div key={i} className="w-[220px] h-[320px] bg-muted animate-pulse rounded-md flex-shrink-0" />
|
||||
<div key={i} className="w-[220px] h-[320px] bg-muted animate-pulse rounded-md shrink-0" />
|
||||
))
|
||||
) : (
|
||||
recentAlbums.map((album) => (
|
||||
<AlbumArtwork
|
||||
key={album.id}
|
||||
album={album}
|
||||
className="w-[220px] flex-shrink-0"
|
||||
className="w-[220px] shrink-0"
|
||||
aspectRatio="square"
|
||||
width={220}
|
||||
height={220}
|
||||
@@ -258,14 +258,14 @@ export default function MusicPage() {
|
||||
{favoritesLoading ? (
|
||||
// Loading skeletons
|
||||
Array.from({ length: 10 }).map((_, i) => (
|
||||
<div key={i} className="w-[220px] h-[320px] bg-muted animate-pulse rounded-md flex-shrink-0" />
|
||||
<div key={i} className="w-[220px] h-[320px] bg-muted animate-pulse rounded-md shrink-0" />
|
||||
))
|
||||
) : (
|
||||
favoriteAlbums.map((album) => (
|
||||
<AlbumArtwork
|
||||
key={album.id}
|
||||
album={album}
|
||||
className="w-[220px] flex-shrink-0"
|
||||
className="w-[220px] shrink-0"
|
||||
aspectRatio="square"
|
||||
width={220}
|
||||
height={220}
|
||||
@@ -294,14 +294,14 @@ export default function MusicPage() {
|
||||
{isLoading ? (
|
||||
// Loading skeletons
|
||||
Array.from({ length: 10 }).map((_, i) => (
|
||||
<div key={i} className="w-[220px] h-[320px] bg-muted animate-pulse rounded-md flex-shrink-0" />
|
||||
<div key={i} className="w-[220px] h-[320px] bg-muted animate-pulse rounded-md shrink-0" />
|
||||
))
|
||||
) : (
|
||||
newestAlbums.map((album) => (
|
||||
<AlbumArtwork
|
||||
key={album.id}
|
||||
album={album}
|
||||
className="w-[220px] flex-shrink-0"
|
||||
className="w-[220px] shrink-0"
|
||||
aspectRatio="square"
|
||||
width={220}
|
||||
height={220}
|
||||
|
||||
@@ -208,7 +208,7 @@ export default function PlaylistPage() {
|
||||
</div>
|
||||
|
||||
{/* Album Art */}
|
||||
<div className="w-12 h-12 mr-4 flex-shrink-0"> <Image
|
||||
<div className="w-12 h-12 mr-4 shrink-0"> <Image
|
||||
src={song.coverArt && api ? api.getCoverArtUrl(song.coverArt, 100) : '/default-user.jpg'}
|
||||
alt={song.album}
|
||||
width={48}
|
||||
|
||||
@@ -49,7 +49,7 @@ const QueuePage: React.FC = () => {
|
||||
<div className="p-4 bg-accent/30 rounded-lg">
|
||||
<div className="flex items-center">
|
||||
{/* Album Art */}
|
||||
<div className="w-16 h-16 mr-4 flex-shrink-0">
|
||||
<div className="w-16 h-16 mr-4 shrink-0">
|
||||
<Image
|
||||
src={currentTrack.coverArt || '/default-user.jpg'}
|
||||
alt={currentTrack.album}
|
||||
@@ -115,7 +115,7 @@ const QueuePage: React.FC = () => {
|
||||
onClick={() => skipToTrackInQueue(index)}
|
||||
>
|
||||
{/* Album Art with Play Indicator */}
|
||||
<div className="w-12 h-12 mr-4 flex-shrink-0 relative">
|
||||
<div className="w-12 h-12 mr-4 shrink-0 relative">
|
||||
<Image
|
||||
src={track.coverArt || '/default-user.jpg'}
|
||||
alt={track.album}
|
||||
|
||||
@@ -142,7 +142,7 @@ export default function SearchPage() {
|
||||
<ScrollArea className="w-full">
|
||||
<div className="flex space-x-4 pb-4">
|
||||
{searchResults.artists.map((artist) => (
|
||||
<ArtistIcon key={artist.id} artist={artist} className="flex-shrink-0" />
|
||||
<ArtistIcon key={artist.id} artist={artist} className="shrink-0" />
|
||||
))}
|
||||
</div>
|
||||
<ScrollBar orientation="horizontal" />
|
||||
@@ -160,7 +160,7 @@ export default function SearchPage() {
|
||||
<AlbumArtwork
|
||||
key={album.id}
|
||||
album={album}
|
||||
className="flex-shrink-0 w-48"
|
||||
className="shrink-0 w-48"
|
||||
aspectRatio="square"
|
||||
width={192}
|
||||
height={192}
|
||||
@@ -192,7 +192,7 @@ export default function SearchPage() {
|
||||
</div>
|
||||
|
||||
{/* Song Cover */}
|
||||
<div className="flex-shrink-0"> <Image
|
||||
<div className="shrink-0"> <Image
|
||||
src={song.coverArt && api ? api.getCoverArtUrl(song.coverArt, 64) : '/default-user.jpg'}
|
||||
alt={song.album}
|
||||
width={48}
|
||||
|
||||
@@ -117,7 +117,7 @@ const AlertDialogCancel = React.forwardRef<
|
||||
<AlertDialogPrimitive.Cancel
|
||||
ref={ref}
|
||||
className={cn(
|
||||
buttonVariants({ variant: "outline" }),
|
||||
buttonVariants({ variant: "outline-solid" }),
|
||||
"mt-2 sm:mt-0",
|
||||
className
|
||||
)}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { cva, type VariantProps } from "class-variance-authority"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const badgeVariants = cva(
|
||||
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
||||
"inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
|
||||
@@ -5,18 +5,18 @@ import { cva, type VariantProps } from "class-variance-authority"
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const buttonVariants = cva(
|
||||
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
||||
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default:
|
||||
"bg-primary text-primary-foreground shadow hover:bg-primary/90",
|
||||
"bg-primary text-primary-foreground shadow-sm hover:bg-primary/90",
|
||||
destructive:
|
||||
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
||||
"bg-destructive text-destructive-foreground shadow-xs hover:bg-destructive/90",
|
||||
outline:
|
||||
"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",
|
||||
"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground",
|
||||
secondary:
|
||||
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
|
||||
"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
|
||||
ghost: "hover:bg-accent hover:text-accent-foreground",
|
||||
link: "text-primary underline-offset-4 hover:underline",
|
||||
},
|
||||
|
||||
@@ -9,7 +9,7 @@ const Card = React.forwardRef<
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"rounded-xl border bg-card text-card-foreground shadow",
|
||||
"rounded-xl border bg-card text-card-foreground shadow-sm",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -27,7 +27,7 @@ const ContextMenuSubTrigger = React.forwardRef<
|
||||
<ContextMenuPrimitive.SubTrigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
|
||||
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
|
||||
inset && "pl-8",
|
||||
className
|
||||
)}
|
||||
@@ -46,7 +46,7 @@ const ContextMenuSubContent = React.forwardRef<
|
||||
<ContextMenuPrimitive.SubContent
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
"z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -62,7 +62,7 @@ const ContextMenuContent = React.forwardRef<
|
||||
<ContextMenuPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
"z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -80,7 +80,7 @@ const ContextMenuItem = React.forwardRef<
|
||||
<ContextMenuPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50",
|
||||
inset && "pl-8",
|
||||
className
|
||||
)}
|
||||
@@ -96,7 +96,7 @@ const ContextMenuCheckboxItem = React.forwardRef<
|
||||
<ContextMenuPrimitive.CheckboxItem
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50",
|
||||
className
|
||||
)}
|
||||
checked={checked}
|
||||
@@ -120,7 +120,7 @@ const ContextMenuRadioItem = React.forwardRef<
|
||||
<ContextMenuPrimitive.RadioItem
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -47,7 +47,7 @@ const DialogContent = React.forwardRef<
|
||||
>
|
||||
{children}
|
||||
{!hideCloseButton && (
|
||||
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
|
||||
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-hidden focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
|
||||
<X className="h-4 w-4" />
|
||||
<span className="sr-only">Close</span>
|
||||
</DialogPrimitive.Close>
|
||||
|
||||
@@ -8,7 +8,7 @@ const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
|
||||
<input
|
||||
type={type}
|
||||
className={cn(
|
||||
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
||||
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-xs transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
||||
className
|
||||
)}
|
||||
ref={ref}
|
||||
|
||||
@@ -23,7 +23,7 @@ const Menubar = React.forwardRef<
|
||||
<MenubarPrimitive.Root
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex h-9 items-center space-x-1 rounded-md border bg-background p-1 shadow-sm",
|
||||
"flex h-9 items-center space-x-1 rounded-md border bg-background p-1 shadow-xs",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -38,7 +38,7 @@ const MenubarTrigger = React.forwardRef<
|
||||
<MenubarPrimitive.Trigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex cursor-default select-none items-center rounded-sm px-3 py-1 text-sm font-medium outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
|
||||
"flex cursor-default select-none items-center rounded-sm px-3 py-1 text-sm font-medium outline-hidden focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -55,7 +55,7 @@ const MenubarSubTrigger = React.forwardRef<
|
||||
<MenubarPrimitive.SubTrigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
|
||||
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
|
||||
inset && "pl-8",
|
||||
className
|
||||
)}
|
||||
@@ -74,7 +74,7 @@ const MenubarSubContent = React.forwardRef<
|
||||
<MenubarPrimitive.SubContent
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
"z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-lg data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -97,7 +97,7 @@ const MenubarContent = React.forwardRef<
|
||||
alignOffset={alignOffset}
|
||||
sideOffset={sideOffset}
|
||||
className={cn(
|
||||
"z-50 min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
"z-50 min-w-48 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -116,7 +116,7 @@ const MenubarItem = React.forwardRef<
|
||||
<MenubarPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50",
|
||||
inset && "pl-8",
|
||||
className
|
||||
)}
|
||||
@@ -132,7 +132,7 @@ const MenubarCheckboxItem = React.forwardRef<
|
||||
<MenubarPrimitive.CheckboxItem
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50",
|
||||
className
|
||||
)}
|
||||
checked={checked}
|
||||
@@ -155,7 +155,7 @@ const MenubarRadioItem = React.forwardRef<
|
||||
<MenubarPrimitive.RadioItem
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -33,9 +33,9 @@ const ScrollBar = React.forwardRef<
|
||||
className={cn(
|
||||
"flex touch-none select-none transition-colors",
|
||||
orientation === "vertical" &&
|
||||
"h-full w-2.5 border-l border-l-transparent p-[1px]",
|
||||
"h-full w-2.5 border-l border-l-transparent p-px",
|
||||
orientation === "horizontal" &&
|
||||
"h-2.5 flex-col border-t border-t-transparent p-[1px]",
|
||||
"h-2.5 flex-col border-t border-t-transparent p-px",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -19,7 +19,7 @@ const SelectTrigger = React.forwardRef<
|
||||
<SelectPrimitive.Trigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
|
||||
"flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs ring-offset-background placeholder:text-muted-foreground focus:outline-hidden focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -75,7 +75,7 @@ const SelectContent = React.forwardRef<
|
||||
<SelectPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
"relative z-50 max-h-96 min-w-32 overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
||||
position === "popper" &&
|
||||
"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",
|
||||
className
|
||||
@@ -88,7 +88,7 @@ const SelectContent = React.forwardRef<
|
||||
className={cn(
|
||||
"p-1",
|
||||
position === "popper" &&
|
||||
"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"
|
||||
"h-(--radix-select-trigger-height) w-full min-w-(--radix-select-trigger-width)"
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
@@ -118,7 +118,7 @@ const SelectItem = React.forwardRef<
|
||||
<SelectPrimitive.Item
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
||||
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-hidden focus:bg-accent focus:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -19,7 +19,7 @@ const Separator = React.forwardRef<
|
||||
orientation={orientation}
|
||||
className={cn(
|
||||
"shrink-0 bg-border",
|
||||
orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
|
||||
orientation === "horizontal" ? "h-px w-full" : "h-full w-px",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -29,7 +29,7 @@ const TabsTrigger = React.forwardRef<
|
||||
<TabsPrimitive.Trigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",
|
||||
"inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -44,7 +44,7 @@ const TabsContent = React.forwardRef<
|
||||
<TabsPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
||||
"mt-2 ring-offset-background focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
@@ -16,7 +16,7 @@ const ToastViewport = React.forwardRef<
|
||||
<ToastPrimitives.Viewport
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]",
|
||||
"fixed top-0 z-100 flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -25,7 +25,7 @@ const ToastViewport = React.forwardRef<
|
||||
ToastViewport.displayName = ToastPrimitives.Viewport.displayName
|
||||
|
||||
const toastVariants = cva(
|
||||
"group pointer-events-auto relative flex w-full items-center justify-between space-x-2 overflow-hidden rounded-md border p-4 pr-6 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",
|
||||
"group pointer-events-auto relative flex w-full items-center justify-between space-x-2 overflow-hidden rounded-md border p-4 pr-6 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-(--radix-toast-swipe-end-x) data-[swipe=move]:translate-x-(--radix-toast-swipe-move-x) data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
@@ -62,7 +62,7 @@ const ToastAction = React.forwardRef<
|
||||
<ToastPrimitives.Action
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium transition-colors hover:bg-secondary focus:outline-none focus:ring-1 focus:ring-ring disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive",
|
||||
"inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium transition-colors hover:bg-secondary focus:outline-hidden focus:ring-1 focus:ring-ring disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 hover:group-[.destructive]:border-destructive/30 hover:group-[.destructive]:bg-destructive hover:group-[.destructive]:text-destructive-foreground focus:group-[.destructive]:ring-destructive",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -77,7 +77,7 @@ const ToastClose = React.forwardRef<
|
||||
<ToastPrimitives.Close
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"absolute right-1 top-1 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-1 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600",
|
||||
"absolute right-1 top-1 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-hidden focus:ring-1 group-hover:opacity-100 group-[.destructive]:text-red-300 hover:group-[.destructive]:text-red-50 focus:group-[.destructive]:ring-red-400 focus:group-[.destructive]:ring-offset-red-600",
|
||||
className
|
||||
)}
|
||||
toast-close=""
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
"zod": "^3.25.70"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4.1.11",
|
||||
"@types/node": "^24.0.10",
|
||||
"@types/react": "19.1.8",
|
||||
"@types/react-dom": "19.1.6",
|
||||
@@ -49,7 +50,7 @@
|
||||
"eslint": "^9.30",
|
||||
"eslint-config-next": "15.3.4",
|
||||
"postcss": "^8",
|
||||
"tailwindcss": "^3.4.15",
|
||||
"tailwindcss": "^4.1.11",
|
||||
"typescript": "^5"
|
||||
},
|
||||
"packageManager": "pnpm@10.12.4",
|
||||
|
||||
921
pnpm-lock.yaml
generated
921
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
/** @type {import('postcss-load-config').Config} */
|
||||
const config = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
'@tailwindcss/postcss': {},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
/* eslint-disable @typescript-eslint/no-require-imports */
|
||||
import type { Config } from "tailwindcss";
|
||||
|
||||
const config: Config = {
|
||||
darkMode: "media",
|
||||
content: [
|
||||
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./components/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./app/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
background: 'hsl(var(--background))',
|
||||
foreground: 'hsl(var(--foreground))',
|
||||
card: {
|
||||
DEFAULT: 'hsl(var(--card))',
|
||||
foreground: 'hsl(var(--card-foreground))'
|
||||
},
|
||||
popover: {
|
||||
DEFAULT: 'hsl(var(--popover))',
|
||||
foreground: 'hsl(var(--popover-foreground))'
|
||||
},
|
||||
primary: {
|
||||
DEFAULT: 'hsl(var(--primary))',
|
||||
foreground: 'hsl(var(--primary-foreground))'
|
||||
},
|
||||
secondary: {
|
||||
DEFAULT: 'hsl(var(--secondary))',
|
||||
foreground: 'hsl(var(--secondary-foreground))'
|
||||
},
|
||||
muted: {
|
||||
DEFAULT: 'hsl(var(--muted))',
|
||||
foreground: 'hsl(var(--muted-foreground))'
|
||||
},
|
||||
accent: {
|
||||
DEFAULT: 'hsl(var(--accent))',
|
||||
foreground: 'hsl(var(--accent-foreground))'
|
||||
},
|
||||
destructive: {
|
||||
DEFAULT: 'hsl(var(--destructive))',
|
||||
foreground: 'hsl(var(--destructive-foreground))'
|
||||
},
|
||||
border: 'hsl(var(--border))',
|
||||
input: 'hsl(var(--input))',
|
||||
ring: 'hsl(var(--ring))',
|
||||
hover: 'hsl(var(--hover))',
|
||||
chart: {
|
||||
'1': 'hsl(var(--chart-1))',
|
||||
'2': 'hsl(var(--chart-2))',
|
||||
'3': 'hsl(var(--chart-3))',
|
||||
'4': 'hsl(var(--chart-4))',
|
||||
'5': 'hsl(var(--chart-5))'
|
||||
}
|
||||
},
|
||||
borderRadius: {
|
||||
lg: 'var(--radius)',
|
||||
md: 'calc(var(--radius) - 2px)',
|
||||
sm: 'calc(var(--radius) - 4px)'
|
||||
},
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
require("tailwindcss-animate")
|
||||
],
|
||||
};
|
||||
export default config;
|
||||
Reference in New Issue
Block a user