Skip to content
This repository was archived by the owner on May 25, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/demo/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ const App = () => {
}
}}
autoSave
viewer
/>
<Uploader
{...{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useState, useEffect } from 'react';
import { Group } from './form.style';
import ControlGroup from './control-group.component';
import ControlGroup from '../control-group.component';
import UIMapping from './UI/ui-mapping';
import Multiple from './UI/Multiple';
import DeleteButton from './UI/DeleteButton';
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import { FormModelConfig } from '@context';
import { Label } from './bool-line.style';

const BoolLine = ({ value, ...rest }) => {
return value ? (
<FormModelConfig.Consumer>
{({ theme }) => (
<Label htmlFor={rest['ui:name']} className={theme && theme.boolLine}>
<input
type="checkbox"
name={rest['ui:name']}
defaultValue={value === 'true'}
checked={value === 'true'}
readOnly
className="input-value"
/>
<span className="label-text">{rest['ui:label'] || 'Label'}</span>
</Label>
)}
</FormModelConfig.Consumer>
) : null;
};

export default BoolLine;
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import styled from 'styled-components';

export const Label = styled.label`
cursor: pointer;
overflow: hidden;
padding: 0.5em 1em;
& > input[type='checkbox'] {
display: none;

& + .label-text {
display: flex;
height: 1em;
width: fit-content;
align-items: center;
position: relative;
&::before,
&::after {
content: '';
border-radius: 0;
box-sizing: border-box;
}

&::before {
left: 0;
width: 1em;
height: 1em;
margin: 0 8px 0 0;
background: #f7f7f7;
box-shadow: 0 0 1px grey;
display: inline-block;
}
&::after {
left: 1.5px;
width: 0.8em;
height: 0.8em;
opacity: 0;
background: #37b2b2;
transform: translate3d(-20px, 0, 0) scale(0.2);
transition: opacity 0.25s ease-in-out, transform 0.25s ease-in-out;
position: absolute;
}
}

&:checked + .label-text {
&::after {
transform: translate3d(0, 0, 0);
opacity: 1;
}
}
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './bool-line.component';
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import moment from 'moment';
import { FormModelConfig } from '@context';
import { Wrapper, Label, Value } from './date-line.style';

const DateLine = ({ value, format = 'D, MMM YYYY', ...rest }) => {
return value ? (
<FormModelConfig.Consumer>
{({ theme }) => (
<Wrapper className={theme && theme.dateLineViewerClass}>
<Label className="label">{rest['ui:label']}</Label>
<Value className="value">{moment(value).format(format)}</Value>
</Wrapper>
)}
</FormModelConfig.Consumer>
) : null;
};

export default DateLine;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './date-line.component';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './multi-line.component';
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';
import { FormModelConfig } from '@context';
import { Wrapper, Label, Value } from './multi-line.style';

const MultiLine = ({ value, ...rest }) => {
return value ? (
<FormModelConfig.Consumer>
{({ theme }) => (
<Wrapper className={theme && theme.multiLineViewerClass}>
<Label className="label">{rest['ui:label']}</Label>
<Value className="value">{value}</Value>
</Wrapper>
)}
</FormModelConfig.Consumer>
) : null;
};

export default MultiLine;
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import styled from 'styled-components';

export const Wrapper = styled.div`
display: flex;
padding: 8px 0;
flex-direction: column;
`;

export const Label = styled.span`
font-weight: bold;
font-size: 16px;
letter-spacing: 0.4px;
`;

export const Value = styled.p``;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './single-line.component';
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import React from 'react';
import { FormModelConfig } from '@context';
import { Wrapper, Label, Value } from './single-line.style';

const SingleLine = ({ value, ...rest }) => {
return value ? (
<FormModelConfig.Consumer>
{({ theme }) => (
<Wrapper className={theme && theme.singleLineViewerClass}>
<Label className="label">{rest['ui:label']}</Label>
<Value className="value">{value}</Value>
</Wrapper>
)}
</FormModelConfig.Consumer>
) : null;
};

export default SingleLine;
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import styled from 'styled-components';

export const Wrapper = styled.div`
display: flex;
padding: 8px 0;
flex-direction: column;
`;

export const Label = styled.span`
font-weight: bold;
font-size: 16px;
letter-spacing: 0.4px;
`;

export const Value = styled.span``;
67 changes: 67 additions & 0 deletions src/lib/components/FormModel/children/Viewer/UI/ui-mapping.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React from 'react';
import { UITypes } from '@constants';

import SingleLine from './SingleLine';
import MultiLine from './MultiLine';
import ColorLine from './ColorLine';
import DateLine from './DateLine';
import BoolLine from './BoolLine';

const UIMapping = type => {
let component;
switch (type) {
case UITypes.SingleLineTextField:
component = SingleLine;
break;
case UITypes.MultiLineTextField:
component = MultiLine;
break;
case UITypes.DecimalField:
component = SingleLine;
break;
case UITypes.FloatField:
component = SingleLine;
break;
case UITypes.IntegerField:
component = SingleLine;
break;
case UITypes.EmailField:
component = SingleLine;
break;
case UITypes.PhoneField:
component = SingleLine;
break;
case UITypes.TriStateField:
component = SingleLine;
break;
case UITypes.BooleanField:
component = BoolLine;
break;
case UITypes.ColorField:
component = ColorLine;
break;
case UITypes.DateField:
component = props => <DateLine format="D M, YYYY" {...props} />;
break;
case UITypes.DateTimeField:
component = props => <DateLine format="HH:mm a - Do M, YYYY" {...props} />;
break;
case UITypes.TimeField:
component = props => <DateLine format="HH:mm a" {...props} />;
break;
case UITypes.Classifier:
component = SingleLine;
break;
case UITypes.Heading:
component = SingleLine;
break;
case UITypes.Comment:
component = MultiLine;
break;
default:
component = null;
}
return component;
};

export default UIMapping;
1 change: 1 addition & 0 deletions src/lib/components/FormModel/children/Viewer/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './viewer.component';
75 changes: 75 additions & 0 deletions src/lib/components/FormModel/children/Viewer/viewer.component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import React, { useEffect, useState } from 'react';
import ControlGroup from '../control-group.component';
import UIMapping from './UI/ui-mapping';
import { Group, Label } from './viewer.style';

const UI_PARTS = 'ui:parts';

type Props = {
formModel: Object,
parent?: any
};

const ParentLabel = ({ formModel }) =>
formModel['rdf:type'] && formModel['rdf:type'].includes('Multiple') ? (
<Label>{formModel['ui:label']}</Label>
) : null;

const Viewer = ({ formModel, parent }: Props) => {
const [formFields, setFormFields] = useState([]);
const parts = formModel[UI_PARTS];

const getArrayFields = () => {
if (typeof formModel === 'object' && parts) {
setFormFields(Object.keys(parts));
}
};

useEffect(() => {
getArrayFields();
}, [formModel]);

return (
<Group parent={parent}>
{formModel['dc:title'] && <h2>{formModel['dc:title']}</h2>}
<ParentLabel formModel={formModel} />
{formFields.length > 0 &&
formFields.map(item => {
const field = parts[item];
const fieldParts = field && field[UI_PARTS];
const component = field && UIMapping(field['rdf:type']);
const id = (field && field['ui:name']) || item;
/**
* Return null when field doesn't exists
* this avoid to crash app using recursive component
*/
if (!field) return null;
/* eslint no-useless-computed-key: "off" */
const { ['ui:parts']: deleted, ...updatedField } = field;

return fieldParts ? (
<Viewer
{...{
key: item,
formModel: field,
parent: updatedField
}}
/>
) : (
<ControlGroup
key={item}
component={component}
value={field['ui:value']}
fieldData={{ id, ...field, parent }}
/>
);
})}
</Group>
);
};

Viewer.defaultProps = {
parent: null
};

export default Viewer;
23 changes: 23 additions & 0 deletions src/lib/components/FormModel/children/Viewer/viewer.style.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import styled from 'styled-components';

export const Group = styled.div`
padding: ${({ parent }) => (parent ? '0' : '1em')};
${({ parent }) =>
!parent
? `

display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: auto;
`
: `
display: flex;
flex-direction: column;`}
`;

export const Label = styled.span`
font-weight: normal;
font-size: 18px;
letter-spacing: 0.5px;
padding: 4px;
`;
9 changes: 7 additions & 2 deletions src/lib/components/FormModel/form-model.component.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { FormModelConfig } from '@context';
// eslint-disable-next-line import/no-extraneous-dependencies
import { FormActions, formUi } from 'solid-forms';
import Form from './children/Form';
import Viewer from './children/Viewer';

type Props = {
modelPath: String,
Expand All @@ -16,7 +17,7 @@ type Props = {
}
};

const FormModel = memo(({ modelPath, podPath, autoSave, settings = {}, title }: Props) => {
const FormModel = memo(({ modelPath, podPath, autoSave, settings = {}, title, viewer }: Props) => {
const [formModel, setFormModel] = useState({});
const [formObject, setFormObject] = useState({});
const formActions = new FormActions(formModel, formObject);
Expand Down Expand Up @@ -57,7 +58,7 @@ const FormModel = memo(({ modelPath, podPath, autoSave, settings = {}, title }:
init();
}, []);

return (
return !viewer ? (
<FormModelConfig.Provider value={settings}>
<form onSubmit={onSave}>
{title && <h1>Form Model</h1>}
Expand All @@ -78,6 +79,10 @@ const FormModel = memo(({ modelPath, podPath, autoSave, settings = {}, title }:
)}
</form>
</FormModelConfig.Provider>
) : (
<FormModelConfig.Provider value={settings}>
<Viewer {...{ formModel }} />
</FormModelConfig.Provider>
);
});

Expand Down