Skip to content

Commit

Permalink
✨ Implemented opening / closing of modal
Browse files Browse the repository at this point in the history
  • Loading branch information
chanjunren committed Feb 7, 2025
1 parent 7d03036 commit 0f135fa
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 40 deletions.
9 changes: 3 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"mdast-util-from-markdown": "^2.0.1",
"path": "^0.12.7",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"unist-builder": "^4.0.0",
"unist-util-map": "^4.0.0"
}
Expand Down
45 changes: 41 additions & 4 deletions src/plugin/css/index.module.css
Original file line number Diff line number Diff line change
@@ -1,22 +1,59 @@
:root {
--vaultusaurus-modal-width: 80%;
--vaultusaurus-modal-height: 60%;
--vaultusaurus-icon-size: 1.7rem;
}

.container {
background: var(--graph-bg);
aspect-ratio: 1 / 1;
border-radius: 8px;
position: relative;
}

.expandIcon {
.hidden {
display: none;
}

.modalContainer {
background: var(--graph-bg);
aspect-ratio: 16 / 9;
border-radius: 8px;
z-index: 9999;
width: var(--vaultusaurus-modal-width);
height: var(--vaultusaurus-modal-height);
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
overflow: hidden;
position: relative;
}

.modalOverlay {
width: 100vw;
position: fixed;
top: 0;
left: 0;
height: 100vh;
z-index: 9998;
display: flex;
justify-content: center;
align-items: center;
backdrop-filter: blur(5px);
}

.actionIcon {
position: absolute;
top: 17px;
right: 1.5rem;
width: 1.5rem;
right: 17px;
width: var(--vaultusaurus-icon-size);
height: var(--vaultusaurus-icon-size);
opacity: 0.5;
transition-property: all;
transition-duration: 0.3s;
cursor: pointer;
color: var(--default-color);
}

.expandIcon:hover {
.actionIcon:hover {
opacity: 1;
}

Expand Down
4 changes: 3 additions & 1 deletion src/plugin/hooks/useLocalGraph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export default function useLocalGraph(rawData: GraphInfo) {
const simulation =
useRef<Simulation<ObsidianNoteNode, ObsidianNoteLink>>(null);

const [expanded, setExpanded] = useState<boolean>(false);

useEffect(() => {
if (!graphData?.nodes) {
return;
Expand Down Expand Up @@ -60,7 +62,7 @@ export default function useLocalGraph(rawData: GraphInfo) {
};
}, [graphData]);

return { nodes, links, simulation };
return { nodes, links, simulation, expanded, setExpanded };
}

function toNodeMap(nodes: ObsidianNoteNode[]) {
Expand Down
5 changes: 5 additions & 0 deletions src/plugin/resources/CollapseIcon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions src/plugin/theme/LocalGraph/GraphContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { ReactElement, useRef } from "react";

import { GraphInfo } from "@vaultusaurus/common/types";
import { useLocalGraph, useZoom } from "@vaultusaurus/plugin/hooks";
import GraphLink from "@vaultusaurus/plugin/theme/GraphLink";
import GraphNode from "@vaultusaurus/plugin/theme/GraphNode";
interface IGraphContent {
info: GraphInfo;
}

export default function GraphContent({ info }): ReactElement<IGraphContent> {
const { nodes, links } = useLocalGraph(info);

const container = useRef(null);
const { transform } = useZoom(container);
return (
<>
<svg viewBox={`0 0 300 300`} ref={container}>
<g transform={transform}>
{links.map((link, idx) => {
return <GraphLink key={`obsidian-link-${idx}`} link={link} />;
})}
{Object.values(nodes).map((node) => (
<GraphNode key={node.id} node={node} />
))}
</g>
</svg>
</>
);
}
75 changes: 46 additions & 29 deletions src/plugin/theme/LocalGraph/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,31 @@ import { usePluginData } from "@docusaurus/useGlobalData";
import { GraphInfo, VaultusaurusGlobalData } from "@vaultusaurus/common/types";
import { GraphContext } from "@vaultusaurus/plugin/context";
import styles from "@vaultusaurus/plugin/css/index.module.css";
import { useHover, useLocalGraph, useZoom } from "@vaultusaurus/plugin/hooks";
import { useHover, useLocalGraph } from "@vaultusaurus/plugin/hooks";
import CollapseIcon from "@vaultusaurus/plugin/resources/CollapseIcon.svg";
import ExpandIcon from "@vaultusaurus/plugin/resources/ExpandIcon.svg";
import GraphLink from "@vaultusaurus/plugin/theme/GraphLink";
import GraphNode from "@vaultusaurus/plugin/theme/GraphNode";
import {
FALLBACK_ACTIVE_COLOR,
FALLBACK_BACKGROUND_COLOR,
FALLBACK_DEFAULT_COLOR,
} from "@vaultusaurus/plugin/utils";
import { ReactElement, useRef } from "react";
import { ReactElement } from "react";
import { createPortal } from "react-dom";
import GraphContent from "./GraphContent";

interface ILocalGraph {
customGraph?: GraphInfo;
expandable?: boolean;
modal?: boolean;
modalCloseCallback: () => void;
}

export default function LocalGraph({ customGraph }): ReactElement<ILocalGraph> {
export default function LocalGraph({
customGraph,
expandable = true,
modal = false,
modalCloseCallback,
}): ReactElement<ILocalGraph> {
const globalData = usePluginData(
"docusaurus-plugin-vaultusaurus"
) as VaultusaurusGlobalData;
Expand All @@ -27,51 +36,59 @@ export default function LocalGraph({ customGraph }): ReactElement<ILocalGraph> {
if (!graphInfo) {
return null;
}

const inputGraphStyle = globalData.graphStyle;

const { nodes, links, simulation } = useLocalGraph(graphInfo);
const container = useRef(null);
const { transform } = useZoom(container);
const { simulation, expanded, setExpanded } = useLocalGraph(graphInfo);
const rawLinks = graphInfo?.links || [];

const defaultColor = inputGraphStyle.defaultColor || FALLBACK_DEFAULT_COLOR;
const activeColor = inputGraphStyle.activeColor || FALLBACK_ACTIVE_COLOR;

return (
<GraphContext.Provider
value={{
...useHover(rawLinks),
simulation,
graphStyle: {
activeColor: inputGraphStyle.activeColor || FALLBACK_ACTIVE_COLOR,
defaultColor: inputGraphStyle.defaultColor || FALLBACK_DEFAULT_COLOR,
activeColor: activeColor,
defaultColor: defaultColor,
},
}}
>
{expanded &&
createPortal(
<div className={styles.modalOverlay}>
<LocalGraph
modal
expandable={false}
modalCloseCallback={() => setExpanded(false)}
/>
</div>,
document.body
)}
<div
className={styles.container}
className={modal ? styles.modalContainer : styles.container}
style={
{
"--graph-bg":
globalData.graphStyle.graphBg || FALLBACK_BACKGROUND_COLOR,
"--default-color": defaultColor,
} as React.CSSProperties
}
>
<ExpandIcon
className={styles.expandIcon}
style={{
color: FALLBACK_DEFAULT_COLOR,
}}
/>

<svg viewBox={`0 0 300 300`} ref={container}>
<g transform={transform}>
{links.map((link, idx) => {
return <GraphLink key={`obsidian-link-${idx}`} link={link} />;
})}
{Object.values(nodes).map((node) => (
<GraphNode key={node.id} node={node} />
))}
</g>
</svg>
{!expanded && expandable && (
<ExpandIcon
className={styles.actionIcon}
onClick={() => setExpanded(true)}
/>
)}
{modal && (
<CollapseIcon
className={styles.actionIcon}
onClick={() => modalCloseCallback()}
/>
)}
<GraphContent info={graphInfo} />
</div>
</GraphContext.Provider>
);
Expand Down

0 comments on commit 0f135fa

Please sign in to comment.