Skip to content

⬅️ Back to Table of Contents

πŸ“„ ConfigEditor

πŸ“Š Analysis Summary

Metric Count
πŸ”§ Functions 4
πŸ“¦ Imports 9
πŸ’  JSX Elements 14
πŸ“ Interfaces 4
πŸ“‘ Type Aliases 1

πŸ“š Table of Contents

πŸ› οΈ File Location:

πŸ“‚ packages/website/src/components/config/ConfigEditor.tsx

πŸ“¦ Imports

Name Source
clsx clsx
useCallback react
useMemo react
useState react
React react
Checkbox ../inputs/Checkbox
Dropdown ../inputs/Dropdown
Text ../inputs/Text
styles ./ConfigEditor.module.css

JSX Elements

Component Type Props Children
label element className={styles.searchResult} , {item.type === 'boolean' ? ( <Checkbox checked={Boolean(value)} indet...
span element className={styles.searchResultDescription} , {item.label &&
}, {item.label && {item.label}}
span element className={styles.searchResultName} {item.key}
br element none none
span element none {item.label}
Checkbox component checked={Boolean(value)}, indeterminate={Boolean(value) && !isDefault(value, ... none
Dropdown component name={config_${item.key}}, onChange={(value): void => onChange(item.key, va... none
div element className={clsx( 'thin-scrollbar', styles.searchResultContainer, className, )}
, {filteredOptions.map(group => (
<h3 classNam...
div element className={styles.searchBar}
Text component name="config-filter", onChange={setFilter}, type="search", value={filter} none
div element key={group.heading}

,

h3 element className={styles.searchResultGroup} {group.heading}
div element none {group.fields.map(item => ( <ConfigEditorField item={item} key={item.key} onC...
ConfigEditorField component item={item}, key={item.key}, onChange={onChange}, value={values[item.key]} none

Functions

filterConfig(options: ConfigOptionsType[], filter: string): ConfigOptionsType[]

Parameters:

  • options ConfigOptionsType[]
  • filter string

Returns: ConfigOptionsType[]

Calls:

  • options .map(group => ({ fields: group.fields.filter(item => item.key.toLowerCase().includes(filter.toLowerCase()), ), heading: group.heading, })) .filter
Code
function filterConfig(
  options: ConfigOptionsType[],
  filter: string,
): ConfigOptionsType[] {
  return options
    .map(group => ({
      fields: group.fields.filter(item =>
        item.key.toLowerCase().includes(filter.toLowerCase()),
      ),
      heading: group.heading,
    }))
    .filter(group => group.fields.length > 0);
}

isDefault(value: unknown, defaults: unknown[]): boolean

Parameters:

  • value unknown
  • defaults unknown[]

Returns: boolean

Calls:

  • defaults.includes
Code
function isDefault(value: unknown, defaults?: unknown[]): boolean {
  return defaults ? defaults.includes(value) : value === true;
}

ConfigEditorField({ item, onChange, value, }: ConfigEditorFieldProps): React.JSX.Element

Parameters:

  • { item, onChange, value, } ConfigEditorFieldProps

Returns: React.JSX.Element

Calls:

  • Boolean
  • isDefault
  • onChange
  • String
Code
function ConfigEditorField({
  item,
  onChange,
  value,
}: ConfigEditorFieldProps): React.JSX.Element {
  return (
    <label className={styles.searchResult}>
      <span className={styles.searchResultDescription}>
        <span className={styles.searchResultName}>{item.key}</span>
        {item.label && <br />}
        {item.label && <span> {item.label}</span>}
      </span>
      {item.type === 'boolean' ? (
        <Checkbox
          checked={Boolean(value)}
          indeterminate={Boolean(value) && !isDefault(value, item.defaults)}
          name={`config_${item.key}`}
          onChange={(checked): void =>
            onChange(
              item.key,
              checked ? (item.defaults?.[0] ?? true) : undefined,
            )
          }
          value={item.key}
        />
      ) : (
        item.enum && (
          <Dropdown
            name={`config_${item.key}`}
            onChange={(value): void => onChange(item.key, value)}
            options={item.enum}
            value={String(value)}
          />
        )
      )}
    </label>
  );
}

ConfigEditor({ className, onChange: onChange…: ConfigEditorProps): React.JSX.Element

Parameters:

  • { className, onChange: onChangeProp, options, values, } ConfigEditorProps

Returns: React.JSX.Element

Calls:

  • useState (from react)
  • useMemo (from react)
  • filterConfig
  • useCallback (from react)
  • onChangeProp
  • clsx (from clsx)
  • filteredOptions.map
  • group.fields.map

Internal Comments:

// Filter out falsy values from the new config (x2)
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete (x2)

Code
function ConfigEditor({
  className,
  onChange: onChangeProp,
  options,
  values,
}: ConfigEditorProps): React.JSX.Element {
  const [filter, setFilter] = useState('');

  const filteredOptions = useMemo(() => {
    return filterConfig(options, filter);
  }, [options, filter]);

  const onChange = useCallback(
    (name: string, value: unknown): void => {
      const newConfig = { ...values };
      if (value === '' || value == null) {
        // Filter out falsy values from the new config
        // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
        delete newConfig[name];
      } else {
        newConfig[name] = value;
      }
      onChangeProp(newConfig);
    },
    [values, onChangeProp],
  );

  return (
    <div
      className={clsx(
        'thin-scrollbar',
        styles.searchResultContainer,
        className,
      )}
    >
      <div className={styles.searchBar}>
        <Text
          name="config-filter"
          onChange={setFilter}
          type="search"
          value={filter}
        />
      </div>
      {filteredOptions.map(group => (
        <div key={group.heading}>
          <h3 className={styles.searchResultGroup}>{group.heading}</h3>
          <div>
            {group.fields.map(item => (
              <ConfigEditorField
                item={item}
                key={item.key}
                onChange={onChange}
                value={values[item.key]}
              />
            ))}
          </div>
        </div>
      ))}
    </div>
  );
}

Interfaces

ConfigOptionsField

Interface Code
export interface ConfigOptionsField {
  defaults?: unknown[];
  enum?: string[];
  key: string;
  label?: string;
  type: 'boolean' | 'string';
}

Properties

Name Type Optional Description
defaults unknown[] βœ“ not shown
enum string[] βœ“ not shown
key string βœ— not shown
label string βœ“ not shown
type 'boolean' \| 'string' βœ— not shown

ConfigOptionsType

Interface Code
export interface ConfigOptionsType {
  fields: ConfigOptionsField[];
  heading: string;
}

Properties

Name Type Optional Description
fields ConfigOptionsField[] βœ— not shown
heading string βœ— not shown

ConfigEditorProps

Interface Code
export interface ConfigEditorProps {
  readonly className?: string;
  readonly onChange: (config: ConfigEditorValues) => void;
  readonly options: ConfigOptionsType[];
  readonly values: ConfigEditorValues;
}

Properties

Name Type Optional Description
className string βœ“ not shown
onChange (config: ConfigEditorValues) => void βœ— not shown
options ConfigOptionsType[] βœ— not shown
values ConfigEditorValues βœ— not shown

ConfigEditorFieldProps

Interface Code
interface ConfigEditorFieldProps {
  readonly item: ConfigOptionsField;
  readonly onChange: (name: string, value: unknown) => void;
  readonly value: unknown;
}

Properties

Name Type Optional Description
item ConfigOptionsField βœ— not shown
onChange (name: string, value: unknown) => void βœ— not shown
value unknown βœ— not shown

Type Aliases

ConfigEditorValues

type ConfigEditorValues = Record<string, unknown>;

Generated by Syntax Scribe