chore: migrate to tailwindcss v4

This commit is contained in:
Asger Juul Brunshøj 2025-03-21 14:11:41 +01:00
parent 98703f2c8b
commit d9406f98d1
13 changed files with 83 additions and 51 deletions

View File

@ -27,7 +27,7 @@ pub fn Button(
});
let separator = icon.get().is_some().then(|| {
let mut classes = "w-0.5 bg-gradient-to-br min-w-0.5".to_string();
let mut classes = "w-0.5 bg-linear-to-br min-w-0.5".to_string();
classes.push(' ');
classes.push_str(color.class_from());
classes.push(' ');
@ -45,7 +45,7 @@ pub fn Button(
};
view! {
<button type="button" class="hover:brightness-125 active:brightness-90">
<button type="button" class="cursor-pointer hover:brightness-125 active:brightness-90">
<OutlinedBox color highlight>
<div class="flex items-stretch">{icon_view} {separator} {text_view}</div>
</OutlinedBox>

View File

@ -8,7 +8,7 @@ pub fn Checkbox(checked: RwSignal<bool>, #[prop(into)] text: Signal<String>, #[p
let unique_id = Oco::from(format!("checkbox-{}", uuid::Uuid::new_v4()));
let checkbox_view = view! {
<div class="self-center text-white bg-white rounded-sm aspect-square mx-5 my-2.5">
<div class="self-center text-white bg-white rounded-xs aspect-square mx-5 my-2.5">
<span class=("text-gray-950", move || checked.get())>
<icons::Check />
</span>
@ -16,7 +16,7 @@ pub fn Checkbox(checked: RwSignal<bool>, #[prop(into)] text: Signal<String>, #[p
};
let separator = {
let mut classes = "w-0.5 bg-gradient-to-br min-w-0.5".to_string();
let mut classes = "w-0.5 bg-linear-to-br min-w-0.5".to_string();
classes.push(' ');
classes.push_str(color.class_from());
classes.push(' ');

View File

@ -6,7 +6,7 @@ pub fn OutlinedBox(children: Children, color: Gradient, #[prop(optional)] highli
let highlight = move || highlight.get().unwrap_or(false);
let outer_classes = move || {
let mut c = "p-0.5 bg-gradient-to-br rounded-lg".to_string();
let mut c = "p-0.5 bg-linear-to-br rounded-lg".to_string();
c.push(' ');
c.push_str(color.class_from());
c.push(' ');

View File

@ -28,11 +28,17 @@ pub fn Problem(
holds.into_iter().collect_view()
};
let grid_classes = move || format!("grid grid-rows-{} grid-cols-{} gap-3", dim.get().rows, dim.get().cols);
let style = move || {
let grid_rows = crate::css::grid_rows_n(dim.get().rows);
let grid_cols = crate::css::grid_cols_n(dim.get().cols);
[grid_rows, grid_cols].join(" ")
};
view! {
<div class="grid gap-8 grid-cols-[auto,1fr]">
<div class=move || { grid_classes }>{holds}</div>
<div class="grid gap-8 grid-cols-[auto_1fr]">
<div style=style class="grid gap-3">
{holds}
</div>
</div>
}
}
@ -48,7 +54,7 @@ fn Hold(#[prop(into)] role: Signal<Option<HoldRole>>) -> impl IntoView {
Some(HoldRole::End) => Some("outline outline-offset-2 outline-red-500"),
None => Some("brightness-50"),
};
let mut s = "min-w-2 bg-sky-100 aspect-square rounded".to_string();
let mut s = "min-w-2 bg-sky-100 aspect-square rounded-sm".to_string();
if let Some(c) = role_classes {
s.push(' ');
s.push_str(c);

View File

@ -11,7 +11,7 @@ pub fn ProblemInfo(#[prop(into)] problem: Signal<models::Problem>) -> impl IntoV
let method = Signal::derive(move || problem.read().method.to_string());
view! {
<div class="grid grid-rows-none gap-y-1 gap-x-0.5 grid-cols-[auto,1fr]">
<div class="grid grid-rows-none gap-y-1 gap-x-0.5 grid-cols-[auto_1fr]">
<NameValue name="Name:" value=name />
<NameValue name="Method:" value=method />
<NameValue name="Set By:" value=set_by />

9
crates/ascend/src/css.rs Normal file
View File

@ -0,0 +1,9 @@
/// Tailwind's grid-rows-<n>
pub fn grid_rows_n(n: u64) -> String {
format!("grid-template-rows: repeat({n}, minmax(0, 1fr));")
}
/// Tailwind's grid-cols-<n>
pub fn grid_cols_n(n: u64) -> String {
format!("grid-template-columns: repeat({n}, minmax(0, 1fr));")
}

View File

@ -38,6 +38,8 @@ pub mod gradient;
pub mod resources;
pub mod css;
pub mod codec;
pub mod models;
pub mod server_functions;

View File

@ -84,12 +84,18 @@ fn Ready(wall: models::Wall) -> impl IntoView {
holds.push(view! { <Hold wall_uid=wall.uid hold /> });
}
let grid_classes = format!("grid grid-rows-{} grid-cols-{} gap-3", wall.rows, wall.cols);
let style = {
let grid_rows = crate::css::grid_rows_n(wall.rows);
let grid_cols = crate::css::grid_cols_n(wall.cols);
[grid_rows, grid_cols].join(" ")
};
view! {
<div>
<p class="my-4 font-semibold">"Click hold to replace image"</p>
<div class=move || { grid_classes.clone() }>{holds}</div>
<div style=style class="grid gap-3">
{holds}
</div>
</div>
}
}
@ -155,7 +161,7 @@ fn Hold(wall_uid: models::WallUid, hold: models::Hold) -> impl IntoView {
view! {
<button on:click=open_camera>
<div class="bg-indigo-100 rounded aspect-square">{img}</div>
<div class="bg-indigo-100 rounded-sm aspect-square">{img}</div>
</button>
<input

View File

@ -182,7 +182,7 @@ fn WithWall(
};
let v = view! {
<button on:click=onclick>
<button on:click=onclick class="cursor-pointer">
<OnHoverRed>
<Hold hold />
</OnHoverRed>
@ -196,7 +196,7 @@ fn WithWall(
let name = view! { <p class="font-light mr-4 text-right text-orange-300">{"Problems:"}</p> };
let value = view! { <p class="text-white">{filtered_problems.read().len()}</p> };
view! {
<div class="grid grid-rows-none gap-y-1 gap-x-0.5 grid-cols-[auto,1fr]">
<div class="grid grid-rows-none gap-y-1 gap-x-0.5 grid-cols-[auto_1fr]">
{name} {value}
</div>
}
@ -271,7 +271,7 @@ fn WithWall(
};
view! {
<div class="inline-grid grid-cols-1 gap-8 md:grid-cols-[auto,1fr]">
<div class="inline-grid grid-cols-1 gap-8 md:grid-cols-[auto_1fr]">
<div>{grid}</div>
<div class="flex flex-col" style="width:38rem">
@ -454,11 +454,15 @@ fn Grid(
};
cells.push(cell);
}
let grid_classes = format!("grid grid-rows-{} grid-cols-{} gap-1", wall.rows, wall.cols,);
let style = {
let grid_rows = crate::css::grid_rows_n(wall.rows);
let grid_cols = crate::css::grid_cols_n(wall.cols);
format!("max-height: 90vh; max-width: 90vh; {}", [grid_rows, grid_cols].join(" "))
};
view! {
<div class="grid grid-cols-[auto,1fr]">
<div style="max-height: 90vh; max-width: 90vh;" class=move || { grid_classes.clone() }>
<div class="grid grid-cols-[auto_1fr]">
<div style=style class="grid gap-1">
{cells}
</div>
</div>
@ -478,15 +482,15 @@ fn Hold(
tracing::trace!("Enter");
move || {
let mut class = "bg-sky-100 aspect-square rounded hover:brightness-125".to_string();
let mut class = "bg-sky-100 aspect-square rounded-sm hover:brightness-125".to_string();
if let Some(role) = role {
let role = role.get()?;
let role_classes = match role {
Some(HoldRole::Start) => Some("outline outline-offset-2 outline-green-500"),
Some(HoldRole::Normal) => Some("outline outline-offset-2 outline-blue-500"),
Some(HoldRole::Zone) => Some("outline outline-offset-2 outline-amber-500"),
Some(HoldRole::End) => Some("outline outline-offset-2 outline-red-500"),
Some(HoldRole::Start) => Some("outline outline-3 outline-green-500"),
Some(HoldRole::Normal) => Some("outline outline-3 outline-blue-500"),
Some(HoldRole::Zone) => Some("outline outline-3 outline-amber-500"),
Some(HoldRole::End) => Some("outline outline-3 outline-red-500"),
None => Some("brightness-50"),
};
if let Some(c) = role_classes {

View File

@ -1,3 +1,19 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@import 'tailwindcss';
/*
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);
}
}

View File

@ -4,21 +4,9 @@
relative: true,
files: ["*.html", "./src/**/*.rs"],
},
// https://tailwindcss.com/docs/content-configuration#using-regular-expressions
safelist: [
{
pattern: /bg-transparent/,
},
{
pattern: /grid-cols-.+/,
},
{
pattern: /grid-rows-.+/,
},
],
theme: {
extend: {},
},
plugins: [],
}

18
flake.lock generated
View File

@ -10,11 +10,11 @@
]
},
"locked": {
"lastModified": 1740523129,
"narHash": "sha256-q/k/T9Hf+aCo8/xQnqyw+E7dYx8Nq1u7KQ2ylORcP+M=",
"lastModified": 1741078851,
"narHash": "sha256-1Qu/Uu+yPUDhHM2XjTbwQqpSrYhhHu7TpHHrT7UO/0o=",
"owner": "plul",
"repo": "basecamp",
"rev": "0882906c106ab0bf193b3417c845c5accbec2419",
"rev": "3e4579d8b4400506e5f53069448b3471608b5281",
"type": "github"
},
"original": {
@ -25,11 +25,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1740547748,
"narHash": "sha256-Ly2fBL1LscV+KyCqPRufUBuiw+zmWrlJzpWOWbahplg=",
"lastModified": 1742456341,
"narHash": "sha256-yvdnTnROddjHxoQqrakUQWDZSzVchczfsuuMOxg476c=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "3a05eebede89661660945da1f151959900903b6a",
"rev": "7344a3b78128f7b1765dba89060b015fb75431a7",
"type": "github"
},
"original": {
@ -53,11 +53,11 @@
]
},
"locked": {
"lastModified": 1740623427,
"narHash": "sha256-3SdPQrZoa4odlScFDUHd4CUPQ/R1gtH4Mq9u8CBiK8M=",
"lastModified": 1742524367,
"narHash": "sha256-KzTwk/5ETJavJZYV1DEWdCx05M4duFCxCpRbQSKWpng=",
"owner": "oxalica",
"repo": "rust-overlay",
"rev": "d342e8b5fd88421ff982f383c853f0fc78a847ab",
"rev": "70bf752d176b2ce07417e346d85486acea9040ef",
"type": "github"
},
"original": {

View File

@ -47,7 +47,7 @@
nativeBuildInputs = [
pkgs.cargo-leptos
pkgs.dart-sass
pkgs.tailwindcss
pkgs.tailwindcss_4
# For optimizing wasm release builds
pkgs.binaryen
@ -137,7 +137,7 @@
pkgs.cargo-leptos
pkgs.leptosfmt
pkgs.dart-sass
pkgs.tailwindcss
pkgs.tailwindcss_4
pkgs.tailwindcss-language-server
# For optimizing wasm release builds
@ -146,6 +146,7 @@
env.RUST_LOG = "info,ascend=debug";
env.MOONBOARD_PROBLEMS = "moonboard-problems";
env.LEPTOS_TAILWIND_VERSION = "v4.0.8";
};
};
}