waveterm/frontend/app/tab/tabcontent.tsx
Evan Simkowitz 74c8044c73
Add gap size setting (#325)
Adds a new setting for the gap size between tiles in a layout. Also
updates the resize handle calculations so they are dynamically generated
based on the gap size. Also updates the styling for the resize handles
to be more robust.

This also updates the default gap size to 3px.

This also slims out the Block Frame padding so it is just enough that
the blocks don't overlap when there's no gap.
2024-09-04 22:07:47 -07:00

84 lines
2.6 KiB
TypeScript

// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
import { Block } from "@/app/block/block";
import { CenteredDiv } from "@/element/quickelems";
import { ContentRenderer, NodeModel, PreviewRenderer, TileLayout } from "@/layout/index";
import { TileLayoutContents } from "@/layout/lib/types";
import { atoms, getApi } from "@/store/global";
import * as services from "@/store/services";
import * as WOS from "@/store/wos";
import { atom, useAtomValue } from "jotai";
import * as React from "react";
import { useMemo } from "react";
import "./tabcontent.less";
const tileGapSizeAtom = atom((get) => {
const settings = get(atoms.settingsAtom);
return settings["window:tilegapsize"];
});
const TabContent = React.memo(({ tabId }: { tabId: string }) => {
const oref = useMemo(() => WOS.makeORef("tab", tabId), [tabId]);
const loadingAtom = useMemo(() => WOS.getWaveObjectLoadingAtom(oref), [oref]);
const tabLoading = useAtomValue(loadingAtom);
const tabAtom = useMemo(() => WOS.getWaveObjectAtom<Tab>(oref), [oref]);
const tabData = useAtomValue(tabAtom);
const tileGapSize = useAtomValue(tileGapSizeAtom);
const tileLayoutContents = useMemo(() => {
const renderContent: ContentRenderer = (nodeModel: NodeModel) => {
return <Block key={nodeModel.blockId} nodeModel={nodeModel} preview={false} />;
};
const renderPreview: PreviewRenderer = (nodeModel: NodeModel) => {
return <Block key={nodeModel.blockId} nodeModel={nodeModel} preview={true} />;
};
function onNodeDelete(data: TabLayoutData) {
return services.ObjectService.DeleteBlock(data.blockId);
}
return {
renderContent,
renderPreview,
tabId,
onNodeDelete,
gapSizePx: tileGapSize,
} as TileLayoutContents;
}, [tabId, tileGapSize]);
if (tabLoading) {
return (
<div className="tabcontent">
<CenteredDiv>Tab Loading</CenteredDiv>
</div>
);
}
if (!tabData) {
return (
<div className="tabcontent">
<CenteredDiv>Tab Not Found</CenteredDiv>
</div>
);
}
if (tabData?.blockids?.length == 0) {
return <div className="tabcontent tabcontent-empty"></div>;
}
return (
<div className="tabcontent">
<TileLayout
key={tabId}
contents={tileLayoutContents}
tabAtom={tabAtom}
getCursorPoint={getApi().getCursorPoint}
/>
</div>
);
});
export { TabContent };