#176 - updated styles for the autoform fields

This commit is contained in:
Elio Struyf
2022-02-11 11:24:27 +01:00
parent 754570a9ec
commit 849af69ce2
18 changed files with 207 additions and 64 deletions
@@ -1,8 +1,8 @@
import * as React from 'react';
import { Ref } from 'react';
import { HTMLFieldProps, connectField, filterDOMProps } from 'uniforms';
import { LabelStyles } from './component-styles';
import './BoolField.css';
import { LabelField } from './LabelField';
export type BoolFieldProps = HTMLFieldProps<
boolean,
@@ -23,7 +23,7 @@ function Bool({
}: BoolFieldProps) {
return (
<div {...filterDOMProps(props)}>
{label && <label htmlFor={id} style={LabelStyles}>{label}</label>}
<LabelField label={label} id={id} required={props.required} />
<label className="field__toggle">
<input
@@ -0,0 +1,14 @@
.autoform__label {
display: block;
margin-bottom: 0.5rem;
margin-top: 0.5rem;
line-height: 16px;
font-weight: bold;
.autoform__label__required {
color: var(--vscode-inputValidation-errorBorder);
margin-left: 0.25rem;
}
}
@@ -0,0 +1,20 @@
import * as React from 'react';
import { ReactNode } from 'react';
import './LabelField.css';
export interface ILabelFieldProps {
id: string;
label: string | ReactNode;
required?: boolean;
}
export const LabelField: React.FunctionComponent<ILabelFieldProps> = ({ label, id, required }: React.PropsWithChildren<ILabelFieldProps>) => {
return (
label ? (
<label className="autoform__label" htmlFor={id}>
{label}
{required && <span title='Required field' className='autoform__label__required'>*</span>}
</label>
) : null
);
};
@@ -14,7 +14,7 @@
.line {
height: 1px;
background: var(--vscode-editor-foreground);
background: var(--frontmatter-list-border, var(--vscode-editor-foreground));
width: 100%;
margin-right: .5rem;
margin-top: .5rem;
@@ -4,5 +4,5 @@
margin-bottom: 1rem;
margin-top: 1rem;
padding: 10px;
border: 1px solid rgba(255, 255, 255, 0.2);
border: 1px solid var(--frontmatter-list-border, rgba(255, 255, 255, 0.2));
}
@@ -1,12 +1,12 @@
import * as React from 'react';
import { Children, cloneElement, isValidElement } from 'react';
import { HTMLFieldProps, connectField, filterDOMProps } from 'uniforms';
import { LabelStyles } from './component-styles';
import ListAddField from './ListAddField';
import ListItemField from './ListItemField';
import './ListField.css';
import { LabelField } from './LabelField';
export type ListFieldProps = HTMLFieldProps<
unknown[],
@@ -24,11 +24,7 @@ function List({
}: ListFieldProps) {
return (
<div className="autoform__list_field" {...filterDOMProps(props)}>
{label && (
<div style={LabelStyles}>
{label}
</div>
)}
<LabelField label={label} id={props.id} required={props.required} />
{value?.map((item, itemIndex) =>
Children.map(children, (child, childIndex) =>
@@ -2,7 +2,7 @@ import * as React from 'react';
import { HTMLFieldProps, connectField, filterDOMProps } from 'uniforms';
import AutoField from './AutoField';
import { LabelStyles } from './component-styles';
import { LabelField } from './LabelField';
export type NestFieldProps = HTMLFieldProps<
object,
@@ -19,7 +19,8 @@ function Nest({
}: NestFieldProps) {
return (
<div {...filterDOMProps(props)}>
{label && <label style={LabelStyles}>{label}</label>}
<LabelField label={label} id={props.id} required={props.required} />
{children ||
fields.map(field => (
<AutoField key={field} name={field} {...itemProps} />
@@ -1,7 +1,7 @@
import * as React from 'react';
import { Ref } from 'react';
import { HTMLFieldProps, connectField, filterDOMProps } from 'uniforms';
import { LabelStyles } from './component-styles';
import { LabelField } from './LabelField';
export type NumFieldProps = HTMLFieldProps<
number,
@@ -27,7 +27,7 @@ function Num({
}: NumFieldProps) {
return (
<div {...filterDOMProps(props)}>
{label && <label htmlFor={id} style={LabelStyles}>{label}</label>}
<LabelField label={label} id={id} required={props.required} />
<input
disabled={disabled}
@@ -1,7 +1,7 @@
import omit = require('lodash.omit');
import * as React from 'react';
import { HTMLFieldProps, connectField, filterDOMProps } from 'uniforms';
import { LabelStyles } from './component-styles';
import { LabelField } from './LabelField';
const base64: typeof btoa =
typeof btoa === 'undefined'
@@ -33,7 +33,7 @@ function Radio({
}: RadioFieldProps) {
return (
<div {...omit(filterDOMProps(props), ['checkboxes'])}>
{label && <label style={LabelStyles}>{label}</label>}
<LabelField label={label} id={id} required={props.required} />
{allowedValues?.map(item => (
<div key={item}>
@@ -0,0 +1,5 @@
.autoform__select_field {
color: var(--frontmatter-select-foreground, var(--vscode-editor-foreground));
}
@@ -2,7 +2,8 @@ import xor = require('lodash.xor');
import * as React from 'react';
import { Ref } from 'react';
import { HTMLFieldProps, connectField, filterDOMProps } from 'uniforms';
import { LabelStyles } from './component-styles';
import { LabelField } from './LabelField';
import './SelectField.css';
const base64: typeof btoa =
typeof btoa === 'undefined'
@@ -42,8 +43,8 @@ function Select({
}: SelectFieldProps) {
const multiple = fieldType === Array;
return (
<div {...filterDOMProps(props)}>
{label && <label htmlFor={id} style={LabelStyles}>{label}</label>}
<div className='autoform__select_field' {...filterDOMProps(props)}>
<LabelField label={label} id={id} required={required} />
{checkboxes ? (
allowedValues!.map(item => (
@@ -1,7 +1,7 @@
import { Ref } from 'react';
import * as React from 'react';
import { HTMLFieldProps, connectField, filterDOMProps } from 'uniforms';
import { LabelStyles } from './component-styles';
import { LabelField } from './LabelField';
export type TextFieldProps = HTMLFieldProps<
string,
@@ -23,9 +23,12 @@ function Text({
value,
...props
}: TextFieldProps) {
console.log('TextFieldProps', props);
return (
<div {...filterDOMProps(props)}>
{label && <label htmlFor={id} style={LabelStyles}>{label}</label>}
<LabelField label={label} id={id} required={props.required} />
<input
autoComplete={autoComplete}
@@ -1,8 +0,0 @@
export const LabelStyles: React.CSSProperties = {
display: "block",
marginBottom: ".5rem",
marginTop: ".5rem",
lineHeight: "16px",
fontWeight: "bold" };
+11 -3
View File
@@ -4,8 +4,8 @@
:root {
/* Bool field */
--frontmatter-toggle-background: #fafafa;
--frontmatter-toggle-secondaryBackground: #f5f5f5;
--frontmatter-toggle-background: #15c2cb;
--frontmatter-toggle-secondaryBackground: #ADADAD;
/* Errors field */
--frontmatter-error-background: rgba(255, 85, 0, 0.2);
@@ -25,7 +25,15 @@
--frontmatter-field-borderActive: #009aa3;
}
/* List delete field */
/* List field */
--frontmatter-list-border: #ADADAD;
.vscode-dark {
--frontmatter-list-border: #404551;
}
/* Select field */
--frontmatter-select-foreground: #0e131f;
}
@@ -5,8 +5,10 @@ import { AutoFields, AutoForm, ErrorsField } from '../../../components/uniforms-
import { JSONSchemaBridge } from 'uniforms-bridge-json-schema';
import { Field, PanelSettings } from '../../../models';
import { DataCollectionControls } from './DataCollectionControls';
import { PencilIcon, TrashIcon } from '@heroicons/react/outline';
import { CollectionIcon, PencilIcon, TrashIcon } from '@heroicons/react/outline';
import { VsLabel } from '../VscodeComponents';
import { DataCollectionRecord } from './DataCollectionRecord';
import { DataCollectionRecords } from './DataCollectionRecords';
export interface IDataCollectionFieldProps {
label: string;
@@ -92,8 +94,10 @@ export const DataCollectionField: React.FunctionComponent<IDataCollectionFieldPr
onSubmit={onUpdate}
ref={form => form?.reset()}>
{
(model && selectedIndex !== null) && (
(model && selectedIndex !== null) ? (
<h3>Editing: Record {selectedIndex + 1}</h3>
) : (
<h3>Create a new record</h3>
)
}
@@ -109,31 +113,11 @@ export const DataCollectionField: React.FunctionComponent<IDataCollectionFieldPr
</AutoForm>
</div>
{
value && (
<div className='data_collection__list'>
<label>Data</label>
<ul>
{
value.map((v: any, i: number) => (
<li key={i}>
<span>Record {i+1}</span>
<button className='data_collection__list__button data_collection__list__button_edit' onClick={() => setSelectedIndex(i)}>
<PencilIcon className='data_collection__list__button_icon' />
<span className='sr-only'>Edit</span>
</button>
<button className='data_collection__list__button data_collection__list__button_delete' onClick={() => deleteItem(i)}>
<TrashIcon className='data_collection__list__button_icon' />
<span className='sr-only'>Delete</span>
</button>
</li>
))
}
</ul>
</div>
)
}
<DataCollectionRecords
records={value}
onAdd={() => setSelectedIndex(null)}
onEdit={(index: number) => setSelectedIndex(index)}
onDelete={deleteItem} />
</div>
);
};
@@ -0,0 +1,27 @@
import * as React from 'react';
import { PencilIcon, TrashIcon } from '@heroicons/react/outline';
export interface IDataCollectionRecordProps {
id: number;
onEdit: (id: number) => void;
onDelete: (id: number) => void;
}
export const DataCollectionRecord: React.FunctionComponent<IDataCollectionRecordProps> = ({ id, onEdit, onDelete }: React.PropsWithChildren<IDataCollectionRecordProps>) => {
return (
<li>
<span>Record {id+1}</span>
<div>
<button title='Edit record' className='data_collection__list__button data_collection__list__button_edit' onClick={() => onEdit(id)}>
<PencilIcon className='data_collection__list__button_icon' />
<span className='sr-only'>Edit</span>
</button>
<button title='Delete record' className='data_collection__list__button data_collection__list__button_delete' onClick={() => onDelete(id)}>
<TrashIcon className='data_collection__list__button_icon' />
<span className='sr-only'>Delete</span>
</button>
</div>
</li>
);
};
@@ -0,0 +1,47 @@
import { CollectionIcon, PlusIcon } from '@heroicons/react/outline';
import * as React from 'react';
import { VsLabel } from '../VscodeComponents';
import { DataCollectionRecord } from './DataCollectionRecord';
export interface IDataCollectionRecordsProps {
records: any[];
onAdd: () => void;
onEdit: (id: number) => void;
onDelete: (id: number) => void;
}
export const DataCollectionRecords: React.FunctionComponent<IDataCollectionRecordsProps> = ({ records, onAdd, onEdit, onDelete }: React.PropsWithChildren<IDataCollectionRecordsProps>) => {
if (!records || !records.length) {
return null;
}
return (
<div className='data_collection__list'>
<VsLabel>
<div className={`metadata_field__label`} >
<div>
<CollectionIcon style={{ width: "16px", height: "16px" }} />
<span style={{ lineHeight: "16px"}}>Records</span>
</div>
<button title='Add new record' className='data_collection__list__button' onClick={onAdd}>
<PlusIcon style={{ width: "16px", height: "16px" }} />
</button>
</div>
</VsLabel>
<ul>
{
records.map((v: any, i: number) => (
<DataCollectionRecord
key={i}
id={i}
onEdit={onEdit}
onDelete={onDelete} />
))
}
</ul>
</div>
);
};
+50 -5
View File
@@ -1,6 +1,7 @@
.data_collection__field {
border: 1px dashed rgba(255, 255, 255, 0.2);
border: 1px dashed var(--vscode-button-secondaryBackground);
color: var(--vscode--settings-headerForeground);
padding: .5rem 1rem;
margin-bottom: .5rem;
@@ -9,6 +10,12 @@
border: 1px dashed var(--vscode-button-background);
padding: 1rem;
filter: brightness(85%);
h3 {
font-size: 1rem;
font-weight: bold;
text-align: center;
}
}
.fields > div {
@@ -63,27 +70,65 @@
font-weight: bold;
}
ul {
list-style: none;
padding: 0;
margin: 0;
}
li {
margin-bottom: .5rem;
border-bottom: 1px solid var(--vscode-button-secondaryBackground);
display: flex;
justify-content: space-between;
align-items: center;
padding: .5rem 0;
span {
margin-right: .5rem;
}
> div {
display: flex;
justify-content: space-between;
align-items: center;
button:last-child {
margin-left: .5rem;
}
}
&:last-child {
margin-bottom: 0;
border-bottom: 0;
}
}
}
.data_collection__list .metadata_field__label {
justify-content: space-between;
> div {
display: flex;
align-items: center;
}
button svg {
margin-right: 0;
}
}
.data_collection__list__button {
width: auto;
background: none;
color: var(--vscode-editor-foreground);
color: inherit;
outline: none !important;
outline-offset: inherit !important;
padding: 0;
margin: 0;
&:hover {
color: var(--vscode-button-secondaryForeground);
background: var(--vscode-button-secondaryHoverBackground);
color: var(--vscode-editor-foreground);
background: none;
}
}