#523 - number options

This commit is contained in:
Elio Struyf
2023-03-04 11:59:39 +01:00
parent ced176adad
commit 34f5e9c41b
6 changed files with 174 additions and 160 deletions
+1
View File
@@ -16,6 +16,7 @@
### 🎨 Enhancements
- [#522](https://github.com/estruyf/vscode-front-matter/issues/522): Configuration support added for [Astro](https://astro.build)
- [#523](https://github.com/estruyf/vscode-front-matter/issues/523): Added support for `floating`/`decimal` numbers with a new number field property called `numberOptions`
- [#524](https://github.com/estruyf/vscode-front-matter/issues/524): Removed the **Global settings** view from the panel. You can still get it back by configuring a [custom view mode](https://frontmatter.codes/docs/panel#view-modes).
### ⚡️ Optimizations
+148 -153
View File
@@ -10,8 +10,7 @@
"color": "#0e131f",
"theme": "dark"
},
"badges": [
{
"badges": [{
"description": "version",
"url": "https://img.shields.io/github/package-json/v/estruyf/vscode-front-matter?color=green&label=vscode-front-matter&style=flat-square",
"href": "https://github.com/estruyf/vscode-front-matter"
@@ -55,8 +54,7 @@
],
"main": "./dist/extension.js",
"contributes": {
"keybindings": [
{
"keybindings": [{
"command": "frontMatter.dashboard",
"key": "alt+d"
},
@@ -74,24 +72,20 @@
}
],
"viewsContainers": {
"activitybar": [
{
"id": "frontmatter-explorer",
"title": "Front Matter",
"icon": "assets/frontmatter-short-min.svg"
}
]
"activitybar": [{
"id": "frontmatter-explorer",
"title": "Front Matter",
"icon": "assets/frontmatter-short-min.svg"
}]
},
"views": {
"frontmatter-explorer": [
{
"id": "frontMatter.explorer",
"name": "Front Matter",
"icon": "assets/frontmatter-short-min.svg",
"contextualTitle": "Front Matter",
"type": "webview"
}
]
"frontmatter-explorer": [{
"id": "frontMatter.explorer",
"name": "Front Matter",
"icon": "assets/frontmatter-short-min.svg",
"contextualTitle": "Front Matter",
"type": "webview"
}]
},
"configuration": {
"title": "Front Matter: use frontmatter.json for shared team settings",
@@ -126,8 +120,7 @@
"frontMatter.content.defaultFileType": {
"type": "string",
"default": "md",
"oneOf": [
{
"oneOf": [{
"enum": [
"md",
"mdx"
@@ -143,8 +136,7 @@
"frontMatter.content.defaultSorting": {
"type": "string",
"default": "",
"oneOf": [
{
"oneOf": [{
"enum": [
"LastModifiedAsc",
"LastModifiedDesc",
@@ -471,8 +463,7 @@
"command": {
"$id": "#scriptCommand",
"type": "string",
"oneOf": [
{
"oneOf": [{
"enum": [
"node",
"bash",
@@ -646,8 +637,7 @@
"title",
"file"
],
"anyOf": [
{
"anyOf": [{
"required": [
"schema"
]
@@ -701,8 +691,7 @@
"id",
"path"
],
"anyOf": [
{
"anyOf": [{
"required": [
"schema"
]
@@ -1048,8 +1037,7 @@
"default": "",
"description": "The ID of your taxonomy field. It cannot contain the \"tags\" or \"categories\" value.",
"not": {
"anyOf": [
{
"anyOf": [{
"const": ""
},
{
@@ -1093,6 +1081,32 @@
"type": "string"
}
},
"numberOptions": {
"type": "object",
"description": "Specify the options for the number field",
"properties": {
"isDecimal": {
"type": "boolean",
"default": false,
"description": "Specify if the number is a decimal"
},
"min": {
"type": "number",
"default": 0,
"description": "The minimum value"
},
"max": {
"type": "number",
"default": 0,
"description": "The maximum value"
},
"step": {
"type": "number",
"default": 1,
"description": "The step value"
}
}
},
"taxonomyLimit": {
"type": "number",
"default": 0,
@@ -1183,8 +1197,7 @@
"type",
"name"
],
"allOf": [
{
"allOf": [{
"if": {
"properties": {
"type": {
@@ -1342,51 +1355,48 @@
"fields"
]
},
"default": [
{
"name": "default",
"pageBundle": false,
"fields": [
{
"title": "Title",
"name": "title",
"type": "string"
},
{
"title": "Description",
"name": "description",
"type": "string"
},
{
"title": "Publishing date",
"name": "date",
"type": "datetime",
"default": "{{now}}",
"isPublishDate": true
},
{
"title": "Content preview",
"name": "preview",
"type": "image"
},
{
"title": "Is in draft",
"name": "draft",
"type": "boolean"
},
{
"title": "Tags",
"name": "tags",
"type": "tags"
},
{
"title": "Categories",
"name": "categories",
"type": "categories"
}
]
}
],
"default": [{
"name": "default",
"pageBundle": false,
"fields": [{
"title": "Title",
"name": "title",
"type": "string"
},
{
"title": "Description",
"name": "description",
"type": "string"
},
{
"title": "Publishing date",
"name": "date",
"type": "datetime",
"default": "{{now}}",
"isPublishDate": true
},
{
"title": "Content preview",
"name": "preview",
"type": "image"
},
{
"title": "Is in draft",
"name": "draft",
"type": "boolean"
},
{
"title": "Tags",
"name": "tags",
"type": "tags"
},
{
"title": "Categories",
"name": "categories",
"type": "categories"
}
]
}],
"scope": "Taxonomy"
},
"frontMatter.taxonomy.customTaxonomy": {
@@ -1399,8 +1409,7 @@
"type": "string",
"description": "ID for your taxonomy field. It cannot contain the \"tags\" or \"categories\" value.",
"not": {
"anyOf": [
{
"anyOf": [{
"const": ""
},
{
@@ -1582,8 +1591,7 @@
}
}
},
"commands": [
{
"commands": [{
"command": "frontMatter.config.reload",
"title": "Reload config",
"category": "Front Matter"
@@ -1897,15 +1905,12 @@
"category": "Front Matter"
}
],
"submenus": [
{
"id": "frontmatter.submenu",
"label": "Front Matter"
}
],
"submenus": [{
"id": "frontmatter.submenu",
"label": "Front Matter"
}],
"menus": {
"editor/title": [
{
"editor/title": [{
"command": "frontMatter.markup.heading",
"group": "navigation@-133",
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
@@ -1981,14 +1986,11 @@
"when": "frontMatter:enabled == true && frontMatter:dashboard:open == true"
}
],
"explorer/context": [
{
"submenu": "frontmatter.submenu",
"group": "frontmatter@1"
}
],
"frontmatter.submenu": [
{
"explorer/context": [{
"submenu": "frontmatter.submenu",
"group": "frontmatter@1"
}],
"frontmatter.submenu": [{
"command": "frontMatter.createFromTemplate",
"when": "explorerResourceIsFolder",
"group": "frontmatter@1"
@@ -2004,8 +2006,7 @@
"group": "frontmatter@3"
}
],
"commandPalette": [
{
"commandPalette": [{
"command": "frontMatter.init",
"when": "frontMatterCanInit"
},
@@ -2146,8 +2147,7 @@
"when": "frontMatter:file:isValid == true"
}
],
"view/title": [
{
"view/title": [{
"command": "frontMatter.collapseSections",
"group": "navigation@0",
"when": "view == frontMatter.explorer"
@@ -2164,57 +2164,52 @@
}
]
},
"grammars": [
{
"path": "./syntaxes/hugo.tmLanguage.json",
"scopeName": "frontmatter.markdown.hugo",
"injectTo": [
"text.html.markdown"
]
}
],
"walkthroughs": [
{
"id": "frontmatter.welcome",
"title": "Get started with Front Matter",
"description": "Discover the features of Front Matter and learn how to use the CMS for your SSG or static site.",
"steps": [
{
"id": "frontmatter.welcome.init",
"title": "Get started",
"description": "Initial steps to get started.\n[Open dashboard](command:frontMatter.dashboard)",
"media": {
"markdown": "assets/walkthrough/get-started.md"
},
"completionEvents": [
"onContext:frontMatterInitialized"
]
"grammars": [{
"path": "./syntaxes/hugo.tmLanguage.json",
"scopeName": "frontmatter.markdown.hugo",
"injectTo": [
"text.html.markdown"
]
}],
"walkthroughs": [{
"id": "frontmatter.welcome",
"title": "Get started with Front Matter",
"description": "Discover the features of Front Matter and learn how to use the CMS for your SSG or static site.",
"steps": [{
"id": "frontmatter.welcome.init",
"title": "Get started",
"description": "Initial steps to get started.\n[Open dashboard](command:frontMatter.dashboard)",
"media": {
"markdown": "assets/walkthrough/get-started.md"
},
{
"id": "frontmatter.welcome.documentation",
"title": "Documentation",
"description": "Check out the documentation for Front Matter.\n[View our documentation](https://frontmatter.codes/docs)",
"media": {
"markdown": "assets/walkthrough/documentation.md"
},
"completionEvents": [
"onLink:https://frontmatter.codes/docs"
]
"completionEvents": [
"onContext:frontMatterInitialized"
]
},
{
"id": "frontmatter.welcome.documentation",
"title": "Documentation",
"description": "Check out the documentation for Front Matter.\n[View our documentation](https://frontmatter.codes/docs)",
"media": {
"markdown": "assets/walkthrough/documentation.md"
},
{
"id": "frontmatter.welcome.supporter",
"title": "Support the project",
"description": "Become a supporter.\n[Support the project](https://github.com/sponsors/estruyf)",
"media": {
"markdown": "assets/walkthrough/support-the-project.md"
},
"completionEvents": [
"onLink:https://github.com/sponsors/estruyf"
]
}
]
}
]
"completionEvents": [
"onLink:https://frontmatter.codes/docs"
]
},
{
"id": "frontmatter.welcome.supporter",
"title": "Support the project",
"description": "Become a supporter.\n[Support the project](https://github.com/sponsors/estruyf)",
"media": {
"markdown": "assets/walkthrough/support-the-project.md"
},
"completionEvents": [
"onLink:https://github.com/sponsors/estruyf"
]
}
]
}]
},
"scripts": {
"dev:ext": "npm run clean && npm-run-all --parallel watch:*",
@@ -2339,4 +2334,4 @@
"vsce": {
"dependencies": false
}
}
}
+1 -1
View File
@@ -238,7 +238,7 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
return `
<!DOCTYPE html>
<html lang="en">
<html lang="en-US">
<head>
<meta http-equiv="Content-Security-Policy" content="${csp.join('; ')}">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
+10
View File
@@ -104,10 +104,20 @@ export interface Field {
dataFileKey?: string;
dataFileValue?: string;
// Number field options
numberOptions?: NumberOptions;
// When clause
when?: WhenClause;
}
export interface NumberOptions {
isDecimal?: boolean;
min?: number;
max?: number;
step?: number;
}
export enum WhenOperator {
equals = 'eq',
notEquals = 'neq',
@@ -1,32 +1,34 @@
import { CalculatorIcon } from '@heroicons/react/outline';
import * as React from 'react';
import { useEffect, useMemo } from 'react';
import { BaseFieldProps } from '../../../models';
import { useCallback, useEffect, useMemo } from 'react';
import { BaseFieldProps, NumberOptions } from '../../../models';
import { FieldTitle } from './FieldTitle';
import { FieldMessage } from './FieldMessage';
export interface INumberFieldProps extends BaseFieldProps<number | null> {
options?: NumberOptions;
onChange: (nrValue: number | null) => void;
}
export const NumberField: React.FunctionComponent<INumberFieldProps> = ({
label,
description,
options,
value,
required,
onChange
}: React.PropsWithChildren<INumberFieldProps>) => {
const [nrValue, setNrValue] = React.useState<number | null>(value);
const onValueChange = (txtValue: string) => {
let newValue: number | null = parseInt(txtValue);
const onValueChange = useCallback((txtValue: string) => {
let newValue: number | null = options?.isDecimal ? parseFloat(txtValue) : parseInt(txtValue);
if (isNaN(newValue)) {
newValue = null;
}
setNrValue(newValue);
onChange(newValue);
};
}, [options?.isDecimal]);
const showRequiredState = useMemo(() => {
return required && (nrValue === null || nrValue === undefined);
@@ -38,6 +40,8 @@ export const NumberField: React.FunctionComponent<INumberFieldProps> = ({
}
}, [value]);
console.log(`NumberField: ${label} - ${value} - ${JSON.stringify(options)}`)
return (
<div className={`metadata_field ${showRequiredState ? 'required' : ''}`}>
<FieldTitle label={label} icon={<CalculatorIcon />} required={required} />
@@ -46,6 +50,9 @@ export const NumberField: React.FunctionComponent<INumberFieldProps> = ({
type={`number`}
className={`metadata_field__number`}
value={`${nrValue}`}
min={options?.min ?? undefined}
max={options?.max ?? undefined}
step={options?.step ?? undefined}
onChange={(e) => onValueChange(e.target.value)}
/>
@@ -217,7 +217,7 @@ export const WrapperField: React.FunctionComponent<IWrapperFieldProps> = ({
</FieldBoundary>
);
} else if (field.type === 'number') {
let nrValue: number | null = parseInt(fieldValue as string);
let nrValue: number | null = field.numberOptions?.isDecimal ? parseFloat(fieldValue as string) : parseInt(fieldValue as string);
if (isNaN(nrValue)) {
nrValue = null;
}
@@ -228,6 +228,7 @@ export const WrapperField: React.FunctionComponent<IWrapperFieldProps> = ({
key={field.name}
label={field.title || field.name}
description={field.description}
options={field.numberOptions}
onChange={(value) => onSendUpdate(field.name, value, parentFields)}
value={nrValue}
required={!!field.required}