diff --git a/src/lib/params.tsx b/src/lib/params.tsx new file mode 100644 index 0000000..04b5e46 --- /dev/null +++ b/src/lib/params.tsx @@ -0,0 +1,128 @@ +import React, { ChangeEvent } from "react"; + + +type Validator = {validate: (val: any) => T | undefined} + +interface Parameter { + tryParseAndSet: (str: string) => boolean; + get value(): T; +} + +export class Num implements Parameter { + _value: number; + + get value(): number { + return this._value; + } + + tryParseAndSet = (str: string) => { + const newValue = parseFloat(str); + if (isNaN(newValue)) { + return false; + } + this._value = newValue; + return true; + } + + validate = (val: any) => { + if (typeof val !== 'number') { + return undefined; + } + return val; + } +} + +export class Str implements Parameter { + _value: string; + get value(): string { + return this._value; + } + tryParseAndSet = (str: string) => { + this._value = str; + return true; + } + validate = (val: any) => { + if (typeof val !== 'string') { + return undefined; + } + return val; + } +} + +export class Arr> implements Parameter { + _value: V[]; + _validator: T; + constructor(validator: T) { + this._validator = validator; + } + get value(): V[] { + return this._value; + } + + tryParseAndSet = (str: string) => { + const json = JSON.parse(str); + const res = this.validate(json); + if (res === undefined) { + return false; + } + this._value = res; + return true; + } + + validate = (val: any) => { + if (!Array.isArray(val)) { + return undefined; + } + return val.map(this._validator.validate).every(v => v !== undefined) ? val as V[] : undefined; + } +} + +export type ParameterProps = { + label: string, + value: Parameter +} + +export type State = { + value: Parameter, + error: boolean +} + +export class ParameterComponent extends React.Component, State> { + label: string; + constructor(prop: ParameterProps) { + super(prop); + this.label = prop.label; + this.state = { + value: prop.value, + error: false, + } + } + + onChange(event: ChangeEvent) { + console.log(this) + try { + this.setState({ + value: this.state.value, + error: !this.state.value.tryParseAndSet(event.target.value), + }) + } catch { + this.setState({ + value: this.state.value, + error: true, + }) + } + } + + render(): React.ReactNode { + return
{this.label}: this.onChange(e)}/> {this.state.error && "invalid value"}
+ } + +} + +// export const ParametersComponent = (object: Parameter) => { +// return +// const c = new Arr(new Arr(new Num())) +// console.log(c) +// console.log(c.tryParseAndSet("[[1], [2], [3]]")) +// console.log(c) +// } \ No newline at end of file diff --git a/src/visualizers/bubble-sort/start.tsx b/src/visualizers/bubble-sort/start.tsx index 404b486..262ae98 100644 --- a/src/visualizers/bubble-sort/start.tsx +++ b/src/visualizers/bubble-sort/start.tsx @@ -1,3 +1,4 @@ +import { ParameterComponent, Num, Arr } from "../../lib/params" import { BubbleSortArguments } from "./bubble-sort" // type Props = { @@ -5,8 +6,17 @@ import { BubbleSortArguments } from "./bubble-sort" // } export const BubbleSortStarter = ({ doStart }) => { + + const propArr = { + label: "массив", + value: new Arr(new Num()) + } + + const components = [ {...propArr} />].map((v) =>
  • {v}
  • ); + return
    - - +
      {components}
    + +
    ; }