Skip to content

Commit d78387d

Browse files
committed
Initial commit
0 parents  commit d78387d

12 files changed

Lines changed: 1456 additions & 0 deletions

File tree

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
node_modules
2+
.DS_Store
3+
dist
4+
dist-ssr
5+
*.local

index.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Logseq Plugin</title>
8+
</head>
9+
<body>
10+
<div id="app"></div>
11+
<script type="module" src="/src/main.tsx"></script>
12+
</body>
13+
</html>

logo.svg

Lines changed: 7 additions & 0 deletions
Loading

package.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "logseq-plugin-template-react",
3+
"version": "0.0.1",
4+
"main": "dist/index.html",
5+
"scripts": {
6+
"dev": "vite",
7+
"build": "tsc && vite build"
8+
},
9+
"license": "MIT",
10+
"dependencies": {
11+
"@logseq/libs": "^0.0.1-alpha.19",
12+
"react": "^17.0.0",
13+
"react-dom": "^17.0.0",
14+
"react-use": "^17.2.4"
15+
},
16+
"devDependencies": {
17+
"@types/react": "17.0.16",
18+
"@types/react-dom": "17.0.9",
19+
"@vitejs/plugin-react-refresh": "1.3.6",
20+
"typescript": "4.3.5",
21+
"vite": "2.4.4",
22+
"vite-plugin-windicss": "1.2.7",
23+
"windicss": "3.1.7"
24+
},
25+
"logseq": {
26+
"id": "_pengx17-logseq-template-react",
27+
"icon": "./logo.svg"
28+
}
29+
}

readme.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Logseq Plugin Template React
2+
3+
## Features
4+
- plug & play boilerplate
5+
- develop with HMR, empowered by lightning fast Vite ⚡
6+
- windicss for styling
7+
8+
### How HMR works?
9+
10+
See vite.config.ts. There is a custom plugin that will write a dev only index.html.
11+
The index.html will
12+
- change its base to `http://${config.server.host}:${config.server.port}`
13+
- attach `/@vite/client` (allows error overlay and connect HMR ws)
14+
- register react-refresh preamble code

renovate.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"extends": [
3+
"config:base"
4+
],
5+
"packageRules": [
6+
{
7+
"matchUpdateTypes": ["minor", "patch"],
8+
"matchCurrentVersion": "!/^0/",
9+
"automerge": true,
10+
"requiredStatusChecks": null
11+
}
12+
]
13+
}

src/App.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React, { useRef } from "react";
2+
import { useAppVisible } from "./utils";
3+
4+
function App() {
5+
const innerRef = useRef<HTMLDivElement>(null);
6+
const visible = useAppVisible();
7+
if (visible) {
8+
return (
9+
<main
10+
className="backdrop-filter backdrop-blur-md fixed inset-0 flex items-center justify-center"
11+
onClick={(e) => {
12+
if (!innerRef.current?.contains(e.target as any)) {
13+
window.logseq.hideMainUI();
14+
}
15+
}}
16+
>
17+
<div ref={innerRef} className="text-size-2em">
18+
Welcome to [[Logseq]] Plugins!
19+
</div>
20+
</main>
21+
);
22+
}
23+
return null;
24+
}
25+
26+
export default App;

src/main.tsx

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import "@logseq/libs";
2+
import "virtual:windi.css";
3+
4+
import React from "react";
5+
import ReactDOM from "react-dom";
6+
import App from "./App";
7+
8+
import { logseq as PL } from '../package.json';
9+
10+
// @ts-expect-error
11+
const css = (t, ...args) => String.raw(t, ...args);
12+
const magicKey = `__${PL.id}__loaded__`;
13+
14+
function main() {
15+
const pluginId = logseq.baseInfo.id;
16+
console.info(`#${pluginId}: MAIN`);
17+
ReactDOM.render(
18+
<React.StrictMode>
19+
<App />
20+
</React.StrictMode>,
21+
document.getElementById("app")
22+
);
23+
24+
function createModel() {
25+
return {
26+
show() {
27+
logseq.showMainUI();
28+
},
29+
};
30+
}
31+
32+
logseq.provideModel(createModel());
33+
logseq.setMainUIInlineStyle({
34+
zIndex: 11,
35+
});
36+
37+
const openIconName = "template-plugin-open";
38+
39+
// @ts-expect-error
40+
top[magicKey] = true;
41+
42+
logseq.provideStyle(css`
43+
div[data-injected-ui=${openIconName}-${pluginId}] {
44+
display: inline-flex;
45+
align-items: center;
46+
opacity: 0.55;
47+
font-weight: 500;
48+
padding: 0 5px;
49+
position: relative;
50+
}
51+
52+
div[data-injected-ui=${openIconName}-${pluginId}]:hover {
53+
opacity: 0.9;
54+
}
55+
`);
56+
57+
logseq.provideUI({
58+
key: openIconName,
59+
path: "#search",
60+
template: `
61+
<a data-on-click="show"
62+
style="opacity: .6; display: inline-flex;">⚙️</a>
63+
`,
64+
});
65+
}
66+
67+
// @ts-expect-error
68+
if (top[magicKey]) {
69+
top.location.reload();
70+
}
71+
72+
logseq.ready(main).catch(console.error);

src/utils.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import React, { useState } from "react";
2+
import { useMountedState } from "react-use";
3+
4+
export const useAppVisible = () => {
5+
const [visible, setVisible] = useState(logseq.isMainUIVisible);
6+
const isMounted = useMountedState();
7+
React.useEffect(() => {
8+
const eventName = "ui:visible:changed";
9+
const handler = async ({ visible }: any) => {
10+
if (isMounted()) {
11+
setVisible(visible);
12+
}
13+
};
14+
logseq.on(eventName, handler);
15+
return () => {
16+
logseq.off(eventName, handler);
17+
};
18+
}, []);
19+
return visible;
20+
};
21+
22+
export const useSidebarVisible = () => {
23+
const [visible, setVisible] = useState(false);
24+
const isMounted = useMountedState();
25+
React.useEffect(() => {
26+
logseq.App.onSidebarVisibleChanged(({ visible }) => {
27+
if (isMounted()) {
28+
setVisible(visible);
29+
}
30+
});
31+
}, []);
32+
return visible;
33+
};

tsconfig.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"compilerOptions": {
3+
"target": "ESNext",
4+
"lib": ["DOM", "DOM.Iterable", "ESNext"],
5+
"types": ["vite/client"],
6+
"allowJs": false,
7+
"skipLibCheck": false,
8+
"esModuleInterop": false,
9+
"allowSyntheticDefaultImports": true,
10+
"strict": true,
11+
"forceConsistentCasingInFileNames": true,
12+
"module": "ESNext",
13+
"moduleResolution": "Node",
14+
"resolveJsonModule": true,
15+
"isolatedModules": true,
16+
"noEmit": true,
17+
"jsx": "react"
18+
},
19+
"include": ["./src"]
20+
}

0 commit comments

Comments
 (0)