Skip to content

Commit

Permalink
Editable user settings
Browse files Browse the repository at this point in the history
  • Loading branch information
ivanjermakov committed Nov 5, 2024
1 parent f3f68cd commit 41443f9
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 13 deletions.
4 changes: 2 additions & 2 deletions src/component/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ export const input: Input = {

export const userSettingsSchema: Schema = {
type: 'group',
title: 'Settings',
title: 'User settings',
items: {
keyMap: {
type: 'group',
Expand Down Expand Up @@ -748,7 +748,7 @@ export const App: Component = () => {

return (
<div class="App">
<Settings schema={userSettingsSchema} settings={userSettings} />
<Settings schema={userSettingsSchema} settings={userSettings} onChange={setUserSettings} />
<canvas ref={canvas!} />
</div>
)
Expand Down
6 changes: 6 additions & 0 deletions src/component/settings/Settings.module.scss
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
:global .Settings {
padding: 4px;

table, td {
border: none;
}
Expand All @@ -7,4 +9,8 @@
padding-inline: 4px;
padding-block: 2px;
}

input {
width: 10ch;
}
}
40 changes: 34 additions & 6 deletions src/component/settings/Settings.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Accessor, Component, For, Match, Switch } from 'solid-js'
import { Schema, StructuredValue, conformSchema } from '../../schema'
import { Schema, StructuredValue, conformSchema, flattenValue } from '../../schema'
import './Settings.module.scss'

export type SettingsProps = {
schema: Schema
settings: Accessor<any>
onChange?: (settings: any) => void
}

export const Settings: Component<SettingsProps> = props => {
Expand All @@ -13,7 +14,10 @@ export const Settings: Component<SettingsProps> = props => {
<table>
<thead />
<tbody>
<Section value={conformSchema(props.settings(), props.schema)} />
<Section
value={conformSchema(props.settings(), props.schema)}
onChange={v => props.onChange?.(flattenValue(v))}
/>
</tbody>
</table>
</div>
Expand All @@ -22,22 +26,26 @@ export const Settings: Component<SettingsProps> = props => {

export type SectionProps = {
value: StructuredValue
onChange?: (v: StructuredValue) => void
}

const Section: Component<SectionProps> = props => {
const onChange = (key: string, v: StructuredValue) => {
props.onChange?.({ ...props.value, items: { ...(props.value as any).items, [key]: v } } as any)
}
return (
<>
<Switch>
<Match when={props.value.type === 'group'}>
<tr>
<td>{props.value.schema.title}</td>
</tr>
<For each={Object.values(props.value.type === 'group' && props.value.items)}>
{value => <Section value={value} />}
<For each={Object.entries(props.value.type === 'group' && props.value.items)}>
{([key, value]) => <Section value={value} onChange={v => onChange(key, v)} />}
</For>
</Match>
<Match when={true}>
<Setting setting={props.value} />
<Setting setting={props.value} onChange={props.onChange} />
</Match>
</Switch>
</>
Expand All @@ -46,13 +54,33 @@ const Section: Component<SectionProps> = props => {

export type SettingProps = {
setting: StructuredValue
onChange?: (v: StructuredValue) => void
}

const Setting: Component<SettingProps> = props => {
const onInput = (e: Event) => {
const v = (e.target as HTMLInputElement).value
const n = Number.parseInt(v)
if (Number.isNaN(n)) return
props.onChange?.({ ...props.setting, value: v } as any)
}
return (
<tr title={props.setting.schema.description}>
<td>{props.setting.schema.title}</td>
<td>{props.setting.type !== 'group' && props.setting.value}</td>
<td>
<Switch>
<Match when={props.setting.type === 'number'}>
<input
type="number"
value={props.setting.type === 'number' && props.setting.value}
onInput={onInput}
/>
</Match>
<Match when={props.setting.type === 'key'}>
<input type="text" value={props.setting.type === 'key' && props.setting.value} />
</Match>
</Switch>
</td>
</tr>
)
}
9 changes: 9 additions & 0 deletions src/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,16 @@ body {
color: white;
}

input {
background-color: #222222;
color: white;
border: 1px solid #555555;
padding-block: 2px;
padding-inline: 0;
}

* {
box-sizing: border-box;
font-family: monospace;
}

Expand Down
14 changes: 9 additions & 5 deletions src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,19 @@ export const conformSchema = (o: any, schema: Schema): StructuredValue => {
Object.entries(schema.items).map(([key, itemSchema]) => {
if (!(key in o)) throw Error(`no property for key \`${key}\``)
const value = o[key]
if (itemSchema.type === 'group') {
return [key, conformSchema(value, itemSchema)]
} else {
return [key, { schema: itemSchema, value }]
}
return [key, conformSchema(value, itemSchema)]
})
)
}
} else {
return { type: schema.type, schema, value: o }
}
}

export const flattenValue = (value: StructuredValue): Record<string, any> => {
if (value.type === 'group') {
return Object.fromEntries(Object.entries(value.items).map(([key, item]) => [key, flattenValue(item)]))
} else {
return value.value
}
}

0 comments on commit 41443f9

Please sign in to comment.