-
Notifications
You must be signed in to change notification settings - Fork 4.3k
/
Copy pathstring-list.js
120 lines (106 loc) · 3.22 KB
/
string-list.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import ArrayProxy from '@ember/array/proxy';
import Component from '@glimmer/component';
import autosize from 'autosize';
import { action } from '@ember/object';
import { set } from '@ember/object';
import { next } from '@ember/runloop';
import { tracked } from '@glimmer/tracking';
import { addToArray } from 'vault/helpers/add-to-array';
import { removeFromArray } from 'vault/helpers/remove-from-array';
/**
* @module StringList
*
* @example
* <StringList @label="My label" @inputValue={{array "one" "two"}} />
*
* @param {string} label - Text displayed in the header above all the inputs.
* @param {function} onChange - Function called when any of the inputs change.
* @param {string} inputValue - A string or an array of strings.
* @param {string} helpText - Text displayed as a tooltip.
* @param {string} type=array - Optional type for inputValue.
* @param {string} attrName - We use this to check the type so we can modify the tooltip content.
* @param {string} subText - Text below the label.
*/
export default class StringList extends Component {
@tracked indicesWithComma = [];
constructor() {
super(...arguments);
// inputList is type ArrayProxy, so addObject etc are fine here
this.inputList = ArrayProxy.create({
// trim the `value` when accessing objects
content: [],
objectAtContent: function (idx) {
const obj = this.content.objectAt(idx);
if (obj && obj.value) {
set(obj, 'value', obj.value.trim());
}
return obj;
},
});
this.type = this.args.type || 'array';
this.setType();
next(() => {
this.toList();
this.addInput();
});
}
setType() {
const list = this.inputList;
if (!list) {
return;
}
this.type = typeof list;
}
toList() {
let input = this.args.inputValue || [];
const inputList = this.inputList;
if (typeof input === 'string') {
input = input.split(',');
}
inputList.addObjects(input.map((value) => ({ value })));
}
toVal() {
const inputs = this.inputList.filter((x) => x.value).map((x) => x.value);
if (this.args.type === 'string') {
return inputs.join(',');
}
return inputs;
}
@action
autoSize(element) {
autosize(element.querySelector('textarea'));
}
@action
autoSizeUpdate(element) {
autosize.update(element.querySelector('textarea'));
}
@action
inputChanged(idx, event) {
if (event.target.value.includes(',') && !this.indicesWithComma.includes(idx)) {
this.indicesWithComma = addToArray(this.indicesWithComma, idx);
}
if (!event.target.value.includes(',')) {
this.indicesWithComma = removeFromArray(this.indicesWithComma, idx);
}
const inputObj = this.inputList.objectAt(idx);
set(inputObj, 'value', event.target.value);
this.args.onChange(this.toVal());
}
@action
addInput() {
const [lastItem] = this.inputList.slice(-1);
if (lastItem?.value !== '') {
this.inputList.pushObject({ value: '' });
}
}
@action
removeInput(idx) {
const itemToRemove = this.inputList.objectAt(idx);
this.inputList.removeObject(itemToRemove);
this.args.onChange(this.toVal());
}
}