Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BREAKING CHANGE] feat(FormItem): remove topNode #7837

Merged
merged 2 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const App = () => {
</FormItem>
{/* test 2: should find TopLabel inside topNode prop */}
<FormItem
topNode={
top={
<FormItem.Top>
<FormItem.TopLabel htmlFor="about">Дополнительная информация</FormItem.TopLabel>
<FormItem.TopAside>0/100</FormItem.TopAside>
Expand Down
9 changes: 4 additions & 5 deletions packages/codemods/src/transforms/v7/form-item.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ export const FormItemTopAsidePlayground = (props: ComponentPlaygroundProps) => {
{({ topLabel, topAside, ...props }: FormItemTopAsideProps) => (
<FormItem
{...props}
topNode={
top={
<FormItem.Top>
{topLabel}
{topAside}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export const WithInputFieldWithError: Story = {
export const WithTopAside: Story = {
...Playground,
args: {
topNode: (
top: (
<FormItem.Top>
<FormItem.TopLabel htmlFor="about">Дополнительная информация</FormItem.TopLabel>
<FormItem.TopAside id="counter">0/100</FormItem.TopAside>
Expand Down
14 changes: 14 additions & 0 deletions packages/vkui/src/components/FormItem/FormItem.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,18 @@ describe('FormItem', () => {
// c htmlFor и без topComponent используется "label"
expect(screen.getByText('Имя').tagName.toLowerCase()).toMatch('label');
});

it('check render top node', () => {
render(
<FormItem
top={
<FormItem.Top data-testid="top">
<FormItem.TopLabel htmlFor="about">Дополнительная информация</FormItem.TopLabel>
<FormItem.TopAside>0/100</FormItem.TopAside>
</FormItem.Top>
}
/>,
);
expect(screen.queryByTestId('top')).toBeTruthy();
});
});
17 changes: 4 additions & 13 deletions packages/vkui/src/components/FormItem/FormItem.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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`.
Expand Down Expand Up @@ -97,7 +89,6 @@ export const FormItem: React.FC<FormItemProps> & {
htmlFor,
bottomId,
noPadding,
topNode,
required = false,
...restProps
}: FormItemProps) => {
Expand All @@ -106,14 +97,14 @@ export const FormItem: React.FC<FormItemProps> & {

const wrappedChildren = (
<React.Fragment>
{hasReactNode(topNode) ? (
topNode
) : hasReactNode(top) ? (
{isPrimitiveReactNode(top) ? (
<FormItemTop>
<FormItemTopLabel htmlFor={htmlFor} Component={topComponentProp} id={topId}>
{top}
</FormItemTopLabel>
</FormItemTop>
) : hasReactNode(top) ? (
top
) : null}
{children}
{hasReactNode(bottom) && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { FormItemTopLabel } from './FormItemTopLabel';

```jsx
<FormItem
topNode={
top={
<FormItem.Top>
<FormItem.TopLabel htmlFor="about">Дополнительная информация</FormItem.TopLabel>
<FormItem.TopAside id="counter">0/100</FormItem.TopAside>
Expand Down
6 changes: 2 additions & 4 deletions packages/vkui/src/components/FormItem/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,11 @@

Компонент `<FormItem.TopAside>` отвечает за отрисовку дополнительного контента справа от заголовка поля.

> Обратите внимание, что составной компонент необходимо прокидывать в свойство `topNode`, а не `top`

Пример использования:

```jsx static
<FormItem
topNode={
top={
<FormItem.Top>
<FormItem.TopLabel htmlFor="about">Дополнительная информация</FormItem.TopLabel>
<FormItem.TopAside>0/100</FormItem.TopAside>
Expand Down Expand Up @@ -246,7 +244,7 @@ const Example = () => {
/>
</FormItem>
<FormItem
topNode={
top={
<FormItem.Top>
<FormItem.TopLabel htmlFor="about">О себе</FormItem.TopLabel>
<FormItem.TopAside>{about.length}/100</FormItem.TopAside>
Expand Down
Loading