Migrate to tailwind v4 (#370)

This commit is contained in:
1ilit 2025-03-21 01:25:36 +04:00 committed by GitHub
parent a358b56d7e
commit f95841f0e7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 631 additions and 743 deletions

1174
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -44,10 +44,10 @@
"usehooks-ts": "^3.1.0"
},
"devDependencies": {
"@tailwindcss/postcss": "^4.0.14",
"@types/react": "^18.2.43",
"@types/react-dom": "^18.2.17",
"@vitejs/plugin-react": "^4.2.1",
"autoprefixer": "^10.4.16",
"eslint": "^8.55.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-react": "^7.33.2",
@ -55,7 +55,7 @@
"eslint-plugin-react-refresh": "^0.4.5",
"postcss": "^8.4.32",
"prettier": "3.2.5",
"tailwindcss": "^3.3.6",
"tailwindcss": "^4.0.14",
"vite": "^5.4.1"
},
"overrides": {

View File

@ -1,6 +1,5 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
'@tailwindcss/postcss': {},
},
}

View File

@ -105,45 +105,41 @@ export default function Area({
onPointerDown={onPointerDown}
>
<div
className={`border-2 ${
className={`w-full h-full p-2 rounded cursor-move border-2 ${
isHovered
? "border-dashed border-blue-500"
: selectedElement.element === ObjectType.AREA &&
selectedElement.id === data.id
? "border-blue-500"
: "border-slate-400"
} w-full h-full cursor-move rounded`}
? "border-blue-500 opacity-100"
: "border-slate-400 opacity-100"
}`}
style={{ backgroundColor: `${data.color}66` }}
>
<div
className="w-fill p-2 h-full"
style={{ backgroundColor: `${data.color}66` }}
>
<div className="flex justify-between gap-1 w-full">
<div className="text-color select-none overflow-hidden text-ellipsis">
{data.name}
</div>
{(isHovered || (areaIsSelected() && !layout.sidebar)) && (
<Popover
visible={areaIsSelected() && !layout.sidebar}
onClickOutSide={onClickOutSide}
stopPropagation
content={<EditPopoverContent data={data} />}
trigger="custom"
position="rightTop"
showArrow
>
<Button
icon={<IconEdit />}
size="small"
theme="solid"
style={{
backgroundColor: "#2F68ADB3",
}}
onClick={edit}
/>
</Popover>
)}
<div className="flex justify-between gap-1 w-full">
<div className="text-color select-none overflow-hidden text-ellipsis">
{data.name}
</div>
{(isHovered || (areaIsSelected() && !layout.sidebar)) && (
<Popover
visible={areaIsSelected() && !layout.sidebar}
onClickOutSide={onClickOutSide}
stopPropagation
content={<EditPopoverContent data={data} />}
trigger="custom"
position="rightTop"
showArrow
>
<Button
icon={<IconEdit />}
size="small"
theme="solid"
style={{
backgroundColor: "#2F68ADB3",
}}
onClick={edit}
/>
</Popover>
)}
</div>
</div>
</foreignObject>
@ -269,7 +265,7 @@ function EditPopoverContent({ data }) {
showArrow
>
<div
className="h-[32px] w-[32px] rounded"
className="h-[32px] w-[32px] rounded-sm"
style={{ backgroundColor: data.color }}
/>
</Popover>

View File

@ -494,7 +494,7 @@ export default function Canvas() {
const theme = localStorage.getItem("theme");
return (
<div className="flex-grow h-full touch-none" id="canvas">
<div className="grow h-full touch-none" id="canvas">
<div
className="w-full h-full"
style={{
@ -587,7 +587,7 @@ export default function Canvas() {
</svg>
</div>
{settings.showDebugCoordinates && (
<div className="fixed flex flex-col flex-wrap gap-6 bg-[rgba(var(--semi-grey-1),var(--tw-bg-opacity))]/40 border border-color bottom-4 right-4 p-4 rounded-xl backdrop-blur-sm pointer-events-none select-none">
<div className="fixed flex flex-col flex-wrap gap-6 bg-[rgba(var(--semi-grey-1),var(--tw-bg-opacity))]/40 border border-color bottom-4 right-4 p-4 rounded-xl backdrop-blur-xs pointer-events-none select-none">
<table className="table-auto grow">
<thead>
<tr>

View File

@ -257,7 +257,7 @@ export default function Note({ data, onPointerDown }) {
showArrow
>
<div
className="h-[32px] w-[32px] rounded"
className="h-[32px] w-[32px] rounded-sm"
style={{ backgroundColor: data.color }}
/>
</Popover>
@ -302,7 +302,7 @@ export default function Note({ data, onPointerDown }) {
})
}
onBlur={handleBlur}
className="w-full resize-none outline-none overflow-y-hidden border-none select-none"
className="w-full resize-none outline-hidden overflow-y-hidden border-none select-none"
style={{ backgroundColor: data.color }}
/>
</div>

View File

@ -1,4 +1,4 @@
import { useState } from "react";
import { useMemo, useState } from "react";
import {
Tab,
ObjectType,
@ -37,8 +37,14 @@ export default function Table(props) {
const { t } = useTranslation();
const { selectedElement, setSelectedElement } = useSelect();
const borderColor = useMemo(
() => (settings.mode === "light" ? "border-zinc-300" : "border-zinc-600"),
[settings.mode],
);
const height =
tableData.fields.length * tableFieldHeight + tableHeaderHeight + 7;
const openEditor = () => {
if (!layout.sidebar) {
setSelectedElement((prev) => ({
@ -84,7 +90,7 @@ export default function Table(props) {
selectedElement.id === tableData.id &&
selectedElement.element === ObjectType.TABLE
? "border-solid border-blue-500"
: "border-zinc-500"
: borderColor
}`}
style={{ direction: "ltr" }}
>
@ -313,7 +319,7 @@ export default function Table(props) {
} flex items-center gap-2 overflow-hidden`}
>
<button
className="flex-shrink-0 w-[10px] h-[10px] bg-[#2f68adcc] rounded-full"
className="shrink-0 w-[10px] h-[10px] bg-[#2f68adcc] rounded-full"
onPointerDown={(e) => {
if (!e.isPrimary) return;
@ -362,14 +368,13 @@ export default function Table(props) {
{fieldData.type +
((dbToTypes[database][fieldData.type].isSized ||
dbToTypes[database][fieldData.type].hasPrecision) &&
fieldData.size &&
fieldData.size !== ""
fieldData.size &&
fieldData.size !== ""
? `(${fieldData.size})`
: "")}
</span>
</div>
) : null
}
) : null}
</div>
</div>
);

View File

@ -1218,7 +1218,10 @@ export default function ControlPanel({
<i className="bi bi-toggle-off" />
),
function: () =>
setSettings((prev) => ({ ...prev, showDataTypes: !prev.showDataTypes })),
setSettings((prev) => ({
...prev,
showDataTypes: !prev.showDataTypes,
})),
},
show_grid: {
state: settings.showGrid ? (
@ -1414,7 +1417,7 @@ export default function ControlPanel({
{window.name.split(" ")[0] !== "t" && (
<Button
type="primary"
className="text-base me-2 pe-6 ps-5 py-[18px] rounded-md"
className="!text-base me-2 !pe-6 !ps-5 !py-[18px] !rounded-md"
size="default"
icon={<IconShareStroked />}
onClick={() => setModal(MODAL.SHARE)}
@ -1497,7 +1500,7 @@ export default function ControlPanel({
}
trigger="click"
>
<div className="py-1 px-2 hover-2 rounded flex items-center justify-center">
<div className="py-1 px-2 hover-2 rounded-sm flex items-center justify-center">
<div className="w-[40px]">
{Math.floor(transform.zoom * 100)}%
</div>
@ -1508,7 +1511,7 @@ export default function ControlPanel({
</Dropdown>
<Tooltip content={t("zoom_in")} position="bottom">
<button
className="py-1 px-2 hover-2 rounded text-lg"
className="py-1 px-2 hover-2 rounded-sm text-lg"
onClick={() =>
setTransform((prev) => ({ ...prev, zoom: prev.zoom * 1.2 }))
}
@ -1518,7 +1521,7 @@ export default function ControlPanel({
</Tooltip>
<Tooltip content={t("zoom_out")} position="bottom">
<button
className="py-1 px-2 hover-2 rounded text-lg"
className="py-1 px-2 hover-2 rounded-sm text-lg"
onClick={() =>
setTransform((prev) => ({ ...prev, zoom: prev.zoom / 1.2 }))
}
@ -1529,7 +1532,7 @@ export default function ControlPanel({
<Divider layout="vertical" margin="8px" />
<Tooltip content={t("undo")} position="bottom">
<button
className="py-1 px-2 hover-2 rounded flex items-center"
className="py-1 px-2 hover-2 rounded-sm flex items-center"
onClick={undo}
>
<IconUndo
@ -1540,7 +1543,7 @@ export default function ControlPanel({
</Tooltip>
<Tooltip content={t("redo")} position="bottom">
<button
className="py-1 px-2 hover-2 rounded flex items-center"
className="py-1 px-2 hover-2 rounded-sm flex items-center"
onClick={redo}
>
<IconRedo
@ -1552,7 +1555,7 @@ export default function ControlPanel({
<Divider layout="vertical" margin="8px" />
<Tooltip content={t("add_table")} position="bottom">
<button
className="flex items-center py-1 px-2 hover-2 rounded"
className="flex items-center py-1 px-2 hover-2 rounded-sm"
onClick={() => addTable()}
>
<IconAddTable />
@ -1560,7 +1563,7 @@ export default function ControlPanel({
</Tooltip>
<Tooltip content={t("add_area")} position="bottom">
<button
className="py-1 px-2 hover-2 rounded flex items-center"
className="py-1 px-2 hover-2 rounded-sm flex items-center"
onClick={() => addArea()}
>
<IconAddArea />
@ -1568,7 +1571,7 @@ export default function ControlPanel({
</Tooltip>
<Tooltip content={t("add_note")} position="bottom">
<button
className="py-1 px-2 hover-2 rounded flex items-center"
className="py-1 px-2 hover-2 rounded-sm flex items-center"
onClick={() => addNote()}
>
<IconAddNote />
@ -1577,7 +1580,7 @@ export default function ControlPanel({
<Divider layout="vertical" margin="8px" />
<Tooltip content={t("save")} position="bottom">
<button
className="py-1 px-2 hover-2 rounded flex items-center"
className="py-1 px-2 hover-2 rounded-sm flex items-center"
onClick={save}
>
<IconSaveStroked size="extra-large" />
@ -1585,7 +1588,7 @@ export default function ControlPanel({
</Tooltip>
<Tooltip content={t("to_do")} position="bottom">
<button
className="py-1 px-2 hover-2 rounded text-xl -mt-0.5"
className="py-1 px-2 hover-2 rounded-sm text-xl -mt-0.5"
onClick={() => setSidesheet(SIDESHEET.TODO)}
>
<i className="fa-regular fa-calendar-check" />
@ -1594,7 +1597,7 @@ export default function ControlPanel({
<Divider layout="vertical" margin="8px" />
<Tooltip content={t("theme")} position="bottom">
<button
className="py-1 px-2 hover-2 rounded text-xl -mt-0.5"
className="py-1 px-2 hover-2 rounded-sm text-xl -mt-0.5"
onClick={() => {
const body = document.body;
if (body.hasAttribute("theme-mode")) {
@ -1782,7 +1785,7 @@ export default function ControlPanel({
</Dropdown.Menu>
}
>
<div className="px-3 py-1 hover-2 rounded">
<div className="px-3 py-1 hover-2 rounded-sm">
{t(category)}
</div>
</Dropdown>

View File

@ -68,7 +68,7 @@ export default function LayoutDropdown() {
}
trigger="click"
>
<div className="py-1 px-2 hover-2 rounded flex items-center justify-center">
<div className="py-1 px-2 hover-2 rounded-sm flex items-center justify-center">
<IconRowsStroked size="extra-large" />
<div>
<IconCaretdown />

View File

@ -42,7 +42,7 @@ export default function Code({ value, language }) {
/>
<button
onClick={copyCode}
className={`absolute right-4 top-2 px-2 py-1 rounded ${settings.mode === "dark" ? "bg-zinc-700" : "bg-zinc-200"}`}
className={`absolute right-4 top-2 px-2 py-1 rounded-sm ${settings.mode === "dark" ? "bg-zinc-700" : "bg-zinc-200"}`}
>
<i className={`bi bi-clipboard${copied ? "-check" : ""} me-2`} />
{t("copy")}

View File

@ -48,7 +48,7 @@ export default function Open({ selectedDiagramId, setSelectedDiagramId }) {
key={d.id}
className={`${
selectedDiagramId === d.id
? "bg-blue-300 bg-opacity-30"
? "bg-blue-300/30"
: "hover-1"
}`}
onClick={() => {

View File

@ -89,7 +89,7 @@ export default function AreaInfo({ data, i }) {
showArrow
>
<div
className="h-[32px] w-[32px] rounded"
className="h-[32px] w-[32px] rounded-sm"
style={{ backgroundColor: data.color }}
/>
</Popover>

View File

@ -133,7 +133,7 @@ export default function NoteInfo({ data, nid }) {
showArrow
>
<div
className="h-[32px] w-[32px] rounded mb-2"
className="h-[32px] w-[32px] rounded-sm mb-2"
style={{ backgroundColor: data.color }}
/>
</Popover>

View File

@ -275,7 +275,7 @@ export default function TableInfo({ data }) {
showArrow
>
<div
className="h-[32px] w-[32px] rounded"
className="h-[32px] w-[32px] rounded-sm"
style={{ backgroundColor: data.color }}
/>
</Popover>

View File

@ -47,7 +47,7 @@ export default function Thumbnail({ diagram, i, zoom, theme }) {
width={a.width > 0 ? a.width : 0}
height={a.height > 0 ? a.height : 0}
>
<div className="border border-slate-400 w-full h-full rounded-sm relative">
<div className="border border-slate-400 w-full h-full rounded-xs relative">
<div
className="opacity-40 w-fill h-full"
style={{ backgroundColor: a.color }}

View File

@ -119,4 +119,4 @@ export const DB = {
export const IMPORT_FROM = {
JSON: 0,
DBML: 1,
};
};

View File

@ -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);
}
}
@layer base {
/*
@ -18,15 +36,6 @@
}
}
*,
::before,
::after {
box-sizing: border-box;
border-width: 0;
border-style: solid;
border-color: #ffffff;
}
.semi-form-vertical .semi-form-field {
margin: 0;
padding-top: 8px !important;

View File

@ -234,13 +234,13 @@ export default function BugReport() {
<hr
className={`${
theme === "dark" ? "border-zinc-700" : "border-zinc-300"
} flex-grow`}
} grow`}
/>
<div className="text-sm font-semibold m-2">Alternatively</div>
<hr
className={`${
theme === "dark" ? "border-zinc-700" : "border-zinc-300"
} flex-grow`}
} grow`}
/>
</div>
<Button

View File

@ -47,7 +47,7 @@ export default function LandingPage() {
<div>
<div className="flex flex-col h-screen bg-zinc-100">
{showSurvey && (
<div className="text-white font-semibold py-1.5 px-4 text-sm text-center bg-gradient-to-r from-[#12495e] from-10% via-slate-500 to-[#12495e]">
<div className="text-white font-semibold py-1.5 px-4 text-sm text-center bg-linear-to-r from-[#12495e] from-10% via-slate-500 to-[#12495e]">
<Link to="/survey" className="hover:underline">
Help us improve! Share your feedback.
</Link>
@ -71,7 +71,7 @@ export default function LandingPage() {
<div className="absolute left-12 w-[45%] top-[50%] translate-y-[-54%] md:left-[50%] md:translate-x-[-50%] p-8 md:p-3 md:w-full text-zinc-800">
<FadeIn duration={0.75}>
<div className="md:px-3">
<h1 className="text-[42px] md:text-3xl font-bold tracking-wide bg-gradient-to-r from-sky-900 from-10% via-slate-500 to-[#12495e] inline-block text-transparent bg-clip-text">
<h1 className="text-[42px] md:text-3xl font-bold tracking-wide bg-linear-to-r from-sky-900 from-10% via-slate-500 to-[#12495e] inline-block text-transparent bg-clip-text">
Draw, Copy, and Paste
</h1>
<div className="text-lg font-medium mt-1 sliding-vertical">
@ -140,7 +140,7 @@ export default function LandingPage() {
</div>
</div>
</div>
<div className="mt-16 w-[75%] text-center sm:w-full mx-auto shadow-sm rounded-2xl border p-6 bg-white space-y-3">
<div className="mt-16 w-[75%] text-center sm:w-full mx-auto shadow-xs rounded-2xl border p-6 bg-white space-y-3">
<div className="text-lg font-medium">
Build diagrams with a few clicks, see the full picture, export SQL
scripts, customize your editor, and more.
@ -188,7 +188,7 @@ export default function LandingPage() {
{features.map((f, i) => (
<div
key={"feature" + i}
className="flex rounded-xl hover:bg-zinc-100 border border-zinc-100 shadow-sm hover:-translate-y-2 transition-all duration-300"
className="flex rounded-xl hover:bg-zinc-100 border border-zinc-100 shadow-xs hover:-translate-y-2 transition-all duration-300"
>
<div className="bg-sky-700 px-0.5 rounded-l-xl" />
<div className="px-8 py-4 ">

View File

@ -88,7 +88,7 @@ export default function Templates() {
{t.title}
</div>
<button
className="border rounded px-2 py-1 bg-white hover:bg-gray-200 transition-all duration-300"
className="border rounded-sm px-2 py-1 bg-white hover:bg-gray-200 transition-all duration-300"
onClick={() => forkTemplate(t.id)}
>
<i className="fa-solid fa-code-fork"></i>
@ -121,7 +121,7 @@ export default function Templates() {
</div>
<div>
<button
className="me-1 border rounded px-2 py-1 bg-white hover:bg-gray-200 transition-all duration-300"
className="me-1 border rounded-sm px-2 py-1 bg-white hover:bg-gray-200 transition-all duration-300"
onClick={() => forkTemplate(c.id)}
>
<i className="fa-solid fa-code-fork"></i>
@ -130,7 +130,7 @@ export default function Templates() {
</div>
<div className="flex justify-around mt-2">
<button
className="w-full text-center flex justify-center items-center border rounded px-2 py-1 bg-white hover:bg-gray-200 transition-all duration-300 text-blue-500"
className="w-full text-center flex justify-center items-center border rounded-sm px-2 py-1 bg-white hover:bg-gray-200 transition-all duration-300 text-blue-500"
onClick={() => editTemplate(c.id)}
>
<i className="bi bi-pencil-fill"></i>
@ -138,7 +138,7 @@ export default function Templates() {
</button>
<div className="border-l border-gray-300 mx-2" />
<button
className="w-full text-center flex justify-center items-center border rounded px-2 py-1 bg-white hover:bg-gray-200 transition-all duration-300 text-red-500"
className="w-full text-center flex justify-center items-center border rounded-sm px-2 py-1 bg-white hover:bg-gray-200 transition-all duration-300 text-red-500"
onClick={() => deleteTemplate(c.id)}
>
<IconDeleteStroked />
@ -162,7 +162,7 @@ export default function Templates() {
<div className="grid grid-cols-5 sm:grid-cols-1 gap-4 place-content-center my-4">
<img
src={template_screenshot}
className="border col-span-3 sm:cols-span-1 rounded"
className="border col-span-3 sm:cols-span-1 rounded-sm"
/>
<div className="col-span-2 sm:cols-span-1">
<div className="text-xl font-bold my-4">