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:
@@ -1 +1 @@
|
|||||||
export { {{name.pascalCase}} } from './{{name.kebabCase}}.ui'
|
export { {name.pascalCase} } from './{{name.kebabCase}}'
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
.root {
|
.root {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
.root {
|
.root {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
.root {
|
.root {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
.root {
|
.root {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@@ -2,8 +2,7 @@
|
|||||||
"editor.defaultFormatter": "biomejs.biome",
|
"editor.defaultFormatter": "biomejs.biome",
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
"quickfix.biome": "explicit",
|
"source.fixAll.biome": "explicit"
|
||||||
"source.organizeImports.biome": "explicit"
|
|
||||||
},
|
},
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"*.css": "postcss"
|
"*.css": "postcss"
|
||||||
|
|||||||
86
AGENTS.md
86
AGENTS.md
@@ -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.
|
||||||
|
|||||||
20
biome.json
20
biome.json
@@ -7,17 +7,33 @@
|
|||||||
},
|
},
|
||||||
"files": {
|
"files": {
|
||||||
"ignoreUnknown": true,
|
"ignoreUnknown": true,
|
||||||
"includes": ["**", "!node_modules", "!.next", "!dist", "!build"]
|
"includes": [
|
||||||
|
"**",
|
||||||
|
"!node_modules",
|
||||||
|
"!.next",
|
||||||
|
"!dist",
|
||||||
|
"!build",
|
||||||
|
"!.templates"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"formatter": {
|
"formatter": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"indentStyle": "space",
|
"indentStyle": "space",
|
||||||
"indentWidth": 2
|
"indentWidth": 2
|
||||||
},
|
},
|
||||||
|
"javascript": {
|
||||||
|
"formatter": {
|
||||||
|
"quoteStyle": "single",
|
||||||
|
"jsxQuoteStyle": "double"
|
||||||
|
}
|
||||||
|
},
|
||||||
"linter": {
|
"linter": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"rules": {
|
"rules": {
|
||||||
"recommended": true
|
"recommended": true,
|
||||||
|
"suspicious": {
|
||||||
|
"noUnknownAtRules": "off"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"domains": {
|
"domains": {
|
||||||
"next": "recommended",
|
"next": "recommended",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { NextConfig } from "next";
|
import type { NextConfig } from 'next';
|
||||||
|
|
||||||
const nextConfig: NextConfig = {
|
const nextConfig: NextConfig = {
|
||||||
/* config options here */
|
/* config options here */
|
||||||
|
|||||||
@@ -12,6 +12,6 @@ const config = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
export default config
|
export default config;
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
import type { PropsWithChildren } from 'react'
|
import { ColorSchemeScript } from '@mantine/core';
|
||||||
import type { Metadata } from 'next'
|
import type { Metadata } from 'next';
|
||||||
import { ColorSchemeScript, MantineProvider } from '@mantine/core'
|
import type { PropsWithChildren } from 'react';
|
||||||
import '@mantine/core/styles.css'
|
import { MantineProvider } from './providers';
|
||||||
import './globals.css'
|
import '@mantine/core/styles.css';
|
||||||
|
import './styles/index.css';
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: {
|
title: {
|
||||||
@@ -27,7 +28,7 @@ export const metadata: Metadata = {
|
|||||||
twitter: {
|
twitter: {
|
||||||
card: 'summary_large_image',
|
card: 'summary_large_image',
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
export default function RootLayout({ children }: PropsWithChildren) {
|
export default function RootLayout({ children }: PropsWithChildren) {
|
||||||
return (
|
return (
|
||||||
@@ -39,5 +40,5 @@ export default function RootLayout({ children }: PropsWithChildren) {
|
|||||||
<MantineProvider>{children}</MantineProvider>
|
<MantineProvider>{children}</MantineProvider>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import type { Metadata } from 'next'
|
import type { Metadata } from 'next';
|
||||||
import { HomeScreen } from '@/screens/home'
|
import { HomeScreen } from '@/screens/home';
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: 'Главная',
|
title: 'Главная',
|
||||||
description: 'Главная страница приложения',
|
description: 'Главная страница приложения',
|
||||||
}
|
};
|
||||||
|
|
||||||
export default function HomePage() {
|
export default function HomePage() {
|
||||||
return <HomeScreen />
|
return <HomeScreen />;
|
||||||
}
|
}
|
||||||
|
|||||||
1
src/app/providers/index.ts
Normal file
1
src/app/providers/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export { MantineProvider } from './mantine-provider';
|
||||||
11
src/app/providers/mantine-provider.tsx
Normal file
11
src/app/providers/mantine-provider.tsx
Normal 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
3
src/app/styles/index.css
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
@import "./variables.css";
|
||||||
|
@import "./media.css";
|
||||||
|
@import "./reset.css";
|
||||||
6
src/app/styles/media.css
Normal file
6
src/app/styles/media.css
Normal 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
28
src/app/styles/reset.css
Normal 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;
|
||||||
|
}
|
||||||
35
src/app/styles/variables.css
Normal file
35
src/app/styles/variables.css
Normal 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
0
src/layouts/.gitkeep
Normal file
@@ -1,6 +1,6 @@
|
|||||||
import type { FC } from 'react'
|
import { Container, Image, Stack, Text, Title } from '@mantine/core';
|
||||||
import { Container, Title, Text, Image, Stack } from '@mantine/core'
|
import type { FC } from 'react';
|
||||||
import styles from './styles/home.module.css'
|
import styles from './styles/home.module.css';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Главный экран приложения.
|
* Главный экран приложения.
|
||||||
@@ -18,11 +18,9 @@ export const HomeScreen: FC = () => {
|
|||||||
fit="contain"
|
fit="contain"
|
||||||
/>
|
/>
|
||||||
<Title order={1}>Добро пожаловать</Title>
|
<Title order={1}>Добро пожаловать</Title>
|
||||||
<Text c="dimmed">
|
<Text c="dimmed">Шаблон приложения на Next.js и TypeScript.</Text>
|
||||||
Шаблон приложения на Next.js и TypeScript.
|
|
||||||
</Text>
|
|
||||||
</Stack>
|
</Stack>
|
||||||
</Container>
|
</Container>
|
||||||
</div>
|
</div>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
export { HomeScreen } from './home.screen'
|
export { HomeScreen } from './home.screen';
|
||||||
|
|||||||
Reference in New Issue
Block a user