@dxos/react-ui-table 0.3.7 → 0.3.8-main.122b580
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/dist/lib/browser/index.mjs +102 -80
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/types/src/components/ComboboxCell.d.ts +12 -0
- package/dist/types/src/components/ComboboxCell.d.ts.map +1 -0
- package/dist/types/src/components/index.d.ts +1 -0
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/helpers.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +10 -0
- package/dist/types/src/translations.d.ts.map +1 -0
- package/package.json +10 -10
- package/src/components/ComboboxCell.tsx +97 -0
- package/src/components/index.ts +1 -0
- package/src/helpers.tsx +7 -88
- package/src/translations.ts +15 -0
|
@@ -520,43 +520,34 @@ var TableFoot = ({ footers, expand, slots, debug, border }) => {
|
|
|
520
520
|
}))));
|
|
521
521
|
};
|
|
522
522
|
|
|
523
|
-
// packages/ui/react-ui-table/src/
|
|
524
|
-
import {
|
|
525
|
-
import
|
|
526
|
-
import {
|
|
527
|
-
import
|
|
528
|
-
import
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
if (next?.tagName === "INPUT") {
|
|
539
|
-
return next;
|
|
540
|
-
}
|
|
541
|
-
if (container.nextElementSibling) {
|
|
542
|
-
return findNextFocusable(findFirstFocusable, container.nextSibling);
|
|
523
|
+
// packages/ui/react-ui-table/src/components/ComboboxCell.tsx
|
|
524
|
+
import { CaretDown as CaretDown2 } from "@phosphor-icons/react";
|
|
525
|
+
import React3, { useCallback, useState as useState3 } from "react";
|
|
526
|
+
import { Popover as Popover2, useTranslation } from "@dxos/react-ui";
|
|
527
|
+
import { PopoverCombobox } from "@dxos/react-ui-searchlist";
|
|
528
|
+
import { descriptionText, getSize as getSize2, mx as mx3, staticPlaceholderText } from "@dxos/react-ui-theme";
|
|
529
|
+
|
|
530
|
+
// packages/ui/react-ui-table/src/translations.ts
|
|
531
|
+
var translationKey = "table";
|
|
532
|
+
var translations_default = [
|
|
533
|
+
{
|
|
534
|
+
"en-US": {
|
|
535
|
+
[translationKey]: {
|
|
536
|
+
"no selection label": "\xA0"
|
|
537
|
+
}
|
|
543
538
|
}
|
|
544
539
|
}
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
builder: new ColumnBuilder()
|
|
549
|
-
});
|
|
550
|
-
var defaults = (options, ...sources) => {
|
|
551
|
-
return stripUndefinedValues(defaultsDeep({}, options, ...sources));
|
|
552
|
-
};
|
|
540
|
+
];
|
|
541
|
+
|
|
542
|
+
// packages/ui/react-ui-table/src/components/ComboboxCell.tsx
|
|
553
543
|
var initialItems = (model, value) => value ? {
|
|
554
544
|
[model.getId(value)]: {
|
|
555
545
|
label: model.getText(value),
|
|
556
546
|
data: value
|
|
557
547
|
}
|
|
558
548
|
} : {};
|
|
559
|
-
var
|
|
549
|
+
var ComboboxCell = ({ model, value, onValueChange }) => {
|
|
550
|
+
const { t } = useTranslation(translationKey);
|
|
560
551
|
const [items, setItems] = useState3(initialItems(model, value));
|
|
561
552
|
const [loading, setLoading] = useState3(false);
|
|
562
553
|
const [searchInputValue, setSearchInputValue] = useState3("");
|
|
@@ -579,37 +570,67 @@ var CellSelector = ({ model, value, onValueChange }) => {
|
|
|
579
570
|
items,
|
|
580
571
|
onValueChange
|
|
581
572
|
]);
|
|
582
|
-
return /* @__PURE__ */ React3.createElement(
|
|
583
|
-
|
|
584
|
-
}, /* @__PURE__ */ React3.createElement(
|
|
573
|
+
return /* @__PURE__ */ React3.createElement(PopoverCombobox.Root, {
|
|
574
|
+
placeholder: t("no selection label")
|
|
575
|
+
}, /* @__PURE__ */ React3.createElement(PopoverCombobox.Trigger, {
|
|
585
576
|
variant: "ghost",
|
|
586
|
-
classNames: "is-full
|
|
587
|
-
}, /* @__PURE__ */ React3.createElement("span", {
|
|
588
|
-
className: "
|
|
589
|
-
},
|
|
590
|
-
|
|
591
|
-
|
|
577
|
+
classNames: "is-full"
|
|
578
|
+
}, value ? /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("span", {
|
|
579
|
+
className: mx3("font-normal text-start flex-1 min-is-0 truncate mie-2", !value && staticPlaceholderText)
|
|
580
|
+
}, model.getText(value)), /* @__PURE__ */ React3.createElement(CaretDown2, {
|
|
581
|
+
weight: "bold",
|
|
582
|
+
className: getSize2(3)
|
|
583
|
+
})) : null), /* @__PURE__ */ React3.createElement(PopoverCombobox.Content, {
|
|
584
|
+
shouldFilter: false,
|
|
592
585
|
classNames: "is-[--radix-popover-trigger-width]"
|
|
593
|
-
}, /* @__PURE__ */ React3.createElement(
|
|
594
|
-
shouldFilter: false
|
|
595
|
-
}, /* @__PURE__ */ React3.createElement(SearchList.Input, {
|
|
586
|
+
}, /* @__PURE__ */ React3.createElement(PopoverCombobox.Input, {
|
|
596
587
|
value: searchInputValue,
|
|
597
588
|
onValueChange: handleSearchInputValueChange
|
|
598
|
-
}), /* @__PURE__ */ React3.createElement(
|
|
589
|
+
}), /* @__PURE__ */ React3.createElement(PopoverCombobox.List, null, searchInputValue.length < 1 ? /* @__PURE__ */ React3.createElement("p", {
|
|
599
590
|
className: mx3("text-center", descriptionText)
|
|
600
591
|
}, "Start typing to search") : loading ? /* @__PURE__ */ React3.createElement("p", {
|
|
601
592
|
className: mx3("text-center", descriptionText)
|
|
602
|
-
}, "Searching\u2026") : /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(
|
|
593
|
+
}, "Searching\u2026") : /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(PopoverCombobox.Empty, {
|
|
603
594
|
classNames: [
|
|
604
595
|
"text-center",
|
|
605
596
|
descriptionText
|
|
606
597
|
]
|
|
607
|
-
}, "No results"), Object.entries(items).map(([id, { label }]) => /* @__PURE__ */ React3.createElement(
|
|
598
|
+
}, "No results"), Object.entries(items).map(([id, { label }]) => /* @__PURE__ */ React3.createElement(PopoverCombobox.Item, {
|
|
608
599
|
key: id,
|
|
609
600
|
value: id,
|
|
610
601
|
onSelect: handleValueChange,
|
|
611
602
|
classNames: "truncate"
|
|
612
|
-
}, label))))
|
|
603
|
+
}, label)))), /* @__PURE__ */ React3.createElement(Popover2.Arrow, null)));
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
// packages/ui/react-ui-table/src/helpers.tsx
|
|
607
|
+
import { useFocusFinders } from "@fluentui/react-tabster";
|
|
608
|
+
import { Check as Check2, ClipboardText, X as X2 } from "@phosphor-icons/react";
|
|
609
|
+
import { createColumnHelper } from "@tanstack/react-table";
|
|
610
|
+
import format from "date-fns/format";
|
|
611
|
+
import formatDistanceToNow from "date-fns/formatDistanceToNow";
|
|
612
|
+
import defaultsDeep from "lodash.defaultsdeep";
|
|
613
|
+
import React4, { useRef as useRef3, useState as useState4 } from "react";
|
|
614
|
+
import { Input as Input2, Tooltip } from "@dxos/react-ui";
|
|
615
|
+
import { getSize as getSize3, mx as mx4 } from "@dxos/react-ui-theme";
|
|
616
|
+
import { stripUndefinedValues } from "@dxos/util";
|
|
617
|
+
var findNextFocusable = (findFirstFocusable, container) => {
|
|
618
|
+
const next = findFirstFocusable(container);
|
|
619
|
+
if (next) {
|
|
620
|
+
if (next?.tagName === "INPUT") {
|
|
621
|
+
return next;
|
|
622
|
+
}
|
|
623
|
+
if (container.nextElementSibling) {
|
|
624
|
+
return findNextFocusable(findFirstFocusable, container.nextSibling);
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
};
|
|
628
|
+
var createColumnBuilder = () => ({
|
|
629
|
+
helper: createColumnHelper(),
|
|
630
|
+
builder: new ColumnBuilder()
|
|
631
|
+
});
|
|
632
|
+
var defaults = (options, ...sources) => {
|
|
633
|
+
return stripUndefinedValues(defaultsDeep({}, options, ...sources));
|
|
613
634
|
};
|
|
614
635
|
var ColumnBuilder = class {
|
|
615
636
|
/**
|
|
@@ -619,18 +640,18 @@ var ColumnBuilder = class {
|
|
|
619
640
|
return defaults(props, {
|
|
620
641
|
minSize: 100,
|
|
621
642
|
header: (column) => {
|
|
622
|
-
return /* @__PURE__ */
|
|
643
|
+
return /* @__PURE__ */ React4.createElement("div", {
|
|
623
644
|
className: "truncate"
|
|
624
645
|
}, label ?? column.header.id);
|
|
625
646
|
},
|
|
626
|
-
cell: model && onUpdate ? (cell) => /* @__PURE__ */
|
|
647
|
+
cell: model && onUpdate ? (cell) => /* @__PURE__ */ React4.createElement(ComboboxCell, {
|
|
627
648
|
model,
|
|
628
649
|
value: cell.getValue(),
|
|
629
650
|
onValueChange: (value) => onUpdate?.(cell.row.original, cell.column.id, value)
|
|
630
651
|
}) : (cell) => {
|
|
631
652
|
const value = cell.getValue();
|
|
632
|
-
return /* @__PURE__ */
|
|
633
|
-
className:
|
|
653
|
+
return /* @__PURE__ */ React4.createElement("div", {
|
|
654
|
+
className: mx4("truncate", className)
|
|
634
655
|
}, value ? model.getText(value) : "");
|
|
635
656
|
}
|
|
636
657
|
});
|
|
@@ -643,13 +664,13 @@ var ColumnBuilder = class {
|
|
|
643
664
|
minSize: 100,
|
|
644
665
|
// TODO(burdon): Default.
|
|
645
666
|
header: (column) => {
|
|
646
|
-
return /* @__PURE__ */
|
|
667
|
+
return /* @__PURE__ */ React4.createElement("div", {
|
|
647
668
|
className: "truncate"
|
|
648
669
|
}, label ?? column.header.id);
|
|
649
670
|
},
|
|
650
671
|
cell: onUpdate ? (cell) => {
|
|
651
672
|
const initialValue = cell.getValue();
|
|
652
|
-
const [value, setValue] =
|
|
673
|
+
const [value, setValue] = useState4(initialValue);
|
|
653
674
|
const inputRef = useRef3(null);
|
|
654
675
|
const { findFirstFocusable } = useFocusFinders();
|
|
655
676
|
const handleSave = (focusNext = false) => {
|
|
@@ -671,7 +692,7 @@ var ColumnBuilder = class {
|
|
|
671
692
|
const rows = cell.table.getRowModel().flatRows;
|
|
672
693
|
const columns = cell.table.getVisibleFlatColumns();
|
|
673
694
|
const placeholder = cell.row.index === rows.length - 1 && columns[0].id === cell.column.id;
|
|
674
|
-
return /* @__PURE__ */
|
|
695
|
+
return /* @__PURE__ */ React4.createElement(Input2.Root, null, /* @__PURE__ */ React4.createElement(Input2.TextInput, {
|
|
675
696
|
ref: inputRef,
|
|
676
697
|
variant: "subdued",
|
|
677
698
|
placeholder: placeholder ? "Add row..." : void 0,
|
|
@@ -683,8 +704,8 @@ var ColumnBuilder = class {
|
|
|
683
704
|
}));
|
|
684
705
|
} : (cell) => {
|
|
685
706
|
const value = cell.getValue();
|
|
686
|
-
return /* @__PURE__ */
|
|
687
|
-
className:
|
|
707
|
+
return /* @__PURE__ */ React4.createElement("div", {
|
|
708
|
+
className: mx4("truncate", className)
|
|
688
709
|
}, value);
|
|
689
710
|
}
|
|
690
711
|
});
|
|
@@ -696,12 +717,12 @@ var ColumnBuilder = class {
|
|
|
696
717
|
return defaults(props, {
|
|
697
718
|
size: 100,
|
|
698
719
|
minSize: 100,
|
|
699
|
-
header: (cell) => /* @__PURE__ */
|
|
720
|
+
header: (cell) => /* @__PURE__ */ React4.createElement("div", {
|
|
700
721
|
className: "w-full truncate text-right"
|
|
701
722
|
}, label ?? cell.header.id),
|
|
702
723
|
cell: (cell) => {
|
|
703
724
|
const value = cell.getValue();
|
|
704
|
-
const [text, setText] =
|
|
725
|
+
const [text, setText] = useState4();
|
|
705
726
|
const handleEdit = () => {
|
|
706
727
|
if (onUpdate) {
|
|
707
728
|
setText(value !== void 0 ? String(value) : "");
|
|
@@ -716,9 +737,9 @@ var ColumnBuilder = class {
|
|
|
716
737
|
setText(void 0);
|
|
717
738
|
};
|
|
718
739
|
if (text !== void 0) {
|
|
719
|
-
return /* @__PURE__ */
|
|
720
|
-
className:
|
|
721
|
-
}, /* @__PURE__ */
|
|
740
|
+
return /* @__PURE__ */ React4.createElement("div", {
|
|
741
|
+
className: mx4("grow text-right font-mono", className)
|
|
742
|
+
}, /* @__PURE__ */ React4.createElement(Input2.Root, null, /* @__PURE__ */ React4.createElement(Input2.TextInput, {
|
|
722
743
|
autoFocus: true,
|
|
723
744
|
value: text,
|
|
724
745
|
classNames: "px-2",
|
|
@@ -727,8 +748,8 @@ var ColumnBuilder = class {
|
|
|
727
748
|
onKeyDown: (event) => event.key === "Escape" && handleCancel() || event.key === "Enter" && handleSave()
|
|
728
749
|
})));
|
|
729
750
|
}
|
|
730
|
-
return /* @__PURE__ */
|
|
731
|
-
className:
|
|
751
|
+
return /* @__PURE__ */ React4.createElement("div", {
|
|
752
|
+
className: mx4('grow w-full text-right font-mono empty:after:content-["\xA0"]', className),
|
|
732
753
|
onClick: handleEdit
|
|
733
754
|
}, value?.toLocaleString(void 0, {
|
|
734
755
|
minimumFractionDigits: digits ?? 0,
|
|
@@ -745,15 +766,15 @@ var ColumnBuilder = class {
|
|
|
745
766
|
return defaults(props, {
|
|
746
767
|
size: 220,
|
|
747
768
|
minSize: 100,
|
|
748
|
-
header: (cell) => /* @__PURE__ */
|
|
769
|
+
header: (cell) => /* @__PURE__ */ React4.createElement("div", null, label ?? cell.header.id),
|
|
749
770
|
cell: (cell) => {
|
|
750
771
|
const value = cell.getValue();
|
|
751
772
|
try {
|
|
752
773
|
const str = value ? formatSpec ? format(value, formatSpec) : relative ? formatDistanceToNow(value, {
|
|
753
774
|
addSuffix: true
|
|
754
775
|
}) : value.toISOString() : void 0;
|
|
755
|
-
return /* @__PURE__ */
|
|
756
|
-
className:
|
|
776
|
+
return /* @__PURE__ */ React4.createElement("div", {
|
|
777
|
+
className: mx4("font-mono", className)
|
|
757
778
|
}, str);
|
|
758
779
|
} catch (err) {
|
|
759
780
|
console.log(value);
|
|
@@ -769,25 +790,25 @@ var ColumnBuilder = class {
|
|
|
769
790
|
return defaults(props, {
|
|
770
791
|
size: 86,
|
|
771
792
|
minSize: 86,
|
|
772
|
-
header: (cell) => /* @__PURE__ */
|
|
793
|
+
header: (cell) => /* @__PURE__ */ React4.createElement("div", null, label ?? cell.header.id),
|
|
773
794
|
cell: (cell) => {
|
|
774
795
|
const value = cell.getValue();
|
|
775
796
|
if (!value) {
|
|
776
797
|
return;
|
|
777
798
|
}
|
|
778
|
-
const element = /* @__PURE__ */
|
|
799
|
+
const element = /* @__PURE__ */ React4.createElement("div", {
|
|
779
800
|
className: "font-mono font-thin text-green-500 dark:text-green-300"
|
|
780
801
|
}, value.truncate());
|
|
781
802
|
if (!tooltip) {
|
|
782
803
|
return element;
|
|
783
804
|
}
|
|
784
|
-
return /* @__PURE__ */
|
|
805
|
+
return /* @__PURE__ */ React4.createElement("div", {
|
|
785
806
|
className: "group inline-flex gap-2 items-center"
|
|
786
|
-
}, /* @__PURE__ */
|
|
807
|
+
}, /* @__PURE__ */ React4.createElement(Tooltip.Provider, null, /* @__PURE__ */ React4.createElement(Tooltip.Root, null, /* @__PURE__ */ React4.createElement(Tooltip.Trigger, {
|
|
787
808
|
asChild: true
|
|
788
|
-
}, element), /* @__PURE__ */
|
|
809
|
+
}, element), /* @__PURE__ */ React4.createElement(Tooltip.Content, {
|
|
789
810
|
side: "right"
|
|
790
|
-
}, /* @__PURE__ */
|
|
811
|
+
}, /* @__PURE__ */ React4.createElement(Tooltip.Arrow, null), /* @__PURE__ */ React4.createElement(ClipboardText, {
|
|
791
812
|
onClick: (ev) => {
|
|
792
813
|
ev.stopPropagation();
|
|
793
814
|
void navigator.clipboard.writeText(value.toHex());
|
|
@@ -803,14 +824,14 @@ var ColumnBuilder = class {
|
|
|
803
824
|
return defaults(props, {
|
|
804
825
|
size: 40,
|
|
805
826
|
minSize: 40,
|
|
806
|
-
header: (column) => /* @__PURE__ */
|
|
827
|
+
header: (column) => /* @__PURE__ */ React4.createElement("div", {
|
|
807
828
|
className: "flex grow justify-center"
|
|
808
829
|
}, label ?? column.header.id),
|
|
809
830
|
cell: (cell) => {
|
|
810
831
|
const value = cell.getValue();
|
|
811
|
-
return /* @__PURE__ */
|
|
832
|
+
return /* @__PURE__ */ React4.createElement("div", {
|
|
812
833
|
className: "flex grow justify-center"
|
|
813
|
-
}, /* @__PURE__ */
|
|
834
|
+
}, /* @__PURE__ */ React4.createElement(Input2.Root, null, /* @__PURE__ */ React4.createElement(Input2.Checkbox, {
|
|
814
835
|
onClick: (event) => event.stopPropagation(),
|
|
815
836
|
classNames: className,
|
|
816
837
|
disabled: !onUpdate,
|
|
@@ -830,22 +851,22 @@ var ColumnBuilder = class {
|
|
|
830
851
|
const IconOff = off?.Icon ?? X2;
|
|
831
852
|
return defaults(props, {
|
|
832
853
|
size: size ?? 32,
|
|
833
|
-
header: (column) => /* @__PURE__ */
|
|
854
|
+
header: (column) => /* @__PURE__ */ React4.createElement("div", {
|
|
834
855
|
className: "justify-center"
|
|
835
856
|
}, label ?? column.header.id),
|
|
836
857
|
cell: (cell) => {
|
|
837
858
|
const value = cell.getValue();
|
|
838
859
|
if (value) {
|
|
839
|
-
return /* @__PURE__ */
|
|
860
|
+
return /* @__PURE__ */ React4.createElement("div", {
|
|
840
861
|
className: "flex grow justify-center"
|
|
841
|
-
}, /* @__PURE__ */
|
|
842
|
-
className:
|
|
862
|
+
}, /* @__PURE__ */ React4.createElement(IconOn, {
|
|
863
|
+
className: mx4(getSize3(6), on?.className ?? "text-green-700")
|
|
843
864
|
}));
|
|
844
865
|
} else if (value === false) {
|
|
845
|
-
return /* @__PURE__ */
|
|
866
|
+
return /* @__PURE__ */ React4.createElement("div", {
|
|
846
867
|
className: "flex grow justify-center"
|
|
847
|
-
}, /* @__PURE__ */
|
|
848
|
-
className:
|
|
868
|
+
}, /* @__PURE__ */ React4.createElement(IconOff, {
|
|
869
|
+
className: mx4(getSize3(6), off?.className ?? "text-red-700")
|
|
849
870
|
}));
|
|
850
871
|
} else {
|
|
851
872
|
return null;
|
|
@@ -858,6 +879,7 @@ export {
|
|
|
858
879
|
ColumnBuilder,
|
|
859
880
|
ColumnMenu,
|
|
860
881
|
ColumnPanel,
|
|
882
|
+
ComboboxCell,
|
|
861
883
|
Table,
|
|
862
884
|
columnTypes,
|
|
863
885
|
createColumnBuilder,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../../../src/components/ColumnMenu.tsx", "../../../src/schema.ts", "../../../src/components/Table.tsx", "../../../src/theme.ts", "../../../src/helpers.tsx"],
|
|
4
|
-
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { Check, CaretDown, Trash, X } from '@phosphor-icons/react';\nimport { type HeaderContext, type RowData } from '@tanstack/react-table';\nimport React, { type FC, type PropsWithChildren, useRef, useState } from 'react';\n\nimport { Button, DensityProvider, Input, Popover, Select, Separator } from '@dxos/react-ui';\nimport { getSize, mx } from '@dxos/react-ui-theme';\nimport { safeParseInt } from '@dxos/util';\n\nimport { type TableDef, type ColumnProps, columnTypes } from '../schema';\n\nexport type ColumnMenuProps<TData extends RowData, TValue> = {\n context: HeaderContext<TData, TValue>;\n tableDefs: TableDef[];\n tableDef: TableDef;\n column: ColumnProps;\n onUpdate?: (id: string, column: ColumnProps) => void;\n onDelete?: (id: string) => void;\n};\n\nexport const ColumnMenu = <TData extends RowData, TValue>({ column, ...props }: ColumnMenuProps<TData, TValue>) => {\n const title = column.label?.length ? column.label : column.id;\n\n return (\n <div className='flex grow items-center overflow-hidden'>\n <div className='truncate' title={title}>\n {title}\n </div>\n <div className='grow' />\n <div className='flex shrink-0'>\n <ColumnPanel {...props} column={column} />\n </div>\n </div>\n );\n};\n\nconst Section: FC<PropsWithChildren & { className?: string }> = ({ children, className }) => (\n <div role='none' className={mx('p-2', className)}>\n {children}\n </div>\n);\n\nexport const ColumnPanel = <TData extends RowData, TValue>({\n context,\n tableDefs,\n tableDef,\n column,\n onUpdate,\n onDelete,\n}: ColumnMenuProps<TData, TValue>) => {\n const [open, setOpen] = useState(false);\n const [prop, setProp] = useState(column.id);\n const [refTable, setRefTable] = useState(column.refTable);\n const [refProp, setRefProp] = useState(column.refProp);\n const [type, setType] = useState(String(column.type));\n const [label, setLabel] = useState(column.label);\n const [digits, setDigits] = useState(String(column.digits ?? '0'));\n const propRef = useRef<HTMLInputElement>(null);\n\n const handleCancel = () => {\n setProp(column.id);\n setOpen(false);\n };\n\n const handleSave = () => {\n // Check valid.\n if (!prop.length || !prop.match(/^[a-zA-Z_].+/i)) {\n propRef.current?.focus();\n return;\n }\n\n // If already exists then check same type.\n const current = tableDef.columns.find((c) => c.id !== column.id && c.id === prop);\n if (current) {\n // TODO(burdon): Allow multiple columns with different refProps. Ensure correct table prop is updated.\n if (current.type !== 'ref' /* || current.ref !== refTable */) {\n // TODO(burdon): Show error.\n propRef.current?.focus();\n return;\n }\n }\n\n onUpdate?.(prop, {\n id: prop, // TODO(burdon): Make unique.\n prop,\n label,\n type: type as ColumnProps['type'],\n refTable,\n refProp,\n digits: safeParseInt(digits),\n });\n\n setOpen(false);\n };\n\n return (\n <Popover.Root open={open} onOpenChange={(nextOpen) => setOpen(nextOpen)}>\n <Popover.Trigger asChild>\n <Button variant='ghost' classNames='p-0'>\n <CaretDown className={getSize(4)} />\n </Button>\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Content>\n <Popover.Viewport classNames='w-60'>\n <DensityProvider density='fine'>\n <div className='flex flex-col gap-1'>\n <Section>\n <Input.Root>\n <Input.Label classNames='mbe-1'>Label</Input.Label>\n <Input.TextInput\n placeholder='Column label'\n value={label ?? ''}\n onChange={(event) => setLabel(event.target.value)}\n autoFocus\n />\n </Input.Root>\n <Input.Root>\n <Input.Label classNames='mbe-1 mbs-3'>Property</Input.Label>\n <Input.TextInput\n ref={propRef}\n placeholder='Property key'\n // TODO(burdon): Provide hooks for value normalization, ENTER, ESC, etc.\n value={prop ?? ''}\n onChange={(event) => setProp(event.target.value.replace(/[^\\w_]/g, ''))}\n />\n </Input.Root>\n <Input.Root>\n <Input.Label classNames='mbe-1 mbs-3'>Type</Input.Label>\n <Select.Root value={type} onValueChange={setType}>\n <Select.TriggerButton placeholder='Type' classNames='is-full' />\n <Select.Portal>\n <Select.Content>\n <Select.Viewport>\n {Array.from(columnTypes.entries()).map(([type, label]) => (\n <Select.Option key={type} value={type}>\n {label}\n </Select.Option>\n ))}\n </Select.Viewport>\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n </Input.Root>\n </Section>\n\n {type === 'number' && (\n <>\n <Section>\n <Input.Root>\n <Input.Label classNames='mbe-1 mbs-3'>Decimal places</Input.Label>\n {/* TODO(burdon): Constrain input to numbers. */}\n <Input.TextInput value={digits ?? ''} onChange={(event) => setDigits(event.target.value)} />\n </Input.Root>\n </Section>\n </>\n )}\n\n {/* TODO(burdon): Selectors on same line. */}\n {type === 'ref' && (\n <>\n <Section>\n <Input.Root>\n <Input.Label classNames='mbe-1 mbs-3'>Table</Input.Label>\n <Select.Root value={refTable} onValueChange={setRefTable}>\n <Select.TriggerButton placeholder='Table' classNames='is-full' />\n <Select.Portal>\n <Select.Content>\n <Select.Viewport>\n {tableDefs\n .filter((t) => t.id !== tableDef.id)\n .map(({ id, name }) => (\n <Select.Option key={id} value={id}>\n {name ?? id}\n </Select.Option>\n ))}\n </Select.Viewport>\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n </Input.Root>\n\n {refTable && (\n <Input.Root>\n <Input.Label classNames='mbe-1 mbs-3'>Table property</Input.Label>\n <Select.Root value={refProp} onValueChange={setRefProp}>\n <Select.TriggerButton placeholder='Property' classNames='is-full' />\n <Select.Portal>\n <Select.Content>\n <Select.Viewport>\n {tableDefs\n .find((tableDef) => tableDef.id === refTable)\n ?.columns.map(({ id, label }) => (\n <Select.Option key={id} value={id}>\n {label ?? id}\n </Select.Option>\n ))}\n </Select.Viewport>\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n </Input.Root>\n )}\n </Section>\n </>\n )}\n\n <Separator classNames='mli-2' />\n\n <Section className='space-b-1.5'>\n {/* TODO(burdon): Style as DropdownMenuItem. */}\n <Button variant='primary' classNames='is-full flex gap-2' onClick={handleSave}>\n <span>Save</span>\n <div className='grow' />\n <Check className={getSize(5)} />\n </Button>\n <Button classNames='is-full flex gap-2' onClick={handleCancel}>\n <span>Cancel</span>\n <div className='grow' />\n <X className={getSize(5)} />\n </Button>\n <Button classNames='is-full flex gap-2' onClick={() => onDelete?.(column.id)}>\n <span>Delete</span>\n <div className='grow' />\n <Trash className={getSize(5)} />\n </Button>\n </Section>\n </div>\n </DensityProvider>\n </Popover.Viewport>\n <Popover.Arrow />\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n );\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nexport type TableDef = {\n id: string;\n name?: string; // TODO(burdon): Required?\n columns: ColumnProps[];\n};\n\nexport type ColumnType = 'number' | 'boolean' | 'date' | 'string' | 'ref';\n\nexport const columnTypes = new Map<ColumnType, string>([\n ['string', 'Text'],\n ['boolean', 'Checkbox'],\n ['number', 'Number'],\n ['date', 'Date'],\n ['ref', 'Reference'],\n]);\n\nexport type ColumnProps = {\n id: string;\n prop: string;\n type: ColumnType;\n size?: number;\n label?: string;\n\n // type = number\n digits?: number;\n\n // type = ref\n refTable?: string;\n refProp?: string;\n\n // TODO(burdon): Move to meta.\n fixed?: boolean;\n editable?: boolean;\n resizable?: boolean;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport {\n flexRender,\n getCoreRowModel,\n getGroupedRowModel,\n useReactTable,\n type ColumnSizingInfoState,\n type ColumnSizingState,\n type GroupingState,\n type HeaderGroup,\n type Row,\n type RowData,\n type RowSelectionState,\n type TableState,\n type VisibilityState,\n} from '@tanstack/react-table';\nimport React, { Fragment, useEffect, useRef, useState } from 'react';\n\nimport { debounce } from '@dxos/async';\nimport { groupBorder, inputSurface, mx } from '@dxos/react-ui-theme';\n\nimport { defaultTableSlots, type TableSlots } from '../theme';\nimport { type TableColumnDef, type KeyValue } from '../types';\n\n// TODO(burdon): Sort/filter.\n// TODO(burdon): Drag-and-drop.\n// TODO(burdon): Virtual (e.g., log panel).\n\nexport type TableSelection<TData extends RowData> = {\n // Controlled if undefined (by default).\n select?: 'single' | 'single-toggle' | 'multiple' | 'multiple-toggle' | undefined;\n selected?: TData[];\n onSelectedChange?: (selected: TData[] | undefined) => void;\n};\n\n/**\n * Util to update the selection based on the mode.\n */\nexport const updateSelection = (\n selectionState: RowSelectionState,\n id: string,\n selection: TableSelection<any>['select'],\n): RowSelectionState => {\n switch (selection) {\n case 'single': {\n return {\n [id]: true,\n };\n }\n case 'single-toggle': {\n return selectionState[id]\n ? {}\n : {\n [id]: true,\n };\n }\n case 'multiple': {\n return {\n [id]: true,\n ...selectionState,\n };\n }\n case 'multiple-toggle': {\n if (selectionState[id]) {\n const newSelectionState = { ...selectionState };\n delete newSelectionState[id];\n return newSelectionState;\n } else {\n return {\n [id]: true,\n ...selectionState,\n };\n }\n }\n }\n\n return selectionState;\n};\n\nexport type TableProps<TData extends RowData> = {\n keyAccessor?: KeyValue<TData>;\n data?: TData[];\n columns?: TableColumnDef<TData>[];\n columnVisibility?: VisibilityState;\n onColumnResize?: (state: Record<string, number>) => void;\n grouping?: string[];\n header?: boolean;\n footer?: boolean;\n border?: boolean;\n fullWidth?: boolean;\n pinToBottom?: boolean;\n slots?: TableSlots;\n debug?: boolean;\n} & TableSelection<TData>;\n\nexport const Table = <TData extends RowData>({ slots = defaultTableSlots, ...props }: TableProps<TData>) => {\n const {\n data = [],\n columns = [],\n onColumnResize,\n columnVisibility,\n header = true,\n footer,\n select,\n selected,\n onSelectedChange,\n fullWidth,\n pinToBottom,\n debug,\n } = props;\n\n // Update controlled selection.\n // https://tanstack.com/table/v8/docs/api/features/row-selection\n const [focus, setFocus] = useState<string>();\n const [rowSelection, setRowSelection] = useState<RowSelectionState>({});\n useEffect(() => {\n setRowSelection(\n selected?.reduce((selectionState: RowSelectionState, selected) => {\n const row = table.getRowModel().rows.find((row) => row.original === selected);\n if (row) {\n selectionState[row.id] = true;\n }\n\n return selectionState;\n }, {}) ?? {},\n );\n }, [select, selected]);\n\n // Resizing.\n const [columnSizingInfo, setColumnSizingInfo] = useState<ColumnSizingInfoState>({} as ColumnSizingInfoState);\n const onColumnResizeDebounced = debounce<ColumnSizingState>((info) => onColumnResize?.(info), 500);\n useEffect(() => {\n if (columnSizingInfo.columnSizingStart?.length === 0) {\n onColumnResizeDebounced(table.getState().columnSizing);\n }\n }, [columnSizingInfo]);\n\n const [grouping, setGrouping] = useState<GroupingState>(props.grouping ?? []);\n useEffect(() => setGrouping(props.grouping ?? []), [props.grouping]);\n\n //\n // Update table state.\n // https://tanstack.com/table/v8/docs/api/core/table\n //\n const table = useReactTable({\n data,\n columns,\n defaultColumn: {\n size: 400, // Required in order remove default width.\n maxSize: 800,\n },\n getCoreRowModel: getCoreRowModel(),\n meta: {},\n\n // TODO(burdon): Pagination.\n // TODO(burdon): Sorting.\n // TODO(burdon): Filtering.\n state: {\n columnVisibility,\n columnSizingInfo,\n rowSelection,\n grouping,\n },\n\n // Grouping.\n getGroupedRowModel: getGroupedRowModel(),\n onGroupingChange: setGrouping,\n\n // Selection.\n enableRowSelection: select === 'single' || select === 'single-toggle',\n enableMultiRowSelection: select === 'multiple' || select === 'multiple-toggle',\n onRowSelectionChange: (rows) => {\n setRowSelection(rows);\n },\n\n // Resize columns.\n // TODO(burdon): Drag to re-order columns.\n columnResizeMode: 'onChange',\n enableColumnResizing: true,\n onColumnSizingInfoChange: setColumnSizingInfo,\n\n debugTable: debug,\n });\n\n // TODO(burdon): Add flex if not resizable.\n // Create additional expansion column if all columns have fixed width.\n const expand = false; // columns.map((column) => column.size).filter(Boolean).length === columns?.length;\n\n // Pin scrollbar to bottom.\n const containerRef = usePinToBottom(data, pinToBottom);\n\n const handleSelect = (row: Row<TData>) => {\n if (select) {\n // Uncontrolled.\n setRowSelection((selectionState: RowSelectionState) => {\n const newSelectionState = updateSelection(selectionState, row.id, select);\n if (onSelectedChange) {\n const rows: TData[] = Object.keys(newSelectionState).map((id) => table.getRowModel().rowsById[id].original);\n onSelectedChange(rows);\n }\n\n return newSelectionState;\n });\n } else {\n // Controlled.\n onSelectedChange?.([row.original]);\n }\n };\n\n // TODO(burdon): Use radix ScrollArea.\n // https://www.radix-ui.com/primitives/docs/components/scroll-area\n return (\n <div ref={containerRef} className={mx('grow overflow-auto', slots?.root?.className)}>\n <table\n // Styles:\n // table-fixed: Prevents fixed sized columns from shrinking.\n className={mx(!fullWidth && 'table-fixed', inputSurface, slots?.table?.className)}\n style={{\n width: fullWidth ? '100%' : table.getTotalSize(),\n }}\n >\n {/* Head */}\n <TableHead\n {...props}\n slots={slots}\n header={header}\n state={table.getState()}\n headers={table.getHeaderGroups()}\n />\n\n {/* Rows */}\n {grouping.length === 0 && (\n <TableBody\n {...props}\n slots={slots}\n rowSelection={rowSelection}\n expand={expand}\n focus={focus}\n onFocus={setFocus}\n onSelect={handleSelect}\n rows={table.getRowModel().rows}\n />\n )}\n\n {/* Groups */}\n {grouping.length !== 0 &&\n table.getGroupedRowModel().rows.map((row, i) => {\n return (\n <Fragment key={i}>\n {/* TODO(burdon): Customize group header renderer. */}\n <thead>\n <tr>\n {slots?.margin && <th className={mx(slots?.margin?.className)} />}\n {debug && <th />}\n <th\n // TODO(burdon): Calculate row span.\n colSpan={table.getHeaderGroups()[0].headers.length}\n className={mx('text-left', slots?.group?.className)}\n >\n {table.getState().grouping[0]}[{String(row.getGroupingValue(table.getState().grouping[0]))}]\n </th>\n </tr>\n </thead>\n\n <TableBody\n {...props}\n slots={slots}\n rowSelection={rowSelection}\n expand={expand}\n focus={focus}\n onFocus={setFocus}\n onSelect={handleSelect}\n rows={row.subRows}\n />\n </Fragment>\n );\n })}\n\n {/* Foot */}\n {footer && <TableFoot {...props} slots={slots} footers={table.getFooterGroups()} />}\n </table>\n\n {debug && (\n <pre className='font-mono text-xs text-neutral-500 my-4 p-2 ring'>\n <code>{JSON.stringify(table.getState(), undefined, 2)}</code>\n </pre>\n )}\n </div>\n );\n};\n\n/**\n * Glue to bottom as rows are added.\n */\n// TODO(burdon): Causes scrollbar to be constantly visible.\n// https://css-tricks.com/books/greatest-css-tricks/pin-scrolling-to-bottom\nconst usePinToBottom = <TData extends RowData>(data: TData[], pinToBottom?: boolean) => {\n const containerRef = useRef<HTMLDivElement | null>(null);\n const [stickyScrolling, setStickyScrolling] = useState(true);\n useEffect(() => {\n const container = containerRef.current;\n if (!pinToBottom || !container) {\n return;\n }\n\n // TODO(burdon): Set when scrolled to bottom and unset when manually scrolled away.\n const handler = () => {\n const bottom = container.scrollHeight - container.scrollTop - container.clientHeight === 0;\n setStickyScrolling(bottom);\n };\n\n container.addEventListener('scroll', handler);\n return () => container.removeEventListener('scroll', handler);\n }, []);\n\n useEffect(() => {\n if (!pinToBottom || !containerRef.current || !stickyScrolling) {\n return;\n }\n\n containerRef.current?.scroll({ top: containerRef.current.scrollHeight });\n }, [data]);\n\n return containerRef;\n};\n\n//\n// Head.\n//\n\ntype TableHeadProps<TData extends RowData> = Partial<TableProps<TData>> & {\n state: TableState;\n headers: HeaderGroup<TData>[];\n expand?: boolean;\n};\n\nconst TableHead = <TData extends RowData>({\n state,\n headers,\n expand,\n header,\n debug,\n fullWidth,\n border,\n slots,\n}: TableHeadProps<TData>) => {\n return (\n <thead className={mx(header ? ['sticky top-0 z-10'] : 'collapse')}>\n {headers.map((headerGroup) => {\n return (\n // Group element to hover resize handles.\n <tr key={headerGroup.id} className='font-light group'>\n {slots?.margin && <th className={mx(slots?.margin?.className)} />}\n\n {/* TODO(burdon): Calc. width. */}\n {debug && (\n <th className='text-left' style={{ width: 32 }}>\n #\n </th>\n )}\n\n {headerGroup.headers.map((header) => {\n return (\n <th\n key={header.id}\n style={{\n // Don't set width if fullWidth and no explicit size.\n width: fullWidth && header.column.columnDef.meta?.expand ? undefined : header.getSize(),\n }}\n // Relative for resize handle.\n // TODO(burdon): Border scrolls with main content.\n // https://stackoverflow.com/questions/50361698/border-style-do-not-work-with-sticky-position-element\n className={mx(\n 'relative text-left',\n border && groupBorder,\n slots?.header?.className,\n header.column.columnDef.meta?.slots?.header?.className,\n )}\n >\n {!header || header.isPlaceholder\n ? null\n : flexRender(header.column.columnDef.header, header.getContext())}\n\n {/*\n * Resize handle.\n * https://codesandbox.io/p/sandbox/github/tanstack/table/tree/main/examples/react/column-sizing\n */}\n {header.column.columnDef.meta?.resizable && (\n <div\n className={mx(\n 'absolute top-0 pl-1 h-full z-[10] w-[7px] -right-[5px]',\n 'cursor-col-resize select-none touch-none opacity-20 hover:opacity-100',\n header.column.getIsResizing() && 'hidden',\n )}\n style={{\n transform: header.column.getIsResizing()\n ? `translateX(${state.columnSizingInfo.deltaOffset}px)`\n : undefined,\n }}\n onMouseDown={header.getResizeHandler()}\n onTouchStart={header.getResizeHandler()}\n >\n <div className='flex group-hover:bg-neutral-700 -ml-[2px] w-[1px] h-full' />\n </div>\n )}\n </th>\n );\n })}\n {expand && <th />}\n {slots?.margin && <th className={mx(slots?.margin?.className)} />}\n </tr>\n );\n })}\n </thead>\n );\n};\n\n//\n// Body.\n//\n\ntype TableBodyProps<TData extends RowData> = Partial<TableProps<TData>> & {\n rows: Row<TData>[];\n rowSelection: RowSelectionState;\n expand?: boolean;\n focus?: string;\n onFocus?: (id?: string) => void;\n onSelect?: (row: Row<TData>) => void;\n};\n\nconst TableBody = <TData extends RowData>({\n keyAccessor,\n rows,\n rowSelection,\n focus,\n onFocus,\n onSelect,\n debug,\n border,\n expand,\n slots,\n}: TableBodyProps<TData>) => {\n return (\n <tbody>\n {rows.map((row) => {\n return (\n <tr\n key={keyAccessor ? keyAccessor(row.original) : row.id}\n onClick={() => onSelect?.(row)}\n role='button' // TODO(burdon): ???\n className={mx(\n 'group',\n rowSelection[row.id] && slots?.selected?.className,\n focus === row.id && slots?.focus?.className,\n slots?.row?.className,\n )}\n >\n {/* TODO(burdon): Dummy button for focus (don't alter geometry). */}\n {slots?.margin && (\n <td className={mx(slots?.margin?.className)}>\n <button\n role='button'\n style={{ width: 1, height: 1 }}\n className='focus:outline-none'\n onFocus={() => onFocus?.(keyAccessor ? keyAccessor(row.original) : row.id)}\n onBlur={() => onFocus?.(undefined)}\n onKeyDown={(event) => {\n // TODO(burdon): Move focus.\n switch (event.key) {\n case 'ArrowUp': {\n break;\n }\n case 'ArrowDown': {\n break;\n }\n }\n }}\n />\n </td>\n )}\n\n {debug && <td>{row.id}</td>}\n\n {row.getVisibleCells().map((cell) => {\n // TODO(burdon): Allow class override from column.\n return (\n <td\n key={cell.id}\n className={mx(\n border && groupBorder,\n slots?.cell?.className,\n cell.column.columnDef.meta?.slots?.cell?.className,\n )}\n >\n {flexRender(cell.column.columnDef.cell, { className: 'px-2', ...cell.getContext() })}\n </td>\n );\n })}\n\n {expand && <td />}\n {slots?.margin && <td className={mx(slots?.margin?.className)} />}\n </tr>\n );\n })}\n </tbody>\n );\n};\n\n//\n// Footer\n//\n\ntype TableFootProps<TData extends RowData> = Partial<TableProps<TData>> & {\n footers: HeaderGroup<TData>[];\n expand?: boolean;\n};\n\nconst TableFoot = <TData extends RowData>({ footers, expand, slots, debug, border }: TableFootProps<TData>) => {\n return (\n <tfoot className={mx('sticky bottom-0 z-[10]', slots?.footer?.className)}>\n {footers.map((footerGroup) => (\n <tr key={footerGroup.id} className='font-thin'>\n {slots?.margin && <th className={mx(slots?.margin?.className)} />}\n {debug && <th />}\n\n {footerGroup.headers.map((footer) => {\n return (\n <th\n key={footer.id}\n className={mx(\n border && groupBorder,\n 'text-left',\n slots?.footer?.className,\n footer.column.columnDef.meta?.slots?.footer?.className,\n )}\n >\n {footer.isPlaceholder ? null : flexRender(footer.column.columnDef.footer, footer.getContext())}\n </th>\n );\n })}\n\n {expand && <th />}\n {slots?.margin && <th className={mx(slots?.margin?.className)} />}\n </tr>\n ))}\n </tfoot>\n );\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { chromeSurface } from '@dxos/react-ui-theme';\n\n// TODO(burdon): Remove nested classNames? Add to theme?\nexport type TableSlots = {\n root?: {\n className?: string | string[];\n };\n table?: {\n className?: string | string[];\n };\n header?: {\n className?: string | string[];\n };\n footer?: {\n className?: string | string[];\n };\n group?: {\n className?: string | string[];\n };\n row?: {\n className?: string | string[];\n };\n cell?: {\n className?: string | string[];\n };\n focus?: {\n className?: string | string[];\n };\n selected?: {\n className?: string | string[];\n };\n margin?: {\n className?: string | string[];\n };\n};\n\n// TODO(burdon): Change to groups.\n/*\nhead: {\n default:\n cell:\n}\nrow: {\n default: '',\n selected: ''\n}\n*/\n\n// TODO(burdon): Scrollbar area.\n// TODO(burdon): Overscroll horizontal (full width).\n\n// TODO(burdon): Integrate with DXOS UI theme (direct dependency -- see react-ui-editor, tailwind.ts).\n// See Link.tsx const { tx } = useThemeContext();\n// Reuse button fragments for hoverColors, selected, primary, etc.\nexport const defaultTableSlots: TableSlots = {\n // TODO(burdon): head/body/table rows.\n header: { className: [chromeSurface, 'px-2 font-light select-none'] },\n footer: { className: [chromeSurface, 'px-2 font-light'] },\n cell: { className: 'px-2' },\n group: { className: 'px-2 font-light text-xs text-left' },\n focus: { className: 'ring ring-primary-600 ring-inset' },\n selected: { className: '!bg-teal-100 dark:!bg-teal-700' },\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { useFocusFinders } from '@fluentui/react-tabster';\nimport { CaretDown, Check, ClipboardText, type Icon, X } from '@phosphor-icons/react';\nimport { createColumnHelper, type ColumnDef, type ColumnMeta, type RowData } from '@tanstack/react-table';\nimport format from 'date-fns/format';\nimport formatDistanceToNow from 'date-fns/formatDistanceToNow';\nimport defaultsDeep from 'lodash.defaultsdeep';\nimport React, { useCallback, useRef, useState } from 'react';\n\nimport { type PublicKey } from '@dxos/keys';\nimport { Button, Input, Popover, Tooltip } from '@dxos/react-ui';\nimport { SearchList } from '@dxos/react-ui-searchlist';\nimport { descriptionText, getSize, mx } from '@dxos/react-ui-theme';\nimport { stripUndefinedValues } from '@dxos/util';\n\n// TODO(burdon): Factor out hack to find next focusable element (extend useFocusFinders)?\nconst findNextFocusable = (\n findFirstFocusable: (container: HTMLElement) => HTMLElement | null | undefined,\n container: HTMLElement,\n): HTMLElement | undefined => {\n const next = findFirstFocusable(container as any);\n if (next) {\n if (next?.tagName === 'INPUT') {\n return next;\n }\n if (container.nextElementSibling) {\n return findNextFocusable(findFirstFocusable, container.nextSibling as any);\n }\n }\n};\n\nexport type ValueUpdater<TData extends RowData, TValue> = (row: TData, id: string, value: TValue) => void;\n\nexport const createColumnBuilder = <TData extends RowData>() => ({\n helper: createColumnHelper<TData>(),\n builder: new ColumnBuilder<TData>(),\n});\n\n/**\n * NOTE: Can use `meta` for custom properties.\n */\nexport type BaseColumnOptions<TData, TValue> = Partial<ColumnDef<TData, TValue>> & {\n meta?: ColumnMeta<TData, TValue>;\n label?: string;\n className?: string;\n onUpdate?: ValueUpdater<TData, TValue | undefined>;\n};\n\n// TODO(burdon): Better abstraction?\nexport type SelectQueryModel<TData extends RowData> = {\n getId(object: TData): string;\n getText(object: TData): string;\n query(text?: string): Promise<TData[]>;\n};\n\nexport type SelectColumnOptions<TData extends RowData> = BaseColumnOptions<TData, any> & {\n model: SelectQueryModel<TData>;\n};\n\nexport type StringColumnOptions<TData extends RowData> = BaseColumnOptions<TData, string> & {};\n\nexport type NumberColumnOptions<TData extends RowData> = BaseColumnOptions<TData, number> & {\n digits?: number;\n};\n\nexport type KeyColumnOptions<TData extends RowData> = BaseColumnOptions<TData, PublicKey> & {\n tooltip?: boolean;\n};\n\nexport type DateColumnOptions<TData extends RowData> = BaseColumnOptions<TData, Date> & {\n format?: string;\n relative?: boolean;\n};\n\nexport type BooleanColumnOptions<TData extends RowData> = BaseColumnOptions<TData, boolean> & {};\n\nexport type IconColumnOptions<TData extends RowData> = BaseColumnOptions<TData, boolean> & {\n on?: {\n Icon?: Icon;\n className?: string;\n };\n off?: {\n Icon?: Icon;\n className?: string;\n };\n};\n\nconst defaults = <TData extends RowData, TValue>(\n options: Partial<ColumnDef<TData, TValue>>,\n ...sources: Partial<ColumnDef<TData, TValue>>[]\n): Partial<ColumnDef<TData, TValue>> => {\n return stripUndefinedValues(defaultsDeep({}, options, ...sources));\n};\n\ntype CellSelectorItems<TData extends RowData> = Record<string, { label: string; data: TData }>;\n\nconst initialItems = <TData extends RowData>(model: SelectQueryModel<TData>, value?: TData) =>\n value\n ? {\n [model.getId(value)]: { label: model.getText(value), data: value },\n }\n : {};\n\nconst CellSelector = <TData extends RowData>({\n model,\n value,\n onValueChange,\n}: {\n model: SelectQueryModel<TData>;\n value: TData;\n onValueChange: (value: TData) => void;\n}) => {\n const [items, setItems] = useState<CellSelectorItems<TData>>(initialItems(model, value));\n const [loading, setLoading] = useState(false);\n const [searchInputValue, setSearchInputValue] = useState('');\n const handleSearchInputValueChange = async (text?: string) => {\n setSearchInputValue(text ?? '');\n setLoading(true);\n const items = await model.query(text);\n setItems(\n items.reduce((acc: CellSelectorItems<TData>, item) => {\n acc[model.getId(item)] = {\n label: model.getText(item),\n data: item,\n };\n return acc;\n }, initialItems(model, value)),\n );\n setLoading(false);\n };\n\n const handleValueChange = useCallback(\n (id: string) => {\n onValueChange(items[id]?.data);\n },\n [items, onValueChange],\n );\n\n return (\n <Popover.Root>\n <Popover.Trigger asChild>\n <Button variant='ghost' classNames='is-full font-normal'>\n <span className='flex-1 text-start truncate'>{value ? model.getText(value) : ' '}</span>\n <CaretDown />\n </Button>\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Content side='bottom' collisionPadding={48} classNames='is-[--radix-popover-trigger-width]'>\n <SearchList.Root shouldFilter={false}>\n <SearchList.Input value={searchInputValue} onValueChange={handleSearchInputValueChange} />\n <Popover.Viewport>\n <SearchList.Content>\n {searchInputValue.length < 1 ? (\n <p className={mx('text-center', descriptionText)}>Start typing to search</p>\n ) : loading ? (\n <p className={mx('text-center', descriptionText)}>Searching…</p>\n ) : (\n <>\n <SearchList.Empty classNames={['text-center', descriptionText]}>No results</SearchList.Empty>\n {Object.entries(items).map(([id, { label }]) => (\n <SearchList.Item key={id} value={id} onSelect={handleValueChange} classNames='truncate'>\n {label}\n </SearchList.Item>\n ))}\n </>\n )}\n </SearchList.Content>\n </Popover.Viewport>\n </SearchList.Root>\n <Popover.Arrow />\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n );\n};\n\n/**\n * Util to create column definitions.\n */\nexport class ColumnBuilder<TData extends RowData> {\n /**\n * Select value\n */\n select({ label, className, model, onUpdate, ...props }: SelectColumnOptions<TData>): Partial<ColumnDef<TData, any>> {\n return defaults(props, {\n minSize: 100,\n header: (column) => {\n return <div className={'truncate'}>{label ?? column.header.id}</div>;\n },\n cell:\n model && onUpdate\n ? (cell) => (\n <CellSelector<any>\n model={model}\n value={cell.getValue()}\n onValueChange={(value) => onUpdate?.(cell.row.original, cell.column.id, value)}\n />\n )\n : (cell) => {\n const value = cell.getValue();\n return <div className={mx('truncate', className)}>{value ? model.getText(value) : ''}</div>;\n },\n });\n }\n\n /**\n * String formats.\n */\n string({ label, className, onUpdate, ...props }: StringColumnOptions<TData> = {}): Partial<ColumnDef<TData, string>> {\n return defaults(props, {\n minSize: 100,\n // TODO(burdon): Default.\n header: (column) => {\n return <div className={'truncate'}>{label ?? column.header.id}</div>;\n },\n cell: onUpdate\n ? (cell) => {\n // https://tanstack.com/table/v8/docs/examples/react/editable-data\n const initialValue = cell.getValue();\n const [value, setValue] = useState(initialValue);\n const inputRef = useRef<HTMLInputElement>(null);\n const { findFirstFocusable } = useFocusFinders();\n\n const handleSave = (focusNext = false) => {\n if (value === initialValue) {\n return;\n }\n\n onUpdate?.(cell.row.original, cell.column.id, value);\n\n // TODO(burdon): More generally support keyboard navigation.\n if (focusNext) {\n const rowElement = inputRef.current?.parentElement?.parentElement;\n // TODO(burdon): Hack to wait for next row to render.\n setTimeout(() => {\n const next = findNextFocusable(findFirstFocusable, rowElement as HTMLElement);\n next?.focus();\n });\n }\n };\n\n const handleCancel = () => {\n setValue(initialValue);\n };\n\n // Check if first input column of last row.\n const rows = cell.table.getRowModel().flatRows;\n const columns = cell.table.getVisibleFlatColumns();\n const placeholder = cell.row.index === rows.length - 1 && columns[0].id === cell.column.id;\n\n // TODO(burdon): Don't render inputs unless mouse over (Show ellipsis when div)?\n return (\n <Input.Root>\n <Input.TextInput\n ref={inputRef}\n variant='subdued'\n placeholder={placeholder ? 'Add row...' : undefined}\n classNames={'px-2'}\n value={(value as string) ?? ''}\n onBlur={() => handleSave(false)}\n onChange={(event) => setValue(event.target.value)}\n onKeyDown={(event) =>\n (event.key === 'Enter' && handleSave(true)) || (event.key === 'Escape' && handleCancel())\n }\n />\n </Input.Root>\n );\n }\n : (cell) => {\n const value = cell.getValue();\n return <div className={mx('truncate', className)}>{value}</div>;\n },\n });\n }\n\n /**\n * Number formats.\n */\n number({ label, minSize, className, digits, onUpdate, ...props }: NumberColumnOptions<TData> = {}): Partial<\n ColumnDef<TData, number>\n > {\n return defaults(props, {\n size: 100,\n minSize: 100,\n header: (cell) => <div className='w-full truncate text-right'>{label ?? cell.header.id}</div>,\n cell: (cell) => {\n const value = cell.getValue();\n const [text, setText] = useState<string>();\n\n const handleEdit = () => {\n if (onUpdate) {\n setText(value !== undefined ? String(value) : '');\n }\n };\n\n // TODO(burdon): Property is encoded as float (e.g., 6.1 => 6.099)\n const handleSave = () => {\n const value = text?.trim().length ? Number(text) : NaN;\n onUpdate?.(cell.row.original, cell.column.id, isNaN(value) ? undefined : value);\n setText(undefined);\n };\n\n const handleCancel = () => {\n setText(undefined);\n };\n\n if (text !== undefined) {\n return (\n <div className={mx('grow text-right font-mono', className)}>\n <Input.Root>\n <Input.TextInput\n autoFocus\n value={text}\n classNames={'px-2'}\n onBlur={handleSave}\n onChange={(event) => setText(event.target.value)}\n onKeyDown={(event) =>\n (event.key === 'Escape' && handleCancel()) || (event.key === 'Enter' && handleSave())\n }\n />\n </Input.Root>\n </div>\n );\n }\n\n return (\n <div\n className={mx('grow w-full text-right font-mono empty:after:content-[\" \"]', className)}\n onClick={handleEdit}\n >\n {value?.toLocaleString(undefined, {\n minimumFractionDigits: digits ?? 0,\n maximumFractionDigits: digits ?? 2,\n })}\n </div>\n );\n },\n });\n }\n\n /**\n * Date formats.\n */\n // TODO(burdon): Date picker (pluggable renderers?)\n date({ label, format: formatSpec, relative, className, ...props }: DateColumnOptions<TData> = {}): Partial<\n ColumnDef<TData, Date>\n > {\n return defaults(props, {\n size: 220, // TODO(burdon): Depends on format.\n minSize: 100,\n header: (cell) => <div>{label ?? cell.header.id}</div>,\n cell: (cell) => {\n const value = cell.getValue();\n\n try {\n const str = value\n ? formatSpec\n ? format(value, formatSpec)\n : relative\n ? formatDistanceToNow(value, { addSuffix: true })\n : value.toISOString()\n : undefined;\n\n return <div className={mx('font-mono', className)}>{str}</div>;\n } catch (err) {\n console.log(value);\n return null;\n }\n },\n });\n }\n\n /**\n * PublicKey with tooltip.\n */\n key({ label, tooltip, ...props }: KeyColumnOptions<TData> = {}): Partial<ColumnDef<TData, PublicKey>> {\n return defaults(props, {\n size: 86,\n minSize: 86,\n header: (cell) => <div>{label ?? cell.header.id}</div>,\n cell: (cell) => {\n const value = cell.getValue();\n if (!value) {\n return;\n }\n\n // TODO(burdon): Factor out styles.\n const element = (\n <div className='font-mono font-thin text-green-500 dark:text-green-300'>{value.truncate()}</div>\n );\n if (!tooltip) {\n return element;\n }\n\n return (\n <div className='group inline-flex gap-2 items-center'>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>{element}</Tooltip.Trigger>\n <Tooltip.Content side='right'>\n <Tooltip.Arrow />\n <ClipboardText\n onClick={(ev) => {\n ev.stopPropagation(); // Prevent select row.\n void navigator.clipboard.writeText(value.toHex());\n }}\n />\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </div>\n );\n },\n });\n }\n\n /**\n * Checkbox.\n */\n checkbox({ label, className, onUpdate, ...props }: BooleanColumnOptions<TData> = {}): Partial<\n ColumnDef<TData, boolean>\n > {\n return defaults(props, {\n size: 40,\n minSize: 40,\n header: (column) => <div className={'flex grow justify-center'}>{label ?? column.header.id}</div>,\n cell: (cell) => {\n const value = cell.getValue();\n // TODO(burdon): Center.\n return (\n <div className='flex grow justify-center'>\n <Input.Root>\n <Input.Checkbox\n onClick={(event) => event.stopPropagation()}\n classNames={className}\n disabled={!onUpdate}\n checked={!!value}\n onCheckedChange={(value) => {\n onUpdate?.(cell.row.original, cell.column.id, !!value);\n }}\n />\n </Input.Root>\n </div>\n );\n },\n });\n }\n\n /**\n * Icon based on boolean value.\n */\n icon({ label, size, on, off, ...props }: IconColumnOptions<TData> = {}): Partial<ColumnDef<TData, boolean>> {\n const IconOn = on?.Icon ?? Check;\n const IconOff = off?.Icon ?? X;\n return defaults(props, {\n size: size ?? 32,\n header: (column) => <div className={'justify-center'}>{label ?? column.header.id}</div>,\n cell: (cell) => {\n const value = cell.getValue();\n if (value) {\n return (\n <div className='flex grow justify-center'>\n <IconOn className={mx(getSize(6), on?.className ?? 'text-green-700')} />\n </div>\n );\n } else if (value === false) {\n return (\n <div className='flex grow justify-center'>\n <IconOff className={mx(getSize(6), off?.className ?? 'text-red-700')} />\n </div>\n );\n } else {\n return null;\n }\n },\n });\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["Check", "CaretDown", "Trash", "X", "React", "useRef", "useState", "Button", "DensityProvider", "Input", "Popover", "Select", "Separator", "getSize", "mx", "safeParseInt", "columnTypes", "Map", "ColumnMenu", "column", "props", "title", "label", "length", "id", "div", "className", "ColumnPanel", "Section", "children", "role", "mx", "context", "tableDefs", "tableDef", "onUpdate", "onDelete", "open", "setOpen", "useState", "prop", "setProp", "refTable", "setRefTable", "refProp", "setRefProp", "type", "setType", "String", "setLabel", "digits", "setDigits", "propRef", "useRef", "handleCancel", "handleSave", "match", "current", "focus", "columns", "find", "c", "safeParseInt", "Popover", "Root", "onOpenChange", "nextOpen", "Trigger", "asChild", "Button", "variant", "classNames", "CaretDown", "getSize", "Portal", "Content", "Viewport", "DensityProvider", "density", "Input", "Label", "TextInput", "placeholder", "value", "onChange", "event", "target", "autoFocus", "ref", "replace", "Select", "onValueChange", "TriggerButton", "Array", "from", "columnTypes", "entries", "map", "Option", "key", "filter", "t", "name", "Separator", "onClick", "span", "Check", "X", "Trash", "Arrow", "flexRender", "getCoreRowModel", "getGroupedRowModel", "useReactTable", "React", "Fragment", "useEffect", "useRef", "useState", "debounce", "groupBorder", "inputSurface", "mx", "chromeSurface", "defaultTableSlots", "header", "className", "chromeSurface", "footer", "cell", "group", "focus", "selected", "updateSelection", "selectionState", "id", "selection", "newSelectionState", "Table", "slots", "defaultTableSlots", "props", "data", "columns", "onColumnResize", "columnVisibility", "header", "footer", "select", "selected", "onSelectedChange", "fullWidth", "pinToBottom", "debug", "focus", "setFocus", "useState", "rowSelection", "setRowSelection", "useEffect", "reduce", "row", "table", "getRowModel", "rows", "find", "original", "columnSizingInfo", "setColumnSizingInfo", "onColumnResizeDebounced", "debounce", "info", "columnSizingStart", "length", "getState", "columnSizing", "grouping", "setGrouping", "useReactTable", "defaultColumn", "size", "maxSize", "getCoreRowModel", "meta", "state", "getGroupedRowModel", "onGroupingChange", "enableRowSelection", "enableMultiRowSelection", "onRowSelectionChange", "columnResizeMode", "enableColumnResizing", "onColumnSizingInfoChange", "debugTable", "expand", "containerRef", "usePinToBottom", "handleSelect", "Object", "keys", "map", "rowsById", "React", "div", "ref", "className", "mx", "root", "inputSurface", "style", "width", "getTotalSize", "TableHead", "headers", "getHeaderGroups", "TableBody", "onFocus", "onSelect", "i", "Fragment", "key", "thead", "tr", "margin", "th", "colSpan", "group", "String", "getGroupingValue", "subRows", "TableFoot", "footers", "getFooterGroups", "pre", "code", "JSON", "stringify", "undefined", "useRef", "stickyScrolling", "setStickyScrolling", "container", "current", "handler", "bottom", "scrollHeight", "scrollTop", "clientHeight", "addEventListener", "removeEventListener", "scroll", "top", "border", "headerGroup", "column", "columnDef", "getSize", "groupBorder", "isPlaceholder", "flexRender", "getContext", "resizable", "getIsResizing", "transform", "deltaOffset", "onMouseDown", "getResizeHandler", "onTouchStart", "keyAccessor", "tbody", "onClick", "role", "td", "button", "height", "onBlur", "onKeyDown", "event", "getVisibleCells", "cell", "tfoot", "footerGroup", "
|
|
3
|
+
"sources": ["../../../src/components/ColumnMenu.tsx", "../../../src/schema.ts", "../../../src/components/Table.tsx", "../../../src/theme.ts", "../../../src/components/ComboboxCell.tsx", "../../../src/translations.ts", "../../../src/helpers.tsx"],
|
|
4
|
+
"sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { Check, CaretDown, Trash, X } from '@phosphor-icons/react';\nimport { type HeaderContext, type RowData } from '@tanstack/react-table';\nimport React, { type FC, type PropsWithChildren, useRef, useState } from 'react';\n\nimport { Button, DensityProvider, Input, Popover, Select, Separator } from '@dxos/react-ui';\nimport { getSize, mx } from '@dxos/react-ui-theme';\nimport { safeParseInt } from '@dxos/util';\n\nimport { type TableDef, type ColumnProps, columnTypes } from '../schema';\n\nexport type ColumnMenuProps<TData extends RowData, TValue> = {\n context: HeaderContext<TData, TValue>;\n tableDefs: TableDef[];\n tableDef: TableDef;\n column: ColumnProps;\n onUpdate?: (id: string, column: ColumnProps) => void;\n onDelete?: (id: string) => void;\n};\n\nexport const ColumnMenu = <TData extends RowData, TValue>({ column, ...props }: ColumnMenuProps<TData, TValue>) => {\n const title = column.label?.length ? column.label : column.id;\n\n return (\n <div className='flex grow items-center overflow-hidden'>\n <div className='truncate' title={title}>\n {title}\n </div>\n <div className='grow' />\n <div className='flex shrink-0'>\n <ColumnPanel {...props} column={column} />\n </div>\n </div>\n );\n};\n\nconst Section: FC<PropsWithChildren & { className?: string }> = ({ children, className }) => (\n <div role='none' className={mx('p-2', className)}>\n {children}\n </div>\n);\n\nexport const ColumnPanel = <TData extends RowData, TValue>({\n context,\n tableDefs,\n tableDef,\n column,\n onUpdate,\n onDelete,\n}: ColumnMenuProps<TData, TValue>) => {\n const [open, setOpen] = useState(false);\n const [prop, setProp] = useState(column.id);\n const [refTable, setRefTable] = useState(column.refTable);\n const [refProp, setRefProp] = useState(column.refProp);\n const [type, setType] = useState(String(column.type));\n const [label, setLabel] = useState(column.label);\n const [digits, setDigits] = useState(String(column.digits ?? '0'));\n const propRef = useRef<HTMLInputElement>(null);\n\n const handleCancel = () => {\n setProp(column.id);\n setOpen(false);\n };\n\n const handleSave = () => {\n // Check valid.\n if (!prop.length || !prop.match(/^[a-zA-Z_].+/i)) {\n propRef.current?.focus();\n return;\n }\n\n // If already exists then check same type.\n const current = tableDef.columns.find((c) => c.id !== column.id && c.id === prop);\n if (current) {\n // TODO(burdon): Allow multiple columns with different refProps. Ensure correct table prop is updated.\n if (current.type !== 'ref' /* || current.ref !== refTable */) {\n // TODO(burdon): Show error.\n propRef.current?.focus();\n return;\n }\n }\n\n onUpdate?.(prop, {\n id: prop, // TODO(burdon): Make unique.\n prop,\n label,\n type: type as ColumnProps['type'],\n refTable,\n refProp,\n digits: safeParseInt(digits),\n });\n\n setOpen(false);\n };\n\n return (\n <Popover.Root open={open} onOpenChange={(nextOpen) => setOpen(nextOpen)}>\n <Popover.Trigger asChild>\n <Button variant='ghost' classNames='p-0'>\n <CaretDown className={getSize(4)} />\n </Button>\n </Popover.Trigger>\n <Popover.Portal>\n <Popover.Content>\n <Popover.Viewport classNames='w-60'>\n <DensityProvider density='fine'>\n <div className='flex flex-col gap-1'>\n <Section>\n <Input.Root>\n <Input.Label classNames='mbe-1'>Label</Input.Label>\n <Input.TextInput\n placeholder='Column label'\n value={label ?? ''}\n onChange={(event) => setLabel(event.target.value)}\n autoFocus\n />\n </Input.Root>\n <Input.Root>\n <Input.Label classNames='mbe-1 mbs-3'>Property</Input.Label>\n <Input.TextInput\n ref={propRef}\n placeholder='Property key'\n // TODO(burdon): Provide hooks for value normalization, ENTER, ESC, etc.\n value={prop ?? ''}\n onChange={(event) => setProp(event.target.value.replace(/[^\\w_]/g, ''))}\n />\n </Input.Root>\n <Input.Root>\n <Input.Label classNames='mbe-1 mbs-3'>Type</Input.Label>\n <Select.Root value={type} onValueChange={setType}>\n <Select.TriggerButton placeholder='Type' classNames='is-full' />\n <Select.Portal>\n <Select.Content>\n <Select.Viewport>\n {Array.from(columnTypes.entries()).map(([type, label]) => (\n <Select.Option key={type} value={type}>\n {label}\n </Select.Option>\n ))}\n </Select.Viewport>\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n </Input.Root>\n </Section>\n\n {type === 'number' && (\n <>\n <Section>\n <Input.Root>\n <Input.Label classNames='mbe-1 mbs-3'>Decimal places</Input.Label>\n {/* TODO(burdon): Constrain input to numbers. */}\n <Input.TextInput value={digits ?? ''} onChange={(event) => setDigits(event.target.value)} />\n </Input.Root>\n </Section>\n </>\n )}\n\n {/* TODO(burdon): Selectors on same line. */}\n {type === 'ref' && (\n <>\n <Section>\n <Input.Root>\n <Input.Label classNames='mbe-1 mbs-3'>Table</Input.Label>\n <Select.Root value={refTable} onValueChange={setRefTable}>\n <Select.TriggerButton placeholder='Table' classNames='is-full' />\n <Select.Portal>\n <Select.Content>\n <Select.Viewport>\n {tableDefs\n .filter((t) => t.id !== tableDef.id)\n .map(({ id, name }) => (\n <Select.Option key={id} value={id}>\n {name ?? id}\n </Select.Option>\n ))}\n </Select.Viewport>\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n </Input.Root>\n\n {refTable && (\n <Input.Root>\n <Input.Label classNames='mbe-1 mbs-3'>Table property</Input.Label>\n <Select.Root value={refProp} onValueChange={setRefProp}>\n <Select.TriggerButton placeholder='Property' classNames='is-full' />\n <Select.Portal>\n <Select.Content>\n <Select.Viewport>\n {tableDefs\n .find((tableDef) => tableDef.id === refTable)\n ?.columns.map(({ id, label }) => (\n <Select.Option key={id} value={id}>\n {label ?? id}\n </Select.Option>\n ))}\n </Select.Viewport>\n </Select.Content>\n </Select.Portal>\n </Select.Root>\n </Input.Root>\n )}\n </Section>\n </>\n )}\n\n <Separator classNames='mli-2' />\n\n <Section className='space-b-1.5'>\n {/* TODO(burdon): Style as DropdownMenuItem. */}\n <Button variant='primary' classNames='is-full flex gap-2' onClick={handleSave}>\n <span>Save</span>\n <div className='grow' />\n <Check className={getSize(5)} />\n </Button>\n <Button classNames='is-full flex gap-2' onClick={handleCancel}>\n <span>Cancel</span>\n <div className='grow' />\n <X className={getSize(5)} />\n </Button>\n <Button classNames='is-full flex gap-2' onClick={() => onDelete?.(column.id)}>\n <span>Delete</span>\n <div className='grow' />\n <Trash className={getSize(5)} />\n </Button>\n </Section>\n </div>\n </DensityProvider>\n </Popover.Viewport>\n <Popover.Arrow />\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n );\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nexport type TableDef = {\n id: string;\n name?: string; // TODO(burdon): Required?\n columns: ColumnProps[];\n};\n\nexport type ColumnType = 'number' | 'boolean' | 'date' | 'string' | 'ref';\n\nexport const columnTypes = new Map<ColumnType, string>([\n ['string', 'Text'],\n ['boolean', 'Checkbox'],\n ['number', 'Number'],\n ['date', 'Date'],\n ['ref', 'Reference'],\n]);\n\nexport type ColumnProps = {\n id: string;\n prop: string;\n type: ColumnType;\n size?: number;\n label?: string;\n\n // type = number\n digits?: number;\n\n // type = ref\n refTable?: string;\n refProp?: string;\n\n // TODO(burdon): Move to meta.\n fixed?: boolean;\n editable?: boolean;\n resizable?: boolean;\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport {\n flexRender,\n getCoreRowModel,\n getGroupedRowModel,\n useReactTable,\n type ColumnSizingInfoState,\n type ColumnSizingState,\n type GroupingState,\n type HeaderGroup,\n type Row,\n type RowData,\n type RowSelectionState,\n type TableState,\n type VisibilityState,\n} from '@tanstack/react-table';\nimport React, { Fragment, useEffect, useRef, useState } from 'react';\n\nimport { debounce } from '@dxos/async';\nimport { groupBorder, inputSurface, mx } from '@dxos/react-ui-theme';\n\nimport { defaultTableSlots, type TableSlots } from '../theme';\nimport { type TableColumnDef, type KeyValue } from '../types';\n\n// TODO(burdon): Sort/filter.\n// TODO(burdon): Drag-and-drop.\n// TODO(burdon): Virtual (e.g., log panel).\n\nexport type TableSelection<TData extends RowData> = {\n // Controlled if undefined (by default).\n select?: 'single' | 'single-toggle' | 'multiple' | 'multiple-toggle' | undefined;\n selected?: TData[];\n onSelectedChange?: (selected: TData[] | undefined) => void;\n};\n\n/**\n * Util to update the selection based on the mode.\n */\nexport const updateSelection = (\n selectionState: RowSelectionState,\n id: string,\n selection: TableSelection<any>['select'],\n): RowSelectionState => {\n switch (selection) {\n case 'single': {\n return {\n [id]: true,\n };\n }\n case 'single-toggle': {\n return selectionState[id]\n ? {}\n : {\n [id]: true,\n };\n }\n case 'multiple': {\n return {\n [id]: true,\n ...selectionState,\n };\n }\n case 'multiple-toggle': {\n if (selectionState[id]) {\n const newSelectionState = { ...selectionState };\n delete newSelectionState[id];\n return newSelectionState;\n } else {\n return {\n [id]: true,\n ...selectionState,\n };\n }\n }\n }\n\n return selectionState;\n};\n\nexport type TableProps<TData extends RowData> = {\n keyAccessor?: KeyValue<TData>;\n data?: TData[];\n columns?: TableColumnDef<TData>[];\n columnVisibility?: VisibilityState;\n onColumnResize?: (state: Record<string, number>) => void;\n grouping?: string[];\n header?: boolean;\n footer?: boolean;\n border?: boolean;\n fullWidth?: boolean;\n pinToBottom?: boolean;\n slots?: TableSlots;\n debug?: boolean;\n} & TableSelection<TData>;\n\nexport const Table = <TData extends RowData>({ slots = defaultTableSlots, ...props }: TableProps<TData>) => {\n const {\n data = [],\n columns = [],\n onColumnResize,\n columnVisibility,\n header = true,\n footer,\n select,\n selected,\n onSelectedChange,\n fullWidth,\n pinToBottom,\n debug,\n } = props;\n\n // Update controlled selection.\n // https://tanstack.com/table/v8/docs/api/features/row-selection\n const [focus, setFocus] = useState<string>();\n const [rowSelection, setRowSelection] = useState<RowSelectionState>({});\n useEffect(() => {\n setRowSelection(\n selected?.reduce((selectionState: RowSelectionState, selected) => {\n const row = table.getRowModel().rows.find((row) => row.original === selected);\n if (row) {\n selectionState[row.id] = true;\n }\n\n return selectionState;\n }, {}) ?? {},\n );\n }, [select, selected]);\n\n // Resizing.\n const [columnSizingInfo, setColumnSizingInfo] = useState<ColumnSizingInfoState>({} as ColumnSizingInfoState);\n const onColumnResizeDebounced = debounce<ColumnSizingState>((info) => onColumnResize?.(info), 500);\n useEffect(() => {\n if (columnSizingInfo.columnSizingStart?.length === 0) {\n onColumnResizeDebounced(table.getState().columnSizing);\n }\n }, [columnSizingInfo]);\n\n const [grouping, setGrouping] = useState<GroupingState>(props.grouping ?? []);\n useEffect(() => setGrouping(props.grouping ?? []), [props.grouping]);\n\n //\n // Update table state.\n // https://tanstack.com/table/v8/docs/api/core/table\n //\n const table = useReactTable({\n data,\n columns,\n defaultColumn: {\n size: 400, // Required in order remove default width.\n maxSize: 800,\n },\n getCoreRowModel: getCoreRowModel(),\n meta: {},\n\n // TODO(burdon): Pagination.\n // TODO(burdon): Sorting.\n // TODO(burdon): Filtering.\n state: {\n columnVisibility,\n columnSizingInfo,\n rowSelection,\n grouping,\n },\n\n // Grouping.\n getGroupedRowModel: getGroupedRowModel(),\n onGroupingChange: setGrouping,\n\n // Selection.\n enableRowSelection: select === 'single' || select === 'single-toggle',\n enableMultiRowSelection: select === 'multiple' || select === 'multiple-toggle',\n onRowSelectionChange: (rows) => {\n setRowSelection(rows);\n },\n\n // Resize columns.\n // TODO(burdon): Drag to re-order columns.\n columnResizeMode: 'onChange',\n enableColumnResizing: true,\n onColumnSizingInfoChange: setColumnSizingInfo,\n\n debugTable: debug,\n });\n\n // TODO(burdon): Add flex if not resizable.\n // Create additional expansion column if all columns have fixed width.\n const expand = false; // columns.map((column) => column.size).filter(Boolean).length === columns?.length;\n\n // Pin scrollbar to bottom.\n const containerRef = usePinToBottom(data, pinToBottom);\n\n const handleSelect = (row: Row<TData>) => {\n if (select) {\n // Uncontrolled.\n setRowSelection((selectionState: RowSelectionState) => {\n const newSelectionState = updateSelection(selectionState, row.id, select);\n if (onSelectedChange) {\n const rows: TData[] = Object.keys(newSelectionState).map((id) => table.getRowModel().rowsById[id].original);\n onSelectedChange(rows);\n }\n\n return newSelectionState;\n });\n } else {\n // Controlled.\n onSelectedChange?.([row.original]);\n }\n };\n\n // TODO(burdon): Use radix ScrollArea.\n // https://www.radix-ui.com/primitives/docs/components/scroll-area\n return (\n <div ref={containerRef} className={mx('grow overflow-auto', slots?.root?.className)}>\n <table\n // Styles:\n // table-fixed: Prevents fixed sized columns from shrinking.\n className={mx(!fullWidth && 'table-fixed', inputSurface, slots?.table?.className)}\n style={{\n width: fullWidth ? '100%' : table.getTotalSize(),\n }}\n >\n {/* Head */}\n <TableHead\n {...props}\n slots={slots}\n header={header}\n state={table.getState()}\n headers={table.getHeaderGroups()}\n />\n\n {/* Rows */}\n {grouping.length === 0 && (\n <TableBody\n {...props}\n slots={slots}\n rowSelection={rowSelection}\n expand={expand}\n focus={focus}\n onFocus={setFocus}\n onSelect={handleSelect}\n rows={table.getRowModel().rows}\n />\n )}\n\n {/* Groups */}\n {grouping.length !== 0 &&\n table.getGroupedRowModel().rows.map((row, i) => {\n return (\n <Fragment key={i}>\n {/* TODO(burdon): Customize group header renderer. */}\n <thead>\n <tr>\n {slots?.margin && <th className={mx(slots?.margin?.className)} />}\n {debug && <th />}\n <th\n // TODO(burdon): Calculate row span.\n colSpan={table.getHeaderGroups()[0].headers.length}\n className={mx('text-left', slots?.group?.className)}\n >\n {table.getState().grouping[0]}[{String(row.getGroupingValue(table.getState().grouping[0]))}]\n </th>\n </tr>\n </thead>\n\n <TableBody\n {...props}\n slots={slots}\n rowSelection={rowSelection}\n expand={expand}\n focus={focus}\n onFocus={setFocus}\n onSelect={handleSelect}\n rows={row.subRows}\n />\n </Fragment>\n );\n })}\n\n {/* Foot */}\n {footer && <TableFoot {...props} slots={slots} footers={table.getFooterGroups()} />}\n </table>\n\n {debug && (\n <pre className='font-mono text-xs text-neutral-500 my-4 p-2 ring'>\n <code>{JSON.stringify(table.getState(), undefined, 2)}</code>\n </pre>\n )}\n </div>\n );\n};\n\n/**\n * Glue to bottom as rows are added.\n */\n// TODO(burdon): Causes scrollbar to be constantly visible.\n// https://css-tricks.com/books/greatest-css-tricks/pin-scrolling-to-bottom\nconst usePinToBottom = <TData extends RowData>(data: TData[], pinToBottom?: boolean) => {\n const containerRef = useRef<HTMLDivElement | null>(null);\n const [stickyScrolling, setStickyScrolling] = useState(true);\n useEffect(() => {\n const container = containerRef.current;\n if (!pinToBottom || !container) {\n return;\n }\n\n // TODO(burdon): Set when scrolled to bottom and unset when manually scrolled away.\n const handler = () => {\n const bottom = container.scrollHeight - container.scrollTop - container.clientHeight === 0;\n setStickyScrolling(bottom);\n };\n\n container.addEventListener('scroll', handler);\n return () => container.removeEventListener('scroll', handler);\n }, []);\n\n useEffect(() => {\n if (!pinToBottom || !containerRef.current || !stickyScrolling) {\n return;\n }\n\n containerRef.current?.scroll({ top: containerRef.current.scrollHeight });\n }, [data]);\n\n return containerRef;\n};\n\n//\n// Head.\n//\n\ntype TableHeadProps<TData extends RowData> = Partial<TableProps<TData>> & {\n state: TableState;\n headers: HeaderGroup<TData>[];\n expand?: boolean;\n};\n\nconst TableHead = <TData extends RowData>({\n state,\n headers,\n expand,\n header,\n debug,\n fullWidth,\n border,\n slots,\n}: TableHeadProps<TData>) => {\n return (\n <thead className={mx(header ? ['sticky top-0 z-10'] : 'collapse')}>\n {headers.map((headerGroup) => {\n return (\n // Group element to hover resize handles.\n <tr key={headerGroup.id} className='font-light group'>\n {slots?.margin && <th className={mx(slots?.margin?.className)} />}\n\n {/* TODO(burdon): Calc. width. */}\n {debug && (\n <th className='text-left' style={{ width: 32 }}>\n #\n </th>\n )}\n\n {headerGroup.headers.map((header) => {\n return (\n <th\n key={header.id}\n style={{\n // Don't set width if fullWidth and no explicit size.\n width: fullWidth && header.column.columnDef.meta?.expand ? undefined : header.getSize(),\n }}\n // Relative for resize handle.\n // TODO(burdon): Border scrolls with main content.\n // https://stackoverflow.com/questions/50361698/border-style-do-not-work-with-sticky-position-element\n className={mx(\n 'relative text-left',\n border && groupBorder,\n slots?.header?.className,\n header.column.columnDef.meta?.slots?.header?.className,\n )}\n >\n {!header || header.isPlaceholder\n ? null\n : flexRender(header.column.columnDef.header, header.getContext())}\n\n {/*\n * Resize handle.\n * https://codesandbox.io/p/sandbox/github/tanstack/table/tree/main/examples/react/column-sizing\n */}\n {header.column.columnDef.meta?.resizable && (\n <div\n className={mx(\n 'absolute top-0 pl-1 h-full z-[10] w-[7px] -right-[5px]',\n 'cursor-col-resize select-none touch-none opacity-20 hover:opacity-100',\n header.column.getIsResizing() && 'hidden',\n )}\n style={{\n transform: header.column.getIsResizing()\n ? `translateX(${state.columnSizingInfo.deltaOffset}px)`\n : undefined,\n }}\n onMouseDown={header.getResizeHandler()}\n onTouchStart={header.getResizeHandler()}\n >\n <div className='flex group-hover:bg-neutral-700 -ml-[2px] w-[1px] h-full' />\n </div>\n )}\n </th>\n );\n })}\n {expand && <th />}\n {slots?.margin && <th className={mx(slots?.margin?.className)} />}\n </tr>\n );\n })}\n </thead>\n );\n};\n\n//\n// Body.\n//\n\ntype TableBodyProps<TData extends RowData> = Partial<TableProps<TData>> & {\n rows: Row<TData>[];\n rowSelection: RowSelectionState;\n expand?: boolean;\n focus?: string;\n onFocus?: (id?: string) => void;\n onSelect?: (row: Row<TData>) => void;\n};\n\nconst TableBody = <TData extends RowData>({\n keyAccessor,\n rows,\n rowSelection,\n focus,\n onFocus,\n onSelect,\n debug,\n border,\n expand,\n slots,\n}: TableBodyProps<TData>) => {\n return (\n <tbody>\n {rows.map((row) => {\n return (\n <tr\n key={keyAccessor ? keyAccessor(row.original) : row.id}\n onClick={() => onSelect?.(row)}\n role='button' // TODO(burdon): ???\n className={mx(\n 'group',\n rowSelection[row.id] && slots?.selected?.className,\n focus === row.id && slots?.focus?.className,\n slots?.row?.className,\n )}\n >\n {/* TODO(burdon): Dummy button for focus (don't alter geometry). */}\n {slots?.margin && (\n <td className={mx(slots?.margin?.className)}>\n <button\n role='button'\n style={{ width: 1, height: 1 }}\n className='focus:outline-none'\n onFocus={() => onFocus?.(keyAccessor ? keyAccessor(row.original) : row.id)}\n onBlur={() => onFocus?.(undefined)}\n onKeyDown={(event) => {\n // TODO(burdon): Move focus.\n switch (event.key) {\n case 'ArrowUp': {\n break;\n }\n case 'ArrowDown': {\n break;\n }\n }\n }}\n />\n </td>\n )}\n\n {debug && <td>{row.id}</td>}\n\n {row.getVisibleCells().map((cell) => {\n // TODO(burdon): Allow class override from column.\n return (\n <td\n key={cell.id}\n className={mx(\n border && groupBorder,\n slots?.cell?.className,\n cell.column.columnDef.meta?.slots?.cell?.className,\n )}\n >\n {flexRender(cell.column.columnDef.cell, { className: 'px-2', ...cell.getContext() })}\n </td>\n );\n })}\n\n {expand && <td />}\n {slots?.margin && <td className={mx(slots?.margin?.className)} />}\n </tr>\n );\n })}\n </tbody>\n );\n};\n\n//\n// Footer\n//\n\ntype TableFootProps<TData extends RowData> = Partial<TableProps<TData>> & {\n footers: HeaderGroup<TData>[];\n expand?: boolean;\n};\n\nconst TableFoot = <TData extends RowData>({ footers, expand, slots, debug, border }: TableFootProps<TData>) => {\n return (\n <tfoot className={mx('sticky bottom-0 z-[10]', slots?.footer?.className)}>\n {footers.map((footerGroup) => (\n <tr key={footerGroup.id} className='font-thin'>\n {slots?.margin && <th className={mx(slots?.margin?.className)} />}\n {debug && <th />}\n\n {footerGroup.headers.map((footer) => {\n return (\n <th\n key={footer.id}\n className={mx(\n border && groupBorder,\n 'text-left',\n slots?.footer?.className,\n footer.column.columnDef.meta?.slots?.footer?.className,\n )}\n >\n {footer.isPlaceholder ? null : flexRender(footer.column.columnDef.footer, footer.getContext())}\n </th>\n );\n })}\n\n {expand && <th />}\n {slots?.margin && <th className={mx(slots?.margin?.className)} />}\n </tr>\n ))}\n </tfoot>\n );\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { chromeSurface } from '@dxos/react-ui-theme';\n\n// TODO(burdon): Remove nested classNames? Add to theme?\nexport type TableSlots = {\n root?: {\n className?: string | string[];\n };\n table?: {\n className?: string | string[];\n };\n header?: {\n className?: string | string[];\n };\n footer?: {\n className?: string | string[];\n };\n group?: {\n className?: string | string[];\n };\n row?: {\n className?: string | string[];\n };\n cell?: {\n className?: string | string[];\n };\n focus?: {\n className?: string | string[];\n };\n selected?: {\n className?: string | string[];\n };\n margin?: {\n className?: string | string[];\n };\n};\n\n// TODO(burdon): Change to groups.\n/*\nhead: {\n default:\n cell:\n}\nrow: {\n default: '',\n selected: ''\n}\n*/\n\n// TODO(burdon): Scrollbar area.\n// TODO(burdon): Overscroll horizontal (full width).\n\n// TODO(burdon): Integrate with DXOS UI theme (direct dependency -- see react-ui-editor, tailwind.ts).\n// See Link.tsx const { tx } = useThemeContext();\n// Reuse button fragments for hoverColors, selected, primary, etc.\nexport const defaultTableSlots: TableSlots = {\n // TODO(burdon): head/body/table rows.\n header: { className: [chromeSurface, 'px-2 font-light select-none'] },\n footer: { className: [chromeSurface, 'px-2 font-light'] },\n cell: { className: 'px-2' },\n group: { className: 'px-2 font-light text-xs text-left' },\n focus: { className: 'ring ring-primary-600 ring-inset' },\n selected: { className: '!bg-teal-100 dark:!bg-teal-700' },\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { CaretDown } from '@phosphor-icons/react';\nimport { type RowData } from '@tanstack/react-table';\nimport React, { useCallback, useState } from 'react';\n\nimport { Popover, useTranslation } from '@dxos/react-ui';\nimport { PopoverCombobox } from '@dxos/react-ui-searchlist';\nimport { descriptionText, getSize, mx, staticPlaceholderText } from '@dxos/react-ui-theme';\n\nimport { type SelectQueryModel } from '../helpers';\nimport { translationKey } from '../translations';\n\nexport type ComboboxCellItems<TData extends RowData> = Record<string, { label: string; data: TData }>;\n\nconst initialItems = <TData extends RowData>(model: SelectQueryModel<TData>, value?: TData) =>\n value\n ? {\n [model.getId(value)]: { label: model.getText(value), data: value },\n }\n : {};\n\nexport const ComboboxCell = <TData extends RowData>({\n model,\n value,\n onValueChange,\n}: {\n model: SelectQueryModel<TData>;\n value: TData;\n onValueChange: (value: TData) => void;\n}) => {\n const { t } = useTranslation(translationKey);\n const [items, setItems] = useState<ComboboxCellItems<TData>>(initialItems(model, value));\n const [loading, setLoading] = useState(false);\n const [searchInputValue, setSearchInputValue] = useState('');\n const handleSearchInputValueChange = async (text?: string) => {\n setSearchInputValue(text ?? '');\n setLoading(true);\n const items = await model.query(text);\n setItems(\n items.reduce((acc: ComboboxCellItems<TData>, item) => {\n acc[model.getId(item)] = {\n label: model.getText(item),\n data: item,\n };\n return acc;\n }, initialItems(model, value)),\n );\n setLoading(false);\n };\n\n const handleValueChange = useCallback(\n (id: string) => {\n onValueChange(items[id]?.data);\n },\n [items, onValueChange],\n );\n\n return (\n <PopoverCombobox.Root placeholder={t('no selection label')}>\n <PopoverCombobox.Trigger variant='ghost' classNames='is-full'>\n {value ? (\n <>\n <span\n className={mx('font-normal text-start flex-1 min-is-0 truncate mie-2', !value && staticPlaceholderText)}\n >\n {model.getText(value)}\n </span>\n <CaretDown weight='bold' className={getSize(3)} />\n </>\n ) : null}\n </PopoverCombobox.Trigger>\n <PopoverCombobox.Content shouldFilter={false} classNames='is-[--radix-popover-trigger-width]'>\n <PopoverCombobox.Input value={searchInputValue} onValueChange={handleSearchInputValueChange} />\n <PopoverCombobox.List>\n {searchInputValue.length < 1 ? (\n <p className={mx('text-center', descriptionText)}>Start typing to search</p>\n ) : loading ? (\n <p className={mx('text-center', descriptionText)}>Searching…</p>\n ) : (\n <>\n <PopoverCombobox.Empty classNames={['text-center', descriptionText]}>No results</PopoverCombobox.Empty>\n {Object.entries(items).map(([id, { label }]) => (\n <PopoverCombobox.Item key={id} value={id} onSelect={handleValueChange} classNames='truncate'>\n {label}\n </PopoverCombobox.Item>\n ))}\n </>\n )}\n </PopoverCombobox.List>\n <Popover.Arrow />\n </PopoverCombobox.Content>\n </PopoverCombobox.Root>\n );\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nexport const translationKey = 'table';\n\nexport default [\n {\n 'en-US': {\n [translationKey]: {\n 'no selection label': ' ',\n },\n },\n },\n];\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport { useFocusFinders } from '@fluentui/react-tabster';\nimport { Check, ClipboardText, type Icon, X } from '@phosphor-icons/react';\nimport { createColumnHelper, type ColumnDef, type ColumnMeta, type RowData } from '@tanstack/react-table';\nimport format from 'date-fns/format';\nimport formatDistanceToNow from 'date-fns/formatDistanceToNow';\nimport defaultsDeep from 'lodash.defaultsdeep';\nimport React, { useRef, useState } from 'react';\n\nimport { type PublicKey } from '@dxos/keys';\nimport { Input, Tooltip } from '@dxos/react-ui';\nimport { getSize, mx } from '@dxos/react-ui-theme';\nimport { stripUndefinedValues } from '@dxos/util';\n\nimport { ComboboxCell } from './components';\n\n// TODO(burdon): Factor out hack to find next focusable element (extend useFocusFinders)?\nconst findNextFocusable = (\n findFirstFocusable: (container: HTMLElement) => HTMLElement | null | undefined,\n container: HTMLElement,\n): HTMLElement | undefined => {\n const next = findFirstFocusable(container as any);\n if (next) {\n if (next?.tagName === 'INPUT') {\n return next;\n }\n if (container.nextElementSibling) {\n return findNextFocusable(findFirstFocusable, container.nextSibling as any);\n }\n }\n};\n\nexport type ValueUpdater<TData extends RowData, TValue> = (row: TData, id: string, value: TValue) => void;\n\nexport const createColumnBuilder = <TData extends RowData>() => ({\n helper: createColumnHelper<TData>(),\n builder: new ColumnBuilder<TData>(),\n});\n\n/**\n * NOTE: Can use `meta` for custom properties.\n */\nexport type BaseColumnOptions<TData, TValue> = Partial<ColumnDef<TData, TValue>> & {\n meta?: ColumnMeta<TData, TValue>;\n label?: string;\n className?: string;\n onUpdate?: ValueUpdater<TData, TValue | undefined>;\n};\n\n// TODO(burdon): Better abstraction?\nexport type SelectQueryModel<TData extends RowData> = {\n getId(object: TData): string;\n getText(object: TData): string;\n query(text?: string): Promise<TData[]>;\n};\n\nexport type SelectColumnOptions<TData extends RowData> = BaseColumnOptions<TData, any> & {\n model: SelectQueryModel<TData>;\n};\n\nexport type StringColumnOptions<TData extends RowData> = BaseColumnOptions<TData, string> & {};\n\nexport type NumberColumnOptions<TData extends RowData> = BaseColumnOptions<TData, number> & {\n digits?: number;\n};\n\nexport type KeyColumnOptions<TData extends RowData> = BaseColumnOptions<TData, PublicKey> & {\n tooltip?: boolean;\n};\n\nexport type DateColumnOptions<TData extends RowData> = BaseColumnOptions<TData, Date> & {\n format?: string;\n relative?: boolean;\n};\n\nexport type BooleanColumnOptions<TData extends RowData> = BaseColumnOptions<TData, boolean> & {};\n\nexport type IconColumnOptions<TData extends RowData> = BaseColumnOptions<TData, boolean> & {\n on?: {\n Icon?: Icon;\n className?: string;\n };\n off?: {\n Icon?: Icon;\n className?: string;\n };\n};\n\nconst defaults = <TData extends RowData, TValue>(\n options: Partial<ColumnDef<TData, TValue>>,\n ...sources: Partial<ColumnDef<TData, TValue>>[]\n): Partial<ColumnDef<TData, TValue>> => {\n return stripUndefinedValues(defaultsDeep({}, options, ...sources));\n};\n\n/**\n * Util to create column definitions.\n */\nexport class ColumnBuilder<TData extends RowData> {\n /**\n * Select value\n */\n select({ label, className, model, onUpdate, ...props }: SelectColumnOptions<TData>): Partial<ColumnDef<TData, any>> {\n return defaults(props, {\n minSize: 100,\n header: (column) => {\n return <div className={'truncate'}>{label ?? column.header.id}</div>;\n },\n cell:\n model && onUpdate\n ? (cell) => (\n <ComboboxCell<any>\n model={model}\n value={cell.getValue()}\n onValueChange={(value) => onUpdate?.(cell.row.original, cell.column.id, value)}\n />\n )\n : (cell) => {\n const value = cell.getValue();\n return <div className={mx('truncate', className)}>{value ? model.getText(value) : ''}</div>;\n },\n });\n }\n\n /**\n * String formats.\n */\n string({ label, className, onUpdate, ...props }: StringColumnOptions<TData> = {}): Partial<ColumnDef<TData, string>> {\n return defaults(props, {\n minSize: 100,\n // TODO(burdon): Default.\n header: (column) => {\n return <div className={'truncate'}>{label ?? column.header.id}</div>;\n },\n cell: onUpdate\n ? (cell) => {\n // https://tanstack.com/table/v8/docs/examples/react/editable-data\n const initialValue = cell.getValue();\n const [value, setValue] = useState(initialValue);\n const inputRef = useRef<HTMLInputElement>(null);\n const { findFirstFocusable } = useFocusFinders();\n\n const handleSave = (focusNext = false) => {\n if (value === initialValue) {\n return;\n }\n\n onUpdate?.(cell.row.original, cell.column.id, value);\n\n // TODO(burdon): More generally support keyboard navigation.\n if (focusNext) {\n const rowElement = inputRef.current?.parentElement?.parentElement;\n // TODO(burdon): Hack to wait for next row to render.\n setTimeout(() => {\n const next = findNextFocusable(findFirstFocusable, rowElement as HTMLElement);\n next?.focus();\n });\n }\n };\n\n const handleCancel = () => {\n setValue(initialValue);\n };\n\n // Check if first input column of last row.\n const rows = cell.table.getRowModel().flatRows;\n const columns = cell.table.getVisibleFlatColumns();\n const placeholder = cell.row.index === rows.length - 1 && columns[0].id === cell.column.id;\n\n // TODO(burdon): Don't render inputs unless mouse over (Show ellipsis when div)?\n return (\n <Input.Root>\n <Input.TextInput\n ref={inputRef}\n variant='subdued'\n placeholder={placeholder ? 'Add row...' : undefined}\n classNames={'px-2'}\n value={(value as string) ?? ''}\n onBlur={() => handleSave(false)}\n onChange={(event) => setValue(event.target.value)}\n onKeyDown={(event) =>\n (event.key === 'Enter' && handleSave(true)) || (event.key === 'Escape' && handleCancel())\n }\n />\n </Input.Root>\n );\n }\n : (cell) => {\n const value = cell.getValue();\n return <div className={mx('truncate', className)}>{value}</div>;\n },\n });\n }\n\n /**\n * Number formats.\n */\n number({ label, minSize, className, digits, onUpdate, ...props }: NumberColumnOptions<TData> = {}): Partial<\n ColumnDef<TData, number>\n > {\n return defaults(props, {\n size: 100,\n minSize: 100,\n header: (cell) => <div className='w-full truncate text-right'>{label ?? cell.header.id}</div>,\n cell: (cell) => {\n const value = cell.getValue();\n const [text, setText] = useState<string>();\n\n const handleEdit = () => {\n if (onUpdate) {\n setText(value !== undefined ? String(value) : '');\n }\n };\n\n // TODO(burdon): Property is encoded as float (e.g., 6.1 => 6.099)\n const handleSave = () => {\n const value = text?.trim().length ? Number(text) : NaN;\n onUpdate?.(cell.row.original, cell.column.id, isNaN(value) ? undefined : value);\n setText(undefined);\n };\n\n const handleCancel = () => {\n setText(undefined);\n };\n\n if (text !== undefined) {\n return (\n <div className={mx('grow text-right font-mono', className)}>\n <Input.Root>\n <Input.TextInput\n autoFocus\n value={text}\n classNames={'px-2'}\n onBlur={handleSave}\n onChange={(event) => setText(event.target.value)}\n onKeyDown={(event) =>\n (event.key === 'Escape' && handleCancel()) || (event.key === 'Enter' && handleSave())\n }\n />\n </Input.Root>\n </div>\n );\n }\n\n return (\n <div\n className={mx('grow w-full text-right font-mono empty:after:content-[\" \"]', className)}\n onClick={handleEdit}\n >\n {value?.toLocaleString(undefined, {\n minimumFractionDigits: digits ?? 0,\n maximumFractionDigits: digits ?? 2,\n })}\n </div>\n );\n },\n });\n }\n\n /**\n * Date formats.\n */\n // TODO(burdon): Date picker (pluggable renderers?)\n date({ label, format: formatSpec, relative, className, ...props }: DateColumnOptions<TData> = {}): Partial<\n ColumnDef<TData, Date>\n > {\n return defaults(props, {\n size: 220, // TODO(burdon): Depends on format.\n minSize: 100,\n header: (cell) => <div>{label ?? cell.header.id}</div>,\n cell: (cell) => {\n const value = cell.getValue();\n\n try {\n const str = value\n ? formatSpec\n ? format(value, formatSpec)\n : relative\n ? formatDistanceToNow(value, { addSuffix: true })\n : value.toISOString()\n : undefined;\n\n return <div className={mx('font-mono', className)}>{str}</div>;\n } catch (err) {\n console.log(value);\n return null;\n }\n },\n });\n }\n\n /**\n * PublicKey with tooltip.\n */\n key({ label, tooltip, ...props }: KeyColumnOptions<TData> = {}): Partial<ColumnDef<TData, PublicKey>> {\n return defaults(props, {\n size: 86,\n minSize: 86,\n header: (cell) => <div>{label ?? cell.header.id}</div>,\n cell: (cell) => {\n const value = cell.getValue();\n if (!value) {\n return;\n }\n\n // TODO(burdon): Factor out styles.\n const element = (\n <div className='font-mono font-thin text-green-500 dark:text-green-300'>{value.truncate()}</div>\n );\n if (!tooltip) {\n return element;\n }\n\n return (\n <div className='group inline-flex gap-2 items-center'>\n <Tooltip.Provider>\n <Tooltip.Root>\n <Tooltip.Trigger asChild>{element}</Tooltip.Trigger>\n <Tooltip.Content side='right'>\n <Tooltip.Arrow />\n <ClipboardText\n onClick={(ev) => {\n ev.stopPropagation(); // Prevent select row.\n void navigator.clipboard.writeText(value.toHex());\n }}\n />\n </Tooltip.Content>\n </Tooltip.Root>\n </Tooltip.Provider>\n </div>\n );\n },\n });\n }\n\n /**\n * Checkbox.\n */\n checkbox({ label, className, onUpdate, ...props }: BooleanColumnOptions<TData> = {}): Partial<\n ColumnDef<TData, boolean>\n > {\n return defaults(props, {\n size: 40,\n minSize: 40,\n header: (column) => <div className={'flex grow justify-center'}>{label ?? column.header.id}</div>,\n cell: (cell) => {\n const value = cell.getValue();\n // TODO(burdon): Center.\n return (\n <div className='flex grow justify-center'>\n <Input.Root>\n <Input.Checkbox\n onClick={(event) => event.stopPropagation()}\n classNames={className}\n disabled={!onUpdate}\n checked={!!value}\n onCheckedChange={(value) => {\n onUpdate?.(cell.row.original, cell.column.id, !!value);\n }}\n />\n </Input.Root>\n </div>\n );\n },\n });\n }\n\n /**\n * Icon based on boolean value.\n */\n icon({ label, size, on, off, ...props }: IconColumnOptions<TData> = {}): Partial<ColumnDef<TData, boolean>> {\n const IconOn = on?.Icon ?? Check;\n const IconOff = off?.Icon ?? X;\n return defaults(props, {\n size: size ?? 32,\n header: (column) => <div className={'justify-center'}>{label ?? column.header.id}</div>,\n cell: (cell) => {\n const value = cell.getValue();\n if (value) {\n return (\n <div className='flex grow justify-center'>\n <IconOn className={mx(getSize(6), on?.className ?? 'text-green-700')} />\n </div>\n );\n } else if (value === false) {\n return (\n <div className='flex grow justify-center'>\n <IconOff className={mx(getSize(6), off?.className ?? 'text-red-700')} />\n </div>\n );\n } else {\n return null;\n }\n },\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["Check", "CaretDown", "Trash", "X", "React", "useRef", "useState", "Button", "DensityProvider", "Input", "Popover", "Select", "Separator", "getSize", "mx", "safeParseInt", "columnTypes", "Map", "ColumnMenu", "column", "props", "title", "label", "length", "id", "div", "className", "ColumnPanel", "Section", "children", "role", "mx", "context", "tableDefs", "tableDef", "onUpdate", "onDelete", "open", "setOpen", "useState", "prop", "setProp", "refTable", "setRefTable", "refProp", "setRefProp", "type", "setType", "String", "setLabel", "digits", "setDigits", "propRef", "useRef", "handleCancel", "handleSave", "match", "current", "focus", "columns", "find", "c", "safeParseInt", "Popover", "Root", "onOpenChange", "nextOpen", "Trigger", "asChild", "Button", "variant", "classNames", "CaretDown", "getSize", "Portal", "Content", "Viewport", "DensityProvider", "density", "Input", "Label", "TextInput", "placeholder", "value", "onChange", "event", "target", "autoFocus", "ref", "replace", "Select", "onValueChange", "TriggerButton", "Array", "from", "columnTypes", "entries", "map", "Option", "key", "filter", "t", "name", "Separator", "onClick", "span", "Check", "X", "Trash", "Arrow", "flexRender", "getCoreRowModel", "getGroupedRowModel", "useReactTable", "React", "Fragment", "useEffect", "useRef", "useState", "debounce", "groupBorder", "inputSurface", "mx", "chromeSurface", "defaultTableSlots", "header", "className", "chromeSurface", "footer", "cell", "group", "focus", "selected", "updateSelection", "selectionState", "id", "selection", "newSelectionState", "Table", "slots", "defaultTableSlots", "props", "data", "columns", "onColumnResize", "columnVisibility", "header", "footer", "select", "selected", "onSelectedChange", "fullWidth", "pinToBottom", "debug", "focus", "setFocus", "useState", "rowSelection", "setRowSelection", "useEffect", "reduce", "row", "table", "getRowModel", "rows", "find", "original", "columnSizingInfo", "setColumnSizingInfo", "onColumnResizeDebounced", "debounce", "info", "columnSizingStart", "length", "getState", "columnSizing", "grouping", "setGrouping", "useReactTable", "defaultColumn", "size", "maxSize", "getCoreRowModel", "meta", "state", "getGroupedRowModel", "onGroupingChange", "enableRowSelection", "enableMultiRowSelection", "onRowSelectionChange", "columnResizeMode", "enableColumnResizing", "onColumnSizingInfoChange", "debugTable", "expand", "containerRef", "usePinToBottom", "handleSelect", "Object", "keys", "map", "rowsById", "React", "div", "ref", "className", "mx", "root", "inputSurface", "style", "width", "getTotalSize", "TableHead", "headers", "getHeaderGroups", "TableBody", "onFocus", "onSelect", "i", "Fragment", "key", "thead", "tr", "margin", "th", "colSpan", "group", "String", "getGroupingValue", "subRows", "TableFoot", "footers", "getFooterGroups", "pre", "code", "JSON", "stringify", "undefined", "useRef", "stickyScrolling", "setStickyScrolling", "container", "current", "handler", "bottom", "scrollHeight", "scrollTop", "clientHeight", "addEventListener", "removeEventListener", "scroll", "top", "border", "headerGroup", "column", "columnDef", "getSize", "groupBorder", "isPlaceholder", "flexRender", "getContext", "resizable", "getIsResizing", "transform", "deltaOffset", "onMouseDown", "getResizeHandler", "onTouchStart", "keyAccessor", "tbody", "onClick", "role", "td", "button", "height", "onBlur", "onKeyDown", "event", "getVisibleCells", "cell", "tfoot", "footerGroup", "CaretDown", "React", "useCallback", "useState", "Popover", "useTranslation", "PopoverCombobox", "descriptionText", "getSize", "mx", "staticPlaceholderText", "translationKey", "initialItems", "model", "value", "getId", "label", "getText", "data", "ComboboxCell", "onValueChange", "t", "useTranslation", "translationKey", "items", "setItems", "useState", "loading", "setLoading", "searchInputValue", "setSearchInputValue", "handleSearchInputValueChange", "text", "query", "reduce", "acc", "item", "handleValueChange", "useCallback", "id", "React", "PopoverCombobox", "Root", "placeholder", "Trigger", "variant", "classNames", "span", "className", "mx", "staticPlaceholderText", "CaretDown", "weight", "getSize", "Content", "shouldFilter", "Input", "List", "length", "p", "descriptionText", "Empty", "Object", "entries", "map", "Item", "key", "onSelect", "Popover", "Arrow", "useFocusFinders", "Check", "ClipboardText", "X", "createColumnHelper", "format", "formatDistanceToNow", "defaultsDeep", "React", "useRef", "useState", "Input", "Tooltip", "getSize", "mx", "stripUndefinedValues", "findNextFocusable", "findFirstFocusable", "container", "next", "tagName", "nextElementSibling", "nextSibling", "createColumnBuilder", "helper", "createColumnHelper", "builder", "ColumnBuilder", "defaults", "options", "sources", "stripUndefinedValues", "defaultsDeep", "select", "label", "className", "model", "onUpdate", "props", "minSize", "header", "column", "React", "div", "id", "cell", "ComboboxCell", "value", "getValue", "onValueChange", "row", "original", "mx", "getText", "string", "initialValue", "setValue", "useState", "inputRef", "useRef", "useFocusFinders", "handleSave", "focusNext", "rowElement", "current", "parentElement", "setTimeout", "focus", "handleCancel", "rows", "table", "getRowModel", "flatRows", "columns", "getVisibleFlatColumns", "placeholder", "index", "length", "Input", "Root", "TextInput", "ref", "variant", "undefined", "classNames", "onBlur", "onChange", "event", "target", "onKeyDown", "key", "number", "digits", "size", "text", "setText", "handleEdit", "String", "trim", "Number", "NaN", "isNaN", "autoFocus", "onClick", "toLocaleString", "minimumFractionDigits", "maximumFractionDigits", "date", "format", "formatSpec", "relative", "str", "formatDistanceToNow", "addSuffix", "toISOString", "err", "console", "log", "tooltip", "element", "truncate", "Tooltip", "Provider", "Trigger", "asChild", "Content", "side", "Arrow", "ClipboardText", "ev", "stopPropagation", "navigator", "clipboard", "writeText", "toHex", "checkbox", "Checkbox", "disabled", "checked", "onCheckedChange", "icon", "on", "off", "IconOn", "Icon", "Check", "IconOff", "X", "getSize"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"inputs":{"packages/ui/react-ui-table/src/schema.ts":{"bytes":
|
|
1
|
+
{"inputs":{"packages/ui/react-ui-table/src/schema.ts":{"bytes":1836,"imports":[],"format":"esm"},"packages/ui/react-ui-table/src/components/ColumnMenu.tsx":{"bytes":28711,"imports":[{"path":"@phosphor-icons/react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/ui/react-ui-table/src/schema.ts","kind":"import-statement","original":"../schema"}],"format":"esm"},"packages/ui/react-ui-table/src/theme.ts":{"bytes":4180,"imports":[{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true}],"format":"esm"},"packages/ui/react-ui-table/src/components/Table.tsx":{"bytes":50838,"imports":[{"path":"@tanstack/react-table","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"packages/ui/react-ui-table/src/theme.ts","kind":"import-statement","original":"../theme"}],"format":"esm"},"packages/ui/react-ui-table/src/translations.ts":{"bytes":990,"imports":[],"format":"esm"},"packages/ui/react-ui-table/src/components/ComboboxCell.tsx":{"bytes":11462,"imports":[{"path":"@phosphor-icons/react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-searchlist","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"packages/ui/react-ui-table/src/translations.ts","kind":"import-statement","original":"../translations"}],"format":"esm"},"packages/ui/react-ui-table/src/components/index.ts":{"bytes":664,"imports":[{"path":"packages/ui/react-ui-table/src/components/ColumnMenu.tsx","kind":"import-statement","original":"./ColumnMenu"},{"path":"packages/ui/react-ui-table/src/components/Table.tsx","kind":"import-statement","original":"./Table"},{"path":"packages/ui/react-ui-table/src/components/ComboboxCell.tsx","kind":"import-statement","original":"./ComboboxCell"}],"format":"esm"},"packages/ui/react-ui-table/src/helpers.tsx":{"bytes":40972,"imports":[{"path":"@fluentui/react-tabster","kind":"import-statement","external":true},{"path":"@phosphor-icons/react","kind":"import-statement","external":true},{"path":"@tanstack/react-table","kind":"import-statement","external":true},{"path":"date-fns/format","kind":"import-statement","external":true},{"path":"date-fns/formatDistanceToNow","kind":"import-statement","external":true},{"path":"lodash.defaultsdeep","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"packages/ui/react-ui-table/src/components/index.ts","kind":"import-statement","original":"./components"}],"format":"esm"},"packages/ui/react-ui-table/src/types.ts":{"bytes":1522,"imports":[],"format":"esm"},"packages/ui/react-ui-table/src/index.ts":{"bytes":803,"imports":[{"path":"packages/ui/react-ui-table/src/components/index.ts","kind":"import-statement","original":"./components"},{"path":"packages/ui/react-ui-table/src/helpers.tsx","kind":"import-statement","original":"./helpers"},{"path":"packages/ui/react-ui-table/src/schema.ts","kind":"import-statement","original":"./schema"},{"path":"packages/ui/react-ui-table/src/theme.ts","kind":"import-statement","original":"./theme"},{"path":"packages/ui/react-ui-table/src/types.ts","kind":"import-statement","original":"./types"}],"format":"esm"}},"outputs":{"packages/ui/react-ui-table/dist/lib/browser/index.mjs.map":{"imports":[],"exports":[],"inputs":{},"bytes":74172},"packages/ui/react-ui-table/dist/lib/browser/index.mjs":{"imports":[{"path":"@phosphor-icons/react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true},{"path":"@tanstack/react-table","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/async","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"@phosphor-icons/react","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-searchlist","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"@fluentui/react-tabster","kind":"import-statement","external":true},{"path":"@phosphor-icons/react","kind":"import-statement","external":true},{"path":"@tanstack/react-table","kind":"import-statement","external":true},{"path":"date-fns/format","kind":"import-statement","external":true},{"path":"date-fns/formatDistanceToNow","kind":"import-statement","external":true},{"path":"lodash.defaultsdeep","kind":"import-statement","external":true},{"path":"react","kind":"import-statement","external":true},{"path":"@dxos/react-ui","kind":"import-statement","external":true},{"path":"@dxos/react-ui-theme","kind":"import-statement","external":true},{"path":"@dxos/util","kind":"import-statement","external":true}],"exports":["ColumnBuilder","ColumnMenu","ColumnPanel","ComboboxCell","Table","columnTypes","createColumnBuilder","defaultTableSlots","updateSelection"],"entryPoint":"packages/ui/react-ui-table/src/index.ts","inputs":{"packages/ui/react-ui-table/src/components/ColumnMenu.tsx":{"bytesInOutput":7708},"packages/ui/react-ui-table/src/schema.ts":{"bytesInOutput":224},"packages/ui/react-ui-table/src/components/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-table/src/components/Table.tsx":{"bytesInOutput":11866},"packages/ui/react-ui-table/src/theme.ts":{"bytesInOutput":542},"packages/ui/react-ui-table/src/components/ComboboxCell.tsx":{"bytesInOutput":3039},"packages/ui/react-ui-table/src/translations.ts":{"bytesInOutput":162},"packages/ui/react-ui-table/src/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-table/src/helpers.tsx":{"bytesInOutput":10021}},"bytes":34303}}}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type RowData } from '@tanstack/react-table';
|
|
2
|
+
import { type SelectQueryModel } from '../helpers';
|
|
3
|
+
export type ComboboxCellItems<TData extends RowData> = Record<string, {
|
|
4
|
+
label: string;
|
|
5
|
+
data: TData;
|
|
6
|
+
}>;
|
|
7
|
+
export declare const ComboboxCell: <TData extends unknown>({ model, value, onValueChange, }: {
|
|
8
|
+
model: SelectQueryModel<TData>;
|
|
9
|
+
value: TData;
|
|
10
|
+
onValueChange: (value: TData) => void;
|
|
11
|
+
}) => JSX.Element;
|
|
12
|
+
//# sourceMappingURL=ComboboxCell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComboboxCell.d.ts","sourceRoot":"","sources":["../../../../src/components/ComboboxCell.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAOrD,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnD,MAAM,MAAM,iBAAiB,CAAC,KAAK,SAAS,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,KAAK,CAAA;CAAE,CAAC,CAAC;AAStG,eAAO,MAAM,YAAY;;;qCAOU,IAAI;iBAiEtC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/index.ts"],"names":[],"mappings":"AAIA,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/index.ts"],"names":[],"mappings":"AAIA,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AACxB,cAAc,gBAAgB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/helpers.tsx"],"names":[],"mappings":"AAKA,OAAO,
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/helpers.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translations.d.ts","sourceRoot":"","sources":["../../../src/translations.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,cAAc,UAAU,CAAC;;;;;;;;AAEtC,wBAQE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dxos/react-ui-table",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.8-main.122b580",
|
|
4
4
|
"description": "A table component.",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -20,14 +20,14 @@
|
|
|
20
20
|
"@tanstack/react-table": "^8.9.3",
|
|
21
21
|
"date-fns": "^2.29.3",
|
|
22
22
|
"lodash.defaultsdeep": "^4.6.1",
|
|
23
|
-
"@dxos/async": "0.3.
|
|
24
|
-
"@dxos/invariant": "0.3.
|
|
25
|
-
"@dxos/
|
|
26
|
-
"@dxos/react-ui": "0.3.
|
|
27
|
-
"@dxos/react-ui-
|
|
28
|
-
"@dxos/react-ui-
|
|
29
|
-
"@dxos/
|
|
30
|
-
"@dxos/
|
|
23
|
+
"@dxos/async": "0.3.8-main.122b580",
|
|
24
|
+
"@dxos/invariant": "0.3.8-main.122b580",
|
|
25
|
+
"@dxos/react-ui": "0.3.8-main.122b580",
|
|
26
|
+
"@dxos/react-ui-searchlist": "0.3.8-main.122b580",
|
|
27
|
+
"@dxos/react-ui-theme": "0.3.8-main.122b580",
|
|
28
|
+
"@dxos/react-ui-types": "0.3.8-main.122b580",
|
|
29
|
+
"@dxos/util": "0.3.8-main.122b580",
|
|
30
|
+
"@dxos/keys": "0.3.8-main.122b580"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
33
|
"@faker-js/faker": "^8.0.2",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"react-dom": "^18.2.0",
|
|
42
42
|
"vite": "^4.3.9",
|
|
43
43
|
"vite-plugin-turbosnap": "^1.0.2",
|
|
44
|
-
"@dxos/react-ui-theme": "0.3.
|
|
44
|
+
"@dxos/react-ui-theme": "0.3.8-main.122b580"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"@phosphor-icons/react": "^2.0.5",
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { CaretDown } from '@phosphor-icons/react';
|
|
6
|
+
import { type RowData } from '@tanstack/react-table';
|
|
7
|
+
import React, { useCallback, useState } from 'react';
|
|
8
|
+
|
|
9
|
+
import { Popover, useTranslation } from '@dxos/react-ui';
|
|
10
|
+
import { PopoverCombobox } from '@dxos/react-ui-searchlist';
|
|
11
|
+
import { descriptionText, getSize, mx, staticPlaceholderText } from '@dxos/react-ui-theme';
|
|
12
|
+
|
|
13
|
+
import { type SelectQueryModel } from '../helpers';
|
|
14
|
+
import { translationKey } from '../translations';
|
|
15
|
+
|
|
16
|
+
export type ComboboxCellItems<TData extends RowData> = Record<string, { label: string; data: TData }>;
|
|
17
|
+
|
|
18
|
+
const initialItems = <TData extends RowData>(model: SelectQueryModel<TData>, value?: TData) =>
|
|
19
|
+
value
|
|
20
|
+
? {
|
|
21
|
+
[model.getId(value)]: { label: model.getText(value), data: value },
|
|
22
|
+
}
|
|
23
|
+
: {};
|
|
24
|
+
|
|
25
|
+
export const ComboboxCell = <TData extends RowData>({
|
|
26
|
+
model,
|
|
27
|
+
value,
|
|
28
|
+
onValueChange,
|
|
29
|
+
}: {
|
|
30
|
+
model: SelectQueryModel<TData>;
|
|
31
|
+
value: TData;
|
|
32
|
+
onValueChange: (value: TData) => void;
|
|
33
|
+
}) => {
|
|
34
|
+
const { t } = useTranslation(translationKey);
|
|
35
|
+
const [items, setItems] = useState<ComboboxCellItems<TData>>(initialItems(model, value));
|
|
36
|
+
const [loading, setLoading] = useState(false);
|
|
37
|
+
const [searchInputValue, setSearchInputValue] = useState('');
|
|
38
|
+
const handleSearchInputValueChange = async (text?: string) => {
|
|
39
|
+
setSearchInputValue(text ?? '');
|
|
40
|
+
setLoading(true);
|
|
41
|
+
const items = await model.query(text);
|
|
42
|
+
setItems(
|
|
43
|
+
items.reduce((acc: ComboboxCellItems<TData>, item) => {
|
|
44
|
+
acc[model.getId(item)] = {
|
|
45
|
+
label: model.getText(item),
|
|
46
|
+
data: item,
|
|
47
|
+
};
|
|
48
|
+
return acc;
|
|
49
|
+
}, initialItems(model, value)),
|
|
50
|
+
);
|
|
51
|
+
setLoading(false);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const handleValueChange = useCallback(
|
|
55
|
+
(id: string) => {
|
|
56
|
+
onValueChange(items[id]?.data);
|
|
57
|
+
},
|
|
58
|
+
[items, onValueChange],
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<PopoverCombobox.Root placeholder={t('no selection label')}>
|
|
63
|
+
<PopoverCombobox.Trigger variant='ghost' classNames='is-full'>
|
|
64
|
+
{value ? (
|
|
65
|
+
<>
|
|
66
|
+
<span
|
|
67
|
+
className={mx('font-normal text-start flex-1 min-is-0 truncate mie-2', !value && staticPlaceholderText)}
|
|
68
|
+
>
|
|
69
|
+
{model.getText(value)}
|
|
70
|
+
</span>
|
|
71
|
+
<CaretDown weight='bold' className={getSize(3)} />
|
|
72
|
+
</>
|
|
73
|
+
) : null}
|
|
74
|
+
</PopoverCombobox.Trigger>
|
|
75
|
+
<PopoverCombobox.Content shouldFilter={false} classNames='is-[--radix-popover-trigger-width]'>
|
|
76
|
+
<PopoverCombobox.Input value={searchInputValue} onValueChange={handleSearchInputValueChange} />
|
|
77
|
+
<PopoverCombobox.List>
|
|
78
|
+
{searchInputValue.length < 1 ? (
|
|
79
|
+
<p className={mx('text-center', descriptionText)}>Start typing to search</p>
|
|
80
|
+
) : loading ? (
|
|
81
|
+
<p className={mx('text-center', descriptionText)}>Searching…</p>
|
|
82
|
+
) : (
|
|
83
|
+
<>
|
|
84
|
+
<PopoverCombobox.Empty classNames={['text-center', descriptionText]}>No results</PopoverCombobox.Empty>
|
|
85
|
+
{Object.entries(items).map(([id, { label }]) => (
|
|
86
|
+
<PopoverCombobox.Item key={id} value={id} onSelect={handleValueChange} classNames='truncate'>
|
|
87
|
+
{label}
|
|
88
|
+
</PopoverCombobox.Item>
|
|
89
|
+
))}
|
|
90
|
+
</>
|
|
91
|
+
)}
|
|
92
|
+
</PopoverCombobox.List>
|
|
93
|
+
<Popover.Arrow />
|
|
94
|
+
</PopoverCombobox.Content>
|
|
95
|
+
</PopoverCombobox.Root>
|
|
96
|
+
);
|
|
97
|
+
};
|
package/src/components/index.ts
CHANGED
package/src/helpers.tsx
CHANGED
|
@@ -3,19 +3,20 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { useFocusFinders } from '@fluentui/react-tabster';
|
|
6
|
-
import {
|
|
6
|
+
import { Check, ClipboardText, type Icon, X } from '@phosphor-icons/react';
|
|
7
7
|
import { createColumnHelper, type ColumnDef, type ColumnMeta, type RowData } from '@tanstack/react-table';
|
|
8
8
|
import format from 'date-fns/format';
|
|
9
9
|
import formatDistanceToNow from 'date-fns/formatDistanceToNow';
|
|
10
10
|
import defaultsDeep from 'lodash.defaultsdeep';
|
|
11
|
-
import React, {
|
|
11
|
+
import React, { useRef, useState } from 'react';
|
|
12
12
|
|
|
13
13
|
import { type PublicKey } from '@dxos/keys';
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import { descriptionText, getSize, mx } from '@dxos/react-ui-theme';
|
|
14
|
+
import { Input, Tooltip } from '@dxos/react-ui';
|
|
15
|
+
import { getSize, mx } from '@dxos/react-ui-theme';
|
|
17
16
|
import { stripUndefinedValues } from '@dxos/util';
|
|
18
17
|
|
|
18
|
+
import { ComboboxCell } from './components';
|
|
19
|
+
|
|
19
20
|
// TODO(burdon): Factor out hack to find next focusable element (extend useFocusFinders)?
|
|
20
21
|
const findNextFocusable = (
|
|
21
22
|
findFirstFocusable: (container: HTMLElement) => HTMLElement | null | undefined,
|
|
@@ -95,88 +96,6 @@ const defaults = <TData extends RowData, TValue>(
|
|
|
95
96
|
return stripUndefinedValues(defaultsDeep({}, options, ...sources));
|
|
96
97
|
};
|
|
97
98
|
|
|
98
|
-
type CellSelectorItems<TData extends RowData> = Record<string, { label: string; data: TData }>;
|
|
99
|
-
|
|
100
|
-
const initialItems = <TData extends RowData>(model: SelectQueryModel<TData>, value?: TData) =>
|
|
101
|
-
value
|
|
102
|
-
? {
|
|
103
|
-
[model.getId(value)]: { label: model.getText(value), data: value },
|
|
104
|
-
}
|
|
105
|
-
: {};
|
|
106
|
-
|
|
107
|
-
const CellSelector = <TData extends RowData>({
|
|
108
|
-
model,
|
|
109
|
-
value,
|
|
110
|
-
onValueChange,
|
|
111
|
-
}: {
|
|
112
|
-
model: SelectQueryModel<TData>;
|
|
113
|
-
value: TData;
|
|
114
|
-
onValueChange: (value: TData) => void;
|
|
115
|
-
}) => {
|
|
116
|
-
const [items, setItems] = useState<CellSelectorItems<TData>>(initialItems(model, value));
|
|
117
|
-
const [loading, setLoading] = useState(false);
|
|
118
|
-
const [searchInputValue, setSearchInputValue] = useState('');
|
|
119
|
-
const handleSearchInputValueChange = async (text?: string) => {
|
|
120
|
-
setSearchInputValue(text ?? '');
|
|
121
|
-
setLoading(true);
|
|
122
|
-
const items = await model.query(text);
|
|
123
|
-
setItems(
|
|
124
|
-
items.reduce((acc: CellSelectorItems<TData>, item) => {
|
|
125
|
-
acc[model.getId(item)] = {
|
|
126
|
-
label: model.getText(item),
|
|
127
|
-
data: item,
|
|
128
|
-
};
|
|
129
|
-
return acc;
|
|
130
|
-
}, initialItems(model, value)),
|
|
131
|
-
);
|
|
132
|
-
setLoading(false);
|
|
133
|
-
};
|
|
134
|
-
|
|
135
|
-
const handleValueChange = useCallback(
|
|
136
|
-
(id: string) => {
|
|
137
|
-
onValueChange(items[id]?.data);
|
|
138
|
-
},
|
|
139
|
-
[items, onValueChange],
|
|
140
|
-
);
|
|
141
|
-
|
|
142
|
-
return (
|
|
143
|
-
<Popover.Root>
|
|
144
|
-
<Popover.Trigger asChild>
|
|
145
|
-
<Button variant='ghost' classNames='is-full font-normal'>
|
|
146
|
-
<span className='flex-1 text-start truncate'>{value ? model.getText(value) : ' '}</span>
|
|
147
|
-
<CaretDown />
|
|
148
|
-
</Button>
|
|
149
|
-
</Popover.Trigger>
|
|
150
|
-
<Popover.Portal>
|
|
151
|
-
<Popover.Content side='bottom' collisionPadding={48} classNames='is-[--radix-popover-trigger-width]'>
|
|
152
|
-
<SearchList.Root shouldFilter={false}>
|
|
153
|
-
<SearchList.Input value={searchInputValue} onValueChange={handleSearchInputValueChange} />
|
|
154
|
-
<Popover.Viewport>
|
|
155
|
-
<SearchList.Content>
|
|
156
|
-
{searchInputValue.length < 1 ? (
|
|
157
|
-
<p className={mx('text-center', descriptionText)}>Start typing to search</p>
|
|
158
|
-
) : loading ? (
|
|
159
|
-
<p className={mx('text-center', descriptionText)}>Searching…</p>
|
|
160
|
-
) : (
|
|
161
|
-
<>
|
|
162
|
-
<SearchList.Empty classNames={['text-center', descriptionText]}>No results</SearchList.Empty>
|
|
163
|
-
{Object.entries(items).map(([id, { label }]) => (
|
|
164
|
-
<SearchList.Item key={id} value={id} onSelect={handleValueChange} classNames='truncate'>
|
|
165
|
-
{label}
|
|
166
|
-
</SearchList.Item>
|
|
167
|
-
))}
|
|
168
|
-
</>
|
|
169
|
-
)}
|
|
170
|
-
</SearchList.Content>
|
|
171
|
-
</Popover.Viewport>
|
|
172
|
-
</SearchList.Root>
|
|
173
|
-
<Popover.Arrow />
|
|
174
|
-
</Popover.Content>
|
|
175
|
-
</Popover.Portal>
|
|
176
|
-
</Popover.Root>
|
|
177
|
-
);
|
|
178
|
-
};
|
|
179
|
-
|
|
180
99
|
/**
|
|
181
100
|
* Util to create column definitions.
|
|
182
101
|
*/
|
|
@@ -193,7 +112,7 @@ export class ColumnBuilder<TData extends RowData> {
|
|
|
193
112
|
cell:
|
|
194
113
|
model && onUpdate
|
|
195
114
|
? (cell) => (
|
|
196
|
-
<
|
|
115
|
+
<ComboboxCell<any>
|
|
197
116
|
model={model}
|
|
198
117
|
value={cell.getValue()}
|
|
199
118
|
onValueChange={(value) => onUpdate?.(cell.row.original, cell.column.id, value)}
|