Skip to content

Commit

Permalink
feat: add flat oneof input, add oneof params to object spec
Browse files Browse the repository at this point in the history
  • Loading branch information
bocembocem committed May 17, 2023
1 parent 0274582 commit 739bdcf
Show file tree
Hide file tree
Showing 16 changed files with 211 additions and 36 deletions.
7 changes: 7 additions & 0 deletions docs/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ type Spec = ArraySpec | BooleanSpec | NumberSpec | ObjectSpec | StringSpec;
| viewSpec.layoutOpen | `boolean` | | Expand [Layout](./config.md#layouts) at the first rendering |
| viewSpec.order | `string[]` | | Array of `properties` keys in the right order |
| viewSpec.link | `any` | | A field containing information for forming a [link](#link) for a value |
| viewSpec.oneOfParams | `object` | | [Parameters](#oneofparams) that must be passed to oneof input |

### StringSpec

Expand Down Expand Up @@ -128,6 +129,12 @@ type Spec = ArraySpec | BooleanSpec | NumberSpec | ObjectSpec | StringSpec;
| language | `string` | yes | Syntax highlighting language |
| fontSize | `string` | | Font size |

#### OneOfParams

| Property | Type | Required | Description |
| :------- | :------------------- | :------: | :---------- |
| toggler | `'select'` `'radio'` | | Switch type |

#### FileInput

| Property | Type | Required | Description |
Expand Down
3 changes: 3 additions & 0 deletions src/lib/core/types/specs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ export interface ObjectSpec<LinkType = any> {
layoutOpen?: boolean;
order?: string[];
link?: LinkType;
oneOfParams?: {
toggler?: 'select' | 'radio';
};
};
}

Expand Down
3 changes: 2 additions & 1 deletion src/lib/kit/components/Card/Card.scss
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,15 @@
&__header-left {
display: flex;
align-items: center;
flex-grow: 1;
}

&__header-right {
display: flex;
align-items: center;

& > * {
margin-left: 5px;
margin-left: 10px;
}
}

Expand Down
60 changes: 38 additions & 22 deletions src/lib/kit/components/Inputs/OneOf/OneOf.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,50 @@
display: flex;
flex-direction: column;

&:last-child {
& > .#{$ns}group-indent {
margin-bottom: 0;
}
}
&_base {
.#{$ns}group-indent {
all: unset;

.#{$ns}group-indent {
all: unset;
& > .#{$ns}use-search {
padding-top: 11px;
padding-left: $normalOffset;
margin-top: 4px;
margin-bottom: 20px;
margin-left: 5px;
border-left: 1px solid var(--yc-color-line-generic-accent);

& > .#{$ns}use-search {
padding-top: 11px;
padding-left: $normalOffset;
margin-top: 4px;
margin-bottom: 20px;
margin-left: 5px;
border-left: 1px solid var(--yc-color-line-generic-accent);
&:empty {
display: none;
}

&:empty {
display: none;
}
&:last-child {
margin-bottom: 0;
}

&:last-child {
margin-bottom: 0;
& > .#{$ns}simple-vertical-accordeon_view {
margin-top: -10px;
}
}
}
}

& > .#{$ns}simple-vertical-accordeon_view {
margin-top: -10px;
}
&_flat {
& > .#{$ns}group-indent {
margin: 0;
border-left: none;
padding: 0;
}
}

&:last-child {
& > .#{$ns}group-indent {
margin-bottom: 0;
}
}

&__toggler {
&_flat {
margin-bottom: 15px;
}
}
}
29 changes: 25 additions & 4 deletions src/lib/kit/components/Inputs/OneOf/OneOf.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,25 @@ import React from 'react';
import _ from 'lodash';

import {GroupIndent} from '../../';
import {Controller, FieldValue, ObjectIndependentInput, ValidateError} from '../../../../core';
import {
Controller,
FieldValue,
ObjectIndependentInput,
ObjectIndependentInputProps,
ValidateError,
} from '../../../../core';
import {useOneOf} from '../../../hooks';
import {block} from '../../../utils';

import './OneOf.scss';

const b = block('oneof');

