refactor(frontend): normalize vertical rhythm scale
This commit is contained in:
parent
318016aee7
commit
c96b9453a5
@ -11,6 +11,23 @@
|
||||
|
||||
Эта шкала обязательна для новых экранов и перерабатываемых блоков.
|
||||
|
||||
## Целевая шкала вертикального ритма
|
||||
|
||||
Радиусы сами по себе не делают систему согласованной. Если блоки одного веса выглядят похоже, у них должен быть одинаковый spacing.
|
||||
|
||||
Нормативная шкала:
|
||||
|
||||
- `gap-2` для compact control clusters и плотных inline actions
|
||||
- `space-y-2` для плотного стека внутри одного secondary/detail block
|
||||
- `space-y-3` для стека однотипных rows или peer secondary cards внутри одной primary panel
|
||||
- `space-y-4` для стека крупных grouped blocks или major subsections внутри одной primary panel
|
||||
- `space-y-6` для page-level section stack
|
||||
|
||||
Правило:
|
||||
|
||||
- spacing выбирается по весу блока и уровню иерархии, а не по конкретному экрану
|
||||
- одинаковые `app-surface-muted rounded-xl` блоки не должны жить на `space-y-2` в одной зоне и на `space-y-4` в другой без явной UX-причины
|
||||
|
||||
## Controls
|
||||
|
||||
К controls относятся:
|
||||
|
||||
@ -171,7 +171,7 @@ export default function EmployeesPage() {
|
||||
return (
|
||||
<AppShell>
|
||||
<section className="app-surface rounded-2xl p-4">
|
||||
<div className="space-y-2">
|
||||
<div className="space-y-3">
|
||||
{sortedEmployees.map((employee) => {
|
||||
const fullName =
|
||||
`${employee.last_name || ""} ${employee.first_name || ""} ${employee.patronymic || ""}`.trim();
|
||||
|
||||
@ -6,7 +6,7 @@ import { useUser } from "@/contexts/UserContext";
|
||||
import Link from "next/link";
|
||||
import { usePathname, useRouter, useSearchParams } from "next/navigation";
|
||||
import { Suspense, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import { Archive, ArrowRightLeft, ArrowUpDown, Check, ChevronDown, ChevronRight, Copy, Download, ExternalLink, Filter, MessageSquare, Monitor, Pencil, Plus, QrCode, Search, Shield, Trash2, Wrench, X } from "lucide-react";
|
||||
import { Archive, ArrowRightLeft, ArrowUpDown, Check, ChevronDown, ChevronRight, Copy, Download, ExternalLink, Filter, MessageSquare, Monitor, Pencil, Plus, QrCode, Search, Shield, Trash2, Wrench } from "lucide-react";
|
||||
import { SearchableSelectSingle } from "@/components/shared/SearchableSelect";
|
||||
import { formatDate, formatMoney } from "@/lib/shared";
|
||||
import { useEquipmentPage } from "@/hooks/useEquipmentPage";
|
||||
@ -549,7 +549,7 @@ function EquipmentPageContent() {
|
||||
|
||||
{/* Filters panel */}
|
||||
{filtersOpen && (
|
||||
<div className="app-surface-muted mb-3 flex flex-col gap-2 rounded-xl p-3">
|
||||
<div className="app-surface-muted mb-4 flex flex-col gap-2 rounded-xl p-3">
|
||||
<div className="grid grid-cols-1 gap-2 sm:grid-cols-2 lg:grid-cols-4">
|
||||
<select value={statusFilter} onChange={(e) => setStatusFilter(e.target.value)} className="app-select rounded-lg px-3 py-2 text-sm">
|
||||
<option value="">Все статусы</option>
|
||||
@ -591,7 +591,7 @@ function EquipmentPageContent() {
|
||||
)}
|
||||
|
||||
{/* Items list */}
|
||||
<div className="space-y-2">
|
||||
<div className="space-y-3">
|
||||
{filteredItems.length === 0 ? (
|
||||
<div className="app-surface-muted rounded-xl p-8 text-center">
|
||||
<Monitor size={22} className="app-text-muted mx-auto mb-2" />
|
||||
|
||||
@ -130,7 +130,7 @@ export function RequestListControls({
|
||||
</div>
|
||||
|
||||
{state.filtersOpen ? (
|
||||
<div className="app-surface-muted mb-3 flex flex-col gap-2 rounded-xl p-3">
|
||||
<div className="app-surface-muted mb-4 flex flex-col gap-2 rounded-xl p-3">
|
||||
<select
|
||||
value={state.view}
|
||||
onChange={(event) => actions.setView(event.target.value as "" | "mine" | "addressed")}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user