mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-07-03 19:41:48 +02:00
Upgrade Tailwind to v4 (#491)
This commit is contained in:
@@ -1,134 +0,0 @@
|
||||
const plugin = require("tailwindcss/plugin");
|
||||
|
||||
const sizes = {
|
||||
"2xs": "1.4rem",
|
||||
xs: "1.8rem",
|
||||
sm: "2.0rem",
|
||||
md: "2.3rem",
|
||||
lg: "2.6rem",
|
||||
};
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
darkMode: ["class", '[data-resolved-appearance="dark"]'],
|
||||
theme: {
|
||||
extend: {
|
||||
keyframes: {
|
||||
blinkRing: {
|
||||
"0%, 49%": { "--tw-ring-color": "var(--primary)" },
|
||||
"50%, 99%": { "--tw-ring-color": "transparent" },
|
||||
"100%": { "--tw-ring-color": "var(--primary)" },
|
||||
},
|
||||
},
|
||||
animation: {
|
||||
blinkRing: "blinkRing 150ms step-start 400ms infinite",
|
||||
},
|
||||
opacity: {
|
||||
disabled: "0.3",
|
||||
},
|
||||
fontSize: {
|
||||
xs: "0.8rem",
|
||||
},
|
||||
height: sizes,
|
||||
width: sizes,
|
||||
minHeight: sizes,
|
||||
minWidth: sizes,
|
||||
lineHeight: {
|
||||
// HACK: Minus 2 to account for borders inside inputs
|
||||
xs: "calc(1.75rem - 2px)",
|
||||
sm: "calc(2.0rem - 2px)",
|
||||
md: "calc(2.5rem - 2px)",
|
||||
},
|
||||
transitionProperty: {
|
||||
grid: "grid",
|
||||
},
|
||||
},
|
||||
fontFamily: {
|
||||
mono: [
|
||||
"var(--font-family-editor)",
|
||||
"JetBrains Mono",
|
||||
"ui-monospace",
|
||||
"SFMono-Regular",
|
||||
"Menlo",
|
||||
"Monaco",
|
||||
"Fira Code",
|
||||
"Ubuntu Mono",
|
||||
"Consolas",
|
||||
"Liberation Mono",
|
||||
"Courier New",
|
||||
"DejaVu Sans Mono",
|
||||
"Hack",
|
||||
"monospace",
|
||||
],
|
||||
sans: [
|
||||
"var(--font-family-interface)",
|
||||
"Inter UI",
|
||||
"-apple-system",
|
||||
"BlinkMacSystemFont",
|
||||
"Segoe UI",
|
||||
"Roboto",
|
||||
"Oxygen-Sans",
|
||||
"Ubuntu",
|
||||
"Cantarell",
|
||||
"Helvetica Neue",
|
||||
"sans-serif",
|
||||
"Apple Color Emoji",
|
||||
"Segoe UI Emoji",
|
||||
"Segoe UI Symbol",
|
||||
],
|
||||
},
|
||||
fontSize: {
|
||||
"4xs": "0.6rem",
|
||||
"3xs": "0.675rem",
|
||||
"2xs": "0.75rem",
|
||||
xs: "0.8rem",
|
||||
sm: "0.9rem",
|
||||
base: "1rem",
|
||||
lg: "1.12rem",
|
||||
xl: "1.25rem",
|
||||
"2xl": "1.5rem",
|
||||
"3xl": "2rem",
|
||||
"4xl": "2.5rem",
|
||||
"5xl": "3rem",
|
||||
editor: "var(--editor-font-size)",
|
||||
shrink: "0.8em",
|
||||
},
|
||||
boxShadow: {
|
||||
DEFAULT: "0 1px 3px 0 var(--shadow)",
|
||||
lg: "0 10px 15px -3px var(--shadow)",
|
||||
},
|
||||
colors: {
|
||||
transparent: "transparent",
|
||||
placeholder: "var(--textSubtlest)",
|
||||
shadow: "var(--shadow)",
|
||||
backdrop: "var(--backdrop)",
|
||||
selection: "var(--selection)",
|
||||
|
||||
// New theme values
|
||||
surface: "var(--surface)",
|
||||
"surface-highlight": "var(--surfaceHighlight)",
|
||||
"surface-active": "var(--surfaceActive)",
|
||||
text: "var(--text)",
|
||||
"text-subtle": "var(--textSubtle)",
|
||||
"text-subtlest": "var(--textSubtlest)",
|
||||
border: "var(--border)",
|
||||
"border-subtle": "var(--borderSubtle)",
|
||||
"border-focus": "var(--borderFocus)",
|
||||
primary: "var(--primary)",
|
||||
danger: "var(--danger)",
|
||||
secondary: "var(--secondary)",
|
||||
success: "var(--success)",
|
||||
info: "var(--info)",
|
||||
notice: "var(--notice)",
|
||||
warning: "var(--warning)",
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
require("@tailwindcss/container-queries"),
|
||||
// oxlint-disable-next-line unbound-method -- destructured from plugin API
|
||||
plugin(({ addVariant }) => {
|
||||
addVariant("hocus", ["&:hover", "&:focus-visible", "&.focus:focus"]);
|
||||
addVariant("focus-visible-or-class", ["&:focus-visible", "&.focus:focus"]);
|
||||
}),
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,124 @@
|
||||
@custom-variant dark (&:is([data-resolved-appearance="dark"] *));
|
||||
@custom-variant hocus (&:hover, &:focus-visible, &.focus:focus);
|
||||
@custom-variant focus-visible-or-class (&:focus-visible, &.focus:focus);
|
||||
|
||||
@theme inline {
|
||||
--font-mono:
|
||||
var(--font-family-editor), JetBrains Mono, ui-monospace, SFMono-Regular,
|
||||
Menlo, Monaco, Fira Code, Ubuntu Mono, Consolas, Liberation Mono,
|
||||
Courier New, DejaVu Sans Mono, Hack, monospace;
|
||||
--font-sans:
|
||||
var(--font-family-interface), Inter UI, -apple-system, BlinkMacSystemFont,
|
||||
Segoe UI, Roboto, Oxygen-Sans, Ubuntu, Cantarell, Helvetica Neue,
|
||||
sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol;
|
||||
--font-serif: initial;
|
||||
|
||||
--text-*: initial;
|
||||
--text-4xs: 0.6rem;
|
||||
--text-3xs: 0.675rem;
|
||||
--text-2xs: 0.75rem;
|
||||
--text-xs: 0.8rem;
|
||||
--text-sm: 0.9rem;
|
||||
--text-base: 1rem;
|
||||
--text-lg: 1.12rem;
|
||||
--text-xl: 1.25rem;
|
||||
--text-2xl: 1.5rem;
|
||||
--text-3xl: 2rem;
|
||||
--text-4xl: 2.5rem;
|
||||
--text-5xl: 3rem;
|
||||
--text-editor: var(--editor-font-size);
|
||||
--text-shrink: 0.8em;
|
||||
|
||||
--shadow-*: initial;
|
||||
--shadow: 0 1px 3px 0 var(--shadow);
|
||||
--shadow-lg: 0 10px 15px -3px var(--shadow);
|
||||
|
||||
--color-*: initial;
|
||||
--color-transparent: transparent;
|
||||
--color-placeholder: var(--textSubtlest);
|
||||
--color-shadow: var(--shadow);
|
||||
--color-backdrop: var(--backdrop);
|
||||
--color-selection: var(--selection);
|
||||
--color-surface: var(--surface);
|
||||
--color-surface-highlight: var(--surfaceHighlight);
|
||||
--color-surface-active: var(--surfaceActive);
|
||||
--color-text: var(--text);
|
||||
--color-text-subtle: var(--textSubtle);
|
||||
--color-text-subtlest: var(--textSubtlest);
|
||||
--color-border: var(--border);
|
||||
--color-border-subtle: var(--borderSubtle);
|
||||
--color-border-focus: var(--borderFocus);
|
||||
--color-primary: var(--primary);
|
||||
--color-danger: var(--danger);
|
||||
--color-secondary: var(--secondary);
|
||||
--color-success: var(--success);
|
||||
--color-info: var(--info);
|
||||
--color-notice: var(--notice);
|
||||
--color-warning: var(--warning);
|
||||
|
||||
--animate-blinkRing: blinkRing 150ms step-start 400ms infinite;
|
||||
|
||||
--opacity-disabled: 30%;
|
||||
|
||||
--height-2xs: 1.4rem;
|
||||
--height-xs: 1.8rem;
|
||||
--height-sm: 2rem;
|
||||
--height-md: 2.3rem;
|
||||
--height-lg: 2.6rem;
|
||||
|
||||
--width-2xs: 1.4rem;
|
||||
--width-xs: 1.8rem;
|
||||
--width-sm: 2rem;
|
||||
--width-md: 2.3rem;
|
||||
--width-lg: 2.6rem;
|
||||
|
||||
--min-height-2xs: 1.4rem;
|
||||
--min-height-xs: 1.8rem;
|
||||
--min-height-sm: 2rem;
|
||||
--min-height-md: 2.3rem;
|
||||
--min-height-lg: 2.6rem;
|
||||
|
||||
--min-width-2xs: 1.4rem;
|
||||
--min-width-xs: 1.8rem;
|
||||
--min-width-sm: 2rem;
|
||||
--min-width-md: 2.3rem;
|
||||
--min-width-lg: 2.6rem;
|
||||
|
||||
--leading-xs: calc(1.75rem - 2px);
|
||||
--leading-sm: calc(2rem - 2px);
|
||||
--leading-md: calc(2.5rem - 2px);
|
||||
|
||||
--transition-property-grid: grid;
|
||||
|
||||
@keyframes blinkRing {
|
||||
0%,
|
||||
49% {
|
||||
--tw-ring-color: var(--primary);
|
||||
}
|
||||
50%,
|
||||
99% {
|
||||
--tw-ring-color: transparent;
|
||||
}
|
||||
100% {
|
||||
--tw-ring-color: var(--primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
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);
|
||||
}
|
||||
}
|
||||
Vendored
-5
@@ -1,5 +0,0 @@
|
||||
import type { Config } from "tailwindcss";
|
||||
|
||||
declare const config: Config;
|
||||
|
||||
export = config;
|
||||
@@ -2,10 +2,5 @@
|
||||
"name": "@yaakapp-internal/tailwind-config",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"main": "index.cjs",
|
||||
"types": "index.d.ts",
|
||||
"dependencies": {
|
||||
"@tailwindcss/container-queries": "^0.1.1",
|
||||
"tailwindcss": "^3.4.17"
|
||||
}
|
||||
"style": "index.css"
|
||||
}
|
||||
|
||||
@@ -61,8 +61,8 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button
|
||||
"border",
|
||||
"max-w-full min-w-0",
|
||||
"hocus:opacity-100",
|
||||
"whitespace-nowrap outline-none",
|
||||
"flex-shrink-0 flex items-center",
|
||||
"whitespace-nowrap outline-hidden",
|
||||
"shrink-0 flex items-center",
|
||||
"outline-0",
|
||||
isDisabled ? "pointer-events-none opacity-disabled" : "pointer-events-auto",
|
||||
justify === "start" && "justify-start",
|
||||
@@ -70,7 +70,7 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button
|
||||
size === "md" && "h-md px-3 rounded-md",
|
||||
size === "sm" && "h-sm px-2.5 rounded-md",
|
||||
size === "xs" && "h-xs px-2 text-sm rounded-md",
|
||||
size === "2xs" && "h-2xs px-2 text-xs rounded",
|
||||
size === "2xs" && "h-2xs px-2 text-xs rounded-sm",
|
||||
size === "auto" && "px-3 py-2 rounded-md",
|
||||
variant === "solid" && "border-transparent",
|
||||
variant === "solid" &&
|
||||
|
||||
@@ -23,8 +23,8 @@ export const DropMarker = memo(
|
||||
<div
|
||||
className={classNames(
|
||||
"absolute bg-primary rounded-full",
|
||||
orientation === "horizontal" && "left-2 right-2 -bottom-[0.1rem] h-[0.2rem]",
|
||||
orientation === "vertical" && "-left-[0.1rem] top-0 bottom-0 w-[0.2rem]",
|
||||
orientation === "horizontal" && "left-2 right-2 bottom-[-0.1rem] h-[0.2rem]",
|
||||
orientation === "vertical" && "left-[-0.1rem] top-0 bottom-0 w-[0.2rem]",
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -12,8 +12,8 @@ export function FormattedError({ children, className }: Props) {
|
||||
className={classNames(
|
||||
className,
|
||||
"cursor-text select-auto",
|
||||
"[&_*]:cursor-text [&_*]:select-auto",
|
||||
"font-mono text-sm w-full bg-surface-highlight p-3 rounded",
|
||||
"**:cursor-text **:select-auto",
|
||||
"font-mono text-sm w-full bg-surface-highlight p-3 rounded-sm",
|
||||
"whitespace-pre-wrap border border-danger border-dashed overflow-x-auto",
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -67,7 +67,7 @@ export function HeaderSize({
|
||||
style={finalStyle}
|
||||
className={classNames(
|
||||
className,
|
||||
"pt-[1px]", // Make up for bottom border
|
||||
"pt-px", // Make up for bottom border
|
||||
"select-none relative flex items-center",
|
||||
"w-full border-b border-border-subtle min-w-0",
|
||||
)}
|
||||
|
||||
@@ -319,7 +319,7 @@ export const Icon = memo(function Icon({
|
||||
className,
|
||||
!spin && "transform-gpu",
|
||||
spin && "animate-spin",
|
||||
"flex-shrink-0",
|
||||
"shrink-0",
|
||||
size === "xl" && "h-6 w-6",
|
||||
size === "lg" && "h-5 w-5",
|
||||
size === "md" && "h-4 w-4",
|
||||
|
||||
@@ -60,8 +60,8 @@ export const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(functio
|
||||
type={type}
|
||||
className={classNames(
|
||||
className,
|
||||
"group/button relative flex-shrink-0",
|
||||
"!px-0",
|
||||
"group/button relative shrink-0",
|
||||
"px-0!",
|
||||
size === "md" && "w-md",
|
||||
size === "sm" && "w-sm",
|
||||
size === "xs" && "w-xs",
|
||||
@@ -85,7 +85,7 @@ export const IconButton = forwardRef<HTMLButtonElement, IconButtonProps>(functio
|
||||
className={classNames(
|
||||
iconClassName,
|
||||
"group-hover/button:text-text",
|
||||
confirmed && "!text-success",
|
||||
confirmed && "text-success!",
|
||||
props.disabled && "opacity-70",
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -6,8 +6,8 @@ export function InlineCode({ className, ...props }: HTMLAttributes<HTMLSpanEleme
|
||||
<code
|
||||
className={classNames(
|
||||
className,
|
||||
"font-mono text-shrink bg-surface-highlight border border-border-subtle flex-grow-0",
|
||||
"px-1.5 py-0.5 rounded text shadow-inner break-words",
|
||||
"font-mono text-shrink bg-surface-highlight border border-border-subtle grow-0",
|
||||
"px-1.5 py-0.5 rounded-sm text shadow-inner wrap-break-word",
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
|
||||
@@ -8,7 +8,7 @@ interface Props {
|
||||
export function LoadingIcon({ size = "md", className }: Props) {
|
||||
const classes = classNames(
|
||||
className,
|
||||
"text-inherit flex-shrink-0",
|
||||
"text-inherit shrink-0",
|
||||
size === "xl" && "h-6 w-6",
|
||||
size === "lg" && "h-5 w-5",
|
||||
size === "md" && "h-4 w-4",
|
||||
|
||||
@@ -72,7 +72,7 @@ export function Overlay({
|
||||
onClick={onClose}
|
||||
className={classNames(
|
||||
"absolute inset-0",
|
||||
variant === "default" && "bg-backdrop backdrop-blur-sm",
|
||||
variant === "default" && "bg-backdrop backdrop-blur-xs",
|
||||
)}
|
||||
/>
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ export function ResizeHandle({
|
||||
{isResizing && (
|
||||
<div
|
||||
className={classNames(
|
||||
"fixed -left-[100vw] -right-[100vw] -top-[100vh] -bottom-[100vh]",
|
||||
"fixed left-[-100vw] right-[-100vw] top-[-100vh] bottom-[-100vh]",
|
||||
vertical && "cursor-row-resize",
|
||||
!vertical && "cursor-col-resize",
|
||||
)}
|
||||
|
||||
@@ -130,7 +130,7 @@ export function SidebarLayout({
|
||||
</div>
|
||||
<ResizeHandle
|
||||
style={drag}
|
||||
className="-translate-x-[1px]"
|
||||
className="-translate-x-px"
|
||||
justify="end"
|
||||
side="right"
|
||||
onResizeStart={handleResizeStart}
|
||||
|
||||
@@ -87,7 +87,7 @@ export function TableCell({
|
||||
<td
|
||||
className={classNames(
|
||||
className,
|
||||
"py-2 [&:not(:first-child)]:pl-4 whitespace-nowrap",
|
||||
"py-2 not-first:pl-4 whitespace-nowrap",
|
||||
align === "left" ? "text-left" : align === "center" ? "text-center" : "text-right",
|
||||
)}
|
||||
>
|
||||
@@ -119,7 +119,7 @@ export function TableHeaderCell({
|
||||
<th
|
||||
className={classNames(
|
||||
className,
|
||||
"whitespace-nowrap py-2 [&:not(:first-child)]:pl-4 text-left text-text-subtle",
|
||||
"whitespace-nowrap py-2 not-first:pl-4 text-left text-text-subtle",
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
|
||||
@@ -38,7 +38,7 @@ export function WindowControls({
|
||||
{!onlyX && (
|
||||
<>
|
||||
<Button
|
||||
className="!h-full px-4 text-text-subtle hocus:text hocus:bg-surface-highlight rounded-none"
|
||||
className="h-full! px-4 text-text-subtle hocus:text hocus:bg-surface-highlight rounded-none"
|
||||
color="custom"
|
||||
onClick={() => getCurrentWebviewWindow().minimize()}
|
||||
>
|
||||
@@ -48,7 +48,7 @@ export function WindowControls({
|
||||
</svg>
|
||||
</Button>
|
||||
<Button
|
||||
className="!h-full px-4 text-text-subtle hocus:text hocus:bg-surface-highlight rounded-none"
|
||||
className="h-full! px-4 text-text-subtle hocus:text hocus:bg-surface-highlight rounded-none"
|
||||
color="custom"
|
||||
onClick={async () => {
|
||||
const w = getCurrentWebviewWindow();
|
||||
@@ -81,7 +81,7 @@ export function WindowControls({
|
||||
)}
|
||||
<Button
|
||||
color="custom"
|
||||
className="!h-full px-4 text-text-subtle rounded-none hocus:bg-danger hocus:text-text"
|
||||
className="h-full! px-4 text-text-subtle rounded-none hocus:bg-danger hocus:text-text"
|
||||
onClick={() => getCurrentWebviewWindow().close()}
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
|
||||
@@ -662,7 +662,7 @@ function TreeInner<T extends { id: string }>(
|
||||
ref={treeRef}
|
||||
className={classNames(
|
||||
className,
|
||||
"outline-none h-full",
|
||||
"outline-hidden h-full",
|
||||
"overflow-y-auto overflow-x-hidden",
|
||||
"grid grid-rows-[auto_1fr]",
|
||||
)}
|
||||
@@ -670,8 +670,8 @@ function TreeInner<T extends { id: string }>(
|
||||
<div
|
||||
className={classNames(
|
||||
"[&_.tree-item.selected_.tree-item-inner]:text-text",
|
||||
"[&:focus-within]:[&_.tree-item.selected]:bg-surface-active",
|
||||
"[&:not(:focus-within)]:[&_.tree-item.selected:not([data-context-menu-open])]:bg-surface-highlight",
|
||||
"focus-within:[&_.tree-item.selected]:bg-surface-active",
|
||||
"not-focus-within:[&_.tree-item.selected:not([data-context-menu-open])]:bg-surface-highlight",
|
||||
"[&_.tree-item.selected[data-context-menu-open]]:bg-surface-active",
|
||||
// Round the items, but only if the ends of the selection.
|
||||
// Also account for the drop marker being in between items
|
||||
|
||||
@@ -326,7 +326,7 @@ function TreeItem_<T extends { id: string }>({
|
||||
<button
|
||||
type="button"
|
||||
tabIndex={-1}
|
||||
className="h-full pl-[0.5rem] outline-none"
|
||||
className="h-full pl-2 outline-hidden"
|
||||
onClick={toggleCollapsed}
|
||||
>
|
||||
<Icon
|
||||
@@ -334,7 +334,7 @@ function TreeItem_<T extends { id: string }>({
|
||||
className={classNames(
|
||||
"transition-transform text-text-subtlest",
|
||||
"ml-auto",
|
||||
"w-[1rem] h-[1rem]",
|
||||
"w-4 h-4",
|
||||
!isCollapsed && node.children.length > 0 && "rotate-90",
|
||||
)}
|
||||
/>
|
||||
@@ -349,7 +349,7 @@ function TreeItem_<T extends { id: string }>({
|
||||
onClick={handleClick}
|
||||
onDoubleClick={handleDoubleClick}
|
||||
disabled={editing}
|
||||
className="cursor-default tree-item-inner pr-1 focus:outline-none flex items-center gap-2 h-full whitespace-nowrap"
|
||||
className="cursor-default tree-item-inner pr-1 focus:outline-hidden flex items-center gap-2 h-full whitespace-nowrap"
|
||||
{...attributes}
|
||||
{...listeners}
|
||||
tabIndex={isLastSelected ? 0 : -1}
|
||||
@@ -366,7 +366,7 @@ function TreeItem_<T extends { id: string }>({
|
||||
placeholder={placeholder}
|
||||
autoCapitalize="off"
|
||||
autoCorrect="off"
|
||||
className="bg-transparent outline-none w-full cursor-text"
|
||||
className="bg-transparent outline-hidden w-full cursor-text"
|
||||
onBlur={handleEditBlur}
|
||||
onKeyDown={handleEditKeyDown}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user