Skip to content
This repository has been archived by the owner on May 21, 2024. It is now read-only.

Commit

Permalink
feat: ✨ write rudimentary dynamic forms
Browse files Browse the repository at this point in the history
  • Loading branch information
BSoDium committed May 30, 2022
1 parent 994fc4d commit 2500183
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 43 deletions.
146 changes: 143 additions & 3 deletions src/components/forms/Form.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,44 @@
import React from 'react';
import { FormData } from 'pages/Settings';

export declare interface JsonCategory {
name: string,
tabs: {
name: string,
url: string,
icon: JSX.Element,
fields: FormData
}[],
}

export enum FormElementType {
Text = 'text',
Password = 'password',
Number = 'number',
Checkbox = 'checkbox',
Select = 'select',
Radio = 'radio',
Textarea = 'textarea',
Date = 'date',
Time = 'time',
DateTime = 'datetime',
Hidden = 'hidden',
}

export declare interface FormElement {
name: string,
type: FormElementType,
value: string | number | boolean | File | Date | FormData,
editable?: boolean,
visible?: boolean,
options?: {
[key: string]: string
},
description?: string,
}

export declare interface FormData {
[key: string]: FormElement;
}

export declare interface FormProps {
title: string,
Expand All @@ -13,8 +52,109 @@ export default function Form({ title, formData }: FormProps) {
<div className="form-content">
{Object.entries(formData).map(([key, value]) => (
<div className="form-field" key={key}>
<label htmlFor={key}>{key}</label>
<input type="text" id={key} defaultValue={value as string} />
<label htmlFor={key}>{value.name}</label>
<div className="form-field-content">
{value.type === FormElementType.Text && (
<input
type="text"
id={key}
value={value.value as string}
disabled={!value.editable}
/>
)}
{value.type === FormElementType.Password && (
<input
type="password"
id={key}
value={value.value as string}
disabled={!value.editable}
/>
)}
{value.type === FormElementType.Number && (
<input
type="number"
id={key}
value={value.value as number}
disabled={!value.editable}
/>
)}
{value.type === FormElementType.Checkbox && (
<input
type="checkbox"
id={key}
checked={value.value as boolean}
disabled={!value.editable}
/>
)}
{value.type === FormElementType.Select && (
<select
id={key}
defaultValue={value.value as string}
disabled={!value.editable}
>
{Object.entries(value.options!).map(([optionsKey, optionsValue]) => (
<option key={optionsKey} value={optionsKey}>
{optionsValue}
</option>
))}
</select>
)}
{value.type === FormElementType.Radio && (
<div className="radio-group">
{Object.entries(value.options!).map(([optionsKey, optionsValue]) => (
<div className="radio-option" key={optionsKey}>
<input
type="radio"
id={optionsKey}
name={optionsKey}
value={optionsKey}
checked={optionsKey === optionsValue}
/>
<label htmlFor={optionsKey}>{optionsValue}</label>
</div>
))}
</div>
)}
{value.type === FormElementType.Textarea && (
<textarea
id={key}
value={value.value as string}
disabled={!value.editable}
/>
)}
{value.type === FormElementType.Date && (
<input
type="date"
id={key}
value={value.value as string}
disabled={!value.editable}
/>
)}
{value.type === FormElementType.Time && (
<input
type="time"
id={key}
value={value.value as string}
disabled={!value.editable}
/>
)}
{value.type === FormElementType.DateTime && (
<input
type="datetime"
id={key}
value={value.value as string}
disabled={!value.editable}
/>
)}
{value.type === FormElementType.Hidden && (
<input
type="hidden"
id={key}
value={value.value as string}
disabled={!value.editable}
/>
)}
</div>
</div>
))}
</div>
Expand Down
57 changes: 18 additions & 39 deletions src/pages/Settings.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,11 @@
import MainInterface from 'components/MainInterface';
import TabView, { Tab, TabCategory } from 'components/TabView';
import TabView, { TabCategory } from 'components/TabView';
import React from 'react';
import { useParams } from 'react-router-dom';
import { BiCog, BiLock } from 'react-icons/bi';
import { MdOutlineAccountCircle } from 'react-icons/md';
import { IoBrushOutline } from 'react-icons/io5';
import Form from 'components/forms/Form';

export declare interface JsonCategory {
name: string,
tabs: {
name: string,
url: string,
icon: JSX.Element,
fields: FormData
}[],
}
import Form, { FormElementType, JsonCategory } from 'components/forms/Form';

export class SettingsBody {
static jsonContent: JsonCategory[] = [
Expand All @@ -26,40 +16,37 @@ export class SettingsBody {
name: 'General',
url: 'general',
icon: <BiCog size="1.3em" />,
fields: {
GeneralTestField: 'testvalue',
GeneralTestField2: 'testvalue',
GeneralTestField3: 'testvalue',
GeneralTestField4: 'testvalue',
GeneralTestField5: 'testvalue',
GeneralTestField6: 24,
GeneralTestField7: true,

},
fields: {},
},
{
name: 'Appearance',
url: 'appearance',
icon: <IoBrushOutline size="1.3em" />,
fields: {
AppearanceTestField: 'testvalue',
theme: {
name: 'Theme',
type: FormElementType.Select,
value: 'light',
options: {
light: 'Light',
dark: 'Dark',
},
editable: true,
description: 'The theme of the application',
},
},
},
{
name: 'Authentication',
url: 'authentication',
icon: <BiLock size="1.3em" />,
fields: {
testfield: 'testvalue',
},
fields: {},
},
{
name: 'Accounts',
url: 'accounts',
icon: <MdOutlineAccountCircle size="1.3em" />,
fields: {
testfield: 'testvalue',
},
fields: {},
},

],
Expand All @@ -71,17 +58,13 @@ export class SettingsBody {
name: 'General',
url: 'remote-general',
icon: <BiCog size="1.3em" />,
fields: {
testfield: 'testvalue',
},
fields: {},
},
{
name: 'Appearance',
url: 'remote-appearance',
icon: <IoBrushOutline size="1.3em" />,
fields: {
testfield: 'testvalue',
},
fields: {},
},
],
},
Expand All @@ -100,10 +83,6 @@ export class SettingsBody {
}
}

export declare interface FormData {
[key: string]: string | number | boolean | FormData;
}

export default function Settings({ theme, toggleTheme }: {theme: string, toggleTheme: () => void}) {
const { tabUrl } = useParams();
const content = SettingsBody.getContent();
Expand Down
2 changes: 1 addition & 1 deletion src/sass/themes/_dark.scss
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ $dark: (
card-note-border: #2f2f36,
card-note-text: grey,

input-border: #5a5a5a,
input-border: #2f2f36,
input-outline: #acbed8,
input-bg: #0d1117,
input-focus-bg: rgba(43, 48, 150, 0.068),
Expand Down

0 comments on commit 2500183

Please sign in to comment.