Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6e41828512 |
@@ -1,21 +1,36 @@
|
|||||||
import { Title } from "./Primitives/Title";
|
import { Title } from "./Primitives/Title";
|
||||||
import { colorForItemAtPath } from "~/utilities/colors";
|
import { colorForItemAtPath } from "~/utilities/colors";
|
||||||
import { IconComponent } from "~/useColumnView";
|
import { ColumnViewNode, IconComponent } from "~/useColumnView";
|
||||||
import { useJson } from "../hooks/useJson";
|
import { useJson } from "../hooks/useJson";
|
||||||
import { memo, useMemo } from "react";
|
import { memo, useCallback, useMemo, useRef } from "react";
|
||||||
|
import { ColumnItem } from "./ColumnItem";
|
||||||
|
import { useJsonColumnViewAPI } from "~/hooks/useJsonColumnView";
|
||||||
|
import { useVirtual } from "react-virtual";
|
||||||
|
|
||||||
export type ColumnProps = {
|
export type ColumnProps = {
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
title: string;
|
||||||
icon?: IconComponent;
|
icon?: IconComponent;
|
||||||
hasHighlightedElement: boolean;
|
hasHighlightedElement: boolean;
|
||||||
children: React.ReactNode;
|
items: ColumnViewNode[];
|
||||||
|
selectedPath: string[];
|
||||||
|
highlightedPath: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
function ColumnElement(column: ColumnProps) {
|
function ColumnElement(column: ColumnProps) {
|
||||||
const { id, title, children } = column;
|
const { id, title, items, selectedPath, highlightedPath } = column;
|
||||||
const [json] = useJson();
|
const [json] = useJson();
|
||||||
const iconColor = useMemo(() => colorForItemAtPath(id, json), [id, json]);
|
const iconColor = useMemo(() => colorForItemAtPath(id, json), [id, json]);
|
||||||
|
const { goToNodeId } = useJsonColumnViewAPI();
|
||||||
|
|
||||||
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
const rowVirtualizer = useVirtual({
|
||||||
|
size: items.length,
|
||||||
|
parentRef: containerRef,
|
||||||
|
estimateSize: useCallback(() => 36, []),
|
||||||
|
overscan: 5,
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@@ -27,8 +42,44 @@ function ColumnElement(column: ColumnProps) {
|
|||||||
{column.icon && <column.icon className="h-6 w-6 mr-1" />}
|
{column.icon && <column.icon className="h-6 w-6 mr-1" />}
|
||||||
<Title className="">{title}</Title>
|
<Title className="">{title}</Title>
|
||||||
</div>
|
</div>
|
||||||
<div className="overflow-y-auto h-viewerHeight no-scrollbar">
|
<div
|
||||||
{children}
|
className="overflow-y-auto h-viewerHeight no-scrollbar"
|
||||||
|
ref={containerRef}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
height: `${rowVirtualizer.totalSize}px`,
|
||||||
|
width: "100%",
|
||||||
|
position: "relative",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{rowVirtualizer.virtualItems.map((virtualRow) => {
|
||||||
|
const item = items[virtualRow.index];
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={virtualRow.index}
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
width: "100%",
|
||||||
|
height: `${virtualRow.size}px`,
|
||||||
|
transform: `translateY(${virtualRow.start}px)`,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ColumnItem
|
||||||
|
item={item}
|
||||||
|
json={json}
|
||||||
|
isSelected={selectedPath.includes(item.id)}
|
||||||
|
isHighlighted={
|
||||||
|
highlightedPath[highlightedPath.length - 1] === item.id
|
||||||
|
}
|
||||||
|
onClick={(id) => goToNodeId(id, "columnView")}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ function ColumnsElement({ columns }: { columns: ColumnDefinition[] }) {
|
|||||||
const [json] = useJson();
|
const [json] = useJson();
|
||||||
const { selectedPath, highlightedPath, highlightedNodeId } =
|
const { selectedPath, highlightedPath, highlightedNodeId } =
|
||||||
useJsonColumnViewState();
|
useJsonColumnViewState();
|
||||||
const { goToNodeId } = useJsonColumnViewAPI();
|
|
||||||
const highlightedItemIsValue = useMemo<boolean>(() => {
|
const highlightedItemIsValue = useMemo<boolean>(() => {
|
||||||
if (highlightedNodeId == null) {
|
if (highlightedNodeId == null) {
|
||||||
return false;
|
return false;
|
||||||
@@ -38,20 +37,10 @@ function ColumnsElement({ columns }: { columns: ColumnDefinition[] }) {
|
|||||||
hasHighlightedElement={
|
hasHighlightedElement={
|
||||||
highlightedPath[highlightedPath.length - 2] === column.id
|
highlightedPath[highlightedPath.length - 2] === column.id
|
||||||
}
|
}
|
||||||
>
|
selectedPath={selectedPath}
|
||||||
{column.items.map((item) => (
|
highlightedPath={highlightedPath}
|
||||||
<ColumnItem
|
items={column.items}
|
||||||
key={item.id}
|
/>
|
||||||
item={item}
|
|
||||||
json={json}
|
|
||||||
isSelected={selectedPath.includes(item.id)}
|
|
||||||
isHighlighted={
|
|
||||||
highlightedPath[highlightedPath.length - 1] === item.id
|
|
||||||
}
|
|
||||||
onClick={(id) => goToNodeId(id, "columnView")}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</Column>
|
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
{highlightedItemIsValue ? <BlankColumn /> : null}
|
{highlightedItemIsValue ? <BlankColumn /> : null}
|
||||||
|
|||||||
Reference in New Issue
Block a user