diff --git a/src/lib/kit/components/Layouts/Column/Column.scss b/src/lib/kit/components/Layouts/Column/Column.scss new file mode 100644 index 00000000..dd5b1c92 --- /dev/null +++ b/src/lib/kit/components/Layouts/Column/Column.scss @@ -0,0 +1,81 @@ +@import '../../../styles/variables.scss'; + +.#{$ns}column { + margin-bottom: 15px; + + &:last-child { + margin-bottom: 0; + } + + &__first-row { + min-height: 28px; + display: flex; + margin-bottom: auto; + flex-direction: column; + flex-shrink: 0; + + &-inner { + display: inline; + margin-top: auto; + margin-bottom: auto; + } + + &::after { + content: ''; + width: 100%; + flex-shrink: 1; + } + } + + &__title { + word-break: break-word; + margin-right: 3px; + + &_required { + &::after { + content: '*'; + color: var(--g-color-text-danger); + } + } + } + + &__note { + position: relative; + + &-inner { + position: absolute; + margin-top: 1px; + + .g-help-popover { + display: flex; + + & > span { + display: flex; + } + } + } + } + + &__second-row { + display: flex; + flex-direction: column; + flex-grow: 1; + + &-inner { + display: flex; + justify-content: space-around; + } + } + + &__remove-button { + margin-left: 5px; + } + + &__required-mark { + color: var(--g-color-text-danger); + } + + &__error-wrapper { + min-width: 100%; + } +} diff --git a/src/lib/kit/components/Layouts/Column/Column.tsx b/src/lib/kit/components/Layouts/Column/Column.tsx new file mode 100644 index 00000000..caee48fc --- /dev/null +++ b/src/lib/kit/components/Layouts/Column/Column.tsx @@ -0,0 +1,93 @@ +import React from 'react'; + +import {HelpPopover} from '@gravity-ui/components'; +import {TrashBin} from '@gravity-ui/icons'; +import {Button, Icon, Text} from '@gravity-ui/uikit'; + +import { + FieldValue, + LayoutProps, + Spec, + StringSpec, + isArrayItem, + isArraySpec, + isObjectSpec, + withGenerateButton, +} from '../../../../core'; +import {ErrorWrapper, GenerateRandomValueButton} from '../../../components'; +import {block} from '../../../utils'; + +import './Column.scss'; + +const b = block('column'); + +interface ColumnProps {} + +const ColumnBase = ({ + name, + spec, + input, + meta, + children, +}: LayoutProps & ColumnProps) => { + const arrayItem = React.useMemo(() => isArrayItem(name), [name]); + const generateButton = React.useMemo(() => withGenerateButton(spec), [spec]); + + return ( +
+
+
+ + {spec.viewSpec.layoutTitle} + + {spec.viewSpec.layoutDescription ? ( + + + + + + ) : null} +
+
+
+
+ + {children} + + {generateButton ? ( + void} + /> + ) : null} + {arrayItem ? ( + + ) : null} +
+
+
+ ); +}; + +export const Column = ( + props: LayoutProps, +) => ; diff --git a/src/lib/kit/components/Layouts/Column/__snapshots__/Column.visual.test.tsx-snapshots/Column-Form-object-spec-dark-chromium-linux.png b/src/lib/kit/components/Layouts/Column/__snapshots__/Column.visual.test.tsx-snapshots/Column-Form-object-spec-dark-chromium-linux.png new file mode 100644 index 00000000..2d754da6 Binary files /dev/null and b/src/lib/kit/components/Layouts/Column/__snapshots__/Column.visual.test.tsx-snapshots/Column-Form-object-spec-dark-chromium-linux.png differ diff --git a/src/lib/kit/components/Layouts/Column/__snapshots__/Column.visual.test.tsx-snapshots/Column-Form-object-spec-dark-webkit-linux.png b/src/lib/kit/components/Layouts/Column/__snapshots__/Column.visual.test.tsx-snapshots/Column-Form-object-spec-dark-webkit-linux.png new file mode 100644 index 00000000..ddd81596 Binary files /dev/null and b/src/lib/kit/components/Layouts/Column/__snapshots__/Column.visual.test.tsx-snapshots/Column-Form-object-spec-dark-webkit-linux.png differ diff --git a/src/lib/kit/components/Layouts/Column/__snapshots__/Column.visual.test.tsx-snapshots/Column-Form-object-spec-light-chromium-linux.png b/src/lib/kit/components/Layouts/Column/__snapshots__/Column.visual.test.tsx-snapshots/Column-Form-object-spec-light-chromium-linux.png new file mode 100644 index 00000000..f395c76d Binary files /dev/null and b/src/lib/kit/components/Layouts/Column/__snapshots__/Column.visual.test.tsx-snapshots/Column-Form-object-spec-light-chromium-linux.png differ diff --git a/src/lib/kit/components/Layouts/Column/__snapshots__/Column.visual.test.tsx-snapshots/Column-Form-object-spec-light-webkit-linux.png b/src/lib/kit/components/Layouts/Column/__snapshots__/Column.visual.test.tsx-snapshots/Column-Form-object-spec-light-webkit-linux.png new file mode 100644 index 00000000..1b125de8 Binary files /dev/null and b/src/lib/kit/components/Layouts/Column/__snapshots__/Column.visual.test.tsx-snapshots/Column-Form-object-spec-light-webkit-linux.png differ diff --git a/src/lib/kit/components/Layouts/Column/__tests__/Column.visual.test.tsx b/src/lib/kit/components/Layouts/Column/__tests__/Column.visual.test.tsx new file mode 100644 index 00000000..3bfbf90d --- /dev/null +++ b/src/lib/kit/components/Layouts/Column/__tests__/Column.visual.test.tsx @@ -0,0 +1,14 @@ +import React from 'react'; + +import {COLUMN_CARD} from './helpers'; + +import {test} from '~playwright/core'; +import {DynamicForm} from '~playwright/core/DynamicForm'; + +test.describe('Column Form', () => { + test('object spec', async ({mount, expectScreenshot}) => { + await mount(); + + await expectScreenshot(); + }); +}); diff --git a/src/lib/kit/components/Layouts/Column/__tests__/helpers.ts b/src/lib/kit/components/Layouts/Column/__tests__/helpers.ts new file mode 100644 index 00000000..84af3482 --- /dev/null +++ b/src/lib/kit/components/Layouts/Column/__tests__/helpers.ts @@ -0,0 +1,55 @@ +import {FormValue, ObjectSpec, SpecTypes} from '../../../../../core'; + +export const COLUMN_CARD: ObjectSpec = { + defaultValue: { + name: 'value', + age: 10, + license: false, + }, + type: SpecTypes.Object, + properties: { + name: { + type: SpecTypes.String, + viewSpec: { + type: 'base', + layout: 'column', + layoutDescription: 'Description for Name', + layoutTitle: 'Name', + }, + }, + age: { + type: SpecTypes.Number, + viewSpec: { + type: 'base', + layout: 'column', + layoutDescription: 'Description for Age', + layoutTitle: 'Age', + }, + }, + license: { + type: SpecTypes.Boolean, + viewSpec: { + type: 'base', + layout: 'column', + layoutDescription: 'Description for License', + layoutTitle: 'License', + }, + }, + }, + viewSpec: { + type: 'base', + layout: 'accordeon', + layoutTitle: 'Candidate', + layoutDescription: 'Description for base', + layoutOpen: true, + }, +}; + +export const VALUE: Record = { + array: ['value', 'value'], + object: { + name: 'name', + age: 21, + license: true, + }, +}; diff --git a/src/lib/kit/components/Layouts/Column/index.ts b/src/lib/kit/components/Layouts/Column/index.ts new file mode 100644 index 00000000..f59b699c --- /dev/null +++ b/src/lib/kit/components/Layouts/Column/index.ts @@ -0,0 +1 @@ +export * from './Column'; diff --git a/src/lib/kit/components/Layouts/index.ts b/src/lib/kit/components/Layouts/index.ts index bb8e4bbd..bbddf926 100644 --- a/src/lib/kit/components/Layouts/index.ts +++ b/src/lib/kit/components/Layouts/index.ts @@ -3,6 +3,7 @@ export * from './AccordeonCard'; export * from './CardAccordeon'; export * from './CardSection'; export * from './Row'; +export * from './Column'; export * from './Section'; export * from './TableCell'; export * from './Transparent'; diff --git a/src/lib/kit/components/ViewLayouts/ViewColumn/ViewColumn.scss b/src/lib/kit/components/ViewLayouts/ViewColumn/ViewColumn.scss new file mode 100644 index 00000000..4521ea30 --- /dev/null +++ b/src/lib/kit/components/ViewLayouts/ViewColumn/ViewColumn.scss @@ -0,0 +1,31 @@ +@import '../../../styles/variables.scss'; +@import '../../../styles/mixins.scss'; + +.#{$ns}view-column { + margin-bottom: 20px; + + &:last-child { + margin-bottom: 0; + } + + &__first-row { + display: flex; + align-items: baseline; + } + + &__note { + margin-inline-start: var(--g-spacing-half); + } + + &__second-row { + & > .#{$ns}view-transparent { + margin-bottom: 6px; + + &:last-child { + margin-bottom: 0; + } + } + } + + @include with-copy-button(); +} diff --git a/src/lib/kit/components/ViewLayouts/ViewColumn/ViewColumn.tsx b/src/lib/kit/components/ViewLayouts/ViewColumn/ViewColumn.tsx new file mode 100644 index 00000000..2ae4cfc8 --- /dev/null +++ b/src/lib/kit/components/ViewLayouts/ViewColumn/ViewColumn.tsx @@ -0,0 +1,43 @@ +import React from 'react'; + +import {Text} from '@gravity-ui/uikit'; +import {HelpPopover} from '@gravity-ui/components'; + +import {FormValue, Spec, ViewLayoutProps, useDynamicFormsCtx} from '../../../../core'; +import {CopyButton} from '../../../../kit'; +import {block, isNotEmptyValue} from '../../../utils'; + +import './ViewColumn.scss'; + +const b = block('view-column'); + +export const ViewColumn = ({ + value, + spec, + children, +}: ViewLayoutProps) => { + const {showLayoutDescription} = useDynamicFormsCtx(); + + if (!isNotEmptyValue(value, spec)) { + return null; + } + + return ( +
+
+ + {spec.viewSpec.layoutTitle} + + {showLayoutDescription && spec.viewSpec.layoutDescription ? ( + + ) : null} +
+
{children}
+ +
+ ); +}; diff --git a/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-dark-chromium-linux.png b/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-dark-chromium-linux.png new file mode 100644 index 00000000..bc00ac40 Binary files /dev/null and b/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-dark-chromium-linux.png differ diff --git a/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-dark-webkit-linux.png b/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-dark-webkit-linux.png new file mode 100644 index 00000000..2c1be90a Binary files /dev/null and b/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-dark-webkit-linux.png differ diff --git a/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-light-chromium-linux.png b/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-light-chromium-linux.png new file mode 100644 index 00000000..cbd6ff95 Binary files /dev/null and b/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-light-chromium-linux.png differ diff --git a/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-light-webkit-linux.png b/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-light-webkit-linux.png new file mode 100644 index 00000000..835f91c4 Binary files /dev/null and b/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-light-webkit-linux.png differ diff --git a/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-with-layoutDescription-dark-chromium-linux.png b/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-with-layoutDescription-dark-chromium-linux.png new file mode 100644 index 00000000..c165878b Binary files /dev/null and b/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-with-layoutDescription-dark-chromium-linux.png differ diff --git a/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-with-layoutDescription-dark-webkit-linux.png b/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-with-layoutDescription-dark-webkit-linux.png new file mode 100644 index 00000000..a88030a0 Binary files /dev/null and b/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-with-layoutDescription-dark-webkit-linux.png differ diff --git a/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-with-layoutDescription-light-chromium-linux.png b/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-with-layoutDescription-light-chromium-linux.png new file mode 100644 index 00000000..a6b6380c Binary files /dev/null and b/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-with-layoutDescription-light-chromium-linux.png differ diff --git a/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-with-layoutDescription-light-webkit-linux.png b/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-with-layoutDescription-light-webkit-linux.png new file mode 100644 index 00000000..252a464c Binary files /dev/null and b/src/lib/kit/components/ViewLayouts/ViewColumn/__snapshots__/ViewColumn.visual.test.tsx-snapshots/ViewColumn-View-object-spec-with-layoutDescription-light-webkit-linux.png differ diff --git a/src/lib/kit/components/ViewLayouts/ViewColumn/__tests__/ViewColumn.visual.test.tsx b/src/lib/kit/components/ViewLayouts/ViewColumn/__tests__/ViewColumn.visual.test.tsx new file mode 100644 index 00000000..03dae636 --- /dev/null +++ b/src/lib/kit/components/ViewLayouts/ViewColumn/__tests__/ViewColumn.visual.test.tsx @@ -0,0 +1,20 @@ +import React from 'react'; + +import {VALUE, VIEW_COLUMN} from './helpers'; + +import {test} from '~playwright/core'; +import {DynamicView} from '~playwright/core/DynamicView'; + +test.describe('ViewColumn View', () => { + test('object spec', async ({mount, expectScreenshot}) => { + await mount(); + + await expectScreenshot(); + }); + + test('object spec with layoutDescription', async ({mount, expectScreenshot}) => { + await mount(); + + await expectScreenshot(); + }); +}); diff --git a/src/lib/kit/components/ViewLayouts/ViewColumn/__tests__/helpers.ts b/src/lib/kit/components/ViewLayouts/ViewColumn/__tests__/helpers.ts new file mode 100644 index 00000000..96bcf317 --- /dev/null +++ b/src/lib/kit/components/ViewLayouts/ViewColumn/__tests__/helpers.ts @@ -0,0 +1,52 @@ +import {FormValue, ObjectSpec, SpecTypes} from '../../../../../core'; + +export const VIEW_COLUMN: ObjectSpec = { + defaultValue: { + name: 'value', + age: 10, + license: false, + }, + type: SpecTypes.Object, + properties: { + name: { + type: SpecTypes.String, + viewSpec: { + type: 'base', + layout: 'column', + layoutDescription: 'Description for Name', + layoutTitle: 'Name', + }, + }, + age: { + type: SpecTypes.Number, + viewSpec: { + type: 'base', + layout: 'column', + layoutDescription: 'Description for Age', + layoutTitle: 'Age', + }, + }, + license: { + type: SpecTypes.Boolean, + viewSpec: { + type: 'base', + layout: 'column', + layoutDescription: 'Description for License', + layoutTitle: 'License', + }, + }, + }, + viewSpec: { + type: 'base', + layout: 'accordeon', + layoutTitle: 'Candidate', + layoutDescription: 'Description for base', + layoutOpen: true, + }, +}; + +export const VALUE: FormValue = { + name: 'name', + age: 21, + license: true, +}; diff --git a/src/lib/kit/components/ViewLayouts/ViewColumn/index.ts b/src/lib/kit/components/ViewLayouts/ViewColumn/index.ts new file mode 100644 index 00000000..aa5517b8 --- /dev/null +++ b/src/lib/kit/components/ViewLayouts/ViewColumn/index.ts @@ -0,0 +1 @@ +export * from './ViewColumn'; diff --git a/src/lib/kit/components/ViewLayouts/index.ts b/src/lib/kit/components/ViewLayouts/index.ts index 943c9e8d..db8fe57f 100644 --- a/src/lib/kit/components/ViewLayouts/index.ts +++ b/src/lib/kit/components/ViewLayouts/index.ts @@ -3,6 +3,7 @@ export * from './ViewCardAccordeon'; export * from './ViewAccordeonCard'; export * from './ViewCardSection'; export * from './ViewRow'; +export * from './ViewColumn'; export * from './ViewSection'; export * from './ViewTableCell'; export * from './ViewTransparent'; diff --git a/src/lib/kit/constants/config.tsx b/src/lib/kit/constants/config.tsx index c10d2cd6..47117f87 100644 --- a/src/lib/kit/constants/config.tsx +++ b/src/lib/kit/constants/config.tsx @@ -12,6 +12,7 @@ import { Checkbox, CheckboxGroup, CheckboxGroupView, + Column, DateInput, DateView, FileInput, @@ -62,6 +63,7 @@ import { ViewAccordeonCard, ViewCardAccordeon, ViewCardSection, + ViewColumn, ViewGroup, ViewGroup2, ViewRow, @@ -89,6 +91,7 @@ export const dynamicConfig: DynamicFormConfig = { layouts: { row: Row, row_verbose: RowVerbose, + column: Column, accordeon: Accordeon, section: Section, section2: Section2, @@ -112,6 +115,7 @@ export const dynamicConfig: DynamicFormConfig = { layouts: { row: Row, row_verbose: RowVerbose, + column: Column, table_item: TableCell, transparent: Transparent, }, @@ -126,6 +130,7 @@ export const dynamicConfig: DynamicFormConfig = { layouts: { row: Row, row_verbose: RowVerbose, + column: Column, table_item: TableCell, transparent: Transparent, }, @@ -150,6 +155,7 @@ export const dynamicConfig: DynamicFormConfig = { layouts: { row: Row, row_verbose: RowVerbose, + column: Column, accordeon: Accordeon, section: Section, section2: Section2, @@ -179,6 +185,7 @@ export const dynamicConfig: DynamicFormConfig = { layouts: { row: Row, row_verbose: RowVerbose, + column: Column, table_item: TableCell, transparent: Transparent, section: Section, @@ -205,6 +212,7 @@ export const dynamicViewConfig: DynamicViewConfig = { layouts: { row: ViewRow, row_verbose: ViewRow, + column: ViewColumn, accordeon: ViewAccordeon, section: ViewSection, section2: ViewSection2, @@ -225,6 +233,7 @@ export const dynamicViewConfig: DynamicViewConfig = { layouts: { row: ViewRow, row_verbose: ViewRow, + column: ViewColumn, table_item: ViewTableCell, transparent: ViewTransparent, }, @@ -236,6 +245,7 @@ export const dynamicViewConfig: DynamicViewConfig = { layouts: { row: ViewRow, row_verbose: ViewRow, + column: ViewColumn, table_item: ViewTableCell, transparent: ViewTransparent, }, @@ -257,6 +267,7 @@ export const dynamicViewConfig: DynamicViewConfig = { layouts: { row: ViewRow, row_verbose: ViewRow, + column: ViewColumn, accordeon: ViewAccordeon, section: ViewSection, section2: ViewSection2, @@ -283,6 +294,7 @@ export const dynamicViewConfig: DynamicViewConfig = { layouts: { row: ViewRow, row_verbose: ViewRow, + column: ViewColumn, table_item: ViewTableCell, transparent: ViewTransparent, section: ViewSection,