github.com/resonatecoop/id@v1.1.0-43/frontend/src/components/forms/roleSwitcher.js (about) 1 const Component = require('choo/component') 2 const html = require('choo/html') 3 const icon = require('@resonate/icon-element') 4 const morph = require('nanomorph') 5 6 // RoleSwitcher component class 7 class RoleSwitcher extends Component { 8 /*** 9 * Create role switcher component 10 * @param {String} id - The role switcher component id (unique) 11 * @param {Number} state - The choo app state 12 * @param {Function} emit - Emit event on choo app 13 */ 14 constructor (id, state, emit) { 15 super(id) 16 17 this.emit = emit 18 this.state = state 19 20 this.local = state.components[id] = {} 21 22 this.local.value = '' 23 24 this.local.items = [ 25 { value: 'user', name: 'I\'m a listener' }, // for both artists and listeners 26 { value: 'artist', name: 'I\'m an artist' } 27 // { value: 'label', name: 'I am a label' } 28 ] 29 30 this.handleKeyPress = this.handleKeyPress.bind(this) 31 this.updateSelection = this.updateSelection.bind(this) 32 } 33 34 /*** 35 * Create role switcher component element 36 * @param {Object} props - The role switcher component props 37 * @param {String} props.value - Selected value 38 * @returns {HTMLElement} 39 */ 40 createElement (props = {}) { 41 this.local.help = props.help 42 this.local.value = props.value 43 this.onChangeCallback = typeof props.onChangeCallback === 'function' 44 ? props.onChangeCallback 45 : this.onChangeCallback 46 47 return html` 48 <div class="mb3"> 49 ${this.renderItems()} 50 ${this.local.help 51 ? html`<p class="f5 lh-copy">Your account type change should take effect at your next log in.</p>` 52 : '' 53 } 54 </div> 55 ` 56 } 57 58 renderItems () { 59 return html` 60 <div class="items flex flex-auto w-100"> 61 ${this.local.items.map((item, index) => { 62 const { value, name } = item 63 64 const id = 'role-item-' + index 65 66 // item attrs 67 const attrs = { 68 class: `flex flex-auto w-100 ${index < this.local.items.length - 1 ? ' mr3' : ''}` 69 } 70 71 const checked = value === this.local.value 72 73 // input attrs 74 const attrs2 = { 75 onchange: this.updateSelection, 76 id: id, 77 tabindex: -1, 78 name: 'role', 79 type: 'radio', 80 disabled: item.hidden ? 'disabled' : false, 81 checked: checked, 82 value: value 83 } 84 85 // label attrs 86 const attrs3 = { 87 class: `flex items-center justify-center fw4 pv2 w-100 grow bw f5${checked ? ' pr2' : ''}`, 88 style: 'outline:solid 1px var(--near-black);outline-offset:-1px', 89 tabindex: '0', 90 onkeypress: this.handleKeyPress, 91 for: id 92 } 93 94 return html` 95 <div ${attrs}> 96 <input ${attrs2}> 97 <label ${attrs3}> 98 ${checked 99 ? html` 100 <div class="flex flex-shrink-0 justify-center bg-white items-center w2 h2"> 101 ${icon('check', { size: 'sm', class: 'fill-transparent' })} 102 </div> 103 ` 104 : ''} 105 ${name} 106 </label> 107 </div> 108 ` 109 })} 110 </div> 111 ` 112 } 113 114 updateSelection (e) { 115 const val = e.target.value 116 this.local.value = val 117 morph(this.element.querySelector('.items'), this.renderItems()) 118 this.onChangeCallback(this.local.value) 119 } 120 121 handleKeyPress (e) { 122 if (e.keyCode === 13) { 123 e.preventDefault() 124 e.target.control.checked = !e.target.control.checked 125 const val = e.target.control.value 126 this.local.value = val 127 morph(this.element.querySelector('.items'), this.renderItems()) 128 this.onChangeCallback(this.local.value) 129 } 130 } 131 132 handleSubmit (e) { 133 e.preventDefault() 134 135 this.onChangeCallback(this.local.value) 136 } 137 138 onSubmit () {} 139 140 update (props) { 141 return props.value !== this.local.value 142 } 143 } 144 145 module.exports = RoleSwitcher