@dxos/react-ui-table 0.3.7-main.ea9e237 → 0.3.7-main.ec7f1fc

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.
@@ -520,6 +520,89 @@ var TableFoot = ({ footers, expand, slots, debug, border }) => {
520
520
  }))));
521
521
  };
522
522
 
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
+ }
538
+ }
539
+ }
540
+ ];
541
+
542
+ // packages/ui/react-ui-table/src/components/ComboboxCell.tsx
543
+ var initialItems = (model, value) => value ? {
544
+ [model.getId(value)]: {
545
+ label: model.getText(value),
546
+ data: value
547
+ }
548
+ } : {};
549
+ var ComboboxCell = ({ model, value, onValueChange }) => {
550
+ const { t } = useTranslation(translationKey);
551
+ const [items, setItems] = useState3(initialItems(model, value));
552
+ const [loading, setLoading] = useState3(false);
553
+ const [searchInputValue, setSearchInputValue] = useState3("");
554
+ const handleSearchInputValueChange = async (text) => {
555
+ setSearchInputValue(text ?? "");
556
+ setLoading(true);
557
+ const items2 = await model.query(text);
558
+ setItems(items2.reduce((acc, item) => {
559
+ acc[model.getId(item)] = {
560
+ label: model.getText(item),
561
+ data: item
562
+ };
563
+ return acc;
564
+ }, initialItems(model, value)));
565
+ setLoading(false);
566
+ };
567
+ const handleValueChange = useCallback((id) => {
568
+ onValueChange(items[id]?.data);
569
+ }, [
570
+ items,
571
+ onValueChange
572
+ ]);
573
+ return /* @__PURE__ */ React3.createElement(PopoverCombobox.Root, {
574
+ placeholder: t("no selection label")
575
+ }, /* @__PURE__ */ React3.createElement(PopoverCombobox.Trigger, {
576
+ variant: "ghost",
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,
585
+ classNames: "is-[--radix-popover-trigger-width]"
586
+ }, /* @__PURE__ */ React3.createElement(PopoverCombobox.Input, {
587
+ value: searchInputValue,
588
+ onValueChange: handleSearchInputValueChange
589
+ }), /* @__PURE__ */ React3.createElement(PopoverCombobox.List, null, searchInputValue.length < 1 ? /* @__PURE__ */ React3.createElement("p", {
590
+ className: mx3("text-center", descriptionText)
591
+ }, "Start typing to search") : loading ? /* @__PURE__ */ React3.createElement("p", {
592
+ className: mx3("text-center", descriptionText)
593
+ }, "Searching\u2026") : /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement(PopoverCombobox.Empty, {
594
+ classNames: [
595
+ "text-center",
596
+ descriptionText
597
+ ]
598
+ }, "No results"), Object.entries(items).map(([id, { label }]) => /* @__PURE__ */ React3.createElement(PopoverCombobox.Item, {
599
+ key: id,
600
+ value: id,
601
+ onSelect: handleValueChange,
602
+ classNames: "truncate"
603
+ }, label)))), /* @__PURE__ */ React3.createElement(Popover2.Arrow, null)));
604
+ };
605
+
523
606
  // packages/ui/react-ui-table/src/helpers.tsx
524
607
  import { useFocusFinders } from "@fluentui/react-tabster";
525
608
  import { Check as Check2, ClipboardText, X as X2 } from "@phosphor-icons/react";
@@ -527,9 +610,9 @@ import { createColumnHelper } from "@tanstack/react-table";
527
610
  import format from "date-fns/format";
528
611
  import formatDistanceToNow from "date-fns/formatDistanceToNow";
529
612
  import defaultsDeep from "lodash.defaultsdeep";
530
- import React3, { useEffect as useEffect2, useRef as useRef3, useState as useState3 } from "react";
531
- import { ComboBox, Input as Input2, Tooltip } from "@dxos/react-ui";
532
- import { getSize as getSize2, mx as mx3 } from "@dxos/react-ui-theme";
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";
533
616
  import { stripUndefinedValues } from "@dxos/util";
