github.com/resonatecoop/id@v1.1.0-43/frontend/src/components/links-input.js (about)

     1  const html = require('choo/html')
     2  const Component = require('choo/component')
     3  const validateFormdata = require('validate-formdata')
     4  const input = require('@resonate/input-element')
     5  const isURL = require('validator/lib/isURL')
     6  const button = require('@resonate/button')
     7  
     8  // LinksInput class
     9  class LinksInput extends Component {
    10    constructor (id, state, emit) {
    11      super(id)
    12  
    13      this.emit = emit
    14      this.state = state
    15  
    16      this.local = state.components[id] = {}
    17  
    18      this.removeLink = this.removeLink.bind(this)
    19      this.addLink = this.addLink.bind(this)
    20  
    21      this.local.links = []
    22  
    23      this.validator = validateFormdata()
    24      this.form = this.validator.state
    25  
    26      this._onchange = this._onchange.bind(this)
    27    }
    28  
    29    createElement (props) {
    30      this.onchange = typeof props.onchange === 'function' ? props.onchange.bind(this) : this._onchange
    31      this.validator = props.validator || this.validator
    32      this.form = props.form || this.form || {
    33        changed: false,
    34        valid: true,
    35        pristine: {},
    36        required: {},
    37        values: {},
    38        errors: {}
    39      }
    40  
    41      this.local.required = props.required || false
    42  
    43      const pristine = this.form.pristine
    44      const errors = this.form.errors
    45      const values = this.form.values
    46  
    47      return html`
    48        <div class="flex flex-column">
    49          <p>Website, Instagram, Twitter, Mastodon, etc.</p>
    50          <div class="flex items-center mb1">
    51            ${input({
    52              type: 'url',
    53              name: 'link',
    54              invalid: errors.link && !pristine.link,
    55              required: false,
    56              placeholder: 'URL',
    57              value: values.link,
    58              onchange: (e) => {
    59                this.validator.validate(e.target.name, e.target.value)
    60                this.rerender()
    61              }
    62            })}
    63            ${button({
    64              onclick: (e) => this.addLink(values.link, errors.link),
    65              prefix: 'db bg-white bw b--black-20 h-100 ml1 pa3 grow',
    66              style: 'none',
    67              size: 'none',
    68              iconName: 'add',
    69              iconSize: 'sm'
    70            })}
    71            ${!this.local.required ? html`<p class="lh-copy f5 pl2 grey">Optional</p>` : ''}
    72          </div>
    73  
    74          <p class="ma0 pa0 message warning">
    75            ${errors.link && !pristine.link ? errors.link.message : ''}
    76          </p>
    77  
    78          <ul class="list ma0 pa0">
    79            ${this.local.links.map((link, index) => {
    80              return html`
    81                <li class="flex items-center relative">
    82                  ${link}
    83                  ${button({
    84                    onclick: (e) => this.removeLink(index),
    85                    prefix: 'bg-transparent bn ml2 pa0 grow',
    86                    iconName: 'close-fat',
    87                    iconSize: 'xxs',
    88                    style: 'none',
    89                    size: 'none'
    90                  })}
    91                </li>
    92              `
    93            })}
    94          </ul>
    95        </div>
    96      `
    97    }
    98  
    99    _onchange () {}
   100  
   101    removeLink (index) {
   102      if (index > -1) {
   103        this.local.links.splice(index, 1)
   104        this.onchange(this.local.links)
   105        this.rerender()
   106      }
   107    }
   108  
   109    addLink (value, error) {
   110      if (value && !this.local.links.includes(value) && !error) {
   111        this.local.links.push(value)
   112        this.onchange(this.local.links)
   113        this.rerender()
   114      }
   115    }
   116  
   117    load () {
   118      this.validator.field('link', { required: this.local.required }, (data) => {
   119        if (!isURL(data, { require_protocol: false })) { return new Error('Link is not valid url') }
   120      })
   121    }
   122  
   123    update () {
   124      return false
   125    }
   126  }
   127  
   128  module.exports = LinksInput