Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@skava/ui / src / forms / input / InputChain.tsx
Size: Mime:
/* eslint-disable brace-style */
import React from 'react'
import { EMPTY_OBJ, isObj, fromCollectionToObj } from 'exotic'
import { action } from 'xmobx/mobx'
import { InputStateType, ObserverInputProps } from './typings'

// @todo import from proper place @@perf @dupe
const isReactProps = (props: any) => Object.isExtensible(props) === false

export interface InputChainMap extends Map<string, any> {
  get(key: string): any
  set(key: string, value: any): this

  get(key: 'state'): InputStateType
  set(key: 'state', value: InputStateType): this

  get(key: 'props'): ObserverInputProps
  set(key: 'props', value: ObserverInputProps): this
}

/**
 * @todo the input should have the aria-error props and that should be tested in a unit test
 */
class InputChain<Props = any, State = any> extends React.Component<
  Props,
  State
  > {
  // static isSatisfiedByProps(props: Props): boolean {
  //   return true
  // }
  // validate(): void {}

  // @note - these were in ReactChain - flattening inheritence
  store: InputChainMap = new Map(Object.entries({
    props: EMPTY_OBJ,
    state: EMPTY_OBJ,
  }) as any)

  get(key: string) {
    return this.store.get(key)
  }
  has(key: string) {
    return this.store.has(key)
  }
  clear() {
    this.store.clear()
    return this
  }
  set(key: string, value: any) {
    this.store.set(key, value)
    return this
  }
  delete(key: string) {
    this.store.delete(key)
    return this
  }
  merge(obj: Object) {
    Object.keys(obj).forEach(key => {
      let val = obj[key]
      if (this.has(key)) {
        val = [this.get(key), val]
      }
      return this.set(key, val)
    })
    return this
  }
  entries() {
    return fromCollectionToObj(this.store)
  }

  /**
   * @note - had to change to this for testing & react warnings
   * @note - make sure it's always an object
   */
  setPluginState(state: InputStateType) {
    if (isObj(state) === false) {
      console.warn(
        'tried to set non object `state` in `InputChain` - expand for stack trace'
      )
      return this.store.set('state', {})
    } else {
      return this.store.set('state', state)
    }
  }
  /**
   * @action
   */
  setPluginProps(props: Props) {
    if (isObj(props) === false) {
      // @todo default to EMPTY_OBJ?
      console.warn(
        'tried to set non object `props` in `InputChain` - expand for stack trace'
      )
      return this.store.set('props', {})
    } else {
      return this.store.set('props', props)
    }
  }

  /**
   * @action
   */
  set isValid(isValid: boolean) {
    // hm, will also  put  on state
    this.set('isValid', isValid)
    this.get('state').isValidInput = isValid
  }
  /**
   * may also want to do relational
   *
   * @sriaarthi
   * @example
   *  - this can be done the same with `isEnabled`
   *    and would allow only being enabled once
   *    this.parent.get('add-to-account').isSelected
   */
  get isValid(): boolean {
    const isValidInput = this.get('state').isValidInput
    return isValidInput
  }

  /**
   * === added these since they were commmon ===
   */
  /**
   * @computed
   */
  get type(): string {
    return this.get('state').value || this.get('props').value
  }
  /**
   * @action
   */
  @action.bound
  setValue(value: any): void {
    this.get('state').value = value
    // return this
  }
  /**
   * @computed
   */
  getValue() {
    return this.get('state').value
  }
}

export { InputChain }
export default InputChain