diff --git a/src/components/Inputs/Checkbox.tsx b/src/components/Inputs/Checkbox.tsx new file mode 100644 index 0000000..ab336bf --- /dev/null +++ b/src/components/Inputs/Checkbox.tsx @@ -0,0 +1,19 @@ +import { Checkbox as PrimerCheckbox, CheckboxProps, FormControl } from '@primer/react'; +import * as React from 'react'; + +export function Checkbox({ + label, value, onChange, checked = value, ...rest +}: Override>) { + return ( + + onChange(e.target.checked)} + {...rest} /> + {label} + + ); +} diff --git a/src/components/SelectInput.tsx b/src/components/Inputs/SelectInput.tsx similarity index 89% rename from src/components/SelectInput.tsx rename to src/components/Inputs/SelectInput.tsx index 9ba17af..1e6051a 100644 --- a/src/components/SelectInput.tsx +++ b/src/components/Inputs/SelectInput.tsx @@ -7,19 +7,18 @@ export type Option = { value: T } +export type SelectInputProps = Override & { + label: React.ReactNode + options: Option[] +}> + export function SelectInput({ value, onChange, label, options, ...selectProps -}: Override< - SelectProps, - IO & { - label: string - options: Option[] - } ->) { +}: SelectInputProps) { return ( = { - key: Key - label: string - wikiLink?: string - tooltip?: string - disabled?: boolean - overwrite?: { - value: (value: Config[Key]) => boolean - onChange: (checked: boolean) => Config[Key] - } -} - -type Props = { - field: SimpleField -} - -export function SimpleToggleField({ field }: Props) { - const { overwrite } = field - const configContext = useConfigs() - const value = configContext.value[field.key] - - const checked = React.useMemo( - () => (overwrite ? overwrite.value(value) : Boolean(value)), - [overwrite, value], - ) - - const handleChange = React.useCallback( - (checked: boolean) => { - const enabled = checked - configContext.onChange({ [field.key]: overwrite ? overwrite.onChange(enabled) : enabled }) - }, - [field.key, overwrite, configContext], - ) - - return ( - - handleChange(e.target.checked)} - checked={checked} - /> - - {field.label} - {(field.wikiLink || field.tooltip) && ' '} - {field.wikiLink ? ( - - (?) - - ) : ( - field.tooltip && ( - - (?) - - ) - )} - - - ) -} diff --git a/src/components/settings/FileTreeSettings.tsx b/src/components/settings/FileTreeSettings.tsx index dae170a..24da05d 100644 --- a/src/components/settings/FileTreeSettings.tsx +++ b/src/components/settings/FileTreeSettings.tsx @@ -1,10 +1,10 @@ import { wikiLinks } from 'components/settings/SettingsBar' -import { SimpleToggleField } from 'components/SimpleToggleField' -import { useConfigs } from 'containers/ConfigsContext' +import { SimpleConfigFieldCheckbox } from 'components/settings/SimpleConfigField/Checkbox' import * as React from 'react' import { Config } from 'utils/config/helper' -import { Option, SelectInput } from '../SelectInput' +import { Option } from '../Inputs/SelectInput' import { SettingsSection } from './SettingsSection' +import { SimpleConfigFieldSelect } from './SimpleConfigField/SelectInput' const iconOptions: Option[] = [ { @@ -38,32 +38,23 @@ const recursiveToggleFolderOptions: Option[] = ] export function FileTreeSettings() { - const configContext = useConfigs() - const { recursiveToggleFolder, icons } = configContext.value return ( - { - configContext.onChange({ - recursiveToggleFolder: v, - }) - }} - value={recursiveToggleFolder} /> - - - label="Icons" + { - configContext.onChange({ - icons: v, - }) - }} - value={icons} /> - - - - [] = +const moreFields: SimpleConfigField<'copyFileButton' | 'copySnippetButton' | 'codeFolding'>[] = platform === GitHub ? [ { @@ -64,7 +65,7 @@ export function SettingsBarContent({ toggleShow }: { toggleShow: () => void }) { {moreFields.map(field => ( - + ))} diff --git a/src/components/settings/SidebarSettings.tsx b/src/components/settings/SidebarSettings.tsx index 952eabc..588b08a 100644 --- a/src/components/settings/SidebarSettings.tsx +++ b/src/components/settings/SidebarSettings.tsx @@ -1,5 +1,5 @@ import { Box, Button, FormControl, TextInput } from '@primer/react' -import { SimpleToggleField } from 'components/SimpleToggleField' +import { SimpleConfigFieldCheckbox } from 'components/settings/SimpleConfigField/Checkbox' import { useConfigs } from 'containers/ConfigsContext' import * as React from 'react' import { friendlyFormatShortcut, noop } from 'utils/general' @@ -13,7 +13,7 @@ export function SidebarSettings() { return ( - ({ + field, +}: SimpleConfigFieldProps) { + const { value, onChange } = useSimpleConfigFieldIO(field) as IO + + return ( + } + disabled={field.disabled} + value={value} + onChange={onChange} + /> + ) +} diff --git a/src/components/settings/SimpleConfigField/FieldLabel.tsx b/src/components/settings/SimpleConfigField/FieldLabel.tsx new file mode 100644 index 0000000..a1bf242 --- /dev/null +++ b/src/components/settings/SimpleConfigField/FieldLabel.tsx @@ -0,0 +1,27 @@ +import * as React from 'react' +import { ConfigKeys } from 'utils/config/helper' +import { SimpleConfigField } from '.' + +export function FieldLabel({ + label, + wikiLink, + tooltip, +}: SimpleConfigField) { + return ( + <> + {label} + {(wikiLink || tooltip) && ' '} + {wikiLink ? ( + + (?) + + ) : ( + tooltip && ( + + (?) + + ) + )} + + ) +} diff --git a/src/components/settings/SimpleConfigField/SelectInput.tsx b/src/components/settings/SimpleConfigField/SelectInput.tsx new file mode 100644 index 0000000..5e185f0 --- /dev/null +++ b/src/components/settings/SimpleConfigField/SelectInput.tsx @@ -0,0 +1,27 @@ +import { SelectInput, SelectInputProps } from 'components/Inputs/SelectInput' +import * as React from 'react' +import { Config, ConfigKeys } from 'utils/config/helper' +import { + SimpleConfigFieldProps, + useSimpleConfigFieldIO +} from '.' +import { FieldLabel } from './FieldLabel' + +export function SimpleConfigFieldSelect({ + field, + options, +}: SimpleConfigFieldProps & { + options: SelectInputProps['options'] +}) { + const { value, onChange } = useSimpleConfigFieldIO(field) + + return ( + } + disabled={field.disabled} + value={value} + onChange={onChange} + options={options} + /> + ) +} diff --git a/src/components/settings/SimpleConfigField/index.tsx b/src/components/settings/SimpleConfigField/index.tsx new file mode 100644 index 0000000..bf607b8 --- /dev/null +++ b/src/components/settings/SimpleConfigField/index.tsx @@ -0,0 +1,37 @@ +import { useConfigs } from 'containers/ConfigsContext' +import React from 'react' +import { Config, ConfigKeys } from 'utils/config/helper' + +export type SimpleConfigField = { + label: string + wikiLink?: string + tooltip?: string + key: Key + disabled?: boolean + overwrite?: { + value: (value: Config[Key]) => Config[Key] + onChange: (newValue: Config[Key]) => Config[Key] + } +} + +export type SimpleConfigFieldProps = { + field: SimpleConfigField +} + +export function useSimpleConfigFieldIO( + field: SimpleConfigField, +): IO { + const { overwrite } = field + const configContext = useConfigs() + const value = configContext.value[field.key] + + return { + value: React.useMemo(() => (overwrite ? overwrite.value(value) : value), [overwrite, value]), + onChange: React.useCallback( + (newValue: Config[Key]) => { + configContext.onChange({ [field.key]: overwrite ? overwrite.onChange(newValue) : newValue }) + }, + [field.key, overwrite, configContext], + ), + } +}