diff --git a/docs/spec.md b/docs/spec.md index dd92167b..c3e602fe 100644 --- a/docs/spec.md +++ b/docs/spec.md @@ -8,33 +8,33 @@ type Spec = ArraySpec | BooleanSpec | NumberSpec | ObjectSpec | StringSpec; ### ArraySpec -| Property | Type | Required | Description | -| :--------------------------- | :----------------------------------------------------------- | :------: | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| defaultValue | `FieldArrayValue` | | Default value | -| type | `"array"` | yes | Entity type | -| required | `boolean` | | Can the value be `undefined` or `null` | -| maxLength | `bigint` | | Maximum number of array elements | -| minLength | `bigint` | | Minimum number of array elements | -| items | `Spec` | | Entity `spec` for an array element | -| enum | `string[]` | | An array of valid values, for example for a select | -| description | `Record` | | Beautiful names for values from `enum` | -| validator | `string` | | The key for determining the [validator](./config.md#validators) for the entity, if the value is empty, the base [validator](./config.md#validators) from the entity config will be used | -| viewSpec.disabled | `boolean` | | Is the field available for editing | -| viewSpec.type | `string` | yes | Key to define [Input](./config.md#inputs) for an entity | -| viewSpec.layout | `string` | | Key to define [Layout](./config.md#layouts) for an entity | -| viewSpec.layoutTitle | `string` | | Title for [Layout](./config.md#layouts) | -| viewSpec.layoutDescription | `string` | | Additional description/hint for [Layout](./config.md#layouts) | -| viewSpec.layoutOpen | `boolean` | | Expand [Layout](./config.md#layouts) at the first rendering | -| viewSpec.itemLabel | `string` | | Text for the button that adds an array element | -| viewSpec.itemPrefix | `string` | | Additional text for an element in the array | -| viewSpec.table | `{label: string; property: string; description?: string;}[]` | | An array whose elements are used to establish column names and their order, if `type === "table"`. `description` adds a hint to a field in the table's header | -| viewSpec.link | `any` | | A field containing information for forming a [link](#link) for a value | -| viewSpec.placeholder | `string` | | A short hint displayed in the field before the user enters the value | -| viewSpec.addButtonPosition | `"down"/"right"` | | The location of the button adding a new element to the array. Default value "down". | -| viewSpec.hidden | `boolean` | | Hide field and view | -| viewSpec.selectParams | `object` | | [Parameters](#selectparams) additional options for the selector | -| viewSpec.checkboxGroupParams | `object` | | [Parameters](#checkboxgroupparams) additional options for the checkbox group | -| viewSpec.inputProps | `object` | | [InputProps](./input-props-map.md) Additional properties for internal input components | +| Property | Type | Required | Description | +| :--------------------------- | :--------------------------------------------------------------------------- | :------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| defaultValue | `FieldArrayValue` | | Default value | +| type | `"array"` | yes | Entity type | +| required | `boolean` | | Can the value be `undefined` or `null` | +| maxLength | `bigint` | | Maximum number of array elements | +| minLength | `bigint` | | Minimum number of array elements | +| items | `Spec` | | Entity `spec` for an array element | +| enum | `string[]` | | An array of valid values, for example for a select | +| description | `Record` | | Beautiful names for values from `enum` | +| validator | `string` | | The key for determining the [validator](./config.md#validators) for the entity, if the value is empty, the base [validator](./config.md#validators) from the entity config will be used | +| viewSpec.disabled | `boolean` | | Is the field available for editing | +| viewSpec.type | `string` | yes | Key to define [Input](./config.md#inputs) for an entity | +| viewSpec.layout | `string` | | Key to define [Layout](./config.md#layouts) for an entity | +| viewSpec.layoutTitle | `string` | | Title for [Layout](./config.md#layouts) | +| viewSpec.layoutDescription | `string` | | Additional description/hint for [Layout](./config.md#layouts) | +| viewSpec.layoutOpen | `boolean` | | Expand [Layout](./config.md#layouts) at the first rendering | +| viewSpec.itemLabel | `string` | | Text for the button that adds an array element | +| viewSpec.itemPrefix | `string` | | Additional text for an element in the array | +| viewSpec.table | `{label: string; property: string; description?: string; width?: number;}[]` | | An array whose elements are used to establish column names and their order, if `type === "table"`. `description` adds a hint to a field in the table's header. `width` sets the width of the column in pixels. | +| viewSpec.link | `any` | | A field containing information for forming a [link](#link) for a value | +| viewSpec.placeholder | `string` | | A short hint displayed in the field before the user enters the value | +| viewSpec.addButtonPosition | `"down"/"right"` | | The location of the button adding a new element to the array. Default value "down". | +| viewSpec.hidden | `boolean` | | Hide field and view | +| viewSpec.selectParams | `object` | | [Parameters](#selectparams) additional options for the selector | +| viewSpec.checkboxGroupParams | `object` | | [Parameters](#checkboxgroupparams) additional options for the checkbox group | +| viewSpec.inputProps | `object` | | [InputProps](./input-props-map.md) Additional properties for internal input components | ### BooleanSpec diff --git a/src/lib/core/types/specs.ts b/src/lib/core/types/specs.ts index 28e330ab..89afd28e 100644 --- a/src/lib/core/types/specs.ts +++ b/src/lib/core/types/specs.ts @@ -32,6 +32,7 @@ export interface ArraySpec< label: string; property: string; description?: string; + width?: number; }[]; link?: LinkType; placeholder?: string; diff --git a/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.scss b/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.scss index 28de4941..10cffc70 100644 --- a/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.scss +++ b/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.scss @@ -9,6 +9,11 @@ } } + &__column-title { + overflow: hidden; + text-overflow: ellipsis; + } + &__row { .g-table__cell { border-bottom: 0px transparent; @@ -58,6 +63,20 @@ } } + &__cell-without-limit { + &_arr, + &_obj { + padding-left: var(--df-table-array-cell-obj-padding-left, var(--g-spacing-half)); + + & > .simple-vertical-accordeon { + margin-bottom: var( + --df-table-array-cell-obj-simple-vertical-accordeon-margin-bottom, + var(--g-spacing-0) + ); + } + } + } + &__idx { padding-top: var(--df-table-array-idx-padding-top, 6px); } diff --git a/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx b/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx index 543dc4c5..8bbfb9d3 100644 --- a/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx +++ b/src/lib/kit/components/Inputs/TableArrayInput/TableArrayInput.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {Plus, TrashBin} from '@gravity-ui/icons'; -import {Button, Flex, HelpMark, Icon, Table} from '@gravity-ui/uikit'; +import {Button, Flex, HelpMark, Icon, Table, type TableColumnConfig} from '@gravity-ui/uikit'; import noop from 'lodash/noop'; import set from 'lodash/set'; @@ -77,7 +77,7 @@ export const TableArrayInput: ArrayInput = ({spec, name, arrayInput, input}) => return null; } - const idxColumn = { + const idxColumn: TableColumnConfig<{key: string}> = { id: 'idx', name: '', sticky: 'left', @@ -88,7 +88,7 @@ export const TableArrayInput: ArrayInput = ({spec, name, arrayInput, input}) => ), }; - const removeColumn = { + const removeColumn: TableColumnConfig<{key: string}> = { id: 'remove', name: '', sticky: 'right', @@ -104,65 +104,79 @@ export const TableArrayInput: ArrayInput = ({spec, name, arrayInput, input}) => ), }; - const columns = table.map(({property, label, description}) => ({ - id: property, - name: !description - ? label - : () => ( - - {label} - [] = table.map( + ({property, label, description, width}) => ({ + id: property, + name: !description + ? () => ( +
- - - - ), - template: ( - { - key, - }: { - key: string; - }, - idx: number, - ) => { - const entitySpec = items?.properties?.[property]; - - if (!entitySpec) { - return null; - } - - const preparedEntitySpec = { - ...entitySpec, - viewSpec: { - ...entitySpec.viewSpec, - layoutTitle: - table.map(({label}) => label).join(` ${idx + 1} `) + ` ${idx + 1}`, + {label} +
+ ) + : () => ( + +
{label}
+ + + +
+ ), + template: ( + { + key, + }: { + key: string; }, - }; - - return ( -
.${property}`} - > - `] as FieldObjectValue)?.[property]} - spec={preparedEntitySpec} - name={`${name}.<${key}>.${property}`} - parentOnChange={parentOnChange} - parentOnUnmount={noop} - /> -
- ); - }, - })); + idx: number, + ) => { + const entitySpec = items?.properties?.[property]; + + if (!entitySpec) { + return null; + } + + const preparedEntitySpec = { + ...entitySpec, + viewSpec: { + ...entitySpec.viewSpec, + layoutTitle: + table.map(({label}) => label).join(` ${idx + 1} `) + ` ${idx + 1}`, + }, + }; + + return ( +
.${property}`} + > + `] as FieldObjectValue)?.[property]} + spec={preparedEntitySpec} + name={`${name}.<${key}>.${property}`} + parentOnChange={parentOnChange} + parentOnUnmount={noop} + /> +
+ ); + }, + }), + ); return [idxColumn, ...columns, removeColumn]; }, [name, spec, onItemRemove, parentOnChange, input.parentOnUnmount, input.value]); diff --git a/src/lib/kit/components/Views/TableArrayView/TableArrayView.scss b/src/lib/kit/components/Views/TableArrayView/TableArrayView.scss index 431c0e87..85d79ac2 100644 --- a/src/lib/kit/components/Views/TableArrayView/TableArrayView.scss +++ b/src/lib/kit/components/Views/TableArrayView/TableArrayView.scss @@ -5,6 +5,11 @@ margin-bottom: var(--df-table-array-view-table-margin-bottom, var(--g-spacing-3)); } + &__column-title { + overflow: hidden; + text-overflow: ellipsis; + } + &__cell { max-width: var(--df-table-array-view-cell-min-width, 150px); min-width: var(--df-table-array-view-cell-max-width, 150px); @@ -23,4 +28,13 @@ min-width: 50px; } } + + &__cell-without-limit { + &_arr, + &_obj { + & > .simple-vertical-accordeon { + margin-bottom: var(--df-spacing-last-child, $df-spacing-last-child); + } + } + } } diff --git a/src/lib/kit/components/Views/TableArrayView/TableArrayView.tsx b/src/lib/kit/components/Views/TableArrayView/TableArrayView.tsx index 610ea029..871aa121 100644 --- a/src/lib/kit/components/Views/TableArrayView/TableArrayView.tsx +++ b/src/lib/kit/components/Views/TableArrayView/TableArrayView.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import {Flex, HelpMark, Table} from '@gravity-ui/uikit'; +import {Flex, HelpMark, Table, type TableColumnConfig} from '@gravity-ui/uikit'; import type {ArrayView, FormValue, ObjectValue} from '../../../../core'; import { @@ -31,7 +31,7 @@ export const TableArrayView: ArrayView = ({value = [], spec, name}) => { return null; } - const idxColumn = { + const idxColumn: TableColumnConfig = { id: 'idx', name: '', sticky: 'left', @@ -42,44 +42,61 @@ export const TableArrayView: ArrayView = ({value = [], spec, name}) => { ), }; - const columns = table.map(({property, label, description}) => ({ - id: property, - name: - description && showLayoutDescription - ? () => ( - - {label} - [] = table.map( + ({property, label, description, width}) => ({ + id: property, + name: + description && showLayoutDescription + ? () => ( + - - - - ) - : label, - template: (_: FormValue, idx: number) => { - const entitySpec = items?.properties?.[property]; +
{label}
+ + + +
+ ) + : () => ( +
+ {label} +
+ ), + template: (_: FormValue, idx: number) => { + const entitySpec = items?.properties?.[property]; - if (!entitySpec) { - return null; - } + if (!entitySpec) { + return null; + } - return ( -
- -
- ); - }, - })); + return ( +
+ +
+ ); + }, + }), + ); return [idxColumn, ...columns]; }, [name, spec, showLayoutDescription]);