@itrocks/list 0.23.1 → 0.24.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 +11 -4
- package/build.d.ts +1 -1
- package/build.js +2 -1
- package/cjs/filter.js +3 -1
- package/cjs/filter.js.map +1 -1
- package/cjs/list.html +10 -1
- package/list.css +46 -2
- package/package.json +1 -1
- package/property-select.d.ts +1 -0
- package/property-select.js +13 -19
- package/search-menu.d.ts +1 -0
- package/search-menu.js +136 -0
- package/search.svg +5 -0
package/README.md
CHANGED
|
@@ -132,6 +132,14 @@ For `json()`, the scope is passed directly to `dataSource().search()`.
|
|
|
132
132
|
|
|
133
133
|
## Search filters
|
|
134
134
|
|
|
135
|
+
The magnifying-glass button submits the column filters, as does Enter in a filter field.
|
|
136
|
+
A long press (500 ms) or right-click on this button opens a menu with Search first and Reset search filters second,
|
|
137
|
+
each with an icon and label. Releasing a long press does not submit the search.
|
|
138
|
+
Reset clears all filters, including saved filters for hidden columns, and reloads the list without changing its sorting
|
|
139
|
+
or column configuration. The menu does not change the selection column's width.
|
|
140
|
+
Arrow Down, the context-menu key or Shift+F10 on the button also opens the menu. Use arrow keys to select an action,
|
|
141
|
+
Enter or Space to activate it, and Escape to close it. Clicking outside dismisses the menu.
|
|
142
|
+
|
|
135
143
|
HTML list filters interpret the first hyphen as an interval separator. Spaces around the bounds are ignored:
|
|
136
144
|
|
|
137
145
|
- `2000 - 2010` uses inclusive `between(2000, 2010)`.
|
|
@@ -352,10 +360,9 @@ and retain their committed order throughout the drag. New accepted drops feed re
|
|
|
352
360
|
cancellations do not. Row-view changes and view disposal cancel transport. The desktop pane stays open, and capture is
|
|
353
361
|
owned by the selector's surviving source controller. The consumer imports no home implementation, SQL or hydration code.
|
|
354
362
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
restoration. Custom pane adapters may implement the same optional suspension argument without importing `home`.
|
|
363
|
+
When a source gesture is recognised, the consumer closes the pane if its rendered width fills its parent.
|
|
364
|
+
It stays closed after a drop, cancellation or rejection. A narrower desktop pane stays open.
|
|
365
|
+
Locating a selected column uses the same width check and closes a full-width pane before revealing the column.
|
|
359
366
|
|
|
360
367
|
`node test/browser-requests.mjs` checks request counts and real mouse gestures in Chromium with synthetic HTTP data.
|
|
361
368
|
It covers initial mount, click placeholders, hidden drag additions, values for 80 loaded rows before entry or drop,
|
package/build.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
import './search-menu.js';
|
package/build.js
CHANGED
|
@@ -9,6 +9,7 @@ import { TableFreezeInheritBorder } from '@itrocks/table/freeze/inherit-border.j
|
|
|
9
9
|
import { TableLink } from '@itrocks/table/link.js';
|
|
10
10
|
import { tableByElement } from '@itrocks/table/table.js';
|
|
11
11
|
import { xTargetCall } from '@itrocks/xtarget/xtarget.js';
|
|
12
|
+
import './search-menu.js';
|
|
12
13
|
build('article[data-action="list"] > form > table.objects', table => {
|
|
13
14
|
let saving = Promise.resolve();
|
|
14
15
|
const request = (query, signal) => {
|
|
@@ -53,7 +54,7 @@ build('article[data-action="list"] > form > table.objects', table => {
|
|
|
53
54
|
}));
|
|
54
55
|
table.addEventListener('click', event => {
|
|
55
56
|
const element = event.target;
|
|
56
|
-
if ((element instanceof
|
|
57
|
+
if (!(element instanceof HTMLElement) || element.closest('input, button'))
|
|
57
58
|
return;
|
|
58
59
|
const cell = element.closest('table, th');
|
|
59
60
|
if (!((cell instanceof HTMLTableCellElement) && cell.classList.contains('select')))
|
package/cjs/filter.js
CHANGED
|
@@ -78,8 +78,10 @@ class Filter extends parameter_1.Parameter {
|
|
|
78
78
|
for (const property of this.columns.map(property => property.name)) {
|
|
79
79
|
this.search[property] ??= '';
|
|
80
80
|
}
|
|
81
|
-
if ('reset' in request.data)
|
|
81
|
+
if ('reset' in request.data) {
|
|
82
82
|
this.search = Object.fromEntries(Object.keys(this.search).map(path => [path, '']));
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
83
85
|
const apply = (value, prefix = '') => {
|
|
84
86
|
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
85
87
|
return;
|
package/cjs/filter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"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"}
|
package/cjs/list.html
CHANGED
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
<thead>
|
|
32
32
|
<tr class="properties">
|
|
33
33
|
<th class="select" data-freeze><input name="select" type="checkbox" value="all">
|
|
34
|
-
<input
|
|
34
|
+
<input class="search-submit" title="Search" type="submit" value="Search">
|
|
35
|
+
</th>
|
|
35
36
|
<!--columns-->
|
|
36
37
|
<th data-property="{name}" data-reverse="{?reverse}" data-sort="{?sort}"
|
|
37
38
|
data-sortable="{sortable}">{label}
|
|
@@ -44,6 +45,14 @@
|
|
|
44
45
|
{./feed.html}
|
|
45
46
|
</tbody>
|
|
46
47
|
</table>
|
|
48
|
+
<div class="search-menu" popover="manual" role="menu">
|
|
49
|
+
<button class="search" role="menuitem" tabindex="-1" type="submit">
|
|
50
|
+
Search
|
|
51
|
+
</button>
|
|
52
|
+
<button class="reset" name="reset" role="menuitem" tabindex="-1" type="submit" value="reset">
|
|
53
|
+
Reset search filters
|
|
54
|
+
</button>
|
|
55
|
+
</div>
|
|
47
56
|
<footer>
|
|
48
57
|
<ul class="selection actions">
|
|
49
58
|
<!--selectionActions-->
|
package/list.css
CHANGED
|
@@ -225,12 +225,14 @@ table.objects > thead > tr.properties > th > input:not([type=checkbox]) {
|
|
|
225
225
|
padding: 0 6px;
|
|
226
226
|
width: 100%;
|
|
227
227
|
}
|
|
228
|
-
table.objects > thead > tr.properties > th > input
|
|
229
|
-
background: url("
|
|
228
|
+
table.objects > thead > tr.properties > th > input.search-submit {
|
|
229
|
+
background: url("search.svg") center/24px no-repeat;
|
|
230
230
|
color: transparent;
|
|
231
231
|
cursor: pointer;
|
|
232
232
|
font-size: 0;
|
|
233
233
|
padding: 0;
|
|
234
|
+
touch-action: manipulation;
|
|
235
|
+
-webkit-touch-callout: none;
|
|
234
236
|
width: 28px;
|
|
235
237
|
}
|
|
236
238
|
table.objects > thead > tr.properties > th > input[data-property-filter] {
|
|
@@ -245,3 +247,45 @@ table.objects > thead > tr.properties > th > input:focus {
|
|
|
245
247
|
box-shadow: inset 0 0 0 2px Highlight, var(--column-reorder-tint, 0 0 transparent);
|
|
246
248
|
outline: none;
|
|
247
249
|
}
|
|
250
|
+
|
|
251
|
+
article[data-action=list] > form > .search-menu {
|
|
252
|
+
background: white;
|
|
253
|
+
border: 1px solid #ccc;
|
|
254
|
+
border-radius: 4px;
|
|
255
|
+
box-shadow: 0 3px 12px rgba(0, 0, 0, 0.2);
|
|
256
|
+
color: #333;
|
|
257
|
+
inset: auto;
|
|
258
|
+
margin: 0;
|
|
259
|
+
max-height: calc(100dvh - 8px);
|
|
260
|
+
max-width: calc(100vw - 8px);
|
|
261
|
+
padding: 4px;
|
|
262
|
+
position: fixed;
|
|
263
|
+
}
|
|
264
|
+
article[data-action=list] > form > .search-menu > button {
|
|
265
|
+
align-items: center;
|
|
266
|
+
background: none;
|
|
267
|
+
border: 0;
|
|
268
|
+
border-radius: 2px;
|
|
269
|
+
color: inherit;
|
|
270
|
+
cursor: pointer;
|
|
271
|
+
display: flex;
|
|
272
|
+
font: inherit;
|
|
273
|
+
gap: 10px;
|
|
274
|
+
min-height: 44px;
|
|
275
|
+
padding: 8px 12px;
|
|
276
|
+
text-align: left;
|
|
277
|
+
width: 100%;
|
|
278
|
+
}
|
|
279
|
+
article[data-action=list] > form > .search-menu > button::before {
|
|
280
|
+
background: currentColor;
|
|
281
|
+
content: "";
|
|
282
|
+
flex: 0 0 24px;
|
|
283
|
+
height: 24px;
|
|
284
|
+
mask: url("search.svg") center/contain no-repeat;
|
|
285
|
+
}
|
|
286
|
+
article[data-action=list] > form > .search-menu > button.reset::before {
|
|
287
|
+
mask-image: url("filter-reset.svg");
|
|
288
|
+
}
|
|
289
|
+
article[data-action=list] > form > .search-menu > button:focus-visible, article[data-action=list] > form > .search-menu > button:hover {
|
|
290
|
+
background: #eee;
|
|
291
|
+
}
|
package/package.json
CHANGED
package/property-select.d.ts
CHANGED
|
@@ -51,6 +51,7 @@ export declare class ListPropertySelect implements ConsumerPort {
|
|
|
51
51
|
private columnContent;
|
|
52
52
|
private add;
|
|
53
53
|
begin(intent: SelectionIntent, sample: PointerSample): void;
|
|
54
|
+
private closeFullWidthPane;
|
|
54
55
|
private columnSource;
|
|
55
56
|
cancel(id: string): void;
|
|
56
57
|
private displayedPaths;
|
package/property-select.js
CHANGED
|
@@ -143,18 +143,17 @@ export class ListPropertySelect {
|
|
|
143
143
|
throw new Error('A column operation is pending');
|
|
144
144
|
const path = normalisePath(intent.path);
|
|
145
145
|
const added = !this.paths().includes(path);
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
146
|
+
this.closeFullWidthPane();
|
|
147
|
+
if (added)
|
|
148
|
+
this.add(path, this.abort.signal, { effects: false, hidden: true });
|
|
149
|
+
const paths = this.paths();
|
|
150
|
+
const operation = this.options.addition.beginExternal(this.columnSource(path), sample, { adding: added, removal: true });
|
|
151
|
+
this.drag = { added, intent, operation, paths };
|
|
152
|
+
}
|
|
153
|
+
closeFullWidthPane() {
|
|
154
|
+
const aside = this.content.closest('aside');
|
|
155
|
+
if (aside && (aside.offsetWidth > 0) && (aside.offsetWidth >= aside.parentElement.clientWidth))
|
|
156
|
+
this.pane.close();
|
|
158
157
|
}
|
|
159
158
|
columnSource(path) {
|
|
160
159
|
const selector = this.view.selector;
|
|
@@ -202,7 +201,6 @@ export class ListPropertySelect {
|
|
|
202
201
|
const drag = this.drag;
|
|
203
202
|
drag.operation.cancel();
|
|
204
203
|
this.drag = undefined;
|
|
205
|
-
drag.restore();
|
|
206
204
|
this.view.selector.setConfiguration({ usedPaths: this.paths() });
|
|
207
205
|
}
|
|
208
206
|
displayedPaths() {
|
|
@@ -256,7 +254,6 @@ export class ListPropertySelect {
|
|
|
256
254
|
finally {
|
|
257
255
|
if (this.drag === drag)
|
|
258
256
|
this.drag = undefined;
|
|
259
|
-
drag.restore();
|
|
260
257
|
}
|
|
261
258
|
}
|
|
262
259
|
async mount() {
|
|
@@ -354,11 +351,8 @@ export class ListPropertySelect {
|
|
|
354
351
|
if (this.disposed)
|
|
355
352
|
throw new Error('List disposed');
|
|
356
353
|
if ((status !== 'removed') && this.paths().includes(path)) {
|
|
357
|
-
if (intent.action === 'add')
|
|
358
|
-
|
|
359
|
-
if (aside && (aside.offsetWidth > 0) && (aside.offsetWidth >= aside.parentElement.clientWidth))
|
|
360
|
-
this.pane.close();
|
|
361
|
-
}
|
|
354
|
+
if (intent.action === 'add')
|
|
355
|
+
this.closeFullWidthPane();
|
|
362
356
|
this.options.addition.reveal(path);
|
|
363
357
|
if (status === 'existing')
|
|
364
358
|
this.options.addition.highlight(path);
|
package/search-menu.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/search-menu.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { build } from '@itrocks/build/build.js';
|
|
2
|
+
const bound = new WeakSet();
|
|
3
|
+
build('article[data-action="list"] > form', form => {
|
|
4
|
+
if (bound.has(form))
|
|
5
|
+
return;
|
|
6
|
+
const trigger = form.querySelector('.search-submit');
|
|
7
|
+
const menu = form.querySelector('.search-menu');
|
|
8
|
+
if (!trigger || !menu)
|
|
9
|
+
return;
|
|
10
|
+
bound.add(form);
|
|
11
|
+
const items = Array.from(menu.querySelectorAll('[role="menuitem"]'));
|
|
12
|
+
let listeners;
|
|
13
|
+
let pointer;
|
|
14
|
+
let suppressClick = false;
|
|
15
|
+
let timer;
|
|
16
|
+
const cancel = () => {
|
|
17
|
+
clearTimeout(timer);
|
|
18
|
+
pointer = undefined;
|
|
19
|
+
};
|
|
20
|
+
const dismiss = () => {
|
|
21
|
+
if (!menu.matches(':popover-open'))
|
|
22
|
+
return;
|
|
23
|
+
menu.hidePopover();
|
|
24
|
+
trigger.setAttribute('aria-expanded', 'false');
|
|
25
|
+
listeners?.abort();
|
|
26
|
+
};
|
|
27
|
+
const close = () => {
|
|
28
|
+
dismiss();
|
|
29
|
+
trigger.focus();
|
|
30
|
+
};
|
|
31
|
+
const open = () => {
|
|
32
|
+
cancel();
|
|
33
|
+
if (!trigger.isConnected || menu.matches(':popover-open'))
|
|
34
|
+
return;
|
|
35
|
+
// A manual popover stays open when the opening right-click or long press is released.
|
|
36
|
+
menu.showPopover();
|
|
37
|
+
const rect = trigger.getBoundingClientRect();
|
|
38
|
+
menu.style.left = `${Math.max(4, Math.min(rect.left, innerWidth - menu.offsetWidth - 4))}px`;
|
|
39
|
+
menu.style.top = `${Math.max(4, rect.bottom + menu.offsetHeight <= innerHeight - 4
|
|
40
|
+
? rect.bottom : rect.top - menu.offsetHeight)}px`;
|
|
41
|
+
trigger.setAttribute('aria-expanded', 'true');
|
|
42
|
+
items[0].focus();
|
|
43
|
+
listeners?.abort();
|
|
44
|
+
listeners = new AbortController();
|
|
45
|
+
const { signal } = listeners;
|
|
46
|
+
document.addEventListener('scroll', close, { capture: true, signal });
|
|
47
|
+
window.addEventListener('resize', close, { signal });
|
|
48
|
+
document.addEventListener('pointerdown', event => {
|
|
49
|
+
if ((event.target instanceof Node) && !menu.contains(event.target) && !trigger.contains(event.target))
|
|
50
|
+
dismiss();
|
|
51
|
+
}, { signal });
|
|
52
|
+
document.addEventListener('keydown', event => {
|
|
53
|
+
if ((event.key !== 'Escape') || event.defaultPrevented)
|
|
54
|
+
return;
|
|
55
|
+
event.preventDefault();
|
|
56
|
+
close();
|
|
57
|
+
}, { signal });
|
|
58
|
+
};
|
|
59
|
+
menu.addEventListener('toggle', () => {
|
|
60
|
+
if (menu.matches(':popover-open'))
|
|
61
|
+
return;
|
|
62
|
+
trigger.setAttribute('aria-expanded', 'false');
|
|
63
|
+
listeners?.abort();
|
|
64
|
+
});
|
|
65
|
+
menu.addEventListener('click', event => {
|
|
66
|
+
if ((event.target instanceof Element) && event.target.closest('button'))
|
|
67
|
+
dismiss();
|
|
68
|
+
});
|
|
69
|
+
menu.addEventListener('keydown', event => {
|
|
70
|
+
const index = items.indexOf(document.activeElement);
|
|
71
|
+
let next;
|
|
72
|
+
switch (event.key) {
|
|
73
|
+
case 'ArrowDown':
|
|
74
|
+
next = (index + 1) % items.length;
|
|
75
|
+
break;
|
|
76
|
+
case 'ArrowUp':
|
|
77
|
+
next = (index + items.length - 1) % items.length;
|
|
78
|
+
break;
|
|
79
|
+
case 'Home':
|
|
80
|
+
next = 0;
|
|
81
|
+
break;
|
|
82
|
+
case 'End':
|
|
83
|
+
next = items.length - 1;
|
|
84
|
+
break;
|
|
85
|
+
case 'Escape':
|
|
86
|
+
event.preventDefault();
|
|
87
|
+
close();
|
|
88
|
+
return;
|
|
89
|
+
case 'Tab':
|
|
90
|
+
close();
|
|
91
|
+
return;
|
|
92
|
+
default: return;
|
|
93
|
+
}
|
|
94
|
+
event.preventDefault();
|
|
95
|
+
items[next].focus();
|
|
96
|
+
});
|
|
97
|
+
trigger.addEventListener('contextmenu', event => {
|
|
98
|
+
event.preventDefault();
|
|
99
|
+
suppressClick = true;
|
|
100
|
+
open();
|
|
101
|
+
});
|
|
102
|
+
trigger.addEventListener('keydown', event => {
|
|
103
|
+
if ((event.key !== 'ArrowDown') && (event.key !== 'ContextMenu')
|
|
104
|
+
&& !((event.key === 'F10') && event.shiftKey))
|
|
105
|
+
return;
|
|
106
|
+
event.preventDefault();
|
|
107
|
+
open();
|
|
108
|
+
});
|
|
109
|
+
trigger.addEventListener('pointerdown', event => {
|
|
110
|
+
cancel();
|
|
111
|
+
suppressClick = false;
|
|
112
|
+
if (!event.isPrimary || (event.button !== 0))
|
|
113
|
+
return;
|
|
114
|
+
pointer = { id: event.pointerId, x: event.clientX, y: event.clientY };
|
|
115
|
+
trigger.setPointerCapture(event.pointerId);
|
|
116
|
+
timer = setTimeout(() => {
|
|
117
|
+
suppressClick = true;
|
|
118
|
+
open();
|
|
119
|
+
}, 500);
|
|
120
|
+
});
|
|
121
|
+
trigger.addEventListener('pointermove', event => {
|
|
122
|
+
if (pointer && (pointer.id === event.pointerId)
|
|
123
|
+
&& (Math.hypot(event.clientX - pointer.x, event.clientY - pointer.y) > 10)) {
|
|
124
|
+
suppressClick = true;
|
|
125
|
+
cancel();
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
for (const type of ['pointercancel', 'pointerup', 'lostpointercapture'])
|
|
129
|
+
trigger.addEventListener(type, cancel);
|
|
130
|
+
trigger.addEventListener('click', event => {
|
|
131
|
+
if (!suppressClick || (event.detail === 0))
|
|
132
|
+
return;
|
|
133
|
+
event.preventDefault();
|
|
134
|
+
event.stopImmediatePropagation();
|
|
135
|
+
}, { capture: true });
|
|
136
|
+
});
|