diff --git a/packages/codemods/src/transforms/v7/__tests__/__snapshots__/form-item.ts.snap b/packages/codemods/src/transforms/v7/__tests__/__snapshots__/form-item.ts.snap index e22d581422..1fdc162923 100644 --- a/packages/codemods/src/transforms/v7/__tests__/__snapshots__/form-item.ts.snap +++ b/packages/codemods/src/transforms/v7/__tests__/__snapshots__/form-item.ts.snap @@ -23,7 +23,7 @@ const App = () => { {/* test 2: should find TopLabel inside topNode prop */} Дополнительная информация 0/100 diff --git a/packages/codemods/src/transforms/v7/form-item.ts b/packages/codemods/src/transforms/v7/form-item.ts index 75cef58a46..1653144edb 100644 --- a/packages/codemods/src/transforms/v7/form-item.ts +++ b/packages/codemods/src/transforms/v7/form-item.ts @@ -1,5 +1,5 @@ import { API, FileInfo, JSXAttribute, JSXElement, JSXExpressionContainer } from 'jscodeshift'; -import { getImportInfo } from '../../codemod-helpers'; +import { getImportInfo, renameProp } from '../../codemod-helpers'; import { JSCodeShiftOptions } from '../../types'; export const parser = 'tsx'; @@ -58,6 +58,8 @@ export default function transformer(file: FileInfo, api: API, options: JSCodeShi return undefined; } + renameProp(j, source, localName, { topNode: 'top' }); + source.find(j.JSXElement, { openingElement: { name: { name: localName } } }).forEach((path) => { const formItem = path.node; let topMultiline: JSXAttribute | undefined; @@ -91,10 +93,7 @@ export default function transformer(file: FileInfo, api: API, options: JSCodeShi // Ищем FormItem.TopLabel в пропе top и topNode formItemAttributes?.forEach((attr) => { - if ( - attr.type === 'JSXAttribute' && - (attr.name.name === 'top' || attr.name.name === 'topNode') - ) { + if (attr.type === 'JSXAttribute' && attr.name.name === 'top') { if (attr.value?.type === 'JSXElement') { topLabelMultiline = findTopLabelRecursive(attr.value); } else if ( diff --git a/packages/vkui/src/components/FormItem/FormItem.e2e-playground.tsx b/packages/vkui/src/components/FormItem/FormItem.e2e-playground.tsx index c13cb9e1cb..b29d430cfc 100644 --- a/packages/vkui/src/components/FormItem/FormItem.e2e-playground.tsx +++ b/packages/vkui/src/components/FormItem/FormItem.e2e-playground.tsx @@ -113,7 +113,7 @@ export const FormItemTopAsidePlayground = (props: ComponentPlaygroundProps) => { {({ topLabel, topAside, ...props }: FormItemTopAsideProps) => ( {topLabel} {topAside} diff --git a/packages/vkui/src/components/FormItem/FormItem.stories.tsx b/packages/vkui/src/components/FormItem/FormItem.stories.tsx index 05984cb361..3e5096a798 100644 --- a/packages/vkui/src/components/FormItem/FormItem.stories.tsx +++ b/packages/vkui/src/components/FormItem/FormItem.stories.tsx @@ -60,7 +60,7 @@ export const WithInputFieldWithError: Story = { export const WithTopAside: Story = { ...Playground, args: { - topNode: ( + top: ( Дополнительная информация 0/100 diff --git a/packages/vkui/src/components/FormItem/FormItem.test.tsx b/packages/vkui/src/components/FormItem/FormItem.test.tsx index ff5a8cfbcf..e24e0d5804 100644 --- a/packages/vkui/src/components/FormItem/FormItem.test.tsx +++ b/packages/vkui/src/components/FormItem/FormItem.test.tsx @@ -22,4 +22,18 @@ describe('FormItem', () => { // c htmlFor и без topComponent используется "label" expect(screen.getByText('Имя').tagName.toLowerCase()).toMatch('label'); }); + + it('check render top node', () => { + render( + + Дополнительная информация + 0/100 + + } + />, + ); + expect(screen.queryByTestId('top')).toBeTruthy(); + }); }); diff --git a/packages/vkui/src/components/FormItem/FormItem.tsx b/packages/vkui/src/components/FormItem/FormItem.tsx index c0a7ee22ad..36c9278771 100644 --- a/packages/vkui/src/components/FormItem/FormItem.tsx +++ b/packages/vkui/src/components/FormItem/FormItem.tsx @@ -1,7 +1,7 @@ 'use client'; import * as React from 'react'; -import { classNames, hasReactNode } from '@vkontakte/vkjs'; +import { classNames, hasReactNode, isPrimitiveReactNode } from '@vkontakte/vkjs'; import { useAdaptivity } from '../../hooks/useAdaptivity'; import { useExternRef } from '../../hooks/useExternRef'; import { useObjectMemo } from '../../hooks/useObjectMemo'; @@ -42,14 +42,6 @@ export interface FormItemProps * Если оставить пустым и использовать htmlFor, то тег top будет label. */ topComponent?: React.ElementType; - /** - * Позволяет полностью заменить шапку поля пользовательским компонентом. - * - * @since 6.1.0 - * - * TODO [>=7]: удалить и использовать top - оно будет принимать либо строку, либо подкомпонент - */ - topNode?: React.ReactNode; bottom?: React.ReactNode; /** * Передаётся при использовании `bottom`. @@ -97,7 +89,6 @@ export const FormItem: React.FC & { htmlFor, bottomId, noPadding, - topNode, required = false, ...restProps }: FormItemProps) => { @@ -106,14 +97,14 @@ export const FormItem: React.FC & { const wrappedChildren = ( - {hasReactNode(topNode) ? ( - topNode - ) : hasReactNode(top) ? ( + {isPrimitiveReactNode(top) ? ( {top} + ) : hasReactNode(top) ? ( + top ) : null} {children} {hasReactNode(bottom) && ( diff --git a/packages/vkui/src/components/FormItem/FormItemTop/FormItemTop.mdx b/packages/vkui/src/components/FormItem/FormItemTop/FormItemTop.mdx index 2c77236efc..699abbac11 100644 --- a/packages/vkui/src/components/FormItem/FormItemTop/FormItemTop.mdx +++ b/packages/vkui/src/components/FormItem/FormItemTop/FormItemTop.mdx @@ -12,7 +12,7 @@ import { FormItemTopLabel } from './FormItemTopLabel'; ```jsx Дополнительная информация 0/100 diff --git a/packages/vkui/src/components/FormItem/Readme.md b/packages/vkui/src/components/FormItem/Readme.md index 20a13ffe3c..d181e0dca9 100644 --- a/packages/vkui/src/components/FormItem/Readme.md +++ b/packages/vkui/src/components/FormItem/Readme.md @@ -43,13 +43,11 @@ Компонент `` отвечает за отрисовку дополнительного контента справа от заголовка поля. -> Обратите внимание, что составной компонент необходимо прокидывать в свойство `topNode`, а не `top` - Пример использования: ```jsx static Дополнительная информация 0/100 @@ -246,7 +244,7 @@ const Example = () => { /> О себе {about.length}/100