mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-08-07 01:13:08 +02:00
#108 - Choice field support added
This commit is contained in:
+2
-1
@@ -7,7 +7,8 @@
|
||||
- [#103](https://github.com/estruyf/vscode-front-matter/issues/103): Added title and description field to the metadata section
|
||||
- [#104](https://github.com/estruyf/vscode-front-matter/issues/104): Allow to set images in front matter from the metadata panel section
|
||||
- [#105](https://github.com/estruyf/vscode-front-matter/issues/105): Content Type support with backwards compatibility
|
||||
- [#107](https://github.com/estruyf/vscode-front-matter/issues/107): Number field support added in content types fields
|
||||
- [#107](https://github.com/estruyf/vscode-front-matter/issues/107): Number field support added in content type fields
|
||||
- [#108](https://github.com/estruyf/vscode-front-matter/issues/108): Choice field support added in content type fields
|
||||
|
||||
## [3.1.0] - 2021-09-10
|
||||
|
||||
|
||||
@@ -451,6 +451,19 @@ input:checked + .field__toggle__slider:before {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.metadata_field__choice {
|
||||
border: 1px solid var(--vscode-inputValidation-infoBorder) !important;
|
||||
outline: none !important;
|
||||
width: 100%;
|
||||
padding: var(--input-padding-vertical) var(--input-padding-horizontal);
|
||||
color: var(--vscode-input-foreground);
|
||||
background-color: var(--vscode-input-background);
|
||||
}
|
||||
|
||||
.metadata_field__choice::placeholde {
|
||||
color: var(--vscode-input-placeholderForeground);
|
||||
}
|
||||
|
||||
.metadata_field__datetime {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
@@ -175,9 +175,19 @@ Front Matter its metadata section supports the following fields:
|
||||
- `datetime`
|
||||
- `boolean`
|
||||
- `image`
|
||||
- `choice`
|
||||
- `tags`: mapped to the tags defined in your settings.
|
||||
- `categories`: mapped to the categories defined in your settings.
|
||||
|
||||
### Field properties
|
||||
|
||||
A field consists out of the following properties:
|
||||
|
||||
- `title`: The title to show in the metadata section (optional);
|
||||
- `name`: The name of your field, will be used to set in the front matter of your Markdown file;
|
||||
- `type`: One of the above supported types;
|
||||
- `choices`: When you picked the `choice` field type, you need to return an array of choices: `["Choice 1", "Choice 2", "Choice 3"]`.
|
||||
|
||||
## Creating a template
|
||||
|
||||
To make sure that your type of content is already defined when creating a new Markdown file. It will be easier to set the type of content within a template.
|
||||
|
||||
@@ -337,6 +337,7 @@
|
||||
"datetime",
|
||||
"boolean",
|
||||
"image",
|
||||
"choice",
|
||||
"tags",
|
||||
"categories"
|
||||
],
|
||||
@@ -349,6 +350,13 @@
|
||||
"title": {
|
||||
"type": "string",
|
||||
"description": "Title to show in the UI"
|
||||
},
|
||||
"choices": {
|
||||
"type": "array",
|
||||
"description": "Define your choices",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
|
||||
@@ -26,7 +26,8 @@ export interface ContentType {
|
||||
export interface Field {
|
||||
title?: string;
|
||||
name: string;
|
||||
type: "string" | "number" | "datetime" | "boolean" | "image" | "tags" | "categories";
|
||||
type: "string" | "number" | "datetime" | "boolean" | "image" | "choice" | "tags" | "categories";
|
||||
choices?: string[];
|
||||
}
|
||||
|
||||
export interface DateInfo {
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
import { CheckIcon } from '@heroicons/react/outline';
|
||||
import * as React from 'react';
|
||||
import { VsLabel } from '../VscodeComponents';
|
||||
|
||||
export interface IChoiceFieldProps {
|
||||
label: string;
|
||||
selected: string;
|
||||
choices: string[];
|
||||
onChange: (value: string) => void;
|
||||
}
|
||||
|
||||
export const ChoiceField: React.FunctionComponent<IChoiceFieldProps> = ({label, selected, choices, onChange}: React.PropsWithChildren<IChoiceFieldProps>) => {
|
||||
const [ crntSelected, setCrntSelected ] = React.useState<string | null>(selected);
|
||||
|
||||
const onValueChange = (txtValue: string) => {
|
||||
setCrntSelected(txtValue);
|
||||
onChange(txtValue);
|
||||
};
|
||||
|
||||
const containsSelected = selected && choices.indexOf(selected) !== -1;
|
||||
|
||||
return (
|
||||
<div className={`metadata_field`}>
|
||||
<VsLabel>
|
||||
<div className={`metadata_field__label`}>
|
||||
<CheckIcon style={{ width: "16px", height: "16px" }} /> <span style={{ lineHeight: "16px"}}>{label}</span>
|
||||
</div>
|
||||
</VsLabel>
|
||||
|
||||
<select
|
||||
value={crntSelected || ""}
|
||||
placeholder={`Select from your ${label}`}
|
||||
className={`metadata_field__choice`}
|
||||
onChange={(e) => onValueChange(e.currentTarget.value)}>
|
||||
{ !containsSelected && <option value='' disabled hidden></option> }
|
||||
{choices.map((choice, index) => (
|
||||
<option key={index} value={choice} selected={crntSelected === selected}>{choice}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -11,12 +11,13 @@ import { TagPicker } from './TagPicker';
|
||||
import { parseJSON } from 'date-fns';
|
||||
import { DateTimeField } from './Fields/DateTimeField';
|
||||
import { TextField } from './Fields/TextField';
|
||||
|
||||
import "react-datepicker/dist/react-datepicker.css";
|
||||
import { PreviewImageField } from './Fields/PreviewImageField';
|
||||
import { DEFAULT_CONTENT_TYPE, DEFAULT_CONTENT_TYPE_NAME } from '../../constants/ContentType';
|
||||
import { ListUnorderedIcon } from './Icons/ListUnorderedIcon';
|
||||
import { NumberField } from './Fields/NumberField';
|
||||
import { ChoiceField } from './Fields/ChoiceField';
|
||||
|
||||
export interface IMetadataProps {
|
||||
settings: PanelSettings | undefined;
|
||||
metadata: { [prop: string]: string[] | string | null };
|
||||
@@ -127,6 +128,18 @@ export const Metadata: React.FunctionComponent<IMetadataProps> = ({settings, met
|
||||
value={metadata[field.name] as string}
|
||||
onChange={(value => sendUpdate(field.name, value))} />
|
||||
);
|
||||
} else if (field.type === 'choice') {
|
||||
const choices = field.choices || [];
|
||||
const choiceValue = metadata[field.name];
|
||||
|
||||
return (
|
||||
<ChoiceField
|
||||
key={field.name}
|
||||
label={field.title || field.name}
|
||||
selected={choiceValue as string}
|
||||
choices={choices}
|
||||
onChange={(value => sendUpdate(field.name, value))} />
|
||||
);
|
||||
} else if (field.type === 'tags') {
|
||||
return (
|
||||
<TagPicker
|
||||
|
||||
Reference in New Issue
Block a user