refactor: приведение проекта к стайлгайду

- Разделён globals.css на styles/variables.css, media.css, reset.css
- Добавлен styles/index.css как единая точка входа глобальных стилей
- Вынесен MantineProvider в app/providers/
- Переименован .ui.tsx в .tsx в шаблоне component
- Приведены CSS-токены радиусов к числовой шкале (--radius-1, --radius-2...)
- Добавлен слой src/layouts/
- Настроен Biome: одинарные кавычки, исключены .templates, разрешён @custom-media
- Обновлён .vscode/settings.json (quickfix.biome → source.fixAll.biome)
- Обновлён AGENTS.md с правилами для агентов
This commit is contained in:
2026-03-29 13:23:00 +03:00
parent 8a8ecba397
commit 9e2167b34d
23 changed files with 208 additions and 107 deletions

View File

@@ -1 +1 @@
export { {{name.pascalCase}} } from './{{name.kebabCase}}.ui'
export { {name.pascalCase} } from './{{name.kebabCase}}'

View File

@@ -2,8 +2,7 @@
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"quickfix.biome": "explicit",
"source.organizeImports.biome": "explicit"
"source.fixAll.biome": "explicit"
},
"files.associations": {
"*.css": "postcss"

View File

@@ -1,5 +1,83 @@
<!-- BEGIN:nextjs-agent-rules -->
# This is NOT the Next.js you know
# Правила работы с проектом
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.
<!-- END:nextjs-agent-rules -->
## Стайлгайд
Проект строго придерживается стайлгайда. Перед любой работой с кодом — прочитай полную документацию:
https://gromlab.ru/docs/nextjs-style-guide/raw/branch/main/generated/ru/RULES.md
Все решения по архитектуре, именованию, стилям, компонентам и структуре принимаются на основе этого документа. Отклонения от стайлгайда недопустимы без явного согласования.
## Язык общения
- Всегда использовать русский язык: размышления, пояснения, подсказки, инструкции — всё формулировать по-русски.
- Не переключаться на английский без прямого запроса пользователя.
## Коммиты
- НЕ добавлять подпись
- Писать сообщения коммитов на русском языке
### Формат
```
<тип>: <краткое описание>
- Детали в прошедшем времени
- Каждый пункт — отдельное изменение
```
### Типы коммитов
| Тип | Назначение |
|---|---|
| `feat` | Новая функциональность |
| `fix` | Исправление бага |
| `refactor` | Рефакторинг без изменения поведения |
| `style` | Стили, форматирование, отступы |
| `docs` | Документация |
| `chore` | Настройка, зависимости, CI |
| `test` | Тесты |
| `perf` | Оптимизация производительности |
### Правила
- Первая строка — не длиннее 72 символов
- Описание — с маленькой буквы (если не имя собственное)
- Пункты — в прошедшем времени
- Scope (область) опционален: `feat(auth): ...`, `fix(ui): ...`
### Примеры
```
feat: автодополнение и режимы запуска
- Добавлены служебные команды и генерация completion для bash/zsh/fish
- Введён детект режимов запуска (npx/local/direct/global)
- Обновлены help и документация
```
```
fix: некорректная ширина sidebar на мобильных
- Исправлен медиа-запрос для breakpoint --sm
- Убран фиксированный width в пользу max-width
```
```
chore: настройка Biome и VS Code
- Добавлены одинарные кавычки в конфигурацию Biome
- Исключена папка .templates из проверок
- Обновлён quickfix.biome на source.fixAll.biome
```
## Генерация кода
- Модули (компоненты, фичи, виджеты, сущности, layouts, screens, сторы) создаются только из шаблонов `.templates/`.
- Ручное создание файловой структуры модулей запрещено.
- Генерация: `npx @gromlab/create <шаблон> <имя> <путь>`
## Next.js
This is NOT the Next.js you know. This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` before writing any code. Heed deprecation notices.

View File

@@ -7,17 +7,33 @@
},
"files": {
"ignoreUnknown": true,
"includes": ["**", "!node_modules", "!.next", "!dist", "!build"]
"includes": [
"**",
"!node_modules",
"!.next",
"!dist",
"!build",
"!.templates"
]
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2
},
"javascript": {
"formatter": {
"quoteStyle": "single",
"jsxQuoteStyle": "double"
}
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
"recommended": true,
"suspicious": {
"noUnknownAtRules": "off"
}
},
"domains": {
"next": "recommended",

View File

@@ -1,4 +1,4 @@
import type { NextConfig } from "next";
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
/* config options here */

View File

@@ -12,6 +12,6 @@ const config = {
},
},
},
}
};
export default config
export default config;

View File

@@ -1,71 +0,0 @@
/* Цвета */
:root {
--color-text: #1a1a1a;
--color-text-secondary: #6b7280;
--color-bg: #ffffff;
--color-bg-secondary: #f9fafb;
--color-border: #e5e7eb;
--color-primary: #228be6;
--color-error: #fa5252;
--color-success: #40c057;
--color-warning: #fab005;
}
/* Отступы */
:root {
--space-1: 4px;
--space-2: 8px;
--space-3: 12px;
--space-4: 16px;
--space-5: 20px;
--space-6: 24px;
--space-8: 32px;
--space-10: 40px;
--space-12: 48px;
--space-16: 64px;
}
/* Скругления */
:root {
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-xl: 16px;
--radius-full: 9999px;
}
/* Медиа-запросы (Mobile First) */
@custom-media --xs (min-width: 36em);
@custom-media --sm (min-width: 48em);
@custom-media --md (min-width: 62em);
@custom-media --lg (min-width: 75em);
@custom-media --xl (min-width: 88em);
/* Базовые стили */
html {
height: 100%;
}
html,
body {
max-width: 100vw;
overflow-x: hidden;
}
body {
min-height: 100%;
display: flex;
flex-direction: column;
color: var(--color-text);
background: var(--color-bg);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}

View File

@@ -1,8 +1,9 @@
import type { PropsWithChildren } from 'react'
import type { Metadata } from 'next'
import { ColorSchemeScript, MantineProvider } from '@mantine/core'
import '@mantine/core/styles.css'
import './globals.css'
import { ColorSchemeScript } from '@mantine/core';
import type { Metadata } from 'next';
import type { PropsWithChildren } from 'react';
import { MantineProvider } from './providers';
import '@mantine/core/styles.css';
import './styles/index.css';
export const metadata: Metadata = {
title: {
@@ -27,7 +28,7 @@ export const metadata: Metadata = {
twitter: {
card: 'summary_large_image',
},
}
};
export default function RootLayout({ children }: PropsWithChildren) {
return (
@@ -39,5 +40,5 @@ export default function RootLayout({ children }: PropsWithChildren) {
<MantineProvider>{children}</MantineProvider>
</body>
</html>
)
);
}

View File

@@ -1,11 +1,11 @@
import type { Metadata } from 'next'
import { HomeScreen } from '@/screens/home'
import type { Metadata } from 'next';
import { HomeScreen } from '@/screens/home';
export const metadata: Metadata = {
title: 'Главная',
description: 'Главная страница приложения',
}
};
export default function HomePage() {
return <HomeScreen />
return <HomeScreen />;
}

View File

@@ -0,0 +1 @@
export { MantineProvider } from './mantine-provider';

View File

@@ -0,0 +1,11 @@
'use client';
import { MantineProvider as BaseMantineProvider } from '@mantine/core';
import type { PropsWithChildren } from 'react';
/**
* Провайдер Mantine UI.
*/
export const MantineProvider = ({ children }: PropsWithChildren) => {
return <BaseMantineProvider>{children}</BaseMantineProvider>;
};

3
src/app/styles/index.css Normal file
View File

@@ -0,0 +1,3 @@
@import "./variables.css";
@import "./media.css";
@import "./reset.css";

6
src/app/styles/media.css Normal file
View File

@@ -0,0 +1,6 @@
/* Медиа-запросы (Mobile First) */
@custom-media --xs (min-width: 36em);
@custom-media --sm (min-width: 48em);
@custom-media --md (min-width: 62em);
@custom-media --lg (min-width: 75em);
@custom-media --xl (min-width: 88em);

28
src/app/styles/reset.css Normal file
View File

@@ -0,0 +1,28 @@
/* Базовые стили */
html {
height: 100%;
}
html,
body {
max-width: 100vw;
overflow-x: hidden;
}
body {
min-height: 100%;
display: flex;
flex-direction: column;
color: var(--color-text);
background: var(--color-bg);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}

View File

@@ -0,0 +1,35 @@
/* Цвета */
:root {
--color-text: #1a1a1a;
--color-text-secondary: #6b7280;
--color-bg: #ffffff;
--color-bg-secondary: #f9fafb;
--color-border: #e5e7eb;
--color-primary: #228be6;
--color-error: #fa5252;
--color-success: #40c057;
--color-warning: #fab005;
}
/* Отступы */
:root {
--space-1: 4px;
--space-2: 8px;
--space-3: 12px;
--space-4: 16px;
--space-5: 20px;
--space-6: 24px;
--space-8: 32px;
--space-10: 40px;
--space-12: 48px;
--space-16: 64px;
}
/* Скругления */
:root {
--radius-1: 4px;
--radius-2: 8px;
--radius-3: 12px;
--radius-4: 16px;
--radius-full: 9999px;
}

0
src/layouts/.gitkeep Normal file
View File

View File

@@ -1,6 +1,6 @@
import type { FC } from 'react'
import { Container, Title, Text, Image, Stack } from '@mantine/core'
import styles from './styles/home.module.css'
import { Container, Image, Stack, Text, Title } from '@mantine/core';
import type { FC } from 'react';
import styles from './styles/home.module.css';
/**
* Главный экран приложения.
@@ -18,11 +18,9 @@ export const HomeScreen: FC = () => {
fit="contain"
/>
<Title order={1}>Добро пожаловать</Title>
<Text c="dimmed">
Шаблон приложения на Next.js и TypeScript.
</Text>
<Text c="dimmed">Шаблон приложения на Next.js и TypeScript.</Text>
</Stack>
</Container>
</div>
)
}
);
};

View File

@@ -1 +1 @@
export { HomeScreen } from './home.screen'
export { HomeScreen } from './home.screen';