Chore: upgrade to tailwind v4 (#4863)

pull/4872/head
shamoon 2 months ago committed by GitHub
parent fdf405fe0a
commit d55a5e5efe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

1188
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -44,7 +44,7 @@
},
"devDependencies": {
"@tailwindcss/forms": "^0.5.10",
"autoprefixer": "^10.4.20",
"@tailwindcss/postcss": "^4.0.9",
"eslint": "^9.21.0",
"eslint-config-next": "^15.1.7",
"eslint-config-prettier": "^10.0.2",
@ -55,8 +55,8 @@
"eslint-plugin-react-hooks": "^5.1.0",
"postcss": "^8.5.2",
"prettier": "^3.5.2",
"tailwind-scrollbar": "^3.1.0",
"tailwindcss": "^3.4.17",
"tailwind-scrollbar": "^4.0.1",
"tailwindcss": "^4.0.9",
"typescript": "^5.7.3"
},
"optionalDependencies": {

File diff suppressed because it is too large Load Diff

@ -1,6 +1,5 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
"@tailwindcss/postcss": {},
},
};

@ -34,7 +34,7 @@ export default function BookmarksGroup({
{layout?.header !== false && (
<Disclosure.Button disabled={disableCollapse} className="flex w-full select-none items-center group">
{layout?.icon && (
<div className="flex-shrink-0 mr-2 w-7 h-7 bookmark-group-icon">
<div className="shrink-0 mr-2 w-7 h-7 bookmark-group-icon">
<ResolvedIcon icon={layout.icon} />
</div>
)}
@ -52,7 +52,7 @@ export default function BookmarksGroup({
)}
<Transition
// Otherwise the transition group does display: none and cancels animation
className="!block"
className="block!"
unmount={false}
beforeLeave={() => {
panel.current.style.height = `${panel.current.scrollHeight}px`;

@ -20,9 +20,10 @@ export default function Item({ bookmark, iconOnly = false }) {
rel="noreferrer"
target={bookmark.target ?? settings.target ?? "_blank"}
className={classNames(
settings.cardBlur !== undefined && `backdrop-blur${settings.cardBlur.length ? "-" : ""}${settings.cardBlur}`,
settings.cardBlur !== undefined &&
`backdrop-blur-sm${settings.cardBlur.length ? "-" : ""}${settings.cardBlur}`,
"text-left cursor-pointer transition-all rounded-md font-medium text-theme-700 dark:text-theme-200 dark:hover:text-theme-300 shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 hover:bg-theme-300/20 dark:bg-white/5 dark:hover:bg-white/10",
iconOnly ? "h-[60px] w-[60px] grid" : "block w-full h-15 mb-3",
iconOnly ? "h-[60px] w-[60px] grid" : "block w-full h-8 mb-3",
)}
>
{iconOnly ? (
@ -36,9 +37,9 @@ export default function Item({ bookmark, iconOnly = false }) {
</div>
) : (
<div className="flex">
<div className="flex-shrink-0 flex items-center justify-center w-11 bg-theme-500/10 dark:bg-theme-900/50 text-theme-700 hover:text-theme-700 dark:text-theme-200 text-sm font-medium rounded-l-md bookmark-icon">
<div className="shrink-0 flex items-center justify-center w-11 bg-theme-500/10 dark:bg-theme-900/50 text-theme-700 hover:text-theme-700 dark:text-theme-200 text-sm font-medium rounded-l-md bookmark-icon">
{bookmark.icon && (
<div className="flex-shrink-0 w-5 h-5">
<div className="shrink-0 w-5 h-5">
<ResolvedIcon icon={bookmark.icon} alt={bookmark.abbr} />
</div>
)}

@ -254,10 +254,10 @@ export default function QuickLaunch({ servicesAndBookmarks, searchString, setSea
role="dialog"
aria-modal="true"
>
<div className="fixed inset-0 bg-gray-500 bg-opacity-50" />
<div className="fixed inset-0 bg-gray-500 opacity-50" />
<div className="fixed inset-0 z-20 overflow-y-auto">
<div className="flex min-h-full min-w-full items-start justify-center text-center">
<dialog className="mt-[10%] min-w-[90%] max-w-[90%] md:min-w-[40%] md:max-w-[40%] rounded-md p-0 block font-medium text-theme-700 dark:text-theme-200 dark:hover:text-theme-300 shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-50 dark:bg-theme-800">
<dialog className="mt-[10%] mx-auto min-w-[90%] max-w-[90%] md:min-w-[40%] md:max-w-[40%] rounded-md p-0 block font-medium text-theme-700 dark:text-theme-200 dark:hover:text-theme-300 shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-50 dark:bg-theme-800">
<input
placeholder="Search"
className={classNames(

@ -7,7 +7,7 @@ export default function Dropdown({ options, value, setValue }) {
return (
<Menu as="div" className="relative inline-block text-left">
<div>
<Menu.Button className="text-xs inline-flex w-full items-center rounded bg-theme-200/50 dark:bg-theme-900/20 px-3 py-1.5">
<Menu.Button className="text-xs inline-flex w-full items-center rounded-sm bg-theme-200/50 dark:bg-theme-900/20 px-3 py-1.5">
{options.find((option) => option.value === value).label}
<BiCog className="-mr-1 ml-2 h-4 w-4" aria-hidden="true" />
</Menu.Button>
@ -22,7 +22,7 @@ export default function Dropdown({ options, value, setValue }) {
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items className="absolute right-0 z-10 mt-2 w-56 origin-top-right rounded-md bg-theme-200/50 dark:bg-theme-900/50 backdrop-blur shadow-md focus:outline-none text-theme-700 dark:text-theme-200">
<Menu.Items className="absolute right-0 z-10 mt-2 w-56 origin-top-right rounded-md bg-theme-200/50 dark:bg-theme-900/50 backdrop-blur-sm shadow-md focus:outline-hidden text-theme-700 dark:text-theme-200">
<div className="py-1">
{options.map((option) => (
<Menu.Item key={option.value} as={Fragment}>
@ -33,7 +33,7 @@ export default function Dropdown({ options, value, setValue }) {
type="button"
className={classNames(
value === option.value ? "bg-theme-300/40 dark:bg-theme-900/40" : "",
"w-full block px-3 py-1.5 text-sm hover:bg-theme-300/70 hover:dark:bg-theme-900/70 text-left",
"w-full block px-3 py-1.5 text-sm hover:bg-theme-300/70 dark:hover:bg-theme-900/70 text-left",
)}
>
{option.label}

@ -42,7 +42,7 @@ export default function ServicesGroup({
{layout?.header !== false && (
<Disclosure.Button disabled={disableCollapse} className="flex w-full select-none items-center group">
{layout?.icon && (
<div className="flex-shrink-0 mr-2 w-7 h-7 service-group-icon">
<div className="shrink-0 mr-2 w-7 h-7 service-group-icon">
<ResolvedIcon icon={layout.icon} />
</div>
)}
@ -60,7 +60,7 @@ export default function ServicesGroup({
)}
<Transition
// Otherwise the transition group does display: none and cancels animation
className="!block"
className="block!"
unmount={false}
beforeLeave={() => {
panel.current.style.height = `${panel.current.scrollHeight}px`;

@ -34,7 +34,8 @@ export default function Item({ service, groupName, useEqualHeights }) {
<li key={service.name} id={service.id} className="service" data-name={service.name || ""}>
<div
className={classNames(
settings.cardBlur !== undefined && `backdrop-blur${settings.cardBlur.length ? "-" : ""}${settings.cardBlur}`,
settings.cardBlur !== undefined &&
`backdrop-blur-sm${settings.cardBlur.length ? "-" : ""}${settings.cardBlur}`,
useEqualHeights && "h-[calc(100%-0.5rem)]",
"transition-all mb-2 p-1 rounded-md font-medium text-theme-700 dark:text-theme-200 dark:hover:text-theme-300 shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 hover:bg-theme-300/20 dark:bg-white/5 dark:hover:bg-white/10 relative overflow-clip service-card",
)}
@ -46,13 +47,13 @@ export default function Item({ service, groupName, useEqualHeights }) {
href={service.href}
target={service.target ?? settings.target ?? "_blank"}
rel="noreferrer"
className="flex-shrink-0 flex items-center justify-center w-12 service-icon z-10"
className="shrink-0 flex items-center justify-center w-12 service-icon z-10"
aria-label={service.icon}
>
<ResolvedIcon icon={service.icon} />
</a>
) : (
<div className="flex-shrink-0 flex items-center justify-center w-12 service-icon z-10">
<div className="shrink-0 flex items-center justify-center w-12 service-icon z-10">
<ResolvedIcon icon={service.icon} />
</div>
))}
@ -88,14 +89,14 @@ export default function Item({ service, groupName, useEqualHeights }) {
} z-10 service-tags`}
>
{service.ping && (
<div className="flex-shrink-0 flex items-center justify-center service-tag service-ping">
<div className="shrink-0 flex items-center justify-center service-tag service-ping">
<Ping groupName={groupName} serviceName={service.name} style={statusStyle} />
<span className="sr-only">Ping status</span>
</div>
)}
{service.siteMonitor && (
<div className="flex-shrink-0 flex items-center justify-center service-tag service-site-monitor">
<div className="shrink-0 flex items-center justify-center service-tag service-site-monitor">
<SiteMonitor groupName={groupName} serviceName={service.name} style={statusStyle} />
<span className="sr-only">Site monitor status</span>
</div>
@ -105,7 +106,7 @@ export default function Item({ service, groupName, useEqualHeights }) {
<button
type="button"
onClick={() => (statsOpen ? closeStats() : setStatsOpen(true))}
className="flex-shrink-0 flex items-center justify-center cursor-pointer service-tag service-container-stats"
className="shrink-0 flex items-center justify-center cursor-pointer service-tag service-container-stats"
>
<Status service={service} style={statusStyle} />
<span className="sr-only">View container stats</span>
@ -115,7 +116,7 @@ export default function Item({ service, groupName, useEqualHeights }) {
<button
type="button"
onClick={() => (statsOpen ? closeStats() : setStatsOpen(true))}
className="flex-shrink-0 flex items-center justify-center cursor-pointer service-tag service-app"
className="shrink-0 flex items-center justify-center cursor-pointer service-tag service-app"
>
<KubernetesStatus service={service} style={statusStyle} />
<span className="sr-only">View container stats</span>
@ -127,7 +128,7 @@ export default function Item({ service, groupName, useEqualHeights }) {
{service.container && service.server && (
<div
className={classNames(
showStats || (statsOpen && !statsClosing) ? "max-h-[110px] opacity-100" : " max-h-[0] opacity-0",
showStats || (statsOpen && !statsClosing) ? "max-h-[110px] opacity-100" : " max-h-0 opacity-0",
"w-full overflow-hidden transition-all duration-300 ease-in-out service-stats",
)}
>
@ -139,7 +140,7 @@ export default function Item({ service, groupName, useEqualHeights }) {
{service.app && (
<div
className={classNames(
showStats || (statsOpen && !statsClosing) ? "max-h-[55px] opacity-100" : " max-h-[0] opacity-0",
showStats || (statsOpen && !statsClosing) ? "max-h-[55px] opacity-100" : " max-h-0 opacity-0",
"w-full overflow-hidden transition-all duration-300 ease-in-out service-stats",
)}
>

@ -19,7 +19,7 @@ export default function Widget({ widget, service }) {
}
return (
<div className="bg-theme-200/50 dark:bg-theme-900/20 rounded m-1 flex-1 flex flex-col items-center justify-center p-1 service-missing">
<div className="bg-theme-200/50 dark:bg-theme-900/20 rounded-sm m-1 flex-1 flex flex-col items-center justify-center p-1 service-missing">
<div className="font-thin text-sm">{t("widget.missing_type", { type: widget.type })}</div>
</div>
);

@ -7,7 +7,7 @@ export default function Block({ value, label }) {
return (
<div
className={classNames(
"bg-theme-200/50 dark:bg-theme-900/20 rounded m-1 flex-1 flex flex-col items-center justify-center text-center p-1",
"bg-theme-200/50 dark:bg-theme-900/20 rounded-sm m-1 flex-1 flex flex-col items-center justify-center text-center p-1",
value === undefined ? "animate-pulse" : "",
"service-block",
)}

@ -22,13 +22,13 @@ export default function Error({ error }) {
return (
<details className="px-1 pb-1">
<summary className="block text-center mt-1 mb-0 mx-auto p-3 rounded bg-rose-900/80 hover:bg-rose-900/95 text-theme-900 cursor-pointer">
<summary className="block text-center mt-1 mb-0 mx-auto p-3 rounded-sm bg-rose-900/80 hover:bg-rose-900/95 text-theme-900 cursor-pointer">
<div className="flex items-center justify-center text-xs font-bold">
<IoAlertCircle className="mr-1 w-5 h-5" />
{t("widget.api_error")} {error.message && t("widget.information")}
</div>
</summary>
<div className="bg-white dark:bg-theme-200/50 mt-2 rounded text-rose-900 text-xs font-mono whitespace-pre-wrap break-all">
<div className="bg-white dark:bg-theme-200/50 mt-2 rounded-sm text-rose-900 text-xs font-mono whitespace-pre-wrap break-all">
<ul className="p-4">
{error.message && (
<li>

@ -39,7 +39,7 @@ export default function ColorToggle() {
return (
<div id="color" className="w-full self-center">
<Popover className="relative flex items-center">
<Popover.Button className="outline-none">
<Popover.Button className="outline-hidden">
<IoColorPalette
className="h-5 w-5 text-theme-800 dark:text-theme-200 transition duration-150 ease-in-out"
aria-hidden="true"

@ -191,7 +191,7 @@ export default function Search({ options }) {
<div>
<Listbox.Button
className="
absolute right-0.5 bottom-0.5 rounded-r-md px-4 py-2 border-1
absolute right-0.5 bottom-0.5 rounded-r-md px-4 py-2
text-white font-medium text-sm
bg-theme-600/40 dark:bg-white/10
focus:ring-theme-500 dark:focus:ring-white/50"
@ -212,7 +212,7 @@ export default function Search({ options }) {
<Listbox.Options
className="absolute right-0 z-10 mt-1 origin-top-right rounded-md
bg-theme-100 dark:bg-theme-600 shadow-lg
ring-1 ring-black ring-opacity-5 focus:outline-none"
ring-1 ring-black ring-opacity-5 focus:outline-hidden"
>
<div className="flex flex-col">
{availableProviderIds.map((providerId) => {

@ -40,7 +40,7 @@ export default function Widget({ options }) {
<button
type="button"
onClick={() => setViewingPercentChange(!viewingPercentChange)}
className="flex items-center w-full h-full hover:outline-none focus:outline-none"
className="flex items-center w-full h-full hover:outline-hidden focus:outline-hidden"
>
<FaChartLine className="flex-none w-5 h-5 text-theme-800 dark:text-theme-200 mr-2" />
<div className="flex flex-wrap items-center gap-0.5">
@ -49,7 +49,7 @@ export default function Widget({ options }) {
stock && (
<div
key={stock.ticker}
className="rounded h-full text-xs px-1 w-[4.75rem] flex flex-col items-center justify-center"
className="rounded-sm h-full text-xs px-1 w-[4.75rem] flex flex-col items-center justify-center"
>
<span className="text-theme-800 dark:text-theme-200 text-xs">
{stock.ticker.split(":").pop()}

@ -13,7 +13,7 @@ export function getAllClasses(options, additionalClassNames = "") {
// eslint-disable-next-line no-param-reassign
additionalClassNames = [
additionalClassNames,
`backdrop-blur${options.style.cardBlur.length ? "-" : ""}${options.style.cardBlur}`,
`backdrop-blur-sm${options.style.cardBlur.length ? "-" : ""}${options.style.cardBlur}`,
].join(" ");
}

@ -303,7 +303,7 @@ function Home({ initialSettings }) {
className={classNames(
"sm:flex rounded-md bg-theme-100/20 dark:bg-white/5",
settings.cardBlur !== undefined &&
`backdrop-blur${settings.cardBlur.length ? "-" : ""}${settings.cardBlur}`,
`backdrop-blur-sm${settings.cardBlur.length ? "-" : ""}${settings.cardBlur}`,
)}
id="myTab"
data-tabs-toggle="#myTabContent"
@ -432,7 +432,7 @@ function Home({ initialSettings }) {
headerStyles[headerStyle],
settings.cardBlur !== undefined &&
headerStyle === "boxed" &&
`backdrop-blur${settings.cardBlur.length ? "-" : ""}${settings.cardBlur}`,
`backdrop-blur-sm${settings.cardBlur.length ? "-" : ""}${settings.cardBlur}`,
)}
>
<div id="widgets-wrap" className={classNames("flex flex-row w-full flex-wrap justify-between gap-x-2")}>
@ -536,7 +536,9 @@ export default function Wrapper({ initialSettings, fallback }) {
className={classNames(
"fixed overflow-auto w-full h-full",
backgroundBlur &&
`backdrop-blur${initialSettings.background.blur.length ? "-" : ""}${initialSettings.background.blur}`,
`backdrop-blur-sm${initialSettings.background.blur.length ? "-" : ""}${
initialSettings.background.blur - sm
}`,
backgroundSaturate && `backdrop-saturate-${initialSettings.background.saturate}`,
backgroundBrightness && `backdrop-brightness-${initialSettings.background.brightness}`,
)}

@ -1,6 +1,24 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@import 'tailwindcss';
@config '../../tailwind.config.js';
/*
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);
}
}
#__next {
width: 100%;

@ -26,7 +26,7 @@ export default function Event({ event, colorVariants, showDate = false, showTime
</span>
)}
<span className="ml-2 h-2 w-2">
<span className={classNames("block w-2 h-2 rounded", colorVariants[event.color] ?? "gray")} />
<span className={classNames("block w-2 h-2 rounded-sm", colorVariants[event.color] ?? "gray")} />
</span>
<div className="ml-2 h-5 text-left relative truncate" style={{ width: "70%" }}>
<div className="absolute mt-0.5 text-xs">{hover && event.additional ? event.additional : event.title}</div>

@ -57,7 +57,7 @@ export function Day({ weekNumber, weekday, events, colorVariants, showDate, setS
.map((event) => (
<span
key={`${event.date.ts}+${event.color}-${event.title}-${event.additional}`}
className={classNames("inline-flex h-1 w-1 m-0.5 rounded", colorVariants[event.color] ?? "gray")}
className={classNames("inline-flex h-1 w-1 m-0.5 rounded-sm", colorVariants[event.color] ?? "gray")}
/>
))}
</span>

@ -73,7 +73,7 @@ export default function Component({ service }) {
{validCryptos.map((crypto) => (
<div
key={crypto.id}
className="bg-theme-200/50 dark:bg-theme-900/20 rounded m-1 flex-1 flex flex-row items-center justify-between p-1 text-xs"
className="bg-theme-200/50 dark:bg-theme-900/20 rounded-sm m-1 flex-1 flex flex-row items-center justify-between p-1 text-xs"
>
<div className="font-thin pl-2">{crypto.name}</div>
<div className="flex flex-row text-right">

@ -172,7 +172,7 @@ export default function Component({ service }) {
{mappings.map((mapping) => (
<div
key={mapping.label}
className="bg-theme-200/50 dark:bg-theme-900/20 rounded m-1 flex-1 flex flex-row items-center justify-between p-1 text-xs animate-pulse"
className="bg-theme-200/50 dark:bg-theme-900/20 rounded-sm m-1 flex-1 flex flex-row items-center justify-between p-1 text-xs animate-pulse"
>
<div className="font-thin pl-2">{mapping.label}</div>
<div className="flex flex-row text-right">
@ -203,7 +203,7 @@ export default function Component({ service }) {
{mappings.map((mapping) => (
<div
key={mapping.label}
className="bg-theme-200/50 dark:bg-theme-900/20 rounded m-1 flex-1 flex flex-row items-center justify-between p-1 text-xs"
className="bg-theme-200/50 dark:bg-theme-900/20 rounded-sm m-1 flex-1 flex flex-row items-center justify-between p-1 text-xs"
>
<div className="font-thin pl-2">{mapping.label}</div>
<div className="flex flex-row text-right">

@ -48,7 +48,7 @@ export default function Component({ service }) {
style={{
height: `${Math.max(20, (140 * (fsData.size - fsData.free)) / fsData.size)}px`,
}}
className="absolute bottom-0 border-t border-t-theme-500 bg-gradient-to-b from-theme-500/40 to-theme-500/10 w-full"
className="absolute bottom-0 border-t border-t-theme-500 bg-linear-to-b from-theme-500/40 to-theme-500/10 w-full"
/>
</div>
)}

@ -109,7 +109,7 @@ export default function Component({ service }) {
return (
<Container chart={chart}>
{chart && (
<div className="bg-gradient-to-br from-theme-500/30 via-theme-600/20 to-theme-700/10 absolute -top-10 -left-2 -right-2 -bottom-2 h-[calc(100%+3em)] w-[calc(100%+1em)]" />
<div className="bg-linear-to-br from-theme-500/30 via-theme-600/20 to-theme-700/10 absolute -top-10 -left-2 -right-2 -bottom-2 h-[calc(100%+3em)] w-[calc(100%+1em)]" />
)}
<Block position="-top-6 right-2">

@ -24,7 +24,7 @@ export default function Component({ service }) {
<Container service={service}>
<div
className={classNames(
"bg-theme-200/50 dark:bg-theme-900/20 rounded m-1 flex-1 flex flex-col items-center justify-center text-center",
"bg-theme-200/50 dark:bg-theme-900/20 rounded-sm m-1 flex-1 flex flex-col items-center justify-center text-center",
"service-block",
)}
>
@ -41,7 +41,7 @@ export default function Component({ service }) {
style={{
scrollingDisableStyle,
}}
className={`rounded w-full ${classes}`}
className={`rounded-sm w-full ${classes}`}
/>
</div>
</Container>

@ -61,7 +61,7 @@ function StockItem({ service, ticker }) {
}
return (
<div className="bg-theme-200/50 dark:bg-theme-900/20 rounded flex flex-1 items-center justify-between m-1 p-1 text-xs">
<div className="bg-theme-200/50 dark:bg-theme-900/20 rounded-sm flex flex-1 items-center justify-between m-1 p-1 text-xs">
<span className="font-thin ml-2 flex-none">{ticker}</span>
<div className="flex items-center flex-row-reverse mr-2 text-right">
<span className={`font-bold ml-2 w-10 ${data.dp > 0 ? "text-emerald-300" : "text-rose-300"}`}>

@ -15,7 +15,7 @@ export default function Pool({ name, free, allocated, healthy }) {
}}
/>
<span className="ml-2 h-2 w-2 z-10">
<span className={classNames("block w-2 h-2 rounded", statusColor)} />
<span className={classNames("block w-2 h-2 rounded-sm", statusColor)} />
</span>
<div className="text-xs z-10 self-center ml-2 relative h-4 grow mr-2">
<div className="absolute w-full whitespace-nowrap text-ellipsis overflow-hidden text-left">{name}</div>

Loading…
Cancel
Save