- recharts: все hex/hsl палитры → var(--chart-1..5), семантика → var(--info/success/warning/destructive) - палитровые Tailwind-классы (red/blue/green/amber и т.д.) → семантические классы через color-mix (Tailwind v3 не генерирует alpha для var-цветов) - ui/table.tsx: шапка по гайду (bg-muted/50, text-[12px]), строки h-[var(--table-row-height,40px)], ячейки px-3, hover muted 40% - lib/field-styles.ts (порт из основного клиента) + fieldControlClass в column-filter - app-sidebar: брендинг «ОмегаПром / Финансы», компактные отступы - bottom-nav.tsx: мобильная нижняя панель (Обзор/Разделы/Настройки) по референсу FinanceBottomNav, safe-area-bottom в index.css - переключатель темы Sun/Moon в хедере (useDi2Theme), SidebarTrigger скрыт на мобильном - заголовки страниц text-lg font-semibold
35 lines
2.8 KiB
TypeScript
35 lines
2.8 KiB
TypeScript
import { cn } from '@/lib/utils';
|
||
|
||
// Единый стиль контрола поля (референс NocoBase/antd): один визуал во всех контекстах
|
||
// size: form — форма создания, detail — карточка задачи, cell — ячейка таблицы
|
||
// Тема 2.0: высоты/паддинги/фон/бордер/радиус читаются из CSS-переменных скина
|
||
// (--control-height-*, --control-px, --control-bg, --control-border-*, --control-radius);
|
||
// fallback'и в var() повторяют прежний вид, поэтому без Темы 2.0 ничего не меняется.
|
||
export type FieldControlSize = 'form' | 'detail' | 'cell';
|
||
|
||
// Базовые классы контрола: рамка, фон, типографика и состояния hover/focus.
|
||
// border-width/цвет/фон/радиус — через var-ы Темы 2.0 (outline — дефолт);
|
||
// в ячейке (cell) они перекрываются border-0/bg-transparent через twMerge.
|
||
const FIELD_CONTROL_BASE =
|
||
'rounded-[var(--control-radius,calc(var(--radius)_-_2px))] border-[length:var(--control-border-width,1px)] border-[color:var(--control-border-color,var(--input))] bg-[color:var(--control-bg,var(--background))] px-[var(--control-px,10px)] text-base md:text-[13px] transition-[color,background-color,border-color,box-shadow] hover:border-[color-mix(in_oklab,var(--primary)_50%,transparent)] focus:outline-none focus:ring-2 focus:ring-[color-mix(in_oklab,var(--ring)_20%,transparent)] focus:border-primary';
|
||
|
||
// Классы по контексту использования
|
||
const FIELD_CONTROL_SIZE: Record<FieldControlSize, string> = {
|
||
form: 'h-[var(--control-height-form,32px)] w-full',
|
||
detail: 'h-[var(--control-height-detail,28px)] w-auto max-w-[420px]',
|
||
cell: 'h-[var(--control-height-cell,28px)] w-full border-0 bg-transparent shadow-none hover:border-transparent focus:ring-1',
|
||
};
|
||
|
||
// Единый класс контрола поля. Дополнительные классы передаются вторым аргументом.
|
||
export function fieldControlClass(size: FieldControlSize = 'form', className?: string): string {
|
||
return cn(FIELD_CONTROL_BASE, FIELD_CONTROL_SIZE[size], className);
|
||
}
|
||
|
||
// Единый стиль label поля формы (вертикальная раскладка, как в NocoBase/antd)
|
||
// Тема 2.0: регистр и жирность — через --label-casing / --label-weight
|
||
export const fieldLabelClass =
|
||
'text-[13px] [font-weight:var(--label-weight,500)] [text-transform:var(--label-casing,none)] text-muted-foreground';
|
||
|
||
// Единый стиль сообщения об ошибке под полем
|
||
export const fieldErrorClass = 'text-xs text-destructive';
|