Skip to content

Commit

Permalink
feat(NewSettingForArray): added new settings to the array (#83)
Browse files Browse the repository at this point in the history
  • Loading branch information
NasgulNexus authored Aug 29, 2023
1 parent d5d8e6d commit de1c422
Show file tree
Hide file tree
Showing 14 changed files with 193 additions and 74 deletions.
2 changes: 2 additions & 0 deletions docs/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ type Spec = ArraySpec | BooleanSpec | NumberSpec | ObjectSpec | StringSpec;
| 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;}[]` | | An array whose elements are used to establish column names and their order, if `type === "table"` |
| 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". |

### BooleanSpec

Expand Down
2 changes: 2 additions & 0 deletions src/lib/core/types/specs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ export interface ArraySpec<LinkType = any> {
layoutDescription?: string;
layoutOpen?: boolean;
itemLabel?: string;
itemPrefix?: string;
table?: {
label: string;
property: string;
}[];
link?: LinkType;
placeholder?: string;
addButtonPosition?: 'down' | 'right';
};
}

Expand Down
25 changes: 25 additions & 0 deletions src/lib/kit/components/Inputs/ArrayBase/ArrayBase.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@import '../../../styles/variables';

.#{$ns}array-base {
&_add-button-right {
display: flex;
align-items: flex-end;
}

&__items-wrapper {
&_add-button-down {
margin-bottom: 15px;
}
}

&__item-prefix {
margin-top: -7px;
margin-bottom: 8px;
}

&__add-button {
&_right {
margin-left: 4px;
}
}
}
141 changes: 91 additions & 50 deletions src/lib/kit/components/Inputs/ArrayBase/ArrayBase.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';

import {Plus} from '@gravity-ui/icons';
import {Button, Icon} from '@gravity-ui/uikit';
import {Button, Icon, Label} from '@gravity-ui/uikit';
import _ from 'lodash';

import {
Expand All @@ -19,6 +19,11 @@ import {
isObjectSpec,
transformArrIn,
} from '../../../../core';
import {block} from '../../../utils';

import './ArrayBase.scss';

const b = block('array-base');

export const ArrayBase: ArrayInput = ({spec, name, arrayInput, input}) => {
const keys = React.useMemo(
Expand All @@ -32,20 +37,6 @@ export const ArrayBase: ArrayInput = ({spec, name, arrayInput, input}) => {

const itemSpecCorrect = React.useMemo(() => isCorrectSpec(spec.items), [spec.items]);

const onItemAdd = React.useCallback(() => {
let item;

if (!spec.items?.required) {
if (isArraySpec(spec.items)) {
item = {[OBJECT_ARRAY_FLAG]: true, [OBJECT_ARRAY_CNT]: 0};
} else if (isObjectSpec(spec.items)) {
item = {};
}
}

arrayInput.onItemAdd(item);
}, [arrayInput.onItemAdd, spec.items]);

const getItemSpec = React.useCallback(
(idx: number): typeof spec.items | null => {
if (!itemSpecCorrect) {
Expand Down Expand Up @@ -80,6 +71,55 @@ export const ArrayBase: ArrayInput = ({spec, name, arrayInput, input}) => {
[input.onChange, input.name],
);

const AddButton: React.FC = React.useCallback(() => {
let onClick = () => {
let item;

if (!spec.items?.required) {
if (isArraySpec(spec.items)) {
item = {[OBJECT_ARRAY_FLAG]: true, [OBJECT_ARRAY_CNT]: 0};
} else if (isObjectSpec(spec.items)) {
item = {};
}
}

arrayInput.onItemAdd(item);
};

let qa = `${name}-add-item`;
let title = spec.viewSpec.itemLabel;

if (!arrayInput.value && spec.defaultValue) {
onClick = () => {
input.onChange(transformArrIn<ArrayValue, FieldArrayValue>(spec.defaultValue!));
};

qa = `${name}-init-arr`;
title = spec.viewSpec.layoutTitle;
}

return (
<Button
onClick={onClick}
disabled={spec.viewSpec.disabled}
qa={qa}
className={b('add-button', {right: spec.viewSpec.addButtonPosition === 'right'})}
>
<Icon data={Plus} size={14} />
{title || null}
</Button>
);
}, [
arrayInput,
input,
name,
spec.defaultValue,
spec.items,
spec.viewSpec.disabled,
spec.viewSpec.itemLabel,
spec.viewSpec.layoutTitle,
]);

const items = React.useMemo(
() =>
keys.map((key, idx) => {
Expand All @@ -89,50 +129,51 @@ export const ArrayBase: ArrayInput = ({spec, name, arrayInput, input}) => {
return null;
}

const showItemPrefix = idx !== 0 && spec.viewSpec.itemPrefix;

return (
<Controller
value={input.value?.[`<${key}>`]}
parentOnChange={parentOnChange}
parentOnUnmount={input.parentOnUnmount}
spec={itemSpec}
name={`${name}.<${key}>`}
key={`${name}.<${key}>`}
/>
<React.Fragment key={`${name}.<${key}>`}>
{showItemPrefix ? (
<Label size="m" className={b('item-prefix')}>
{spec.viewSpec.itemPrefix}
</Label>
) : null}
<Controller
value={input.value?.[`<${key}>`]}
parentOnChange={parentOnChange}
parentOnUnmount={input.parentOnUnmount}
spec={itemSpec}
name={`${name}.<${key}>`}
/>
</React.Fragment>
);
}),
[keys.join(''), name, getItemSpec, parentOnChange, input.parentOnUnmount, input.value],
[
keys.join(''),
name,
getItemSpec,
parentOnChange,
input.parentOnUnmount,
input.value,
spec.viewSpec.itemPrefix,
],
);

if (!itemSpecCorrect) {
return null;
}

return (
<React.Fragment>
{items}
{!arrayInput.value && spec.defaultValue ? (
<Button
onClick={() =>
input.onChange(
transformArrIn<ArrayValue, FieldArrayValue>(spec.defaultValue!),
)
}
disabled={spec.viewSpec.disabled}
qa={`${name}-init-arr`}
>
<Icon data={Plus} size={14} />
{spec.viewSpec.layoutTitle || null}
</Button>
) : (
<Button
onClick={onItemAdd}
disabled={spec.viewSpec.disabled}
qa={`${name}-add-item`}
>
<Icon data={Plus} size={14} />
{spec.viewSpec.itemLabel || null}
</Button>
)}
</React.Fragment>
<div className={b({'add-button-right': spec.viewSpec.addButtonPosition === 'right'})}>
<div
className={b('items-wrapper', {
'add-button-down':
spec.viewSpec.addButtonPosition !== 'right' && keys.length > 0,
})}
>
{items}
</div>
<AddButton />
</div>
);
};
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';

import {Plus, Xmark} from '@gravity-ui/icons';
import {Plus, TrashBin} from '@gravity-ui/icons';
import {Button, Icon, Table} from '@gravity-ui/uikit';
import _ from 'lodash';

Expand Down Expand Up @@ -93,12 +93,12 @@ export const TableArrayInput: ArrayInput = ({spec, name, arrayInput, input}) =>
sticky: 'right',
template: ({key}: {key: string}) => (
<Button
view="flat"
view="flat-secondary"
onClick={() => onItemRemove(key)}
key={`remove-${key}`}
qa={`${name}-item-remove-${key}`}
>
<Icon data={Xmark} size={16} />
<Icon data={TrashBin} size={16} />
</Button>
),
};
Expand Down
6 changes: 3 additions & 3 deletions src/lib/kit/components/Layouts/Row/Row.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';

import {HelpPopover} from '@gravity-ui/components';
import {Xmark} from '@gravity-ui/icons';
import {TrashBin} from '@gravity-ui/icons';
import {Button, Icon} from '@gravity-ui/uikit';

import {
Expand Down Expand Up @@ -63,12 +63,12 @@ const RowBase = <T extends FieldValue, S extends Spec>({
</ErrorWrapper>
{arrayItem ? (
<Button
view="flat"
view="flat-secondary"
className={b('remove-button')}
onClick={input.onDrop}
qa={`${name}-remove-item`}
>
<Icon data={Xmark} size={16} />
<Icon data={TrashBin} size={16} />
</Button>
) : null}
</div>
Expand Down
6 changes: 3 additions & 3 deletions src/lib/kit/components/Layouts/Row2/Row2.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';

import {Xmark} from '@gravity-ui/icons';
import {TrashBin} from '@gravity-ui/icons';
import {Button, Icon} from '@gravity-ui/uikit';

import {
Expand Down Expand Up @@ -44,12 +44,12 @@ export const Row2 = <T extends FieldValue, S extends Spec>({
</ErrorWrapper>
{isArrayItem(name) ? (
<Button
view="flat"
view="flat-secondary"
className={b('remove-button')}
onClick={input.onDrop}
qa={`${name}-remove-item`}
>
<Icon data={Xmark} size={16} />
<Icon data={TrashBin} size={16} />
</Button>
) : null}
</div>
Expand Down
6 changes: 3 additions & 3 deletions src/lib/kit/components/Layouts/Transparent/Transparent.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';

import {Xmark} from '@gravity-ui/icons';
import {TrashBin} from '@gravity-ui/icons';
import {Button, Icon} from '@gravity-ui/uikit';

import {
Expand Down Expand Up @@ -32,12 +32,12 @@ export const Transparent = <T extends FieldValue, S extends Spec>({
if (arrayItem) {
return (
<Button
view="flat"
view="flat-secondary"
className={b('remove-button')}
onClick={input.onDrop}
qa={`${name}-remove-item`}
>
<Icon data={Xmark} size={16} />
<Icon data={TrashBin} size={16} />
</Button>
);
}
Expand Down
8 changes: 8 additions & 0 deletions src/lib/kit/components/Views/ArrayBaseView/ArrayBaseView.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@import '../../../styles/variables';

.#{$ns}array-base-view {
&__item-prefix {
margin-top: -10px;
margin-bottom: 15px;
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import React from 'react';

import {Label} from '@gravity-ui/uikit';
import _ from 'lodash';

import {ArrayView, Spec, ViewController, isCorrectSpec} from '../../../core';
import {ArrayView, Spec, ViewController, isCorrectSpec} from '../../../../core';
import {block} from '../../../utils';

import './ArrayBaseView.scss';

const b = block('array-base-view');

export const ArrayBaseView: ArrayView = ({spec, name, value = []}) => {
const itemSpecCorrect = React.useMemo(() => isCorrectSpec(spec.items), [spec.items]);
Expand Down Expand Up @@ -36,20 +42,25 @@ export const ArrayBaseView: ArrayView = ({spec, name, value = []}) => {
return null;
}

const showItemPrefix = idx !== 0 && spec.viewSpec.itemPrefix;

return (
<ViewController
spec={itemSpec}
name={`${name}[${idx}]`}
key={`${name}[${idx}]`}
/>
<React.Fragment key={`${name}[${idx}]`}>
{showItemPrefix ? (
<Label size="m" className={b('item-prefix')}>
{spec.viewSpec.itemPrefix}
</Label>
) : null}
<ViewController spec={itemSpec} name={`${name}[${idx}]`} />
</React.Fragment>
);
}),
[value.length, name, getItemSpec],
[value.length, name, getItemSpec, spec.viewSpec.itemPrefix],
);

if (!itemSpecCorrect) {
return null;
}

return <>{items}</>;
return <React.Fragment>{items}</React.Fragment>;
};
1 change: 1 addition & 0 deletions src/lib/kit/components/Views/ArrayBaseView/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ArrayBaseView';
Loading

0 comments on commit de1c422

Please sign in to comment.