534
617
  var findNextFocusable = (findFirstFocusable, container) => {
535
618
  const next = findFirstFocusable(container);
@@ -549,44 +632,6 @@ var createColumnBuilder = () => ({
549
632
  var defaults = (options, ...sources) => {
550
633
  return stripUndefinedValues(defaultsDeep({}, options, ...sources));
551
634
  };
552
- var CellSelector = ({ model, value: _value, onUpdate }) => {
553
- const [edit, setEdit] = useState3(false);
554
- const [value, setValue] = useState3();
555
- useEffect2(() => setValue(_value ? {
556
- id: model.getId(_value),
557
- label: model.getText(_value)
558
- } : void 0), [
559
- _value
560
- ]);
561
- const [items, setItems] = useState3([]);
562
- const handleUpdate = async (text) => {
563
- const items2 = await model.query(text);
564
- setItems(items2.map((item) => ({
565
- id: model.getId(item),
566
- label: model.getText(item),
567
- data: item
568
- })));
569
- };
570
- if (!edit) {
571
- const text = _value ? model.getText(_value) : void 0;
572
- return (
573
- // TODO(burdon): Hack to prevent div from collapsing.
574
- /* @__PURE__ */ React3.createElement("div", {
575
- className: mx3("w-full px-2", !text && "opacity-0"),
576
- onClick: () => setEdit(true)
577
- }, text ?? "-")
578
- );
579
- }
580
- return /* @__PURE__ */ React3.createElement(ComboBox.Root, {
581
- items,
582
- value,
583
- onChange: (value2) => onUpdate(value2?.data),
584
- onInputChange: handleUpdate
585
- }, /* @__PURE__ */ React3.createElement(ComboBox.Input, null), /* @__PURE__ */ React3.createElement(ComboBox.Content, null, items.map((item) => /* @__PURE__ */ React3.createElement(ComboBox.Item, {
586
- key: item.id,
587
- item
588
- }, item.label))));
589
- };
590
635
  var ColumnBuilder = class {
591
636
  /**
592
637
  * Select value
@@ -595,18 +640,18 @@ var ColumnBuilder = class {
595
640
  return defaults(props, {
596
641
  minSize: 100,
597
642
  header: (column) => {
598
- return /* @__PURE__ */ React3.createElement("div", {
643
+ return /* @__PURE__ */ React4.createElement("div", {
599
644
  className: "truncate"
600
645
  }, label ?? column.header.id);
601
646
  },
602
- cell: model && onUpdate ? (cell) => /* @__PURE__ */ React3.createElement(CellSelector, {
647
+ cell: model && onUpdate ? (cell) => /* @__PURE__ */ React4.createElement(ComboboxCell, {
603
648
  model,
604
649
  value: cell.getValue(),
605
- onUpdate: (value) => onUpdate?.(cell.row.original, cell.column.id, value)
650
+ onValueChange: (value) => onUpdate?.(cell.row.original, cell.column.id, value)
606
651
  }) : (cell) => {
607
652
  const value = cell.getValue();
608
- return /* @__PURE__ */ React3.createElement("div", {
609
- className: mx3("truncate", className)
653
+ return /* @__PURE__ */ React4.createElement("div", {
654
+ className: mx4("truncate", className)
610
655
  }, value ? model.getText(value) : "");
611
656
  }
612
657
  });
@@ -619,13 +664,13 @@ var ColumnBuilder = class {
619
664
  minSize: 100,
620
665
  // TODO(burdon): Default.
621
666
  header: (column) => {
622
- return /* @__PURE__ */ React3.createElement("div", {
667
+ return /* @__PURE__ */ React4.createElement("div", {
623
668
  className: "truncate"
624
669
  }, label ?? column.header.id);
625
670
  },
626
671
  cell: onUpdate ? (cell) => {
627
672
  const initialValue = cell.getValue();
628
- const [value, setValue] = useState3(initialValue);
673
+ const [value, setValue] = useState4(initialValue);
629
674
  const inputRef = useRef3(null);
630
675
  const { findFirstFocusable } = useFocusFinders();
631
676
  const handleSave = (focusNext = false) => {
@@ -647,7 +692,7 @@ var ColumnBuilder = class {
647
692
  const rows = cell.table.getRowModel().flatRows;
648
693
  const columns = cell.table.getVisibleFlatColumns();
649
694
  const placeholder = cell.row.index === rows.length - 1 && columns[0].id === cell.column.id;
650
- return /* @__PURE__ */ React3.createElement(Input2.Root, null, /* @__PURE__ */ React3.createElement(Input2.TextInput, {
695
+ return /* @__PURE__ */ React4.createElement(Input2.Root, null, /* @__PURE__ */ React4.createElement(Input2.TextInput, {
651
696
  ref: inputRef,
652
697
  variant: "subdued",
653
698
  placeholder: placeholder ? "Add row..." : void 0,
@@ -659,8 +704,8 @@ var ColumnBuilder = class {
659
704
  }));
660
705
  } : (cell) => {
661
706
  const value = cell.getValue();
662
- return /* @__PURE__ */ React3.createElement("div", {
663
- className: mx3("truncate", className)
707
+ return /* @__PURE__ */ React4.createElement("div", {
708
+ className: mx4("truncate", className)
664
709
  }, value);
665
710
  }
666
711
  });
@@ -672,12 +717,12 @@ var ColumnBuilder = class {
672
717
  return defaults(props, {
673
718
  size: 100,
674
719
  minSize: 100,
675
- header: (cell) => /* @__PURE__ */ React3.createElement("div", {
720
+ header: (cell) => /* @__PURE__ */ React4.createElement("div", {
676
721
  className: "w-full truncate text-right"
677
722
  }, label ?? cell.header.id),
678
723
  cell: (cell) => {
679
724
  const value = cell.getValue();
680
- const [text, setText] = useState3();
725
+ const [text, setText] = useState4();
681
726
  const handleEdit = () => {
682
727
  if (onUpdate) {
683
728
  setText(value !== void 0 ? String(value) : "");
@@ -692,9 +737,9 @@ var ColumnBuilder = class {
692
737
  setText(void 0);
693
738
  };
694
739
  if (text !== void 0) {
695
- return /* @__PURE__ */ React3.createElement("div", {
696
- className: mx3("grow text-right font-mono", className)
697
- }, /* @__PURE__ */ React3.createElement(Input2.Root, null, /* @__PURE__ */ React3.createElement(Input2.TextInput, {
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, {
698
743
  autoFocus: true,
699
744
  value: text,
700
745
  classNames: "px-2",
@@ -703,8 +748,8 @@ var ColumnBuilder = class {
703
748
  onKeyDown: (event) => event.key === "Escape" && handleCancel() || event.key === "Enter" && handleSave()
704
749
  })));
705
750
  }
706
- return /* @__PURE__ */ React3.createElement("div", {
707
- className: mx3('grow w-full text-right font-mono empty:after:content-["\xA0"]', className),
751
+ return /* @__PURE__ */ React4.createElement("div", {
752
+ className: mx4('grow w-full text-right font-mono empty:after:content-["\xA0"]', className),
708
753
  onClick: handleEdit
709
754
  }, value?.toLocaleString(void 0, {
710
755
  minimumFractionDigits: digits ?? 0,
@@ -721,15 +766,15 @@ var ColumnBuilder = class {
721
766
  return defaults(props, {
722
767
  size: 220,
723
768
  minSize: 100,
724
- header: (cell) => /* @__PURE__ */ React3.createElement("div", null, label ?? cell.header.id),
769
+ header: (cell) => /* @__PURE__ */ React4.createElement("div", null, label ?? cell.header.id),
725
770
  cell: (cell) => {
726
771
  const value = cell.getValue();
727
772
  try {
728
773
  const str = value ? formatSpec ? format(value, formatSpec) : relative ? formatDistanceToNow(value, {
729
774
  addSuffix: true
730
775
  }) : value.toISOString() : void 0;
731
- return /* @__PURE__ */ React3.createElement("div", {
732
- className: mx3("font-mono", className)
776
+ return /* @__PURE__ */ React4.createElement("div", {
777
+ className: mx4("font-mono", className)
733
778
  }, str);
734
779
  } catch (err) {
735
780
  console.log(value);
@@ -745,25 +790,25 @@ var ColumnBuilder = class {
745
790
  return defaults(props, {
746
791
  size: 86,
747
792
  minSize: 86,
748
- header: (cell) => /* @__PURE__ */ React3.createElement("div", null, label ?? cell.header.id),
793
+ header: (cell) => /* @__PURE__ */ React4.createElement("div", null, label ?? cell.header.id),
749
794
  cell: (cell) => {
750
795
  const value = cell.getValue();
751
796
  if (!value) {
752
797
  return;
753
798
  }
754
- const element = /* @__PURE__ */ React3.createElement("div", {
799
+ const element = /* @__PURE__ */ React4.createElement("div", {
755
800
  className: "font-mono font-thin text-green-500 dark:text-green-300"
756
801
  }, value.truncate());
757
802
  if (!tooltip) {
758
803
  return element;
759
804
  }
760
- return /* @__PURE__ */ React3.createElement("div", {
805
+ return /* @__PURE__ */ React4.createElement("div", {
761
806
  className: "group inline-flex gap-2 items-center"
762
- }, /* @__PURE__ */ React3.createElement(Tooltip.Provider, null, /* @__PURE__ */ React3.createElement(Tooltip.Root, null, /* @__PURE__ */ React3.createElement(Tooltip.Trigger, {
807
+ }, /* @__PURE__ */ React4.createElement(Tooltip.Provider, null, /* @__PURE__ */ React4.createElement(Tooltip.Root, null, /* @__PURE__ */ React4.createElement(Tooltip.Trigger, {
763
808
  asChild: true
764
- }, element), /* @__PURE__ */ React3.createElement(Tooltip.Content, {
809
+ }, element), /* @__PURE__ */ React4.createElement(Tooltip.Content, {
765
810
  side: "right"
766
- }, /* @__PURE__ */ React3.createElement(Tooltip.Arrow, null), /* @__PURE__ */ React3.createElement(ClipboardText, {
811
+ }, /* @__PURE__ */ React4.createElement(Tooltip.Arrow, null), /* @__PURE__ */ React4.createElement(ClipboardText, {
767
812
  onClick: (ev) => {
768
813
  ev.stopPropagation();
769
814
  void navigator.clipboard.writeText(value.toHex());
@@ -779,14 +824,14 @@ var ColumnBuilder = class {
779
824
  return defaults(props, {
780
825
  size: 40,
781
826
  minSize: 40,
782
- header: (column) => /* @__PURE__ */ React3.createElement("div", {
827
+ header: (column) => /* @__PURE__ */ React4.createElement("div", {
783
828
  className: "flex grow justify-center"
784
829
  }, label ?? column.header.id),
785
830
  cell: (cell) => {
786
831
  const value = cell.getValue();
787
- return /* @__PURE__ */ React3.createElement("div", {
832
+ return /* @__PURE__ */ React4.createElement("div", {
788
833
  className: "flex grow justify-center"
789
- }, /* @__PURE__ */ React3.createElement(Input2.Root, null, /* @__PURE__ */ React3.createElement(Input2.Checkbox, {
834
+ }, /* @__PURE__ */ React4.createElement(Input2.Root, null, /* @__PURE__ */ React4.createElement(Input2.Checkbox, {
790
835
  onClick: (event) => event.stopPropagation(),
791
836
  classNames: className,
792
837
  disabled: !onUpdate,
@@ -806,22 +851,22 @@ var ColumnBuilder = class {
806
851
  const IconOff = off?.Icon ?? X2;
807
852
  return defaults(props, {
808
853
  size: size ?? 32,
809
- header: (column) => /* @__PURE__ */ React3.createElement("div", {
854
+ header: (column) => /* @__PURE__ */ React4.createElement("div", {
810
855
  className: "justify-center"
811
856
  }, label ?? column.header.id),
812
857
  cell: (cell) => {
813
858
  const value = cell.getValue();
814
859
  if (value) {
815
- return /* @__PURE__ */ React3.createElement("div", {
860
+ return /* @__PURE__ */ React4.createElement("div", {
816
861
  className: "flex grow justify-center"
817
- }, /* @__PURE__ */ React3.createElement(IconOn, {
818
- className: mx3(getSize2(6), on?.className ?? "text-green-700")
862
+ }, /* @__PURE__ */ React4.createElement(IconOn, {
863
+ className: mx4(getSize3(6), on?.className ?? "text-green-700")
819
864
  }));
820
865
  } else if (value === false) {
821
- return /* @__PURE__ */ React3.createElement("div", {
866
+ return /* @__PURE__ */ React4.createElement("div", {
822
867
  className: "flex grow justify-center"
823
- }, /* @__PURE__ */ React3.createElement(IconOff, {
824
- className: mx3(getSize2(6), off?.className ?? "text-red-700")
868
+ }, /* @__PURE__ */ React4.createElement(IconOff, {
869
+ className: mx4(getSize3(6), off?.className ?? "text-red-700")
825
870
  }));
826
871
  } else {
827
872
  return null;
@@ -834,6 +879,7 @@ export {
834
879
  ColumnBuilder,
835
880
  ColumnMenu,
836
881
  ColumnPanel,
882
+ ComboboxCell,
837
883
  Table,
838
884
  columnTypes,
839
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 { 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, { useEffect, useRef, useState } from 'react';\n\nimport { type PublicKey } from '@dxos/keys';\nimport { ComboBox, type ComboBoxItem, Input, Tooltip } from '@dxos/react-ui';\nimport { 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\n/**\n * Lazy cell selector (click to activate).\n */\nconst CellSelector = <TData extends RowData>({\n model,\n value: _value,\n onUpdate,\n}: {\n model: SelectQueryModel<TData>;\n value: TData;\n onUpdate: (value: TData) => void;\n}) => {\n const [edit, setEdit] = useState(false);\n const [value, setValue] = useState<ComboBoxItem>();\n useEffect(() => setValue(_value ? { id: model.getId(_value), label: model.getText(_value) } : undefined), [_value]);\n const [items, setItems] = useState<ComboBoxItem[]>([]);\n const handleUpdate = async (text?: string) => {\n const items = await model.query(text);\n setItems(items.map((item) => ({ id: model.getId(item), label: model.getText(item), data: item })));\n };\n\n if (!edit) {\n const text = _value ? model.getText(_value) : undefined;\n return (\n // TODO(burdon): Hack to prevent div from collapsing.\n <div className={mx('w-full px-2', !text && 'opacity-0')} onClick={() => setEdit(true)}>\n {text ?? '-'}\n </div>\n );\n }\n\n return (\n <ComboBox.Root items={items} value={value} onChange={(value) => onUpdate(value?.data)} onInputChange={handleUpdate}>\n <ComboBox.Input />\n <ComboBox.Content>\n {items.map((item) => (\n <ComboBox.Item key={item.id} item={item}>\n {item.label}\n </ComboBox.Item>\n ))}\n </ComboBox.Content>\n </ComboBox.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 onUpdate={(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", "useFocusFinders", "Check", "ClipboardText", "X", "createColumnHelper", "format", "formatDistanceToNow", "defaultsDeep", "React", "useEffect", "useRef", "useState", "ComboBox", "Input", "Tooltip", "getSize", "mx", "stripUndefinedValues", "findNextFocusable", "findFirstFocusable", "container", "next", "tagName", "nextElementSibling", "nextSibling", "createColumnBuilder", "helper", "createColumnHelper", "builder", "ColumnBuilder", "defaults", "options", "sources", "stripUndefinedValues", "defaultsDeep", "CellSelector", "model", "value", "_value", "onUpdate", "edit", "setEdit", "useState", "setValue", "useEffect", "id", "getId", "label", "getText", "undefined", "items", "setItems", "handleUpdate", "text", "query", "map", "item", "data", "React", "div", "className", "mx", "onClick", "ComboBox", "Root", "onChange", "onInputChange", "Input", "Content", "Item", "key", "select", "props", "minSize", "header", "column", "cell", "getValue", "row", "original", "string", "initialValue", "inputRef", "useRef", "useFocusFinders", "handleSave", "focusNext", "rowElement", "current", "parentElement", "setTimeout", "focus", "handleCancel", "rows", "table", "getRowModel", "flatRows", "columns", "getVisibleFlatColumns", "placeholder", "index", "length", "TextInput", "ref", "variant", "classNames", "onBlur", "event", "target", "onKeyDown", "number", "digits", "size", "setText", "handleEdit", "String", "trim", "Number", "NaN", "isNaN", "autoFocus", "toLocaleString", "minimumFractionDigits", "maximumFractionDigits", "date", "format", "formatSpec", "relative", "str", "formatDistanceToNow", "addSuffix", "toISOString", "err", "console", "log", "tooltip", "element", "truncate", "Tooltip", "Provider", "Trigger", "asChild", "side", "Arrow", "ClipboardText", "ev", "stopPropagation", "navigator", "clipboard", "writeText", "toHex", "checkbox", "Checkbox", "disabled", "checked", "onCheckedChange", "icon", "on", "off", "IconOn", "Icon", "Check", "IconOff", "X", "getSize"]
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":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/components/index.ts":{"bytes":564,"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"}],"format":"esm"},"packages/ui/react-ui-table/src/helpers.tsx":{"bytes":45871,"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}],"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":70078},"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":"@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","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/index.ts":{"bytesInOutput":0},"packages/ui/react-ui-table/src/helpers.tsx":{"bytesInOutput":11339}},"bytes":32227}}}
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"}
@@ -4,6 +4,7 @@ import { type TableColumnDef } from '../types';
4
4
  type Item = {
5
5
  publicKey: PublicKey;
6
6
  name: string;
7
+ company?: string;
7
8
  count?: number;
8
9
  started?: Date;
9
10
  complete?: boolean;
@@ -56,9 +57,6 @@ declare const _default: {
56
57
  };
57
58
  };
58
59
  decorators: ((Story: any) => JSX.Element)[];
59
- parameters: {
60
- layout: string;
61
- };
62
60
  };
63
61
  export default _default;
64
62
  export declare const Default: {
@@ -1 +1 @@
1
- {"version":3,"file":"Table.stories.d.ts","sourceRoot":"","sources":["../../../../src/components/Table.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,YAAY,CAAC;AAOpB,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAMvC,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AAK/C,KAAK,IAAI,GAAG;IACV,SAAS,EAAE,SAAS,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;;;;;4BAiEsB,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAyChB,GAAG;;;;;AA7Cf,wBA0DE;AAEF,eAAO,MAAM,OAAO;;;;;CAKnB,CAAC;AAEF,eAAO,MAAM,SAAS;;;;;CAKrB,CAAC;AAEF,eAAO,MAAM,UAAU;;;;;;;;;CAMtB,CAAC;AAEF,eAAO,MAAM,KAAK;;;;CAIjB,CAAC;AAEF,eAAO,MAAM,OAAO;;CA8BnB,CAAC;AAEF,eAAO,MAAM,QAAQ;;CAmBpB,CAAC;AAEF,eAAO,MAAM,SAAS;;CAwBrB,CAAC"}
1
+ {"version":3,"file":"Table.stories.d.ts","sourceRoot":"","sources":["../../../../src/components/Table.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,YAAY,CAAC;AAOpB,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAMvC,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AAK/C,KAAK,IAAI,GAAG;IACV,SAAS,EAAE,SAAS,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;;;;;4BAgGsB,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yBAyChB,GAAG;;AA7Cf,wBAmDE;AAEF,eAAO,MAAM,OAAO;;;;;CAKnB,CAAC;AAEF,eAAO,MAAM,SAAS;;;;;CAKrB,CAAC;AAEF,eAAO,MAAM,UAAU;;;;;;;;;CAMtB,CAAC;AAEF,eAAO,MAAM,KAAK;;;;CAIjB,CAAC;AAEF,eAAO,MAAM,OAAO;;CA8BnB,CAAC;AAEF,eAAO,MAAM,QAAQ;;CAmBpB,CAAC;AAEF,eAAO,MAAM,SAAS;;CAwBrB,CAAC"}
@@ -1,3 +1,4 @@
1
1
  export * from './ColumnMenu';
2
2
  export * from './Table';
3
+ export * from './ComboboxCell';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -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":"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"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/helpers.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export declare const translationKey = "table";
2
+ declare const _default: {
3
+ 'en-US': {
4
+ table: {
5
+ 'no selection label': string;
6
+ };
7
+ };
8
+ }[];
9
+ export default _default;
10
+ //# sourceMappingURL=translations.d.ts.map
@@ -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.7-main.ea9e237",
3
+ "version": "0.3.7-main.ec7f1fc",
4
4
  "description": "A table component.",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -20,13 +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/invariant": "0.3.7-main.ea9e237",
24
- "@dxos/keys": "0.3.7-main.ea9e237",
25
- "@dxos/react-ui": "0.3.7-main.ea9e237",
26
- "@dxos/async": "0.3.7-main.ea9e237",
27
- "@dxos/react-ui-types": "0.3.7-main.ea9e237",
28
- "@dxos/react-ui-theme": "0.3.7-main.ea9e237",
29
- "@dxos/util": "0.3.7-main.ea9e237"
23
+ "@dxos/invariant": "0.3.7-main.ec7f1fc",
24
+ "@dxos/async": "0.3.7-main.ec7f1fc",
25
+ "@dxos/keys": "0.3.7-main.ec7f1fc",
26
+ "@dxos/react-ui-searchlist": "0.3.7-main.ec7f1fc",
27
+ "@dxos/react-ui": "0.3.7-main.ec7f1fc",
28
+ "@dxos/react-ui-types": "0.3.7-main.ec7f1fc",
29
+ "@dxos/react-ui-theme": "0.3.7-main.ec7f1fc",
30
+ "@dxos/util": "0.3.7-main.ec7f1fc"
30
31
  },
31
32
  "devDependencies": {
32
33
  "@faker-js/faker": "^8.0.2",
@@ -40,7 +41,7 @@
40
41
  "react-dom": "^18.2.0",
41
42
  "vite": "^4.3.9",
42
43
  "vite-plugin-turbosnap": "^1.0.2",
43
- "@dxos/react-ui-theme": "0.3.7-main.ea9e237"
44
+ "@dxos/react-ui-theme": "0.3.7-main.ec7f1fc"
44
45
  },
45
46
  "peerDependencies": {
46
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
+ };
@@ -14,7 +14,7 @@ import { DensityProvider } from '@dxos/react-ui';
14
14
  import { range } from '@dxos/util';
15
15
 
16
16
  import { Table } from './Table';
17
- import { createColumnBuilder, type ValueUpdater } from '../helpers';
17
+ import { createColumnBuilder, type SelectQueryModel, type ValueUpdater } from '../helpers';
18
18
  import { type TableColumnDef } from '../types';
19
19
 
20
20
  // TODO(burdon): Header menu builder.
@@ -23,11 +23,13 @@ import { type TableColumnDef } from '../types';
23
23
  type Item = {
24
24
  publicKey: PublicKey;
25
25
  name: string;
26
+ company?: string;
26
27
  count?: number;
27
28
  started?: Date;
28
29
  complete?: boolean;
29
30
  };
30
31
 
32
+ // TODO(thure): …y’all okay?
31
33
  faker.seed(911);
32
34
 
33
35
  const createItems = (count: number) =>
@@ -46,6 +48,28 @@ const updateItems = <TValue = any,>(items: Item[], key: PublicKey, id: string, v
46
48
  return items.map((item) => (item.publicKey.equals(key) ? { ...item, [id]: value } : item));
47
49
  };
48
50
 
51
+ const tableStorySelectItems: Record<string, Item> = range(128).reduce((acc: Record<string, Item>, _i) => {
52
+ const id = PublicKey.random();
53
+ acc[id.toHex()] = {
54
+ publicKey: id,
55
+ name: faker.company.name(),
56
+ };
57
+ return acc;
58
+ }, {});
59
+
60
+ const timeout = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
61
+
62
+ const tableStorySelectModel: SelectQueryModel<Item> = {
63
+ getId: (object) => object?.publicKey?.toHex() ?? 'never',
64
+ getText: (object) => object?.name ?? 'never',
65
+ query: async (search: string) => {
66
+ await timeout(400);
67
+ return Object.values(tableStorySelectItems).filter((item) => {
68
+ return item.name.toLowerCase().includes(search.toLowerCase());
69
+ });
70
+ },
71
+ };
72
+
49
73
  const { helper, builder } = createColumnBuilder<Item>();
50
74
  const columns = (onUpdate?: ValueUpdater<Item, any>): TableColumnDef<Item, any>[] => [
51
75
  helper.accessor(
@@ -62,6 +86,14 @@ const columns = (onUpdate?: ValueUpdater<Item, any>): TableColumnDef<Item, any>[
62
86
  'name',
63
87
  builder.string({ onUpdate, meta: { expand: true }, footer: (props) => props.table.getRowModel().rows.length }),
64
88
  ),
89
+ helper.accessor(
90
+ 'company',
91
+ builder.select({
92
+ label: 'Company',
93
+ model: tableStorySelectModel,
94
+ onUpdate,
95
+ }),
96
+ ),
65
97
  helper.accessor('started', builder.date({ relative: true, meta: { resizable: true } })),
66
98
  helper.accessor(
67
99
  'count',
@@ -133,18 +165,11 @@ export default {
133
165
  },
134
166
  decorators: [
135
167
  (Story: any) => (
136
- <div className='flex flex-col items-center h-screen w-full overflow-hidden bg-zinc-200'>
137
- <div className='flex w-[800px] h-full'>
138
- <DensityProvider density='fine'>
139
- <Story />
140
- </DensityProvider>
141
- </div>
142
- </div>
168
+ <DensityProvider density='fine'>
169
+ <Story />
170
+ </DensityProvider>
143
171
  ),
144
172
  ],
145
- parameters: {
146
- layout: 'fullscreen',
147
- },
148
173
  };
149
174
 
150
175
  export const Default = {
@@ -4,3 +4,4 @@
4
4
 
5
5
  export * from './ColumnMenu';
6
6
  export * from './Table';
7
+ export * from './ComboboxCell';
package/src/helpers.tsx CHANGED
@@ -8,13 +8,15 @@ import { createColumnHelper, type ColumnDef, type ColumnMeta, type RowData } fro
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, { useEffect, useRef, useState } from 'react';
11
+ import React, { useRef, useState } from 'react';
12
12
 
13
13
  import { type PublicKey } from '@dxos/keys';
14
- import { ComboBox, type ComboBoxItem, Input, Tooltip } from '@dxos/react-ui';
14
+ import { Input, Tooltip } from '@dxos/react-ui';
15
15
  import { getSize, mx } from '@dxos/react-ui-theme';
16
16
  import { stripUndefinedValues } from '@dxos/util';
17
17
 
18
+ import { ComboboxCell } from './components';
19
+
18
20
  // TODO(burdon): Factor out hack to find next focusable element (extend useFocusFinders)?
19
21
  const findNextFocusable = (
20
22
  findFirstFocusable: (container: HTMLElement) => HTMLElement | null | undefined,
@@ -94,51 +96,6 @@ const defaults = <TData extends RowData, TValue>(
94
96
  return stripUndefinedValues(defaultsDeep({}, options, ...sources));
95
97
  };
96
98
 
97
- /**
98
- * Lazy cell selector (click to activate).
99
- */
100
- const CellSelector = <TData extends RowData>({
101
- model,
102
- value: _value,
103
- onUpdate,
104
- }: {
105
- model: SelectQueryModel<TData>;
106
- value: TData;
107
- onUpdate: (value: TData) => void;
108
- }) => {
109
- const [edit, setEdit] = useState(false);
110
- const [value, setValue] = useState<ComboBoxItem>();
111
- useEffect(() => setValue(_value ? { id: model.getId(_value), label: model.getText(_value) } : undefined), [_value]);
112
- const [items, setItems] = useState<ComboBoxItem[]>([]);
113
- const handleUpdate = async (text?: string) => {
114
- const items = await model.query(text);
115
- setItems(items.map((item) => ({ id: model.getId(item), label: model.getText(item), data: item })));
116
- };
117
-
118
- if (!edit) {
119
- const text = _value ? model.getText(_value) : undefined;
120
- return (
121
- // TODO(burdon): Hack to prevent div from collapsing.
122
- <div className={mx('w-full px-2', !text && 'opacity-0')} onClick={() => setEdit(true)}>
123
- {text ?? '-'}
124
- </div>
125
- );
126
- }
127
-
128
- return (
129
- <ComboBox.Root items={items} value={value} onChange={(value) => onUpdate(value?.data)} onInputChange={handleUpdate}>
130
- <ComboBox.Input />
131
- <ComboBox.Content>
132
- {items.map((item) => (
133
- <ComboBox.Item key={item.id} item={item}>
134
- {item.label}
135
- </ComboBox.Item>
136
- ))}
137
- </ComboBox.Content>
138
- </ComboBox.Root>
139
- );
140
- };
141
-
142
99
  /**
143
100
  * Util to create column definitions.
144
101
  */
@@ -155,10 +112,10 @@ export class ColumnBuilder<TData extends RowData> {
155
112
  cell:
156
113
  model && onUpdate
157
114
  ? (cell) => (
158
- <CellSelector<any>
115
+ <ComboboxCell<any>
159
116
  model={model}
160
117
  value={cell.getValue()}
161
- onUpdate={(value) => onUpdate?.(cell.row.original, cell.column.id, value)}
118
+ onValueChange={(value) => onUpdate?.(cell.row.original, cell.column.id, value)}
162
119
  />
163
120
  )
164
121
  : (cell) => {
@@ -0,0 +1,15 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ export const translationKey = 'table';
6
+
7
+ export default [
8
+ {
9
+ 'en-US': {
10
+ [translationKey]: {
11
+ 'no selection label': ' ',
12
+ },
13
+ },
14
+ },
15
+ ];