@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 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
- The consumer requests `pane.suspend({ mobileOnly: true })` only when a source gesture has been recognised. The pane
356
- host owns its responsive breakpoint. The token is restored after acceptance and column persistence, or after
357
- cancellation/rejection; it never focuses the search field. View disposal removes the registration and invalidates late
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
- export {};
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 HTMLInputElement) || !(element instanceof HTMLElement))
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 name="reset" title="reset search filters" type="submit" value="reset"></th>
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[name=reset] {
229
- background: url("filter-reset.svg") center no-repeat;
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
@@ -94,5 +94,5 @@
94
94
  "build:front": "tsc -p src/front/tsconfig.json",
95
95
  "test": "npm run build:cjs && node --test \"test/**/*.test.mjs\""
96
96
  },
97
- "version": "0.23.1"
97
+ "version": "0.24.0"
98
98
  }
@@ -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;
@@ -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
- const suspension = this.pane.suspend({ mobileOnly: true });
147
- try {
148
- if (added)
149
- this.add(path, this.abort.signal, { effects: false, hidden: true });
150
- const paths = this.paths();
151
- const operation = this.options.addition.beginExternal(this.columnSource(path), sample, { adding: added, removal: true });
152
- this.drag = { added, intent, operation, paths, restore: () => suspension.restore() };
153
- }
154
- catch (error) {
155
- suspension.restore();
156
- throw error;
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
- const aside = this.content.closest('aside');
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);
@@ -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
+ });
package/search.svg ADDED
@@ -0,0 +1,5 @@
1
+ <svg fill="none" stroke="#666" stroke-linecap="round" stroke-width="2" viewBox="0 0 24 24"
2
+ xmlns="http://www.w3.org/2000/svg">
3
+ <circle cx="10" cy="10" r="7"/>
4
+ <path d="m15 15 6 6"/>
5
+ </svg>