@fieldia/widgets 0.9.2 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/package.json +2 -2
- package/src/index.d.mts +2 -0
- package/src/index.d.ts +2 -0
- package/src/index.js +4 -0
- package/src/index.js.map +1 -1
- package/src/index.mjs +2 -0
- package/src/index.mjs.map +1 -1
- package/src/lib/address.d.mts +4 -0
- package/src/lib/address.d.ts +4 -0
- package/src/lib/address.js +105 -0
- package/src/lib/address.js.map +1 -0
- package/src/lib/address.mjs +100 -0
- package/src/lib/address.mjs.map +1 -0
- package/src/lib/cards.d.mts +2 -0
- package/src/lib/cards.d.ts +2 -0
- package/src/lib/cards.js +152 -0
- package/src/lib/cards.js.map +1 -0
- package/src/lib/cards.mjs +148 -0
- package/src/lib/cards.mjs.map +1 -0
- package/src/lib/choice-images.d.mts +2 -0
- package/src/lib/choice-images.d.ts +2 -0
- package/src/lib/choice-images.js +99 -0
- package/src/lib/choice-images.js.map +1 -0
- package/src/lib/choice-images.mjs +95 -0
- package/src/lib/choice-images.mjs.map +1 -0
- package/src/lib/choice-rules.d.mts +22 -0
- package/src/lib/choice-rules.d.ts +22 -0
- package/src/lib/choice-rules.js +46 -0
- package/src/lib/choice-rules.js.map +1 -0
- package/src/lib/choice-rules.mjs +41 -0
- package/src/lib/choice-rules.mjs.map +1 -0
- package/src/lib/choice-tags.d.mts +17 -0
- package/src/lib/choice-tags.d.ts +17 -0
- package/src/lib/choice-tags.js +187 -0
- package/src/lib/choice-tags.js.map +1 -0
- package/src/lib/choice-tags.mjs +182 -0
- package/src/lib/choice-tags.mjs.map +1 -0
- package/src/lib/choices-from.d.mts +8 -0
- package/src/lib/choices-from.d.ts +8 -0
- package/src/lib/choices-from.js +63 -0
- package/src/lib/choices-from.js.map +1 -0
- package/src/lib/choices-from.mjs +60 -0
- package/src/lib/choices-from.mjs.map +1 -0
- package/src/lib/display.js +4 -3
- package/src/lib/display.js.map +1 -1
- package/src/lib/display.mjs +5 -4
- package/src/lib/display.mjs.map +1 -1
- package/src/lib/extras.js +8 -4
- package/src/lib/extras.js.map +1 -1
- package/src/lib/extras.mjs +8 -4
- package/src/lib/extras.mjs.map +1 -1
- package/src/lib/files.d.mts +2 -0
- package/src/lib/files.d.ts +2 -0
- package/src/lib/files.js +236 -78
- package/src/lib/files.js.map +1 -1
- package/src/lib/files.mjs +235 -78
- package/src/lib/files.mjs.map +1 -1
- package/src/lib/focus-trap.d.mts +7 -0
- package/src/lib/focus-trap.d.ts +7 -0
- package/src/lib/focus-trap.js +26 -0
- package/src/lib/focus-trap.js.map +1 -0
- package/src/lib/focus-trap.mjs +23 -0
- package/src/lib/focus-trap.mjs.map +1 -0
- package/src/lib/icons.js +1 -0
- package/src/lib/icons.js.map +1 -1
- package/src/lib/icons.mjs +1 -0
- package/src/lib/icons.mjs.map +1 -1
- package/src/lib/kind-parts.d.mts +56 -0
- package/src/lib/kind-parts.d.ts +56 -0
- package/src/lib/kind-parts.js +121 -0
- package/src/lib/kind-parts.js.map +1 -0
- package/src/lib/kind-parts.mjs +107 -0
- package/src/lib/kind-parts.mjs.map +1 -0
- package/src/lib/labels.d.mts +85 -0
- package/src/lib/labels.d.ts +85 -0
- package/src/lib/labels.js +111 -189
- package/src/lib/labels.js.map +1 -1
- package/src/lib/labels.mjs +111 -189
- package/src/lib/labels.mjs.map +1 -1
- package/src/lib/layout-styles.d.mts +11 -0
- package/src/lib/layout-styles.d.ts +11 -0
- package/src/lib/layout-styles.js +178 -0
- package/src/lib/layout-styles.js.map +1 -0
- package/src/lib/layout-styles.mjs +175 -0
- package/src/lib/layout-styles.mjs.map +1 -0
- package/src/lib/limits.d.mts +20 -0
- package/src/lib/limits.d.ts +20 -0
- package/src/lib/limits.js +71 -0
- package/src/lib/limits.js.map +1 -0
- package/src/lib/limits.mjs +66 -0
- package/src/lib/limits.mjs.map +1 -0
- package/src/lib/line-moves.d.mts +8 -0
- package/src/lib/line-moves.d.ts +8 -0
- package/src/lib/line-moves.js +20 -0
- package/src/lib/line-moves.js.map +1 -0
- package/src/lib/line-moves.mjs +17 -0
- package/src/lib/line-moves.mjs.map +1 -0
- package/src/lib/lines.js +85 -7
- package/src/lib/lines.js.map +1 -1
- package/src/lib/lines.mjs +86 -8
- package/src/lib/lines.mjs.map +1 -1
- package/src/lib/locales/all.d.mts +8 -0
- package/src/lib/locales/all.d.ts +8 -0
- package/src/lib/locales/all.js +13 -0
- package/src/lib/locales/all.js.map +1 -0
- package/src/lib/locales/all.mjs +10 -0
- package/src/lib/locales/all.mjs.map +1 -0
- package/src/lib/locales/ar.d.mts +3 -0
- package/src/lib/locales/ar.d.ts +3 -0
- package/src/lib/locales/ar.js +108 -0
- package/src/lib/locales/ar.js.map +1 -0
- package/src/lib/locales/ar.mjs +105 -0
- package/src/lib/locales/ar.mjs.map +1 -0
- package/src/lib/locales/de.d.mts +3 -0
- package/src/lib/locales/de.d.ts +3 -0
- package/src/lib/locales/de.js +108 -0
- package/src/lib/locales/de.js.map +1 -0
- package/src/lib/locales/de.mjs +105 -0
- package/src/lib/locales/de.mjs.map +1 -0
- package/src/lib/locales/fr.d.mts +3 -0
- package/src/lib/locales/fr.d.ts +3 -0
- package/src/lib/locales/fr.js +108 -0
- package/src/lib/locales/fr.js.map +1 -0
- package/src/lib/locales/fr.mjs +105 -0
- package/src/lib/locales/fr.mjs.map +1 -0
- package/src/lib/matrix.d.mts +10 -0
- package/src/lib/matrix.d.ts +10 -0
- package/src/lib/matrix.js +86 -0
- package/src/lib/matrix.js.map +1 -0
- package/src/lib/matrix.mjs +82 -0
- package/src/lib/matrix.mjs.map +1 -0
- package/src/lib/numbers.d.mts +7 -0
- package/src/lib/numbers.d.ts +7 -0
- package/src/lib/numbers.js +15 -0
- package/src/lib/numbers.js.map +1 -1
- package/src/lib/numbers.mjs +14 -0
- package/src/lib/numbers.mjs.map +1 -1
- package/src/lib/progress.js +8 -4
- package/src/lib/progress.js.map +1 -1
- package/src/lib/progress.mjs +8 -4
- package/src/lib/progress.mjs.map +1 -1
- package/src/lib/ranking.d.mts +2 -0
- package/src/lib/ranking.d.ts +2 -0
- package/src/lib/ranking.js +172 -0
- package/src/lib/ranking.js.map +1 -0
- package/src/lib/ranking.mjs +168 -0
- package/src/lib/ranking.mjs.map +1 -0
- package/src/lib/relations.d.mts +1 -1
- package/src/lib/relations.d.ts +1 -1
- package/src/lib/relations.js +43 -18
- package/src/lib/relations.js.map +1 -1
- package/src/lib/relations.mjs +43 -18
- package/src/lib/relations.mjs.map +1 -1
- package/src/lib/shuffle.d.mts +7 -0
- package/src/lib/shuffle.d.ts +7 -0
- package/src/lib/shuffle.js +60 -0
- package/src/lib/shuffle.js.map +1 -0
- package/src/lib/shuffle.mjs +57 -0
- package/src/lib/shuffle.mjs.map +1 -0
- package/src/lib/signature.d.mts +2 -0
- package/src/lib/signature.d.ts +2 -0
- package/src/lib/signature.js +223 -0
- package/src/lib/signature.js.map +1 -0
- package/src/lib/signature.mjs +219 -0
- package/src/lib/signature.mjs.map +1 -0
- package/src/lib/slider.d.mts +10 -0
- package/src/lib/slider.d.ts +10 -0
- package/src/lib/slider.js +57 -0
- package/src/lib/slider.js.map +1 -0
- package/src/lib/slider.mjs +53 -0
- package/src/lib/slider.mjs.map +1 -0
- package/src/lib/styles-choices.d.mts +7 -0
- package/src/lib/styles-choices.d.ts +7 -0
- package/src/lib/styles-choices.js +47 -0
- package/src/lib/styles-choices.js.map +1 -0
- package/src/lib/styles-choices.mjs +44 -0
- package/src/lib/styles-choices.mjs.map +1 -0
- package/src/lib/styles-inputs.d.mts +9 -0
- package/src/lib/styles-inputs.d.ts +9 -0
- package/src/lib/styles-inputs.js +41 -0
- package/src/lib/styles-inputs.js.map +1 -0
- package/src/lib/styles-inputs.mjs +38 -0
- package/src/lib/styles-inputs.mjs.map +1 -0
- package/src/lib/styles-kinds.d.mts +7 -0
- package/src/lib/styles-kinds.d.ts +7 -0
- package/src/lib/styles-kinds.js +119 -0
- package/src/lib/styles-kinds.js.map +1 -0
- package/src/lib/styles-kinds.mjs +116 -0
- package/src/lib/styles-kinds.mjs.map +1 -0
- package/src/lib/styles-parts.d.mts +16 -0
- package/src/lib/styles-parts.d.ts +16 -0
- package/src/lib/styles-parts.js +69 -0
- package/src/lib/styles-parts.js.map +1 -0
- package/src/lib/styles-parts.mjs +66 -0
- package/src/lib/styles-parts.mjs.map +1 -0
- package/src/lib/styles.d.mts +10 -12
- package/src/lib/styles.d.ts +10 -12
- package/src/lib/styles.js +259 -64
- package/src/lib/styles.js.map +1 -1
- package/src/lib/styles.mjs +258 -63
- package/src/lib/styles.mjs.map +1 -1
- package/src/lib/units.d.mts +10 -0
- package/src/lib/units.d.ts +10 -0
- package/src/lib/units.js +19 -0
- package/src/lib/units.js.map +1 -0
- package/src/lib/units.mjs +16 -0
- package/src/lib/units.mjs.map +1 -0
- package/src/lib/widgets.js +215 -57
- package/src/lib/widgets.js.map +1 -1
- package/src/lib/widgets.mjs +215 -57
- package/src/lib/widgets.mjs.map +1 -1
- package/src/lib/yes-no.d.mts +9 -0
- package/src/lib/yes-no.d.ts +9 -0
- package/src/lib/yes-no.js +58 -0
- package/src/lib/yes-no.js.map +1 -0
- package/src/lib/yes-no.mjs +54 -0
- package/src/lib/yes-no.mjs.map +1 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rankingWidget = void 0;
|
|
4
|
+
const kind_parts_1 = require("./kind-parts");
|
|
5
|
+
const shuffle_1 = require("./shuffle");
|
|
6
|
+
/** How far the pointer goes before a press becomes a drag. */
|
|
7
|
+
const SLOP = 4;
|
|
8
|
+
const rankingWidget = ({ form, name, field, node, id, document, labels, locale }) => {
|
|
9
|
+
const words = (0, kind_parts_1.wordsFor)(labels, locale);
|
|
10
|
+
const make = (0, kind_parts_1.maker)(document);
|
|
11
|
+
const options = (0, shuffle_1.shownOptions)(field.type === 'selection' ? field.options : [], form, name, node);
|
|
12
|
+
const list = make('ol', { class: 'fd-rank-list' });
|
|
13
|
+
const voice = (0, kind_parts_1.announcer)(make);
|
|
14
|
+
const most = node.options?.['top'];
|
|
15
|
+
const top = typeof most === 'number' && most >= 1 && most < options.length ? Math.floor(most) : 0;
|
|
16
|
+
const pool = make('div', { class: 'fd-rank-pool' });
|
|
17
|
+
const keepAsShown = make('button', { type: 'button', class: 'fd-button fd-rank-keep' }, words.keepOrder);
|
|
18
|
+
keepAsShown.addEventListener('click', () => form.setValue(name, shown.map((item) => item.option.value)));
|
|
19
|
+
const element = make('div', { id, class: 'fd-ranking', role: 'group' }, ...(top ? [make('div', { class: 'fd-choice-limit' }, (0, kind_parts_1.fillIn)(words.upTo, { n: top })), pool, list] : [list, keepAsShown]), voice.element);
|
|
20
|
+
const items = options.map((option) => {
|
|
21
|
+
const label = option.label;
|
|
22
|
+
const place = make('span', { class: 'fd-rank-place', 'aria-hidden': 'true' });
|
|
23
|
+
const up = make('button', { type: 'button', class: 'fd-rank-move fd-rank-up', 'aria-label': (0, kind_parts_1.fillIn)(words.moveUp, { label }) }, '↑');
|
|
24
|
+
const down = make('button', { type: 'button', class: 'fd-rank-move fd-rank-down', 'aria-label': (0, kind_parts_1.fillIn)(words.moveDown, { label }) }, '↓');
|
|
25
|
+
const grip = make('span', { class: 'fd-rank-grip', 'aria-hidden': 'true' });
|
|
26
|
+
const tools = make('span', { class: 'fd-rank-tools' }, up, down);
|
|
27
|
+
const li = make('li', { class: 'fd-rank-item', 'data-value': String(option.value) }, grip, place, make('span', { class: 'fd-rank-words' }, label), tools);
|
|
28
|
+
const item = { option, element: li, place, up, down };
|
|
29
|
+
if (top) {
|
|
30
|
+
// Picked from the rest to the end of those ranked; its × takes it out again.
|
|
31
|
+
const pick = make('button', { type: 'button', class: 'fd-rank-pick' }, label);
|
|
32
|
+
pick.addEventListener('click', () => !readonly && shown.length < top && keep([...shown, item], item));
|
|
33
|
+
const out = make('button', { type: 'button', class: 'fd-rank-move fd-rank-out', 'aria-label': (0, kind_parts_1.fillIn)(words.remove, { name: label }) }, '×');
|
|
34
|
+
out.addEventListener('click', () => {
|
|
35
|
+
voice.say((0, kind_parts_1.fillIn)(words.removed, { name: label }));
|
|
36
|
+
form.setValue(name, shown.filter((other) => other !== item).map((other) => other.option.value));
|
|
37
|
+
});
|
|
38
|
+
tools.append(out);
|
|
39
|
+
pool.append(pick);
|
|
40
|
+
item.pick = pick;
|
|
41
|
+
}
|
|
42
|
+
up.addEventListener('click', () => move(item, -1, 'up'));
|
|
43
|
+
down.addEventListener('click', () => move(item, 1, 'down'));
|
|
44
|
+
li.addEventListener('pointerdown', (event) => press(item, event));
|
|
45
|
+
return item;
|
|
46
|
+
});
|
|
47
|
+
let readonly = false;
|
|
48
|
+
/** The lines in the order shown now. */
|
|
49
|
+
let shown = [...items];
|
|
50
|
+
/** The button to give the cursor back to once a move has been drawn. */
|
|
51
|
+
let refocus = null;
|
|
52
|
+
function draw(next) {
|
|
53
|
+
shown = next;
|
|
54
|
+
next.forEach((item, i) => {
|
|
55
|
+
if (list.children[i] !== item.element)
|
|
56
|
+
list.insertBefore(item.element, list.children[i] ?? null);
|
|
57
|
+
item.place.textContent = String(i + 1);
|
|
58
|
+
item.up.disabled = i === 0;
|
|
59
|
+
item.down.disabled = i === next.length - 1;
|
|
60
|
+
});
|
|
61
|
+
// Ranking the top few, those not ranked wait among the rest.
|
|
62
|
+
while (list.children.length > next.length)
|
|
63
|
+
list.lastElementChild?.remove();
|
|
64
|
+
}
|
|
65
|
+
/** Keep the order as the answer, and say where the line went. */
|
|
66
|
+
function keep(next, moved) {
|
|
67
|
+
voice.say((0, kind_parts_1.fillIn)(words.movedTo, { label: moved.option.label, n: next.indexOf(moved) + 1, total: next.length }));
|
|
68
|
+
form.setValue(name, next.map((item) => item.option.value));
|
|
69
|
+
}
|
|
70
|
+
function move(item, step, which) {
|
|
71
|
+
const from = shown.indexOf(item);
|
|
72
|
+
const to = from + step;
|
|
73
|
+
if (readonly || to < 0 || to >= shown.length)
|
|
74
|
+
return;
|
|
75
|
+
const next = [...shown];
|
|
76
|
+
next.splice(from, 1);
|
|
77
|
+
next.splice(to, 0, item);
|
|
78
|
+
const holding = item.element.contains(document.activeElement);
|
|
79
|
+
// At an end, the button that moved it is no use: the cursor goes to the other.
|
|
80
|
+
refocus = holding ? { item, which: (which === 'up' && to === 0) || (which === 'down' && to === next.length - 1) ? (which === 'up' ? 'down' : 'up') : which } : null;
|
|
81
|
+
keep(next, item);
|
|
82
|
+
giveBackFocus();
|
|
83
|
+
}
|
|
84
|
+
function giveBackFocus() {
|
|
85
|
+
if (!refocus)
|
|
86
|
+
return;
|
|
87
|
+
const { item, which } = refocus;
|
|
88
|
+
refocus = null;
|
|
89
|
+
item[which].focus();
|
|
90
|
+
}
|
|
91
|
+
list.addEventListener('keydown', (event) => {
|
|
92
|
+
if (readonly || !event.altKey || (event.key !== 'ArrowUp' && event.key !== 'ArrowDown'))
|
|
93
|
+
return;
|
|
94
|
+
const item = items.find((i) => i.element.contains(event.target));
|
|
95
|
+
if (!item)
|
|
96
|
+
return;
|
|
97
|
+
event.preventDefault();
|
|
98
|
+
move(item, event.key === 'ArrowUp' ? -1 : 1, event.key === 'ArrowUp' ? 'up' : 'down');
|
|
99
|
+
});
|
|
100
|
+
// Dragging: the line follows the pointer from place to place; the order is kept when it is let go.
|
|
101
|
+
function press(item, event) {
|
|
102
|
+
if (readonly || event.button !== 0 || event.target.closest('button'))
|
|
103
|
+
return;
|
|
104
|
+
// On a touch screen only the grip drags: anywhere else the page scrolls.
|
|
105
|
+
if (event.pointerType === 'touch' && !event.target.closest('.fd-rank-grip'))
|
|
106
|
+
return;
|
|
107
|
+
const startY = event.clientY;
|
|
108
|
+
const before = [...shown];
|
|
109
|
+
let lifted = false;
|
|
110
|
+
item.element.setPointerCapture?.(event.pointerId);
|
|
111
|
+
const onMove = (e) => {
|
|
112
|
+
if (!lifted && Math.abs(e.clientY - startY) < SLOP)
|
|
113
|
+
return;
|
|
114
|
+
if (!lifted) {
|
|
115
|
+
lifted = true;
|
|
116
|
+
item.element.classList.add('fd-rank-lifted');
|
|
117
|
+
}
|
|
118
|
+
e.preventDefault();
|
|
119
|
+
// Its place: after every other line whose middle the pointer has passed.
|
|
120
|
+
const others = shown.filter((other) => other !== item);
|
|
121
|
+
const at = others.filter((other) => {
|
|
122
|
+
const box = other.element.getBoundingClientRect();
|
|
123
|
+
return box.top + box.height / 2 < e.clientY;
|
|
124
|
+
}).length;
|
|
125
|
+
if (shown.indexOf(item) !== at)
|
|
126
|
+
draw([...others.slice(0, at), item, ...others.slice(at)]);
|
|
127
|
+
};
|
|
128
|
+
const onEnd = () => {
|
|
129
|
+
item.element.removeEventListener('pointermove', onMove);
|
|
130
|
+
item.element.removeEventListener('pointerup', onEnd);
|
|
131
|
+
item.element.removeEventListener('pointercancel', onEnd);
|
|
132
|
+
item.element.classList.remove('fd-rank-lifted');
|
|
133
|
+
if (shown.some((other, i) => other !== before[i]))
|
|
134
|
+
keep(shown, item);
|
|
135
|
+
};
|
|
136
|
+
item.element.addEventListener('pointermove', onMove);
|
|
137
|
+
item.element.addEventListener('pointerup', onEnd);
|
|
138
|
+
item.element.addEventListener('pointercancel', onEnd);
|
|
139
|
+
}
|
|
140
|
+
/** The order a value says: its options first, in its order, then those it leaves out, as they were shown. */
|
|
141
|
+
function orderOf(value) {
|
|
142
|
+
const named = (Array.isArray(value) ? value : []).map((v) => items.find((item) => item.option.value === v)).filter((item) => !!item);
|
|
143
|
+
if (top)
|
|
144
|
+
return named.slice(0, top);
|
|
145
|
+
return Array.isArray(value) ? [...new Set([...named, ...shown])] : shown;
|
|
146
|
+
}
|
|
147
|
+
draw(top ? [] : shown);
|
|
148
|
+
return {
|
|
149
|
+
element,
|
|
150
|
+
focus: () => (items.find((item) => item.pick && !item.pick.hidden && !item.pick.disabled)?.pick ?? (shown[0]?.down.disabled ? shown[0]?.up : shown[0]?.down))?.focus(),
|
|
151
|
+
update(state) {
|
|
152
|
+
readonly = state.readonly;
|
|
153
|
+
element.classList.toggle('fd-ranking-locked', readonly);
|
|
154
|
+
const next = orderOf(state.value);
|
|
155
|
+
if (next.length !== shown.length || next.some((item, i) => item !== shown[i]) || (!top && !list.children.length))
|
|
156
|
+
draw(next);
|
|
157
|
+
for (const item of items) {
|
|
158
|
+
item.up.hidden = item.down.hidden = readonly;
|
|
159
|
+
if (item.pick) {
|
|
160
|
+
item.pick.hidden = shown.includes(item);
|
|
161
|
+
item.pick.disabled = readonly || shown.length >= top;
|
|
162
|
+
item.element.querySelector('.fd-rank-out').hidden = readonly;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
keepAsShown.hidden = readonly || (Array.isArray(state.value) && state.value.length > 0);
|
|
166
|
+
giveBackFocus();
|
|
167
|
+
(0, kind_parts_1.describeState)(element, state);
|
|
168
|
+
},
|
|
169
|
+
};
|
|
170
|
+
};
|
|
171
|
+
exports.rankingWidget = rankingWidget;
|
|
172
|
+
//# sourceMappingURL=ranking.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ranking.js","sourceRoot":"","sources":["../../../../../libs/widgets/src/lib/ranking.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { announcer, describeState, fillIn, maker, wordsFor } from './kind-parts.mjs';
|
|
2
|
+
import { shownOptions } from './shuffle.mjs';
|
|
3
|
+
/** How far the pointer goes before a press becomes a drag. */
|
|
4
|
+
const SLOP = 4;
|
|
5
|
+
export const rankingWidget = ({ form, name, field, node, id, document, labels, locale }) => {
|
|
6
|
+
const words = wordsFor(labels, locale);
|
|
7
|
+
const make = maker(document);
|
|
8
|
+
const options = shownOptions(field.type === 'selection' ? field.options : [], form, name, node);
|
|
9
|
+
const list = make('ol', { class: 'fd-rank-list' });
|
|
10
|
+
const voice = announcer(make);
|
|
11
|
+
const most = node.options?.['top'];
|
|
12
|
+
const top = typeof most === 'number' && most >= 1 && most < options.length ? Math.floor(most) : 0;
|
|
13
|
+
const pool = make('div', { class: 'fd-rank-pool' });
|
|
14
|
+
const keepAsShown = make('button', { type: 'button', class: 'fd-button fd-rank-keep' }, words.keepOrder);
|
|
15
|
+
keepAsShown.addEventListener('click', () => form.setValue(name, shown.map((item) => item.option.value)));
|
|
16
|
+
const element = make('div', { id, class: 'fd-ranking', role: 'group' }, ...(top ? [make('div', { class: 'fd-choice-limit' }, fillIn(words.upTo, { n: top })), pool, list] : [list, keepAsShown]), voice.element);
|
|
17
|
+
const items = options.map((option) => {
|
|
18
|
+
const label = option.label;
|
|
19
|
+
const place = make('span', { class: 'fd-rank-place', 'aria-hidden': 'true' });
|
|
20
|
+
const up = make('button', { type: 'button', class: 'fd-rank-move fd-rank-up', 'aria-label': fillIn(words.moveUp, { label }) }, '↑');
|
|
21
|
+
const down = make('button', { type: 'button', class: 'fd-rank-move fd-rank-down', 'aria-label': fillIn(words.moveDown, { label }) }, '↓');
|
|
22
|
+
const grip = make('span', { class: 'fd-rank-grip', 'aria-hidden': 'true' });
|
|
23
|
+
const tools = make('span', { class: 'fd-rank-tools' }, up, down);
|
|
24
|
+
const li = make('li', { class: 'fd-rank-item', 'data-value': String(option.value) }, grip, place, make('span', { class: 'fd-rank-words' }, label), tools);
|
|
25
|
+
const item = { option, element: li, place, up, down };
|
|
26
|
+
if (top) {
|
|
27
|
+
// Picked from the rest to the end of those ranked; its × takes it out again.
|
|
28
|
+
const pick = make('button', { type: 'button', class: 'fd-rank-pick' }, label);
|
|
29
|
+
pick.addEventListener('click', () => !readonly && shown.length < top && keep([...shown, item], item));
|
|
30
|
+
const out = make('button', { type: 'button', class: 'fd-rank-move fd-rank-out', 'aria-label': fillIn(words.remove, { name: label }) }, '×');
|
|
31
|
+
out.addEventListener('click', () => {
|
|
32
|
+
voice.say(fillIn(words.removed, { name: label }));
|
|
33
|
+
form.setValue(name, shown.filter((other) => other !== item).map((other) => other.option.value));
|
|
34
|
+
});
|
|
35
|
+
tools.append(out);
|
|
36
|
+
pool.append(pick);
|
|
37
|
+
item.pick = pick;
|
|
38
|
+
}
|
|
39
|
+
up.addEventListener('click', () => move(item, -1, 'up'));
|
|
40
|
+
down.addEventListener('click', () => move(item, 1, 'down'));
|
|
41
|
+
li.addEventListener('pointerdown', (event) => press(item, event));
|
|
42
|
+
return item;
|
|
43
|
+
});
|
|
44
|
+
let readonly = false;
|
|
45
|
+
/** The lines in the order shown now. */
|
|
46
|
+
let shown = [...items];
|
|
47
|
+
/** The button to give the cursor back to once a move has been drawn. */
|
|
48
|
+
let refocus = null;
|
|
49
|
+
function draw(next) {
|
|
50
|
+
shown = next;
|
|
51
|
+
next.forEach((item, i) => {
|
|
52
|
+
if (list.children[i] !== item.element)
|
|
53
|
+
list.insertBefore(item.element, list.children[i] ?? null);
|
|
54
|
+
item.place.textContent = String(i + 1);
|
|
55
|
+
item.up.disabled = i === 0;
|
|
56
|
+
item.down.disabled = i === next.length - 1;
|
|
57
|
+
});
|
|
58
|
+
// Ranking the top few, those not ranked wait among the rest.
|
|
59
|
+
while (list.children.length > next.length)
|
|
60
|
+
list.lastElementChild?.remove();
|
|
61
|
+
}
|
|
62
|
+
/** Keep the order as the answer, and say where the line went. */
|
|
63
|
+
function keep(next, moved) {
|
|
64
|
+
voice.say(fillIn(words.movedTo, { label: moved.option.label, n: next.indexOf(moved) + 1, total: next.length }));
|
|
65
|
+
form.setValue(name, next.map((item) => item.option.value));
|
|
66
|
+
}
|
|
67
|
+
function move(item, step, which) {
|
|
68
|
+
const from = shown.indexOf(item);
|
|
69
|
+
const to = from + step;
|
|
70
|
+
if (readonly || to < 0 || to >= shown.length)
|
|
71
|
+
return;
|
|
72
|
+
const next = [...shown];
|
|
73
|
+
next.splice(from, 1);
|
|
74
|
+
next.splice(to, 0, item);
|
|
75
|
+
const holding = item.element.contains(document.activeElement);
|
|
76
|
+
// At an end, the button that moved it is no use: the cursor goes to the other.
|
|
77
|
+
refocus = holding ? { item, which: (which === 'up' && to === 0) || (which === 'down' && to === next.length - 1) ? (which === 'up' ? 'down' : 'up') : which } : null;
|
|
78
|
+
keep(next, item);
|
|
79
|
+
giveBackFocus();
|
|
80
|
+
}
|
|
81
|
+
function giveBackFocus() {
|
|
82
|
+
if (!refocus)
|
|
83
|
+
return;
|
|
84
|
+
const { item, which } = refocus;
|
|
85
|
+
refocus = null;
|
|
86
|
+
item[which].focus();
|
|
87
|
+
}
|
|
88
|
+
list.addEventListener('keydown', (event) => {
|
|
89
|
+
if (readonly || !event.altKey || (event.key !== 'ArrowUp' && event.key !== 'ArrowDown'))
|
|
90
|
+
return;
|
|
91
|
+
const item = items.find((i) => i.element.contains(event.target));
|
|
92
|
+
if (!item)
|
|
93
|
+
return;
|
|
94
|
+
event.preventDefault();
|
|
95
|
+
move(item, event.key === 'ArrowUp' ? -1 : 1, event.key === 'ArrowUp' ? 'up' : 'down');
|
|
96
|
+
});
|
|
97
|
+
// Dragging: the line follows the pointer from place to place; the order is kept when it is let go.
|
|
98
|
+
function press(item, event) {
|
|
99
|
+
if (readonly || event.button !== 0 || event.target.closest('button'))
|
|
100
|
+
return;
|
|
101
|
+
// On a touch screen only the grip drags: anywhere else the page scrolls.
|
|
102
|
+
if (event.pointerType === 'touch' && !event.target.closest('.fd-rank-grip'))
|
|
103
|
+
return;
|
|
104
|
+
const startY = event.clientY;
|
|
105
|
+
const before = [...shown];
|
|
106
|
+
let lifted = false;
|
|
107
|
+
item.element.setPointerCapture?.(event.pointerId);
|
|
108
|
+
const onMove = (e) => {
|
|
109
|
+
if (!lifted && Math.abs(e.clientY - startY) < SLOP)
|
|
110
|
+
return;
|
|
111
|
+
if (!lifted) {
|
|
112
|
+
lifted = true;
|
|
113
|
+
item.element.classList.add('fd-rank-lifted');
|
|
114
|
+
}
|
|
115
|
+
e.preventDefault();
|
|
116
|
+
// Its place: after every other line whose middle the pointer has passed.
|
|
117
|
+
const others = shown.filter((other) => other !== item);
|
|
118
|
+
const at = others.filter((other) => {
|
|
119
|
+
const box = other.element.getBoundingClientRect();
|
|
120
|
+
return box.top + box.height / 2 < e.clientY;
|
|
121
|
+
}).length;
|
|
122
|
+
if (shown.indexOf(item) !== at)
|
|
123
|
+
draw([...others.slice(0, at), item, ...others.slice(at)]);
|
|
124
|
+
};
|
|
125
|
+
const onEnd = () => {
|
|
126
|
+
item.element.removeEventListener('pointermove', onMove);
|
|
127
|
+
item.element.removeEventListener('pointerup', onEnd);
|
|
128
|
+
item.element.removeEventListener('pointercancel', onEnd);
|
|
129
|
+
item.element.classList.remove('fd-rank-lifted');
|
|
130
|
+
if (shown.some((other, i) => other !== before[i]))
|
|
131
|
+
keep(shown, item);
|
|
132
|
+
};
|
|
133
|
+
item.element.addEventListener('pointermove', onMove);
|
|
134
|
+
item.element.addEventListener('pointerup', onEnd);
|
|
135
|
+
item.element.addEventListener('pointercancel', onEnd);
|
|
136
|
+
}
|
|
137
|
+
/** The order a value says: its options first, in its order, then those it leaves out, as they were shown. */
|
|
138
|
+
function orderOf(value) {
|
|
139
|
+
const named = (Array.isArray(value) ? value : []).map((v) => items.find((item) => item.option.value === v)).filter((item) => !!item);
|
|
140
|
+
if (top)
|
|
141
|
+
return named.slice(0, top);
|
|
142
|
+
return Array.isArray(value) ? [...new Set([...named, ...shown])] : shown;
|
|
143
|
+
}
|
|
144
|
+
draw(top ? [] : shown);
|
|
145
|
+
return {
|
|
146
|
+
element,
|
|
147
|
+
focus: () => (items.find((item) => item.pick && !item.pick.hidden && !item.pick.disabled)?.pick ?? (shown[0]?.down.disabled ? shown[0]?.up : shown[0]?.down))?.focus(),
|
|
148
|
+
update(state) {
|
|
149
|
+
readonly = state.readonly;
|
|
150
|
+
element.classList.toggle('fd-ranking-locked', readonly);
|
|
151
|
+
const next = orderOf(state.value);
|
|
152
|
+
if (next.length !== shown.length || next.some((item, i) => item !== shown[i]) || (!top && !list.children.length))
|
|
153
|
+
draw(next);
|
|
154
|
+
for (const item of items) {
|
|
155
|
+
item.up.hidden = item.down.hidden = readonly;
|
|
156
|
+
if (item.pick) {
|
|
157
|
+
item.pick.hidden = shown.includes(item);
|
|
158
|
+
item.pick.disabled = readonly || shown.length >= top;
|
|
159
|
+
item.element.querySelector('.fd-rank-out').hidden = readonly;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
keepAsShown.hidden = readonly || (Array.isArray(state.value) && state.value.length > 0);
|
|
163
|
+
giveBackFocus();
|
|
164
|
+
describeState(element, state);
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
//# sourceMappingURL=ranking.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ranking.mjs","sourceRoot":"","sources":["../../../../../libs/widgets/src/lib/ranking.ts"],"names":[],"mappings":"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"}
|
package/src/lib/relations.d.mts
CHANGED
|
@@ -5,7 +5,7 @@ export declare const tagsWidget: WidgetFactory;
|
|
|
5
5
|
* Free-text tags on a text field, kept as "oak, glass": Enter or a comma adds
|
|
6
6
|
* what was typed, Backspace in an empty box takes the last one away, and the
|
|
7
7
|
* node's `options.suggestions` are offered as you type. `options.separator`
|
|
8
|
-
* is "," unless set.
|
|
8
|
+
* is "," unless set; with `options.max`, the box goes once there are as many.
|
|
9
9
|
*/
|
|
10
10
|
export declare const charTagsWidget: WidgetFactory;
|
|
11
11
|
/** Every record as a checkbox. For short lists: it loads up to 50. */
|
package/src/lib/relations.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export declare const tagsWidget: WidgetFactory;
|
|
|
5
5
|
* Free-text tags on a text field, kept as "oak, glass": Enter or a comma adds
|
|
6
6
|
* what was typed, Backspace in an empty box takes the last one away, and the
|
|
7
7
|
* node's `options.suggestions` are offered as you type. `options.separator`
|
|
8
|
-
* is "," unless set.
|
|
8
|
+
* is "," unless set; with `options.max`, the box goes once there are as many.
|
|
9
9
|
*/
|
|
10
10
|
export declare const charTagsWidget: WidgetFactory;
|
|
11
11
|
/** Every record as a checkbox. For short lists: it loads up to 50. */
|
package/src/lib/relations.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.referenceWidget = exports.linkCheckboxesWidget = exports.charTagsWidget = exports.tagsWidget = exports.many2oneWidget = void 0;
|
|
4
4
|
const labels_1 = require("./labels");
|
|
5
|
+
const kind_parts_1 = require("./kind-parts");
|
|
5
6
|
/**
|
|
6
7
|
* Pickers for related records: a search-as-you-type combobox (the ARIA 1.2
|
|
7
8
|
* combobox pattern), tags for a many2many, and a reference picker. Results
|
|
@@ -193,12 +194,13 @@ function combobox(options) {
|
|
|
193
194
|
input,
|
|
194
195
|
setText(text) {
|
|
195
196
|
shown = text;
|
|
196
|
-
if (!editing)
|
|
197
|
+
if (!editing && input.value !== text)
|
|
197
198
|
input.value = text;
|
|
198
199
|
},
|
|
199
200
|
setReadonly(next) {
|
|
200
201
|
readonly = next;
|
|
201
|
-
input.readOnly
|
|
202
|
+
if (input.readOnly !== next)
|
|
203
|
+
input.readOnly = next;
|
|
202
204
|
if (next)
|
|
203
205
|
close();
|
|
204
206
|
},
|
|
@@ -270,21 +272,22 @@ const many2oneWidget = ({ form, name, field, node, id, document, labels = labels
|
|
|
270
272
|
readonly = state.readonly;
|
|
271
273
|
box.setText(record?.label ?? '');
|
|
272
274
|
box.setReadonly(state.readonly);
|
|
273
|
-
clear
|
|
275
|
+
(0, kind_parts_1.setHidden)(clear, !record || state.readonly);
|
|
274
276
|
if (open) {
|
|
275
|
-
open
|
|
277
|
+
(0, kind_parts_1.setHidden)(open, !record);
|
|
276
278
|
if (record)
|
|
277
|
-
|
|
279
|
+
(0, kind_parts_1.setAttr)(open, 'aria-label', fill(labels.openNamed, { name: record.label }));
|
|
278
280
|
}
|
|
279
|
-
box.input
|
|
280
|
-
box.input
|
|
281
|
+
(0, kind_parts_1.setAttr)(box.input, 'aria-invalid', String(state.invalid));
|
|
282
|
+
(0, kind_parts_1.setAttr)(box.input, 'aria-required', String(state.required));
|
|
281
283
|
if (state.describedBy)
|
|
282
|
-
box.input
|
|
284
|
+
(0, kind_parts_1.setAttr)(box.input, 'aria-describedby', state.describedBy);
|
|
283
285
|
},
|
|
284
286
|
};
|
|
285
287
|
};
|
|
286
288
|
exports.many2oneWidget = many2oneWidget;
|
|
287
|
-
const tagsWidget = ({ form, name, node, id, document, labels = labels_1.WIDGET_LABELS.en }) => {
|
|
289
|
+
const tagsWidget = ({ form, name, field, node, id, document, labels = labels_1.WIDGET_LABELS.en, dialogs }) => {
|
|
290
|
+
const relation = field.type === 'many2many' ? field.relation : '';
|
|
288
291
|
const current = () => form.getState().values[name] ?? [];
|
|
289
292
|
const element = document.createElement('div');
|
|
290
293
|
element.className = 'fd-tags';
|
|
@@ -295,9 +298,12 @@ const tagsWidget = ({ form, name, node, id, document, labels = labels_1.WIDGET_L
|
|
|
295
298
|
document,
|
|
296
299
|
id,
|
|
297
300
|
labels,
|
|
298
|
-
|
|
301
|
+
// One past what the list shows, besides those chosen, to know whether Search more… has more to find.
|
|
302
|
+
search: (query) => form.search(name, query, SHOWN + 1 + current().length),
|
|
303
|
+
shown: SHOWN,
|
|
299
304
|
pick: (record) => {
|
|
300
|
-
|
|
305
|
+
if (!current().some((r) => r.id === record.id))
|
|
306
|
+
form.setValue(name, [...current(), record]);
|
|
301
307
|
box.input.value = '';
|
|
302
308
|
},
|
|
303
309
|
exclude: () => new Set(current().map((record) => record.id)),
|
|
@@ -307,7 +313,17 @@ const tagsWidget = ({ form, name, node, id, document, labels = labels_1.WIDGET_L
|
|
|
307
313
|
form.setValue(name, records.slice(0, -1));
|
|
308
314
|
},
|
|
309
315
|
create: creator(form, name, node),
|
|
316
|
+
// With dialogs: pick from a full list when the short one has no room.
|
|
317
|
+
more: (_typed, overflow) => (dialogs && overflow ? [{ label: labels.searchMore, act: () => dialogs.searchMore({ title: field.label, search: (query, limit) => form.search(name, query, limit) }) }] : []),
|
|
310
318
|
});
|
|
319
|
+
// A linked record, opened from its tag in a dialog where the app can show it; a new name it is saved with follows here.
|
|
320
|
+
const open = dialogs && dialogs.canOpen(relation)
|
|
321
|
+
? async (record) => {
|
|
322
|
+
const saved = await dialogs.openRecord(relation, { recordId: record.id, title: record.label });
|
|
323
|
+
if (saved && saved.label !== record.label)
|
|
324
|
+
form.setValue(name, current().map((r) => (r.id === record.id ? saved : r)));
|
|
325
|
+
}
|
|
326
|
+
: undefined;
|
|
311
327
|
element.append(chips, box.element);
|
|
312
328
|
let readonly = false;
|
|
313
329
|
let drawn = '';
|
|
@@ -327,21 +343,26 @@ const tagsWidget = ({ form, name, node, id, document, labels = labels_1.WIDGET_L
|
|
|
327
343
|
if (key === drawn)
|
|
328
344
|
return;
|
|
329
345
|
drawn = key;
|
|
330
|
-
drawChips(chips, records, readonly, labels, (record) => form.setValue(name, current().filter((r) => r.id !== record.id)));
|
|
346
|
+
drawChips(chips, records, readonly, labels, (record) => form.setValue(name, current().filter((r) => r.id !== record.id)), open);
|
|
331
347
|
box.setText('');
|
|
332
348
|
},
|
|
333
349
|
};
|
|
334
350
|
};
|
|
335
351
|
exports.tagsWidget = tagsWidget;
|
|
336
|
-
/** Chips for tags, each with a remove button unless read-only. */
|
|
337
|
-
function drawChips(chips, records, readonly, labels, remove) {
|
|
352
|
+
/** Chips for tags, each with a remove button unless read-only; with `open`, each one's words a button that opens it. */
|
|
353
|
+
function drawChips(chips, records, readonly, labels, remove, open) {
|
|
338
354
|
const doc = chips.ownerDocument;
|
|
339
355
|
chips.replaceChildren(...records.map((record) => {
|
|
340
356
|
const chip = doc.createElement('li');
|
|
341
357
|
chip.className = 'fd-chip';
|
|
342
|
-
const text = doc.createElement('span');
|
|
358
|
+
const text = doc.createElement(open ? 'button' : 'span');
|
|
343
359
|
text.className = 'fd-chip-label';
|
|
344
360
|
text.textContent = record.label;
|
|
361
|
+
if (open) {
|
|
362
|
+
text.type = 'button';
|
|
363
|
+
text.setAttribute('aria-label', fill(labels.openNamed, { name: record.label }));
|
|
364
|
+
text.addEventListener('click', () => open(record));
|
|
365
|
+
}
|
|
345
366
|
chip.append(text);
|
|
346
367
|
if (!readonly) {
|
|
347
368
|
const button = doc.createElement('button');
|
|
@@ -359,7 +380,7 @@ function drawChips(chips, records, readonly, labels, remove) {
|
|
|
359
380
|
* Free-text tags on a text field, kept as "oak, glass": Enter or a comma adds
|
|
360
381
|
* what was typed, Backspace in an empty box takes the last one away, and the
|
|
361
382
|
* node's `options.suggestions` are offered as you type. `options.separator`
|
|
362
|
-
* is "," unless set.
|
|
383
|
+
* is "," unless set; with `options.max`, the box goes once there are as many.
|
|
363
384
|
*/
|
|
364
385
|
const charTagsWidget = ({ form, name, node, id, document, labels = labels_1.WIDGET_LABELS.en }) => {
|
|
365
386
|
const options = node.options ?? {};
|
|
@@ -371,7 +392,7 @@ const charTagsWidget = ({ form, name, node, id, document, labels = labels_1.WIDG
|
|
|
371
392
|
const add = (raw) => {
|
|
372
393
|
const tag = raw.trim();
|
|
373
394
|
const tags = current();
|
|
374
|
-
if (tag && !tags.some((t) => t.toLowerCase() === tag.toLowerCase()))
|
|
395
|
+
if (tag && !tags.some((t) => t.toLowerCase() === tag.toLowerCase()) && !(tags.length >= options['max']))
|
|
375
396
|
write([...tags, tag]);
|
|
376
397
|
};
|
|
377
398
|
const element = document.createElement('div');
|
|
@@ -431,7 +452,7 @@ const charTagsWidget = ({ form, name, node, id, document, labels = labels_1.WIDG
|
|
|
431
452
|
update(state) {
|
|
432
453
|
const tags = split(state.value);
|
|
433
454
|
box.setReadonly(state.readonly);
|
|
434
|
-
box.element.hidden = state.readonly;
|
|
455
|
+
box.element.hidden = state.readonly || tags.length >= options['max'];
|
|
435
456
|
box.input.setAttribute('aria-invalid', String(state.invalid));
|
|
436
457
|
if (state.describedBy)
|
|
437
458
|
box.input.setAttribute('aria-describedby', state.describedBy);
|
|
@@ -439,8 +460,12 @@ const charTagsWidget = ({ form, name, node, id, document, labels = labels_1.WIDG
|
|
|
439
460
|
if (key === drawn)
|
|
440
461
|
return;
|
|
441
462
|
drawn = key;
|
|
463
|
+
const typing = document.activeElement === box.input;
|
|
442
464
|
drawChips(chips, tags.map((t) => ({ id: t, label: t })), state.readonly, labels, (record) => write(current().filter((t) => t !== record.label)));
|
|
443
465
|
box.setText('');
|
|
466
|
+
// The box gone at the most, the cursor stays in the keywords: on the last one's ×.
|
|
467
|
+
if (typing && box.element.hidden)
|
|
468
|
+
chips.querySelector('li:last-child button')?.focus();
|
|
444
469
|
},
|
|
445
470
|
};
|
|
446
471
|
};
|