export const OneOf: ObjectIndependentInput = (props) => {
export interface OneOfProps extends ObjectIndependentInputProps {
withoutIndent?: boolean;
}

const OneOfComponent: React.FC<OneOfProps> = (props) => {
const {oneOfValue, specProperties, toggler} = useOneOf({props});

const parentOnChange = React.useCallback(
Expand All @@ -34,8 +44,13 @@ export const OneOf: ObjectIndependentInput = (props) => {
);

return (
<div className={b()}>
<div>{toggler}</div>
<div
className={b({
base: !props.withoutIndent,
flat: props.withoutIndent,
})}
>
<div className={b('toggler', {flat: props.withoutIndent})}>{toggler}</div>
{specProperties[oneOfValue] ? (
<GroupIndent>
<Controller
Expand All @@ -51,3 +66,9 @@ export const OneOf: ObjectIndependentInput = (props) => {
</div>
);
};

export const OneOf = OneOfComponent;

export const OneOfFlat: ObjectIndependentInput = (props) => (
<OneOfComponent {...props} withoutIndent />
);
11 changes: 11 additions & 0 deletions src/lib/kit/components/Views/OneOfView/OneOfView.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@import '../../../styles/variables';

.#{$ns}oneof-view {
&_flat {
& > .#{$ns}group-indent {
margin: 0 0 20px;
border-left: none;
padding: 0;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,19 @@ import React from 'react';

import _ from 'lodash';

import {GroupIndent} from '../';
import {ObjectIndependentView, ViewController} from '../../../core';
import {GroupIndent} from '../../';
import {ObjectIndependentView, ObjectIndependentViewProps, ViewController} from '../../../../core';
import {block} from '../../../utils';

export const OneOfView: ObjectIndependentView = (props) => {
import './OneOfView.scss';

const b = block('oneof-view');

export interface OneOfViewProps extends ObjectIndependentViewProps {
withoutIndent?: boolean;
}

const OneOfViewComponent: React.FC<OneOfViewProps> = (props) => {
const {value = {}, spec, Layout, name} = props;

const specProperties = React.useMemo(
Expand Down Expand Up @@ -40,7 +49,7 @@ export const OneOfView: ObjectIndependentView = (props) => {
}

return (
<React.Fragment>
<div className={b({flat: props.withoutIndent})}>
{wrappedValue}
{specProperties[valueKey] ? (
<GroupIndent>
Expand All @@ -51,6 +60,12 @@ export const OneOfView: ObjectIndependentView = (props) => {
/>
</GroupIndent>
) : null}
</React.Fragment>
</div>
);
};

export const OneOfView = OneOfViewComponent;

export const OneOfFlatView: ObjectIndependentView = (props) => (
<OneOfViewComponent {...props} withoutIndent />
);
1 change: 1 addition & 0 deletions src/lib/kit/components/Views/OneOfView/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './OneOfView';
4 changes: 4 additions & 0 deletions src/lib/kit/constants/config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import {
OneOf,
OneOfCard,
OneOfCardView,
OneOfFlat,
OneOfFlatView,
OneOfView,
Row,
Row2,
Expand Down Expand Up @@ -128,6 +130,7 @@ export const dynamicConfig: DynamicFormConfig = {
object: {
inputs: {
oneof: {Component: OneOf, independent: true},
oneof_flat: {Component: OneOfFlat, independent: true},
card_oneof: {Component: CardOneOf, independent: true},
secret: {Component: Secret, independent: true},
base: {Component: ObjectBase, independent: true},
Expand Down Expand Up @@ -315,6 +318,7 @@ export const dynamicViewConfig: DynamicViewConfig = {
object: {
views: {
oneof: {Component: OneOfView, independent: true},
oneof_flat: {Component: OneOfFlatView, independent: true},
card_oneof: {Component: CardOneOfView, independent: true},
secret: undefined,
base: {Component: ObjectBaseView, independent: true},
Expand Down
8 changes: 5 additions & 3 deletions src/lib/kit/hooks/useOneOf.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@ export const useOneOf = ({props, onTogglerChange}: UseOneOfParams) => {

const togglerInput = React.useMemo(() => {
if (
options.length > 3 ||
_.some(options, ({title}) => title.length > MAX_TAB_TITLE_LENGTH)
spec.viewSpec.oneOfParams?.toggler !== 'radio' &&
(spec.viewSpec.oneOfParams?.toggler === 'select' ||
options.length > 3 ||
_.some(options, ({title}) => title.length > MAX_TAB_TITLE_LENGTH))
) {
return (
<Select
Expand Down Expand Up @@ -95,7 +97,7 @@ export const useOneOf = ({props, onTogglerChange}: UseOneOfParams) => {
))}
</RadioButton>
);
}, [options, oneOfValue, onOneOfChange, name]);
}, [options, oneOfValue, onOneOfChange, name, spec.viewSpec.oneOfParams?.toggler]);

const toggler = React.useMemo(() => {
if (Layout) {
Expand Down
2 changes: 1 addition & 1 deletion src/stories/ObjectBase.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const baseSpec: ObjectSpec = {

const value = {name: 'Foo', age: 13, license: false};

const excludeOptions = ['description', 'viewSpec.type'];
const excludeOptions = ['description', 'viewSpec.type', 'viewSpec.oneOfParams'];

const template = (spec: ObjectSpec = baseSpec) => {
const Template: ComponentStory<typeof ObjectBase> = (__, {viewMode}) => (
Expand Down
73 changes: 73 additions & 0 deletions src/stories/ObjectOneOfFlat.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React from 'react';

import {ComponentStory} from '@storybook/react';

import {ObjectSpec, OneOfFlat as OneOfFlatBase, SpecTypes} from '../lib';

import {InputPreview} from './components';

export default {
title: 'Object/OneOfFlat',
component: OneOfFlatBase,
};

const baseSpec: ObjectSpec = {
type: SpecTypes.Object,
properties: {
internal: {
required: true,
type: SpecTypes.String,
viewSpec: {type: 'base', layout: 'row', layoutTitle: 'Person id'},
},
empty: {
required: true,
type: SpecTypes.Object,
viewSpec: {type: 'base', layoutTitle: 'Empty'},
},
external: {
required: true,
type: SpecTypes.Object,
properties: {
name: {
type: SpecTypes.String,
viewSpec: {type: 'base', layout: 'row', layoutTitle: 'Name'},
},
age: {
type: SpecTypes.Number,
viewSpec: {type: 'base', layout: 'row', layoutTitle: 'Age'},
},
license: {
type: SpecTypes.Boolean,
viewSpec: {type: 'base', layout: 'row', layoutTitle: 'License'},
},
},
viewSpec: {
type: 'base',
layoutTitle: 'Person data',
},
},
},
description: {
external: 'External candidate',
internal: 'Internal candidate',
empty: 'None',
},
viewSpec: {
type: 'oneof_flat',
layout: 'row',
layoutTitle: 'Candidate',
order: ['external', 'internal', 'empty'],
},
};

const excludeOptions = ['viewSpec.type'];

const template = (spec: ObjectSpec = baseSpec) => {
const Template: ComponentStory<typeof OneOfFlatBase> = (__, {viewMode}) => (
<InputPreview spec={spec} excludeOptions={excludeOptions} viewMode={viewMode} />
);

return Template;
};

export const OneOfFlat = template();
1 change: 1 addition & 0 deletions src/stories/ObjectSecret.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const excludeOptions = [
'viewSpec.order',
'viewSpec.layoutOpen',
'viewSpec.disabled',
'viewSpec.oneOfParams',
];

const template = (spec: ObjectSpec = baseSpec) => {
Expand Down
1 change: 1 addition & 0 deletions src/stories/ObjectTextLink.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const excludeOptions = [
'viewSpec.order',
'viewSpec.layoutOpen',
'viewSpec.disabled',
'viewSpec.oneOfParams',
];

const template = (spec: ObjectSpec = baseSpec) => {
Expand Down
1 change: 1 addition & 0 deletions src/stories/ObjectValue.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const excludeOptions = [
'viewSpec.order',
'viewSpec.layoutOpen',
'viewSpec.disabled',
'viewSpec.oneOfParams',
];

const template = (spec: ObjectSpec = baseSpec) => {
Expand Down
Loading

0 comments on commit 739bdcf

Please sign in to comment.