Skip to content

Commit

Permalink
feat(ObjectBase): add inline variant (#104)
Browse files Browse the repository at this point in the history
  • Loading branch information
DakEnviy authored Sep 5, 2023
1 parent 65283d6 commit 31480c3
Show file tree
Hide file tree
Showing 10 changed files with 214 additions and 45 deletions.
19 changes: 19 additions & 0 deletions src/lib/kit/components/Inputs/ObjectBase/ObjectBase.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@import '../../../styles/variables.scss';

.#{$ns}object-base {
&__content {
&_inline {
display: flex;

& > .#{$ns}use-search {
width: 150px;
margin-bottom: 0;
margin-right: 8px;

&:last-child {
margin-right: 0;
}
}
}
}
}
44 changes: 35 additions & 9 deletions src/lib/kit/components/Inputs/ObjectBase/ObjectBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,28 @@ import {
FieldObjectValue,
FieldValue,
ObjectIndependentInput,
ObjectIndependentInputProps,
ObjectValue,
Spec,
ValidateError,
transformArrIn,
} from '../../../../core';
import {block, filterPropertiesForObjectInline} from '../../../utils';

export const ObjectBase: ObjectIndependentInput = ({spec, name, Layout, ...restProps}) => {
import './ObjectBase.scss';

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

export interface ObjectBaseProps extends ObjectIndependentInputProps {
inline?: boolean;
}

export const ObjectBase: React.FC<ObjectBaseProps> = ({
inline,
spec,
name,
Layout,
...restProps
}) => {
const addBtn = React.useMemo(
() => (
<Button
Expand Down Expand Up @@ -49,18 +64,24 @@ export const ObjectBase: ObjectIndependentInput = ({spec, name, Layout, ...restP
);

const content = React.useMemo(() => {
if (!_.isObjectLike(spec.properties) || !Object.keys(spec.properties || {}).length) {
if (
!spec.properties ||
!_.isObjectLike(spec.properties) ||
!Object.keys(spec.properties || {}).length
) {
return null;
}

if (!restProps.input.value) {
if (!inline && !restProps.input.value) {
return addBtn;
}

const specProperties = {...spec.properties} as Record<string, Spec>;
const specProperties = inline
? filterPropertiesForObjectInline(spec.properties)
: spec.properties;

return (
<React.Fragment>
<div className={b('content', {inline})}>
{(spec.viewSpec.order || Object.keys(specProperties)).map((property: string) =>
specProperties[property] ? (
<Controller
Expand All @@ -73,16 +94,17 @@ export const ObjectBase: ObjectIndependentInput = ({spec, name, Layout, ...restP
/>
) : null,
)}
</React.Fragment>
</div>
);
}, [
spec.properties,
spec.viewSpec.order,
name,
restProps.input.value,
restProps.input.parentOnUnmount,
inline,
addBtn,
name,
parentOnChange,
restProps.input.parentOnUnmount,
]);

if (!Layout || !content) {
Expand All @@ -95,3 +117,7 @@ export const ObjectBase: ObjectIndependentInput = ({spec, name, Layout, ...restP
</Layout>
);
};

export const ObjectInline: ObjectIndependentInput = (props) => {
return <ObjectBase {...props} inline />;
};
36 changes: 0 additions & 36 deletions src/lib/kit/components/Views/ObjectBaseView.tsx

This file was deleted.

19 changes: 19 additions & 0 deletions src/lib/kit/components/Views/ObjectBaseView/ObjectBaseView.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
@import '../../../styles/variables.scss';

.#{$ns}object-base-view {
&__content {
&_inline {
display: flex;

& > div {
flex: auto;
margin-right: 8px;
margin-bottom: 0;

&:last-child {
margin-right: 0;
}
}
}
}
}
58 changes: 58 additions & 0 deletions src/lib/kit/components/Views/ObjectBaseView/ObjectBaseView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React from 'react';

import _ from 'lodash';

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

import './ObjectBaseView.scss';

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

export interface ObjectBaseViewProps extends ObjectIndependentViewProps {
inline?: boolean;
}

export const ObjectBaseView: React.FC<ObjectBaseViewProps> = ({
inline,
spec,
name,
Layout,
...restProps
}) => {
if (!spec.properties || !_.isObjectLike(spec.properties)) {
return null;
}

const specProperties = inline
? filterPropertiesForObjectInline(spec.properties)
: spec.properties;

const content = (
<div className={b('content', {inline})}>
{(spec.viewSpec.order || Object.keys(specProperties)).map((property: string) =>
specProperties[property] ? (
<ViewController
spec={specProperties[property]}
name={`${name ? name + '.' : ''}${property}`}
key={`${name ? name + '.' : ''}${property}`}
/>
) : null,
)}
</div>
);

if (!Layout) {
return content;
}

return (
<Layout spec={spec} name={name} {...restProps}>
{content}
</Layout>
);
};

export const ObjectInlineView: ObjectIndependentView = (props) => {
return <ObjectBaseView {...props} inline />;
};
1 change: 1 addition & 0 deletions src/lib/kit/components/Views/ObjectBaseView/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ObjectBaseView';
6 changes: 6 additions & 0 deletions src/lib/kit/constants/config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import {
NumberWithScaleView,
ObjectBase,
ObjectBaseView,
ObjectInline,
ObjectInlineView,
ObjectValueInput,
ObjectValueInputView,
OneOf,
Expand Down Expand Up @@ -144,6 +146,7 @@ export const dynamicConfig: DynamicFormConfig = {
object_value: {Component: ObjectValueInput, independent: true},
multi_oneof: {Component: MultiOneOf, independent: true},
multi_oneof_flat: {Component: MultiOneOfFlat, independent: true},
inline: {Component: ObjectInline, independent: true},
},
layouts: {
row: Row,
Expand Down Expand Up @@ -246,6 +249,7 @@ export const dynamicCardConfig: DynamicFormConfig = {
object_value: {Component: ObjectValueInput, independent: true},
multi_oneof: {Component: MultiOneOf, independent: true},
multi_oneof_flat: {Component: MultiOneOfFlat, independent: true},
inline: {Component: ObjectInline, independent: true},
},
layouts: {
row: Row2,
Expand Down Expand Up @@ -341,6 +345,7 @@ export const dynamicViewConfig: DynamicViewConfig = {
object_value: {Component: ObjectValueInputView, independent: true},
multi_oneof: {Component: MultiOneOfView, independent: true},
multi_oneof_flat: {Component: MultiOneOfFlatView, independent: true},
inline: {Component: ObjectInlineView, independent: true},
},
layouts: {
row: ViewRow,
Expand Down Expand Up @@ -427,6 +432,7 @@ export const dynamicViewCardConfig: DynamicViewConfig = {
object_value: {Component: ObjectValueInputView, independent: true},
multi_oneof: {Component: MultiOneOfView, independent: true},
multi_oneof_flat: {Component: MultiOneOfFlatView, independent: true},
inline: {Component: ObjectInlineView, independent: true},
},
layouts: {
row: ViewRow2,
Expand Down
1 change: 1 addition & 0 deletions src/lib/kit/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './cn';
export * from './common';
export * from './bigIntMath';
export * from './objectInline';
9 changes: 9 additions & 0 deletions src/lib/kit/utils/objectInline.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import {Spec, isNumberSpec, isStringSpec} from '../../core';

export const filterPropertiesForObjectInline = (properties: Record<string, Spec>) => {
return Object.fromEntries(
Object.entries(properties).filter(
([, propSpec]) => isStringSpec(propSpec) || isNumberSpec(propSpec),
),
);
};
66 changes: 66 additions & 0 deletions src/stories/ObjectInline.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React from 'react';

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

import {ObjectInline as ObjectInlineBase, ObjectSpec, SpecTypes} from '../lib';

import {InputPreview} from './components';

export default {
title: 'Object/Inline',
component: ObjectInlineBase,
};

const baseSpec: ObjectSpec = {
type: SpecTypes.Object,
properties: {
type: {
type: SpecTypes.String,
enum: ['first', 'second', 'third'],
viewSpec: {
type: 'select',
placeholder: 'Choose type',
layout: 'transparent',
layoutTitle: 'Type',
},
},
name: {
type: SpecTypes.String,
viewSpec: {
type: 'base',
placeholder: 'Type your name',
layout: 'transparent',
layoutTitle: 'Name',
},
},
},
viewSpec: {
type: 'inline',
layout: 'row',
layoutTitle: 'Candidate',
},
};

const value = {type: 'first', name: 'Foo'};

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

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

return Template;
};

export const Inline = template();

0 comments on commit 31480c3

Please sign in to comment.