diff --git a/.ai/conventions/ui.md b/.ai/conventions/ui.md index 69db119..432d6ec 100644 --- a/.ai/conventions/ui.md +++ b/.ai/conventions/ui.md @@ -110,8 +110,8 @@ Render-helper замени самостоятельным presentation component При переносе обновляй imports, ссылки документации и проверки, зависящие от пути. Пример: [BankCardForm](../../src/entities/bank-card/ui/BankCardForm/BankCardForm.tsx) -лежит рядом со своим view, тестом и story; общий `BankForms.module.css` -остаётся в `bank-card/ui`. +лежит рядом со своим view, тестом и story. Формы используют Mantine +`Fieldset variant="unstyled"` для групповой блокировки полей без локального CSS. ## Формы diff --git a/dependency-cruiser.cjs b/dependency-cruiser.cjs index 777da44..39beab8 100644 --- a/dependency-cruiser.cjs +++ b/dependency-cruiser.cjs @@ -1,5 +1,14 @@ module.exports = { forbidden: [ + { + from: { + path: "^(src|packages/[^/]+/src)/", + pathNot: "[.](test|stories|fixtures)[.]|^src/test/", + }, + name: "production-must-not-depend-on-test-code", + severity: "error", + to: { path: "[.](test|stories|fixtures)[.]|^src/test/" }, + }, { from: {}, name: "no-unresolved", diff --git a/eslint.config.mjs b/eslint.config.mjs index 2885a5a..1222ea7 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -153,11 +153,13 @@ export default defineConfig( }, }, rules: { + "@typescript-eslint/consistent-type-imports": "error", // React ignores event handler return values; floating promises are still checked in bodies. "@typescript-eslint/no-misused-promises": [ "error", { checksVoidReturn: { attributes: false } }, ], + "@typescript-eslint/no-non-null-assertion": "error", "@typescript-eslint/switch-exhaustiveness-check": "error", }, }, @@ -197,6 +199,7 @@ export default defineConfig( ignoreTypeIndexes: true, }, ], + "@typescript-eslint/no-unnecessary-condition": ["error", { allowConstantLoopConditions: true }], }, }, { diff --git a/packages/icons/tsconfig.json b/packages/icons/tsconfig.json index 77d9d3e..a937da9 100644 --- a/packages/icons/tsconfig.json +++ b/packages/icons/tsconfig.json @@ -1,15 +1,12 @@ { + "extends": "../../tsconfig.base.json", "compilerOptions": { - "target": "ES2023", "lib": [ "ES2023", "DOM" ], "module": "ESNext", "moduleResolution": "Bundler", - "strict": true, - "skipLibCheck": true, - "verbatimModuleSyntax": true, "declaration": true, "emitDeclarationOnly": true, "rootDir": "src", diff --git a/packages/ui/src/EntryCard/EntryCard.module.css b/packages/ui/src/EntryCard/EntryCard.module.css index 2aca6de..fbdcf96 100644 --- a/packages/ui/src/EntryCard/EntryCard.module.css +++ b/packages/ui/src/EntryCard/EntryCard.module.css @@ -93,3 +93,13 @@ transition: none; } } + +.row[data-wrap] p { + white-space: normal; + overflow-wrap: anywhere; +} +@media (min-width: 36em) { + .row[data-wrap] { + grid-template-columns: auto minmax(0, 1fr) minmax(0, 40%); + } +} diff --git a/packages/ui/src/EntryCard/EntryCard.stories.tsx b/packages/ui/src/EntryCard/EntryCard.stories.tsx index 3d06295..063520c 100644 --- a/packages/ui/src/EntryCard/EntryCard.stories.tsx +++ b/packages/ui/src/EntryCard/EntryCard.stories.tsx @@ -39,3 +39,5 @@ export default meta; type Story = StoryObj; export const LongContentAndFallback: Story = {}; + +export const WrappedOperation: Story = { args: { value: "−123 456 789 012 345 678,90 ₽", wrap: true } }; diff --git a/packages/ui/src/EntryCard/EntryCard.tsx b/packages/ui/src/EntryCard/EntryCard.tsx index 9f5d9c0..8a63f82 100644 --- a/packages/ui/src/EntryCard/EntryCard.tsx +++ b/packages/ui/src/EntryCard/EntryCard.tsx @@ -18,6 +18,7 @@ type EntryCardProps = { | "positive"; value: string; valueLabel: string; + wrap?: boolean; }; const EntryCard: FC = (props) => { @@ -31,7 +32,12 @@ const EntryCard: FC = (props) => { const valueLabelClass = `${classes[props.tone]} ${props.actions ? classes.valueLabel : ""}`; return ( - +