Skip to content

Commit 7895785

Browse files
committed
feat: map setting type
Do I use it? No. Maybe someone will. Maybe I will later.
1 parent 8d4fe54 commit 7895785

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed

src/utils/settings/types/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ export { default as Remove } from './remove.js';
77
export { default as Select } from './select.js';
88
export { default as Slider } from './slider.js';
99
export { default as Text } from './text.js';
10+
export { default as MapType } from './map.js';

src/utils/settings/types/map.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import Setting from './array.js';
2+
3+
export default class MapList extends Setting {
4+
constructor(name = 'map') {
5+
super(name);
6+
}
7+
8+
default() {
9+
return new Map();
10+
}
11+
12+
element(val = new Map(), update, { container }) {
13+
const data = [...val.entries()];
14+
function invalid(text) {
15+
return data.some(([value]) => value === text);
16+
}
17+
function add(value) {
18+
function save(remove) {
19+
if (remove) data.splice(data.indexOf(value), 1);
20+
update(data.filter(([key]) => key));
21+
}
22+
container.append(createItem({ value, save, invalid }));
23+
}
24+
data.forEach(add);
25+
return $('<button class="btn btn-success glyphicon glyphicon-plus">').on('click', () => {
26+
const item = ['', ''];
27+
data.push(item);
28+
add(item);
29+
});
30+
}
31+
32+
encode(value = []) {
33+
if (value instanceof Map) {
34+
return super.encode([...value.entries()]);
35+
}
36+
return super.encode(value);
37+
}
38+
39+
styles() {
40+
return [
41+
'{ border-top: 1px solid white; border-bottom: 1px solid white; padding: 5px 0; }',
42+
'label { align-self: flex-end; }',
43+
'.btn { padding: 3px 6px; }',
44+
'.item { display: inline-flex; flex-wrap: wrap; align-items: center; padding-top: 5px; }',
45+
'.item > input { margin: 0 5px; }',
46+
'.error input:first-child { border-color: red; }',
47+
'.warning { display: none; color: red; flex-basis: 100%; user-select: none; }',
48+
'.error .warning { display: block; }',
49+
];
50+
}
51+
52+
value(value) {
53+
return new Map(super.value(value));
54+
}
55+
}
56+
57+
function createItem({
58+
value = ['key', 'value'],
59+
save,
60+
invalid,
61+
}) {
62+
const left = $('<input type="text">').val(value[0]).on('blur', () => {
63+
const newVal = left.val();
64+
const isInvalid = newVal !== value[0] && invalid(newVal);
65+
left.parent().toggleClass('error', isInvalid);
66+
if (isInvalid || newVal === value[0]) return;
67+
value[0] = newVal;
68+
save();
69+
});
70+
const right = $('<input type="text">').val(value[1]).on('blur', () => {
71+
const newVal = right.val();
72+
if (newVal === value[1]) return;
73+
value[1] = newVal;
74+
save();
75+
});
76+
const button = $('<button class="btn btn-danger glyphicon glyphicon-trash">').on('click', () => {
77+
save(true);
78+
button.parent().remove();
79+
});
80+
const warning = $('<div class="warning clickable">')
81+
.text('Duplicate value, not updated! Click here to reset.')
82+
.on('click', () => left.val(value[0])
83+
.parent().removeClass('error'));
84+
return $('<div class="item">').append(left, ' : ', right, button, warning);
85+
}

0 commit comments

Comments
 (0)