1import { ComponentType } from 'react';
2import { RegistryItem, Registry } from '../utils/Registry';
3import {
4  NumberFieldConfigSettings,
5  SliderFieldConfigSettings,
6  SelectFieldConfigSettings,
7  StringFieldConfigSettings,
8} from '../field';
9import { OptionEditorConfig } from './options';
10
11/**
12 * Option editor registry item
13 */
14export interface OptionsEditorItem<TOptions, TSettings, TEditorProps, TValue>
15  extends RegistryItem,
16    OptionEditorConfig<TOptions, TSettings, TValue> {
17  /**
18   * React component used to edit the options property
19   */
20  editor: ComponentType<TEditorProps>;
21
22  /*
23   * @param value
24   */
25  getItemsCount?: (value?: TValue) => number;
26}
27
28/**
29 * Describes an API for option editors UI builder
30 */
31export interface OptionsUIRegistryBuilderAPI<
32  TOptions,
33  TEditorProps,
34  T extends OptionsEditorItem<TOptions, any, TEditorProps, any>
35> {
36  addNumberInput?<TSettings extends NumberFieldConfigSettings = NumberFieldConfigSettings>(
37    config: OptionEditorConfig<TOptions, TSettings, number>
38  ): this;
39
40  addSliderInput?<TSettings extends SliderFieldConfigSettings = SliderFieldConfigSettings>(
41    config: OptionEditorConfig<TOptions, TSettings, number>
42  ): this;
43
44  addTextInput?<TSettings extends StringFieldConfigSettings = StringFieldConfigSettings>(
45    config: OptionEditorConfig<TOptions, TSettings, string>
46  ): this;
47
48  addStringArray?<TSettings extends StringFieldConfigSettings = StringFieldConfigSettings>(
49    config: OptionEditorConfig<TOptions, TSettings, string[]>
50  ): this;
51
52  addSelect?<TOption, TSettings extends SelectFieldConfigSettings<TOption>>(
53    config: OptionEditorConfig<TOptions, TSettings, TOption>
54  ): this;
55
56  addRadio?<TOption, TSettings extends SelectFieldConfigSettings<TOption> = SelectFieldConfigSettings<TOption>>(
57    config: OptionEditorConfig<TOptions, TSettings, TOption>
58  ): this;
59
60  addBooleanSwitch?<TSettings = any>(config: OptionEditorConfig<TOptions, TSettings, boolean>): this;
61
62  addUnitPicker?<TSettings = any>(config: OptionEditorConfig<TOptions, TSettings, string>): this;
63
64  addColorPicker?<TSettings = any>(config: OptionEditorConfig<TOptions, TSettings, string>): this;
65
66  /**
67   * Enables custom editor definition
68   * @param config
69   */
70  addCustomEditor<TSettings, TValue>(config: OptionsEditorItem<TOptions, TSettings, TEditorProps, TValue>): this;
71
72  /**
73   * Returns registry of option editors
74   */
75  getRegistry: () => Registry<T>;
76}
77
78export abstract class OptionsUIRegistryBuilder<
79  TOptions,
80  TEditorProps,
81  T extends OptionsEditorItem<TOptions, any, TEditorProps, any>
82> implements OptionsUIRegistryBuilderAPI<TOptions, TEditorProps, T> {
83  private properties: T[] = [];
84
85  addCustomEditor<TSettings, TValue>(config: T & OptionsEditorItem<TOptions, TSettings, TEditorProps, TValue>): this {
86    this.properties.push(config);
87    return this;
88  }
89
90  getRegistry() {
91    return new Registry(() => {
92      return this.properties;
93    });
94  }
95
96  getItems() {
97    return this.properties;
98  }
99}
100