@fluixi-ui/bulk-editor 0.3.0-alpha.12 → 0.3.0-alpha.13

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.
@@ -3,57 +3,41 @@ import { For } from "@fluixi/core";
3
3
  import { createSignal, createMemo, createEffect, onCleanup, untrack } from "@fluixi/reactive/signal";
4
4
  import { Checkbox } from "@fluixi-ui/checkbox";
5
5
  import { createBulkEditorState } from "./state.js";
6
- const _tmpl$0 = '<div class="flx-ui-be-check-wrap"><!--fx--><!--fx/--></div>';
7
- const _tmpl$1 = "<tbody><!--fx--><!--fx/--></tbody>";
8
- delegateEvents(["click", "change", "input", "blur", "focus", "keydown"]);
6
+ const _fxTmpl$0 = '<div role="separator"></div>';
7
+ const _fxTmpl$1 = '<td class="flx-ui-be-foot-cell"></td>';
8
+ const _fxTmpl$2 = '<td class="flx-ui-be-group-cell"></td>';
9
+ const _fxTmpl$3 = '<th class="flx-ui-be-filter-cell"></th>';
10
+ const _fxTmpl$4 = '<th class="flx-ui-be-actions-head"></th>';
11
+ const _fxTmpl$5 = "<tbody><!--fx--><!--fx/--></tbody>";
12
+ const _fxTmpl$6 = '<div class="flx-ui-be-check-wrap"><!--fx--><!--fx/--></div>';
13
+ delegateEvents(["click", "mousedown", "dblclick", "input", "change", "focus", "blur", "keydown"]);
9
14
  const DEFAULT_COL_W = 130;
10
15
  const toggleAttr = (el, name, on) => on ? el.setAttribute(name, "") : el.removeAttribute(name);
