mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-08-09 10:22:55 +02:00
#176 - updated styles for the autoform fields
This commit is contained in:
@@ -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" };
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user