Zimin A.N.
787cea9db1
fix(table+layout): TableHead alias to THEAD wrapper + kill horizontal scroll
...
CRITICAL bugs reported by user — table выглядела кривой, контент уезжал
за экран с горизонтальным скроллом.
Bug 1 — invalid HTML в Table:
Callsites используют <TableHead><TableRow><TableHeaderCell>... ожидая
нstart-style THEAD wrapper. Но мой alias делал TableHead = TableHeaderCell
(TH cell). Получалось <th><tr><th>...</th></tr></th> — invalid nested,
browser parser hoist'ил TableRow наружу, создавая phantom 509px column
слева от данных. Колонки выглядели misaligned, content смещён вправо.
Fix: TableHead → THEAD wrapper (alias TableHeader). TableHeaderCell
остаётся отдельным TH cell. Source semantically correct, browser parses
валидно, phantom column исчез.
Bug 2 — horizontal overflow:
Scope strip border на верху detail-страницы использовал
'-mt-6 -mx-4 sm:-mx-6 lg:-mx-8'. На lg viewport main padding только
sm:px-6 (24px), strip negative margins -mx-8 (32px) → 8px overflow each
side → body.scrollWidth > viewport → horizontal scrollbar.
Fix:
- Strip negative margins только до -mx-6 (соответствует main padding)
- main получил overflow-x-clip + max-w-7xl wrapper получил min-w-0
(защита от любых future overflow children)
Verified в preview viewport 1440 + 375: body.scrollWidth === viewport,
no h-scroll.
2026-05-11 15:49:27 +03:00
Zimin A.N.
7a3b31b957
feat(mobile): Sidebar drawer <1024px + Modal/Sheet fullscreen <880px
...
Per design_handoff_ordinis_mdm/README.md responsive table (line 464-465):
- ≤1024px: Sidebar becomes overlay drawer (hamburger в TopBar)
- ≤880px: Drawers и modals fullscreen (100vw × 100dvh, no border-radius)
Implementation:
src/components/layout/Sidebar.tsx
- Extracted SidebarContent (logo + nav + user block) для DRY
- Desktop <Sidebar /> wraps SidebarContent в hidden lg:flex aside
- New <MobileSidebar open onClose /> — Sheet с тем же содержимым,
260px wide, slides from left
- SidebarLink принимает onClick → drawer auto-close при navigate
src/components/layout/TopBar.tsx
- Optional onMenuClick prop — рендерит hamburger button (Menu icon
из lucide-react) с lg:hidden
- VersionBadge скрыт <md (768px) — diagnostic info, не critical UX
src/routes/__root.tsx
- useState mobileNavOpen, передаём в MobileSidebar + TopBar
src/ui/components/dialog.tsx
- SIZE_CLASSES получили prefix (arbitrary Tailwind v4
breakpoint per handoff exact 880px). На mobile <880px modal становится
fullscreen (inset-0 w-full h-full no rounded), ≥880px — centered с
translate + max-w из SIZE_CLASSES.
src/ui/components/sheet.tsx
- size variants: sm:max-w-* → min-[880px]:max-w-*. На mobile <880px
sheet берёт w-full (fullscreen drawer per handoff).
src/components/record/RecordDrawer.tsx
- max-width переключатель 520/880 теперь применяется только ≥880px.
На mobile drawer всегда fullscreen.
src/ui/components/language-switch.tsx
- Display fallback: opt.short → opt.label → uppercase id.
Previously показывал id ('ru-RU', 'en-US') когда short не был задан —
теперь использует label ('RU', 'EN') как fallback.
Browser-verified в preview viewport 375×812:
- Hamburger ☰ visible, click открывает Sheet с nav items
- Backdrop fade + slide-from-left animation
- TopBar fits в 375px (RU/EN compact, Sign in visible)
- LoadingBlock + Alert text-wrap correctly
2026-05-11 15:39:23 +03:00
Zimin A.N.
5007e0f4eb
feat(ui): drop @nstart/ui dependency (Stage 3.9)
...
Все font cascade bugs из последних MR были вызваны @nstart/ui pollution
(Tektur inheritance от Card parent'ов, Onest font в Button, font-primary
class overrides). Решили обрезать раньше plan'а.
What changed:
New primitives (8 файлов в src/ui/components/):
- panel.tsx — container с border/surface
- field.tsx — FieldLabel/Hint/Error typography helpers
- text-input.tsx — Input + label/hint/error composite
- table.tsx — Table/TableHeader/Body/Row/HeaderCell/Cell/Empty
- date-picker.tsx — native <input type=date> wrapper с label/hint/error
- multi-select.tsx — Radix Popover + inline checkboxes
- single-select.tsx — native <select> с label/hint/error chrome
- language-switch.tsx — segmented control в Tektur uppercase
Compatibility shims (existing components extended):
- checkbox.tsx — + label/description/error/onChange (nstart-compat
synthetic event), wrap в <label> когда есть chrome
- modal.tsx — + panelClassName / bodyClassName props
- form-actions.tsx — + align prop (start/end/between)
- tabs-simple.tsx — TabItem.count alias for .trailing (nstart-compat)
- table TableHead — alias TableHeaderCell с align prop
Barrel rewrite (src/ui/index.ts):
- Удалён 'export * from @nstart/ui'
- Explicit exports для всех 45+ нужных символов
- SelectOption / MultiSelectOption / LanguageOption теперь {id, label}
с optional 'value' alias — nstart-compat без массового codemod call-sites
styles.css cleanup:
- Removed @import @nstart/ui/styles/{fonts,theme}.css
- Removed @source nstart/dist directive (Tailwind v4 scan)
- Removed --text-sm: 13px override (был костыль для @nstart/ui dist)
- Legacy color tokens (--color-carbon/ultramarain/orbit/regolith/asteroid)
sсодержали fallback mappings — оставлены, но callsites больше не используют
Codemod: 9 файлов конвертированы legacy colors → handoff tokens
carbon → ink, ultramarain → accent, orbit → warn, regolith → line, asteroid → mute
main.tsx:
- NStartUiProvider → TooltipProvider (Radix)
- DatePickerProvider убран (наш DatePicker native, no provider needed)
routes/dictionaries.$name.tsx:
- Removed useRef-based <input>.indeterminate hack
- Radix Checkbox принимает checked='indeterminate' declaratively
package.json: -@nstart/ui (was 0.1.3)
Bundle impact:
before: vendor-nstart-ui chunk = 1228 KB
after: no nstart chunk, всё в vendor-misc (+~70 KB Radix wrappers)
net savings: ~1.15 MB minified, ~440 KB gzip
Tests: 116 pass (1 fixed: tab role from 'button' → 'tab', Radix semantically correct).
TS strict: clean.
Browser-verified (preview): 7 utilities computed correctly, nstart bundle absent.
2026-05-11 15:17:37 +03:00
Zimin A.N.
b94912789f
fix(fonts): semantic typography utilities per handoff (7 roles)
...
Заменяет blanket override из MR !45 на типизированную type scale per
design_handoff_ordinis_mdm/README.md "Scale" section.
Семь semantic @utility в styles.css:
text-title-xl 22/600 — modal title, section header
text-title-lg 17/600 — page title в editor
text-title-md 15/600 — dictionary card title
text-body 13/400 — workhorse: body, buttons, tabs, inputs
text-cell 12.5/500 — table cell text
text-mono 11/500 — Mono: IDs, dates, FK refs (font-mono baked in)
text-cap 10.5/600 — Tektur UPPERCASE caption (font/uppercase baked in)
Audit phases:
P1: добавил 7 утилит, font/uppercase/tracking baked где надо
P2: 43 deterministic codemods (font-mono+text-2xs/[11px] → text-mono,
[15/17/22]px+font-semibold → text-title-*, [12.5]px → text-cell,
[10.5]px+uppercase+tracking → text-cap)
P3: 64 text-sm → text-body (handoff workhorse), 84 text-2xs context-aware
(TableCell → text-cell, bare → text-cell, плюс cleanup caps в backticks
template literals который Phase 2 пропустил), 25 text-xs (6 → text-mono
когда с font-mono, 19 → text-cell), 8 titles text-base/lg → text-title-*
P4: убрал --text-2xs override (no users), оставил --text-sm: 13px scoped
к @nstart/ui passthrough (см. comment в styles.css — убирается в Stage 3.9)
Stats:
text-body: 69 | text-cell: 99 | text-mono: 50 | text-cap: 42
text-title-xl: 5 | text-title-lg: 5 | text-title-md: 7
text-sm/text-2xs/text-xs в src/: 0 (только в styles.css комментариях)
Поведение всех 277 typography usages теперь явно соответствует handoff —
каждое место осознанно выбрано под роль, не плажирующий override.
2026-05-11 14:31:35 +03:00
Zimin A.N.
71432e9ae7
fix(fonts): align all text sizes to handoff spec via Tailwind theme overrides
...
Глобальные правки через @theme в styles.css вместо 200+ точечных правок:
- text-sm: 14px -> 13px (handoff workhorse — body, buttons, tabs)
- text-2xs: undefined -> 11px (handoff IDs, mono meta — было невидимо)
- @utility text-cap: 10.5px Tektur uppercase 0.10em (handoff caps)
Codemod (30 sites): text-2xs + uppercase + tracking-[0.10em] -> text-cap.
Sidebar section labels consolidated с explicit text-[10.5px] на text-cap.
Покрывает 64 text-sm + 148 text-2xs автоматически. Table cells (12.5px)
и page/modal titles (17px/22px) остаются explicit text-[Npx] arbitrary
values по месту — нет slots в Tailwind scale.
2026-05-11 14:12:57 +03:00
Александр Зимин
649b7c4244
feat(admin-ui): shadcn TextArea (Stage 3.8a)
2026-05-11 09:13:10 +00:00
Александр Зимин
e2f1c3527b
feat(admin-ui): sonner Toast + TimeTravel polish (Stage 3.6+3.7)
2026-05-11 09:11:21 +00:00
Александр Зимин
b7d2fbd7ce
feat(admin-ui): codemod @nstart/ui → @/ui (Stage 2.2)
2026-05-10 22:17:06 +00:00
Александр Зимин
5d12c89c4f
feat(admin-ui): shadcn primitives + @/ui barrel (Stage 2.1)
2026-05-10 21:47:24 +00:00