11
16
  const Padlock = () => (() => {
12
17
  const _el$ = createNativeElement("svg", true);
13
- spread({
14
- element: _el$,
15
- props: {
16
- viewBox: "0 0 24 24",
17
- width: "12",
18
- height: "12",
19
- fill: "none",
20
- stroke: "currentColor",
21
- "stroke-width": "2",
22
- "stroke-linecap": "round",
23
- "stroke-linejoin": "round",
24
- "aria-hidden": "true"
25
- },
26
- isSVG: true
27
- });
18
+ spread({ element: _el$, props: { viewBox: "0 0 24 24", width: "12", height: "12", fill: "none", stroke: "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "aria-hidden": "true" }, isSVG: true });
28
19
  insert(_el$, (() => {
29
20
  const _el$2 = createNativeElement("rect", true);
30
- spread({
31
- element: _el$2,
32
- props: {
33
- x: "5",
34
- y: "11",
35
- width: "14",
36
- height: "10",
37
- rx: "2"
38
- },
39
- isSVG: true
40
- });
21
+ spread({ element: _el$2, props: { x: "5", y: "11", width: "14", height: "10", rx: "2" }, isSVG: true });
41
22
  return _el$2;
42
23
  })());
43
24
  insert(_el$, (() => {
44
25
  const _el$2 = createNativeElement("path", true);
45
- spread({
46
- element: _el$2,
47
- props: {
48
- d: "M8 11V7a4 4 0 0 1 8 0v4"
49
- },
50
- isSVG: true
51
- });
26
+ spread({ element: _el$2, props: { d: "M8 11V7a4 4 0 0 1 8 0v4" }, isSVG: true });
52
27
  return _el$2;
53
28
  })());
54
29
  return _el$;
55
30
  })();
56
- const HINTS = [["↑↓←→", "navigate"], ["⇧+↑↓←→", "extend"], ["Click header", "column"], ["Ctrl+A", "all"], ["Enter/F2", "edit"], ["Del", "clear"], ["Ctrl+D", "fill down"], ["Ctrl+C/V", "copy/paste"]];
31
+ const HINTS = [
32
+ ["↑↓←→", "navigate"],
33
+ ["⇧+↑↓←→", "extend"],
34
+ ["Click header", "column"],
35
+ ["Ctrl+A", "all"],
36
+ ["Enter/F2", "edit"],
37
+ ["Del", "clear"],
38
+ ["Ctrl+D", "fill down"],
39
+ ["Ctrl+C/V", "copy/paste"]
40
+ ];
57
41
  function BulkEditor(props) {
58
42
  const state = createBulkEditorState(props);
59
43
  const labelWidth = props.labelWidth ?? 200;
@@ -141,10 +125,7 @@ function BulkEditor(props) {
141
125
  const tabMove = (back) => {
142
126
  const s = untrack(state.selection);
143
127
  if (!s) return;
144
- const {
145
- row: r,
146
- col: c
147
- } = s.anchor;
128
+ const { row: r, col: c } = s.anchor;
148
129
  const nc = state.colCount();
149
130
  if (back) state.selectCell(c > 0 ? r : r - 1, c > 0 ? c - 1 : nc - 1);
150
131
  else state.selectCell(c < nc - 1 ? r : r + 1, c < nc - 1 ? c + 1 : 0);
@@ -184,10 +165,7 @@ function BulkEditor(props) {
184
165
  }
185
166
  return;
186
167
  }
187
- const {
188
- row: r,
189
- col: c
190
- } = s.anchor;
168
+ const { row: r, col: c } = s.anchor;
191
169
  switch (e.key) {
192
170
  case "ArrowUp":
193
171
  e.preventDefault();
@@ -268,10 +246,7 @@ function BulkEditor(props) {
268
246
  const el = document.elementFromPoint(x, y)?.closest("[data-cell]");
269
247
  if (!el?.dataset.cell) return null;
270
248
  const [r, c] = el.dataset.cell.split(":").map(Number);
271
- return {
272
- r,
273
- c
274
- };
249
+ return { r, c };
275
250
  };
276
251
  const trackDrag = (onMove, onEnd) => {
277
252
  const move = (ev) => onMove(ev);
@@ -302,10 +277,13 @@ function BulkEditor(props) {
302
277
  const onFillHandleDown = (e) => {
303
278
  e.preventDefault();
304
279
  e.stopPropagation();
305
- trackDrag((ev) => {
306
- const pos = cellFromPoint(ev.clientX, ev.clientY);
307
- if (pos) state.selectCell(pos.r, pos.c, true);
308
- }, () => state.fillDown());
280
+ trackDrag(
281
+ (ev) => {
282
+ const pos = cellFromPoint(ev.clientX, ev.clientY);
283
+ if (pos) state.selectCell(pos.r, pos.c, true);
284
+ },
285
+ () => state.fillDown()
286
+ );
309
287
  };
310
288
  const [menu, setMenu] = createSignal(null);
311
289
  const closeMenu = () => setMenu(null);
@@ -314,24 +292,12 @@ function BulkEditor(props) {
314
292
  e.preventDefault();
315
293
  containerEl?.focus();
316
294
  if (!state.isSelected(r, c)) state.selectCell(r, c);
317
- setMenu({
318
- x: e.clientX,
319
- y: e.clientY,
320
- kind: "cell",
321
- r,
322
- c
323
- });
295
+ setMenu({ x: e.clientX, y: e.clientY, kind: "cell", r, c });
324
296
  };
325
297
  const openColumnMenu = (e, c) => {
326
298
  if (props.contextMenu === false) return;
327
299
  e.preventDefault();
328
- setMenu({
329
- x: e.clientX,
330
- y: e.clientY,
331
- kind: "column",
332
- r: -1,
333
- c
334
- });
300
+ setMenu({ x: e.clientX, y: e.clientY, kind: "column", r: -1, c });
335
301
  };
336
302
  const cellMenuItems = (r, c) => {
337
303
  const row = state.rowAt(r);
@@ -341,49 +307,20 @@ function BulkEditor(props) {
341
307
  const items = [];
342
308
  if (row && col && !state.isColumnReadOnly(col)) {
343
309
  const locked = state.isCellLockedAt(r, c);
344
- items.push({
345
- label: locked ? "Unlock cell" : "Lock cell",
346
- run: () => state.toggleCellLock(row.id, col.key)
347
- });
310
+ items.push({ label: locked ? "Unlock cell" : "Lock cell", run: () => state.toggleCellLock(row.id, col.key) });
348
311
  }
349
312
  if (multi) {
350
- items.push({
351
- label: "Lock selection",
352
- run: () => state.lockSelection(true)
353
- });
354
- items.push({
355
- label: "Unlock selection",
356
- run: () => state.lockSelection(false)
357
- });
313
+ items.push({ label: "Lock selection", run: () => state.lockSelection(true) });
314
+ items.push({ label: "Unlock selection", run: () => state.lockSelection(false) });
358
315
  }
359
316
  if (row) {
360
317
  const locked = state.getRowLockState(row.id) === "all";
361
- items.push({
362
- label: locked ? "Unlock row" : "Lock row",
363
- run: () => state.toggleRowLock(row.id)
364
- });
318
+ items.push({ label: locked ? "Unlock row" : "Lock row", run: () => state.toggleRowLock(row.id) });
365
319
  }
366
- items.push({
367
- label: "",
368
- separator: true
369
- }, {
370
- label: "Copy",
371
- run: copy
372
- }, {
373
- label: "Clear",
374
- run: () => state.clearRange()
375
- });
320
+ items.push({ label: "", separator: true }, { label: "Copy", run: copy }, { label: "Clear", run: () => state.clearRange() });
376
321
  if (props.contextMenuItems && row && col) {
377
- const custom = props.contextMenuItems({
378
- row,
379
- col,
380
- r,
381
- c
382
- });
383
- if (custom.length) items.push({
384
- label: "",
385
- separator: true
386
- }, ...custom);
322
+ const custom = props.contextMenuItems({ row, col, r, c });
323
+ if (custom.length) items.push({ label: "", separator: true }, ...custom);
387
324
  }
388
325
  return items;
389
326
  };
@@ -392,52 +329,19 @@ function BulkEditor(props) {
392
329
  if (!col) return [];
393
330
  const items = [];
394
331
  if (props.sortable ?? true) {
395
- items.push({
396
- label: "Sort ascending",
397
- run: () => state.setSort({
398
- colKey: col.key,
399
- dir: "asc"
400
- })
401
- });
402
- items.push({
403
- label: "Sort descending",
404
- run: () => state.setSort({
405
- colKey: col.key,
406
- dir: "desc"
407
- })
408
- });
409
- if (state.sort()?.colKey === col.key) items.push({
410
- label: "Clear sort",
411
- run: () => state.setSort(null)
412
- });
332
+ items.push({ label: "Sort ascending", run: () => state.setSort({ colKey: col.key, dir: "asc" }) });
333
+ items.push({ label: "Sort descending", run: () => state.setSort({ colKey: col.key, dir: "desc" }) });
334
+ if (state.sort()?.colKey === col.key) items.push({ label: "Clear sort", run: () => state.setSort(null) });
413
335
  }
414
336
  if (!state.isColumnReadOnly(col)) {
415
337
  const locked = state.getColumnLockState(col.key) === "all";
416
- items.push({
417
- label: "",
418
- separator: true
419
- }, {
420
- label: locked ? "Unlock column" : "Lock column",
421
- run: () => state.toggleColumnLock(col.key)
422
- });
338
+ items.push({ label: "", separator: true }, { label: locked ? "Unlock column" : "Lock column", run: () => state.toggleColumnLock(col.key) });
423
339
  }
424
- if (state.getColumnFilter(col.key)) items.push({
425
- label: "Clear filter",
426
- run: () => state.setColumnFilter(col.key, "")
427
- });
428
- if (state.columnWidths().has(col.key)) items.push({
429
- label: "Reset width",
430
- run: () => state.resetColumnWidth(col.key)
431
- });
340
+ if (state.getColumnFilter(col.key)) items.push({ label: "Clear filter", run: () => state.setColumnFilter(col.key, "") });
341
+ if (state.columnWidths().has(col.key)) items.push({ label: "Reset width", run: () => state.resetColumnWidth(col.key) });
432
342
  if (props.columnMenuItems) {
433
- const custom = props.columnMenuItems({
434
- col,
435
- c
436
- });
437
- if (custom.length) items.push({
438
- label: "",
439
- separator: true
440
- }, ...custom);
343
+ const custom = props.columnMenuItems({ col, c });
344
+ if (custom.length) items.push({ label: "", separator: true }, ...custom);
441
345
  }
442
346
  return items;
443
347
  };
@@ -471,64 +375,37 @@ function BulkEditor(props) {
471
375
  const cellContent = (row, col, r, c) => {
472
376
  if (col.type === "checkbox") {
473
377
  return (() => {
474
- const _el$ = templateNode(_tmpl$0, "div", true);
378
+ const _el$ = templateNode(_fxTmpl$6, "div", true);
475
379
  const _n$0 = _el$.firstChild;
476
380
  const _n$1 = holeEnd(_n$0);
477
- insert(_el$, holeScope(_n$0, () => createMemo(() => createComponent(Checkbox, {
478
- get className() {
479
- return "flx-ui-be-check";
480
- },
481
- get checked() {
482
- return state.getRawAt(r, c) === "1";
483
- },
484
- get disabled() {
485
- return (col.disable?.({
486
- row,
487
- col
488
- }) ?? false) || state.isCellLockedAt(r, c);
489
- },
490
- get onClick() {
491
- return (e) => e.stopPropagation();
492
- },
493
- get onChange() {
494
- return (checked) => state.setCellAt(r, c, checked ? "1" : "0");
495
- }
496
- }))), _n$1, holeContent(_n$0, _n$1));
381
+ insert(_el$, holeScope(_n$0, () => createMemo(() => createComponent(Checkbox, { get className() {
382
+ return "flx-ui-be-check";
383
+ }, get checked() {
384
+ return state.getRawAt(r, c) === "1";
385
+ }, get disabled() {
386
+ return (col.disable?.({ row, col }) ?? false) || state.isCellLockedAt(r, c);
387
+ }, get onClick() {
388
+ return ((e) => e.stopPropagation());
389
+ }, get onChange() {
390
+ return ((checked) => state.setCellAt(r, c, checked ? "1" : "0"));
391
+ } }))), _n$1, holeContent(_n$0, _n$1));
497
392
  return _el$;
498
393
  })();
499
394
  }
500
395
  if (state.isEditing(r, c)) {
501
396
  return (() => {
502
397
  const _el$ = createNativeElement("input");
503
- spread({
504
- element: _el$,
505
- props: {
506
- className: "flx-ui-be-input",
507
- type: "text",
508
- inputmode: () => col.type === "number" ? "decimal" : void 0,
509
- style: () => `text-align:${align(col)}`,
510
- value: () => state.editBuffer(),
511
- onInput: (e) => state.setEditBuffer(e.target.value),
512
- onBlur: () => {
513
- state.commitEdit();
514
- containerEl?.focus();
515
- },
516
- onClick: (e) => e.stopPropagation()
517
- }
518
- });
398
+ spread({ element: _el$, props: { className: "flx-ui-be-input", type: "text", inputmode: () => col.type === "number" ? "decimal" : void 0, style: () => `text-align:${align(col)}`, value: (() => state.editBuffer()), onInput: ((e) => state.setEditBuffer(e.target.value)), onBlur: (() => {
399
+ state.commitEdit();
400
+ containerEl?.focus();
401
+ }), onClick: ((e) => e.stopPropagation()) } });
519
402
  return _el$;
520
403
  })();
521
404
  }
522
405
  return (() => {
523
406
  const _el$ = createNativeElement("div");
524
- spread({
525
- element: _el$,
526
- props: {
527
- className: "flx-ui-be-val",
528
- style: () => `justify-content:${align(col) === "left" ? "flex-start" : align(col) === "center" ? "center" : "flex-end"}`
529
- }
530
- });
531
- insert(_el$, () => {
407
+ spread({ element: _el$, props: { className: "flx-ui-be-val", style: () => `justify-content:${align(col) === "left" ? "flex-start" : align(col) === "center" ? "center" : "flex-end"}` } });
408
+ insert(_el$, (() => {
532
409
  const v = state.getDisplayAt(r, c);
533
410
  return v ? v : (() => {
534
411
  const _el$2 = createNativeElement("span");
@@ -536,39 +413,20 @@ function BulkEditor(props) {
536
413
  insert(_el$2, () => col.placeholder ?? "", null);
537
414
  return _el$2;
538
415
  })();
539
- });
416
+ }));
540
417
  return _el$;
541
418
  })();
542
419
  };
543
420
  return (() => {
544
421
  const _el$ = createNativeElement("div");
545
- spread({
546
- element: _el$,
547
- props: {
548
- className: () => props.class ? `flx-ui-bulk-editor ${props.class}` : "flx-ui-bulk-editor",
549
- role: "grid",
550
- tabindex: 0,
551
- "aria-colcount": () => state.colCount() + 1,
552
- ref: (el) => {
553
- containerEl = el;
554
- },
555
- onFocus: () => setFocused(true),
556
- onBlur: (e) => {
557
- if (!containerEl?.contains(e.relatedTarget)) setFocused(false);
558
- },
559
- onKeyDown
560
- }
561
- });
422
+ spread({ element: _el$, props: { className: () => props.class ? `flx-ui-bulk-editor ${props.class}` : "flx-ui-bulk-editor", role: "grid", tabindex: 0, "aria-colcount": (() => state.colCount() + 1), ref: ((el) => {
423
+ containerEl = el;
424
+ }), onFocus: (() => setFocused(true)), onBlur: ((e) => {
425
+ if (!containerEl?.contains(e.relatedTarget)) setFocused(false);
426
+ }), onKeyDown } });
562
427
  insert(_el$, (() => {
563
428
  const _el$2 = createNativeElement("div");
564
- spread({
565
- element: _el$2,
566
- props: {
567
- className: "flx-ui-be-scroll",
568
- ref: (el) => setScrollEl(el),
569
- style: () => props.maxHeight ? `max-height:${props.maxHeight}` : void 0
570
- }
571
- });
429
+ spread({ element: _el$2, props: { className: "flx-ui-be-scroll", ref: ((el) => setScrollEl(el)), style: () => props.maxHeight ? `max-height:${props.maxHeight}` : void 0 } });
572
430
  insert(_el$2, (() => {
573
431
  const _el$3 = createNativeElement("table");
574
432
  _el$3.setAttribute("class", "flx-ui-be-table");
@@ -579,384 +437,232 @@ function BulkEditor(props) {
579
437
  _el$5.setAttribute("role", "row");
580
438
  insert(_el$5, (() => {
581
439
  const _el$6 = createNativeElement("th");
582
- spread({
583
- element: _el$6,
584
- props: {
585
- className: "flx-ui-be-corner",
586
- style: `min-width:${labelWidth}px;width:${labelWidth}px`,
587
- onClick: () => state.selectAll(),
588
- title: "Select all (Ctrl+A)"
589
- }
590
- });
591
- insert(_el$6, () => typeof props.labelHeader === "function" ? props.labelHeader() : props.labelHeader ?? "");
440
+ spread({ element: _el$6, props: { className: "flx-ui-be-corner", style: `min-width:${labelWidth}px;width:${labelWidth}px`, onClick: (() => state.selectAll()), title: "Select all (Ctrl+A)" } });
441
+ insert(_el$6, (() => typeof props.labelHeader === "function" ? props.labelHeader() : props.labelHeader ?? ""));
592
442
  return _el$6;
593
443
  })());
594
- insert(_el$5, createMemo(() => createComponent(For, {
595
- get each() {
596
- return state.columns;
597
- },
598
- get children() {
599
- return (col, ci) => (() => {
600
- const _el$6 = createNativeElement("th");
601
- spread({
602
- element: _el$6,
603
- props: {
604
- className: "flx-ui-be-colh",
605
- role: "columnheader",
606
- "data-col-head": () => String(ci()),
607
- "data-drop-target": () => dropCol() === col.key ? "" : void 0,
608
- style: () => `${colBox(col)};text-align:${align(col)}`,
609
- draggable: () => props.reorderable !== false,
610
- onClick: () => state.selectColumn(ci()),
611
- onContextMenu: (e) => openColumnMenu(e, ci()),
612
- onDragStart: (e) => {
613
- setDragCol(col.key);
614
- e.dataTransfer?.setData("text/plain", col.key);
615
- },
616
- onDragEnter: () => {
617
- if (dragCol() && dragCol() !== col.key) setDropCol(col.key);
618
- },
619
- onDragOver: (e) => {
620
- if (dragCol() && dragCol() !== col.key) e.preventDefault();
621
- },
622
- onDrop: (e) => {
623
- e.preventDefault();
624
- const from = dragCol();
625
- if (from) state.moveColumn(from, col.key);
626
- endReorder();
627
- },
628
- onDragEnd: endReorder
629
- }
630
- });
631
- insert(_el$6, () => props.resizable !== false && (() => {
632
- const _el$7 = createNativeElement("div");
633
- spread({
634
- element: _el$7,
635
- props: {
636
- className: "flx-ui-be-col-resize",
637
- onMouseDown: (e) => startResize(e, col)
638
- }
639
- });
640
- return _el$7;
641
- })());
642
- insert(_el$6, (() => {
643
- const _el$7 = createNativeElement("div");
644
- _el$7.setAttribute("class", "flx-ui-be-colh-inner");
645
- insert(_el$7, () => col.type === "checkbox" && createMemo(() => createComponent(Checkbox, {
646
- get className() {
647
- return "flx-ui-be-head-check";
648
- },
649
- get "aria-label"() {
650
- return "Toggle all";
651
- },
652
- get checked() {
653
- return state.getColumnCheckedState(col.key) === "all" ? true : state.getColumnCheckedState(col.key) === "some" ? "indeterminate" : false;
654
- },
655
- get onClick() {
656
- return (e) => e.stopPropagation();
657
- },
658
- get onChange() {
659
- return () => state.toggleColumnChecked(col.key);
660
- }
661
- })), null);
662
- insert(_el$7, (() => {
663
- const _el$8 = createNativeElement("span");
664
- _el$8.setAttribute("class", "flx-ui-be-colh-label");
665
- insert(_el$8, () => typeof col.header === "function" ? col.header() : col.header, null);
666
- return _el$8;
667
- })());
668
- insert(_el$7, () => col.headerExtra, null);
669
- insert(_el$7, () => (props.sortable ?? true) && (() => {
670
- const _el$8 = createNativeElement("button");
671
- spread({
672
- element: _el$8,
673
- props: {
674
- type: "button",
675
- className: "flx-ui-be-sort",
676
- "aria-label": "Sort column",
677
- onClick: (e) => {
678
- e.stopPropagation();
679
- state.sortBy(col.key);
680
- }
681
- }
682
- });
683
- insert(_el$8, () => {
684
- const s = state.sort();
685
- return s && s.colKey === col.key ? s.dir === "asc" ? "▲" : "▼" : "↕";
686
- });
687
- return _el$8;
688
- })());
689
- return _el$7;
444
+ insert(_el$5, createMemo(() => createComponent(For, { get each() {
445
+ return state.columns;
446
+ }, get children() {
447
+ return ((col, ci) => (() => {
448
+ const _el$6 = createNativeElement("th");
449
+ spread({ element: _el$6, props: { className: "flx-ui-be-colh", role: "columnheader", "data-col-head": (() => String(ci())), "data-drop-target": (() => dropCol() === col.key ? "" : void 0), style: (() => `${colBox(col)};text-align:${align(col)}`), draggable: () => props.reorderable !== false, onClick: (() => state.selectColumn(ci())), onContextMenu: ((e) => openColumnMenu(e, ci())), onDragStart: ((e) => {
450
+ setDragCol(col.key);
451
+ e.dataTransfer?.setData("text/plain", col.key);
452
+ }), onDragEnter: (() => {
453
+ if (dragCol() && dragCol() !== col.key) setDropCol(col.key);
454
+ }), onDragOver: ((e) => {
455
+ if (dragCol() && dragCol() !== col.key) e.preventDefault();
456
+ }), onDrop: ((e) => {
457
+ e.preventDefault();
458
+ const from = dragCol();
459
+ if (from) state.moveColumn(from, col.key);
460
+ endReorder();
461
+ }), onDragEnd: endReorder } });
462
+ insert(_el$6, (() => props.resizable !== false && (() => {
463
+ const _el$7 = createNativeElement("div");
464
+ spread({ element: _el$7, props: { className: "flx-ui-be-col-resize", onMouseDown: ((e) => startResize(e, col)) } });
465
+ return _el$7;
466
+ })()));
467
+ insert(_el$6, (() => {
468
+ const _el$7 = createNativeElement("div");
469
+ _el$7.setAttribute("class", "flx-ui-be-colh-inner");
470
+ insert(_el$7, () => col.type === "checkbox" && createMemo(() => createComponent(Checkbox, { get className() {
471
+ return "flx-ui-be-head-check";
472
+ }, get "aria-label"() {
473
+ return "Toggle all";
474
+ }, get checked() {
475
+ return state.getColumnCheckedState(col.key) === "all" ? true : state.getColumnCheckedState(col.key) === "some" ? "indeterminate" : false;
476
+ }, get onClick() {
477
+ return ((e) => e.stopPropagation());
478
+ }, get onChange() {
479
+ return (() => state.toggleColumnChecked(col.key));
480
+ } })), null);
481
+ insert(_el$7, (() => {
482
+ const _el$8 = createNativeElement("span");
483
+ _el$8.setAttribute("class", "flx-ui-be-colh-label");
484
+ insert(_el$8, () => typeof col.header === "function" ? col.header() : col.header, null);
485
+ return _el$8;
690
486
  })());
691
- return _el$6;
692
- })();
693
- }
694
- })), null);
695
- insert(_el$5, () => hasActions() && templateNode('<th class="flx-ui-be-actions-head"></th>', "th"));
487
+ insert(_el$7, () => col.headerExtra, null);
488
+ insert(_el$7, (() => (props.sortable ?? true) && (() => {
489
+ const _el$8 = createNativeElement("button");
490
+ spread({ element: _el$8, props: { type: "button", className: "flx-ui-be-sort", "aria-label": "Sort column", onClick: ((e) => {
491
+ e.stopPropagation();
492
+ state.sortBy(col.key);
493
+ }) } });
494
+ insert(_el$8, (() => {
495
+ const s = state.sort();
496
+ return s && s.colKey === col.key ? s.dir === "asc" ? "▲" : "▼" : "↕";
497
+ }));
498
+ return _el$8;
499
+ })()));
500
+ return _el$7;
501
+ })());
502
+ return _el$6;
503
+ })());
504
+ } })), null);
505
+ insert(_el$5, (() => hasActions() && templateNode(_fxTmpl$4, "th")));
696
506
  return _el$5;
697
507
  })());
698
- insert(_el$4, () => props.filterRow && (() => {
508
+ insert(_el$4, (() => props.filterRow && (() => {
699
509
  const _el$5 = createNativeElement("tr");
700
510
  _el$5.setAttribute("role", "row");
701
511
  _el$5.setAttribute("class", "flx-ui-be-filter-row");
702
512
  insert(_el$5, (() => {
703
513
  const _el$6 = createNativeElement("th");
704
- spread({
705
- element: _el$6,
706
- props: {
707
- className: "flx-ui-be-filter-corner",
708
- style: `min-width:${labelWidth}px;width:${labelWidth}px`
709
- }
710
- });
514
+ spread({ element: _el$6, props: { className: "flx-ui-be-filter-corner", style: `min-width:${labelWidth}px;width:${labelWidth}px` } });
711
515
  return _el$6;
712
516
  })());
713
- insert(_el$5, createMemo(() => createComponent(For, {
714
- get each() {
715
- return state.columns;
716
- },
717
- get children() {
718
- return (col) => (() => {
719
- const _el$6 = createNativeElement("th");
720
- spread({
721
- element: _el$6,
722
- props: {
723
- className: "flx-ui-be-filter-cell",
724
- style: () => colBox(col)
725
- }
726
- });
727
- insert(_el$6, (() => {
728
- const _el$7 = createNativeElement("input");
729
- spread({
730
- element: _el$7,
731
- props: {
732
- className: "flx-ui-be-filter",
733
- type: "text",
734
- placeholder: () => col.type === "number" ? "e.g. >20" : "Filter…",
735
- value: () => state.getColumnFilter(col.key),
736
- onInput: (e) => state.setColumnFilter(col.key, e.target.value)
737
- }
738
- });
739
- return _el$7;
740
- })());
741
- return _el$6;
742
- })();
743
- }
744
- })), null);
745
- insert(_el$5, () => hasActions() && templateNode('<th class="flx-ui-be-filter-cell"></th>', "th"));
517
+ insert(_el$5, createMemo(() => createComponent(For, { get each() {
518
+ return state.columns;
519
+ }, get children() {
520
+ return ((col) => (() => {
521
+ const _el$6 = createNativeElement("th");
522
+ spread({ element: _el$6, props: { className: "flx-ui-be-filter-cell", style: (() => colBox(col)) } });
523
+ insert(_el$6, (() => {
524
+ const _el$7 = createNativeElement("input");
525
+ spread({ element: _el$7, props: { className: "flx-ui-be-filter", type: "text", placeholder: () => col.type === "number" ? "e.g. >20" : "Filter…", value: (() => state.getColumnFilter(col.key)), onInput: ((e) => state.setColumnFilter(col.key, e.target.value)) } });
526
+ return _el$7;
527
+ })());
528
+ return _el$6;
529
+ })());
530
+ } })), null);
531
+ insert(_el$5, (() => hasActions() && templateNode(_fxTmpl$3, "th")));
746
532
  return _el$5;
747
- })());
533
+ })()));
748
534
  return _el$4;
749
535
  })());
750
536
  insert(_el$3, (() => {
751
- const _el$4 = templateNode(_tmpl$1, "tbody", true);
537
+ const _el$4 = templateNode(_fxTmpl$5, "tbody", true);
752
538
  const _n$0 = _el$4.firstChild;
753
539
  const _n$1 = holeEnd(_n$0);
754
- insert(_el$4, holeScope(_n$0, () => createMemo(() => createComponent(For, {
755
- get each() {
756
- return state.viewRows;
757
- },
758
- get children() {
759
- return (row) => {
760
- if (row.isGroup) {
761
- return (() => {
762
- const _el$5 = createNativeElement("tr");
763
- _el$5.setAttribute("role", "row");
764
- _el$5.setAttribute("class", "flx-ui-be-group");
765
- insert(_el$5, (() => {
766
- const _el$6 = createNativeElement("th");
767
- spread({
768
- element: _el$6,
769
- props: {
770
- className: "flx-ui-be-group-label",
771
- style: `min-width:${labelWidth}px;width:${labelWidth}px`
772
- }
773
- });
774
- insert(_el$6, (() => {
775
- const _el$7 = createNativeElement("div");
776
- _el$7.setAttribute("class", "flx-ui-be-group-head");
777
- insert(_el$7, () => row.thumbnail && (() => {
778
- const _el$8 = createNativeElement("img");
779
- spread({
780
- element: _el$8,
781
- props: {
782
- className: "flx-ui-be-group-thumb",
783
- src: () => row.thumbnail,
784
- alt: ""
785
- }
786
- });
787
- return _el$8;
788
- })(), null);
789
- insert(_el$7, (() => {
790
- const _el$8 = createNativeElement("span");
791
- insert(_el$8, () => row.label, null);
792
- return _el$8;
793
- })());
794
- insert(_el$7, () => row.subLabel && (() => {
795
- const _el$8 = createNativeElement("span");
796
- _el$8.setAttribute("class", "flx-ui-be-rowh-sub");
797
- insert(_el$8, () => row.subLabel, null);
798
- return _el$8;
799
- })(), null);
800
- return _el$7;
801
- })());
802
- return _el$6;
803
- })());
804
- insert(_el$5, createMemo(() => createComponent(For, {
805
- get each() {
806
- return state.columns;
807
- },
808
- get children() {
809
- return (col) => (() => {
810
- const _el$6 = createNativeElement("td");
811
- spread({
812
- element: _el$6,
813
- props: {
814
- className: "flx-ui-be-group-cell",
815
- style: () => colBox(col)
816
- }
817
- });
818
- insert(_el$6, () => row.groupData ? row.groupData[col.key] : null, null);
819
- return _el$6;
820
- })();
821
- }
822
- })), null);
823
- insert(_el$5, () => hasActions() && templateNode('<td class="flx-ui-be-group-cell"></td>', "td"));
824
- return _el$5;
825
- })();
826
- }
827
- const di = () => dataIndex().get(row.id) ?? 0;
540
+ insert(_el$4, holeScope(_n$0, () => createMemo(() => createComponent(For, { get each() {
541
+ return state.viewRows;
542
+ }, get children() {
543
+ return ((row) => {
544
+ if (row.isGroup) {
828
545
  return (() => {
829
546
  const _el$5 = createNativeElement("tr");
830
547
  _el$5.setAttribute("role", "row");
548
+ _el$5.setAttribute("class", "flx-ui-be-group");
831
549
  insert(_el$5, (() => {
832
550
  const _el$6 = createNativeElement("th");
833
- spread({
834
- element: _el$6,
835
- props: {
836
- className: "flx-ui-be-rowh",
837
- role: "rowheader",
838
- "data-row-lbl": () => String(di()),
839
- style: `min-width:${labelWidth}px;width:${labelWidth}px`,
840
- onClick: () => state.selectRow(di())
841
- }
842
- });
551
+ spread({ element: _el$6, props: { className: "flx-ui-be-group-label", style: `min-width:${labelWidth}px;width:${labelWidth}px` } });
843
552
  insert(_el$6, (() => {
844
553
  const _el$7 = createNativeElement("div");
845
- _el$7.setAttribute("class", "flx-ui-be-rowh-inner");
846
- insert(_el$7, (() => {
847
- const _el$8 = createNativeElement("button");
848
- spread({
849
- element: _el$8,
850
- props: {
851
- className: "flx-ui-be-row-lock",
852
- type: "button",
853
- tabindex: -1,
854
- "aria-label": "Lock row",
855
- onMouseDown: (e) => e.stopPropagation(),
856
- onClick: (e) => {
857
- e.stopPropagation();
858
- state.toggleRowLock(row.id);
859
- }
860
- }
861
- });
862
- insert(_el$8, createMemo(() => createComponent(Padlock, {})), null);
554
+ _el$7.setAttribute("class", "flx-ui-be-group-head");
555
+ insert(_el$7, () => row.thumbnail && (() => {
556
+ const _el$8 = createNativeElement("img");
557
+ spread({ element: _el$8, props: { className: "flx-ui-be-group-thumb", src: () => row.thumbnail, alt: "" } });
863
558
  return _el$8;
864
- })());
559
+ })(), null);
865
560
  insert(_el$7, (() => {
866
- const _el$8 = createNativeElement("div");
867
- _el$8.setAttribute("class", "flx-ui-be-rowh-text");
868
- insert(_el$8, (() => {
869
- const _el$9 = createNativeElement("div");
870
- _el$9.setAttribute("class", "flx-ui-be-rowh-label");
871
- insert(_el$9, () => row.label, null);
872
- return _el$9;
873
- })());
874
- insert(_el$8, () => row.subLabel && (() => {
875
- const _el$9 = createNativeElement("div");
876
- _el$9.setAttribute("class", "flx-ui-be-rowh-sub");
877
- insert(_el$9, () => row.subLabel, null);
878
- return _el$9;
879
- })(), null);
561
+ const _el$8 = createNativeElement("span");
562
+ insert(_el$8, () => row.label, null);
880
563
  return _el$8;
881
564
  })());
565
+ insert(_el$7, () => row.subLabel && (() => {
566
+ const _el$8 = createNativeElement("span");
567
+ _el$8.setAttribute("class", "flx-ui-be-rowh-sub");
568
+ insert(_el$8, () => row.subLabel, null);
569
+ return _el$8;
570
+ })(), null);
882
571
  return _el$7;
883
572
  })());
884
573
  return _el$6;
885
574
  })());
886
- insert(_el$5, createMemo(() => createComponent(For, {
887
- get each() {
888
- return state.columns;
889
- },
890
- get children() {
891
- return (col, ci) => (() => {
892
- const _el$6 = createNativeElement("td");
893
- spread({
894
- element: _el$6,
895
- props: {
896
- className: "flx-ui-be-cell",
897
- role: "gridcell",
898
- "data-cell": () => `${di()}:${ci()}`,
899
- style: () => `${colBox(col)};text-align:${align(col)}`,
900
- onMouseDown: (e) => onCellMouseDown(e, di(), ci()),
901
- onDblClick: () => beginEdit(di(), ci()),
902
- onContextMenu: (e) => openMenu(e, di(), ci())
903
- }
904
- });
905
- insert(_el$6, () => cellContent(row, col, di(), ci()));
906
- insert(_el$6, !state.isColumnReadOnly(col) && (() => {
907
- const _el$7 = createNativeElement("button");
908
- spread({
909
- element: _el$7,
910
- props: {
911
- className: "flx-ui-be-lock",
912
- type: "button",
913
- tabindex: -1,
914
- "aria-label": "Lock cell",
915
- onMouseDown: (e) => e.stopPropagation(),
916
- onClick: (e) => {
917
- e.stopPropagation();
918
- state.toggleCellLock(row.id, col.key);
919
- }
920
- }
921
- });
922
- insert(_el$7, createMemo(() => createComponent(Padlock, {})), null);
923
- return _el$7;
924
- })());
925
- insert(_el$6, () => state.isAnchor(di(), ci()) && !state.isEditing(di(), ci()) && (() => {
926
- const _el$7 = createNativeElement("div");
927
- spread({
928
- element: _el$7,
929
- props: {
930
- className: "flx-ui-be-fill-handle",
931
- onMouseDown: onFillHandleDown
932
- }
933
- });
934
- return _el$7;
935
- })());
936
- return _el$6;
937
- })();
938
- }
939
- })), null);
940
- insert(_el$5, () => hasActions() && (() => {
575
+ insert(_el$5, createMemo(() => createComponent(For, { get each() {
576
+ return state.columns;
577
+ }, get children() {
578
+ return ((col) => (() => {
579
+ const _el$6 = createNativeElement("td");
580
+ spread({ element: _el$6, props: { className: "flx-ui-be-group-cell", style: (() => colBox(col)) } });
581
+ insert(_el$6, () => row.groupData ? row.groupData[col.key] : null, null);
582
+ return _el$6;
583
+ })());
584
+ } })), null);
585
+ insert(_el$5, (() => hasActions() && templateNode(_fxTmpl$2, "td")));
586
+ return _el$5;
587
+ })();
588
+ }
589
+ const di = () => dataIndex().get(row.id) ?? 0;
590
+ return (() => {
591
+ const _el$5 = createNativeElement("tr");
592
+ _el$5.setAttribute("role", "row");
593
+ insert(_el$5, (() => {
594
+ const _el$6 = createNativeElement("th");
595
+ spread({ element: _el$6, props: { className: "flx-ui-be-rowh", role: "rowheader", "data-row-lbl": (() => String(di())), style: `min-width:${labelWidth}px;width:${labelWidth}px`, onClick: (() => state.selectRow(di())) } });
596
+ insert(_el$6, (() => {
597
+ const _el$7 = createNativeElement("div");
598
+ _el$7.setAttribute("class", "flx-ui-be-rowh-inner");
599
+ insert(_el$7, (() => {
600
+ const _el$8 = createNativeElement("button");
601
+ spread({ element: _el$8, props: { className: "flx-ui-be-row-lock", type: "button", tabindex: -1, "aria-label": "Lock row", onMouseDown: ((e) => e.stopPropagation()), onClick: ((e) => {
602
+ e.stopPropagation();
603
+ state.toggleRowLock(row.id);
604
+ }) } });
605
+ insert(_el$8, createMemo(() => createComponent(Padlock, {})), null);
606
+ return _el$8;
607
+ })());
608
+ insert(_el$7, (() => {
609
+ const _el$8 = createNativeElement("div");
610
+ _el$8.setAttribute("class", "flx-ui-be-rowh-text");
611
+ insert(_el$8, (() => {
612
+ const _el$9 = createNativeElement("div");
613
+ _el$9.setAttribute("class", "flx-ui-be-rowh-label");
614
+ insert(_el$9, () => row.label, null);
615
+ return _el$9;
616
+ })());
617
+ insert(_el$8, () => row.subLabel && (() => {
618
+ const _el$9 = createNativeElement("div");
619
+ _el$9.setAttribute("class", "flx-ui-be-rowh-sub");
620
+ insert(_el$9, () => row.subLabel, null);
621
+ return _el$9;
622
+ })(), null);
623
+ return _el$8;
624
+ })());
625
+ return _el$7;
626
+ })());
627
+ return _el$6;
628
+ })());
629
+ insert(_el$5, createMemo(() => createComponent(For, { get each() {
630
+ return state.columns;
631
+ }, get children() {
632
+ return ((col, ci) => (() => {
941
633
  const _el$6 = createNativeElement("td");
942
- spread({
943
- element: _el$6,
944
- props: {
945
- className: "flx-ui-be-actions",
946
- onMouseDown: (e) => e.stopPropagation()
947
- }
948
- });
949
- insert(_el$6, () => row.rowActions, null);
634
+ spread({ element: _el$6, props: { className: "flx-ui-be-cell", role: "gridcell", "data-cell": (() => `${di()}:${ci()}`), style: (() => `${colBox(col)};text-align:${align(col)}`), onMouseDown: ((e) => onCellMouseDown(e, di(), ci())), onDblClick: (() => beginEdit(di(), ci())), onContextMenu: ((e) => openMenu(e, di(), ci())) } });
635
+ insert(_el$6, (() => cellContent(row, col, di(), ci())));
636
+ insert(_el$6, !state.isColumnReadOnly(col) && (() => {
637
+ const _el$7 = createNativeElement("button");
638
+ spread({ element: _el$7, props: { className: "flx-ui-be-lock", type: "button", tabindex: -1, "aria-label": "Lock cell", onMouseDown: ((e) => e.stopPropagation()), onClick: ((e) => {
639
+ e.stopPropagation();
640
+ state.toggleCellLock(row.id, col.key);
641
+ }) } });
642
+ insert(_el$7, createMemo(() => createComponent(Padlock, {})), null);
643
+ return _el$7;
644
+ })());
645
+ insert(_el$6, (() => state.isAnchor(di(), ci()) && !state.isEditing(di(), ci()) && (() => {
646
+ const _el$7 = createNativeElement("div");
647
+ spread({ element: _el$7, props: { className: "flx-ui-be-fill-handle", onMouseDown: onFillHandleDown } });
648
+ return _el$7;
649
+ })()));
950
650
  return _el$6;
951
651
  })());
952
- return _el$5;
953
- })();
954
- };
955
- }
956
- }))), _n$1, holeContent(_n$0, _n$1));
652
+ } })), null);
653
+ insert(_el$5, (() => hasActions() && (() => {
654
+ const _el$6 = createNativeElement("td");
655
+ spread({ element: _el$6, props: { className: "flx-ui-be-actions", onMouseDown: ((e) => e.stopPropagation()) } });
656
+ insert(_el$6, () => row.rowActions, null);
657
+ return _el$6;
658
+ })()));
659
+ return _el$5;
660
+ })();
661
+ });
662
+ } }))), _n$1, holeContent(_n$0, _n$1));
957
663
  return _el$4;
958
664
  })());
959
- insert(_el$3, () => showFooter() && (() => {
665
+ insert(_el$3, (() => showFooter() && (() => {
960
666
  const _el$4 = createNativeElement("tfoot");
961
667
  insert(_el$4, (() => {
962
668
  const _el$5 = createNativeElement("tr");
@@ -964,106 +670,70 @@ function BulkEditor(props) {
964
670
  _el$5.setAttribute("class", "flx-ui-be-foot-row");
965
671
  insert(_el$5, (() => {
966
672
  const _el$6 = createNativeElement("th");
967
- spread({
968
- element: _el$6,
969
- props: {
970
- className: "flx-ui-be-foot-corner",
971
- style: `min-width:${labelWidth}px;width:${labelWidth}px`
972
- }
973
- });
974
- insert(_el$6, () => typeof props.footerLabel === "function" ? props.footerLabel() : props.footerLabel ?? "");
673
+ spread({ element: _el$6, props: { className: "flx-ui-be-foot-corner", style: `min-width:${labelWidth}px;width:${labelWidth}px` } });
674
+ insert(_el$6, (() => typeof props.footerLabel === "function" ? props.footerLabel() : props.footerLabel ?? ""));
975
675
  return _el$6;
976
676
  })());
977
- insert(_el$5, createMemo(() => createComponent(For, {
978
- get each() {
979
- return state.columns;
980
- },
981
- get children() {
982
- return (col) => (() => {
983
- const _el$6 = createNativeElement("td");
984
- spread({
985
- element: _el$6,
986
- props: {
987
- className: "flx-ui-be-foot-cell",
988
- style: () => `${colBox(col)};text-align:${align(col)}`
989
- }
990
- });
991
- insert(_el$6, () => state.getColumnAggregate(col.key));
992
- return _el$6;
993
- })();
994
- }
995
- })), null);
996
- insert(_el$5, () => hasActions() && templateNode('<td class="flx-ui-be-foot-cell"></td>', "td"));
677
+ insert(_el$5, createMemo(() => createComponent(For, { get each() {
678
+ return state.columns;
679
+ }, get children() {
680
+ return ((col) => (() => {
681
+ const _el$6 = createNativeElement("td");
682
+ spread({ element: _el$6, props: { className: "flx-ui-be-foot-cell", style: (() => `${colBox(col)};text-align:${align(col)}`) } });
683
+ insert(_el$6, (() => state.getColumnAggregate(col.key)));
684
+ return _el$6;
685
+ })());
686
+ } })), null);
687
+ insert(_el$5, (() => hasActions() && templateNode(_fxTmpl$1, "td")));
997
688
  return _el$5;
998
689
  })());
999
690
  return _el$4;
1000
- })());
691
+ })()));
1001
692
  return _el$3;
1002
693
  })());
1003
694
  return _el$2;
1004
695
  })());
1005
- insert(_el$, () => focused() && state.hasSelection() && (() => {
696
+ insert(_el$, (() => focused() && state.hasSelection() && (() => {
1006
697
  const _el$2 = createNativeElement("div");
1007
698
  _el$2.setAttribute("class", "flx-ui-be-hints");
1008
- insert(_el$2, createMemo(() => createComponent(For, {
1009
- get each() {
1010
- return () => HINTS;
1011
- },
1012
- get children() {
1013
- return ([k, label]) => (() => {
1014
- const _el$3 = createNativeElement("span");
1015
- insert(_el$3, (() => {
1016
- const _el$4 = createNativeElement("kbd");
1017
- insert(_el$4, k);
1018
- return _el$4;
1019
- })());
1020
- insert(_el$3, " ");
1021
- insert(_el$3, label);
1022
- return _el$3;
1023
- })();
1024
- }
1025
- })), null);
699
+ insert(_el$2, createMemo(() => createComponent(For, { get each() {
700
+ return (() => HINTS);
701
+ }, get children() {
702
+ return (([k, label]) => (() => {
703
+ const _el$3 = createNativeElement("span");
704
+ insert(_el$3, (() => {
705
+ const _el$4 = createNativeElement("kbd");
706
+ insert(_el$4, k);
707
+ return _el$4;
708
+ })());
709
+ insert(_el$3, " ");
710
+ insert(_el$3, label);
711
+ return _el$3;
712
+ })());
713
+ } })), null);
1026
714
  return _el$2;
1027
- })());
1028
- insert(_el$, () => {
715
+ })()));
716
+ insert(_el$, (() => {
1029
717
  const m = menu();
1030
718
  return m ? (() => {
1031
719
  const _el$2 = createNativeElement("div");
1032
- spread({
1033
- element: _el$2,
1034
- props: {
1035
- className: "flx-ui-be-menu",
1036
- role: "menu",
1037
- style: () => `left:${m.x}px;top:${m.y}px`
1038
- }
1039
- });
1040
- insert(_el$2, createMemo(() => createComponent(For, {
1041
- get each() {
1042
- return menuItems;
1043
- },
1044
- get children() {
1045
- return (item) => item.separator ? templateNode('<div role="separator"></div>', "div") : (() => {
1046
- const _el$3 = createNativeElement("button");
1047
- spread({
1048
- element: _el$3,
1049
- props: {
1050
- type: "button",
1051
- role: "menuitem",
1052
- disabled: () => item.disabled,
1053
- onClick: () => {
1054
- item.run?.();
1055
- closeMenu();
1056
- }
1057
- }
1058
- });
1059
- insert(_el$3, () => item.label, null);
1060
- return _el$3;
1061
- })();
1062
- }
1063
- })), null);
720
+ spread({ element: _el$2, props: { className: "flx-ui-be-menu", role: "menu", style: () => `left:${m.x}px;top:${m.y}px` } });
721
+ insert(_el$2, createMemo(() => createComponent(For, { get each() {
722
+ return menuItems;
723
+ }, get children() {
724
+ return ((item) => item.separator ? templateNode(_fxTmpl$0, "div") : (() => {
725
+ const _el$3 = createNativeElement("button");
726
+ spread({ element: _el$3, props: { type: "button", role: "menuitem", disabled: () => item.disabled, onClick: (() => {
727
+ item.run?.();
728
+ closeMenu();
729
+ }) } });
730
+ insert(_el$3, () => item.label, null);
731
+ return _el$3;
732
+ })());
733
+ } })), null);
1064
734
  return _el$2;
1065
735
  })() : null;
1066
- });
736
+ }));
1067
737
  return _el$;
1068
738
  })();
1069
739
  }