Skip to content

Latest commit

 

History

History
157 lines (133 loc) · 2.55 KB

README.md

File metadata and controls

157 lines (133 loc) · 2.55 KB

Props

Props contain configurations & data for how we configure Components. Each Node can contain multiple props, & each prop can be considered as having a PropType.

// prettier-ignore
type PropTypeLiteral =
  | 'Default'
  | 'Eval'
  | 'RenderProps'
  | 'LeafRenderProps'

type PropValue = {
  propType: PropTypeLiteral | Array<PropTypeLiteral>
  value: any
}

type Prop = {
  [key: string]: string | PropValue
}

PropTypes

Default

const node = {
  nodeType: 'React',
  type: 'Button',
  props: {
    size: {
      propType: 'Default',
      value: 'large',
    },
  },
}

or simplified to

const node = {
  // ...
  props: {
    size: 'large',
  },
}

Eval

We can also write JavaScript code which is then evaluated to a value.

const node = {
  // ...
  props: {
    secondsInAnHour: {
      propType: 'Eval',
      value: 'return 60 * 60 * 1',
    },
  },
}

Or write a callback function

const node = {
  // ...
  props: {
    onClick: {
      propType: 'Eval',
      value: 'return () => console.log("Clicked!")',
    },
  },
}

In fact our function contains a ctx variable that is passed as argument. This ctx contains libraries like React or lodash

const node = {
  // ...
  props: {
    addItem: {
      propType: 'Eval',
      value: `
        const items = []
        return this.lodash.concat(items, 'Apple')
      `,
    },
  },
}

The this keyword contains all renderProps passed from the parent, so in the above example you may append to props instead

const node = {
  // ...
  props: {
    addItem: {
      propType: 'Eval',
      value: `
        return this.lodash.concat(this.props.items, 'Apple')
      `,
    },
  },
}

RenderProps

So how do we make items accessible from this.props? We can create what's called RenderProps in React. It is just a prop that is passed from the parent to the child.

RenderProps passes 1 level down, while LeafRenderProps passes all the way to the leaf nodes.

const node = {
  // ...
  props: {
    items: {
      propType: 'RenderProps',
      value: ['Orange']
    },
  },
  children: [
    props: {
      addItem: {
        propType: 'Eval',
        value: `
          return this.lodash.concat(this.props.items, 'Apple')
        `,
      },
    },
  ]
}

We can also chain propType like so

const node = {
  // ...
  props: {
    items: {
      propType: ['RenderProps', 'Eval'],
      value: `return []`,
    },
  },
  children: [
    // ...
  ],
}